diff --git a/app/Classes/General/Eloquent/Filters/AmountExceed.php b/app/Classes/General/Eloquent/Filters/AmountExceed.php new file mode 100644 index 00000000..a3e353fa --- /dev/null +++ b/app/Classes/General/Eloquent/Filters/AmountExceed.php @@ -0,0 +1,19 @@ +where('amount', '>', $value); + } +} diff --git a/app/Classes/General/Eloquent/Filters/AmountShort.php b/app/Classes/General/Eloquent/Filters/AmountShort.php new file mode 100644 index 00000000..7406fc47 --- /dev/null +++ b/app/Classes/General/Eloquent/Filters/AmountShort.php @@ -0,0 +1,19 @@ +where('amount', '<', $value); + } +} diff --git a/app/Classes/General/Eloquent/Filters/CreatedBefore.php b/app/Classes/General/Eloquent/Filters/CreatedBefore.php new file mode 100644 index 00000000..bbbe3232 --- /dev/null +++ b/app/Classes/General/Eloquent/Filters/CreatedBefore.php @@ -0,0 +1,20 @@ +where('created_at', '<', Carbon::parse($value)); + } +} diff --git a/app/Classes/General/Eloquent/Filters/EmailLike.php b/app/Classes/General/Eloquent/Filters/EmailLike.php new file mode 100644 index 00000000..2151b1c8 --- /dev/null +++ b/app/Classes/General/Eloquent/Filters/EmailLike.php @@ -0,0 +1,20 @@ +where('email', 'LIKE', '%'.$value.'%'); + } + +} \ No newline at end of file diff --git a/app/Classes/General/Eloquent/Filters/PaymentMethod.php b/app/Classes/General/Eloquent/Filters/PaymentMethod.php new file mode 100644 index 00000000..cd8ba435 --- /dev/null +++ b/app/Classes/General/Eloquent/Filters/PaymentMethod.php @@ -0,0 +1,20 @@ +where('payment_method', $value); + } + +} diff --git a/app/Classes/General/Helper.php b/app/Classes/General/Helper.php index cad68208..ddadbb8d 100644 --- a/app/Classes/General/Helper.php +++ b/app/Classes/General/Helper.php @@ -2,8 +2,8 @@ namespace App\Classes\General; - use Illuminate\Support\Str; +use Illuminate\Support\Facades\Log; class Helper { @@ -24,4 +24,21 @@ class Helper return array_slice(get_class_methods($className), 1); } -} \ No newline at end of file + /** + * @param $log + * @return none + */ + static function debugLoggerForPerfexCRM($log){ + if($log){ + $message = $log['message']; + $substring = 'No data were found'; + if (isset($message)) { + if (strpos($message, $substring) !== false) { + // Log::info('Message exist'); + } else { + Log::info($log['message']); + } + } + } + } +} diff --git a/app/Classes/Jobs/InitializePerfexCRM.php b/app/Classes/Jobs/InitializePerfexCRM.php deleted file mode 100644 index ac77f87e..00000000 --- a/app/Classes/Jobs/InitializePerfexCRM.php +++ /dev/null @@ -1,33 +0,0 @@ -initialPerfexCRMObject = $initialPerfexCRMObject; - } - - public function handle() - { - (App()->make(InitializePerfexCRMProcessor::class))->execute($this->initialPerfexCRMObject); - } -} diff --git a/app/Classes/Jobs/UpdatePerfexCRM.php b/app/Classes/Jobs/UpdatePerfexCRM.php index cbc686e3..dfe0db93 100644 --- a/app/Classes/Jobs/UpdatePerfexCRM.php +++ b/app/Classes/Jobs/UpdatePerfexCRM.php @@ -9,6 +9,7 @@ use Illuminate\Foundation\Bus\Dispatchable; use Illuminate\Queue\InteractsWithQueue; use Illuminate\Queue\SerializesModels; use App\Classes\Modules\PerfexCRM\DataTransferObjects\UpdatePerfexCRMObject; +use App\Classes\Modules\PerfexCRM\DataTransferObjects\UpdatePerfexCRMInvoiceObject; class UpdatePerfexCRM implements ShouldQueue { @@ -17,17 +18,37 @@ class UpdatePerfexCRM implements ShouldQueue /** @var UpdatePerfexCRMObject */ private $updatePerfexCRMObject; + /** @var UpdatePerfexCRMInvoice */ + private $nextJob; + + /** @var */ + private $transaction; + /** * UpdatePerfexCRM constructor. * @param UpdatePerfexCRMObject $updatePerfexCRMObject + * @param UpdatePerfexCRMInvoice $nextJob + * @param $transaction */ - public function __construct(UpdatePerfexCRMObject $updatePerfexCRMObject) + public function __construct(UpdatePerfexCRMObject $updatePerfexCRMObject, $transaction, $nextJob) { $this->updatePerfexCRMObject = $updatePerfexCRMObject; + $this->nextJob = $nextJob; + $this->transaction = $transaction; } public function handle() { - (App()->make(UpdatePerfexCRMProcessor::class))->execute($this->updatePerfexCRMObject); + $result = (App()->make(UpdatePerfexCRMProcessor::class))->execute($this->updatePerfexCRMObject); + if($this->nextJob != null && $this->transaction != null){ + $updatePerfexCRMInvoiceOject = new UpdatePerfexCRMInvoiceObject( + $this->updatePerfexCRMObject->getContactEmail(), + $result->projectId, + $this->transaction, + true + ); + /** @var UpdatePerfexCRMInvoice $nextJob */ + $this->nextJob::dispatch($updatePerfexCRMInvoiceOject); + } } } diff --git a/app/Classes/Jobs/UpdatePerfexCRMInvoice.php b/app/Classes/Jobs/UpdatePerfexCRMInvoice.php index 64f6e02d..ac16a77c 100644 --- a/app/Classes/Jobs/UpdatePerfexCRMInvoice.php +++ b/app/Classes/Jobs/UpdatePerfexCRMInvoice.php @@ -19,7 +19,7 @@ use Illuminate\Queue\InteractsWithQueue; use Illuminate\Queue\SerializesModels; use Carbon\Carbon; use Illuminate\Support\Facades\Log; - +use App\Classes\General\Helper; class UpdatePerfexCRMInvoice implements ShouldQueue { @@ -47,10 +47,16 @@ class UpdatePerfexCRMInvoice implements ShouldQueue $invoiceId = 0; $invoiceStatus = 0; $invoice = (App()->make(FetchesPerfexCRMInvoice::class))->execute($customer->userid,"INV-", $transaction->owner->bill_no); + Log::error(json_encode('UpdatePerfexCRMInvoice debug $transaction->owner->bill_no: '.$transaction->owner->bill_no)); if(is_null($invoice)){ $result = (App()->make(CreatePerfexCRMInvoiceProcessor::class))->execute($transaction->owner, $this->updatePerfexCRMInvoiceObject->getIsPaid()); - $invoiceId = $result->payload['id']; + if ($result) { + $invoiceId = $result->payload['id']; + } else { + // Log::error(json_encode('UpdatePerfexCRMInvoice CreatePerfexCRMInvoiceProcessor failed')); + Helper::debugLoggerForPerfexCRM('UpdatePerfexCRMInvoice CreatePerfexCRMInvoiceProcessor failed'); + } } else{ $invoiceId = $invoice->id; @@ -58,26 +64,9 @@ class UpdatePerfexCRMInvoice implements ShouldQueue //This only run when invoice already exist and the invoice does not have a PAID status if($invoiceStatus != PerfexCRMInvoiceStatus::PAID){ - //get project - $projectId = ""; - $projectName = ""; - if($transaction->owner instanceof Transaction){ - $orderReference = $transaction->owner->owner->owner()->first()->reference; - $packingListReference = $transaction->owner->owner->reference; - $projectName = 'IZYIM | X1 Shipping | '.$orderReference.' | '.$packingListReference; - $project = (App()->make(FetchesPerfexCRMProject::class))->execute($projectName, $customer->userid); - if(!is_null($project)){ - $projectId = $project->id; - } - } - - if($projectId == ""){ - Log::error(json_encode('UpdatePerfexCRMInvoice debug: '.$projectName)); - Log::error(json_encode($transaction->owner)); - } - + Log::error(json_encode('UpdatePerfexCRMInvoice debug $this->updatePerfexCRMInvoiceObject->getProjectId(): '.$this->updatePerfexCRMInvoiceObject->getProjectId())); //update invoice - (App()->make(UpdatesPerfexCRMInvoice::class))->execute($invoice, $projectId); + (App()->make(UpdatesPerfexCRMInvoice::class))->execute($invoice, $this->updatePerfexCRMInvoiceObject->getProjectId()); } } diff --git a/app/Classes/Jobs/UpdatePerfexCRMPrelude.php b/app/Classes/Jobs/UpdatePerfexCRMPrelude.php new file mode 100644 index 00000000..8241939e --- /dev/null +++ b/app/Classes/Jobs/UpdatePerfexCRMPrelude.php @@ -0,0 +1,96 @@ +packingList = $packingList; + $this->transaction = $transaction; + $this->updatePerfexCRMObject = $updatePerfexCRMObject; + $this->nextJob1 = $nextJob1; + $this->nextJob2 = $nextJob2; + } + + public function handle() + { + if(is_null($this->packingList)){ + $this->packingList = $this->transaction->owner->owner; + } + $amount = 0.00; + if(!is_null($this->transaction)){ + $amount = $this->transaction->amount; + } + $data = [ + 'amount' => number_format($amount, 2, '.', ''), + 'link_order' => config('app.url').'/order/show/'.$this->packingList->owner->reference, + 'link_autocount_or' => 'https://docs.google.com/spreadsheets/d/1Q3rJBGQ9Bo04HZp5WR9zbLp7pIW2kfDYsabxG7JON-4/edit#gid=2013983170', + 'link_perfex' => 'https://perfex.cief-malaysia.com/admin/projects/view/89', + ]; + + + $result = $this->replacePlaceholders($this->updatePerfexCRMObject->getTasks(), $data); + $this->updatePerfexCRMObject->setTasks($result); + /** @var UpdatePerfexCRM $nextJob1 */ + /** @var UpdatePerfexCRMInvoice $nextJob2 */ + $this->nextJob1::dispatch($this->updatePerfexCRMObject, $this->transaction, $this->nextJob2); + } + + function replacePlaceholders($template, $data, $prefix = '') + { + foreach ($template as $key => $value) { + foreach ($data as $dataKey => $dataValue) { + if (is_array($dataValue)) { + $template[$key] = $this->replacePlaceholders($template[$key], $dataValue, $dataKey); + } else { + if ($prefix != '') { + $template[$key] = str_replace('{' .$prefix. "." .$dataKey . '}', $dataValue, $template[$key]); + } else { + $template[$key] = str_replace('{' . $dataKey . '}', $dataValue, $template[$key]); + } + } + } + } + + return $template; + } + +} diff --git a/app/Classes/Modules/Accounts/ControllersLogic/UpdateUserLogic.php b/app/Classes/Modules/Accounts/ControllersLogic/UpdateUserLogic.php index d3ce528d..912d5e31 100644 --- a/app/Classes/Modules/Accounts/ControllersLogic/UpdateUserLogic.php +++ b/app/Classes/Modules/Accounts/ControllersLogic/UpdateUserLogic.php @@ -4,7 +4,7 @@ namespace App\Classes\Modules\Accounts\ControllersLogic; use App\Classes\General\Abstracts\AbstractControllerLogic; -use App\Classes\Modules\Accounts\Services\UpdatesUser; +use App\Classes\Modules\Accounts\Services\UpdatesUserFullName; use App\Classes\Modules\Accounts\Services\FetchesUser; use App\Classes\Modules\Accounts\Standards\Rules\CanUpdateUser; use App\Classes\Modules\Accounts\DataTransferObjects\FullNameObject; @@ -29,8 +29,8 @@ class UpdateUserLogic extends AbstractControllerLogic /** @var CanUpdateUser */ private $canUpdateUser; - /** @var UpdatesUser */ - private $updatesUser; + /** @var UpdatesUserFullName */ + private $updatesUserFullName; /** @var FetchesUser */ private $fetchesUser; @@ -38,13 +38,13 @@ class UpdateUserLogic extends AbstractControllerLogic /** * UpdateAddressLogic constructor. * @param CanUpdateUser $canUpdateUser - * @param UpdatesUser $updatesUser + * @param UpdatesUserFullName $updatesUserFullName * @param FetchesUser $fetchesUSer */ - public function __construct(CanUpdateUser $canUpdateUser, UpdatesUser $updatesUser, FetchesUser $fetchesUser) + public function __construct(CanUpdateUser $canUpdateUser, UpdatesUserFullName $updatesUserFullName, FetchesUser $fetchesUser) { $this->canUpdateUser = $canUpdateUser; - $this->updatesUser = $updatesUser; + $this->updatesUserFullName = $updatesUserFullName; $this->fetchesUser = $fetchesUser; } @@ -64,7 +64,7 @@ class UpdateUserLogic extends AbstractControllerLogic $query = $this->fetchesUser->execute(['id' => $request->route('id')]); - $query = $this->updatesUser->execute($query, $object); + $query = $this->updatesUserFullName->execute($query, $object); return $this->resourceResponse(new UserResource($query)); diff --git a/app/Classes/Modules/Accounts/ControllersLogic/UpdateUserRoleLogic.php b/app/Classes/Modules/Accounts/ControllersLogic/UpdateUserRoleLogic.php new file mode 100644 index 00000000..934711e7 --- /dev/null +++ b/app/Classes/Modules/Accounts/ControllersLogic/UpdateUserRoleLogic.php @@ -0,0 +1,71 @@ + 'Updated Admin Role', + 'message' => 'You have successfully updated the Admin Role' + ]; + } + + /** @var CanUpdateUser */ + private $canUpdateUser; + + /** @var UpdatesUser */ + private $updatesUser; + + /** @var FetchesUser */ + private $fetchesUser; + + /** + * UpdateAddressLogic constructor. + * @param CanUpdateUser $canUpdateUser + * @param UpdatesUser $updatesUser + * @param FetchesUser $fetchesUSer + */ + public function __construct(CanUpdateUser $canUpdateUser, UpdatesUser $updatesUser, FetchesUser $fetchesUser) + { + $this->canUpdateUser = $canUpdateUser; + $this->updatesUser = $updatesUser; + $this->fetchesUser = $fetchesUser; + } + + + /** + * @param Request $request + * @return JsonResponse + * @throws ErrorException + */ + public function logic(Request $request) : JsonResponse + { + $query = $this->fetchesUser->execute(['id' => $request->route('id')]); + + $object = new UserObject($query->name, $request->input('type')); + + $this->canUpdateUser->passes($object); + + $query = $this->updatesUser->execute($query, $object); + + return $this->resourceResponse(new UserResource($query)); + } + +} \ No newline at end of file diff --git a/app/Classes/Modules/Accounts/DataTransferObjects/UserObject.php b/app/Classes/Modules/Accounts/DataTransferObjects/UserObject.php new file mode 100644 index 00000000..4ebbc22c --- /dev/null +++ b/app/Classes/Modules/Accounts/DataTransferObjects/UserObject.php @@ -0,0 +1,40 @@ +name = $name; + $this->type = $type; + } + + /** + * @return string + */ + public function getName(): string + { + return $this->name; + } + + /** + * @return int + */ + public function getType(): int + { + return $this->type; + } +} diff --git a/app/Classes/Modules/Accounts/Services/UpdatesUser.php b/app/Classes/Modules/Accounts/Services/UpdatesUser.php index dfccbae7..f7c6cfab 100644 --- a/app/Classes/Modules/Accounts/Services/UpdatesUser.php +++ b/app/Classes/Modules/Accounts/Services/UpdatesUser.php @@ -3,7 +3,7 @@ namespace App\Classes\Modules\Accounts\Services; use App\Classes\General\Eloquent\AbstractUpdateRecord; -use App\Classes\Modules\Accounts\DataTransferObjects\FullNameObject; +use App\Classes\Modules\Accounts\DataTransferObjects\UserObject; use App\Models\User; class UpdatesUser extends AbstractUpdateRecord @@ -11,13 +11,14 @@ class UpdatesUser extends AbstractUpdateRecord /** * @param User $model - * @param FullNameObject $object + * @param UserObject $object * @return \Illuminate\Database\Eloquent\Model * @throws \App\Classes\Exceptions\MalformedRequestException */ - public function execute(User $model, FullNameObject $object) { + public function execute(User $model, UserObject $object) { $model->name = $object->getName(); + $model->type = $object->getType(); return $this->handler($model); } diff --git a/app/Classes/Modules/Accounts/Services/UpdatesUserFullName.php b/app/Classes/Modules/Accounts/Services/UpdatesUserFullName.php new file mode 100644 index 00000000..9836e695 --- /dev/null +++ b/app/Classes/Modules/Accounts/Services/UpdatesUserFullName.php @@ -0,0 +1,24 @@ +name = $object->getName(); + return $this->handler($model); + + } +} \ No newline at end of file diff --git a/app/Classes/Modules/Announcements/ControllersLogic/UpdateAnnouncementLogic.php b/app/Classes/Modules/Announcements/ControllersLogic/UpdateAnnouncementLogic.php index 4fac4144..fc1f4359 100644 --- a/app/Classes/Modules/Announcements/ControllersLogic/UpdateAnnouncementLogic.php +++ b/app/Classes/Modules/Announcements/ControllersLogic/UpdateAnnouncementLogic.php @@ -10,7 +10,7 @@ use App\Classes\Modules\Announcements\Services\FetchesAnnouncement; use App\Classes\Modules\Announcements\Services\UpdatesAnnouncement; use App\Http\Resources\AnnouncementResource; - +use Carbon\Carbon; use Illuminate\Http\JsonResponse; use Illuminate\Http\Request; @@ -66,8 +66,8 @@ class UpdateAnnouncementLogic extends AbstractControllerLogic $annoucement_object = new AnnouncementObject( $request->input('title'), $request->input('description'), - $request->input('starting_on'), - $request->input('ending_on') + Carbon::createFromFormat('d-m-Y', $request->input('starting_on'))->format('Y-m-d H:i:s'), + Carbon::createFromFormat('d-m-Y', $request->input('ending_on'))->format('Y-m-d H:i:s') ); $this->canUpdateAnnouncement->passes($annoucement_object); diff --git a/app/Classes/Modules/Companies/ControllersLogic/UpdateCompanyTypeLogic.php b/app/Classes/Modules/Companies/ControllersLogic/UpdateCompanyTypeLogic.php new file mode 100644 index 00000000..4a7e68cc --- /dev/null +++ b/app/Classes/Modules/Companies/ControllersLogic/UpdateCompanyTypeLogic.php @@ -0,0 +1,69 @@ + 'Updated Company Type', + 'message' => 'You have successfully updated the Company Tyoe' + ]; + } + + /** @var CanUpdateCompany */ + private $canUpdateCompany; + + /** @var UpdatesCompany */ + private $updatesCompany; + + /** @var FetchesCompany */ + private $fetchesCompany; + + /** + * UpdateCompanyControllersLogic constructor. + * @param CanUpdateCompany $canUpdateCompany + * @param UpdatesCompany $updatesCompany + * @param FetchesCompany $fetchesCompany + */ + public function __construct(CanUpdateCompany $canUpdateCompany, UpdatesCompany $updatesCompany, FetchesCompany $fetchesCompany) + { + $this->canUpdateCompany = $canUpdateCompany; + $this->updatesCompany = $updatesCompany; + $this->fetchesCompany = $fetchesCompany; + } + + /** + * @param Request $request + * @return JsonResponse + * @throws ErrorException + */ + public function logic(Request $request) : JsonResponse + { + $query = $this->fetchesCompany->execute(['id' => $request->route('id')]); + + $object = new CompanyObject($query->name, $query->reference, $request->input('type')); + + $this->canUpdateCompany->passes($object); + + $query = $this->updatesCompany->execute($query, $object); + + return $this->resourceResponse(new CompanyResource($query)); + } + +} diff --git a/app/Classes/Modules/Contacts/ControllersLogic/UpdateContactLogic.php b/app/Classes/Modules/Contacts/ControllersLogic/UpdateContactLogic.php new file mode 100644 index 00000000..2a78da13 --- /dev/null +++ b/app/Classes/Modules/Contacts/ControllersLogic/UpdateContactLogic.php @@ -0,0 +1,69 @@ + 'Updated Contact', + 'message' => 'You have successfully updated the Contact' + ]; + } + + /** @var UpdatesContact */ + private $updatesContact; + + /** @var FetchesContact */ + private $fetchesContact; + + /** + * UpdateContactLogic constructor. + * @param UpdatesContact $updatesContact + * @param FetchesContact $fetchesContact + */ + public function __construct(UpdatesContact $updatesContact, FetchesContact $fetchesContact) + { + $this->updatesContact = $updatesContact; + $this->fetchesContact = $fetchesContact; + } + + + /** + * @param Request $request + * @return JsonResponse + * @throws ErrorException + */ + public function logic(Request $request) : JsonResponse + { + $object = new ContactObject( + $request->input('reference'), + $request->input('phone'), + $request->input('email'), + $request->input('wechat_id') + ); + + // $this->canUpdateContact->passes($object); + + $query = $this->fetchesContact->execute(['id' => $request->route('id')]); + + $query = $this->updatesContact->execute($query, $object); + + return $this->resourceResponse(new ContactResource($query)); + } + +} \ No newline at end of file diff --git a/app/Classes/Modules/Contacts/Services/FetchesContact.php b/app/Classes/Modules/Contacts/Services/FetchesContact.php new file mode 100644 index 00000000..3521a0dd --- /dev/null +++ b/app/Classes/Modules/Contacts/Services/FetchesContact.php @@ -0,0 +1,32 @@ +repository = $repository; + } + + /** + * @return Builder + */ + public function getRepository(): Builder + { + return $this->repository->newQuery(); + } +} \ No newline at end of file diff --git a/app/Classes/Modules/Contacts/Services/UpdatesContact.php b/app/Classes/Modules/Contacts/Services/UpdatesContact.php new file mode 100644 index 00000000..4da2a44a --- /dev/null +++ b/app/Classes/Modules/Contacts/Services/UpdatesContact.php @@ -0,0 +1,26 @@ +reference = $object->getReference(); + $model->phone = $object->getPhone(); + $model->email = $object->getEmail(); + $model->wechat_id = $object->getWechatId(); + + return $this->handler($model); + } +} \ No newline at end of file diff --git a/app/Classes/Modules/Exports/Services/ExportsPaymentTransactions.php b/app/Classes/Modules/Exports/Services/ExportsPaymentTransactions.php index ab1af2d0..946f36c6 100644 --- a/app/Classes/Modules/Exports/Services/ExportsPaymentTransactions.php +++ b/app/Classes/Modules/Exports/Services/ExportsPaymentTransactions.php @@ -39,7 +39,12 @@ class ExportsPaymentTransactions implements FromQuery, WithHeadings, WithHeading 'ProjNo', 'DeptNo', 'Qty', - 'UnitPrice' + 'UnitPrice', +// 'marking', +// 'contact person', +// 'contact number', +// 'link', +// 'amount' ]; } @@ -97,6 +102,10 @@ class ExportsPaymentTransactions implements FromQuery, WithHeadings, WithHeading $order = $transaction->owner->owner; $company = $order->companyModule->company; $shippingTransactionDetails = $transaction->transactionDetails()->where('reference', 'SHIPPING_FEE')->first(); + $marking = $order->companyModule->inviters()->withPivot('invitee_reference')->first()->pivot->invitee_reference; + $contact = $order->companyModule->company->contacts->first(); + $userName = $order->companyModule->employees()->first(); + $link = route('customer.payment-and-billing', $marking); $furtherDescription = ''; @@ -123,7 +132,12 @@ class ExportsPaymentTransactions implements FromQuery, WithHeadings, WithHeading $container->reference, 'CIEF', $shippingTransactionDetails->quantity, - $shippingTransactionDetails->price + $shippingTransactionDetails->price, +// $marking, +// $contact ? $contact->phone : '', +// $userName->name, +// $link, +// $transaction->amount ]; return [ '<>', diff --git a/app/Classes/Modules/Orders/ControllersLogic/CreateOrderLogic.php b/app/Classes/Modules/Orders/ControllersLogic/CreateOrderLogic.php index 2c4743d2..3aded198 100644 --- a/app/Classes/Modules/Orders/ControllersLogic/CreateOrderLogic.php +++ b/app/Classes/Modules/Orders/ControllersLogic/CreateOrderLogic.php @@ -18,7 +18,8 @@ use Illuminate\Http\JsonResponse; class CreateOrderLogic extends AbstractControllerLogic { - protected function notification():array { + protected function notification(): array + { return [ 'title' => 'Created Order', 'message' => 'You have successfully created a new Order' @@ -62,19 +63,31 @@ class CreateOrderLogic extends AbstractControllerLogic } - public function logic(Request $request) : JsonResponse { + public function logic(Request $request): JsonResponse + { $company = $this->fetchesCompany->execute(['id' => $request->input('company_id')]); $address = $this->fetchesAddress->execute(['id' => $request->input('address_id')]); - $originWarehouse = $this->fetchesCompanyModule->execute(['id' => $request->input('warehouse_id')]); + // todo-new: fix this + // if select warehouse foshan + if ($request->input('warehouse_id') === 'foshan') { + // 13 - sabah, 14 - sarawak + if (in_array($address->state->id, [13, 14])) { + $originWarehouse = $this->fetchesCompanyModule->execute(['reference' => WarehouseReferences::YD_FS_WEST_MALAYSIA]); + } else { + $originWarehouse = $this->fetchesCompanyModule->execute(['reference' => WarehouseReferences::YD_FS_WEST_MALAYSIA]); + } + } else { + $originWarehouse = $this->fetchesCompanyModule->execute(['id' => $request->input('warehouse_id')]); - if(!in_array($company->companyModules()->importers()->first()->id, WarehouseReferences::YD_EXEMPT_LIST)){ - $originWarehouse = $this->fetchesCompanyModule->execute(['reference' => $originWarehouse->reference === WarehouseReferences::VT_GUANG_ZHOU ? WarehouseReferences::YD_GUANG_ZHOU : WarehouseReferences::YD_YIWU]); + if (!in_array($company->companyModules()->importers()->first()->id, WarehouseReferences::YD_EXEMPT_LIST)) { + $originWarehouse = $this->fetchesCompanyModule->execute(['reference' => $originWarehouse->reference === WarehouseReferences::VT_GUANG_ZHOU ? WarehouseReferences::YD_GUANG_ZHOU : WarehouseReferences::YD_YIWU]); + } } - + if($originWarehouse->reference === WarehouseReferences::YD_YIWU && in_array($address->state_id, [5, 13, 14])) { throw new RequestValidationException('Our Yiwu warehouse is unable to ship goods to Sabah & Sarawak at the moment. you can select our Guangzhou warehouse as an alternative.'); } diff --git a/app/Classes/Modules/Orders/ControllersLogic/FetchOrderV2Logic.php b/app/Classes/Modules/Orders/ControllersLogic/FetchOrderV2Logic.php new file mode 100644 index 00000000..08d3cc5d --- /dev/null +++ b/app/Classes/Modules/Orders/ControllersLogic/FetchOrderV2Logic.php @@ -0,0 +1,60 @@ + 'Retrieved Order', + 'message' => 'You have successfully retrieved an order' + ]; + } + + /** @var CanFetchOrder */ + private $canFetchOrder; + + /** @var FetchesOrder */ + private $fetchesOrder; + + /** + * FetchOrderLogic constructor. + * @param CanFetchOrder $canFetchOrder + * @param FetchesOrder $fetchesOrder + */ + public function __construct(CanFetchOrder $canFetchOrder, FetchesOrder $fetchesOrder) + { + $this->canFetchOrder = $canFetchOrder; + $this->fetchesOrder = $fetchesOrder; + } + + /** + * @param Request $request + * @return JsonResponse + * @throws \App\Classes\Exceptions\AccessForbiddenException + * @throws \App\Classes\Exceptions\RequestValidationException + */ + public function logic(Request $request) : JsonResponse + { + + $this->canFetchOrder->passes(); + + $query = $this->fetchesOrder->execute(['reference' => $request->route('id'), 'with_packing_lists' => true]); + + return $this->resourceResponse(new OrderV2Resource($query)); + + } + +} \ No newline at end of file diff --git a/app/Classes/Modules/Orders/ControllersLogic/ListOrdersV2Logic.php b/app/Classes/Modules/Orders/ControllersLogic/ListOrdersV2Logic.php new file mode 100644 index 00000000..c563051d --- /dev/null +++ b/app/Classes/Modules/Orders/ControllersLogic/ListOrdersV2Logic.php @@ -0,0 +1,56 @@ + 'Retrieved Orders', + 'message' => 'You have successfully retrieved a list of Orders' + ]; + } + + /** @var CanListOrders */ + private $canListOrders; + + /** @var ListsOrders */ + private $listsOrders; + + /** + * ListOrdersLogic constructor. + * @param CanListOrders $canListOrders + * @param ListsOrders $listsOrders + */ + public function __construct(CanListOrders $canListOrders, ListsOrders $listsOrders) + { + $this->canListOrders = $canListOrders; + $this->listsOrders = $listsOrders; + } + + public function logic(Request $request) : JsonResponse + { + $this->canListOrders->passes(); + + $query = $this->listsOrders->execute(array_merge($this->listsOrders->deserializeFilters($request->input('filters')), ['with_parcels' => true, 'type_in' => [OrderType::SHARED_CONTAINER, OrderType::DEDICATED_CONTAINER]])); + + return $this->collectionResponse(OrderV2Resource::collection($query)); + + } + + + +} diff --git a/app/Classes/Modules/PackingLists/ControllersLogic/DeletePackingListByPackageIdLogic.php b/app/Classes/Modules/PackingLists/ControllersLogic/DeletePackingListByPackageIdLogic.php new file mode 100644 index 00000000..a221c501 --- /dev/null +++ b/app/Classes/Modules/PackingLists/ControllersLogic/DeletePackingListByPackageIdLogic.php @@ -0,0 +1,81 @@ + 'Deleted PackingList', + 'message' => 'You have successfully deleted a PackingList' + ]; + } + + + /** @var CanDeletePackingList */ + private $canDeletePackingList; + + /** @var DeletesPackingList */ + private $deletesPackingList; + + /** @var FetchesPackingList */ + private $fetchesPackingList; + + /** @var FetchesPackage */ + private $fetchesPackage; + + /** + * DeletePackingListByPackageIdLogic constructor. + * @param CanDeletePackingList $canDeletePackingList + * @param DeletesPackingList $deletesPackingList + * @param FetchesPackingList $fetchesPackingList + * @param FetchesPackage $fetchesPackage + */ + public function __construct(CanDeletePackingList $canDeletePackingList, DeletesPackingList $deletesPackingList, FetchesPackingList $fetchesPackingList, FetchesPackage $fetchesPackage) + { + $this->canDeletePackingList = $canDeletePackingList; + $this->deletesPackingList = $deletesPackingList; + $this->fetchesPackingList = $fetchesPackingList; + $this->fetchesPackage = $fetchesPackage; + } + + /** + * @param Request $request + * @return JsonResponse + * @throws ErrorException + */ + public function logic(Request $request) : JsonResponse + { + $this->canDeletePackingList->passes(); + + $package = $this->fetchesPackage->execute(['id' => $request->route('id')]); + + $packingList = $package->packingList; + + $packingList = PackingList::where('reference', $packingList->reference)->get(); + + $childPackingList = PackingList::where('owner_type', PackingList::class)->whereIn('owner_id', $packingList->pluck('id'))->get(); + + $packingList->each->delete(); + + $childPackingList->each->delete(); + + return $this->response([]); + } + +} diff --git a/app/Classes/Modules/PerfexCRM/DataTransferObjects/CreateTaskPerfexCRMObject.php b/app/Classes/Modules/PerfexCRM/DataTransferObjects/CreateTaskPerfexCRMObject.php index 8923ec01..6c6354f1 100644 --- a/app/Classes/Modules/PerfexCRM/DataTransferObjects/CreateTaskPerfexCRMObject.php +++ b/app/Classes/Modules/PerfexCRM/DataTransferObjects/CreateTaskPerfexCRMObject.php @@ -36,7 +36,13 @@ class CreateTaskPerfexCRMObject implements DataTransferObject /** @var string */ private $department; - public function __construct(string $email, string $name, string $description, string $leadId, string $projectId, string $milestoneId, string $reference, string $onTaskCompletion, string $status, string $department) + /** @var string */ + private $priority; + + /** @var string */ + private $duedate; + + public function __construct(string $email, string $name, string $description, string $leadId, string $projectId, string $milestoneId, string $reference, string $onTaskCompletion, string $status, string $department, string $priority, string $duedate) { $this->email = $email; $this->name = $name; @@ -48,6 +54,8 @@ class CreateTaskPerfexCRMObject implements DataTransferObject $this->onTaskCompletion = $onTaskCompletion; $this->status = $status; $this->department = $department; + $this->priority = $priority; + $this->duedate = $duedate; } /** @@ -134,4 +142,20 @@ class CreateTaskPerfexCRMObject implements DataTransferObject { return $this->department; } + + /** + * @return string + */ + public function getPriority(): string + { + return $this->priority; + } + + /** + * @return string + */ + public function getDuedate(): string + { + return $this->duedate; + } } diff --git a/app/Classes/Modules/PerfexCRM/DataTransferObjects/UpdatePerfexCRMInvoiceObject.php b/app/Classes/Modules/PerfexCRM/DataTransferObjects/UpdatePerfexCRMInvoiceObject.php index d19e6153..20df1dc9 100644 --- a/app/Classes/Modules/PerfexCRM/DataTransferObjects/UpdatePerfexCRMInvoiceObject.php +++ b/app/Classes/Modules/PerfexCRM/DataTransferObjects/UpdatePerfexCRMInvoiceObject.php @@ -17,11 +17,15 @@ class UpdatePerfexCRMInvoiceObject implements DataTransferObject /** @var bool */ private $isPaid; - public function __construct(string $email, Transaction $transaction, bool $isPaid) + /** @var string */ + private $projectId; + + public function __construct(string $email, string $projectId, Transaction $transaction, bool $isPaid) { $this->email = $email; $this->transaction = $transaction; $this->isPaid = $isPaid; + $this->projectId = $projectId; } /** @@ -32,6 +36,14 @@ class UpdatePerfexCRMInvoiceObject implements DataTransferObject return $this->email; } + /** + * @return string + */ + public function getProjectId(): string + { + return $this->projectId; + } + /** * @return Transaction */ diff --git a/app/Classes/Modules/PerfexCRM/DataTransferObjects/UpdatePerfexCRMObject.php b/app/Classes/Modules/PerfexCRM/DataTransferObjects/UpdatePerfexCRMObject.php index 42af2b54..d5335b4f 100644 --- a/app/Classes/Modules/PerfexCRM/DataTransferObjects/UpdatePerfexCRMObject.php +++ b/app/Classes/Modules/PerfexCRM/DataTransferObjects/UpdatePerfexCRMObject.php @@ -32,10 +32,10 @@ class UpdatePerfexCRMObject implements DataTransferObject private $milestoneNames; /** @var array */ - private $taskNames; + private $tasks; - public function __construct(string $companyName, string $companyReference, string $contactName, string $contactEmail, string $bookingMarking, string $projectName, int $projectStatus, array $milestoneNames, array $taskNames) + public function __construct(string $companyName, string $companyReference, string $contactName, string $contactEmail, string $bookingMarking, string $projectName, int $projectStatus, array $milestoneNames, array $tasks) { $this->companyName = $companyName; @@ -46,7 +46,7 @@ class UpdatePerfexCRMObject implements DataTransferObject $this->projectName = $projectName; $this->projectStatus = $projectStatus; $this->milestoneNames = $milestoneNames; - $this->taskNames = $taskNames; + $this->tasks = $tasks; } /** @@ -116,8 +116,13 @@ class UpdatePerfexCRMObject implements DataTransferObject /** * @return array */ - public function getTaskNames(): array + public function getTasks(): array { - return $this->taskNames; + return $this->tasks; + } + + public function setTasks($tasks) + { + $this->tasks = $tasks; } } diff --git a/app/Classes/Modules/PerfexCRM/Processors/CreatePerfexCRMInvoiceProcessor.php b/app/Classes/Modules/PerfexCRM/Processors/CreatePerfexCRMInvoiceProcessor.php index e3a3a4a5..d9adcc7e 100644 --- a/app/Classes/Modules/PerfexCRM/Processors/CreatePerfexCRMInvoiceProcessor.php +++ b/app/Classes/Modules/PerfexCRM/Processors/CreatePerfexCRMInvoiceProcessor.php @@ -69,7 +69,7 @@ class CreatePerfexCRMInvoiceProcessor $date = Carbon::parse($transaction->created_at)->format('Y-m-d'); $dueDate = Carbon::parse($transaction->created_at)->addDays(6)->startOfDay()->format('Y-m-d'); - $currency = 1; //cief TODO: To look into Malaysia and Chinese currency + $currency = 1; $subTotal = 0.00; $total = 0.00; @@ -80,12 +80,17 @@ class CreatePerfexCRMInvoiceProcessor ->where('status', '=', \App\Classes\ValueObjects\Constants\ApprovalStatus::APPROVED) ->where('type', '=', \App\Classes\ValueObjects\Constants\AddressType::BILLING)->first(); - $billingStreet = $billingStreet.$addresses->street_one; - $billingStreet = $billingStreet.$addresses->street_two.','; - $billingStreet = $billingStreet.$addresses->district()->first()->name.','; - $billingStreet = $billingStreet.$addresses->postcode; - $billingStreet = $billingStreet.$addresses->state()->first()->name.','; - $billingStreet = $billingStreet.$addresses->country()->first()->name; + if ($addresses !== null) { + $billingStreet = $billingStreet.$addresses->street_one; + $billingStreet = $billingStreet.$addresses->street_two.','; + $billingStreet = $billingStreet.$addresses->district()->first()->name.','; + $billingStreet = $billingStreet.$addresses->postcode; + $billingStreet = $billingStreet.$addresses->state()->first()->name.','; + $billingStreet = $billingStreet.$addresses->country()->first()->name; + } + else{ + $billingStreet = "[Pending Billing Details by user]"; + } $allowedPaymentModes = []; $invoiceItems = []; @@ -106,9 +111,10 @@ class CreatePerfexCRMInvoiceProcessor $orderReference = $transaction->owner->owner->reference; $packingListReference = $transaction->owner->reference; $projectName = 'IZYIM | X1 Shipping | '.$orderReference.' | '.$packingListReference; - $project = $this->fetchesPerfexCRMProject->execute($projectName, $clientId); - if(!is_null($project)){ - $projectId = $project->id; + $result = $this->fetchesPerfexCRMProject->execute($projectName, $clientId); + if(isset($result->payload)){ + $project = $result->payload[0]; + $projectId = $project['id']; } else{ $result = $this->createsPerfexCRMCustomerProject->execute($projectName, PerfexCRMProjectStatus::NOT_STARTED, $clientId); diff --git a/app/Classes/Modules/PerfexCRM/Processors/CreatePerfexCRMTaskProcessor.php b/app/Classes/Modules/PerfexCRM/Processors/CreatePerfexCRMTaskProcessor.php index f70760f8..c16a4e1b 100644 --- a/app/Classes/Modules/PerfexCRM/Processors/CreatePerfexCRMTaskProcessor.php +++ b/app/Classes/Modules/PerfexCRM/Processors/CreatePerfexCRMTaskProcessor.php @@ -35,6 +35,8 @@ class CreatePerfexCRMTaskProcessor $createTaskPerfexCRMObject->getOnTaskCompletion(), $createTaskPerfexCRMObject->getDepartment(), $createTaskPerfexCRMObject->getStatus(), + $createTaskPerfexCRMObject->getPriority(), + $createTaskPerfexCRMObject->getDuedate() ); return true; } diff --git a/app/Classes/Modules/PerfexCRM/Processors/InitializePerfexCRMProcessor.php b/app/Classes/Modules/PerfexCRM/Processors/InitializePerfexCRMProcessor.php deleted file mode 100644 index 82ef0d36..00000000 --- a/app/Classes/Modules/PerfexCRM/Processors/InitializePerfexCRMProcessor.php +++ /dev/null @@ -1,195 +0,0 @@ -convertsPerfexCRMLeadToCustomer = $convertsPerfexCRMLeadToCustomer; - $this->createsPerfexCRMCustomerProject = $createsPerfexCRMCustomerProject; - $this->createsPerfexCRMMilestone = $createsPerfexCRMMilestone; - $this->createsPerfexCRMTask = $createsPerfexCRMTask; - $this->fetchesPerfexCRMProject = $fetchesPerfexCRMProject; - $this->fetchesPerfexCRMMilestone = $fetchesPerfexCRMMilestone; - $this->fetchesPerfexCRMTask = $fetchesPerfexCRMTask; - $this->createsPerfexCRMCustomer = $createsPerfexCRMCustomer; - $this->createsPerfexCRMCustomerContact = $createsPerfexCRMCustomerContact; - $this->updatesPerfexCRMCustomer = $updatesPerfexCRMCustomer; - } - - /** - * @param InitialPerfexCRMObject $initialPerfexCRMObject - * @return null|object - * @throws \App\Classes\Exceptions\MalformedRequestException - */ - public function execute(InitialPerfexCRMObject $initialPerfexCRMObject) { - - // Customer has to exist first before Project can appear under it - // Check with Perfex CRM, if this user (email) was previously a lead, should automatically now become a customer - $crmCompany = $initialPerfexCRMObject->getCompanyName(); - $result = $this->convertsPerfexCRMLeadToCustomer->execute($initialPerfexCRMObject->getContactEmail()); - if(isset($result->payload)){ - $crmClientId = $result->payload['client_id']; - if (isset($result->payload['company'])) { - $crmCompany = $result->payload['company']; - } - } - else{ - //if reach this point, this means this user is not a official customer nor is a lead in crm - //Create Customer has 2 parts: Create Company (client), Create Contact - $result = $this->createsPerfexCRMCustomer->execute($crmCompany); - if(is_null($result)){ - $crmCompany = $crmCompany." 2"; - $result = $this->createsPerfexCRMCustomer->execute($crmCompany); - } - - $crmClientId = $result->payload['clientId']; - - $customerContactObject = new CustomerContactObject( - $crmClientId, - $initialPerfexCRMObject->getContactName(), - $initialPerfexCRMObject->getContactName(), - $initialPerfexCRMObject->getContactEmail(), - "pU^T@sC#9Q", - "on", - "on" - ); - $result = $this->createsPerfexCRMCustomerContact->execute($customerContactObject); - } - - //Update custom fields to identify company reference from exchange or shipping portal - $value_exists = false; - if (isset($result->payload['customfields'])) { - foreach ($result->payload['customfields'] as $element) { - if ($element['value'] === $initialPerfexCRMObject->getCompanyReference()) { - $value_exists = true; - break; - } - } - } - if(!$value_exists); - { - $result = $this->updatesPerfexCRMCustomer->execute($crmClientId, $crmCompany, $initialPerfexCRMObject->getCompanyReference()); - } - - // Get existing or create project, project has to exist first before milestone can appear under it - $result = $this->createsPerfexCRMCustomerProject->execute($initialPerfexCRMObject->getProjectName(), $initialPerfexCRMObject->getProjectStatus(), $crmClientId); - if(isset($result->payload)){ //Here means project creation successful - $projectId = $result->payload['project_id']; - } - else{ - $projectId = $this->fetchesPerfexCRMProject->execute($initialPerfexCRMObject->getProjectName(), $crmClientId)->id; - } - - $tasks = $initialPerfexCRMObject->getTaskNames(); - if(count($tasks) > 0){ - - //Create tasks with milestone - for($count=0; $count < count($tasks); $count++) { - $milestoneId = 0; //By default milestoneId is 0, having this set at individual task is optional - if($tasks[$count]['milestone'] != "") //Create milestone only if it is defined - { - // Get existing or create milestone, milestone has to exist first before task can appear under it - $result = $this->createsPerfexCRMMilestone->execute($tasks[$count]['milestone'], $projectId, $count); - if(isset($result->payload)){ - $milestoneId = $result->payload['milestone_id']; - } - else{ - $milestone = $this->fetchesPerfexCRMMilestone->execute($tasks[$count]['milestone'], $projectId); - $array = json_decode(json_encode($milestone), true); - $milestoneId = $array[0]['id']; - } - } - - $taskStatus = PerfexCRMTaskStatus::NOT_STARTED; - if($tasks[$count]['status'] != ''){ - $taskStatus = $tasks[$count]['status']; - } - - // Get existing or create task - $result = $this->createsPerfexCRMTask->execute($tasks[$count]['name'], $tasks[$count]['description'], '', $milestoneId, $projectId, $tasks[$count]['reference'], $tasks[$count]['on_task_completion'],$tasks[$count]['department'], $taskStatus); - if(is_null($result)){ - break; //Breaking the rest of the tasks in array assuming that they are all created as a batch previously - } - } - } - return true; - } - -} diff --git a/app/Classes/Modules/PerfexCRM/Processors/NewLeadTaskToPerfexCRMProcessor.php b/app/Classes/Modules/PerfexCRM/Processors/NewLeadTaskToPerfexCRMProcessor.php index d2fdf961..89b66638 100644 --- a/app/Classes/Modules/PerfexCRM/Processors/NewLeadTaskToPerfexCRMProcessor.php +++ b/app/Classes/Modules/PerfexCRM/Processors/NewLeadTaskToPerfexCRMProcessor.php @@ -4,6 +4,7 @@ namespace App\Classes\Modules\PerfexCRM\Processors; use App\Classes\Modules\PerfexCRM\DataTransferObjects\CreateTaskPerfexCRMObject; use App\Classes\Jobs\CreatePerfexCRMSingleTask; +use App\Classes\ValueObjects\Constants\PerfexCRMTaskPriority; use App\Classes\ValueObjects\Constants\PerfexCRMTasks; use App\Models\Company; @@ -30,7 +31,9 @@ class NewLeadTaskToPerfexCRMProcessor "", "", PerfexCRMTasks::TASK_IDENTIFICATION_1['status'], - PerfexCRMTasks::TASK_IDENTIFICATION_1['department'] + PerfexCRMTasks::TASK_IDENTIFICATION_1['department'], + PerfexCRMTaskPriority::DEFAULT, + "0" ); CreatePerfexCRMSingleTask::dispatch($createTaskPerfexCRMObject); diff --git a/app/Classes/Modules/PerfexCRM/Processors/PackingListToPerfexCRMProcessor.php b/app/Classes/Modules/PerfexCRM/Processors/PackingListToPerfexCRMProcessor.php index 0be1cd0d..b433049b 100644 --- a/app/Classes/Modules/PerfexCRM/Processors/PackingListToPerfexCRMProcessor.php +++ b/app/Classes/Modules/PerfexCRM/Processors/PackingListToPerfexCRMProcessor.php @@ -5,6 +5,7 @@ namespace App\Classes\Modules\PerfexCRM\Processors; use App\Classes\Modules\PerfexCRM\DataTransferObjects\UpdatePerfexCRMObject; use App\Classes\ValueObjects\Constants\PerfexCRMTasks; use App\Classes\Jobs\UpdatePerfexCRM; +use App\Classes\Jobs\UpdatePerfexCRMPrelude; use App\Models\PackingList; use App\Classes\ValueObjects\Constants\PerfexCRMProjectStatus; use Illuminate\Support\Facades\Log; @@ -20,7 +21,6 @@ class PackingListToPerfexCRMProcessor { try { if($packingList->owner instanceof \App\Models\Order) { - Log::error(json_encode($packingList)); $order = $packingList->owner; $companyModule = $order->companyModule()->first(); $connection = $companyModule->inviters()->withPivot('invitee_reference')->first(); @@ -48,7 +48,7 @@ class PackingListToPerfexCRMProcessor PerfexCRMTasks::TASK_LOADED_CONTAINER_2, ] ); - UpdatePerfexCRM::dispatch($updatePerfexCRMObject); + UpdatePerfexCRMPrelude::dispatch($packingList, null, $updatePerfexCRMObject, UpdatePerfexCRM::class, null); } } catch (\Exception $exception){ Log::error(json_encode('PackingListToPerfexCRMProcessor debug:')); diff --git a/app/Classes/Modules/PerfexCRM/Processors/TransactionToPerfexCRMProcessor.php b/app/Classes/Modules/PerfexCRM/Processors/TransactionToPerfexCRMProcessor.php index dc674d0e..d7aeeff2 100644 --- a/app/Classes/Modules/PerfexCRM/Processors/TransactionToPerfexCRMProcessor.php +++ b/app/Classes/Modules/PerfexCRM/Processors/TransactionToPerfexCRMProcessor.php @@ -2,47 +2,19 @@ namespace App\Classes\Modules\PerfexCRM\Processors; -use App\Classes\Modules\PerfexCRM\Processors\UpdatePerfexCRMProcessor; -use App\Classes\Modules\PerfexCRM\Processors\InitializePerfexCRMProcessor; -use App\Classes\Modules\PerfexCRM\Services\Init; -use App\Classes\Modules\Companies\Services\FetchesCompany; use App\Classes\Modules\PerfexCRM\DataTransferObjects\UpdatePerfexCRMObject; -use App\Classes\Modules\PerfexCRM\DataTransferObjects\UpdatePerfexCRMInvoiceObject; -use App\Classes\General\Eloquent\AbstractUpdateRecord; -use App\Classes\ValueObjects\Constants\PerfexCRMMilestones; use App\Classes\ValueObjects\Constants\PerfexCRMTasks; use App\Classes\ValueObjects\Constants\PerfexCRMProjectStatus; use App\Classes\ValueObjects\Constants\ApprovalStatus; use App\Classes\Jobs\UpdatePerfexCRMInvoice; use App\Classes\Jobs\UpdatePerfexCRM; +use App\Classes\Jobs\UpdatePerfexCRMPrelude; +use App\Classes\Jobs\CreatePerfexCRMInvoice; use App\Models\Transaction; use Illuminate\Support\Facades\Log; class TransactionToPerfexCRMProcessor { - /** @var FetchesCompany */ - private $fetchesCompany; - - /** @var UpdatePerfexCRMProcessor */ - private $updatePerfexCRMProcessor; - - /** @var InitializePerfexCRMProcessor */ - private $initializePerfexCRMProcessor; - - /** - * TransactionToPerfexCRMProcessor constructor. - * @param UpdatePerfexCRMProcessor $updatePerfexCRMProcessor - * @param InitializePerfexCRMProcessor $initializePerfexCRMProcessor - * @param FetchesCompany $fetchesCompany - */ - public function __construct(UpdatePerfexCRMProcessor $updatePerfexCRMProcessor, InitializePerfexCRMProcessor $initializePerfexCRMProcessor, FetchesCompany $fetchesCompany) - { - $this->updatePerfexCRMProcessor = $updatePerfexCRMProcessor; - $this->initializePerfexCRMProcessor = $initializePerfexCRMProcessor; - $this->fetchesCompany = $fetchesCompany; - } - - /** * @param Transaction $model * @param int $status @@ -51,50 +23,53 @@ class TransactionToPerfexCRMProcessor */ public function execute(Transaction $model, int $status) { - if($model->owner instanceof \App\Models\Transaction && $status == ApprovalStatus::APPROVED) + try { - $packingList = $model->owner->owner; - $order = $packingList->owner()->first(); - $companyModule = $order->companyModule()->first(); - $companyName = $companyModule->name; - $companyReference = $companyModule->inviters()->withPivot('invitee_reference')->first()->pivot->invitee_reference; - $employee = $companyModule->employees()->first(); - $contactEmail = $employee->email; - $contactName = $employee->name; + if($model->owner instanceof \App\Models\Transaction && $status == ApprovalStatus::APPROVED) + { + $packingList = $model->owner->owner; + $order = $packingList->owner()->first(); + $companyModule = $order->companyModule()->first(); + $companyName = $companyModule->name; + $companyReference = $companyModule->inviters()->withPivot('invitee_reference')->first()->pivot->invitee_reference; + $employee = $companyModule->employees()->first(); + $contactEmail = $employee->email; + $contactName = $employee->name; - $orderReference = $order->reference; - $packingListReference = $packingList->reference; - $projectName = 'IZYIM | X1 Shipping | '.$orderReference.' | '.$packingListReference; + $orderReference = $order->reference; + $packingListReference = $packingList->reference; + $projectName = 'IZYIM | X1 Shipping | '.$orderReference.' | '.$packingListReference; - $bookingMarking = $packingList->id."-".$packingList->owner->id; - $updatePerfexCRMObject = new UpdatePerfexCRMObject( - $companyName, - $companyReference, - $contactName, - $contactEmail, - $bookingMarking, - $projectName, - PerfexCRMProjectStatus::IN_PROGRESS, - [], - [ - PerfexCRMTasks::TASK_1, - PerfexCRMTasks::TASK_POST_PAYMENT_1, - PerfexCRMTasks::TASK_POST_PAYMENT_2, - PerfexCRMTasks::TASK_POST_PAYMENT_3, - PerfexCRMTasks::TASK_POST_PAYMENT_4, - ] - ); + $bookingMarking = $packingList->id."-".$packingList->owner->id; + $updatePerfexCRMObject = new UpdatePerfexCRMObject( + $companyName, + $companyReference, + $contactName, + $contactEmail, + $bookingMarking, + $projectName, + PerfexCRMProjectStatus::IN_PROGRESS, + [], + [ + PerfexCRMTasks::TASK_1, + PerfexCRMTasks::TASK_POST_PAYMENT_1, + PerfexCRMTasks::TASK_POST_PAYMENT_2, + PerfexCRMTasks::TASK_POST_PAYMENT_3, + PerfexCRMTasks::TASK_POST_PAYMENT_4, + ] + ); - UpdatePerfexCRM::dispatch($updatePerfexCRMObject); - - $updatePerfexCRMInvoiceOject = new UpdatePerfexCRMInvoiceObject( - $contactEmail, - $model, - true - ); - UpdatePerfexCRMInvoice::dispatch($updatePerfexCRMInvoiceOject)->delay(6); + UpdatePerfexCRMPrelude::dispatch(null, $model, $updatePerfexCRMObject, UpdatePerfexCRM::class, UpdatePerfexCRMInvoice::class); + } + else if($model->owner instanceof \App\Models\PackingList && $model->status == ApprovalStatus::PENDING_SUBMISSION && $status == ApprovalStatus::APPROVED) + { + CreatePerfexCRMInvoice::dispatch($model); + } + } + catch (\Exception $exception) { + Log::error('TransactionToPerfexCRMProcessor debug:'); + Log::error($exception); } - return true; } } diff --git a/app/Classes/Modules/PerfexCRM/Processors/UpdatePerfexCRMProcessor.php b/app/Classes/Modules/PerfexCRM/Processors/UpdatePerfexCRMProcessor.php index 475a2eaf..7806b161 100644 --- a/app/Classes/Modules/PerfexCRM/Processors/UpdatePerfexCRMProcessor.php +++ b/app/Classes/Modules/PerfexCRM/Processors/UpdatePerfexCRMProcessor.php @@ -11,6 +11,7 @@ use App\Classes\Modules\PerfexCRM\Services\FetchesPerfexCRMMilestone; use App\Classes\Modules\PerfexCRM\Services\FetchesPerfexCRMTask; use App\Classes\Modules\PerfexCRM\Services\CreatesPerfexCRMCustomer; use App\Classes\Modules\PerfexCRM\Services\CreatesPerfexCRMCustomerContact; +use App\Classes\Modules\PerfexCRM\Services\UpdatesPerfexCRMTask; use App\Classes\Modules\PerfexCRM\Services\UpdatesPerfexCRMCustomer; use App\Classes\Modules\PerfexCRM\Services\UpdatesPerfexCRMProject; use App\Classes\Modules\PerfexCRM\DataTransferObjects\CustomerContactObject; @@ -51,8 +52,8 @@ class UpdatePerfexCRMProcessor /** @var CreatesPerfexCRMCustomerContact */ private $createsPerfexCRMCustomerContact; - /** @var UpdatesPerfexCRM */ - private $updatePerfexCRM; + /** @var UpdatesPerfexCRMTask */ + private $updatesPerfexCRMTask; /** @var UpdatesPerfexCRMCustomer */ private $updatesPerfexCRMCustomer; @@ -70,6 +71,7 @@ class UpdatePerfexCRMProcessor * @param FetchesPerfexCRMTask $fetchesPerfexCRMTask * @param CreatesPerfexCRMCustomer $createsPerfexCRMCustomer * @param CreatesPerfexCRMCustomerContact $createsPerfexCRMCustomerContact + * @param UpdatesPerfexCRMTask $updatesPerfexCRMTask * @param UpdatesPerfexCRMCustomer $updatesPerfexCRMCustomer * @param UpdatesPerfexCRMProject $updatesPerfexCRMProject */ @@ -82,6 +84,7 @@ class UpdatePerfexCRMProcessor FetchesPerfexCRMTask $fetchesPerfexCRMTask, CreatesPerfexCRMCustomer $createsPerfexCRMCustomer, CreatesPerfexCRMCustomerContact $createsPerfexCRMCustomerContact, + UpdatesPerfexCRMTask $updatesPerfexCRMTask, UpdatesPerfexCRMCustomer $updatesPerfexCRMCustomer, UpdatesPerfexCRMProject $updatesPerfexCRMProject) { @@ -94,6 +97,7 @@ class UpdatePerfexCRMProcessor $this->fetchesPerfexCRMTask = $fetchesPerfexCRMTask; $this->createsPerfexCRMCustomer = $createsPerfexCRMCustomer; $this->createsPerfexCRMCustomerContact = $createsPerfexCRMCustomerContact; + $this->updatesPerfexCRMTask = $updatesPerfexCRMTask; $this->updatesPerfexCRMCustomer = $updatesPerfexCRMCustomer; $this->updatesPerfexCRMProject = $updatesPerfexCRMProject; } @@ -104,6 +108,7 @@ class UpdatePerfexCRMProcessor * @throws \App\Classes\Exceptions\MalformedRequestException */ public function execute(UpdatePerfexCRMObject $updatePerfexCRMObject) { + $projectId = ""; // Customer has to exist first before Project can appear under it // Check with Perfex CRM, if this user (email) was previously a lead, should automatically now become a customer @@ -154,21 +159,27 @@ class UpdatePerfexCRMProcessor } // Get existing or create project, project has to exist first before milestone can appear under it - $result = $this->createsPerfexCRMCustomerProject->execute($updatePerfexCRMObject->getProjectName(), $updatePerfexCRMObject->getProjectStatus(), $crmClientId); - if(isset($result->payload)){ //Here means project creation successful - $projectId = $result->payload['project_id']; - } - else{ - $project = $this->fetchesPerfexCRMProject->execute($updatePerfexCRMObject->getProjectName(), $crmClientId); - $projectId = $project->id; + $result = $this->fetchesPerfexCRMProject->execute($updatePerfexCRMObject->getProjectName(), $crmClientId); + + if(isset($result->payload)){ + $project = $result->payload[0]; + $projectId = $project['id']; + //if the project status is anything but PerfexCRMProjectStatus::NOT_STARTED, update the project - if($updatePerfexCRMObject->getProjectStatus() != PerfexCRMProjectStatus::NOT_STARTED) + if($updatePerfexCRMObject->getProjectStatus() != PerfexCRMProjectStatus::NOT_STARTED && $project['status'] == PerfexCRMProjectStatus::NOT_STARTED) { $this->updatesPerfexCRMProject->execute($project, $updatePerfexCRMObject->getProjectStatus()); } - } + } + else{ + $result = $this->createsPerfexCRMCustomerProject->execute($updatePerfexCRMObject->getProjectName(), $updatePerfexCRMObject->getProjectStatus(), $crmClientId); + if(isset($result->payload)){ //Here means project creation successful + $projectId = $result->payload['project_id']; + } + } - $tasks = $updatePerfexCRMObject->getTaskNames(); + + $tasks = $updatePerfexCRMObject->getTasks(); if(count($tasks) > 0){ //Create tasks with milestone @@ -177,14 +188,16 @@ class UpdatePerfexCRMProcessor if($tasks[$count]['milestone'] != "") //Create milestone only if it is defined { // Get existing or create milestone, milestone has to exist first before task can appear under it - $result = $this->createsPerfexCRMMilestone->execute($tasks[$count]['milestone'], $projectId, $count); + $result = $this->fetchesPerfexCRMMilestone->execute($tasks[$count]['milestone'], $projectId); if(isset($result->payload)){ - $milestoneId = $result->payload['milestone_id']; + $array = json_decode(json_encode($result->payload[0]), true); + $milestoneId = $array['id']; } else{ - $milestone = $this->fetchesPerfexCRMMilestone->execute($tasks[$count]['milestone'], $projectId); - $array = json_decode(json_encode($milestone), true); - $milestoneId = $array[0]['id']; + $result = $this->createsPerfexCRMMilestone->execute($tasks[$count]['milestone'], $projectId, $count); + if(isset($result->payload)){ + $milestoneId = $result->payload['milestone_id']; + } } } @@ -194,13 +207,25 @@ class UpdatePerfexCRMProcessor } // Get existing or create task - $result = $this->createsPerfexCRMTask->execute($tasks[$count]['name'], $tasks[$count]['description'], '', $milestoneId, $projectId, $tasks[$count]['reference'], $tasks[$count]['on_task_completion'], $tasks[$count]['department'], $taskStatus); - if(is_null($result)){ + $result = $this->fetchesPerfexCRMTask->execute($tasks[$count]['name'], $milestoneId, 'project', $projectId); + if(isset($result->payload)){ break; //Breaking the rest of the tasks in array assuming that they are all created as a batch previously + //The following are code not needed at Shipping Portal, Exchange need certain task's status to be updated dynamically + // if($taskStatus != PerfexCRMTaskStatus::NOT_STARTED && $result->payload[0]['status'] == PerfexCRMTaskStatus::NOT_STARTED) + // { + // $task = $result->payload[0]; + // $result = $this->updatesPerfexCRMTask->execute($task['id'], $task['name'], $task['milestone'], $task['rel_id'], $taskStatus, $task['startdate'], is_null($task['duedate']) ? '': $task['duedate']); + // } + } + else{ + $result = $this->createsPerfexCRMTask->execute($tasks[$count]['name'], $tasks[$count]['description'], '', $milestoneId, $projectId, $tasks[$count]['reference'], $tasks[$count]['on_task_completion'], $tasks[$count]['department'], $taskStatus, $tasks[$count]['priority'], $tasks[$count]['duedate']); } } } - return true; + + $payload = []; + $payload['projectId'] = $projectId; + return (object) $payload; } } diff --git a/app/Classes/Modules/PerfexCRM/Services/CreatesPerfexCRMTask.php b/app/Classes/Modules/PerfexCRM/Services/CreatesPerfexCRMTask.php index 8d75989a..f2f461a4 100644 --- a/app/Classes/Modules/PerfexCRM/Services/CreatesPerfexCRMTask.php +++ b/app/Classes/Modules/PerfexCRM/Services/CreatesPerfexCRMTask.php @@ -15,13 +15,16 @@ class CreatesPerfexCRMTask * @param string $leadId * @param string $milestoneId * @param string $projectId - * @param string $reference, default: '' - * @param string $on_task_completion, default: '' - * @param string $status, default: 1 + * @param string $reference + * @param string $on_task_completion + * @param string $department + * @param string $status + * @param string $priority + * @param string $duedate * @return null|object * @throws MalformedRequestException */ - public function execute(string $taskName, string $taskDescription, string $leadId, string $milestoneId, string $projectId, string $reference = '', string $on_task_completion = '', string $department = '', string $status = "1") { + public function execute(string $taskName, string $taskDescription, string $leadId, string $milestoneId, string $projectId, string $reference, string $on_task_completion, string $department, string $status, string $priority, string $duedate) { try{ $custom_fields = []; if($department != ""){ @@ -43,7 +46,9 @@ class CreatesPerfexCRMTask 'is_system_created' => 1, 'reference' => $reference, 'on_task_completion' => $on_task_completion, - 'custom_fields' => $custom_fields + 'custom_fields' => $custom_fields, + 'priority' => $priority, + 'duedate' => date('Y-m-d', strtotime('+' . $duedate . ' days')), ]; if($leadId != '') { @@ -58,7 +63,9 @@ class CreatesPerfexCRMTask 'is_system_created' => 1, 'reference' => $reference, 'on_task_completion' => $on_task_completion, - 'custom_fields' => $custom_fields + 'custom_fields' => $custom_fields, + 'priority' => $priority, + 'duedate' => date('Y-m-d', strtotime('+' . $duedate . ' days')), ]; } diff --git a/app/Classes/Modules/PerfexCRM/Services/FetchesPerfexCRMMilestone.php b/app/Classes/Modules/PerfexCRM/Services/FetchesPerfexCRMMilestone.php index 8a5ba559..30ae0737 100644 --- a/app/Classes/Modules/PerfexCRM/Services/FetchesPerfexCRMMilestone.php +++ b/app/Classes/Modules/PerfexCRM/Services/FetchesPerfexCRMMilestone.php @@ -16,9 +16,14 @@ class FetchesPerfexCRMMilestone */ public function execute(string $milestoneName, string $projectId) { try{ - $response = Http::withHeaders([ - 'authtoken' => config('perfexcrm.api_key'),]) - ->get(config('perfexcrm.base_url').'/api/milestones/bynameandprojectid/'.rawurlencode($milestoneName).'/'.$projectId); + $data = [ + 'name' => $milestoneName, + 'project_id' => $projectId, + ]; + + $response = Http::asForm()->withHeaders([ + 'authtoken' => config('perfexcrm.api_key')]) + ->post(config('perfexcrm.base_url').'/api/milestones/bynameandprojectid', $data); if($response->successful()){ $data = $response->json(); diff --git a/app/Classes/Modules/PerfexCRM/Services/FetchesPerfexCRMTask.php b/app/Classes/Modules/PerfexCRM/Services/FetchesPerfexCRMTask.php index 97707acb..14aa72a0 100644 --- a/app/Classes/Modules/PerfexCRM/Services/FetchesPerfexCRMTask.php +++ b/app/Classes/Modules/PerfexCRM/Services/FetchesPerfexCRMTask.php @@ -5,27 +5,41 @@ namespace App\Classes\Modules\PerfexCRM\Services; use Illuminate\Support\Facades\Http; use App\Classes\Exceptions\MalformedRequestException; use Illuminate\Support\Facades\Log; +use App\Classes\General\Helper; class FetchesPerfexCRMTask { /** * @param string $taskName * @param string $milestoneId + * @param string $relType + * @param string $relId * @return null|object * @throws MalformedRequestException */ - public function execute(string $taskName, string $milestoneId) { + public function execute(string $taskName, string $milestoneId, string $relType, string $relId) { try{ - $response = Http::withHeaders([ - 'authtoken' => config('perfexcrm.api_key'),]) - ->get(config('perfexcrm.base_url').'/api/tasks/bynameandmilestoneid/'.rawurlencode($taskName).'/'.$milestoneId); + $data = [ + 'name' => $taskName, + 'rel_type' => $relType, + 'rel_id' => $relId, + ]; + + if($milestoneId != '') { + $newItem = ['milestone' => $milestoneId ]; + $data = array_merge($data, $newItem); + } + + $response = Http::asForm()->withHeaders([ + 'authtoken' => config('perfexcrm.api_key')]) + ->post(config('perfexcrm.base_url').'/api/tasks/customsearch', $data); if($response->successful()){ $data = $response->json(); return (object) $data; }else{ - Log::error($response); + Helper::debugLoggerForPerfexCRM($response); return null; } }catch(\Exception $exception){ diff --git a/app/Classes/Modules/PerfexCRM/Services/UpdatesPerfexCRMCustomer.php b/app/Classes/Modules/PerfexCRM/Services/UpdatesPerfexCRMCustomer.php index bdcf7437..b9f90a7c 100644 --- a/app/Classes/Modules/PerfexCRM/Services/UpdatesPerfexCRMCustomer.php +++ b/app/Classes/Modules/PerfexCRM/Services/UpdatesPerfexCRMCustomer.php @@ -6,6 +6,7 @@ use Illuminate\Support\Facades\Http; use App\Classes\Exceptions\MalformedRequestException; use Illuminate\Support\Facades\Log; use App\Classes\ValueObjects\Constants\PerfexCRMCustomFields; +use App\Classes\General\Helper; class UpdatesPerfexCRMCustomer { @@ -37,7 +38,7 @@ class UpdatesPerfexCRMCustomer $data = $response->json(); return (object) $data; }else{ - Log::error($response); + Helper::debugLoggerForPerfexCRM($response); return null; } }catch(\Exception $exception){ diff --git a/app/Classes/Modules/PerfexCRM/Services/UpdatesPerfexCRMProject.php b/app/Classes/Modules/PerfexCRM/Services/UpdatesPerfexCRMProject.php index 6c016ff0..cf782806 100644 --- a/app/Classes/Modules/PerfexCRM/Services/UpdatesPerfexCRMProject.php +++ b/app/Classes/Modules/PerfexCRM/Services/UpdatesPerfexCRMProject.php @@ -17,17 +17,17 @@ class UpdatesPerfexCRMProject public function execute($project, int $status) { try{ $data = [ - 'name' => $project->name, - 'clientid' => $project->clientid, + 'name' => $project['name'], + 'clientid' => $project['clientid'], // 'rel_type' => 'customer', 'billing_type' => 1, - 'start_date' => $project->start_date, + 'start_date' => $project['start_date'], 'status' => $status ]; $response = Http::asJson()->withHeaders([ 'authtoken' => config('perfexcrm.api_key')]) - ->put(config('perfexcrm.base_url').'/api/projects/'.$project->id, $data); + ->put(config('perfexcrm.base_url').'/api/projects/'.$project['id'], $data); if($response->successful()){ $data = $response->json(); diff --git a/app/Classes/Modules/Transactions/ControllersLogic/DeleteTransactionLogic.php b/app/Classes/Modules/Transactions/ControllersLogic/DeleteTransactionLogic.php new file mode 100644 index 00000000..56d24523 --- /dev/null +++ b/app/Classes/Modules/Transactions/ControllersLogic/DeleteTransactionLogic.php @@ -0,0 +1,52 @@ + 'Delete Transaction', + 'message' => 'You have successfully deleted the transaction' + ]; + } + + /** @var FetchesTransaction */ + private $fetchesTransaction; + + /** @var UpdatesTransactionStatus */ + private $updatesTransactionStatus; + + + /** + * SuspendTransactionLogic constructor. + * @param FetchesTransaction $fetchesTransaction + * @param UpdatesTransactionStatus $updatesTransactionStatus + */ + public function __construct(FetchesTransaction $fetchesTransaction, UpdatesTransactionStatus $updatesTransactionStatus) + { + $this->fetchesTransaction = $fetchesTransaction; + $this->updatesTransactionStatus = $updatesTransactionStatus; + } + + + public function logic(Request $request) : JsonResponse + { + $transaction = $this->fetchesTransaction->execute(['id' => $request->route('id')]); + + $transaction->delete(); + + return $this->response([]); + } +} diff --git a/app/Classes/Modules/Transactions/Processors/ApproveShippingInvoiceTransactionProcessor.php b/app/Classes/Modules/Transactions/Processors/ApproveShippingInvoiceTransactionProcessor.php index 852205cb..b8fb81c6 100644 --- a/app/Classes/Modules/Transactions/Processors/ApproveShippingInvoiceTransactionProcessor.php +++ b/app/Classes/Modules/Transactions/Processors/ApproveShippingInvoiceTransactionProcessor.php @@ -75,11 +75,6 @@ class ApproveShippingInvoiceTransactionProcessor $user->notify(new InvoiceIssuedEmail($user, $packingList)); } - // update perfex crm - if(config('perfexcrm.is_enabled') == 'true'){ - CreatePerfexCRMInvoice::dispatch($invoice_transaction); - } - return; } diff --git a/app/Classes/Modules/Transactions/Services/UpdatesTransactionStatus.php b/app/Classes/Modules/Transactions/Services/UpdatesTransactionStatus.php index 2928f36f..85b85d1f 100644 --- a/app/Classes/Modules/Transactions/Services/UpdatesTransactionStatus.php +++ b/app/Classes/Modules/Transactions/Services/UpdatesTransactionStatus.php @@ -5,25 +5,19 @@ namespace App\Classes\Modules\Transactions\Services; use App\Classes\General\Eloquent\AbstractUpdateRecord; use App\Models\Transaction; use App\Classes\Modules\PerfexCRM\Processors\TransactionToPerfexCRMProcessor; -use App\Classes\Modules\PerfexCRM\Processors\NewLeadTaskToPerfexCRMProcessor; class UpdatesTransactionStatus extends AbstractUpdateRecord { /** @var TransactionToPerfexCRMProcessor */ private $transactionToPerfexCRMProcessor; - /** @var NewLeadTaskToPerfexCRMProcessor */ - private $newLeadTaskToPerfexCRMProcessor; - /** * UpdatesTransactionStatus constructor. * @param TransactionToPerfexCRMProcessor $transactionToPerfexCRMProcessor - * @param NewLeadTaskToPerfexCRMProcessor $newLeadTaskToPerfexCRMProcessor */ - public function __construct(TransactionToPerfexCRMProcessor $transactionToPerfexCRMProcessor, NewLeadTaskToPerfexCRMProcessor $newLeadTaskToPerfexCRMProcessor) + public function __construct(TransactionToPerfexCRMProcessor $transactionToPerfexCRMProcessor) { $this->transactionToPerfexCRMProcessor = $transactionToPerfexCRMProcessor; - $this->newLeadTaskToPerfexCRMProcessor = $newLeadTaskToPerfexCRMProcessor; } /** @@ -34,11 +28,13 @@ class UpdatesTransactionStatus extends AbstractUpdateRecord */ public function execute(Transaction $model, int $status) { - if(config('perfexcrm.is_enabled') == 'true'){ - $this->transactionToPerfexCRMProcessor->execute($model, $status); - // $this->newLeadTaskToPerfexCRMProcessor->execute(); - } + $transaction = clone($model); $model->status = $status; - return $this->handler($model); + $result = $this->handler($model); + + if(config('perfexcrm.is_enabled') == 'true'){ + $this->transactionToPerfexCRMProcessor->execute($transaction, $status); + } + return $result; } } diff --git a/app/Classes/ValueObjects/Constants/CompanyType.php b/app/Classes/ValueObjects/Constants/CompanyType.php index 61918925..7f12da36 100644 --- a/app/Classes/ValueObjects/Constants/CompanyType.php +++ b/app/Classes/ValueObjects/Constants/CompanyType.php @@ -8,4 +8,9 @@ final class CompanyType { public const COMPANY_BUSINESS = 1; + public const COMPANY_TYPE_ID = [ + self::PERSONAL_BUSINESS => "Personal Business", + self::COMPANY_BUSINESS => "Company Business", + + ]; } diff --git a/app/Classes/ValueObjects/Constants/PerfexCRMTaskPriority.php b/app/Classes/ValueObjects/Constants/PerfexCRMTaskPriority.php new file mode 100644 index 00000000..ead37aba --- /dev/null +++ b/app/Classes/ValueObjects/Constants/PerfexCRMTaskPriority.php @@ -0,0 +1,17 @@ + '', 'on_task_completion' => '', 'department' => '', - 'status' => PerfexCRMTaskStatus::COMPLETED + 'status' => PerfexCRMTaskStatus::COMPLETED, + 'priority' => PerfexCRMTaskPriority::DEFAULT, + 'duedate' => 0 ]; public const TASK_POST_PAYMENT_1 = [ @@ -31,23 +33,21 @@ class PerfexCRMTasks 'reference' => 'TASK_POST_PAYMENT_1', 'on_task_completion' => 'TASK_POST_PAYMENT_2', 'department' => 'Accounts', - 'status' => PerfexCRMTaskStatus::IN_PROGRESS + 'status' => PerfexCRMTaskStatus::IN_PROGRESS, + 'priority' => PerfexCRMTaskPriority::HIGH, + 'duedate' => 0 ]; public const TASK_POST_PAYMENT_2 = [ 'name' => 'Approve Payment', 'description' => '○ Purpose: To verify and approve the customer\'s payment on IZYIM
- ○ Initial Status: Not Started
- ○ Deadline:Same day
- ○ Responsible department: Accounts
- ○ Next step: Change the status of the Issue Shipping Autocount Invoice operation to "In Progress"
- ○ Additional details: When the payment method is FPX or Wallet this task is performed automatically by the system.
- ○ Dependencies: Map Transaction operation must be completed before this operation can begin.
- ○ Outcomes: The payment will be approved in IZYIM, which will release the customer’s goods for delivery.
', + ○ Amount To be Approve: RM {amount}
', 'milestone' => '', 'reference' => 'TASK_POST_PAYMENT_2', 'on_task_completion' => 'TASK_POST_PAYMENT_3', 'department' => 'Accounts', - 'status' => '' + 'status' => '', + 'priority' => PerfexCRMTaskPriority::HIGH, + 'duedate' => 0 ]; public const TASK_POST_PAYMENT_3 = [ 'name' => 'Issue Shipping Autocount Invoince', @@ -63,7 +63,22 @@ class PerfexCRMTasks 'reference' => 'TASK_POST_PAYMENT_3', 'on_task_completion' => 'TASK_POST_PAYMENT_4', 'department' => 'Accounts', - 'status' => '' + 'status' => '', + 'priority' => PerfexCRMTaskPriority::MEDIUM, + 'duedate' => 1 + ]; + public const TASK_POST_PAYMENT_3_1 = [ + 'name' => 'Issue Shipping Autocount OR', + 'description' => '○ Purpose: To issue an invoice for the customer\'s payment in accounting software.
+ ○ Note: Customer Actually Upload Bank Slip or Not, If not, Invoice Will Not be Exported
+ ○ {link_autocount_or}
', + 'milestone' => '', + 'reference' => 'TASK_POST_PAYMENT_3_1', + 'on_task_completion' => 'TASK_POST_PAYMENT_4', + 'department' => 'Accounts', + 'status' => '', + 'priority' => PerfexCRMTaskPriority::DEFAULT, + 'duedate' => 0 ]; public const TASK_POST_PAYMENT_4 = [ 'name' => 'Knockoff Invoice', @@ -79,36 +94,35 @@ class PerfexCRMTasks 'reference' => 'TASK_POST_PAYMENT_4', 'on_task_completion' => '', 'department' => 'Accounts', - 'status' => '' + 'status' => '', + 'priority' => PerfexCRMTaskPriority::MEDIUM, + 'duedate' => 1 ]; public const TASK_LOADED_CONTAINER_1 = [ 'name' => 'Generate Shipping Invoices', 'description' => '○ Purpose: -
- ○ Initial Status: In Progress
- ○ Deadline: Next day
- ○ Responsible department: Operation
- ○ Assignee: -
- ○ Next step: Approve Shipping Invoice change to in progress.
', + ○ Link to order page: {link_order}
', 'milestone' => '', 'reference' => 'TASK_LOADED_CONTAINER_1', 'on_task_completion' => 'TASK_LOADED_CONTAINER_2', 'department' => 'Operations', - 'status' => PerfexCRMTaskStatus::IN_PROGRESS + 'status' => PerfexCRMTaskStatus::IN_PROGRESS, + 'priority' => PerfexCRMTaskPriority::HIGH, + 'duedate' => 1 ]; public const TASK_LOADED_CONTAINER_2 = [ 'name' => 'Approve Shipping Invoices', 'description' => '○ Purpose: -
- ○ Initial Status: Not Starteds
- ○ Deadline: Next day
- ○ Responsible department: Customer Services
- ○ Next step: -
', + ○ Link to refer Pay On Behalf or Any extra charge: : {link_perfex}
', 'milestone' => '', 'reference' => 'TASK_LOADED_CONTAINER_2', 'on_task_completion' => '', 'department' => 'Customer Services', - 'status' => '' + 'status' => '', + 'priority' => PerfexCRMTaskPriority::HIGH, + 'duedate' => 1 ]; @@ -126,6 +140,8 @@ class PerfexCRMTasks 'reference' => 'TASK_IDENTIFICATION_1', 'on_task_completion' => '', 'department' => 'Operations', - 'status' => PerfexCRMTaskStatus::IN_PROGRESS + 'status' => PerfexCRMTaskStatus::IN_PROGRESS, + 'priority' => PerfexCRMTaskPriority::DEFAULT, + 'duedate' => 0 ]; } diff --git a/app/Classes/ValueObjects/Constants/RoleTypes.php b/app/Classes/ValueObjects/Constants/RoleTypes.php index 3027bcb1..b24a60c7 100644 --- a/app/Classes/ValueObjects/Constants/RoleTypes.php +++ b/app/Classes/ValueObjects/Constants/RoleTypes.php @@ -16,4 +16,10 @@ final class RoleTypes public const USER = 3; + public const USER_TYPE_ID = [ + self::SHADOW_ADMIN => "Shadow Admin", + self::SUPER_ADMIN => "Super Admin", + self::ADMIN => "Admin", + self::USER => "User", + ]; } \ No newline at end of file diff --git a/app/Classes/ValueObjects/Constants/TransactionType.php b/app/Classes/ValueObjects/Constants/TransactionType.php index cdfb5f73..3e20545f 100644 --- a/app/Classes/ValueObjects/Constants/TransactionType.php +++ b/app/Classes/ValueObjects/Constants/TransactionType.php @@ -35,4 +35,10 @@ final class TransactionType { // public const SHIPPING_COST = 14; public const GROUP_PAYMENT = 15; + + public const TRANSACTION_TYPE_ID = [ + self::SHIPPING_INVOICE => "Shipping Invoice", + self::PAYMENT => "Payment", + ]; + } diff --git a/app/Classes/ValueObjects/Constants/WarehouseReferences.php b/app/Classes/ValueObjects/Constants/WarehouseReferences.php index 966ae665..b62a9938 100644 --- a/app/Classes/ValueObjects/Constants/WarehouseReferences.php +++ b/app/Classes/ValueObjects/Constants/WarehouseReferences.php @@ -22,6 +22,10 @@ final class WarehouseReferences { public const VT_SARAWAK = 'SRW-V01'; + public const YD_FS_WEST_MALAYSIA = 'FS-V01'; + + public const YD_FS_EAST_MALAYSIA = 'FS-V02'; + public const VT_DESTINATION_WAREHOUSE = [ 1 => self::VT_KLANG, 2 => self::VT_KLANG, diff --git a/app/Console/Commands/AuditBillplzInvoice.php b/app/Console/Commands/AuditBillplzInvoice.php index 19c974d9..753905be 100644 --- a/app/Console/Commands/AuditBillplzInvoice.php +++ b/app/Console/Commands/AuditBillplzInvoice.php @@ -24,7 +24,7 @@ class AuditBillplzInvoice extends Command * * @var string */ - protected $description = 'Check all unpaid invoice but marked at paid at out system'; + protected $description = 'Check all unpaid invoice but marked paid at our system'; /** * Create a new command instance. diff --git a/app/Console/Commands/BillplzFailedCallbackPayment.php b/app/Console/Commands/BillplzFailedCallbackPayment.php deleted file mode 100644 index e2b69858..00000000 --- a/app/Console/Commands/BillplzFailedCallbackPayment.php +++ /dev/null @@ -1,98 +0,0 @@ -appendToOutput(Carbon::now() . ' : Billplz Failled Callback cron started.'); - $this->outputArray = []; - $start = new Carbon(); - - $approvalStatusArray = ApprovalStatus::APPROVAL_STATUS_ID; - - $transactions = Transaction::where('type', TransactionType::PAYMENT)->where('payment_method', PaymentMethodType::PAYMENT_GATEWAY)->whereIn('status', [ApprovalStatus::REJECTED, ApprovalStatus::PENDING_VERIFICATION])->get(); - $totalTransactions = count($transactions); - $counter = 1; - $totalAmount = 0; - foreach ($transactions as $transaction){ - $response = Http::withBasicAuth(config('billplz.api_key').':', '')->get(config('billplz.base_url').'/api/v3/bills/'.$transaction->payment_reference); - - if($response->successful()){ - $data = $response->json(); - if($data['paid']){ - $totalAmount += $transaction->amount; - $this->appendToOutput($counter . ' of ' . $totalTransactions . '. Order: '. $transaction->owner->owner->owner->reference . ' - Date: '.$transaction->owner->created_at->format('d-m-Y').' - Amount: '. $transaction->amount . '. Status: ' . $approvalStatusArray[$transaction->status]); - } else { - // $totalAmount += $transaction->amount; - // $this->appendToOutput($counter . ' of ' . $totalTransactions . '. Order: '. $transaction->owner->owner->owner->reference . ' - Date: '.$transaction->owner->created_at->format('d-m-Y').' - Amount: '. $transaction->amount); - } - }else{ - $this->appendToOutput("billplz error
"); - } - $counter++; - } - - $end = new Carbon(); - $elapsedTime = $start->diff($end)->format('%H:%I:%S'); - - $this->appendToOutput(Carbon::now() . ' : Done Billplz Failled Callback. ElapsedTime: ' . $elapsedTime . '. Total: ' . $totalAmount); - - $this->output = json_encode($this->outputArray); - } - - public function appendToOutput($string) { - $this->outputArray[] = $string; - $this->info($string); - } - - public function getOutput() - { - return $this->output; - } -} diff --git a/app/Console/Commands/CheckDeletedInvoiceButPaid.php b/app/Console/Commands/CheckDeletedInvoiceButPaid.php new file mode 100644 index 00000000..e89d80a3 --- /dev/null +++ b/app/Console/Commands/CheckDeletedInvoiceButPaid.php @@ -0,0 +1,86 @@ +info(Carbon::now() . ' : Start Check all deleted invoice but has completed payment.'); + $start = new Carbon(); + + $totalAmount = 0; + + $softDeletedTransactions = Transaction::onlyTrashed()->where('type', TransactionType::SHIPPING_INVOICE)->whereHas('transactions', function (Builder $query) { + $query->where('type', TransactionType::PAYMENT)->where('payment_method', PaymentMethodType::PAYMENT_GATEWAY); + })->get(); + + foreach ($softDeletedTransactions as $invoice) { + $invoice_payments = $invoice->transactions()->payments()->get(); + + foreach($invoice_payments as $invoice_payment) { + + $response = Http::withBasicAuth(config('billplz.api_key').':', '')->get(config('billplz.base_url').'/api/v3/bills/'.$invoice_payment->payment_reference); + + if($response->successful()){ + $data = $response->json(); + + $orderReference = $invoice->owner->owner->reference ?? null; + + if($data['paid']){ + $this->info('Invoice id: ' . $invoice->id. '. Payment id: ' . $invoice_payment->id . '. Order: ' . $orderReference); + } else { + + } + }else{ + $this->info("billplz error
"); + } + } + } + + $end = new Carbon(); + $elapsedTime = $start->diff($end)->format('%H:%I:%S'); + + $this->info(Carbon::now() . ' : Done Check all deleted invoice but has completed payment. ElapsedTime: ' . $elapsedTime . '. Total: ' . $totalAmount); + } +} diff --git a/app/Console/Commands/FixBillplzFailedCallbackPayment.php b/app/Console/Commands/FixBillplzFailedCallbackPayment.php new file mode 100644 index 00000000..a3f2ebb4 --- /dev/null +++ b/app/Console/Commands/FixBillplzFailedCallbackPayment.php @@ -0,0 +1,185 @@ +getBillplzBill = $getBillplzBill; + $this->fetchesTransaction = $fetchesTransaction; + $this->updatesTransactionStatus = $updatesTransactionStatus; + $this->updateDoFromVTPortalProcessor = $updateDoFromVTPortalProcessor; + $this->updateDoFromYDPortalProcessor = $updateDoFromYDPortalProcessor; + } + + /** + * Execute the console command. + * + * @return int + */ + public function handle() + { + ini_set('memory_limit', '-1'); + + $this->info(Carbon::now() . ' : Fix failled callback from billplz cron started.'); + $this->outputArray = []; + $start = new Carbon(); + + $approvalStatusArray = ApprovalStatus::APPROVAL_STATUS_ID; + + $transactions = Transaction::where('type', TransactionType::PAYMENT)->where('payment_method', PaymentMethodType::PAYMENT_GATEWAY)->whereNotIn('status', [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED])->get(); + $totalTransactions = count($transactions); + $counter = 1; + $totalAmount = 0; + foreach ($transactions as $transaction){ + $response = Http::withBasicAuth(config('billplz.api_key').':', '')->get(config('billplz.base_url').'/api/v3/bills/'.$transaction->payment_reference); + + if($response->successful()){ + $data = $response->json(); + if($data['paid']){ + $totalAmount += $transaction->amount; + $invoiceStatus = null; + + switch($transaction->owner->status) { + case 3: + $invoiceStatus = 'Payment Completed'; + break; + case 5: + $invoiceStatus = 'Dispute in progress'; + break; + case 6: + $invoiceStatus = 'Cancelled Invoice'; + break; + default: + $invoiceStatus = 'Pending Payment'; + } + + $order = $transaction->owner->owner->owner; + + if (in_array($invoiceStatus , ['Pending Payment', 'Payment Completed'])) { + // code here + + // $billPlz = $this->getBillplzBill->execute($billplzXSignatureObject->getBillPlzId()); + + // if(!$billPlz) throw new ResourceNotFoundException('Billplz bill not found.'); + + // $transaction = $this->fetchesTransaction->execute(['payment_reference' => $billplzXSignatureObject->getBillPlzId()]); + + $invoice = $transaction->owner; + $packingList = $invoice->owner; + $order = $packingList->owner; + + $status = ApprovalStatus::PENDING_VERIFICATION; + + if($data['state'] === 'paid') { + $status = ApprovalStatus::APPROVED; + } + + // if($data->state === 'due') { + // $status = $billplzXSignatureObject->getStatus() === 'failed' ? ApprovalStatus::REJECTED : ApprovalStatus::PENDING_VERIFICATION; + // } + + // $token = Auth::fromUser(User::find(1)); + // $request->headers->set('Authorization', 'Bearer '.$token); + + $this->updatesTransactionStatus->execute($transaction, $status); + + $totalPaidAmount = $invoice->transactions->where('type', TransactionType::PAYMENT)->whereIn('status', [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED])->sum('amount'); + + if(($invoice->amount - $totalPaidAmount) < 0.01) { + $this->updatesTransactionStatus->execute($invoice, ApprovalStatus::COMPLETED); + + $packingList->status = ApprovalStatus::APPROVED; + $packingList->save(); + + if(app()->environment('production')){ + $this->updateDoFromVTPortalProcessor->execute($packingList); + $this->updateDoFromYDPortalProcessor->execute($packingList); + } + + $this->info('Updated invoice ' . $counter . ' of ' . $totalTransactions . '. Order: '. $order->reference . ' - Date: '.$transaction->owner->created_at->format('d-m-Y').' - Amount: '. $transaction->amount . '. Status: ' . $approvalStatusArray[$transaction->status] . '. Invoice Status: ' . $invoiceStatus); + } else { + $this->info('Failed to update invoice due to unsufficeint payment ' . $counter . ' of ' . $totalTransactions . '. Order: '. $order->reference . ' - Date: '.$transaction->owner->created_at->format('d-m-Y').' - Amount: '. $transaction->amount . '. Status: ' . $approvalStatusArray[$transaction->status] . '. Invoice Status: ' . $invoiceStatus); + } + + + } else { + if(!$order instanceof Order) { + $this->info("Error transaction id:" . $transaction->id . 'Type: ' . get_class($order)); + } else { + $this->info($counter . ' of ' . $totalTransactions . '. Order: '. $order->reference . ' - Date: '.$transaction->owner->created_at->format('d-m-Y').' - Amount: '. $transaction->amount . '. Status: ' . $approvalStatusArray[$transaction->status] . '. Invoice Status: ' . $invoiceStatus); + } + } + + } else { + // $totalAmount += $transaction->amount; + // $this->appendToOutput($counter . ' of ' . $totalTransactions . '. Order: '. $transaction->owner->owner->owner->reference . ' - Date: '.$transaction->owner->created_at->format('d-m-Y').' - Amount: '. $transaction->amount); + } + }else{ + $this->info("billplz error
"); + } + $counter++; + } + + $end = new Carbon(); + $elapsedTime = $start->diff($end)->format('%H:%I:%S'); + + $this->info(Carbon::now() . ' : Done Billplz Failled Callback. ElapsedTime: ' . $elapsedTime . '. Total: ' . $totalAmount); + } +} diff --git a/app/Console/Commands/ShowBillplzPaymentStatus.php b/app/Console/Commands/ShowBillplzPaymentStatus.php new file mode 100644 index 00000000..a8fe7ae9 --- /dev/null +++ b/app/Console/Commands/ShowBillplzPaymentStatus.php @@ -0,0 +1,69 @@ +info(Carbon::now() . ' : Show Billplz payment status started.'); + $start = new Carbon(); + + $billplz_id = $this->argument('billplz_id'); + $billplz_id = explode(",", $billplz_id); + + foreach ($billplz_id as $payment) { + $response = Http::withBasicAuth(config('billplz.api_key').':', '')->get(config('billplz.base_url').'/api/v3/bills/'.$payment); + if($response->successful()){ + $data = $response->json(); + dump($data); + }else{ + $this->info("billplz error
"); + } + } + + $end = new Carbon(); + $elapsedTime = $start->diff($end)->format('%H:%I:%S'); + + $this->info(Carbon::now() . ' : Done Showing Billplz payment status. ElapsedTime: ' . $elapsedTime); + } +} diff --git a/app/Console/Commands/ShowFixBillplzFailedCallbackPayment.php b/app/Console/Commands/ShowFixBillplzFailedCallbackPayment.php new file mode 100644 index 00000000..b21902c2 --- /dev/null +++ b/app/Console/Commands/ShowFixBillplzFailedCallbackPayment.php @@ -0,0 +1,136 @@ +getBillplzBill = $getBillplzBill; + $this->fetchesTransaction = $fetchesTransaction; + $this->updatesTransactionStatus = $updatesTransactionStatus; + $this->updateDoFromVTPortalProcessor = $updateDoFromVTPortalProcessor; + $this->updateDoFromYDPortalProcessor = $updateDoFromYDPortalProcessor; + } + + /** + * Execute the console command. + * + * @return int + */ + public function handle() + { + ini_set('memory_limit', '-1'); + + $this->info(Carbon::now() . ' : Billplz Failled Callback cron started.'); + $this->outputArray = []; + $start = new Carbon(); + + $approvalStatusArray = ApprovalStatus::APPROVAL_STATUS_ID; + + $transactions = Transaction::where('type', TransactionType::PAYMENT)->where('payment_method', PaymentMethodType::PAYMENT_GATEWAY)->whereNotIn('status', [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED])->get(); + $totalTransactions = count($transactions); + $counter = 1; + $totalAmount = 0; + foreach ($transactions as $transaction){ + $response = Http::withBasicAuth(config('billplz.api_key').':', '')->get(config('billplz.base_url').'/api/v3/bills/'.$transaction->payment_reference); + + if($response->successful()){ + $data = $response->json(); + if($data['paid']){ + $totalAmount += $transaction->amount; + $invoiceStatus = null; + + switch($transaction->owner->status) { + case 3: + $invoiceStatus = 'Payment Completed'; + break; + case 5: + $invoiceStatus = 'Dispute in progress'; + break; + case 6: + $invoiceStatus = 'Cancelled Invoice'; + break; + default: + $invoiceStatus = 'Pending Payment'; + } + + $order = $transaction->owner->owner->owner; + + if(!$order instanceof Order) { + $this->info("Error transaction id:" . $transaction->id . 'Type: ' . get_class($order)); + } else { + $this->info($counter . ' of ' . $totalTransactions . '. Order: '. $order->reference . ' - Date: '.$transaction->owner->created_at->format('d-m-Y').' - Amount: '. $transaction->amount . '. Status: ' . $approvalStatusArray[$transaction->status] . '. Invoice Status: ' . $invoiceStatus); + } + + } else { + // $totalAmount += $transaction->amount; + // $this->appendToOutput($counter . ' of ' . $totalTransactions . '. Order: '. $transaction->owner->owner->owner->reference . ' - Date: '.$transaction->owner->created_at->format('d-m-Y').' - Amount: '. $transaction->amount); + } + }else{ + $this->info("billplz error
"); + } + $counter++; + } + + $end = new Carbon(); + $elapsedTime = $start->diff($end)->format('%H:%I:%S'); + + $this->info(Carbon::now() . ' : Done Billplz Failled Callback. ElapsedTime: ' . $elapsedTime . '. Total: ' . $totalAmount); + } +} diff --git a/app/Console/Commands/SuccessUpdatePaymentStatusButFailedCallback.php b/app/Console/Commands/SuccessUpdatePaymentStatusButFailedCallback.php new file mode 100644 index 00000000..078cb171 --- /dev/null +++ b/app/Console/Commands/SuccessUpdatePaymentStatusButFailedCallback.php @@ -0,0 +1,138 @@ +getBillplzBill = $getBillplzBill; + $this->fetchesTransaction = $fetchesTransaction; + $this->updatesTransactionStatus = $updatesTransactionStatus; + $this->updateDoFromVTPortalProcessor = $updateDoFromVTPortalProcessor; + $this->updateDoFromYDPortalProcessor = $updateDoFromYDPortalProcessor; + } + + /** + * Execute the console command. + * + * @return int + */ + public function handle() + { + ini_set('memory_limit', '-1'); + + $this->info(Carbon::now() . ' : Billplz Failled Callback cron started.'); + $this->outputArray = []; + $start = new Carbon(); + + $approvalStatusArray = ApprovalStatus::APPROVAL_STATUS_ID; + + $transactions = Transaction::where('type', TransactionType::PAYMENT) + ->where('payment_method', PaymentMethodType::PAYMENT_GATEWAY) + ->whereIn('status', [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED]) + ->get(); + + foreach ($transactions as $payment) { + $invoice = $payment->owner ?? null; + if (!$invoice) { + $this->info('Payment has no owner. Payment ID: ' . $payment->id); + continue; + } + + $packingList = $invoice->owner ?? null; + if (!$packingList) { + $this->info('Invoice has no owner. Invoice ID: ' . $invoice->id); + continue; + } + + $order = $packingList->owner; + if (!$invoice) { + $this->info('PackingList has no owner. PackingList ID: ' . $packingList->id); + continue; + } + + if ($invoice->status == ApprovalStatus::APPROVED) { + + $totalPaidAmount = $invoice->transactions->where('type', TransactionType::PAYMENT)->whereIn('status', [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED])->sum('amount'); + + if(($invoice->amount - $totalPaidAmount) < 0.01) { + $this->updatesTransactionStatus->execute($invoice, ApprovalStatus::COMPLETED); + + $packingList->status = ApprovalStatus::APPROVED; + $packingList->save(); + + if(app()->environment('production')){ + $this->updateDoFromVTPortalProcessor->execute($packingList); + $this->updateDoFromYDPortalProcessor->execute($packingList); + } + + dump('Updated invoice ' . $invoice->id . '. Order: '. $order->reference); + } else { + $this->info('Failed Update invoice ' . $invoice->id . ' because payment not enough. Invoice Amount: ' . $invoice->amount . ' . Paid Amount: ' . $totalPaidAmount . ' . Order: '. $order->reference); + } + } + } + + $end = new Carbon(); + $elapsedTime = $start->diff($end)->format('%H:%I:%S'); + + $this->info(Carbon::now() . ' : Done Billplz Failled Callback. ElapsedTime: ' . $elapsedTime ); + } +} diff --git a/app/Console/Commands/debugBillplzFailedPayment.php b/app/Console/Commands/debugBillplzFailedPayment.php deleted file mode 100644 index 729ecfee..00000000 --- a/app/Console/Commands/debugBillplzFailedPayment.php +++ /dev/null @@ -1,77 +0,0 @@ -where('payment_method', PaymentMethodType::PAYMENT_GATEWAY)->whereNotIn('status', [ApprovalStatus::COMPLETED, ApprovalStatus::APPROVED])->get(); - - $i = 0; - $totalAmount = 0; - foreach ($transactions as $transaction){ - $response = Http::withBasicAuth(config('billplz.api_key').':', '')->get(config('billplz.base_url').'/api/v3/bills/'.$transaction->payment_reference); - - // dd($response); - - // dd($transaction->owner->owner->owner->reference); - - if($response->successful()){ - $data = $response->json(); - if($data['paid']){ - if (!in_array($transaction->status, [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED])) { - $this->returnLog('Paid transaction', $transaction); - } - } - // else { - // $totalAmount += $transaction->amount; - // $this->returnLog('Unpaid Transaction', $transaction); - // } - }else{ - $this->returnLog('billplz error', $transaction); - } - } - } - - public function returnLog($text, $transaction) { - $approvalStatusArray = ApprovalStatus::APPROVAL_STATUS_ID; - $this->info($text . ' - id: '. $transaction->id . '. Order Marking: '. $transaction->owner->owner->owner->reference . ' - Date: '.$transaction->created_at->format('d-m-Y').' - Amount: '. $transaction->amount . '. Current Status: ' . $approvalStatusArray[$transaction->status]); - } -} diff --git a/app/Console/Kernel.php b/app/Console/Kernel.php index 2986eb25..259d5692 100644 --- a/app/Console/Kernel.php +++ b/app/Console/Kernel.php @@ -47,6 +47,11 @@ class Kernel extends ConsoleKernel ->hourly() ->withoutOverlapping() ->appendOutputTo (storage_path().'/logs/auto_generate_invoice.log'); + + $schedule->command('billplz-failed-callback:fix') + ->dailyAt('00:00') + ->withoutOverlapping() + ->appendOutputTo (storage_path().'/logs/dix_failed_callback_from_billplz.log'); } /** diff --git a/app/Http/Controllers/Accounts/UpdateUserRoleController.php b/app/Http/Controllers/Accounts/UpdateUserRoleController.php new file mode 100644 index 00000000..aef992c8 --- /dev/null +++ b/app/Http/Controllers/Accounts/UpdateUserRoleController.php @@ -0,0 +1,19 @@ +execute($request); + } +} \ No newline at end of file diff --git a/app/Http/Controllers/Companies/UpdateCompanyTypeController.php b/app/Http/Controllers/Companies/UpdateCompanyTypeController.php new file mode 100644 index 00000000..44f39a6f --- /dev/null +++ b/app/Http/Controllers/Companies/UpdateCompanyTypeController.php @@ -0,0 +1,20 @@ +execute($request); + } +} diff --git a/app/Http/Controllers/Contacts/UpdateContactController.php b/app/Http/Controllers/Contacts/UpdateContactController.php new file mode 100644 index 00000000..fcda33a2 --- /dev/null +++ b/app/Http/Controllers/Contacts/UpdateContactController.php @@ -0,0 +1,20 @@ +execute($request); + } + +} \ No newline at end of file diff --git a/app/Http/Controllers/Orders/DownloadOrderQrPdfController.php b/app/Http/Controllers/Orders/DownloadOrderQrPdfController.php index 11837206..29247dd0 100644 --- a/app/Http/Controllers/Orders/DownloadOrderQrPdfController.php +++ b/app/Http/Controllers/Orders/DownloadOrderQrPdfController.php @@ -41,7 +41,7 @@ class DownloadOrderQrPdfController $warehousePrefix = 'YW/'; } - if(in_array($warehouse->reference,[WarehouseReferences::YD_GUANG_ZHOU, WarehouseReferences::YD_GUANG_ZHOU_2])){ + if(in_array($warehouse->reference,[WarehouseReferences::YD_GUANG_ZHOU, WarehouseReferences::YD_GUANG_ZHOU_2, WarehouseReferences::YD_FS_EAST_MALAYSIA, WarehouseReferences::YD_FS_WEST_MALAYSIA])){ $warehousePrefix = 'YD/'; if(strtolower($deliveryAddress->state->name) === 'sabah' || strtolower($deliveryAddress->state->name) === 'labuan' || in_array(strtolower($deliveryAddress->district->name), ['limbang', 'lawas'])) { diff --git a/app/Http/Controllers/Orders/FetchOrderV2Controller.php b/app/Http/Controllers/Orders/FetchOrderV2Controller.php new file mode 100644 index 00000000..45161f7f --- /dev/null +++ b/app/Http/Controllers/Orders/FetchOrderV2Controller.php @@ -0,0 +1,20 @@ +execute($request); + } +} \ No newline at end of file diff --git a/app/Http/Controllers/Orders/ListOrdersV2Controller.php b/app/Http/Controllers/Orders/ListOrdersV2Controller.php new file mode 100644 index 00000000..f52d206d --- /dev/null +++ b/app/Http/Controllers/Orders/ListOrdersV2Controller.php @@ -0,0 +1,22 @@ +execute($request); + } +} diff --git a/app/Http/Controllers/PackingLists/DeletePackingListByPackageIdController.php b/app/Http/Controllers/PackingLists/DeletePackingListByPackageIdController.php new file mode 100644 index 00000000..53008334 --- /dev/null +++ b/app/Http/Controllers/PackingLists/DeletePackingListByPackageIdController.php @@ -0,0 +1,20 @@ +execute($request); + } + +} diff --git a/app/Http/Controllers/Transactions/DeleteTransactionController.php b/app/Http/Controllers/Transactions/DeleteTransactionController.php new file mode 100644 index 00000000..a9dee9ba --- /dev/null +++ b/app/Http/Controllers/Transactions/DeleteTransactionController.php @@ -0,0 +1,21 @@ +execute($request); + } +} diff --git a/app/Http/Kernel.php b/app/Http/Kernel.php index 79e670f6..dc3bc265 100644 --- a/app/Http/Kernel.php +++ b/app/Http/Kernel.php @@ -44,6 +44,11 @@ class Kernel extends HttpKernel 'throttle:300,1', \Illuminate\Routing\Middleware\SubstituteBindings::class, ], + + 'apipub' => [ + // \Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class, + \Illuminate\Routing\Middleware\SubstituteBindings::class, + ], ]; /** @@ -63,6 +68,7 @@ class Kernel extends HttpKernel 'signed' => \Illuminate\Routing\Middleware\ValidateSignature::class, 'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class, 'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class, - 'valid.token' => ValidateToken::class + 'valid.token' => ValidateToken::class, + 'token.check' => \App\Http\Middleware\TokenCheckerMiddleware::class, ]; } diff --git a/app/Http/Middleware/TokenCheckerMiddleware.php b/app/Http/Middleware/TokenCheckerMiddleware.php new file mode 100644 index 00000000..480ea348 --- /dev/null +++ b/app/Http/Middleware/TokenCheckerMiddleware.php @@ -0,0 +1,56 @@ +query('api-key')) { + return response()->json(['message' => 'Invalid API key.'], 401); + } + + // Check if the api_key is valid + $apiKey = $request->query('api-key'); + $personalAccessToken = PersonalAccessTokens::where('token', $apiKey)->first(); + + if (!$personalAccessToken) { + return response()->json(['error' => 'Unauthorized'], 401); + } + return $next($request); + + //Method 2: Token pass via request header + /* + $authHeader = $request->header('Authorization'); + if (preg_match('/Bearer\s+(.*)$/i', $authHeader, $matches)) { + $token = $matches[1]; + // validate the token here + + $personalAccessToken = PersonalAccessToken::where('token', $token)->first(); + + if (!$personalAccessToken) { + return response()->json(['error' => 'Unauthorized'], 401); + } + + + // if the token is valid, you can attach it to the request + $request->attributes->add(['bearerToken' => $token]); + return $next($request); + } + return response()->json(['error' => 'Unauthorized'], 401); + */ + } +} diff --git a/app/Http/Resources/AnnouncementResource.php b/app/Http/Resources/AnnouncementResource.php index 26e1c2f9..2e6048e0 100644 --- a/app/Http/Resources/AnnouncementResource.php +++ b/app/Http/Resources/AnnouncementResource.php @@ -20,8 +20,8 @@ class AnnouncementResource extends JsonResource 'title' => $this->title, 'description' => $this->description, 'segments' => $this->segments, - 'starting_on' => Carbon::parse($this->starting_on)->format('Y-m-d'), - 'ending_on' => Carbon::parse($this->ending_on)->format('Y-m-d'), + 'starting_on' => Carbon::parse($this->starting_on)->format('d-m-Y'), + 'ending_on' => Carbon::parse($this->ending_on)->format('d-m-Y'), 'created_at' => Carbon::parse($this->created_at)->format('d-m-Y'), ]; } diff --git a/app/Http/Resources/CompanyModuleResource.php b/app/Http/Resources/CompanyModuleResource.php index 0fdb2c46..87315c71 100644 --- a/app/Http/Resources/CompanyModuleResource.php +++ b/app/Http/Resources/CompanyModuleResource.php @@ -49,6 +49,7 @@ class CompanyModuleResource extends JsonResource 'marking' => $marking, 'warehouseCharges' => array_key_exists($this->id, $segmentConstant) ? $segmentConstant[$this->id] : null, 'connections' => $this->connections, + 'contact' => new ContactResource ($this->when($this->has('contacts'), $this->contacts->first())), ]; } diff --git a/app/Http/Resources/CompanyResource.php b/app/Http/Resources/CompanyResource.php index c896c154..4590f46b 100644 --- a/app/Http/Resources/CompanyResource.php +++ b/app/Http/Resources/CompanyResource.php @@ -4,6 +4,7 @@ namespace App\Http\Resources; use App\Classes\ValueObjects\Constants\ApprovalStatus; use App\Classes\ValueObjects\Constants\BusinessType; +use App\Classes\ValueObjects\Constants\CompanyType; use App\Classes\ValueObjects\Constants\DocumentType; use Illuminate\Http\Resources\Json\JsonResource; use Illuminate\Support\Facades\Crypt; @@ -19,6 +20,8 @@ class CompanyResource extends JsonResource public function toArray($request) { $companyModule = $this->companyModules()->first(); + $companyTypeArray = CompanyType::COMPANY_TYPE_ID; + return [ 'id' => $this->id, 'hash_id' => Crypt::encryptString($this->id), @@ -26,6 +29,7 @@ class CompanyResource extends JsonResource 'debtor' => $this->debtor, 'reference' => $this->reference, 'type' => (int) $this->type, + 'type_name' => ($companyTypeArray[(int) $this->type]), 'business_type' => (int) $this->business_type, 'status' => (int) $this->status, 'segments' => SegmentResource::collection($companyModule->connections()->first()->segments), diff --git a/app/Http/Resources/OrderV2Resource.php b/app/Http/Resources/OrderV2Resource.php new file mode 100644 index 00000000..7ca77149 --- /dev/null +++ b/app/Http/Resources/OrderV2Resource.php @@ -0,0 +1,40 @@ + $this->id, + 'reference' => $this->reference, + 'reference_contract' => (int) $this->type, + 'type' => (int) $this->type, + 'status' => (int) $this->status, + 'company_module' => new CompanyModuleResource($this->companyModule), + 'warehouse' => new CompanyModuleResource($this->orderRoles()->where('role_id', '=', OrderRoleTypes::ORIGIN_WAREHOUSE)->first()->appointee), + '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])->get()); + }), + 'remarks' => RemarkResource::collection($this->remarks), + 'created_at' => $this->created_at->format('d-m-Y') + ]; + + } +} diff --git a/app/Http/Resources/UserResource.php b/app/Http/Resources/UserResource.php index 3d052d02..724d3e1c 100644 --- a/app/Http/Resources/UserResource.php +++ b/app/Http/Resources/UserResource.php @@ -2,6 +2,7 @@ namespace App\Http\Resources; +use App\Classes\ValueObjects\Constants\RoleTypes; use Illuminate\Http\Resources\Json\JsonResource; class UserResource extends JsonResource @@ -14,11 +15,13 @@ class UserResource extends JsonResource */ public function toArray($request) { + $userTypeArray = RoleTypes::USER_TYPE_ID; return [ 'id' => $this->id, 'name' => $this->name, 'email' => $this->email, 'type' => (int) $this->type, + 'type_name' => ($userTypeArray[(int) $this->type]), 'status' => (int) $this->status ]; } diff --git a/app/Models/PersonalAccessTokens.php b/app/Models/PersonalAccessTokens.php new file mode 100644 index 00000000..5efc331d --- /dev/null +++ b/app/Models/PersonalAccessTokens.php @@ -0,0 +1,9 @@ +namespace($this->namespace) ->group(base_path('routes/api.php')); + Route::prefix('public/api') + ->middleware('apipub') + ->namespace($this->namespace) + ->group(base_path('routes/apipub.php')); + Route::middleware('web') ->namespace($this->namespace) ->group(base_path('routes/web.php')); diff --git a/database/migrations/2023_04_06_000001_create_personal_access_tokens_table.php b/database/migrations/2023_04_06_000001_create_personal_access_tokens_table.php new file mode 100644 index 00000000..691a4bf8 --- /dev/null +++ b/database/migrations/2023_04_06_000001_create_personal_access_tokens_table.php @@ -0,0 +1,36 @@ +bigIncrements('id'); + // $table->morphs('tokenable'); + $table->string('name'); + $table->string('token', 64)->unique(); + $table->text('abilities')->nullable(); + $table->timestamp('last_used_at')->nullable(); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('personal_access_tokens'); + } +} diff --git a/database/seeders/FoshanWarehouseTableSeeder.php b/database/seeders/FoshanWarehouseTableSeeder.php new file mode 100644 index 00000000..9873150f --- /dev/null +++ b/database/seeders/FoshanWarehouseTableSeeder.php @@ -0,0 +1,127 @@ +createCompanyProcessor = $createCompanyProcessor; + $this->updatesCompanyStatus = $updatesCompanyStatus; + $this->createCompanyModuleProcessor = $createCompanyModuleProcessor; + $this->createContactProcessor = $createContactProcessor; + $this->createsCompanyConnection = $createsCompanyConnection; + $this->approvesCompanyConnection = $approvesCompanyConnection; + $this->createAddressFromOldAddressProcessor = $createAddressFromOldAddressProcessor; + $this->createsAddress = $createsAddress; + $this->fetchesCompany = $fetchesCompany; + $this->createsContact = $createsContact; + } + + + /** + * Run the database seeds. + * + * @return void + * @throws \App\Classes\Exceptions\AccessForbiddenException + * @throws \App\Classes\Exceptions\MalformedRequestException + * @throws \App\Classes\Exceptions\RequestValidationException + */ + public function run() + { + /** @var Company $company */ + $company = $this->fetchesCompany->execute(['reference' => 'MODERN']); + + // YD_FS_WEST_MALAYSIA - FS-V01 + /** @var CompanyModule $companyModule */ + $companyModule = $this->createCompanyModuleProcessor->execute($company, BusinessType::WAREHOUSE); + $companyModule->update(['name' => 'Foshan', 'reference' => WarehouseReferences::YD_FS_WEST_MALAYSIA]); + + $address = new AddressObject('广东省 佛山市 南海区 狮山镇北园东路6号D幢1楼', '', 2, 35, 638, 528225, AddressType::DELIVERY, ApprovalStatus::APPROVED); + $contact = new ContactObject('郑佳鹏', '18520607573', '', ''); + + $this->createsAddress->execute($companyModule, $address); + $this->createsContact->execute($companyModule, $contact); + + // FS_EAST_MALAYSIA - FS-V02 + /** @var CompanyModule $companyModule */ + $companyModule = $this->createCompanyModuleProcessor->execute($company, BusinessType::WAREHOUSE); + $companyModule->update(['name' => 'Foshan', 'reference' => WarehouseReferences::YD_FS_EAST_MALAYSIA]); + + $address = new AddressObject('广东省 佛山市 南海区 狮山镇北园东路6号C幢1楼', '', 2, 35, 638, 528225, AddressType::DELIVERY, ApprovalStatus::APPROVED); + $contact = new ContactObject('游万彬', '18520607573', '', ''); + + $this->createsAddress->execute($companyModule, $address); + $this->createsContact->execute($companyModule, $contact); + } +} diff --git a/docker-setup/nginx/default.conf b/docker-setup/nginx/default.conf index 0f052b34..d1392c4d 100644 --- a/docker-setup/nginx/default.conf +++ b/docker-setup/nginx/default.conf @@ -23,5 +23,9 @@ server { fastcgi_intercept_errors on; fastcgi_keep_conn on; fastcgi_param PHP_VALUE "auto_prepend_file= \n allow_url_include=Off \n output_buffering=Off \n output_buffering=4096"; + proxy_send_timeout 3600; + proxy_read_timeout 3600; + fastcgi_send_timeout 3600; + fastcgi_read_timeout 3600; } } diff --git a/resources/assets/images/foshan-map.png b/resources/assets/images/foshan-map.png new file mode 100644 index 00000000..f42eaa43 Binary files /dev/null and b/resources/assets/images/foshan-map.png differ diff --git a/resources/assets/vue/components/addresses/elements/DisplayWarehouseAddressComponent.vue b/resources/assets/vue/components/addresses/elements/DisplayWarehouseAddressComponent.vue new file mode 100644 index 00000000..8b440b1e --- /dev/null +++ b/resources/assets/vue/components/addresses/elements/DisplayWarehouseAddressComponent.vue @@ -0,0 +1,76 @@ + + + \ No newline at end of file diff --git a/resources/assets/vue/components/addresses/forms/WarehouseAddressFormComponent.vue b/resources/assets/vue/components/addresses/forms/WarehouseAddressFormComponent.vue new file mode 100644 index 00000000..81800c43 --- /dev/null +++ b/resources/assets/vue/components/addresses/forms/WarehouseAddressFormComponent.vue @@ -0,0 +1,230 @@ + + diff --git a/resources/assets/vue/components/companies/elements/CustomerProfileComponent.vue b/resources/assets/vue/components/companies/elements/CustomerProfileComponent.vue index 31cb7d57..69625c6a 100644 --- a/resources/assets/vue/components/companies/elements/CustomerProfileComponent.vue +++ b/resources/assets/vue/components/companies/elements/CustomerProfileComponent.vue @@ -16,8 +16,9 @@ -
{{item.name}} -
+
+ {{item.name}} +
@@ -92,10 +93,24 @@
{{item.contact.phone}}
+
-
WeChat ID
-
{{item.contact.wechat_id}}
+
Company Type
+ + + +
+ {{item.type_name}} +
+ +
+
diff --git a/resources/assets/vue/components/companies/elements/IdentificationVerificationComponent.vue b/resources/assets/vue/components/companies/elements/IdentificationVerificationComponent.vue index bcb5b80c..dd7ba28d 100644 --- a/resources/assets/vue/components/companies/elements/IdentificationVerificationComponent.vue +++ b/resources/assets/vue/components/companies/elements/IdentificationVerificationComponent.vue @@ -16,7 +16,8 @@
-
+{{item.owner.contact.country_code}} {{parseInt(item.owner.contact.phone, 10)}}
+
+{{item.owner.contact.country_code}} {{parseInt(item.owner.contact.phone, 10)}}
+
@@ -51,7 +52,8 @@
-
{{item.owner.contact.wechat_id}}
+
{{item.owner.contact.wechat_id}}
+
diff --git a/resources/assets/vue/components/companies/forms/ContactFormComponent.vue b/resources/assets/vue/components/companies/forms/ContactFormComponent.vue new file mode 100644 index 00000000..9ad6650b --- /dev/null +++ b/resources/assets/vue/components/companies/forms/ContactFormComponent.vue @@ -0,0 +1,89 @@ + + \ No newline at end of file diff --git a/resources/assets/vue/components/general/elements/BoxLoadingComponent.vue b/resources/assets/vue/components/general/elements/BoxLoadingComponent.vue new file mode 100644 index 00000000..e3aec930 --- /dev/null +++ b/resources/assets/vue/components/general/elements/BoxLoadingComponent.vue @@ -0,0 +1,144 @@ + + \ No newline at end of file diff --git a/resources/assets/vue/components/general/sections/SupportSectionComponent.vue b/resources/assets/vue/components/general/sections/SupportSectionComponent.vue new file mode 100644 index 00000000..75839088 --- /dev/null +++ b/resources/assets/vue/components/general/sections/SupportSectionComponent.vue @@ -0,0 +1,83 @@ + + + \ No newline at end of file diff --git a/resources/assets/vue/components/orders/elements/ListOrderComponent.vue b/resources/assets/vue/components/orders/elements/ListOrderComponent.vue new file mode 100644 index 00000000..b7c82ede --- /dev/null +++ b/resources/assets/vue/components/orders/elements/ListOrderComponent.vue @@ -0,0 +1,124 @@ + + + diff --git a/resources/assets/vue/components/orders/elements/OrderComponent.vue b/resources/assets/vue/components/orders/elements/OrderComponent.vue index da21cef8..a744f38a 100644 --- a/resources/assets/vue/components/orders/elements/OrderComponent.vue +++ b/resources/assets/vue/components/orders/elements/OrderComponent.vue @@ -62,15 +62,18 @@
Received -
{{item.parcels.received_packages.flatMap(packing_list => packing_list.packages).reduce((total, obj) => obj.quantity + total, 0)}}
+
{{item.parcels.received_packages.flatMap(packing_list => packing_list.packages).reduce((total, obj) => obj.quantity + total, 0)}}
+
-
In Transit -
{{item.parcels.in_transit_packages.flatMap(packing_list => packing_list.packages).concat(item.parcels.destination_warehouse_packages.flatMap(packing_list => packing_list.packages)).reduce((total, obj) => obj.quantity + total, 0)}}
+
{{item.parcels.in_transit_packages.flatMap(packing_list => packing_list.packages).concat(item.parcels.destination_warehouse_packages.flatMap(packing_list => packing_list.packages)).reduce((total, obj) => obj.quantity + total, 0)}}
+
-
Delivered -
{{item.parcels.delivered_packages.flatMap(packing_list => packing_list.packages).reduce((total, obj) => obj.quantity + total, 0)}}
+
{{item.parcels.delivered_packages.flatMap(packing_list => packing_list.packages).reduce((total, obj) => obj.quantity + total, 0)}}
+
-
@@ -90,7 +93,8 @@
Total CBM -
{{(Math.ceil((item.parcels.origin_warehouse_packages.flatMap(packing_list => packing_list.packages).reduce((total, obj) => obj.cbm + total, 0) + item.parcels.in_transit_packages.flatMap(packing_list => packing_list.packages).reduce((total, obj) => obj.cbm + total, 0) + item.parcels.destination_warehouse_packages.flatMap(packing_list => packing_list.packages).reduce((total, obj) => obj.cbm + total, 0) + item.parcels.delivered_packages.flatMap(packing_list => packing_list.packages).reduce((total, obj) => obj.cbm + total, 0)) * 10000) / 10000).toFixed(3)}}
+
{{(Math.ceil((item.parcels.origin_warehouse_packages.flatMap(packing_list => packing_list.packages).reduce((total, obj) => obj.cbm + total, 0) + item.parcels.in_transit_packages.flatMap(packing_list => packing_list.packages).reduce((total, obj) => obj.cbm + total, 0) + item.parcels.destination_warehouse_packages.flatMap(packing_list => packing_list.packages).reduce((total, obj) => obj.cbm + total, 0) + item.parcels.delivered_packages.flatMap(packing_list => packing_list.packages).reduce((total, obj) => obj.cbm + total, 0)) * 10000) / 10000).toFixed(3)}}
+
-
diff --git a/resources/assets/vue/components/orders/elements/ParcelComponent.vue b/resources/assets/vue/components/orders/elements/ParcelComponent.vue index 248aec73..cef41560 100644 --- a/resources/assets/vue/components/orders/elements/ParcelComponent.vue +++ b/resources/assets/vue/components/orders/elements/ParcelComponent.vue @@ -1,5 +1,5 @@