ver. 0.276: ShopOrder migration, Integrations cleanup, global admin search

This commit is contained in:
2026-02-15 16:37:57 +01:00
parent c0030c3cf3
commit 7cc0cadd6d
34 changed files with 2196 additions and 1063 deletions

View File

@@ -0,0 +1,207 @@
<?php
namespace Domain\Order;
class OrderAdminService
{
private OrderRepository $orders;
public function __construct(OrderRepository $orders)
{
$this->orders = $orders;
}
public function details(int $orderId): array
{
return $this->orders->findForAdmin($orderId);
}
public function statuses(): array
{
return $this->orders->orderStatuses();
}
/**
* @return array{items: array<int, array<string, mixed>>, total: int}
*/
public function listForAdmin(
array $filters,
string $sortColumn = 'date_order',
string $sortDir = 'DESC',
int $page = 1,
int $perPage = 15
): array {
return $this->orders->listForAdmin($filters, $sortColumn, $sortDir, $page, $perPage);
}
public function nextOrderId(int $orderId): ?int
{
return $this->orders->nextOrderId($orderId);
}
public function prevOrderId(int $orderId): ?int
{
return $this->orders->prevOrderId($orderId);
}
public function saveNotes(int $orderId, string $notes): bool
{
return $this->orders->saveNotes($orderId, $notes);
}
public function saveOrderByAdmin(array $input): bool
{
$saved = $this->orders->saveOrderByAdmin(
(int)($input['order_id'] ?? 0),
(string)($input['client_name'] ?? ''),
(string)($input['client_surname'] ?? ''),
(string)($input['client_street'] ?? ''),
(string)($input['client_postal_code'] ?? ''),
(string)($input['client_city'] ?? ''),
(string)($input['client_email'] ?? ''),
(string)($input['firm_name'] ?? ''),
(string)($input['firm_street'] ?? ''),
(string)($input['firm_postal_code'] ?? ''),
(string)($input['firm_city'] ?? ''),
(string)($input['firm_nip'] ?? ''),
(int)($input['transport_id'] ?? 0),
(string)($input['inpost_paczkomat'] ?? ''),
(int)($input['payment_method_id'] ?? 0)
);
if ($saved && isset($GLOBALS['user']['id'])) {
\Log::save_log('Zamówienie zmienione przez administratora | ID: ' . (int)($input['order_id'] ?? 0), (int)$GLOBALS['user']['id']);
}
return $saved;
}
public function changeStatus(int $orderId, int $status, bool $sendEmail): array
{
$order = new \shop\Order($orderId);
$response = $order->update_status($status, $sendEmail ? 1 : 0);
return is_array($response) ? $response : ['result' => false];
}
public function resendConfirmationEmail(int $orderId): bool
{
$order = new \shop\Order($orderId);
return (bool)$order->order_resend_confirmation_email();
}
public function setOrderAsUnpaid(int $orderId): bool
{
$order = new \shop\Order($orderId);
return (bool)$order->set_as_unpaid();
}
public function setOrderAsPaid(int $orderId, bool $sendMail): bool
{
$order = new \shop\Order($orderId);
if (!$order->set_as_paid()) {
return false;
}
$order->update_status(4, $sendMail ? 1 : 0);
return true;
}
public function sendOrderToApilo(int $orderId): bool
{
global $mdb;
if ($orderId <= 0) {
return false;
}
$order = $this->orders->findForAdmin($orderId);
if (empty($order) || empty($order['apilo_order_id'])) {
return false;
}
$integrationsRepository = new \Domain\Integrations\IntegrationsRepository( $mdb );
$accessToken = $integrationsRepository -> apiloGetAccessToken();
if (!$accessToken) {
return false;
}
$newStatus = 8;
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://projectpro.apilo.com/rest/api/orders/' . $order['apilo_order_id'] . '/status/');
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PUT');
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode([
'id' => (int)$order['apilo_order_id'],
'status' => (int)\front\factory\ShopStatuses::get_apilo_status_id($newStatus),
]));
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Authorization: Bearer ' . $accessToken,
'Accept: application/json',
'Content-Type: application/json',
]);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$apiloResultRaw = curl_exec($ch);
$apiloResult = json_decode((string)$apiloResultRaw, true);
if (!is_array($apiloResult) || (int)($apiloResult['updates'] ?? 0) !== 1) {
curl_close($ch);
return false;
}
$query = "SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 'pp_shop_orders' AND COLUMN_NAME != 'id'";
$columns = $mdb->query($query)->fetchAll(\PDO::FETCH_COLUMN);
$columnsList = implode(', ', $columns);
$mdb->query('INSERT INTO pp_shop_orders (' . $columnsList . ') SELECT ' . $columnsList . ' FROM pp_shop_orders pso WHERE pso.id = ' . $orderId);
$newOrderId = (int)$mdb->id();
$query = "SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 'pp_shop_order_products' AND COLUMN_NAME != 'id' AND COLUMN_NAME != 'order_id'";
$columns = $mdb->query($query)->fetchAll(\PDO::FETCH_COLUMN);
$columnsList = implode(', ', $columns);
$mdb->query('INSERT INTO pp_shop_order_products (order_id, ' . $columnsList . ') SELECT ' . $newOrderId . ', ' . $columnsList . ' FROM pp_shop_order_products psop WHERE psop.order_id = ' . $orderId);
$query = "SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 'pp_shop_order_statuses' AND COLUMN_NAME != 'id' AND COLUMN_NAME != 'order_id'";
$columns = $mdb->query($query)->fetchAll(\PDO::FETCH_COLUMN);
$columnsList = implode(', ', $columns);
$mdb->query('INSERT INTO pp_shop_order_statuses (order_id, ' . $columnsList . ') SELECT ' . $newOrderId . ', ' . $columnsList . ' FROM pp_shop_order_statuses psos WHERE psos.order_id = ' . $orderId);
$mdb->delete('pp_shop_orders', ['id' => $orderId]);
$mdb->delete('pp_shop_order_products', ['order_id' => $orderId]);
$mdb->delete('pp_shop_order_statuses', ['order_id' => $orderId]);
$mdb->update('pp_shop_orders', ['apilo_order_id' => null], ['id' => $newOrderId]);
curl_close($ch);
return true;
}
public function toggleTrustmateSend(int $orderId): array
{
$newValue = $this->orders->toggleTrustmateSend($orderId);
if ($newValue === null) {
return [
'result' => false,
];
}
return [
'result' => true,
'trustmate_send' => $newValue,
];
}
public function deleteOrder(int $orderId): bool
{
$deleted = $this->orders->deleteOrder($orderId);
if ($deleted && isset($GLOBALS['user']['id'])) {
\Log::save_log('Usunięcie zamówienia | ID: ' . $orderId, (int)$GLOBALS['user']['id']);
}
return $deleted;
}
}

View File

