Data patch for a problem reported about an item not suppose to appear in export/on-hold-packing-list

This commit is contained in:
Dillon Ngo
2024-08-17 08:39:19 +08:00
parent 499782bbec
commit 694876c31f
4 changed files with 169 additions and 13 deletions
@@ -0,0 +1,140 @@
<?php
namespace App\Classes\Modules\Billplzs\Processors;
use Illuminate\Http\Request;
use App\Models\Wallet;
use App\Models\Group;
use App\Classes\ValueObjects\Constants\ApprovalStatus;
use App\Classes\ValueObjects\Constants\PaymentMethodType;
use App\Classes\Modules\Transactions\Processors\CreatePaymentTransactionProcessor;
use App\Classes\Modules\Transactions\Processors\ReleaseGoodsToCustomerProcessor;
use App\Classes\Modules\Transactions\Services\UpdatesTransactionStatus;
use App\Classes\Modules\Wallets\Services\UpdatesWalletBalance;
use App\Classes\Modules\Orders\Processors\UpdateDoFromVTPortalProcessor;
use App\Classes\Modules\Orders\Processors\UpdateDoFromYDPortalProcessor;
use Illuminate\Support\Facades\Log;
//Date: 20240817
//This Processor is used for one time data patching with OneTimeTransactionFixBillplzFailedCallback.php
class CallbackBillplzDataPatchProcessor
{
/** @var UpdatesTransactionStatus */
private $updatesTransactionStatus;
/** @var UpdateDoFromVTPortalProcessor */
private $updateDoFromVTPortalProcessor;
/** @var UpdateDoFromYDPortalProcessor */
private $updateDoFromYDPortalProcessor;
/** @var UpdatesWalletBalance */
private $updatesWalletBalance;
/** @var CreatePaymentTransactionProcessor */
private $createPaymentTransactionProcessor;
/** @var ReleaseGoodsToCustomerProcessor */
private $releaseGoodsToCustomerProcessor;
/**
* CallbackBillplzDataPatchProcessor constructor.
* @param UpdatesTransactionStatus $updatesTransactionStatus
* @param UpdateDoFromVTPortalProcessor $updateDoFromVTPortalProcessor
* @param UpdateDoFromYDPortalProcessor $updateDoFromYDPortalProcessor
* @param UpdatesWalletBalance $updatesWalletBalance
* @param CreatePaymentTransactionProcessor $createPaymentTransactionProcessor
* @param ReleaseGoodsToCustomerProcessor $releaseGoodsToCustomerProcessor
*/
public function __construct(UpdatesTransactionStatus $updatesTransactionStatus, UpdateDoFromVTPortalProcessor $updateDoFromVTPortalProcessor, UpdateDoFromYDPortalProcessor $updateDoFromYDPortalProcessor, UpdatesWalletBalance $updatesWalletBalance, CreatePaymentTransactionProcessor $createPaymentTransactionProcessor, ReleaseGoodsToCustomerProcessor $releaseGoodsToCustomerProcessor)
{
$this->updatesTransactionStatus = $updatesTransactionStatus;
$this->updateDoFromVTPortalProcessor = $updateDoFromVTPortalProcessor;
$this->updateDoFromYDPortalProcessor = $updateDoFromYDPortalProcessor;
$this->updatesWalletBalance = $updatesWalletBalance;
$this->createPaymentTransactionProcessor = $createPaymentTransactionProcessor;
$this->releaseGoodsToCustomerProcessor = $releaseGoodsToCustomerProcessor;
}
/**
* @param Request $request
* @throws \App\Classes\Exceptions\MalformedRequestException
*/
public function execute($transaction, $status)
{
$invoice = $transaction->owner;
$packingList = $invoice->owner;
$proceed = $this->checkForGroupPayment($transaction);
if(!$proceed) return false;
$this->updatesTransactionStatus->execute($transaction, $status);
Log::info('CallbackBillplzDataPatchProcessor 1');
// check if is wallet top up
if ($transaction->owner instanceof Wallet && $status === ApprovalStatus::APPROVED) {
Log::info('CallbackBillplzDataPatchProcessor 2');
$this->updatesWalletBalance->execute($transaction->owner, $transaction->amount);
$group = Group::where('reference', $transaction->payment_reference)->first();
// check if is group payment
if ($group) {
foreach ($group->groupTransactions as $groupTransaction) {
$invoice = $groupTransaction->transaction;
Log::info('CallbackBillplzDataPatchProcessor 3: '.json_encode($invoice));
//if($invoice->status !== ApprovalStatus::COMPLETED){
// $paymentTransaction = $this->createPaymentTransactionProcessor->execute($invoice, PaymentMethodType::WALLET, null, false);
// if($paymentTransaction && $paymentTransaction->status == ApprovalStatus::APPROVED){
$pL = $invoice->owner;
$this->releaseGoodsToCustomerProcessor->execute($pL, $invoice, true);
//}
//}
}
$group->status = $status;
$group->save();
}
}
if (!$transaction->owner instanceof Wallet) {
Log::info('CallbackBillplzDataPatchProcessor 3');
$this->releaseGoodsToCustomerProcessor->execute($packingList, $invoice);
}
return true;
}
private function checkForGroupPayment($transaction){
//This check is targetting group payment that expired and soft deleted
//command:check-storage-invoices must already run for this part of the code to work properly
$group = Group::withTrashed()->where('reference', $transaction->payment_reference)->first();
if ($group) {
$totalAmountToBePaid = 0;
$actualAmountPaid = $transaction->amount;
foreach ($group->groupTransactions as $groupTransaction) {
$invoice = $groupTransaction->transaction;
if($invoice->status !== ApprovalStatus::COMPLETED){
$totalAmountToBePaid += $invoice->amount;
}
}
if(($totalAmountToBePaid - $actualAmountPaid) < 0.01){
}
else{
Log::channel('storage_invoices')->info('Total amount from current transaction: '.$totalAmountToBePaid); //cief todo: to be removed
Log::channel('storage_invoices')->info('Total amount from paid transaction: '.$transaction->amount); //cief todo: to be removed
return false;
}
}
return true;
}
}
@@ -36,7 +36,7 @@ class CallbackBillplzProcessor
private $releaseGoodsToCustomerProcessor; private $releaseGoodsToCustomerProcessor;
/** /**
* CreateUserProcessor constructor. * CallbackBillplzProcessor constructor.
* @param UpdatesTransactionStatus $updatesTransactionStatus * @param UpdatesTransactionStatus $updatesTransactionStatus
* @param UpdateDoFromVTPortalProcessor $updateDoFromVTPortalProcessor * @param UpdateDoFromVTPortalProcessor $updateDoFromVTPortalProcessor
* @param UpdateDoFromYDPortalProcessor $updateDoFromYDPortalProcessor * @param UpdateDoFromYDPortalProcessor $updateDoFromYDPortalProcessor
@@ -44,24 +44,33 @@ class ReleaseGoodsToCustomerProcessor
/** /**
* @param $packingList * @param $packingList
* @param $invoice * @param $invoice
* @param $processCompletedInvoices
* @throws \App\Classes\Exceptions\MalformedRequestException * @throws \App\Classes\Exceptions\MalformedRequestException
*/ */
public function execute($packingList, $invoice = null) public function execute($packingList, $invoice = null, $processCompletedInvoices = false)
{ {
$result = false; $result = false;
$totalInvoicesAmountPaid = 0.00; $totalInvoicesAmountPaid = 0.00;
$totalInvoicesAmount = 0.00; $totalInvoicesAmount = 0.00;
$invoiceTransactions = $packingList->transactions()->where('status', [ApprovalStatus::APPROVED])->whereIn('type', [TransactionType::SHIPPING_INVOICE, TransactionType::STORAGE_INVOICE])->get(); if($processCompletedInvoices){
//processCompletedInvoices, for manual processing of invoices, e.g. incomplete payment gateway finish with storage invoice
$invoiceTransactions = $packingList->transactions()->whereIn('status', [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED])->whereIn('type', [TransactionType::SHIPPING_INVOICE, TransactionType::STORAGE_INVOICE])->get();
}
else{
$invoiceTransactions = $packingList->transactions()->where('status', ApprovalStatus::APPROVED)->whereIn('type', [TransactionType::SHIPPING_INVOICE, TransactionType::STORAGE_INVOICE])->get();
}
//Part 1: Process each single invoice type and get the total of all invoices //Part 1: Process each single invoice type and get the total of all invoices (STORAGE + SHIPPING)
foreach($invoiceTransactions as $invoiceTransaction){ foreach($invoiceTransactions as $invoiceTransaction){
$totalInvoiceAmountPaid = $invoiceTransaction->transactions->where('type', TransactionType::PAYMENT)->whereIn('status', [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED])->sum('amount'); $totalInvoiceAmountPaid = $invoiceTransaction->transactions->where('type', TransactionType::PAYMENT)->whereIn('status', [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED])->sum('amount');
if ($invoice && $invoice->type == $invoiceTransaction->type) { if ($invoice && $invoice->type == $invoiceTransaction->type) {
if(($invoice->amount - $totalInvoiceAmountPaid) < 0.01){ if(($invoice->amount - $totalInvoiceAmountPaid) < 0.01){
Log::channel('storage_invoices')->info('ReleaseGoodsToCustomerProcessor updatesTransactionStatus');
$this->updatesTransactionStatus->execute($invoice, ApprovalStatus::COMPLETED); $this->updatesTransactionStatus->execute($invoice, ApprovalStatus::COMPLETED);
if($invoice->type == TransactionType::STORAGE_INVOICE){ //cief todo: remove the following if block
if($invoice->type === TransactionType::STORAGE_INVOICE){
Log::channel('storage_invoices')->info('ReleaseGoodsToCustomerProcessor createStorageInvoiceDocTransactionProcessor');
$this->createStorageInvoiceDocTransactionProcessor->execute($packingList); $this->createStorageInvoiceDocTransactionProcessor->execute($packingList);
} }
} }
@@ -4,6 +4,7 @@ namespace App\Console\Commands;
use App\Classes\Modules\Billplzs\Processors\CallbackBillplzProcessor; use App\Classes\Modules\Billplzs\Processors\CallbackBillplzProcessor;
use App\Classes\Modules\Billplzs\Processors\CallbackBillplzDataPatchProcessor;
use App\Classes\ValueObjects\Constants\ApprovalStatus; use App\Classes\ValueObjects\Constants\ApprovalStatus;
use App\Models\Transaction; use App\Models\Transaction;
use Carbon\Carbon; use Carbon\Carbon;
@@ -32,15 +33,19 @@ class OneTimeTransactionFixBillplzFailedCallback extends Command
/** @var CallbackBillplzProcessor */ /** @var CallbackBillplzProcessor */
private $callbackBillplzProcessor; private $callbackBillplzProcessor;
/** @var CallbackBillplzDataPatchProcessor */
private $callbackBillplzDataPatchProcessor;
/** /**
* Create a new command instance. * Create a new command instance.
* *
* @return void * @return void
*/ */
public function __construct(CallbackBillplzProcessor $callbackBillplzProcessor) public function __construct(CallbackBillplzProcessor $callbackBillplzProcessor, CallbackBillplzDataPatchProcessor $callbackBillplzDataPatchProcessor)
{ {
parent::__construct(); parent::__construct();
$this->callbackBillplzProcessor = $callbackBillplzProcessor; $this->callbackBillplzProcessor = $callbackBillplzProcessor;
$this->callbackBillplzDataPatchProcessor = $callbackBillplzDataPatchProcessor;
} }
/** /**
@@ -55,20 +60,22 @@ class OneTimeTransactionFixBillplzFailedCallback extends Command
$this->outputArray = []; $this->outputArray = [];
$start = new Carbon(); $start = new Carbon();
//Transaction fix with this one time fix command: 15205, 16803 //Transaction fix with this one time fix command: 15205, 16803, 17310
//This transaction, 16803 has approve payment but not its owner, shipping invoice //This transaction, 16803 has approve payment but not its owner, shipping invoice
$transaction = Transaction::whereIn('id', [16803])->first(); $transaction = Transaction::whereIn('id', [17310])->first();
$this->info(Carbon::now() . ' : One time fix failled callback from billplz for transaction with id 16803 cron started.'); $this->info(Carbon::now() . ' : One time fix failled callback from billplz for transaction with id 17310 cron started.');
if($transaction && $transaction->id == 16803){ if($transaction && $transaction->id == 17310){
$this->info(Carbon::now() . ' : 17310.');
$status = ApprovalStatus::APPROVED; $status = ApprovalStatus::APPROVED;
$this->callbackBillplzProcessor->execute($transaction, $status); // $this->callbackBillplzProcessor->execute($transaction, $status);
$this->callbackBillplzDataPatchProcessor->execute($transaction, $status);
} }
$end = new Carbon(); $end = new Carbon();
$elapsedTime = $start->diff($end)->format('%H:%I:%S'); $elapsedTime = $start->diff($end)->format('%H:%I:%S');
$this->info(Carbon::now() . ' : One time fix failled callback from billplz for transaction with id 16803 cron ended. ElapsedTime: ' . $elapsedTime); $this->info(Carbon::now() . ' : One time fix failled callback from billplz for transaction with id 17310 cron ended. ElapsedTime: ' . $elapsedTime);
} }
} }