diff --git a/app/Classes/General/Eloquent/Filters/IsMapped.php b/app/Classes/General/Eloquent/Filters/IsMapped.php
new file mode 100644
index 00000000..12282d3b
--- /dev/null
+++ b/app/Classes/General/Eloquent/Filters/IsMapped.php
@@ -0,0 +1,20 @@
+whereHas('owners') : $builder->whereDoesntHave('owners');
+ }
+
+}
diff --git a/app/Classes/General/Eloquent/Filters/IsMappedWithMultiple.php b/app/Classes/General/Eloquent/Filters/IsMappedWithMultiple.php
new file mode 100644
index 00000000..066fa6ef
--- /dev/null
+++ b/app/Classes/General/Eloquent/Filters/IsMappedWithMultiple.php
@@ -0,0 +1,20 @@
+has('owners', '>', 1) : $builder->has('owners', '=',1);
+ }
+
+}
diff --git a/app/Classes/General/Eloquent/Filters/MaxAmount.php b/app/Classes/General/Eloquent/Filters/MaxAmount.php
new file mode 100644
index 00000000..3a0476c8
--- /dev/null
+++ b/app/Classes/General/Eloquent/Filters/MaxAmount.php
@@ -0,0 +1,20 @@
+where('amount', '<=', $value);
+ }
+
+}
diff --git a/app/Classes/General/Eloquent/Filters/MinAmount.php b/app/Classes/General/Eloquent/Filters/MinAmount.php
new file mode 100644
index 00000000..52b72636
--- /dev/null
+++ b/app/Classes/General/Eloquent/Filters/MinAmount.php
@@ -0,0 +1,20 @@
+where('amount', '>=', $value);
+ }
+
+}
diff --git a/app/Classes/General/Eloquent/Filters/StatementTransactionAccountId.php b/app/Classes/General/Eloquent/Filters/StatementTransactionAccountId.php
new file mode 100644
index 00000000..b07bede9
--- /dev/null
+++ b/app/Classes/General/Eloquent/Filters/StatementTransactionAccountId.php
@@ -0,0 +1,22 @@
+whereHas('account', function ($query) use ($value) {
+ $query->where('statement_accounts.id', $value);
+ });
+ }
+}
diff --git a/app/Classes/General/Eloquent/Filters/StatementTransactionOwnerStatusIn.php b/app/Classes/General/Eloquent/Filters/StatementTransactionOwnerStatusIn.php
new file mode 100644
index 00000000..e309cd4d
--- /dev/null
+++ b/app/Classes/General/Eloquent/Filters/StatementTransactionOwnerStatusIn.php
@@ -0,0 +1,22 @@
+whereHas('owners', function ($query) use ($value) {
+ return $query->whereIn('status', $value);
+ });
+ }
+
+}
diff --git a/app/Classes/General/Eloquent/Filters/StatementTransactionOwnerTypeIn.php b/app/Classes/General/Eloquent/Filters/StatementTransactionOwnerTypeIn.php
new file mode 100644
index 00000000..e23d0bcc
--- /dev/null
+++ b/app/Classes/General/Eloquent/Filters/StatementTransactionOwnerTypeIn.php
@@ -0,0 +1,22 @@
+whereHas('owners', function ($query) use ($value) {
+ return $query->whereIn('type', $value);
+ });
+ }
+
+}
diff --git a/app/Classes/Jobs/CreateBankStatementDetails.php b/app/Classes/Jobs/CreateBankStatementTransactionOwners.php
similarity index 53%
rename from app/Classes/Jobs/CreateBankStatementDetails.php
rename to app/Classes/Jobs/CreateBankStatementTransactionOwners.php
index 9d12c6ba..e7797210 100644
--- a/app/Classes/Jobs/CreateBankStatementDetails.php
+++ b/app/Classes/Jobs/CreateBankStatementTransactionOwners.php
@@ -2,33 +2,20 @@
namespace App\Classes\Jobs;
-use App\Classes\Modules\Accounting\Processors\CreateBankStatementDetailsProcessor;
+use App\Classes\Modules\Accounting\Processors\CreateBankStatementTransactionOwnersProcessor;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
-use App\Models\AccountStatement;
-class CreateBankStatementDetails implements ShouldQueue
+class CreateBankStatementTransactionOwners implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
- /** @var AccountStatement $statement*/
- private $statement;
-
- /**
- * CreateBankStatementDetails constructor.
- * @param AccountStatement $statement
- */
- public function __construct(AccountStatement $statement)
- {
- $this->statement = $statement;
- }
-
public function handle()
{
- (App()->make(CreateBankStatementDetailsProcessor::class))->execute($this->statement);
+ (App()->make(CreateBankStatementTransactionOwnersProcessor::class))->execute();
}
public function delay($delay)
diff --git a/app/Classes/Modules/Accounting/ControllersLogic/ImportBankStatementLogic.php b/app/Classes/Modules/Accounting/ControllersLogic/ImportBankStatementLogic.php
new file mode 100644
index 00000000..b7f737da
--- /dev/null
+++ b/app/Classes/Modules/Accounting/ControllersLogic/ImportBankStatementLogic.php
@@ -0,0 +1,147 @@
+ 'Import Bank Statement Transactions Details',
+ 'message' => 'You have successfully updated the Bank Statement Transactions Details'
+ ];
+ }
+
+
+ /**
+ * @param Request $request
+ * @return JsonResponse
+ * @throws MalformedRequestException
+ */
+ public function logic(Request $request) : JsonResponse
+ {
+
+ $files = $request->file('files');
+
+ $object = new DocumentObject('', $request->input('files'), '', ApprovalStatus::APPROVED, 'imports');
+ foreach ($object->getFiles() as $file){
+ $collection = Excel::toCollection(null, json_decode($file)->file_info->original->file, null, null, true);
+
+ $sheet = $collection->first()->skip(1);
+
+ $statementDetails = $sheet->first();
+
+ $accountNumber = $statementDetails[0];
+ $accountType = $statementDetails[1];
+ $accountName = $statementDetails[2];
+ $accountCurrency = $statementDetails[3];
+ $dateFrom = carbon::parse(str_replace(' MY (UTC+08:00)', '', $statementDetails[4]));
+ $dateTo = carbon::parse(str_replace(' MY (UTC+08:00)', '', $statementDetails[5]));
+ $totalDebit = $statementDetails[6];
+ $totalCredit = $statementDetails[7];
+ $beginBalance = $statementDetails[8];
+ $endBalance = $statementDetails[9];
+ $account = StatementAccount::updateOrCreate(
+ ['number' => $accountNumber],
+ [
+ 'type' => $accountType,
+ 'name' => $accountName,
+ 'currency' => $accountCurrency,
+ ]
+ );
+
+ $statement = AccountStatement::where('date_from', $dateFrom)
+ ->where('date_to', $dateTo)
+ ->where('total_amount', $totalDebit ?: $totalCredit,)
+ ->where('begin_balance', $beginBalance)
+ ->where('end_balance', $endBalance)->first();
+
+
+ if(!$statement){
+ $statement = new AccountStatement([
+ 'date_from' => $dateFrom,
+ 'date_to' => $dateTo,
+ 'total_amount' => $totalDebit ?: $totalCredit,
+ 'begin_balance' => $beginBalance,
+ 'end_balance' => $endBalance,
+ ]);
+ }
+
+ $account->statements()->save($statement);
+
+ CreateBankStatementTransactionOwners::dispatch($statement);
+
+
+ $sheet->map(function ($row) use ($statement, $account) {
+ $transactionRef = $row[15];
+ $amount = $row[17] !== '-' ? ((float) str_replace(',', '', $row[17])) : (-((float) str_replace(',', '', $row[16])));
+ $transactionDate = $row[10] !== '-' ? carbon::parse(str_replace(' MY (UTC+08:00)', '', $row[10]) . $row[11]) : null;
+ $postingDate = carbon::createFromFormat('d/M/Y H:i', str_replace(' MY (UTC+08:00)', '', $row[12]) . str_replace(' MY (UTC+08:00)', '', $row[13]));
+ $transactionDescription = is_numeric($row[14]) ? (int) sprintf('%.2f', $row[14]) : $row[14];
+ $tellerId = $row[19];
+ $branchChannel = $row[20];
+ $transactionCode = $row[21];
+ $endBalance = $row[22];
+ $description2 = $row[25];
+ $description3 = $row[26];
+ $description4 = $row[27];
+ $description5 = $row[28];
+ $transaction = new StatementTransaction([
+ 'transaction_ref' => $transactionRef,
+ 'amount' => $amount,
+ 'transaction_date' => $transactionDate,
+ 'posting_date' => $postingDate,
+ 'transaction_description' => $transactionDescription,
+ 'teller_id' => $tellerId,
+ 'branch_channel' => $branchChannel,
+ 'transaction_code' => $transactionCode,
+ 'end_balance' => $endBalance,
+ 'transaction_description_2' => $description2,
+ 'transaction_description_3' => $description3,
+ 'transaction_description_4' => $description4,
+ 'transaction_description_5' => $description5,
+ ]);
+
+ // Check if the transaction already exists for this statement
+ $existingTransaction = StatementTransaction::where('transaction_ref', $transactionRef)
+ ->where('posting_date', $postingDate)
+ ->where('amount', $amount)
+ ->where('transaction_description', $transactionDescription)
+ ->where('teller_id', $tellerId)
+ ->where('branch_channel', $branchChannel)
+ ->where('transaction_code', $transactionCode)
+ ->where('end_balance', $endBalance)
+ ->first();
+
+ if (!$existingTransaction) {
+ $statement->transactions()->save($transaction);
+ }
+
+ return $transaction;
+ });
+ }
+
+
+
+ return $this->response([]);
+
+ }
+
+}
diff --git a/app/Classes/Modules/Accounting/ControllersLogic/ListBankStatementTransactionsLogic.php b/app/Classes/Modules/Accounting/ControllersLogic/ListBankStatementTransactionsLogic.php
new file mode 100644
index 00000000..3d2b8273
--- /dev/null
+++ b/app/Classes/Modules/Accounting/ControllersLogic/ListBankStatementTransactionsLogic.php
@@ -0,0 +1,53 @@
+ 'Retrieved Bank Statement Transactions',
+ 'message' => 'You have successfully retrieved a Bank Statement Transactions'
+ ];
+ }
+
+
+ /** @var ListsBankStatementTransactions */
+ private $listsBankStatementTransactions;
+
+ /**
+ * @param ListsBankStatementTransactions $listsBankStatementTransactions
+ */
+ public function __construct(ListsBankStatementTransactions $listsBankStatementTransactions)
+ {
+ $this->listsBankStatementTransactions = $listsBankStatementTransactions;
+ }
+
+ /**
+ * @param Request $request
+ * @return JsonResponse
+ * @throws ErrorException
+ */
+ public function logic(Request $request) : JsonResponse
+ {
+ $query = $this->listsBankStatementTransactions->execute($this->listsBankStatementTransactions->deserializeFilters($request->input('filters')));
+
+ return $this->collectionResponse(BankStatementTransactionResource::collection($query));
+ }
+
+}
diff --git a/app/Classes/Modules/Accounting/ControllersLogic/UpdateBankStatementDetailLogic.php b/app/Classes/Modules/Accounting/ControllersLogic/UpdateBankStatementDetailLogic.php
index bbdeef35..f29bd627 100644
--- a/app/Classes/Modules/Accounting/ControllersLogic/UpdateBankStatementDetailLogic.php
+++ b/app/Classes/Modules/Accounting/ControllersLogic/UpdateBankStatementDetailLogic.php
@@ -56,8 +56,6 @@ class UpdateBankStatementDetailLogic extends AbstractControllerLogic
{
$object = new BankStatementDetailObject($request->input('pay_for'), $request->input('system_references'));
- // $this->canUpdateCompany->passes($object);
-
$query = $this->fetchesBankStatementDetails->execute(['id' => $request->route('id')]);
$query = $this->updatesBankStatementDetails->execute($query, $object);
diff --git a/app/Classes/Modules/Accounting/Processors/CreateBankStatementDetailsProcessor.php b/app/Classes/Modules/Accounting/Processors/CreateBankStatementDetailsProcessor.php
deleted file mode 100644
index a978fb33..00000000
--- a/app/Classes/Modules/Accounting/Processors/CreateBankStatementDetailsProcessor.php
+++ /dev/null
@@ -1,212 +0,0 @@
-transactions();
- $transactions = $transactions->get();
-
- $headers = [
- 'Date',
- 'Bank',
- 'Description',
- 'Credit',
- 'Debit',
- 'Pay For',
- 'System',
- 'System Reference',
- 'Human Reference',
- 'Multiple',
- 'Match?',
- 'System Amount'
- ];
-
- $branches = [
- 0 => 'MBB Cyber',
- 1 => 'MBB SS2',
- ];
-
- $yes = 'Yes';
- $no = 'No';
-
- $table = '
'.implode(' ', $headers).' ';
- $count = 0;
-
- foreach ($transactions as $row) {
- $existingRecord = StatementTransactionsDetail::where('statement_transaction_id', $row->id)->first();
- if ($existingRecord && $existingRecord->pay_for != "") {
- continue;
- }
-
- $count++;
- $credit = 0.00;
- $debit = 0.00;
-
- $date = new DateTime($row['posting_date']);
- $description = $row['transaction_description_2'];
-
- if($row['amount'] < 0){
- $debit = (float) $row['amount'];
- }
- else{
- $credit = (float) $row['amount'];
- }
-
- $creditTransactions = [];
- $debitTransactions = [];
-
- $system = [];
- $systemReference = null;
- $systemAmount = null;
-
- if($credit){
- $creditTransactions = $this->getTransactions($date, $credit, TransactionType::PAYMENT, Booking::class, PaymentMethodType::WALLET, [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED]);
- foreach ($creditTransactions as $transaction) {
- $systemReference[] = $transaction->owner instanceof Booking ? $transaction->owner->marking : $transaction->bill_no;
- $systemAmount[] = $transaction->amount;
- $system[] = 'EXCHANGE';
- }
-
- $creditTransactions = $this->getTransactions($date, $credit, TransactionType::TOP_UP, Wallet::class, null, [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED]);
- foreach ($creditTransactions as $transaction) {
- $systemReference[] = $transaction->owner instanceof Booking ? $transaction->owner->marking : $transaction->bill_no;
- $systemAmount[] = $transaction->amount;
- $system[] = 'EXCHANGE';
- }
-
- $creditTransactions = $this->getTransactionsFromShippingPortal($credit, $this->getDateRange($row['posting_date']));
- foreach ($creditTransactions as $transaction) {
- $systemReference[] = $transaction['order']['reference'];
- $systemAmount[] = $transaction['amount'];
- $system[] = 'SHIPPING';
- }
- }
-
- if($debit){
- $debitTransactions = $this->getTransactions($date, $debit, null, null, null, [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED], Group::class);
-
- if(!count($debitTransactions)) {
- foreach (['YSN', 'HCK', 'ATVANTIC', 'HIGH HILL'] as $reference){
- if(str_contains($description, $reference)) {
- $paymentDate = date('Y-m-d', strtotime('+1 day', strtotime($row['posting_date']))); //$date->addDays(1)->format('Y-m-d');
-
- if($reference = 'ATVANTIC'){
- $paymentDate = date('Y-m-d', strtotime($row['posting_date']));//$date->format('Y-m-d');
- }
- $issuer = Company::where('name', 'like', '%'.$reference.'%')->get()->pluck('id');
- $debitTransactions = Group::whereIn('issuer', $issuer)->whereDate('created_at', $paymentDate)->get();
- break;
- }
- }
-
- }
-
- foreach ($debitTransactions as $transaction) {
- $systemReference[] = $transaction->reference;
- $systemAmount[] = $transaction->amount;
- $system[] = 'EXCHANGE';
- }
- }
-
-
- $multiple = count($creditTransactions) + count($debitTransactions) > 1 ? $yes : $no;
-
- $systemReference = $systemReference ? implode(',', $systemReference) : null;
- $systemAmount = $systemAmount ? implode(',', $systemAmount) : null;
- $system = $system ? implode(',', $system) : null;
-
- $matches = $systemReference == $row['remarkreferences'] ? $yes : $no;
-
- StatementTransactionsDetail::updateOrCreate(
- ['statement_transaction_id' => $row->id],
- [
- 'date' => $date,
- 'pay_for' => is_null($system) ? "" : $system,
- 'system_references' => is_null($systemReference) ? "" : $systemReference,
- 'system_amounts'=> is_null($systemAmount) ? "" : $systemAmount,
- 'remark_references'=> is_null($row['remarkreferences']) ? "" : $row['remarkreferences'],
- ]
- );
-
- // if($count == 10){
- // break;
- // }
- }
- }
-
- private function getTransactions($date, $amount, $type, $ownerType, $paymentMethod, $statuses, $model = Transaction::class) {
- $query = $model::whereIn('status', $statuses)
- ->where(function ($query) use ($ownerType, $paymentMethod, $type) {
- if ($ownerType) {
- $query->where('owner_type', $ownerType);
- }
-
- if ($paymentMethod) {
- $query->where('payment_method', '!=', $paymentMethod);
- }
-
- if ($type) {
- $query->where('type', $type);
- }
- })
- ->whereDate('created_at', $date->format('Y-m-d'))
- ->where('amount', '>', ($amount - 0.01))
- ->where('amount', '<', ($amount + 0.01));
-
- return $query->get();
- }
-
- private function getTransactionsFromShippingPortal($amount, $dateRange){
- try{
-
- $client = new \GuzzleHttp\Client();
- $response = $client->request('GET', 'https://izyim.cief-malaysia.com/public/api/v1/list?api-key=510acd13d8d24375cf038ad626c282565451461a9c2399357e0b65365300787e&filters={"order_by":{"column":"id","DESC":true},"status_in":[2],"type":2,"created_after":"'.$dateRange['start_date'].'","created_before":"'.$dateRange['end_date'].'","amount_exceed":'.($amount - 0.01).',"amount_short":'.($amount + 0.01).'}');
- $body = $response->getBody();
- $data = json_decode($body, true);
- $payload = $data['payload'];
- $transactions2 = $payload['data'];
- return $transactions2;
- }catch(\Exception $exception){
- Log::error($exception);
- return [];
- }
- }
-
- private function getDateRange(string $dateStr) {
- // Create a DateTime object from the input string
- $date = strtotime($dateStr);
-
- // Get the first day of the month
- $today = date('Y-m-d', $date);
-
- // Get the first day of the next month
- $nextDay = date('Y-m-d', strtotime('+1 day', $date));
-
- return [
- 'start_date' => $today,
- 'end_date' => $nextDay,
- ];
- }
-}
diff --git a/app/Classes/Modules/Accounting/Processors/CreateBankStatementTransactionOwnersProcessor.php b/app/Classes/Modules/Accounting/Processors/CreateBankStatementTransactionOwnersProcessor.php
new file mode 100644
index 00000000..f3d61595
--- /dev/null
+++ b/app/Classes/Modules/Accounting/Processors/CreateBankStatementTransactionOwnersProcessor.php
@@ -0,0 +1,275 @@
+whereIn('status', [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED]);
+// })->get();
+
+ $transactions = StatementTransaction::whereDoesntHave('owners')->where('amount', '<', 0)->get();
+
+ foreach ($transactions as $transaction) {
+
+ if($transaction->amount > 0){
+
+ // Exchange Sales
+ $creditTransactions = $this->getTransactions($transaction->posting_date, $transaction->amount, TransactionType::PAYMENT, Booking::class, PaymentMethodType::WALLET, [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED]);
+ foreach ($creditTransactions as $creditTransaction) {
+ $transaction->owners()->firstOrCreate([
+ 'type' => StatementTransactionOwnerType::SALES,
+ 'system' => 'EXCHANGE',
+ 'owner_type' => Transaction::class,
+ 'owner_id'=> $creditTransaction->id,
+ ]);
+ }
+
+
+ // Shipping Portal Sales
+ $creditTransactions = $this->getTransactionsFromShippingPortal($transaction->amount, $this->getDateRange($transaction->posting_date));
+ foreach ($creditTransactions as $creditTransaction) {
+ $transaction->owners()->firstOrCreate([
+ 'type' => StatementTransactionOwnerType::SALES,
+ 'system' => 'SHIPPING_PORTAL',
+ 'owner_type' => Transaction::class,
+ 'owner_id'=> $creditTransaction['id'],
+ ]);
+ }
+
+ // Exchange Wallet Top Up
+ $creditTransactions = $this->getTransactions($transaction->posting_date, $transaction->amount, TransactionType::TOP_UP, Wallet::class, null, [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED]);
+ foreach ($creditTransactions as $creditTransaction) {
+ $transaction->owners()->firstOrCreate([
+ 'type' => StatementTransactionOwnerType::WALLET_TOP_UP,
+ 'system' => 'EXCHANGE',
+ 'owner_type' => Transaction::class,
+ 'owner_id'=> $creditTransaction->id,
+ ]);
+ }
+
+ // fpx charge refund
+ if($transaction->transaction_description === 'DUITNOW S/CHRG REFUND'){
+ $transaction->owners()->firstOrCreate([
+ 'type' => StatementTransactionOwnerType::FPX_CHARGE_REFUND
+ ]);
+ }
+
+ // Customer Refund
+
+ // INTERNAL_BANK_TRANSFER_IN
+ if(str_contains($transaction->transaction_description_2, 'CIEF WORLDWIDE')){
+ $transaction->owners()->firstOrCreate([
+ 'type' => StatementTransactionOwnerType::INTERNAL_BANK_TRANSFER_IN
+ ]);
+ }
+
+
+ }
+
+ if($transaction->amount < 0){
+
+ // Supplier Purchase Order Payments
+ foreach (['YSN', 'HCK', 'ATVANTIC', 'HIGH HILL'] as $reference){
+ if(str_contains($transaction->transaction_description.' '.$transaction->transaction_description_2.' '.$transaction->transaction_description_3.' '.$transaction->transaction_description_4.' '.$transaction->transaction_description_5 , $reference)) {
+ $paymentDateStart = $transaction->posting_date->startOfDay()->subDays(1);
+ $paymentDateEnd = $transaction->posting_date->endOfDay();
+
+ if($paymentDateStart->dayOfWeek === Carbon::SUNDAY){
+ $paymentDateStart->subDays(2);
+ }
+ $issuer = Company::where('name', 'like', '%'.$reference.'%')->get()->pluck('id');
+
+ $debitTransactions = Group::whereIn('issuer', $issuer)->where('amount', '>=', (($transaction->amount * -1) - 0.01))
+ ->where('amount', '<=', (($transaction->amount * -1) + 0.01))->whereDate('created_at', '>=', $paymentDateStart)->whereDate('created_at', '<=', $paymentDateEnd)->get();
+
+ foreach ($debitTransactions as $debitTransaction) {
+ $transaction->owners()->firstOrCreate([
+ 'type' => StatementTransactionOwnerType::SUPPLIER_PAYMENT,
+ 'system' => 'EXCHANGE',
+ 'owner_type' => Group::class,
+ 'owner_id'=> $debitTransaction->id,
+ ]);
+ }
+
+ }
+ }
+
+ // Exchange Wallet Withdrawal
+ $debitTransactions = $this->getTransactions($transaction->posting_date, $transaction->amount, TransactionType::DEBIT_NOTE, Wallet::class, null, [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED]);
+ foreach ($debitTransactions as $debitTransaction) {
+ $transaction->owners()->firstOrCreate([
+ 'type' => StatementTransactionOwnerType::WALLET_WITHDRAWAL,
+ 'system' => 'EXCHANGE',
+ 'owner_type' => Transaction::class,
+ 'owner_id'=> $debitTransaction->id,
+ ]);
+ }
+
+ // SALARY
+
+ // STATUTORY
+ if(str_contains($transaction->transaction_description_2, 'PEMBANGUNAN SUMBER') || str_contains($transaction->transaction_description_2, 'HASIL') || str_contains($transaction->transaction_description_2, 'PERTUBUHAN KESELAMAT') || str_contains($transaction->transaction_description_2, 'KUMPULAN WANG SIMPAN')){
+ $transaction->owners()->firstOrCreate([
+ 'type' => StatementTransactionOwnerType::STATUTORY
+ ]);
+ }
+
+ // FPX_CHARGE
+ if($transaction->transaction_description === 'DR DUITNOW S/CHRG' || str_contains($transaction->transaction_description, 'Manual FPX') || str_contains($transaction->transaction_description, 'CMS - DR FPX CHG')){
+ $transaction->owners()->firstOrCreate([
+ 'type' => StatementTransactionOwnerType::FPX_CHARGE
+ ]);
+ }
+
+ // BANK_CHARGE
+ if($transaction->transaction_description === 'CMS - DR CORP CHG' || $transaction->transaction_description === 'MONTHLY PROFIT DEBIT'){
+ $transaction->owners()->firstOrCreate([
+ 'type' => StatementTransactionOwnerType::BANK_CHARGE
+ ]);
+ }
+
+ // CREDIT_CARD_PAYMENT
+ if(str_contains($transaction->transaction_description_2, 'VISA CARD')){
+ $transaction->owners()->firstOrCreate([
+ 'type' => StatementTransactionOwnerType::CREDIT_CARD_PAYMENT
+ ]);
+ }
+
+ // INTERNAL_BANK_TRANSFER_OUT
+ if(str_contains($transaction->transaction_description_2, 'CIEF WORLDWIDE') || str_contains($transaction->transaction_description_2, 'CIEF WORLWIDE') || str_contains($transaction->transaction_description_2, 'IZYIM GLOBAL')){
+ $transaction->owners()->firstOrCreate([
+ 'type' => StatementTransactionOwnerType::INTERNAL_BANK_TRANSFER_OUT
+ ]);
+ }
+
+ // non-operational charges
+ if(str_contains($transaction->transaction_description_2, 'HIRE PURCHASE') || str_contains($transaction->transaction_description_2, 'TENAGA NASIONAL') || str_contains($transaction->transaction_description, 'CABLE CHARGE') || str_contains($transaction->transaction_description_2, 'CTOS DATA SYSTEMS') || str_contains($transaction->transaction_description_2, 'MAXIS')){
+ $transaction->owners()->firstOrCreate([
+ 'type' => StatementTransactionOwnerType::NON_OPERATIONAL
+ ]);
+ }
+ }
+ }
+ }
+
+ public function get(int $statementTransactionId){
+
+ $owners = [
+ 'data' => []
+ ];
+
+ $statementTransaction = StatementTransaction::find($statementTransactionId);
+
+ if($statementTransaction->amount > 0) {
+ $creditTransactions = $this->getTransactions($statementTransaction->posting_date, $statementTransaction->amount, TransactionType::PAYMENT, Booking::class, PaymentMethodType::WALLET, [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED]);
+ foreach ($creditTransactions as $transaction) {
+ $owners['data'][] = [
+ 'system' => 'EXCHANGE',
+ 'owner_type' => Transaction::class,
+ 'owner_id' => $transaction->id,
+ 'bill_no' => $transaction->bill_no
+ ];
+ }
+
+ $creditTransactions = $this->getTransactions($statementTransaction->posting_date, $statementTransaction->amount, TransactionType::TOP_UP, Wallet::class, null, [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED]);
+ foreach ($creditTransactions as $transaction) {
+ $owners[] = [
+ 'system' => 'EXCHANGE',
+ 'owner_type' => Transaction::class,
+ 'owner_id' => $transaction->id,
+ 'bill_no' => $transaction->bill_no
+ ];
+ }
+
+ $creditTransactions = $this->getTransactionsFromShippingPortal($statementTransaction->amount, $this->getDateRange($statementTransaction->posting_date));
+ foreach ($creditTransactions as $transaction) {
+ $owners[] = [
+ 'system' => 'IZYIM',
+ 'owner_type' => Transaction::class,
+ 'owner_id' => $transaction->id,
+ 'bill_no' => $transaction->bill_no
+ ];
+ }
+ }
+
+ return $owners;
+ }
+
+ private function getTransactions($date, $amount, $type, $ownerType, $paymentMethod, $statuses, $model = Transaction::class) {
+ $query = $model::whereIn('status', $statuses)
+ ->where(function ($query) use ($ownerType, $paymentMethod, $type) {
+ if ($ownerType) {
+ $query->where('owner_type', $ownerType);
+ }
+
+ if ($paymentMethod) {
+ $query->where('payment_method', '!=', $paymentMethod);
+ }
+
+ if ($type) {
+ $query->where('type', $type);
+ }
+ })
+ ->whereDate('created_at', $date->format('Y-m-d'))
+ ->where('amount', '>', ($amount - 0.01))
+ ->where('amount', '<', ($amount + 0.01));
+
+ return $query->get();
+ }
+
+ private function getTransactionsFromShippingPortal($amount, $dateRange){
+ try{
+
+ $client = new \GuzzleHttp\Client(['verify' => false]);
+ $response = $client->request('GET', 'https://izyim.cief-malaysia.com/public/api/v1/list?api-key=510acd13d8d24375cf038ad626c282565451461a9c2399357e0b65365300787e&filters={"order_by":{"column":"id","DESC":true},"status_in":[2],"type":2,"created_after":"'.$dateRange['start_date'].'","created_before":"'.$dateRange['end_date'].'","amount_exceed":'.($amount - 0.01).',"amount_short":'.($amount + 0.01).'}');
+ $body = $response->getBody();
+ $data = json_decode($body, true);
+ $payload = $data['payload'];
+ $transactions2 = $payload['data'];
+ return $transactions2;
+ }catch(\Exception $exception){
+ Log::error($exception);
+ return [];
+ }
+ }
+
+ private function getDateRange(string $dateStr) {
+ // 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));
+
+ // Get the first day of the next month
+ $nextDay = date('Y-m-d', strtotime('+1 day', $date));
+
+ return [
+ 'start_date' => $today,
+ 'end_date' => $nextDay,
+ ];
+ }
+}
diff --git a/app/Classes/Modules/Accounting/Services/FetchesBankStatementDetails.php b/app/Classes/Modules/Accounting/Services/FetchesBankStatementDetails.php
index 37a3d785..22de5c39 100644
--- a/app/Classes/Modules/Accounting/Services/FetchesBankStatementDetails.php
+++ b/app/Classes/Modules/Accounting/Services/FetchesBankStatementDetails.php
@@ -5,20 +5,20 @@ namespace App\Classes\Modules\Accounting\Services;
use App\Classes\General\Eloquent\AbstractFetchRecord;
use Illuminate\Database\Eloquent\Builder;
-use App\Models\StatementTransactionsDetail;
+use App\Models\StatementTransactionOwner;
class FetchesBankStatementDetails extends AbstractFetchRecord
{
- /** @var StatementTransactionsDetail */
+ /** @var StatementTransactionOwner */
private $repository;
/**
* FetchesBankStatementDetails constructor.
- * @param StatementTransactionsDetail $repository
+ * @param StatementTransactionOwner $repository
*/
- public function __construct(StatementTransactionsDetail $repository)
+ public function __construct(StatementTransactionOwner $repository)
{
$this->repository = $repository;
}
diff --git a/app/Classes/Modules/Accounting/Services/ListsBankStatementDetails.php b/app/Classes/Modules/Accounting/Services/ListsBankStatementDetails.php
index 2f1290e5..6e085e44 100644
--- a/app/Classes/Modules/Accounting/Services/ListsBankStatementDetails.php
+++ b/app/Classes/Modules/Accounting/Services/ListsBankStatementDetails.php
@@ -4,19 +4,19 @@ namespace App\Classes\Modules\Accounting\Services;
use App\Classes\General\Eloquent\AbstractListRecord;
use Illuminate\Database\Eloquent\Builder;
-use App\Models\StatementTransactionsDetail;
+use App\Models\StatementTransactionOwner;
class ListsBankStatementDetails extends AbstractListRecord
{
- /** @var StatementTransactionsDetail */
+ /** @var StatementTransactionOwner */
private $repository;
/**
* ListsBankStatementDetails constructor.
- * @param StatementTransactionsDetail $repository
+ * @param StatementTransactionOwner $repository
*/
- public function __construct(StatementTransactionsDetail $repository)
+ public function __construct(StatementTransactionOwner $repository)
{
$this->repository = $repository;
}
diff --git a/app/Classes/Modules/Accounting/Services/ListsBankStatementTransactions.php b/app/Classes/Modules/Accounting/Services/ListsBankStatementTransactions.php
new file mode 100644
index 00000000..8d4fbf69
--- /dev/null
+++ b/app/Classes/Modules/Accounting/Services/ListsBankStatementTransactions.php
@@ -0,0 +1,33 @@
+repository = $repository;
+ }
+
+
+ /**
+ * @return Builder
+ */
+ public function getRepository(): Builder
+ {
+ return $this->repository->newQuery();
+ }
+}
diff --git a/app/Classes/Modules/Accounting/Services/UpdatesBankStatementDetails.php b/app/Classes/Modules/Accounting/Services/UpdatesBankStatementDetails.php
index 2e4ad23c..e87121ac 100644
--- a/app/Classes/Modules/Accounting/Services/UpdatesBankStatementDetails.php
+++ b/app/Classes/Modules/Accounting/Services/UpdatesBankStatementDetails.php
@@ -4,18 +4,18 @@ namespace App\Classes\Modules\Accounting\Services;
use App\Classes\General\Eloquent\AbstractUpdateRecord;
use App\Classes\Modules\Accounting\DataTransferObjects\BankStatementDetailObject;
-use App\Models\StatementTransactionsDetail;
+use App\Models\StatementTransactionOwner;
class UpdatesBankStatementDetails extends AbstractUpdateRecord
{
/**
- * @param StatementTransactionsDetail $model
+ * @param StatementTransactionOwner $model
* @param BankStatementDetailsObject $object
* @return \Illuminate\Database\Eloquent\Model
* @throws \App\Classes\Exceptions\MalformedRequestException
*/
- public function execute(StatementTransactionsDetail $model, BankStatementDetailObject $object)
+ public function execute(StatementTransactionOwner $model, BankStatementDetailObject $object)
{
$model->system_references = $object->getSystemReferences();
$model->pay_for = $object->getPayFor();
diff --git a/app/Classes/Modules/Documents/DataTransferObjects/FileObject.php b/app/Classes/Modules/Documents/DataTransferObjects/FileObject.php
index 736853fc..2a425f7d 100644
--- a/app/Classes/Modules/Documents/DataTransferObjects/FileObject.php
+++ b/app/Classes/Modules/Documents/DataTransferObjects/FileObject.php
@@ -28,7 +28,7 @@ class FileObject implements DataTransferObject
*/
public function getData()
{
- return in_array($this->getExtension(), ['pdf', 'excel']) ? $this->data : (new imageManager())->make($this->data);
+ return in_array($this->getExtension(), ['pdf', 'excel', 'text']) ? $this->data : (new imageManager())->make($this->data);
}
/**
@@ -66,7 +66,7 @@ class FileObject implements DataTransferObject
*/
public function getDecodedData(): string
{
- return in_array($this->getExtension(), ['pdf', 'excel']) ?
+ return in_array($this->getExtension(), ['pdf', 'excel', 'text']) ?
base64_decode((explode('base64,', $this->getData()))[1]):
$this->getData()->encode('data-url')->encoded;
}
@@ -83,4 +83,4 @@ class FileObject implements DataTransferObject
-}
\ No newline at end of file
+}
diff --git a/app/Classes/Modules/Documents/Services/ConvertsBase64ToFile.php b/app/Classes/Modules/Documents/Services/ConvertsBase64ToFile.php
index 8741b823..0e0cf6b9 100644
--- a/app/Classes/Modules/Documents/Services/ConvertsBase64ToFile.php
+++ b/app/Classes/Modules/Documents/Services/ConvertsBase64ToFile.php
@@ -36,7 +36,7 @@ class ConvertsBase64ToFile
foreach ($files as $file) {
$object = new FileObject($file);
- in_array($object->getExtension(), ['pdf', 'excel']) ? $this->generatePDF($object) : $this->generateImage($object);
+ in_array($object->getExtension(), ['pdf', 'excel', 'text']) ? $this->generatePDF($object) : $this->generateImage($object);
}
@@ -122,4 +122,4 @@ class ConvertsBase64ToFile
]);
}
-}
\ No newline at end of file
+}
diff --git a/app/Classes/ValueObjects/Constants/FileType.php b/app/Classes/ValueObjects/Constants/FileType.php
index d5404e7a..fc6dbf1b 100644
--- a/app/Classes/ValueObjects/Constants/FileType.php
+++ b/app/Classes/ValueObjects/Constants/FileType.php
@@ -23,6 +23,7 @@ class FileType
'application/pdf' => 'pdf',
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' => 'excel',
'application/vnd.ms-excel' => 'excel',
+ 'text/plain' => 'text',
];
-}
\ No newline at end of file
+}
diff --git a/app/Classes/ValueObjects/Constants/StatementTransactionOwnerType.php b/app/Classes/ValueObjects/Constants/StatementTransactionOwnerType.php
new file mode 100644
index 00000000..24d31516
--- /dev/null
+++ b/app/Classes/ValueObjects/Constants/StatementTransactionOwnerType.php
@@ -0,0 +1,37 @@
+paginate(10);
+ $statements = $statementsQuery->orderBy('date_from')->paginate(10);
return view('pages.accounting.bank-statements.index', compact('accounts', 'selectedAccount', 'search', 'statements'));
}
- public function import(Request $request)
+ public function indexv2(Request $request)
{
+ $selectedAccount = $request->input('account');
+ $search = $request->input('search');
- $request->validate([
- 'file' => 'required|mimes:csv,txt'
- ]);
+ $accounts = StatementAccount::all();
- $file = $request->file('file');
+ $statementsQuery = AccountStatement::query();
- $collection = Excel::toCollection(null, $file, null, null, true);
-
- $sheet = $collection->first()->skip(1);
-
- $statementDetails = $sheet->first();
-
- $accountNumber = $statementDetails[0];
- $accountType = $statementDetails[1];
- $accountName = $statementDetails[2];
- $accountCurrency = $statementDetails[3];
- $dateFrom = carbon::parse(str_replace(' MY (UTC+08:00)', '', $statementDetails[4]));
- $dateTo = carbon::parse(str_replace(' MY (UTC+08:00)', '', $statementDetails[5]));
- $totalDebit = $statementDetails[6];
- $totalCredit = $statementDetails[7];
- $beginBalance = $statementDetails[8];
- $endBalance = $statementDetails[9];
- $account = StatementAccount::updateOrCreate(
- ['number' => $accountNumber],
- [
- 'type' => $accountType,
- 'name' => $accountName,
- 'currency' => $accountCurrency,
- ]
- );
-
- $statement = AccountStatement::where('date_from', $dateFrom)
- ->where('date_to', $dateTo)
- ->where('total_amount', $totalDebit ?: $totalCredit,)
- ->where('begin_balance', $beginBalance)
- ->where('end_balance', $endBalance)->first();
-
-
- if(!$statement){
- $statement = new AccountStatement([
- 'date_from' => $dateFrom,
- 'date_to' => $dateTo,
- 'total_amount' => $totalDebit ?: $totalCredit,
- 'begin_balance' => $beginBalance,
- 'end_balance' => $endBalance,
- ]);
+ if ($selectedAccount) {
+ $statementsQuery->where('statement_account_id', $selectedAccount);
}
- // $existingStatement = AccountStatement::where('date_from', $dateFrom)
- // ->where('date_to', $dateTo)
- // ->where('statement_account_id', $account->id)
- // ->first();
+ if ($search) {
+ $statementsQuery->where(function ($query) use ($search) {
+ $query->where('date_from', 'LIKE', "%$search%")
+ ->orWhere('date_to', 'LIKE', "%$search%")
+ ->orWhere('total_amount', 'LIKE', "%$search%")
+ ->orWhere('begin_balance', 'LIKE', "%$search%")
+ ->orWhere('end_balance', 'LIKE', "%$search%");
+ });
+ }
- // // if ($existingStatement) {
- // // return redirect()->back()->with('error', 'This statement has already been imported.');
- // // }
+ $statements = $statementsQuery->paginate(10);
- $account->statements()->save($statement);
-
- CreateBankStatementDetails::dispatch($statement)->delay(30);
-
-
- // $account = null;
- $newTransactions = $sheet->map(function ($row) use ($statement, $account) {
- $transactionRef = $row[15];
- $amount = $row[17] !== '-' ? ((float) str_replace(',', '', $row[17])) : (-((float) str_replace(',', '', $row[16])));
- $transactionDate = $row[10] !== '-' ? carbon::parse(str_replace(' MY (UTC+08:00)', '', $row[10]) . $row[11]) : null;
- $postingDate = carbon::createFromFormat('d/M/Y H:i', str_replace(' MY (UTC+08:00)', '', $row[12]) . str_replace(' MY (UTC+08:00)', '', $row[13]));
- $transactionDescription = is_numeric($row[14]) ? (int) sprintf('%.2f', $row[14]) : $row[14];
- $tellerId = $row[19];
- $branchChannel = $row[20];
- $transactionCode = $row[21];
- $endBalance = $row[22];
- $description2 = $row[25];
- $description3 = $row[26];
- $description4 = $row[27];
- $description5 = $row[28];
- $transaction = new StatementTransaction([
- 'transaction_ref' => $transactionRef,
- 'amount' => $amount,
- 'transaction_date' => $transactionDate,
- 'posting_date' => $postingDate,
- 'transaction_description' => $transactionDescription,
- 'teller_id' => $tellerId,
- 'branch_channel' => $branchChannel,
- 'transaction_code' => $transactionCode,
- 'end_balance' => $endBalance,
- 'transaction_description_2' => $description2,
- 'transaction_description_3' => $description3,
- 'transaction_description_4' => $description4,
- 'transaction_description_5' => $description5,
- ]);
-
- // Check if the transaction already exists for this statement
- $existingTransaction = StatementTransaction::where('transaction_ref', $transactionRef)
- ->where('posting_date', $postingDate)
- ->where('amount', $amount)
- ->where('transaction_description', $transactionDescription)
- ->where('teller_id', $tellerId)
- ->where('branch_channel', $branchChannel)
- ->where('transaction_code', $transactionCode)
- ->where('end_balance', $endBalance)
- ->first();
-
- if (!$existingTransaction) {
- $statement->transactions()->save($transaction);
- }
-
- return $transaction;
- });
-
-
- // dd(json_encode($newTransactions));
- return redirect()->back()->with('success', 'Statement imported successfully.')->with('newTransactions', $newTransactions);
+ return view('pages.accounting.bank-statements.indexv2', compact('accounts', 'selectedAccount', 'search', 'statements'));
}
- public function rerun(AccountStatement $statement, Request $request)
+ public function import(Request $request, ImportBankStatementLogic $logic): JsonResponse
{
- CreateBankStatementDetails::dispatch($statement)->delay(30);
+ return $logic->execute($request);
+ }
+
+ public function rerun()
+ {
+ CreateBankStatementTransactionOwners::dispatch();
return redirect()->back()->with('success', 'Rerun triggered successfully');
}
@@ -227,6 +134,11 @@ class BankStatementController extends Controller
return $logic->execute($request);
}
+ public function transactions(Request $request, ListBankStatementTransactionsLogic $logic): JsonResponse
+ {
+ return $logic->execute($request);
+ }
+
public function update(Request $request, UpdateBankStatementDetailLogic $logic): JsonResponse
{
return $logic->execute($request);
@@ -264,7 +176,7 @@ class BankStatementController extends Controller
$count = 0;
foreach ($transactions as $row) {
- $isExist = StatementTransactionsDetail::where('statement_transaction_id', $row->id)->first();
+ $isExist = StatementTransactionOwner::where('statement_transaction_id', $row->id)->first();
if ($isExist) {
continue;
@@ -371,7 +283,7 @@ class BankStatementController extends Controller
//AccountStatement
// $row->statement()->first()->id)
- $statementTransactionsDetail = new StatementTransactionsDetail([
+ $statementTransactionsDetail = new StatementTransactionOwner([
'date' => $date,
'statement_transaction_id' => $row->id,
'description' => is_null($description) ? "" : $description,
diff --git a/app/Http/Resources/BankStatementDetailResource.php b/app/Http/Resources/BankStatementDetailResource.php
deleted file mode 100644
index 5533728c..00000000
--- a/app/Http/Resources/BankStatementDetailResource.php
+++ /dev/null
@@ -1,37 +0,0 @@
- $this->id,
- 'account_number' => $this->statementTransaction->statement->account->number,
- 'account_type' => $this->statementTransaction->statement->account->type,
- 'account_name' => $this->statementTransaction->statement->account->name,
- 'account_statement_id' => $this->statementTransaction->statement->id,
- 'account_statement_date_from' => $this->statementTransaction->statement->date_from,
- 'account_statement_date_to' => $this->statementTransaction->statement->date_to,
- 'date' => $this->date,
- 'description' => $this->description,
- 'amount' => $this->statementTransaction->amount,
- 'pay_for' => $this->pay_for,
- 'system_references' => $this->system_references,
- 'transaction_description_1' => $this->statementTransaction->transaction_description,
- 'transaction_description_2' => $this->statementTransaction->transaction_description_2,
- 'transaction_description_3' => $this->statementTransaction->transaction_description_3,
- 'transaction_description_4' => $this->statementTransaction->transaction_description_4,
- 'transaction_description_5' => $this->statementTransaction->transaction_description_5,
- ];
- }
-}
diff --git a/app/Http/Resources/BankStatementTransactionOwnerResource.php b/app/Http/Resources/BankStatementTransactionOwnerResource.php
new file mode 100644
index 00000000..0066eafa
--- /dev/null
+++ b/app/Http/Resources/BankStatementTransactionOwnerResource.php
@@ -0,0 +1,65 @@
+system === 'EXCHANGE') {
+ if($this->owner_type === Transaction::class){
+ $transaction = Transaction::find($this->owner_id);
+
+ if($transaction->owner_type === Booking::class){
+ $reference = $transaction->owner->marking;
+ $referenceLink = route('booking.details', $transaction->owner->marking);
+ }
+
+ if($transaction->owner_type === Wallet::class) {
+ $reference = $transaction->owner->owner->reference;
+ $referenceLink = route('wallet.details', $transaction->owner->owner->reference);
+ }
+ }
+
+ if($this->owner_type === Group::class){
+ $transaction = Group::find($this->owner_id);
+ $reference = $transaction->reference;
+// $referenceLink = route('booking.details', $transaction->owner->marking);
+ }
+ }
+
+ if($this->system === 'SHIPPING_PORTAL') {
+ if($this->owner_type === Transaction::class){
+ $transaction = Transaction::find($this->owner_id);
+
+ }
+ }
+
+ return [
+ 'id' => $this->id,
+ 'type' => $this->type,
+ 'system' => $this->system,
+ 'owner_type' => $this->owner_type,
+ 'owner_id' => $this->owner_id,
+ 'reference_link' => $referenceLink,
+ 'reference' => $reference,
+ 'invoice_reference' => $this->invoice_reference,
+ 'receipt_reference' => $this->receipt_reference,
+ 'status' => $this->status
+ ];
+ }
+}
diff --git a/app/Http/Resources/BankStatementTransactionResource.php b/app/Http/Resources/BankStatementTransactionResource.php
new file mode 100644
index 00000000..09768f51
--- /dev/null
+++ b/app/Http/Resources/BankStatementTransactionResource.php
@@ -0,0 +1,36 @@
+ $this->id,
+ 'account_number' => $this->statement->account->number,
+ 'account_type' => $this->statement->account->type,
+ 'account_name' => $this->statement->account->name,
+ 'account_statement_id' => $this->statement->id,
+ 'account_statement_date_from' => $this->statement->date_from,
+ 'account_statement_date_to' => $this->statement->date_to,
+ 'posting_date' => $this->posting_date->format('d-m-Y g:i A'),
+ 'amount' => $this->amount,
+ 'transaction_description_1' => $this->transaction_description,
+ 'transaction_description_2' => $this->transaction_description_2,
+ 'transaction_description_3' => $this->transaction_description_3,
+ 'transaction_description_4' => $this->transaction_description_4,
+ 'transaction_description_5' => $this->transaction_description_5,
+ 'owners' => BankStatementTransactionOwnerResource::collection($this->owners)
+ ];
+ }
+}
diff --git a/app/Models/StatementTransaction.php b/app/Models/StatementTransaction.php
index 6b789f08..80d6759f 100644
--- a/app/Models/StatementTransaction.php
+++ b/app/Models/StatementTransaction.php
@@ -4,9 +4,12 @@ namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
+use Staudenmeir\EloquentHasManyDeep\HasRelationships;
class StatementTransaction extends Model
{
+ use HasRelationships;
+
use HasFactory;
protected $fillable = [
@@ -30,18 +33,18 @@ class StatementTransaction extends Model
'posting_date' => 'datetime',
];
+ public function account()
+ {
+ return $this->hasOneDeep(StatementAccount::class, [AccountStatement::class], ['id', 'id'], ['account_statement_id', 'statement_account_id']);
+ }
+
public function statement()
{
return $this->belongsTo(AccountStatement::class, 'account_statement_id', 'id');
}
- public function owner()
+ public function owners()
{
- return $this->morphTo()->nullable();
- }
-
- public function statementDetail()
- {
- return $this->hasMany(StatementTransactionsDetail::class);
+ return $this->hasMany(StatementTransactionOwner::class);
}
}
diff --git a/app/Models/StatementTransactionsDetail.php b/app/Models/StatementTransactionOwner.php
similarity index 50%
rename from app/Models/StatementTransactionsDetail.php
rename to app/Models/StatementTransactionOwner.php
index 074f5304..1db5404d 100644
--- a/app/Models/StatementTransactionsDetail.php
+++ b/app/Models/StatementTransactionOwner.php
@@ -4,26 +4,24 @@ namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
+use Illuminate\Database\Eloquent\Relations\BelongsTo;
-class StatementTransactionsDetail extends Model
+class StatementTransactionOwner extends Model
{
use HasFactory;
protected $fillable = [
- 'date',
'statement_transaction_id',
- // 'description',
- // 'credit',
- // 'debit',
- 'pay_for',
- 'system_references',
- // 'remark_references',
- // 'is_multiple',
- // 'is_matches',
- 'system_amounts',
+ 'type',
+ 'system',
+ 'owner_type',
+ 'owner_id',
+ 'invoice_reference',
+ 'receipt_reference',
+ 'status',
];
- public function statementTransaction()
+ public function transaction(): BelongsTo
{
return $this->belongsTo(StatementTransaction::class, 'statement_transaction_id', 'id');
}
diff --git a/database/migrations/2023_03_26_190934_create_statement_transactions_table.php b/database/migrations/2023_03_26_190934_create_statement_transactions_table.php
index 95ad3571..29cacb80 100644
--- a/database/migrations/2023_03_26_190934_create_statement_transactions_table.php
+++ b/database/migrations/2023_03_26_190934_create_statement_transactions_table.php
@@ -29,11 +29,6 @@ class CreateStatementTransactionsTable extends Migration
$table->string('branch_channel');
$table->string('transaction_code');
$table->string('end_balance')->nullable();
- $table->string('owner_system')->nullable();
- $table->string('owner_type')->nullable();
- $table->unsignedBigInteger('owner_id')->nullable();
- $table->string('invoice_reference')->nullable();
- $table->string('payment_reference')->nullable();
$table->timestamps();
$table->foreign('account_statement_id')->references('id')->on('account_statements');
diff --git a/database/migrations/2023_04_07_212512_create_statement_transaction_owners_table.php b/database/migrations/2023_04_07_212512_create_statement_transaction_owners_table.php
new file mode 100644
index 00000000..50d3a9c8
--- /dev/null
+++ b/database/migrations/2023_04_07_212512_create_statement_transaction_owners_table.php
@@ -0,0 +1,44 @@
+id();
+ $table->foreignId('statement_transaction_id');
+ $table->integer('type')->default(StatementTransactionOwnerType::UNKNOWN);
+ $table->string('system')->nullable();
+ $table->string('owner_type')->nullable();
+ $table->bigInteger('owner_id')->nullable();
+ $table->string('invoice_reference')->nullable();
+ $table->string('receipt_reference')->nullable();
+ $table->string('is_auto_mapped')->default(true);
+ $table->integer('status')->default(ApprovalStatus::PENDING_VERIFICATION);
+
+ $table->foreign('statement_transaction_id')->references('id')->on('statement_transactions');
+ $table->timestamps();
+ });
+ }
+
+ /**
+ * Reverse the migrations.
+ *
+ * @return void
+ */
+ public function down()
+ {
+ Schema::dropIfExists('statement_transaction_owners');
+ }
+}
diff --git a/database/migrations/2023_04_07_212512_create_statement_transactions_details_table.php b/database/migrations/2023_04_07_212512_create_statement_transactions_details_table.php
deleted file mode 100644
index 3bc547fd..00000000
--- a/database/migrations/2023_04_07_212512_create_statement_transactions_details_table.php
+++ /dev/null
@@ -1,43 +0,0 @@
-id();
- $table->date('date');
- $table->unsignedBigInteger('statement_transaction_id');
- $table->foreign('statement_transaction_id')->references('id')->on('statement_transactions');
- // $table->string('description');
- // $table->decimal('credit', 8, 2);
- // $table->decimal('debit', 8, 2);
- $table->string('pay_for');
- $table->string('system_references');
- // $table->string('remark_references');
- // $table->boolean('is_multiple')->default(false);
- // $table->boolean('is_matches')->default(false);
- $table->string('system_amounts');
- $table->timestamps();
- });
- }
-
- /**
- * Reverse the migrations.
- *
- * @return void
- */
- public function down()
- {
- Schema::dropIfExists('statement_transactions_details');
- }
-}
diff --git a/resources/assets/vue/components/accounting/elements/StatementTransactionComponent.vue b/resources/assets/vue/components/accounting/elements/StatementTransactionComponent.vue
new file mode 100644
index 00000000..e2072785
--- /dev/null
+++ b/resources/assets/vue/components/accounting/elements/StatementTransactionComponent.vue
@@ -0,0 +1,93 @@
+
+
+
+
+
{{ item.posting_date }}
+
{{ item.transaction_description_1 + ' - ' + item.transaction_description_2 }}
+
+
+
{{item.owners[0].system}}
+
{{ typeString(item.owners[0].type) }}
+
+
+
+
+
+
+
+
+ {{ owner.system }}
+
+
+
+
+
+
+ {{ typeString(owner.type) }}
+
+
+
+
+
+
+
+
{{ item.amount }}
+
+
+
+
+
+
+
+
diff --git a/resources/assets/vue/components/accounting/forms/ImportStatementFormComponent.vue b/resources/assets/vue/components/accounting/forms/ImportStatementFormComponent.vue
new file mode 100644
index 00000000..54db23df
--- /dev/null
+++ b/resources/assets/vue/components/accounting/forms/ImportStatementFormComponent.vue
@@ -0,0 +1,59 @@
+
+
+
+
+
+
+
+
+
+
+
+
+ Import Bank Statement CSV
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/resources/assets/vue/components/accounting/sections/TransactionsMappingComponent.vue b/resources/assets/vue/components/accounting/sections/TransactionsMappingComponent.vue
new file mode 100644
index 00000000..3a4863a4
--- /dev/null
+++ b/resources/assets/vue/components/accounting/sections/TransactionsMappingComponent.vue
@@ -0,0 +1,185 @@
+
+
+
+
+
+
+
+
+
Receivable Mapping
+
Payable Mapping
+
+
+
+
+
+
+
+
{{ type === 1 ? 'Receivable Mapping' : 'Payable Mapping'}}
+
+
+
+
Mapping Approval
+
+
Mapping Review
+
+
Unknown
+
+
Pending Export
+
+
+
+
+
+
+
All
+
Sales
+
Wallet Top Up
+
Internal Bank Transfer In
+
Unknown
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Date
+
Description
+
+
+
System
+
Type
+
Reference
+
+
+
Amount
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Export Invoices To AutoCount
+
+
+
+
+
+
Export Receipts To AutoCount
+
+
+
+
+
+ All Done, Good Job 👏
+
+
+
+
+
+
+
+
diff --git a/resources/views/pages/accounting/bank-statements/bank_statement.blade.php b/resources/views/pages/accounting/bank-statements/bank_statement.blade.php
new file mode 100644
index 00000000..87bbf321
--- /dev/null
+++ b/resources/views/pages/accounting/bank-statements/bank_statement.blade.php
@@ -0,0 +1,12 @@
+@extends('layouts.base_portal')
+@section('inner_content')
+
+@endsection
diff --git a/resources/views/pages/accounting/bank-statements/index.blade.php b/resources/views/pages/accounting/bank-statements/index.blade.php
index f41813db..e4071c26 100644
--- a/resources/views/pages/accounting/bank-statements/index.blade.php
+++ b/resources/views/pages/accounting/bank-statements/index.blade.php
@@ -1,102 +1,370 @@
@extends('layouts.base_portal')
@section('inner_content')
-
-
-
-
-
+
+
+
-
- @if (session('success'))
-
- {{ session('success') }}
+ {{--
--}}
+{{--
--}}
+{{--
--}}
+{{--
--}}
+{{--
--}}
+{{--
--}}
+{{--
--}}
+{{--
--}}
+{{--
--}}
+{{-- --}}
+{{-- --}}
+{{-- --}}
+{{-- --}}
+{{--
--}}
+{{--
--}}
+{{--
--}}
+{{--
--}}
+{{--
--}}
+{{--
--}}
+{{--
--}}
+
+
+
+
- @endif
- @if (session('error'))
-
- {{ session('error') }}
-
- @endif
+
+
+
+
+
+
+
+
+
+
+ Account
+ Currency
+
+
+
+
+ @foreach($accounts as $account)
+
+ {{$account->number}} {{$account->type}}
+ {{$account->currency}}
+
+ Open
+
+
+ @endforeach
+
+
+
+
+
+
+
+
+
-
Import
-
-
-
-
-
-
- @if (session('message'))
-
- {{ session('message') }}
- @endif
-
-
-
-
-
-
-
-
-
- Account
- Date From
- Date To
- Total Amount
- Begin Balance
- End Balance
- Actions
-
-
-
- @foreach($statements as $statement)
-
- {{ $statement->account->name }} ({{ $statement->account->number }})
- {{ $statement->date_from->format('d-m-Y') }}
- {{ $statement->date_to->format('d-m-Y') }}
- {{ $statement->total_amount }}
- {{ $statement->begin_balance }}
- {{ $statement->end_balance }}
-
- View
-
-
- Rerun
-
-
- @endforeach
-
-
- {{ $statements->links() }}
@endsection
+{{--@extends('layouts.base_portal')--}}
+{{--@section('inner_content')--}}
+{{--
--}}
+{{--
--}}
+{{--
--}}
+{{--
--}}
+{{-- --}}
+
+{{--
--}}
+{{-- @if (session('success'))--}}
+{{--
--}}
+{{-- {{ session('success') }}--}}
+{{--
--}}
+{{-- @endif--}}
+{{-- @if (session('error'))--}}
+{{--
--}}
+{{-- {{ session('error') }}--}}
+{{--
--}}
+{{-- @endif--}}
+
+{{--
--}}
+{{--
--}}
+{{--
--}}
+{{--
--}}
+{{--
--}}
+{{--
--}}
+{{-- @if (session('message'))--}}
+{{--
--}}
+{{-- {{ session('message') }}--}}
+{{--
--}}
+{{-- @endif--}}
+{{-- --}}
+
+{{--
--}}
+{{--
--}}
+{{--
--}}
+{{--
--}}
+{{--@endsection--}}
diff --git a/resources/views/pages/accounting/bank-statements/indexv2.blade.php b/resources/views/pages/accounting/bank-statements/indexv2.blade.php
new file mode 100644
index 00000000..f18a77ae
--- /dev/null
+++ b/resources/views/pages/accounting/bank-statements/indexv2.blade.php
@@ -0,0 +1,461 @@
+@extends('layouts.base_portal')
+@section('inner_content')
+
+
+
+
+
+
Accounting Dashboard
+
+
+
+
+
+
+
+
+
+
+ @if (session('success'))
+
+ {{ session('success') }}
+
+ @endif
+ @if (session('error'))
+
+ {{ session('error') }}
+
+ @endif
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Date
+ Transaction Type
+ Account Name
+ Description
+ Status
+
+
+
+
+ 2023-04-11
+ Deposit
+ Bank Account 1
+ Salary Payment
+ Pending
+
+
+ 2023-04-09
+ Withdrawal
+ Bank Account 2
+ Vendor Payment
+ Reconciled
+
+
+ 2023-04-07
+ Deposit
+ Bank Account 3
+ Online Order Payment
+ Exception
+
+
+
+
+
+
+
+
+
+
+
Step 1: Start Mapping bank Transactions
+
This is the first step in the wizard.
+
+
+
Step 2: List of automatically mapped bank transactions
+
This is the second step in the wizard.
+
+
+
Step 3: List of bank transactions that require manual mapping
+
This is the third step in the wizard.
+
+
+
Step 4: Export invoices to accounting software
+
This is the fourth step in the wizard.
+
+
+
Step 5: Import invoices from accounting software
+
This is the fifth step in the wizard.
+
+
+
Step 6: Export payment receipts
+
This is the sixth step in the wizard.
+
+
+
Step 7: Import payment receipts
+
This is the final step in the wizard.
+
+
+
+
+
+ Previous
+ Next
+ Finish
+
+
+
+
+
Tab 3 Content
+
Aliquam vitae magna sit amet tellus bibendum posuere. Integer nec leo quis arcu tincidunt eleifend. Suspendisse potenti. Proin ullamcorper sodales nisl vel tincidunt. Etiam malesuada, mauris sit amet tincidunt facilisis, nisl enim aliquet turpis, ac pretium lacus nulla a libero. Vivamus euismod ex vel sapien dignissim, a fringilla enim fringilla. Sed sit amet lobortis augue. Aenean ut neque ac elit interdum pretium vel vel purus. Duis ut magna at ante dignissim efficitur. Pellentesque molestie bibendum ipsum a malesuada. Nulla cursus vehicula felis vel dapibus. Suspendisse eget vulputate ex. In pulvinar tincidunt justo, eu viverra orci malesuada id. Sed posuere arcu ac diam finibus posuere.
+
+
+
+
+
+
+
+
+
+ Account
+ Date From
+ Date To
+ Total Amount
+ Begin Balance
+ End Balance
+ Actions
+
+
+
+ @foreach($statements as $statement)
+
+ {{ $statement->account->name }} ({{ $statement->account->number }})
+ {{ $statement->date_from->format('d-m-Y') }}
+ {{ $statement->date_to->format('d-m-Y') }}
+ {{ $statement->total_amount }}
+ {{ $statement->begin_balance }}
+ {{ $statement->end_balance }}
+
+ View
+
+
+ @endforeach
+
+
+ {{ $statements->links() }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Date
+ Transaction Type
+ Account Name
+ Description
+ Status
+
+
+
+
+ 2023-04-11
+ Deposit
+ Bank Account 1
+ Salary Payment
+ Pending
+
+
+ 2023-04-09
+ Withdrawal
+ Bank Account 2
+ Vendor Payment
+ Reconciled
+
+
+ 2023-04-07
+ Deposit
+ Bank Account 3
+ Online Order Payment
+ Exception
+
+
+
+
+
+
+
+
+
+
+
+
+ Account
+ Date From
+ Date To
+ Total Amount
+ Begin Balance
+ End Balance
+ Actions
+
+
+
+ @foreach($statements as $statement)
+
+ {{ $statement->account->name }} ({{ $statement->account->number }})
+ {{ $statement->date_from->format('d-m-Y') }}
+ {{ $statement->date_to->format('d-m-Y') }}
+ {{ $statement->total_amount }}
+ {{ $statement->begin_balance }}
+ {{ $statement->end_balance }}
+
+ View
+
+
+ @endforeach
+
+
+ {{ $statements->links() }}
+
+
+
Tab 3 Content
+
Aliquam vitae magna sit amet tellus bibendum posuere. Integer nec leo quis arcu tincidunt eleifend. Suspendisse potenti. Proin ullamcorper sodales nisl vel tincidunt. Etiam malesuada, mauris sit amet tincidunt facilisis, nisl enim aliquet turpis, ac pretium lacus nulla a libero. Vivamus euismod ex vel sapien dignissim, a fringilla enim fringilla. Sed sit amet lobortis augue. Aenean ut neque ac elit interdum pretium vel vel purus. Duis ut magna at ante dignissim efficitur. Pellentesque molestie bibendum ipsum a malesuada. Nulla cursus vehicula felis vel dapibus. Suspendisse eget vulputate ex. In pulvinar tincidunt justo, eu viverra orci malesuada id. Sed posuere arcu ac diam finibus posuere.
+
+
+
+
+
+
+
+
+
+
+