@@ -0,0 +1,472 @@
<?php
namespace Domain\Order;
class OrderRepository
{
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 = 'date_order',
string $sortDir = 'DESC',
int $page = 1,
int $perPage = 15
): array {
$allowedSortColumns = [
'id' => 'q1.id',
'number' => 'q1.number',
'date_order' => 'q1.date_order',
'status' => 'q1.status',
'summary' => 'q1.summary',
'client' => 'q1.client',
'order_email' => 'q1.order_email',
'client_phone' => 'q1.client_phone',
'transport' => 'q1.transport',
'payment_method' => 'q1.payment_method',
'total_orders' => 'shop_order.total_orders',
'paid' => 'q1.paid',
];
$sortSql = $allowedSortColumns[$sortColumn] ?? 'q1.date_order';
$sortDir = strtoupper(trim($sortDir)) === 'ASC' ? 'ASC' : 'DESC';
$page = max(1, $page);
$perPage = min(self::MAX_PER_PAGE, max(1, $perPage));
$offset = ($page - 1) * $perPage;
$where = [];
$params = [];
$number = $this->normalizeTextFilter($filters['number'] ?? '');
if ($number !== '') {
$where[] = 'q1.number LIKE :number';
$params[':number'] = '%' . $number . '%';
}
$dateFrom = $this->normalizeDateFilter($filters['date_from'] ?? '');
if ($dateFrom !== null) {
$where[] = 'q1.date_order >= :date_from';
$params[':date_from'] = $dateFrom . ' 00:00:00';
}
$dateTo = $this->normalizeDateFilter($filters['date_to'] ?? '');
if ($dateTo !== null) {
$where[] = 'q1.date_order <= :date_to';
$params[':date_to'] = $dateTo . ' 23:59:59';
}
$status = trim((string)($filters['status'] ?? ''));
if ($status !== '' && is_numeric($status)) {
$where[] = 'q1.status = :status';
$params[':status'] = (int)$status;
}
$client = $this->normalizeTextFilter($filters['client'] ?? '');
if ($client !== '') {
$where[] = 'q1.client LIKE :client';
$params[':client'] = '%' . $client . '%';
}
$address = $this->normalizeTextFilter($filters['address'] ?? '');
if ($address !== '') {
$where[] = 'q1.address LIKE :address';
$params[':address'] = '%' . $address . '%';
}
$email = $this->normalizeTextFilter($filters['order_email'] ?? '');
if ($email !== '') {
$where[] = 'q1.order_email LIKE :order_email';
$params[':order_email'] = '%' . $email . '%';
}
$phone = $this->normalizeTextFilter($filters['client_phone'] ?? '');
if ($phone !== '') {
$where[] = 'q1.client_phone LIKE :client_phone';
$params[':client_phone'] = '%' . $phone . '%';
}
$transport = $this->normalizeTextFilter($filters['transport'] ?? '');
if ($transport !== '') {
$where[] = 'q1.transport LIKE :transport';
$params[':transport'] = '%' . $transport . '%';
}
$payment = $this->normalizeTextFilter($filters['payment_method'] ?? '');
if ($payment !== '') {
$where[] = 'q1.payment_method LIKE :payment_method';
$params[':payment_method'] = '%' . $payment . '%';
}
$whereSql = '';
if (!empty($where)) {
$whereSql = ' WHERE ' . implode(' AND ', $where);
}
$baseSql = "
FROM (
SELECT
id,
number,
date_order,
CONCAT(client_name, ' ', client_surname) AS client,
client_email AS order_email,
CONCAT(client_street, ', ', client_postal_code, ' ', client_city) AS address,
status,
client_phone,
transport,
payment_method,
summary,
paid
FROM pp_shop_orders AS pso
) AS q1
LEFT JOIN (
SELECT
client_email,
COUNT(*) AS total_orders
FROM pp_shop_orders
WHERE client_name IS NOT NULL AND client_surname IS NOT NULL AND client_email IS NOT NULL
GROUP BY client_email
) AS shop_order ON q1.order_email = shop_order.client_email
";
$sqlCount = 'SELECT COUNT(0) ' . $baseSql . $whereSql;
$stmtCount = $this->db->query($sqlCount, $params);
$countRows = $stmtCount ? $stmtCount->fetchAll() : [];
$total = 0;
if (is_array($countRows) && isset($countRows[0]) && is_array($countRows[0])) {
$firstRow = $countRows[0];
$firstValue = reset($firstRow);
$total = $firstValue !== false ? (int)$firstValue : 0;
}
$sql = '
SELECT
q1.*,
COALESCE(shop_order.total_orders, 0) AS total_orders
'
. $baseSql
. $whereSql
. ' ORDER BY ' . $sortSql . ' ' . $sortDir . ', q1.id DESC'
. ' LIMIT ' . $perPage . ' OFFSET ' . $offset;
$stmt = $this->db->query($sql, $params);
if (!$stmt) {
return [
'items' => [],
'total' => $total,
];
}
$items = $stmt ? $stmt->fetchAll() : [];
if (!is_array($items)) {
$items = [];
}
foreach ($items as &$item) {
$item['id'] = (int)($item['id'] ?? 0);
$item['status'] = (int)($item['status'] ?? 0);
$item['paid'] = (int)($item['paid'] ?? 0);
$item['summary'] = (float)($item['summary'] ?? 0);
$item['total_orders'] = (int)($item['total_orders'] ?? 0);
$item['number'] = (string)($item['number'] ?? '');
$item['date_order'] = (string)($item['date_order'] ?? '');
$item['client'] = trim((string)($item['client'] ?? ''));
$item['order_email'] = (string)($item['order_email'] ?? '');
$item['address'] = trim((string)($item['address'] ?? ''));
$item['client_phone'] = (string)($item['client_phone'] ?? '');
$item['transport'] = (string)($item['transport'] ?? '');
$item['payment_method'] = (string)($item['payment_method'] ?? '');
}
unset($item);
return [
'items' => $items,
'total' => $total,
];
}
public function findForAdmin(int $orderId): array
{
if ($orderId <= 0) {
return [];
}
$order = $this->db->get('pp_shop_orders', '*', ['id' => $orderId]);
if (!is_array($order)) {
return [];
}
$order['id'] = (int)($order['id'] ?? 0);
$order['status'] = (int)($order['status'] ?? 0);
$order['paid'] = (int)($order['paid'] ?? 0);
$order['summary'] = (float)($order['summary'] ?? 0);
$order['transport_cost'] = (float)($order['transport_cost'] ?? 0);
$order['products'] = $this->orderProducts($orderId);
$order['statuses'] = $this->orderStatusHistory($orderId);
return $order;
}
public function orderProducts(int $orderId): array
{
if ($orderId <= 0) {
return [];
}
$rows = $this->db->select('pp_shop_order_products', '*', [
'order_id' => $orderId,
]);
return is_array($rows) ? $rows : [];
}
public function orderStatusHistory(int $orderId): array
{
if ($orderId <= 0) {
return [];
}
$rows = $this->db->select('pp_shop_order_statuses', '*', [
'order_id' => $orderId,
'ORDER' => ['id' => 'DESC'],
]);
return is_array($rows) ? $rows : [];
}
public function orderStatuses(): array
{
$rows = $this->db->select('pp_shop_statuses', ['id', 'status'], [
'ORDER' => ['o' => 'ASC'],
]);
if (!is_array($rows)) {
return [];
}
$result = [];
foreach ($rows as $row) {
$id = (int)($row['id'] ?? 0);
if ($id < 0) {
continue;
}
$result[$id] = (string)($row['status'] ?? '');
}
return $result;
}
public function nextOrderId(int $orderId): ?int
{
if ($orderId <= 0) {
return null;
}
$next = $this->db->get('pp_shop_orders', 'id', [
'id[>]' => $orderId,
'ORDER' => ['id' => 'ASC'],
'LIMIT' => 1,
]);
if (!$next) {
return null;
}
return (int)$next;
}
public function prevOrderId(int $orderId): ?int
{
if ($orderId <= 0) {
return null;
}
$prev = $this->db->get('pp_shop_orders', 'id', [
'id[<]' => $orderId,
'ORDER' => ['id' => 'DESC'],
'LIMIT' => 1,
]);
if (!$prev) {
return null;
}
return (int)$prev;
}
public function saveNotes(int $orderId, string $notes): bool
{
if ($orderId <= 0) {
return false;
}
$this->db->update('pp_shop_orders', ['notes' => $notes], ['id' => $orderId]);
return true;
}
public function saveOrderByAdmin(
int $orderId,
string $clientName,
string $clientSurname,
string $clientStreet,
string $clientPostalCode,
string $clientCity,
string $clientEmail,
string $firmName,
string $firmStreet,
string $firmPostalCode,
string $firmCity,
string $firmNip,
int $transportId,
string $inpostPaczkomat,
int $paymentMethodId
): bool {
if ($orderId <= 0) {
return false;
}
$transportName = $this->db->get('pp_shop_transports', 'name_visible', ['id' => $transportId]);
$transportCost = $this->db->get('pp_shop_transports', 'cost', ['id' => $transportId]);
$transportDescription = $this->db->get('pp_shop_transports', 'description', ['id' => $transportId]);
$paymentMethodName = $this->db->get('pp_shop_payment_methods', 'name', ['id' => $paymentMethodId]);
$this->db->update('pp_shop_orders', [
'client_name' => $clientName,
'client_surname' => $clientSurname,
'client_street' => $clientStreet,
'client_postal_code' => $clientPostalCode,
'client_city' => $clientCity,
'client_email' => $clientEmail,
'firm_name' => $this->nullableString($firmName),
'firm_street' => $this->nullableString($firmStreet),
'firm_postal_code' => $this->nullableString($firmPostalCode),
'firm_city' => $this->nullableString($firmCity),
'firm_nip' => $this->nullableString($firmNip),
'transport_id' => $transportId,
'transport' => $transportName ?: null,
'transport_cost' => $transportCost !== null ? $transportCost : 0,
'transport_description' => $transportDescription ?: null,
'inpost_paczkomat' => $inpostPaczkomat,
'payment_method_id' => $paymentMethodId,
'payment_method' => $paymentMethodName ?: null,
], [
'id' => $orderId,
]);
$this->db->update('pp_shop_orders', [
'summary' => $this->calculateOrderSummaryByAdmin($orderId),
], [
'id' => $orderId,
]);
return true;
}
public function calculateOrderSummaryByAdmin(int $orderId): float
{
if ($orderId <= 0) {
return 0.0;
}
$rows = $this->db->select('pp_shop_order_products', [
'price_brutto',
'price_brutto_promo',
'quantity',
], [
'order_id' => $orderId,
]);
$summary = 0.0;
if (is_array($rows)) {
foreach ($rows as $row) {
$quantity = (float)($row['quantity'] ?? 0);
$pricePromo = (float)($row['price_brutto_promo'] ?? 0);
$price = (float)($row['price_brutto'] ?? 0);
if ($pricePromo > 0) {
$summary += $pricePromo * $quantity;
} else {
$summary += $price * $quantity;
}
}
}
$transportCost = (float)$this->db->get('pp_shop_orders', 'transport_cost', ['id' => $orderId]);
return (float)$summary + $transportCost;
}
public function toggleTrustmateSend(int $orderId): ?int
{
if ($orderId <= 0) {
return null;
}
$order = $this->db->get('pp_shop_orders', ['trustmate_send'], ['id' => $orderId]);
if (!is_array($order)) {
return null;
}
$newValue = ((int)($order['trustmate_send'] ?? 0) === 1) ? 0 : 1;
$this->db->update('pp_shop_orders', ['trustmate_send' => $newValue], ['id' => $orderId]);
return $newValue;
}
public function deleteOrder(int $orderId): bool
{
if ($orderId <= 0) {
return false;
}
$this->db->delete('pp_shop_orders', ['id' => $orderId]);
return true;
}
private function nullableString(string $value): ?string
{
$value = trim($value);
return $value === '' ? null : $value;
}
private function normalizeTextFilter($value): string
{
$value = trim((string)$value);
if ($value === '') {
return '';
}
if (strlen($value) > 255) {
return substr($value, 0, 255);
}
return $value;
}
private function normalizeDateFilter($value): ?string
{
$value = trim((string)$value);
if ($value === '') {
return null;
}
if (!preg_match('/^\d{4}-\d{2}-\d{2}$/', $value)) {
return null;
}
return $value;
}
}

