diff --git a/.env.example b/.env.example index a75778c8..5ae78676 100644 --- a/.env.example +++ b/.env.example @@ -53,3 +53,5 @@ MIX_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}" UNITY_APP_URL="https://unity.izyim.com" EXCHANGE_URL=https://dev.exchange.cief-malaysia.com/ MIX_EXCHANGE_URL="${EXCHANGE_URL}" + +YD_API_CODE='' diff --git a/app/Classes/General/Abstracts/AbstractControllerLogic.php b/app/Classes/General/Abstracts/AbstractControllerLogic.php index 9f8ba4b5..24a3763b 100644 --- a/app/Classes/General/Abstracts/AbstractControllerLogic.php +++ b/app/Classes/General/Abstracts/AbstractControllerLogic.php @@ -63,7 +63,7 @@ abstract class AbstractControllerLogic } catch (ErrorException|GeneralExceptions|TypeError $exception){ return (new ApiResponseObject($this->getNotificationTitle().' failed', $exception->getMessage(), - $exception->getCode() ? $exception->getCode() : HttpStatus::SERVER_ERROR))->handler(); + !in_array($exception->getCode(), [0, 42000]) ? $exception->getCode() : HttpStatus::SERVER_ERROR))->handler(); } } diff --git a/app/Classes/General/Eloquent/Filters/Delivered.php b/app/Classes/General/Eloquent/Filters/Delivered.php new file mode 100644 index 00000000..f6c09b98 --- /dev/null +++ b/app/Classes/General/Eloquent/Filters/Delivered.php @@ -0,0 +1,32 @@ +whereHas('packingList', function($packingList){ + return $packingList->where('type', PackingListType::SHIPPING_PACKING_LIST)->where('status', ApprovalStatus::APPROVED); + })->whereHas('container', + function($container) { + return $container->where('containers.status', ApprovalStatus::COMPLETED); + } + )->whereHas('deliverySchedules', + function($schedule) { + return $schedule->where('eta', '<', Carbon::now())->whereIn('schedules.status', [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED]); + } + ); + } +} \ No newline at end of file diff --git a/app/Classes/General/Eloquent/Filters/InDestinationWarehouse.php b/app/Classes/General/Eloquent/Filters/InDestinationWarehouse.php new file mode 100644 index 00000000..b4a56b23 --- /dev/null +++ b/app/Classes/General/Eloquent/Filters/InDestinationWarehouse.php @@ -0,0 +1,32 @@ +whereHas('packingList', function($packingList){ + return $packingList->where('type', PackingListType::SHIPPING_PACKING_LIST)->where('status', ApprovalStatus::APPROVED); + })->whereHas('container', + function($container) { + return $container->where('containers.status', ApprovalStatus::COMPLETED); + } + )->whereDoesntHave('deliverySchedules', + function($schedule) { + return $schedule->where('etd', '<', Carbon::now())->whereIn('schedules.status', [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED]); + } + ); + } +} \ No newline at end of file diff --git a/app/Classes/General/Eloquent/Filters/InOriginWarehouse.php b/app/Classes/General/Eloquent/Filters/InOriginWarehouse.php new file mode 100644 index 00000000..80bac25a --- /dev/null +++ b/app/Classes/General/Eloquent/Filters/InOriginWarehouse.php @@ -0,0 +1,29 @@ +whereHas('packingList', function($packingList){ + return $packingList->where('type', PackingListType::SHIPPING_PACKING_LIST)->where('status', ApprovalStatus::APPROVED); + })->whereDoesntHave('shippingSchedules', + function($schedule) { + return $schedule->where('etd', '<', Carbon::now()) + ->whereIn('schedules.status', [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED]); + } + ); + } +} \ No newline at end of file diff --git a/app/Classes/General/Eloquent/Filters/InTransit.php b/app/Classes/General/Eloquent/Filters/InTransit.php new file mode 100644 index 00000000..db453486 --- /dev/null +++ b/app/Classes/General/Eloquent/Filters/InTransit.php @@ -0,0 +1,33 @@ +whereHas('packingList', function($packingList){ + return $packingList->where('type', PackingListType::SHIPPING_PACKING_LIST)->where('status', ApprovalStatus::APPROVED); + })->whereHas('container', + function($container) { + return $container->where('containers.status', ApprovalStatus::PENDING_VERIFICATION); + } + )->whereHas('shippingSchedules', + function($schedule) { + return $schedule->where('etd', '<', Carbon::now()) + ->whereIn('schedules.status', [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED]); + } + ); + } +} \ No newline at end of file diff --git a/app/Classes/General/Eloquent/Filters/WarehouseParcels.php b/app/Classes/General/Eloquent/Filters/WarehouseParcels.php new file mode 100644 index 00000000..a342a964 --- /dev/null +++ b/app/Classes/General/Eloquent/Filters/WarehouseParcels.php @@ -0,0 +1,24 @@ +whereHas('packingList', function ($query){ + return $query->where('type', PackingListType::WAREHOUSE_RECEIVE_LIST)->where('status', ApprovalStatus::APPROVED); + }); + } +} \ No newline at end of file diff --git a/app/Classes/Jobs/CurlContainerListJob.php b/app/Classes/Jobs/CurlContainerListJob.php deleted file mode 100644 index e65a1a18..00000000 --- a/app/Classes/Jobs/CurlContainerListJob.php +++ /dev/null @@ -1,94 +0,0 @@ -page = $page; - } - - /** - * Execute the job. - * - * @return void - * @throws \GuzzleHttp\Exception\GuzzleException - */ - public function handle() - { - $cookies = $this->getCookie(); - - $headers = [ - 'Content-Type' => 'application/json', - 'Cookie' => $cookies, - ]; - - $last_two_month = Carbon::now()->subMonth(2)->format('Y-m-d'); - - $client = new \GuzzleHttp\Client(['headers' => $headers]); - $res = $client->post('http://portal.vtnation.com.my/Services/DataControllerService.asmx/GetPage', [\GuzzleHttp\RequestOptions::JSON => json_decode('{"controller":"VCustomercontainer","view":"grid1","request":{"PageIndex":' . $this->page . ',"PageSize":10,"PageOffset":0,"SortExpression":"CreatedOn DESC","GroupExpression":"","Filter":["LoadedTime:<=%js%\"' . $last_two_month . 'T00:00:00.000\"\u0000"],"ContextKey":"view1","FilterIsExternal":false,"LookupContextFieldName":null,"LookupContextController":null,"LookupContextView":null,"LookupContext":null,"Inserting":false,"LastCommandName":null,"ExternalFilter":[],"DoesNotRequireData":false,"LastView":"grid1","Tag":null,"RequiresFirstLetters":false,"ViewType":"Grid","SupportsCaching":true,"SystemFilter":null,"RequiresRowCount":true,"QuickFindHint":null,"RequiresPivot":false,"PivotDefinitions":null,"RequiresMetaData":true}}')]); - - $data = json_decode($res->getBody()->getContents()); - - if (!empty($data->d->Rows)) { - // insert data here - - // next page - $this->page = $this->page > 0 ? $this->page + 1 : 1; - CurlContainerListJob::dispatch($this->page + 1) - ->delay(Carbon::now()->addSeconds(10)); - } - } - - public function getCookie() - { - // get latest cookies - $client = new \GuzzleHttp\Client(['cookies' => true]); - $r = $client->request('GET', 'http://portal.vtnation.com.my'); - $call_cookie = $client->getConfig('cookies'); - $call_cookie = $call_cookie->toArray(); - $latest_cookie = []; - - foreach ($call_cookie as $key => $row) { - $latest_cookie[] = $row['Name'] . '=' . $row['Value']; - } - $latest_cookie = implode(';', $latest_cookie); - - // get access token - $headers = [ - 'Content-Type' => 'application/json', - 'Cookie' => $latest_cookie, - ]; - $client = new \GuzzleHttp\Client(['headers' => $headers]); - $res = $client->post('http://portal.vtnation.com.my/Services/DataControllerService.asmx/Login', [\GuzzleHttp\RequestOptions::JSON => [ - "username" => "CIEF", - "password" => "0122120880", - "createPersistentCookie" => true, - ]]); - - $token = json_decode($res->getBody()->getContents()); - $token = $token->d->AccessToken; - - $latest_cookie = $latest_cookie . ';AppVTCC=' . $token; - return $latest_cookie; - } -} diff --git a/app/Classes/Jobs/FetchOrdersFromYDPortalJob.php b/app/Classes/Jobs/FetchOrdersFromYDPortalJob.php new file mode 100644 index 00000000..b67130d3 --- /dev/null +++ b/app/Classes/Jobs/FetchOrdersFromYDPortalJob.php @@ -0,0 +1,32 @@ +make(FetchOrderListsFromYdPortalProcessor::class))->execute(); + } + +} diff --git a/app/Classes/Modules/Addresses/ControllersLogic/CreateAddressLogic.php b/app/Classes/Modules/Addresses/ControllersLogic/CreateAddressLogic.php index f0240e5c..91f5c42e 100644 --- a/app/Classes/Modules/Addresses/ControllersLogic/CreateAddressLogic.php +++ b/app/Classes/Modules/Addresses/ControllersLogic/CreateAddressLogic.php @@ -4,12 +4,18 @@ namespace App\Classes\Modules\Addresses\ControllersLogic; use App\Classes\General\Abstracts\AbstractControllerLogic; +use App\Classes\General\Interfaces\Contactable; use App\Classes\Modules\Addresses\Services\CreatesAddress; use App\Classes\Modules\Addresses\Services\FetchesDistrict; use App\Classes\Modules\Addresses\Standards\Rules\CanCreateAddress; use App\Classes\Modules\Addresses\DataTransferObjects\AddressObject; use App\Classes\Modules\Companies\Services\FetchesCompanyModule; +use App\Classes\Modules\Contacts\DataTransferObjects\ContactObject; +use App\Classes\Modules\Contacts\Processors\CreateContactProcessor; +use App\Classes\Modules\Remarks\DataTransferObjects\RemarkObject; +use App\Classes\Modules\Remarks\Processors\CreateRemarkProcessor; use App\Http\Resources\AddressResource; +use App\Models\Address; use ErrorException; use Illuminate\Http\JsonResponse; use Illuminate\Http\Request; @@ -39,19 +45,29 @@ class CreateAddressLogic extends AbstractControllerLogic /** @var CreatesAddress */ private $createsAddress; + /** @var CreateContactProcessor */ + private $createContactProcessor; + + /** @var CreateRemarkProcessor */ + private $createRemarkProcessor; + /** * CreateAddressLogic constructor. * @param CanCreateAddress $canCreateAddress * @param FetchesDistrict $fetchesDistrict * @param FetchesCompanyModule $fetchesCompanyModule * @param CreatesAddress $createsAddress + * @param CreateContactProcessor $createContactProcessor + * @param CreateRemarkProcessor $createRemarkProcessor */ - public function __construct(CanCreateAddress $canCreateAddress, FetchesDistrict $fetchesDistrict, FetchesCompanyModule $fetchesCompanyModule, CreatesAddress $createsAddress) + public function __construct(CanCreateAddress $canCreateAddress, FetchesDistrict $fetchesDistrict, FetchesCompanyModule $fetchesCompanyModule, CreatesAddress $createsAddress, CreateContactProcessor $createContactProcessor, CreateRemarkProcessor $createRemarkProcessor) { $this->canCreateAddress = $canCreateAddress; $this->fetchesDistrict = $fetchesDistrict; $this->fetchesCompanyModule = $fetchesCompanyModule; $this->createsAddress = $createsAddress; + $this->createContactProcessor = $createContactProcessor; + $this->createRemarkProcessor = $createRemarkProcessor; } /** @@ -70,8 +86,19 @@ class CreateAddressLogic extends AbstractControllerLogic $this->canCreateAddress->passes($object); + /** @var Address $address */ $address = $this->createsAddress->execute($this->fetchesCompanyModule->execute(['id' => $request->input('company_module_id')]), $object); + if($request->input('phone')){ + $contactObject = new ContactObject($request->input('person_in_charge'), $request->input('phone'), '', ''); + $this->createContactProcessor->execute($contactObject, $address); + } + + if($request->input('remark')){ + $remarkObject = new RemarkObject($request->input('remark'), Auth()->user()->id); + $this->createRemarkProcessor->execute($address, $remarkObject); + } + return $this->resourceResponse(new AddressResource($address)); } diff --git a/app/Classes/Modules/Addresses/ControllersLogic/UpdateAddressLogic.php b/app/Classes/Modules/Addresses/ControllersLogic/UpdateAddressLogic.php index 9d8f0600..95b8bf64 100644 --- a/app/Classes/Modules/Addresses/ControllersLogic/UpdateAddressLogic.php +++ b/app/Classes/Modules/Addresses/ControllersLogic/UpdateAddressLogic.php @@ -9,7 +9,12 @@ use App\Classes\Modules\Addresses\Services\FetchesAddress; use App\Classes\Modules\Addresses\Services\FetchesDistrict; use App\Classes\Modules\Addresses\Standards\Rules\CanUpdateAddress; use App\Classes\Modules\Addresses\DataTransferObjects\AddressObject; +use App\Classes\Modules\Contacts\DataTransferObjects\ContactObject; +use App\Classes\Modules\Contacts\Processors\CreateContactProcessor; +use App\Classes\Modules\Remarks\DataTransferObjects\RemarkObject; +use App\Classes\Modules\Remarks\Processors\CreateRemarkProcessor; use App\Http\Resources\AddressResource; +use App\Models\Address; use Illuminate\Http\JsonResponse; use Illuminate\Http\Request; @@ -38,22 +43,31 @@ class UpdateAddressLogic extends AbstractControllerLogic /** @var FetchesDistrict */ private $fetchesDistrict; + /** @var CreateContactProcessor */ + private $createContactProcessor; + + /** @var CreateRemarkProcessor */ + private $createRemarkProcessor; + /** * UpdateAddressLogic constructor. * @param CanUpdateAddress $canUpdateAddress * @param UpdatesAddress $updatesAddress * @param FetchesAddress $fetchesAddress * @param FetchesDistrict $fetchesDistrict + * @param CreateContactProcessor $createContactProcessor + * @param CreateRemarkProcessor $createRemarkProcessor */ - public function __construct(CanUpdateAddress $canUpdateAddress, UpdatesAddress $updatesAddress, FetchesAddress $fetchesAddress, FetchesDistrict $fetchesDistrict) + public function __construct(CanUpdateAddress $canUpdateAddress, UpdatesAddress $updatesAddress, FetchesAddress $fetchesAddress, FetchesDistrict $fetchesDistrict, CreateContactProcessor $createContactProcessor, CreateRemarkProcessor $createRemarkProcessor) { $this->canUpdateAddress = $canUpdateAddress; $this->updatesAddress = $updatesAddress; $this->fetchesAddress = $fetchesAddress; $this->fetchesDistrict = $fetchesDistrict; + $this->createContactProcessor = $createContactProcessor; + $this->createRemarkProcessor = $createRemarkProcessor; } - /** * @param Request $request * @return JsonResponse @@ -71,8 +85,21 @@ class UpdateAddressLogic extends AbstractControllerLogic $address = $this->fetchesAddress->execute(['id' => $request->route('id')]); + /** @var Address $address */ $address = $this->updatesAddress->execute($address, $object); + $address->contacts()->delete(); $address->remarks()->delete(); + + if($request->input('phone')){ + $contactObject = new ContactObject($request->input('person_in_charge'), $request->input('phone'), '', ''); + $this->createContactProcessor->execute($contactObject, $address); + } + + if($request->input('remark')){ + $remarkObject = new RemarkObject($request->input('remark'), Auth()->user()->id); + $this->createRemarkProcessor->execute($address, $remarkObject); + } + return $this->resourceResponse(new AddressResource($address)); } diff --git a/app/Classes/Modules/Announcements/ControllersLogic/AssignAnnouncementToSegmentLogic.php b/app/Classes/Modules/Announcements/ControllersLogic/AssignAnnouncementToSegmentLogic.php new file mode 100644 index 00000000..18552989 --- /dev/null +++ b/app/Classes/Modules/Announcements/ControllersLogic/AssignAnnouncementToSegmentLogic.php @@ -0,0 +1,61 @@ + 'Assign Announcement To Segment', + 'message' => 'You have successfully assigned Announcement to segment' + ]; + } + + /** @var FetchesAnnouncement */ + private $fetchesAnnouncement; + + /** @var AssignAnnouncementToSegmentProcessor */ + private $assignAnnouncementToSegmentProcessor; + + /** + * AssignAnnouncementToSegmentLogic constructor. + * @param FetchesAnnouncement $fetchesAnnouncement + * @param AssignAnnouncementToSegmentProcessor $assignAnnouncementToSegmentProcessor + */ + public function __construct(FetchesAnnouncement $fetchesAnnouncement, AssignAnnouncementToSegmentProcessor $assignAnnouncementToSegmentProcessor) + { + $this->fetchesAnnouncement = $fetchesAnnouncement; + $this->assignAnnouncementToSegmentProcessor = $assignAnnouncementToSegmentProcessor; + } + + /** + * @param Request $request + * @return JsonResponse + * @throws \App\Classes\Exceptions\AccessForbiddenException + * @throws \App\Classes\Exceptions\MalformedRequestException + * @throws \App\Classes\Exceptions\RequestValidationException + */ + public function logic(Request $request): JsonResponse + { + $announcement = $this->fetchesAnnouncement->execute(['id' => $request->route('id')]); + + $this->assignAnnouncementToSegmentProcessor->execute($announcement, $request->input('segment_id')); + + return $this->resourceResponse(new AnnouncementResource($announcement)); + } +} diff --git a/app/Classes/Modules/Announcements/ControllersLogic/CreateAnnouncementLogic.php b/app/Classes/Modules/Announcements/ControllersLogic/CreateAnnouncementLogic.php new file mode 100644 index 00000000..9c740601 --- /dev/null +++ b/app/Classes/Modules/Announcements/ControllersLogic/CreateAnnouncementLogic.php @@ -0,0 +1,82 @@ + 'Created Annoucement', + 'message' => 'You have successfully created a new Annoucements' + ]; + } + + /** @var CanCreateAnnouncement */ + private $canCreateAnnouncement; + + /** @var CreatesAnnoucement */ + private $createsAnnoucement; + + /** @var AssignAnnouncementToSegmentProcessor */ + private $assignAnnouncementToSegmentProcessor; + + + /** + * CreateAnnouncementLogic constructor. + * @param CanCreateAnnoucement $canCreateAnnoucement + * @param CreatesAnnoucement $createsAnnoucement + * @param AssignAnnouncementToSegmentProcessor $assignAnnouncementToSegmentProcessor + */ + public function __construct( + CanCreateAnnouncement $canCreateAnnouncement, + CreatesAnnouncement $createsAnnoucement, + AssignAnnouncementToSegmentProcessor $assignAnnouncementToSegmentProcessor + ) { + $this->canCreateAnnouncement = $canCreateAnnouncement; + $this->createsAnnoucement = $createsAnnoucement; + $this->assignAnnouncementToSegmentProcessor = $assignAnnouncementToSegmentProcessor; + } + + /** + * @param Request $request + * @return JsonResponse + * @throws \App\Classes\Exceptions\AccessForbiddenException + * @throws \App\Classes\Exceptions\MalformedRequestException + * @throws \App\Classes\Exceptions\RequestValidationException + */ + public function logic(Request $request): JsonResponse + { + $annoucement_object = new AnnouncementObject( + $request->input('title'), + $request->input('description'), + $request->input('starting_on'), + $request->input('ending_on') + ); + + $this->canCreateAnnouncement->passes($annoucement_object); + + $announcement = $this->createsAnnoucement->execute($annoucement_object); + + $this->assignAnnouncementToSegmentProcessor->execute($announcement); + + return $this->resourceResponse(new AnnouncementResource($announcement)); + } +} diff --git a/app/Classes/Modules/Announcements/ControllersLogic/DeleteAnnouncementLogic.php b/app/Classes/Modules/Announcements/ControllersLogic/DeleteAnnouncementLogic.php new file mode 100644 index 00000000..55dc710c --- /dev/null +++ b/app/Classes/Modules/Announcements/ControllersLogic/DeleteAnnouncementLogic.php @@ -0,0 +1,71 @@ + 'Delete Announcement', + 'message' => 'You have successfully deleted the Announcement' + ]; + } + + /** @var CanDeleteAnnouncement */ + private $canDeleteAnnouncement; + + /** @var FetchesAnnouncement */ + private $fetchesAnnouncement; + + /** @var DeletesAnnouncement */ + private $deletesAnnouncement; + + /** + * DeleteAnnouncementLogic constructor. + * @param CanDeleteAnnouncement $canDeleteAnnouncement + * @param FetchesAnnouncement $fetchesAnnouncement + * @param DeletesAnnouncement $deletesAnnouncement + */ + public function __construct( + CanDeleteAnnouncement $canDeleteAnnoucement, + FetchesAnnouncement $fetchesAnnoucement, + DeletesAnnouncement $deletesAnnoucement + ) { + $this->canDeleteAnnoucement = $canDeleteAnnoucement; + $this->fetchesAnnoucement = $fetchesAnnoucement; + $this->deletesAnnoucement = $deletesAnnoucement; + } + + /** + * @param Request $request + * @return JsonResponse + * @throws \App\Classes\Exceptions\AccessForbiddenException + * @throws \App\Classes\Exceptions\MalformedRequestException + * @throws \App\Classes\Exceptions\RequestValidationException + */ + public function logic(Request $request): JsonResponse + { + + $this->canDeleteAnnoucement->passes(); + + $annoucement = $this->fetchesAnnoucement->execute(['id' => $request->route('id')]); + + $this->deletesAnnoucement->execute($annoucement); + + return $this->response([]); + } +} diff --git a/app/Classes/Modules/Announcements/ControllersLogic/ListAnnouncementsLogic.php b/app/Classes/Modules/Announcements/ControllersLogic/ListAnnouncementsLogic.php new file mode 100644 index 00000000..0055ebeb --- /dev/null +++ b/app/Classes/Modules/Announcements/ControllersLogic/ListAnnouncementsLogic.php @@ -0,0 +1,60 @@ + 'Retrieve Announcements', + 'message' => 'You have successfully retrieved a list of Announcements' + ]; + } + + /** @var CanListAnnouncements */ + private $canListAnnouncements; + + /** @var ListsAnnouncements */ + private $listsAnnouncements; + + /** + * ListAnnouncementsLogic constructor. + * @param CanListAnnouncements $canListAnnouncements + * @param ListsAnnouncements $listsAnnouncements + */ + public function __construct(CanListAnnouncements $canListAnnouncements, ListsAnnouncements $listsAnnouncements) + { + $this->canListAnnouncements = $canListAnnouncements; + $this->listsAnnouncements = $listsAnnouncements; + } + + + /** + * @param Request $request + * @return JsonResponse + * @throws \App\Classes\Exceptions\AccessForbiddenException + * @throws \App\Classes\Exceptions\MalformedRequestException + * @throws \App\Classes\Exceptions\RequestValidationException + */ + public function logic(Request $request): JsonResponse + { + + $this->canListAnnouncements->passes(); + + $annoucements = $this->listsAnnouncements->execute($this->listsAnnouncements->deserializeFilters($request->input('filters'))); + + return $this->collectionResponse(AnnouncementResource::collection($annoucements)); + } +} diff --git a/app/Classes/Modules/Announcements/ControllersLogic/RemoveSegmentFromAnnouncementLogic.php b/app/Classes/Modules/Announcements/ControllersLogic/RemoveSegmentFromAnnouncementLogic.php new file mode 100644 index 00000000..284d20b9 --- /dev/null +++ b/app/Classes/Modules/Announcements/ControllersLogic/RemoveSegmentFromAnnouncementLogic.php @@ -0,0 +1,68 @@ + 'Detach Announcement From Segment', + 'message' => 'You have successfully detached Announcement from segment' + ]; + } + + /** @var FetchesAnnouncement */ + private $fetchesAnnnouncement; + + /** @var FetchesSegment */ + private $fetchesSegment; + + /** @var RemovesAnnouncementFromSegment */ + private $removesAnnouncementFromSegment; + + /** + * RemoveSegmentFromAnnouncementLogic constructor. + * @param FetchesAnnouncement $fetchesAnnnouncement + * @param FetchesSegment $fetchesSegment + * @param RemovesAnnouncementFromSegment $removesAnnouncementFromSegment + */ + public function __construct(FetchesAnnouncement $fetchesAnnnouncement, FetchesSegment $fetchesSegment, RemovesAnnouncementFromSegment $removesAnnouncementFromSegment) + { + $this->fetchesAnnnouncement = $fetchesAnnnouncement; + $this->fetchesSegment = $fetchesSegment; + $this->removesAnnouncementFromSegment = $removesAnnouncementFromSegment; + } + + /** + * @param Request $request + * @return JsonResponse + * @throws \App\Classes\Exceptions\MalformedRequestException + */ + public function logic(Request $request): JsonResponse + { + + $announcement = $this->fetchesAnnnouncement->execute(['id' => $request->route('id')]); + + $segment = $this->fetchesSegment->execute(['id' => $request->route('segment_id')]); + + $this->removesAnnouncementFromSegment->execute($announcement, $segment); + + return $this->resourceResponse(new AnnouncementResource($announcement)); + } +} diff --git a/app/Classes/Modules/Announcements/ControllersLogic/UpdateAnnouncementLogic.php b/app/Classes/Modules/Announcements/ControllersLogic/UpdateAnnouncementLogic.php new file mode 100644 index 00000000..4fac4144 --- /dev/null +++ b/app/Classes/Modules/Announcements/ControllersLogic/UpdateAnnouncementLogic.php @@ -0,0 +1,83 @@ + 'Update Announcement', + 'message' => 'You have successfully updated the Announcement' + ]; + } + + /** @var CanUpdateAnnouncement */ + private $canUpdateAnnouncement; + + /** @var FetchesAnnouncement */ + private $fetchesAnnouncement; + + /** @var UpdatesAnnouncement */ + private $updatesAnnouncement; + + /** + * UpdateAnnouncementLogic constructor. + * @param CanUpdateAnnouncement $canUpdateAnnouncement + * @param FetchesAnnouncement $fetchesAnnouncement + * @param UpdatesAnnouncement $updatesAnnouncement + */ + public function __construct( + CanUpdateAnnouncement $canUpdateAnnouncement, + FetchesAnnouncement $fetchesAnnouncement, + UpdatesAnnouncement $updatesAnnouncement + ) { + $this->canUpdateAnnouncement = $canUpdateAnnouncement; + $this->fetchesAnnouncement = $fetchesAnnouncement; + $this->updatesAnnouncement = $updatesAnnouncement; + } + + /** + * @param Request $request + * @return JsonResponse + * @throws \App\Classes\Exceptions\AccessForbiddenException + * @throws \App\Classes\Exceptions\MalformedRequestException + * @throws \App\Classes\Exceptions\RequestValidationException + */ + public function logic(Request $request): JsonResponse + { + $annoucement_object = new AnnouncementObject( + $request->input('title'), + $request->input('description'), + $request->input('starting_on'), + $request->input('ending_on') + ); + + $this->canUpdateAnnouncement->passes($annoucement_object); + + $annoucement = $this->fetchesAnnouncement->execute(['id' => $request->route('id')]); + + $announcement_query = $this->updatesAnnouncement->execute($annoucement, $annoucement_object); + + //$announcement_query->segments()->sync($request->input('segment_id')); + + return $this->resourceResponse(new AnnouncementResource($announcement_query)); + } +} diff --git a/app/Classes/Modules/Announcements/DataTransferObjects/AnnouncementObject.php b/app/Classes/Modules/Announcements/DataTransferObjects/AnnouncementObject.php new file mode 100644 index 00000000..6493811d --- /dev/null +++ b/app/Classes/Modules/Announcements/DataTransferObjects/AnnouncementObject.php @@ -0,0 +1,73 @@ +title = $title; + $this->description = $description; + $this->starting_on = $starting_on; + $this->ending_on = $ending_on; + } + + /** + * @return string + */ + public function getTitle(): string + { + return $this->title; + } + + /** + * @return string + */ + public function getDescription(): string + { + return $this->description; + } + + /** + * @return Carbon + */ + public function getStartingOn(): Carbon + { +// return $this->starting_on; + return Carbon::parse($this->starting_on); + } + + /** + * @return Carbon + */ + public function getEndingOn(): Carbon + { +// return $this->ending_on; + return Carbon::parse($this->ending_on); + } +} diff --git a/app/Classes/Modules/Announcements/Processors/AssignAnnouncementToSegmentProcessor.php b/app/Classes/Modules/Announcements/Processors/AssignAnnouncementToSegmentProcessor.php new file mode 100644 index 00000000..f5468a80 --- /dev/null +++ b/app/Classes/Modules/Announcements/Processors/AssignAnnouncementToSegmentProcessor.php @@ -0,0 +1,56 @@ +canAssignSegment = $canAssignSegment; + $this->assignsAnnouncementToSegment = $assignsAnnouncementToSegment; + $this->fetchesSegment = $fetchesSegment; + } + + + /** + * @param Announcement $announcement + * @param int|null $segmentId + * @return Model + * @throws \App\Classes\Exceptions\AccessForbiddenException + * @throws \App\Classes\Exceptions\MalformedRequestException + * @throws \App\Classes\Exceptions\RequestValidationException + */ + public function execute(Announcement $announcement, ?int $segmentId = SegmentConstants::STANDARD_SEGMENT): Model + { + $this->canAssignSegment->passes(); + + $segment = $this->fetchesSegment->execute(['id' => $segmentId]); + + return $this->assignsAnnouncementToSegment->execute($announcement, $segment); + } +} diff --git a/app/Classes/Modules/Announcements/Services/AssignsAnnouncementToSegment.php b/app/Classes/Modules/Announcements/Services/AssignsAnnouncementToSegment.php new file mode 100644 index 00000000..5cc459b1 --- /dev/null +++ b/app/Classes/Modules/Announcements/Services/AssignsAnnouncementToSegment.php @@ -0,0 +1,33 @@ +segments()->attach($segment); + + return $announcement; + + } catch (QueryException $exception){ + throw new MalformedRequestException($exception); + } + + + } +} \ No newline at end of file diff --git a/app/Classes/Modules/Announcements/Services/CreatesAnnouncement.php b/app/Classes/Modules/Announcements/Services/CreatesAnnouncement.php new file mode 100644 index 00000000..4a43bac8 --- /dev/null +++ b/app/Classes/Modules/Announcements/Services/CreatesAnnouncement.php @@ -0,0 +1,26 @@ +title = $object->getTitle(); + $model->description = $object->getDescription(); + $model->starting_on = $object->getStartingOn(); + $model->ending_on = $object->getEndingOn(); + + return $this->handler($model); + } +} diff --git a/app/Classes/Modules/Announcements/Services/DeletesAnnouncement.php b/app/Classes/Modules/Announcements/Services/DeletesAnnouncement.php new file mode 100644 index 00000000..82e312cc --- /dev/null +++ b/app/Classes/Modules/Announcements/Services/DeletesAnnouncement.php @@ -0,0 +1,19 @@ +handler($model); + } +} \ No newline at end of file diff --git a/app/Classes/Modules/Announcements/Services/FetchesAnnouncement.php b/app/Classes/Modules/Announcements/Services/FetchesAnnouncement.php new file mode 100644 index 00000000..f43b9e46 --- /dev/null +++ b/app/Classes/Modules/Announcements/Services/FetchesAnnouncement.php @@ -0,0 +1,34 @@ +repository = $repository; + } + + + /** + * @return Builder + */ + public function getRepository(): Builder + { + return $this->repository->newQuery(); + } +} \ No newline at end of file diff --git a/app/Classes/Modules/Announcements/Services/ListsAnnouncements.php b/app/Classes/Modules/Announcements/Services/ListsAnnouncements.php new file mode 100644 index 00000000..b821819a --- /dev/null +++ b/app/Classes/Modules/Announcements/Services/ListsAnnouncements.php @@ -0,0 +1,32 @@ +repository = $repository; + } + + + /** + * @return Builder + */ + function getRepository(): Builder + { + return $this->repository->newQuery(); + } +} diff --git a/app/Classes/Modules/Announcements/Services/RemovesAnnouncementFromSegment.php b/app/Classes/Modules/Announcements/Services/RemovesAnnouncementFromSegment.php new file mode 100644 index 00000000..bd34d52f --- /dev/null +++ b/app/Classes/Modules/Announcements/Services/RemovesAnnouncementFromSegment.php @@ -0,0 +1,33 @@ +segments()->detach($segment); + + return $announcement; + + } catch (QueryException $exception){ + throw new MalformedRequestException($exception); + } + + + } +} \ No newline at end of file diff --git a/app/Classes/Modules/Announcements/Services/UpdatesAnnouncement.php b/app/Classes/Modules/Announcements/Services/UpdatesAnnouncement.php new file mode 100644 index 00000000..98d5da7a --- /dev/null +++ b/app/Classes/Modules/Announcements/Services/UpdatesAnnouncement.php @@ -0,0 +1,27 @@ +title = $object->getTitle(); + $model->description = $object->getDescription(); + $model->starting_on = $object->getStartingOn(); + $model->ending_on = $object->getEndingOn(); + + return $this->handler($model); + } +} \ No newline at end of file diff --git a/app/Classes/Modules/Announcements/Standards/Rules/CanAssignSegment.php b/app/Classes/Modules/Announcements/Standards/Rules/CanAssignSegment.php new file mode 100644 index 00000000..625a07a1 --- /dev/null +++ b/app/Classes/Modules/Announcements/Standards/Rules/CanAssignSegment.php @@ -0,0 +1,40 @@ +AnnouncementValidation = $AnnouncementValidation; + } + + /** + * @return bool + */ + protected function authorized(): bool + { + return true; + } + + /** + * @param AnnouncementObject $object + * @return bool + * @throws \App\Classes\Exceptions\RequestValidationException + */ + protected function validators($object): bool + { + return $this->AnnouncementValidation->validate($object); + } + + /** + * @param AnnouncementObject $object + * @return bool + */ + protected function criteria($object): bool + { + return true; + } +} \ No newline at end of file diff --git a/app/Classes/Modules/Announcements/Standards/Rules/CanDeleteAnnouncement.php b/app/Classes/Modules/Announcements/Standards/Rules/CanDeleteAnnouncement.php new file mode 100644 index 00000000..8a41deab --- /dev/null +++ b/app/Classes/Modules/Announcements/Standards/Rules/CanDeleteAnnouncement.php @@ -0,0 +1,40 @@ +AnnouncementValidation = $AnnouncementValidation; + } + + /** + * @return bool + */ + protected function authorized(): bool + { + // TODO Set Authorization rules + return true; + } + + /** + * @param AnnouncementObject $object + * @return bool + * @throws \App\Classes\Exceptions\RequestValidationException + */ + protected function validators($object): bool + { + return $this->AnnouncementValidation->validate($object); + } + + /** + * @param AnnouncementObject $object + * @return bool + */ + protected function criteria($object): bool + { + return true; + } + +} \ No newline at end of file diff --git a/app/Classes/Modules/Announcements/Standards/Validators/AnnouncementValidation.php b/app/Classes/Modules/Announcements/Standards/Validators/AnnouncementValidation.php new file mode 100644 index 00000000..f094b8aa --- /dev/null +++ b/app/Classes/Modules/Announcements/Standards/Validators/AnnouncementValidation.php @@ -0,0 +1,44 @@ + $object->getTitle(), + 'description' => $object->getDescription(), + 'starting_on' => $object->getStartingOn(), + 'ending_on' => $object->getEndingOn() + ]; + } + + /** + * @return array + */ + protected function rules(): array + { + return [ + 'title' => 'required', + 'description' => 'required', + 'starting_on' => 'required', + 'ending_on' => 'required' + ]; + } + + /** + * @return array + */ + protected function messages(): array + { + return []; + } +} \ No newline at end of file diff --git a/app/Classes/Modules/Contacts/Processors/CreateContactProcessor.php b/app/Classes/Modules/Contacts/Processors/CreateContactProcessor.php index 9e04a134..060e4ad5 100644 --- a/app/Classes/Modules/Contacts/Processors/CreateContactProcessor.php +++ b/app/Classes/Modules/Contacts/Processors/CreateContactProcessor.php @@ -2,11 +2,10 @@ namespace App\Classes\Modules\Contacts\Processors; +use App\Classes\General\Interfaces\Contactable; use App\Classes\Modules\Contacts\DataTransferObjects\ContactObject; use App\Classes\Modules\Contacts\Services\CreatesContact; use App\Classes\Modules\Contacts\Standards\Rules\CanCreateContact; -use App\Models\Company; -use Illuminate\Http\Request; use Illuminate\Database\Eloquent\Model; class CreateContactProcessor @@ -15,6 +14,9 @@ class CreateContactProcessor /** @var CanCreateContact */ private $canCreateContact; + /** @var CreatesContact */ + private $createsContact; + /** * CreateContactProcessor constructor. * @param CanCreateContact $canCreateContact @@ -28,17 +30,17 @@ class CreateContactProcessor /** * @param ContactObject $object - * @param Company $company + * @param Contactable $contactable * @return Model * @throws \App\Classes\Exceptions\AccessForbiddenException * @throws \App\Classes\Exceptions\MalformedRequestException * @throws \App\Classes\Exceptions\RequestValidationException */ - public function execute(ContactObject $object, Company $company): Model + public function execute(ContactObject $object, Contactable $contactable): Model { $this->canCreateContact->passes($object); - return $this->createsContact->execute($company,$object); + return $this->createsContact->execute($contactable,$object); } } diff --git a/app/Classes/Modules/Orders/ControllersLogic/CreateOrderLogic.php b/app/Classes/Modules/Orders/ControllersLogic/CreateOrderLogic.php index e9c92aef..b43e2997 100644 --- a/app/Classes/Modules/Orders/ControllersLogic/CreateOrderLogic.php +++ b/app/Classes/Modules/Orders/ControllersLogic/CreateOrderLogic.php @@ -2,6 +2,7 @@ namespace App\Classes\Modules\Orders\ControllersLogic; +use App\Classes\Exceptions\RequestValidationException; use App\Classes\General\Abstracts\AbstractControllerLogic; use App\Classes\Modules\Addresses\Services\FetchesAddress; use App\Classes\Modules\Companies\Services\FetchesCompany; @@ -58,17 +59,17 @@ class CreateOrderLogic extends AbstractControllerLogic 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')]); - if($originWarehouse->reference === WarehouseReferences::VT_GUANG_ZHOU){ - $marking = $company->companyModules()->importers()->first()->inviters()->withPivot('invitee_reference')->first()->pivot->invitee_reference; - if(in_array($marking, ['2192KAA', '2353GFE', '6866DTR', '1905JYW', '1291NSC', '8288MIB'])){ - $originWarehouse = $this->fetchesCompanyModule->execute(['reference' => WarehouseReferences::YD_GUANG_ZHOU]); - } + $originWarehouse = $originWarehouse->reference === WarehouseReferences::VT_GUANG_ZHOU ? $this->fetchesCompanyModule->execute(['reference' => WarehouseReferences::YD_GUANG_ZHOU]) : $this->fetchesCompanyModule->execute(['reference' => 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 due to the chinese new year\'s holiday. you can select our Guangzhou warehouse as an alternative.'); } $order = $this->createOrderProcessor->execute($company, $originWarehouse, $address, $this->generatesOrderNumber->execute()); diff --git a/app/Classes/Modules/Orders/ControllersLogic/CreateOrderRemarkLogic.php b/app/Classes/Modules/Orders/ControllersLogic/CreateOrderRemarkLogic.php new file mode 100644 index 00000000..e134bcc7 --- /dev/null +++ b/app/Classes/Modules/Orders/ControllersLogic/CreateOrderRemarkLogic.php @@ -0,0 +1,60 @@ + 'Created Order', + 'message' => 'You have successfully created a new Order' + ]; + } + + /** @var FetchesOrder */ + private $fetchesOrder; + + /** @var CreateRemarkProcessor */ + private $createRemarkProcessor; + + /** + * CreateOrderRemarkLogic constructor. + * @param FetchesOrder $fetchesOrder + * @param CreateRemarkProcessor $createRemarkProcessor + */ + public function __construct(FetchesOrder $fetchesOrder, CreateRemarkProcessor $createRemarkProcessor) + { + $this->fetchesOrder = $fetchesOrder; + $this->createRemarkProcessor = $createRemarkProcessor; + } + + /** + * @param Request $request + * @return JsonResponse + * @throws \App\Classes\Exceptions\AccessForbiddenException + * @throws \App\Classes\Exceptions\MalformedRequestException + * @throws \App\Classes\Exceptions\RequestValidationException + */ + public function logic(Request $request) : JsonResponse + { + $order = $this->fetchesOrder->execute(['id' => $request->route('id')]); + + $object = new RemarkObject($request->input('content'), auth()->user()->id); + + $this->createRemarkProcessor->execute($order, $object); + + return $this->resourceResponse(new OrderResource($order)); + + } +} diff --git a/app/Classes/Modules/Orders/ControllersLogic/UpdateOrderLogic.php b/app/Classes/Modules/Orders/ControllersLogic/UpdateOrderLogic.php new file mode 100644 index 00000000..06c00de3 --- /dev/null +++ b/app/Classes/Modules/Orders/ControllersLogic/UpdateOrderLogic.php @@ -0,0 +1,46 @@ + 'Update Order', + 'message' => 'You have successfully update the order' + ]; + } + + private $updateOrderReference; + private $fetchesOrder; + + public function __construct(UpdateOrderReference $updateOrderReference, FetchesOrder $fetchesOrder) + { + $this->updateOrderReference = $updateOrderReference; + $this->fetchesOrder = $fetchesOrder; + } + + protected function logic(Request $request): JsonResponse + { + $reference_id = $request->input('reference_id'); + + $order = $this->fetchesOrder->execute(['id' => $request->route('id')]); + + $order = $this->updateOrderReference->execute($order, $reference_id); + + return $this->resourceResponse(new OrderResource($order)); + + } +} diff --git a/app/Classes/Modules/Orders/Processors/ApproveChangeOrderAddressProcessor.php b/app/Classes/Modules/Orders/Processors/ApproveChangeOrderAddressProcessor.php index fbd84f90..3477131c 100644 --- a/app/Classes/Modules/Orders/Processors/ApproveChangeOrderAddressProcessor.php +++ b/app/Classes/Modules/Orders/Processors/ApproveChangeOrderAddressProcessor.php @@ -6,6 +6,7 @@ use App\Classes\Modules\Addresses\Services\FetchesAddress; use App\Classes\Modules\Orders\Standards\Rules\CanApproveChangeOrderAddress; use App\Classes\Modules\Orders\Services\UpdatesOrdersAddress; use App\Classes\ValueObjects\Constants\ApprovalStatus; +use App\Classes\Modules\Orders\Processors\UpdateDoFromVTPortalProcessor; use Illuminate\Http\Request; @@ -20,17 +21,21 @@ class ApproveChangeOrderAddressProcessor /** @var UpdatesOrdersAddress */ private $updatesOrdersAddress; + /** @var UpdateDoFromVTPortalProcessor */ + private $updateDoFromVTPortalProcessor; + /** * ApproveChangeOrderAddressProcessor constructor. * @param CanApproveChangeOrderAddress $canApproveChangeOrderAddress * @param FetchesAddress $fetchesAddress * @param UpdatesOrdersAddress $updatesOrdersAddress */ - public function __construct(CanApproveChangeOrderAddress $canApproveChangeOrderAddress, FetchesAddress $fetchesAddress, UpdatesOrdersAddress $updatesOrdersAddress) + public function __construct(CanApproveChangeOrderAddress $canApproveChangeOrderAddress, FetchesAddress $fetchesAddress, UpdatesOrdersAddress $updatesOrdersAddress, UpdateDoFromVTPortalProcessor $updateDoFromVTPortalProcessor) { $this->canApproveChangeOrderAddress = $canApproveChangeOrderAddress; $this->fetchesAddress = $fetchesAddress; $this->updatesOrdersAddress = $updatesOrdersAddress; + $this->updateDoFromVTPortalProcessor = $updateDoFromVTPortalProcessor; } @@ -38,12 +43,13 @@ class ApproveChangeOrderAddressProcessor * @param Request $request * @return mixed * @throws \App\Classes\Exceptions\AccessForbiddenException + * @throws \App\Classes\Exceptions\InternalServerErrorException * @throws \App\Classes\Exceptions\MalformedRequestException * @throws \App\Classes\Exceptions\RequestValidationException + * @throws \GuzzleHttp\Exception\GuzzleException */ public function execute(Request $request) { - $status = (int) $request->route('status'); $this->canApproveChangeOrderAddress->passes(); @@ -52,9 +58,10 @@ class ApproveChangeOrderAddressProcessor if($status === ApprovalStatus::APPROVED){ $address->owner->addresses()->update(['status' => ApprovalStatus::EXPIRED]); + $this->updateDoFromVTPortalProcessor->execute($address); } - $this->updatesOrdersAddress->execute($address, $status); + $address = $this->updatesOrdersAddress->execute($address, $status); return $address; } diff --git a/app/Classes/Modules/Orders/Processors/CreateOrderProcessor.php b/app/Classes/Modules/Orders/Processors/CreateOrderProcessor.php index 53350d59..5a7c22eb 100644 --- a/app/Classes/Modules/Orders/Processors/CreateOrderProcessor.php +++ b/app/Classes/Modules/Orders/Processors/CreateOrderProcessor.php @@ -8,6 +8,11 @@ use App\Classes\Modules\Addresses\Services\CreatesAddress; use App\Classes\Modules\Addresses\Services\FetchesAddress; use App\Classes\Modules\Companies\Services\FetchesCompany; use App\Classes\Modules\Orders\DataTransferObjects\OrderObject; +use App\Classes\Modules\Contacts\DataTransferObjects\ContactObject; +use App\Classes\Modules\Remarks\DataTransferObjects\RemarkObject; +use App\Classes\Modules\Contacts\Processors\CreateContactProcessor; +use App\Classes\Modules\Remarks\Processors\CreateRemarkProcessor; + use App\Classes\Modules\Orders\Services\CreatesOrder; use App\Classes\Modules\Orders\Services\GeneratesOrderNumber; use App\Classes\Modules\Orders\Standards\Rules\CanCreateOrder; @@ -33,6 +38,12 @@ class CreateOrderProcessor /** @var CreateOrderRolesProcessor */ private $createOrderRolesProcessor; + /** @var CreateContactProcessor */ + private $createContactProcessor; + + /** @var CreateRemarkProcessor */ + private $createRemarkProcessor; + /** * CreateOrderProcessor constructor. * @param CanCreateOrder $canCreateOrder @@ -40,12 +51,14 @@ class CreateOrderProcessor * @param CreatesAddress $createAddress * @param CreateOrderRolesProcessor $createOrderRolesProcessor */ - public function __construct(CanCreateOrder $canCreateOrder, CreatesOrder $createsOrder, CreatesAddress $createAddress, CreateOrderRolesProcessor $createOrderRolesProcessor) + public function __construct(CanCreateOrder $canCreateOrder, CreatesOrder $createsOrder, CreatesAddress $createAddress, CreateOrderRolesProcessor $createOrderRolesProcessor, CreateContactProcessor $createContactProcessor, CreateRemarkProcessor $createRemarkProcessor) { $this->canCreateOrder = $canCreateOrder; $this->createsOrder = $createsOrder; $this->createAddress = $createAddress; $this->createOrderRolesProcessor = $createOrderRolesProcessor; + $this->createContactProcessor = $createContactProcessor; + $this->createRemarkProcessor = $createRemarkProcessor; } @@ -73,7 +86,37 @@ class CreateOrderProcessor $addressObject = new AddressObject($address->street_one, $address->street_two, $address->country_id, $address->state_id, $address->district_id, $address->postcode,$address->reference); - $this->createAddress->execute($order, $addressObject); + /** @var Address $order_address */ + $order_address = $this->createAddress->execute($order, $addressObject); + + $contact = $address->contacts()->first(); + + if ($contact) { + $contactObject = new ContactObject( + $contact->reference, + $contact->phone, + '', + '' + ); + + if($contactObject->getPhone()){ + $order_remark = $this->createContactProcessor->execute($contactObject, $order_address); + } + } + + $remark = $address->remarks()->first(); + + if ($remark){ + $remarkObject = new RemarkObject( + $remark->content, + Auth()->user()->id + ); + + if($remarkObject->getContent()){ + $this->createRemarkProcessor->execute($order_address, $remarkObject); + } + } + $this->createOrderRolesProcessor->execute($originWarehouse, $order); diff --git a/app/Classes/Modules/Orders/Processors/CreateOrderRolesProcessor.php b/app/Classes/Modules/Orders/Processors/CreateOrderRolesProcessor.php index 7ca3603f..82cf1e27 100644 --- a/app/Classes/Modules/Orders/Processors/CreateOrderRolesProcessor.php +++ b/app/Classes/Modules/Orders/Processors/CreateOrderRolesProcessor.php @@ -53,7 +53,7 @@ class CreateOrderRolesProcessor $importer = $order->companyModule; /** @var CompanyModule $destinationWarehouse */ - $destinationWarehouse = $this->fetchesCompanyModule->execute(['reference' => $originWarehouse->reference === WarehouseReferences::YD_GUANG_ZHOU ? WarehouseReferences::YD_DESTINATION_WAREHOUSE : WarehouseReferences::VT_DESTINATION_WAREHOUSE[$address->state_id]]); + $destinationWarehouse = $this->fetchesCompanyModule->execute(['reference' => $originWarehouse->reference === WarehouseReferences::YD_GUANG_ZHOU || $originWarehouse->reference === WarehouseReferences::YD_YIWU ? WarehouseReferences::YD_DESTINATION_WAREHOUSE : WarehouseReferences::VT_DESTINATION_WAREHOUSE[$address->state_id]]); /** @var CompanyModule $freightForwarder */ $freightForwarder = $originWarehouse->company->companyModules()->freightForwarders()->first(); @@ -79,7 +79,6 @@ class CreateOrderRolesProcessor $roleObject = new OrderRoleObject($order, $destinationWarehouse, OrderRoleTypes::DESTINATION_WAREHOUSE); $this->createsOrderRole->execute($roleObject); - $roleObject = new OrderRoleObject($order, $freightForwarder, OrderRoleTypes::LAST_MILE_DELIVERY_DRIVER); $this->createsOrderRole->execute($roleObject); diff --git a/app/Classes/Modules/Orders/Processors/RequestChangeOrderAddressProcessor.php b/app/Classes/Modules/Orders/Processors/RequestChangeOrderAddressProcessor.php index 7f01726b..81b31026 100644 --- a/app/Classes/Modules/Orders/Processors/RequestChangeOrderAddressProcessor.php +++ b/app/Classes/Modules/Orders/Processors/RequestChangeOrderAddressProcessor.php @@ -9,6 +9,10 @@ use App\Classes\Modules\Addresses\Services\FetchesAddress; use App\Classes\Modules\Addresses\Services\DeletesAddress; use App\Classes\Modules\Addresses\DataTransferObjects\AddressObject; use App\Classes\ValueObjects\Constants\ApprovalStatus; +use App\Classes\Modules\Contacts\DataTransferObjects\ContactObject; +use App\Classes\Modules\Remarks\DataTransferObjects\RemarkObject; +use App\Classes\Modules\Contacts\Processors\CreateContactProcessor; +use App\Classes\Modules\Remarks\Processors\CreateRemarkProcessor; use Illuminate\Http\Request; @@ -29,6 +33,12 @@ class RequestChangeOrderAddressProcessor /** @var DeletesAddress */ private $deletesAddress; + /** @var CreateContactProcessor */ + private $createContactProcessor; + + /** @var CreateRemarkProcessor */ + private $createRemarkProcessor; + /** * ChangeOrderAddressProcessor constructor. * @param FetchesOrder $fetchesOrder @@ -36,7 +46,7 @@ class RequestChangeOrderAddressProcessor * @param FetchesAddress $fetchesAddress * @param DeletesAddress $deletesAddress */ - public function __construct(CanChangeOrderAddress $canChangeOrderAddress, FetchesOrder $fetchesOrder, CreatesAddress $createsAddress, FetchesAddress $fetchesAddress, DeletesAddress $deletesAddress) + public function __construct(CanChangeOrderAddress $canChangeOrderAddress, FetchesOrder $fetchesOrder, CreatesAddress $createsAddress, FetchesAddress $fetchesAddress, DeletesAddress $deletesAddress, CreateContactProcessor $createContactProcessor, CreateRemarkProcessor $createRemarkProcessor) { $this->canChangeOrderAddress = $canChangeOrderAddress; @@ -44,12 +54,20 @@ class RequestChangeOrderAddressProcessor $this->createsAddress = $createsAddress; $this->fetchesAddress = $fetchesAddress; $this->deletesAddress = $deletesAddress; + $this->createContactProcessor = $createContactProcessor; + $this->createRemarkProcessor = $createRemarkProcessor; } + /** + * @param Request $request + * @return mixed + * @throws \App\Classes\Exceptions\AccessForbiddenException + * @throws \App\Classes\Exceptions\MalformedRequestException + * @throws \App\Classes\Exceptions\RequestValidationException + */ public function execute(Request $request) { - $this->canChangeOrderAddress->passes(); $order = $this->fetchesOrder->execute(['id' => $request->get('order_id')]); @@ -59,7 +77,32 @@ class RequestChangeOrderAddressProcessor $address = $this->fetchesAddress->execute(['id' => $request->get('address_id')]); $addressObject = new AddressObject($address->street_one, $address->street_two, $address->country_id, $address->state_id, $address->district_id, $address->postcode, $address->reference, ApprovalStatus::PENDING_VERIFICATION); - $this->createsAddress->execute($order, $addressObject); + $order_address = $this->createsAddress->execute($order, $addressObject); + + $contact = $address->contacts()->first(); + if($contact){ + $contactObject = new ContactObject( + $contact->reference, + $contact->phone, + '', + '' + ); + + $this->createContactProcessor->execute($contactObject, $order_address); + + } + + $remark = $address->remarks()->first(); + + if($remark){ + $remarkObject = new RemarkObject( + $remark->content, + Auth()->user()->id + ); + + $this->createRemarkProcessor->execute($order_address, $remarkObject); + } + return $order; } diff --git a/app/Classes/Modules/Orders/Processors/UpdateDoFromVTPortalProcessor.php b/app/Classes/Modules/Orders/Processors/UpdateDoFromVTPortalProcessor.php new file mode 100644 index 00000000..74fb7f62 --- /dev/null +++ b/app/Classes/Modules/Orders/Processors/UpdateDoFromVTPortalProcessor.php @@ -0,0 +1,148 @@ +fetchesDataFRomVTPortal = $fetchesDataFRomVTPortal; + $this->fetchesAddress = $fetchesAddress; + } + + /** + * @param $address + * @return array + * @throws GuzzleException + */ + public function execute($address) { + + if(!app()->environment(['production'])){ + return []; + } + + try { + $order = $address->owner()->orderBy('id', 'desc')->first(); + $packing_list = $order->packingLists()->orderBy('id', 'desc')->first(); + + if ($packing_list) { + $contact = $address->contacts()->first(); + $remark = $address->remarks()->first(); + + $remark = $remark ? $remark->content : 'URGENT!!! PLEASE CALL BEFORE ONE DAY DELIVERY.'; + $phone = $contact ? $contact->phone : null; + $reference = $contact ? $contact->reference : null; + + $status = 'On Hold'; + + if (in_array($packing_list->status, [ApprovalStatus::PENDING_VERIFICATION, ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED])) { + $status = 'Release'; + } + + $vt_do = $this->fetchesDataFRomVTPortal->clientRequest('http://portal.vtnation.com.my/Services/DataControllerService.asmx/GetPage', 'POST', json_decode('{"controller":"Do","view":"grid1","request":{"PageIndex":-1,"PageSize":10000,"Filter": ["FullMarking:$contains$%js%\"' . $order->reference . '\"\u0000"]}}'), ''); + + $vt_do = $this->fetchesDataFRomVTPortal->getResponseBody($vt_do); + + if ($vt_do) { + foreach ($vt_do->Rows as $key => $row) { + $vt_do_update = $this->fetchesDataFRomVTPortal->clientRequest( + 'http://portal.vtnation.com.my/Services/DataControllerService.asmx/Execute', + 'POST', + json_decode('{ + "controller": "Do", + "view": "editForm1", + "args": { + "CommandName": "Update", + "CommandArgument": "Save", + "Path": "ag2/a4", + "LastCommandName": "Edit", + "Values": [ + { + "Name": "ShippingAddress", + "NewValue": "' . $address->street_one . ' ' . $address->street_two . ' '. $address->district->name.' '. $address->post_code.' '.$address->state->name.' '.$address->country->name.'", + "Modified": true, + "ReadOnly": false, + "Error": null + }, + { + "Name": "Attn", + "NewValue": "'.$reference.'", + "Modified": true, + "ReadOnly": false, + "Error": null + }, + { + "Name": "Tel", + "NewValue": "'.$phone.'", + "Modified": true, + "ReadOnly": false, + "Error": null + }, + { + "Name": "Status", + "NewValue": "' . $status . '", + "Modified": true, + "ReadOnly": false, + "Error": null + }, + { + "Name": "Doremarks", + "NewValue": "'. $remark .'", + "Modified": true, + "ReadOnly": false, + "Error": null + }, + { + "Name": "DoID", + "OldValue": '.$row[0].', + "NewValue": '.$row[0].', + "Modified": false, + "ReadOnly": true, + "Error": null + } + ], + "Controller": "Do" + } + }'), ''); + } + } + } + + } catch (\Exception $exception){ + return []; + } + + } +} diff --git a/app/Classes/Modules/Orders/Services/FetchesDataFromYDPortal.php b/app/Classes/Modules/Orders/Services/FetchesDataFromYDPortal.php new file mode 100644 index 00000000..4948ad4f --- /dev/null +++ b/app/Classes/Modules/Orders/Services/FetchesDataFromYDPortal.php @@ -0,0 +1,34 @@ +requestAsync($method, $url, ['query' => $body]); + + return $request->wait(); + } + + public function getResponseBody(ResponseInterface $request){ + $content = $request->getBody()->getContents(); + $content = str_replace("\r",'', $content); + return json_decode($content); + } +} \ No newline at end of file diff --git a/app/Classes/Modules/Orders/Services/UpdateOrderReference.php b/app/Classes/Modules/Orders/Services/UpdateOrderReference.php new file mode 100644 index 00000000..0768c4c9 --- /dev/null +++ b/app/Classes/Modules/Orders/Services/UpdateOrderReference.php @@ -0,0 +1,17 @@ +reference = $reference; + + return $this->handler($model); + } +} diff --git a/app/Classes/Modules/PackingLists/ControllersLogic/Containers/FetchContainerLogic.php b/app/Classes/Modules/PackingLists/ControllersLogic/Containers/FetchContainerLogic.php index c8c8548d..f1f46eb1 100644 --- a/app/Classes/Modules/PackingLists/ControllersLogic/Containers/FetchContainerLogic.php +++ b/app/Classes/Modules/PackingLists/ControllersLogic/Containers/FetchContainerLogic.php @@ -45,21 +45,16 @@ class FetchContainerLogic extends AbstractControllerLogic /** * @param Request $request * @return JsonResponse - * @throws ErrorException + * @throws \App\Classes\Exceptions\AccessForbiddenException + * @throws \App\Classes\Exceptions\RequestValidationException */ public function logic(Request $request) : JsonResponse { - try { + $this->canFetchContainer->passes(); - $this->canFetchContainer->passes(); + $query = $this->fetchesContainer->execute(['id' => $request->route('id'), 'with_packing_lists' => true]); - $query = $this->fetchesContainer->execute(['id' => $request->route('id'), 'with_packing_lists' => true]); - - return $this->resourceResponse(new ContainerResource($query)); - - } catch (\Exception $exception){ - throw new ErrorException($exception->getMessage(), $exception->getCode()); - } + return $this->resourceResponse(new ContainerResource($query)); } diff --git a/app/Classes/Modules/PackingLists/ControllersLogic/Packages/ListPackagesLogic.php b/app/Classes/Modules/PackingLists/ControllersLogic/Packages/ListPackagesLogic.php index 80d73e5b..73b05ddb 100644 --- a/app/Classes/Modules/PackingLists/ControllersLogic/Packages/ListPackagesLogic.php +++ b/app/Classes/Modules/PackingLists/ControllersLogic/Packages/ListPackagesLogic.php @@ -45,21 +45,17 @@ class ListPackagesLogic extends AbstractControllerLogic /** * @param Request $request * @return JsonResponse - * @throws ErrorException + * @throws \App\Classes\Exceptions\AccessForbiddenException + * @throws \App\Classes\Exceptions\MalformedRequestException + * @throws \App\Classes\Exceptions\RequestValidationException */ public function logic(Request $request) : JsonResponse { - try { + $this->canListPackages->passes(); - $this->canListPackages->passes(); + $query = $this->listsPackages->execute($this->listsPackages->deserializeFilters($request->input('filters'))); - $query = $this->listsPackages->execute($this->listsPackages->deserializeFilters($request->input('filters'))); - - return $this->collectionResponse(PackageResource::collection($query)); - - } catch (\Exception $exception){ - throw new ErrorException($exception->getMessage(), $exception->getCode()); - } + return $this->collectionResponse(PackageResource::collection($query)); } diff --git a/app/Classes/Modules/PackingLists/ControllersLogic/UpdatePackingListStatusLogic.php b/app/Classes/Modules/PackingLists/ControllersLogic/UpdatePackingListStatusLogic.php index 67a1733c..9bf1735a 100644 --- a/app/Classes/Modules/PackingLists/ControllersLogic/UpdatePackingListStatusLogic.php +++ b/app/Classes/Modules/PackingLists/ControllersLogic/UpdatePackingListStatusLogic.php @@ -9,6 +9,7 @@ use App\Classes\Modules\PackingLists\Services\FetchesPackingList; use App\Classes\Modules\PackingLists\Services\UpdatesPackingListStatus; use App\Classes\Modules\PackingLists\Standards\Rules\CanUpdatePackingList; use App\Classes\Modules\PackingLists\DataTransferObjects\PackingListObject; +use App\Classes\Modules\Orders\Processors\UpdateDoFromVTPortalProcessor; use App\Http\Resources\PackingListResource; use ErrorException; use Illuminate\Http\JsonResponse; @@ -34,29 +35,38 @@ class UpdatePackingListStatusLogic extends AbstractControllerLogic /** @var UpdatesPackingListStatus */ private $updatesPackingListStatus; + /** @var UpdateDoFromVTPortalProcessor */ + private $updateDoFromVTPortalProcessor; + /** * UpdatePackingListStatusLogic constructor. * @param FetchesPackingList $fetchesPackingList * @param UpdatesPackingListStatus $updatesPackingListStatus */ - public function __construct(FetchesPackingList $fetchesPackingList, UpdatesPackingListStatus $updatesPackingListStatus) + public function __construct(FetchesPackingList $fetchesPackingList, UpdatesPackingListStatus $updatesPackingListStatus, UpdateDoFromVTPortalProcessor $updateDoFromVTPortalProcessor) { $this->fetchesPackingList = $fetchesPackingList; $this->updatesPackingListStatus = $updatesPackingListStatus; + $this->updateDoFromVTPortalProcessor = $updateDoFromVTPortalProcessor; } /** * @param Request $request * @return JsonResponse + * @throws \App\Classes\Exceptions\InternalServerErrorException * @throws \App\Classes\Exceptions\MalformedRequestException + * @throws \GuzzleHttp\Exception\GuzzleException */ public function logic(Request $request) : JsonResponse { $packingList = $this->fetchesPackingList->execute(['id' => $request->route('id')]); - $query = $this->updatesPackingListStatus->execute($packingList, $request->route('status')); + $packing_list = $this->updatesPackingListStatus->execute($packingList, $request->route('status')); + $address = $packing_list->owner()->first()->addresses()->first(); - return $this->resourceResponse(new PackingListResource($query)); + $this->updateDoFromVTPortalProcessor->execute($address); + + return $this->resourceResponse(new PackingListResource($packing_list)); } } diff --git a/app/Classes/Modules/PackingLists/Processors/CreatePackageProcessor.php b/app/Classes/Modules/PackingLists/Processors/CreatePackageProcessor.php index 500a4550..13e4a83b 100644 --- a/app/Classes/Modules/PackingLists/Processors/CreatePackageProcessor.php +++ b/app/Classes/Modules/PackingLists/Processors/CreatePackageProcessor.php @@ -33,7 +33,7 @@ class CreatePackageProcessor /** * @param PackageObject $object * @param PackingList $packingList - * @return \Illuminate\Database\Eloquent\Model + * @return void * @throws \App\Classes\Exceptions\AccessForbiddenException * @throws \App\Classes\Exceptions\RequestValidationException */ @@ -41,7 +41,18 @@ class CreatePackageProcessor $this->canCreatePackage->passes($object); - return $this->createsPackage->execute($object, $packingList); + $this->createsPackage->execute($object, $packingList); + + /** @var PackingList $replica */ + $replica = $packingList->packingLists()->first(); + + if($replica) { + $modificationValue = 1; + $packageObject = new PackageObject($object->getType(), $object->getDescription(), $object->getWidth() + $modificationValue, $object->getHeight() + $modificationValue, $object->getLength() + $modificationValue, $object->getWeight(), $object->getQuantity(), $object->getStatus()); + $this->createsPackage->execute($packageObject, $replica); + } + + return ; } diff --git a/app/Classes/Modules/PackingLists/Processors/CreatePackingListProcessor.php b/app/Classes/Modules/PackingLists/Processors/CreatePackingListProcessor.php index 982b7307..3e2a861d 100644 --- a/app/Classes/Modules/PackingLists/Processors/CreatePackingListProcessor.php +++ b/app/Classes/Modules/PackingLists/Processors/CreatePackingListProcessor.php @@ -7,6 +7,10 @@ use App\Classes\General\Interfaces\Packable; use App\Classes\Modules\PackingLists\DataTransferObjects\PackingListObject; use App\Classes\Modules\PackingLists\Services\CreatesPackingList; use App\Classes\Modules\PackingLists\Standards\Rules\CanCreatePackingList; +use App\Classes\ValueObjects\Constants\ApprovalStatus; +use App\Classes\ValueObjects\Constants\OrderRoleTypes; +use App\Classes\ValueObjects\Constants\PackingListType; +use App\Models\PackingList; class CreatePackingListProcessor { @@ -41,7 +45,15 @@ class CreatePackingListProcessor public function execute(PackingListObject $object, Packable $packable){ $this->canCreatePackingList->passes($object); - return $this->createsPackingList->execute($object, $packable); + /** @var PackingList $packingList */ + $packingList = $this->createsPackingList->execute($object, $packable); + + $type = $object->getType() === PackingListType::SHIPPING_PACKING_LIST ? PackingListType::SHIPPING_PACKING_LIST_REPLICA : PackingListType::WAREHOUSE_RECEIVE_LIST_REPLICA; + /** create packing list replica */ + $object = new PackingListObject($object->getReference().'_01', $packingList->owner->orderRoles()->where('role_id', '=', OrderRoleTypes::ORIGIN_FREIGHT_FORWARDER)->first()->appointee->id, $type, ApprovalStatus::PENDING_SUBMISSION); + $this->createsPackingList->execute($object, $packingList); + + return $packingList; } } \ No newline at end of file diff --git a/app/Classes/Modules/PackingLists/Processors/FetchContainersStatusUpdateFromVTPortalProcessor.php b/app/Classes/Modules/PackingLists/Processors/FetchContainersStatusUpdateFromVTPortalProcessor.php index 955d68d0..b1daeeb9 100644 --- a/app/Classes/Modules/PackingLists/Processors/FetchContainersStatusUpdateFromVTPortalProcessor.php +++ b/app/Classes/Modules/PackingLists/Processors/FetchContainersStatusUpdateFromVTPortalProcessor.php @@ -80,6 +80,10 @@ class FetchContainersStatusUpdateFromVTPortalProcessor $containerDetails = $this->fetchesDataFRomVTPortal->getResponseBody($containerDetailsRequest); + if(!$containerDetails->Rows){ + continue; + } + $containerDetails = $containerDetails->Rows[0]; if(!$eta = $containerDetails[3]){ diff --git a/app/Classes/Modules/PackingLists/Processors/FetchLoadedContainersFromVTPortalProcessor.php b/app/Classes/Modules/PackingLists/Processors/FetchLoadedContainersFromVTPortalProcessor.php index bb9986c0..6d4f8164 100644 --- a/app/Classes/Modules/PackingLists/Processors/FetchLoadedContainersFromVTPortalProcessor.php +++ b/app/Classes/Modules/PackingLists/Processors/FetchLoadedContainersFromVTPortalProcessor.php @@ -21,6 +21,7 @@ use App\Classes\Modules\Unity\Services\CreatesContract; use App\Classes\ValueObjects\Constants\ApprovalStatus; use App\Classes\ValueObjects\Constants\ContainerTypes; use App\Classes\ValueObjects\Constants\OrderRoleTypes; +use App\Classes\ValueObjects\Constants\RoleTypes; use App\Classes\ValueObjects\Constants\PackingListType; use App\Models\Order; use App\Models\PackingList; @@ -201,7 +202,7 @@ class FetchLoadedContainersFromVTPortalProcessor $connection = $order->companyModule->connections()->first(); $marking = $connection->invitee_reference; - $packingListObject = new PackingListObject($packingListReference, $order->orderRoles()->where('role_id', '=', OrderRoleTypes::ORIGIN_FREIGHT_FORWARDER)->first()->appointee->id, PackingListType::SHIPPING_PACKING_LIST, (int) filter_var($marking, FILTER_SANITIZE_NUMBER_INT) <= 1000 ? ApprovalStatus::PENDING_VERIFICATION : ApprovalStatus::SUSPENDED, $contractReference); + $packingListObject = new PackingListObject($packingListReference, $order->orderRoles()->where('role_id', '=', OrderRoleTypes::ORIGIN_FREIGHT_FORWARDER)->first()->appointee->id, PackingListType::SHIPPING_PACKING_LIST, ApprovalStatus::SUSPENDED, $contractReference); /** @var PackingList $packingList */ $packingList = $this->createPackingListProcessor->execute($packingListObject, $order); @@ -212,7 +213,6 @@ class FetchLoadedContainersFromVTPortalProcessor $this->createsStep->execute($packingList, $stepObject); } - } } diff --git a/app/Classes/Modules/PackingLists/Processors/FetchOrderListsFromYdPortalProcessor.php b/app/Classes/Modules/PackingLists/Processors/FetchOrderListsFromYdPortalProcessor.php new file mode 100644 index 00000000..0fb1dd8f --- /dev/null +++ b/app/Classes/Modules/PackingLists/Processors/FetchOrderListsFromYdPortalProcessor.php @@ -0,0 +1,321 @@ +fetchesDataFRomYDPortal = $fetchesDataFRomYDPortal; + $this->fetchesOrder = $fetchesOrder; + $this->updatesContractObligations = $updatesContractObligations; + $this->createPackingListProcessor = $createPackingListProcessor; + $this->createPackageProcessor = $createPackageProcessor; + $this->createsTransport = $createsTransport; + $this->createsSchedule = $createsSchedule; + $this->fetchesContainer = $fetchesContainer; + $this->fetchesPackingList = $fetchesPackingList; + $this->fetchesCompanyModule = $fetchesCompanyModule; + $this->createContainerProcessor = $createContainerProcessor; + $this->unityCreateContract = $unityCreateContract; + $this->unityAssignContractEntity = $unityAssignContractEntity; + $this->unityCreateContractEntity = $unityCreateContractEntity; + $this->createsStep = $createsStep; + $this->unityActivateContract = $unityActivateContract; + } + + + /** + * @param Carbon|null $start + * @param Carbon|null $end + * @return void + * @throws \GuzzleHttp\Exception\GuzzleException + */ + public function execute(?Carbon $start = null, ?Carbon $end = null) + { + + try { + $start = $start ? $start : Carbon::now()->subMonths(2); + + $startLimit = Carbon::parse('01-12-2021'); + + if($start->isBefore($startLimit)){ + $start = $startLimit; + } + + $end = $end ? $end : Carbon::now(); + + $orderRequest = $this->fetchesDataFRomYDPortal->clientRequest('http://www.yd-wl.com/api/GetOrderList.ashx', 'GET', [ + 'begintime' => $start->timestamp, + 'endtime' => $end->timestamp, + ]); + + $rows = $this->fetchesDataFRomYDPortal->getResponseBody($orderRequest); + foreach($rows->data as $row){ + + $containerReference = null; + $loadingDate = null; + $unstuffingDate = null; + $etd = null; + $eta = null; + + $trackingRequest = $this->fetchesDataFRomYDPortal->clientRequest('http://www.yd-wl.com/api/ApiTracking.ashx', 'GET', [ + 'trakingno' => $row->expressno + ]); + $rows = $this->fetchesDataFRomYDPortal->getResponseBody($trackingRequest); + + foreach ($rows->data as $trackingRow) { + if($trackingRow->tracking === '货物已送达仓库准备入库中'){ + $receiveDate = Carbon::parse($trackingRow->trackingtime); + } + + if (strpos($trackingRow->tracking, '货物装柜完成。') !== false) { + $tracking = explode(':', $trackingRow->tracking); + $containerReference = explode('预计到港时间', $tracking[1])[0]; + $loadingDate = Carbon::parse($trackingRow->trackingtime); + $etd = Carbon::parse($tracking[2])->subDays(5); + $eta = Carbon::parse($tracking[2]); + } + + if($trackingRow->tracking === '货物已进目的港仓库'){ + $unstuffingDate = Carbon::parse($trackingRow->trackingtime); + } + } + + $customerno = preg_split('(-|\(|\)|\/)', $row->customerno); + + $orderNumber = $customerno[array_key_last($customerno)]; + + try { + $order = $this->fetchesOrder->execute(['reference' => $orderNumber]); + } catch (ResourceNotFoundException $exception) { + try { + $order = $this->fetchesOrder->execute(['reference' => substr($orderNumber, -9)]); + } catch (ResourceNotFoundException $exception) { + continue; + } + } + + DB::beginTransaction(); + + $packingListReference = $row->expressno; + + try{ + $packingList = $this->fetchesPackingList->execute(['reference' => $row->expressno, 'type' => PackingListType::SHIPPING_PACKING_LIST]); + + $packingList->packages()->delete(); + $replica = $packingList->packingLists()->where('type', PackingListType::SHIPPING_PACKING_LIST_REPLICA)->first(); + if($replica) $replica->packages()->delete(); + + $warehouseReceiveList = $this->fetchesPackingList->execute(['reference' => $row->expressno, 'type' => PackingListType::WAREHOUSE_RECEIVE_LIST]); + $warehouseReceiveList->packages()->delete(); + $replica = $warehouseReceiveList->packingLists()->where('type', PackingListType::WAREHOUSE_RECEIVE_LIST_REPLICA)->first(); + if($replica) $replica->packages()->delete(); + + } catch (ResourceNotFoundException $exception){ + $warehouseReceiveObject = new PackingListObject($packingListReference, $order->orderRoles()->where('role_id', '=', OrderRoleTypes::ORIGIN_FREIGHT_FORWARDER)->first()->appointee->id, PackingListType::WAREHOUSE_RECEIVE_LIST, ApprovalStatus::APPROVED); + /** @var PackingList $warehouseReceiveList */ + $warehouseReceiveList = $this->createPackingListProcessor->execute($warehouseReceiveObject, $order); + $transportObject = new TransportObject(TransportType::LAND, null, $row->kuaidilist, Carbon::parse($receiveDate), Carbon::parse($receiveDate), ApprovalStatus::APPROVED); + /** @var Transport $warehouseTransport */ + $warehouseTransport = $this->createsTransport->execute($transportObject, $warehouseReceiveList); + $this->createsSchedule->execute($warehouseTransport, new ScheduleObject(Carbon::parse($receiveDate), Carbon::parse($receiveDate), ApprovalStatus::APPROVED)); + + $contract = $this->unityCreateContract->execute(); + + $contractReference = $contract->hash_id; + $contractObligations = $contract->contract_obligation_list; + + $this->unityActivateContract->execute($contractReference); + + $supervisorHashId = $order->orderRoles()->where('role_id', '=', OrderRoleTypes::SUPERVISOR)->first()->appointee->unity_hash_id; + + $supervisorContractEntity = $this->unityCreateContractEntity->execute($contractReference, $supervisorHashId); + $order->orderRoles()->where('role_id', '=', OrderRoleTypes::SUPERVISOR)->first()->update(['entity_hash_id' => $supervisorContractEntity->hash_id, 'entity_signature' => $supervisorContractEntity->entity_signature_hash_id]); + + $importerContractEntity = $this->unityCreateContractEntity->execute($contractReference, $order->orderRoles()->where('role_id', '=', OrderRoleTypes::IMPORTER)->first()->appointee->unity_hash_id); + $order->orderRoles()->where('role_id', '=', OrderRoleTypes::IMPORTER)->first()->update(['entity_hash_id' => $importerContractEntity->hash_id, 'entity_signature' => $importerContractEntity->entity_signature_hash_id]); + + $this->unityAssignContractEntity->execute($supervisorContractEntity->hash_id, $contractObligations); + + $packingListObject = new PackingListObject($packingListReference, $order->orderRoles()->where('role_id', '=', OrderRoleTypes::ORIGIN_FREIGHT_FORWARDER)->first()->appointee->id, PackingListType::SHIPPING_PACKING_LIST, ApprovalStatus::SUSPENDED , $contractReference); + + /** @var PackingList $packingList */ + $packingList = $this->createPackingListProcessor->execute($packingListObject, $order); + + foreach($contractObligations as $obligation) { + $stepObject = new StepsObject($order->orderRoles()->where('role_id', '=', OrderRoleTypes::SUPERVISOR)->first()->appointee->id, $obligation->reference, $obligation->sequence, $obligation->hash_id); + $this->createsStep->execute($packingList, $stepObject); + } + } + + foreach($row->deliverysize as $package) { + $packageObject = new PackageObject(PackageType::CARTON, $row->goodname, (float) $package->width, (float) $package->height, (float) $package->length, 0, (float) $package->num, ApprovalStatus::APPROVED); + $this->createPackageProcessor->execute($packageObject, $warehouseReceiveList); + $this->createPackageProcessor->execute($packageObject, $packingList); + } + + DB::commit(); + + $marking = $order->companyModule->inviters()->withPivot('invitee_reference')->first()->pivot->invitee_reference; + if(!in_array($marking, ['2192KAA', '2353GFE', '6866DTR', '153DSR', '1291NSC', '8288MIB'])){ + $this->fetchesDataFRomYDPortal->clientRequest('http://www.yd-wl.com/api/confirmsendorder.ashx', 'GET', [ + 'expressno' => $row->expressno + ]); + } + + if($containerReference) { + try { + $container = $this->fetchesContainer->execute(['reference' => $containerReference]); + } catch (ResourceNotFoundException $exception){ + $originWarehouse = $this->fetchesCompanyModule->execute(['id' => $order->orderRoles()->where('role_id', '=', OrderRoleTypes::ORIGIN_WAREHOUSE)->first()->appointee->id]); + $containerObject = new ContainerObject($containerReference, '', '', ContainerTypes::FORTY_FEET_DRY_CONTAINER, $loadingDate, ApprovalStatus::PENDING_VERIFICATION); + /** @var Container $container */ + $container = $this->createContainerProcessor->execute($containerObject, $originWarehouse); + } + + $container->packingLists()->detach($packingList); + $container->packingLists()->attach($packingList); + + $transport = $container->transports()->first(); + + if(!$transport){ + $transportObject = new TransportObject(TransportType::SEA, null, null, $etd, null, ApprovalStatus::APPROVED); + /** @var Transport $transport */ + $transport = $this->createsTransport->execute($transportObject, $container); + $this->createsSchedule->execute($transport, new ScheduleObject($etd, $eta, ApprovalStatus::APPROVED)); + } + + + if($unstuffingDate && $container->status !== ApprovalStatus::COMPLETED){ + $container->update(['status' => ApprovalStatus::COMPLETED]); + $container->transports()->first()->update(['drop_date' => $unstuffingDate, 'status' => ApprovalStatus::COMPLETED]); + + /** @var PackingList $packingList */ + foreach($container->packingLists as $packingList){ + + if($packingList->status === ApprovalStatus::PENDING_VERIFICATION){ + $packingList->status = ApprovalStatus::APPROVED; + $packingList->save(); + } + + $signature = $packingList->owner->orderRoles()->where('role_id', '=', OrderRoleTypes::SUPERVISOR)->first()->appointee->entity_sigiture; + foreach($packingList->steps()->where('reference', '!=', 'DELIVERY')->get() as $step){ + $this->updatesContractObligations->execute($signature, $step->obligation_hash_id); + $step->update(['status' => ApprovalStatus::COMPLETED]); + } + } + } + + } + + } + } catch (\Exception $exception) { + Log::debug($exception); + } + + + } +} diff --git a/app/Classes/Modules/PackingLists/Processors/FetchPackingListFromVTPortalProcessor.php b/app/Classes/Modules/PackingLists/Processors/FetchPackingListFromVTPortalProcessor.php index 00c3e112..2f977222 100644 --- a/app/Classes/Modules/PackingLists/Processors/FetchPackingListFromVTPortalProcessor.php +++ b/app/Classes/Modules/PackingLists/Processors/FetchPackingListFromVTPortalProcessor.php @@ -61,17 +61,25 @@ class FetchPackingListFromVTPortalProcessor $shippingPackingLists = $this->fetchesDataFRomVTPortal->getResponseBody($shippingPackingListsRequest); - $packingList->packages()->delete(); + if(count($shippingPackingLists->Rows)) { - foreach($shippingPackingLists->Rows as $shippingPackingList){ - if(!$shippingPackingList[22]) { - continue; + $packingList->packages()->delete(); + + $replica = $packingList->packingLists()->where('type', PackingListType::SHIPPING_PACKING_LIST_REPLICA)->first(); + if($replica) $replica->packages()->delete(); + + foreach($shippingPackingLists->Rows as $shippingPackingList){ + if(!$shippingPackingList[22]) { + continue; + } + + $packageObject = new PackageObject(PackageType::CARTON, $shippingPackingList[19], $shippingPackingList[31], $shippingPackingList[30], $shippingPackingList[29], 0, $shippingPackingList[22], ApprovalStatus::APPROVED); + $this->createPackageProcessor->execute($packageObject, $packingList); } - - $packageObject = new PackageObject(PackageType::CARTON, $shippingPackingList[19], $shippingPackingList[31], $shippingPackingList[30], $shippingPackingList[29], 0, $shippingPackingList[22], ApprovalStatus::APPROVED); - $this->createPackageProcessor->execute($packageObject, $packingList); } + + DB::commit(); } catch (GuzzleException $exception) { continue; diff --git a/app/Classes/Modules/PackingLists/Processors/FetchWarehouseReceiveListFromVTPortalProcessor.php b/app/Classes/Modules/PackingLists/Processors/FetchWarehouseReceiveListFromVTPortalProcessor.php index d1eb8516..a4b846cf 100644 --- a/app/Classes/Modules/PackingLists/Processors/FetchWarehouseReceiveListFromVTPortalProcessor.php +++ b/app/Classes/Modules/PackingLists/Processors/FetchWarehouseReceiveListFromVTPortalProcessor.php @@ -206,10 +206,7 @@ class FetchWarehouseReceiveListFromVTPortalProcessor if(!$packingList) { $packingList = $this->createPackingListProcessor->execute($packingListObject, $order); - $transportObject = new TransportObject(TransportType::LAND, null, $tracking, Carbon::parse($receiveDate), Carbon::parse($receiveDate), ApprovalStatus::APPROVED); - - $this->createsTransport->execute($transportObject, $packingList); } @@ -220,14 +217,14 @@ class FetchWarehouseReceiveListFromVTPortalProcessor $this->createsSchedule->execute($transport, new ScheduleObject(Carbon::parse($receiveDate), Carbon::parse($receiveDate), ApprovalStatus::APPROVED)); + /** @var PackingList $replica */ + $replica = $packingList->packingLists()->where('type', PackingListType::WAREHOUSE_RECEIVE_LIST_REPLICA)->first(); $packingList->packages()->delete(); + if($replica) $replica->packages()->delete(); $packageObject = new PackageObject(PackageType::CARTON, $description, $measurement, $measurement, $measurement, 0, $quantity, ApprovalStatus::APPROVED); $this->createPackageProcessor->execute($packageObject, $packingList); - } - - } catch (\Exception $exception){ Log::error($exception->getMessage()); } diff --git a/app/Classes/Modules/Unity/Services/CreatesContract.php b/app/Classes/Modules/Unity/Services/CreatesContract.php index 43451b1b..88ef138d 100644 --- a/app/Classes/Modules/Unity/Services/CreatesContract.php +++ b/app/Classes/Modules/Unity/Services/CreatesContract.php @@ -23,6 +23,7 @@ class CreatesContract public function execute(){ + $accessToken=$this->getAccessToken->execute(); $response = Http::withToken($accessToken)->post($this->createEntityEndpoint,['contract_template_id'=>[$this->contract_hash_id]])->object(); diff --git a/app/Classes/ValueObjects/Constants/PackingListType.php b/app/Classes/ValueObjects/Constants/PackingListType.php index 56f29244..bd83c6ba 100644 --- a/app/Classes/ValueObjects/Constants/PackingListType.php +++ b/app/Classes/ValueObjects/Constants/PackingListType.php @@ -14,5 +14,10 @@ final class PackingListType { public const DELIVERY_PACKING_LIST = 4; + public const WAREHOUSE_RECEIVE_LIST_REPLICA = 5; + + public const SHIPPING_PACKING_LIST_REPLICA = 6; + + } diff --git a/app/Classes/ValueObjects/Constants/RemarkTypes.php b/app/Classes/ValueObjects/Constants/RemarkTypes.php new file mode 100644 index 00000000..9629e89a --- /dev/null +++ b/app/Classes/ValueObjects/Constants/RemarkTypes.php @@ -0,0 +1,13 @@ +dispatch(); } } diff --git a/app/Console/Kernel.php b/app/Console/Kernel.php index 6ee797a6..de764786 100644 --- a/app/Console/Kernel.php +++ b/app/Console/Kernel.php @@ -27,20 +27,55 @@ class Kernel extends ConsoleKernel */ protected function schedule(Schedule $schedule) { + $schedule->command('command:curlVTCommand') + ->dailyAt('09:00') + ->withoutOverlapping() + ->appendOutputTo (storage_path().'/logs/curlvt.log'); + + $schedule->command('command:curlYdOrderListCommand') + ->dailyAt('09:00') + ->withoutOverlapping() + ->appendOutputTo (storage_path().'/logs/curlyd.log'); + $schedule->command('command:curlVTCommand') ->dailyAt('11:00') ->withoutOverlapping() ->appendOutputTo (storage_path().'/logs/curlvt.log'); + $schedule->command('command:curlYdOrderListCommand') + ->dailyAt('11:00') + ->withoutOverlapping() + ->appendOutputTo (storage_path().'/logs/curlyd.log'); + $schedule->command('command:curlVTCommand') ->dailyAt('14:00') ->withoutOverlapping() ->appendOutputTo (storage_path().'/logs/curlvt.log'); + $schedule->command('command:curlYdOrderListCommand') + ->dailyAt('14:00') + ->withoutOverlapping() + ->appendOutputTo (storage_path().'/logs/curlyd.log'); + $schedule->command('command:curlVTCommand') - ->dailyAt('17:00') + ->dailyAt('16:00') ->withoutOverlapping() ->appendOutputTo (storage_path().'/logs/curlvt.log'); + + $schedule->command('command:curlYdOrderListCommand') + ->dailyAt('16:00') + ->withoutOverlapping() + ->appendOutputTo (storage_path().'/logs/curlyd.log'); + + $schedule->command('command:curlVTCommand') + ->dailyAt('18:00') + ->withoutOverlapping() + ->appendOutputTo (storage_path().'/logs/curlvt.log'); + + $schedule->command('command:curlYdOrderListCommand') + ->dailyAt('18:00') + ->withoutOverlapping() + ->appendOutputTo (storage_path().'/logs/curlyd.log'); } /** diff --git a/app/Http/Controllers/Announcements/AssignAnnouncementToSegmentController.php b/app/Http/Controllers/Announcements/AssignAnnouncementToSegmentController.php new file mode 100644 index 00000000..508d929f --- /dev/null +++ b/app/Http/Controllers/Announcements/AssignAnnouncementToSegmentController.php @@ -0,0 +1,20 @@ +execute($request); + } + +} diff --git a/app/Http/Controllers/Announcements/CreateAnnouncementController.php b/app/Http/Controllers/Announcements/CreateAnnouncementController.php new file mode 100644 index 00000000..84da07cf --- /dev/null +++ b/app/Http/Controllers/Announcements/CreateAnnouncementController.php @@ -0,0 +1,20 @@ +execute($request); + } +} diff --git a/app/Http/Controllers/Announcements/DeleteAnnouncementController.php b/app/Http/Controllers/Announcements/DeleteAnnouncementController.php new file mode 100644 index 00000000..257640d3 --- /dev/null +++ b/app/Http/Controllers/Announcements/DeleteAnnouncementController.php @@ -0,0 +1,20 @@ +execute($request); + } +} diff --git a/app/Http/Controllers/Announcements/ListAnnouncementsController.php b/app/Http/Controllers/Announcements/ListAnnouncementsController.php new file mode 100644 index 00000000..a69dff50 --- /dev/null +++ b/app/Http/Controllers/Announcements/ListAnnouncementsController.php @@ -0,0 +1,20 @@ +execute($request); + } +} \ No newline at end of file diff --git a/app/Http/Controllers/Announcements/RemoveSegmentFromAnnouncementController.php b/app/Http/Controllers/Announcements/RemoveSegmentFromAnnouncementController.php new file mode 100644 index 00000000..86e15877 --- /dev/null +++ b/app/Http/Controllers/Announcements/RemoveSegmentFromAnnouncementController.php @@ -0,0 +1,20 @@ +execute($request); + } + +} diff --git a/app/Http/Controllers/Announcements/UpdateAnnouncementController.php b/app/Http/Controllers/Announcements/UpdateAnnouncementController.php new file mode 100644 index 00000000..72431980 --- /dev/null +++ b/app/Http/Controllers/Announcements/UpdateAnnouncementController.php @@ -0,0 +1,21 @@ +execute($request); + } +} + diff --git a/app/Http/Controllers/Orders/CreateOrderRemarkController.php b/app/Http/Controllers/Orders/CreateOrderRemarkController.php new file mode 100644 index 00000000..3464566a --- /dev/null +++ b/app/Http/Controllers/Orders/CreateOrderRemarkController.php @@ -0,0 +1,14 @@ +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 ae23bae0..b456d880 100644 --- a/app/Http/Controllers/Orders/DownloadOrderQrPdfController.php +++ b/app/Http/Controllers/Orders/DownloadOrderQrPdfController.php @@ -5,6 +5,7 @@ namespace App\Http\Controllers\Orders; use App\Classes\ValueObjects\Constants\ApprovalStatus; use App\Classes\ValueObjects\Constants\OrderRoleTypes; +use App\Classes\ValueObjects\Constants\WarehouseReferences; use App\Models\Order; use Illuminate\Http\Request; use Meneses\LaravelMpdf\Facades\LaravelMpdf; @@ -20,9 +21,39 @@ class DownloadOrderQrPdfController $warehouseAddress = $warehouse->addresses()->first(); $warehouseContacts = $warehouse->contacts; + $warehousePrefix = ''; + $deliveryPrefix = ''; + + if($warehouse->reference === WarehouseReferences::VT_GUANG_ZHOU || $warehouse->reference === WarehouseReferences::VT_YIWU) { + if(strtolower($deliveryAddress->state->name) === 'sabah' || strtolower($deliveryAddress->state->name) === 'labuan') { + $deliveryPrefix = 'SB/'; + } + + if(strtolower($deliveryAddress->state->name) === 'sarawak') { + $deliveryPrefix = 'SRW/'; + } + } + + if($warehouse->reference === WarehouseReferences::YD_YIWU){ + $warehousePrefix = 'YW/'; + } + + if($warehouse->reference === WarehouseReferences::YD_GUANG_ZHOU){ + $warehousePrefix = 'YD/'; + + if(strtolower($deliveryAddress->state->name) === 'sabah' || strtolower($deliveryAddress->state->name) === 'labuan') { + $warehousePrefix = 'KK/'; + } + + if(strtolower($deliveryAddress->state->name) === 'sarawak') { + $warehousePrefix = 'KU/'; + } + } + + $data = [ 'order' => $order, - 'marking' => $order->companyModule->connections()->first()->invitee_reference, + 'marking' => $warehousePrefix.$deliveryPrefix.'CIEF/'.$order->companyModule->connections()->first()->invitee_reference, 'delivery_address' => $deliveryAddress, 'warehouse_address' => $warehouseAddress, 'warehouse_contacts' => $warehouseContacts, diff --git a/app/Http/Controllers/Orders/UpdateOrderController.php b/app/Http/Controllers/Orders/UpdateOrderController.php new file mode 100644 index 00000000..c8321284 --- /dev/null +++ b/app/Http/Controllers/Orders/UpdateOrderController.php @@ -0,0 +1,15 @@ +execute($request); + } +} diff --git a/app/Http/Controllers/Reports/MonthlyReportController.php b/app/Http/Controllers/Reports/MonthlyReportController.php index f9335360..20c90e70 100644 --- a/app/Http/Controllers/Reports/MonthlyReportController.php +++ b/app/Http/Controllers/Reports/MonthlyReportController.php @@ -5,6 +5,8 @@ namespace App\Http\Controllers\Reports; use App\Classes\ValueObjects\Constants\ApprovalStatus; use App\Classes\ValueObjects\Constants\BusinessType; use App\Classes\ValueObjects\Constants\HttpStatus; +use App\Classes\ValueObjects\Constants\PackingListType; +use App\Classes\ValueObjects\Constants\RoleTypes; use App\Classes\ValueObjects\Response\ApiResponseObject; use App\Models\CompanyConnection; use App\Models\CompanyModule; @@ -37,8 +39,15 @@ class MonthlyReportController return $container->orders; })->unique(); - $packages = $containers->flatMap(function ($container) { - return $container->packages; + $packingLists = $containers->flatMap(function ($container) { + return $container->packingLists; + }); + + $packages = $packingLists->map(function ($packingList) { + $replica = in_array(Auth()->user()->type, [RoleTypes::SHADOW_ADMIN, RoleTypes::SUPER_ADMIN]) ? $packingList : $packingList->packingLists()->where('type', PackingListType::SHIPPING_PACKING_LIST_REPLICA)->first(); + return $replica ? $replica : $packingList; + })->flatMap(function ($packingList) { + return $packingList->packages; }); $totalCbm = $packages->sum(function($package){ @@ -83,8 +92,15 @@ class MonthlyReportController $containers = Container::whereBetween('loading_date', [$from, $to])->orderBy('loading_date')->get(); - $packages = $containers->flatMap(function ($container) { - return $container->packages; + $packingLists = $containers->flatMap(function ($container) { + return $container->packingLists; + }); + + $packages = $packingLists->map(function ($packingList) { + $replica = in_array(Auth()->user()->type, [RoleTypes::SHADOW_ADMIN, RoleTypes::SUPER_ADMIN]) ? $packingList : $packingList->packingLists()->where('type', PackingListType::SHIPPING_PACKING_LIST_REPLICA)->first(); + return $replica ? $replica : $packingList; + })->flatMap(function ($packingList) { + return $packingList->packages; }); $totalCbm = $packages->sum(function($package){ @@ -128,8 +144,15 @@ class MonthlyReportController $containers = Container::whereBetween('loading_date', [$from, $to])->orderBy('loading_date')->get(); - $packages = $containers->flatMap(function ($container) { - return $container->packages; + $packingLists = $containers->flatMap(function ($container) { + return $container->packingLists; + }); + + $packages = $packingLists->map(function ($packingList) { + $replica = in_array(Auth()->user()->type, [RoleTypes::SHADOW_ADMIN, RoleTypes::SUPER_ADMIN]) ? $packingList : $packingList->packingLists()->where('type', PackingListType::SHIPPING_PACKING_LIST_REPLICA)->first(); + return $replica ? $replica : $packingList; + })->flatMap(function ($packingList) { + return $packingList->packages; }); $packages = $packages->filter(function($package) use ($id) { diff --git a/app/Http/Resources/AddressResource.php b/app/Http/Resources/AddressResource.php index 6f6a6237..95a60b9f 100644 --- a/app/Http/Resources/AddressResource.php +++ b/app/Http/Resources/AddressResource.php @@ -28,6 +28,8 @@ class AddressResource extends JsonResource 'country' => $this->country, 'default' => (int) $this->default, 'status' => (int) $this->status, + 'contact' => new ContactResource($this->contacts->first()), + 'remark' => new RemarkResource($this->remarks->first()), $this->mergeWhen($this->relationLoaded('owner'), [ 'owner' => $this->when($this->owner instanceof Order, [ 'reference' => $this->owner->reference, diff --git a/app/Http/Resources/AnnouncementResource.php b/app/Http/Resources/AnnouncementResource.php new file mode 100644 index 00000000..26e1c2f9 --- /dev/null +++ b/app/Http/Resources/AnnouncementResource.php @@ -0,0 +1,28 @@ + $this->id, + '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'), + 'created_at' => Carbon::parse($this->created_at)->format('d-m-Y'), + ]; + } +} diff --git a/app/Http/Resources/ContainerResource.php b/app/Http/Resources/ContainerResource.php index 23cb7817..557ffe74 100644 --- a/app/Http/Resources/ContainerResource.php +++ b/app/Http/Resources/ContainerResource.php @@ -5,6 +5,7 @@ namespace App\Http\Resources; use App\Classes\ValueObjects\Constants\ContainerTypes; use App\Models\Remark; use Illuminate\Http\Resources\Json\JsonResource; +use Illuminate\Support\Facades\DB; class ContainerResource extends JsonResource { @@ -24,11 +25,13 @@ class ContainerResource extends JsonResource 'seal_reference' => $this->seal_reference, 'loading_date' => $this->loading_date ? $this->loading_date->format('d-m-Y') : $this->loading_date, 'transport' => new TransportResource($this->transports()->first()), - 'packing_lists' => PackingListResource::collection($this->whenLoaded('packingLists', function(){ - return $this->packingLists()->whereHas('packages')->get(); - })), + 'packages_count' => $this->packages->sum('quantity'), + 'total_cbm' => $this->packages()->sum(DB::raw('(width/100) * (height/100) * (length/100) * quantity')), 'remarks' => RemarkResource::collection($this->remarks), - 'status' => $this->status + 'status' => $this->status, + 'packing_lists' => $this->whenLoaded('packingLists', PackingListResource::collection($this->whenLoaded('packingLists', function(){ + return $this->packingLists()->whereHas('packages')->get(); + }))) ]; } } diff --git a/app/Http/Resources/OrderResource.php b/app/Http/Resources/OrderResource.php index 06e31b6f..d2c72930 100644 --- a/app/Http/Resources/OrderResource.php +++ b/app/Http/Resources/OrderResource.php @@ -31,21 +31,22 @@ class OrderResource extends JsonResource 'address_change_request' => new AddressResource($this->addressesPendingVerification()->first()), 'parcels' => $this->whenLoaded('packingLists', function() { return [ - 'origin_warehouse_packages' => PackageResource::collection( + 'origin_warehouse_packages' => PackingListResource::collection( $this->originWarehousePackages()->get() ), - 'in_transit_packages' => PackageResource::collection( + 'in_transit_packages' => PackingListResource::collection( $this->inTransitPackages()->get() ), - 'destination_warehouse_packages' => PackageResource::collection( + 'destination_warehouse_packages' => PackingListResource::collection( $this->destinationWarehousePackages()->get() ), - 'delivered_packages' => PackageResource::collection( + 'delivered_packages' => PackingListResource::collection( $this->deliveredPackages()->get() ), - 'received_packages' => PackageResource::collection($this->parcels()->warehouseReceiveList()->get()), + 'received_packages' => PackingListResource::collection($this->packingLists()->where('type', PackingListType::WAREHOUSE_RECEIVE_LIST)->whereHas('packages')->get()), ]; }), + 'remarks' => RemarkResource::collection($this->remarks), 'created_at' => $this->created_at->format('d-m-Y') ]; diff --git a/app/Http/Resources/PackageResource.php b/app/Http/Resources/PackageResource.php index 75f5589f..2cd76a1b 100644 --- a/app/Http/Resources/PackageResource.php +++ b/app/Http/Resources/PackageResource.php @@ -2,6 +2,7 @@ namespace App\Http\Resources; +use App\Models\Order; use Illuminate\Http\Resources\Json\JsonResource; class PackageResource extends JsonResource @@ -14,6 +15,7 @@ class PackageResource extends JsonResource */ public function toArray($request) { + return [ 'id' => $this->id, 'type' => $this->type, @@ -25,9 +27,9 @@ class PackageResource extends JsonResource 'quantity' => $this->quantity, 'cbm' => (($this->width / 100) * ($this->height / 100) * ($this->length / 100)) * $this->quantity, 'status' => $this->status, - 'order' => new OrderResource($this->packingList->owner), - 'container' => new ContainerResource($this->container), - 'transport' => new TransportResource($this->transport) + 'order' => New OrderResource($this->packingList->owner instanceof Order ? $this->packingList->owner : $this->packingList->owner->owner), + 'container' => new ContainerResource($this->packingList->owner instanceof Order ? $this->container : $this->packingList->owner->containers()->first()), + 'transport' => new TransportResource($this->packingList->owner instanceof Order ? $this->transport : $this->packingList->owner->transports()->first()) ]; } } diff --git a/app/Http/Resources/PackingListResource.php b/app/Http/Resources/PackingListResource.php index 4024833d..38c568e7 100644 --- a/app/Http/Resources/PackingListResource.php +++ b/app/Http/Resources/PackingListResource.php @@ -2,6 +2,8 @@ namespace App\Http\Resources; +use App\Classes\ValueObjects\Constants\RoleTypes; +use App\Models\Order; use Illuminate\Http\Resources\Json\JsonResource; class PackingListResource extends JsonResource @@ -14,14 +16,20 @@ class PackingListResource extends JsonResource */ public function toArray($request) { + $exceptionUsers = in_array(Auth()->user()->type, [RoleTypes::SHADOW_ADMIN, RoleTypes::SUPER_ADMIN]); + $packages = !$this->packingLists()->exists() || $exceptionUsers ? $this->packages : $this->packingLists->first()->packages; + return [ 'id' => $this->id, 'claimant_id' => $this->claimant_id, 'reference' => $this->reference, 'status' => $this->status, 'transport' => new TransportResource($this->transports()->first()), - 'packages' => PackageResource::collection($this->packages), - 'order' => New OrderResource($this->owner) + 'type' => $this->type, + 'packages' => PackageResource::collection($packages), + $this->mergeWhen($this->owner instanceof Order, [ + 'order' => New OrderResource($this->owner) + ]) ]; } } diff --git a/app/Models/Address.php b/app/Models/Address.php index bbd60d70..8357940f 100644 --- a/app/Models/Address.php +++ b/app/Models/Address.php @@ -2,9 +2,12 @@ namespace App\Models; +use App\Classes\General\Interfaces\Contactable; +use App\Classes\General\Interfaces\Remarkable; use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Relations\BelongsTo; use Illuminate\Database\Eloquent\Relations\HasOne; +use Illuminate\Database\Eloquent\Relations\MorphMany; use Illuminate\Database\Eloquent\SoftDeletes; use Illuminate\Database\Eloquent\Relations\MorphTo; /** @@ -20,7 +23,7 @@ use Illuminate\Database\Eloquent\Relations\MorphTo; * @property string street_two * @property integer billing_type */ -class Address extends AbstractModel +class Address extends AbstractModel implements Contactable, Remarkable { use SoftDeletes; @@ -70,4 +73,20 @@ class Address extends AbstractModel { return $query->where('default', true); } + + /** + * @return MorphMany + */ + public function contacts(): morphMany + { + return $this->morphMany(Contact::class, 'owner'); + } + + /** + * @return MorphMany + */ + public function remarks(): morphMany + { + return $this->morphMany(Remark::class, 'owner'); + } } diff --git a/app/Models/Announcement.php b/app/Models/Announcement.php new file mode 100644 index 00000000..b0094a6c --- /dev/null +++ b/app/Models/Announcement.php @@ -0,0 +1,26 @@ +BelongsToMany(Segment::class); + } +} diff --git a/app/Models/Order.php b/app/Models/Order.php index 995267ed..5aabfd44 100644 --- a/app/Models/Order.php +++ b/app/Models/Order.php @@ -5,6 +5,8 @@ namespace App\Models; use App\Classes\General\Interfaces\Addressable; use App\Classes\General\Interfaces\Contactable; use App\Classes\General\Interfaces\Packable; +use App\Classes\General\Interfaces\Remarkable; +use App\Classes\ValueObjects\Constants\PackingListType; use App\Classes\ValueObjects\Constants\RoleTypes; use App\Classes\ValueObjects\Constants\ApprovalStatus; use App\Scopes\CustomerOrdersScope; @@ -14,7 +16,7 @@ use Illuminate\Database\Eloquent\SoftDeletes; use Illuminate\Database\Eloquent\Relations\BelongsTo; use Illuminate\Database\Eloquent\Relations\MorphMany; -class Order extends AbstractModel implements Addressable, Packable +class Order extends AbstractModel implements Addressable, Packable, Remarkable { use SoftDeletes; @@ -99,34 +101,34 @@ class Order extends AbstractModel implements Addressable, Packable public function originWarehousePackages() { - return $this->parcels()->shippingList() + return $this->packingLists()->where('type', PackingListType::SHIPPING_PACKING_LIST) ->whereDoesntHave('shippingSchedules', function($schedule) { return $schedule->dispatched() ->whereIn('schedules.status', [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED]); } - ); + )->whereHas('packages'); } public function inTransitPackages() { - return $this->parcels()->shippingList()->Shipping() + return $this->packingLists()->where('type', PackingListType::SHIPPING_PACKING_LIST)->Shipping() ->whereHas('shippingSchedules', function($schedule) { return $schedule->dispatched() ->whereIn('schedules.status', [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED]); } ) - ->whereDoesntHave('container', function($container) { + ->whereDoesntHave('containers', function($container) { return $container->where('containers.status', ApprovalStatus::COMPLETED); } - ); + )->whereHas('packages'); } public function destinationWarehousePackages() { - return $this->parcels()->shippingList() - ->whereHas('container', + return $this->packingLists()->where('type', PackingListType::SHIPPING_PACKING_LIST) + ->whereHas('containers', function($container) { return $container->where('containers.status', ApprovalStatus::COMPLETED); } @@ -135,12 +137,12 @@ class Order extends AbstractModel implements Addressable, Packable function($schedule) { return $schedule->dispatched()->whereIn('schedules.status', [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED]); } - ); + )->whereHas('packages'); } public function deliveredPackages() { - return $this->parcels()->shippingList() + return $this->packingLists()->where('type', PackingListType::SHIPPING_PACKING_LIST) ->whereHas('deliverySchedules', function($schedule) { return $schedule->dispatched()->whereIn('schedules.status', [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED]); diff --git a/app/Models/Package.php b/app/Models/Package.php index e78402f2..cb2bf35f 100644 --- a/app/Models/Package.php +++ b/app/Models/Package.php @@ -4,6 +4,9 @@ namespace App\Models; use App\Classes\ValueObjects\Constants\ApprovalStatus; use App\Classes\ValueObjects\Constants\PackingListType; +use App\Classes\ValueObjects\Constants\RoleTypes; +use App\Scopes\CustomerOrdersScope; +use App\Scopes\CustomerPackagesScope; use Carbon\Carbon; use Illuminate\Database\Eloquent\Relations\BelongsTo; use Illuminate\Database\Eloquent\Relations\HasManyThrough; @@ -137,4 +140,11 @@ class Package extends AbstractModel }); } + protected static function booted() + { +// if (auth()->user()->type === RoleTypes::USER) { +// static::addGlobalScope(new CustomerPackagesScope()); +// } + } + } diff --git a/app/Models/PackingList.php b/app/Models/PackingList.php index fc775ba2..7ef5910a 100644 --- a/app/Models/PackingList.php +++ b/app/Models/PackingList.php @@ -4,15 +4,22 @@ namespace App\Models; use App\Classes\General\Interfaces\Steppable; use App\Classes\General\Interfaces\Transportable; -use Illuminate\Database\Eloquent\Relations\BelongsTo; +use App\Classes\General\Interfaces\Packable; +use App\Classes\ValueObjects\Constants\ApprovalStatus; +use Carbon\Carbon; use Illuminate\Database\Eloquent\Relations\BelongsToMany; use Illuminate\Database\Eloquent\Relations\HasMany; use Illuminate\Database\Eloquent\Relations\MorphMany; use Illuminate\Database\Eloquent\Relations\MorphTo; use Illuminate\Database\Eloquent\SoftDeletes; +use Staudenmeir\EloquentHasManyDeep\HasManyDeep; +use Staudenmeir\EloquentHasManyDeep\HasRelationships; +use Staudenmeir\EloquentHasManyDeep\HasTableAlias; -class PackingList extends AbstractModel implements Transportable, Steppable +class PackingList extends AbstractModel implements Transportable, Steppable, Packable { + use HasTableAlias; + use HasRelationships; use SoftDeletes; protected $table = 'packing_lists'; @@ -48,6 +55,15 @@ class PackingList extends AbstractModel implements Transportable, Steppable return $this->hasMany(Package::class, 'packing_list_id'); } + /** + * @return HasManyDeep + */ + public function replicatedPackages(): HasManyDeep + { +// return $this->hasManyDeep(Package::class, [PackingList::class.' as replica', PackingList::class], [['owner_type', 'owner_id'], ['owner_type', 'owner_id'], 'packing_list_id'], [null, null, 'id']); + return $this->hasManyDeepFromRelations($this->packingLists(), (new PackingList)->setAlias('replica')->packages()); + } + /** * @return morphMany */ @@ -71,4 +87,50 @@ class PackingList extends AbstractModel implements Transportable, Steppable { return $this->BelongsToMany(PackingList::class, 'packing_list_owner', 'owner_packing_list_id', 'packing_list_id'); } + + /** + * @return MorphMany + */ + public function packingLists(): morphMany + { + return $this->morphMany(PackingList::class, 'owner'); + } + + /** + * @return hasManyDeep + */ + public function shippingTransports(): hasManyDeep + { + return $this->hasManyDeep(Transport::class, [ContainerPackingList::class, Container::class], ['packing_list_id', 'id', ['owner_type', 'owner_id']], ['id', 'container_id', null]); + } + + /** + * @return hasManyDeep + */ + public function shippingSchedules(): hasManyDeep + { + return $this->hasManyDeep(Schedule::class, [ContainerPackingList::class, Container::class, Transport::class], ['packing_list_id', 'id', ['owner_type', 'owner_id'], ['owner_type', 'owner_id']], ['id', 'container_id', null, null]); + } + + + /** + * @return hasManyDeep + */ + public function deliverySchedules(): hasManyDeep + { + return $this->hasManyDeep(Schedule::class, [Transport::class], [['owner_type', 'owner_id'], ['owner_type', 'owner_id']], [null, null]); + } + + /** + * @param $query + * @return mixed + */ + public function scopeShipping($query){ + return $query->whereHas('shippingSchedules', function($schedule){ + return $schedule->where('etd', '<', Carbon::now())->where('schedules.status', ApprovalStatus::APPROVED); + })->whereDoesntHave('shippingTransports', function($transport){ + return $transport->where('transport_arrangements.status', ApprovalStatus::COMPLETED); + }); + } + } diff --git a/app/Scopes/CustomerPackagesScope.php b/app/Scopes/CustomerPackagesScope.php new file mode 100644 index 00000000..dd8a50d1 --- /dev/null +++ b/app/Scopes/CustomerPackagesScope.php @@ -0,0 +1,29 @@ +whereHas('order', function ($query) { + $query->whereHas('companyModule', function($query){ + return $query->whereHas('employees', function($query){ + return $query->where('user_id', Auth()->user()->id); + }); + }); + }); + } + +} \ No newline at end of file diff --git a/database/migrations/2021_07_21_110310_create_remarks_table.php b/database/migrations/2021_07_21_110310_create_remarks_table.php index e02b0f44..6656fd77 100644 --- a/database/migrations/2021_07_21_110310_create_remarks_table.php +++ b/database/migrations/2021_07_21_110310_create_remarks_table.php @@ -1,5 +1,6 @@ morphs('owner'); $table->bigInteger('commenter_id')->unsigned()->index(); $table->string('content',200); + $table->integer('type')->default(RemarkTypes::INTERNAL); $table->softDeletes(); $table->timestamps(); }); diff --git a/database/migrations/2021_10_17_201021_create_announcements_table.php b/database/migrations/2021_10_17_201021_create_announcements_table.php new file mode 100644 index 00000000..35508479 --- /dev/null +++ b/database/migrations/2021_10_17_201021_create_announcements_table.php @@ -0,0 +1,40 @@ +id(); + $table->string('title', 50); + $table->longText('description'); + $table->timestamp('starting_on')->nullable(); + $table->timestamp('ending_on')->nullable(); + $table->boolean('is_all_day')->default(false); + $table->integer('duration')->default(0); + $table->boolean('is_recurring')->default(false); + $table->string('recurrence_pattern')->nullable(); + $table->softDeletes(); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('announcements'); + } +} diff --git a/database/migrations/2021_10_17_201244_create_announcement_segment_table.php b/database/migrations/2021_10_17_201244_create_announcement_segment_table.php new file mode 100644 index 00000000..c2777abf --- /dev/null +++ b/database/migrations/2021_10_17_201244_create_announcement_segment_table.php @@ -0,0 +1,40 @@ +primary(['announcement_id', 'segment_id']); + $table->bigInteger('announcement_id')->unsigned(); + $table->bigInteger('segment_id')->unsigned(); + $table->timestamps(); + $table->foreign('announcement_id') + ->references('id') + ->on('announcements')->onDelete('cascade'); + $table->foreign('segment_id') + ->references('id') + ->on('segments')->onDelete('cascade'); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('announcement_segment'); + } +} diff --git a/database/seeders/DatabaseSeeder.php b/database/seeders/DatabaseSeeder.php index 983c7aad..474a16de 100644 --- a/database/seeders/DatabaseSeeder.php +++ b/database/seeders/DatabaseSeeder.php @@ -23,7 +23,7 @@ class DatabaseSeeder extends Seeder $this->call(CountriesTableSeeder::class); $this->call(CurrenciesTableSeeder::class); - // $this->call(CompaniesTableSeeder::class); + $this->call(CompaniesTableSeeder::class); // $this->call(OrdersTableSeeder::class); } } \ No newline at end of file diff --git a/database/seeders/ModernWarehouseTableSeeder.php b/database/seeders/ModernWarehouseTableSeeder.php index 42058cfd..7f76fd2e 100644 --- a/database/seeders/ModernWarehouseTableSeeder.php +++ b/database/seeders/ModernWarehouseTableSeeder.php @@ -12,6 +12,7 @@ use App\Classes\Modules\Companies\Processors\CreateCompanyProcessor; use App\Classes\Modules\Companies\Services\ApprovesCompanyConnection; use App\Classes\Modules\Companies\Services\CreatesCompany; use App\Classes\Modules\Companies\Services\CreatesCompanyConnection; +use App\Classes\Modules\Companies\Services\FetchesCompany; use App\Classes\Modules\Companies\Services\UpdatesCompanyStatus; use App\Classes\Modules\Contacts\DataTransferObjects\ContactObject; use App\Classes\Modules\Contacts\Processors\CreateContactProcessor; @@ -53,14 +54,14 @@ class ModernWarehouseTableSeeder extends Seeder /** @var CreatesAddress */ private $createsAddress; - /** @var CreatesCompany */ - private $createsCompany; + /** @var FetchesCompany */ + private $fetchesCompany; /** @var CreatesContact */ private $createsContact; /** - * CompaniesTableSeeder constructor. + * ModernWarehouseTableSeeder constructor. * @param CreateCompanyProcessor $createCompanyProcessor * @param UpdatesCompanyStatus $updatesCompanyStatus * @param CreateCompanyModuleProcessor $createCompanyModuleProcessor @@ -69,10 +70,10 @@ class ModernWarehouseTableSeeder extends Seeder * @param ApprovesCompanyConnection $approvesCompanyConnection * @param CreateAddressFromOldAddressProcessor $createAddressFromOldAddressProcessor * @param CreatesAddress $createsAddress - * @param CreatesCompany $createsCompany + * @param FetchesCompany $fetchesCompany * @param CreatesContact $createsContact */ - public function __construct(CreateCompanyProcessor $createCompanyProcessor, UpdatesCompanyStatus $updatesCompanyStatus, CreateCompanyModuleProcessor $createCompanyModuleProcessor, CreateContactProcessor $createContactProcessor, CreatesCompanyConnection $createsCompanyConnection, ApprovesCompanyConnection $approvesCompanyConnection, CreateAddressFromOldAddressProcessor $createAddressFromOldAddressProcessor, CreatesAddress $createsAddress, CreatesCompany $createsCompany, CreatesContact $createsContact) + public function __construct(CreateCompanyProcessor $createCompanyProcessor, UpdatesCompanyStatus $updatesCompanyStatus, CreateCompanyModuleProcessor $createCompanyModuleProcessor, CreateContactProcessor $createContactProcessor, CreatesCompanyConnection $createsCompanyConnection, ApprovesCompanyConnection $approvesCompanyConnection, CreateAddressFromOldAddressProcessor $createAddressFromOldAddressProcessor, CreatesAddress $createsAddress, FetchesCompany $fetchesCompany, CreatesContact $createsContact) { $this->createCompanyProcessor = $createCompanyProcessor; $this->updatesCompanyStatus = $updatesCompanyStatus; @@ -82,7 +83,7 @@ class ModernWarehouseTableSeeder extends Seeder $this->approvesCompanyConnection = $approvesCompanyConnection; $this->createAddressFromOldAddressProcessor = $createAddressFromOldAddressProcessor; $this->createsAddress = $createsAddress; - $this->createsCompany = $createsCompany; + $this->fetchesCompany = $fetchesCompany; $this->createsContact = $createsContact; } @@ -99,23 +100,19 @@ class ModernWarehouseTableSeeder extends Seeder { /** @var Company $company */ - $company = $this->createsCompany->execute(new CompanyObject('Modern', 'MODERN', CompanyType::COMPANY_BUSINESS, ApprovalStatus::APPROVED)); + $company = $this->fetchesCompany->execute(['reference' => 'MODERN']); /** @var CompanyModule $companyModule */ - $this->createCompanyModuleProcessor->execute($company, BusinessType::FREIGHT_FORWARDER); - $companyModule = $this->createCompanyModuleProcessor->execute($company, BusinessType::WAREHOUSE); + $companyModule->update(['name' => 'Yiwu', 'reference' => 'YW-V02']); + + $address = new AddressObject('义乌市 后宅街道 起航路233号百汇科创园园区里面', '(进口处进来第一个路口左转至出口处右手边国际物流仓库)', 2, 27, 532, 322000); + $contact = new ContactObject('韩成名', '18058489899 / 18058929899', '', ''); - $companyModule->update(['name' => 'Guangzhou', 'reference' => 'GZ-V02']); - $address = new AddressObject('白云区 白云湖街道 大朗北路 大朗生活区 523A', '(公交车总站对面)', 2, 35, 633, 510000); - - $contact = new ContactObject('郑学钟', '18665696389', '', ''); $this->createsAddress->execute($companyModule, $address); $this->createsContact->execute($companyModule, $contact); - $companyModule = $this->createCompanyModuleProcessor->execute($company, BusinessType::WAREHOUSE); - $companyModule->update(['name' => 'Klang', 'reference' => 'KL-V02']); - + $this->createsContact->execute($companyModule, $contact); } diff --git a/resources/assets/vue/components/addresses/forms/AddressFormComponent.vue b/resources/assets/vue/components/addresses/forms/AddressFormComponent.vue index 3a0b4ac8..0b6edc6b 100644 --- a/resources/assets/vue/components/addresses/forms/AddressFormComponent.vue +++ b/resources/assets/vue/components/addresses/forms/AddressFormComponent.vue @@ -3,6 +3,14 @@
Packages
-{{ item.packing_lists.reduce((total, obj) => total + obj.packages.reduce((total, obj) => obj.quantity + total, 0), 0) }}
+{{ item.packages_count }}
Loaded CBM
-{{ (Math.ceil((item.packing_lists.reduce((total, obj) => total + obj.packages.reduce((total, obj) => obj.cbm + total, 0), 0)) * 1000) / 1000).toFixed(3) }}
+{{ (Math.ceil(item.total_cbm * 1000) / 1000).toFixed(3) }}
Status
@@ -49,52 +49,7 @@{{packingList.transport ? packingList.transport.current_schedule.eta : 'n/a'}}
-{{item.transport ? item.transport.current_schedule.eta : 'n/a'}}
+尊敬的顾客,
-Dear Valued Customers,
-为确保您的货物在华人农历新年前收到, 务必提前通知您的供应商安排在以下日期前把货物送到仓库:
-To ensure your goods received before the Chinese New Year Holidays, we advised the customer to inform their suppliers to arrange their goods earlier beforehand to the schedule below:
-| 仓库 WAREHOUSE | -入仓日期 RECEIVED DATE | -|
|---|---|---|
| 广州 GUANGHZOU |
- 西马 WEST MALAYSIA |
- 25/12/2021 | -
| 东马 EAST MALAYSIA |
- 11/12/2021 | -|
| 义乌 YIWU |
- 西马 WEST MALAYSIA |
- 18/12/2021 | -
| 东马 EAST MALAYSIA |
- 04/12/2021 | -|
我们建议客户尽早安排送货到中国仓库,以确保货物在恶劣天气、运输延误、海关检查等情况下准时到达目的地。
-Customers are advised to arrange delivery to China warehouse as soon as possible to ensure goods reach their destination on time due to the events of Bad weather, Shipping delay, Custom inspection and etc.
+由于今年年前运输需求非常庞大,我们决定投入更多的资源,把仓库收货的日期延长,以便确保更多货可以顺利在过年前把货顺利运出。
+广州 - 延长至 25/1/2022
+义乌 - 延长至 23/1/2022
+仓库地址将会有所更改,请大家务必要在发货之前留意二维码上的新仓库地址。
| 仓库 WAREHOUSE |
- 仓库截止收货日期 LAST DAY RECEIVE GOODS |
- 仓库復工日期 RESUME OPERATION DATE |
-
|---|---|---|
| 义乌 YIWU |
- 18/01/2022 西马 WEST MALAYSIA |
- 16/02/2022 | -
| 25/12/2021 东马 EAST MALAYSIA |
- ||
| 广州 GUANGHZOU |
- 18/01/2022 西马 WEST MALAYSIA |
- 12/02/2022 | -
| 08/01/2022 东马 EAST MALAYSIA |
-
Due to large traffic for shipment before Chinese New Year, we have decided to invest more resource to extend our warehouse receiving date,
to ensure goods are sent out before CNY.
Guangzhou - extend till 25/1/2022
+Yiwu - extend till 23/1/2022
+Changes were made to the warehouse address, please change your delivery address according to the QR code.
{{item.order.reference}}
+Arrival Date
-{{item.transport.drop_date}}
+{{item.transport ? item.transport.drop_date : 'n/a'}}
Qty
{{item.quantity}}
Est. CBM
{{((parseFloat(item.cbm) * 1000) / 1000).toFixed(3)}}
Warehouse
+{{item.order.warehouse.reference}}
+Order Number
Plese enter the new order number.
+仓库截止收货日期/LAST DAY RECEIVE GOODS:
+请注意!! 由于近期船公司对于重量严格把控,我司对于货物超重的算法也进行了调整。新超重算法将从 2022 年 1 月 20日(货物装箱日期)起实行。
+Attention!! Due to the shipping liner company are strict on checking the weight recently, our company has modified the calculation formula against overweight goods. The new formula will start to be applied on 20th January 2022 (goods loaded date).
+For more details: https://www.cief-malaysia.com/services-sea-shipping/
+浙江北仑疫情爆发, 义乌船期非常不稳定,建议发广州仓库
Due to Beilun, Zhejiang pandemic outbreak our Yiwu warehouse might experience unexpected shipping delays, you can select our Guangzhou warehouse as an alternative.
You can trace and track all packages associated with this order number.
You can trace and track all packages associated with this order number.
-Parcels received at our warehouse
+Parcels received at our warehouse
-
Nothing To Show Here Yet!
+

Nothing To Show Here Yet!
+Nothing To Show Here Yet!
+