ver. 0.290: ShopCoupon + ShopOrder frontend migration to Domain + Controllers
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -359,7 +359,7 @@ class ClientRepository
|
|||||||
$orders = [];
|
$orders = [];
|
||||||
if (is_array($rows)) {
|
if (is_array($rows)) {
|
||||||
foreach ($rows as $row) {
|
foreach ($rows as $row) {
|
||||||
$orders[] = \front\factory\ShopOrder::order_details($row);
|
$orders[] = (new \Domain\Order\OrderRepository($this->db))->orderDetailsFrontend($row);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -188,6 +188,73 @@ class CouponRepository
|
|||||||
return (bool)$this->db->delete('pp_shop_coupon', ['id' => $couponId]);
|
return (bool)$this->db->delete('pp_shop_coupon', ['id' => $couponId]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function findByName(string $name)
|
||||||
|
{
|
||||||
|
$name = trim($name);
|
||||||
|
if ($name === '') {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
$coupon = $this->db->get('pp_shop_coupon', '*', ['name' => $name]);
|
||||||
|
if (!is_array($coupon)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
$coupon['id'] = (int)($coupon['id'] ?? 0);
|
||||||
|
$coupon['status'] = (int)($coupon['status'] ?? 0);
|
||||||
|
$coupon['used'] = (int)($coupon['used'] ?? 0);
|
||||||
|
$coupon['one_time'] = (int)($coupon['one_time'] ?? 0);
|
||||||
|
$coupon['type'] = (int)($coupon['type'] ?? 0);
|
||||||
|
$coupon['include_discounted_product'] = (int)($coupon['include_discounted_product'] ?? 0);
|
||||||
|
$coupon['used_count'] = (int)($coupon['used_count'] ?? 0);
|
||||||
|
|
||||||
|
return (object)$coupon;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function isAvailable($coupon)
|
||||||
|
{
|
||||||
|
if (!$coupon) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$id = is_object($coupon) ? ($coupon->id ?? 0) : ($coupon['id'] ?? 0);
|
||||||
|
$status = is_object($coupon) ? ($coupon->status ?? 0) : ($coupon['status'] ?? 0);
|
||||||
|
$used = is_object($coupon) ? ($coupon->used ?? 0) : ($coupon['used'] ?? 0);
|
||||||
|
|
||||||
|
if (!(int)$id) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(int)$status) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return !(int)$used;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function markAsUsed(int $couponId)
|
||||||
|
{
|
||||||
|
if ($couponId <= 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->db->update('pp_shop_coupon', [
|
||||||
|
'used' => 1,
|
||||||
|
'date_used' => date('Y-m-d H:i:s'),
|
||||||
|
], ['id' => $couponId]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function incrementUsedCount(int $couponId)
|
||||||
|
{
|
||||||
|
if ($couponId <= 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->db->update('pp_shop_coupon', [
|
||||||
|
'used_count[+]' => 1,
|
||||||
|
], ['id' => $couponId]);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return array<int, array<string, mixed>>
|
* @return array<int, array<string, mixed>>
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -435,6 +435,278 @@ class OrderRepository
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// --- Frontend methods ---
|
||||||
|
|
||||||
|
public function findIdByHash(string $hash)
|
||||||
|
{
|
||||||
|
$hash = trim($hash);
|
||||||
|
if ($hash === '') {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
$id = $this->db->get('pp_shop_orders', 'id', ['hash' => $hash]);
|
||||||
|
|
||||||
|
return $id ? (int)$id : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function findHashById(int $orderId)
|
||||||
|
{
|
||||||
|
if ($orderId <= 0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
$hash = $this->db->get('pp_shop_orders', 'hash', ['id' => $orderId]);
|
||||||
|
|
||||||
|
return $hash ? (string)$hash : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function orderDetailsFrontend($orderId = null, $hash = '', $przelewy24Hash = '')
|
||||||
|
{
|
||||||
|
$order = null;
|
||||||
|
|
||||||
|
if ($orderId) {
|
||||||
|
$order = $this->db->get('pp_shop_orders', '*', ['id' => $orderId]);
|
||||||
|
if (is_array($order)) {
|
||||||
|
$order['products'] = $this->db->select('pp_shop_order_products', '*', ['order_id' => $orderId]);
|
||||||
|
if (!is_array($order['products'])) {
|
||||||
|
$order['products'] = [];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($hash) {
|
||||||
|
$order = $this->db->get('pp_shop_orders', '*', ['hash' => $hash]);
|
||||||
|
if (is_array($order)) {
|
||||||
|
$order['products'] = $this->db->select('pp_shop_order_products', '*', ['order_id' => $order['id']]);
|
||||||
|
if (!is_array($order['products'])) {
|
||||||
|
$order['products'] = [];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($przelewy24Hash) {
|
||||||
|
$order = $this->db->get('pp_shop_orders', '*', ['przelewy24_hash' => $przelewy24Hash]);
|
||||||
|
if (is_array($order)) {
|
||||||
|
$order['products'] = $this->db->select('pp_shop_order_products', '*', ['order_id' => $order['id']]);
|
||||||
|
if (!is_array($order['products'])) {
|
||||||
|
$order['products'] = [];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return is_array($order) ? $order : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function generateOrderNumber()
|
||||||
|
{
|
||||||
|
$date = date('Y-m');
|
||||||
|
|
||||||
|
$results = $this->db->query(
|
||||||
|
'SELECT MAX( CONVERT( substring_index( substring_index( number, \'/\', -1 ), \' \', -1 ), UNSIGNED INTEGER) ) FROM pp_shop_orders WHERE date_order LIKE \'' . $date . '%\''
|
||||||
|
)->fetchAll();
|
||||||
|
|
||||||
|
$nr = 0;
|
||||||
|
if (is_array($results) && count($results)) {
|
||||||
|
foreach ($results as $row) {
|
||||||
|
$nr = ++$row[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$nr) {
|
||||||
|
$nr = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($nr < 10) {
|
||||||
|
$nr = '00' . $nr;
|
||||||
|
} elseif ($nr < 100) {
|
||||||
|
$nr = '0' . $nr;
|
||||||
|
}
|
||||||
|
|
||||||
|
return date('Y/m', strtotime($date)) . '/' . $nr;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function createFromBasket(
|
||||||
|
$client_id,
|
||||||
|
$basket,
|
||||||
|
$transport_id,
|
||||||
|
$payment_id,
|
||||||
|
$email,
|
||||||
|
$phone,
|
||||||
|
$name,
|
||||||
|
$surname,
|
||||||
|
$street,
|
||||||
|
$postal_code,
|
||||||
|
$city,
|
||||||
|
$firm_name,
|
||||||
|
$firm_street,
|
||||||
|
$firm_postal_code,
|
||||||
|
$firm_city,
|
||||||
|
$firm_nip,
|
||||||
|
$inpost_info,
|
||||||
|
$orlen_point_id,
|
||||||
|
$orlen_point_info,
|
||||||
|
$coupon,
|
||||||
|
$basket_message
|
||||||
|
) {
|
||||||
|
global $lang_id, $settings;
|
||||||
|
|
||||||
|
if ($client_id) {
|
||||||
|
$email = (new \Domain\Client\ClientRepository($this->db))->clientEmail((int)$client_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!is_array($basket) || !$transport_id || !$payment_id || !$email || !$phone || !$name || !$surname) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$transport = \front\factory\ShopTransport::transport($transport_id);
|
||||||
|
$payment_method = \front\factory\ShopPaymentMethod::payment_method($payment_id);
|
||||||
|
$basket_summary = \Domain\Basket\BasketCalculator::summaryPrice($basket, $coupon);
|
||||||
|
$order_number = $this->generateOrderNumber();
|
||||||
|
$order_date = date('Y-m-d H:i:s');
|
||||||
|
$hash = md5($order_number . time());
|
||||||
|
|
||||||
|
if ($transport['delivery_free'] == 1 && $basket_summary >= $settings['free_delivery']) {
|
||||||
|
$transport_cost = '0.00';
|
||||||
|
} else {
|
||||||
|
$transport_cost = $transport['cost'];
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->db->insert('pp_shop_orders', [
|
||||||
|
'number' => $order_number,
|
||||||
|
'client_id' => $client_id ? $client_id : null,
|
||||||
|
'date_order' => $order_date,
|
||||||
|
'comment' => null,
|
||||||
|
'client_name' => $name,
|
||||||
|
'client_surname' => $surname,
|
||||||
|
'client_email' => $email,
|
||||||
|
'client_street' => $street,
|
||||||
|
'client_postal_code' => $postal_code,
|
||||||
|
'client_city' => $city,
|
||||||
|
'client_phone' => $phone,
|
||||||
|
'firm_name' => $firm_name ? $firm_name : null,
|
||||||
|
'firm_street' => $firm_street ? $firm_street : null,
|
||||||
|
'firm_postal_code' => $firm_postal_code ? $firm_postal_code : null,
|
||||||
|
'firm_city' => $firm_city ? $firm_city : null,
|
||||||
|
'firm_nip' => $firm_nip ? $firm_nip : null,
|
||||||
|
'transport_id' => $transport_id,
|
||||||
|
'transport' => $transport['name_visible'],
|
||||||
|
'transport_cost' => $transport_cost,
|
||||||
|
'transport_description' => $transport['description'],
|
||||||
|
'orlen_point' => ($orlen_point_id) ? $orlen_point_id . ' | ' . $orlen_point_info : null,
|
||||||
|
'inpost_paczkomat' => ($transport_id == 1 || $transport_id == 2) ? $inpost_info : null,
|
||||||
|
'payment_method' => $payment_method['name'],
|
||||||
|
'payment_method_id' => $payment_id,
|
||||||
|
'hash' => $hash,
|
||||||
|
'summary' => \Shared\Helpers\Helpers::normalize_decimal($basket_summary + $transport_cost),
|
||||||
|
'coupon_id' => $coupon ? $coupon->id : null,
|
||||||
|
'message' => $basket_message ? $basket_message : null,
|
||||||
|
'apilo_order_status_date' => date('Y-m-d H:i:s'),
|
||||||
|
]);
|
||||||
|
|
||||||
|
$order_id = $this->db->id();
|
||||||
|
|
||||||
|
if (!$order_id) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($coupon) {
|
||||||
|
(new \Domain\Coupon\CouponRepository($this->db))->incrementUsedCount((int)$coupon->id);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ustawienie statusu zamówienia
|
||||||
|
$this->db->insert('pp_shop_order_statuses', ['order_id' => $order_id, 'status_id' => 0, 'mail' => 1]);
|
||||||
|
|
||||||
|
if (is_array($basket)) {
|
||||||
|
foreach ($basket as $basket_position) {
|
||||||
|
$attributes = '';
|
||||||
|
$product = \shop\Product::getFromCache($basket_position['product-id'], $lang_id);
|
||||||
|
|
||||||
|
if (is_array($basket_position['attributes'])) {
|
||||||
|
foreach ($basket_position['attributes'] as $row) {
|
||||||
|
$row = explode('-', $row);
|
||||||
|
$attributeRepo = new \Domain\Attribute\AttributeRepository($this->db);
|
||||||
|
$attribute = $attributeRepo->frontAttributeDetails((int)$row[0], $lang_id);
|
||||||
|
$value = $attributeRepo->frontValueDetails((int)$row[1], $lang_id);
|
||||||
|
|
||||||
|
if ($attributes) {
|
||||||
|
$attributes .= '<br>';
|
||||||
|
}
|
||||||
|
$attributes .= '<b>' . $attribute['language']['name'] . '</b>: ';
|
||||||
|
$attributes .= $value['language']['name'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// custom fields
|
||||||
|
$product_custom_fields = '';
|
||||||
|
if (is_array($basket_position['custom_fields'])) {
|
||||||
|
foreach ($basket_position['custom_fields'] as $key => $val) {
|
||||||
|
$custom_field = \shop\ProductCustomField::getFromCache($key);
|
||||||
|
if ($product_custom_fields) {
|
||||||
|
$product_custom_fields .= '<br>';
|
||||||
|
}
|
||||||
|
$product_custom_fields .= '<b>' . $custom_field['name'] . '</b>: ' . $val;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$product_price_tmp = \shop\Product::calculate_basket_product_price((float)$product['price_brutto_promo'], (float)$product['price_brutto'], $coupon, $basket_position);
|
||||||
|
|
||||||
|
$this->db->insert('pp_shop_order_products', [
|
||||||
|
'order_id' => $order_id,
|
||||||
|
'product_id' => $basket_position['product-id'],
|
||||||
|
'parent_product_id' => $basket_position['parent_id'] ? $basket_position['parent_id'] : $basket_position['product-id'],
|
||||||
|
'name' => $product->language['name'],
|
||||||
|
'attributes' => $attributes,
|
||||||
|
'vat' => $product->vat,
|
||||||
|
'price_brutto' => $product_price_tmp['price'],
|
||||||
|
'price_brutto_promo' => $product_price_tmp['price_new'],
|
||||||
|
'quantity' => $basket_position['quantity'],
|
||||||
|
'message' => $basket_position['message'],
|
||||||
|
'custom_fields' => $product_custom_fields,
|
||||||
|
]);
|
||||||
|
|
||||||
|
$product_quantity = \shop\Product::get_product_quantity($basket_position['product-id']);
|
||||||
|
if ($product_quantity != null) {
|
||||||
|
$this->db->update('pp_shop_products', ['quantity[-]' => $basket_position['quantity']], ['id' => $basket_position['product-id']]);
|
||||||
|
} else {
|
||||||
|
$this->db->update('pp_shop_products', ['quantity[-]' => $basket_position['quantity']], ['id' => $basket_position['parent_id']]);
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->db->update('pp_shop_products', ['quantity' => 0], ['quantity[<]' => 0]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($coupon && $coupon->is_one_time()) {
|
||||||
|
$coupon->set_as_used();
|
||||||
|
}
|
||||||
|
|
||||||
|
$order = $this->orderDetailsFrontend($order_id);
|
||||||
|
|
||||||
|
$mail_order = \Shared\Tpl\Tpl::view('shop-order/mail-summary', [
|
||||||
|
'settings' => $settings,
|
||||||
|
'order' => $order,
|
||||||
|
'coupon' => $coupon,
|
||||||
|
]);
|
||||||
|
|
||||||
|
$settings['ssl'] ? $base = 'https' : $base = 'http';
|
||||||
|
|
||||||
|
$regex = "-(<img[^>]+src\s*=\s*['\"])(((?!'|\"|https?://).)*)(['\"][^>]*>)-i";
|
||||||
|
$mail_order = preg_replace($regex, "$1" . $base . "://" . $_SERVER['SERVER_NAME'] . "$2$4", $mail_order);
|
||||||
|
|
||||||
|
$regex = "-(<a[^>]+href\s*=\s*['\"])(((?!'|\"|https?://).)*)(['\"][^>]*>)-i";
|
||||||
|
$mail_order = preg_replace($regex, "$1" . $base . "://" . $_SERVER['SERVER_NAME'] . "$2$4", $mail_order);
|
||||||
|
|
||||||
|
\Shared\Helpers\Helpers::send_email($email, \Shared\Helpers\Helpers::lang('potwierdzenie-zamowienia-ze-sklepu') . ' ' . $settings['firm_name'], $mail_order);
|
||||||
|
\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) {
|
||||||
|
$order_tmp = new \shop\Order($order_id);
|
||||||
|
$order_tmp->update_status(4, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $order_id;
|
||||||
|
}
|
||||||
|
|
||||||
private function nullableString(string $value): ?string
|
private function nullableString(string $value): ?string
|
||||||
{
|
{
|
||||||
$value = trim($value);
|
$value = trim($value);
|
||||||
|
|||||||
@@ -7,6 +7,13 @@ class ShopBasketController
|
|||||||
'mainView' => 'Koszyk'
|
'mainView' => 'Koszyk'
|
||||||
];
|
];
|
||||||
|
|
||||||
|
private $orderRepository;
|
||||||
|
|
||||||
|
public function __construct( \Domain\Order\OrderRepository $orderRepository )
|
||||||
|
{
|
||||||
|
$this->orderRepository = $orderRepository;
|
||||||
|
}
|
||||||
|
|
||||||
public function basketMessageSave()
|
public function basketMessageSave()
|
||||||
{
|
{
|
||||||
\Shared\Helpers\Helpers::set_session( 'basket_message', \Shared\Helpers\Helpers::get( 'basket_message' ) );
|
\Shared\Helpers\Helpers::set_session( 'basket_message', \Shared\Helpers\Helpers::get( 'basket_message' ) );
|
||||||
@@ -283,7 +290,7 @@ class ShopBasketController
|
|||||||
exit;
|
exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( $order_id = \front\factory\ShopOrder::basket_save(
|
if ( $order_id = $this->orderRepository->createFromBasket(
|
||||||
$client[ 'id' ],
|
$client[ 'id' ],
|
||||||
\Shared\Helpers\Helpers::get_session( 'basket' ),
|
\Shared\Helpers\Helpers::get_session( 'basket' ),
|
||||||
\Shared\Helpers\Helpers::get_session( 'basket-transport-method-id' ),
|
\Shared\Helpers\Helpers::get_session( 'basket-transport-method-id' ),
|
||||||
@@ -326,7 +333,7 @@ class ShopBasketController
|
|||||||
if ( $redis )
|
if ( $redis )
|
||||||
$redis -> flushAll();
|
$redis -> flushAll();
|
||||||
|
|
||||||
header( 'Location: /zamowienie/' . \front\factory\ShopOrder::order_hash( $order_id ) );
|
header( 'Location: /zamowienie/' . $this->orderRepository->findHashById( $order_id ) );
|
||||||
exit;
|
exit;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|||||||
34
autoload/front/Controllers/ShopCouponController.php
Normal file
34
autoload/front/Controllers/ShopCouponController.php
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
<?php
|
||||||
|
namespace front\Controllers;
|
||||||
|
|
||||||
|
use Domain\Coupon\CouponRepository;
|
||||||
|
|
||||||
|
class ShopCouponController
|
||||||
|
{
|
||||||
|
private CouponRepository $repository;
|
||||||
|
|
||||||
|
public function __construct( CouponRepository $repository )
|
||||||
|
{
|
||||||
|
$this->repository = $repository;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function useCoupon()
|
||||||
|
{
|
||||||
|
$coupon = $this->repository->findByName( (string)\Shared\Helpers\Helpers::get( 'coupon' ) );
|
||||||
|
|
||||||
|
if ( $coupon && $this->repository->isAvailable( $coupon ) )
|
||||||
|
\Shared\Helpers\Helpers::set_session( 'coupon', $coupon );
|
||||||
|
else
|
||||||
|
\Shared\Helpers\Helpers::alert( 'Podany kod rabatowy jest nieprawidłowy.' );
|
||||||
|
|
||||||
|
header( 'Location: /koszyk' );
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function deleteCoupon()
|
||||||
|
{
|
||||||
|
\Shared\Helpers\Helpers::delete_session( 'coupon' );
|
||||||
|
header( 'Location: /koszyk' );
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,12 +1,22 @@
|
|||||||
<?php
|
<?php
|
||||||
namespace front\controls;
|
namespace front\Controllers;
|
||||||
class ShopOrder
|
|
||||||
|
use Domain\Order\OrderRepository;
|
||||||
|
|
||||||
|
class ShopOrderController
|
||||||
{
|
{
|
||||||
public static function payment_confirmation()
|
private $repository;
|
||||||
|
|
||||||
|
public function __construct( OrderRepository $repository )
|
||||||
|
{
|
||||||
|
$this->repository = $repository;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function paymentConfirmation()
|
||||||
{
|
{
|
||||||
global $settings;
|
global $settings;
|
||||||
|
|
||||||
$order = \front\factory\ShopOrder::order_details( null, \Shared\Helpers\Helpers::get( 'order_hash' ) );
|
$order = $this->repository->orderDetailsFrontend( null, \Shared\Helpers\Helpers::get( 'order_hash' ) );
|
||||||
|
|
||||||
return \Shared\Tpl\Tpl::view( 'shop-order/payment-confirmation', [
|
return \Shared\Tpl\Tpl::view( 'shop-order/payment-confirmation', [
|
||||||
'order' => $order,
|
'order' => $order,
|
||||||
@@ -14,20 +24,18 @@ class ShopOrder
|
|||||||
] );
|
] );
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function payment_status_tpay()
|
public function paymentStatusTpay()
|
||||||
{
|
{
|
||||||
global $mdb;
|
|
||||||
|
|
||||||
file_put_contents( 'tpay.txt', print_r( $_POST, true ) . print_r( $_GET, true ), FILE_APPEND );
|
file_put_contents( 'tpay.txt', print_r( $_POST, true ) . print_r( $_GET, true ), FILE_APPEND );
|
||||||
|
|
||||||
if ( \Shared\Helpers\Helpers::get( 'tr_status' ) == 'TRUE' and \Shared\Helpers\Helpers::get( 'tr_crc' ) )
|
if ( \Shared\Helpers\Helpers::get( 'tr_status' ) == 'TRUE' && \Shared\Helpers\Helpers::get( 'tr_crc' ) )
|
||||||
{
|
{
|
||||||
$order = new \shop\Order( 0, \Shared\Helpers\Helpers::get( 'tr_crc' ) );
|
$order = new \shop\Order( 0, \Shared\Helpers\Helpers::get( 'tr_crc' ) );
|
||||||
|
|
||||||
if ( $order -> id )
|
if ( $order->id )
|
||||||
{
|
{
|
||||||
$order -> set_as_paid( true );
|
$order->set_as_paid( true );
|
||||||
$order -> update_status( 4, true );
|
$order->update_status( 4, true );
|
||||||
echo 'TRUE';
|
echo 'TRUE';
|
||||||
exit;
|
exit;
|
||||||
}
|
}
|
||||||
@@ -37,9 +45,9 @@ class ShopOrder
|
|||||||
exit;
|
exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function payment_status_przelewy24pl()
|
public function paymentStatusPrzelewy24pl()
|
||||||
{
|
{
|
||||||
global $mdb, $settings;
|
global $settings;
|
||||||
|
|
||||||
$post = [
|
$post = [
|
||||||
'p24_merchant_id' => \Shared\Helpers\Helpers::get( 'p24_merchant_id' ),
|
'p24_merchant_id' => \Shared\Helpers\Helpers::get( 'p24_merchant_id' ),
|
||||||
@@ -62,24 +70,21 @@ class ShopOrder
|
|||||||
|
|
||||||
$order = new \shop\Order( 0, '', \Shared\Helpers\Helpers::get( 'p24_session_id' ) );
|
$order = new \shop\Order( 0, '', \Shared\Helpers\Helpers::get( 'p24_session_id' ) );
|
||||||
|
|
||||||
if ( $order['status'] == 0 and $order['summary'] * 100 == \Shared\Helpers\Helpers::get( 'p24_amount' ) )
|
if ( $order['status'] == 0 && $order['summary'] * 100 == \Shared\Helpers\Helpers::get( 'p24_amount' ) )
|
||||||
{
|
{
|
||||||
if ( $order['id'] )
|
if ( $order['id'] )
|
||||||
{
|
{
|
||||||
$mdb -> update( 'pp_shop_orders', [ 'status' => 1, 'paid' => 1 ], [ 'id' => $order['id'] ] );
|
$order->set_as_paid( true );
|
||||||
$mdb -> insert( 'pp_shop_order_statuses', [ 'order_id' => $order['id'], 'status_id' => 1, 'mail' => 1 ] );
|
$order->update_status( 4, true );
|
||||||
|
|
||||||
$order -> status = 4;
|
|
||||||
$order -> send_status_change_email();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
exit;
|
exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function payment_status_hotpay()
|
public function paymentStatusHotpay()
|
||||||
{
|
{
|
||||||
global $mdb, $lang;
|
global $lang;
|
||||||
|
|
||||||
if ( !empty( $_POST["KWOTA"] ) && !empty( $_POST["ID_PLATNOSCI"] ) && !empty( $_POST["ID_ZAMOWIENIA"] ) && !empty( $_POST["STATUS"] ) && !empty( $_POST["SEKRET"] ) && !empty( $_POST["HASH"] ) )
|
if ( !empty( $_POST["KWOTA"] ) && !empty( $_POST["ID_PLATNOSCI"] ) && !empty( $_POST["ID_ZAMOWIENIA"] ) && !empty( $_POST["STATUS"] ) && !empty( $_POST["SEKRET"] ) && !empty( $_POST["HASH"] ) )
|
||||||
{
|
{
|
||||||
@@ -87,7 +92,8 @@ class ShopOrder
|
|||||||
|
|
||||||
if ( $order['id'] )
|
if ( $order['id'] )
|
||||||
{
|
{
|
||||||
if ( is_array( $order['products'] ) and count( $order['products'] ) ):
|
if ( is_array( $order['products'] ) && count( $order['products'] ) ):
|
||||||
|
$summary_tmp = 0;
|
||||||
foreach ( $order['products'] as $product ):
|
foreach ( $order['products'] as $product ):
|
||||||
$product_tmp = \front\factory\ShopProduct::product_details( $product['product_id'], $lang['id'] );
|
$product_tmp = \front\factory\ShopProduct::product_details( $product['product_id'], $lang['id'] );
|
||||||
$summary_tmp += \Shared\Helpers\Helpers::normalize_decimal( $product['price_netto'] + $product['price_netto'] * $product['vat'] / 100 ) * $product['quantity'];
|
$summary_tmp += \Shared\Helpers\Helpers::normalize_decimal( $product['price_netto'] + $product['price_netto'] * $product['vat'] / 100 ) * $product['quantity'];
|
||||||
@@ -99,32 +105,21 @@ class ShopOrder
|
|||||||
{
|
{
|
||||||
if ( $_POST["STATUS"] == "SUCCESS" )
|
if ( $_POST["STATUS"] == "SUCCESS" )
|
||||||
{
|
{
|
||||||
$mdb -> update( 'pp_shop_orders', [ 'status' => 1, 'paid' => 1 ], [ 'id' => $order['id'] ] );
|
$order->set_as_paid( true );
|
||||||
$mdb -> insert( 'pp_shop_order_statuses', [ 'order_id' => $order['id'], 'status_id' => 1, 'mail' => 1 ] );
|
$order->update_status( 4, true );
|
||||||
|
|
||||||
$order -> status = 4;
|
|
||||||
$order -> send_status_change_email();
|
|
||||||
|
|
||||||
echo \Shared\Helpers\Helpers::lang( 'zamowienie-zostalo-oplacone' );
|
echo \Shared\Helpers\Helpers::lang( 'zamowienie-zostalo-oplacone' );
|
||||||
}
|
}
|
||||||
else if ( $_POST["STATUS"] == "FAILURE" )
|
else if ( $_POST["STATUS"] == "FAILURE" )
|
||||||
{
|
{
|
||||||
$mdb -> update( 'pp_shop_orders', [ 'status' => 2 ], [ 'id' => $order['id'] ] );
|
$order->update_status( 2, true );
|
||||||
$mdb -> insert( 'pp_shop_order_statuses', [ 'order_id' => $order['id'], 'status_id' => 2, 'mail' => 1 ] );
|
|
||||||
|
|
||||||
$order -> status = 2;
|
|
||||||
$order -> send_status_change_email();
|
|
||||||
|
|
||||||
echo \Shared\Helpers\Helpers::lang( 'platnosc-zostala-odrzucona' );
|
echo \Shared\Helpers\Helpers::lang( 'platnosc-zostala-odrzucona' );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
$mdb -> update( 'pp_shop_orders', [ 'status' => 3 ], [ 'id' => $order['id'] ] );
|
$order->update_status( 3, true );
|
||||||
$mdb -> insert( 'pp_shop_order_statuses', [ 'order_id' => $order['id'], 'status_id' => 3, 'mail' => 1 ] );
|
|
||||||
|
|
||||||
$order -> status = 3;
|
|
||||||
$order -> send_status_change_email();
|
|
||||||
|
|
||||||
echo \Shared\Helpers\Helpers::lang( 'zamowienie-zostalo-oplacone-reczne' );
|
echo \Shared\Helpers\Helpers::lang( 'zamowienie-zostalo-oplacone-reczne' );
|
||||||
}
|
}
|
||||||
@@ -133,13 +128,13 @@ class ShopOrder
|
|||||||
exit;
|
exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function order_details()
|
public function orderDetails()
|
||||||
{
|
{
|
||||||
global $page, $settings;
|
global $page, $settings;
|
||||||
|
|
||||||
$page['language']['meta_title'] = \Shared\Helpers\Helpers::lang( 'meta-title-szczegoly-zamowienia' ) . ' | ' . $settings['firm_name'];
|
$page['language']['meta_title'] = \Shared\Helpers\Helpers::lang( 'meta-title-szczegoly-zamowienia' ) . ' | ' . $settings['firm_name'];
|
||||||
$order = \front\factory\ShopOrder::order_details(
|
$order = $this->repository->orderDetailsFrontend(
|
||||||
\front\factory\ShopOrder::order_id( \Shared\Helpers\Helpers::get( 'order_hash' ) )
|
$this->repository->findIdByHash( \Shared\Helpers\Helpers::get( 'order_hash' ) )
|
||||||
);
|
);
|
||||||
$coupon = (int)$order['coupon_id'] ? new \shop\Coupon( (int)$order['coupon_id'] ) : null;
|
$coupon = (int)$order['coupon_id'] ? new \shop\Coupon( (int)$order['coupon_id'] ) : null;
|
||||||
|
|
||||||
@@ -1,25 +0,0 @@
|
|||||||
<?php
|
|
||||||
namespace front\controls;
|
|
||||||
class ShopCoupon
|
|
||||||
{
|
|
||||||
public static function delete_coupon()
|
|
||||||
{
|
|
||||||
\Shared\Helpers\Helpers::delete_session( 'coupon' );
|
|
||||||
header( 'Location: /koszyk' );
|
|
||||||
exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function use_coupon()
|
|
||||||
{
|
|
||||||
$coupon = new \shop\Coupon( 0 );
|
|
||||||
$coupon -> load_from_db_by_name( (string)\Shared\Helpers\Helpers::get( 'coupon' ) );
|
|
||||||
|
|
||||||
if ( $coupon -> is_available() )
|
|
||||||
\Shared\Helpers\Helpers::set_session( 'coupon', $coupon );
|
|
||||||
else
|
|
||||||
\Shared\Helpers\Helpers::alert( 'Podany kod rabatowy jest nieprawidłowy.' );
|
|
||||||
|
|
||||||
header( 'Location: /koszyk' );
|
|
||||||
exit;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -168,7 +168,10 @@ class Site
|
|||||||
);
|
);
|
||||||
},
|
},
|
||||||
'ShopBasket' => function() {
|
'ShopBasket' => function() {
|
||||||
return new \front\Controllers\ShopBasketController();
|
global $mdb;
|
||||||
|
return new \front\Controllers\ShopBasketController(
|
||||||
|
new \Domain\Order\OrderRepository( $mdb )
|
||||||
|
);
|
||||||
},
|
},
|
||||||
'ShopClient' => function() {
|
'ShopClient' => function() {
|
||||||
global $mdb;
|
global $mdb;
|
||||||
@@ -176,6 +179,18 @@ class Site
|
|||||||
new \Domain\Client\ClientRepository( $mdb )
|
new \Domain\Client\ClientRepository( $mdb )
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
'ShopCoupon' => function() {
|
||||||
|
global $mdb;
|
||||||
|
return new \front\Controllers\ShopCouponController(
|
||||||
|
new \Domain\Coupon\CouponRepository( $mdb )
|
||||||
|
);
|
||||||
|
},
|
||||||
|
'ShopOrder' => function() {
|
||||||
|
global $mdb;
|
||||||
|
return new \front\Controllers\ShopOrderController(
|
||||||
|
new \Domain\Order\OrderRepository( $mdb )
|
||||||
|
);
|
||||||
|
},
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,30 +0,0 @@
|
|||||||
<?php
|
|
||||||
namespace front\factory;
|
|
||||||
class ShopCoupon {
|
|
||||||
private $id;
|
|
||||||
private $name;
|
|
||||||
private $status;
|
|
||||||
private $type;
|
|
||||||
private $amount;
|
|
||||||
private $one_time;
|
|
||||||
private $used;
|
|
||||||
private $include_discounted_product;
|
|
||||||
|
|
||||||
public function __construct() {
|
|
||||||
;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function __get( $var ) {
|
|
||||||
return $this -> $var;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function __set( $var, $value ) {
|
|
||||||
return $this -> $var = $value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function set_as_used() {
|
|
||||||
global $mdb;
|
|
||||||
$mdb -> update( 'pp_shop_coupon', [ 'used' => 1, 'date_used' => date( 'Y-m-d H:i:s' ) ], [ 'id' => $this -> id ] );
|
|
||||||
$this -> used = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,247 +0,0 @@
|
|||||||
<?php
|
|
||||||
namespace front\factory;
|
|
||||||
|
|
||||||
class ShopOrder
|
|
||||||
{
|
|
||||||
public static function order_id( $order_hash )
|
|
||||||
{
|
|
||||||
global $mdb;
|
|
||||||
return $mdb -> get( 'pp_shop_orders', 'id', [ 'hash' => $order_hash ] );
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function order_hash( $order_id )
|
|
||||||
{
|
|
||||||
global $mdb;
|
|
||||||
return $mdb -> get( 'pp_shop_orders', 'hash', [ 'id' => $order_id ] );
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function order_details( $order_id = '', $hash = '', $przelewy24_hash = '' )
|
|
||||||
{
|
|
||||||
global $mdb;
|
|
||||||
|
|
||||||
if ( $order_id )
|
|
||||||
{
|
|
||||||
$order = $mdb -> get( 'pp_shop_orders', '*', [ 'id' => $order_id ] );
|
|
||||||
$order[ 'products' ] = $mdb -> select( 'pp_shop_order_products', '*', [ 'order_id' => $order_id ] );
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( $hash )
|
|
||||||
{
|
|
||||||
$order = $mdb -> get( 'pp_shop_orders', '*', [ 'hash' => $hash ] );
|
|
||||||
$order[ 'products' ] = $mdb -> select( 'pp_shop_order_products', '*', [ 'order_id' => $order[ 'id' ] ] );
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( $przelewy24_hash )
|
|
||||||
{
|
|
||||||
$order = $mdb -> get( 'pp_shop_orders', '*', [ 'przelewy24_hash' => $przelewy24_hash ] );
|
|
||||||
$order[ 'products' ] = $mdb -> select( 'pp_shop_order_products', '*', [ 'order_id' => $order[ 'id' ] ] );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
return $order;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function generate_order_number()
|
|
||||||
{
|
|
||||||
global $mdb;
|
|
||||||
|
|
||||||
$date = date( 'Y-m' );
|
|
||||||
|
|
||||||
$results = $mdb -> query( 'SELECT MAX( CONVERT( substring_index( substring_index( number, \'/\', -1 ), \' \', -1 ), UNSIGNED INTEGER) ) FROM pp_shop_orders WHERE date_order LIKE \'' . $date . '%\'' ) -> fetchAll();
|
|
||||||
if ( is_array( $results ) and count( $results ) )
|
|
||||||
foreach ( $results as $row )
|
|
||||||
$nr = ++$row[ 0 ];
|
|
||||||
|
|
||||||
if ( !$nr )
|
|
||||||
$nr = 1;
|
|
||||||
|
|
||||||
if ( $nr < 10 )
|
|
||||||
$nr = '00' . $nr;
|
|
||||||
|
|
||||||
if ( $nr < 100 and $nr >= 10 )
|
|
||||||
$nr = '0' . $nr;
|
|
||||||
|
|
||||||
return date( 'Y/m', strtotime( $date ) ) . '/' . $nr;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function basket_save(
|
|
||||||
$client_id,
|
|
||||||
$basket,
|
|
||||||
$transport_id,
|
|
||||||
$payment_id,
|
|
||||||
$email,
|
|
||||||
$phone,
|
|
||||||
$name,
|
|
||||||
$surname,
|
|
||||||
$street,
|
|
||||||
$postal_code,
|
|
||||||
$city,
|
|
||||||
$firm_name,
|
|
||||||
$firm_street,
|
|
||||||
$firm_postal_code,
|
|
||||||
$firm_city,
|
|
||||||
$firm_nip,
|
|
||||||
$inpost_info,
|
|
||||||
$orlen_point_id,
|
|
||||||
$orlen_point_info,
|
|
||||||
$coupon,
|
|
||||||
$basket_message )
|
|
||||||
{
|
|
||||||
global $mdb, $lang_id, $settings;
|
|
||||||
|
|
||||||
if ( $client_id )
|
|
||||||
$email = ( new \Domain\Client\ClientRepository( $mdb ) )->clientEmail( (int)$client_id );
|
|
||||||
|
|
||||||
if ( !is_array( $basket ) or !$transport_id or !$payment_id or !$email or !$phone or !$name or !$surname )
|
|
||||||
return false;
|
|
||||||
|
|
||||||
$transport = \front\factory\ShopTransport::transport( $transport_id );
|
|
||||||
$payment_method = \front\factory\ShopPaymentMethod::payment_method( $payment_id );
|
|
||||||
$basket_summary = \Domain\Basket\BasketCalculator::summaryPrice( $basket, $coupon );
|
|
||||||
$order_number = self::generate_order_number();
|
|
||||||
$order_date = date( 'Y-m-d H:i:s' );
|
|
||||||
$hash = md5( $order_number . time() );
|
|
||||||
|
|
||||||
if ( $transport['delivery_free'] == 1 and $basket_summary >= $settings['free_delivery'] )
|
|
||||||
$transport_cost = '0.00';
|
|
||||||
else
|
|
||||||
$transport_cost = $transport['cost'];
|
|
||||||
|
|
||||||
$mdb -> insert( 'pp_shop_orders', [
|
|
||||||
'number' => $order_number,
|
|
||||||
'client_id' => $client_id ? $client_id : null,
|
|
||||||
'date_order' => $order_date,
|
|
||||||
'comment' => null,
|
|
||||||
'client_name' => $name,
|
|
||||||
'client_surname' => $surname,
|
|
||||||
'client_email' => $email,
|
|
||||||
'client_street' => $street,
|
|
||||||
'client_postal_code' => $postal_code,
|
|
||||||
'client_city' => $city,
|
|
||||||
'client_phone' => $phone,
|
|
||||||
'firm_name' => $firm_name ? $firm_name : null,
|
|
||||||
'firm_street' => $firm_street ? $firm_street : null,
|
|
||||||
'firm_postal_code' => $firm_postal_code ? $firm_postal_code : null,
|
|
||||||
'firm_city' => $firm_city ? $firm_city : null,
|
|
||||||
'firm_nip' => $firm_nip ? $firm_nip : null,
|
|
||||||
'transport_id' => $transport_id,
|
|
||||||
'transport' => $transport[ 'name_visible' ],
|
|
||||||
'transport_cost' => $transport_cost,
|
|
||||||
'transport_description' => $transport[ 'description' ],
|
|
||||||
'orlen_point' => ( $orlen_point_id ) ? $orlen_point_id . ' | ' . $orlen_point_info : null,
|
|
||||||
'inpost_paczkomat' => ( $transport_id == 1 or $transport_id == 2 ) ? $inpost_info : null,
|
|
||||||
'payment_method' => $payment_method[ 'name' ],
|
|
||||||
'payment_method_id' => $payment_id,
|
|
||||||
'hash' => $hash,
|
|
||||||
'summary' => \Shared\Helpers\Helpers::normalize_decimal( $basket_summary + $transport_cost ),
|
|
||||||
'coupon_id' => $coupon ? $coupon -> id : null,
|
|
||||||
'message' => $basket_message ? $basket_message : null,
|
|
||||||
'apilo_order_status_date' => date( 'Y-m-d H:i:s' ),
|
|
||||||
] );
|
|
||||||
|
|
||||||
$order_id = $mdb -> id();
|
|
||||||
|
|
||||||
if ( !$order_id )
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if ( $coupon )
|
|
||||||
$mdb -> update( 'pp_shop_coupon', [ 'used_count[+]' => 1 ], [ 'id' => $coupon -> id ] );
|
|
||||||
|
|
||||||
// ustawienie statusu zamówienia
|
|
||||||
$mdb -> insert( 'pp_shop_order_statuses', [ 'order_id' => $order_id, 'status_id' => 0, 'mail' => 1 ] );
|
|
||||||
|
|
||||||
if ( is_array( $basket ) )
|
|
||||||
{
|
|
||||||
foreach ( $basket as $basket_position )
|
|
||||||
{
|
|
||||||
$attributes = '';
|
|
||||||
$product = \shop\Product::getFromCache( $basket_position[ 'product-id' ], $lang_id );
|
|
||||||
|
|
||||||
if ( is_array( $basket_position[ 'attributes' ] ) )
|
|
||||||
{
|
|
||||||
foreach ( $basket_position[ 'attributes' ] as $row )
|
|
||||||
{
|
|
||||||
$row = explode( '-', $row );
|
|
||||||
$attributeRepo = new \Domain\Attribute\AttributeRepository( $mdb );
|
|
||||||
$attribute = $attributeRepo->frontAttributeDetails( (int)$row[ 0 ], $lang_id );
|
|
||||||
$value = $attributeRepo->frontValueDetails( (int)$row[ 1 ], $lang_id );
|
|
||||||
|
|
||||||
if ( $attributes )
|
|
||||||
$attributes .= '<br>';
|
|
||||||
$attributes .= '<b>' . $attribute[ 'language' ][ 'name' ] . '</b>: ';
|
|
||||||
$attributes .= $value[ 'language' ][ 'name' ];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// custom fields
|
|
||||||
$product_custom_fields = '';
|
|
||||||
if ( is_array( $basket_position[ 'custom_fields' ] ) )
|
|
||||||
{
|
|
||||||
foreach ( $basket_position[ 'custom_fields' ] as $key => $val )
|
|
||||||
{
|
|
||||||
$custom_field = \shop\ProductCustomField::getFromCache( $key );
|
|
||||||
if ( $product_custom_fields )
|
|
||||||
$product_custom_fields .= '<br>';
|
|
||||||
$product_custom_fields .= '<b>' . $custom_field[ 'name' ] . '</b>: ' . $val;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$product_price_tmp = \shop\Product::calculate_basket_product_price( (float)$product['price_brutto_promo'], (float)$product['price_brutto'], $coupon, $basket_position );
|
|
||||||
|
|
||||||
$mdb -> insert( 'pp_shop_order_products', [
|
|
||||||
'order_id' => $order_id,
|
|
||||||
'product_id' => $basket_position['product-id'],
|
|
||||||
'parent_product_id' => $basket_position['parent_id'] ? $basket_position['parent_id'] : $basket_position['product-id'],
|
|
||||||
'name' => $product -> language['name'],
|
|
||||||
'attributes' => $attributes,
|
|
||||||
'vat' => $product -> vat,
|
|
||||||
'price_brutto' => $product_price_tmp['price'],
|
|
||||||
'price_brutto_promo' => $product_price_tmp['price_new'],
|
|
||||||
'quantity' => $basket_position['quantity'],
|
|
||||||
'message' => $basket_position['message'],
|
|
||||||
'custom_fields' => $product_custom_fields,
|
|
||||||
] );
|
|
||||||
|
|
||||||
$product_quantity = \shop\Product::get_product_quantity( $basket_position['product-id'] );
|
|
||||||
if ( $product_quantity != null )
|
|
||||||
$mdb -> update( 'pp_shop_products', [ 'quantity[-]' => $basket_position[ 'quantity' ] ], [ 'id' => $basket_position['product-id'] ] );
|
|
||||||
else
|
|
||||||
$mdb -> update( 'pp_shop_products', [ 'quantity[-]' => $basket_position[ 'quantity' ] ], [ 'id' => $basket_position['parent_id'] ] );
|
|
||||||
|
|
||||||
$mdb -> update( 'pp_shop_products', [ 'quantity' => 0 ], [ 'quantity[<]' => 0 ] );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( $coupon and $coupon -> is_one_time() )
|
|
||||||
$coupon -> set_as_used();
|
|
||||||
|
|
||||||
$order = \front\factory\ShopOrder::order_details( $order_id );
|
|
||||||
|
|
||||||
$mail_order = \Shared\Tpl\Tpl::view( 'shop-order/mail-summary', [
|
|
||||||
'settings' => $settings,
|
|
||||||
'order' => $order,
|
|
||||||
'coupon' => $coupon,
|
|
||||||
] );
|
|
||||||
|
|
||||||
$settings[ 'ssl' ] ? $base = 'https' : $base = 'http';
|
|
||||||
|
|
||||||
$regex = "-(<img[^>]+src\s*=\s*['\"])(((?!'|\"|https?://).)*)(['\"][^>]*>)-i";
|
|
||||||
$mail_order = preg_replace( $regex, "$1" . $base . "://" . $_SERVER[ 'SERVER_NAME' ] . "$2$4", $mail_order );
|
|
||||||
|
|
||||||
$regex = "-(<a[^>]+href\s*=\s*['\"])(((?!'|\"|https?://).)*)(['\"][^>]*>)-i";
|
|
||||||
$mail_order = preg_replace( $regex, "$1" . $base . "://" . $_SERVER[ 'SERVER_NAME' ] . "$2$4", $mail_order );
|
|
||||||
|
|
||||||
\Shared\Helpers\Helpers::send_email( $email, \Shared\Helpers\Helpers::lang( 'potwierdzenie-zamowienia-ze-sklepu' ) . ' ' . $settings[ 'firm_name' ], $mail_order );
|
|
||||||
\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 )
|
|
||||||
{
|
|
||||||
$order_tmp = new \shop\Order( $order_id );
|
|
||||||
$order_tmp -> update_status( 4, true );
|
|
||||||
}
|
|
||||||
|
|
||||||
return $order_id;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
<?php
|
|
||||||
namespace front\view;
|
|
||||||
class ShopOrder
|
|
||||||
{
|
|
||||||
public static function order_details( $values )
|
|
||||||
{
|
|
||||||
$tpl = new \Shared\Tpl\Tpl;
|
|
||||||
if ( is_array( $values ) ) foreach ( $values as $key => $val )
|
|
||||||
$tpl -> $key = $val;
|
|
||||||
return $tpl -> render( 'shop-order/order-details' );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,77 +1,83 @@
|
|||||||
<?
|
<?php
|
||||||
namespace shop;
|
namespace shop;
|
||||||
class Coupon implements \ArrayAccess
|
class Coupon implements \ArrayAccess
|
||||||
{
|
{
|
||||||
|
private $data = [];
|
||||||
|
|
||||||
public function __construct( int $element_id )
|
public function __construct( int $element_id )
|
||||||
{
|
{
|
||||||
global $mdb;
|
global $mdb;
|
||||||
if ( $element_id )
|
if ( $element_id )
|
||||||
{
|
{
|
||||||
$result = $mdb -> get( 'pp_shop_coupon', '*', [ 'id' => $element_id ] );
|
$result = $mdb -> get( 'pp_shop_coupon', '*', [ 'id' => $element_id ] );
|
||||||
if ( \Shared\Helpers\Helpers::is_array_fix( $result ) ) foreach ( $result as $key => $val )
|
if ( is_array( $result ) )
|
||||||
$this -> $key = $val;
|
$this -> data = $result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function load_from_db_by_name( string $name )
|
public function load_from_db_by_name( string $name )
|
||||||
{
|
{
|
||||||
global $mdb;
|
global $mdb;
|
||||||
|
|
||||||
$result = $mdb -> get( 'pp_shop_coupon', '*', [ 'name' => $name ] );
|
$result = $mdb -> get( 'pp_shop_coupon', '*', [ 'name' => $name ] );
|
||||||
if ( is_array( $result ) ) foreach ( $result as $key => $val )
|
if ( is_array( $result ) )
|
||||||
$this -> $key = $val;
|
$this -> data = $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function is_one_time() {
|
public function is_one_time()
|
||||||
// return $this -> bean -> one_time;
|
{
|
||||||
|
return (bool)( $this -> data['one_time'] ?? 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
public function is_available()
|
public function is_available()
|
||||||
{
|
{
|
||||||
if ( !$this -> id )
|
if ( !( $this -> data['id'] ?? 0 ) )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if ( !$this -> status )
|
if ( !( $this -> data['status'] ?? 0 ) )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return !$this -> used;
|
return !( $this -> data['used'] ?? 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
public function set_as_used()
|
public function set_as_used()
|
||||||
{
|
{
|
||||||
// $this -> bean -> used = 1;
|
$id = (int)( $this -> data['id'] ?? 0 );
|
||||||
// $this -> bean -> date_used = date( 'Y-m-d H:i:s' );
|
if ( $id > 0 )
|
||||||
// \R::store( $this -> bean );
|
{
|
||||||
|
global $mdb;
|
||||||
|
$repo = new \Domain\Coupon\CouponRepository( $mdb );
|
||||||
|
$repo -> markAsUsed( $id );
|
||||||
|
$this -> data['used'] = 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function __get( $variable )
|
public function __get( $variable )
|
||||||
{
|
{
|
||||||
if ( array_key_exists( $variable, $this -> data ) )
|
return isset( $this -> data[$variable] ) ? $this -> data[$variable] : null;
|
||||||
return $this -> $variable;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function __set( $variable, $value )
|
public function __set( $variable, $value )
|
||||||
{
|
{
|
||||||
$this -> $variable = $value;
|
$this -> data[$variable] = $value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function offsetExists( $offset )
|
public function offsetExists( $offset )
|
||||||
{
|
{
|
||||||
return isset( $this -> $offset );
|
return isset( $this -> data[$offset] );
|
||||||
}
|
}
|
||||||
|
|
||||||
public function offsetGet( $offset )
|
public function offsetGet( $offset )
|
||||||
{
|
{
|
||||||
return $this -> $offset;
|
return isset( $this -> data[$offset] ) ? $this -> data[$offset] : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function offsetSet( $offset, $value )
|
public function offsetSet( $offset, $value )
|
||||||
{
|
{
|
||||||
$this -> $offset = $value;
|
$this -> data[$offset] = $value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function offsetUnset( $offset )
|
public function offsetUnset( $offset )
|
||||||
{
|
{
|
||||||
unset( $this -> $offset );
|
unset( $this -> data[$offset] );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -166,7 +166,8 @@ class Order implements \ArrayAccess
|
|||||||
{
|
{
|
||||||
global $settings;
|
global $settings;
|
||||||
|
|
||||||
$order = \front\factory\ShopOrder::order_details( $this -> id );
|
global $mdb;
|
||||||
|
$order = ( new \Domain\Order\OrderRepository( $mdb ) )->orderDetailsFrontend( $this -> id );
|
||||||
$coupon = (int)$order['coupon_id'] ? new \shop\Coupon( (int)$order['coupon_id'] ) : null;
|
$coupon = (int)$order['coupon_id'] ? new \shop\Coupon( (int)$order['coupon_id'] ) : null;
|
||||||
|
|
||||||
$mail_order = \Shared\Tpl\Tpl::view( 'shop-order/mail-summary', [
|
$mail_order = \Shared\Tpl\Tpl::view( 'shop-order/mail-summary', [
|
||||||
|
|||||||
@@ -63,7 +63,7 @@ $settings = ( new \Domain\Settings\SettingsRepository( $mdb ) )->allSettings();
|
|||||||
$order_id = $mdb -> get( 'pp_shop_orders', '*', [ 'AND' => [ 'status' => 6, 'trustmate_send' => 0 ] ] );
|
$order_id = $mdb -> get( 'pp_shop_orders', '*', [ 'AND' => [ 'status' => 6, 'trustmate_send' => 0 ] ] );
|
||||||
if ( is_array( $order_id ) and $order_id['id'] )
|
if ( is_array( $order_id ) and $order_id['id'] )
|
||||||
{
|
{
|
||||||
$order = \front\factory\ShopOrder::order_details( $order_id['id'] );
|
$order = ( new \Domain\Order\OrderRepository( $mdb ) )->orderDetailsFrontend( $order_id['id'] );
|
||||||
?>
|
?>
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<head>
|
<head>
|
||||||
|
|||||||
@@ -4,6 +4,27 @@ Logi zmian z migracji na Domain-Driven Architecture. Najnowsze na gorze.
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
## ver. 0.290 (2026-02-17) - ShopCoupon + ShopOrder frontend migration
|
||||||
|
|
||||||
|
- **ShopCoupon (frontend)** — migracja controls + factory na Domain + Controllers
|
||||||
|
- NOWE METODY w `CouponRepository`: 4 metody frontendowe (findByName, isAvailable, markAsUsed, incrementUsedCount)
|
||||||
|
- NOWY: `front\Controllers\ShopCouponController` — instancyjny kontroler z DI (useCoupon, deleteCoupon)
|
||||||
|
- KONWERSJA: `shop\Coupon` na fasade z dzialajacymi metodami (is_one_time, set_as_used)
|
||||||
|
- FIX: kupony jednorazowe nigdy nie byly oznaczane jako uzyte (is_one_time zwracalo null)
|
||||||
|
- USUNIETA: `front\controls\class.ShopCoupon.php`, `front\factory\class.ShopCoupon.php`
|
||||||
|
- **ShopOrder (frontend)** — migracja controls + factory + view na Domain + Controllers
|
||||||
|
- NOWE METODY w `OrderRepository`: 5 metod frontendowych (findIdByHash, findHashById, orderDetailsFrontend, generateOrderNumber, createFromBasket ~180 linii)
|
||||||
|
- NOWY: `front\Controllers\ShopOrderController` — instancyjny kontroler z DI (paymentConfirmation, paymentStatusTpay, paymentStatusPrzelewy24pl, paymentStatusHotpay, orderDetails)
|
||||||
|
- POPRAWA: webhooks przelewy24/hotpay — zamiana recznych $mdb->update/insert na \shop\Order::set_as_paid() + update_status() (spójnosc z tpay, poprawna obsluga Apilo sync)
|
||||||
|
- UPDATE: `ShopBasketController` — DI OrderRepository (createFromBasket, findHashById)
|
||||||
|
- UPDATE: `ClientRepository::clientOrders()` — OrderRepository::orderDetailsFrontend()
|
||||||
|
- UPDATE: `shop\Order::order_resend_confirmation_email()` — OrderRepository::orderDetailsFrontend()
|
||||||
|
- UPDATE: `cron-turstmate.php` — OrderRepository::orderDetailsFrontend()
|
||||||
|
- USUNIETA: `front\controls\class.ShopOrder.php`, `front\factory\class.ShopOrder.php`, `front\view\class.ShopOrder.php`
|
||||||
|
- Testy: 565 OK, 1716 asercji (+28: 12 CouponRepository frontend, 3 ShopCouponController, 10 OrderRepository frontend, 3 ShopOrderController)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## ver. 0.289 (2026-02-17) - ShopCategory + ShopClient frontend migration
|
## ver. 0.289 (2026-02-17) - ShopCategory + ShopClient frontend migration
|
||||||
|
|
||||||
- **ShopCategory (frontend)** — migracja factory + view na Domain + Views
|
- **ShopCategory (frontend)** — migracja factory + view na Domain + Views
|
||||||
|
|||||||
@@ -117,6 +117,8 @@ Zamówienia sklepu (źródło danych dla list i szczegółów klientów w panelu
|
|||||||
|
|
||||||
**Aktualizacja 2026-02-15 (ver. 0.276):** moduł `/admin/shop_order/*` korzysta z `Domain\Order\OrderRepository` przez `admin\Controllers\ShopOrderController`; usunięto legacy `admin\controls\ShopOrder` i `admin\factory\ShopOrder`.
|
**Aktualizacja 2026-02-15 (ver. 0.276):** moduł `/admin/shop_order/*` korzysta z `Domain\Order\OrderRepository` przez `admin\Controllers\ShopOrderController`; usunięto legacy `admin\controls\ShopOrder` i `admin\factory\ShopOrder`.
|
||||||
|
|
||||||
|
**Aktualizacja 2026-02-17 (ver. 0.290):** frontend `/shop_order/*` korzysta z `Domain\Order\OrderRepository` przez `front\Controllers\ShopOrderController`; usunięto legacy `front\controls\ShopOrder`, `front\factory\ShopOrder`, `front\view\ShopOrder`. Callery (ShopBasketController, ClientRepository, shop\Order, cron-turstmate) przepięte na OrderRepository.
|
||||||
|
|
||||||
## pp_banners
|
## pp_banners
|
||||||
Banery.
|
Banery.
|
||||||
|
|
||||||
@@ -465,7 +467,7 @@ Kody rabatowe sklepu (modul `/admin/shop_coupon`).
|
|||||||
| include_discounted_product | Czy obejmuje rowniez produkty przecenione (0/1) |
|
| include_discounted_product | Czy obejmuje rowniez produkty przecenione (0/1) |
|
||||||
| categories | JSON z ID kategorii objetych kuponem (NULL = bez ograniczenia) |
|
| categories | JSON z ID kategorii objetych kuponem (NULL = bez ograniczenia) |
|
||||||
|
|
||||||
**Uzywane w:** `Domain\Coupon\CouponRepository`, `admin\Controllers\ShopCouponController`, `shop\Coupon`, `front\factory\ShopCoupon`, `front\factory\ShopOrder`
|
**Uzywane w:** `Domain\Coupon\CouponRepository`, `admin\Controllers\ShopCouponController`, `front\Controllers\ShopCouponController`, `shop\Coupon`, `Domain\Order\OrderRepository`
|
||||||
|
|
||||||
**Aktualizacja 2026-02-13 (ver. 0.266):** modul `/admin/shop_coupon` korzysta z `Domain\Coupon\CouponRepository` przez `admin\Controllers\ShopCouponController`. Usunieto legacy klasy `admin\controls\ShopCoupon` i `admin\factory\ShopCoupon`.
|
**Aktualizacja 2026-02-13 (ver. 0.266):** modul `/admin/shop_coupon` korzysta z `Domain\Coupon\CouponRepository` przez `admin\Controllers\ShopCouponController`. Usunieto legacy klasy `admin\controls\ShopCoupon` i `admin\factory\ShopCoupon`.
|
||||||
|
|
||||||
|
|||||||
@@ -16,17 +16,17 @@ Panel administratora (33 moduły) został w pełni zmigrowany na architekturę D
|
|||||||
| Site | Router główny | route(), check_url_params(), title() |
|
| Site | Router główny | route(), check_url_params(), title() |
|
||||||
| ShopBasket | ZMIGROWANY do `front\Controllers\ShopBasketController` | Operacje koszyka, add/remove/quantity, checkout |
|
| ShopBasket | ZMIGROWANY do `front\Controllers\ShopBasketController` | Operacje koszyka, add/remove/quantity, checkout |
|
||||||
| ShopClient | ZMIGROWANY do `front\Controllers\ShopClientController` | Logowanie, rejestracja, odzyskiwanie hasla, adresy, zamowienia |
|
| ShopClient | ZMIGROWANY do `front\Controllers\ShopClientController` | Logowanie, rejestracja, odzyskiwanie hasla, adresy, zamowienia |
|
||||||
| ShopOrder | KRYTYCZNY | Webhooki płatności (tPay, Przelewy24, Hotpay) — bezpośrednie operacje DB |
|
| ShopOrder | ZMIGROWANY do `front\Controllers\ShopOrderController` | Webhooki płatności + order details |
|
||||||
| ShopProduct | Fasada | lazy_loading, warehouse_message, draw_product_attributes |
|
| ShopProduct | Fasada | lazy_loading, warehouse_message, draw_product_attributes |
|
||||||
| ShopProducer | Fasada | list(), products() |
|
| ShopProducer | Fasada | list(), products() |
|
||||||
| ShopCoupon | Fasada | use_coupon(), delete_coupon() |
|
| ShopCoupon | ZMIGROWANY do `front\Controllers\ShopCouponController` | use_coupon(), delete_coupon() |
|
||||||
| Newsletter | Fasada | signin(), confirm(), unsubscribe() |
|
| Newsletter | ZMIGROWANY do `front\Controllers\NewsletterController` | signin(), confirm(), unsubscribe() |
|
||||||
|
|
||||||
### front/factory/ (20 klas — pobieranie danych + logika)
|
### front/factory/ (20 klas — pobieranie danych + logika)
|
||||||
| Klasa | Status | Priorytet migracji |
|
| Klasa | Status | Priorytet migracji |
|
||||||
|-------|--------|--------------------|
|
|-------|--------|--------------------|
|
||||||
| ShopProduct | ORYGINALNA LOGIKA (~370 linii) | KRYTYCZNY — product_details(), promoted/top/new products |
|
| ShopProduct | ORYGINALNA LOGIKA (~370 linii) | KRYTYCZNY — product_details(), promoted/top/new products |
|
||||||
| ShopOrder | ORYGINALNA LOGIKA (~180 linii) | KRYTYCZNY — basket_save() tworzy zamówienie |
|
| ShopOrder | ZMIGROWANA do `OrderRepository` — usunięta | — |
|
||||||
| ShopClient | ZMIGROWANA do `ClientRepository` + `ShopClientController` — usunięta | — |
|
| ShopClient | ZMIGROWANA do `ClientRepository` + `ShopClientController` — usunięta | — |
|
||||||
| ShopCategory | ZMIGROWANA do `CategoryRepository` — usunięta | — |
|
| ShopCategory | ZMIGROWANA do `CategoryRepository` — usunięta | — |
|
||||||
| Articles | ORYGINALNA LOGIKA | WYSOKI — złożone SQL z language fallback |
|
| Articles | ORYGINALNA LOGIKA | WYSOKI — złożone SQL z language fallback |
|
||||||
@@ -44,7 +44,7 @@ Panel administratora (33 moduły) został w pełni zmigrowany na architekturę D
|
|||||||
| Menu | USUNIETA — przepieta na Domain | — |
|
| Menu | USUNIETA — przepieta na Domain | — |
|
||||||
| Pages | USUNIETA — przepieta na Domain | — |
|
| Pages | USUNIETA — przepieta na Domain | — |
|
||||||
| ShopAttribute | ZMIGROWANA (Domain) — usunięta | — |
|
| ShopAttribute | ZMIGROWANA (Domain) — usunięta | — |
|
||||||
| ShopCoupon | Model danych | NISKI |
|
| ShopCoupon | ZMIGROWANA do `CouponRepository` — usunięta | — |
|
||||||
|
|
||||||
### front/view/ (12 klas — renderowanie)
|
### front/view/ (12 klas — renderowanie)
|
||||||
| Klasa | Status |
|
| Klasa | Status |
|
||||||
@@ -57,7 +57,8 @@ Panel administratora (33 moduły) został w pełni zmigrowany na architekturę D
|
|||||||
| Banners | PRZENIESIONA do `front\Views\Banners` |
|
| Banners | PRZENIESIONA do `front\Views\Banners` |
|
||||||
| Languages, Newsletter | PRZENIESIONE do `front\Views\` (nowy namespace) |
|
| Languages, Newsletter | PRZENIESIONE do `front\Views\` (nowy namespace) |
|
||||||
| ShopClient | PRZENIESIONA do `front\Views\ShopClient` |
|
| ShopClient | PRZENIESIONA do `front\Views\ShopClient` |
|
||||||
| ShopOrder, ShopPaymentMethod | Czyste VIEW |
|
| ShopOrder | ZMIGROWANA do `ShopOrderController` — usunięta |
|
||||||
|
| ShopPaymentMethod | Czyste VIEW |
|
||||||
| ShopTransport | PUSTA klasa (placeholder) |
|
| ShopTransport | PUSTA klasa (placeholder) |
|
||||||
|
|
||||||
### shop/ (14 klas — encje biznesowe)
|
### shop/ (14 klas — encje biznesowe)
|
||||||
@@ -464,38 +465,41 @@ front\factory\ShopPromotion::promotion_type_XX() → shop\Product::is_product_on
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### Etap: Order Creation Frontend Service
|
### Etap: Order Creation Frontend Service — ZREALIZOWANY (ver. 0.290)
|
||||||
|
|
||||||
**Cel:** Migracja `front\factory\ShopOrder::basket_save()` (~180 linii).
|
**Cel:** Migracja `front\factory\ShopOrder::basket_save()` (~180 linii).
|
||||||
|
|
||||||
**NOWE:**
|
**ZREALIZOWANE:** (wg wytycznej "NIE tworzymy osobnych FrontendService/AdminService" — metody dodane do istniejącego `OrderRepository`)
|
||||||
- `Domain/Order/OrderFrontendService.php`:
|
- `Domain/Order/OrderRepository.php` — dodane metody frontendowe:
|
||||||
- `createOrder()` — tworzenie zamówienia z koszyka (walidacja, kalkulacja cen, insert, redukcja stanów, obsługa kuponu, wysyłka emaili, auto-status dla pobrania)
|
- `createFromBasket()` — tworzenie zamówienia z koszyka (21 parametrów, pełna logika basket_save)
|
||||||
- `generateOrderNumber()` — format YYYY/MM/NNN
|
- `generateOrderNumber()` — format YYYY/MM/NNN
|
||||||
- `orderDetails()`, `orderIdByHash()`, `orderHashById()`
|
- `orderDetailsFrontend()`, `findIdByHash()`, `findHashById()`
|
||||||
- Testy: `OrderFrontendServiceTest`
|
- `front/Controllers/ShopOrderController.php` — kontroler z DI (OrderRepository)
|
||||||
|
- Testy: `OrderRepositoryTest` (9 nowych), `ShopOrderControllerTest` (3 nowe)
|
||||||
|
|
||||||
**ZMIANA:**
|
**USUNIĘTE:**
|
||||||
- `front/factory/ShopOrder` → fasada
|
- `front/factory/class.ShopOrder.php`
|
||||||
|
- `front/controls/class.ShopOrder.php`
|
||||||
|
- `front/view/class.ShopOrder.php`
|
||||||
|
|
||||||
|
**CALLERY ZAKTUALIZOWANE:**
|
||||||
|
- `ShopBasketController` — DI OrderRepository, zmiana basket_save/order_hash
|
||||||
|
- `ClientRepository::clientOrders()` — OrderRepository::orderDetailsFrontend()
|
||||||
|
- `shop\Order::order_resend_confirmation_email()` — OrderRepository::orderDetailsFrontend()
|
||||||
|
- `cron-turstmate.php` — OrderRepository::orderDetailsFrontend()
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### Etap: Payment Webhook Service
|
### Etap: Payment Webhook Service — ZREALIZOWANY (ver. 0.290)
|
||||||
|
|
||||||
**Cel:** Wyodrębnienie webhooków płatności z `front\controls\ShopOrder`.
|
**Cel:** Wyodrębnienie webhooków płatności z `front\controls\ShopOrder`.
|
||||||
|
|
||||||
**NOWE:**
|
**ZREALIZOWANE:** (webhooki przeniesione do `front\Controllers\ShopOrderController` — nadal używają `\shop\Order` do operacji statusów/płatności)
|
||||||
- `Domain/Payment/PaymentWebhookService.php`:
|
- `ShopOrderController::paymentStatusTpay()` — przeniesione 1:1
|
||||||
- `processTpay(array $params)` — weryfikacja tPay
|
- `ShopOrderController::paymentStatusPrzelewy24pl()` — ujednolicone z tpay (set_as_paid + update_status zamiast ręcznego $mdb->update)
|
||||||
- `processPrzelewy24(array $params)` — weryfikacja przez API + walidacja kwoty
|
- `ShopOrderController::paymentStatusHotpay()` — analogiczna zamiana na \shop\Order metody
|
||||||
- `processHotpay(array $params)` — walidacja SHA256 hash
|
|
||||||
- `private markOrderPaid()` — wspólna logika (update status + email + Apilo sync)
|
|
||||||
- Testy: `PaymentWebhookServiceTest`
|
|
||||||
|
|
||||||
**ZMIANA:**
|
**UWAGA:** `\shop\Order` nie jest jeszcze zmigrowany — osobny etap (Order Instance + Apilo Service)
|
||||||
- `front/controls/ShopOrder` — webhooki stają się thin wrappers
|
|
||||||
|
|
||||||
**POPRAWA:** Zamiana `file_put_contents('tpay.txt')` na `\Log::save_log()`
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|||||||
@@ -457,4 +457,21 @@ Pelna dokumentacja testow: `TESTING.md`
|
|||||||
- OPTYMALIZACJA: `addressSave()` przyjmuje `array $data` zamiast 6 parametrow
|
- OPTYMALIZACJA: `addressSave()` przyjmuje `array $data` zamiast 6 parametrow
|
||||||
|
|
||||||
---
|
---
|
||||||
*Dokument aktualizowany: 2026-02-17 (ver. 0.289)*
|
|
||||||
|
## Aktualizacja 2026-02-17 (ver. 0.290) - ShopCoupon + ShopOrder frontend migration
|
||||||
|
- **ShopCoupon (frontend)** — migracja controls + factory na Domain + Controllers
|
||||||
|
- NOWE METODY w `CouponRepository`: `findByName()`, `isAvailable()`, `markAsUsed()`, `incrementUsedCount()`
|
||||||
|
- NOWY: `front\Controllers\ShopCouponController` — instancyjny kontroler z DI (`useCoupon()`, `deleteCoupon()`)
|
||||||
|
- KONWERSJA: `shop\Coupon` na fasade z dzialajacymi metodami (`is_one_time()`, `set_as_used()`)
|
||||||
|
- FIX: kupony jednorazowe nigdy nie byly oznaczane jako uzyte
|
||||||
|
- USUNIETA: `front\controls\class.ShopCoupon.php`, `front\factory\class.ShopCoupon.php`
|
||||||
|
- **ShopOrder (frontend)** — migracja controls + factory + view na Domain + Controllers
|
||||||
|
- NOWE METODY w `OrderRepository`: `findIdByHash()`, `findHashById()`, `orderDetailsFrontend()`, `generateOrderNumber()`, `createFromBasket()` (~180 linii logiki basket_save)
|
||||||
|
- NOWY: `front\Controllers\ShopOrderController` — instancyjny kontroler z DI (`paymentConfirmation()`, `paymentStatusTpay()`, `paymentStatusPrzelewy24pl()`, `paymentStatusHotpay()`, `orderDetails()`)
|
||||||
|
- POPRAWA: webhooks przelewy24/hotpay — ujednolicone z tpay (set_as_paid + update_status zamiast recznego $mdb->update)
|
||||||
|
- UPDATE: `ShopBasketController` — DI OrderRepository, zmiana wywolan basket_save/order_hash
|
||||||
|
- UPDATE: `ClientRepository::clientOrders()`, `shop\Order::order_resend_confirmation_email()`, `cron-turstmate.php` — przepiete na `OrderRepository`
|
||||||
|
- USUNIETA: `front\controls\class.ShopOrder.php`, `front\factory\class.ShopOrder.php`, `front\view\class.ShopOrder.php`
|
||||||
|
|
||||||
|
---
|
||||||
|
*Dokument aktualizowany: 2026-02-17 (ver. 0.290)*
|
||||||
|
|||||||
@@ -36,7 +36,16 @@ Alternatywnie (Git Bash):
|
|||||||
Ostatnio zweryfikowano: 2026-02-17
|
Ostatnio zweryfikowano: 2026-02-17
|
||||||
|
|
||||||
```text
|
```text
|
||||||
OK (537 tests, 1648 assertions)
|
OK (565 tests, 1716 assertions)
|
||||||
|
```
|
||||||
|
|
||||||
|
Aktualizacja po migracji ShopCoupon + ShopOrder frontend (2026-02-17, ver. 0.290):
|
||||||
|
```text
|
||||||
|
Pelny suite: OK (565 tests, 1716 assertions)
|
||||||
|
Nowe testy: CouponRepositoryTest (+12: findByName 3 scenariusze, isAvailable 5 scenariuszy, markAsUsed 2 scenariusze, incrementUsedCount 2 scenariusze)
|
||||||
|
Nowe testy: ShopCouponControllerTest (+3: constructorAcceptsRepository, hasMainActionMethods, constructorRequiresCouponRepository)
|
||||||
|
Nowe testy: OrderRepositoryTest (+10: findIdByHash 3 scenariusze, findHashById 2 scenariusze, orderDetailsFrontend 3 scenariusze, generateOrderNumber 2 scenariusze)
|
||||||
|
Nowe testy: ShopOrderControllerTest (+3: constructorAcceptsRepository, hasMainActionMethods, constructorRequiresOrderRepository)
|
||||||
```
|
```
|
||||||
|
|
||||||
Aktualizacja po migracji ShopCategory + ShopClient frontend (2026-02-17, ver. 0.289):
|
Aktualizacja po migracji ShopCategory + ShopClient frontend (2026-02-17, ver. 0.289):
|
||||||
|
|||||||
@@ -18,16 +18,16 @@ Aktualizacje znajdują się w folderze `updates/0.XX/` gdzie XX oznacza dziesią
|
|||||||
|
|
||||||
## Procedura tworzenia nowej aktualizacji
|
## Procedura tworzenia nowej aktualizacji
|
||||||
|
|
||||||
## Status biezacej aktualizacji (ver. 0.289)
|
## Status biezacej aktualizacji (ver. 0.290)
|
||||||
|
|
||||||
- Wersja udostepniona: `0.289` (data: 2026-02-17).
|
- Wersja udostepniona: `0.290` (data: 2026-02-17).
|
||||||
- Pliki publikacyjne:
|
- Pliki publikacyjne:
|
||||||
- `updates/0.20/ver_0.289.zip`, `ver_0.289_files.txt`
|
- `updates/0.20/ver_0.290.zip`, `ver_0.290_files.txt`
|
||||||
- Pliki metadanych aktualizacji:
|
- Pliki metadanych aktualizacji:
|
||||||
- `updates/changelog.php` (dodany wpis `ver. 0.289`)
|
- `updates/changelog.php` (dodany wpis `ver. 0.290`)
|
||||||
- `updates/versions.php` (`$current_ver = 289`)
|
- `updates/versions.php` (`$current_ver = 290`)
|
||||||
- Weryfikacja testow przed publikacja:
|
- Weryfikacja testow przed publikacja:
|
||||||
- `OK (537 tests, 1648 assertions)`
|
- `OK (565 tests, 1716 assertions)`
|
||||||
|
|
||||||
### 1. Określ numer wersji
|
### 1. Określ numer wersji
|
||||||
Sprawdź ostatnią wersję w `updates/` i zwiększ o 1.
|
Sprawdź ostatnią wersję w `updates/` i zwiększ o 1.
|
||||||
|
|||||||
@@ -265,4 +265,153 @@ class CouponRepositoryTest extends TestCase
|
|||||||
$this->assertCount(1, $tree[0]['subcategories']);
|
$this->assertCount(1, $tree[0]['subcategories']);
|
||||||
$this->assertSame(11, (int)$tree[0]['subcategories'][0]['id']);
|
$this->assertSame(11, (int)$tree[0]['subcategories'][0]['id']);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testFindByNameReturnsObjectWhenFound(): void
|
||||||
|
{
|
||||||
|
$mockDb = $this->createMock(\medoo::class);
|
||||||
|
$mockDb->expects($this->once())
|
||||||
|
->method('get')
|
||||||
|
->with('pp_shop_coupon', '*', ['name' => 'RABAT10'])
|
||||||
|
->willReturn([
|
||||||
|
'id' => '5',
|
||||||
|
'name' => 'RABAT10',
|
||||||
|
'status' => '1',
|
||||||
|
'used' => '0',
|
||||||
|
'type' => '1',
|
||||||
|
'amount' => '10.00',
|
||||||
|
'one_time' => '1',
|
||||||
|
'include_discounted_product' => '0',
|
||||||
|
'categories' => '[1,2]',
|
||||||
|
'used_count' => '0',
|
||||||
|
]);
|
||||||
|
|
||||||
|
$repository = new CouponRepository($mockDb);
|
||||||
|
$result = $repository->findByName('RABAT10');
|
||||||
|
|
||||||
|
$this->assertIsObject($result);
|
||||||
|
$this->assertSame(5, $result->id);
|
||||||
|
$this->assertSame('RABAT10', $result->name);
|
||||||
|
$this->assertSame(1, $result->status);
|
||||||
|
$this->assertSame(0, $result->used);
|
||||||
|
$this->assertSame(1, $result->type);
|
||||||
|
$this->assertSame('10.00', $result->amount);
|
||||||
|
$this->assertSame(1, $result->one_time);
|
||||||
|
$this->assertSame(0, $result->include_discounted_product);
|
||||||
|
$this->assertSame('[1,2]', $result->categories);
|
||||||
|
$this->assertSame(0, $result->used_count);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testFindByNameReturnsNullWhenNotFound(): void
|
||||||
|
{
|
||||||
|
$mockDb = $this->createMock(\medoo::class);
|
||||||
|
$mockDb->expects($this->once())
|
||||||
|
->method('get')
|
||||||
|
->willReturn(null);
|
||||||
|
|
||||||
|
$repository = new CouponRepository($mockDb);
|
||||||
|
$this->assertNull($repository->findByName('NIEISTNIEJACY'));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testFindByNameReturnsNullForEmptyName(): void
|
||||||
|
{
|
||||||
|
$mockDb = $this->createMock(\medoo::class);
|
||||||
|
$mockDb->expects($this->never())->method('get');
|
||||||
|
|
||||||
|
$repository = new CouponRepository($mockDb);
|
||||||
|
$this->assertNull($repository->findByName(''));
|
||||||
|
$this->assertNull($repository->findByName(' '));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testIsAvailableReturnsTrueForActiveCoupon(): void
|
||||||
|
{
|
||||||
|
$mockDb = $this->createMock(\medoo::class);
|
||||||
|
$repository = new CouponRepository($mockDb);
|
||||||
|
|
||||||
|
$coupon = (object)['id' => 1, 'status' => 1, 'used' => 0];
|
||||||
|
$this->assertTrue($repository->isAvailable($coupon));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testIsAvailableReturnsFalseForUsedCoupon(): void
|
||||||
|
{
|
||||||
|
$mockDb = $this->createMock(\medoo::class);
|
||||||
|
$repository = new CouponRepository($mockDb);
|
||||||
|
|
||||||
|
$coupon = (object)['id' => 1, 'status' => 1, 'used' => 1];
|
||||||
|
$this->assertFalse($repository->isAvailable($coupon));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testIsAvailableReturnsFalseForInactiveCoupon(): void
|
||||||
|
{
|
||||||
|
$mockDb = $this->createMock(\medoo::class);
|
||||||
|
$repository = new CouponRepository($mockDb);
|
||||||
|
|
||||||
|
$coupon = (object)['id' => 1, 'status' => 0, 'used' => 0];
|
||||||
|
$this->assertFalse($repository->isAvailable($coupon));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testIsAvailableReturnsFalseForNullCoupon(): void
|
||||||
|
{
|
||||||
|
$mockDb = $this->createMock(\medoo::class);
|
||||||
|
$repository = new CouponRepository($mockDb);
|
||||||
|
|
||||||
|
$this->assertFalse($repository->isAvailable(null));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testIsAvailableWorksWithArray(): void
|
||||||
|
{
|
||||||
|
$mockDb = $this->createMock(\medoo::class);
|
||||||
|
$repository = new CouponRepository($mockDb);
|
||||||
|
|
||||||
|
$this->assertTrue($repository->isAvailable(['id' => 1, 'status' => 1, 'used' => 0]));
|
||||||
|
$this->assertFalse($repository->isAvailable(['id' => 0, 'status' => 1, 'used' => 0]));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testMarkAsUsedCallsUpdate(): void
|
||||||
|
{
|
||||||
|
$mockDb = $this->createMock(\medoo::class);
|
||||||
|
$mockDb->expects($this->once())
|
||||||
|
->method('update')
|
||||||
|
->willReturnCallback(function ($table, $row, $where) {
|
||||||
|
$this->assertSame('pp_shop_coupon', $table);
|
||||||
|
$this->assertSame(1, $row['used']);
|
||||||
|
$this->assertArrayHasKey('date_used', $row);
|
||||||
|
$this->assertSame(['id' => 10], $where);
|
||||||
|
});
|
||||||
|
|
||||||
|
$repository = new CouponRepository($mockDb);
|
||||||
|
$repository->markAsUsed(10);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testMarkAsUsedSkipsInvalidId(): void
|
||||||
|
{
|
||||||
|
$mockDb = $this->createMock(\medoo::class);
|
||||||
|
$mockDb->expects($this->never())->method('update');
|
||||||
|
|
||||||
|
$repository = new CouponRepository($mockDb);
|
||||||
|
$repository->markAsUsed(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testIncrementUsedCountCallsUpdate(): void
|
||||||
|
{
|
||||||
|
$mockDb = $this->createMock(\medoo::class);
|
||||||
|
$mockDb->expects($this->once())
|
||||||
|
->method('update')
|
||||||
|
->willReturnCallback(function ($table, $row, $where) {
|
||||||
|
$this->assertSame('pp_shop_coupon', $table);
|
||||||
|
$this->assertSame(1, $row['used_count[+]']);
|
||||||
|
$this->assertSame(['id' => 7], $where);
|
||||||
|
});
|
||||||
|
|
||||||
|
$repository = new CouponRepository($mockDb);
|
||||||
|
$repository->incrementUsedCount(7);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testIncrementUsedCountSkipsInvalidId(): void
|
||||||
|
{
|
||||||
|
$mockDb = $this->createMock(\medoo::class);
|
||||||
|
$mockDb->expects($this->never())->method('update');
|
||||||
|
|
||||||
|
$repository = new CouponRepository($mockDb);
|
||||||
|
$repository->incrementUsedCount(0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -91,4 +91,141 @@ class OrderRepositoryTest extends TestCase
|
|||||||
$this->assertSame(2, $result['items'][0]['total_orders']);
|
$this->assertSame(2, $result['items'][0]['total_orders']);
|
||||||
$this->assertSame(1, $result['items'][0]['paid']);
|
$this->assertSame(1, $result['items'][0]['paid']);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// --- Frontend method tests ---
|
||||||
|
|
||||||
|
public function testFindIdByHashReturnsIdWhenFound(): void
|
||||||
|
{
|
||||||
|
$mockDb = $this->createMock(\medoo::class);
|
||||||
|
$mockDb->method('get')
|
||||||
|
->with('pp_shop_orders', 'id', ['hash' => 'abc123'])
|
||||||
|
->willReturn('42');
|
||||||
|
|
||||||
|
$repository = new OrderRepository($mockDb);
|
||||||
|
$this->assertSame(42, $repository->findIdByHash('abc123'));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testFindIdByHashReturnsNullWhenNotFound(): void
|
||||||
|
{
|
||||||
|
$mockDb = $this->createMock(\medoo::class);
|
||||||
|
$mockDb->method('get')->willReturn(null);
|
||||||
|
|
||||||
|
$repository = new OrderRepository($mockDb);
|
||||||
|
$this->assertNull($repository->findIdByHash('nonexistent'));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testFindIdByHashReturnsNullForEmptyHash(): void
|
||||||
|
{
|
||||||
|
$mockDb = $this->createMock(\medoo::class);
|
||||||
|
$mockDb->expects($this->never())->method('get');
|
||||||
|
|
||||||
|
$repository = new OrderRepository($mockDb);
|
||||||
|
$this->assertNull($repository->findIdByHash(''));
|
||||||
|
$this->assertNull($repository->findIdByHash(' '));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testFindHashByIdReturnsHashWhenFound(): void
|
||||||
|
{
|
||||||
|
$mockDb = $this->createMock(\medoo::class);
|
||||||
|
$mockDb->method('get')
|
||||||
|
->with('pp_shop_orders', 'hash', ['id' => 42])
|
||||||
|
->willReturn('abc123hash');
|
||||||
|
|
||||||
|
$repository = new OrderRepository($mockDb);
|
||||||
|
$this->assertSame('abc123hash', $repository->findHashById(42));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testFindHashByIdReturnsNullForInvalidId(): void
|
||||||
|
{
|
||||||
|
$mockDb = $this->createMock(\medoo::class);
|
||||||
|
$mockDb->expects($this->never())->method('get');
|
||||||
|
|
||||||
|
$repository = new OrderRepository($mockDb);
|
||||||
|
$this->assertNull($repository->findHashById(0));
|
||||||
|
$this->assertNull($repository->findHashById(-1));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testOrderDetailsFrontendByIdReturnsArrayWithProducts(): void
|
||||||
|
{
|
||||||
|
$mockDb = $this->createMock(\medoo::class);
|
||||||
|
$mockDb->method('get')
|
||||||
|
->willReturn(['id' => 1, 'number' => '2026/02/001', 'coupon_id' => null]);
|
||||||
|
$mockDb->method('select')
|
||||||
|
->willReturn([['product_id' => 10, 'name' => 'Test Product']]);
|
||||||
|
|
||||||
|
$repository = new OrderRepository($mockDb);
|
||||||
|
$result = $repository->orderDetailsFrontend(1);
|
||||||
|
|
||||||
|
$this->assertIsArray($result);
|
||||||
|
$this->assertSame(1, $result['id']);
|
||||||
|
$this->assertIsArray($result['products']);
|
||||||
|
$this->assertCount(1, $result['products']);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testOrderDetailsFrontendByHashReturnsArrayWithProducts(): void
|
||||||
|
{
|
||||||
|
$mockDb = $this->createMock(\medoo::class);
|
||||||
|
$mockDb->method('get')
|
||||||
|
->willReturn(['id' => 5, 'number' => '2026/02/005', 'hash' => 'testhash']);
|
||||||
|
$mockDb->method('select')
|
||||||
|
->willReturn([]);
|
||||||
|
|
||||||
|
$repository = new OrderRepository($mockDb);
|
||||||
|
$result = $repository->orderDetailsFrontend(null, 'testhash');
|
||||||
|
|
||||||
|
$this->assertIsArray($result);
|
||||||
|
$this->assertSame(5, $result['id']);
|
||||||
|
$this->assertIsArray($result['products']);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testOrderDetailsFrontendReturnsNullWhenNotFound(): void
|
||||||
|
{
|
||||||
|
$mockDb = $this->createMock(\medoo::class);
|
||||||
|
$mockDb->method('get')->willReturn(null);
|
||||||
|
|
||||||
|
$repository = new OrderRepository($mockDb);
|
||||||
|
$this->assertNull($repository->orderDetailsFrontend(999));
|
||||||
|
$this->assertNull($repository->orderDetailsFrontend(null, 'nonexistent'));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testGenerateOrderNumberFormatsCorrectly(): void
|
||||||
|
{
|
||||||
|
$mockDb = $this->createMock(\medoo::class);
|
||||||
|
|
||||||
|
$resultSet = new class {
|
||||||
|
public function fetchAll(): array
|
||||||
|
{
|
||||||
|
return [[5]];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
$mockDb->method('query')->willReturn($resultSet);
|
||||||
|
|
||||||
|
$repository = new OrderRepository($mockDb);
|
||||||
|
$number = $repository->generateOrderNumber();
|
||||||
|
|
||||||
|
$expectedPrefix = date('Y/m') . '/';
|
||||||
|
$this->assertStringStartsWith($expectedPrefix, $number);
|
||||||
|
$this->assertSame($expectedPrefix . '006', $number);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testGenerateOrderNumberStartsAt001(): void
|
||||||
|
{
|
||||||
|
$mockDb = $this->createMock(\medoo::class);
|
||||||
|
|
||||||
|
$resultSet = new class {
|
||||||
|
public function fetchAll(): array
|
||||||
|
{
|
||||||
|
return [[null]];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
$mockDb->method('query')->willReturn($resultSet);
|
||||||
|
|
||||||
|
$repository = new OrderRepository($mockDb);
|
||||||
|
$number = $repository->generateOrderNumber();
|
||||||
|
|
||||||
|
$expectedPrefix = date('Y/m') . '/';
|
||||||
|
$this->assertSame($expectedPrefix . '001', $number);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
40
tests/Unit/front/Controllers/ShopCouponControllerTest.php
Normal file
40
tests/Unit/front/Controllers/ShopCouponControllerTest.php
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
<?php
|
||||||
|
namespace Tests\Unit\front\Controllers;
|
||||||
|
|
||||||
|
use PHPUnit\Framework\TestCase;
|
||||||
|
use front\Controllers\ShopCouponController;
|
||||||
|
use Domain\Coupon\CouponRepository;
|
||||||
|
|
||||||
|
class ShopCouponControllerTest extends TestCase
|
||||||
|
{
|
||||||
|
private $repository;
|
||||||
|
private $controller;
|
||||||
|
|
||||||
|
protected function setUp(): void
|
||||||
|
{
|
||||||
|
$this->repository = $this->createMock(CouponRepository::class);
|
||||||
|
$this->controller = new ShopCouponController($this->repository);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testConstructorAcceptsRepository(): void
|
||||||
|
{
|
||||||
|
$controller = new ShopCouponController($this->repository);
|
||||||
|
$this->assertInstanceOf(ShopCouponController::class, $controller);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testHasMainActionMethods(): void
|
||||||
|
{
|
||||||
|
$this->assertTrue(method_exists($this->controller, 'useCoupon'));
|
||||||
|
$this->assertTrue(method_exists($this->controller, 'deleteCoupon'));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testConstructorRequiresCouponRepository(): void
|
||||||
|
{
|
||||||
|
$reflection = new \ReflectionClass(ShopCouponController::class);
|
||||||
|
$constructor = $reflection->getConstructor();
|
||||||
|
$params = $constructor->getParameters();
|
||||||
|
|
||||||
|
$this->assertCount(1, $params);
|
||||||
|
$this->assertEquals('Domain\Coupon\CouponRepository', $params[0]->getType()->getName());
|
||||||
|
}
|
||||||
|
}
|
||||||
43
tests/Unit/front/Controllers/ShopOrderControllerTest.php
Normal file
43
tests/Unit/front/Controllers/ShopOrderControllerTest.php
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
<?php
|
||||||
|
namespace Tests\Unit\front\Controllers;
|
||||||
|
|
||||||
|
use PHPUnit\Framework\TestCase;
|
||||||
|
use front\Controllers\ShopOrderController;
|
||||||
|
use Domain\Order\OrderRepository;
|
||||||
|
|
||||||
|
class ShopOrderControllerTest extends TestCase
|
||||||
|
{
|
||||||
|
private $repository;
|
||||||
|
private $controller;
|
||||||
|
|
||||||
|
protected function setUp(): void
|
||||||
|
{
|
||||||
|
$this->repository = $this->createMock(OrderRepository::class);
|
||||||
|
$this->controller = new ShopOrderController($this->repository);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testConstructorAcceptsRepository(): void
|
||||||
|
{
|
||||||
|
$controller = new ShopOrderController($this->repository);
|
||||||
|
$this->assertInstanceOf(ShopOrderController::class, $controller);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testHasMainActionMethods(): void
|
||||||
|
{
|
||||||
|
$this->assertTrue(method_exists($this->controller, 'paymentConfirmation'));
|
||||||
|
$this->assertTrue(method_exists($this->controller, 'paymentStatusTpay'));
|
||||||
|
$this->assertTrue(method_exists($this->controller, 'paymentStatusPrzelewy24pl'));
|
||||||
|
$this->assertTrue(method_exists($this->controller, 'paymentStatusHotpay'));
|
||||||
|
$this->assertTrue(method_exists($this->controller, 'orderDetails'));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testConstructorRequiresOrderRepository(): void
|
||||||
|
{
|
||||||
|
$reflection = new \ReflectionClass(ShopOrderController::class);
|
||||||
|
$constructor = $reflection->getConstructor();
|
||||||
|
$params = $constructor->getParameters();
|
||||||
|
|
||||||
|
$this->assertCount(1, $params);
|
||||||
|
$this->assertEquals('Domain\Order\OrderRepository', $params[0]->getType()->getName());
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -12,6 +12,7 @@ if (file_exists(__DIR__ . '/../vendor/autoload.php')) {
|
|||||||
$prefixes = [
|
$prefixes = [
|
||||||
'Domain\\' => __DIR__ . '/../autoload/Domain/',
|
'Domain\\' => __DIR__ . '/../autoload/Domain/',
|
||||||
'admin\\Controllers\\' => __DIR__ . '/../autoload/admin/Controllers/',
|
'admin\\Controllers\\' => __DIR__ . '/../autoload/admin/Controllers/',
|
||||||
|
'front\\Controllers\\' => __DIR__ . '/../autoload/front/Controllers/',
|
||||||
'admin\\Support\\Forms\\' => __DIR__ . '/../autoload/admin/Support/Forms/',
|
'admin\\Support\\Forms\\' => __DIR__ . '/../autoload/admin/Support/Forms/',
|
||||||
'admin\\ViewModels\\Forms\\' => __DIR__ . '/../autoload/admin/ViewModels/Forms/',
|
'admin\\ViewModels\\Forms\\' => __DIR__ . '/../autoload/admin/ViewModels/Forms/',
|
||||||
'admin\\Validation\\' => __DIR__ . '/../autoload/admin/Validation/',
|
'admin\\Validation\\' => __DIR__ . '/../autoload/admin/Validation/',
|
||||||
|
|||||||
BIN
updates/0.20/ver_0.290.zip
Normal file
BIN
updates/0.20/ver_0.290.zip
Normal file
Binary file not shown.
5
updates/0.20/ver_0.290_files.txt
Normal file
5
updates/0.20/ver_0.290_files.txt
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
F: ../autoload/front/controls/class.ShopCoupon.php
|
||||||
|
F: ../autoload/front/factory/class.ShopCoupon.php
|
||||||
|
F: ../autoload/front/controls/class.ShopOrder.php
|
||||||
|
F: ../autoload/front/factory/class.ShopOrder.php
|
||||||
|
F: ../autoload/front/view/class.ShopOrder.php
|
||||||
@@ -1,3 +1,9 @@
|
|||||||
|
<b>ver. 0.290 - 17.02.2026</b><br />
|
||||||
|
- UPDATE - migracja front\factory\ShopCoupon + front\controls\ShopCoupon do Domain\Coupon\CouponRepository + front\Controllers\ShopCouponController
|
||||||
|
- UPDATE - migracja front\factory\ShopOrder + front\controls\ShopOrder + front\view\ShopOrder do Domain\Order\OrderRepository + front\Controllers\ShopOrderController
|
||||||
|
- FIX - kupony jednorazowe nigdy nie byly oznaczane jako uzyte (is_one_time/set_as_used w shop\Coupon)
|
||||||
|
- FIX - webhooks przelewy24/hotpay ujednolicone z tpay (poprawna obsluga Apilo sync)
|
||||||
|
<hr>
|
||||||
<b>ver. 0.289 - 17.02.2026</b><br />
|
<b>ver. 0.289 - 17.02.2026</b><br />
|
||||||
- UPDATE - migracja front\factory\ShopCategory + front\view\ShopCategory do Domain\Category\CategoryRepository + front\Views\ShopCategory
|
- UPDATE - migracja front\factory\ShopCategory + front\view\ShopCategory do Domain\Category\CategoryRepository + front\Views\ShopCategory
|
||||||
- UPDATE - migracja front\factory\ShopClient + front\view\ShopClient + front\controls\ShopClient do Domain\Client\ClientRepository + front\Views\ShopClient + front\Controllers\ShopClientController
|
- UPDATE - migracja front\factory\ShopClient + front\view\ShopClient + front\controls\ShopClient do Domain\Client\ClientRepository + front\Views\ShopClient + front\Controllers\ShopClientController
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<?
|
<?
|
||||||
$current_ver = 289;
|
$current_ver = 290;
|
||||||
|
|
||||||
for ($i = 1; $i <= $current_ver; $i++)
|
for ($i = 1; $i <= $current_ver; $i++)
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user