Merge branch 'master' into 'customer_latest_order_date_export_master'

# Conflicts:
#   app/Http/Controllers/Exports/ExportCustomersToExcelController.php
#   routes/web.php
This commit is contained in:
omair saleh
2022-01-27 03:50:27 +00:00
115 changed files with 3741 additions and 850 deletions
+2
View File
@@ -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=''
@@ -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();
}
}
@@ -0,0 +1,32 @@
<?php
namespace App\Classes\General\Eloquent\Filters;
use App\Classes\ValueObjects\Constants\ApprovalStatus;
use App\Classes\ValueObjects\Constants\PackingListType;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Support\Carbon;
class Delivered implements Filter
{
/**
* @param Builder $builder
* @param $value
* @return mixed
*/
public static function apply(Builder $builder, $value)
{
return $builder->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]);
}
);
}
}
@@ -0,0 +1,32 @@
<?php
namespace App\Classes\General\Eloquent\Filters;
use App\Classes\ValueObjects\Constants\ApprovalStatus;
use App\Classes\ValueObjects\Constants\PackingListType;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Support\Carbon;
class InDestinationWarehouse implements Filter
{
/**
* @param Builder $builder
* @param $value
* @return mixed
*/
public static function apply(Builder $builder, $value)
{
return $builder->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]);
}
);
}
}
@@ -0,0 +1,29 @@
<?php
namespace App\Classes\General\Eloquent\Filters;
use App\Classes\ValueObjects\Constants\ApprovalStatus;
use App\Classes\ValueObjects\Constants\PackingListType;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Support\Carbon;
class InOriginWarehouse implements Filter
{
/**
* @param Builder $builder
* @param $value
* @return mixed
*/
public static function apply(Builder $builder, $value)
{
return $builder->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]);
}
);
}
}
@@ -0,0 +1,33 @@
<?php
namespace App\Classes\General\Eloquent\Filters;
use App\Classes\ValueObjects\Constants\ApprovalStatus;
use App\Classes\ValueObjects\Constants\PackingListType;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Support\Carbon;
class InTransit implements Filter
{
/**
* @param Builder $builder
* @param $value
* @return mixed
*/
public static function apply(Builder $builder, $value)
{
return $builder->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]);
}
);
}
}
@@ -0,0 +1,24 @@
<?php
namespace App\Classes\General\Eloquent\Filters;
use App\Classes\ValueObjects\Constants\ApprovalStatus;
use App\Classes\ValueObjects\Constants\PackingListType;
use Illuminate\Database\Eloquent\Builder;
class WarehouseParcels implements Filter
{
/**
* @param Builder $builder
* @param $value
* @return mixed
*/
public static function apply(Builder $builder, $value)
{
return $builder->whereHas('packingList', function ($query){
return $query->where('type', PackingListType::WAREHOUSE_RECEIVE_LIST)->where('status', ApprovalStatus::APPROVED);
});
}
}
-94
View File
@@ -1,94 +0,0 @@
<?php
namespace App\Classes\Jobs;
use Carbon\Carbon;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
class CurlContainerListJob implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
/**
* Create a new job instance.
*
* @return void
*/
private $page;
public function __construct($page = 1)
{
$this->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;
}
}
@@ -0,0 +1,32 @@
<?php
namespace App\Classes\Jobs;
use App\Classes\Modules\PackingLists\Processors\FetchOrderListsFromYdPortalProcessor;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
class FetchOrdersFromYDPortalJob implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
public $timeout = 900;
/**
* Execute the job.
*
* @return void
* @throws \Illuminate\Contracts\Container\BindingResolutionException
*/
public function handle()
{
(App()->make(FetchOrderListsFromYdPortalProcessor::class))->execute();
}
}
@@ -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));
}
@@ -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));
}
@@ -0,0 +1,61 @@
<?php
namespace App\Classes\Modules\Announcements\ControllersLogic;
use App\Classes\General\Abstracts\AbstractControllerLogic;
use App\Classes\Modules\Announcements\Services\FetchesAnnouncement;
use App\Classes\Modules\Announcements\Processors\AssignAnnouncementToSegmentProcessor;
use App\Http\Resources\AnnouncementResource;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
class AssignAnnouncementToSegmentLogic extends AbstractControllerLogic
{
/**
* @return array
*/
protected function notification(): array
{
return [
'title' => '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));
}
}
@@ -0,0 +1,82 @@
<?php
namespace App\Classes\Modules\Announcements\ControllersLogic;
use App\Classes\General\Abstracts\AbstractControllerLogic;
use App\Classes\Modules\Announcements\DataTransferObjects\AnnouncementObject;
use App\Classes\Modules\Announcements\Standards\Rules\CanCreateAnnouncement;
use App\Classes\Modules\Announcements\Services\CreatesAnnouncement;
use App\Classes\Modules\Announcements\Processors\AssignAnnouncementToSegmentProcessor;
use App\Http\Resources\AnnouncementResource;
use ErrorException;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
class CreateAnnouncementLogic extends AbstractControllerLogic
{
/**
* @return array
*/
protected function notification(): array
{
return [
'title' => '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));
}
}
@@ -0,0 +1,71 @@
<?php
namespace App\Classes\Modules\Announcements\ControllersLogic;
use App\Classes\General\Abstracts\AbstractControllerLogic;
use App\Classes\Modules\Announcements\Standards\Rules\CanDeleteAnnouncement;
use App\Classes\Modules\Announcements\Services\FetchesAnnouncement;
use App\Classes\Modules\Announcements\Services\DeletesAnnouncement;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
class DeleteAnnouncementLogic extends AbstractControllerLogic
{
/**
* @return array
*/
protected function notification(): array
{
return [
'title' => '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([]);
}
}
@@ -0,0 +1,60 @@
<?php
namespace App\Classes\Modules\Announcements\ControllersLogic;
use App\Classes\General\Abstracts\AbstractControllerLogic;
use App\Classes\Modules\Announcements\Services\ListsAnnouncements;
use App\Classes\Modules\Announcements\Standards\Rules\CanListAnnouncements;
use App\Http\Resources\AnnouncementResource;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
class ListAnnouncementsLogic extends AbstractControllerLogic
{
/**
* @return array
*/
protected function notification(): array
{
return [
'title' => '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));
}
}
@@ -0,0 +1,68 @@
<?php
namespace App\Classes\Modules\Announcements\ControllersLogic;
use App\Classes\General\Abstracts\AbstractControllerLogic;
use App\Classes\Modules\Announcements\Services\FetchesAnnouncement;
use App\Classes\Modules\Segments\Services\FetchesSegment;
use App\Classes\Modules\Announcements\Services\RemovesAnnouncementFromSegment;
use App\Http\Resources\AnnouncementResource;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
class RemoveSegmentFromAnnouncementLogic extends AbstractControllerLogic
{
/**
* @return array
*/
protected function notification(): array
{
return [
'title' => '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));
}
}
@@ -0,0 +1,83 @@
<?php
namespace App\Classes\Modules\Announcements\ControllersLogic;
use App\Classes\General\Abstracts\AbstractControllerLogic;
use App\Classes\Modules\Announcements\DataTransferObjects\AnnouncementObject;
use App\Classes\Modules\Announcements\Standards\Rules\CanUpdateAnnouncement;
use App\Classes\Modules\Announcements\Services\FetchesAnnouncement;
use App\Classes\Modules\Announcements\Services\UpdatesAnnouncement;
use App\Http\Resources\AnnouncementResource;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
class UpdateAnnouncementLogic extends AbstractControllerLogic
{
/**
* @return array
*/
protected function notification(): array
{
return [
'title' => '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));
}
}
@@ -0,0 +1,73 @@
<?php
namespace App\Classes\Modules\Announcements\DataTransferObjects;
use App\Classes\General\Interfaces\DataTransferObject;
use Carbon\Carbon;
class AnnouncementObject implements DataTransferObject
{
/** @var string */
private $title;
/** @var string */
private $description;
/** @var string */
private $starting_on;
/** @var string */
private $ending_on;
/**
* AnnouncementObject constructor.
* @param string $title
* @param string $description
* @param string $start_date
* @param string $end_date
*/
public function __construct(string $title, string $description, string $starting_on, string $ending_on)
{
$this->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);
}
}
@@ -0,0 +1,56 @@
<?php
namespace App\Classes\Modules\Announcements\Processors;
use App\Classes\Modules\Announcements\Services\AssignsAnnouncementToSegment;
use App\Classes\Modules\Announcements\Standards\Rules\CanAssignSegment;
use App\Classes\Modules\Segments\Services\FetchesSegment;
use App\Classes\ValueObjects\Constants\SegmentConstants;
use App\Models\Announcement;
use Illuminate\Database\Eloquent\Model;
class AssignAnnouncementToSegmentProcessor
{
/** @var CanAssignSegment */
private $canAssignSegment;
/** @var FetchesSegment */
private $fetchesSegment;
/** @var AssignAnnouncementToSegment */
private $assignsAnnouncementToSegment;
/**
* AssignAnnouncementToSegmentProcessor constructor.
* @param CanAssignSegment $canAssignSegment
* @param AssignAnnouncementToSegment $assignsAnnouncementToSegment
* @param FetchesSegment $fetchesSegment
*/
public function __construct(CanAssignSegment $canAssignSegment, FetchesSegment $fetchesSegment, AssignsAnnouncementToSegment $assignsAnnouncementToSegment)
{
$this->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);
}
}
@@ -0,0 +1,33 @@
<?php
namespace App\Classes\Modules\Announcements\Services;
use App\Classes\Exceptions\MalformedRequestException;
use App\Classes\General\Eloquent\AbstractUpdateRecord;
use App\Models\Announcement;
use App\Models\Segment;
use Illuminate\Database\QueryException;
class AssignsAnnouncementToSegment extends AbstractUpdateRecord
{
/**
* @param Announcement $announcement
* @param Segment $segment
* @return \Illuminate\Database\Eloquent\Model
* @throws MalformedRequestException
*/
public function execute(Announcement $announcement, Segment $segment)
{
try {
$announcement->segments()->attach($segment);
return $announcement;
} catch (QueryException $exception){
throw new MalformedRequestException($exception);
}
}
}
@@ -0,0 +1,26 @@
<?php
namespace App\Classes\Modules\Announcements\Services;
use App\Classes\General\Eloquent\AbstractUpdateRecord;
use App\Classes\Modules\Announcements\DataTransferObjects\AnnouncementObject;
use App\Models\Announcement;
class CreatesAnnouncement extends AbstractUpdateRecord
{
/**
* @param AnnouncementObject $object
* @return \Illuminate\Database\Eloquent\Model
* @throws \App\Classes\Exceptions\MalformedRequestException
*/
public function execute(AnnouncementObject $object)
{
$model = new Announcement();
$model->title = $object->getTitle();
$model->description = $object->getDescription();
$model->starting_on = $object->getStartingOn();
$model->ending_on = $object->getEndingOn();
return $this->handler($model);
}
}
@@ -0,0 +1,19 @@
<?php
namespace App\Classes\Modules\Announcements\Services;
use App\Classes\General\Eloquent\AbstractDeleteRecord;
use App\Models\Announcement;
class DeletesAnnouncement extends AbstractDeleteRecord
{
/**
* @param Announcement $model
* @return mixed
* @throws \App\Classes\Exceptions\MalformedRequestException
*/
public function execute(Announcement $model) {
return $this->handler($model);
}
}
@@ -0,0 +1,34 @@
<?php
namespace App\Classes\Modules\Announcements\Services;
use App\Classes\General\Eloquent\AbstractFetchRecord;
use Illuminate\Database\Eloquent\Builder;
use App\Models\Announcement;
class FetchesAnnouncement extends AbstractFetchRecord
{
/** @var Announcement */
private $repository;
/**
* FetchesAnnouncement constructor.
* @param Announcement $repository
*/
public function __construct(Announcement $repository)
{
$this->repository = $repository;
}
/**
* @return Builder
*/
public function getRepository(): Builder
{
return $this->repository->newQuery();
}
}
@@ -0,0 +1,32 @@
<?php
namespace App\Classes\Modules\Announcements\Services;
use App\Classes\General\Eloquent\AbstractListRecord;
use Illuminate\Database\Eloquent\Builder;
use App\Models\Announcement;
class ListsAnnouncements extends AbstractListRecord
{
/** @var Announcement */
private $repository;
/**
* ListsAnnouncement constructor.
* @param Announcement $repository
*/
public function __construct(Announcement $repository)
{
$this->repository = $repository;
}
/**
* @return Builder
*/
function getRepository(): Builder
{
return $this->repository->newQuery();
}
}
@@ -0,0 +1,33 @@
<?php
namespace App\Classes\Modules\Announcements\Services;
use App\Classes\Exceptions\MalformedRequestException;
use App\Classes\General\Eloquent\AbstractUpdateRecord;
use App\Models\Announcement;
use App\Models\Segment;
use Illuminate\Database\QueryException;
class RemovesAnnouncementFromSegment extends AbstractUpdateRecord
{
/**
* @param Announcement $announcement
* @param Segment $segment
* @return \Illuminate\Database\Eloquent\Model
* @throws MalformedRequestException
*/
public function execute(Announcement $announcement, Segment $segment)
{
try {
$announcement->segments()->detach($segment);
return $announcement;
} catch (QueryException $exception){
throw new MalformedRequestException($exception);
}
}
}
@@ -0,0 +1,27 @@
<?php
namespace App\Classes\Modules\Announcements\Services;
use App\Classes\General\Eloquent\AbstractUpdateRecord;
use App\Classes\Modules\Announcements\DataTransferObjects\AnnouncementObject;
use App\Models\Announcement;
class UpdatesAnnouncement extends AbstractUpdateRecord
{
/**
* @param Announcement $model
* @param AnnouncementObject $object
* @return \Illuminate\Database\Eloquent\Model
* @throws \App\Classes\Exceptions\MalformedRequestException
*/
public function execute(Announcement $model, AnnouncementObject $object)
{
$model->title = $object->getTitle();
$model->description = $object->getDescription();
$model->starting_on = $object->getStartingOn();
$model->ending_on = $object->getEndingOn();
return $this->handler($model);
}
}
@@ -0,0 +1,40 @@
<?php
namespace App\Classes\Modules\Announcements\Standards\Rules;
use App\Classes\General\Abstracts\AbstractRule;
use App\Classes\Modules\SegmentConstants\DataTransferObjects\SegmentConstantObject;
use App\Classes\Modules\Segments\DataTransferObjects\ConstantObject;
class CanAssignSegment extends AbstractRule
{
/**
* @return bool
*/
protected function authorized(): bool
{
// TODO Set Authorization rules
return true;
}
/**
* @param ConstantObject $object
* @return bool
*/
protected function validators($object): bool
{
return true;
}
/**
* @param ConstantObject $object
* @return bool
*/
protected function criteria($object): bool
{
return true;
}
}
@@ -0,0 +1,50 @@
<?php
namespace App\Classes\Modules\Announcements\Standards\Rules;
use App\Classes\General\Abstracts\AbstractRule;
use App\Classes\Modules\Announcements\Standards\Validators\AnnouncementValidation;
use App\Classes\Modules\Companies\DataTransferObjects\AnnouncementObject;
class CanCreateAnnouncement extends AbstractRule
{
/** @var AnnouncementValidation */
private $AnnouncementValidation;
/**
* CanCreateAnnouncement constructor.
* @param AnnouncementValidation $AnnouncementValidation
*/
public function __construct(AnnouncementValidation $AnnouncementValidation)
{
$this->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;
}
}
@@ -0,0 +1,40 @@
<?php
namespace App\Classes\Modules\Announcements\Standards\Rules;
use App\Classes\General\Abstracts\AbstractRule;
use App\Classes\Modules\Announcement\DataTransferObjects\AnnouncementObject;
class CanDeleteAnnouncement extends AbstractRule
{
/**
* @return bool
*/
protected function authorized(): bool
{
// TODO Set Authorization rules
return true;
}
/**
* @param AnnouncementObject $object
* @return bool
*/
protected function validators($object): bool
{
return true;
}
/**
* @param AnnouncementObject $object
* @return bool
*/
protected function criteria($object): bool
{
return true;
}
}
@@ -0,0 +1,36 @@
<?php
namespace App\Classes\Modules\Announcements\Standards\Rules;
use App\Classes\General\Abstracts\AbstractRule;
use App\Classes\Modules\Announcements\DataTransferObjects\AnnouncementObject;
class CanListAnnouncements extends AbstractRule
{
/**
* @return bool
*/
protected function authorized(): bool
{
return true;
}
/**
* @param AnnouncementObject $object
* @return bool
*/
protected function validators($object): bool
{
return true;
}
/**
* @param AnnouncementObject $object
* @return bool
*/
protected function criteria($object): bool
{
return true;
}
}
@@ -0,0 +1,54 @@
<?php
namespace App\Classes\Modules\Announcements\Standards\Rules;
use App\Classes\General\Abstracts\AbstractRule;
use App\Classes\Modules\Announcements\DataTransferObjects\AnnouncementObject;
use App\Classes\Modules\Announcements\Standards\Validators\AnnouncementValidation;
class CanUpdateAnnouncement extends AbstractRule
{
/** @var AnnouncementValidation */
private $AnnouncementValidation;
/**
* CanUpdateAnnouncement constructor.
* @param AnnouncementValidation $AnnouncementValidation
*/
public function __construct(AnnouncementValidation $AnnouncementValidation)
{
$this->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;
}
}
@@ -0,0 +1,44 @@
<?php
namespace App\Classes\Modules\Announcements\Standards\Validators;
use App\Classes\General\Abstracts\AbstractValidation;
use App\Classes\Modules\Announcements\DataTransferObjects\AnnouncementObject;
class AnnouncementValidation extends AbstractValidation
{
/**
* @param AnnouncementObject $object
* @return array
*/
protected function data($object): array
{
return [
'title' => $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 [];
}
}
@@ -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);
}
}
@@ -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());
@@ -0,0 +1,60 @@
<?php
namespace App\Classes\Modules\Orders\ControllersLogic;
use App\Classes\General\Abstracts\AbstractControllerLogic;
use App\Classes\Modules\Orders\Services\FetchesOrder;
use App\Classes\Modules\Remarks\DataTransferObjects\RemarkObject;
use App\Classes\Modules\Remarks\Processors\CreateRemarkProcessor;
use App\Http\Resources\OrderResource;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
class CreateOrderRemarkLogic extends AbstractControllerLogic
{
/**
* @return array
*/
protected function notification():array {
return [
'title' => '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));
}
}
@@ -0,0 +1,46 @@
<?php
namespace App\Classes\Modules\Orders\ControllersLogic;
use App\Classes\Exceptions\ErrorException;
use App\Classes\General\Abstracts\AbstractControllerLogic;
use App\Classes\Modules\Orders\Services\FetchesOrder;
use App\Classes\Modules\Orders\Services\UpdateOrderReference;
use App\Http\Resources\OrderResource;
use App\Models\Company;
use App\Models\Order;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
class UpdateOrderLogic extends AbstractControllerLogic
{
protected function notification(): array
{
return [
'title' => '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));
}
}
@@ -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;
}
@@ -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);
@@ -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);
@@ -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;
}
@@ -0,0 +1,148 @@
<?php
namespace App\Classes\Modules\Orders\Processors;
use App\Classes\Exceptions\InternalServerErrorException;
use App\Classes\Modules\Orders\Services\FetchesDataFromVTPortal;
use App\Classes\Modules\Addresses\Services\FetchesAddress;
use App\Classes\Modules\Schedules\DataTransferObjects\ScheduleObject;
use App\Classes\Modules\Schedules\Services\CreatesSchedule;
use App\Classes\Modules\Transports\DataTransferObjects\TransportObject;
use App\Classes\Modules\Transports\Services\CreatesTransport;
use App\Classes\Modules\Unity\Services\UpdatesContractObligation;
use App\Classes\ValueObjects\Constants\ApprovalStatus;
use App\Classes\ValueObjects\Constants\OrderRoleTypes;
use App\Classes\ValueObjects\Constants\PackingListType;
use App\Classes\ValueObjects\Constants\TransportType;
use App\Models\PackingList;
use App\Models\Transport;
use Carbon\Carbon;
use GuzzleHttp\Exception\GuzzleException;
use Illuminate\Support\Facades\Log;
use Illuminate\Http\Request;
class UpdateDoFromVTPortalProcessor
{
/** @var FetchesDataFromVTPortal */
private $fetchesDataFRomVTPortal;
/** @var FetchesAddress */
private $fetchesAddress;
/**
* FetchDeliveryListFromVTPortalProcessor constructor.
* @param FetchesDataFromVTPortal $fetchesDataFRomVTPortal
* @param FetchesAddress $fetchesAddress
*/
public function __construct(FetchesDataFromVTPortal $fetchesDataFRomVTPortal, FetchesAddress $fetchesAddress)
{
$this->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 [];
}
}
}
@@ -0,0 +1,34 @@
<?php
namespace App\Classes\Modules\Orders\Services;
use Psr\Http\Message\ResponseInterface;
class FetchesDataFromYDPortal
{
/**
* @param string $url
* @param string $method
* @param $body
* @param bool $requiresAuthentication
* @return \Psr\Http\Message\ResponseInterface
* @throws \GuzzleHttp\Exception\GuzzleException
*/
public function clientRequest(string $url, string $method, $body){
$client = new \GuzzleHttp\Client();
$body['apicode'] = env('YD_API_CODE');
$request = $client->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);
}
}
@@ -0,0 +1,17 @@
<?php
namespace App\Classes\Modules\Orders\Services;
use App\Classes\General\Eloquent\AbstractUpdateRecord;
use App\Models\Order;
use App\Classes\Modules\Orders\DataTransferObjects\OrderObject;
class UpdateOrderReference extends AbstractUpdateRecord
{
public function execute(Order $model, string $reference)
{
$model->reference = $reference;
return $this->handler($model);
}
}
@@ -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));
}
@@ -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));
}
@@ -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));
}
}
@@ -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 ;
}
@@ -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;
}
}
@@ -80,6 +80,10 @@ class FetchContainersStatusUpdateFromVTPortalProcessor
$containerDetails = $this->fetchesDataFRomVTPortal->getResponseBody($containerDetailsRequest);
if(!$containerDetails->Rows){
continue;
}
$containerDetails = $containerDetails->Rows[0];
if(!$eta = $containerDetails[3]){
@@ -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);
}
}
}
@@ -0,0 +1,321 @@
<?php
namespace App\Classes\Modules\PackingLists\Processors;
use App\Classes\Exceptions\ResourceNotFoundException;
use App\Classes\Modules\Companies\Services\FetchesCompanyModule;
use App\Classes\Modules\Orders\Services\FetchesDataFromYDPortal;
use App\Classes\Modules\Orders\Services\FetchesOrder;
use App\Classes\Modules\PackingLists\DataTransferObjects\ContainerObject;
use App\Classes\Modules\PackingLists\DataTransferObjects\PackageObject;
use App\Classes\Modules\PackingLists\DataTransferObjects\PackingListObject;
use App\Classes\Modules\PackingLists\Services\Containers\FetchesContainer;
use App\Classes\Modules\PackingLists\Services\FetchesPackingList;
use App\Classes\Modules\Schedules\DataTransferObjects\ScheduleObject;
use App\Classes\Modules\Schedules\Services\CreatesSchedule;
use App\Classes\Modules\Steps\DataTransferObjects\StepsObject;
use App\Classes\Modules\Steps\Services\CreatesStep;
use App\Classes\Modules\Transports\DataTransferObjects\TransportObject;
use App\Classes\Modules\Transports\Services\CreatesTransport;
use App\Classes\Modules\Unity\Processors\ActivateContractProcessor;
use App\Classes\Modules\Unity\Processors\AssignContractEntityProcessor;
use App\Classes\Modules\Unity\Processors\CreateContractEntityProcessor;
use App\Classes\Modules\Unity\Services\CreatesContract;
use App\Classes\Modules\Unity\Services\UpdatesContractObligation;
use App\Classes\ValueObjects\Constants\ApprovalStatus;
use App\Classes\ValueObjects\Constants\ContainerTypes;
use App\Classes\ValueObjects\Constants\OrderRoleTypes;
use App\Classes\ValueObjects\Constants\PackageType;
use App\Classes\ValueObjects\Constants\PackingListType;
use App\Classes\ValueObjects\Constants\TransportType;
use App\Models\Container;
use App\Models\PackingList;
use App\Models\Transaction;
use App\Models\Transport;
use Carbon\Carbon;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
class FetchOrderListsFromYdPortalProcessor
{
/** @var FetchesDataFromYDPortal */
private $fetchesDataFRomYDPortal;
/** @var FetchesOrder */
private $fetchesOrder;
/** @var UpdatesContractObligation */
private $updatesContractObligations;
/** @var CreatePackingListProcessor */
private $createPackingListProcessor;
/** @var CreatePackageProcessor */
private $createPackageProcessor;
/** @var CreatesTransport */
private $createsTransport;
/** @var CreatesSchedule */
private $createsSchedule;
/** @var FetchesContainer */
private $fetchesContainer;
/** @var FetchesPackingList */
private $fetchesPackingList;
/** @var FetchesCompanyModule */
private $fetchesCompanyModule;
/** @var CreateContainerProcessor */
private $createContainerProcessor;
/** @var CreatesContract */
private $unityCreateContract;
/** @var AssignContractEntityProcessor */
private $unityAssignContractEntity;
/** @var CreateContractEntityProcessor */
private $unityCreateContractEntity;
/** @var CreatesStep */
private $createsStep;
/** @var ActivateContractProcessor */
private $unityActivateContract;
/**
* FetchOrderListsFromYdPortalProcessor constructor.
* @param FetchesDataFromYDPortal $fetchesDataFRomYDPortal
* @param FetchesOrder $fetchesOrder
* @param UpdatesContractObligation $updatesContractObligations
* @param CreatePackingListProcessor $createPackingListProcessor
* @param CreatePackageProcessor $createPackageProcessor
* @param CreatesTransport $createsTransport
* @param CreatesSchedule $createsSchedule
* @param FetchesContainer $fetchesContainer
* @param FetchesPackingList $fetchesPackingList
* @param FetchesCompanyModule $fetchesCompanyModule
* @param CreateContainerProcessor $createContainerProcessor
* @param CreatesContract $unityCreateContract
* @param AssignContractEntityProcessor $unityAssignContractEntity
* @param CreateContractEntityProcessor $unityCreateContractEntity
* @param CreatesStep $createsStep
* @param ActivateContractProcessor $unityActivateContract
*/
public function __construct(FetchesDataFromYDPortal $fetchesDataFRomYDPortal, FetchesOrder $fetchesOrder, UpdatesContractObligation $updatesContractObligations, CreatePackingListProcessor $createPackingListProcessor, CreatePackageProcessor $createPackageProcessor, CreatesTransport $createsTransport, CreatesSchedule $createsSchedule, FetchesContainer $fetchesContainer, FetchesPackingList $fetchesPackingList, FetchesCompanyModule $fetchesCompanyModule, CreateContainerProcessor $createContainerProcessor, CreatesContract $unityCreateContract, AssignContractEntityProcessor $unityAssignContractEntity, CreateContractEntityProcessor $unityCreateContractEntity, CreatesStep $createsStep, ActivateContractProcessor $unityActivateContract)
{
$this->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);
}
}
}
@@ -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;
@@ -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());
}
@@ -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();
@@ -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;
}
@@ -0,0 +1,13 @@
<?php
namespace App\Classes\ValueObjects\Constants;
final class RemarkTypes
{
public const INTERNAL = 0;
public const EXTERNAL = 1;
}
@@ -10,6 +10,8 @@ final class WarehouseReferences {
public const VT_YIWU = 'YW-V01';
public const YD_YIWU = 'YW-V02';
public const VT_KLANG = 'KL-V01';
public const YD_KLANG = 'KL-V02';
+1 -1
View File
@@ -47,7 +47,7 @@ class CurlVTCommand extends Command
*/
public function handle()
{
FetchWarehouseReceiveListFromVTPortalJob::withChain([
return FetchWarehouseReceiveListFromVTPortalJob::withChain([
new FetchLoadedContainersFromVTPortalJob,
new FetchPackingListFromVTPortalJob,
new FetchContainersStatusUpdateFromVTPortalJob,
@@ -1,48 +0,0 @@
<?php
namespace App\Console\Commands;
use App\Models\State;
use App\Http\Helpers\General;
use Illuminate\Console\Command;
use App\Jobs\CurlWarehouseListJob;
class CurlWarehouseListCommand extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'command:curlWarehouseListCommand';
// php artisan queue:work
/**
* The console command description.
*
* @var string
*/
protected $description = 'Command description';
/**
* Create a new command instance.
*
* @return void
*/
public function __construct()
{
parent::__construct();
}
/**
* Execute the console command.
*
* @return mixed
*/
public function handle()
{
CurlWarehouseListJob::dispatch();
}
}
@@ -2,13 +2,12 @@
namespace App\Console\Commands;
use App\Models\State;
use App\Classes\Jobs\FetchOrdersFromYDPortalJob;
use App\Http\Helpers\General;
use Illuminate\Console\Command;
use App\Jobs\CurlContainerListJob;
class CurlContainerListCommand extends Command
class CurlYdOrderListCommand extends Command
{
/**
* The name and signature of the console command.
@@ -16,8 +15,7 @@ class CurlContainerListCommand extends Command
* @var string
*/
protected $signature = 'command:curlContainerListCommand';
// php artisan queue:work
protected $signature = 'command:curlYdOrderListCommand';
/**
* The console command description.
@@ -43,6 +41,6 @@ class CurlContainerListCommand extends Command
*/
public function handle()
{
CurlContainerListJob::dispatch();
return FetchOrdersFromYDPortalJob::withChain([])->dispatch();
}
}
+36 -1
View File
@@ -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');
}
/**
@@ -0,0 +1,20 @@
<?php
namespace App\Http\Controllers\Announcements;
use App\Classes\Modules\Announcements\ControllersLogic\AssignAnnouncementToSegmentLogic;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
class AssignAnnouncementToSegmentController
{
/**
* @param Request $request
* @param AssignCompanyToSegmentLogic $logic
* @return JsonResponse
*/
public function assign(Request $request, AssignAnnouncementToSegmentLogic $logic): JsonResponse {
return $logic->execute($request);
}
}
@@ -0,0 +1,20 @@
<?php
namespace App\Http\Controllers\Announcements;
use App\Classes\Modules\Announcements\ControllersLogic\CreateAnnouncementLogic;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
class CreateAnnouncementController
{
/**
* @param Request $request
* @param CreateAnnouncementLogic $logic
* @return JsonResponse
*/
public function create(Request $request, CreateAnnouncementLogic $logic): JsonResponse
{
return $logic->execute($request);
}
}
@@ -0,0 +1,20 @@
<?php
namespace App\Http\Controllers\Announcements;
use App\Classes\Modules\Announcements\ControllersLogic\DeleteAnnouncementLogic;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
class DeleteAnnouncementController
{
/**
* @param Request $request
* @param DeleteAnnouncementLogic $logic
* @return JsonResponse
*/
public function delete(Request $request, DeleteAnnouncementLogic $logic): JsonResponse
{
return $logic->execute($request);
}
}
@@ -0,0 +1,20 @@
<?php
namespace App\Http\Controllers\Announcements;
use App\Classes\Modules\Announcements\ControllersLogic\ListAnnouncementsLogic;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
class ListAnnouncementsController
{
/**
* @param Request $request
* @param ListAnnouncementsLogic $logic
* @return JsonResponse
*/
public function list(Request $request, ListAnnouncementsLogic $logic): JsonResponse
{
return $logic->execute($request);
}
}
@@ -0,0 +1,20 @@
<?php
namespace App\Http\Controllers\Announcements;
use App\Classes\Modules\Announcements\ControllersLogic\RemoveSegmentFromAnnouncementLogic;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
class RemoveSegmentFromAnnouncementController
{
/**
* @param Request $request
* @param RemoveCompanyFromSegmentLogic $logic
* @return JsonResponse
*/
public function detach(Request $request, RemoveSegmentFromAnnouncementLogic $logic): JsonResponse {
return $logic->execute($request);
}
}
@@ -0,0 +1,21 @@
<?php
namespace App\Http\Controllers\Announcements;
use App\Classes\Modules\Announcements\ControllersLogic\UpdateAnnouncementLogic;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
class UpdateAnnouncementController
{
/**
* @param Request $request
* @param UpdateAnnouncementLogic $logic
* @return JsonResponse
*/
public function update(Request $request, UpdateAnnouncementLogic $logic): JsonResponse
{
return $logic->execute($request);
}
}
@@ -0,0 +1,14 @@
<?php
namespace App\Http\Controllers\Orders;
use App\Classes\Modules\Orders\ControllersLogic\CreateOrderRemarkLogic;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
class CreateOrderRemarkController
{
public function create(Request $request, CreateOrderRemarkLogic $logic): JsonResponse{
return $logic->execute($request);
}
}
@@ -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,
@@ -0,0 +1,15 @@
<?php
namespace App\Http\Controllers\Orders;
use App\Classes\Modules\Orders\ControllersLogic\UpdateOrderLogic;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
class UpdateOrderController
{
public function update(Request $request, UpdateOrderLogic $logic)
{
return $logic->execute($request);
}
}
@@ -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) {
+2
View File
@@ -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,
@@ -0,0 +1,28 @@
<?php
namespace App\Http\Resources;
use Illuminate\Http\Resources\Json\JsonResource;
use Carbon\Carbon;
class AnnouncementResource extends JsonResource
{
/**
* Transform the resource into an array.
*
* @param \Illuminate\Http\Request $request
* @return array
*/
public function toArray($request)
{
return [
'id' => $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'),
];
}
}
+7 -4
View File
@@ -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();
})))
];
}
}
+6 -5
View File
@@ -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')
];
+5 -3
View File
@@ -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())
];
}
}
+10 -2
View File
@@ -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)
])
];
}
}
+20 -1
View File
@@ -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');
}
}
+26
View File
@@ -0,0 +1,26 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
use Illuminate\Database\Eloquent\SoftDeletes;
/**
* Class Announcement
* @package App\Models
*
*/
class Announcement extends AbstractModel
{
use SoftDeletes;
protected $table = 'announcements';
/**
* @return \Illuminate\Database\Eloquent\Relations\BelongsToMany
**/
public function segments(): BelongsToMany
{
return $this->BelongsToMany(Segment::class);
}
}
+12 -10
View File
@@ -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]);
+10
View File
@@ -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());
// }
}
}
+64 -2
View File
@@ -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);
});
}
}
+29
View File
@@ -0,0 +1,29 @@
<?php
namespace App\Scopes;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Scope;
class CustomerPackagesScope implements Scope
{
/**
* Apply the scope to a given Eloquent query builder.
*
* @param \Illuminate\Database\Eloquent\Builder $builder
* @param \Illuminate\Database\Eloquent\Model $model
* @return void
*/
public function apply(Builder $builder, Model $model)
{
$builder->whereHas('order', function ($query) {
$query->whereHas('companyModule', function($query){
return $query->whereHas('employees', function($query){
return $query->where('user_id', Auth()->user()->id);
});
});
});
}
}
@@ -1,5 +1,6 @@
<?php
use App\Classes\ValueObjects\Constants\RemarkTypes;
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
@@ -18,6 +19,7 @@ class CreateRemarksTable extends Migration
$table->morphs('owner');
$table->bigInteger('commenter_id')->unsigned()->index();
$table->string('content',200);
$table->integer('type')->default(RemarkTypes::INTERNAL);
$table->softDeletes();
$table->timestamps();
});
@@ -0,0 +1,40 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateAnnouncementsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('announcements', function (Blueprint $table) {
$table->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');
}
}
@@ -0,0 +1,40 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateAnnouncementSegmentTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('announcement_segment', function (Blueprint $table) {
$table->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');
}
}
+1 -1
View File
@@ -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);
}
}
+13 -16
View File
@@ -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);
}
@@ -3,6 +3,14 @@
<div class="col">
<div class="row">
<div class="col">
<div class="row m-b-15">
<div class="col">
<validation-wrapper-component :validator="$v.parameters.reference">
<label>Address Reference/Label</label>
<input class="form-control" name="reference" v-model="parameters.reference">
</validation-wrapper-component>
</div>
</div>
<div class="row m-b-15">
<div class="col">
<validation-wrapper-component :validator="$v.parameters.street_one">
@@ -33,12 +41,34 @@
</validation-wrapper-component>
</div>
</div>
<div class="row m-b-15">
<div class="row">
<div class="col">
<validation-wrapper-component :validator="$v.parameters.reference">
<label>Address Reference/Label</label>
<input class="form-control" name="reference" v-model="parameters.reference">
</validation-wrapper-component>
<div class="row">
<div class="col">
<div class="row m-b-15">
<div class="col-12 col-md pr-md-1 pb-3 pb-md-0">
<validation-wrapper-component :validator="$v.parameters.person_in_charge">
<label>Person In Charge</label>
<input class="form-control" name="person_in_charge" v-model="parameters.person_in_charge">
</validation-wrapper-component>
</div>
<div class="col-12 col-md pl-md-1">
<validation-wrapper-component :validator="$v.parameters.phone">
<label>Phone</label>
<input class="form-control" name="phone" v-model="parameters.phone">
</validation-wrapper-component>
</div>
</div>
<div class="row m-b-15">
<div class="col">
<validation-wrapper-component :validator="$v.parameters.remark">
<label>Delivery Remark</label>
<input class="form-control" name="remark" v-model="parameters.remark">
</validation-wrapper-component>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
@@ -46,7 +76,8 @@
<div class="row">
<div class="col">
<div class="row">
<div class="col text-right">
<div class="col"></div>
<div class="col-auto">
<button type="button" class="btn btn-sm btn-complete b-rad-none" @click="submitForm()">{{ this.data ? "Update" : "Save" }} Address</button>
</div>
</div>
@@ -73,6 +104,9 @@
street_two: '',
district_id: '',
post_code: '',
remark: '',
phone: '',
person_in_charge: '',
}
}
@@ -84,6 +118,9 @@
this.parameters.street_two = this.data.street_two;
this.parameters.district_id = this.data.district.id;
this.parameters.post_code = this.data.post_code;
this.parameters.phone = this.data.contact ? this.data.contact.phone : '';
this.parameters.person_in_charge = this.data.contact ? this.data.contact.reference : '';
this.parameters.remark = this.data.remark ? this.data.remark.content : '';
}
},
watch: {
@@ -28,11 +28,11 @@
</div>
<div class="col-auto">
<p class="no-margin fs-10 all-caps">Packages</p>
<p class="no-margin">{{ item.packing_lists.reduce((total, obj) => total + obj.packages.reduce((total, obj) => obj.quantity + total, 0), 0) }}</p>
<p class="no-margin">{{ item.packages_count }}</p>
</div>
<div class="col-auto">
<p class="no-margin fs-10 all-caps">Loaded CBM</p>
<p class="no-margin">{{ (Math.ceil((item.packing_lists.reduce((total, obj) => total + obj.packages.reduce((total, obj) => obj.cbm + total, 0), 0)) * 1000) / 1000).toFixed(3) }}</p>
<p class="no-margin">{{ (Math.ceil(item.total_cbm * 1000) / 1000).toFixed(3) }}</p>
</div>
<div class="col-auto">
<p class="no-margin fs-10 all-caps">Status</p>
@@ -49,52 +49,7 @@
</div>
</div>
</div>
<div class="row" v-show="expanded">
<div class="col">
<div class="row">
<div class="col">
<div class="row align-items-center p-t-10 p-b-10 b-t b-grey muted all-caps fs-10">
<div class="col-2">Marking</div>
<div class="col-1 text-center">Quantity</div>
<div class="col-1">CBM</div>
<div class="col-1 text-center">status</div>
<div class="col-3">Delivery Address</div>
<div class="col">Delivery Date</div>
</div>
</div>
</div>
<div class="row">
<div class="col">
<div class="row">
<div class="col">
<div class="row align-items-center p-t-10 p-b-10 b-t b-grey" v-for="(packingList, index) in item.packing_lists">
<div class="col-2"><a :href="route('customer.profile', packingList.order.company_module.marking)">{{packingList.order.company_module.marking}}</a>/<a :href="route('order.show', packingList.order.reference)">{{packingList.order.reference}}</a></div>
<div class="col-1 text-center">{{packingList.packages.reduce((total, obj) => obj.quantity + total, 0)}}</div>
<div class="col-1">{{ (Math.ceil((packingList.packages.reduce((total, obj) => obj.cbm + total, 0)) * 1000) / 1000).toFixed(3)}}</div>
<div class="col-1 bold text-center" :class="{'text-danger': packingList.status === 5, 'text-success': packingList.status !== 5}">{{packingList.transport ? 'Delivery' : packingList.status === 5 ? 'On Hold' : 'Release'}}</div>
<div class="col-3">{{packingList.order.address.street_one+' '+(packingList.order.address.street_two ? packingList.order.address.street_two : '')+', '+ packingList.order.address.district.name+', '+packingList.order.address.post_code+' '+packingList.order.address.state.name+', '+packingList.order.address.country.name}}</div>
<div class="col">
<p class="no-margin">{{packingList.transport ? packingList.transport.current_schedule.eta : 'n/a'}}</p>
</div>
<div class="col-auto text-right" v-if="!packingList.transport">
<div class="btn btn-xs btn-success pointer" v-if="packingList.status === 5" @click="updateStatus(index, item.status === 1 ? 1 : 2)"><i class="fa fa-check m-r-5"></i>Release</div>
<div class="btn btn-xs btn-danger pointer" v-if="packingList.status !== 5" @click="updateStatus(index, 5)"><i class="fa fa-hand-paper-o m-r-5"></i>Hold</div>
</div>
<div class="col-auto hide">
<a class="btn btn-xs btn-warning all-caps b-rad-none pointer" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
Report&nbsp;<i class="fa fa-download m-r-10"></i>
</a>
<div class="dropdown-menu">
<a class="dropdown-item" :href="route('report.customclearance',packingList.order.id)">Origin custom cleared</a>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<packing-list-section-component :data="item" v-if="expanded"></packing-list-section-component>
</div>
</div>
</template>
@@ -104,21 +59,6 @@
data(){
return {
expanded: false,
index: null,
}
},
methods: {
updateStatus(index, status){
this.index = index;
this.submit(this.route('api.packing_list.status.update', this.item.packing_lists[index].id, status), 'put', 'containerListSection', true, true)
},
successHandler(response){
this.item.packing_lists[this.index] = response.payload.data;
this.$forceUpdate();
this.index = null;
},
errorHandler(){
this.index = null;
}
},
mixins: [componentHandler]
@@ -0,0 +1,31 @@
<template>
<div class="row">
<div class="col-2"><a :href="route('customer.profile', item.order.company_module.marking)">{{item.order.company_module.marking}}</a>/<a :href="route('order.show', item.order.reference)">{{item.order.reference}}</a></div>
<div class="col-1 text-center">{{item.packages.reduce((total, obj) => obj.quantity + total, 0)}}</div>
<div class="col-1">{{ (Math.ceil((item.packages.reduce((total, obj) => obj.cbm + total, 0)) * 1000) / 1000).toFixed(3)}}</div>
<div class="col-1 bold text-center" :class="{'text-danger': item.status === 5, 'text-success': item.status !== 5}">{{item.transport ? 'Delivery' : item.status === 5 ? 'On Hold' : 'Release'}}</div>
<div class="col-3">{{item.order.address.contact ? item.order.address.contact.reference+' '+item.order.address.contact.phone : ''}}<br>{{item.order.address.street_one+' '+(item.order.address.street_two ? item.order.address.street_two : '')+', '+ item.order.address.district.name+', '+item.order.address.post_code+' '+item.order.address.state.name+', '+item.order.address.country.name}}<br>{{item.order.address.remark ? item.order.address.remark.content: ''}}</div>
<div class="col">
<p class="no-margin">{{item.transport ? item.transport.current_schedule.eta : 'n/a'}}</p>
</div>
<div class="col-auto text-right" v-if="!item.transport">
<div class="btn btn-xs btn-success pointer" v-if="item.status === 5" @click="updateStatus(item.status === 1 ? 1 : 2)"><i class="fa fa-check m-r-5"></i>Release</div>
<div class="btn btn-xs btn-danger pointer" v-if="item.status !== 5" @click="updateStatus(5)"><i class="fa fa-hand-paper-o m-r-5"></i>Hold</div>
</div>
</div>
</template>
<script>
import componentHandler from '../../../general/mixins/componentHandler';
export default {
methods: {
updateStatus(status){
this.submit(this.route('api.packing_list.status.update', this.item.id, status), 'put', '', true, true)
},
successHandler(response){
this.item = response.payload.data;
// this.$forceUpdate();
}
},
mixins: [componentHandler]
}
</script>
@@ -0,0 +1,60 @@
<template>
<div class="row">
<div class="col">
<loading-component v-if="isLoading" style="height: 200px; top: 0;"></loading-component>
<div class="row" v-show="!isLoading">
<div class="col">
<div class="row">
<div class="col">
<div class="row align-items-center p-t-10 p-b-10 b-t b-grey muted all-caps fs-10">
<div class="col-2">Marking</div>
<div class="col-1 text-center">Quantity</div>
<div class="col-1">CBM</div>
<div class="col-1 text-center">status</div>
<div class="col-3">Delivery Details</div>
<div class="col">Delivery Date</div>
</div>
</div>
</div>
<div class="row">
<div class="col">
<div class="row">
<div class="col">
<div class="row align-items-center p-t-10 p-b-10 b-t b-grey" v-for="packingList in packingLists">
<div class="col">
<packing-list-component :data="packingList"></packing-list-component>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
import componentHandler from '../../../general/mixins/componentHandler';
import LoadingComponent from "../../general/elements/LoadingComponent";
import PackingListComponent from "../elements/PackingListComponent";
export default {
components: {PackingListComponent, LoadingComponent},
data(){
return {
isLoading: true,
packingLists: []
}
},
created(){
this.submit(route('api.packing_list.container.show', this.item.id), 'get', this.section, false, false);
},
methods: {
successHandler(response){
this.packingLists = response.payload.data.packing_lists;
this.isLoading = false;
}
},
mixins: [componentHandler]
}
</script>
@@ -3,134 +3,39 @@
<div class="col">
<div class="row">
<div class="col">
<div class="text-white p-t-25 p-l-25 p-r-25" style="background-image: radial-gradient(rgb(182, 3, 17), rgb(118, 0, 12));">
<div class="row" style="max-width: 650px; margin: 0px auto;">
<div class="col">
<div class="row m-b-25">
<div class="col text-center">
<h4 class="text-warning no-margin">2022年农历新春前夕仓库运作通知</h4>
<h4 class="text-warning no-margin">Chinese New Year Shipping Memo 2022</h4>
</div>
</div>
<div class="row">
<div class="col">
<div class="alert alert-success p-t-25 p-l-25 p-r-25">
<div class="row">
<div class="col">
<p class="no-margin">尊敬的顾客,</p>
<p class="m-b-15">Dear Valued Customers,</p>
<p class="no-margin">为确保您的货物在华人农历新年前收到 务必提前通知您的供应商安排在以下日期前把货物送到仓库:</p>
<p>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:</p>
</div>
</div>
<div class="row m-t-10">
<div class="col">
<div class="tg-wrap"><table class="tg">
<thead>
<tr>
<th class="tg-2bkf" colspan="2">仓库 WAREHOUSE</th>
<th class="tg-2bkf">入仓日期 RECEIVED DATE</th>
</tr>
</thead>
<tbody>
<tr>
<td class="tg-2bkf" rowspan="2">广州<br>GUANGHZOU<br></td>
<td class="tg-2bkf">西马<br>WEST MALAYSIA</td>
<td class="tg-2bkf">25/12/2021</td>
</tr>
<tr>
<td class="tg-2bkf">东马<br>EAST MALAYSIA</td>
<td class="tg-2bkf">11/12/2021</td>
</tr>
<tr v-if="expanded">
<td class="tg-2bkf" rowspan="2">义乌<br>YIWU</td>
<td class="tg-2bkf">西马<br>WEST MALAYSIA</td>
<td class="tg-2bkf">18/12/2021</td>
</tr>
<tr v-if="expanded">
<td class="tg-2bkf">东马<br>EAST MALAYSIA</td>
<td class="tg-2bkf">04/12/2021</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<div class="row m-t-15" v-if="expanded">
<div class="col">
<div class="row m-b-20">
<div class="row m-b-25">
<div class="col">
<p class="no-margin">我们建议客户尽早安排送货到中国仓库以确保货物在恶劣天气运输延误海关检查等情况下准时到达目的地</p>
<p>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.</p>
<h4 class="no-margin">好消息过年前仓库延长收货通知</h4>
<h4 class="no-margin">New Year Warehouse Operation Extend Notice</h4>
</div>
</div>
<div class="row">
<div class="col">
<h6 class="text-warning no-margin bold">仓库运营日期</h6>
<h6 class="text-warning no-margin bold">Warehouse Operation Date</h6>
</div>
<p class="m-b-15">由于今年年前运输需求非常庞大我们决定投入更多的资源把仓库收货的日期延长以便确保更多货可以顺利在过年前把货顺利运出</p>
<p class="no-margin bold">广州 - 延长至 25/1/2022</p>
<p class="bold">义乌 - 延长至 23/1/2022</p>
<p class="m-b-15">仓库地址将会有所更改请大家务必要在发货之前留意二维码上的新仓库地址</p></div>
</div>
<div class="row m-t-15 m-b-15">
<div class="row">
<div class="col">
<div class="tg-wrap"><table class="tg">
<thead>
<tr>
<th class="tg-2bkf">仓库<br>WAREHOUSE</th>
<th class="tg-2bkf">仓库截止收货日期<br>LAST DAY RECEIVE GOODS</th>
<th class="tg-2bkf">仓库復工日期<br>RESUME OPERATION DATE</th>
</tr>
</thead>
<tbody>
<tr>
<td class="tg-2bkf" rowspan="2">义乌<br>YIWU</td>
<td class="tg-2bkf">18/01/2022<br>西马 WEST MALAYSIA</td>
<td class="tg-2bkf" rowspan="2">16/02/2022</td>
</tr>
<tr>
<td class="tg-2bkf">25/12/2021<br>东马 EAST MALAYSIA</td>
</tr>
<tr>
<td class="tg-2bkf" rowspan="2">广州<br>GUANGHZOU</td>
<td class="tg-2bkf">18/01/2022<br>西马 WEST MALAYSIA</td>
<td class="tg-2bkf" rowspan="2">12/02/2022</td>
</tr>
<tr>
<td class="tg-2bkf">08/01/2022<br>东马 EAST MALAYSIA</td>
</tr>
</tbody>
</table>
</div>
<p>Due to large traffic for shipment before Chinese New Year, we have decided to invest more resource to extend our warehouse receiving date,<br>to ensure goods are sent out before CNY.</p>
<p class="no-margin bold">Guangzhou - extend till 25/1/2022</p>
<p class="bold">Yiwu - extend till 23/1/2022</p>
<p class="m-b-15">Changes were made to the warehouse address, please change your delivery address according to the QR code.</p>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="row" style="margin-top: -1px;">
<div class="col text-center">
<div class="btn btn-block btn-danger bg-danger-darker no-border p-t-10 p-b-10" @click="expanded = !expanded"><i class="fa m-r-10" :class="[{'fa-angle-double-down': !expanded}, {'fa-angle-double-up': expanded}]"></i> Click To view {{expanded ? 'less' : 'more'}} details <i class="fa m-l-10" :class="[{'fa-angle-double-down': !expanded}, {'fa-angle-double-up': expanded}]"></i></div>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
data(){
return {
expanded: false
}
}
}
</script>
<style scoped>
.tg {border-collapse:collapse;border-spacing:0; width: 650px; margin: 0px auto; }
.tg td{border-color:black;border-style:solid;border-width:1px;font-family:Arial, sans-serif;font-size:14px;
overflow:hidden;padding:8px 20px;word-break:normal;}
.tg th{border-color:black;border-style:solid;border-width:1px;font-family:Arial, sans-serif;font-size:14px;
font-weight:normal;overflow:hidden;padding:8px 20px;word-break:normal;}
.tg .tg-2bkf{background-color:#76000c;border-color:#ffffff;color:#ffffff;text-align:center;vertical-align:middle}
@media screen and (max-width: 767px) {.tg {width: auto !important;}.tg col {width: auto !important;}.tg-wrap {overflow-x: auto;-webkit-overflow-scrolling: touch;margin: auto 0px;}}
</style>
@@ -16,14 +16,25 @@
<div class="col-6">
<div class="row m-b-5">
<div class="col">
<small class="fs-10 all-caps muted">Order No.</small>
<h6 class="no-margin small">{{item.reference}}</h6>
<div class="row">
<div class="col">
<small class="fs-10 all-caps muted">Order No</small>
</div>
</div>
<div class="row">
<div class="col-9 p-r-0">
<h6 class="no-margin small" style="white-space: nowrap;overflow: hidden;text-overflow: ellipsis;">{{item.reference}}</h6>
</div>
<div class="col p-l-0" v-if="item.remarks.length >= 1">
<i class="fa fa-info-circle m-l-5" data-html="true" v-tooltip:right="'<h6 class=\'text-white text-left fs-13 m-t-0 m-b-5 semi-bold\'>Remarks</h6><p class=\'text-white text-left lh-17 no-margin\'>'+item.remarks[0].content+'</p>'" ></i>
</div>
</div>
</div>
</div>
<div class="row m-b-5">
<div class="col">
<small class="fs-10 all-caps muted">Warehouse</small>
<h6 class="no-margin small">{{item.warehouse.name}}</h6>
<h6 class="no-margin small">{{item.warehouse.name}} {{$store.getters.isAdmin ? item.warehouse.reference : ''}}</h6>
</div>
</div>
<div class="row m-b-5">
@@ -51,15 +62,15 @@
<div class="row text-center">
<div class="col b-r b-grey text-info p-t-5 p-b-10">
<small class="fs-10 all-caps bold">Received</small>
<h6 class="bold no-margin text-info">{{item.parcels.received_packages.reduce((total, obj) => obj.quantity + total, 0)}}</h6>
<h6 class="bold no-margin text-info">{{item.parcels.received_packages.flatMap(packing_list => packing_list.packages).reduce((total, obj) => obj.quantity + total, 0)}}</h6>
</div>
<div class="col b-r b-grey text-primary p-t-5 p-b-10">
<small class="fs-10 all-caps bold">In Transit</small>
<h6 class="bold no-margin text-primary">{{item.parcels.in_transit_packages.reduce((total, obj) => obj.quantity + total, 0)}}</h6>
<h6 class="bold no-margin text-primary">{{item.parcels.in_transit_packages.flatMap(packing_list => packing_list.packages).concat(item.parcels.destination_warehouse_packages.flatMap(packing_list => packing_list.packages)).reduce((total, obj) => obj.quantity + total, 0)}}</h6>
</div>
<div class="col text-success p-t-5 p-b-10">
<small class="fs-10 all-caps bold">Delivered</small>
<h6 class="bold no-margin text-success">{{item.parcels.delivered_packages.reduce((total, obj) => obj.quantity + total, 0)}}</h6>
<h6 class="bold no-margin text-success">{{item.parcels.delivered_packages.flatMap(packing_list => packing_list.packages).reduce((total, obj) => obj.quantity + total, 0)}}</h6>
</div>
</div>
</div>
@@ -79,7 +90,7 @@
</div>
<div class="col-auto text-right">
<small class="fs-10 all-caps muted">Total CBM</small>
<h6 class="no-margin semi-bold">{{(Math.ceil((item.parcels.origin_warehouse_packages.reduce((total, obj) => obj.cbm + total, 0) + item.parcels.in_transit_packages.reduce((total, obj) => obj.cbm + total, 0) + item.parcels.delivered_packages.reduce((total, obj) => obj.cbm + total, 0)) * 10000) / 10000).toFixed(3)}}</h6>
<h6 class="no-margin semi-bold">{{(Math.ceil((item.parcels.origin_warehouse_packages.flatMap(packing_list => packing_list.packages).reduce((total, obj) => obj.cbm + total, 0) + item.parcels.in_transit_packages.flatMap(packing_list => packing_list.packages).reduce((total, obj) => obj.cbm + total, 0) + item.parcels.destination_warehouse_packages.flatMap(packing_list => packing_list.packages).reduce((total, obj) => obj.cbm + total, 0) + item.parcels.delivered_packages.flatMap(packing_list => packing_list.packages).reduce((total, obj) => obj.cbm + total, 0)) * 10000) / 10000).toFixed(3)}}</h6>
</div>
</div>
</div>
@@ -46,7 +46,7 @@
<div class="row m-b-5">
<div class="col-auto">
<small class="fs-10 all-caps muted">Order Number</small>
<p class="no-margin bold">{{item.order.reference}}</p>
<p class="no-margin bold"><a :href="route('order.show', item.order.reference)">{{item.order.reference}}</a></p>
</div>
<div class="col-auto">
<small class="fs-10 all-caps muted">Status</small>
@@ -60,7 +60,7 @@
<div class="row">
<div class="col-auto">
<small class="fs-10 all-caps muted">Warehouse</small>
<h6 class="no-margin small">{{item.order.warehouse.name}}</h6>
<h6 class="no-margin small">{{item.order.warehouse.name}} {{$store.getters.isAdmin ? item.order.warehouse.reference : ''}}</h6>
</div>
<div class="col-auto">
<small class="fs-10 all-caps muted">Delivery Address</small>
@@ -69,72 +69,76 @@
</div>
</div>
</div>
<div class="row p-t-10 p-b-10" v-if="item.container.transport">
<div class="col-auto p-r-0 p-t-10">
<div class="row" v-for="schedule in item.container.transport.schedule_history" :key="schedule.id">
<div class="col">
<div class="row justify-content-center">
<div class="col-auto">
<i class="fa fa-times fs-15 text-danger"></i>
<div class="row p-t-10 p-b-10" v-if="item.container">
<div class="col">
<div class="row" v-if="item.container.transport">
<div class="col-auto p-r-0 p-t-10">
<div class="row" v-for="schedule in item.container.transport.schedule_history" :key="schedule.id">
<div class="col">
<div class="row justify-content-center">
<div class="col-auto">
<i class="fa fa-times fs-15 text-danger"></i>
</div>
</div>
<div class="row justify-content-center">
<div class="col-auto">
<div class="b-l b-dashed b-danger" style="height: 35px;"></div>
</div>
</div>
</div>
</div>
<div class="row justify-content-center">
<div class="col-auto">
<div class="b-l b-dashed b-danger" style="height: 35px;"></div>
<i class="fa fa-check fs-15" :class="{'text-primary': status !== 'Ready To Ship', 'muted': status === 'Ready To Ship'}"></i>
</div>
</div>
<div class="row justify-content-center">
<div class="col-auto">
<div class="b-l b-dashed " style="height: 35px;" :class="{'b-primary': status === 'Preparing Delivery' || status === 'Delivered', 'b-grey': status !== 'Preparing Delivery' || status !== 'Delivered'}"></div>
</div>
</div>
<div class="row justify-content-center">
<div class="col-auto">
<i class="fa fa-check fs-15" :class="{'text-primary': item.transport, 'muted': !item.transport}"></i>
</div>
</div>
</div>
</div>
<div class="row justify-content-center">
<div class="col-auto">
<i class="fa fa-check fs-15" :class="{'text-primary': status !== 'Ready To Ship', 'muted': status === 'Ready To Ship'}"></i>
</div>
</div>
<div class="row justify-content-center">
<div class="col-auto">
<div class="b-l b-dashed " style="height: 35px;" :class="{'b-primary': status === 'Preparing Delivery' || status === 'Delivered', 'b-grey': status !== 'Preparing Delivery' || status !== 'Delivered'}"></div>
</div>
</div>
<div class="row justify-content-center">
<div class="col-auto">
<i class="fa fa-check fs-15" :class="{'text-primary': item.transport, 'muted': !item.transport}"></i>
</div>
</div>
</div>
<div class="col p-l-0">
<div class="row m-b-15" v-for="schedule in item.container.transport.schedule_history" :key="schedule.id">
<div class="col">
<div class="row no-margin">
<div class="col-auto">
<small class="fs-10 all-caps muted">Etd</small>
<h6 class="no-margin small">{{schedule.etd}}</h6>
</div>
<div class="col-auto">
<small class="fs-10 all-caps muted">Eta</small>
<h6 class="no-margin small">{{schedule.eta}}</h6>
<div class="col p-l-0">
<div class="row m-b-15" v-for="schedule in item.container.transport.schedule_history" :key="schedule.id">
<div class="col">
<div class="row no-margin">
<div class="col-auto">
<small class="fs-10 all-caps muted">Etd</small>
<h6 class="no-margin small">{{schedule.etd}}</h6>
</div>
<div class="col-auto">
<small class="fs-10 all-caps muted">Eta</small>
<h6 class="no-margin small">{{schedule.eta}}</h6>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="row m-b-15">
<div class="col">
<div class="row no-margin">
<div class="col-auto" v-if="!item.container.transport.schedule_history.length">
<small class="fs-10 all-caps muted">Etd</small>
<h6 class="no-margin small">{{item.container ? item.container.transport.current_schedule.etd : 'n/a'}}</h6>
</div>
<div class="col-auto">
<small class="fs-10 all-caps muted">{{!item.container.transport.schedule_history.length ? 'Eta' : 'Rescheduled Eta' }}</small>
<h6 class="no-margin small">{{item.container ? item.container.transport.current_schedule.eta : 'n/a'}}</h6>
<div class="row m-b-15">
<div class="col">
<div class="row no-margin">
<div class="col-auto" v-if="!item.container.transport.schedule_history.length">
<small class="fs-10 all-caps muted">Etd</small>
<h6 class="no-margin small">{{item.container ? item.container.transport.current_schedule.etd : 'n/a'}}</h6>
</div>
<div class="col-auto">
<small class="fs-10 all-caps muted">{{!item.container.transport.schedule_history.length ? 'Eta' : 'Rescheduled Eta' }}</small>
<h6 class="no-margin small">{{item.container ? item.container.transport.current_schedule.eta : 'n/a'}}</h6>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col">
<div class="col-auto">
<small class="fs-10 all-caps muted">Delivery Date</small>
<h6 class="no-margin small">{{item.transport ? item.transport.current_schedule.eta : 'n/a'}}</h6>
<div class="row">
<div class="col">
<div class="col-auto">
<small class="fs-10 all-caps muted">Delivery Date</small>
<h6 class="no-margin small">{{item.transport ? item.transport.current_schedule.eta : 'n/a'}}</h6>
</div>
</div>
</div>
</div>
</div>
@@ -142,7 +146,7 @@
</div>
</div>
</div>
<div class="row m-t-25" v-if="item.container.transport">
<div class="row m-t-25" v-if="item.container">
<div class="col"></div>
<div class="col b-t b-primary" style="border-top-width: 5px;"></div>
</div>
@@ -20,16 +20,20 @@
<div class="row align-items-center">
<div class="col-auto">
<p class="no-margin all-caps fs-10 light">Arrival Date</p>
<p class="no-margin text-success bold">{{item.transport.drop_date}}</p>
<p class="no-margin text-success bold">{{item.transport ? item.transport.drop_date : 'n/a'}}</p>
</div>
<div class="col-auto text-center">
<p class="no-margin all-caps fs-10 light">Qty</p>
<p class="no-margin bold">{{item.quantity}}</p>
</div>
<div class="col-auto">
<div class="col-auto" v-if="!$store.getters.isAdmin">
<p class="no-margin all-caps fs-10 light">Est. CBM</p>
<p class="no-margin">{{((parseFloat(item.cbm) * 1000) / 1000).toFixed(3)}}</p>
</div>
<div class="col-auto" v-if="$store.getters.isAdmin">
<p class="no-margin all-caps fs-10 light">Warehouse</p>
<p class="no-margin">{{item.order.warehouse.reference}}</p>
</div>
<div class="col text-right">
<div class="btn btn-xs btn-default" @click="expanded = !expanded"><i class="fa" :class="{'fa-angle-up': expanded, 'fa-angle-down': !expanded}"></i></div>
</div>
@@ -62,7 +66,7 @@
<p class="no-margin bold text-info fs-12"><a :href="route('customer.profile', item.order.company_module.marking)">{{item.order.company_module.marking}}</a></p>
</div>
</div>
<div class="row m-b-5" v-if="$store.getters.isAdmin">
<div class="row m-b-5">
<div class="col-auto p-r-5">
<p class="no-margin all-caps fs-10 light">Order Number</p>
</div>
@@ -0,0 +1,57 @@
<template>
<div class="row" style="width: 450px; margin: auto;" @keyup.enter="submitForm">
<div class="col bg-white padding-40 b-rad-lg">
<div class="row m-b-10">
<div class="col text-center">
<p>Plese enter the new order number.</p>
</div>
</div>
<div class="row">
<div class="col">
<validation-wrapper-component class="m-b-15" :validator="$v.parameters.reference_id">
<label class="text-primary">Order Number</label>
<input class="form-control" v-model="parameters.reference_id">
</validation-wrapper-component>
</div>
</div>
<div class="row m-t-15">
<div class="col-auto p-r-5">
<div class="btn btn-lg btn-default b-rad-none" data-dismiss="modal">Cancel</div>
</div>
<div class="col p-l-5">
<div class="btn btn-primary w-100 btn-lg" @click="submit(route('api.order.reference.update', data.id), 'post', section, true, true)">Confirm</div>
</div>
</div>
</div>
</div>
</template>
<script>
import modalFormHandler from '../../../general/mixins/modalFormHandler';
import { required, minLength } from "vuelidate/lib/validators";
export default {
data() {
return {
parameters: {
id: this.data.id,
reference_id: '',
}
};
},
validations: {
parameters: {
reference_id: {
required,
minLength: minLength(8)
},
}
},
methods: {
successHandler(response) {
window.location.replace(this.route('order.show', response.payload.data.reference));
}
},
mixins: [modalFormHandler]
}
</script>
@@ -0,0 +1,32 @@
<template>
<div class="row">
<div class="col">
<loading-component style="height: 300px; top: 0;" key="1" color="success" v-show="isLoading" ></loading-component>
<div class="row justify-content-center" v-show="!isLoading">
<div class="col">
<div class="row m-b-20">
<div class="col">
<h3 class="all-caps">Are you Sure?</h3>
<div class="fs-11">Are you sure you want to delete this comment?</div>
</div>
</div>
<div class="row">
<div class="col p-r-5">
<div class="btn btn-sm btn-success btn-block b-rad-none" data-dismiss="modal">Cancel</div>
</div>
<div class="col p-l-5">
<div class="btn btn-sm btn-danger btn-block b-rad-none" @click="submit(route('api.remark.delete', item.id), 'delete', section, true, true)">Delete</div>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
import componentHandler from '../../../general/mixins/componentHandler';
import ModalFormHandler from '../../../general/mixins/modalFormHandler';
export default {
mixins: [componentHandler, ModalFormHandler]
}
</script>
@@ -41,6 +41,30 @@
</div>
</div>
</div>
<div class="row justify-content-center m-t-15 align-items-center" v-if="parameters.warehouse_id">
<div class="col-6">
<div class="row justify-content-center">
<div class="col-auto">
<p class="m-b-0">仓库截止收货日期/LAST DAY RECEIVE GOODS:</p>
</div>
<div class="col-auto p-l-0">
<span class="bold text-success">{{parameters.warehouse_id === 4 ? '23':'25'}}/01/2022</span>
</div>
</div>
<div class="row m-t-20">
<div class="col">
<p>请注意!! 由于近期船公司对于重量严格把控我司对于货物超重的算法也进行了调整新超重算法将从 2022 1 20货物装箱日期起实行</p>
<p>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).</p>
<p>For more details: <a href="https://www.cief-malaysia.com/services-sea-shipping/" target="_blank">https://www.cief-malaysia.com/services-sea-shipping/</a></p>
</div>
</div>
</div>
</div>
<div class="row text-center justify-content-center">
<div class="col-8">
<p class="m-b-0 text-danger m-t-15" v-if="parameters.warehouse_id === 4">浙江北仑疫情爆发 义乌船期非常不稳定建议发广州仓库<br>Due to Beilun, Zhejiang pandemic outbreak our Yiwu warehouse might experience unexpected shipping delays, you can select our Guangzhou warehouse as an alternative.</p>
</div>
</div>
</div>
</div>
<div class="row justify-content-center">
@@ -66,6 +90,11 @@
<h3>Please select the address where you want to receive this order</h3>
</div>
</div>
<div class="row justify-content-center m-b-15" v-if="error">
<div class="col-10">
<small class="text-danger">{{error}}</small>
</div>
</div>
<div class="row justify-content-center">
<div class="col col-md-10">
<list-component style="min-height: 50px;" section="addressList" :emptyListSection=false :endpoint="route('api.address.list')" :options="{per_page: 10, HasMorphCompanyModule: company.company_module.id}">
@@ -146,6 +175,7 @@
return {
section: 'createOrderForm',
step: 1,
error: '',
parameters : {
warehouse_id: '',
address_id: '',
@@ -156,7 +186,7 @@
methods:{
createOrder(){
this.step++;
this.submit((this.route('api.order.create')), 'post', 'orderListSection', true, true)
this.submit((this.route('api.order.create')), 'post', 'orderListSection', true, false)
},
cancelOrder(){
this.parameters.warehouse_id = '';
@@ -170,7 +200,8 @@
}, 5000);
},
errorHandler(){
errorHandler(response){
this.error = response.message;
this.step--;
}
}
@@ -0,0 +1,49 @@
<template>
<div class="row">
<div class="col-6 p-r-0">
<validation-wrapper-component :validator="$v.parameters.content">
<input type="text" class="form-control fs-12" placeholder="Make a remark on this order." v-model.trim="parameters.content">
</validation-wrapper-component>
</div>
<div class="col-auto bg-success d-flex justify-content-center align-items-center pointer text-white">
<i class="fa fa-check" @click="submitForm"></i>
</div>
</div>
</template>
<script>
import modalFormHandler from '../../../general/mixins/modalFormHandler';
import { required } from "vuelidate/lib/validators";
export default {
props: {
id: {
type: Number,
required: true
}
},
data() {
return {
parameters: {
content: this.content,
},
};
},
validations: {
parameters: {
content: { required },
}
},
created() {
if (this.data) {
this.parameters.content = this.data.content
}
},
methods: {
submitForm() {
this.submit(this.data ? this.route('api.remark.update', this.data.id) : this.route('api.order.remark.create', this.id), this.data ? 'put' : 'post', this.section, true, true);
this.$emit('submit')
}
},
mixins: [modalFormHandler]
}
</script>

Some files were not shown because too many files have changed in this diff Show More