Merge branch 'master' of https://gitlab.com/CIEFWorldwideSdnBhd/exchange-2.0 into steve/currency-setting

This commit is contained in:
Steve Ng
2024-01-03 15:03:12 +08:00
38 changed files with 1248 additions and 223 deletions
@@ -0,0 +1,18 @@
<?php
namespace App\Classes\General\Eloquent\Filters;
use Illuminate\Database\Eloquent\Builder;
class GroupByImportedDate implements Filter
{
/**
* @param Builder $builder
* @param $value
* @return mixed
*/
public static function apply(Builder $builder, $value)
{
return $builder->groupby('imported_date');
}
}
@@ -0,0 +1,18 @@
<?php
namespace App\Classes\General\Eloquent\Filters;
use Illuminate\Database\Eloquent\Builder;
class ImportedDateFrom implements Filter
{
/**
* @param Builder $builder
* @param $value
* @return mixed
*/
public static function apply(Builder $builder, $value)
{
return $builder->whereDate('imported_date', '>=', date('Y-m-d',strtotime($value)));
}
}
@@ -0,0 +1,18 @@
<?php
namespace App\Classes\General\Eloquent\Filters;
use Illuminate\Database\Eloquent\Builder;
class ImportedDateTo implements Filter
{
/**
* @param Builder $builder
* @param $value
* @return mixed
*/
public static function apply(Builder $builder, $value)
{
return $builder->whereDate('imported_date', '<=', date('Y-m-d',strtotime($value)));
}
}
@@ -0,0 +1,22 @@
<?php
namespace App\Classes\General\Eloquent\Filters;
use Illuminate\Database\Eloquent\Builder;
class StatementTransactionInvoiceReference implements Filter
{
/**
* @param Builder $builder
* @param $value
* @return Builder|mixed
*/
public static function apply(Builder $builder, $value)
{
return $builder->whereHas('owners', function ($query) use ($value) {
return $query->where('Invoice_reference', $value);
});
}
}
@@ -0,0 +1,22 @@
<?php
namespace App\Classes\General\Eloquent\Filters;
use Illuminate\Database\Eloquent\Builder;
class StatementTransactionOwnerReference implements Filter
{
/**
* @param Builder $builder
* @param $value
* @return Builder|mixed
*/
public static function apply(Builder $builder, $value)
{
return $builder->whereHas('owners', function ($query) use ($value) {
return $query->where('owner_reference', $value);
});
}
}
@@ -0,0 +1,22 @@
<?php
namespace App\Classes\General\Eloquent\Filters;
use Illuminate\Database\Eloquent\Builder;
class StatementTransactionReceiptReference implements Filter
{
/**
* @param Builder $builder
* @param $value
* @return Builder|mixed
*/
public static function apply(Builder $builder, $value)
{
return $builder->whereHas('owners', function ($query) use ($value) {
return $query->where('receipt_reference', $value);
});
}
}
@@ -0,0 +1,22 @@
<?php
namespace App\Classes\General\Eloquent\Filters;
use Illuminate\Database\Eloquent\Builder;
class WhereHasOwnersAndNotNull implements Filter
{
/**
* @param Builder $builder
* @param $value
* @return Builder|mixed
*/
public static function apply(Builder $builder, $value)
{
return $builder->whereHas('owners', function ($query) use ($value) {
return $query->whereNotNull($value);
});
}
}
@@ -0,0 +1,22 @@
<?php
namespace App\Classes\General\Eloquent\Filters;
use Illuminate\Database\Eloquent\Builder;
class WhereHasOwnersAndNull implements Filter
{
/**
* @param Builder $builder
* @param $value
* @return Builder|mixed
*/
public static function apply(Builder $builder, $value)
{
return $builder->whereHas('owners', function ($query) use ($value) {
return $query->whereNull($value);
});
}
}
@@ -0,0 +1,25 @@
<?php
namespace App\Classes\General\Services;
use Illuminate\Support\Facades\Log;
class GuzzleShippingPortal
{
public function execute($route, $requests)
{
try {
$url = 'https://izyim.cief-malaysia.com/public/api/v1/'.$route;
$client = new \GuzzleHttp\Client(['verify' => 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 [];
}
}
}
@@ -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);
@@ -0,0 +1,49 @@
<?php
namespace App\Classes\Modules\Accounting\ControllersLogic;
use Illuminate\Http\Request;
use Illuminate\Http\JsonResponse;
use App\Http\Resources\TransactionMappingLogResource;
use App\Classes\General\Abstracts\AbstractControllerLogic;
use App\Classes\Modules\Accounting\Services\ListTransactionMappingLogs;
class HistoryImportedTransactionMappedControllerLogic extends AbstractControllerLogic
{
/**
* @return array
*/
protected function notification(): array
{
return [
'title' => '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));
}
}
@@ -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){
@@ -0,0 +1,32 @@
<?php
namespace App\Classes\Modules\Accounting\Services;
use App\Models\TransactionMappingLog;
use Illuminate\Database\Eloquent\Builder;
use App\Classes\General\Eloquent\AbstractListRecord;
class ListTransactionMappingLogs extends AbstractListRecord
{
/** @var TransactionMappingLog */
private $repository;
/**
* ListsBankStatementDetails constructor.
* @param TransactionMappingLog $repository
*/
public function __construct(TransactionMappingLog $repository)
{
$this->repository = $repository;
}
/**
* @return Builder
*/
public function getRepository(): Builder
{
return $this->repository->newQuery();
}
}
@@ -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'),
];
}
@@ -0,0 +1,86 @@
<?php
namespace App\Classes\Modules\Exports\Services;
use Carbon\Carbon;
use Illuminate\Support\Arr;
use Illuminate\Http\Request;
use App\Models\TransactionMappingLog;
use Maatwebsite\Excel\Concerns\FromQuery;
use Maatwebsite\Excel\Concerns\Exportable;
use Maatwebsite\Excel\Concerns\WithMapping;
use Maatwebsite\Excel\Concerns\WithHeadings;
use Maatwebsite\Excel\Concerns\ShouldAutoSize;
use Maatwebsite\Excel\Concerns\WithHeadingRow;
class ExportsImportedReceiptMappeds implements FromQuery, WithHeadings, WithHeadingRow, WithMapping, ShouldAutoSize
{
use Exportable;
private $dateTime;
private $count;
private $counter = 1;
public function __construct(Request $request)
{
$this->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'),
];
}
}
@@ -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);
}
}
@@ -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
'<<New>>',
Carbon::parse($transaction->posting_date)->format('d/m/Y'),
($company ? $company->debtor : null),
$transaction->transaction_description,
'Payment for '.$transaction->transaction_description,
'',
'',
'',
@@ -0,0 +1,20 @@
<?php
namespace App\Http\Controllers\Accounting;
use Illuminate\Http\Request;
use Illuminate\Http\JsonResponse;
use App\Classes\Modules\Accounting\ControllersLogic\HistoryImportedTransactionMappedControllerLogic;
class HistoryImportedTransactionMappedController
{
/**
* @param Request $request
* @param ApprovePaymentLogic $logic
* @return JsonResponse
*/
public function getImported(Request $request, HistoryImportedTransactionMappedControllerLogic $logic): JsonResponse {
return $logic->execute($request);
}
}
@@ -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;
}
}
@@ -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'
}
}
@@ -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'
}
}
@@ -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()),
]
];
}
@@ -0,0 +1,23 @@
<?php
namespace App\Http\Resources;
use Illuminate\Http\Resources\Json\JsonResource;
class TransactionMappingLogResource extends JsonResource
{
/**
* Transform the resource into an array.
*
* @param \Illuminate\Http\Request $request
* @return array
*/
public function toArray($request)
{
return [
'id' => $this->id,
'imported_date' => $this->imported_date,
'type' => $this->type
];
}
}
+19 -7
View File
@@ -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 {
+1 -1
View File
@@ -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',
+4
View File
@@ -104,6 +104,10 @@ return [
'path' => storage_path('logs/regenerateInvoice.log'),
'level' => 'info',
],
'guzzleShippingPortal' => [
'driver' => 'errorlog',
'level' => 'debug',
],
],
];
@@ -0,0 +1,40 @@
<?php
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class AddTypeToTransactionMappingLogsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('transaction_mapping_logs', function (Blueprint $table) {
$table->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');
});
}
}
@@ -0,0 +1,39 @@
<template>
<div class="row m-b-10 parentContainer">
<div class="col">
<div class="row p-b-10 b-b b-grey">
<div class="col-2">{{ item.imported_date }}</div>
<div class="col-2">
<button class="btn btn-xs btn-outline-success b-rad-none m-r-5" @click="downloadInvoiceMapped(item.imported_date)">
Download Invoices Mapped
</button>
</div>
</div>
</div>
</div>
</template>
<script>
import componentHandler from '../../../general/mixins/componentHandler';
export default {
props: {
stage: {
type: Number,
default: 0
},
section:{
type: String,
required: true
},
},
methods: {
downloadInvoiceMapped(importedDate) {
var arrDateTime = importedDate.split(" ");
const fileName = 'InvoiceMapped';
window.open(this.route('importedInvoiceMapped.export')+'?date='+arrDateTime[0]+'&time='+arrDateTime[1]+'&fileName='+fileName, '_blank');
},
},
mixins: [componentHandler]
}
</script>
@@ -0,0 +1,39 @@
<template>
<div class="row m-b-10 parentContainer">
<div class="col">
<div class="row p-b-10 b-b b-grey">
<div class="col-2">{{ item.imported_date }}</div>
<div class="col-2">
<button class="btn btn-xs btn-outline-success b-rad-none m-r-5" @click="downloadInvoiceMapped(item.imported_date)">
Download Receipts Mapped
</button>
</div>
</div>
</div>
</div>
</template>
<script>
import componentHandler from '../../../general/mixins/componentHandler';
export default {
props: {
stage: {
type: Number,
default: 0
},
section:{
type: String,
required: true
},
},
methods: {
downloadInvoiceMapped(importedDate) {
var arrDateTime = importedDate.split(" ");
const fileName = 'ReceiptMapped';
window.open(this.route('importedReceiptMapped.export')+'?date='+arrDateTime[0]+'&time='+arrDateTime[1]+'&fileName='+fileName, '_blank');
},
},
mixins: [componentHandler]
}
</script>
@@ -4,6 +4,8 @@
<div class="row p-b-10 b-b b-grey">
<div class="col-2">{{ item.posting_date }}</div>
<div class="col-2">{{ item.transaction_description_1 + ' - ' + item.transaction_description_2 }}</div>
<!-- Mapping Approval tab -->
<div class="col-5" v-if="item.owners.pending_verification.length === 1">
<div class="row">
<div class="col">{{item.owners.pending_verification[0].system}}</div>
@@ -51,6 +53,7 @@
</div>
</div>
<!-- Mapping Review tab -->
<div class="col-5" v-if="item.owners.pending_verification.length > 1">
<div class="row">
<div class="col">
@@ -93,6 +96,7 @@
</div>
</div>
<!-- unknow tab -->
<div class="col-5" v-if="!item.owners.pending_verification.length && !item.owners.approved.length">
<div class="row">
<div class="col">
@@ -6,11 +6,11 @@
<div class="col-2">{{ item.transaction_description_1 + ' - ' + item.transaction_description_2 }}</div>
<div class="col-7">
<div class="row">
<div class="col">{{item.owners.approved[0].system}}</div>
<div class="col">{{ typeString(item.owners.approved[0].type) }}</div>
<div class="col"><a :href="item.owners.approved[0].reference_link" target="_blank">{{item.owners.approved[0].reference}}</a></div>
<div class="col">{{item.owners.approved[0].invoice_reference}}</div>
<div class="col">{{item.owners.approved[0].receipt_reference}}</div>
<div class="col">{{item.owners.completed[0].system}}</div>
<div class="col">{{ typeString(item.owners.completed[0].type) }}</div>
<div class="col"><a :href="item.owners.completed[0].reference_link" target="_blank">{{item.owners.completed[0].reference}}</a></div>
<div class="col">{{item.owners.completed[0].invoice_reference}}</div>
<div class="col">{{item.owners.completed[0].receipt_reference}}</div>
</div>
</div>
@@ -8,6 +8,11 @@
<div class="card">
<div class="card-header">
<h3>{{ componentTitle }}</h3>
<div class="row m-b-10 animate__animated animate__fadeInUpBig animate__fast" v-if="error">
<div class="col">
<small class="bold fs-10 text-danger">{{error}}</small>
</div>
</div>
<div class="text-right">
<button class="btn btn-xs btn-outline-success b-rad-none m-r-5" @click="downloadInvoiceMapped">
Download Invoices Mapped
@@ -34,6 +39,7 @@
<td>{{item.cancelled}}</td>
<td>{{item.mapped_status}}</td>
<td>{{item.mapped_result_reference}}</td>
<td>{{item.payment_received_date}}</td>
</tr>
</tbody>
</table>
@@ -69,6 +75,7 @@
data() {
return {
isLoading: false,
error: '',
importedDate: null,
}
},
@@ -91,21 +98,17 @@
},
methods: {
appendComponentTitle() {
this.componentTitle = this.section == 'importInvoiceMapping' ? 'Imported Invoices Mapped' : 'Imported Receipts Mapped';
this.componentTitle = 'Imported Invoices Mapped';
},
appendComponentTableHeader() {
if (this.section == 'importInvoiceMapping') {
this.tableHeaders = ['No','Doc No','Date','Debtor Code','Debtor Name','Shipping Info','Net Total','Cancelled','Mapped Status','Mapped Reference No'];
} else {
this.tableHeaders = ['No','OR No','Date','Creditor Code','Creditor Name','Shipping Info','Net Total','Cancelled','Mapped Status','Mapped Reference No'];
}
this.tableHeaders = ['No','Doc No','Date','Debtor Code','Debtor Name','Shipping Info','Net Total','Cancelled','Mapped Status','Mapped Reference No','Payment Received Date'];
},
importInvoice(){
this.isLoading = true;
this.parameters = {
files: this.files
};
this.submit(this.route('api.'+(this.section == 'importInvoiceMapping' ? 'import_invoices' : 'import_receipts')+'.upload'), 'post', this.section, true, false);
this.submit(this.route('api.import_invoices.upload'), 'post', this.section, true, false);
},
successHandler(response){
@@ -114,9 +117,14 @@
this.isLoading = false;
},
errorHandler(error){
this.isLoading = false;
this.error = error.message;
},
downloadInvoiceMapped() {
var arrDateTime = this.importedDate.split(" ");
const fileName = this.section == 'importInvoiceMapping' ? 'InvoiceMapped' : 'ReceiptMapped';
const fileName = 'importInvoiceMapping';
window.open(this.route('importedInvoiceMapped.export')+'?date='+arrDateTime[0]+'&time='+arrDateTime[1]+'&fileName='+fileName, '_blank');
},
@@ -0,0 +1,138 @@
<template>
<div class="row h-100 parentContainer">
<div class="col-12" style="min-height: 20px;">
<loading-component style="height: 20px; top: 0;" key="1" color="success" v-show="isLoading"></loading-component>
</div>
<div class="col-12">
<div class="card">
<div class="card-header">
<h3>{{ componentTitle }}</h3>
<div class="row m-b-10 animate__animated animate__fadeInUpBig animate__fast" v-if="error">
<div class="col">
<small class="bold fs-10 text-danger">{{error}}</small>
</div>
</div>
<div class="text-right">
<button class="btn btn-xs btn-outline-success b-rad-none m-r-5" @click="downloadInvoiceMapped">
Download Receipts Mapped
</button>
</div>
</div>
<!-- /.card-header -->
<div class="card-body table-responsive p-0">
<table class="table table-hover">
<thead>
<tr>
<th v-for="item in tableHeaders">{{ item }}</th>
</tr>
</thead>
<tbody v-show="!isLoading">
<tr v-for="(item, index) in $store.getters.getListData(section)">
<td>{{index+1}}</td>
<td>{{item.check }}</td>
<td>{{item.doc_no}}</td>
<td>{{item.doc_date }}}</td>
<td>{{item.debtor_code}}</td>
<td>{{item.company_name}}</td>
<td>{{item.description}}</td>
<td>{{item.payment_amount}}</td>
<td>{{item.created_user}}</td>
<td>{{item.curr}}</td>
<td>{{item.to_home_rate}}</td>
<td>{{item.local_payment_amount}}</td>
<td>{{item.cancelled}}</td>
<td>{{item.mapped_status}}</td>
<td>{{item.mapped_result_reference}}</td>
</tr>
</tbody>
</table>
</div>
<!-- /.card-body -->
<div class="card-footer">
</div>
</div>
</div>
<div class="col-12">
<pagination-component :section="section" class="mb-5" ref="pagination"></pagination-component>
</div>
</div>
</template>
<script>
export default {
props: {
files: {
required: true
},
type: {
type: String,
required: true,
},
section:{
type: String,
required: true
},
},
data() {
return {
isLoading: false,
error: '',
importedDate: null,
}
},
computed: {
pendingQueue() {
return this.$store.getters.isInCompleteQueue(this.section);
}
},
watch: {
pendingQueue(inComplete, oldValue){
if(inComplete){
this.importInvoice();
}
},
},
created(){
this.appendComponentTitle();
this.appendComponentTableHeader();
this.$store.dispatch('updateListQueue', {'name': this.section});
},
methods: {
appendComponentTitle() {
this.componentTitle = 'Imported Receipts Mapped';
},
appendComponentTableHeader() {
this.tableHeaders = ['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'];
},
importInvoice(){
this.isLoading = true;
this.parameters = {
files: this.files
};
this.submit(this.route('api.import_receipts.upload'), 'post', this.section, true, false);
},
successHandler(response){
this.$store.dispatch('completeList', {'name': this.section, 'data': response.payload.data});
this.importedDate = response.payload.importedDate;
this.isLoading = false;
},
errorHandler(error){
this.isLoading = false;
this.error = error.message;
},
downloadInvoiceMapped() {
var arrDateTime = this.importedDate.split(" ");
const fileName = 'ReceiptMapped';
window.open(this.route('importedReceiptMapped.export')+'?date='+arrDateTime[0]+'&time='+arrDateTime[1]+'&fileName='+fileName, '_blank');
},
}
}
</script>
@@ -3,19 +3,74 @@
<div class="col">
<div class="row">
<div class="col">
<div class="row justify-content-center align-items-center m-t-50 m-b-50" v-show="step === 0">
<div class="col-5">
<div class="row text-center">
<div class="col b-a b-grey padding-20 m-r-15 pointer bg-complete text-white" @click="getReportFilter()">Mapped Report</div>
<div class="justify-content-center align-items-center m-t-50 m-b-50" v-show="step === 0">
<div class="row">
<div class="col-3">
<div class="row text-center">
<div class="col b-a b-grey padding-20 m-r-15 pointer bg-complete text-white" @click="getReportFilter()">Mapped Report</div>
</div>
</div>
<div class="col-3">
<div class="row text-center">
<div class="col b-a b-grey padding-20 m-r-15 pointer bg-complete text-white" @click="getHistoryImportedInvReport()">History Imported Invoices Report</div>
</div>
</div>
<div class="col-3">
<div class="row text-center">
<div class="col b-a b-grey padding-20 m-r-15 pointer bg-complete text-white" @click="getHistoryImportedRecReport()">History Imported Receipts Report</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="row" v-if="step == 1">
<div class="row" v-if="step > 0 && report == 'mappedRecords'">
<div class="col">
<div class="row">
<div class="col">
<div class="justify-content-center align-items-center m-t-50 m-b-50">
<div class="row mb-3">
<div class="col-4">
<validation-wrapper-component :validator="$v.parameters.owner_reference">
<label class="text-primary">Reference</label>
<input type="text" class="form-control" v-model="parameters.owner_reference">
</validation-wrapper-component>
</div>
<div class="col-4">
<validation-wrapper-component :validator="$v.parameters.invoice_reference">
<label class="text-primary">Invoice Reference</label>
<input type="text" class="form-control" v-model="parameters.invoice_reference">
</validation-wrapper-component>
</div>
<div class="col-4">
<validation-wrapper-component :validator="$v.parameters.receipt_reference">
<label class="text-primary">Receipt Reference</label>
<input type="text" class="form-control" v-model="parameters.receipt_reference">
</validation-wrapper-component>
</div>
</div>
<div class="row">
<div class="col-3">
<validation-wrapper-component :validator="$v.parameters.startDate">
<label class="all-caps">Start Date</label>
<date-picker-component :parameters="parameters" v-model.lazy="parameters.startDate"></date-picker-component>
</validation-wrapper-component>
</div>
<div class="col-3">
<validation-wrapper-component :validator="$v.parameters.endDate">
<label class="all-caps">End Date</label>
<date-picker-component :parameters="parameters" v-model.lazy="parameters.endDate"></date-picker-component>
</validation-wrapper-component>
</div>
<div class="col-3">
<div class="row text-center">
<div class="col b-a b-grey padding-20 m-r-15 pointer bg-complete text-white" @click="getReportFilter()">Mapped Report</div>
</div>
</div>
</div>
</div>
<div class="row m-t-10 m-b-10">
<div class="col">
<div class="row p-t-10 p-b-10 b-b b-grey text-master-light">
@@ -35,7 +90,7 @@
</div>
</div>
<list-component ref="TransactionsMappedList" section="TransactionsMappedSection" :endpoint="route('api.accounting.bank.transaction')" :options="filter">
<list-component :key="step" ref="TransactionsMappedList" section="TransactionsMappedSection" :endpoint="route('api.accounting.bank.transaction')" :options="filter">
<template slot="list" slot-scope="{data}">
<statement-transaction-mapped-component :data="data" :section="section"></statement-transaction-mapped-component>
</template>
@@ -44,22 +99,175 @@
</div>
</div>
</div>
<!-- report for imported Invoices -->
<div class="row" v-if="step > 0 && report == 'importedInv'">
<div class="col">
<div class="row">
<div class="col">
<div class="justify-content-center align-items-center m-t-50 m-b-50">
<div class="row">
<div class="col-3">
<validation-wrapper-component :validator="$v.parameters.startDate">
<label class="all-caps">Start Date</label>
<date-picker-component :parameters="parameters" v-model.lazy="parameters.startDate"></date-picker-component>
</validation-wrapper-component>
</div>
<div class="col-3">
<validation-wrapper-component :validator="$v.parameters.endDate">
<label class="all-caps">End Date</label>
<date-picker-component :parameters="parameters" v-model.lazy="parameters.endDate"></date-picker-component>
</validation-wrapper-component>
</div>
<div class="col-3">
<div class="row text-center">
<div class="col b-a b-grey padding-20 m-r-15 pointer bg-complete text-white" @click="getHistoryImportedInvReport()">History Imported Invoices Report</div>
</div>
</div>
</div>
</div>
<div class="row m-t-10 m-b-10">
<div class="col">
<div class="row p-t-10 p-b-10 b-b b-grey text-master-light">
<div class="col-2">Date</div>
</div>
</div>
</div>
<list-component :key="step" ref="HistoryImportedInvList" section="HistoryImportedInvSection" :endpoint="route('api.accounting.history.imported')" :options="filter">
<template slot="list" slot-scope="{data}">
<history-imported-invoices :data="data" :section="section"></history-imported-invoices>
</template>
</list-component>
</div>
</div>
</div>
</div>
<!-- report for imported Receipts -->
<div class="row" v-if="step > 0 && report == 'importedRec'">
<div class="col">
<div class="row">
<div class="col">
<div class="justify-content-center align-items-center m-t-50 m-b-50">
<div class="row">
<div class="col-3">
<validation-wrapper-component :validator="$v.parameters.startDate">
<label class="all-caps">Start Date</label>
<date-picker-component :parameters="parameters" v-model.lazy="parameters.startDate"></date-picker-component>
</validation-wrapper-component>
</div>
<div class="col-3">
<validation-wrapper-component :validator="$v.parameters.endDate">
<label class="all-caps">End Date</label>
<date-picker-component :parameters="parameters" v-model.lazy="parameters.endDate"></date-picker-component>
</validation-wrapper-component>
</div>
<div class="col-3">
<div class="row text-center">
<div class="col b-a b-grey padding-20 m-r-15 pointer bg-complete text-white" @click="getHistoryImportedRecReport()">History Imported Receipts Report</div>
</div>
</div>
</div>
</div>
<div class="row m-t-10 m-b-10">
<div class="col">
<div class="row p-t-10 p-b-10 b-b b-grey text-master-light">
<div class="col-2">Date</div>
</div>
</div>
</div>
<list-component :key="step" ref="HistoryImportedRecList" section="HistoryImportedRecSection" :endpoint="route('api.accounting.history.imported')" :options="filter">
<template slot="list" slot-scope="{data}">
<history-imported-receipts :data="data" :section="section"></history-imported-receipts>
</template>
</list-component>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
import { required } from "vuelidate/lib/validators";
export default {
data() {
return {
parameters: {
startDate: '',
endDate: '',
owner_reference: '',
invoice_reference: '',
receipt_reference: ''
},
step: 0,
filter: {},
report: ''
}
},
validations: {
parameters: {
startDate: {
required
},
endDate: {
required
},
owner_reference: {},
invoice_reference: {},
receipt_reference: {}
},
},
created(){
this.parameters.startDate = this.startDate();
this.parameters.endDate = this.endDate();
},
methods: {
startDate() {
var date = new Date();
return '01-'+(date.getMonth() + 1)+'-'+date.getFullYear();
},
endDate() {
var date = new Date();
var lastDay = new Date(date.getFullYear(), date.getMonth() + 1, 0);
return lastDay.getDate()+'-'+(lastDay.getMonth() + 1)+'-'+lastDay.getFullYear();
},
getReportFilter() {
this.filter = {min_amount: 0, is_mapped: true, statement_transaction_owner_type_in: [1, 2], statement_transaction_owner_status_in: [2], statement_transaction_owner_invoice_or_receipt_ref_not_null: true, per_page: 100, order_by: {column: 'posting_date', DESC: true}};
this.filter = {min_amount: 0, is_mapped: true, statement_transaction_owner_type_in: [1, 2], statement_transaction_owner_status_in: [3], per_page: 100, order_by: {column: 'posting_date', DESC: true}};
this.step = 1
this.filter = {...this.filter, ...{statement_transaction_posting_start: this.parameters.startDate}};
this.filter = {...this.filter, ...{statement_transaction_posting_end:this.parameters.endDate}}
if (typeof this.parameters.owner_reference != 'undefined' && this.parameters.owner_reference != '') this.filter = {...this.filter, ...{statement_transaction_owner_reference: this.parameters.owner_reference}};
if (typeof this.parameters.invoice_reference != 'undefined' && this.parameters.invoice_reference != '') this.filter = {...this.filter, ...{statement_transaction_invoice_reference: this.parameters.invoice_reference}};
if (typeof this.parameters.receipt_reference != 'undefined' && this.parameters.receipt_reference != '') this.filter = {...this.filter, ...{statement_transaction_receipt_reference: this.parameters.receipt_reference}};
this.step = this.step + 1;
this.report = 'mappedRecords';
},
getHistoryImportedRecReport() {
this.filter = {
imported_date_from: this.parameters.startDate,
imported_date_to:this.parameters.endDate,
group_by_imported_date:true,
type:'receipts'
};
this.step = this.step + 1;
this.report = 'importedRec';
},
getHistoryImportedInvReport() {
this.filter = {
imported_date_from: this.parameters.startDate,
imported_date_to:this.parameters.endDate,
group_by_imported_date:true,
type:'invoices'
};
this.step = this.step + 1;
this.report = 'importedInv';
}
},
}
@@ -164,7 +164,7 @@
<div class="row">
<div class="col-12">
<modal-component class="animate__animated animate__fast animate__fadeIn" styleType="fill-in" type="ModalImportInvoice">
<imported-invoice-mapped-component section="importInvoiceMapping" v-if="mappedTrue" :files="files"></imported-invoice-mapped-component>
<imported-invoice-mapped-component section="importInvoiceMapping" v-if="invMappedTrue" :files="files"></imported-invoice-mapped-component>
</modal-component>
</div>
</div>
@@ -192,7 +192,7 @@
</file-input-component>
</div>
</div>
<div class="btn btn-lg btn-primary m-t-20 requestModal" data-type="ModalImportInvoice" @click="importReceipts">Import Receipts</div>
<div class="btn btn-lg btn-primary m-t-20 requestModal" data-type="ModalImportReceipt" @click="importReceipts">Import Receipts</div>
<!-- todo-new: delete later --><br><div class="btn btn-lg btn-primary m-t-20" @click="exportStage++">Nest Step</div>
<br>
<div class="row">
@@ -202,8 +202,8 @@
</div>
<div class="row">
<div class="col-12">
<modal-component class="animate__animated animate__fast animate__fadeIn" styleType="fill-in" type="ModalImportInvoice">
<imported-invoice-mapped-component section="importReceiptMapping" v-if="mappedTrue" :files="files"></imported-invoice-mapped-component>
<modal-component class="animate__animated animate__fast animate__fadeIn" styleType="fill-in" type="ModalImportReceipt">
<imported-receipt-mapped-component section="importReceiptMapping" v-if="recMappedTrue" :files="files"></imported-receipt-mapped-component>
</modal-component>
</div>
</div>
@@ -240,7 +240,8 @@ export default {
files: [],
parameters: {},
section: 'bankTransactionSection',
mappedTrue: false,
invMappedTrue: false,
recMappedTrue: false,
selectAll: false,
}
},
@@ -259,10 +260,10 @@ export default {
},
methods: {
importInvoice(){
this.mappedTrue = true;
this.invMappedTrue = true;
},
importReceipts(){
this.mappedTrue = true;
this.recMappedTrue = true;
},
exportInvoiceToAutoCount(){
const checkedStatementTransactions = this.getCheckedStatementOwners();
@@ -277,7 +278,8 @@ export default {
exportReceiptToAutoCount(){
const checkedStatementTransactions = this.getCheckedStatementOwners();
this.filter['statement_transaction_owner_type_in'] = [3,4,5,7,13,14];
this.filter['where_has_owners_and_null'] = 'statement_transaction_owners.receipt_reference';
this.filter['where_has_owners_and_not_null'] = 'statement_transaction_owners.invoice_reference';
let route = this.route('receiptTransactions.export')+'?filter='+JSON.stringify(this.filter);
if (checkedStatementTransactions) {
route += '&bankStatementTransactionId='+checkedStatementTransactions;
@@ -22,7 +22,7 @@
</div>
</div>
</div>
<div class="col d-none d-lg-block" v-if="$store.getters.isAdmin">
<div class="col-auto d-none d-lg-block" v-if="$store.getters.isAdmin">
<div class="font-heading fs-10 muted all-caps">Marking</div>
<div class="font-heading">
<a :href="route('customer.profile', item.company.reference)">{{this.item.company.reference}}</a>
@@ -34,7 +34,7 @@
<span class="flag-icon" :class="'flag-icon-'+item.convertible_currency.country.short_code.toLowerCase()"></span> {{this.item.convertible_currency.short_code}}
</div>
</div>
<div class="col-auto d-none d-lg-block">
<div class="col-3 d-none d-lg-block">
<div class="font-heading fs-10 muted all-caps">Transfer Type</div>
<div class="font-heading fs-12">{{this.item.service.name}}</div>
</div>
+3
View File
@@ -16,4 +16,7 @@ Route::group(['prefix' => 'accounting', 'as' => 'accounting.', 'namespace' => 'A
Route::post('/owner/group-approve', 'GroupApproveStatementTransactionController@approve')->name('owner.groupApprove');
Route::post('/{id}/owner/{status}', 'UpdateStatementTransactionStatusController@update')->where('status', 'approve|reject')->name('owner.status.update');
});
Route::get('history/imported', 'HistoryImportedTransactionMappedController@getImported')->name('history.imported');
});
+1
View File
@@ -263,6 +263,7 @@ Route::get('/export/booking-transactions', 'Exports\ExportCustomersToExcelContro
Route::get('/export/invoice-transactions/f614e339d7058904a831aad742e24d55', 'Exports\ExportCustomersToExcelController@invoiceTransactions')->name('invoiceTransactions.export');
Route::get('/export/receipt-transactions/f614e339d7058904a831aad742e24d55', 'Exports\ExportCustomersToExcelController@receiptTransactions')->name('receiptTransactions.export');
Route::get('/export/imported-invoice-mapped', 'Exports\ExportCustomersToExcelController@importedInvoiceMapped')->name('importedInvoiceMapped.export');
Route::get('/export/imported-receipt-mapped', 'Exports\ExportCustomersToExcelController@importedReceiptMapped')->name('importedReceiptMapped.export');
Route::get('/products', function (\App\Classes\Modules\Exports\Services\ExportsProducts $exportsProducts) {
$bookings = Booking::where(function($query){