View File

@@ -68,6 +68,159 @@ class SettingsController
exit;
}
/**
* Globalna wyszukiwarka admin (produkty + zamowienia) - AJAX.
*/
public function globalSearchAjax(): void
{
global $mdb;
$phrase = trim((string)\S::get('q'));
if ($phrase === '' || mb_strlen($phrase) < 2) {
echo json_encode([
'status' => 'ok',
'items' => [],
]);
exit;
}
$phrase = mb_substr($phrase, 0, 120);
$phraseNormalized = preg_replace('/\s+/', ' ', $phrase);
$phraseNormalized = trim((string)$phraseNormalized);
$like = '%' . $phrase . '%';
$likeNormalized = '%' . $phraseNormalized . '%';
$items = [];
$defaultLang = (string)\front\factory\Languages::default_language();
try {
$productStmt = $mdb->query(
'SELECT '
. 'p.id, p.ean, p.sku, p.parent_id, psl.name '
. 'FROM pp_shop_products AS p '
. 'LEFT JOIN pp_shop_products_langs AS psl ON psl.product_id = p.id AND psl.lang_id = :lang_id '
. 'WHERE '
. '(p.ean LIKE :q1 OR p.sku LIKE :q2 OR psl.name LIKE :q3) '
. 'AND p.archive != 1 '
. 'ORDER BY p.id DESC '
. 'LIMIT 15',
[
':lang_id' => $defaultLang,
':q1' => $like,
':q2' => $like,
':q3' => $like,
]
);
} catch (\Throwable $e) {
$productStmt = false;
}
$productRows = $productStmt ? $productStmt->fetchAll() : [];
if (is_array($productRows)) {
foreach ($productRows as $row) {
$productId = (int)($row['id'] ?? 0);
if ($productId <= 0) {
continue;
}
$name = trim((string)($row['name'] ?? ''));
if ($name === '') {
$name = 'Produkt #' . $productId;
}
$meta = [];
$sku = trim((string)($row['sku'] ?? ''));
$ean = trim((string)($row['ean'] ?? ''));
if ($sku !== '') {
$meta[] = 'SKU: ' . $sku;
}
if ($ean !== '') {
$meta[] = 'EAN: ' . $ean;
}
$items[] = [
'type' => 'product',
'title' => $name,
'subtitle' => implode(' | ', $meta),
'url' => '/admin/shop_product/product_edit/id=' . $productId,
];
}
}
try {
$orderStmt = $mdb->query(
'SELECT '
. 'id, number, client_name, client_surname, client_email, client_phone '
. 'FROM pp_shop_orders '
. 'WHERE '
. '('
. 'number LIKE :q1 '
. 'OR client_email LIKE :q2 '
. 'OR client_name LIKE :q3 '
. 'OR client_surname LIKE :q4 '
. 'OR client_phone LIKE :q5 '
. "OR CONCAT_WS(' ', TRIM(client_name), TRIM(client_surname)) LIKE :q6 "
. "OR CONCAT_WS(' ', TRIM(client_surname), TRIM(client_name)) LIKE :q7 "
. ') '
. 'ORDER BY id DESC '
. 'LIMIT 15',
[
':q1' => $like,
':q2' => $like,
':q3' => $like,
':q4' => $like,
':q5' => $like,
':q6' => $likeNormalized,
':q7' => $likeNormalized,
]
);
} catch (\Throwable $e) {
$orderStmt = false;
}
$orderRows = $orderStmt ? $orderStmt->fetchAll() : [];
if (is_array($orderRows)) {
foreach ($orderRows as $row) {
$orderId = (int)($row['id'] ?? 0);
if ($orderId <= 0) {
continue;
}
$orderNumber = trim((string)($row['number'] ?? ''));
$clientName = trim((string)($row['client_name'] ?? ''));
$clientSurname = trim((string)($row['client_surname'] ?? ''));
$clientEmail = trim((string)($row['client_email'] ?? ''));
$clientPhone = trim((string)($row['client_phone'] ?? ''));
$title = $orderNumber !== '' ? 'Zamówienie ' . $orderNumber : 'Zamówienie #' . $orderId;
$subtitleParts = [];
$fullName = trim($clientName . ' ' . $clientSurname);
if ($fullName !== '') {
$subtitleParts[] = $fullName;
}
if ($clientEmail !== '') {
$subtitleParts[] = $clientEmail;
}
if ($clientPhone !== '') {
$subtitleParts[] = $clientPhone;
}
$items[] = [
'type' => 'order',
'title' => $title,
'subtitle' => implode(' | ', $subtitleParts),
'url' => '/admin/shop_order/order_details/order_id=' . $orderId,
];
}
}
echo json_encode([
'status' => 'ok',
'items' => array_slice($items, 0, 20),
]);
exit;
}
/**
* Zapis ustawien (AJAX).
*/

