update
This commit is contained in:
@@ -16,6 +16,8 @@ use App\Modules\Email\EmailSendingService;
|
||||
use App\Modules\Settings\EmailMailboxRepository;
|
||||
use App\Modules\Settings\EmailTemplateRepository;
|
||||
use App\Modules\Settings\ReceiptConfigRepository;
|
||||
use App\Modules\Settings\ShopproApiClient;
|
||||
use App\Modules\Settings\ShopproIntegrationsRepository;
|
||||
use App\Modules\Shipments\ShipmentPackageRepository;
|
||||
|
||||
final class OrdersController
|
||||
@@ -32,7 +34,8 @@ final class OrdersController
|
||||
private readonly ?EmailTemplateRepository $emailTemplateRepo = null,
|
||||
private readonly ?EmailMailboxRepository $emailMailboxRepo = null,
|
||||
private readonly string $storagePath = '',
|
||||
private readonly ?\App\Modules\Printing\PrintJobRepository $printJobRepo = null
|
||||
private readonly ?\App\Modules\Printing\PrintJobRepository $printJobRepo = null,
|
||||
private readonly ?ShopproIntegrationsRepository $shopproIntegrations = null
|
||||
) {
|
||||
}
|
||||
|
||||
@@ -781,4 +784,102 @@ final class OrdersController
|
||||
return Response::json($preview);
|
||||
}
|
||||
|
||||
public function addPayment(Request $request): Response
|
||||
{
|
||||
$orderId = max(0, (int) $request->input('id', 0));
|
||||
if ($orderId <= 0) {
|
||||
return Response::json(['ok' => false, 'error' => 'Nieprawidłowe ID zamówienia.'], 400);
|
||||
}
|
||||
|
||||
if (!Csrf::verify((string) $request->input('_token', ''))) {
|
||||
return Response::json(['ok' => false, 'error' => 'Nieprawidłowy token CSRF.'], 403);
|
||||
}
|
||||
|
||||
$amount = (float) $request->input('amount', 0);
|
||||
$paymentTypeId = trim((string) $request->input('payment_type_id', ''));
|
||||
$paymentDate = trim((string) $request->input('payment_date', ''));
|
||||
$comment = trim((string) $request->input('comment', ''));
|
||||
|
||||
if ($amount <= 0) {
|
||||
return Response::json(['ok' => false, 'error' => 'Kwota musi być większa od 0.'], 422);
|
||||
}
|
||||
if ($paymentTypeId === '') {
|
||||
return Response::json(['ok' => false, 'error' => 'Wybierz typ płatności.'], 422);
|
||||
}
|
||||
|
||||
$result = $this->orders->addPayment($orderId, [
|
||||
'amount' => $amount,
|
||||
'payment_type_id' => $paymentTypeId,
|
||||
'payment_date' => $paymentDate !== '' ? $paymentDate . ' ' . date('H:i:s') : '',
|
||||
'comment' => $comment,
|
||||
]);
|
||||
|
||||
if ($result === null) {
|
||||
return Response::json(['ok' => false, 'error' => 'Nie udało się zapisać płatności.'], 500);
|
||||
}
|
||||
|
||||
$this->orders->recordActivity(
|
||||
$orderId,
|
||||
'payment',
|
||||
'Dodano płatność: ' . number_format($amount, 2, '.', ' ') . ' PLN (' . $paymentTypeId . ')',
|
||||
['payment_id' => $result['id'], 'amount' => $amount, 'type' => $paymentTypeId],
|
||||
'user',
|
||||
$this->auth->user()['name'] ?? null
|
||||
);
|
||||
|
||||
$this->pushPaymentToShoppro($orderId, $result['payment_status']);
|
||||
|
||||
return Response::json([
|
||||
'ok' => true,
|
||||
'payment_id' => $result['id'],
|
||||
'payment_status' => $result['payment_status'],
|
||||
'total_paid' => $result['total_paid'],
|
||||
]);
|
||||
}
|
||||
|
||||
private function pushPaymentToShoppro(int $orderId, int $paymentStatus): void
|
||||
{
|
||||
if ($paymentStatus !== 2 || $this->shopproIntegrations === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
$orderStmt = $this->orders->findOrderSourceInfo($orderId);
|
||||
if ($orderStmt === null || ($orderStmt['source'] ?? '') !== 'shoppro') {
|
||||
return;
|
||||
}
|
||||
|
||||
$integrationId = (int) ($orderStmt['integration_id'] ?? 0);
|
||||
$sourceOrderId = trim((string) ($orderStmt['source_order_id'] ?? ''));
|
||||
if ($integrationId <= 0 || $sourceOrderId === '') {
|
||||
return;
|
||||
}
|
||||
|
||||
$integration = $this->shopproIntegrations->findIntegration($integrationId);
|
||||
if ($integration === null || empty($integration['is_active']) || empty($integration['has_api_key'])) {
|
||||
return;
|
||||
}
|
||||
|
||||
$baseUrl = trim((string) ($integration['base_url'] ?? ''));
|
||||
$apiKey = $this->shopproIntegrations->getApiKeyDecrypted($integrationId);
|
||||
if ($baseUrl === '' || $apiKey === null || trim($apiKey) === '') {
|
||||
return;
|
||||
}
|
||||
|
||||
$client = new ShopproApiClient();
|
||||
$pushResult = $client->setOrderPaid($baseUrl, $apiKey, 10, $sourceOrderId);
|
||||
|
||||
$this->orders->recordActivity(
|
||||
$orderId,
|
||||
'sync',
|
||||
$pushResult['ok']
|
||||
? 'Wysłano status płatności do shopPRO (opłacone)'
|
||||
: 'Błąd push płatności do shopPRO: ' . ($pushResult['message'] ?? 'unknown'),
|
||||
['direction' => 'push', 'target' => 'shoppro', 'ok' => $pushResult['ok']],
|
||||
'system'
|
||||
);
|
||||
} catch (\Throwable) {
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -847,6 +847,94 @@ final class OrdersRepository
|
||||
], $actorType, $actorName);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<string, mixed> $data Keys: payment_type_id, amount, payment_date, comment, currency
|
||||
* @return array{id:int, payment_status:int, total_paid:float}|null
|
||||
*/
|
||||
/**
|
||||
* @return array{source:string, integration_id:int, source_order_id:string}|null
|
||||
*/
|
||||
public function findOrderSourceInfo(int $orderId): ?array
|
||||
{
|
||||
if ($orderId <= 0) {
|
||||
return null;
|
||||
}
|
||||
$stmt = $this->pdo->prepare('SELECT source, integration_id, source_order_id FROM orders WHERE id = :id LIMIT 1');
|
||||
$stmt->execute(['id' => $orderId]);
|
||||
$row = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||
return is_array($row) ? $row : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<string, mixed> $data Keys: payment_type_id, amount, payment_date, comment, currency
|
||||
* @return array{id:int, payment_status:int, total_paid:float}|null
|
||||
*/
|
||||
public function addPayment(int $orderId, array $data): ?array
|
||||
{
|
||||
if ($orderId <= 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$stmt = $this->pdo->prepare('SELECT id, total_with_tax, currency FROM orders WHERE id = :id LIMIT 1');
|
||||
$stmt->execute(['id' => $orderId]);
|
||||
$order = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||
if (!is_array($order)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$amount = round((float) ($data['amount'] ?? 0), 2);
|
||||
$paymentTypeId = trim((string) ($data['payment_type_id'] ?? ''));
|
||||
$paymentDate = trim((string) ($data['payment_date'] ?? ''));
|
||||
$comment = trim((string) ($data['comment'] ?? ''));
|
||||
$currency = trim((string) ($data['currency'] ?? $order['currency'] ?? 'PLN'));
|
||||
|
||||
if ($amount <= 0 || $paymentTypeId === '') {
|
||||
return null;
|
||||
}
|
||||
|
||||
$sourcePaymentId = 'manual_' . $orderId . '_' . time();
|
||||
|
||||
$insert = $this->pdo->prepare(
|
||||
'INSERT INTO order_payments (order_id, source_payment_id, payment_type_id, payment_date, amount, currency, comment, created_at, updated_at)
|
||||
VALUES (:order_id, :source_payment_id, :payment_type_id, :payment_date, :amount, :currency, :comment, NOW(), NOW())'
|
||||
);
|
||||
$insert->execute([
|
||||
'order_id' => $orderId,
|
||||
'source_payment_id' => $sourcePaymentId,
|
||||
'payment_type_id' => $paymentTypeId,
|
||||
'payment_date' => $paymentDate !== '' ? $paymentDate : date('Y-m-d H:i:s'),
|
||||
'amount' => $amount,
|
||||
'currency' => $currency,
|
||||
'comment' => $comment !== '' ? $comment : null,
|
||||
]);
|
||||
$paymentId = (int) $this->pdo->lastInsertId();
|
||||
|
||||
$sumStmt = $this->pdo->prepare('SELECT COALESCE(SUM(amount), 0) FROM order_payments WHERE order_id = :order_id');
|
||||
$sumStmt->execute(['order_id' => $orderId]);
|
||||
$totalPaid = round((float) $sumStmt->fetchColumn(), 2);
|
||||
|
||||
$totalWithTax = $order['total_with_tax'] !== null ? (float) $order['total_with_tax'] : null;
|
||||
$paymentStatus = 0;
|
||||
if ($totalPaid > 0 && $totalWithTax !== null && $totalPaid >= $totalWithTax) {
|
||||
$paymentStatus = 2;
|
||||
} elseif ($totalPaid > 0) {
|
||||
$paymentStatus = 1;
|
||||
}
|
||||
|
||||
$update = $this->pdo->prepare('UPDATE orders SET payment_status = :payment_status, total_paid = :total_paid, updated_at = NOW() WHERE id = :id');
|
||||
$update->execute([
|
||||
'payment_status' => $paymentStatus,
|
||||
'total_paid' => $totalPaid,
|
||||
'id' => $orderId,
|
||||
]);
|
||||
|
||||
return [
|
||||
'id' => $paymentId,
|
||||
'payment_status' => $paymentStatus,
|
||||
'total_paid' => $totalPaid,
|
||||
];
|
||||
}
|
||||
|
||||
public function updateOrderStatus(int $orderId, string $newStatusCode, string $actorType = 'user', ?string $actorName = null): bool
|
||||
{
|
||||
try {
|
||||
|
||||
Reference in New Issue
Block a user