fix: duplikaty zamowien + status COD (is_cod flag)
- summaryView(): guard — redirect do istniejacego zamowienia gdy ORDER_SUBMIT_LAST_ORDER_ID w sesji - basketSave(): try-catch wokol createFromBasket(), wyjatki logowane, koszyk zachowany - OrderRepository: usunieto hardkodowane payment_id == 3, uzywana flaga is_cod - PaymentMethodRepository: nowe pole is_cod w normalizacji, save() i forTransport() SQL - ShopPaymentMethodController: switch "Platnosc przy odbiorze" w formularzu edycji - migrations/0.338.sql: ALTER TABLE pp_shop_payment_methods ADD COLUMN is_cod Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -814,7 +814,7 @@ class OrderRepository
|
||||
\Shared\Helpers\Helpers::send_email($settings['contact_email'], 'Nowe zamówienie / ' . $settings['firm_name'] . ' / ' . $order['number'] . ' - ' . $order['client_surname'] . ' ' . $order['client_name'], $mail_order);
|
||||
|
||||
// zmiana statusu w realizacji jeżeli płatność przy odbiorze
|
||||
if ($payment_id == 3) {
|
||||
if (!empty($payment_method['is_cod'])) {
|
||||
$this->updateOrderStatus($order_id, 4);
|
||||
$this->insertStatusHistory($order_id, 4, 1);
|
||||
}
|
||||
|
||||
@@ -122,6 +122,7 @@ class PaymentMethodRepository
|
||||
'apilo_payment_type_id' => $this->normalizeApiloPaymentTypeId($data['apilo_payment_type_id'] ?? null),
|
||||
'min_order_amount' => $this->normalizeDecimalOrNull($data['min_order_amount'] ?? null),
|
||||
'max_order_amount' => $this->normalizeDecimalOrNull($data['max_order_amount'] ?? null),
|
||||
'is_cod' => (int)(!empty($data['is_cod']) ? 1 : 0),
|
||||
];
|
||||
|
||||
$this->db->update('pp_shop_payment_methods', $row, ['id' => $paymentMethodId]);
|
||||
@@ -240,7 +241,8 @@ class PaymentMethodRepository
|
||||
spm.status,
|
||||
spm.apilo_payment_type_id,
|
||||
spm.min_order_amount,
|
||||
spm.max_order_amount
|
||||
spm.max_order_amount,
|
||||
spm.is_cod
|
||||
FROM pp_shop_payment_methods AS spm
|
||||
INNER JOIN pp_shop_transport_payment_methods AS stpm
|
||||
ON stpm.id_payment_method = spm.id
|
||||
@@ -335,6 +337,7 @@ class PaymentMethodRepository
|
||||
$row['apilo_payment_type_id'] = $this->normalizeApiloPaymentTypeId($row['apilo_payment_type_id'] ?? null);
|
||||
$row['min_order_amount'] = $this->normalizeDecimalOrNull($row['min_order_amount'] ?? null);
|
||||
$row['max_order_amount'] = $this->normalizeDecimalOrNull($row['max_order_amount'] ?? null);
|
||||
$row['is_cod'] = (int)($row['is_cod'] ?? 0);
|
||||
|
||||
return $row;
|
||||
}
|
||||
|
||||
@@ -184,6 +184,7 @@ class ShopPaymentMethodController
|
||||
'apilo_payment_type_id' => $paymentMethod['apilo_payment_type_id'] ?? '',
|
||||
'min_order_amount' => $paymentMethod['min_order_amount'] ?? '',
|
||||
'max_order_amount' => $paymentMethod['max_order_amount'] ?? '',
|
||||
'is_cod' => (int)($paymentMethod['is_cod'] ?? 0),
|
||||
];
|
||||
|
||||
$fields = [
|
||||
@@ -220,6 +221,10 @@ class ShopPaymentMethodController
|
||||
'tab' => 'settings',
|
||||
'options' => $apiloOptions,
|
||||
]),
|
||||
FormField::switch('is_cod', [
|
||||
'label' => 'Platnosc przy odbiorze',
|
||||
'tab' => 'settings',
|
||||
]),
|
||||
FormField::switch('status', [
|
||||
'label' => 'Aktywny',
|
||||
'tab' => 'settings',
|
||||
|
||||
@@ -276,6 +276,19 @@ class ShopBasketController
|
||||
exit;
|
||||
}
|
||||
|
||||
$existingOrderId = isset( $_SESSION[ self::ORDER_SUBMIT_LAST_ORDER_ID_SESSION_KEY ] )
|
||||
? (int)$_SESSION[ self::ORDER_SUBMIT_LAST_ORDER_ID_SESSION_KEY ]
|
||||
: 0;
|
||||
if ( $existingOrderId > 0 )
|
||||
{
|
||||
$existingOrderHash = $this->orderRepository->findHashById( $existingOrderId );
|
||||
if ( $existingOrderHash )
|
||||
{
|
||||
header( 'Location: /zamowienie/' . $existingOrderHash );
|
||||
exit;
|
||||
}
|
||||
}
|
||||
|
||||
$client = \Shared\Helpers\Helpers::get_session( 'client' );
|
||||
$orderSubmitToken = $this->createOrderSubmitToken();
|
||||
|
||||
@@ -325,7 +338,10 @@ class ShopBasketController
|
||||
exit;
|
||||
}
|
||||
|
||||
if ( $order_id = $this->orderRepository->createFromBasket(
|
||||
$order_id = null;
|
||||
try
|
||||
{
|
||||
$order_id = $this->orderRepository->createFromBasket(
|
||||
$client[ 'id' ],
|
||||
\Shared\Helpers\Helpers::get_session( 'basket' ),
|
||||
\Shared\Helpers\Helpers::get_session( 'basket-transport-method-id' ),
|
||||
@@ -347,7 +363,17 @@ class ShopBasketController
|
||||
\Shared\Helpers\Helpers::get_session( 'basket_orlen_point_info' ),
|
||||
\Shared\Helpers\Helpers::get_session( 'coupon' ),
|
||||
\Shared\Helpers\Helpers::get_session( 'basket_message' )
|
||||
) )
|
||||
);
|
||||
}
|
||||
catch ( \Exception $e )
|
||||
{
|
||||
error_log( '[basketSave] createFromBasket exception: ' . $e->getMessage() );
|
||||
\Shared\Helpers\Helpers::error( \Shared\Helpers\Helpers::lang( 'zamowienie-zostalo-zlozone-komunikat-blad' ) );
|
||||
header( 'Location: /koszyk' );
|
||||
exit;
|
||||
}
|
||||
|
||||
if ( $order_id )
|
||||
{
|
||||
\Shared\Helpers\Helpers::set_session( self::ORDER_SUBMIT_LAST_ORDER_ID_SESSION_KEY, (int)$order_id );
|
||||
\Shared\Helpers\Helpers::alert( \Shared\Helpers\Helpers::lang( 'zamowienie-zostalo-zlozone-komunikat' ) );
|
||||
|
||||
@@ -4,6 +4,17 @@ Logi zmian z migracji na Domain-Driven Architecture. Najnowsze na gorze.
|
||||
|
||||
---
|
||||
|
||||
## ver. 0.338 (2026-03-12) - Bugfix: duplikaty zamówień + status COD
|
||||
|
||||
- **FIX**: `autoload/front/Controllers/ShopBasketController::summaryView()` — guard przed ponownym złożeniem zamówienia: jeśli sesja zawiera `ORDER_SUBMIT_LAST_ORDER_ID`, użytkownik jest przekierowywany do istniejącego zamówienia zamiast widzieć formularz ponownie
|
||||
- **FIX**: `autoload/front/Controllers/ShopBasketController::basketSave()` — owinięcie wywołania `createFromBasket()` w try-catch; wyjątek jest logowany przez `error_log()`, użytkownik widzi komunikat błędu, koszyk sesyjny zostaje zachowany
|
||||
- **FIX**: `autoload/Domain/Order/OrderRepository::createFromBasket()` — usunięcie hardkodowanego `payment_id == 3` do wykrywania płatności przy odbiorze; zamiast tego używana jest flaga `$payment_method['is_cod']`
|
||||
- **FEATURE**: `autoload/Domain/PaymentMethod/PaymentMethodRepository` — nowa kolumna `is_cod` (normalizacja, zapis w `save()`, kolumna w `forTransport()` SQL)
|
||||
- **FEATURE**: `autoload/admin/Controllers/ShopPaymentMethodController` — nowe pole "Platnosc przy odbiorze" w formularzu edycji metody płatności
|
||||
- **MIGRATION**: `migrations/0.338.sql` — `ALTER TABLE pp_shop_payment_methods ADD COLUMN is_cod TINYINT(1) NOT NULL DEFAULT 0`
|
||||
|
||||
---
|
||||
|
||||
## ver. 0.337 (2026-03-12) - Bezpieczeństwo: ochrona CSRF panelu administracyjnego
|
||||
|
||||
- **SECURITY**: `autoload/Shared/Security/CsrfToken.php` — nowa klasa z `getToken()`, `validate()`, `regenerate()` (token 64-znakowy hex, `hash_equals()` przeciw timing attacks)
|
||||
|
||||
@@ -521,10 +521,13 @@ Metody platnosci sklepu (modul `/admin/shop_payment_method`).
|
||||
| apilo_payment_type_id | ID typu platnosci Apilo (NULL gdy brak mapowania) |
|
||||
| min_order_amount | Minimalna kwota zamowienia (DECIMAL(10,2), NULL = brak limitu) |
|
||||
| max_order_amount | Maksymalna kwota zamowienia (DECIMAL(10,2), NULL = brak limitu) |
|
||||
| is_cod | Platnosc przy odbiorze: 1 = tak, 0 = nie (TINYINT DEFAULT 0) |
|
||||
| sellasist_payment_type_id | DEPRECATED (integracja Sellasist usunieta w ver. 0.263) |
|
||||
|
||||
**Uzywane w:** `Domain\PaymentMethod\PaymentMethodRepository`, `admin\Controllers\ShopPaymentMethodController`, `front\factory\ShopPaymentMethod`, `shop\PaymentMethod`, `admin\controls\ShopTransport`, `cron.php`
|
||||
|
||||
**Aktualizacja 2026-03-12 (ver. 0.338):** dodano kolumne `is_cod` — flaga platnosci przy odbiorze, zastepuje hardkodowane `payment_id == 3` w `OrderRepository::createFromBasket()`.
|
||||
|
||||
**Aktualizacja 2026-02-14 (ver. 0.268):** modul `/admin/shop_payment_method` korzysta z `Domain\PaymentMethod\PaymentMethodRepository` przez `admin\Controllers\ShopPaymentMethodController`. Usunieto legacy klasy `admin\controls\ShopPaymentMethod`, `admin\factory\ShopPaymentMethod`, `admin\view\ShopPaymentMethod` oraz widok `admin/templates/shop-payment-method/view-list.php`.
|
||||
|
||||
**Aktualizacja 2026-02-22 (ver. 0.304):** dodano kolumny `min_order_amount` i `max_order_amount` — konfigurowalne limity kwotowe metod platnosci. Zastapiono hardcoded warunek PayPo (id=6, 40-1000 PLN) generycznym filtrowaniem na froncie.
|
||||
|
||||
3
migrations/0.338.sql
Normal file
3
migrations/0.338.sql
Normal file
@@ -0,0 +1,3 @@
|
||||
ALTER TABLE `pp_shop_payment_methods`
|
||||
ADD COLUMN `is_cod` TINYINT(1) NOT NULL DEFAULT 0
|
||||
COMMENT 'Platnosc przy odbiorze (cash on delivery): 1 = tak, 0 = nie';
|
||||
Reference in New Issue
Block a user