View File

@@ -0,0 +1,323 @@
<?php
namespace admin\Controllers;
use Domain\Order\OrderAdminService;
use admin\ViewModels\Common\PaginatedTableViewModel;
class ShopOrderController
{
private OrderAdminService $service;
public function __construct(OrderAdminService $service)
{
$this->service = $service;
}
public function list(): string
{
return $this->view_list();
}
public function view_list(): string
{
$sortableColumns = [
'number',
'date_order',
'status',
'summary',
'client',
'order_email',
'client_phone',
'transport',
'payment_method',
'total_orders',
'paid',
];
$statusOptions = ['' => '- status -'];
foreach ($this->service->statuses() as $statusId => $statusName) {
$statusOptions[(string)$statusId] = (string)$statusName;
}
$filterDefinitions = [
['key' => 'number', 'label' => 'Nr zamówienia', 'type' => 'text'],
['key' => 'date_from', 'label' => 'Data od', 'type' => 'date'],
['key' => 'date_to', 'label' => 'Data do', 'type' => 'date'],
['key' => 'status', 'label' => 'Status', 'type' => 'select', 'options' => $statusOptions],
['key' => 'client', 'label' => 'Klient', 'type' => 'text'],
['key' => 'address', 'label' => 'Adres', 'type' => 'text'],
['key' => 'order_email', 'label' => 'Email', 'type' => 'text'],
['key' => 'client_phone', 'label' => 'Telefon', 'type' => 'text'],
['key' => 'transport', 'label' => 'Dostawa', 'type' => 'text'],
['key' => 'payment_method', 'label' => 'Płatność', 'type' => 'text'],
];
$listRequest = \admin\Support\TableListRequestFactory::fromRequest(
$filterDefinitions,
$sortableColumns,
'date_order'
);
$result = $this->service->listForAdmin(
$listRequest['filters'],
$listRequest['sortColumn'],
$listRequest['sortDir'],
$listRequest['page'],
$listRequest['perPage']
);
$statusesMap = $this->service->statuses();
$rows = [];
$lp = ($listRequest['page'] - 1) * $listRequest['perPage'] + 1;
foreach ($result['items'] as $item) {
$orderId = (int)($item['id'] ?? 0);
$orderNumber = (string)($item['number'] ?? '');
$statusId = (int)($item['status'] ?? 0);
$statusLabel = (string)($statusesMap[$statusId] ?? ('Status #' . $statusId));
$rows[] = [
'lp' => $lp++ . '.',
'date_order' => $this->formatDateTime((string)($item['date_order'] ?? '')),
'number' => '<a href="/admin/shop_order/order_details/order_id=' . $orderId . '">' . htmlspecialchars($orderNumber, ENT_QUOTES, 'UTF-8') . '</a>',
'paid' => ((int)($item['paid'] ?? 0) === 1)
? '<i class="fa fa-check text-success"></i>'
: '<i class="fa fa-times text-dark"></i>',
'status' => htmlspecialchars($statusLabel, ENT_QUOTES, 'UTF-8'),
'summary' => number_format((float)($item['summary'] ?? 0), 2, '.', ' ') . ' zł',
'client' => htmlspecialchars((string)($item['client'] ?? ''), ENT_QUOTES, 'UTF-8') . ' | zamówienia: <strong>' . (int)($item['total_orders'] ?? 0) . '</strong>',
'address' => (string)($item['address'] ?? ''),
'order_email' => (string)($item['order_email'] ?? ''),
'client_phone' => (string)($item['client_phone'] ?? ''),
'transport' => (string)($item['transport'] ?? ''),
'payment_method' => (string)($item['payment_method'] ?? ''),
'_actions' => [
[
'label' => 'Szczegóły',
'url' => '/admin/shop_order/order_details/order_id=' . $orderId,
'class' => 'btn btn-xs btn-primary',
],
[
'label' => 'Usuń',
'url' => '/admin/shop_order/order_delete/id=' . $orderId,
'class' => 'btn btn-xs btn-danger',
'confirm' => 'Na pewno chcesz usunąć wybrane zamówienie?',
'confirm_ok' => 'Usuń',
'confirm_cancel' => 'Anuluj',
],
],
];
}
$total = (int)$result['total'];
$totalPages = max(1, (int)ceil($total / $listRequest['perPage']));
$viewModel = new PaginatedTableViewModel(
[
['key' => 'lp', 'label' => 'Lp.', 'class' => 'text-center', 'sortable' => false],
['key' => 'date_order', 'sort_key' => 'date_order', 'label' => 'Data dodania', 'class' => 'text-center', 'sortable' => true],
['key' => 'number', 'sort_key' => 'number', 'label' => 'Nr zamówienia', 'class' => 'text-center', 'sortable' => true, 'raw' => true],
['key' => 'paid', 'sort_key' => 'paid', 'label' => '', 'class' => 'text-center', 'sortable' => true, 'raw' => true],
['key' => 'status', 'sort_key' => 'status', 'label' => 'Status', 'sortable' => true, 'raw' => true],
['key' => 'summary', 'sort_key' => 'summary', 'label' => 'Wartość', 'class' => 'text-right align-middle', 'sortable' => true],
['key' => 'client', 'sort_key' => 'client', 'label' => 'Klient', 'sortable' => true, 'raw' => true],
['key' => 'address', 'label' => 'Adres', 'sortable' => false],
['key' => 'order_email', 'sort_key' => 'order_email', 'label' => 'Email', 'sortable' => true],
['key' => 'client_phone', 'sort_key' => 'client_phone', 'label' => 'Telefon', 'sortable' => true],
['key' => 'transport', 'sort_key' => 'transport', 'label' => 'Dostawa', 'sortable' => true],
['key' => 'payment_method', 'sort_key' => 'payment_method', 'label' => 'Płatność', 'sortable' => true],
],
$rows,
$listRequest['viewFilters'],
[
'column' => $listRequest['sortColumn'],
'dir' => $listRequest['sortDir'],
],
[
'page' => $listRequest['page'],
'per_page' => $listRequest['perPage'],
'total' => $total,
'total_pages' => $totalPages,
],
array_merge($listRequest['queryFilters'], [
'sort' => $listRequest['sortColumn'],
'dir' => $listRequest['sortDir'],
'per_page' => $listRequest['perPage'],
]),
$listRequest['perPageOptions'],
$sortableColumns,
'/admin/shop_order/list/',
'Brak danych w tabeli.'
);
return \Tpl::view('shop-order/orders-list', [
'viewModel' => $viewModel,
]);
}
public function details(): string
{
return $this->order_details();
}
public function order_details(): string
{
$orderId = (int)\S::get('order_id');
$order = $this->service->details($orderId);
$coupon = null;
if (!empty($order) && !empty($order['coupon_id'])) {
$coupon = new \shop\Coupon((int)$order['coupon_id']);
}
return \Tpl::view('shop-order/order-details', [
'order' => $order,
'coupon' => $coupon,
'order_statuses' => $this->service->statuses(),
'next_order_id' => $this->service->nextOrderId($orderId),
'prev_order_id' => $this->service->prevOrderId($orderId),
]);
}
public function edit(): string
{
return $this->order_edit();
}
public function order_edit(): string
{
$orderId = (int)\S::get('order_id');
return \Tpl::view('shop-order/order-edit', [
'order' => $this->service->details($orderId),
'order_statuses' => $this->service->statuses(),
'transport' => \shop\Transport::transport_list(),
'payment_methods' => \shop\PaymentMethod::method_list(),
]);
}
public function save(): void
{
$this->order_save();
}
public function order_save(): void
{
$saved = $this->service->saveOrderByAdmin([
'order_id' => (int)\S::get('order_id'),
'client_name' => (string)\S::get('client_name'),
'client_surname' => (string)\S::get('client_surname'),
'client_street' => (string)\S::get('client_street'),
'client_postal_code' => (string)\S::get('client_postal_code'),
'client_city' => (string)\S::get('client_city'),
'client_email' => (string)\S::get('client_email'),
'firm_name' => (string)\S::get('firm_name'),
'firm_street' => (string)\S::get('firm_street'),
'firm_postal_code' => (string)\S::get('firm_postal_code'),
'firm_city' => (string)\S::get('firm_city'),
'firm_nip' => (string)\S::get('firm_nip'),
'transport_id' => (int)\S::get('transport_id'),
'inpost_paczkomat' => (string)\S::get('inpost_paczkomat'),
'payment_method_id' => (int)\S::get('payment_method_id'),
]);
if ($saved) {
\S::alert('Zamówienie zostało zapisane.');
}
header('Location: /admin/shop_order/order_details/order_id=' . (int)\S::get('order_id'));
exit;
}
public function notes_save(): void
{
$this->service->saveNotes((int)\S::get('order_id'), (string)\S::get('notes'));
}
public function order_status_change(): void
{
$response = $this->service->changeStatus(
(int)\S::get('order_id'),
(int)\S::get('status'),
(string)\S::get('email') === 'true'
);
echo json_encode($response);
exit;
}
public function order_resend_confirmation_email(): void
{
$response = $this->service->resendConfirmationEmail((int)\S::get('order_id'));
echo json_encode(['result' => $response]);
exit;
}
public function set_order_as_unpaid(): void
{
$orderId = (int)\S::get('order_id');
$this->service->setOrderAsUnpaid($orderId);
header('Location: /admin/shop_order/order_details/order_id=' . $orderId);
exit;
}
public function set_order_as_paid(): void
{
$orderId = (int)\S::get('order_id');
$this->service->setOrderAsPaid($orderId, (int)\S::get('send_mail') === 1);
header('Location: /admin/shop_order/order_details/order_id=' . $orderId);
exit;
}
public function send_order_to_apilo(): void
{
$orderId = (int)\S::get('order_id');
if ($this->service->sendOrderToApilo($orderId)) {
\S::alert('Zamówienie zostanie wysłane ponownie do apilo.com');
} else {
\S::alert('Wystąpił błąd podczas wysyłania zamówienia do apilo.com');
}
header('Location: /admin/shop_order/order_details/order_id=' . $orderId);
exit;
}
public function toggle_trustmate_send(): void
{
echo json_encode($this->service->toggleTrustmateSend((int)\S::get('order_id')));
exit;
}
public function delete(): void
{
$this->order_delete();
}
public function order_delete(): void
{
if ($this->service->deleteOrder((int)\S::get('id'))) {
\S::alert('Zamówienie zostało usunięte');
}
header('Location: /admin/shop_order/list/');
exit;
}
private function formatDateTime(string $value): string
{
if ($value === '') {
return '';
}
$ts = strtotime($value);
if ($ts === false) {
return $value;
}
return date('Y-m-d H:i', $ts);
}
}

