feat(114): accounting configs refactor + invoice configs CRUD
Phase 114 complete (v3.7 Invoices): - /settings/accounting jako hub-rozdroze (Paragony / Faktury) - /settings/accounting/receipts + /invoices osobne podstrony list i edycji - InvoiceConfigRepository + Controller (CRUD z walidacja delegacji) - Seed Domyslny VAT (NOT EXISTS idempotent) - invoice-config-form.js (toggle is_delegated -> integration_id) - confirm-delete.js (globalny modul OrderProAlerts.confirm) - Legacy aliasy starych endpointow /settings/accounting/save|toggle|delete Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
158
src/Modules/Settings/InvoiceConfigController.php
Normal file
158
src/Modules/Settings/InvoiceConfigController.php
Normal file
@@ -0,0 +1,158 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Modules\Settings;
|
||||
|
||||
use App\Core\Http\Request;
|
||||
use App\Core\Http\Response;
|
||||
use App\Core\I18n\Translator;
|
||||
use App\Core\Security\Csrf;
|
||||
use App\Core\Support\Flash;
|
||||
use App\Core\View\Template;
|
||||
use App\Modules\Auth\AuthService;
|
||||
use Throwable;
|
||||
|
||||
final class InvoiceConfigController
|
||||
{
|
||||
public function __construct(
|
||||
private readonly Template $template,
|
||||
private readonly Translator $translator,
|
||||
private readonly AuthService $auth,
|
||||
private readonly InvoiceConfigRepository $repository,
|
||||
private readonly FakturowniaIntegrationRepository $fakturownia
|
||||
) {
|
||||
}
|
||||
|
||||
public function index(Request $request): Response
|
||||
{
|
||||
$configs = $this->repository->listAll();
|
||||
$accounts = $this->fakturownia->findAll();
|
||||
|
||||
$html = $this->template->render('settings/accounting-invoices', [
|
||||
'title' => 'Konfiguracje faktur',
|
||||
'activeMenu' => 'settings',
|
||||
'activeSettings' => 'accounting',
|
||||
'user' => $this->auth->user(),
|
||||
'csrfToken' => Csrf::token(),
|
||||
'configs' => $configs,
|
||||
'fakturowniaAccounts' => $accounts,
|
||||
'successMessage' => (string) Flash::get('accounting.invoices.save', ''),
|
||||
'errorMessage' => (string) Flash::get('accounting.invoices.error', ''),
|
||||
], 'layouts/app');
|
||||
|
||||
return Response::html($html);
|
||||
}
|
||||
|
||||
public function edit(Request $request): Response
|
||||
{
|
||||
$id = (int) $request->input('id', 0);
|
||||
$config = $id > 0 ? $this->repository->findById($id) : null;
|
||||
|
||||
if ($id > 0 && $config === null) {
|
||||
Flash::set('accounting.invoices.error', 'Nie znaleziono konfiguracji faktury ID ' . $id . '.');
|
||||
return Response::redirect('/settings/accounting/invoices');
|
||||
}
|
||||
|
||||
$accounts = array_values(array_filter(
|
||||
$this->fakturownia->findAll(),
|
||||
static fn (array $row) => !empty($row['is_active'])
|
||||
));
|
||||
|
||||
$html = $this->template->render('settings/accounting-invoice-edit', [
|
||||
'title' => $config === null ? 'Nowa konfiguracja faktury' : 'Edycja konfiguracji faktury',
|
||||
'activeMenu' => 'settings',
|
||||
'activeSettings' => 'accounting',
|
||||
'user' => $this->auth->user(),
|
||||
'csrfToken' => Csrf::token(),
|
||||
'config' => $config,
|
||||
'fakturowniaAccounts' => $accounts,
|
||||
'successMessage' => (string) Flash::get('accounting.invoices.save', ''),
|
||||
'errorMessage' => (string) Flash::get('accounting.invoices.error', ''),
|
||||
], 'layouts/app');
|
||||
|
||||
return Response::html($html);
|
||||
}
|
||||
|
||||
public function save(Request $request): Response
|
||||
{
|
||||
$id = (int) $request->input('id', 0);
|
||||
$redirectFail = $id > 0
|
||||
? '/settings/accounting/invoices/edit?id=' . $id
|
||||
: '/settings/accounting/invoices/new';
|
||||
|
||||
if (!Csrf::validate((string) $request->input('_token', ''))) {
|
||||
Flash::set('accounting.invoices.error', $this->translator->get('auth.errors.csrf_expired'));
|
||||
return Response::redirect($redirectFail);
|
||||
}
|
||||
|
||||
try {
|
||||
$this->repository->save([
|
||||
'id' => $id > 0 ? $id : '',
|
||||
'name' => (string) $request->input('name', ''),
|
||||
'number_format' => (string) $request->input('number_format', ''),
|
||||
'numbering_type' => (string) $request->input('numbering_type', 'monthly'),
|
||||
'sale_date_source' => (string) $request->input('sale_date_source', 'issue_date'),
|
||||
'order_reference' => (string) $request->input('order_reference', 'none'),
|
||||
'payment_to_days' => (int) $request->input('payment_to_days', 7),
|
||||
'default_kind' => (string) $request->input('default_kind', 'vat'),
|
||||
'is_delegated' => $request->input('is_delegated', ''),
|
||||
'integration_id' => $request->input('integration_id', ''),
|
||||
'is_active' => $request->input('is_active', ''),
|
||||
]);
|
||||
|
||||
Flash::set('accounting.invoices.save', 'Zapisano konfiguracje faktury.');
|
||||
return Response::redirect('/settings/accounting/invoices');
|
||||
} catch (Throwable $exception) {
|
||||
Flash::set('accounting.invoices.error', $exception->getMessage());
|
||||
return Response::redirect($redirectFail);
|
||||
}
|
||||
}
|
||||
|
||||
public function toggleStatus(Request $request): Response
|
||||
{
|
||||
$redirect = '/settings/accounting/invoices';
|
||||
if (!Csrf::validate((string) $request->input('_token', ''))) {
|
||||
Flash::set('accounting.invoices.error', $this->translator->get('auth.errors.csrf_expired'));
|
||||
return Response::redirect($redirect);
|
||||
}
|
||||
|
||||
$id = (int) $request->input('id', 0);
|
||||
if ($id <= 0) {
|
||||
Flash::set('accounting.invoices.error', 'Brak identyfikatora konfiguracji.');
|
||||
return Response::redirect($redirect);
|
||||
}
|
||||
|
||||
try {
|
||||
$this->repository->toggleStatus($id);
|
||||
Flash::set('accounting.invoices.save', 'Zmieniono status konfiguracji.');
|
||||
} catch (Throwable $exception) {
|
||||
Flash::set('accounting.invoices.error', $exception->getMessage());
|
||||
}
|
||||
|
||||
return Response::redirect($redirect);
|
||||
}
|
||||
|
||||
public function delete(Request $request): Response
|
||||
{
|
||||
$redirect = '/settings/accounting/invoices';
|
||||
if (!Csrf::validate((string) $request->input('_token', ''))) {
|
||||
Flash::set('accounting.invoices.error', $this->translator->get('auth.errors.csrf_expired'));
|
||||
return Response::redirect($redirect);
|
||||
}
|
||||
|
||||
$id = (int) $request->input('id', 0);
|
||||
if ($id <= 0) {
|
||||
Flash::set('accounting.invoices.error', 'Brak identyfikatora konfiguracji.');
|
||||
return Response::redirect($redirect);
|
||||
}
|
||||
|
||||
try {
|
||||
$this->repository->delete($id);
|
||||
Flash::set('accounting.invoices.save', 'Usunieto konfiguracje faktury.');
|
||||
} catch (Throwable $exception) {
|
||||
Flash::set('accounting.invoices.error', $exception->getMessage());
|
||||
}
|
||||
|
||||
return Response::redirect($redirect);
|
||||
}
|
||||
}
|
||||
228
src/Modules/Settings/InvoiceConfigRepository.php
Normal file
228
src/Modules/Settings/InvoiceConfigRepository.php
Normal file
@@ -0,0 +1,228 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Modules\Settings;
|
||||
|
||||
use App\Core\Exceptions\IntegrationConfigException;
|
||||
use App\Core\Http\ToggleableRepositoryTrait;
|
||||
use PDO;
|
||||
use RuntimeException;
|
||||
use Throwable;
|
||||
|
||||
final class InvoiceConfigRepository
|
||||
{
|
||||
use ToggleableRepositoryTrait;
|
||||
|
||||
public function __construct(private readonly PDO $pdo)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return list<array<string, mixed>>
|
||||
*/
|
||||
public function listAll(): array
|
||||
{
|
||||
$statement = $this->pdo->prepare(
|
||||
'SELECT ic.*, i.name AS integration_name
|
||||
FROM invoice_configs ic
|
||||
LEFT JOIN integrations i ON i.id = ic.integration_id AND i.type = :type
|
||||
ORDER BY ic.is_active DESC, ic.name ASC'
|
||||
);
|
||||
$statement->execute(['type' => 'fakturownia']);
|
||||
$rows = $statement->fetchAll(PDO::FETCH_ASSOC);
|
||||
|
||||
return is_array($rows) ? $rows : [];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, mixed>|null
|
||||
*/
|
||||
public function findById(int $id): ?array
|
||||
{
|
||||
if ($id <= 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$statement = $this->pdo->prepare(
|
||||
'SELECT ic.*, i.name AS integration_name
|
||||
FROM invoice_configs ic
|
||||
LEFT JOIN integrations i ON i.id = ic.integration_id AND i.type = :type
|
||||
WHERE ic.id = :id
|
||||
LIMIT 1'
|
||||
);
|
||||
$statement->execute(['id' => $id, 'type' => 'fakturownia']);
|
||||
$row = $statement->fetch(PDO::FETCH_ASSOC);
|
||||
|
||||
return is_array($row) ? $row : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<string, mixed> $data
|
||||
* @return int Saved config id
|
||||
*/
|
||||
public function save(array $data): int
|
||||
{
|
||||
$name = trim((string) ($data['name'] ?? ''));
|
||||
if ($name === '') {
|
||||
throw new IntegrationConfigException('Nazwa konfiguracji faktury jest wymagana.');
|
||||
}
|
||||
if (mb_strlen($name) > 128) {
|
||||
throw new IntegrationConfigException('Nazwa konfiguracji jest za dluga (max 128 znakow).');
|
||||
}
|
||||
|
||||
$numberFormat = trim((string) ($data['number_format'] ?? ''));
|
||||
if ($numberFormat === '') {
|
||||
throw new IntegrationConfigException('Format numeracji jest wymagany.');
|
||||
}
|
||||
if (mb_strlen($numberFormat) > 64) {
|
||||
throw new IntegrationConfigException('Format numeracji jest za dlugi (max 64 znakow).');
|
||||
}
|
||||
|
||||
$numberingType = (string) ($data['numbering_type'] ?? 'monthly');
|
||||
if (!in_array($numberingType, ['monthly', 'yearly'], true)) {
|
||||
$numberingType = 'monthly';
|
||||
}
|
||||
|
||||
$saleDateSource = (string) ($data['sale_date_source'] ?? 'issue_date');
|
||||
if (!in_array($saleDateSource, ['order_date', 'payment_date', 'issue_date'], true)) {
|
||||
$saleDateSource = 'issue_date';
|
||||
}
|
||||
|
||||
$orderReference = (string) ($data['order_reference'] ?? 'none');
|
||||
if (!in_array($orderReference, ['none', 'orderpro', 'integration'], true)) {
|
||||
$orderReference = 'none';
|
||||
}
|
||||
|
||||
$paymentToDays = (int) ($data['payment_to_days'] ?? 7);
|
||||
if ($paymentToDays < 0) {
|
||||
$paymentToDays = 0;
|
||||
}
|
||||
if ($paymentToDays > 365) {
|
||||
$paymentToDays = 365;
|
||||
}
|
||||
|
||||
$defaultKind = trim((string) ($data['default_kind'] ?? 'vat'));
|
||||
if ($defaultKind === '') {
|
||||
$defaultKind = 'vat';
|
||||
}
|
||||
if (mb_strlen($defaultKind) > 32) {
|
||||
throw new IntegrationConfigException('Typ dokumentu jest za dlugi (max 32 znakow).');
|
||||
}
|
||||
|
||||
$isDelegated = !empty($data['is_delegated']) ? 1 : 0;
|
||||
$isActive = !empty($data['is_active']) ? 1 : 0;
|
||||
$integrationId = isset($data['integration_id']) && $data['integration_id'] !== ''
|
||||
? (int) $data['integration_id']
|
||||
: null;
|
||||
|
||||
if ($isDelegated === 1) {
|
||||
if ($integrationId === null || $integrationId <= 0) {
|
||||
throw new IntegrationConfigException(
|
||||
'Przy delegacji wystawiania do Fakturowni musisz wskazac konto Fakturowni.'
|
||||
);
|
||||
}
|
||||
if (!$this->isFakturowniaIntegration($integrationId)) {
|
||||
throw new IntegrationConfigException(
|
||||
'Wybrana integracja nie jest kontem Fakturowni - sprawdz konfiguracje.'
|
||||
);
|
||||
}
|
||||
} else {
|
||||
$integrationId = null;
|
||||
}
|
||||
|
||||
$params = [
|
||||
'name' => $name,
|
||||
'integration_id' => $integrationId,
|
||||
'is_delegated' => $isDelegated,
|
||||
'is_active' => $isActive,
|
||||
'number_format' => $numberFormat,
|
||||
'numbering_type' => $numberingType,
|
||||
'sale_date_source' => $saleDateSource,
|
||||
'order_reference' => $orderReference,
|
||||
'payment_to_days' => $paymentToDays,
|
||||
'default_kind' => $defaultKind,
|
||||
];
|
||||
|
||||
$id = isset($data['id']) && $data['id'] !== '' ? (int) $data['id'] : 0;
|
||||
|
||||
if ($id > 0) {
|
||||
$statement = $this->pdo->prepare(
|
||||
'UPDATE invoice_configs SET
|
||||
name = :name,
|
||||
integration_id = :integration_id,
|
||||
is_delegated = :is_delegated,
|
||||
is_active = :is_active,
|
||||
number_format = :number_format,
|
||||
numbering_type = :numbering_type,
|
||||
sale_date_source = :sale_date_source,
|
||||
order_reference = :order_reference,
|
||||
payment_to_days = :payment_to_days,
|
||||
default_kind = :default_kind,
|
||||
updated_at = NOW()
|
||||
WHERE id = :id'
|
||||
);
|
||||
$params['id'] = $id;
|
||||
$statement->execute($params);
|
||||
return $id;
|
||||
}
|
||||
|
||||
$statement = $this->pdo->prepare(
|
||||
'INSERT INTO invoice_configs
|
||||
(name, integration_id, is_delegated, is_active, number_format, numbering_type,
|
||||
sale_date_source, order_reference, payment_to_days, default_kind)
|
||||
VALUES
|
||||
(:name, :integration_id, :is_delegated, :is_active, :number_format, :numbering_type,
|
||||
:sale_date_source, :order_reference, :payment_to_days, :default_kind)'
|
||||
);
|
||||
$statement->execute($params);
|
||||
|
||||
return (int) $this->pdo->lastInsertId();
|
||||
}
|
||||
|
||||
public function toggleStatus(int $id): void
|
||||
{
|
||||
$this->toggleActive('invoice_configs', $id);
|
||||
}
|
||||
|
||||
public function delete(int $id): void
|
||||
{
|
||||
if ($id <= 0) {
|
||||
throw new IntegrationConfigException('Nieprawidlowy identyfikator konfiguracji.');
|
||||
}
|
||||
|
||||
if ($this->hasInvoices($id)) {
|
||||
throw new IntegrationConfigException(
|
||||
'Nie mozna usunac konfiguracji - istnieja juz wystawione faktury powiazane z ta konfiguracja.'
|
||||
);
|
||||
}
|
||||
|
||||
$statement = $this->pdo->prepare('DELETE FROM invoice_configs WHERE id = :id');
|
||||
$statement->execute(['id' => $id]);
|
||||
}
|
||||
|
||||
private function isFakturowniaIntegration(int $integrationId): bool
|
||||
{
|
||||
try {
|
||||
$statement = $this->pdo->prepare(
|
||||
'SELECT 1 FROM integrations WHERE id = :id AND type = :type LIMIT 1'
|
||||
);
|
||||
$statement->execute(['id' => $integrationId, 'type' => 'fakturownia']);
|
||||
return $statement->fetchColumn() !== false;
|
||||
} catch (Throwable) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private function hasInvoices(int $configId): bool
|
||||
{
|
||||
try {
|
||||
$statement = $this->pdo->prepare(
|
||||
'SELECT 1 FROM invoices WHERE config_id = :id LIMIT 1'
|
||||
);
|
||||
$statement->execute(['id' => $configId]);
|
||||
return $statement->fetchColumn() !== false;
|
||||
} catch (Throwable) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -22,27 +22,58 @@ final class ReceiptConfigController
|
||||
) {
|
||||
}
|
||||
|
||||
public function index(Request $request): Response
|
||||
public function hub(Request $request): Response
|
||||
{
|
||||
$html = $this->template->render('settings/accounting', [
|
||||
'title' => $this->translator->get('settings.accounting.title'),
|
||||
'activeMenu' => 'settings',
|
||||
'activeSettings' => 'accounting',
|
||||
'user' => $this->auth->user(),
|
||||
'csrfToken' => Csrf::token(),
|
||||
'successMessage' => (string) Flash::get('settings.accounting.success', ''),
|
||||
'errorMessage' => (string) Flash::get('settings.accounting.error', ''),
|
||||
], 'layouts/app');
|
||||
|
||||
return Response::html($html);
|
||||
}
|
||||
|
||||
public function list(Request $request): Response
|
||||
{
|
||||
$t = $this->translator;
|
||||
$configs = $this->repository->listAll();
|
||||
|
||||
$editConfig = null;
|
||||
$editId = (int) $request->input('edit', '0');
|
||||
if ($editId > 0) {
|
||||
$editConfig = $this->repository->findById($editId);
|
||||
}
|
||||
|
||||
$html = $this->template->render('settings/accounting', [
|
||||
'title' => $t->get('settings.accounting.title'),
|
||||
$html = $this->template->render('settings/accounting-receipts', [
|
||||
'title' => 'Konfiguracje paragonow',
|
||||
'activeMenu' => 'settings',
|
||||
'activeSettings' => 'accounting',
|
||||
'user' => $this->auth->user(),
|
||||
'csrfToken' => Csrf::token(),
|
||||
'configs' => $configs,
|
||||
'editConfig' => $editConfig,
|
||||
'successMessage' => Flash::get('settings.accounting.success', ''),
|
||||
'errorMessage' => Flash::get('settings.accounting.error', ''),
|
||||
'successMessage' => (string) Flash::get('settings.accounting.success', ''),
|
||||
'errorMessage' => (string) Flash::get('settings.accounting.error', ''),
|
||||
], 'layouts/app');
|
||||
|
||||
return Response::html($html);
|
||||
}
|
||||
|
||||
public function edit(Request $request): Response
|
||||
{
|
||||
$id = (int) $request->input('id', 0);
|
||||
$config = $id > 0 ? $this->repository->findById($id) : null;
|
||||
|
||||
if ($id > 0 && $config === null) {
|
||||
Flash::set('settings.accounting.error', 'Nie znaleziono konfiguracji paragonu ID ' . $id . '.');
|
||||
return Response::redirect('/settings/accounting/receipts');
|
||||
}
|
||||
|
||||
$html = $this->template->render('settings/accounting-receipt-edit', [
|
||||
'title' => $config === null ? 'Nowa konfiguracja paragonu' : 'Edycja konfiguracji paragonu',
|
||||
'activeMenu' => 'settings',
|
||||
'activeSettings' => 'accounting',
|
||||
'user' => $this->auth->user(),
|
||||
'csrfToken' => Csrf::token(),
|
||||
'config' => $config,
|
||||
'successMessage' => (string) Flash::get('settings.accounting.success', ''),
|
||||
'errorMessage' => (string) Flash::get('settings.accounting.error', ''),
|
||||
], 'layouts/app');
|
||||
|
||||
return Response::html($html);
|
||||
@@ -50,9 +81,15 @@ final class ReceiptConfigController
|
||||
|
||||
public function save(Request $request): Response
|
||||
{
|
||||
$id = (int) $request->input('id', 0);
|
||||
$redirectFail = $id > 0
|
||||
? '/settings/accounting/receipts/edit?id=' . $id
|
||||
: '/settings/accounting/receipts/new';
|
||||
$redirectOk = '/settings/accounting/receipts';
|
||||
|
||||
if (!Csrf::validate((string) $request->input('_token', ''))) {
|
||||
Flash::set('settings.accounting.error', 'Nieprawidlowy token CSRF');
|
||||
return Response::redirect('/settings/accounting');
|
||||
return Response::redirect($redirectFail);
|
||||
}
|
||||
|
||||
$name = trim((string) $request->input('name', ''));
|
||||
@@ -60,17 +97,17 @@ final class ReceiptConfigController
|
||||
|
||||
if ($name === '') {
|
||||
Flash::set('settings.accounting.error', 'Nazwa konfiguracji jest wymagana');
|
||||
return Response::redirect('/settings/accounting');
|
||||
return Response::redirect($redirectFail);
|
||||
}
|
||||
|
||||
if ($numberFormat === '' || strpos($numberFormat, '%N') === false) {
|
||||
Flash::set('settings.accounting.error', 'Format numeracji jest wymagany i musi zawierac %N');
|
||||
return Response::redirect('/settings/accounting');
|
||||
return Response::redirect($redirectFail);
|
||||
}
|
||||
|
||||
try {
|
||||
$this->repository->save([
|
||||
'id' => $request->input('id', ''),
|
||||
'id' => $id > 0 ? $id : '',
|
||||
'name' => $name,
|
||||
'is_active' => $request->input('is_active', null),
|
||||
'number_format' => $numberFormat,
|
||||
@@ -81,24 +118,25 @@ final class ReceiptConfigController
|
||||
]);
|
||||
|
||||
Flash::set('settings.accounting.success', $this->translator->get('settings.accounting.flash.saved'));
|
||||
return Response::redirect($redirectOk);
|
||||
} catch (Throwable) {
|
||||
Flash::set('settings.accounting.error', $this->translator->get('settings.accounting.flash.save_failed'));
|
||||
return Response::redirect($redirectFail);
|
||||
}
|
||||
|
||||
return Response::redirect('/settings/accounting');
|
||||
}
|
||||
|
||||
public function toggleStatus(Request $request): Response
|
||||
{
|
||||
$redirect = '/settings/accounting/receipts';
|
||||
if (!Csrf::validate((string) $request->input('_token', ''))) {
|
||||
Flash::set('settings.accounting.error', 'Nieprawidlowy token CSRF');
|
||||
return Response::redirect('/settings/accounting');
|
||||
return Response::redirect($redirect);
|
||||
}
|
||||
|
||||
$id = (int) $request->input('id', '0');
|
||||
if ($id <= 0) {
|
||||
Flash::set('settings.accounting.error', 'Nieprawidlowy identyfikator konfiguracji');
|
||||
return Response::redirect('/settings/accounting');
|
||||
return Response::redirect($redirect);
|
||||
}
|
||||
|
||||
try {
|
||||
@@ -108,20 +146,21 @@ final class ReceiptConfigController
|
||||
Flash::set('settings.accounting.error', 'Blad zmiany statusu');
|
||||
}
|
||||
|
||||
return Response::redirect('/settings/accounting');
|
||||
return Response::redirect($redirect);
|
||||
}
|
||||
|
||||
public function delete(Request $request): Response
|
||||
{
|
||||
$redirect = '/settings/accounting/receipts';
|
||||
if (!Csrf::validate((string) $request->input('_token', ''))) {
|
||||
Flash::set('settings.accounting.error', 'Nieprawidlowy token CSRF');
|
||||
return Response::redirect('/settings/accounting');
|
||||
return Response::redirect($redirect);
|
||||
}
|
||||
|
||||
$id = (int) $request->input('id', '0');
|
||||
if ($id <= 0) {
|
||||
Flash::set('settings.accounting.error', 'Nieprawidlowy identyfikator konfiguracji');
|
||||
return Response::redirect('/settings/accounting');
|
||||
return Response::redirect($redirect);
|
||||
}
|
||||
|
||||
try {
|
||||
@@ -131,6 +170,6 @@ final class ReceiptConfigController
|
||||
Flash::set('settings.accounting.error', $this->translator->get('settings.accounting.flash.delete_failed'));
|
||||
}
|
||||
|
||||
return Response::redirect('/settings/accounting');
|
||||
return Response::redirect($redirect);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user