diff --git a/app/Classes/Modules/Accounting/ControllersLogic/ImportAmbankStatementLogic.php b/app/Classes/Modules/Accounting/ControllersLogic/ImportAmbankStatementLogic.php index a1c253c0..e5d7adf0 100644 --- a/app/Classes/Modules/Accounting/ControllersLogic/ImportAmbankStatementLogic.php +++ b/app/Classes/Modules/Accounting/ControllersLogic/ImportAmbankStatementLogic.php @@ -14,6 +14,7 @@ use Exception; use Illuminate\Http\JsonResponse; use Illuminate\Http\Request; use Illuminate\Support\Carbon; +use Illuminate\Support\Collection; use Illuminate\Support\Facades\Log; use Maatwebsite\Excel\Facades\Excel; @@ -44,19 +45,24 @@ class ImportAmbankStatementLogic extends AbstractControllerLogic foreach ($object->getFiles() as $file){ $collection = Excel::toCollection(null, json_decode($file)->file_info->original->file, null, null, true); - $statementDetails = $collection->first(); + $statementDetailRows = $collection->first()->slice(0,13); - $statementDateRange = trim(explode(':', $statementDetails[3][0])[1]); + $dateInfoKey = $this->findInfoIndexFromExcelCollection($statementDetailRows, "STATEMENT DATE"); + $statementDateRange = trim(explode(':', $this->extractInfoFromExcelCollection($statementDetailRows[$dateInfoKey])[0])[1]); $dateFrom = trim(explode('-', $statementDateRange)[0]); $dateTo = trim(explode('-', $statementDateRange)[1]); $dateFrom = carbon::createFromFormat('d/m/Y', $dateFrom); $dateTo = carbon::createFromFormat('d/m/Y', $dateTo); - $dateTo = carbon::parse($dateTo); - $totalDebit = $statementDetails[7][7]; - $totalCredit = $statementDetails[8][7]; + $dateTo = carbon::parse($dateTo); + $totalDebitKey = $this->findInfoIndexFromExcelCollection($statementDetailRows, "TOTAL DEBIT"); + $totalDebit = $this->extractInfoFromExcelCollection($statementDetailRows[$totalDebitKey])[1]; + $totalCreditKey = $this->findInfoIndexFromExcelCollection($statementDetailRows, "TOTAL CREDIT"); + $totalCredit = $this->extractInfoFromExcelCollection($statementDetailRows[$totalCreditKey])[1]; $totalTransactions = $totalDebit + $totalCredit; - $beginBalance = ((float) str_replace(',', '', $statementDetails[6][10])); - $endBalance = ((float) str_replace(',', '', $statementDetails[9][10])); + $beginBalanceKey = $this->findInfoIndexFromExcelCollection($statementDetailRows, "OPENING BALANCE"); + $beginBalance = ((float) str_replace(',', '', $this->extractInfoFromExcelCollection($statementDetailRows[$beginBalanceKey])[1])); + $endBalanceKey = $this->findInfoIndexFromExcelCollection($statementDetailRows, "CLOSING BALANCE"); + $endBalance = ((float) str_replace(',', '', $this->extractInfoFromExcelCollection($statementDetailRows[$endBalanceKey])[1])); $account = StatementAccount::where('number', 8881040198515)->first(); @@ -86,140 +92,123 @@ class ImportAmbankStatementLogic extends AbstractControllerLogic $collection->map(function ($sheet, $key) use ($statement) { if ($key === 0) { - $sheet->slice(13)->map(function ($row, $index) use ($statement, $sheet, $key) { - if (!$row[0] || !$row[11]) { - return; - } - - $postingDate = carbon::createFromFormat('dM', trim($row[0])); - - $description = trim($row[1]); - - $nextRow = $sheet->slice(13)[$index + 1]; - - if (!$nextRow[0] && $nextRow[1]) { - foreach ($nextRow as $col) { - if ($col) { - $description .= ' '. $col; - } - } - } - - $descriptionArr = explode(',', $description); - - $transactionDescription = array_key_exists(0, $descriptionArr) ? trim($descriptionArr[0]) : ""; - $description2 = array_key_exists(1, $descriptionArr) ? trim($descriptionArr[1]) : ""; - $description3 = array_key_exists(2, $descriptionArr) ? trim($descriptionArr[2]) : ""; - $description4 = array_key_exists(3, $descriptionArr) ? trim($descriptionArr[3]) : ""; - $description5 = array_key_exists(4, $descriptionArr) ? trim($descriptionArr[4]) : ""; - - if (count($descriptionArr) > 5) { - for ($i = 5; $i < count($descriptionArr); $i++) { - $description5 = $description5 . array_key_exists($i, $descriptionArr) ? trim($descriptionArr[$i]) : ""; - } - } - - $amount = $row[9] ? ((float) str_replace(',', '', trim($row[9]))) : (-((float) str_replace(',', '', $row[8]))); - $endBalance = ((float) str_replace(',', '', $row[11])); - $transaction = new StatementTransaction([ - 'posting_date' => $postingDate, - 'transaction_description' => $transactionDescription, - 'transaction_description_2' => $description2, - 'transaction_description_3' => $description3, - 'transaction_description_4' => $description4, - 'transaction_description_5' => $description5, - 'amount' => $amount, - 'end_balance' => $endBalance, - ]); - - // Check if the transaction already exists for this statement - $existingTransaction = StatementTransaction::whereDate('posting_date', $postingDate) - ->where('amount', $amount) - ->where('transaction_description', $transactionDescription) - ->whereRaw("CAST(REPLACE(end_balance,',','') AS DECIMAL(15,2)) = ?",[$endBalance]) - ->first(); - - if (!$existingTransaction) { - $statement->transactions()->save($transaction); - } - - return $transaction; - }); + $headerColumnKey = $this->findInfoIndexFromExcelCollection($sheet->slice(11), "DATE"); + $dateColumnKey = $this->findInfoIndexFromExcelCollection($sheet->slice(11)[$headerColumnKey], "DATE"); + $descriptionColumnKey = $this->findInfoIndexFromExcelCollection($sheet->slice(11)[$headerColumnKey], "TRANSACTION"); + $debitColumnKey = $this->findInfoIndexFromExcelCollection($sheet->slice(11)[$headerColumnKey], "DEBIT"); + $creditColumnKey = $this->findInfoIndexFromExcelCollection($sheet->slice(11)[$headerColumnKey], "CREDIT"); + $balanceColumnKey = $this->findInfoIndexFromExcelCollection($sheet->slice(11)[$headerColumnKey], "BALANCE"); } else { if (strpos($sheet->first()->first(), "DATE") === false) { return; } - - $extraColumn = 0; - if (count($sheet->first()) > 7 && $sheet->first()[7]) { - $extraColumn = 1; + $headerColumnKey = $this->findInfoIndexFromExcelCollection($sheet, "DATE"); + $dateColumnKey = $this->findInfoIndexFromExcelCollection($sheet[$headerColumnKey], "DATE"); + $descriptionColumnKey = $this->findInfoIndexFromExcelCollection($sheet[$headerColumnKey], "TRANSACTION"); + $debitColumnKey = $this->findInfoIndexFromExcelCollection($sheet[$headerColumnKey], "DEBIT"); + $creditColumnKey = $this->findInfoIndexFromExcelCollection($sheet[$headerColumnKey], "CREDIT"); + $balanceColumnKey = $this->findInfoIndexFromExcelCollection($sheet[$headerColumnKey], "BALANCE"); + } + + $sheet->slice($headerColumnKey + 1)->map(function ($row, $index) use ( + $statement, + $sheet, + $dateColumnKey, + $descriptionColumnKey, + $debitColumnKey, + $creditColumnKey, + $balanceColumnKey, + $key) + { + // if date or balance is null or empty, skip the row + if (!$row[$dateColumnKey] || !$row[$balanceColumnKey]) { + return; } - $sheet->slice(1)->map(function ($row, $index) use ($statement, $sheet, $extraColumn, $key) { - if (!$row[0] || !$row[6 + $extraColumn]) { - return; - } + $postingDate = carbon::createFromFormat('dM', trim($row[$dateColumnKey])); - $postingDate = carbon::createFromFormat('dM', trim($row[0])); + $description = trim($row[$descriptionColumnKey]); - $description = trim($row[1]); + $nextRow = $sheet[$index + 1]; - $nextRow = $sheet->slice(1)[$index + 1]; - - if (!$nextRow[0] && $nextRow[1]) { - foreach ($nextRow as $col) { - if ($col) { - $description .= ' '. $col; - } + if (!$nextRow[$dateColumnKey] && $nextRow[$descriptionColumnKey]) { + $nextRowInfoArr = $this->extractInfoFromExcelCollection($nextRow); + foreach ($nextRowInfoArr as $col) { + if ($col) { + $description .= ' '. $col; } } + } - $descriptionArr = explode(',', $description); + $descriptionArr = explode(',', $description); - $transactionDescription = array_key_exists(0, $descriptionArr) ? trim($descriptionArr[0]) : ""; - $description2 = array_key_exists(1, $descriptionArr) ? trim($descriptionArr[1]) : ""; - $description3 = array_key_exists(2, $descriptionArr) ? trim($descriptionArr[2]) : ""; - $description4 = array_key_exists(3, $descriptionArr) ? trim($descriptionArr[3]) : ""; - $description5 = array_key_exists(4, $descriptionArr) ? trim($descriptionArr[4]) : ""; - - if (count($descriptionArr) > 5) { - for ($i = 5; $i < count($descriptionArr); $i++) { - $description5 = $description5 . array_key_exists($i, $descriptionArr) ? trim($descriptionArr[$i]) : ""; - } + $transactionDescription = array_key_exists(0, $descriptionArr) ? trim($descriptionArr[0]) : ""; + $description2 = array_key_exists(1, $descriptionArr) ? trim($descriptionArr[1]) : ""; + $description3 = array_key_exists(2, $descriptionArr) ? trim($descriptionArr[2]) : ""; + $description4 = array_key_exists(3, $descriptionArr) ? trim($descriptionArr[3]) : ""; + $description5 = array_key_exists(4, $descriptionArr) ? trim($descriptionArr[4]) : ""; + + if (count($descriptionArr) > 5) { + for ($i = 5; $i < count($descriptionArr); $i++) { + $description5 = array_key_exists($i, $descriptionArr) ? $description5 . " " . trim($descriptionArr[$i]) : $description5; } + } - $amount = $row[5 + $extraColumn] ? ((float) str_replace(',', '', trim($row[5 + $extraColumn]))) : (-((float) str_replace(',', '', $row[4 + $extraColumn]))); - $endBalance = ((float) str_replace(',', '', $row[6 + $extraColumn])); - $transaction = new StatementTransaction([ - 'posting_date' => $postingDate, - 'transaction_description' => $transactionDescription, - 'transaction_description_2' => $description2, - 'transaction_description_3' => $description3, - 'transaction_description_4' => $description4, - 'transaction_description_5' => $description5, - 'amount' => $amount, - 'end_balance' => $endBalance, - ]); + $amount = $row[$creditColumnKey] ? ((float) str_replace(',', '', trim($row[$creditColumnKey]))) : (-((float) str_replace(',', '', $row[$debitColumnKey]))); + $endBalance = ((float) str_replace(',', '', $row[$balanceColumnKey])); + $transaction = new StatementTransaction([ + 'posting_date' => $postingDate, + 'transaction_description' => $transactionDescription, + 'transaction_description_2' => $description2, + 'transaction_description_3' => $description3, + 'transaction_description_4' => $description4, + 'transaction_description_5' => $description5, + 'amount' => $amount, + 'end_balance' => $endBalance, + ]); - // Check if the transaction already exists for this statement - $existingTransaction = StatementTransaction::whereDate('posting_date', $postingDate) - ->where('amount', $amount) - ->where('transaction_description', $transactionDescription) - ->whereRaw("CAST(REPLACE(end_balance,',','') AS DECIMAL(15,2)) = ?",[$endBalance]) - ->first(); + // Check if the transaction already exists for this statement + $existingTransaction = StatementTransaction::whereDate('posting_date', $postingDate) + ->where('amount', $amount) + ->where('transaction_description', $transactionDescription) + ->whereRaw("CAST(REPLACE(end_balance,',','') AS DECIMAL(15,2)) = ?",[$endBalance]) + ->first(); + + if (!$existingTransaction) { + $statement->transactions()->save($transaction); + } - if (!$existingTransaction) { - $statement->transactions()->save($transaction); - } - - return $transaction; - }); - } + return $transaction; + }); }); } return $this->response([]); + } + private function findInfoIndexFromExcelCollection($collection, $keyword) + { + foreach ($collection as $key => $row) { + if ($row instanceof Collection) { + $infoArr = $this->extractInfoFromExcelCollection($row); + foreach ($infoArr as $info) { + if (str_contains(strtolower($info), strtolower($keyword))) { + return $key; + } + } + } else { + if (str_contains(strtolower($row), strtolower($keyword))) { + return $key; + } + } + + } + } + + // return an array with information of the row start from 0 index + private function extractInfoFromExcelCollection($collection) + { + return array_values(array_filter($collection->toArray())); } }