View File

@@ -2,6 +2,7 @@
namespace admin\Controllers;
use Domain\PaymentMethod\PaymentMethodRepository;
use Domain\Integrations\IntegrationsRepository;
use admin\ViewModels\Common\PaginatedTableViewModel;
use admin\ViewModels\Forms\FormAction;
use admin\ViewModels\Forms\FormEditViewModel;
@@ -240,7 +241,10 @@ class ShopPaymentMethodController
private function getApiloPaymentTypes(): array
{
$rawSetting = \admin\factory\Integrations::apilo_settings('payment-types-list');
global $mdb;
$integrationsRepository = new IntegrationsRepository( $mdb );
$rawSetting = $integrationsRepository -> getSetting( 'apilo', 'payment-types-list' );
$raw = null;
if (is_array($rawSetting)) {

View File

@@ -2,6 +2,7 @@
namespace admin\Controllers;
use Domain\ShopStatus\ShopStatusRepository;
use Domain\Integrations\IntegrationsRepository;
use admin\ViewModels\Common\PaginatedTableViewModel;
use admin\ViewModels\Forms\FormAction;
use admin\ViewModels\Forms\FormEditViewModel;
@@ -246,8 +247,12 @@ class ShopStatusesController
private function getApiloStatusList(): array
{
global $mdb;
$integrationsRepository = new IntegrationsRepository( $mdb );
$list = [];
$raw = @unserialize(\admin\factory\Integrations::apilo_settings('status-types-list'));
$raw = @unserialize( $integrationsRepository -> getSetting( 'apilo', 'status-types-list' ) );
if (is_array($raw)) {
foreach ($raw as $apiloStatus) {
if (isset($apiloStatus['id'], $apiloStatus['name'])) {

View File

@@ -3,6 +3,7 @@ namespace admin\Controllers;
use Domain\Transport\TransportRepository;
use Domain\PaymentMethod\PaymentMethodRepository;
use Domain\Integrations\IntegrationsRepository;
use admin\ViewModels\Common\PaginatedTableViewModel;
use admin\ViewModels\Forms\FormAction;
use admin\ViewModels\Forms\FormEditViewModel;
@@ -314,7 +315,10 @@ class ShopTransportController
private function getApiloCarrierAccounts(): array
{
$rawSetting = \admin\factory\Integrations::apilo_settings('carrier-account-list');
global $mdb;
$integrationsRepository = new IntegrationsRepository( $mdb );
$rawSetting = $integrationsRepository -> getSetting( 'apilo', 'carrier-account-list' );
$raw = null;
if (is_array($rawSetting)) {

View File

@@ -399,6 +399,15 @@ class Site
new \Domain\Client\ClientRepository( $mdb )
);
},
'ShopOrder' => function() {
global $mdb;
return new \admin\Controllers\ShopOrderController(
new \Domain\Order\OrderAdminService(
new \Domain\Order\OrderRepository( $mdb )
)
);
},
];
return self::$newControllers;

View File

@@ -4,9 +4,13 @@ class Dashboard
{
static public function main_view()
{
global $mdb;
$statusesRepository = new \Domain\ShopStatus\ShopStatusRepository( $mdb );
return \Tpl::view( 'dashboard/main-view', [
'last_orders' => \shop\Dashboard::last_orders(),
'order_statuses' => \shop\Order::order_statuses(),
'order_statuses' => $statusesRepository -> allStatuses(),
'sales' => \shop\Dashboard::last_24_months_sales(),
'best_sales_products' => \shop\Dashboard::best_sales_products(),
'most_view_products' => \shop\Dashboard::most_view_products(),

View File

@@ -1,133 +0,0 @@
<?php
namespace admin\controls;
class ShopOrder
{
static public function send_order_to_apilo()
{
$order_id = \S::get( 'order_id' );
if ( \admin\factory\ShopOrder::send_order_to_apilo( $order_id ) ) {
\S::alert( 'Zamówienie zostanie wysłane ponownie do apilo.com' );
} else {
\S::alert( 'Wystąpił błąd podczas wysyłania zamówienia do apilo.com' );
}
header( 'Location: /admin/shop_order/order_details/order_id=' . $order_id );
exit;
}
static public function order_resend_confirmation_email()
{
$order = new \shop\Order( (int)\S::get( 'order_id' ) );
$response = $order -> order_resend_confirmation_email();
echo json_encode( [ 'result' => $response ] );
exit;
}
static public function notes_save()
{
\shop\Order::notes_save( \S::get( 'order_id' ), \S::get( 'notes' ) );
}
static public function order_save()
{
if ( \shop\Order::order_save_by_admin(
\S::get( 'order_id' ), \S::get( 'client_name' ), \S::get( 'client_surname' ), \S::get( 'client_street' ), \S::get( 'client_postal_code' ), \S::get( 'client_city' ), \S::get( 'client_email' ), \S::get( 'firm_name' ), \S::get( 'firm_street' ), \S::get( 'firm_postal_code' ), \S::get( 'firm_city' ), \S::get( 'firm_nip' ), \S::get( 'transport_id' ), \S::get( 'inpost_paczkomat' ), \S::get( 'payment_method_id' )
) )
\S::alert( 'Zamówienie zostało zapisane.' );
header( 'Location: /admin/shop_order/order_details/order_id=' . \S::get( 'order_id' ) );
exit;
}
static public function order_edit()
{
return \Tpl::view( 'shop-order/order-edit', [
'order' => new \shop\Order( (int)\S::get( 'order_id' ) ),
'order_statuses' => \shop\Order::order_statuses(),
'transport' => \shop\Transport::transport_list(),
'payment_methods' => \shop\PaymentMethod::method_list()
] );
}
public static function order_details()
{
$order = new \shop\Order( (int)\S::get( 'order_id' ) );
$coupon = $order -> coupon_id ? new \shop\Coupon( $order -> coupon_id ) : null;
return \Tpl::view( 'shop-order/order-details', [
'order' => $order,
'coupon' => $coupon,
'order_statuses' => \shop\Order::order_statuses(),
'next_order_id' => \admin\factory\ShopOrder::next_order_id( (int)\S::get( 'order_id' ) ),
'prev_order_id' => \admin\factory\ShopOrder::prev_order_id( (int)\S::get( 'order_id' ) ),
] );
}
public static function view_list()
{
return \Tpl::view(
'shop-order/view-list'
);
}
public static function order_status_change()
{
global $mdb;
$order = new \shop\Order( (int)\S::get( 'order_id' ) );
$response = $order -> update_status( (int)\S::get( 'status' ), \S::get( 'email' ) == 'true' ? 1 : 0 );
echo json_encode( $response );
exit;
}
public static function order_delete()
{
global $user;
if ( \shop\Order::order_delete( (int)\S::get( 'id' ) ) )
{
\S::alert( 'Zamówienie zostało usunięte' );
\Log::save_log( 'Usunięcie zamówienia | ID: ' . (int)\S::get( 'id' ), $user['id'] );
}
header( 'Location: /admin/shop_order/view_list/' );
exit;
}
// set_order_as_unpaid
public static function set_order_as_unpaid()
{
$order = new \shop\Order( (int)\S::get( 'order_id' ) );
$order -> set_as_unpaid();
header( 'Location: /admin/shop_order/order_details/order_id=' . (int)\S::get( 'order_id' ) );
exit;
}
// set_order_as_paid
public static function set_order_as_paid()
{
$order = new \shop\Order( (int)\S::get( 'order_id' ) );
if ( $order -> set_as_paid() )
{
$order -> update_status( 4, (int)\S::get( 'send_mail' ) );
}
header( 'Location: /admin/shop_order/order_details/order_id=' . (int)\S::get( 'order_id' ) );
exit;
}
// toggle_trustmate_send
public static function toggle_trustmate_send()
{
global $mdb;
$order_id = (int)\S::get( 'order_id' );
$order = $mdb -> get( 'pp_shop_orders', [ 'trustmate_send' ], [ 'id' => $order_id ] );
$new_value = $order['trustmate_send'] ? 0 : 1;
$mdb -> update( 'pp_shop_orders', [ 'trustmate_send' => $new_value ], [ 'id' => $order_id ] );
echo json_encode( [ 'result' => true, 'trustmate_send' => $new_value ] );
exit;
}
}

View File

@@ -229,6 +229,10 @@ class ShopProduct
// ajax_load_products
static public function ajax_load_products() {
global $mdb;
$integrationsRepository = new \Domain\Integrations\IntegrationsRepository( $mdb );
$response = [ 'status' => 'error', 'msg' => 'Podczas ładowania produktów wystąpił błąd. Proszę spróbować ponownie.' ];
\S::set_session( 'products_list_current_page', \S::get( 'current_page' ) );
@@ -241,7 +245,7 @@ class ShopProduct
'html' => \Tpl::view( 'shop-product/products-list-table', [
'products' => $products['products'],
'current_page' => \S::get( 'current_page' ),
'apilo_enabled' => \admin\factory\Integrations::apilo_settings( 'enabled' ),
'apilo_enabled' => $integrationsRepository -> getSetting( 'apilo', 'enabled' ),
'show_xml_data' => \S::get_session( 'show_xml_data' )
] )
];
@@ -253,6 +257,10 @@ class ShopProduct
static public function view_list()
{
global $mdb;
$integrationsRepository = new \Domain\Integrations\IntegrationsRepository( $mdb );
$current_page = \S::get_session( 'products_list_current_page' );
if ( !$current_page ) {
@@ -276,9 +284,9 @@ class ShopProduct
'current_page' => $current_page,
'query_array' => $query_array,
'pagination_max' => ceil( \admin\factory\ShopProduct::count_product() / 10 ),
'apilo_enabled' => \admin\factory\Integrations::apilo_settings( 'enabled' ),
'apilo_enabled' => $integrationsRepository -> getSetting( 'apilo', 'enabled' ),
'show_xml_data' => \S::get_session( 'show_xml_data' ),
'shoppro_enabled' => \admin\factory\Integrations::shoppro_settings( 'enabled' )
'shoppro_enabled' => $integrationsRepository -> getSetting( 'shoppro', 'enabled' )
] );
}

View File

@@ -1,69 +0,0 @@
<?php
namespace admin\factory;
/**
* Fasada kompatybilnosci wstecznej.
* Deleguje do Domain\Integrations\IntegrationsRepository.
* Uzywane przez: cron.php, shop\Order, admin\Controllers\ShopStatusesController, admin\controls\ShopTransport, admin\controls\ShopProduct, admin\Controllers\ShopPaymentMethodController.
*/
class Integrations {
private static function repo(): \Domain\Integrations\IntegrationsRepository
{
global $mdb;
return new \Domain\Integrations\IntegrationsRepository( $mdb );
}
// ── Apilo settings ──────────────────────────────────────────
static public function apilo_settings( $name = '' )
{
$repo = self::repo();
return $name ? $repo->getSetting( 'apilo', $name ) : $repo->getSettings( 'apilo' );
}
static public function apilo_settings_save( $field_id, $value )
{
return self::repo()->saveSetting( 'apilo', $field_id, $value );
}
static public function apilo_get_access_token()
{
return self::repo()->apiloGetAccessToken();
}
static public function apilo_keepalive( int $refresh_lead_seconds = 300 )
{
return self::repo()->apiloKeepalive( $refresh_lead_seconds );
}
static public function apilo_authorization( $client_id, $client_secret, $authorization_code )
{
return self::repo()->apiloAuthorize( $client_id, $client_secret, $authorization_code );
}
// ── Apilo product linking ─────────────────────────────────────
static public function apilo_product_select_save( int $product_id, $apilo_product_id, $apilo_product_name )
{
return self::repo()->linkProduct( $product_id, $apilo_product_id, $apilo_product_name );
}
static public function apilo_product_select_delete( int $product_id )
{
return self::repo()->unlinkProduct( $product_id );
}
// ── ShopPRO settings ──────────────────────────────────────────
static public function shoppro_settings( $name = '' )
{
$repo = self::repo();
return $name ? $repo->getSetting( 'shoppro', $name ) : $repo->getSettings( 'shoppro' );
}
static public function shoppro_settings_save( $field_id, $value )
{
return self::repo()->saveSetting( 'shoppro', $field_id, $value );
}
}

View File

@@ -1,114 +0,0 @@
<?php
namespace admin\factory;
class ShopOrder
{
static public function send_order_to_apilo( int $order_id ) {
global $mdb;
// początek - anulowanie zamówienia w apilo
$apilo_settings = \admin\factory\Integrations::apilo_settings();
$new_status = 8; // zamówienie anulowwane
$order = \admin\factory\ShopOrder::order_details( $order_id );
if ( $order['apilo_order_id'] ) {
$access_token = \admin\factory\Integrations::apilo_get_access_token();
$ch = curl_init();
curl_setopt( $ch, CURLOPT_URL, "https://projectpro.apilo.com/rest/api/orders/" . $order['apilo_order_id'] . '/status/' );
curl_setopt( $ch, CURLOPT_POST, 1 );
curl_setopt( $ch, CURLOPT_CUSTOMREQUEST, "PUT");
curl_setopt( $ch, CURLOPT_POSTFIELDS, json_encode( [
'id' => $order['apilo_order_id'],
'status' => (int)\front\factory\ShopStatuses::get_apilo_status_id( $new_status )
] ) );
curl_setopt( $ch, CURLOPT_HTTPHEADER, [
"Authorization: Bearer " . $access_token,
"Accept: application/json",
"Content-Type: application/json"
] );
curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true);
$apilo_result = curl_exec( $ch );
$apilo_result = json_decode( $apilo_result, true );
if ( $apilo_result['updates'] == 1 ) {
// zmień ID zamówienia na największe ID zamówienia + 1, oraz usuń ID zamówienia z apilo
$new_order_id = $mdb -> max( 'pp_shop_orders', 'id' ) + 1;
// pobierz listę kolumn zamówienia
$query = "SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 'pp_shop_orders' AND COLUMN_NAME != 'id'";
$columns = $mdb -> query( $query ) -> fetchAll( \PDO::FETCH_COLUMN );
$columns_list = implode( ', ', $columns );
// kopiuj stare zamówienie do nowego ID
$mdb -> query( 'INSERT INTO pp_shop_orders (' . $columns_list . ') SELECT ' . $columns_list . ' FROM pp_shop_orders pso WHERE pso.id = ' . $order_id );
$new_order_id = $mdb -> id();
// pobierz listę kolumn produktów zamówienia
$query = "SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 'pp_shop_order_products' AND COLUMN_NAME != 'id' AND COLUMN_NAME != 'order_id'";
$columns = $mdb -> query( $query ) -> fetchAll( \PDO::FETCH_COLUMN );
$columns_list = implode( ', ', $columns );
// kopiuj produkty zamówienia do nowego zamówienia
$mdb -> query( 'INSERT INTO pp_shop_order_products (order_id, ' . $columns_list . ') SELECT ' . $new_order_id . ',' . $columns_list . ' FROM pp_shop_order_products psop WHERE psop.order_id = ' . $order_id );
// pobierz listę kolumn z tabeli pp_shop_order_statuses
$query = "SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 'pp_shop_order_statuses' AND COLUMN_NAME != 'id' AND COLUMN_NAME != 'order_id'";
$columns = $mdb -> query( $query ) -> fetchAll( \PDO::FETCH_COLUMN );
$columns_list = implode( ', ', $columns );
// kopiuj statusy zamówienia do nowego zamówienia
$mdb -> query( 'INSERT INTO pp_shop_order_statuses (order_id, ' . $columns_list . ') SELECT ' . $new_order_id . ',' . $columns_list . ' FROM pp_shop_order_statuses psos WHERE psos.order_id = ' . $order_id );
// usuń stare zamówienie
$mdb -> delete( 'pp_shop_orders', [ 'id' => $order_id ] );
$mdb -> delete( 'pp_shop_order_products', [ 'order_id' => $order_id ] );
$mdb -> delete( 'pp_shop_order_statuses', [ 'order_id' => $order_id ] );
// zmień wartość kolumny apilo_order_id na NULL
$mdb -> update( 'pp_shop_orders', [ 'apilo_order_id' => NULL ], [ 'id' => $new_order_id ] );
return true;
}
curl_close( $ch );
}
return false;
}
static public function next_order_id( int $order_id )
{
global $mdb;
if ( !$order_id )
return false;
return $mdb -> get( 'pp_shop_orders', 'id', [ 'id[>]' => $order_id, 'ORDER' => [ 'id' => 'ASC' ], 'LIMIT' => 1 ] );
}
static public function prev_order_id( int $order_id )
{
global $mdb;
if ( !$order_id )
return false;
return $mdb -> get( 'pp_shop_orders', 'id', [ 'id[<]' => $order_id, 'ORDER' => [ 'id' => 'DESC' ], 'LIMIT' => 1 ] );
}
static public function order_details( int $order_id )
{
global $mdb;
$order = $mdb -> get( 'pp_shop_orders', '*', [ 'id' => $order_id ] );
$order['products'] = $mdb -> select( 'pp_shop_order_products', '*', [ 'order_id' => $order_id ] );
return $order;
}
}

View File

@@ -55,10 +55,9 @@ class Order implements \ArrayAccess
public static function order_statuses()
{
global $mdb;
$results = $mdb -> select( 'pp_shop_statuses', [ 'id', 'status' ], [ 'ORDER' => [ 'o' => 'ASC' ] ] );
if ( \S::is_array_fix( $results ) ) foreach ( $results as $row )
$statuses[ (int)$row['id'] ] = $row['status'];
return $statuses;
$repository = new \Domain\ShopStatus\ShopStatusRepository( $mdb );
return $repository -> allStatuses();
}
public function update_aplio_order_status_date( $date )
@@ -80,8 +79,10 @@ class Order implements \ArrayAccess
{
global $mdb, $config;
$integrationsRepository = new \Domain\Integrations\IntegrationsRepository( $mdb );
// apilo
$apilo_settings = \admin\factory\Integrations::apilo_settings();
$apilo_settings = $integrationsRepository -> getSettings( 'apilo' );
if ( $apilo_settings['enabled'] and $apilo_settings['access-token'] and $apilo_settings['sync_orders'] )
{
// put data to file
@@ -117,6 +118,8 @@ class Order implements \ArrayAccess
{
global $mdb, $config;
$integrationsRepository = new \Domain\Integrations\IntegrationsRepository( $mdb );
if ( $this -> status == $status )
return false;
@@ -137,7 +140,7 @@ class Order implements \ArrayAccess
$response['result'] = true;
// apilo
$apilo_settings = \admin\factory\Integrations::apilo_settings();
$apilo_settings = $integrationsRepository -> getSettings( 'apilo' );
if ( $apilo_settings['enabled'] and $apilo_settings['access-token'] and $apilo_settings['sync_orders'] )
{
// put data to file
@@ -322,7 +325,9 @@ class Order implements \ArrayAccess
private function sync_apilo_payment(): bool
{
global $config;
global $config, $mdb;
$integrationsRepository = new \Domain\Integrations\IntegrationsRepository( $mdb );
if ( !(int)$this -> apilo_order_id )
return true;
@@ -332,7 +337,7 @@ class Order implements \ArrayAccess
$payment_type = 1;
$payment_date = new \DateTime( $this -> date_order );
$access_token = \admin\factory\Integrations::apilo_get_access_token();
$access_token = $integrationsRepository -> apiloGetAccessToken();
$ch = curl_init();
curl_setopt( $ch, CURLOPT_URL, "https://projectpro.apilo.com/rest/api/orders/" . $this -> apilo_order_id . '/payment/' );
@@ -371,12 +376,14 @@ class Order implements \ArrayAccess
private function sync_apilo_status( int $status ): bool
{
global $config;
global $config, $mdb;
$integrationsRepository = new \Domain\Integrations\IntegrationsRepository( $mdb );
if ( !(int)$this -> apilo_order_id )
return true;
$access_token = \admin\factory\Integrations::apilo_get_access_token();
$access_token = $integrationsRepository -> apiloGetAccessToken();
$ch = curl_init();
curl_setopt( $ch, CURLOPT_URL, "https://projectpro.apilo.com/rest/api/orders/" . $this -> apilo_order_id . '/status/' );