- 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>
401 lines
11 KiB
PHP
401 lines
11 KiB
PHP
<?php
|
|
namespace Domain\PaymentMethod;
|
|
|
|
class PaymentMethodRepository
|
|
{
|
|
private const MAX_PER_PAGE = 100;
|
|
|
|
private $db;
|
|
|
|
public function __construct($db)
|
|
{
|
|
$this->db = $db;
|
|
}
|
|
|
|
/**
|
|
* @return array{items: array<int, array<string, mixed>>, total: int}
|
|
*/
|
|
public function listForAdmin(
|
|
array $filters,
|
|
string $sortColumn = 'name',
|
|
string $sortDir = 'ASC',
|
|
int $page = 1,
|
|
int $perPage = 15
|
|
): array {
|
|
$allowedSortColumns = [
|
|
'id' => 'spm.id',
|
|
'name' => 'spm.name',
|
|
'status' => 'spm.status',
|
|
'apilo_payment_type_id' => 'spm.apilo_payment_type_id',
|
|
];
|
|
|
|
$sortSql = $allowedSortColumns[$sortColumn] ?? 'spm.name';
|
|
$sortDir = strtoupper(trim($sortDir)) === 'DESC' ? 'DESC' : 'ASC';
|
|
$page = max(1, $page);
|
|
$perPage = min(self::MAX_PER_PAGE, max(1, $perPage));
|
|
$offset = ($page - 1) * $perPage;
|
|
|
|
$where = ['1 = 1'];
|
|
$params = [];
|
|
|
|
$name = trim((string)($filters['name'] ?? ''));
|
|
if ($name !== '') {
|
|
if (strlen($name) > 255) {
|
|
$name = substr($name, 0, 255);
|
|
}
|
|
$where[] = 'spm.name LIKE :name';
|
|
$params[':name'] = '%' . $name . '%';
|
|
}
|
|
|
|
$status = trim((string)($filters['status'] ?? ''));
|
|
if ($status === '0' || $status === '1') {
|
|
$where[] = 'spm.status = :status';
|
|
$params[':status'] = (int)$status;
|
|
}
|
|
|
|
$whereSql = implode(' AND ', $where);
|
|
|
|
$sqlCount = "
|
|
SELECT COUNT(0)
|
|
FROM pp_shop_payment_methods AS spm
|
|
WHERE {$whereSql}
|
|
";
|
|
|
|
$stmtCount = $this->db->query($sqlCount, $params);
|
|
$countRows = $stmtCount ? $stmtCount->fetchAll() : [];
|
|
$total = isset($countRows[0][0]) ? (int)$countRows[0][0] : 0;
|
|
|
|
$sql = "
|
|
SELECT
|
|
spm.id,
|
|
spm.name,
|
|
spm.description,
|
|
spm.status,
|
|
spm.apilo_payment_type_id
|
|
FROM pp_shop_payment_methods AS spm
|
|
WHERE {$whereSql}
|
|
ORDER BY {$sortSql} {$sortDir}, spm.id ASC
|
|
LIMIT {$perPage} OFFSET {$offset}
|
|
";
|
|
|
|
$stmt = $this->db->query($sql, $params);
|
|
$items = $stmt ? $stmt->fetchAll() : [];
|
|
|
|
if (!is_array($items)) {
|
|
$items = [];
|
|
}
|
|
|
|
foreach ($items as &$item) {
|
|
$item = $this->normalizePaymentMethod($item);
|
|
}
|
|
unset($item);
|
|
|
|
return [
|
|
'items' => $items,
|
|
'total' => $total,
|
|
];
|
|
}
|
|
|
|
public function find(int $paymentMethodId): ?array
|
|
{
|
|
if ($paymentMethodId <= 0) {
|
|
return null;
|
|
}
|
|
|
|
$paymentMethod = $this->db->get('pp_shop_payment_methods', '*', ['id' => $paymentMethodId]);
|
|
if (!is_array($paymentMethod)) {
|
|
return null;
|
|
}
|
|
|
|
return $this->normalizePaymentMethod($paymentMethod);
|
|
}
|
|
|
|
public function save(int $paymentMethodId, array $data): ?int
|
|
{
|
|
if ($paymentMethodId <= 0) {
|
|
return null;
|
|
}
|
|
|
|
$row = [
|
|
'description' => trim((string)($data['description'] ?? '')),
|
|
'status' => $this->toSwitchValue($data['status'] ?? 0),
|
|
'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]);
|
|
|
|
$cacheHandler = new \Shared\Cache\CacheHandler();
|
|
$cacheHandler->deletePattern('payment_method*');
|
|
$cacheHandler->deletePattern('payment_methods*');
|
|
|
|
return $paymentMethodId;
|
|
}
|
|
|
|
/**
|
|
* @return array<int, array<string, mixed>>
|
|
*/
|
|
public function allActive(): array
|
|
{
|
|
$rows = $this->db->select('pp_shop_payment_methods', '*', [
|
|
'status' => 1,
|
|
'ORDER' => ['id' => 'ASC'],
|
|
]);
|
|
|
|
if (!is_array($rows)) {
|
|
return [];
|
|
}
|
|
|
|
$result = [];
|
|
foreach ($rows as $row) {
|
|
if (is_array($row)) {
|
|
$result[] = $this->normalizePaymentMethod($row);
|
|
}
|
|
}
|
|
|
|
return $result;
|
|
}
|
|
|
|
/**
|
|
* @return array<int, array<string, mixed>>
|
|
*/
|
|
public function allForAdmin(): array
|
|
{
|
|
$rows = $this->db->select('pp_shop_payment_methods', '*', [
|
|
'ORDER' => ['name' => 'ASC'],
|
|
]);
|
|
|
|
if (!is_array($rows)) {
|
|
return [];
|
|
}
|
|
|
|
$result = [];
|
|
foreach ($rows as $row) {
|
|
if (is_array($row)) {
|
|
$result[] = $this->normalizePaymentMethod($row);
|
|
}
|
|
}
|
|
|
|
return $result;
|
|
}
|
|
|
|
public function findActiveById(int $paymentMethodId): ?array
|
|
{
|
|
if ($paymentMethodId <= 0) {
|
|
return null;
|
|
}
|
|
|
|
$paymentMethod = $this->db->get('pp_shop_payment_methods', '*', [
|
|
'AND' => [
|
|
'id' => $paymentMethodId,
|
|
'status' => 1,
|
|
],
|
|
]);
|
|
|
|
if (!is_array($paymentMethod)) {
|
|
return null;
|
|
}
|
|
|
|
return $this->normalizePaymentMethod($paymentMethod);
|
|
}
|
|
|
|
public function isActive(int $paymentMethodId): int
|
|
{
|
|
if ($paymentMethodId <= 0) {
|
|
return 0;
|
|
}
|
|
|
|
$status = $this->db->get('pp_shop_payment_methods', 'status', ['id' => $paymentMethodId]);
|
|
return $this->toSwitchValue($status);
|
|
}
|
|
|
|
/**
|
|
* @return int|string|null
|
|
*/
|
|
public function getApiloPaymentTypeId(int $paymentMethodId)
|
|
{
|
|
if ($paymentMethodId <= 0) {
|
|
return null;
|
|
}
|
|
|
|
$value = $this->db->get('pp_shop_payment_methods', 'apilo_payment_type_id', ['id' => $paymentMethodId]);
|
|
return $this->normalizeApiloPaymentTypeId($value);
|
|
}
|
|
|
|
/**
|
|
* @return array<int, array<string, mixed>>
|
|
*/
|
|
public function forTransport(int $transportMethodId): array
|
|
{
|
|
if ($transportMethodId <= 0) {
|
|
return [];
|
|
}
|
|
|
|
$sql = "
|
|
SELECT
|
|
spm.id,
|
|
spm.name,
|
|
spm.description,
|
|
spm.status,
|
|
spm.apilo_payment_type_id,
|
|
spm.min_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
|
|
WHERE spm.status = 1
|
|
AND stpm.id_transport = :transport_id
|
|
";
|
|
|
|
$stmt = $this->db->query($sql, [':transport_id' => $transportMethodId]);
|
|
$rows = $stmt ? $stmt->fetchAll() : [];
|
|
|
|
if (!is_array($rows)) {
|
|
return [];
|
|
}
|
|
|
|
$result = [];
|
|
foreach ($rows as $row) {
|
|
if (is_array($row)) {
|
|
$result[] = $this->normalizePaymentMethod($row);
|
|
}
|
|
}
|
|
|
|
return $result;
|
|
}
|
|
|
|
/**
|
|
* Metody platnosci dla danego transportu — z Redis cache (frontend).
|
|
*
|
|
* @return array<int, array<string, mixed>>
|
|
*/
|
|
public function paymentMethodsByTransport(int $transportMethodId): array
|
|
{
|
|
$cacheHandler = new \Shared\Cache\CacheHandler();
|
|
$cacheKey = 'payment_methods_by_transport' . $transportMethodId;
|
|
$cached = $cacheHandler->get($cacheKey);
|
|
|
|
if ($cached) {
|
|
return unserialize($cached);
|
|
}
|
|
|
|
$result = $this->forTransport($transportMethodId);
|
|
$cacheHandler->set($cacheKey, $result);
|
|
|
|
return $result;
|
|
}
|
|
|
|
/**
|
|
* Pojedyncza aktywna metoda platnosci — z Redis cache (frontend).
|
|
*/
|
|
public function paymentMethodCached(int $paymentMethodId): ?array
|
|
{
|
|
$cacheHandler = new \Shared\Cache\CacheHandler();
|
|
$cacheKey = 'payment_method' . $paymentMethodId;
|
|
$cached = $cacheHandler->get($cacheKey);
|
|
|
|
if ($cached) {
|
|
return unserialize($cached);
|
|
}
|
|
|
|
$result = $this->findActiveById($paymentMethodId);
|
|
$cacheHandler->set($cacheKey, $result);
|
|
|
|
return $result;
|
|
}
|
|
|
|
/**
|
|
* Wszystkie aktywne metody platnosci — z Redis cache (frontend).
|
|
*
|
|
* @return array<int, array<string, mixed>>
|
|
*/
|
|
public function paymentMethodsCached(): array
|
|
{
|
|
$cacheHandler = new \Shared\Cache\CacheHandler();
|
|
$cacheKey = 'payment_methods';
|
|
$cached = $cacheHandler->get($cacheKey);
|
|
|
|
if ($cached) {
|
|
return unserialize($cached);
|
|
}
|
|
|
|
$result = $this->allActive();
|
|
$cacheHandler->set($cacheKey, $result);
|
|
|
|
return $result;
|
|
}
|
|
|
|
private function normalizePaymentMethod(array $row): array
|
|
{
|
|
$row['id'] = (int)($row['id'] ?? 0);
|
|
$row['name'] = trim((string)($row['name'] ?? ''));
|
|
$row['description'] = (string)($row['description'] ?? '');
|
|
$row['status'] = $this->toSwitchValue($row['status'] ?? 0);
|
|
$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;
|
|
}
|
|
|
|
/**
|
|
* @return int|string|null
|
|
*/
|
|
private function normalizeApiloPaymentTypeId($value)
|
|
{
|
|
if ($value === null || $value === false) {
|
|
return null;
|
|
}
|
|
|
|
$text = trim((string)$value);
|
|
if ($text === '') {
|
|
return null;
|
|
}
|
|
|
|
if (preg_match('/^-?\d+$/', $text) === 1) {
|
|
return (int)$text;
|
|
}
|
|
|
|
return $text;
|
|
}
|
|
|
|
/**
|
|
* @return float|null
|
|
*/
|
|
private function normalizeDecimalOrNull($value)
|
|
{
|
|
if ($value === null || $value === false) {
|
|
return null;
|
|
}
|
|
|
|
$text = trim((string)$value);
|
|
if ($text === '') {
|
|
return null;
|
|
}
|
|
|
|
return (float)$text;
|
|
}
|
|
|
|
private function toSwitchValue($value): int
|
|
{
|
|
if (is_bool($value)) {
|
|
return $value ? 1 : 0;
|
|
}
|
|
|
|
if (is_numeric($value)) {
|
|
return ((int)$value) === 1 ? 1 : 0;
|
|
}
|
|
|
|
if (is_string($value)) {
|
|
$normalized = strtolower(trim($value));
|
|
return in_array($normalized, ['1', 'on', 'true', 'yes'], true) ? 1 : 0;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
}
|