diff --git a/app/Classes/General/Abstracts/AbstractControllerLogic.php b/app/Classes/General/Abstracts/AbstractControllerLogic.php index 48cde9cf..f523ed3c 100644 --- a/app/Classes/General/Abstracts/AbstractControllerLogic.php +++ b/app/Classes/General/Abstracts/AbstractControllerLogic.php @@ -65,7 +65,7 @@ abstract class AbstractControllerLogic } catch (ErrorException|GeneralExceptions|TypeError $exception){ if ($exception instanceof JobResourceNotFoundException) { - Log::error(sprintf( + Log::channel('vue_polling')->info(sprintf( "Uncaught exception '%s' with message '%s' in %s:%d", get_class($exception), $exception->getMessage(), diff --git a/app/Classes/General/Eloquent/Filters/PackingListLimitOneByTypeOrderedByInvoiceDate.php b/app/Classes/General/Eloquent/Filters/PackingListLimitOneByTypeOrderedByInvoiceDate.php new file mode 100644 index 00000000..a0316805 --- /dev/null +++ b/app/Classes/General/Eloquent/Filters/PackingListLimitOneByTypeOrderedByInvoiceDate.php @@ -0,0 +1,32 @@ +select('packing_lists.*')->join('transactions', function($join){ + $join->on('transactions.owner_id', '=', 'packing_lists.id'); + $join->where('transactions.owner_type', '=', PackingList::class); + $join->where('transactions.status', '=', ApprovalStatus::APPROVED); + $join->whereRaw('(transactions.type <> 16 OR transactions.id = ( + SELECT id FROM transactions WHERE owner_id = packing_lists.id AND type = 16 LIMIT 1 + ))'); + })->orderBy('transactions.updated_at', 'DESC'); + } + +} diff --git a/app/Classes/General/Eloquent/Filters/PostcodeLike.php b/app/Classes/General/Eloquent/Filters/PostcodeLike.php new file mode 100644 index 00000000..b8873d43 --- /dev/null +++ b/app/Classes/General/Eloquent/Filters/PostcodeLike.php @@ -0,0 +1,20 @@ +where('postcode', 'LIKE', '%'.$value.'%'); + } + +} \ No newline at end of file diff --git a/app/Classes/General/Eloquent/Filters/WithContainersPackages.php b/app/Classes/General/Eloquent/Filters/WithContainersPackages.php new file mode 100644 index 00000000..b4f30b31 --- /dev/null +++ b/app/Classes/General/Eloquent/Filters/WithContainersPackages.php @@ -0,0 +1,23 @@ +with(['containers', 'packages']); + return null; + } +} diff --git a/app/Classes/Jobs/ListPackingListsJob.php b/app/Classes/Jobs/ListPackingListsJob.php index 474531f4..37a970fe 100644 --- a/app/Classes/Jobs/ListPackingListsJob.php +++ b/app/Classes/Jobs/ListPackingListsJob.php @@ -15,6 +15,8 @@ class ListPackingListsJob implements ShouldQueue { use Dispatchable, InteractsWithQueue, Queueable, SerializesModels; + public $timeout = 900; + /** @var ListGenericJobObject */ private $listGenericJobObject; diff --git a/app/Classes/Jobs/UpdatePerfexCRMInvoice.php b/app/Classes/Jobs/UpdatePerfexCRMInvoice.php index 77493f6d..44192e7b 100644 --- a/app/Classes/Jobs/UpdatePerfexCRMInvoice.php +++ b/app/Classes/Jobs/UpdatePerfexCRMInvoice.php @@ -47,7 +47,7 @@ class UpdatePerfexCRMInvoice implements ShouldQueue $invoiceId = 0; $invoiceStatus = 0; $invoice = (App()->make(FetchesPerfexCRMInvoice::class))->execute($customer->userid,"INV-", $transaction->owner->bill_no); - Log::error('UpdatePerfexCRMInvoice debug bill_no: ' . $transaction->owner->bill_no . ', Project Id: ' . $this->updatePerfexCRMInvoiceObject->getProjectId()); + Log::channel('perfex_crm')->info('UpdatePerfexCRMInvoice debug bill_no: ' . $transaction->owner->bill_no . ', Project Id: ' . $this->updatePerfexCRMInvoiceObject->getProjectId()); if(is_null($invoice)){ $result = (App()->make(CreatePerfexCRMInvoiceProcessor::class))->execute($transaction->owner, $this->updatePerfexCRMInvoiceObject->getIsPaid()); @@ -55,7 +55,7 @@ class UpdatePerfexCRMInvoice implements ShouldQueue $invoiceId = $result->payload['id']; } else { // Log::error(json_encode('UpdatePerfexCRMInvoice CreatePerfexCRMInvoiceProcessor failed')); - Helper::debugLogger('UpdatePerfexCRMInvoice CreatePerfexCRMInvoiceProcessor failed'); + Log::channel('perfex_crm')->info('UpdatePerfexCRMInvoice CreatePerfexCRMInvoiceProcessor failed'); } } else{ diff --git a/app/Classes/Modules/Billplzs/ControllersLogic/CallbackBillplzLogic.php b/app/Classes/Modules/Billplzs/ControllersLogic/CallbackBillplzLogic.php index a9f94410..d094ef74 100644 --- a/app/Classes/Modules/Billplzs/ControllersLogic/CallbackBillplzLogic.php +++ b/app/Classes/Modules/Billplzs/ControllersLogic/CallbackBillplzLogic.php @@ -145,7 +145,7 @@ class CallbackBillplzLogic $pL = $invoice->owner; $order = $pL->owner; if($order){ - $this->storageInvoiceTransactionProcessor->executeOrder($order, false); //original was set true here so that no group is soft deleted or billplz bill got deleted + $this->storageInvoiceTransactionProcessor->executeOrder($order); } } } diff --git a/app/Classes/Modules/Billplzs/Processors/CallbackBillplzProcessor.php b/app/Classes/Modules/Billplzs/Processors/CallbackBillplzProcessor.php index f8dfc119..79b81452 100644 --- a/app/Classes/Modules/Billplzs/Processors/CallbackBillplzProcessor.php +++ b/app/Classes/Modules/Billplzs/Processors/CallbackBillplzProcessor.php @@ -6,10 +6,9 @@ use Illuminate\Http\Request; use App\Models\Wallet; use App\Models\Group; use App\Classes\ValueObjects\Constants\ApprovalStatus; -use App\Classes\ValueObjects\Constants\TransactionType; use App\Classes\ValueObjects\Constants\PaymentMethodType; use App\Classes\Modules\Transactions\Processors\CreatePaymentTransactionProcessor; -use App\Classes\Modules\Transactions\Processors\CreateStorageInvoiceDocTransactionProcessor; +use App\Classes\Modules\Transactions\Processors\ReleaseGoodsToCustomerProcessor; use App\Classes\Modules\Transactions\Services\UpdatesTransactionStatus; use App\Classes\Modules\Wallets\Services\UpdatesWalletBalance; use App\Classes\Modules\Orders\Processors\UpdateDoFromVTPortalProcessor; @@ -33,8 +32,8 @@ class CallbackBillplzProcessor /** @var CreatePaymentTransactionProcessor */ private $createPaymentTransactionProcessor; - /** @var CreateStorageInvoiceDocTransactionProcessor */ - private $ceateStorageInvoiceDocTransactionProcessor; + /** @var ReleaseGoodsToCustomerProcessor */ + private $releaseGoodsToCustomerProcessor; /** * CreateUserProcessor constructor. @@ -43,16 +42,16 @@ class CallbackBillplzProcessor * @param UpdateDoFromYDPortalProcessor $updateDoFromYDPortalProcessor * @param UpdatesWalletBalance $updatesWalletBalance * @param CreatePaymentTransactionProcessor $createPaymentTransactionProcessor - * @param CreateStorageInvoiceDocTransactionProcessor $ceateStorageInvoiceDocTransactionProcessor + * @param ReleaseGoodsToCustomerProcessor $releaseGoodsToCustomerProcessor */ - public function __construct(UpdatesTransactionStatus $updatesTransactionStatus, UpdateDoFromVTPortalProcessor $updateDoFromVTPortalProcessor, UpdateDoFromYDPortalProcessor $updateDoFromYDPortalProcessor, UpdatesWalletBalance $updatesWalletBalance, CreatePaymentTransactionProcessor $createPaymentTransactionProcessor, CreateStorageInvoiceDocTransactionProcessor $ceateStorageInvoiceDocTransactionProcessor) + public function __construct(UpdatesTransactionStatus $updatesTransactionStatus, UpdateDoFromVTPortalProcessor $updateDoFromVTPortalProcessor, UpdateDoFromYDPortalProcessor $updateDoFromYDPortalProcessor, UpdatesWalletBalance $updatesWalletBalance, CreatePaymentTransactionProcessor $createPaymentTransactionProcessor, ReleaseGoodsToCustomerProcessor $releaseGoodsToCustomerProcessor) { $this->updatesTransactionStatus = $updatesTransactionStatus; $this->updateDoFromVTPortalProcessor = $updateDoFromVTPortalProcessor; $this->updateDoFromYDPortalProcessor = $updateDoFromYDPortalProcessor; $this->updatesWalletBalance = $updatesWalletBalance; $this->createPaymentTransactionProcessor = $createPaymentTransactionProcessor; - $this->ceateStorageInvoiceDocTransactionProcessor = $ceateStorageInvoiceDocTransactionProcessor; + $this->releaseGoodsToCustomerProcessor = $releaseGoodsToCustomerProcessor; } @@ -82,11 +81,11 @@ class CallbackBillplzProcessor foreach ($group->groupTransactions as $groupTransaction) { $invoice = $groupTransaction->transaction; - $paymentTransaction = $this->createPaymentTransactionProcessor->execute($invoice, PaymentMethodType::WALLET, null); + $paymentTransaction = $this->createPaymentTransactionProcessor->execute($invoice, PaymentMethodType::WALLET, null, false); if($paymentTransaction && $paymentTransaction->status == ApprovalStatus::APPROVED){ $pL = $invoice->owner; - $this->processPackingListAndInvoice($pL, $invoice); + $this->releaseGoodsToCustomerProcessor->execute($pL, $invoice); } } @@ -96,7 +95,7 @@ class CallbackBillplzProcessor } if (!$transaction->owner instanceof Wallet) { - $this->processPackingListAndInvoice($packingList, $invoice); + $this->releaseGoodsToCustomerProcessor->execute($packingList, $invoice); } return true; @@ -126,49 +125,4 @@ class CallbackBillplzProcessor } return true; } - - private function processPackingListAndInvoice($packingList, $invoice = null){ - $result = false; - $totalInvoicesAmountPaid = 0.00; - $totalInvoicesAmount = 0.00; - $invoiceTransactions = $packingList->transactions()->where('status', [ApprovalStatus::APPROVED])->whereIn('type', [TransactionType::SHIPPING_INVOICE, TransactionType::STORAGE_INVOICE])->get(); - - //Part 1: Process each single invoice type and get the total of all invoices - foreach($invoiceTransactions as $invoiceTransaction){ - - $totalInvoiceAmountPaid = $invoiceTransaction->transactions->where('type', TransactionType::PAYMENT)->whereIn('status', [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED])->sum('amount'); - if ($invoice && $invoice->type == $invoiceTransaction->type) { - if(($invoice->amount - $totalInvoiceAmountPaid) < 0.01){ - $this->updatesTransactionStatus->execute($invoice, ApprovalStatus::COMPLETED); - - if($invoice->type == TransactionType::STORAGE_INVOICE){ - $this->ceateStorageInvoiceDocTransactionProcessor->execute($packingList); - } - } - } - - $totalInvoicesAmount = $totalInvoicesAmount + $invoiceTransaction->amount; - $totalInvoicesAmountPaid = $totalInvoicesAmountPaid + $totalInvoiceAmountPaid; - } - - Log::channel('storage_invoices')->info('Total invoice amount paid 1: '.$totalInvoicesAmount); //cief todo: to be removed - Log::channel('storage_invoices')->info('Total invoice amount paid 2: '.$totalInvoicesAmountPaid); //cief todo: to be removed - - //Part 2: Based on the collected info for all the total of all invoices - if (($totalInvoicesAmount - $totalInvoicesAmountPaid) < 0.01) { - Log::channel('storage_invoices')->info('Total invoice amount paid 3: '.$totalInvoicesAmountPaid); //cief todo: to be removed - - $packingList->status = ApprovalStatus::APPROVED; - $packingList->save(); - - if (app()->environment('production')) { - $this->updateDoFromVTPortalProcessor->execute($packingList); - $this->updateDoFromYDPortalProcessor->execute($packingList); - } - - $result = true; - } - - return $result; - } } diff --git a/app/Classes/Modules/Companies/ControllersLogic/UpdateCompanyCreditTermStatusLogic.php b/app/Classes/Modules/Companies/ControllersLogic/UpdateCompanyCreditTermStatusLogic.php new file mode 100644 index 00000000..ff57b814 --- /dev/null +++ b/app/Classes/Modules/Companies/ControllersLogic/UpdateCompanyCreditTermStatusLogic.php @@ -0,0 +1,121 @@ + 'Update Company Credit Term Status', + 'message' => 'You have successfully updated Company Credit Term Status' + ]; + } + + /** @var FetchesCompany */ + private $fetchesCompany; + + /** @var UpdatesCompanyModuleIsCreditTerm */ + private $updatesCompanyModuleIsCreditTerm; + + /** @var CanUpdateCompanyModule */ + private $canUpdateCompanyModule; + + /** @var ListsTransactions */ + private $listsTransactions; + + /** @var UpdatesTransactionIsWaived */ + private $updatesTransactionIsWaived; + + /** @var CheckStorageInvoiceTransactionProcessor */ + private $storageInvoiceTransactionProcessor; + + + + /** + * UpdateCompanyCreditTermStatusLogic constructor. + * @param FetchesCompany $fetchesCompany + * @param UpdatesCompanyModuleIsCreditTerm $updatesCompanyModuleIsCreditTerm + * @param CanUpdateCompanyModule $canUpdateCompanyModule + * @param UpdatesTransactionIsWaived $updatesTransactionIsWaived + * @param ListsTransactions $listsTransactions + * @param CheckStorageInvoiceTransactionProcessor $storageInvoiceTransactionProcessor + */ + public function __construct(FetchesCompany $fetchesCompany, UpdatesCompanyModuleIsCreditTerm $updatesCompanyModuleIsCreditTerm, CanUpdateCompanyModule $canUpdateCompanyModule, UpdatesTransactionIsWaived $updatesTransactionIsWaived, ListsTransactions $listsTransactions, CheckStorageInvoiceTransactionProcessor $storageInvoiceTransactionProcessor) + { + $this->fetchesCompany = $fetchesCompany; + $this->updatesCompanyModuleIsCreditTerm = $updatesCompanyModuleIsCreditTerm; + $this->canUpdateCompanyModule = $canUpdateCompanyModule; + $this->listsTransactions = $listsTransactions; + $this->updatesTransactionIsWaived = $updatesTransactionIsWaived; + $this->storageInvoiceTransactionProcessor = $storageInvoiceTransactionProcessor; + } + + /** + * @param Request $request + * @return JsonResponse + * @throws \App\Classes\Exceptions\AccessForbiddenException + * @throws \App\Classes\Exceptions\MalformedRequestException + * @throws \App\Classes\Exceptions\RequestValidationException + */ + public function logic(Request $request) : JsonResponse + { + $this->canUpdateCompanyModule->passes(); + + $company = $this->fetchesCompany->execute(['id' => $request->route('id')]); + $companyModule = $company->companyModules()->first(); + $isCreditTerm = $companyModule->connections()->first()->is_credit_term; + + if ($isCreditTerm == 1) { + $isCreditTerm = 0; + } else { + $isCreditTerm = 1; + } + + if($isCreditTerm === 1){ + //{"per_page":10,"order_by":{"column":"id","DESC":true},"status_in":[2],"receiver":190,"type_in":[1],"does_not_have_payment_status_in":[0,1],"does_not_have_groups":1,"check_for_storage_invoice":1} + + $filters = [ + 'status_in' => [2], + 'receiver' => $companyModule->id, + 'type_in' => [TransactionType::STORAGE_INVOICE] + ]; + + $transactions = $this->listsTransactions->execute($filters); + foreach($transactions as $transaction){ + $this->updatesTransactionIsWaived->execute($transaction); + $packingList = $transaction->owner()->first(); + if($packingList){ + $order = $packingList->owner()->first(); + if($order instanceof Order){ + $storages = $this->storageInvoiceTransactionProcessor->executeOrder($order); + } + } + } + } + + $this->updatesCompanyModuleIsCreditTerm->execute($company->companyModules()->first()->connections()->first(), $isCreditTerm); + Log::info(Auth::user()->email." updated credit term status for customer with id: " .$request->route('id'). " to status " . $isCreditTerm); + + $result = ['is_credit_term' => $isCreditTerm]; + return $this->response(['data' => $result]); + } +} diff --git a/app/Classes/Modules/Companies/Services/UpdatesCompanyModuleIsCreditTerm.php b/app/Classes/Modules/Companies/Services/UpdatesCompanyModuleIsCreditTerm.php new file mode 100644 index 00000000..2a0b24fb --- /dev/null +++ b/app/Classes/Modules/Companies/Services/UpdatesCompanyModuleIsCreditTerm.php @@ -0,0 +1,23 @@ +is_credit_term = $isCreditTerm; + + return $this->handler($model); + } +} diff --git a/app/Classes/Modules/Companies/Standards/Rules/CanUpdateCompanyModule.php b/app/Classes/Modules/Companies/Standards/Rules/CanUpdateCompanyModule.php new file mode 100644 index 00000000..64f827fa --- /dev/null +++ b/app/Classes/Modules/Companies/Standards/Rules/CanUpdateCompanyModule.php @@ -0,0 +1,53 @@ +user(); + if($user){ + $roleToCheck = Auth()->user()->type; + if (in_array($roleToCheck, RoleTypes::ADMIN_ROLES)) { + return true; + } + } + + return false; + } + + /** + * @param $object + * @return bool + * @throws \App\Classes\Exceptions\RequestValidationException + */ + protected function validators($object): bool + { + return true; + } + + /** + * @param CompanyObject $object + * @return bool + */ + protected function criteria($object): bool + { + return true; + } +} diff --git a/app/Classes/Modules/Imports/Services/GenericImport.php b/app/Classes/Modules/Imports/Services/GenericImport.php new file mode 100644 index 00000000..b2ffdb8f --- /dev/null +++ b/app/Classes/Modules/Imports/Services/GenericImport.php @@ -0,0 +1,23 @@ +rows = $collection; + } +} diff --git a/app/Classes/Modules/Orders/Processors/UpdateDoFromYDPortalProcessor.php b/app/Classes/Modules/Orders/Processors/UpdateDoFromYDPortalProcessor.php index 2273e10b..a035c053 100644 --- a/app/Classes/Modules/Orders/Processors/UpdateDoFromYDPortalProcessor.php +++ b/app/Classes/Modules/Orders/Processors/UpdateDoFromYDPortalProcessor.php @@ -38,6 +38,7 @@ class UpdateDoFromYDPortalProcessor */ public function execute(PackingList $packingList) { Log::info('Trying to Call UpdateDoFromYDPortalProcessor'); + Log::channel('storage_invoices')->info('UpdateDoFromYDPortalProcessor: '.json_encode($packingList)); if(!app()->environment(['production'])){ return; diff --git a/app/Classes/Modules/PackingLists/ControllersLogic/ListPackingListsJobLogic.php b/app/Classes/Modules/PackingLists/ControllersLogic/ListPackingListsJobLogic.php index 260ac9bd..98d16f20 100644 --- a/app/Classes/Modules/PackingLists/ControllersLogic/ListPackingListsJobLogic.php +++ b/app/Classes/Modules/PackingLists/ControllersLogic/ListPackingListsJobLogic.php @@ -75,7 +75,7 @@ class ListPackingListsJobLogic extends AbstractControllerLogic // ListPackingListsJob::dispatch($listGenericJobObject)->onQueue('hellokitty2'); //cief todo: testing sqs // } // } - ListPackingListsJob::dispatch($listGenericJobObject); + ListPackingListsJob::dispatch($listGenericJobObject)->onQueue('high_priority'); $result = []; $result['job_id'] = $jobId; diff --git a/app/Classes/Modules/PackingLists/ControllersLogic/ListPackingListsLogic.php b/app/Classes/Modules/PackingLists/ControllersLogic/ListPackingListsLogic.php index b9e3142d..1a63eb89 100644 --- a/app/Classes/Modules/PackingLists/ControllersLogic/ListPackingListsLogic.php +++ b/app/Classes/Modules/PackingLists/ControllersLogic/ListPackingListsLogic.php @@ -6,8 +6,8 @@ namespace App\Classes\Modules\PackingLists\ControllersLogic; use App\Classes\General\Abstracts\AbstractControllerLogic; use App\Classes\Modules\PackingLists\Services\ListsPackingLists; use App\Classes\Modules\PackingLists\Standards\Rules\CanListPackingLists; -use App\Http\Resources\PackingListNullOrderResource; use App\Http\Resources\PackingListResource; +use App\Http\Resources\PackingListWithStorageResource; use ErrorException; use Illuminate\Http\JsonResponse; use Illuminate\Http\Request; @@ -54,7 +54,14 @@ class ListPackingListsLogic extends AbstractControllerLogic $query = $this->listsPackingLists->execute($this->listsPackingLists->deserializeFilters($request->input('filters'))); - return $this->collectionResponse(PackingListResource::collection($query)); + if($request->input('storages')){ + foreach ($query->items() as $item) { + $item['storages'] = $request->input('storages'); + } + return $this->collectionResponse(PackingListWithStorageResource::collection($query)); + } + else{ + return $this->collectionResponse(PackingListResource::collection($query)); + } } - } diff --git a/app/Classes/Modules/PackingLists/Processors/ListPackingListsJobProcessor.php b/app/Classes/Modules/PackingLists/Processors/ListPackingListsJobProcessor.php index 4e67f7a1..b0bcbd93 100644 --- a/app/Classes/Modules/PackingLists/Processors/ListPackingListsJobProcessor.php +++ b/app/Classes/Modules/PackingLists/Processors/ListPackingListsJobProcessor.php @@ -7,7 +7,11 @@ use App\Classes\Modules\PackingLists\Services\ListsPackingLists; use App\Classes\Modules\Jobs\Processors\UpdateJobResultProcessor; use App\Classes\General\Helper; use App\Classes\Modules\Jobs\DataTransferObjects\ListGenericJobObject; +use App\Http\Middleware\CheckForStorageInvoiceByPackingLists; use App\Http\Resources\ListPackingListJobResource; +use App\Http\Resources\ListPackingListDetailsJobResource; +use App\Http\Resources\ListPackingListJobWithStorageResource; +use Illuminate\Support\Facades\Log; class ListPackingListsJobProcessor { @@ -18,15 +22,19 @@ class ListPackingListsJobProcessor /** @var UpdateJobResultProcessor */ private $updateJobResultProcessor; + /** @var CheckForStorageInvoiceByPackingLists */ + private $checkForStorageInvoiceByPackingLists; + /** * ListPackingListsJobProcessor constructor. * @param ListsPackingLists $listsPackingLists * @param UpdateJobResultProcessor $updateJobResultProcessor */ - public function __construct(ListsPackingLists $listsPackingLists, UpdateJobResultProcessor $updateJobResultProcessor) + public function __construct(ListsPackingLists $listsPackingLists, UpdateJobResultProcessor $updateJobResultProcessor, CheckForStorageInvoiceByPackingLists $checkForStorageInvoiceByPackingLists) { $this->listsPackingLists = $listsPackingLists; $this->updateJobResultProcessor = $updateJobResultProcessor; + $this->checkForStorageInvoiceByPackingLists = $checkForStorageInvoiceByPackingLists; } /** @@ -36,12 +44,44 @@ class ListPackingListsJobProcessor * @throws \App\Classes\Exceptions\JobResourceNotFoundException */ public function execute(ListGenericJobObject $listGenericJobObject) { - + // $query = $this->listsPackingLists->execute($this->listsPackingLists->deserializeFilters($listGenericJobObject->getPayload()['filters']), ['page' => $listGenericJobObject->getPayload()['page'], 'with_containers_packages' => true]); $query = $this->listsPackingLists->execute($this->listsPackingLists->deserializeFilters($listGenericJobObject->getPayload()['filters']), ['page' => $listGenericJobObject->getPayload()['page']]); + // $query = $this->listsPackingLists->execute(array_merge($this->listsPackingLists->deserializeFilters($listGenericJobObject->getPayload()['filters']), ['page' => $listGenericJobObject->getPayload()['page'], 'with_containers_packages' => true])); + + $filtersArray = json_decode($listGenericJobObject->getPayload()['filters'], true); + + $storages = []; + if(isset($filtersArray['check_for_storage_invoice'])) + { + $myRequest = new \Illuminate\Http\Request(); + $myRequest->setMethod('POST'); + $myRequest->request->add($listGenericJobObject->getPayload()); + $next = function ($request) { + return $request; + }; + + $response = $this->checkForStorageInvoiceByPackingLists->handle($myRequest, $next); + $storages = $response->input('storages'); + } + foreach ($query->items() as &$item) { $item['userInfo'] = $listGenericJobObject->getUserInfo(); + $item['storages'] = $storages; + } + + if(isset($filtersArray['does_not_have_transaction_type'])){ //For Payment and Billing page > Pending Invoice tab + $resultCurrent = Helper::collectionResponse(ListPackingListDetailsJobResource::collection($query)); + $this->updateJobResultProcessor->execute($listGenericJobObject, $resultCurrent); + } + else{ + if($storages){ //For Payment and Billing page > Pending Payment tab, Paid Invoice tab + $resultCurrent = Helper::collectionResponse(ListPackingListJobWithStorageResource::collection($query)); + $this->updateJobResultProcessor->execute($listGenericJobObject, $resultCurrent); + } + else{ + $resultCurrent = Helper::collectionResponse(ListPackingListJobResource::collection($query)); + $this->updateJobResultProcessor->execute($listGenericJobObject, $resultCurrent); + } } - $resultCurrent = Helper::collectionResponse(ListPackingListJobResource::collection($query)); - $this->updateJobResultProcessor->execute($listGenericJobObject, $resultCurrent); } } diff --git a/app/Classes/Modules/PerfexCRM/Processors/FetchPerfexCRMInvoiceProcessor.php b/app/Classes/Modules/PerfexCRM/Processors/FetchPerfexCRMInvoiceProcessor.php index 21c6159c..769c4023 100644 --- a/app/Classes/Modules/PerfexCRM/Processors/FetchPerfexCRMInvoiceProcessor.php +++ b/app/Classes/Modules/PerfexCRM/Processors/FetchPerfexCRMInvoiceProcessor.php @@ -61,7 +61,7 @@ class FetchPerfexCRMInvoiceProcessor $invoiceId = $result->payload['id']; } else { $log['message'] = 'FetchPerfexCRMInvoiceProcessor failed for transaction > bill_no: '.$number; - Helper::debugLogger($log); + Log::channel('perfex_crm')->info($log); } } else{ diff --git a/app/Classes/Modules/PerfexCRM/Services/ConvertsPerfexCRMLeadToCustomer.php b/app/Classes/Modules/PerfexCRM/Services/ConvertsPerfexCRMLeadToCustomer.php index 0e41b5a7..e4e619e2 100644 --- a/app/Classes/Modules/PerfexCRM/Services/ConvertsPerfexCRMLeadToCustomer.php +++ b/app/Classes/Modules/PerfexCRM/Services/ConvertsPerfexCRMLeadToCustomer.php @@ -25,7 +25,7 @@ class ConvertsPerfexCRMLeadToCustomer return (object) $data; }else{ - Log::error('ConvertsPerfexCRMLeadToCustomer: '.$response); + Log::channel('perfex_crm')->info('ConvertsPerfexCRMLeadToCustomer: '.$response); return null; } } diff --git a/app/Classes/Modules/PerfexCRM/Services/CreatesPerfexCRMCustomer.php b/app/Classes/Modules/PerfexCRM/Services/CreatesPerfexCRMCustomer.php index 9555c61b..70eea579 100644 --- a/app/Classes/Modules/PerfexCRM/Services/CreatesPerfexCRMCustomer.php +++ b/app/Classes/Modules/PerfexCRM/Services/CreatesPerfexCRMCustomer.php @@ -28,7 +28,7 @@ class CreatesPerfexCRMCustomer $data = $response->json(); return (object) $data; }else{ - Log::error('CreatesPerfexCRMCustomer: '.$response); + Log::channel('perfex_crm')->info('CreatesPerfexCRMCustomer: '.$response); return null; } } diff --git a/app/Classes/Modules/PerfexCRM/Services/CreatesPerfexCRMCustomerContact.php b/app/Classes/Modules/PerfexCRM/Services/CreatesPerfexCRMCustomerContact.php index 1f5478eb..ddbb9634 100644 --- a/app/Classes/Modules/PerfexCRM/Services/CreatesPerfexCRMCustomerContact.php +++ b/app/Classes/Modules/PerfexCRM/Services/CreatesPerfexCRMCustomerContact.php @@ -35,7 +35,7 @@ class CreatesPerfexCRMCustomerContact $data = $response->json(); return (object) $data; }else{ - Log::error('CreatesPerfexCRMCustomerContact: '.$response); + Log::channel('perfex_crm')->info('CreatesPerfexCRMCustomerContact: '.$response); return null; } } diff --git a/app/Classes/Modules/PerfexCRM/Services/CreatesPerfexCRMCustomerProject.php b/app/Classes/Modules/PerfexCRM/Services/CreatesPerfexCRMCustomerProject.php index 2b6fa9de..0af171bd 100644 --- a/app/Classes/Modules/PerfexCRM/Services/CreatesPerfexCRMCustomerProject.php +++ b/app/Classes/Modules/PerfexCRM/Services/CreatesPerfexCRMCustomerProject.php @@ -34,7 +34,7 @@ class CreatesPerfexCRMCustomerProject $data = $response->json(); return (object) $data; }else{ - Log::error('CreatesPerfexCRMCustomerProject: '.$response); + Log::channel('perfex_crm')->info('CreatesPerfexCRMCustomerProject: '.$response); return null; } } diff --git a/app/Classes/Modules/PerfexCRM/Services/CreatesPerfexCRMInvoice.php b/app/Classes/Modules/PerfexCRM/Services/CreatesPerfexCRMInvoice.php index 21de87e5..4a8c213a 100644 --- a/app/Classes/Modules/PerfexCRM/Services/CreatesPerfexCRMInvoice.php +++ b/app/Classes/Modules/PerfexCRM/Services/CreatesPerfexCRMInvoice.php @@ -54,7 +54,7 @@ class CreatesPerfexCRMInvoice $data = $response->json(); return (object) $data; }else{ - Log::error('CreatesPerfexCRMInvoice: '.$response); + Log::channel('perfex_crm')->info('CreatesPerfexCRMInvoice: '.$response); return null; } } diff --git a/app/Classes/Modules/PerfexCRM/Services/CreatesPerfexCRMInvoicePayment.php b/app/Classes/Modules/PerfexCRM/Services/CreatesPerfexCRMInvoicePayment.php index 4e58d59f..1ecaf0f1 100644 --- a/app/Classes/Modules/PerfexCRM/Services/CreatesPerfexCRMInvoicePayment.php +++ b/app/Classes/Modules/PerfexCRM/Services/CreatesPerfexCRMInvoicePayment.php @@ -34,7 +34,7 @@ class CreatesPerfexCRMInvoicePayment $data = $response->json(); return (object) $data; }else{ - Log::error('CreatesPerfexCRMInvoicePayment: '.$response); + Log::channel('perfex_crm')->info('CreatesPerfexCRMInvoicePayment: '.$response); return null; } } diff --git a/app/Classes/Modules/PerfexCRM/Services/CreatesPerfexCRMLead.php b/app/Classes/Modules/PerfexCRM/Services/CreatesPerfexCRMLead.php index b2ac9c23..7249f91f 100644 --- a/app/Classes/Modules/PerfexCRM/Services/CreatesPerfexCRMLead.php +++ b/app/Classes/Modules/PerfexCRM/Services/CreatesPerfexCRMLead.php @@ -41,7 +41,7 @@ class CreatesPerfexCRMLead $data = $response->json(); return (object) $data; }else{ - Log::error('CreatesPerfexCRMLead: '.$response); + Log::channel('perfex_crm')->info('CreatesPerfexCRMLead: '.$response); return null; } } diff --git a/app/Classes/Modules/PerfexCRM/Services/CreatesPerfexCRMMilestone.php b/app/Classes/Modules/PerfexCRM/Services/CreatesPerfexCRMMilestone.php index 37342882..1a730be5 100644 --- a/app/Classes/Modules/PerfexCRM/Services/CreatesPerfexCRMMilestone.php +++ b/app/Classes/Modules/PerfexCRM/Services/CreatesPerfexCRMMilestone.php @@ -37,7 +37,7 @@ class CreatesPerfexCRMMilestone $data = $response->json(); return (object) $data; }else{ - Log::error('CreatesPerfexCRMMilestone: '.$response); + Log::channel('perfex_crm')->info('CreatesPerfexCRMMilestone: '.$response); return null; } } diff --git a/app/Classes/Modules/PerfexCRM/Services/CreatesPerfexCRMSupportTicket.php b/app/Classes/Modules/PerfexCRM/Services/CreatesPerfexCRMSupportTicket.php index b15f09c1..34692701 100644 --- a/app/Classes/Modules/PerfexCRM/Services/CreatesPerfexCRMSupportTicket.php +++ b/app/Classes/Modules/PerfexCRM/Services/CreatesPerfexCRMSupportTicket.php @@ -34,7 +34,7 @@ class CreatesPerfexCRMSupportTicket $data = $response->json(); return (object) $data; }else{ - Log::error($response); + Log::channel('perfex_crm')->info($response); return null; } } diff --git a/app/Classes/Modules/PerfexCRM/Services/CreatesPerfexCRMTask.php b/app/Classes/Modules/PerfexCRM/Services/CreatesPerfexCRMTask.php index 1d04ce5e..2bb3ab5f 100644 --- a/app/Classes/Modules/PerfexCRM/Services/CreatesPerfexCRMTask.php +++ b/app/Classes/Modules/PerfexCRM/Services/CreatesPerfexCRMTask.php @@ -58,7 +58,7 @@ class CreatesPerfexCRMTask $data = $response->json(); return (object) $data; }else{ - Log::error('CreatesPerfexCRMTask: '.$response); + Log::channel('perfex_crm')->info('CreatesPerfexCRMTask: '.$response); return null; } } diff --git a/app/Classes/Modules/PerfexCRM/Services/FetchesPerfexCRMCustomer.php b/app/Classes/Modules/PerfexCRM/Services/FetchesPerfexCRMCustomer.php index decc51bc..3898552d 100644 --- a/app/Classes/Modules/PerfexCRM/Services/FetchesPerfexCRMCustomer.php +++ b/app/Classes/Modules/PerfexCRM/Services/FetchesPerfexCRMCustomer.php @@ -25,7 +25,7 @@ class FetchesPerfexCRMCustomer return (object) $data; }else{ - Log::error('FetchesPerfexCRMCustomer: '.$response); + Log::channel('perfex_crm')->info('FetchesPerfexCRMCustomer: '.$response); return null; } } diff --git a/app/Classes/Modules/PerfexCRM/Services/FetchesPerfexCRMInvoice.php b/app/Classes/Modules/PerfexCRM/Services/FetchesPerfexCRMInvoice.php index 9104a3a9..98f2588a 100644 --- a/app/Classes/Modules/PerfexCRM/Services/FetchesPerfexCRMInvoice.php +++ b/app/Classes/Modules/PerfexCRM/Services/FetchesPerfexCRMInvoice.php @@ -27,7 +27,7 @@ class FetchesPerfexCRMInvoice return (object) $data; }else{ - Log::error('FetchesPerfexCRMInvoice: '.$response); + Log::channel('perfex_crm')->info('FetchesPerfexCRMInvoice: '.$response); return null; } } diff --git a/app/Classes/Modules/PerfexCRM/Services/FetchesPerfexCRMLead.php b/app/Classes/Modules/PerfexCRM/Services/FetchesPerfexCRMLead.php index 09f1af6e..ec9dc673 100644 --- a/app/Classes/Modules/PerfexCRM/Services/FetchesPerfexCRMLead.php +++ b/app/Classes/Modules/PerfexCRM/Services/FetchesPerfexCRMLead.php @@ -25,7 +25,7 @@ class FetchesPerfexCRMLead return (object) $data; }else{ - Log::error('FetchesPerfexCRMLead: '.$response); + Log::channel('perfex_crm')->info('FetchesPerfexCRMLead: '.$response); return null; } } diff --git a/app/Classes/Modules/PerfexCRM/Services/FetchesPerfexCRMMilestone.php b/app/Classes/Modules/PerfexCRM/Services/FetchesPerfexCRMMilestone.php index 77433f6e..8250c267 100644 --- a/app/Classes/Modules/PerfexCRM/Services/FetchesPerfexCRMMilestone.php +++ b/app/Classes/Modules/PerfexCRM/Services/FetchesPerfexCRMMilestone.php @@ -31,7 +31,7 @@ class FetchesPerfexCRMMilestone return (object) $data; }else{ - Log::error('FetchesPerfexCRMMilestone: '.$response); + Log::channel('perfex_crm')->info('FetchesPerfexCRMMilestone: '.$response); return null; } } diff --git a/app/Classes/Modules/PerfexCRM/Services/FetchesPerfexCRMProject.php b/app/Classes/Modules/PerfexCRM/Services/FetchesPerfexCRMProject.php index a6f43b7e..73c4d10b 100644 --- a/app/Classes/Modules/PerfexCRM/Services/FetchesPerfexCRMProject.php +++ b/app/Classes/Modules/PerfexCRM/Services/FetchesPerfexCRMProject.php @@ -31,7 +31,7 @@ class FetchesPerfexCRMProject return (object) $data; }else{ - Log::error('FetchesPerfexCRMProject: '.$response); + Log::channel('perfex_crm')->info('FetchesPerfexCRMProject: '.$response); return null; } } diff --git a/app/Classes/Modules/PerfexCRM/Services/FetchesPerfexCRMTask.php b/app/Classes/Modules/PerfexCRM/Services/FetchesPerfexCRMTask.php index a83eb112..da594f1d 100644 --- a/app/Classes/Modules/PerfexCRM/Services/FetchesPerfexCRMTask.php +++ b/app/Classes/Modules/PerfexCRM/Services/FetchesPerfexCRMTask.php @@ -45,7 +45,7 @@ class FetchesPerfexCRMTask return (object) $data; }else{ - Helper::debugLogger($response); + Log::channel('perfex_crm')->info($response); return null; } } diff --git a/app/Classes/Modules/PerfexCRM/Services/UpdatesPerfexCRMCustomer.php b/app/Classes/Modules/PerfexCRM/Services/UpdatesPerfexCRMCustomer.php index 193155e3..8cc99d87 100644 --- a/app/Classes/Modules/PerfexCRM/Services/UpdatesPerfexCRMCustomer.php +++ b/app/Classes/Modules/PerfexCRM/Services/UpdatesPerfexCRMCustomer.php @@ -39,7 +39,7 @@ class UpdatesPerfexCRMCustomer $data = $response->json(); return (object) $data; }else{ - // Helper::debugLogger($response); + // Log::channel('perfex_crm')->info($response); return null; } } diff --git a/app/Classes/Modules/PerfexCRM/Services/UpdatesPerfexCRMInvoice.php b/app/Classes/Modules/PerfexCRM/Services/UpdatesPerfexCRMInvoice.php index 5f21cd32..2b77438d 100644 --- a/app/Classes/Modules/PerfexCRM/Services/UpdatesPerfexCRMInvoice.php +++ b/app/Classes/Modules/PerfexCRM/Services/UpdatesPerfexCRMInvoice.php @@ -61,7 +61,7 @@ class UpdatesPerfexCRMInvoice $data = $response->json(); return (object) $data; }else{ - Log::error('UpdatesPerfexCRMInvoice: '.$response); + Log::channel('perfex_crm')->info('UpdatesPerfexCRMInvoice: '.$response); return null; } } diff --git a/app/Classes/Modules/PerfexCRM/Services/UpdatesPerfexCRMLead.php b/app/Classes/Modules/PerfexCRM/Services/UpdatesPerfexCRMLead.php index 6ac332f7..b519be44 100644 --- a/app/Classes/Modules/PerfexCRM/Services/UpdatesPerfexCRMLead.php +++ b/app/Classes/Modules/PerfexCRM/Services/UpdatesPerfexCRMLead.php @@ -42,7 +42,7 @@ class UpdatesPerfexCRMLead $data = $response->json(); return (object) $data; }else{ - Log::error('UpdatesPerfexCRMLead: '.$response); + Log::channel('perfex_crm')->info('UpdatesPerfexCRMLead: '.$response); return null; } } diff --git a/app/Classes/Modules/PerfexCRM/Services/UpdatesPerfexCRMProject.php b/app/Classes/Modules/PerfexCRM/Services/UpdatesPerfexCRMProject.php index 9dceba4c..73ec6906 100644 --- a/app/Classes/Modules/PerfexCRM/Services/UpdatesPerfexCRMProject.php +++ b/app/Classes/Modules/PerfexCRM/Services/UpdatesPerfexCRMProject.php @@ -34,7 +34,7 @@ class UpdatesPerfexCRMProject $data = $response->json(); return (object) $data; }else{ - Log::error('UpdatesPerfexCRMProject: '.$response); + Log::channel('perfex_crm')->info('UpdatesPerfexCRMProject: '.$response); return null; } } diff --git a/app/Classes/Modules/PerfexCRM/Services/UpdatesPerfexCRMTask.php b/app/Classes/Modules/PerfexCRM/Services/UpdatesPerfexCRMTask.php index 1ece3431..2a6789ff 100644 --- a/app/Classes/Modules/PerfexCRM/Services/UpdatesPerfexCRMTask.php +++ b/app/Classes/Modules/PerfexCRM/Services/UpdatesPerfexCRMTask.php @@ -39,7 +39,7 @@ class UpdatesPerfexCRMTask $data = $response->json(); return (object) $data; }else{ - Log::error('UpdatesPerfexCRMTask: '.$response); + Log::channel('perfex_crm')->info('UpdatesPerfexCRMTask: '.$response); return null; } } diff --git a/app/Classes/Modules/Transactions/ControllersLogic/CreateGroupsLogic.php b/app/Classes/Modules/Transactions/ControllersLogic/CreateGroupsLogic.php index 49a59f05..c750f3f2 100644 --- a/app/Classes/Modules/Transactions/ControllersLogic/CreateGroupsLogic.php +++ b/app/Classes/Modules/Transactions/ControllersLogic/CreateGroupsLogic.php @@ -21,6 +21,8 @@ use App\Classes\ValueObjects\Constants\ApprovalStatus; use App\Models\GroupTransaction; use App\Http\Resources\WalletTransactionResource; use App\Models\Wallet; +use App\Classes\Modules\Transactions\Processors\ReleaseGoodsToCustomerProcessor; + class CreateGroupsLogic extends AbstractControllerLogic { @@ -55,13 +57,18 @@ class CreateGroupsLogic extends AbstractControllerLogic /** @var CreatesGroup */ private $createsGroup; + /** @var ReleaseGoodsToCustomerProcessor */ + private $releaseGoodsToCustomerProcessor; + + public function __construct( - FetchesTransaction $fetchesTransaction, - GeneratesTransactionBillNumber $generatesTransactionBillNumber, + FetchesTransaction $fetchesTransaction, + GeneratesTransactionBillNumber $generatesTransactionBillNumber, FetchesCompanyModule $fetchesCompanyModule, CreateWalletTopUpTransactionProcessor $createWalletTopUpTransactionProcessor, CreatePaymentTransactionProcessor $createPaymentTransactionProcessor, - CreatesGroup $createsGroup + CreatesGroup $createsGroup, + ReleaseGoodsToCustomerProcessor $releaseGoodsToCustomerProcessor ) { $this->fetchesTransaction = $fetchesTransaction; @@ -70,20 +77,40 @@ class CreateGroupsLogic extends AbstractControllerLogic $this->createWalletTopUpTransactionProcessor = $createWalletTopUpTransactionProcessor; $this->createPaymentTransactionProcessor = $createPaymentTransactionProcessor; $this->createsGroup = $createsGroup; + $this->releaseGoodsToCustomerProcessor = $releaseGoodsToCustomerProcessor; } public function logic(Request $request) : JsonResponse { - $payment_method = PaymentMethodType::PAYMENT_METHODS[$request->input('payment_method')]; - $groupPyamentStatus = ApprovalStatus::PENDING_VERIFICATION; - $invoice_ids = json_decode($request->route('transaction_ids')); - $billNumber = $this->generatesTransactionBillNumber->execute('PYMT-'); // todo-new: check why is this not working // $invoices = $this->fetchesTransaction->execute(['id_in' => $invoice_ids]); $invoices = Transaction::whereIn('id', $invoice_ids)->get(); + $isInvoicesApprove = $this->checkIfInvoicesAreApprove($invoices); + if(!$isInvoicesApprove){ + $response = ['message' => 'One of the transactions might be suspended; please check if there are any disputes in progress.']; + return $this->response(['data' => $response]); + } + else{ + $paymentMethodStr = $request->input('payment_method'); + $paymentMethod = PaymentMethodType::PAYMENT_METHODS[$paymentMethodStr]; + $amount = $request->input('amount'); + $bankCode = $request->input('bank_code'); + $result = $this->processInvoices($invoices, $paymentMethodStr, $amount, $bankCode); + if ($paymentMethod === PaymentMethodType::PAYMENT_GATEWAY) { + return $this->resourceResponse(new WalletTransactionResource($result)); + } + } + return $this->response([]); + } + + private function processInvoices($invoices, $reqPaymentMethod, $reqAmount, $reqBankCode){ + $result = []; + $payment_method = PaymentMethodType::PAYMENT_METHODS[$reqPaymentMethod]; + $groupPyamentStatus = ApprovalStatus::PENDING_VERIFICATION; + $billNumber = $this->generatesTransactionBillNumber->execute('PYMT-'); foreach ($invoices as $invoice) { $order = null; if ($invoice->owner instanceof Transaction) { @@ -110,7 +137,7 @@ class CreateGroupsLogic extends AbstractControllerLogic $wallet = Wallet::where('owner_id', $companyModuleId)->first(); // todo-new: verify currently checking wallet amount based on 'amount' value passed by frontend - if((float) number_format(($wallet->amount - $request->input('amount')),2) < 0){ + if((float) number_format(($wallet->amount - $reqAmount),2) < 0){ throw new MalformedRequestException('Insufficient wallet balance. Please Top up your wallet.'); } @@ -146,7 +173,12 @@ class CreateGroupsLogic extends AbstractControllerLogic foreach ($invoices as $invoice) { if ($payment_method == PaymentMethodType::WALLET) { - $this->createPaymentTransactionProcessor->execute($invoice, PaymentMethodType::WALLET, $request->input('bank_code')); + $paymentTransaction = $this->createPaymentTransactionProcessor->execute($invoice, PaymentMethodType::WALLET, $reqBankCode, false); + + if($paymentTransaction && $paymentTransaction->status == ApprovalStatus::APPROVED){ + $pL = $invoice->owner; + $this->releaseGoodsToCustomerProcessor->execute($pL, $invoice); + } } $issuer = $invoice->issuer; @@ -168,11 +200,12 @@ class CreateGroupsLogic extends AbstractControllerLogic if (in_array($payment_method, [PaymentMethodType::PAYMENT_GATEWAY, PaymentMethodType::CASH])) { // create only one billplz payment for wallet top up - $amount = floatval(str_replace(',', '', $request->input('amount'))); + $amount = floatval(str_replace(',', '', $reqAmount)); $companyModuleId = $invoice->receiver; $companyModule = $this->fetchesCompanyModule->execute(['id' => $companyModuleId]); - $topUpTransaction = $this->createWalletTopUpTransactionProcessor->execute($companyModule, $amount, $request->input('bank_code'), $payment_method, $billNumber, true); + $topUpTransaction = $this->createWalletTopUpTransactionProcessor->execute($companyModule, $amount, $reqBankCode, $payment_method, $billNumber, true); + $result = $topUpTransaction; } $group->issuer = $issuer; @@ -188,11 +221,15 @@ class CreateGroupsLogic extends AbstractControllerLogic $group->status = $groupPyamentStatus; $group->save(); - if ($payment_method === PaymentMethodType::PAYMENT_GATEWAY) { - return $this->resourceResponse(new WalletTransactionResource($topUpTransaction)); + return $result; + } - } else { - return $this->response([]); + private function checkIfInvoicesAreApprove($invoices){ + foreach ($invoices as $invoice) { + if($invoice->status !== ApprovalStatus::APPROVED && $invoice->status !== ApprovalStatus::COMPLETED){ + return false; + } } + return true; } } diff --git a/app/Classes/Modules/Transactions/ControllersLogic/CreatePaymentTransactionLogic.php b/app/Classes/Modules/Transactions/ControllersLogic/CreatePaymentTransactionLogic.php index ae10403a..c8c8d914 100644 --- a/app/Classes/Modules/Transactions/ControllersLogic/CreatePaymentTransactionLogic.php +++ b/app/Classes/Modules/Transactions/ControllersLogic/CreatePaymentTransactionLogic.php @@ -10,6 +10,8 @@ use App\Http\Resources\TransactionResource; use Illuminate\Http\JsonResponse; use Illuminate\Http\Request; use App\Classes\Modules\Transactions\Processors\CreatePaymentTransactionProcessor; +use App\Classes\Modules\Transactions\Processors\ReleaseGoodsToCustomerProcessor; +use App\Classes\ValueObjects\Constants\ApprovalStatus; class CreatePaymentTransactionLogic extends AbstractControllerLogic { @@ -30,13 +32,18 @@ class CreatePaymentTransactionLogic extends AbstractControllerLogic /** @var CreatePaymentTransactionProcessor */ private $createPaymentTransactionProcessor; + /** @var ReleaseGoodsToCustomerProcessor */ + private $releaseGoodsToCustomerProcessor; + public function __construct( FetchesTransaction $fetchesTransaction, - CreatePaymentTransactionProcessor $createPaymentTransactionProcessor + CreatePaymentTransactionProcessor $createPaymentTransactionProcessor, + ReleaseGoodsToCustomerProcessor $releaseGoodsToCustomerProcessor ) { $this->fetchesTransaction = $fetchesTransaction; $this->createPaymentTransactionProcessor = $createPaymentTransactionProcessor; + $this->releaseGoodsToCustomerProcessor = $releaseGoodsToCustomerProcessor; } public function logic(Request $request) : JsonResponse @@ -45,22 +52,20 @@ class CreatePaymentTransactionLogic extends AbstractControllerLogic $invoice_transaction = $this->fetchesTransaction->execute(['id' => $request->input('transaction_id')]); - $payment_transaction = $this->createPaymentTransactionProcessor->execute($invoice_transaction, $payment_method , $request->input('bank_code')); + if($invoice_transaction->status === ApprovalStatus::APPROVED){ + $payment_transaction = $this->createPaymentTransactionProcessor->execute($invoice_transaction, $payment_method , $request->input('bank_code'), false); - //cief todo: at exchange there is a transition step - starts - // if(PaymentMethodType::PAYMENT_METHODS[$request->input('payment_method')] == PaymentMethodType::PAYMENT_GATEWAY){ - // $this->updatesTransactionStatus->execute($transaction, ApprovalStatus::PENDING_VERIFICATION); - // } + if($payment_transaction && $payment_transaction->status === ApprovalStatus::APPROVED){ + $pL = $invoice_transaction->owner; + $this->releaseGoodsToCustomerProcessor->execute($pL, $invoice_transaction); + } + return $this->resourceResponse(new TransactionResource($payment_transaction)); + } - // if(config('perfexcrm.is_enabled') == 'true'){ - // $this->transactionToPerfexCRMV2Processor->execute($transaction, $status); - // } - - //To use - //ApprovalStatus::PENDING_VERIFICATION; - //use this to trigger $this->transactionToPerfexCRMV2Processor->execute > defineTasks > defineTasks_handlePendingVerificationStatus > definePaymentTasks - //cief todo: at exchange there is a transition step - ends - - return $this->resourceResponse(new TransactionResource($payment_transaction)); + $response = ['message' => 'A transaction might be suspended; please check if there is any dispute in progress.']; + return $this->response(['data' => $response]); } + + + } diff --git a/app/Classes/Modules/Transactions/ControllersLogic/DeleteTransactionLogic.php b/app/Classes/Modules/Transactions/ControllersLogic/DeleteTransactionLogic.php index 56d24523..7fff74f5 100644 --- a/app/Classes/Modules/Transactions/ControllersLogic/DeleteTransactionLogic.php +++ b/app/Classes/Modules/Transactions/ControllersLogic/DeleteTransactionLogic.php @@ -30,7 +30,7 @@ class DeleteTransactionLogic extends AbstractControllerLogic /** - * SuspendTransactionLogic constructor. + * DeleteTransactionLogic constructor. * @param FetchesTransaction $fetchesTransaction * @param UpdatesTransactionStatus $updatesTransactionStatus */ diff --git a/app/Classes/Modules/Transactions/ControllersLogic/ListTransactionsLogic.php b/app/Classes/Modules/Transactions/ControllersLogic/ListTransactionsLogic.php index c0a77b50..2d5c40dd 100644 --- a/app/Classes/Modules/Transactions/ControllersLogic/ListTransactionsLogic.php +++ b/app/Classes/Modules/Transactions/ControllersLogic/ListTransactionsLogic.php @@ -5,6 +5,7 @@ namespace App\Classes\Modules\Transactions\ControllersLogic; use App\Classes\General\Abstracts\AbstractControllerLogic; use App\Classes\Modules\Transactions\Services\ListsTransactions; +use App\Http\Resources\TransactionWithStorageResource; use App\Http\Resources\TransactionResource; use Illuminate\Http\JsonResponse; use Illuminate\Http\Request; @@ -42,15 +43,18 @@ class ListTransactionsLogic extends AbstractControllerLogic $query = $this->listsTransactions->execute($this->listsTransactions->deserializeFilters($request->input('filters'))); if($request->input('storages')){ - foreach ($query->items() as &$item) { + foreach ($query->items() as $item) { $transactionId = $item['id']; $filteredStorages = array_filter($request->input('storages'), function ($storage) use ($transactionId) { return isset($storage['parentInvoiceId']) && $storage['parentInvoiceId'] == $transactionId; }); $item['storages'] = $filteredStorages; } + //return $this->collectionResponse(TransactionWithStorageResource::collection($query)); } - - return $this->collectionResponse(TransactionResource::collection($query)); + // else{ + // return $this->collectionResponse(TransactionResource::collection($query)); + // + return $this->collectionResponse(TransactionWithStorageResource::collection($query)); } } diff --git a/app/Classes/Modules/Transactions/ControllersLogic/RegenerateSingleStorageInvoiceTransactionLogic.php b/app/Classes/Modules/Transactions/ControllersLogic/RegenerateSingleStorageInvoiceTransactionLogic.php new file mode 100644 index 00000000..3ea0a2ac --- /dev/null +++ b/app/Classes/Modules/Transactions/ControllersLogic/RegenerateSingleStorageInvoiceTransactionLogic.php @@ -0,0 +1,67 @@ + 'Regenerate Storage Invoice', + 'message' => 'You have successfully regenerated storage invoice' + ]; + } + + + /** @var FetchesTransaction */ + private $fetchesTransaction; + + /** @var CreateStorageInvoiceDocTransactionFixProcessor */ + private $createStorageInvoiceDocTransactionProcessor; + + /** @var CanRegenerateStorageInvoice */ + private $canRegenerateStorageInvoice; + + /** + * @param CreatesDocument $createsDocument + */ + public function __construct(FetchesTransaction $fetchesTransaction, CreateStorageInvoiceDocTransactionFixProcessor $createStorageInvoiceDocTransactionProcessor, CanRegenerateStorageInvoice $canRegenerateStorageInvoice) + { + $this->fetchesTransaction = $fetchesTransaction; + $this->createStorageInvoiceDocTransactionProcessor = $createStorageInvoiceDocTransactionProcessor; + $this->canRegenerateStorageInvoice = $canRegenerateStorageInvoice; + } + + public function logic(Request $request) : JsonResponse + { + $this->canRegenerateStorageInvoice->passes(); + + $invoice = $this->fetchesTransaction->execute(['id' => $request->route('invoice_id')]); + $packingList = $invoice->owner; + $order = $packingList->owner; + $invoices = $order->transactions()->where('transactions.type', TransactionType::STORAGE_INVOICE)->get(); + foreach ($invoices as $invoice){ + $invoice->documents()->delete(); + } + + $this->createStorageInvoiceDocTransactionProcessor->execute($packingList, true); + Log::info(Auth::user()->email." regenerate storage invoice for transaction with id ".$request->route('invoice_id')); + + return $this->response([]); + } + +} diff --git a/app/Classes/Modules/Transactions/ControllersLogic/WaiveTransactionLogic.php b/app/Classes/Modules/Transactions/ControllersLogic/WaiveTransactionLogic.php new file mode 100644 index 00000000..61e48ac0 --- /dev/null +++ b/app/Classes/Modules/Transactions/ControllersLogic/WaiveTransactionLogic.php @@ -0,0 +1,65 @@ + 'Waive Transaction', + 'message' => 'You have successfully waived the transaction' + ]; + } + + /** @var FetchesTransaction */ + private $fetchesTransaction; + + /** @var UpdatesTransactionIsWaived */ + private $updatesTransactionIsWaived; + + /** @var CanWaiveTransaction */ + private $canWaiveTransaction; + + + /** + * WaiveTransactionLogic constructor. + * @param FetchesTransaction $fetchesTransaction + * @param UpdatesTransactionIsWaived $updatesTransactionIsWaived + * @param CanWaiveTransaction $canWaiveTransaction + */ + public function __construct(FetchesTransaction $fetchesTransaction, UpdatesTransactionIsWaived $updatesTransactionIsWaived, CanWaiveTransaction $canWaiveTransaction) + { + $this->fetchesTransaction = $fetchesTransaction; + $this->updatesTransactionIsWaived = $updatesTransactionIsWaived; + $this->canWaiveTransaction = $canWaiveTransaction; + } + + + public function logic(Request $request) : JsonResponse + { + $transaction = $this->fetchesTransaction->execute(['id' => $request->route('id')]); + + $object = new WaiveTransactionObject($transaction->id, $transaction->bill_no, $transaction->type, $transaction->status); + $this->canWaiveTransaction->passes($object); + + $this->updatesTransactionIsWaived->execute($transaction); + Log::info(Auth::user()->email." waive storage invoice charges with bill_no: ".$transaction->bill_no); + + return $this->response([]); + } +} diff --git a/app/Classes/Modules/Transactions/DataTransferObjects/WaiveTransactionObject.php b/app/Classes/Modules/Transactions/DataTransferObjects/WaiveTransactionObject.php new file mode 100644 index 00000000..452a75d6 --- /dev/null +++ b/app/Classes/Modules/Transactions/DataTransferObjects/WaiveTransactionObject.php @@ -0,0 +1,61 @@ +id = $id; + $this->billNo = $billNo; + $this->type = $type; + $this->status = $status; + } + + /** + * @return int + */ + public function getId(): int + { + return $this->id; + } + + /** + * @return string + */ + public function getBillNo(): string + { + return $this->billNo; + } + + /** + * @return int + */ + public function getType(): int + { + return $this->type; + } + + /** + * @return int + */ + public function getStatus(): int + { + return $this->status; + } +} diff --git a/app/Classes/Modules/Transactions/Processors/CheckStorageInvoiceTransactionProcessor.php b/app/Classes/Modules/Transactions/Processors/CheckStorageInvoiceTransactionProcessor.php index 82ce94da..d5c87ce0 100644 --- a/app/Classes/Modules/Transactions/Processors/CheckStorageInvoiceTransactionProcessor.php +++ b/app/Classes/Modules/Transactions/Processors/CheckStorageInvoiceTransactionProcessor.php @@ -24,7 +24,7 @@ use App\Classes\ValueObjects\Constants\ApprovalStatus; use App\Classes\ValueObjects\Constants\PackageType; use App\Classes\ValueObjects\Constants\PackingListType; use App\Classes\ValueObjects\Constants\TransactionDetailType; -use App\Http\Resources\TransactionResource; +use App\Http\Resources\TransactionWithStorageResource; use App\Models\Order; use App\Models\PackingList; use App\Models\Transaction; @@ -99,33 +99,38 @@ class CheckStorageInvoiceTransactionProcessor return $this->executeOrder($order); } - public function executeOrder(Order $order, bool $isBackDoorCheck = false){ + public function executeOrder(Order $order){ $results = []; $marking = $order->companyModule->inviters()->withPivot('invitee_reference')->first()->pivot->invitee_reference; $is_credit_term = $order->companyModule->inviters()->withPivot('is_credit_term')->first()->pivot->is_credit_term; - if(!$is_credit_term){ - Log::channel('storage_invoices')->info('orderId: '.$order->id.', orderReference: '.$order->reference.', marking: '.$marking.', is_credit_term: '.$is_credit_term); - $packingLists = $order->destinationWarehousePackages; + Log::channel('storage_invoices')->info('orderId: '.$order->id.', orderReference: '.$order->reference.', marking: '.$marking.', is_credit_term: '.$is_credit_term); + $packingLists = $order->destinationWarehousePackages; - foreach ($packingLists as $packingList){ - $arrivalDateAtChinaWarehouse = $this->getArrivalDateAtChinaWarehoue($packingList); - Log::channel('storage_invoices')->info('arrivalDateAtChinaWarehouse: '.json_encode($arrivalDateAtChinaWarehouse)); - Log::channel('storage_invoices')->info('destinationWarehousePackage: '.json_encode($packingList)); - $eta = $this->getEtaFromPackingList($packingList); - if($arrivalDateAtChinaWarehouse && $eta){ - $transactions = $packingList->transactions()->where('transactions.type', TransactionType::SHIPPING_INVOICE)->whereIn('transactions.status', [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED])->get(); - // $transactions = $destinationWarehousePackage->transactions()->where('transactions.type', TransactionType::SHIPPING_INVOICE)->where('transactions.status', ApprovalStatus::APPROVED)->get(); + foreach ($packingLists as $packingList){ + $arrivalDateAtChinaWarehouse = $this->getArrivalDateAtChinaWarehoue($packingList); + Log::channel('storage_invoices')->info('arrivalDateAtChinaWarehouse: '.json_encode($arrivalDateAtChinaWarehouse)); + Log::channel('storage_invoices')->info('destinationWarehousePackage: '.json_encode($packingList)); + $eta = $this->getEtaFromPackingList($packingList); + if($arrivalDateAtChinaWarehouse && $eta){ + $transactions = $packingList->transactions()->where('transactions.type', TransactionType::SHIPPING_INVOICE)->whereIn('transactions.status', [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED])->get(); + // $transactions = $destinationWarehousePackage->transactions()->where('transactions.type', TransactionType::SHIPPING_INVOICE)->where('transactions.status', ApprovalStatus::APPROVED)->get(); - /** @var Transaction $invoice_transaction */ - foreach ($transactions as $invoice_transaction){ - $result = $this->processSingleTransactionOfTypeShippingInvoice($invoice_transaction, $packingList, $order->company_module_id, $eta, $isBackDoorCheck); - if($result){ - $results[] = $result; - } + /** @var Transaction $invoice_transaction */ + foreach ($transactions as $invoice_transaction){ + $result = null; + if(!$is_credit_term){ + $result = $this->processSingleTransactionOfTypeShippingInvoice($invoice_transaction, $packingList, $order->company_module_id, $eta); + } + else{ + $result = $this->isPaidOrWaivedStorageInvoiceExist($invoice_transaction, $packingList, $eta); + } + if($result){ + $results[] = $result; } } } } + return $results; } @@ -167,7 +172,7 @@ class CheckStorageInvoiceTransactionProcessor return null; } - private function processSingleTransactionOfTypeShippingInvoice($transaction, $destinationWarehousePackage, $company_module_id, $eta, $isBackDoorCheck){ + private function processSingleTransactionOfTypeShippingInvoice($transaction, $destinationWarehousePackage, $company_module_id, $eta){ $pricePerCBM = 3; $resultNumberOfDaysFree = 10; $dt1 = $eta->copy()->addDay()->startOfDay(); @@ -200,6 +205,11 @@ class CheckStorageInvoiceTransactionProcessor $this->createStorageInvoiceTransactionDetails($storageInvoice, $destinationWarehousePackage, $cbm, $pricePerCBM, $resultNumberOfDaysExceeded); } else if($storageInvoice){ + //Additional handling for giving selected storage invoice a waiver + if(isset($storageInvoice->is_waived) && $storageInvoice->is_waived){ + $pricePerCBM = 0; + $price_cbm = $pricePerCBM * $cbm * $resultNumberOfDaysExceeded; + } //Additional handling for calculation of numberOfDaysExceeded in the event of the storage already paid $paymentStorageTransaction = $storageInvoice->transactions()->where('transactions.type', TransactionType::PAYMENT)->where('transactions.status', ApprovalStatus::APPROVED)->first(); @@ -216,19 +226,26 @@ class CheckStorageInvoiceTransactionProcessor Log::channel('storage_invoices')->info('Update $transaction->id: '.$transaction->id); Log::channel('storage_invoices')->info('$storageInvoice->status: '.$storageInvoice->status); Log::channel('storage_invoices')->info('price_cbm: '.$price_cbm."-".gettype($price_cbm)); + Log::channel('storage_invoices')->info('amount: '.$amount); + + $proceedToUpdate = false; if(abs($price_cbm - $amount) > $epsilon && $storageInvoice->status !== ApprovalStatus::COMPLETED){ $paymentTransactions = $storageInvoice->transactions()->where('transactions.type', TransactionType::PAYMENT)->where('transactions.status', ApprovalStatus::PENDING_SUBMISSION)->get(); - - if(!$isBackDoorCheck){ - if(count($paymentTransactions) > 0){ - $this->updatePaymentTransactionViaNonGroupPayment($paymentTransactions); - } - else{ - $this->updatePaymentTransactionViaGroupPayment($storageInvoice); - } + // if(!$isBackDoorCheck){ + if(count($paymentTransactions) > 0){ + $this->updatePaymentTransactionViaNonGroupPayment($paymentTransactions); } + else{ + $this->updatePaymentTransactionViaGroupPayment($storageInvoice); + } + //} + $proceedToUpdate = true; + } + + if($proceedToUpdate || ($pricePerCBM == 0 && $amount != 0)){ + Log::channel('storage_invoices')->info('proceedToUpdate'); $storageInvoice = $this->updateStorageInvoiceTransaction($storageInvoice, $price_cbm); $invoiceTransactionDetails = $storageInvoice->transactionDetails()->first(); $this->updateStorageInvoiceTransactionDetails($invoiceTransactionDetails, $destinationWarehousePackage, $cbm, $pricePerCBM, $resultNumberOfDaysExceeded); @@ -247,13 +264,68 @@ class CheckStorageInvoiceTransactionProcessor 'currentDate' => $resultCurrentDate, 'cbm' => $cbm, 'pricePerCBM' => $pricePerCBM, - 'storageInvoice' => new TransactionResource($storageInvoice) + 'storageInvoice' => new TransactionWithStorageResource($storageInvoice) ]; return $result; } } + private function isPaidOrWaivedStorageInvoiceExist($transaction, $packingList, $eta){ + $pricePerCBM = 3; + $resultNumberOfDaysFree = 10; + $dt1 = $eta->copy()->addDay()->startOfDay(); + $resultStartDate = $dt1->format('Y-m-d'); + $currentDatetime = Carbon::now(); + $dt2 = $currentDatetime->copy()->addDay()->startOfDay(); + $resultCurrentDate = $dt2->format('Y-m-d H:i:s'); + $interval = Carbon::parse($dt2)->diff($dt1); + $resultNumberOfDaysExceeded = $interval->days - $resultNumberOfDaysFree; + $paidStorageInvoice = $packingList->transactions()->where('transactions.type', TransactionType::STORAGE_INVOICE)->whereIn('transactions.status', [ApprovalStatus::COMPLETED])->first(); + if($paidStorageInvoice){ + $storageInvoice = $paidStorageInvoice; + } + else{ + $waivedStorageInvoice = $packingList->transactions()->where('transactions.type', TransactionType::STORAGE_INVOICE)->where('transactions.is_waived', 1)->whereIn('transactions.status', [ApprovalStatus::APPROVED])->first(); + $storageInvoice = $waivedStorageInvoice; + } + + if($storageInvoice){ + $storageInvoiceId = $storageInvoice->id; + + if(isset($storageInvoice->is_waived) && $storageInvoice->is_waived){ + $pricePerCBM = 0; + } + + $transactionDetailsItems = $transaction->transactionDetails()->get(); + $cbm = 0.00; + foreach ($transactionDetailsItems as $tdItem){ + $quantity = $tdItem->quantity; + if($tdItem->price < 0.00){ + $quantity = $quantity * -1; + } + $cbm = $cbm + $quantity; + } + + if($storageInvoiceId !== 0){ + $result = [ + 'parentInvoiceId' => $transaction->id, + 'storageInvoiceId' => $storageInvoiceId, + 'numberOfDaysExceeded' => $resultNumberOfDaysExceeded, + 'numberOfDaysFree' => $resultNumberOfDaysFree, + 'startDate' => $resultStartDate, + 'currentDate' => $resultCurrentDate, + 'cbm' => $cbm, + 'pricePerCBM' => $pricePerCBM, + 'storageInvoice' => new TransactionWithStorageResource($storageInvoice) + ]; + return $result; + } + } + + return []; + } + private function updatePaymentTransactionViaGroupPayment($storageInvoice){ Log::channel('storage_invoices')->info('updatePaymentTransactionViaGroupPayment'); $groups = $storageInvoice->groups()->get(); diff --git a/app/Classes/Modules/Transactions/Processors/CreatePaymentTransactionProcessor.php b/app/Classes/Modules/Transactions/Processors/CreatePaymentTransactionProcessor.php index 8f589de0..ad5e79ab 100644 --- a/app/Classes/Modules/Transactions/Processors/CreatePaymentTransactionProcessor.php +++ b/app/Classes/Modules/Transactions/Processors/CreatePaymentTransactionProcessor.php @@ -85,7 +85,7 @@ class CreatePaymentTransactionProcessor /** * @throws MalformedRequestException */ - public function execute(Transaction $invoice, $payment_method, $bank_code) + public function execute(Transaction $invoice, $payment_method, $bank_code, $run = true) { $amount = $invoice->amount; Log::info($invoice->owner); @@ -127,22 +127,26 @@ class CreatePaymentTransactionProcessor $this->updatesWalletBalance->execute($wallet, ($amount * -1)); - // $packingList = $invoice->owner; - // $order = $packingList->owner; - // $packingList->status = ApprovalStatus::APPROVED; - // $packingList->save(); + if($run) + { + $packingList = $invoice->owner; + $order = $packingList->owner; + $packingList->status = ApprovalStatus::APPROVED; + $packingList->save(); - // if(app()->environment('production')){ - // $this->updateDoFromVTPortalProcessor->execute($packingList); - // $this->updateDoFromYDPortalProcessor->execute($packingList); - // } + if(app()->environment('production')){ + $this->updateDoFromVTPortalProcessor->execute($packingList); + $this->updateDoFromYDPortalProcessor->execute($packingList); + } + } // later use this variabke to create a approved payment transaction $approvalStatus = ApprovalStatus::APPROVED; // update invoice to completed - // $this->updatesTransactionStatus->execute($invoice, ApprovalStatus::COMPLETED); - + if($run){ + $this->updatesTransactionStatus->execute($invoice, ApprovalStatus::COMPLETED); + } } else { $payment_method = PaymentMethodType::CASH; diff --git a/app/Classes/Modules/Transactions/Processors/CreateStorageInvoiceDocTransactionFixProcessor.php b/app/Classes/Modules/Transactions/Processors/CreateStorageInvoiceDocTransactionFixProcessor.php new file mode 100644 index 00000000..f019209e --- /dev/null +++ b/app/Classes/Modules/Transactions/Processors/CreateStorageInvoiceDocTransactionFixProcessor.php @@ -0,0 +1,79 @@ +updatesTransactionStatus = $updatesTransactionStatus; + $this->createsDocument = $createsDocument; + $this->createsFiles = $createsFiles; + } + + + /** + * @throws MalformedRequestException + */ + public function execute(PackingList $packingList) + { + /** @var Transaction $invoice_transaction */ + $invoice_transaction = $packingList->transactions()->where('transactions.type', TransactionType::STORAGE_INVOICE)->whereIn('status', [ApprovalStatus::COMPLETED])->first(); + + // $this->updatesTransactionStatus->execute($invoice_transaction, ApprovalStatus::APPROVED); + + $transaction_invoice_pdf = LaravelMpdf::loadView('pages.pdfs.shipping_invoice', ['invoice_transaction' => $invoice_transaction]); + + $document_object = new DocumentObject( + DocumentType::STORAGE_INVOICE, + [chunk_split('data:application/pdf;base64,'.base64_encode($transaction_invoice_pdf->output()))], + '', + ApprovalStatus::COMPLETED, + 'storage_invoice' + ); + + // $invouce_transaction_document = $invoice_transaction->documents()->where('document_type', DocumentType::STORAGE_INVOICE)->first(); + // if(!$invouce_transaction_document){ + /** @var Document $document */ + $document = $this->createsDocument->execute($invoice_transaction, $document_object); + + $this->createsFiles->execute($document, $document_object); + // $user = $packingList->owner->companyModule->employees()->first(); + // if(app()->environment(['production'])) { + // $user->notify(new InvoiceIssuedEmail($user, $packingList)); + // } + // } + } + +} diff --git a/app/Classes/Modules/Transactions/Processors/ReleaseGoodsToCustomerProcessor.php b/app/Classes/Modules/Transactions/Processors/ReleaseGoodsToCustomerProcessor.php new file mode 100644 index 00000000..766947c6 --- /dev/null +++ b/app/Classes/Modules/Transactions/Processors/ReleaseGoodsToCustomerProcessor.php @@ -0,0 +1,94 @@ +updatesTransactionStatus = $updatesTransactionStatus; + $this->updateDoFromVTPortalProcessor = $updateDoFromVTPortalProcessor; + $this->updateDoFromYDPortalProcessor = $updateDoFromYDPortalProcessor; + $this->createStorageInvoiceDocTransactionProcessor = $createStorageInvoiceDocTransactionProcessor; + } + + + /** + * @param $packingList + * @param $invoice + * @throws \App\Classes\Exceptions\MalformedRequestException + */ + public function execute($packingList, $invoice = null) + { + $result = false; + $totalInvoicesAmountPaid = 0.00; + $totalInvoicesAmount = 0.00; + $invoiceTransactions = $packingList->transactions()->where('status', [ApprovalStatus::APPROVED])->whereIn('type', [TransactionType::SHIPPING_INVOICE, TransactionType::STORAGE_INVOICE])->get(); + + //Part 1: Process each single invoice type and get the total of all invoices + foreach($invoiceTransactions as $invoiceTransaction){ + + $totalInvoiceAmountPaid = $invoiceTransaction->transactions->where('type', TransactionType::PAYMENT)->whereIn('status', [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED])->sum('amount'); + if ($invoice && $invoice->type == $invoiceTransaction->type) { + if(($invoice->amount - $totalInvoiceAmountPaid) < 0.01){ + $this->updatesTransactionStatus->execute($invoice, ApprovalStatus::COMPLETED); + + if($invoice->type == TransactionType::STORAGE_INVOICE){ + $this->createStorageInvoiceDocTransactionProcessor->execute($packingList); + } + } + } + + $totalInvoicesAmount = $totalInvoicesAmount + $invoiceTransaction->amount; + $totalInvoicesAmountPaid = $totalInvoicesAmountPaid + $totalInvoiceAmountPaid; + } + + Log::channel('storage_invoices')->info('Total invoice amount paid 1: '.$totalInvoicesAmount); //cief todo: to be removed + Log::channel('storage_invoices')->info('Total invoice amount paid 2: '.$totalInvoicesAmountPaid); //cief todo: to be removed + + //Part 2: Based on the collected info for all the total of all invoices + if (($totalInvoicesAmount - $totalInvoicesAmountPaid) < 0.01 && $totalInvoicesAmountPaid > 0.01) { + Log::channel('storage_invoices')->info('Total invoice amount paid 3: '.$totalInvoicesAmountPaid); //cief todo: to be removed + + $packingList->status = ApprovalStatus::APPROVED; + $packingList->save(); + + if (app()->environment('production')) { + $this->updateDoFromVTPortalProcessor->execute($packingList); + $this->updateDoFromYDPortalProcessor->execute($packingList); + } + + $result = true; + } + + return $result; + } +} diff --git a/app/Classes/Modules/Transactions/Services/UpdatesTransactionIsWaived.php b/app/Classes/Modules/Transactions/Services/UpdatesTransactionIsWaived.php new file mode 100644 index 00000000..9f9a6ae3 --- /dev/null +++ b/app/Classes/Modules/Transactions/Services/UpdatesTransactionIsWaived.php @@ -0,0 +1,22 @@ +is_waived = 1; + + return $this->handler($model); + } +} diff --git a/app/Classes/Modules/Transactions/Standards/Rules/CanRegenerateStorageInvoice.php b/app/Classes/Modules/Transactions/Standards/Rules/CanRegenerateStorageInvoice.php new file mode 100644 index 00000000..d7a7a9bf --- /dev/null +++ b/app/Classes/Modules/Transactions/Standards/Rules/CanRegenerateStorageInvoice.php @@ -0,0 +1,47 @@ +user(); + if($user){ + $roleToCheck = Auth()->user()->type; + if (in_array($roleToCheck, RoleTypes::ADMIN_ROLES)) { + return true; + } + } + + return false; + } + + /** + * @param $object + * @return bool + * @throws \App\Classes\Exceptions\RequestValidationException + */ + protected function validators($object): bool + { + return true; + } + + /** + * @param $object + * @return bool + */ + protected function criteria($object): bool + { + return true; + } + +} diff --git a/app/Classes/Modules/Transactions/Standards/Rules/CanWaiveTransaction.php b/app/Classes/Modules/Transactions/Standards/Rules/CanWaiveTransaction.php new file mode 100644 index 00000000..5a596acb --- /dev/null +++ b/app/Classes/Modules/Transactions/Standards/Rules/CanWaiveTransaction.php @@ -0,0 +1,58 @@ +waiveTransactionValidation = $waiveTransactionValidation; + } + + /** + * @return bool + */ + protected function authorized($object): bool + { + $user = Auth()->user(); + if($user){ + $roleToCheck = Auth()->user()->type; + if (in_array($roleToCheck, RoleTypes::ADMIN_ROLES)) { + return true; + } + } + + return false; + } + + /** + * @param WaiveTransactionObject $object + * @return bool + * @throws \App\Classes\Exceptions\RequestValidationException + */ + protected function validators($object): bool + { + return $this->waiveTransactionValidation->validate($object); + } + + /** + * @param $object + * @return bool + */ + protected function criteria($object): bool + { + return true; + } + +} diff --git a/app/Classes/Modules/Transactions/Standards/Validators/WaiveTransactionValidation.php b/app/Classes/Modules/Transactions/Standards/Validators/WaiveTransactionValidation.php new file mode 100644 index 00000000..b6de888b --- /dev/null +++ b/app/Classes/Modules/Transactions/Standards/Validators/WaiveTransactionValidation.php @@ -0,0 +1,46 @@ + $object->getId(), + 'billNo' => $object->getBillNo(), + 'type' => $object->getType(), + 'status' => $object->getStatus(), + ]; + } + + /** + * @return array + */ + protected function rules(): array { + return [ + 'id' => 'required', + 'type' => ['required', 'numeric', 'in:'.TransactionType::STORAGE_INVOICE], //Only storage invoice (type 16) can be waived + 'status' => ['required', 'numeric', 'in:'.ApprovalStatus::APPROVED], //Approve storage invoice only, paid invoice stricly forbidden + // 'billNo' => 'required', + ]; + } + + /** + * @return array + */ + protected function messages(): array { + return []; + } + +} diff --git a/app/Classes/Notifications/PermitsReminderEmail.php b/app/Classes/Notifications/PermitsReminderEmail.php new file mode 100644 index 00000000..5524c949 --- /dev/null +++ b/app/Classes/Notifications/PermitsReminderEmail.php @@ -0,0 +1,36 @@ +user = $user; + $this->reminders = $reminders; + } + + public function toMail() + { + return (new MailMessage) + ->subject('Permits Renew Remidner Email') + ->view('emails.reminder.permits_reminder', ['user' => $this->user, 'reminders' => $this->reminders]); + } + + +} \ No newline at end of file diff --git a/app/Console/Commands/FixGroupPaymentProblem.php b/app/Console/Commands/FixGroupPaymentProblem.php new file mode 100644 index 00000000..fee8fb35 --- /dev/null +++ b/app/Console/Commands/FixGroupPaymentProblem.php @@ -0,0 +1,95 @@ +fetchesGroup = $fetchesGroup; + $this->releaseGoodsToCustomerProcessor = $releaseGoodsToCustomerProcessor; + $this->fetchesOrder = $fetchesOrder; + $this->createStorageInvoiceDocTransactionProcessor = $createStorageInvoiceDocTransactionProcessor; + } + + + /** + * Execute the console command. + * + * @return int + */ + public function handle() + { + ini_set('memory_limit', '-1'); + + $this->info(Carbon::now() . ': Start data patch.'); + $start = new Carbon(); + + /* + $group = $this->fetchesGroup->execute(['id' => 325]); + $this->info('FixGroupPaymentProblem group: '.json_encode($group)); + if ($group) { + foreach ($group->groupTransactions as $groupTransaction) { + $invoice = $groupTransaction->transaction; + $this->info('FixGroupPaymentProblem group: '.json_encode($invoice)); + $pL = $invoice->owner; + $this->releaseGoodsToCustomerProcessor->execute($pL, $invoice); + } + } + */ + + $order = $this->fetchesOrder->execute(['reference' => '729251424']); + $packingLists = $order->destinationWarehousePackages; + + foreach ($packingLists as $packingList){ + $this->createStorageInvoiceDocTransactionProcessor->execute($packingList, true); + dd(json_encode($packingList)); + } + + + $end = new Carbon(); + $elapsedTime = $start->diff($end)->format('%H:%I:%S'); + + $this->info(Carbon::now() . ': Done data patch. ElapsedTime: ' . $elapsedTime . '.'); + } +} diff --git a/app/Console/Commands/OneTimeTransactionFixBillplzFailedCallback.php b/app/Console/Commands/OneTimeTransactionFixBillplzFailedCallback.php new file mode 100644 index 00000000..f015e41b --- /dev/null +++ b/app/Console/Commands/OneTimeTransactionFixBillplzFailedCallback.php @@ -0,0 +1,73 @@ +callbackBillplzProcessor = $callbackBillplzProcessor; + } + + /** + * Execute the console command. + * + * @return int + */ + public function handle() + { + ini_set('memory_limit', '-1'); + + $this->outputArray = []; + $start = new Carbon(); + + //This transaction, 15205 has approve payment but not its owner, shipping invoice + $transaction = Transaction::whereIn('id', [15205])->first(); + $this->info(Carbon::now() . ' : One time fix failled callback from billplz for transaction with id 15205 cron started.'); + + if($transaction && $transaction->id == 15205){ + + $status = ApprovalStatus::APPROVED; + $this->callbackBillplzProcessor->execute($transaction, $status); + } + + + $end = new Carbon(); + $elapsedTime = $start->diff($end)->format('%H:%I:%S'); + $this->info(Carbon::now() . ' : One time fix failled callback from billplz for transaction with id 15205 cron ended. ElapsedTime: ' . $elapsedTime); + } +} diff --git a/app/Console/Commands/SendPermitsReminderEmails.php b/app/Console/Commands/SendPermitsReminderEmails.php new file mode 100644 index 00000000..1126d7fb --- /dev/null +++ b/app/Console/Commands/SendPermitsReminderEmails.php @@ -0,0 +1,83 @@ +subDays(3)->startOfDay(); + $endRange = $currentDateTime->copy()->addDays(6)->endOfDay(); + + $reminders = PermitsReminder::whereDate('reminder_date', '>=', $startRange) + ->whereDate('reminder_date', '<=', $endRange) + ->orWhere('reminder_date', '<', now()) + ->pluck('model'); + + if ($reminders->isEmpty()) { + $this->info('No reminders expiring within the specified range.'); + return; + } + + $this->info($this->getTimeStamp() . 'Reminders: ' . $reminders->toJson()); + + $users = User::whereIn('email', $this->getEmailList())->get(); + + foreach ($users as $user) { + $this->info($this->getTimeStamp() . 'Reminder email sent to ' . $user->email); + if (app()->environment('production')) { + $user->notify(new PermitsReminderEmail($user, $reminders)); + } + } + } + + public function getTimeStamp() + { + return '[' . Carbon::now()->format('Y-m-d H:i:s') . '] - '; + } + + protected function getEmailList(): array + { + return [ + 'edmond.wuiming2021@gmail.com', + 'anithagurl96@gmail.com' + ]; + } +} diff --git a/app/Console/Kernel.php b/app/Console/Kernel.php index 66ebdcc4..93534e57 100644 --- a/app/Console/Kernel.php +++ b/app/Console/Kernel.php @@ -104,6 +104,12 @@ class Kernel extends ConsoleKernel ->dailyAt('0:01') ->withoutOverlapping() ->appendOutputTo(storage_path().'/logs/check_storage_invoices.log'); + + //cief todo: command version 2 + $schedule->command('permitsReminder:send') + ->dailyAt('09:30') + ->withoutOverlapping() + ->appendOutputTo(storage_path().'/logs/permits-reminder-send.log'); } } diff --git a/app/Http/Controllers/Companies/UpdateCompanyCreditTermStatusController.php b/app/Http/Controllers/Companies/UpdateCompanyCreditTermStatusController.php new file mode 100644 index 00000000..d41ca64a --- /dev/null +++ b/app/Http/Controllers/Companies/UpdateCompanyCreditTermStatusController.php @@ -0,0 +1,20 @@ +execute($request); + } + +} diff --git a/app/Http/Controllers/Imports/ImportPermitsReminderController.php b/app/Http/Controllers/Imports/ImportPermitsReminderController.php new file mode 100644 index 00000000..2f82b628 --- /dev/null +++ b/app/Http/Controllers/Imports/ImportPermitsReminderController.php @@ -0,0 +1,85 @@ +input('files'), '', ApprovalStatus::APPROVED, 'imports'); + $file = json_decode($object->getFiles()[0])->file_info->original->file; + $file = storage_path('app/documents/' . $file); + + $import = new GenericImport(); + Excel::import($import, $file); + $excelRows = $import->rows->toArray(); + $successRows = []; + $returnArray = []; // Initialize the return array + + foreach ($excelRows as $row) { + if (is_null($row['expiry_date']) && is_null($row['reminder_date'])) { + continue; + } + + $row['expiry_date'] = $this->changeExcelDate($row['expiry_date']); + $row['reminder_date'] = $this->changeExcelDate($row['reminder_date']); + + $validator = Validator::make($row, [ + 'model' => 'required|unique:permits_reminders,model', + 'expiry_date' => 'required|date|after_or_equal:today', + 'reminder_date' => 'required|date|after_or_equal:today', + ]); + + if ($validator->fails()) { + $row['status'] = 'failed'; + $row['message'] = $validator->errors()->all(); + + $returnArray[] = $row; + } else { + $row['created_at'] = Carbon::now(); + $row['updated_at'] = Carbon::now(); + $successRows[] = $row; + } + } + + if (!empty($successRows)) { + PermitsReminder::insert($successRows); // Insert only if there are successful rows + } + + $successCount = count($successRows); + + return response()->json([ + 'completedRows' => $successCount, + 'failedRows' => count($returnArray), + 'remark' => "Successful Imported {$successCount} data.", + 'data' => $returnArray + ]); + } + + public function changeExcelDate($date) + { + $formatedDate = DateTime::createFromFormat('d/m/Y', $date); + if ($formatedDate instanceof DateTime) { + return $formatedDate->format('Y-m-d'); + } + + $unixTime = (($date - 25569) * 86400); + + return (new DateTime("@$unixTime"))->format('Y-m-d'); + } +} diff --git a/app/Http/Controllers/PermitsReminder/CreatePermitsReminderController.php b/app/Http/Controllers/PermitsReminder/CreatePermitsReminderController.php new file mode 100644 index 00000000..0e093b04 --- /dev/null +++ b/app/Http/Controllers/PermitsReminder/CreatePermitsReminderController.php @@ -0,0 +1,59 @@ + 'required|unique:permits_reminders,model', + 'expiry_date' => 'required|date|after_or_equal:today', + 'reminder_date' => 'required|date|after_or_equal:today', + ]; + + // Perform validation + $validator = Validator::make($request->all(), $rules); + + if ($validator->fails()) { + $validationErrors = $validator->errors()->all(); + $validationError = implode("
", $validationErrors); + + // Return validation error response + return response()->json([ + 'title' => 'Create Permits Reminder Failed', + 'message' => $validationError, + "payload" => [] + ], 422); // 422 Unprocessable Entity status code for validation errors + } + + // If validation passes, create the record + $record = PermitsReminder::create([ + 'expiry_date' => Carbon::parse($request->input('expiry_date'))->format('Y-m-d'), + 'reminder_date' => Carbon::parse($request->input('reminder_date'))->format('Y-m-d'), + 'model' => $request->input('model'), + ]); + + $response = [ + "title" => "Create Permits Reminder Successful", + "message" => "You have successfully created a Permits Reminder", + "payload" => [ + "data" => $record + ] + ]; + + return response()->json($response); + } +} diff --git a/app/Http/Controllers/PermitsReminder/DeletePermitsReminderController.php b/app/Http/Controllers/PermitsReminder/DeletePermitsReminderController.php new file mode 100644 index 00000000..763f4fcb --- /dev/null +++ b/app/Http/Controllers/PermitsReminder/DeletePermitsReminderController.php @@ -0,0 +1,28 @@ +route('id')); + $record->delete(); + + $response = [ + "title" => "Delete Permits Reminder Successful", + "message" => "You have successfully deleted a Permits Reminder", + "payload" => [] + ]; + + return response()->json($response); + } +} diff --git a/app/Http/Controllers/PermitsReminder/ListPermitsReminderController.php b/app/Http/Controllers/PermitsReminder/ListPermitsReminderController.php new file mode 100644 index 00000000..111381bc --- /dev/null +++ b/app/Http/Controllers/PermitsReminder/ListPermitsReminderController.php @@ -0,0 +1,68 @@ +query('page', 1); // Get the current page from the request + + // Paginate the PermitsReminder model + $paginator = PermitsReminder::orderBy('reminder_date')->paginate($perPage, ['*'], 'page', $page); + + // Get current date and time + $currentDateTime = now(); + + // Define date range + $startRange = $currentDateTime->subDays(3)->startOfDay(); + $endRange = $currentDateTime->copy()->addDays(6)->endOfDay(); + + // Process paginated items + $data = $paginator->items(); + foreach ($data as &$item) { + // Check if the reminder_date is within the date range or after the current date + $reminderDate = Carbon::parse($item->reminder_date); + $item->show_remind = $reminderDate->between($startRange, $endRange) || $reminderDate->isBefore($currentDateTime); + } + + // Create pagination links + $links = [ + "first" => $paginator->url(1), + "last" => $paginator->url($paginator->lastPage()), + "prev" => $paginator->previousPageUrl(), + "next" => $paginator->nextPageUrl(), + ]; + + // Prepare response + $response = [ + "title" => "List Permits Reminder", + "message" => "You have successfully retrieved a list of Permits Reminder", + "payload" => [ + 'data' => $data, + "links" => $links, + "meta" => [ + "current_page" => $paginator->currentPage(), + "from" => $paginator->firstItem(), + "last_page" => $paginator->lastPage(), + "path" => $request->path(), + "per_page" => $paginator->perPage(), + "to" => $paginator->lastItem(), + "total" => $paginator->total(), + ] + ] + ]; + + return response()->json($response); + } +} diff --git a/app/Http/Controllers/PermitsReminder/UpdatePermitsReminderController.php b/app/Http/Controllers/PermitsReminder/UpdatePermitsReminderController.php new file mode 100644 index 00000000..14bcec7b --- /dev/null +++ b/app/Http/Controllers/PermitsReminder/UpdatePermitsReminderController.php @@ -0,0 +1,51 @@ + 'required|unique:permits_reminders,model,' . $request->route('id'), + 'expiry_date' => 'required|date|after_or_equal:today', + 'reminder_date' => 'required|date|after_or_equal:today', + ]; + + $validator = Validator::make($request->all(), $rules); + + if ($validator->fails()) { + $validationErrors = $validator->errors()->all(); + $validationError = implode("
", $validationErrors); + + return response()->json([ + 'title' => 'Update Permits Reminder Failed', + 'message' => $validationError, + "payload" => [] + ], 422); + } + + $record = PermitsReminder::findOrFail($request->route('id')); + + $record->model = $request->input('model'); + $record->expiry_date = Carbon::parse($request->input('expiry_date'))->format('Y-m-d'); + $record->reminder_date = Carbon::parse($request->input('reminder_date'))->format('Y-m-d'); + $record->save(); + + return response()->json([ + 'title' => 'Permits Reminder Updated', + 'message' => 'The permits reminder has been successfully updated.', + "payload" => $record + ]); + } +} diff --git a/app/Http/Controllers/Transactions/RegenerateSingleStorageInvoiceTransactionController.php b/app/Http/Controllers/Transactions/RegenerateSingleStorageInvoiceTransactionController.php new file mode 100644 index 00000000..0edebadd --- /dev/null +++ b/app/Http/Controllers/Transactions/RegenerateSingleStorageInvoiceTransactionController.php @@ -0,0 +1,21 @@ +execute($request); + } +} diff --git a/app/Http/Controllers/Transactions/WaiveTransactionController.php b/app/Http/Controllers/Transactions/WaiveTransactionController.php new file mode 100644 index 00000000..cb36a973 --- /dev/null +++ b/app/Http/Controllers/Transactions/WaiveTransactionController.php @@ -0,0 +1,21 @@ +execute($request); + } +} diff --git a/app/Http/Kernel.php b/app/Http/Kernel.php index d458f7b1..fcd38fae 100644 --- a/app/Http/Kernel.php +++ b/app/Http/Kernel.php @@ -73,5 +73,6 @@ class Kernel extends HttpKernel 'storage.invoice.check.byorder' => \App\Http\Middleware\CheckForStorageInvoiceByOrderId::class, 'storage.invoice.check.bytransactions' => \App\Http\Middleware\CheckForStorageInvoiceByTransactions::class, 'storage.invoice.check.bygroup' => \App\Http\Middleware\CheckForStorageInvoiceByGroup::class, + 'storage.invoice.check.bypackinglists' => \App\Http\Middleware\CheckForStorageInvoiceByPackingLists::class, ]; } diff --git a/app/Http/Middleware/CheckForStorageInvoiceByOrderId.php b/app/Http/Middleware/CheckForStorageInvoiceByOrderId.php index 5765a284..c576da51 100644 --- a/app/Http/Middleware/CheckForStorageInvoiceByOrderId.php +++ b/app/Http/Middleware/CheckForStorageInvoiceByOrderId.php @@ -29,7 +29,12 @@ class CheckForStorageInvoiceByOrderId public function handle(Request $request, Closure $next) { $orderId = $request->route('id'); - $storages = $this->storageInvoiceTransactionProcessor->execute($orderId); + $storages = []; + try{ + $storages = $this->storageInvoiceTransactionProcessor->execute($orderId); + } catch (\Exception $exception) { + $storages = []; + } $request->merge(['storages' => $storages]); return $next($request); } diff --git a/app/Http/Middleware/CheckForStorageInvoiceByPackingLists.php b/app/Http/Middleware/CheckForStorageInvoiceByPackingLists.php new file mode 100644 index 00000000..a393e3b5 --- /dev/null +++ b/app/Http/Middleware/CheckForStorageInvoiceByPackingLists.php @@ -0,0 +1,69 @@ +storageInvoiceTransactionProcessor = $storageInvoiceTransactionProcessor; + $this->listsPackingLists = $listsPackingLists; + } + + + /** + * Handle an incoming request. + * + * @param Request $request + * @param \Closure(\Illuminate\Http\Request): (\Illuminate\Http\Response|\Illuminate\Http\RedirectResponse) $next + * @return \Illuminate\Http\Response|\Illuminate\Http\RedirectResponse + */ + public function handle(Request $request, Closure $next) + { + $results = []; + $packinglists = null; + + $filters = json_decode($request->input('filters'), true); + // $filters['type_in'] = [TransactionType::SHIPPING_INVOICE]; + // if(json_encode($filters['order_by']) == '{"column":"id","DESC":true}'){ + // $filters['order_by_id_desc'] = true; + // } + + if(isset($filters['check_for_storage_invoice'])){ + unset($filters['order_by']); + $packinglists = $this->listsPackingLists->execute($filters); + foreach($packinglists as $packingList){ + if($packingList){ + $order = $packingList->owner()->first(); + if($order instanceof Order){ + $storages = $this->storageInvoiceTransactionProcessor->executeOrder($order); + if($storages){ + $results = array_merge($results, $storages); + } + } + } + } + } + + $request->merge(['storages' => $results]); + + return $next($request); + } +} diff --git a/app/Http/Resources/CompanyResource.php b/app/Http/Resources/CompanyResource.php index 4590f46b..d969ac0d 100644 --- a/app/Http/Resources/CompanyResource.php +++ b/app/Http/Resources/CompanyResource.php @@ -21,7 +21,7 @@ class CompanyResource extends JsonResource { $companyModule = $this->companyModules()->first(); $companyTypeArray = CompanyType::COMPANY_TYPE_ID; - + return [ 'id' => $this->id, 'hash_id' => Crypt::encryptString($this->id), @@ -33,6 +33,7 @@ class CompanyResource extends JsonResource 'business_type' => (int) $this->business_type, 'status' => (int) $this->status, 'segments' => SegmentResource::collection($companyModule->connections()->first()->segments), + 'is_credit_term' => $companyModule->connections()->first()->is_credit_term, 'contact' => new ContactResource ($this->when($this->has('contacts'), $this->contacts->first())), 'employee' => new UserResource($companyModule->employees()->first()), 'company_module' => new CompanyModuleResource($companyModule), diff --git a/app/Http/Resources/ContainerResource.php b/app/Http/Resources/ContainerResource.php index 49a33232..dd45412c 100644 --- a/app/Http/Resources/ContainerResource.php +++ b/app/Http/Resources/ContainerResource.php @@ -23,17 +23,25 @@ class ContainerResource extends JsonResource 'container_specification' => ContainerTypes::CONTAINER_SPECIFICATION[$this->container_type], 'container_number' => $this->container_number, 'seal_reference' => $this->seal_reference, - 'loading_date' => $this->loading_date ? $this->loading_date->format('d-m-Y') : $this->loading_date, + 'loading_date' => optional($this->loading_date)->format('d-m-Y'), 'transport' => new TransportResource($this->transports()->first()), 'packages_count' => $this->packages()->where('packages.type', '!=', 2)->sum('quantity'), 'total_cbm' => $this->packages()->sum(DB::raw('(width/100) * (height/100) * (length/100) * quantity')), 'remarks' => RemarkResource::collection($this->remarks), 'status' => $this->status, - 'packing_lists' => $this->whenLoaded('packingLists', PackingListResource::collection($this->whenLoaded('packingLists', function(){ - return $this->packingLists()->get()->sortBy(function ($packingList) { - return $packingList->owner->company_module_id; - }); - }))) + 'packing_lists' => $this->shouldIncludePackingListData($request) ? $this->getSortedPackingLists() : null, ]; } + + protected function shouldIncludePackingListData($request) + { + return (isset($request->all()['with_packing_list_data']) && ($request->all()['with_packing_list_data'] == false)) ? false : true; + } + + protected function getSortedPackingLists() + { + return $this->whenLoaded('packingLists', PackingListResource::collection( + $this->packingLists()->get()->sortBy(fn ($packingList) => $packingList->owner->company_module_id) + )); + } } diff --git a/app/Http/Resources/GroupForOrderV2Resource.php b/app/Http/Resources/GroupForOrderV2Resource.php index d5cf69e8..4c4c8c33 100644 --- a/app/Http/Resources/GroupForOrderV2Resource.php +++ b/app/Http/Resources/GroupForOrderV2Resource.php @@ -4,6 +4,7 @@ namespace App\Http\Resources; use App\Classes\ValueObjects\Constants\ApprovalStatus; use App\Classes\ValueObjects\Constants\PaymentMethodType; +use App\Models\Transaction; use Carbon\Carbon; use Illuminate\Http\Resources\Json\JsonResource; @@ -17,6 +18,8 @@ class GroupForOrderV2Resource extends JsonResource */ public function toArray($request) { + $payment_transaction = Transaction::where('payment_reference', $this->reference)->first(); + return [ 'id' => $this->id, 'original_amount' => (float) $this->original_amount, @@ -33,7 +36,12 @@ class GroupForOrderV2Resource extends JsonResource 'payment_method' => (int)$this->payment_method, 'payment_method_name' => ucwords(PaymentMethodType::PAYMENT_METHODS_ID[$this->payment_method]), 'payment_reference' => $this->reference, - 'transactions_ids' => GroupTransactionsForOrderV2Resource::collection($this->groupTransactions) + 'transactions_ids' => GroupTransactionsForOrderV2Resource::collection($this->groupTransactions), + 'payment_transaction' => $payment_transaction ? [ + 'id' => $payment_transaction->id, + 'status' => $payment_transaction->status, + 'status_name' => ApprovalStatus::APPROVAL_STATUS_ID[$payment_transaction->status] + ] : [] ]; } } diff --git a/app/Http/Resources/ListPackingListDetailsJobResource.php b/app/Http/Resources/ListPackingListDetailsJobResource.php new file mode 100644 index 00000000..48bed481 --- /dev/null +++ b/app/Http/Resources/ListPackingListDetailsJobResource.php @@ -0,0 +1,47 @@ +userInfo ? $this->userInfo->type : Auth()->user()->type, [RoleTypes::SHADOW_ADMIN, RoleTypes::SUPER_ADMIN]); + $packages = !$this->packingLists()->exists() || $exceptionUsers ? $this->packages : $this->packingLists->first()->packages; + + return [ + 'id' => $this->id, + 'claimant_id' => $this->claimant_id, + 'reference' => $this->reference, + 'status' => $this->status, + 'transport' => new TransportResource($this->transports()->first()), + 'type' => $this->type, + 'receive_packing_list' => $this->when($this->type === PackingListType::SHIPPING_PACKING_LIST, new PackingListV2Resource(PackingList::where('reference', $this->reference)->where('type', PackingListType::WAREHOUSE_RECEIVE_LIST)->first(), $this->userInfo)), + // 'packages' => PackageResource::collection($packages), + // $this->mergeWhen($this->owner instanceof Order, [ + // 'order' => New OrderResource($this->owner) + // ]), + 'container' => new ContainerResource($this->containers->first()), + 'packages' => PackageWithoutOrderResource::collection($packages), + $this->mergeWhen($this->owner instanceof Order, [ 'order' => New OrderResource($this->owner) ]), + 'shipping_transaction' => new TransactionResource($this->transactions()->where('type', TransactionType::SHIPPING_INVOICE)->whereNotIn('status', [ApprovalStatus::SUSPENDED, ApprovalStatus::EXPIRED])->first()), + 'suspended_invoice' => new TransactionResource($this->transactions()->where('type', TransactionType::SHIPPING_INVOICE)->whereIn('status', [ApprovalStatus::SUSPENDED])->first()), + // 'suspended_invoices' => TransactionResource::collection($this->transactions()->where('type', TransactionType::SHIPPING_INVOICE)->whereIn('status', [ApprovalStatus::SUSPENDED])->get()), + ]; + } +} diff --git a/app/Http/Resources/ListPackingListJobResource.php b/app/Http/Resources/ListPackingListJobResource.php index d260f4b6..db094db1 100644 --- a/app/Http/Resources/ListPackingListJobResource.php +++ b/app/Http/Resources/ListPackingListJobResource.php @@ -31,11 +31,14 @@ class ListPackingListJobResource extends JsonResource 'status' => $this->status, 'transport' => new TransportResource($this->transports()->first()), 'type' => $this->type, - 'receive_packing_list' => $this->when($this->type === PackingListType::SHIPPING_PACKING_LIST, new PackingListV2Resource(PackingList::where('reference', $this->reference)->where('type', PackingListType::WAREHOUSE_RECEIVE_LIST)->first(), $this->userInfo)), - 'packages' => PackageResource::collection($packages), - $this->mergeWhen($this->owner instanceof Order, [ - 'order' => New OrderResource($this->owner) - ]), + // 'receive_packing_list' => $this->when($this->type === PackingListType::SHIPPING_PACKING_LIST, new PackingListV2Resource(PackingList::where('reference', $this->reference)->where('type', PackingListType::WAREHOUSE_RECEIVE_LIST)->first(), $this->userInfo)), + // 'packages' => PackageResource::collection($packages), + // $this->mergeWhen($this->owner instanceof Order, [ + // 'order' => New OrderResource($this->owner) + // ]), + 'container' => new ContainerResource($this->containers->first()), + 'packages' => PackageWithoutOrderResource::collection($packages), + $this->mergeWhen($this->owner instanceof Order, [ 'order' => New OrderResource($this->owner) ]), 'shipping_transaction' => new TransactionResource($this->transactions()->where('type', TransactionType::SHIPPING_INVOICE)->whereNotIn('status', [ApprovalStatus::SUSPENDED, ApprovalStatus::EXPIRED])->first()), 'suspended_invoice' => new TransactionResource($this->transactions()->where('type', TransactionType::SHIPPING_INVOICE)->whereIn('status', [ApprovalStatus::SUSPENDED])->first()), // 'suspended_invoices' => TransactionResource::collection($this->transactions()->where('type', TransactionType::SHIPPING_INVOICE)->whereIn('status', [ApprovalStatus::SUSPENDED])->get()), diff --git a/app/Http/Resources/ListPackingListJobWithStorageResource.php b/app/Http/Resources/ListPackingListJobWithStorageResource.php new file mode 100644 index 00000000..2cb01699 --- /dev/null +++ b/app/Http/Resources/ListPackingListJobWithStorageResource.php @@ -0,0 +1,57 @@ +userInfo ? $this->userInfo->type : Auth()->user()->type, [RoleTypes::SHADOW_ADMIN, RoleTypes::SUPER_ADMIN]); + $packages = !$this->packingLists()->exists() || $exceptionUsers ? $this->packages : $this->packingLists->first()->packages; + $shippingTransaction = $this->transactions()->where('type', TransactionType::SHIPPING_INVOICE)->whereNotIn('status', [ApprovalStatus::SUSPENDED, ApprovalStatus::EXPIRED])->first(); + $transactions = $this->transactions()->whereNotIn('transactions.status', [0, 1])->whereIn('transactions.type', [TransactionType::SHIPPING_INVOICE, TransactionType::STORAGE_INVOICE])->get(); + $storages = []; + + if($this->storages){ + $transactionId = $shippingTransaction->id; + $filteredStorages = array_filter($this->storages, function ($storage) use ($transactionId) { + return isset($storage['parentInvoiceId']) && $storage['parentInvoiceId'] == $transactionId; + }); + $storages = $filteredStorages; + } + + return [ + 'id' => $this->id, + 'claimant_id' => $this->claimant_id, + 'reference' => $this->reference, + 'status' => $this->status, + 'transport' => new TransportResource($this->transports()->first()), + 'type' => $this->type, + // 'receive_packing_list' => $this->when($this->type === PackingListType::SHIPPING_PACKING_LIST, new PackingListV2Resource(PackingList::where('reference', $this->reference)->where('type', PackingListType::WAREHOUSE_RECEIVE_LIST)->first(), $this->userInfo)), + // 'packages' => PackageResource::collection($packages), + // $this->mergeWhen($this->owner instanceof Order, [ + // 'order' => New OrderResource($this->owner) + // ]), + 'container' => new ContainerResource($this->containers->first()), + 'packages' => PackageWithoutOrderResource::collection($packages), + $this->mergeWhen($this->owner instanceof Order, [ 'order' => New OrderResource($this->owner) ]), + 'shipping_transaction' => count($storages) == 0 ? new TransactionWithStorageResource($shippingTransaction): null, + 'storages' => $storages, + 'invoices' => TransactionWithStorageResource::collection($transactions), + 'suspended_invoice' => new TransactionResource($this->transactions()->where('type', TransactionType::SHIPPING_INVOICE)->whereIn('status', [ApprovalStatus::SUSPENDED])->first()), + // 'suspended_invoices' => TransactionResource::collection($this->transactions()->where('type', TransactionType::SHIPPING_INVOICE)->whereIn('status', [ApprovalStatus::SUSPENDED])->get()), + ]; + } +} diff --git a/app/Http/Resources/MappableTransactionResource.php b/app/Http/Resources/MappableTransactionResource.php index 2b1486da..447e6150 100644 --- a/app/Http/Resources/MappableTransactionResource.php +++ b/app/Http/Resources/MappableTransactionResource.php @@ -37,6 +37,7 @@ class MappableTransactionResource extends JsonResource 'owner_type' => Transaction::class, 'owner_id'=> $this->id, 'owner_reference'=> $reference, + 'created_at'=> $this->created_at, // invoice date ]; } } diff --git a/app/Http/Resources/MappableTransactionWithDetailsResource.php b/app/Http/Resources/MappableTransactionWithDetailsResource.php index 8622d85b..bf1fcf1d 100644 --- a/app/Http/Resources/MappableTransactionWithDetailsResource.php +++ b/app/Http/Resources/MappableTransactionWithDetailsResource.php @@ -27,16 +27,19 @@ class MappableTransactionWithDetailsResource extends JsonResource 'order_reference' => null, 'bill_no' => null, 'marking' => null, + 'created_at' => null ]; if ($this->type === TransactionType::PAYMENT) { $order = $this->owner->owner->owner; $data['order_reference'] = $order->reference; $data['debtor_code'] = $order->companyModule->company->debtor; + $data['created_at'] = $this->owner->created_at; // invoice date } elseif (in_array($this->type, [TransactionType::GROUP_PAYMENT, TransactionType::TOP_UP])) { $connection = $this->owner->owner->inviters()->withPivot('invitee_reference')->first(); $data['marking'] = $connection ? $connection->pivot->invitee_reference : ''; $data['bill_no'] = $this->bill_no; + $data['created_at'] = $this->created_at; } else { $payments = $this->transactions() ->payments()->where('status', ApprovalStatus::APPROVED) @@ -54,6 +57,7 @@ class MappableTransactionWithDetailsResource extends JsonResource 'type' => $payment->type, 'marking' => null, 'amount' => $payment->amount, + 'created_at' => $this->created_at ]; })->toArray(); } else { @@ -61,6 +65,7 @@ class MappableTransactionWithDetailsResource extends JsonResource $data['amount'] = 'Transaction Type not allowed'; $data['transaction_type'] = $this->type; $data['payment_transactions'] = null; + $data['created_at'] = null; } } diff --git a/app/Http/Resources/OrderV2Resource.php b/app/Http/Resources/OrderV2Resource.php index 8e28a656..8b83d14f 100644 --- a/app/Http/Resources/OrderV2Resource.php +++ b/app/Http/Resources/OrderV2Resource.php @@ -31,7 +31,7 @@ class OrderV2Resource extends JsonResource 'address' => new AddressResource($this->addresses()->where('status', '=', ApprovalStatus::APPROVED)->first()), 'address_change_request' => new AddressResource($this->addressesPendingVerification()->first()), 'invoices' => $this->whenLoaded('packingLists', function() { - return TransactionResource::collection($this->transactions()->whereNotIn('transactions.status', [0, 1])->whereIn('transactions.type', [TransactionType::SHIPPING_INVOICE, TransactionType::STORAGE_INVOICE])->get()); + return TransactionWithStorageResource::collection($this->transactions()->whereNotIn('transactions.status', [0, 1])->whereIn('transactions.type', [TransactionType::SHIPPING_INVOICE, TransactionType::STORAGE_INVOICE])->get()); }), 'storages' => $this->storages ? $this->storages : null, //from middleware 'remarks' => RemarkResource::collection($this->remarks), diff --git a/app/Http/Resources/PackageWithoutOrderResource.php b/app/Http/Resources/PackageWithoutOrderResource.php new file mode 100644 index 00000000..fea5500b --- /dev/null +++ b/app/Http/Resources/PackageWithoutOrderResource.php @@ -0,0 +1,38 @@ + $this->id, + 'type' => $this->type, + 'description' => $this->description, + 'width' => floatval($this->width), + 'height' => floatval($this->height), + 'length' => floatval($this->length), + 'weight' => $this->weight, + 'quantity' => $this->quantity, + 'cbm' => (($this->width / 100) * ($this->height / 100) * ($this->length / 100)) * $this->quantity, + 'reference' => $this->packingList->reference, + 'status' => $this->status, + // $this->mergeWhen($originalPackingList->owner instanceof Order, [ + // 'order' => New OrderResource($originalPackingList->owner) + // ]), + // 'container' => new ContainerResource($originalPackingList->containers()->first()), + // 'transport' => new TransportResource($originalPackingList->transports()->first()) + ]; + } +} diff --git a/app/Http/Resources/PackingListWithStorageResource.php b/app/Http/Resources/PackingListWithStorageResource.php new file mode 100644 index 00000000..386af053 --- /dev/null +++ b/app/Http/Resources/PackingListWithStorageResource.php @@ -0,0 +1,56 @@ +user()->type, [RoleTypes::SHADOW_ADMIN, RoleTypes::SUPER_ADMIN]); + $packages = !$this->packingLists()->exists() || $exceptionUsers ? $this->packages : $this->packingLists->first()->packages; + $shippingTransaction = $this->transactions()->where('type', TransactionType::SHIPPING_INVOICE)->whereNotIn('status', [ApprovalStatus::SUSPENDED, ApprovalStatus::EXPIRED])->first(); + $transactions = $this->transactions()->whereNotIn('transactions.status', [0, 1])->whereIn('transactions.type', [TransactionType::SHIPPING_INVOICE, TransactionType::STORAGE_INVOICE])->get(); + $storages = []; + + if($this->storages){ + $transactionId = $shippingTransaction->id; + $filteredStorages = array_filter($this->storages, function ($storage) use ($transactionId) { + return isset($storage['parentInvoiceId']) && $storage['parentInvoiceId'] == $transactionId; + }); + $storages = $filteredStorages; + } + + return [ + 'id' => $this->id, + 'claimant_id' => $this->claimant_id, + 'reference' => $this->reference, + 'status' => $this->status, + 'transport' => new TransportResource($this->transports()->first()), + 'type' => $this->type, + 'receive_packing_list' => $this->when($this->type === PackingListType::SHIPPING_PACKING_LIST, new PackingListResource(PackingList::where('reference', $this->reference)->where('type', PackingListType::WAREHOUSE_RECEIVE_LIST)->first())), + 'packages' => PackageResource::collection($packages), + $this->mergeWhen($this->owner instanceof Order, [ + 'order' => New OrderResource($this->owner) + ]), + 'shipping_transaction' => count($storages) == 0 ? new TransactionWithStorageResource($shippingTransaction): null, + 'storages' => $storages, + 'invoices' => TransactionWithStorageResource::collection($transactions), + 'suspended_invoice' => new TransactionResource($this->transactions()->where('type', TransactionType::SHIPPING_INVOICE)->whereIn('status', [ApprovalStatus::SUSPENDED])->first()), + ]; + } +} diff --git a/app/Http/Resources/TransactionResource.php b/app/Http/Resources/TransactionResource.php index 60b36104..40984608 100644 --- a/app/Http/Resources/TransactionResource.php +++ b/app/Http/Resources/TransactionResource.php @@ -3,14 +3,15 @@ namespace App\Http\Resources; use App\Classes\ValueObjects\Constants\ApprovalStatus; +use App\Classes\ValueObjects\Constants\DocumentType; use App\Classes\ValueObjects\Constants\TransactionType; use App\Models\Group; +use App\Models\Order; use App\Models\Transaction; use App\Models\Wallet; use Carbon\Carbon; use Illuminate\Http\Resources\Json\JsonResource; - class TransactionResource extends JsonResource { /** @@ -23,8 +24,6 @@ class TransactionResource extends JsonResource { $order = null; $groupTransactions = null; - $group_payment_attempts = null; - $group_payment_expired = null; if ($this->owner instanceof Transaction) { if ($this->owner) { @@ -36,12 +35,6 @@ class TransactionResource extends JsonResource if ($this->owner) { $order = new OrderResource($this->owner->owner); } - - if($this->groups){ - $group_payment_attempts = GroupForOrderV2Resource::collection($this->groups->whereNotIn('status', [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED])); - $group_payment_expired = GroupForOrderV2Resource::collection($this->groupsWithTrashed->whereIn('status', [ApprovalStatus::EXPIRED])); - } - } else { $group = Group::where('reference', $this->payment_reference)->first(); if ($group) { @@ -55,9 +48,7 @@ class TransactionResource extends JsonResource 'owner_type' => $this->owner_type, 'order' => $order, 'group_transactions' => $groupTransactions, - 'group_reference' => $groupTransactions ? ($group ? $group->reference : null ) : null, - 'groups_payment_attempts' => $group_payment_attempts, - 'groups_payment_expired' => $group_payment_expired, + 'group_reference' => $groupTransactions ? ($group ? $group->reference : null ) : null, 'documents' => $groupTransactions ? DocumentResource::collection($this->documents->where('status', ApprovalStatus::PENDING_VERIFICATION)) : DocumentResource::collection($this->documents), 'type' => (int) $this->type, 'bill_no' => $this->bill_no, @@ -80,11 +71,6 @@ class TransactionResource extends JsonResource ->payments()->where('status', ApprovalStatus::PENDING_SUBMISSION) ->get() ), - 'payments_expired' => TransactionResource::collection( - $this->transactions() - ->payments()->where('status', ApprovalStatus::EXPIRED) - ->get() - ), 'payment_history' => TransactionResource::collection( $this->transactions() ->payments() @@ -92,7 +78,6 @@ class TransactionResource extends JsonResource ->get() ), 'remarks' => RemarkResource::collection($this->remarks), - 'storages' => $this->storages ? $this->storages : null, //from middleware 'expires_on' => Carbon::parse($this->expires_on)->format('d-m-Y h:s:i'), 'updated_at' => Carbon::parse($this->updated_at)->format('d-m-Y'), 'created_at' => Carbon::parse($this->created_at)->format('d-m-Y') diff --git a/app/Http/Resources/TransactionWithStorageResource.php b/app/Http/Resources/TransactionWithStorageResource.php new file mode 100644 index 00000000..d072913a --- /dev/null +++ b/app/Http/Resources/TransactionWithStorageResource.php @@ -0,0 +1,129 @@ +owner instanceof Transaction) { + if ($this->owner) { + if ($this->owner->owner) { + $order = new OrderResource($this->owner->owner->owner); + } + } + } else if (!($this->owner instanceof Transaction) && !($this->owner instanceof Wallet)) { + if ($this->owner) { + $order = new OrderResource($this->owner->owner); + } + + if($this->groups){ + $group_payment_attempts = GroupForOrderV2Resource::collection($this->groups->whereNotIn('status', [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED])); + $group_payment_expired = GroupForOrderV2Resource::collection($this->groupsWithTrashed->whereIn('status', [ApprovalStatus::EXPIRED])); + $group_payment_history = GroupForOrderV2Resource::collection($this->groups->whereIn('status', [ApprovalStatus::PENDING_VERIFICATION, ApprovalStatus::REJECTED])); + } + + } else { + $group = Group::where('reference', $this->payment_reference)->first(); + if ($group) { + $groupTransactions = GroupTransactionResource::collection($group->groupTransactions); + } + + } + + + $ts = $this->groups->whereIn('status', [ApprovalStatus::PENDING_VERIFICATION])->last(); + if ($ts) { + $paymentTransaction = Transaction::where('payment_reference', $ts->reference)->whereIn('status', [ApprovalStatus::PENDING_SUBMISSION])->first(); + if($paymentTransaction){ + $groupTotalAmount = (double) $this->amount; + + foreach ($group_payment_history as $key => $value) { + if ($value->id === $ts->id && $value->reference === $ts->reference) { + unset($group_payment_history[$key]); + } + } + + foreach ($group_payment_attempts as $key => $value) { + if ($value->id === $ts->id && $value->reference == $ts->reference) { + $groupPaymentAttemptsFiltered[$key] = $value; + } + } + } + } + + + return [ + 'id' => $this->id, + 'owner_type' => $this->owner_type, + 'order' => $order, + 'group_transactions' => $groupTransactions, + 'group_reference' => $groupTransactions ? ($group ? $group->reference : null ) : null, + 'groups_payment_attempts' => $groupPaymentAttemptsFiltered, + 'groups_payment_expired' => $group_payment_expired, + 'groups_payment_history' => $group_payment_history, + 'documents' => $groupTransactions ? DocumentResource::collection($this->documents->where('status', ApprovalStatus::PENDING_VERIFICATION)) : DocumentResource::collection($this->documents), + 'type' => (int) $this->type, + 'bill_no' => $this->bill_no, + 'amount' => (double) $this->amount, + 'payment_method' => (int) $this->payment_method, + 'payment_reference' => $this->payment_reference, + 'outstanding' => (double) $this->amount - ($this->transactions()->where('type', TransactionType::PAYMENT)->whereIn('status', [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED])->sum('amount')), + 'floating' => $group_payment_attempts ? $groupTotalAmount : (double) $this->transactions()->where('type', TransactionType::PAYMENT)->whereIn('status', [ApprovalStatus::PENDING_SUBMISSION, ApprovalStatus::PENDING_VERIFICATION])->sum('amount'), + 'service_charge' => (double) $this->service_charge, + 'tax' => (double) $this->tax, + 'original_amount' => (double) $this->original_amount, + 'currency' => new CurrencyResource($this->currency), + 'original_currency' => new CurrencyResource($this->original_currency), + 'currency_rate' => (double) $this->currency_rate, + 'status' => (int) $this->status, + 'details' => TransactionDetailResource::collection($this->transactionDetails), + 'transactions' => TransactionResource::collection($this->transactions), + 'payment_attempts' => TransactionResource::collection( + $this->transactions() + ->payments()->where('status', ApprovalStatus::PENDING_SUBMISSION) + ->get() + ), + 'payments_expired' => TransactionResource::collection( + $this->transactions() + ->payments()->where('status', ApprovalStatus::EXPIRED) + ->get() + ), + 'payment_history' => TransactionResource::collection( + $this->transactions() + ->payments() + ->whereIn('status', [ApprovalStatus::APPROVED, ApprovalStatus::PENDING_VERIFICATION, ApprovalStatus::COMPLETED, ApprovalStatus::REJECTED]) + ->get() + ), + 'remarks' => RemarkResource::collection($this->remarks), + 'storages' => $this->storages ? $this->storages : null, //from middleware + 'is_waived' => (int) $this->is_waived, + 'expires_on' => Carbon::parse($this->expires_on)->format('d-m-Y h:s:i'), + 'updated_at' => Carbon::parse($this->updated_at)->format('d-m-Y'), + 'created_at' => Carbon::parse($this->created_at)->format('d-m-Y') + ]; + } +} diff --git a/app/Models/PermitsReminder.php b/app/Models/PermitsReminder.php new file mode 100644 index 00000000..1f9762a9 --- /dev/null +++ b/app/Models/PermitsReminder.php @@ -0,0 +1,33 @@ +attributes['expiry_date'] === null ? NULL : Carbon::parse($this->attributes['expiry_date'])->format('d-m-Y'); + } + + public function getReminderDateAttribute($value) + { + return $this->attributes['reminder_date'] === null ? NULL : Carbon::parse($this->attributes['reminder_date'])->format('d-m-Y'); + } + + public function getCreatedAtAttribute($value) + { + return $this->attributes['created_at'] === null ? NULL : Carbon::parse($this->attributes['created_at'])->format('d-m-Y'); + } +} diff --git a/config/logging.php b/config/logging.php index 03031050..5edd17d9 100644 --- a/config/logging.php +++ b/config/logging.php @@ -112,6 +112,18 @@ return [ 'path' => storage_path('logs/paymentUnknownOrderLog.log'), 'level' => 'info', ], + + 'vue_polling' => [ + 'driver' => 'single', + 'path' => storage_path('logs/laravel_vue_plling.log'), + 'level' => 'info', + ], + + 'perfex_crm' => [ + 'driver' => 'single', + 'path' => storage_path('logs/laravel_perfex_crm.log'), + 'level' => 'info', + ], ], ]; diff --git a/config/queue.php b/config/queue.php index 0f221cb6..d86a8f5b 100644 --- a/config/queue.php +++ b/config/queue.php @@ -34,6 +34,14 @@ return [ 'driver' => 'sync', ], + 'high_priority' => [ + 'driver' => 'database', + 'table' => 'jobs', + 'queue' => 'high_priority', + 'retry_after' => 3600, + 'after_commit' => false, + ], + 'database' => [ 'driver' => 'database', 'table' => 'jobs', diff --git a/database/migrations/2024_01_14_230705_create_permits_reminders_table.php b/database/migrations/2024_01_14_230705_create_permits_reminders_table.php new file mode 100644 index 00000000..4c2fa1df --- /dev/null +++ b/database/migrations/2024_01_14_230705_create_permits_reminders_table.php @@ -0,0 +1,35 @@ +id(); + $table->string('model')->nullable(); + $table->timestamp('expiry_date')->nullable(); + $table->timestamp('reminder_date')->nullable(); + $table->timestamps(); + $table->softDeletes(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('permits_reminders'); + } +} diff --git a/database/migrations/2024_01_23_233651_add_is_waived_to_transactions_logs_table.php b/database/migrations/2024_01_23_233651_add_is_waived_to_transactions_logs_table.php new file mode 100644 index 00000000..6755dcef --- /dev/null +++ b/database/migrations/2024_01_23_233651_add_is_waived_to_transactions_logs_table.php @@ -0,0 +1,32 @@ +boolean('is_waived')->nullable()->after('status')->default(false); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::table('transaction_logs', function (Blueprint $table) { + $table->dropColumn('is_waived'); + }); + } +} diff --git a/database/migrations/2024_01_23_233651_add_is_waived_to_transactions_table.php b/database/migrations/2024_01_23_233651_add_is_waived_to_transactions_table.php new file mode 100644 index 00000000..30a5e738 --- /dev/null +++ b/database/migrations/2024_01_23_233651_add_is_waived_to_transactions_table.php @@ -0,0 +1,32 @@ +boolean('is_waived')->nullable()->after('status')->default(false); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::table('transactions', function (Blueprint $table) { + $table->dropColumn('is_waived'); + }); + } +} diff --git a/public/excel-templates/permits_reminder_template.xlsx b/public/excel-templates/permits_reminder_template.xlsx new file mode 100644 index 00000000..b72e82f1 Binary files /dev/null and b/public/excel-templates/permits_reminder_template.xlsx differ diff --git a/resources/assets/vue/components/addresses/elements/DisplayWarehouseAddressComponent.vue b/resources/assets/vue/components/addresses/elements/DisplayWarehouseAddressComponent.vue index 8b440b1e..5be63536 100644 --- a/resources/assets/vue/components/addresses/elements/DisplayWarehouseAddressComponent.vue +++ b/resources/assets/vue/components/addresses/elements/DisplayWarehouseAddressComponent.vue @@ -5,7 +5,7 @@
-
{{item.street_one}} {{item.street_two}}, {{item.district.name}}, {{item.post_code}} {{item.state.name}}, {{item.country.name}}
+
{{item.street_one}} {{item.street_two}}, {{item.district.name}}, {{item.post_code}} {{item.state.name}}, {{item.country.name}}
diff --git a/resources/assets/vue/components/companies/elements/CustomerProfileComponent.vue b/resources/assets/vue/components/companies/elements/CustomerProfileComponent.vue index 69625c6a..3c8aae23 100644 --- a/resources/assets/vue/components/companies/elements/CustomerProfileComponent.vue +++ b/resources/assets/vue/components/companies/elements/CustomerProfileComponent.vue @@ -17,7 +17,7 @@
- {{item.name}} + {{item.name}}
@@ -35,6 +35,26 @@
+
+
+
+
+
+ Credit term customer: YES +
+
+ Credit term customer: NO +
+
+
+ +
+ + + +
+
+
@@ -95,13 +115,13 @@
-
Company Type
+
Company Type
@@ -216,4 +236,4 @@ }, mixins: [componentHandler] } - \ No newline at end of file + diff --git a/resources/assets/vue/components/companies/forms/UpdateCreditTermStatusFormComponent.vue b/resources/assets/vue/components/companies/forms/UpdateCreditTermStatusFormComponent.vue new file mode 100644 index 00000000..512678b0 --- /dev/null +++ b/resources/assets/vue/components/companies/forms/UpdateCreditTermStatusFormComponent.vue @@ -0,0 +1,39 @@ + + diff --git a/resources/assets/vue/components/containers/forms/ContainerCommentFormComponent.vue b/resources/assets/vue/components/containers/forms/ContainerCommentFormComponent.vue index a77807fa..b38f7ebb 100644 --- a/resources/assets/vue/components/containers/forms/ContainerCommentFormComponent.vue +++ b/resources/assets/vue/components/containers/forms/ContainerCommentFormComponent.vue @@ -1,5 +1,5 @@ - --> - - - +
diff --git a/resources/assets/vue/components/paymentsBilling/elements/AdminPaymentsBillingWithSearchPollingComponent.vue b/resources/assets/vue/components/paymentsBilling/elements/AdminPaymentsBillingWithSearchPollingComponent.vue new file mode 100644 index 00000000..a7017c1f --- /dev/null +++ b/resources/assets/vue/components/paymentsBilling/elements/AdminPaymentsBillingWithSearchPollingComponent.vue @@ -0,0 +1,85 @@ + + diff --git a/resources/assets/vue/components/paymentsBilling/elements/CustomerPaymentsBillingVariant2Component.vue b/resources/assets/vue/components/paymentsBilling/elements/CustomerPaymentsBillingWithStorageComponent.vue similarity index 72% rename from resources/assets/vue/components/paymentsBilling/elements/CustomerPaymentsBillingVariant2Component.vue rename to resources/assets/vue/components/paymentsBilling/elements/CustomerPaymentsBillingWithStorageComponent.vue index bc14ca99..4c8c9538 100644 --- a/resources/assets/vue/components/paymentsBilling/elements/CustomerPaymentsBillingVariant2Component.vue +++ b/resources/assets/vue/components/paymentsBilling/elements/CustomerPaymentsBillingWithStorageComponent.vue @@ -41,7 +41,21 @@ -
+
+ + Waive Transaction + + + Transaction Waived + + + N/A + + + + +
+
Billing Question?
@@ -68,11 +82,48 @@
-
- +
+ + + + + + + + + + + + + + + + + + + + + + - +
@@ -102,7 +153,7 @@
-
+
@@ -111,12 +162,12 @@
- +
-
+
@@ -125,7 +176,21 @@
- + +
+
+
+
+
+
+
+
+
Payment History
+
+
+
+
+
@@ -216,7 +281,7 @@
Make Payment
- +
diff --git a/resources/assets/vue/components/paymentsBilling/elements/GroupPaymentsBillingComponents.vue b/resources/assets/vue/components/paymentsBilling/elements/GroupPaymentsBillingComponents.vue index 3d8a39ae..763f0174 100644 --- a/resources/assets/vue/components/paymentsBilling/elements/GroupPaymentsBillingComponents.vue +++ b/resources/assets/vue/components/paymentsBilling/elements/GroupPaymentsBillingComponents.vue @@ -85,7 +85,7 @@
- +
diff --git a/resources/assets/vue/components/paymentsBilling/elements/PaymentHistoryComponent.vue b/resources/assets/vue/components/paymentsBilling/elements/PaymentHistoryComponent.vue index c09d9334..ec886b13 100644 --- a/resources/assets/vue/components/paymentsBilling/elements/PaymentHistoryComponent.vue +++ b/resources/assets/vue/components/paymentsBilling/elements/PaymentHistoryComponent.vue @@ -50,10 +50,10 @@
- +
+
+
+
+
+
+

