201 lines
No EOL
7 KiB
PHP
201 lines
No EOL
7 KiB
PHP
<?php
|
|
|
|
namespace App\Services;
|
|
|
|
use App\Models\ShoppingOrder;
|
|
use App\Models\ShoppingPayment;
|
|
use App\Models\UserPayCredit;
|
|
use App\Models\PaymentTransaction;
|
|
use Illuminate\Support\Facades\DB;
|
|
use Illuminate\Support\Facades\Log;
|
|
|
|
class PaymentService
|
|
{
|
|
public static $txaction_art = [
|
|
'user_order' => "Vertriebspartner",
|
|
'customer_order' => "Kundenbestellung",
|
|
'user_for_customer' => "VP.Kundenbestellung",
|
|
];
|
|
|
|
// Konstanten für bessere Wartbarkeit
|
|
const CREDIT_STATUS_DEDUCTION = 2;
|
|
const CREDIT_STATUS_RETURN = 4;
|
|
const CREDIT_STATUS_CHARGED = 7;
|
|
const CREDIT_STATUS_REMOVED = 8;
|
|
|
|
const TRANSACTION_REQUEST = 'transaction';
|
|
const DEFAULT_TXID = 0;
|
|
const DEFAULT_USERID = 0;
|
|
|
|
/**
|
|
* Aktualisiert den Transaktionsstatus einer Bestellung
|
|
*
|
|
* @param int $orderId
|
|
* @param string $txaction
|
|
* @param int $paymentId
|
|
* @return bool
|
|
* @throws \Exception
|
|
*/
|
|
public static function updateTransactionStatus($orderId, $txaction, $paymentId)
|
|
{
|
|
// Validierung der Eingabeparameter
|
|
if (empty($orderId) || empty($txaction) || empty($paymentId)) {
|
|
throw new \InvalidArgumentException('Alle Parameter müssen angegeben werden');
|
|
}
|
|
|
|
return DB::transaction(function () use ($orderId, $txaction, $paymentId) {
|
|
$shopping_order = ShoppingOrder::findOrFail($orderId);
|
|
$shopping_payment = ShoppingPayment::findOrFail($paymentId);
|
|
|
|
// Prüfen ob sich der Status tatsächlich geändert hat
|
|
if ($shopping_payment->txaction === $txaction) {
|
|
return false;
|
|
}
|
|
|
|
// Guthaben-Logik für Partner-Center Bestellungen
|
|
self::handlePartnerCenterCredits($shopping_order, $txaction);
|
|
|
|
// PaymentTransaction erstellen
|
|
$paymentTransaction = self::createPaymentTransaction($shopping_payment, $txaction);
|
|
|
|
// Bestellung und Payment aktualisieren
|
|
self::updateOrderAndPayment($shopping_order, $shopping_payment, $txaction, $paymentTransaction);
|
|
|
|
// Paid-Action ausführen falls nötig
|
|
self::handlePaidAction($paymentTransaction, $shopping_order);
|
|
|
|
// Credit-Loading Logik
|
|
self::handleCreditLoading($shopping_order, $txaction);
|
|
|
|
// E-Mail versenden
|
|
self::sendStatusEmail($shopping_order, $shopping_payment, $paymentTransaction);
|
|
|
|
return true;
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Behandelt Guthaben-Logik für Partner-Center Bestellungen
|
|
*/
|
|
private static function handlePartnerCenterCredits(ShoppingOrder $shoppingOrder, string $txaction): void
|
|
{
|
|
if (!$shoppingOrder->shopping_order_margin || $shoppingOrder->shopping_order_margin->from_payment_credit <= 0) {
|
|
return;
|
|
}
|
|
|
|
$lastUserPayCredit = self::getLastUserPayCredit($shoppingOrder->id, [self::CREDIT_STATUS_DEDUCTION, self::CREDIT_STATUS_RETURN]);
|
|
|
|
if (!$lastUserPayCredit) {
|
|
return;
|
|
}
|
|
|
|
// Status Keine Zahlung, Guthaben zurückführen
|
|
if ($txaction === 'non' && $lastUserPayCredit->status === self::CREDIT_STATUS_DEDUCTION) {
|
|
Payment::handelUserPayCredits($shoppingOrder, 'return');
|
|
}
|
|
|
|
// Status Zahlung, vorher gab es eine Storno, Guthaben abziehen
|
|
if ($lastUserPayCredit->status === self::CREDIT_STATUS_RETURN && in_array($txaction, ['open', 'paid'])) {
|
|
Payment::handelUserPayCredits($shoppingOrder, 'deduction');
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Erstellt eine neue PaymentTransaction
|
|
*/
|
|
private static function createPaymentTransaction(ShoppingPayment $shoppingPayment, string $txaction): PaymentTransaction
|
|
{
|
|
return PaymentTransaction::create([
|
|
'shopping_payment_id' => $shoppingPayment->id,
|
|
'request' => self::TRANSACTION_REQUEST,
|
|
'txid' => self::DEFAULT_TXID,
|
|
'userid' => self::DEFAULT_USERID,
|
|
'status' => $shoppingPayment->clearingtype,
|
|
'transmitted_data' => null,
|
|
'txaction' => $txaction,
|
|
'mode' => $shoppingPayment->mode,
|
|
]);
|
|
}
|
|
|
|
/**
|
|
* Aktualisiert Bestellung und Payment
|
|
*/
|
|
private static function updateOrderAndPayment(ShoppingOrder $shoppingOrder, ShoppingPayment $shoppingPayment, string $txaction, PaymentTransaction $paymentTransaction): void
|
|
{
|
|
$shoppingOrder->txaction = $txaction;
|
|
$shoppingOrder->paid = $paymentTransaction->txaction === 'paid';
|
|
$shoppingOrder->save();
|
|
|
|
$shoppingPayment->txaction = $txaction;
|
|
$shoppingPayment->save();
|
|
}
|
|
|
|
/**
|
|
* Führt Paid-Action aus falls nötig
|
|
*/
|
|
private static function handlePaidAction(PaymentTransaction $paymentTransaction, ShoppingOrder $shoppingOrder): void
|
|
{
|
|
if ($paymentTransaction->status === 'vor' && $paymentTransaction->txaction === 'paid') {
|
|
Payment::paymentStatusPaidAction($shoppingOrder, true);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Behandelt Credit-Loading Logik
|
|
*/
|
|
private static function handleCreditLoading(ShoppingOrder $shoppingOrder, string $txaction): void
|
|
{
|
|
if (!$shoppingOrder->shopping_user || $shoppingOrder->shopping_user->is_for !== 'cr') {
|
|
return;
|
|
}
|
|
|
|
$lastUserPayCredit = self::getLastUserPayCredit($shoppingOrder->id, [self::CREDIT_STATUS_CHARGED, self::CREDIT_STATUS_REMOVED]);
|
|
|
|
if (!$lastUserPayCredit) {
|
|
return;
|
|
}
|
|
|
|
// Status Keine Zahlung, Guthaben abziehen
|
|
if ($txaction === 'non' && $lastUserPayCredit->status === self::CREDIT_STATUS_CHARGED) {
|
|
Payment::handelUserPayChargingCredits($shoppingOrder, 'remove');
|
|
}
|
|
|
|
// Status Zahlung, vorher gab es eine Storno, Guthaben wieder aufladen
|
|
if ($lastUserPayCredit->status === self::CREDIT_STATUS_REMOVED && $txaction === 'paid') {
|
|
Payment::handelUserPayChargingCredits($shoppingOrder, 'add');
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Sendet Status-E-Mail
|
|
*/
|
|
private static function sendStatusEmail(ShoppingOrder $shoppingOrder, ShoppingPayment $shoppingPayment, PaymentTransaction $paymentTransaction): void
|
|
{
|
|
$emailData = [
|
|
'mode' => $paymentTransaction->mode,
|
|
'txaction' => $paymentTransaction->txaction,
|
|
'send_link' => false,
|
|
];
|
|
|
|
try {
|
|
Payment::paymentStatusSendMail($shoppingOrder, $shoppingPayment, $emailData);
|
|
} catch (\Exception $e) {
|
|
Log::error('Fehler beim Senden der Status-E-Mail', [
|
|
'order_id' => $shoppingOrder->id,
|
|
'payment_id' => $shoppingPayment->id,
|
|
'error' => $e->getMessage()
|
|
]);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Holt den letzten UserPayCredit Eintrag
|
|
*/
|
|
private static function getLastUserPayCredit(int $orderId, array $statuses): ?UserPayCredit
|
|
{
|
|
return UserPayCredit::where('shopping_order_id', $orderId)
|
|
->whereIn('status', $statuses)
|
|
->orderBy('id', 'DESC')
|
|
->first();
|
|
}
|
|
}
|