diff --git a/app/Classes/General/Eloquent/Filters/GroupByImportedDate.php b/app/Classes/General/Eloquent/Filters/GroupByImportedDate.php new file mode 100644 index 00000000..25f20fa3 --- /dev/null +++ b/app/Classes/General/Eloquent/Filters/GroupByImportedDate.php @@ -0,0 +1,18 @@ +groupby('imported_date'); + } +} \ No newline at end of file diff --git a/app/Classes/General/Eloquent/Filters/ImportedDateFrom.php b/app/Classes/General/Eloquent/Filters/ImportedDateFrom.php new file mode 100644 index 00000000..140bbb20 --- /dev/null +++ b/app/Classes/General/Eloquent/Filters/ImportedDateFrom.php @@ -0,0 +1,18 @@ +whereDate('imported_date', '>=', date('Y-m-d',strtotime($value))); + } +} \ No newline at end of file diff --git a/app/Classes/General/Eloquent/Filters/ImportedDateTo.php b/app/Classes/General/Eloquent/Filters/ImportedDateTo.php new file mode 100644 index 00000000..11bd3857 --- /dev/null +++ b/app/Classes/General/Eloquent/Filters/ImportedDateTo.php @@ -0,0 +1,18 @@ +whereDate('imported_date', '<=', date('Y-m-d',strtotime($value))); + } +} \ No newline at end of file diff --git a/app/Classes/General/Eloquent/Filters/StatementTransactionInvoiceReference.php b/app/Classes/General/Eloquent/Filters/StatementTransactionInvoiceReference.php new file mode 100644 index 00000000..9e3ba1e9 --- /dev/null +++ b/app/Classes/General/Eloquent/Filters/StatementTransactionInvoiceReference.php @@ -0,0 +1,22 @@ +whereHas('owners', function ($query) use ($value) { + return $query->where('Invoice_reference', $value); + }); + } + +} diff --git a/app/Classes/General/Eloquent/Filters/StatementTransactionOwnerReference.php b/app/Classes/General/Eloquent/Filters/StatementTransactionOwnerReference.php new file mode 100644 index 00000000..c0a7beaf --- /dev/null +++ b/app/Classes/General/Eloquent/Filters/StatementTransactionOwnerReference.php @@ -0,0 +1,22 @@ +whereHas('owners', function ($query) use ($value) { + return $query->where('owner_reference', $value); + }); + } + +} diff --git a/app/Classes/General/Eloquent/Filters/StatementTransactionReceiptReference.php b/app/Classes/General/Eloquent/Filters/StatementTransactionReceiptReference.php new file mode 100644 index 00000000..f808f784 --- /dev/null +++ b/app/Classes/General/Eloquent/Filters/StatementTransactionReceiptReference.php @@ -0,0 +1,22 @@ +whereHas('owners', function ($query) use ($value) { + return $query->where('receipt_reference', $value); + }); + } + +} diff --git a/app/Classes/General/Eloquent/Filters/WhereHasOwnersAndNotNull.php b/app/Classes/General/Eloquent/Filters/WhereHasOwnersAndNotNull.php new file mode 100644 index 00000000..b10fd92d --- /dev/null +++ b/app/Classes/General/Eloquent/Filters/WhereHasOwnersAndNotNull.php @@ -0,0 +1,22 @@ +whereHas('owners', function ($query) use ($value) { + return $query->whereNotNull($value); + }); + } + +} \ No newline at end of file diff --git a/app/Classes/General/Eloquent/Filters/WhereHasOwnersAndNull.php b/app/Classes/General/Eloquent/Filters/WhereHasOwnersAndNull.php new file mode 100644 index 00000000..a9317771 --- /dev/null +++ b/app/Classes/General/Eloquent/Filters/WhereHasOwnersAndNull.php @@ -0,0 +1,22 @@ +whereHas('owners', function ($query) use ($value) { + return $query->whereNull($value); + }); + } + +} \ No newline at end of file diff --git a/app/Classes/General/Services/GuzzleShippingPortal.php b/app/Classes/General/Services/GuzzleShippingPortal.php new file mode 100644 index 00000000..2fed1e9a --- /dev/null +++ b/app/Classes/General/Services/GuzzleShippingPortal.php @@ -0,0 +1,25 @@ + false]); + $response = $client->request('GET', $url . '?api-key=510acd13d8d24375cf038ad626c282565451461a9c2399357e0b65365300787e&'. $requests); + $body = $response->getBody(); + $data = json_decode($body, true); + $payload = $data['payload']; + return $payload['data']; + } catch (\Exception $exception) { + Log::error($exception->getMessage()); + Log::channel('guzzleShippingPortal')->debug($exception->getMessage()); + return []; + } + } +} diff --git a/app/Classes/Modules/Accounting/ControllersLogic/GroupApproveStatementTransactionLogic.php b/app/Classes/Modules/Accounting/ControllersLogic/GroupApproveStatementTransactionLogic.php index f9eb9c7b..7ae8a2ae 100644 --- a/app/Classes/Modules/Accounting/ControllersLogic/GroupApproveStatementTransactionLogic.php +++ b/app/Classes/Modules/Accounting/ControllersLogic/GroupApproveStatementTransactionLogic.php @@ -62,7 +62,7 @@ class GroupApproveStatementTransactionLogic extends AbstractControllerLogic $statementTransactions = $this->listsBankStatementTransactions->execute($filters); foreach ($statementTransactions as $statementTransaction) { - $owners = $statementTransaction->owners; + $owners = $statementTransaction->owners()->where('status', ApprovalStatus::PENDING_VERIFICATION)->get(); if (count($owners)) { $this->updatesBankStatementTransactionOwnerStatus->execute($owners->first(), ApprovalStatus::APPROVED); diff --git a/app/Classes/Modules/Accounting/ControllersLogic/HistoryImportedTransactionMappedControllerLogic.php b/app/Classes/Modules/Accounting/ControllersLogic/HistoryImportedTransactionMappedControllerLogic.php new file mode 100644 index 00000000..2f96c613 --- /dev/null +++ b/app/Classes/Modules/Accounting/ControllersLogic/HistoryImportedTransactionMappedControllerLogic.php @@ -0,0 +1,49 @@ + 'Retrieved History Imported Invoices', + 'message' => 'You have successfully retrieved history imported invoices' + ]; + } + + /** @var ListTransactionMappingLogs */ + private $listTransactionMappingLogs; + + /** + * UpdateAnnouncementLogic constructor. + * @param ListTransactionMappingLogs $listTransactionMappingLogs + */ + public function __construct( + ListTransactionMappingLogs $listTransactionMappingLogs + ) { + $this->listTransactionMappingLogs = $listTransactionMappingLogs; + } + + /** + * @param Request $request + * @return JsonResponse + */ + public function logic(Request $request): JsonResponse + { + $query = $this->listTransactionMappingLogs->execute($this->listTransactionMappingLogs->deserializeFilters($request->input('filters'))); + + return $this->collectionResponse(TransactionMappingLogResource::collection($query)); + } +} diff --git a/app/Classes/Modules/Accounting/ControllersLogic/UpdateBankStatementDetailLogic.php b/app/Classes/Modules/Accounting/ControllersLogic/UpdateBankStatementDetailLogic.php index 9f6c28e6..70186ce1 100644 --- a/app/Classes/Modules/Accounting/ControllersLogic/UpdateBankStatementDetailLogic.php +++ b/app/Classes/Modules/Accounting/ControllersLogic/UpdateBankStatementDetailLogic.php @@ -157,7 +157,7 @@ class UpdateBankStatementDetailLogic extends AbstractControllerLogic 'owner_reference' => $owner_reference, ]; - return $bankStatementTransaction->owners()->firstOrCreate($ownerData); + return $bankStatementTransaction->owners()->where('status','<>',ApprovalStatus::REJECTED)->firstOrCreate($ownerData); } private function editAccountMapped(StatementTransactionOwner $owner){ diff --git a/app/Classes/Modules/Accounting/Services/ListTransactionMappingLogs.php b/app/Classes/Modules/Accounting/Services/ListTransactionMappingLogs.php new file mode 100644 index 00000000..fdeff835 --- /dev/null +++ b/app/Classes/Modules/Accounting/Services/ListTransactionMappingLogs.php @@ -0,0 +1,32 @@ +repository = $repository; + } + + + /** + * @return Builder + */ + public function getRepository(): Builder + { + return $this->repository->newQuery(); + } +} diff --git a/app/Classes/Modules/Exports/Services/ExportsImportedInvoiceMappeds.php b/app/Classes/Modules/Exports/Services/ExportsImportedInvoiceMappeds.php index 71363b52..ead22543 100644 --- a/app/Classes/Modules/Exports/Services/ExportsImportedInvoiceMappeds.php +++ b/app/Classes/Modules/Exports/Services/ExportsImportedInvoiceMappeds.php @@ -39,7 +39,8 @@ class ExportsImportedInvoiceMappeds implements FromQuery, WithHeadings, WithHead 'Net Total', 'Cancelled', 'Mapped Status', - 'Mapped Reference No' + 'Mapped Reference No', + 'MapPayment Received Date' ]; } @@ -58,7 +59,6 @@ class ExportsImportedInvoiceMappeds implements FromQuery, WithHeadings, WithHead */ public function map($transaction): array { - // dd($transaction); $this->count += 1; $data = $transaction->data; return [ @@ -72,6 +72,7 @@ class ExportsImportedInvoiceMappeds implements FromQuery, WithHeadings, WithHead Arr::get($data,'cancelled'), Arr::get($data,'mapped_status'), Arr::get($data,'mapped_result_reference'), + Arr::get($data,'payment_received_date'), ]; } diff --git a/app/Classes/Modules/Exports/Services/ExportsImportedReceiptMappeds.php b/app/Classes/Modules/Exports/Services/ExportsImportedReceiptMappeds.php new file mode 100644 index 00000000..efe95fd3 --- /dev/null +++ b/app/Classes/Modules/Exports/Services/ExportsImportedReceiptMappeds.php @@ -0,0 +1,86 @@ +dateTime = $request->input('date').' '.$request->input('time'); + $this->count = 0; + } + + public function headings(): array + { + return [ + 'Check', + 'Doc No', + 'Doc Date', + 'Debtor Code', + 'Company Name', + 'Description', + 'Payment Amount', + 'Created User', + 'Curr.', + 'To Home Rate', + 'Local Payment Amount', + 'Cancelled', + 'Mapped Status', + 'Mapped Reference No', + ]; + } + + /** + * @return \Illuminate\Support\Collection|mixed + */ + public function query() + { + return TransactionMappingLog::where('imported_date', $this->dateTime); + } + + /** + * @param Transaction $transaction + * + * @return array + */ + public function map($transaction): array + { + $this->count += 1; + $data = $transaction->data; + return [ + $this->count, + Arr::get($data,'doc_no'), + Arr::get($data,'doc_date'), + Arr::get($data,'debtor_code'), + Arr::get($data,'company_name'), + Arr::get($data,'description'), + Arr::get($data,'payment_amount'), + Arr::get($data,'created_user'), + Arr::get($data,'curr'), + Arr::get($data,'to_home_rate'), + Arr::get($data,'local_payment_amount'), + Arr::get($data,'cancelled'), + Arr::get($data,'2nd_doc_no'), + Arr::get($data,'mapped_status'), + Arr::get($data,'mapped_result_reference'), + ]; + + } +} diff --git a/app/Classes/Modules/Exports/Services/ExportsInvoiceTransactions.php b/app/Classes/Modules/Exports/Services/ExportsInvoiceTransactions.php index a7041b1c..ee07f435 100644 --- a/app/Classes/Modules/Exports/Services/ExportsInvoiceTransactions.php +++ b/app/Classes/Modules/Exports/Services/ExportsInvoiceTransactions.php @@ -19,6 +19,7 @@ use App\Classes\ValueObjects\Constants\TransactionType; use Illuminate\Support\Facades\Log; use App\Classes\General\Eloquent\ApplyFiltersToQuery; use App\Models\StatementTransaction; +use App\Classes\General\Services\GuzzleShippingPortal; class ExportsInvoiceTransactions implements FromQuery, WithHeadings, WithHeadingRow, WithMapping, ShouldAutoSize { @@ -124,12 +125,11 @@ class ExportsInvoiceTransactions implements FromQuery, WithHeadings, WithHeading $textToAppend = Carbon::now()->format('[Y-m-d H:i:s]') . ' Shipping Portal Respnose ' . json_encode($row) . PHP_EOL; file_put_contents($errorFilePath, $textToAppend, FILE_APPEND); - - Log::info('Error in Exports Invoice Transactions ' . $this->counter); + $transactionShippingPortal = $this->getFromShippingPortal($statementTransactionOwner->owner_id); return [ 'Transaction Not Found', - $transaction->posting_date->format('m/d/Y H:m'), + (isset($transactionShippingPortal['created_at']) ? Carbon::parse($transactionShippingPortal['created_at'])->format('m/d/Y H:m') : null), $transaction->transaction_description.' - '.$transaction->transaction_description_2, $statementTransactionOwner->system, '', @@ -167,4 +167,9 @@ class ExportsInvoiceTransactions implements FromQuery, WithHeadings, WithHeading ]; } } + + private function getFromShippingPortal($id){ + $data = (new guzzleShippingPortal)->execute('transactions/mappable/query','filters={"id":'.$id.'}'); + return (count($data) > 0 ? $data[0] : null); + } } diff --git a/app/Classes/Modules/Exports/Services/ExportsReceiptTransactions.php b/app/Classes/Modules/Exports/Services/ExportsReceiptTransactions.php index 07c5d3c1..bde46225 100644 --- a/app/Classes/Modules/Exports/Services/ExportsReceiptTransactions.php +++ b/app/Classes/Modules/Exports/Services/ExportsReceiptTransactions.php @@ -15,8 +15,11 @@ use Illuminate\Support\Facades\Log; use App\Classes\General\Eloquent\ApplyFiltersToQuery; use App\Models\StatementTransaction; use App\Models\Company; +use Maatwebsite\Excel\Concerns\WithEvents; +use Maatwebsite\Excel\Concerns\WithCustomStartCell; +use Maatwebsite\Excel\Events\AfterSheet; -class ExportsReceiptTransactions implements FromQuery, WithHeadings, WithHeadingRow, WithMapping, ShouldAutoSize +class ExportsReceiptTransactions implements FromQuery, WithHeadings, WithHeadingRow, WithMapping, ShouldAutoSize, WithEvents, WithCustomStartCell { use Exportable; @@ -28,37 +31,101 @@ class ExportsReceiptTransactions implements FromQuery, WithHeadings, WithHeading $this->request = $request; } + public function startCell(): string + { + return 'A2'; + } + + public function registerEvents(): array { + + return [ + AfterSheet::class => function(AfterSheet $event) { + $sheet = $event->sheet; + + $sheet->mergeCells('A1:A1'); + $sheet->setCellValue('A1', '"'); + + $sheet->mergeCells('M1:Y1'); + $sheet->setCellValue('M1', "Payment Detail Column"); + + $sheet->mergeCells('Z1:AB1'); + $sheet->setCellValue('Z1', "Knock Off Detail"); + + $styleArray = [ + 'alignment' => [ + 'horizontal' => \PhpOffice\PhpSpreadsheet\Style\Alignment::HORIZONTAL_CENTER, + ], + ]; + + $cellRange = 'A1:AB1'; + $event->sheet->getDelegate()->getStyle($cellRange)->applyFromArray($styleArray); + }, + ]; + } + public function headings(): array { $header = [ - 'DocNo', - 'DocDate', - 'DebtorCode', - 'Description', - 'DocNo2', - 'ProjNo', - 'DeptNo', - 'CurrencyCode', - 'ToHomeRate', - 'ToDebtorRate', - 'Note', - 'PaymentMethod', - 'ChequeNo', - 'PaymentAmt', - 'BankCharge', - 'ToBankRate', - 'BankChargeTaxType', - 'BankChargeTaxRefNo', - 'BankChargeProjNo', - 'BankChargeDeptNo', - 'PaymentBy', - 'FloatDay', - 'IsRCHQ', - 'RCHQDate', - 'KnockOffDocType', - 'KnockOffDocNo', - 'KnockOffAmt', - '', + [ + ' ', + '(20 chars)', + '(Date: dd/MM/yyyy)', + '(12 chars)', + '(40 chars)', + '(25 chars)', + '(10 chars)', + '(10 chars)', + '(5 chars)', + '(Number, use System Currency Rate Decimal)', + '(Number, use System Currency Rate Decimal)', + '(Rich Text)', + '(20 chars)', + '(20 chars)', + '(Number, use System Currency Decimal)', + '(Number, use System Currency Decimal)', + '(Number, use System Currency Rate Decimal)', + '(14 chars)', + '(30 chars)', + '(10 chars)', + '(10 chars)', + '(20 chars)', + '(Integer)', + '(Boolean. Indicate T for stock control or F for non stock control)', + '(Returned Cheque Date: dd/MM/yyyy)', + '(2 chars, RI for Invoice, RD for D/N)', + '', + '(Number, use System Currency Decimal)', + ], + [ + 'DocNo', + 'DocDate', + 'DebtorCode', + 'Description', + 'DocNo2', + 'ProjNo', + 'DeptNo', + 'CurrencyCode', + 'ToHomeRate', + 'ToDebtorRate', + 'Note', + 'PaymentMethod', + 'ChequeNo', + 'PaymentAmt', + 'BankCharge', + 'ToBankRate', + 'BankChargeTaxType', + 'BankChargeTaxRefNo', + 'BankChargeProjNo', + 'BankChargeDeptNo', + 'PaymentBy', + 'FloatDay', + 'IsRCHQ', + 'RCHQDate', + 'KnockOffDocType', + 'KnockOffDocNo', + 'KnockOffAmt', + '', + ] ]; return $header; } @@ -102,7 +169,7 @@ class ExportsReceiptTransactions implements FromQuery, WithHeadings, WithHeading '<>', Carbon::parse($transaction->posting_date)->format('d/m/Y'), ($company ? $company->debtor : null), - $transaction->transaction_description, + 'Payment for '.$transaction->transaction_description, '', '', '', diff --git a/app/Http/Controllers/Accounting/HistoryImportedTransactionMappedController.php b/app/Http/Controllers/Accounting/HistoryImportedTransactionMappedController.php new file mode 100644 index 00000000..8b4a2cde --- /dev/null +++ b/app/Http/Controllers/Accounting/HistoryImportedTransactionMappedController.php @@ -0,0 +1,20 @@ +execute($request); + } + +} \ No newline at end of file diff --git a/app/Http/Controllers/Exports/ExportCustomersToExcelController.php b/app/Http/Controllers/Exports/ExportCustomersToExcelController.php index 733c84fa..0f351c7d 100644 --- a/app/Http/Controllers/Exports/ExportCustomersToExcelController.php +++ b/app/Http/Controllers/Exports/ExportCustomersToExcelController.php @@ -18,6 +18,7 @@ use Maatwebsite\Excel\Excel; use App\Classes\Modules\Exports\Services\ExportsImportedInvoiceMappeds; use App\Models\TransactionMappingLog; use App\Classes\Modules\Exports\Services\ExportsReceiptTransactions; +use App\Classes\Modules\Exports\Services\ExportsImportedReceiptMappeds; class ExportCustomersToExcelController { @@ -91,4 +92,10 @@ class ExportCustomersToExcelController ob_end_clean(); return $response; } + + public function importedReceiptMapped(ExportsImportedReceiptMappeds $exportsImportedReceiptMappeds, Request $request) { + $response = $exportsImportedReceiptMappeds->download($request->input('fileName').'.xls', Excel::XLS, ['Content-Type' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet']); + ob_end_clean(); + return $response; + } } \ No newline at end of file diff --git a/app/Http/Controllers/Imports/ImportStatementInvoiceController.php b/app/Http/Controllers/Imports/ImportStatementInvoiceController.php index 8d2b920b..e4c35eb5 100644 --- a/app/Http/Controllers/Imports/ImportStatementInvoiceController.php +++ b/app/Http/Controllers/Imports/ImportStatementInvoiceController.php @@ -34,99 +34,124 @@ class ImportStatementInvoiceController $this->responseMessage = 'You have successfully imported invoice mapping'; } + public function mapping($row) { + // Shipping Info + // TOPUP -> map with transaction.bill_no + if (str_starts_with($row['shipping_info'], 'TOPUP')) { + // find in exchange first, if cannont then find in izyim + foreach (['exchange','izyim'] as $system) { + [$returnReference, $transactionDate] = $this->mappingTopUp($row, $system); + if ($returnReference) { + // $row['mapped_result_reference'] = $data['owner_reference']; + // $row['payment_received_date'] = date('Y-m-d', strtotime($data['created_at'])); + $row['mapped_result_reference'] = $returnReference; + $row['payment_received_date'] = $transactionDate ? date('d-m-Y', strtotime($transactionDate)) : null; + $row['mapped_status'] = 'success'; + return $row; + } + } + } + + [$returnReference, $transactionDate] = $this->mappingExchange($row); + if ($returnReference) { + $row['mapped_result_reference'] = $returnReference; + $row['payment_received_date'] = date('d-m-Y', strtotime($transactionDate)); + $row['mapped_status'] = 'success'; + return $row; + } + + // if still unable to map, will try to check the shipping_info without TOPUP + // foreach (['exchange','izyim'] as $system) { + // $returnReference = $this->mappingTopUp($row, $system); + // if ($returnReference) { + // $row['mapped_result_reference'] = $returnReference; + // $row['mapped_status'] = 'success'; + // } + // } + + return $row; + } + /** * @param Request $request * @return array - * @throws \App\Classes\Exceptions\MalformedRequestException */ public function import(Request $request) : JsonResponse { - ini_set('memory_limit', '-1'); - $importDate = date('Y-m-d H:i:s'); - $object = new DocumentObject('', $request->input('files'), '', ApprovalStatus::APPROVED, 'imports'); - $file = json_decode($object->getFiles()[0])->file_info->original->file; + try { + ini_set('memory_limit', '-1'); + $importDate = date('Y-m-d H:i:s'); + $object = new DocumentObject('', $request->input('files'), '', ApprovalStatus::APPROVED, 'imports'); + $file = json_decode($object->getFiles()[0])->file_info->original->file; - $import = new GenericImport(); - Excel::import($import, $file); - $excelRows = $import->rows; - $excelRows = $excelRows->toArray(); + $import = new GenericImport(); + Excel::import($import, $file); + $excelRows = $import->rows; + $excelRows = $excelRows->toArray(); + + $data = []; + foreach ($excelRows as $row) { + $row['mapped_result_reference'] = null; + $row['payment_received_date'] = null; + $row['mapped_status'] = 'failed'; + $row['date'] = in_array(gettype($row['date']), ['integer', 'double']) ? $this->changeExcelDate($row['date']) : date('Y-m-d', strtotime($row['date'])); + + $row = $this->mapping($row); + + TransactionMappingLog::create([ + 'imported_date'=>$importDate, + 'type' => 'invoices', + 'data'=>$row, + ]); + array_push($data, $row); + + + // if 5 digits -> exchange booking reference + // find transation + // find statement_transaction_owners, and fill up the details + + // if <5 digits, find the transaction id (order number in izyim), find the payment in izyim + // find transation + // find statement_transaction_owners, and fill up the details + + // dd([ + // 'type' => $statementTransactionOwnerType, + // 'system' => $system, + // // 'owner_type' => Transaction::class, + // // todo-new: make sure owner_type is a class + // 'owner_type' => $owner_type, + // 'owner_id' => $owner_id, + // 'owner_reference' => $owner_reference + // ]); + + // $bankStatementTransaction->owners()->firstOrCreate([ + // 'type' => $statementTransactionOwnerType, + // 'system' => $system, + // // 'owner_type' => Transaction::class, + // // todo-new: make sure owner_type is a class + // 'owner_type' => $owner_type, + // 'owner_id' => $owner_id, + // 'owner_reference' => $owner_reference + // ]); - $data = []; - foreach ($excelRows as $row) { - $row['mapped_result_reference'] = null; - $row['mapped_status'] = 'failed'; - $row['date'] = date('Y-m-d', strtotime($row['date'])); - // Shipping Info - // TOPUP -> map with transaction.bill_no - if (str_starts_with($row['shipping_info'], 'TOPUP')) { - // find in exchange first, if cannont then find in izyim - foreach (['exchange','izyim'] as $system) { - $returnReference = $this->mappingTopUp($row, $system); - if ($returnReference) { - $row['mapped_result_reference'] = $returnReference; - $row['mapped_status'] = 'success'; - } - } - } else { - $returnReference = $this->mappingExchange($row); - if ($returnReference) { - $row['mapped_result_reference'] = $returnReference; - $row['mapped_status'] = 'success'; - } } - TransactionMappingLog::create([ - 'imported_date'=>$importDate, - 'data'=>$row, - ]); - array_push($data, $row); - - - // if 5 digits -> exchange booking reference - // find transation - // find statement_transaction_owners, and fill up the details - - // if <5 digits, find the transaction id (order number in izyim), find the payment in izyim - // find transation - // find statement_transaction_owners, and fill up the details - - // dd([ - // 'type' => $statementTransactionOwnerType, - // 'system' => $system, - // // 'owner_type' => Transaction::class, - // // todo-new: make sure owner_type is a class - // 'owner_type' => $owner_type, - // 'owner_id' => $owner_id, - // 'owner_reference' => $owner_reference - // ]); - - // $bankStatementTransaction->owners()->firstOrCreate([ - // 'type' => $statementTransactionOwnerType, - // 'system' => $system, - // // 'owner_type' => Transaction::class, - // // todo-new: make sure owner_type is a class - // 'owner_type' => $owner_type, - // 'owner_id' => $owner_id, - // 'owner_reference' => $owner_reference - // ]); - - + return $this->response($this->responseTitle, $this->responseMessage, HttpStatus::OK_WITH_MESSAGE, ['data'=>$data,'importedDate'=>$importDate]); + } catch (\Exception $exception){ + return $this->response('import invoice failed',$exception->getMessage(), ($exception->getCode()? $exception->getCode() : HttpStatus::SERVER_ERROR)); } - - return $this->response(['data'=>$data,'importedDate'=>$importDate]); } - public function response(?array $data = []) : JsonResponse { - return (new ApiResponseObject($this->responseTitle, - $this->responseMessage, - HttpStatus::OK_WITH_MESSAGE, $data))->handler(); + public function response(String $responseTitle, String $responseMessage, int $httpStatus, ?array $data = []) : JsonResponse { + return (new ApiResponseObject($responseTitle, $responseMessage, $httpStatus, $data))->handler(); } private function mappingTopUp(Array $row, String $system) { try { if ($data = (App()->make(ChecksBillNumber::class))->execute($row['shipping_info'], $system)) { - if ($system == 'izyim' && isset($data['owner_reference'])) return $data['owner_reference']; + // if ($system == 'izyim' && isset($data['owner_reference'])) return $data; + if ($system == 'izyim' && isset($data['owner_reference'])) return [$data['owner_reference'], null]; if ($system == 'exchange') return $this->updateTransactionOwnerReference($data, $row['doc_no']); } @@ -137,18 +162,20 @@ class ImportStatementInvoiceController private function mappingExchange(Array $row) { $date = $row['date']; - $transactions = Transaction::getReceiverWithJoinStatementTransactionAndOwner($row)->select('transactions.*')->where('statement_transactions.amount', $row['net_total'])->whereRaw("DATE(posting_date) = '$date'")->get(); - - if ($transactions && $transactions->count() == 0) { - $transactions = Transaction::getReceiverWithJoinStatementTransactionAndOwner($row)->select('transactions.*')->where(DB::raw('FLOOR(statement_transactions.amount)'), floor($row['net_total']))->whereRaw("DATE(posting_date) = '$date'")->get(); + $transaction = Transaction::getReceiverWithJoinStatementTransactionAndOwner($row)->select('transactions.*')->where('owner_reference', $row['shipping_info'])->first(); + + if ($transaction && $transaction->count() == 0) { + $transaction = Transaction::getReceiverWithJoinStatementTransactionAndOwner($row)->select('transactions.*')->where('statement_transactions.amount', $row['net_total'])->whereRaw("DATE(posting_date) = '$date'")->first(); } - if ($transactions && $transactions->count() == 1) { - foreach ($transactions as $key => $transaction) { - return $this->updateTransactionOwnerReference($transaction, $row['doc_no']); - } + if ($transaction && $transaction->count() == 0) { + $transaction = Transaction::getReceiverWithJoinStatementTransactionAndOwner($row)->select('transactions.*')->where(DB::raw('FLOOR(statement_transactions.amount)'), floor($row['net_total']))->whereRaw("DATE(posting_date) = '$date'")->first(); } - return false; + + if ($transaction && $transaction->count() > 0) { + return $this->updateTransactionOwnerReference($transaction, $row['doc_no']); + } + return [false, false]; } public function updateTransactionOwnerReference($transaction, String $docNo) { @@ -158,8 +185,15 @@ class ImportStatementInvoiceController 'invoice_reference'=>$docNo, 'status'=>ApprovalStatus::COMPLETED ]); - return $transactionOwner->owner_reference; + return [$transactionOwner->owner_reference, $transaction->created_at]; } - return false; + return [false, false]; + } + + public function changeExcelDate($date) + { + $unixTime = (($date - 25569) * 86400); + $date = new DateTime("@$unixTime"); + return $date->format('Y-m-d'); // Change the format to 'Y-m-d' } } diff --git a/app/Http/Controllers/Imports/ImportStatementReceiptsController.php b/app/Http/Controllers/Imports/ImportStatementReceiptsController.php index 4006e130..6c117642 100644 --- a/app/Http/Controllers/Imports/ImportStatementReceiptsController.php +++ b/app/Http/Controllers/Imports/ImportStatementReceiptsController.php @@ -2,32 +2,35 @@ namespace App\Http\Controllers\Imports; -use App\Classes\Modules\Documents\DataTransferObjects\DocumentObject; -use App\Classes\Modules\Imports\Services\GenericImport; -use App\Classes\Modules\Segments\DataTransferObjects\SeasonalSegmentObject; -use App\Classes\ValueObjects\Constants\ApprovalStatus; -use App\Models\Segment; -use App\Models\User; -use Carbon\Carbon; use DateTime; -use Illuminate\Http\Request; -use Maatwebsite\Excel\Facades\Excel; -use App\Classes\Modules\Segments\Services\CreatesSeasonalSegment; -use App\Classes\Modules\Companies\Processors\AssignSegmentProcessor; +use Carbon\Carbon; +use App\Models\User; use App\Models\Company; -use App\Models\SeasonalSegment; +use App\Models\Segment; use App\Models\Transaction; -use App\Models\TransactionMappingLog; -use App\Classes\ValueObjects\Response\ApiResponseObject; -use App\Classes\ValueObjects\Constants\HttpStatus; +use Illuminate\Http\Request; +use App\Models\SeasonalSegment; use Illuminate\Http\JsonResponse; use Illuminate\Support\Facades\DB; +use Maatwebsite\Excel\Facades\Excel; +use App\Models\TransactionMappingLog; +use App\Models\StatementTransactionOwner; +use App\Classes\ValueObjects\Constants\HttpStatus; +use App\Classes\ValueObjects\Constants\ApprovalStatus; +use App\Classes\Modules\Imports\Services\GenericImport; +use App\Classes\ValueObjects\Response\ApiResponseObject; +use App\Classes\Modules\Segments\Services\CreatesSeasonalSegment; +use App\Classes\Modules\Companies\Processors\AssignSegmentProcessor; +use App\Classes\Modules\Documents\DataTransferObjects\DocumentObject; +use App\Classes\Modules\Segments\DataTransferObjects\SeasonalSegmentObject; class ImportStatementReceiptsController { private $responseTitle; private $responseMessage; + private $removeStr = 'Payment for '; + public function __construct() { $this->responseTitle = 'Import Receipt Mapping'; $this->responseMessage = 'You have successfully imported receipt mapping'; @@ -40,61 +43,64 @@ class ImportStatementReceiptsController */ public function import(Request $request) { - $importDate = date('Y-m-d H:i:s'); - $object = new DocumentObject('', $request->input('files'), '', ApprovalStatus::APPROVED, 'imports'); - $file = json_decode($object->getFiles()[0])->file_info->original->file; + try { + $importDate = date('Y-m-d H:i:s'); + $object = new DocumentObject('', $request->input('files'), '', ApprovalStatus::APPROVED, 'imports'); + $file = json_decode($object->getFiles()[0])->file_info->original->file; - $import = new GenericImport(); - Excel::import($import, $file); - $excelRows = $import->rows; - $excelRows = $excelRows->toArray(); + $import = new GenericImport(); + Excel::import($import, $file); + $excelRows = $import->rows; + $excelRows = $excelRows->toArray(); - $data = []; - foreach ($excelRows as $row) { - $row['mapped_result_reference'] = null; - $row['mapped_status'] = 'failed'; - $row['date'] = date('Y-m-d', strtotime($row['doc_date'])); + $data = []; + foreach ($excelRows as $row) { + $row['mapped_result_reference'] = null; + $row['mapped_status'] = 'failed'; + $row['date'] = in_array(gettype($row['doc_date']), ['integer', 'double']) ? $this->changeExcelDate($row['doc_date']) : date('Y-m-d', strtotime($row['doc_date'])); - $returnReference = $this->mappingExchange($row); - if ($returnReference) { - $row['mapped_result_reference'] = $returnReference; - $row['mapped_status'] = 'success'; - } + if ($invRefer = $this->getInvoiceReference($row['description'])) { + $returnReference = $this->mappingExchange($invRefer, $row['doc_no']); + if ($returnReference) { + $row['mapped_result_reference'] = $returnReference; + $row['mapped_status'] = 'success'; + } + } - TransactionMappingLog::create([ - 'imported_date'=>$importDate, - 'data'=>$row, - ]); - array_push($data, $row); - } - - return $this->response(['data'=>$data,'importedDate'=>$importDate]); - } - - public function response(?array $data = []) : JsonResponse { - return (new ApiResponseObject($this->responseTitle, - $this->responseMessage, - HttpStatus::OK_WITH_MESSAGE, $data))->handler(); - } - - private function mappingExchange(Array $row) { - $date = $row['date']; - $transactions = Transaction::getReceiverWithJoinStatementTransactionAndOwner($row)->select('transactions.*')->where('statement_transactions.amount', $row['payment_amount'])->whereRaw("DATE(posting_date) = '$date'")->get(); - - if ($transactions && $transactions->count() == 0) { - $transactions = Transaction::getReceiverWithJoinStatementTransactionAndOwner($row)->select('transactions.*')->where(DB::raw('FLOOR(statement_transactions.amount)'), floor($row['payment_amount']))->whereRaw("DATE(posting_date) = '$date'")->get(); - } - - if ($transactions && $transactions->count() == 1) { - foreach ($transactions as $key => $transaction) { - return $this->updateTransactionOwnerReference($transaction, $row['doc_no']); + TransactionMappingLog::create([ + 'imported_date'=>$importDate, + 'type' => 'receipts', + 'data'=>$row, + ]); + array_push($data, $row); } + + return $this->response($this->responseTitle, $this->responseMessage, HttpStatus::OK_WITH_MESSAGE, ['data'=>$data,'importedDate'=>$importDate]); + } catch (\Exception $exception){ + return $this->response('import invoice failed',$exception->getMessage(), ($exception->getCode()? $exception->getCode() : HttpStatus::SERVER_ERROR)); + } + } + + private function getInvoiceReference($invRefer) { + $arrStr = explode($this->removeStr, $invRefer); + if (isset($arrStr[1])) return $arrStr[1]; + return null; + } + + public function response(String $responseTitle, String $responseMessage, int $httpStatus, ?array $data = []) : JsonResponse { + return (new ApiResponseObject($responseTitle, $responseMessage, $httpStatus, $data))->handler(); + } + + private function mappingExchange($invRefer, $docNo) { + $transactionOwner = StatementTransactionOwner::where('invoice_reference',$invRefer)->whereNull('receipt_reference')->where('status', ApprovalStatus::COMPLETED)->first(); + + if ($transactionOwner) { + return $this->updateTransactionOwnerReference($transactionOwner, $docNo); } return false; } - public function updateTransactionOwnerReference($transaction, String $docNo) { - $transactionOwner = $transaction->transaction_owner; + public function updateTransactionOwnerReference($transactionOwner, String $docNo) { if ($transactionOwner) { $transactionOwner->update([ 'receipt_reference'=>$docNo, @@ -104,4 +110,11 @@ class ImportStatementReceiptsController } return false; } + + public function changeExcelDate($date) + { + $unixTime = (($date - 25569) * 86400); + $date = new DateTime("@$unixTime"); + return $date->format('Y-m-d'); // Change the format to 'Y-m-d' + } } diff --git a/app/Http/Resources/BankStatementTransactionResource.php b/app/Http/Resources/BankStatementTransactionResource.php index 993b8c93..8f5e0193 100644 --- a/app/Http/Resources/BankStatementTransactionResource.php +++ b/app/Http/Resources/BankStatementTransactionResource.php @@ -34,7 +34,8 @@ class BankStatementTransactionResource extends JsonResource 'owners' => [ 'approved' => BankStatementTransactionOwnerResource::collection($this->owners()->whereIn('status', [ApprovalStatus::APPROVED])->get()), 'pending_verification' => BankStatementTransactionOwnerResource::collection($this->owners()->whereIn('status', [ApprovalStatus::PENDING_VERIFICATION])->get()), - 'rejected' => BankStatementTransactionOwnerResource::collection($this->owners()->whereIn('status', [ApprovalStatus::REJECTED])->get()) + 'rejected' => BankStatementTransactionOwnerResource::collection($this->owners()->whereIn('status', [ApprovalStatus::REJECTED])->get()), + 'completed' => BankStatementTransactionOwnerResource::collection($this->owners()->whereIn('status', [ApprovalStatus::COMPLETED])->get()), ] ]; } diff --git a/app/Http/Resources/TransactionMappingLogResource.php b/app/Http/Resources/TransactionMappingLogResource.php new file mode 100644 index 00000000..954294f1 --- /dev/null +++ b/app/Http/Resources/TransactionMappingLogResource.php @@ -0,0 +1,23 @@ + $this->id, + 'imported_date' => $this->imported_date, + 'type' => $this->type + ]; + } +} diff --git a/app/Models/Company.php b/app/Models/Company.php index 8b2e6081..54ae1e23 100644 --- a/app/Models/Company.php +++ b/app/Models/Company.php @@ -109,7 +109,7 @@ class Company extends AbstractModel implements Documentable { return $this->hasManyDeep(Transaction::class, [Booking::class], ['company_id', 'owner_id'], ['id', 'id']); } - + /** * @return HasMany */ @@ -130,13 +130,25 @@ class Company extends AbstractModel implements Documentable * @return Builder */ public function services(): Builder { - return ServiceType::where('status', ApprovalStatus::APPROVED)->whereHas('constants', function($query) { - $query->Where(function($query){ - $query->where('reference', SegmentConstants::SERVICE_TYPE)->where('detail->is_active', true); - })->orWhere(function($query) { - $query->where('reference', SegmentConstants::CUSTOM_SERVICE_TYPE)->where('detail->is_active', true)->whereIn('segment_id', $this->segments->pluck('id')); + + if ($this->business_type === 3) { + return ServiceType::where('status', ApprovalStatus::APPROVED)->whereHas('constants', function($query) { + $query->where(function($query) { + $query->where('reference', SegmentConstants::SERVICE_TYPE)->where('detail->is_active', true); + })->orWhere(function($query) { + $query->where('reference', SegmentConstants::CUSTOM_SERVICE_TYPE)->where('detail->is_active', true); + }); }); - }); + } else { + // Existing logic for other company types + return ServiceType::where('status', ApprovalStatus::APPROVED)->whereHas('constants', function($query) { + $query->Where(function($query){ + $query->where('reference', SegmentConstants::SERVICE_TYPE)->where('detail->is_active', true); + })->orWhere(function($query) { + $query->where('reference', SegmentConstants::CUSTOM_SERVICE_TYPE)->where('detail->is_active', true)->whereIn('segment_id', $this->segments->pluck('id')); + }); + }); + } } public function servicesConfigurations(): Collection { diff --git a/app/Models/TransactionMappingLog.php b/app/Models/TransactionMappingLog.php index d6093f39..e9ddab33 100644 --- a/app/Models/TransactionMappingLog.php +++ b/app/Models/TransactionMappingLog.php @@ -7,7 +7,7 @@ use Illuminate\Database\Eloquent\Model; class TransactionMappingLog extends Model { - protected $fillable = ['imported_by','data','imported_date']; + protected $fillable = ['imported_by','data','imported_date','type']; protected $casts = [ 'data' => 'array', diff --git a/config/logging.php b/config/logging.php index fb872693..d0d0a009 100644 --- a/config/logging.php +++ b/config/logging.php @@ -104,6 +104,10 @@ return [ 'path' => storage_path('logs/regenerateInvoice.log'), 'level' => 'info', ], + 'guzzleShippingPortal' => [ + 'driver' => 'errorlog', + 'level' => 'debug', + ], ], ]; diff --git a/database/migrations/2023_12_26_152448_add_type_to_transaction_mapping_logs_table.php b/database/migrations/2023_12_26_152448_add_type_to_transaction_mapping_logs_table.php new file mode 100644 index 00000000..3927920a --- /dev/null +++ b/database/migrations/2023_12_26_152448_add_type_to_transaction_mapping_logs_table.php @@ -0,0 +1,40 @@ +string('type',50)->default('invoices')->after('imported_date'); + }); + + foreach (DB::table('transaction_mapping_logs')->get() as $key => $value) { + $data = json_decode($value->data); + DB::table('transaction_mapping_logs')->where('id',$value->id)->update([ + 'type' => (isset($data->description) ? 'receipts' : 'invoices') + ]); + } + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::table('transaction_mapping_logs', function (Blueprint $table) { + $table->dropColumn('type'); + }); + } +} diff --git a/resources/assets/vue/components/accounting/elements/HistoryImportedInvoices.vue b/resources/assets/vue/components/accounting/elements/HistoryImportedInvoices.vue new file mode 100644 index 00000000..d3d68cfb --- /dev/null +++ b/resources/assets/vue/components/accounting/elements/HistoryImportedInvoices.vue @@ -0,0 +1,39 @@ + + + diff --git a/resources/assets/vue/components/accounting/elements/HistoryImportedReceipts.vue b/resources/assets/vue/components/accounting/elements/HistoryImportedReceipts.vue new file mode 100644 index 00000000..00138fa5 --- /dev/null +++ b/resources/assets/vue/components/accounting/elements/HistoryImportedReceipts.vue @@ -0,0 +1,39 @@ + + + diff --git a/resources/assets/vue/components/accounting/elements/StatementTransactionComponent.vue b/resources/assets/vue/components/accounting/elements/StatementTransactionComponent.vue index b09b9a56..0c193871 100644 --- a/resources/assets/vue/components/accounting/elements/StatementTransactionComponent.vue +++ b/resources/assets/vue/components/accounting/elements/StatementTransactionComponent.vue @@ -4,6 +4,8 @@
{{ item.posting_date }}
{{ item.transaction_description_1 + ' - ' + item.transaction_description_2 }}
+ +
{{item.owners.pending_verification[0].system}}
@@ -51,6 +53,7 @@
+
@@ -93,6 +96,7 @@
+
diff --git a/resources/assets/vue/components/accounting/elements/StatementTransactionMappedComponent.vue b/resources/assets/vue/components/accounting/elements/StatementTransactionMappedComponent.vue index e4186bb6..e37e4f3b 100644 --- a/resources/assets/vue/components/accounting/elements/StatementTransactionMappedComponent.vue +++ b/resources/assets/vue/components/accounting/elements/StatementTransactionMappedComponent.vue @@ -6,11 +6,11 @@
{{ item.transaction_description_1 + ' - ' + item.transaction_description_2 }}
-
{{item.owners.approved[0].system}}
-
{{ typeString(item.owners.approved[0].type) }}
- -
{{item.owners.approved[0].invoice_reference}}
-
{{item.owners.approved[0].receipt_reference}}
+
{{item.owners.completed[0].system}}
+
{{ typeString(item.owners.completed[0].type) }}
+ +
{{item.owners.completed[0].invoice_reference}}
+
{{item.owners.completed[0].receipt_reference}}
diff --git a/resources/assets/vue/components/accounting/sections/ImportedInvoiceMappedComponent.vue b/resources/assets/vue/components/accounting/sections/ImportedInvoiceMappedComponent.vue index 3e52b70b..185da370 100644 --- a/resources/assets/vue/components/accounting/sections/ImportedInvoiceMappedComponent.vue +++ b/resources/assets/vue/components/accounting/sections/ImportedInvoiceMappedComponent.vue @@ -8,6 +8,11 @@

{{ componentTitle }}

+
+
+ {{error}} +
+