Marking

+
+ +
Unclaimed Packing List
+
+
+
+

Container

+
{{item.container.container_reference}}
+
+
+

Invoice Date

+
n/a
+
{{ item.shipping_transaction.updated_at }}
+
+
+
+

Address

+
{{ item.order.address.post_code_area}}
+
{{ item.order.address.district.name +' '+item.order.address.postcode+' '+item.order.address.state.name }}
+
+
Unclaimed
+
+
+

Status

+
{{ invoice_status }}
+
+
+

Amount

+
n/a
+
MYR {{ item.shipping_transaction.amount.toFixed(2) }}
+
+
+
+
+
+ + + +
+
+
+ +
+
+
+
+
+
+
+ Add Warehouse Transport +
+ + + +
+
+
+
+
+ +
+
+
+
+
Add Billing Address
+ + + +
+
+
+
+ Edit billing Address +
+ +
+
+ +
+
+
+
+
+
+
Define Location
+ + + +
+
Generate Invoice
+
+
+ +
+
+
+ +
+
+ +
+ + + + + + +
+
+
+
+
+
+
+
+
+
+
+
+

Container Reference

+
{{ item.container ? item.container.container_reference : 'n/a' }}
+
n/a
+
+
+

Due Date

+
+
+
{{ item.container.transport.drop_date == null ? item.container.transport.current_schedule.etd : item.container.transport.drop_date }}
+
n/a
+
+
n/a
+
+
n/a
+
+ +
+

