diff --git a/app/Classes/Modules/Transactions/ControllersLogic/FetchCompanyTransactionStatementLogic.php b/app/Classes/Modules/Transactions/ControllersLogic/FetchCompanyTransactionStatementLogic.php index a078a01d..6b596477 100644 --- a/app/Classes/Modules/Transactions/ControllersLogic/FetchCompanyTransactionStatementLogic.php +++ b/app/Classes/Modules/Transactions/ControllersLogic/FetchCompanyTransactionStatementLogic.php @@ -13,6 +13,7 @@ use App\Models\Booking; use App\Models\Company; use App\Models\Transaction; use App\Models\Wallet; +use Illuminate\Support\Facades\DB; class FetchCompanyTransactionStatementLogic extends AbstractControllerLogic { @@ -37,14 +38,15 @@ class FetchCompanyTransactionStatementLogic extends AbstractControllerLogic public function logic(Request $request): JsonResponse { $companyId = $request->route('id'); + $filterArray = json_decode($request->input('filters')); $transactions = Transaction::where(function ($query) use ($companyId) { $query ->where('type', TransactionType::PAYMENT) ->where('owner_type', Booking::class) ->whereIn('status', [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED]) - ->whereHas('booking', function ($query) use ($companyId) { - $query->where('company_id', $companyId); + ->whereHas('booking', function ($q) use ($companyId) { + $q->where('company_id', $companyId); }); }) ->orWhere(function ($query) use ($companyId) { @@ -66,7 +68,83 @@ class FetchCompanyTransactionStatementLogic extends AbstractControllerLogic }) ->whereIn('status', [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED]) ->orderBy('created_at', 'desc') - ->get(); + ->paginate($filterArray->per_page); + + $total_incoming = Transaction::where(function ($query) use ($companyId, $transactions) { + $query->whereHas('owner', function ($query) use ($companyId) { + $query->where('owner_id', $companyId); + $query->where('owner_type', Company::class); + }) + ->where('owner_type', Wallet::class) + ->where('type', '!=', TransactionType::PAYMENT); + }) + ->orWhere(function ($query) use ($companyId, $transactions) { + $query + ->where('type', TransactionType::INVOICE) + ->where('owner_type', Booking::class) + ->whereIn('status', [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED]) + ->whereHas('booking', function ($query) use ($companyId) { + $query->where('company_id', $companyId); + }); + }) + ->sum( + DB::raw( + 'if (transactions.type = 2,(transactions.amount / transactions.currency_rate + transactions.service_charge),transactions.amount)' + ) + ); + + $total_outgoing = Transaction::where(function ($query) use ($companyId, $transactions) { + $query + ->where('type', TransactionType::PAYMENT) + ->where('owner_type', Booking::class) + ->whereIn('status', [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED]) + ->whereHas('booking', function ($query) use ($companyId) { + $query->where('company_id', $companyId); + }); + }) + ->sum('transactions.amount'); + + $currentBalance = $total_incoming - $total_outgoing; + + $incoming = Transaction::where(function ($query) use ($companyId, $transactions) { + $query->whereHas('owner', function ($query) use ($companyId) { + $query->where('owner_id', $companyId); + $query->where('owner_type', Company::class); + }) + ->where('owner_type', Wallet::class) + ->where('type', '!=', TransactionType::PAYMENT) + ->where('id', '>', $transactions->first()->id); + }) + ->orWhere(function ($query) use ($companyId, $transactions) { + $query + ->where('type', TransactionType::INVOICE) + ->where('owner_type', Booking::class) + ->whereIn('status', [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED]) + ->whereHas('booking', function ($query) use ($companyId) { + $query->where('company_id', $companyId); + }) + ->where('id', '>', $transactions->first()->id); + }) + ->sum( + DB::raw( + 'if (transactions.type = 2,(transactions.amount / transactions.currency_rate + transactions.service_charge),transactions.amount)' + ) + ); + + $outgoing = Transaction::where(function ($query) use ($companyId, $transactions) { + $query + ->where('type', TransactionType::PAYMENT) + ->where('owner_type', Booking::class) + ->whereIn('status', [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED]) + ->whereHas('booking', function ($query) use ($companyId) { + $query->where('company_id', $companyId); + }) + ->where('id', '>', $transactions->first()->id); + }) + ->sum('transactions.amount'); + + $runningBalanceInReverse = $currentBalance - $incoming + $outgoing; + $request['running_balance'] = $runningBalanceInReverse; return $this->collectionResponse(PaymentTransactionResource::collection($transactions)); } diff --git a/app/Http/Controllers/Exports/ExportCustomersAccountStatementTransactionToPDFController.php b/app/Http/Controllers/Exports/ExportCustomersAccountStatementTransactionToPDFController.php new file mode 100644 index 00000000..2ab8f4a7 --- /dev/null +++ b/app/Http/Controllers/Exports/ExportCustomersAccountStatementTransactionToPDFController.php @@ -0,0 +1,110 @@ +headers->set('Authorization', 'Bearer ' . $token); + } + + public function export(Request $request) + { + ini_set('max_execution_time', '1000000'); + ini_set("pcre.backtrack_limit", "5000000"); + + $companyId = $request->route('id'); + $company = Company::find($companyId); + + $transactions = Transaction::where(function ($query) use ($companyId) { + $query + ->where('type', TransactionType::PAYMENT) + ->where('owner_type', Booking::class) + ->whereIn('status', [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED]) + ->whereHas('booking', function ($q) use ($companyId) { + $q->where('company_id', $companyId); + }); + }) + ->orWhere(function ($query) use ($companyId) { + $query->whereHas('owner', function ($query) use ($companyId) { + $query->where('owner_id', $companyId); + $query->where('owner_type', Company::class); + }) + ->where('owner_type', Wallet::class) + ->where('type', '!=', TransactionType::PAYMENT); + }) + ->orWhere(function ($query) use ($companyId) { + $query + ->where('type', TransactionType::INVOICE) + ->where('owner_type', Booking::class) + ->whereIn('status', [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED]) + ->whereHas('booking', function ($query) use ($companyId) { + $query->where('company_id', $companyId); + }); + }) + ->whereIn('status', [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED]) + ->orderBy('created_at', 'desc') + ->get(); + + $total_incoming = Transaction::where(function ($query) use ($companyId, $transactions) { + $query->whereHas('owner', function ($query) use ($companyId) { + $query->where('owner_id', $companyId); + $query->where('owner_type', Company::class); + }) + ->where('owner_type', Wallet::class) + ->where('type', '!=', TransactionType::PAYMENT); + }) + ->orWhere(function ($query) use ($companyId, $transactions) { + $query + ->where('type', TransactionType::INVOICE) + ->where('owner_type', Booking::class) + ->whereIn('status', [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED]) + ->whereHas('booking', function ($query) use ($companyId) { + $query->where('company_id', $companyId); + }); + }) + ->sum( + DB::raw( + 'if (transactions.type = 2,(transactions.amount / transactions.currency_rate + transactions.service_charge),transactions.amount)' + ) + ); + + $total_outgoing = Transaction::where(function ($query) use ($companyId) { + $query + ->where('type', TransactionType::PAYMENT) + ->where('owner_type', Booking::class) + ->whereIn('status', [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED]) + ->whereHas('booking', function ($query) use ($companyId) { + $query->where('company_id', $companyId); + }); + }) + ->sum('transactions.amount'); + + $currentBalance = $total_incoming - $total_outgoing; + + $pdf = LaravelMpdf::loadView('pages.pdfs.company_account_statement_transaction', ['transactions' => $transactions, 'runningBalance' => $currentBalance, 'company' => $company, 'isPrecise' => $request->route('is_precise') == 'true']); + + return $pdf->download("test.pdf"); + } +} diff --git a/app/Http/Resources/PaymentTransactionResource.php b/app/Http/Resources/PaymentTransactionResource.php index 456ece3d..76ec697d 100644 --- a/app/Http/Resources/PaymentTransactionResource.php +++ b/app/Http/Resources/PaymentTransactionResource.php @@ -20,6 +20,22 @@ class PaymentTransactionResource extends JsonResource { $booking = in_array((int)$this->type, [TransactionType::BILL, TransactionType::REFUND])? $this->owner->owner : $this->owner; + $current_running_balance = $request['running_balance']; + + switch((int) $this->type){ + case 1: + $request['running_balance'] = bcadd($request['running_balance'], $this->amount, 7); + break; + case 2: + $request['running_balance'] = bcsub($request['running_balance'], $this->amount / $this->currency_rate + $this->service_charge, 7); + break; + case 5: + $request['running_balance'] = bcsub($request['running_balance'], $this->amount, 7); + break; + case 9: + $request['running_balance'] = bcsub($request['running_balance'], $this->amount, 7); + break; + } $booking_marking = ''; switch ($this->owner_type) { @@ -43,6 +59,7 @@ class PaymentTransactionResource extends JsonResource 'issuer_id' => $this->issuerCompany->id, 'amount' => (double) $this->amount, 'original_amount' => (double) $this->original_amount, + 'running_balance' => (double) $current_running_balance, 'currency' => new CurrencyResource($this->currency), 'original_currency' => new CurrencyResource($this->original_currency), 'service_charge' => (double) $this->service_charge, diff --git a/resources/assets/vue/components/bookings/elements/CustomerAccountStatementTransactionSectionComponent.vue b/resources/assets/vue/components/bookings/elements/CustomerAccountStatementTransactionSectionComponent.vue new file mode 100644 index 00000000..8050bce2 --- /dev/null +++ b/resources/assets/vue/components/bookings/elements/CustomerAccountStatementTransactionSectionComponent.vue @@ -0,0 +1,64 @@ + + \ No newline at end of file diff --git a/resources/assets/vue/components/bookings/elements/CustomerTransactionHistorySectionComponent.vue b/resources/assets/vue/components/bookings/elements/CustomerTransactionHistorySectionComponent.vue index d1448193..d5f28370 100644 --- a/resources/assets/vue/components/bookings/elements/CustomerTransactionHistorySectionComponent.vue +++ b/resources/assets/vue/components/bookings/elements/CustomerTransactionHistorySectionComponent.vue @@ -2,14 +2,28 @@
-
+
Account Statement - Transaction History
-
+
+
+
+ {{ showingPreciseAmount ? 'Showing Precise Wallet Transaction' : 'Show Precise Wallet Transaction'}} + {{ showingPreciseAmount ? 'Download Precise Transaction' : 'Download Transaction'}} +
+
+
+ + + + +
+
+
Date
@@ -20,7 +34,13 @@
Balance
-
+ + + + +
@@ -46,15 +66,21 @@ export default { }, data(){ return { + key: 1, section: 'customerTransactionSection', - isLoading: true, + isLoading: false, transaction: null, - attention: false + attention: false, + showingPreciseAmount: false, + showingTransactionCount: 10, + options: { + per_page: this.showingTransactionCount + } } }, computed: { pendingQueue () { - return this.$store.getters.isInCompleteQueue(this.section); + // return this.$store.getters.isInCompleteQueue(this.section); } }, watch: { @@ -62,8 +88,15 @@ export default { if(inComplete){ this.fetchTransaction(); } + }, + showingTransactionCount() { + this.options.per_page = this.showingTransactionCount + this.key ++; } }, + validations: { + showingTransactionCount: { }, + }, created(){ this.$store.dispatch('updateListQueue', {'name': this.section}); }, diff --git a/resources/views/pages/pdfs/company_account_statement_transaction.blade.php b/resources/views/pages/pdfs/company_account_statement_transaction.blade.php new file mode 100644 index 00000000..fbbf21ac --- /dev/null +++ b/resources/views/pages/pdfs/company_account_statement_transaction.blade.php @@ -0,0 +1,123 @@ +@extends('layouts.base_pdf') + +@section('inner_content') + +
+ +

+
{{ $company->reference }}
+
+ + + + + + + + + + + +
+ CIEF WORLDWIDE SDN BHD + (1134596-M)
+ No. 72-3, Jalan Jalil 1,
+ The Earth Bukit Jalil,
+ 57000 Kuala Lumpur
+ Tel: 03-8082 1252 +
+
Account Statement Transactions
+
 
+
+
{{ $company->name }}
+
+ +
+
+ + + + + + + + + + + + + + + + @php + $roundOff = 2; + if ($isPrecise) { + $roundOff = 5; + } + @endphp + @foreach ($transactions as $key => $transaction) + @php + $description = ""; + $incoming = ""; + $outgoing = ""; + $current_running_balance = $runningBalance; + $marking = ""; + + switch ($transaction->type) { + case 1: + $description = "Payment - " . $transaction->payment_reference; + $outgoing = number_format($transaction->amount, $roundOff); + $runningBalance = bcadd($runningBalance, $transaction->amount, 7); + $marking = $transaction->owner->marking; + break; + case 2: + $description = "Invoice"; + $incoming = number_format(($transaction->amount / $transaction->currency_rate + $transaction->service_charge), $roundOff); + $runningBalance = bcsub($runningBalance, $transaction->amount, 7); + $marking = $transaction->owner->marking; + break; + case 5: + $description = "Top Up - " . $transaction->payment_reference; + $incoming = number_format($transaction->amount, $roundOff); + $runningBalance = bcsub($runningBalance, $transaction->amount, 7); + break; + case 9: + $description = "Credit Note - " . $transaction->payment_reference; + $incoming = number_format($transaction->amount, $roundOff); + $runningBalance = bcsub($runningBalance, $transaction->amount, 7); + break; + } + + + @endphp + + + + + + + + + + @endforeach + +
NoDateDescriptionMarkingIncomingOutgoingBalance
(RM)
{{ $key + 1 }}{{ $transaction->created_at }}{{ $description }}{{ $marking }} + {{ $incoming }} + + {{ $outgoing }} + + {{ number_format($current_running_balance, $roundOff) }} +
+ +
+ + + + + + +
This is generated by computer. No signature required.Page {PAGENO} of {nbpg}
+
+@endsection diff --git a/routes/web.php b/routes/web.php index 989d3296..3723cf6b 100644 --- a/routes/web.php +++ b/routes/web.php @@ -238,6 +238,7 @@ Route::get('/wallet/{marking}/details', function ($marking) { })->name('wallet.details'); Route::get('/wallet/{marking}/{is_precise}/export', 'Exports\ExportCustomersWalletTransactionToExcelController@export')->name('wallet.details-export'); +Route::get('/company/{id}/{is_precise}/transaction/export', 'Exports\ExportCustomersAccountStatementTransactionToPDFController@export')->name('company.transaction.export'); Route::get('/wallets', function () { return view('pages.wallet.wallets');