Merge branch 'fix-account-statement-issue' of gitlab.com:CIEFWorldwideSdnBhd/exchange-2.0 into development

This commit is contained in:
edmondlang
2023-09-05 16:06:56 +08:00
10 changed files with 152 additions and 48 deletions
@@ -30,11 +30,12 @@ class CreateBankStatementTransactionOwnersProcessor
// $transactions = StatementTransaction::whereDoesntHave('owners')->where('amount', '<', 0)->get();
foreach ($transactions as $transaction) {
$keywords = array_filter(explode(" ", $transaction->transaction_description . " " . $transaction->transaction_description_2));
if($transaction->amount > 0){
// Exchange Sales
$creditTransactions = $this->getTransactions($transaction->posting_date, $transaction->amount, TransactionType::PAYMENT, Booking::class, PaymentMethodType::WALLET, [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED]);
$creditTransactions = $this->getTransactions($transaction->posting_date, $transaction->amount, TransactionType::PAYMENT, Booking::class, PaymentMethodType::WALLET, [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED], $keywords);
foreach ($creditTransactions as $creditTransaction) {
$transaction->owners()->firstOrCreate([
'type' => StatementTransactionOwnerType::SALES,
@@ -47,7 +48,7 @@ class CreateBankStatementTransactionOwnersProcessor
// Shipping Portal Sales
$creditTransactions = $this->getTransactionsFromShippingPortal($transaction->amount, $this->getDateRange($transaction->posting_date), 2);
$creditTransactions = $this->getTransactionsFromShippingPortal($transaction->amount, $this->getDateRange($transaction->posting_date, 1), 2);
foreach ($creditTransactions as $creditTransaction) {
if($creditTransaction['owner_type'] === Wallet::class) continue;
$transaction->owners()->firstOrCreate([
@@ -60,7 +61,7 @@ class CreateBankStatementTransactionOwnersProcessor
}
// Exchange Wallet Top Up
$creditTransactions = $this->getTransactions($transaction->posting_date, $transaction->amount, TransactionType::TOP_UP, Wallet::class, null, [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED]);
$creditTransactions = $this->getTransactions($transaction->posting_date, $transaction->amount, TransactionType::TOP_UP, Wallet::class, null, [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED], $keywords);
foreach ($creditTransactions as $creditTransaction) {
$transaction->owners()->firstOrCreate([
'type' => StatementTransactionOwnerType::WALLET_TOP_UP,
@@ -71,7 +72,7 @@ class CreateBankStatementTransactionOwnersProcessor
]);
}
$creditTransactions = $this->getTransactionsFromShippingPortal($transaction->amount, $this->getDateRange($transaction->posting_date), 5);
$creditTransactions = $this->getTransactionsFromShippingPortal($transaction->amount, $this->getDateRange($transaction->posting_date, 1), 5);
foreach ($creditTransactions as $creditTransaction) {
$transaction->owners()->firstOrCreate([
'type' => StatementTransactionOwnerType::WALLET_TOP_UP,
@@ -131,7 +132,7 @@ class CreateBankStatementTransactionOwnersProcessor
}
// Exchange Wallet Withdrawal
$debitTransactions = $this->getTransactions($transaction->posting_date, $transaction->amount, TransactionType::DEBIT_NOTE, Wallet::class, null, [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED]);
$debitTransactions = $this->getTransactions($transaction->posting_date, $transaction->amount, TransactionType::DEBIT_NOTE, Wallet::class, null, [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED], $keywords);
foreach ($debitTransactions as $debitTransaction) {
$transaction->owners()->firstOrCreate([
'type' => StatementTransactionOwnerType::WALLET_WITHDRAWAL,
@@ -189,7 +190,8 @@ class CreateBankStatementTransactionOwnersProcessor
}
}
private function getTransactions($date, $amount, $type, $ownerType, $paymentMethod, $statuses, $model = Transaction::class) {
private function getTransactions($date, $amount, $type, $ownerType, $paymentMethod, $statuses, $keywords, $model = Transaction::class) {
$dateRange = $this->getDateRange($date, 4);
$query = $model::whereIn('status', $statuses)
->where(function ($query) use ($ownerType, $paymentMethod, $type) {
if ($ownerType) {
@@ -204,9 +206,65 @@ class CreateBankStatementTransactionOwnersProcessor
$query->where('type', $type);
}
})
->whereDate('created_at', $date->format('Y-m-d'))
->where('amount', '>', ($amount - 0.01))
->where('amount', '<', ($amount + 0.01));
->whereDate('created_at', '>=', $dateRange['start_date'])
->whereDate('created_at', '<=', $dateRange['end_date'])
->where('amount', '>', ($amount - 0.05))
->where('amount', '<', ($amount + 0.05));
if ($query->count() > 1) {
$transactions = clone $query;
$transactions->whereDate('created_at', $date->format('Y-m-d'));
if ($transactions->count() === 1) {
return $transactions->get();
}
$transactions = clone $query;
if ($ownerType === Booking::class) {
$transactions = $transactions->whereHasMorph('owner', [Booking::class], function ($q1) use ($keywords) {
return $q1->whereHas('company', function ($company) use ($keywords) {
return $company->where(function ($q2) use ($keywords) {
foreach($keywords as $keyword) {
$q2->orWhere('name', 'LIKE', '%'.$keyword.'%');
}
$q2->orWhereHas('contacts', function ($contact) use($keywords) {
return $contact->where(function ($q3) use($keywords) {
foreach($keywords as $keyword) {
$q3->orWhere('reference', 'LIKE', '%'.$keyword.'%');
}
});
});
});
});
});
}
if ($ownerType === Wallet::class) {
$transactions = $transactions->whereHasMorph('owner', [Wallet::class], function ($q1) use ($keywords) {
return $q1->whereHasMorph('owner', [Company::class], function ($company) use($keywords) {
return $company->where(function ($q2) use ($keywords) {
foreach($keywords as $keyword) {
$q2->orWhere('name', 'LIKE', '%'.$keyword.'%');
}
$q2->orWhereHas('contacts', function ($contact) use($keywords) {
return $contact->where(function ($q3) use($keywords) {
foreach($keywords as $keyword) {
$q3->orWhere('reference', 'LIKE', '%'.$keyword.'%');
}
});
});
});
});
});
}
if ($transactions->count() === 1) {
return $transactions->get();
}
}
return $query->get();
}
@@ -237,15 +295,15 @@ class CreateBankStatementTransactionOwnersProcessor
}
}
private function getDateRange(string $dateStr) {
private function getDateRange(string $dateStr, int $range) {
// Create a DateTime object from the input string
$date = strtotime($dateStr);
// Get the first day of the month
$today = date('Y-m-d', strtotime('-1 day', $date));
$today = date('Y-m-d', strtotime('-' . $range . ' day', $date));
// Get the first day of the next month
$nextDay = date('Y-m-d', strtotime('+1 day', $date));
$nextDay = date('Y-m-d', strtotime('+' . $range . ' day', $date));
return [
'start_date' => $today,
@@ -3,6 +3,7 @@
namespace App\Classes\Modules\Transactions\Services;
use App\Classes\Exceptions\InternalServerErrorException;
use Carbon\Carbon;
class GeneratesTransactionBillNumber
@@ -27,14 +28,21 @@ class GeneratesTransactionBillNumber
* @return string
*/
public function execute(string $prefix, ?Carbon $date = null): string {
if(!$date){
$date = carbon::now();
if (!$date) {
$date = Carbon::now();
}
$billNumber = $prefix.$date->format('Y').$date->format('m').'-'.mt_rand(10000, 99999);
return !$this->checksIfTransactionBillNumberExists->execute($billNumber) ? $billNumber : self::execute($prefix);
$attempt = 0;
while ($attempt < 10) { // Retry up to 10 times
$billNumber = $prefix . $date->format('Y') . $date->format('m') . '-' . microtime(true);
if (!$this->checksIfTransactionBillNumberExists->execute($billNumber)) {
return $billNumber;
}
$attempt++;
}
throw new InternalServerErrorException("Unable to generate unique bill number after {$attempt} attempts.");
}
}
}
+2 -2
View File
@@ -41,8 +41,8 @@ class DeleteOrderCommand extends Command
*/
public function handle()
{
// $bookings_reference = $this->argument('bookings_reference');
$bookings_reference = '28546,38599,44487,71086,70133,58580,42831,96028,41188,33894,95877,86732,31894,50962,44215,92894,40968,30303,89762,74693,45271,27169';
$bookings_reference = $this->argument('bookings_reference');
// $bookings_reference = '28546,38599,44487,71086,70133,58580,42831,96028,41188,33894,95877,86732,31894,50962,44215,92894,40968,30303,89762,74693,45271,27169';
$bookings_reference = explode(',', $bookings_reference);
$start = new Carbon();
+1
View File
@@ -21,6 +21,7 @@ class BankResource extends JsonResource
'reference' => $this->reference,
'bank_name' => $this->bank_name,
'bank_branch' => $this->bank_branch,
'swift' => $this->swift,
'holder_name' => $this->holder_name,
'account_no' => $this->account_no,
'country_id' => $this->country_id,
@@ -76,7 +76,7 @@
</div>
<div class="row" v-if="item.bank.type !== 3 ">
<div class="col-auto p-r-10">
<div class="font-heading fs-10 small">{{item.bank.bank_name}} <span class="m-l-5">({{item.bank.bank_branch}})</span></div>
<div class="font-heading fs-10 small">{{item.bank.bank_name}} <span class="m-l-5">({{item.bank.bank_branch}})</span> <span class="m-l-5">({{item.bank.swift}})</span></div>
</div>
</div>
</div>
@@ -42,7 +42,7 @@
<td>{{$transaction->currency_rate}}</td>
<td>{{$transaction->currency->short_code}} {{number_format((float)$transaction->amount, 2, '.', '')}}</td>
<td>Account Holder Name: {{$transaction->owner->owner->bank->holder_name}}<br>{{$transaction->owner->owner->bank->bank_name}}: {{$transaction->owner->owner->bank->account_no}}
<br>Branch: {{$transaction->owner->owner->bank->bank_branch}}<br>Bank in Amount: {{$transaction->original_currency->short_code}} {{$transaction->original_amount}}</td>
<br>Branch: {{$transaction->owner->owner->bank->bank_branch}}@if($transaction->original_currency->short_code === 'USD')<br>Swift Code: {{$transaction->owner->owner->bank->swift}}@endif<br>Bank in Amount: {{$transaction->original_currency->short_code}} {{$transaction->original_amount}}</td>
</tr>
@endforeach
</tbody>
@@ -84,17 +84,22 @@
<tbody>
@php
$subtotal = "0";
$voucherDiscount = $voucher_redemption ? bcmul((string)$voucher_redemption->value, "-1", 2) : "0";
$displayedSubtotal = 0;
$voucherDiscount = $voucher_redemption ? bcmul((string)$voucher_redemption->value, "-1", 5) : "0";
$displayedSubtotal = "0";
$exactTotal = "0";
@endphp
@foreach ($po_order_transaction->transactionDetails as $key => $transaction_detail)
@php
$exactUnitPrice = bcdiv($transaction_detail->price, $transaction->currency_rate, 5);
$itemTotal = bcmul($exactUnitPrice, $transaction_detail->quantity, 5);
$displayedItemTotal = bcmul($exactUnitPrice, $transaction_detail->quantity, 2);
// Round half to even for displayed item total
$displayedItemTotal = round(bcmul($exactUnitPrice, $transaction_detail->quantity, 2), 2, PHP_ROUND_HALF_EVEN);
$displayedSubtotal = bcadd($displayedSubtotal, $displayedItemTotal, 2);
$subtotal = bcadd($subtotal, $displayedItemTotal, 2);
$subtotal = bcadd($subtotal, $itemTotal, 5);
$exactTotal = bcadd($exactTotal, $displayedItemTotal, 5);
@endphp
<tr>
<td width="5%" class="center top">{{ $key + 1 }}</td>
@@ -112,7 +117,7 @@
</tbody>
<tfoot>
@php
$subtotalWithDiscount = bcsub($subtotal, $voucherDiscount, 5); // Use bcsub to subtract
$subtotalWithDiscount = bcsub($subtotal, $voucherDiscount, 5);
@endphp
<tr class="subtotal">
<td colspan="4"></td>
@@ -141,10 +146,17 @@
</tr>
@endif
@php
$displayedTotal = bcadd(bcadd(bcadd($displayedSubtotal, $transaction->service_charge, 2), $transaction->tax, 2), $voucherDiscount, 2);
// Calculate the totals with 5 decimal places
$expectedTotal = bcadd(bcadd(bcadd($subtotal, $transaction->service_charge, 5), $transaction->tax, 5), $voucherDiscount, 5);
$discrepancy = bcsub($displayedTotal, $expectedTotal, 5);
$total = bcadd(bcadd(bcadd($subtotal, $transaction->service_charge, 5), $transaction->tax, 5), $voucherDiscount, 5); // Keep precision
// Calculate the displayed totals with 2 decimal places
$displayedTotal = bcadd(bcadd(bcadd($displayedSubtotal, $transaction->service_charge, 2), $transaction->tax, 2), $voucherDiscount, 2);
// Calculate the discrepancy
$discrepancy = bcsub($expectedTotal, $displayedTotal, 5);
// Calculate the final total
$total = bcadd($expectedTotal, $discrepancy, 5);
@endphp
<tr>
<td colspan="4"></td>
+19 -7
View File
@@ -73,17 +73,22 @@
<tbody>
@php
$subtotal = "0";
$voucherDiscount = $voucher_redemption ? bcmul((string)$voucher_redemption->value, "-1", 2) : "0";
$displayedSubtotal = 0;
$voucherDiscount = $voucher_redemption ? bcmul((string)$voucher_redemption->value, "-1", 5) : "0";
$displayedSubtotal = "0";
$exactTotal = "0";
@endphp
@foreach ($po_order_transaction->transactionDetails as $key => $transaction_detail)
@php
$exactUnitPrice = bcdiv($transaction_detail->price, $transaction->currency_rate, 7);
$exactUnitPrice = bcdiv($transaction_detail->price, $transaction->currency_rate, 5);
$itemTotal = bcmul($exactUnitPrice, $transaction_detail->quantity, 5);
$displayedItemTotal = bcmul($exactUnitPrice, $transaction_detail->quantity, 2);
// Round half to even for displayed item total
$displayedItemTotal = round(bcmul($exactUnitPrice, $transaction_detail->quantity, 2), 2, PHP_ROUND_HALF_EVEN);
$displayedSubtotal = bcadd($displayedSubtotal, $displayedItemTotal, 2);
$subtotal = bcadd($subtotal, $itemTotal, 5);
$exactTotal = bcadd($exactTotal, $displayedItemTotal, 5);
@endphp
<tr>
<td width="5%" class="center top">{{ $key + 1 }}</td>
@@ -130,10 +135,17 @@
</tr>
@endif
@php
$displayedTotal = bcadd(bcadd(bcadd($subtotal, $transaction->service_charge, 5), $transaction->tax, 5), $voucherDiscount, 5);
// Calculate the totals with 5 decimal places
$expectedTotal = bcadd(bcadd(bcadd($subtotal, $transaction->service_charge, 5), $transaction->tax, 5), $voucherDiscount, 5);
$discrepancy = bcsub($displayedTotal, $expectedTotal, 5);
$total = bcadd(bcadd(bcadd($subtotal, $transaction->service_charge, 5), $transaction->tax, 5), $voucherDiscount, 5);
// Calculate the displayed totals with 2 decimal places
$displayedTotal = bcadd(bcadd(bcadd($displayedSubtotal, $transaction->service_charge, 2), $transaction->tax, 2), $voucherDiscount, 2);
// Calculate the discrepancy
$discrepancy = bcsub($expectedTotal, $displayedTotal, 5);
// Calculate the final total
$total = bcadd($expectedTotal, $discrepancy, 5);
@endphp
<tr>
<td colspan="4"></td>
@@ -91,15 +91,22 @@
<tbody>
@php
$subtotal = "0";
$displayedSubtotal = 0;
$voucherDiscount = $voucher_redemption ? bcmul((string)$voucher_redemption->value, "-1", 5) : "0";
$displayedSubtotal = "0";
$exactTotal = "0";
@endphp
@foreach ($po_order_transaction->transactionDetails as $key => $transaction_detail)
@php
$exactUnitPrice = bcdiv($transaction_detail->price, $transaction->currency_rate, 5);
$itemTotal = bcmul($exactUnitPrice, $transaction_detail->quantity, 5);
$displayedItemTotal = bcmul($exactUnitPrice, $transaction_detail->quantity, 2);
// Round half to even for displayed item total
$displayedItemTotal = round(bcmul($exactUnitPrice, $transaction_detail->quantity, 2), 2, PHP_ROUND_HALF_EVEN);
$displayedSubtotal = bcadd($displayedSubtotal, $displayedItemTotal, 2);
$subtotal = bcadd($subtotal, $itemTotal, 5);
$exactTotal = bcadd($exactTotal, $displayedItemTotal, 5);
@endphp
<tr>
<td width="5%" class="center top">{{ $key + 1 }}</td>
@@ -117,13 +124,7 @@
</tbody>
<tfoot>
@php
$voucherDiscount = $voucher_redemption ? bcmul((string)$voucher_redemption->value, "-1", 2) : "0";
$subtotalWithDiscount = bcsub($subtotal, $voucherDiscount, 5); // Use bcsub to subtract
$displayedTotal = bcadd(bcadd(bcadd($displayedSubtotal, $transaction->service_charge, 2), $transaction->tax, 2), $voucherDiscount, 2);
$expectedTotal = bcadd(bcadd(bcadd($subtotal, $transaction->service_charge, 5), $transaction->tax, 5), $voucherDiscount, 5);
$discrepancy = bcsub($displayedTotal, $expectedTotal, 5);
$total = bcadd(bcadd(bcadd($subtotal, $transaction->service_charge, 5), $transaction->tax, 5), $voucherDiscount, 5); // Keep precision
$subtotal = bcadd($subtotal, $displayedItemTotal, 2);
$subtotalWithDiscount = bcsub($subtotal, $voucherDiscount, 5);
@endphp
<tr class="subtotal">
<td colspan="4"></td>
@@ -151,7 +152,19 @@
<td class="right">{{ number_format($transaction->tax, 2) }}</td>
</tr>
@endif
@php
// Calculate the totals with 5 decimal places
$expectedTotal = bcadd(bcadd(bcadd($subtotal, $transaction->service_charge, 5), $transaction->tax, 5), $voucherDiscount, 5);
// Calculate the displayed totals with 2 decimal places
$displayedTotal = bcadd(bcadd(bcadd($displayedSubtotal, $transaction->service_charge, 2), $transaction->tax, 2), $voucherDiscount, 2);
// Calculate the discrepancy
$discrepancy = bcsub($expectedTotal, $displayedTotal, 5);
// Calculate the final total
$total = bcadd($expectedTotal, $discrepancy, 5);
@endphp
<tr>
<td colspan="4"></td>
<td class="right middle">Adjustment</td>
+2 -2
View File
@@ -125,7 +125,7 @@ Route::get('/transfer/{marking}/latest-invoice', function ($marking) {
$transaction = $booking->transactions()
->where('type', TransactionType::PAYMENT)
->latest()->get()[0];
$supplier = Company::where('id', $transaction->receiver)->first();
$lowercaseDocumentType = strtolower(DocumentType::INVOICE);
@@ -490,7 +490,7 @@ Route::get('/payments/manual', function(){
Route::get('/invoice/fix', function(){
set_time_limit(1800);
set_time_limit(14400);
$bookings = Booking::where('status', ApprovalStatus::COMPLETED)->whereDate('updated_at', '>=', Carbon::parse('01-01-2023'))->get();
foreach($bookings as $booking){