Total CBM

+
{{ (parseFloat(cbm) + parseFloat(overweight)).toFixed(3) }}
+
+
+
+
+ +
Invoice Details
+ + +
+
+

Subtotal

+
{{ item.shipping_transaction.amount - item.shipping_transaction.service_charge - item.shipping_transaction.tax }}
+
+
+

Service Charges

+
{{ item.shipping_transaction.service_charge }}
+
+
+

Tax

+
{{ item.shipping_transaction.tax }}
+
+
+

Total

+
{{ item.shipping_transaction.amount }}
+
+
+
+
+
+
+
+
+
+
+
+
+
Payment Attempt
+
+
+
+
+ +
+
+
+
+
+
+
+
+
Payment History
+
+
+
+
+ +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Total Amount:
+
+
+
MYR {{(Math.round((item.shipping_transaction.amount + Number.EPSILON) * 100) / 100).toFixed(2).toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",")}}
+
+
+
+
+
Paid Total:
+
+
+ +
Paid Total
+
+
+
+
+
Floating Amount:
+
+
+ +
Floating Amount
+
+
+
+
+
OutStanding Total:
+
+
+
MYR {{(Math.round((item.shipping_transaction.outstanding + Number.EPSILON) * 100) / 100).toFixed(2).toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",")}}
+
+
+
+
+
Make Payment
+
+
+
+
+ + + +
+
+
+
+
+
+ + diff --git a/resources/assets/vue/components/paymentsBilling/elements/SingleAdminPaymentsBillingWithStorageComponent.vue b/resources/assets/vue/components/paymentsBilling/elements/SingleAdminPaymentsBillingWithStorageComponent.vue new file mode 100644 index 00000000..dbec47a0 --- /dev/null +++ b/resources/assets/vue/components/paymentsBilling/elements/SingleAdminPaymentsBillingWithStorageComponent.vue @@ -0,0 +1,294 @@ + + diff --git a/resources/assets/vue/components/paymentsBilling/elements/SingleAdminPaymentsBillingWithoutStorageComponent.vue b/resources/assets/vue/components/paymentsBilling/elements/SingleAdminPaymentsBillingWithoutStorageComponent.vue new file mode 100644 index 00000000..4a26c402 --- /dev/null +++ b/resources/assets/vue/components/paymentsBilling/elements/SingleAdminPaymentsBillingWithoutStorageComponent.vue @@ -0,0 +1,325 @@ + + diff --git a/resources/assets/vue/components/paymentsBilling/elements/SingleGroupPaymentHistoryTransactionDetailsComponent.vue b/resources/assets/vue/components/paymentsBilling/elements/SingleGroupPaymentHistoryTransactionDetailsComponent.vue new file mode 100644 index 00000000..7a95322e --- /dev/null +++ b/resources/assets/vue/components/paymentsBilling/elements/SingleGroupPaymentHistoryTransactionDetailsComponent.vue @@ -0,0 +1,150 @@ + + + diff --git a/resources/assets/vue/components/paymentsBilling/elements/SingleGroupPaymentTransactionDetailsComponent.vue b/resources/assets/vue/components/paymentsBilling/elements/SingleGroupPaymentTransactionDetailsComponent.vue new file mode 100644 index 00000000..b2db1dfa --- /dev/null +++ b/resources/assets/vue/components/paymentsBilling/elements/SingleGroupPaymentTransactionDetailsComponent.vue @@ -0,0 +1,76 @@ + + + + diff --git a/resources/assets/vue/components/paymentsBilling/elements/SingleParentAdminPaymentsBillingComponent.vue b/resources/assets/vue/components/paymentsBilling/elements/SingleParentAdminPaymentsBillingComponent.vue new file mode 100644 index 00000000..acf2ed18 --- /dev/null +++ b/resources/assets/vue/components/paymentsBilling/elements/SingleParentAdminPaymentsBillingComponent.vue @@ -0,0 +1,77 @@ + + diff --git a/resources/assets/vue/components/paymentsBilling/forms/DeleteGroupPaymentAttemptFormComponent.vue b/resources/assets/vue/components/paymentsBilling/forms/DeleteGroupPaymentAttemptFormComponent.vue new file mode 100644 index 00000000..85b6121f --- /dev/null +++ b/resources/assets/vue/components/paymentsBilling/forms/DeleteGroupPaymentAttemptFormComponent.vue @@ -0,0 +1,40 @@ + + diff --git a/resources/assets/vue/components/paymentsBilling/forms/DeletePaymentAttemptFormComponent.vue b/resources/assets/vue/components/paymentsBilling/forms/DeletePaymentAttemptFormComponent.vue index f3248ed8..9feeda60 100644 --- a/resources/assets/vue/components/paymentsBilling/forms/DeletePaymentAttemptFormComponent.vue +++ b/resources/assets/vue/components/paymentsBilling/forms/DeletePaymentAttemptFormComponent.vue @@ -27,6 +27,15 @@ import componentHandler from '../../../general/mixins/componentHandler'; import ModalFormHandler from '../../../general/mixins/modalFormHandler'; export default { + methods:{ + successHandler(response){ + this.closeModal(); + this.formHandler(); + if(response.payload.data.id){ + window.location.reload(); + } + }, + }, mixins: [componentHandler, ModalFormHandler] } diff --git a/resources/assets/vue/components/paymentsBilling/forms/GroupPaymentFormComponent.vue b/resources/assets/vue/components/paymentsBilling/forms/GroupPaymentFormComponent.vue index 5888565b..ea71ef03 100644 --- a/resources/assets/vue/components/paymentsBilling/forms/GroupPaymentFormComponent.vue +++ b/resources/assets/vue/components/paymentsBilling/forms/GroupPaymentFormComponent.vue @@ -55,7 +55,7 @@
-
+
{{$store.getters.isShowing('otherPaymentMethods') ? 'Hide' : 'Show'}} Alternative Methods
@@ -138,7 +138,7 @@
Cancel
-
Proceed
+
Proceed
@@ -170,6 +170,10 @@ type: Array, required: true, }, + showManualPayment: { + type: Boolean, + default: false + }, }, data(){ return { @@ -198,8 +202,9 @@ }, methods:{ submitForm(){ + this.error = ''; this.parameters.payment_method = this.paymentMethod.id; - this.submit(this.route('api.transaction.group.create', JSON.stringify(this.selectedIds)), 'post', this.section, true, true); + this.submit(this.route('api.transaction.group.create', JSON.stringify(this.selectedIds)), 'post', this.section, false, true); }, updatePaymentType(payment){ this.paymentMethod = { @@ -220,11 +225,17 @@ // } // } - if (response.payload.length == 0) { + let isClearToUpdateList = true; + if(response.payload.data && response.payload.data.message){ + this.error = response.payload.data.message; + isClearToUpdateList = false; + } + else if (response.payload.length == 0) { setTimeout(function() { location.reload(); }, 2000); - } else if (response.payload) { + } + else if (response.payload) { if (response.payload.data.payment_method === 5) { window.location.href = this.route('billplz.bill', response.payload.data.reference) + '?auto_submit=true'; } else { @@ -232,7 +243,9 @@ } } - this.updateList(); + if(isClearToUpdateList){ + this.updateList(); + } } }, mixins: [formHandler] diff --git a/resources/assets/vue/components/paymentsBilling/forms/PaymentFormComponent.vue b/resources/assets/vue/components/paymentsBilling/forms/PaymentFormComponent.vue index 71234a08..b641e87f 100644 --- a/resources/assets/vue/components/paymentsBilling/forms/PaymentFormComponent.vue +++ b/resources/assets/vue/components/paymentsBilling/forms/PaymentFormComponent.vue @@ -97,7 +97,7 @@
Cancel
-
Proceed
+
Proceed
@@ -134,8 +134,9 @@ }, methods:{ submitForm(){ + this.error = ''; this.parameters.payment_method = this.paymentMethod.id; - this.submit(this.route('api.transaction.payment.create'), 'post', 'orderProfileSection', true, true); + this.submit(this.route('api.transaction.payment.create'), 'post', 'orderProfileSection', false, true); }, updatePaymentType(payment){ this.paymentMethod = { @@ -152,7 +153,12 @@ } } - this.updateList(); + if(response.payload.data && response.payload.data.message){ + this.error = response.payload.data.message; + } + else{ + this.updateList(); + } } }, mixins: [formHandler] diff --git a/resources/assets/vue/components/paymentsBilling/forms/WaiveInvoiceFormComponent.vue b/resources/assets/vue/components/paymentsBilling/forms/WaiveInvoiceFormComponent.vue new file mode 100644 index 00000000..9895bbd1 --- /dev/null +++ b/resources/assets/vue/components/paymentsBilling/forms/WaiveInvoiceFormComponent.vue @@ -0,0 +1,30 @@ + + diff --git a/resources/assets/vue/components/paymentsBilling/sections/AdminPaymentsBillingPollingSectionComponent.vue b/resources/assets/vue/components/paymentsBilling/sections/AdminPaymentsBillingPollingSectionComponent.vue new file mode 100644 index 00000000..a8315f55 --- /dev/null +++ b/resources/assets/vue/components/paymentsBilling/sections/AdminPaymentsBillingPollingSectionComponent.vue @@ -0,0 +1,141 @@ + + diff --git a/resources/assets/vue/components/paymentsBilling/sections/AdminPaymentsBillingSectionComponent.vue b/resources/assets/vue/components/paymentsBilling/sections/AdminPaymentsBillingSectionComponent.vue index 4e30cd66..91ee0aab 100644 --- a/resources/assets/vue/components/paymentsBilling/sections/AdminPaymentsBillingSectionComponent.vue +++ b/resources/assets/vue/components/paymentsBilling/sections/AdminPaymentsBillingSectionComponent.vue @@ -113,12 +113,12 @@
- +
- +
diff --git a/resources/assets/vue/components/settings/elements/ListPostcodeComponent.vue b/resources/assets/vue/components/settings/elements/ListPostcodeComponent.vue index fd9df462..0a6c8ab9 100644 --- a/resources/assets/vue/components/settings/elements/ListPostcodeComponent.vue +++ b/resources/assets/vue/components/settings/elements/ListPostcodeComponent.vue @@ -1,5 +1,5 @@