This commit is contained in:
glovetleong
2021-09-28 22:09:05 +08:00
135 changed files with 4048 additions and 522 deletions
+2 -1
View File
@@ -24,4 +24,5 @@ db/*
docker-compose.yml
package-lock.json
public/*
/public/*
/public/*
storage/framework/laravel-excel/*
@@ -43,4 +43,4 @@ abstract class AbstractListRecord extends AbstractGetRecord
}
}
}
@@ -0,0 +1,20 @@
<?php
namespace App\Classes\General\Eloquent\Filters;
use Illuminate\Database\Eloquent\Builder;
class WithOwner implements Filter
{
/**
* @param Builder $builder
* @param $value
* @return mixed
*/
public static function apply(Builder $builder, $value)
{
return $builder->with('owner');
}
}
@@ -0,0 +1,20 @@
<?php
namespace App\Classes\General\Eloquent\Filters;
use Illuminate\Database\Eloquent\Builder;
class WithPackingLists implements Filter
{
/**
* @param Builder $builder
* @param $value
* @return mixed
*/
public static function apply(Builder $builder, $value)
{
return $builder->with('packingLists');
}
}
+3 -3
View File
@@ -45,7 +45,7 @@ class CurlContainerListJob implements ShouldQueue
$last_two_month = Carbon::now()->subMonth(2)->format('Y-m-d');
$client = new \GuzzleHttp\Client(['headers' => $headers]);
$res = $client->post('https://portalvt.azurewebsites.net/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}}')]);
$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());
@@ -63,7 +63,7 @@ class CurlContainerListJob implements ShouldQueue
{
// get latest cookies
$client = new \GuzzleHttp\Client(['cookies' => true]);
$r = $client->request('GET', 'https://portalvt.azurewebsites.net');
$r = $client->request('GET', 'http://portal.vtnation.com.my');
$call_cookie = $client->getConfig('cookies');
$call_cookie = $call_cookie->toArray();
$latest_cookie = [];
@@ -79,7 +79,7 @@ class CurlContainerListJob implements ShouldQueue
'Cookie' => $latest_cookie,
];
$client = new \GuzzleHttp\Client(['headers' => $headers]);
$res = $client->post('https://portalvt.azurewebsites.net/Services/DataControllerService.asmx/Login', [\GuzzleHttp\RequestOptions::JSON => [
$res = $client->post('http://portal.vtnation.com.my/Services/DataControllerService.asmx/Login', [\GuzzleHttp\RequestOptions::JSON => [
"username" => "CIEF",
"password" => "0122120880",
"createPersistentCookie" => true,
@@ -0,0 +1,105 @@
<?php
namespace App\Classes\Modules\Accounts\ControllersLogic;
use App\Classes\Exceptions\AccessForbiddenException;
use App\Classes\General\Abstracts\AbstractControllerLogic;
use App\Classes\Modules\Accounts\Processors\AuthenticationProcessor;
use App\Classes\Modules\Accounts\Processors\CreateUserProcessor;
use App\Classes\Modules\Companies\Processors\AssignEmployeeProcessor;
use App\Classes\Modules\Companies\DataTransferObjects\EmploymentObject;
use App\Classes\Modules\Companies\Services\FetchesCompany;
use App\Classes\Modules\Contacts\DataTransferObjects\ContactObject;
use App\Classes\Modules\Contacts\Processors\CreateContactProcessor;
use App\Classes\ValueObjects\Constants\ApprovalStatus;
use App\Classes\ValueObjects\Constants\RoleTypes;
use App\Models\Company;
use App\Models\CompanyModule;
use App\Models\User;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\App;
class CreateInvitedCustomerLogic extends AbstractControllerLogic
{
/**
* @return array
*/
protected function notification(): array
{
return [
'title' => 'Created User',
'message' => 'You have successfully created a new User'
];
}
/** @var CreateUserProcessor */
private $createUserProcessor;
/** @var CreateContactProcessor */
private $createContactProcessor;
/** @var FetchesCompany */
private $fetchesCompany;
/** @var AssignEmployeeProcessor */
private $assignEmployeeProcessor;
/** @var AuthenticationProcessor */
private $authenticationProcessor;
/**
* CreateInvitedCustomerLogic constructor.
* @param CreateUserProcessor $createUserProcessor
* @param CreateContactProcessor $createContactProcessor
* @param FetchesCompany $fetchesCompany
* @param AssignEmployeeProcessor $assignEmployeeProcessor
* @param AuthenticationProcessor $authenticationProcessor
*/
public function __construct(CreateUserProcessor $createUserProcessor, CreateContactProcessor $createContactProcessor, FetchesCompany $fetchesCompany, AssignEmployeeProcessor $assignEmployeeProcessor, AuthenticationProcessor $authenticationProcessor)
{
$this->createUserProcessor = $createUserProcessor;
$this->createContactProcessor = $createContactProcessor;
$this->fetchesCompany = $fetchesCompany;
$this->assignEmployeeProcessor = $assignEmployeeProcessor;
$this->authenticationProcessor = $authenticationProcessor;
}
/**
* @param Request $request
* @return JsonResponse
* @throws \App\Classes\Exceptions\AccessForbiddenException
* @throws \App\Classes\Exceptions\AccessUnauthorisedException
* @throws \App\Classes\Exceptions\MalformedRequestException
* @throws \App\Classes\Exceptions\RequestValidationException
*/
public function logic(Request $request): JsonResponse
{
/** @var Company $company */
$company = $this->fetchesCompany->execute(['id' => $request->input('company_id')]);
/** @var CompanyModule $companyModule */
$companyModule = $company->companyModules()->first();
if($companyModule->employees()->exists()){
throw new AccessForbiddenException('This company\'s account has been claimed by another user already!');
}
/** @var User $user */
$user = $this->createUserProcessor->execute($request, RoleTypes::USER, !App::environment(['production']) ? ApprovalStatus::APPROVED : ApprovalStatus::PENDING_VERIFICATION);
$contactObject = new ContactObject($request->input('name'), $request->input('phone'), $request->input('contact_email'), $request->input('wechat_id'));
$this->createContactProcessor->execute($contactObject, $company);
$Object = new EmploymentObject($companyModule, $user);
$this->assignEmployeeProcessor->execute($Object);
return $this->response($this->authenticationProcessor->execute($request));
}
}
@@ -37,7 +37,6 @@ class LogoutUserLogic extends AbstractControllerLogic
*/
protected function logic(Request $request): JsonResponse {
logger("logout");
$this->invalidatesAuthenticationToken->execute();
return $this->response();
@@ -3,6 +3,7 @@
namespace App\Classes\Modules\Addresses\DataTransferObjects;
use App\Classes\General\Interfaces\DataTransferObject;
use App\Classes\ValueObjects\Constants\ApprovalStatus;
class AddressObject implements DataTransferObject
{
@@ -38,7 +39,7 @@ class AddressObject implements DataTransferObject
* @param int $postCode
* @param null|string $reference
*/
public function __construct(string $streetOne, ?string $streetTwo, int $countryId, int $stateId, int $districtId, int $postCode, ?string $reference = null)
public function __construct(string $streetOne, ?string $streetTwo, int $countryId, int $stateId, int $districtId, int $postCode, ?string $reference = null, ?int $status = ApprovalStatus::APPROVED)
{
$this->streetOne = $streetOne;
$this->streetTwo = $streetTwo;
@@ -47,6 +48,7 @@ class AddressObject implements DataTransferObject
$this->districtId = $districtId;
$this->postCode = $postCode;
$this->reference = $reference;
$this->status = $status;
}
/**
@@ -105,5 +107,13 @@ class AddressObject implements DataTransferObject
return $this->reference;
}
/**
* @return int
*/
public function getStatus(): int
{
return $this->status;
}
}
@@ -7,6 +7,7 @@ use App\Classes\Modules\Addresses\Services\CleansOldAddress;
use App\Classes\Modules\Addresses\Services\CreatesAddress;
use App\Classes\Modules\Addresses\Services\FetchesAddress;
use App\Models\OldAddress;
use App\Models\Order;
use Illuminate\Database\Eloquent\Model;
class CreateAddressFromOldAddressProcessor
@@ -44,8 +45,8 @@ class CreateAddressFromOldAddressProcessor
}
if($address = $addressable->addresses()->where('street_one', $object->getStreetOne())->first()){
return $address;
if(!$addressable instanceof Order && $address = $addressable->addresses()->where('street_one', $object->getStreetOne())->first()) {
return $address;
}
return $this->createsAddress->execute($addressable, $object);
@@ -28,6 +28,7 @@ class CreatesAddress extends AbstractUpdateRelationshipRecord
$model->state_id = $object->getStateId();
$model->district_id = $object->getDistrictId();
$model->postcode = $object->getPostCode();
$model->status = $object->getStatus();
return $this->handler($addressable->addresses(), $model);
@@ -0,0 +1,44 @@
<?php
namespace App\Classes\Modules\Orders\ControllersLogic;
use App\Classes\General\Abstracts\AbstractControllerLogic;
use App\Classes\Modules\Orders\Processors\ApproveChangeOrderAddressProcessor;
use App\Http\Resources\AddressResource;
use App\Http\Resources\OrderResource;
use Illuminate\Http\Request;
use Illuminate\Http\JsonResponse;
class ApproveChangeOrderAddressLogic extends AbstractControllerLogic
{
/**
* @return array
*/
protected function notification(): array
{
return [
'title' => 'Change Order Address Approval',
'message' => 'You have successfully change the order address'
];
}
/** @var ApproveChangeOrderAddressProcessor */
private $approveChangeOrderAddressProcessor;
/**
* ApproveChangeOrderAddressLogic constructor.
* @param ApproveChangeOrderAddressProcessor $approveChangeOrderAddressProcessor
*/
public function __construct(ApproveChangeOrderAddressProcessor $approveChangeOrderAddressProcessor)
{
$this->approveChangeOrderAddressProcessor = $approveChangeOrderAddressProcessor;
}
public function logic(Request $request): JsonResponse
{
$address = $this->approveChangeOrderAddressProcessor->execute($request);
return $this->resourceResponse(new AddressResource($address));
}
}
@@ -0,0 +1,49 @@
<?php
namespace App\Classes\Modules\Orders\ControllersLogic;
use App\Classes\General\Abstracts\AbstractControllerLogic;
use App\Classes\Modules\Orders\Processors\RequestChangeOrderAddressProcessor;
use App\Http\Resources\OrderResource;
use Illuminate\Http\Request;
use Illuminate\Http\JsonResponse;
class RequestChangeOrderAddressLogic extends AbstractControllerLogic
{
/**
* @return array
*/
protected function notification(): array
{
return [
'title' => 'Request To Change Order Address',
'message' => 'You have successfully request to change order address'
];
}
/** @var RequestChangeOrderAddressProcessor */
private $requestChangeOrderAddressProcessor;
/**
* RequestChangeOrderAddressLogic constructor.
* @param RequestChangeOrderAddressProcessor $requestChangeOrderAddressProcessor
*/
public function __construct(RequestChangeOrderAddressProcessor $requestChangeOrderAddressProcessor)
{
$this->requestChangeOrderAddressProcessor = $requestChangeOrderAddressProcessor;
}
/**
* @param Request $request
* @return JsonResponse
* @throws \App\Classes\Exceptions\MalformedRequestException
*/
public function logic(Request $request): JsonResponse
{
$order = $this->requestChangeOrderAddressProcessor->execute($request);
return $this->resourceResponse(new OrderResource($order));
}
}
@@ -0,0 +1,61 @@
<?php
namespace App\Classes\Modules\Orders\Processors;
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 Illuminate\Http\Request;
class ApproveChangeOrderAddressProcessor
{
/** @var CanApproveChangeOrderAddress */
private $canApproveChangeOrderAddress;
/** @var FetchesAddress */
private $fetchesAddress;
/** @var UpdatesOrdersAddress */
private $updatesOrdersAddress;
/**
* ApproveChangeOrderAddressProcessor constructor.
* @param CanApproveChangeOrderAddress $canApproveChangeOrderAddress
* @param FetchesAddress $fetchesAddress
* @param UpdatesOrdersAddress $updatesOrdersAddress
*/
public function __construct(CanApproveChangeOrderAddress $canApproveChangeOrderAddress, FetchesAddress $fetchesAddress, UpdatesOrdersAddress $updatesOrdersAddress)
{
$this->canApproveChangeOrderAddress = $canApproveChangeOrderAddress;
$this->fetchesAddress = $fetchesAddress;
$this->updatesOrdersAddress = $updatesOrdersAddress;
}
/**
* @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)
{
$status = (int) $request->route('status');
$this->canApproveChangeOrderAddress->passes();
$address = $this->fetchesAddress->execute(['id' => $request->route('id')]);
if($status === ApprovalStatus::APPROVED){
$address->owner->addresses()->update(['status' => ApprovalStatus::EXPIRED]);
}
$this->updatesOrdersAddress->execute($address, $status);
return $address;
}
}
@@ -79,6 +79,7 @@ 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);
@@ -0,0 +1,66 @@
<?php
namespace App\Classes\Modules\Orders\Processors;
use App\Classes\Modules\Orders\Standards\Rules\CanChangeOrderAddress;
use App\Classes\Modules\Orders\Services\FetchesOrder;
use App\Classes\Modules\Addresses\Services\CreatesAddress;
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 Illuminate\Http\Request;
class RequestChangeOrderAddressProcessor
{
/** @var CanChangeOrderAddress */
private $canChangeOrderAddress;
/** @var FetchesOrder */
private $fetchesOrder;
/** @var FetchesAddress */
private $fetchesAddress;
/** @var CreatesAddress */
private $createsAddress;
/** @var DeletesAddress */
private $deletesAddress;
/**
* ChangeOrderAddressProcessor constructor.
* @param FetchesOrder $fetchesOrder
* @param CreatesAddress $createsAddress
* @param FetchesAddress $fetchesAddress
* @param DeletesAddress $deletesAddress
*/
public function __construct(CanChangeOrderAddress $canChangeOrderAddress, FetchesOrder $fetchesOrder, CreatesAddress $createsAddress, FetchesAddress $fetchesAddress, DeletesAddress $deletesAddress)
{
$this->canChangeOrderAddress = $canChangeOrderAddress;
$this->fetchesOrder = $fetchesOrder;
$this->createsAddress = $createsAddress;
$this->fetchesAddress = $fetchesAddress;
$this->deletesAddress = $deletesAddress;
}
public function execute(Request $request)
{
$this->canChangeOrderAddress->passes();
$order = $this->fetchesOrder->execute(['id' => $request->get('order_id')]);
foreach ($order->addressesPendingVerification as $address) {
$this->deletesAddress->execute($address);
}
$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);
return $order;
}
}
@@ -68,7 +68,7 @@ class FetchesDataFromVTPortal
$latest_cookie = [];
$cookieRequest = new \GuzzleHttp\Client(['cookies' => true]);
$cookieRequest->get('https://portalvt.azurewebsites.net');
$cookieRequest->get('http://portal.vtnation.com.my');
foreach ($cookieRequest->getConfig('cookies')->toArray() as $key => $row) {
$latest_cookie[] = $row['Name'] . '=' . $row['Value'];
}
@@ -77,7 +77,7 @@ class FetchesDataFromVTPortal
/** @var $loginRequest */
$loginRequest = $this->clientRequest('https://portalvt.azurewebsites.net/Services/DataControllerService.asmx/Login', 'POST', [
$loginRequest = $this->clientRequest('http://portal.vtnation.com.my/Services/DataControllerService.asmx/Login', 'POST', [
"username" => "CIEF",
"password" => "0122120880",
"createPersistentCookie" => true,
@@ -0,0 +1,21 @@
<?php
namespace App\Classes\Modules\Orders\Services;
use App\Classes\General\Eloquent\AbstractUpdateRecord;
use App\Models\Address;
class UpdatesOrdersAddress extends AbstractUpdateRecord
{
/**
* @param Address $address
* @param int $type
* @return \Illuminate\Database\Eloquent\Model
* @throws \App\Classes\Exceptions\MalformedRequestException
*/
public function execute(Address $address, int $type)
{
$address->status = $type;
return $this->handler($address);
}
}
@@ -0,0 +1,39 @@
<?php
namespace App\Classes\Modules\Orders\Standards\Rules;
use App\Classes\General\Abstracts\AbstractRule;
class CanApproveChangeOrderAddress extends AbstractRule
{
/**
* @return bool
*/
protected function authorized(): bool
{
// TODO Set Authorization rules
return true;
}
/**
* @param OrderObject $object
* @return bool
*/
protected function validators($object): bool
{
return true;
}
/**
* @param OrderObject $object
* @return bool
*/
protected function criteria($object): bool
{
return true;
}
}
@@ -0,0 +1,39 @@
<?php
namespace App\Classes\Modules\Orders\Standards\Rules;
use App\Classes\General\Abstracts\AbstractRule;
class CanChangeOrderAddress extends AbstractRule
{
/**
* @return bool
*/
protected function authorized(): bool
{
// TODO Set Authorization rules
return true;
}
/**
* @param OrderObject $object
* @return bool
*/
protected function validators($object): bool
{
return true;
}
/**
* @param OrderObject $object
* @return bool
*/
protected function criteria($object): bool
{
return true;
}
}
@@ -0,0 +1,67 @@
<?php
namespace App\Classes\Modules\PackingLists\ControllersLogic\Containers;
use App\Classes\General\Abstracts\AbstractControllerLogic;
use App\Classes\Modules\PackingLists\Services\Containers\FetchesContainer;
use App\Classes\Modules\PackingLists\Services\FetchesPackingList;
use App\Http\Resources\ContainerResource;
use ErrorException;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
class AssignPackingListContainerLogic extends AbstractControllerLogic
{
/**
* @return array
*/
protected function notification():array {
return [
'title' => 'Assign Packing List Container',
'message' => 'You have successfully assign Packing List to Container'
];
}
/** @var FetchesContainer */
private $fetchesContainer;
/** @var FetchesPackingList */
private $fetchesPackingList;
/**
* DeleteContainerControllersLogic constructor.
* @param FetchesContainer $fetchesContainer
* @param FetchesPackingList $fetchesPackingList
*/
public function __construct(FetchesContainer $fetchesContainer, FetchesPackingList $fetchesPackingList)
{
$this->fetchesContainer = $fetchesContainer;
$this->fetchesPackingList = $fetchesPackingList;
}
/**
* @param Request $request
* @return JsonResponse
* @throws ErrorException
*/
public function logic(Request $request) : JsonResponse
{
try {
$container = $this->fetchesContainer->execute(['id' => $request->route('id')]);
$packing_list = $request->input('packing_list_id');
foreach ($packing_list as $key => $row) {
$packing_list_item = $this->fetchesPackingList->execute(['id' => $row]);
$container->packingLists()->attach($packing_list_item);
}
return $this->resourceResponse(new ContainerResource($container));
} catch (\Exception $exception){
throw new ErrorException($exception->getMessage(), $exception->getCode());
}
}
}
@@ -4,10 +4,12 @@ namespace App\Classes\Modules\PackingLists\ControllersLogic\Containers;
use App\Classes\General\Abstracts\AbstractControllerLogic;
use App\Classes\Modules\Companies\Services\FetchesCompanyModule;
use App\Classes\Modules\PackingLists\Services\Containers\CreatesContainer;
use App\Classes\Modules\PackingLists\Standards\Rules\Containers\CanCreateContainer;
use App\Classes\Modules\PackingLists\DataTransferObjects\ContainerObject;
use App\Classes\Modules\PackingLists\Services\FetchesPackingList;
use App\Http\Resources\ContainerResource;
use ErrorException;
use Illuminate\Http\JsonResponse;
@@ -32,13 +34,17 @@ class CreateContainerLogic extends AbstractControllerLogic
/** @var FetchesPackingList */
private $fetchesPackingList;
/** @var FetchesCompanyModule */
private $fetchesCompanyModule;
/** @var CreatesPackingList */
private $createsContainer;
public function __construct(CanCreateContainer $canCreateContainer, FetchesPackingList $fetchesPackingList, CreatesContainer $createsContainer)
public function __construct(CanCreateContainer $canCreateContainer, FetchesPackingList $fetchesPackingList, FetchesCompanyModule $fetchesCompanyModule, CreatesContainer $createsContainer)
{
$this->canCreateContainer = $canCreateContainer;
$this->fetchesPackingList = $fetchesPackingList;
$this->fetchesCompanyModule = $fetchesCompanyModule;
$this->createsContainer = $createsContainer;
}
@@ -51,15 +57,21 @@ class CreateContainerLogic extends AbstractControllerLogic
*/
public function logic(Request $request) : JsonResponse
{
$object = new ContainerObject(
$request->input('container_reference'),
$request->input('container_number'),
$request->input('seal_reference'),
$request->input('container_type'),
$request->input('status')
);
$object = new ContainerObject($request->input('container_reference'), $request->input('container_type'), $request->input('seal_reference'));
$company = $this->fetchesCompanyModule->execute(['id' => 2]);
$this->canCreateContainer->passes($object);
$query = $this->createsContainer->execute($object);
$query = $this->createsContainer->execute($object, $this->fetchesCompanyModule->execute(['id' => $request->input('company_module_id')]));
return $this->resourceResponse(new ContainerResource($query));
}
}
@@ -53,7 +53,7 @@ class FetchContainerLogic extends AbstractControllerLogic
$this->canFetchContainer->passes();
$query = $this->fetchesContainer->execute(['id' => $request->route('id')]);
$query = $this->fetchesContainer->execute(['id' => $request->route('id'), 'with_packing_lists' => true]);
return $this->resourceResponse(new ContainerResource($query));
@@ -0,0 +1,66 @@
<?php
namespace App\Classes\Modules\PackingLists\ControllersLogic\Containers;
use App\Classes\General\Abstracts\AbstractControllerLogic;
use App\Classes\Modules\PackingLists\Services\Containers\ListsContainers;
use App\Classes\Modules\PackingLists\Standards\Rules\Containers\CanListContainers;
use App\Classes\Modules\PackingLists\Processors\FetchInboundCustomClearedProcessor;
use App\Http\Resources\ContainerResource;
use ErrorException;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
class InboundCustomClearedLogic extends AbstractControllerLogic
{
/**
* @return array
*/
protected function notification():array {
return [
'title' => 'Retrieved Containers',
'message' => 'You have successfully retrieved a list of Containers'
];
}
/** @var CanListContainers */
private $canListContainers;
/** @var ListsContainers */
private $listsContainers;
private $fetchInboundCustomCleared;
/**
* ListContainersLogic constructor.
* @param CanListContainers $canListContainers
* @param ListsContainers $listsContainers
*/
public function __construct(CanListContainers $canListContainers, ListsContainers $listsContainers, FetchInboundCustomClearedProcessor $fetchInboundCustomCleared)
{
$this->canListContainers = $canListContainers;
$this->listsContainers = $listsContainers;
$this->fetchInboundCustomCleared = $fetchInboundCustomCleared;
}
/**
* @param Request $request
* @return JsonResponse
* @throws ErrorException
*/
public function logic(Request $request) : JsonResponse
{
//$this->canListOrders->passes();
//$query = $this->listsOrders->execute(array_merge($this->listsOrders->deserializeFilters($request->input('filters')), ['with_parcels' => true]));
$d = $this->fetchInboundCustomCleared->execute();
return response()->json($d);
}
}
@@ -58,8 +58,14 @@ class UpdateContainerLogic extends AbstractControllerLogic
{
$container = $this->fetchesContainer->execute(['id' => $request->route('id')]);
$object = new ContainerObject( $container->packing_list_id , $request->input('container_reference'), $request->input('container_type'), $request->input('seal_reference'));
$object = new ContainerObject(
$request->input('container_reference'),
$container->container_number,
$request->input('container_type'),
$request->input('seal_reference'),
$container->status,
);
$this->canUpdateContainer->passes($object);
@@ -5,6 +5,7 @@ namespace App\Classes\Modules\PackingLists\ControllersLogic;
use App\Classes\Modules\Companies\Services\FetchesCompany;
use App\Classes\Modules\PackingLists\DataTransferObjects\PackageObject;
use App\Classes\Modules\PackingLists\Processors\CreatePackingListProcessor;
use App\Classes\Modules\Orders\Services\FetchesOrder;
use App\Classes\Modules\PackingLists\Services\Packages\FetchesPackage;
use App\Classes\ValueObjects\Constants\ApprovalStatus;
use App\Classes\General\Abstracts\AbstractControllerLogic;
@@ -13,6 +14,9 @@ use App\Classes\Modules\PackingLists\Services\CreatesPackingListPackage;
use App\Classes\Modules\PackingLists\Standards\Rules\CanCreatePackingList;
use App\Classes\Modules\PackingLists\Standards\Rules\CanCreatePackingListPackage;
use App\Classes\Modules\PackingLists\DataTransferObjects\PackingListObject;
use App\Classes\ValueObjects\Constants\OrderRoleTypes;
use App\Classes\ValueObjects\Constants\PackingListType;
use App\Http\Resources\PackingListResource;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
@@ -34,13 +38,18 @@ class CreatePackingListLogic extends AbstractControllerLogic
/** @var CreatePackingListProcessor */
private $createPackingListProcessor;
/** @var FetchesOrder */
private $fetchesOrder;
/**
* CreatePackingListLogic constructor.
* @param CreatePackingListProcessor $createPackingListProcessor
* @param FetchesOrder $fetchesOrder
*/
public function __construct(CreatePackingListProcessor $createPackingListProcessor)
public function __construct(CreatePackingListProcessor $createPackingListProcessor, FetchesOrder $fetchesOrder)
{
$this->createPackingListProcessor = $createPackingListProcessor;
$this->fetchesOrder = $fetchesOrder;
}
/**
@@ -50,11 +59,13 @@ class CreatePackingListLogic extends AbstractControllerLogic
public function logic(Request $request) : JsonResponse
{
$object = new PackingListObject($request->input('reference_number'), ApprovalStatus::PENDING_SUBMISSION);
$order = $this->fetchesOrder->execute(['reference' => $request->input('reference_number')]);
$query = $this->createPackingListProcessor->execute($object);
$packingListObject = new PackingListObject($request->input('reference_number'), $order->orderRoles()->where('role_id', '=', OrderRoleTypes::ORIGIN_WAREHOUSE)->first()->appointee->id, PackingListType::WAREHOUSE_RECEIVE_LIST, ApprovalStatus::PENDING_SUBMISSION);
return $this->resourceResponse(new PackingListResource($query));
$packingList = $this->createPackingListProcessor->execute($packingListObject, $order);
return $this->resourceResponse(new PackingListResource($packingList));
}
@@ -12,6 +12,7 @@ use App\Classes\Modules\Companies\Services\FetchesCompany;
use App\Http\Resources\PackageResource;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use App\Classes\ValueObjects\Constants\PackageType;
class CreatePackageLogic extends AbstractControllerLogic
{
@@ -61,23 +62,23 @@ class CreatePackageLogic extends AbstractControllerLogic
*/
public function logic(Request $request) : JsonResponse
{
$order = $this->fetchesOrder->execute(['id' => $request->input('order_id')]);
$object = new PackageObject(
null,
$request->input('type'),
$request->input('description'),
$request->input('width'),
$request->input('height'),
$request->input('length'),
$request->input('weight'),
0,
$request->input('quantity'),
ApprovalStatus::PENDING_VERIFICATION);
$this->canCreatePackage->passes($object);
$query = $this->createsPackage->execute($object);
$query = $this->createsPackage->execute($object, $order->packingLists()->first());
return $this->resourceResponse(new PackageResource($query));
@@ -4,8 +4,8 @@ namespace App\Classes\Modules\PackingLists\ControllersLogic\Packages;
use App\Classes\General\Abstracts\AbstractControllerLogic;
use App\Classes\Modules\Packages\Services\FetchesPackage;
use App\Classes\Modules\Packages\Standards\Rules\CanFetchPackage;
use App\Classes\Modules\PackingLists\Services\Packages\FetchesPackage;
use App\Classes\Modules\PackingLists\Standards\Rules\Packages\CanFetchPackage;
use App\Http\Resources\PackageResource;
use ErrorException;
use Illuminate\Http\JsonResponse;
@@ -4,8 +4,8 @@ namespace App\Classes\Modules\PackingLists\ControllersLogic\Packages;
use App\Classes\General\Abstracts\AbstractControllerLogic;
use App\Classes\Modules\Packages\Services\ListsPackages;
use App\Classes\Modules\Packages\Standards\Rules\CanListPackages;
use App\Classes\Modules\PackingLists\Services\Packages\ListsPackages;
use App\Classes\Modules\PackingLists\Standards\Rules\Packages\CanListPackages;
use App\Http\Resources\PackageResource;
use ErrorException;
use Illuminate\Http\JsonResponse;
@@ -0,0 +1,68 @@
<?php
namespace App\Classes\Modules\PackingLists\ControllersLogic\Packages;
use App\Classes\General\Abstracts\AbstractControllerLogic;
use App\Classes\Modules\PackingLists\Services\Packages\SwitchesPackagePackingList;
use App\Classes\Modules\PackingLists\Services\Packages\FetchesPackage;
use App\Classes\Modules\PackingLists\Services\FetchesPackingList;
use App\Classes\Modules\PackingLists\DataTransferObjects\PackageObject;
use App\Http\Resources\PackageResource;
use ErrorException;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
class SwitchPackagePackingListLogic extends AbstractControllerLogic
{
/**
* @return array
*/
protected function notification():array {
return [
'title' => 'Switched Package Packing List',
'message' => 'You have successfully switched the Package Packing List'
];
}
/** @var SwitchesPackagePackingList */
private $switchesPackagePackingList;
/** @var FetchesPackage */
private $fetchesPackage;
/** @var FetchesPackingList */
private $fetchesPackingList;
/**
* UpdatePackageLogic constructor.
* @param SwitchesPackagePackingList $switchesPackagePackingList
* @param FetchesPackage $fetchesPackage
* @param FetchesPackingList $fetchesPackingList
*/
public function __construct(SwitchesPackagePackingList $switchesPackagePackingList, FetchesPackage $fetchesPackage, FetchesPackingList $fetchesPackingList)
{
$this->switchesPackagePackingList = $switchesPackagePackingList;
$this->fetchesPackage = $fetchesPackage;
$this->fetchesPackingList = $fetchesPackingList;
}
/**
* @param Request $request
* @return JsonResponse
* @throws ErrorException
*/
public function logic(Request $request) : JsonResponse
{
$package = $this->fetchesPackage->execute(['id' => $request->route('id')]);
$packing_list = $this->fetchesPackingList->execute(['id' => $request->input('packing_list_id')]);
$query = $this->switchesPackagePackingList->execute($package, $packing_list);
return $this->resourceResponse(new PackageResource($query));
}
}
@@ -4,10 +4,10 @@ namespace App\Classes\Modules\PackingLists\ControllersLogic\Packages;
use App\Classes\General\Abstracts\AbstractControllerLogic;
use App\Classes\Modules\Packages\Services\UpdatesPackage;
use App\Classes\Modules\Packages\Services\FetchesPackage;
use App\Classes\Modules\Packages\Standards\Rules\CanUpdatePackage;
use App\Classes\Modules\Packages\DataTransferObjects\PackageObject;
use App\Classes\Modules\PackingLists\Services\Packages\UpdatesPackage;
use App\Classes\Modules\PackingLists\Services\Packages\FetchesPackage;
use App\Classes\Modules\PackingLists\Standards\Rules\Packages\CanUpdatePackage;
use App\Classes\Modules\PackingLists\DataTransferObjects\PackageObject;
use App\Http\Resources\PackageResource;
use ErrorException;
use Illuminate\Http\JsonResponse;
@@ -60,8 +60,6 @@ class UpdatePackageLogic extends AbstractControllerLogic
$package = $this->fetchesPackage->execute(['id' => $request->route('id')]);
$object = new PackageObject(
$package->order_id,
null,
$request->input('type'),
$request->input('description'),
$request->input('width'),
@@ -69,7 +67,9 @@ class UpdatePackageLogic extends AbstractControllerLogic
$request->input('length'),
$request->input('weight'),
$request->input('quantity'),
$request->input('status'));
$request->input('status'),
$package->reference
);
$this->canUpdatePackage->passes($object);
@@ -57,7 +57,7 @@ class UpdatePackingListLogic extends AbstractControllerLogic
{
$packingList = $this->fetchesPackingList->execute(['id' => $request->route('id')]);
$object = new PackingListObject($packingList->reference, $request->input('status'));
$object = new PackingListObject($packingList->reference, $packingList->claimant_id, $packingList->type, $request->input('status'));
$this->canUpdatePackingList->passes($object);
@@ -0,0 +1,62 @@
<?php
namespace App\Classes\Modules\PackingLists\ControllersLogic;
use App\Classes\General\Abstracts\AbstractControllerLogic;
use App\Classes\Modules\PackingLists\Services\UpdatesPackingList;
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\Http\Resources\PackingListResource;
use ErrorException;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
class UpdatePackingListStatusLogic extends AbstractControllerLogic
{
/**
* @return array
*/
protected function notification():array {
return [
'title' => 'Updated PackingList Status',
'message' => 'You have successfully updated the PackingList status'
];
}
/** @var FetchesPackingList */
private $fetchesPackingList;
/** @var UpdatesPackingListStatus */
private $updatesPackingListStatus;
/**
* UpdatePackingListStatusLogic constructor.
* @param FetchesPackingList $fetchesPackingList
* @param UpdatesPackingListStatus $updatesPackingListStatus
*/
public function __construct(FetchesPackingList $fetchesPackingList, UpdatesPackingListStatus $updatesPackingListStatus)
{
$this->fetchesPackingList = $fetchesPackingList;
$this->updatesPackingListStatus = $updatesPackingListStatus;
}
/**
* @param Request $request
* @return JsonResponse
* @throws \App\Classes\Exceptions\MalformedRequestException
*/
public function logic(Request $request) : JsonResponse
{
$packingList = $this->fetchesPackingList->execute(['id' => $request->route('id')]);
$query = $this->updatesPackingListStatus->execute($packingList, $request->route('status'));
return $this->resourceResponse(new PackingListResource($query));
}
}
@@ -14,7 +14,7 @@ class ContainerObject implements DataTransferObject
private $containerNumber;
/** @var string */
private $sealNumber;
private $sealReference;
/** @var int */
private $containerType;
@@ -26,15 +26,15 @@ class ContainerObject implements DataTransferObject
* ContainerObject constructor.
* @param string $reference
* @param string $containerNumber
* @param string $sealNumber
* @param string $sealReference
* @param int $containerType
* @param int $status
*/
public function __construct(string $reference, string $containerNumber, string $sealNumber, int $containerType, int $status)
public function __construct(string $reference, string $containerNumber, string $sealReference, int $containerType, int $status)
{
$this->reference = $reference;
$this->containerNumber = $containerNumber;
$this->sealNumber = $sealNumber;
$this->sealReference = $sealReference;
$this->containerType = $containerType;
$this->status = $status;
}
@@ -58,9 +58,9 @@ class ContainerObject implements DataTransferObject
/**
* @return string
*/
public function getSealNumber(): string
public function getSealReference(): string
{
return $this->sealNumber;
return $this->sealReference;
}
/**
@@ -65,7 +65,6 @@ class FetchContainersStatusUpdateFromVTPortalProcessor
/**
* @return array
* @throws \App\Classes\Exceptions\MalformedRequestException
*/
public function execute(){
@@ -77,7 +76,7 @@ class FetchContainersStatusUpdateFromVTPortalProcessor
try {
$filter = '["RefNo:=%js%\"'.$container->reference.'\"\u0000"]';
$containerDetailsRequest = $this->fetchesDataFRomVTPortal->clientRequest('https://portalvt.azurewebsites.net/Services/DataControllerService.asmx/GetPage', 'POST', json_decode('{"controller":"VCustomercontainer","view":"grid1","request":{"PageIndex":-1,"PageSize":10000,"SortExpression":"ModifiedOn DESC","Filter":'.$filter.'}}'), '');
$containerDetailsRequest = $this->fetchesDataFRomVTPortal->clientRequest('http://portal.vtnation.com.my/Services/DataControllerService.asmx/GetPage', 'POST', json_decode('{"controller":"VCustomercontainer","view":"grid1","request":{"PageIndex":-1,"PageSize":10000,"SortExpression":"CreatedOn asc","Filter":'.$filter.'}}'), '');
$containerDetails = $this->fetchesDataFRomVTPortal->getResponseBody($containerDetailsRequest);
@@ -89,6 +88,8 @@ class FetchContainersStatusUpdateFromVTPortalProcessor
$eta = Carbon::parse($eta);
$etd = Carbon::parse($eta)->subDays(5);
$delayDate = $containerDetails[6];
$containerStatus = $containerDetails[9];
@@ -98,31 +99,37 @@ class FetchContainersStatusUpdateFromVTPortalProcessor
$transport = $container->transports()->first();
if(!$transport){
$transportObject = new TransportObject(TransportType::SEA, null, null, $eta, null, ApprovalStatus::APPROVED);
$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($eta->subDays(5), $eta, ApprovalStatus::APPROVED));
$this->createsSchedule->execute($transport, new ScheduleObject($etd, $eta, ApprovalStatus::APPROVED));
}
if($delayDate){
$delayDate = Carbon::parse($delayDate);
$transport = $container->transports()->first();
$schedule = $transport->schedules()->where('eta', '=', $delayDate)->first();
$etd = $delayDate->subDays(5);
if(!$schedule){
$etd = $schedule->etd;
if(!$transport->schedules()->where('eta', '=', $delayDate)->first()) {
$etd = $transport->schedules()->where('status', '=', ApprovalStatus::APPROVED)->first()->etd;
$transport->schedules()->update(['status' => ApprovalStatus::EXPIRED]);
$this->createsSchedule->execute($transport, new ScheduleObject($etd, $delayDate, ApprovalStatus::APPROVED));
}
$this->createsSchedule->execute($transport, new ScheduleObject($etd, $delayDate, ApprovalStatus::APPROVED));
}
if($containerStatus === 'Unstuffing'){
$container->update(['status' => ApprovalStatus::COMPLETED]);
$container->transports()->first()->update(['drop_date' => Carbon::parse($unstuffingDate)->subDay(), 'status' => ApprovalStatus::COMPLETED]);
$container->packingLists()->update(['status' => ApprovalStatus::APPROVED]);
/** @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);
@@ -3,8 +3,6 @@
namespace App\Classes\Modules\PackingLists\Processors;
use App\Classes\Modules\Orders\Services\FetchesDataFromVTPortal;
use App\Classes\Modules\PackingLists\DataTransferObjects\PackageObject;
use App\Classes\Modules\PackingLists\Services\ListsPackingLists;
use App\Classes\Modules\Schedules\DataTransferObjects\ScheduleObject;
use App\Classes\Modules\Schedules\Services\CreatesSchedule;
use App\Classes\Modules\Transports\DataTransferObjects\TransportObject;
@@ -12,7 +10,6 @@ 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\PackageType;
use App\Classes\ValueObjects\Constants\PackingListType;
use App\Classes\ValueObjects\Constants\TransportType;
use App\Models\PackingList;
@@ -58,36 +55,37 @@ class FetchDeliveryListFromVTPortalProcessor
public function execute(){
try {
$packingLists = PackingList::where('type', '=', PackingListType::SHIPPING_PACKING_LIST)->where('status', '=', ApprovalStatus::APPROVED)->get();
$packingLists = PackingList::where('type', '=', PackingListType::SHIPPING_PACKING_LIST)->whereIn('status', [ApprovalStatus::APPROVED, ApprovalStatus::SUSPENDED])->get();
/** @var PackingList $packingList */
foreach($packingLists as $packingList){
try {
$filter = '["PoNumber:=%js%\"'.$packingList->reference.'\"\u0000"]';
$shippingPackingListsRequest = $this->fetchesDataFRomVTPortal->clientRequest('https://portalvt.azurewebsites.net/Services/DataControllerService.asmx/GetPage', 'POST', json_decode('{"controller":"VPodetailparcel","view":"grid1","request":{"PageIndex":-1,"PageSize":10000,"SortExpression":"ModifiedOn DESC","Filter":'.$filter.'}}'), '');
$shippingPackingListsRequest = $this->fetchesDataFRomVTPortal->clientRequest('http://portal.vtnation.com.my/Services/DataControllerService.asmx/GetPage', 'POST', json_decode('{"controller":"VPodetailparcel","view":"grid1","request":{"PageIndex":-1,"PageSize":10000,"SortExpression":"CreatedOn asc","Filter":'.$filter.'}}'), '');
$shippingPackingLists = $this->fetchesDataFRomVTPortal->getResponseBody($shippingPackingListsRequest);
foreach($shippingPackingLists->Rows as $shippingPackingList){
if(!$shippingPackingList[9] && !$shippingPackingList[10]) {
continue;
}
$deliveryDate = Carbon::parse($shippingPackingList[9] ? $shippingPackingList[9]:$shippingPackingList[10]);
$transportObject = new TransportObject(TransportType::LAND, null, null, $deliveryDate, $deliveryDate, ApprovalStatus::APPROVED);
/** @var Transport $transport */
$transport = $this->createsTransport->execute($transportObject, $packingList);
$this->createsSchedule->execute($transport, new ScheduleObject($deliveryDate, $deliveryDate, ApprovalStatus::APPROVED));
$deliveryStep = $packingList->steps()->where('reference', '=', 'LAST_MILE_DELIVERY')->first();
$signature = $packingList->owner->orderRoles()->where('role_id', '=', OrderRoleTypes::SUPERVISOR)->first()->appointee->entity_sigiture;
$this->updatesContractObligations->execute($signature, $deliveryStep->obligation_hash_id);
$deliveryStep->update(['status' => ApprovalStatus::COMPLETED]);
$shippingPackingList = $shippingPackingLists->Rows[0];
if(!$shippingPackingList[9] && !$shippingPackingList[10]) {
continue;
}
$packingList->status = ApprovalStatus::COMPLETED;
$packingList->save();
$deliveryDate = Carbon::parse($shippingPackingList[9] ? $shippingPackingList[9]:$shippingPackingList[10]);
$transportObject = new TransportObject(TransportType::LAND, null, null, $deliveryDate, $deliveryDate, ApprovalStatus::APPROVED);
/** @var Transport $transport */
$transport = $this->createsTransport->execute($transportObject, $packingList);
$this->createsSchedule->execute($transport, new ScheduleObject($deliveryDate, $deliveryDate, ApprovalStatus::APPROVED));
$deliveryStep = $packingList->steps()->where('reference', '=', 'LAST_MILE_DELIVERY')->first();
$signature = $packingList->owner->orderRoles()->where('role_id', '=', OrderRoleTypes::SUPERVISOR)->first()->appointee->entity_sigiture;
$this->updatesContractObligations->execute($signature, $deliveryStep->obligation_hash_id);
$deliveryStep->update(['status' => ApprovalStatus::COMPLETED]);
} catch (GuzzleException $exception) {
continue;
}
@@ -0,0 +1,105 @@
<?php
namespace App\Classes\Modules\PackingLists\Processors;
use App\Classes\Modules\Orders\Services\FetchesDataFromVTPortal;
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 App\Models\Container;
use Carbon\Carbon;
use GuzzleHttp\Exception\GuzzleException;
use Illuminate\Support\Facades\Log;
class FetchInboundCustomClearedProcessor
{
/** @var FetchesDataFromVTPortal */
private $fetchesDataFRomVTPortal;
/** @var CreatesTransport */
private $createsTransport;
/** @var CreatesSchedule */
private $createsSchedule;
/** @var UpdatesContractObligation */
private $updatesContractObligations;
/**
* FetchDeliveryListFromVTPortalProcessor constructor.
* @param FetchesDataFromVTPortal $fetchesDataFRomVTPortal
* @param CreatesTransport $createsTransport
* @param CreatesSchedule $createsSchedule
* @param UpdatesContractObligation $updatesContractObligations
*/
public function __construct(FetchesDataFromVTPortal $fetchesDataFRomVTPortal, CreatesTransport $createsTransport, CreatesSchedule $createsSchedule, UpdatesContractObligation $updatesContractObligations)
{
$this->fetchesDataFRomVTPortal = $fetchesDataFRomVTPortal;
$this->createsTransport = $createsTransport;
$this->createsSchedule = $createsSchedule;
$this->updatesContractObligations = $updatesContractObligations;
}
/**
* @return array
*/
public function execute(){
$packingLists = PackingList::query()->with(['steps' => function ($query) {
$query->where('steps.status', '<>', 3);
}])->first();
dd($packingLists);
/*
$packingLists = PackingList::where('type', '=', PackingListType::SHIPPING_PACKING_LIST)
->whereIn('status', [ApprovalStatus::APPROVED, ApprovalStatus::SUSPENDED])->get();
foreach($packingLists as $packingList){
try {
$filter = '["PoNumber:=%js%\"'.$packingList->reference.'\"\u0000"]';
$shippingPackingListsRequest = $this->fetchesDataFRomVTPortal->clientRequest('https://portalvt.azurewebsites.net/Services/DataControllerService.asmx/GetPage', 'POST', json_decode('{"controller":"VPodetailparcel","view":"grid1","request":{"PageIndex":-1,"PageSize":10000,"SortExpression":"CreatedOn asc","Filter":'.$filter.'}}'), '');
$shippingPackingLists = $this->fetchesDataFRomVTPortal->getResponseBody($shippingPackingListsRequest);
$shippingPackingList = $shippingPackingLists->Rows[0];
if(!$shippingPackingList[9] && !$shippingPackingList[10]) {
continue;
}
$packingList->status = ApprovalStatus::COMPLETED;
$packingList->save();
$deliveryDate = Carbon::parse($shippingPackingList[9] ? $shippingPackingList[9]:$shippingPackingList[10]);
$transportObject = new TransportObject(TransportType::LAND, null, null, $deliveryDate, $deliveryDate, ApprovalStatus::APPROVED);
$transport = $this->createsTransport->execute($transportObject, $packingList);
$this->createsSchedule->execute($transport, new ScheduleObject($deliveryDate, $deliveryDate, ApprovalStatus::APPROVED));
$deliveryStep = $packingList->steps()->where('reference', '=', 'LAST_MILE_DELIVERY')->first();
$signature = $packingList->owner->orderRoles()->where('role_id', '=', OrderRoleTypes::SUPERVISOR)->first()->appointee->entity_sigiture;
$this->updatesContractObligations->execute($signature, $deliveryStep->obligation_hash_id);
$deliveryStep->update(['status' => ApprovalStatus::COMPLETED]);
} catch (GuzzleException $exception) {
continue;
}
}*/
return [];
}
}
@@ -137,14 +137,14 @@ class FetchLoadedContainersFromVTPortalProcessor
$end = $end ? $end : Carbon::now();
$filter = '["LoadedTime:$between$%js%\"'.$start->format('Y-m-d').'T00:00:00.000\"$and$%js%\"'.$end->format('Y-m-d').'T00:00:00.000\"\u0000"]';
$containersRequest = $this->fetchesDataFRomVTPortal->clientRequest('https://portalvt.azurewebsites.net/Services/DataControllerService.asmx/GetPage', 'POST', json_decode('{"controller":"VCustomercontainer","view":"grid1","request":{"PageIndex":-1,"PageSize":10000,"SortExpression":"ModifiedOn DESC","Filter":'.$filter.'}}'), '');
$containersRequest = $this->fetchesDataFRomVTPortal->clientRequest('http://portal.vtnation.com.my/Services/DataControllerService.asmx/GetPage', 'POST', json_decode('{"controller":"VCustomercontainer","view":"grid1","request":{"PageIndex":-1,"PageSize":10000,"SortExpression":"LoadedTime asc","Filter":'.$filter.'}}'), '');
$containers = $this->fetchesDataFRomVTPortal->getResponseBody($containersRequest);
foreach ($containers->Rows as $container){
$filter = '["ContainerID:=%js%'.$container[11].'"]';
$containerDetailRequest = $this->fetchesDataFRomVTPortal->clientRequest('https://portalvt.azurewebsites.net/Services/DataControllerService.asmx/GetPage', 'POST', json_decode('{"controller":"VPodetailparcel","view":"grid1","request":{"PageIndex":-1,"PageSize":10000,"SortExpression":"ModifiedOn DESC","Filter":'.$filter.'}}'), '');
$containerDetailRequest = $this->fetchesDataFRomVTPortal->clientRequest('http://portal.vtnation.com.my/Services/DataControllerService.asmx/GetPage', 'POST', json_decode('{"controller":"VPodetailparcel","view":"grid1","request":{"PageIndex":-1,"PageSize":10000,"SortExpression":"CreatedOn asc","Filter":'.$filter.'}}'), '');
$containerDetail = $this->fetchesDataFRomVTPortal->getResponseBody($containerDetailRequest);
@@ -199,7 +199,10 @@ class FetchLoadedContainersFromVTPortalProcessor
$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::PENDING_VERIFICATION, $contractReference);
$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);
/** @var PackingList $packingList */
$packingList = $this->createPackingListProcessor->execute($packingListObject, $order);
@@ -46,7 +46,9 @@ class FetchPackingListFromVTPortalProcessor
*/
public function execute(){
$packingLists = PackingList::where('type', '=', PackingListType::SHIPPING_PACKING_LIST)->where('status', '=', ApprovalStatus::PENDING_VERIFICATION)->get();
$packingLists = PackingList::where('type', '=', PackingListType::SHIPPING_PACKING_LIST)->whereIn('status', [ApprovalStatus::PENDING_VERIFICATION, ApprovalStatus::SUSPENDED])->whereDoesntHave('containers', function($query){
$query->where('status', '=', ApprovalStatus::COMPLETED);
})->get();
foreach($packingLists as $packingList){
@@ -55,7 +57,7 @@ class FetchPackingListFromVTPortalProcessor
$filter = '["PoNumber:=%js%\"'.$packingList->reference.'\"\u0000"]';
$shippingPackingListsRequest = $this->fetchesDataFRomVTPortal->clientRequest('https://portalvt.azurewebsites.net/Services/DataControllerService.asmx/GetPage', 'POST', json_decode('{"controller":"VPodetailparcel","view":"grid1","request":{"PageIndex":-1,"PageSize":10000,"SortExpression":"ModifiedOn DESC","Filter":'.$filter.'}}'), '');
$shippingPackingListsRequest = $this->fetchesDataFRomVTPortal->clientRequest('http://portal.vtnation.com.my/Services/DataControllerService.asmx/GetPage', 'POST', json_decode('{"controller":"VPodetailparcel","view":"grid1","request":{"PageIndex":-1,"PageSize":10000,"SortExpression":"CreatedOn asc","Filter":'.$filter.'}}'), '');
$shippingPackingLists = $this->fetchesDataFRomVTPortal->getResponseBody($shippingPackingListsRequest);
@@ -0,0 +1,64 @@
<?php
namespace App\Classes\Modules\PackingLists\Processors;
use App\Classes\Modules\Orders\Services\FetchesDataFromVTPortal;
use App\Classes\Modules\PackingLists\DataTransferObjects\PackageObject;
use App\Classes\Modules\PackingLists\Services\ListsPackingLists;
use App\Classes\ValueObjects\Constants\ApprovalStatus;
use App\Classes\ValueObjects\Constants\PackageType;
use App\Classes\ValueObjects\Constants\PackingListType;
use App\Models\PackingList;
use GuzzleHttp\Exception\GuzzleException;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
class FetchPackingListProcessor
{
/** @var ListsPackingLists */
private $listsPackingLists;
/**
* FetchPackingListFromVTPortalProcessor constructor.
* @param ListsPackingLists $listsPackingLists
*/
public function __construct(ListsPackingLists $listsPackingLists)
{
$this->listsPackingLists = $listsPackingLists;
}
/**
* @return array
* @throws \App\Classes\Exceptions\AccessForbiddenException
* @throws \App\Classes\Exceptions\RequestValidationException
*/
public function execute($params){
$packingLists = PackingList::where('type', '=', PackingListType::SHIPPING_PACKING_LIST)
->whereIn('status', [ApprovalStatus::PENDING_VERIFICATION, ApprovalStatus::SUSPENDED])
->whereDoesntHave('containers', function($query){
$query->where('status', '=', ApprovalStatus::COMPLETED);
})->orderBy('created_at','desc')->where('owner_id',$params['orderId'])->get();
//dd($packingLists);
$packingListsArray=[];
foreach($packingLists as $packingList){
$address = $packingList->owner->addresses()->first();
$packingList->fulladdress = $address->street_one.', '.$address->street_two.', '.$address->district->name.', '.$address->post_code.' '.$address->state->name.', '.$address->country->name;
$container = $packingList->containers()->first();
$packingList->container_reference = $container->reference;
$packingList->container_number = $container->container_number;
$packingListsArray[]=$packingList;
}
return $packingListsArray;
}
}
@@ -125,13 +125,15 @@ class FetchWarehouseReceiveListFromVTPortalProcessor
}
$end = $end ? $end : Carbon::now();
$filter = '["ParcelDate:$between$%js%\"'.$start->format('Y-m-d').'T00:00:00.000\"$and$%js%\"'.$end->format('Y-m-d').'T00:00:00.000\"\u0000"]';
$warehouseListRequest = $this->fetchesDataFRomVTPortal->clientRequest('https://portalvt.azurewebsites.net/Services/DataControllerService.asmx/GetPage', 'POST', json_decode('{"controller":"WarehouseList","view":"grid1","request":{"PageIndex":-1,"PageSize":10000,"SortExpression":"ModifiedOn DESC","Filter":'.$filter.'}}'), '');
$warehouseListRequest = $this->fetchesDataFRomVTPortal->clientRequest('http://portal.vtnation.com.my/Services/DataControllerService.asmx/GetPage', 'POST', json_decode('{"controller":"WarehouseList","view":"grid1","request":{"PageIndex":-1,"PageSize":10000,"SortExpression":"ParcelDate asc","Filter":'.$filter.'}}'), '');
$response = $this->fetchesDataFRomVTPortal->getResponseBody($warehouseListRequest);
foreach ($response->Rows as $parcel){
$marking = explode('/', explode('CIEF/', $parcel[5])[1]);
if(!array_key_exists(1, $marking)){
@@ -144,6 +146,7 @@ class FetchWarehouseReceiveListFromVTPortalProcessor
continue;
}
try {
$order = $this->fetchesOrder->execute(['reference' => $orderNumber]);
} catch (ResourceNotFoundException $exception) {
@@ -154,13 +157,16 @@ class FetchWarehouseReceiveListFromVTPortalProcessor
continue;
}
$customerMarking = str_replace(' ', '', str_replace('/', '', str_replace('CIEF/', '', $oldOrder->company->marking)));
$customerMarking = str_replace('/', '', str_replace(' ', '', explode('CIEF/', $oldOrder->company->marking)[1]));
$companyModule = CompanyModule::whereHas('inviters', function($query) use ($customerMarking) {
return $query->where('invitee_reference', '=', $customerMarking);
})->first();
if(!$companyModule) {
if(!$companyModule){
log::error('unknown customer: '.$customerMarking);
continue;
}
@@ -180,6 +186,10 @@ class FetchWarehouseReceiveListFromVTPortalProcessor
$originWarehouse = $this->fetchesCompanyModule->execute(['id' => $warehouseId === 11 ? 3 : 4]);
$order = $this->createOrderProcessor->execute($companyModule->company, $originWarehouse, $address, $orderNumber);
$order->created_at = Carbon::parse($parcel[1]);
$order->save();
}
$packingListReference = $parcel[17];
@@ -217,13 +227,13 @@ class FetchWarehouseReceiveListFromVTPortalProcessor
}
return [];
} catch (\Exception $exception){
Log::error($exception->getMessage());
}
DB::commit();
return [];
}
@@ -22,7 +22,7 @@ class CreatesContainer extends AbstractUpdateRelationshipRecord
$model->reference = $object->getReference();
$model->container_number = $object->getContainerNumber();
$model->container_type = $object->getContainerType();
$model->seal_reference = $object->getSealNumber();
$model->seal_reference = $object->getSealReference();
$model->status = $object->getStatus();
return $this->handler($owner->containers(), $model);
@@ -17,7 +17,7 @@ class UpdatesContainer extends AbstractUpdateRecord
*/
public function execute(Container $model, ContainerObject $object) {
$model->container_reference = $object->getContainerReference();
$model->reference = $object->getReference();
$model->container_type = $object->getContainerType();
$model->seal_reference = $object->getSealReference();
@@ -0,0 +1,25 @@
<?php
namespace App\Classes\Modules\PackingLists\Services\Packages;
use App\Classes\General\Eloquent\AbstractUpdateRecord;
use App\Models\Package;
use App\Models\PackingList;
class SwitchesPackagePackingList extends AbstractUpdateRecord
{
/**
* @param Package $model
* @param int $status
* @return \Illuminate\Database\Eloquent\Model
* @throws \App\Classes\Exceptions\MalformedRequestException
*/
public function execute(Package $model, PackingList $packing_list) {
$model->packing_list_id = $packing_list->id;
return $this->handler($model);
}
}
@@ -10,7 +10,6 @@ class UpdatesPackage extends AbstractUpdateRecord
{
public function execute(Package $model, PackageObject $object) {
$model->claimant_id = $object->getClaimantId();
$model->type = $object->getType();
$model->description = $object->getDescription();
$model->width = $object->getWidth();
@@ -0,0 +1,24 @@
<?php
namespace App\Classes\Modules\PackingLists\Services;
use App\Classes\General\Eloquent\AbstractUpdateRecord;
use App\Models\PackingList;
class UpdatesPackingListStatus extends AbstractUpdateRecord
{
/**
* @param PackingList $model
* @param int $status
* @return \Illuminate\Database\Eloquent\Model
* @throws \App\Classes\Exceptions\MalformedRequestException
*/
public function execute(PackingList $model, int $status) {
$model->status = $status;
return $this->handler($model);
}
}
@@ -0,0 +1,39 @@
<?php
namespace App\Classes\Modules\Reports\ControllersLogic;
use App\Classes\General\Abstracts\AbstractControllerLogic;
use App\Models\User;
use Maatwebsite\Excel\Concerns\FromCollection;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use App\Classes\Modules\Reports\ControllersLogic\ExportExcelLogic;
use App\Classes\Modules\PackingLists\Processors\FetchPackingListProcessor;
class CustomcClearanceLogic extends AbstractControllerLogic
{
private $excelExportLogic;
private $listsPackingListProcessor;
public function __construct(FetchPackingListProcessor $listsPackingListProcessor){
$this->listsPackingListProcessor = $listsPackingListProcessor;
}
protected function notification():array {
return [];
}
public function logic(Request $request) : JsonResponse
{
$params = $request->all();
$packingLists = $this->listsPackingListProcessor->execute($params);
$excelExportLogic = new ExportExcelLogic(collect($packingLists));
$this->excelExportLogic = $excelExportLogic;
return response()->json(['success' => true]);
}
public function getExcelCollection(){
return $this->excelExportLogic;
}
}
@@ -0,0 +1,50 @@
<?php
namespace App\Classes\Modules\Reports\ControllersLogic;
use Maatwebsite\Excel\Concerns\FromCollection;
use PhpOffice\PhpSpreadsheet\Shared\Date;
use PhpOffice\PhpSpreadsheet\Style\NumberFormat;
use Maatwebsite\Excel\Concerns\WithColumnFormatting;
use Maatwebsite\Excel\Concerns\WithMapping;
use Maatwebsite\Excel\Concerns\WithHeadings;
use Maatwebsite\Excel\Concerns\ShouldAutoSize;
class ExportExcelLogic implements FromCollection, ShouldAutoSize, WithHeadings, WithColumnFormatting, WithMapping
{
private $data;
public function __construct($data)
{
$this->data=$data;
}
public function collection()
{
return $this->data;
}
public function map($order): array
{
return [
(string)$order->reference,
(string)$order->container_number,
(string)$order->fulladdress,
(string)$order->created_at,
"ssxxx"
];
}
public function columnFormats(): array
{
return [
'A'=>'@',
'B' => NumberFormat::FORMAT_DATE_DDMMYYYY,
];
}
public function headings(): array
{
return ["Reference", "Container", "Address", "Created", "Status"];
}
}
@@ -56,7 +56,7 @@ class CreateScheduleLogic extends AbstractControllerLogic
*/
public function logic(Request $request) : JsonResponse
{
$object = new ScheduleObject($request->input('etd'), $request->input('eta'), $request->input('transport_id'), ApprovalStatus::PENDING_SUBMISSION);
$object = new ScheduleObject($request->input('etd'), $request->input('eta'), ApprovalStatus::PENDING_SUBMISSION);
$this->canCreateSchedule->passes($object);
@@ -16,7 +16,6 @@ class ScheduleValidation extends AbstractValidation
*/
protected function data($object): array {
return [
'transport_id' => $object->getTransportId(),
'etd' => $object->getETD(),
'eta' => $object->getETA(),
'status' => $object->getStatus(),
@@ -28,7 +27,6 @@ class ScheduleValidation extends AbstractValidation
*/
protected function rules(): array {
return [
'transport_id' => 'required',
'etd' => 'required',
'eta' => 'required',
];
@@ -7,7 +7,7 @@ use App\Classes\General\Abstracts\AbstractControllerLogic;
use App\Classes\Modules\Transports\Services\CreatesTransport;
use App\Classes\Modules\Transports\Standards\Rules\CanCreateTransport;
use App\Classes\Modules\Transports\DataTransferObjects\TransportObject;
use App\Classes\Modules\PackingLists\Services\Containers\FetchesContainer;
use App\Classes\Modules\PackingLists\Services\FetchesPackingList;
use App\Http\Resources\TransportResource;
use ErrorException;
use Illuminate\Http\JsonResponse;
@@ -29,8 +29,8 @@ class CreateTransportLogic extends AbstractControllerLogic
/** @var CanCreateTransport */
private $canCreateTransport;
/** @var FetchesContainer */
private $fetchesContainer;
/** @var FetchesPackingList */
private $fetchesPackingList;
/** @var CreatesTransport */
private $createsTransport;
@@ -38,13 +38,13 @@ class CreateTransportLogic extends AbstractControllerLogic
/**
* CreateTransportLogic constructor.
* @param CanCreateTransport $canCreateTransport
* @param FetchesContainer $fetchesContainer
* @param FetchesPackingList $fetchesPackingList
* @param CreatesTransport $createsTransport
*/
public function __construct(CanCreateTransport $canCreateTransport, FetchesContainer $fetchesContainer, CreatesTransport $createsTransport)
public function __construct(CanCreateTransport $canCreateTransport, FetchesPackingList $fetchesPackingList, CreatesTransport $createsTransport)
{
$this->canCreateTransport = $canCreateTransport;
$this->fetchesContainer = $fetchesContainer;
$this->fetchesPackingList = $fetchesPackingList;
$this->createsTransport = $createsTransport;
}
@@ -58,11 +58,18 @@ class CreateTransportLogic extends AbstractControllerLogic
public function logic(Request $request) : JsonResponse
{
$object = new TransportObject($request->input('type'), $request->input('courier'), $request->input('tracking_number'), null, null, ApprovalStatus::PENDING_SUBMISSION);
$object = new TransportObject(
$request->input('type'),
$request->input('courier'),
$request->input('tracking_number'),
null,
null,
pprovalStatus::PENDING_SUBMISSION
);
$this->canCreateTransport->passes($object);
$query = $this->createsTransport->execute($this->fetchesContainer->execute(['id' => $request->input('container_id')]), $object);
$query = $this->createsTransport->execute($object, $this->fetchesPackingList->execute(['id' => $request->input('packing_list_id')]));
return $this->resourceResponse(new TransportResource($query));
@@ -58,7 +58,14 @@ class UpdateTransportLogic extends AbstractControllerLogic
{
$query = $this->fetchesTransport->execute(['id' => $request->route('id')]);
$object = new TransportObject($request->input('type'), $request->input('courier'), $request->input('tracking_number'), $request->input('dispatch_date'), $request->input('drop_date'), $request->input('status'));
$object = new TransportObject(
$request->input('type'),
$request->input('courier'),
$request->input('tracking_number'),
$request->input('dispatch_date'),
$request->input('drop_date'),
$request->input('status')
);
$this->canUpdateTransport->passes($object);
+57
View File
@@ -0,0 +1,57 @@
<?php
namespace App\Console\Commands;
use App\Models\State;
use App\Http\Helpers\General;
use Illuminate\Console\Command;
use App\Classes\Jobs\FetchContainersStatusUpdateFromVTPortalJob;
use App\Classes\Jobs\FetchDeliveryListFromVTPortalJob;
use App\Classes\Jobs\FetchLoadedContainersFromVTPortalJob;
use App\Classes\Jobs\FetchPackingListFromVTPortalJob;
use App\Classes\Jobs\FetchWarehouseReceiveListFromVTPortalJob;
class CurlVTCommand extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'command:curlVTCommand';
// 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()
{
FetchWarehouseReceiveListFromVTPortalJob::withChain([
new FetchLoadedContainersFromVTPortalJob,
new FetchPackingListFromVTPortalJob,
new FetchContainersStatusUpdateFromVTPortalJob,
new FetchDeliveryListFromVTPortalJob
])->dispatch();
}
}
+10 -8
View File
@@ -17,9 +17,7 @@ class Kernel extends ConsoleKernel
*
* @var array
*/
protected $commands = [
//
];
protected $commands = [];
/**
* Define the application's command schedule.
@@ -29,11 +27,15 @@ class Kernel extends ConsoleKernel
*/
protected function schedule(Schedule $schedule)
{
$schedule->job(FetchWarehouseReceiveListFromVTPortalJob::class)->dailyAt('21:00');
$schedule->job(FetchLoadedContainersFromVTPortalJob::class)->dailyAt('21:15');
$schedule->job(FetchPackingListFromVTPortalJob::class)->dailyAt('21:30');
$schedule->job(FetchContainersStatusUpdateFromVTPortalJob::class)->dailyAt('21:45');
$schedule->job(FetchDeliveryListFromVTPortalJob::class)->dailyAt('22:00');
$schedule->command('command:curlVTCommand')
->dailyAt('15:00')
->withoutOverlapping()
->appendOutputTo (storage_path().'/logs/curlvt.log');
$schedule->command('command:curlVTCommand')
->dailyAt('21:00')
->withoutOverlapping()
->appendOutputTo (storage_path().'/logs/curlvt.log');
}
/**
@@ -0,0 +1,20 @@
<?php
namespace App\Http\Controllers\Accounts;
use App\Classes\Modules\Accounts\ControllersLogic\CreateInvitedCustomerLogic;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
class CreateInvitedCustomerController
{
/**
* @param Request $request
* @param CreateInvitedCustomerLogic $createCustomerLogic
* @return JsonResponse
*/
public function create(Request $request, CreateInvitedCustomerLogic $createCustomerLogic): JsonResponse
{
return $createCustomerLogic->execute($request);
}
}
@@ -0,0 +1,20 @@
<?php
namespace App\Http\Controllers\Orders;
use App\Classes\Modules\Orders\ControllersLogic\ApproveChangeOrderAddressLogic;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
class ApproveChangeOrderAddressController
{
/**
* @param Request $request
* @param ApproveChangeOrderAddressLogic $logic
* @return JsonResponse
*/
public function approve(Request $request, ApproveChangeOrderAddressLogic $logic): JsonResponse
{
return $logic->execute($request);
}
}
@@ -0,0 +1,20 @@
<?php
namespace App\Http\Controllers\Orders;
use App\Classes\Modules\Orders\ControllersLogic\RequestChangeOrderAddressLogic;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
class RequestChangeOrderAddressController
{
/**
* @param Request $request
* @param ChangeOrderAddressLogic $logic
* @return JsonResponse
*/
public function request(Request $request, RequestChangeOrderAddressLogic $logic): JsonResponse
{
return $logic->execute($request);
}
}
@@ -0,0 +1,20 @@
<?php
namespace App\Http\Controllers\PackingLists\Containers;
use App\Classes\Modules\PackingLists\ControllersLogic\Containers\AssignPackingListContainerLogic;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
class AssignPackingListContainerController
{
/**
* @param Request $request
* @param AssignPackingListContainerLogic $logic
* @return JsonResponse
*/
public function assign(Request $request, AssignPackingListContainerLogic $logic): JsonResponse {
return $logic->execute($request);
}
}
@@ -0,0 +1,20 @@
<?php
namespace App\Http\Controllers\PackingLists\Containers;
use App\Classes\Modules\PackingLists\ControllersLogic\Containers\InboundCustomClearedLogic;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
class InboundCustomClearedController
{
/**
* @param Request $request
* @param InboundCustomClearedLogic $logic
* @return JsonResponse
*/
public function list(Request $request, InboundCustomClearedLogic $logic): JsonResponse {
return $logic->execute($request);
}
}
@@ -10,7 +10,7 @@ class ListContainersController
{
/**
* @param Request $request
* @param ListContainerLogic $logic
* @param ListContainersLogic $logic
* @return JsonResponse
*/
public function list(Request $request, ListContainersLogic $logic): JsonResponse {
@@ -2,7 +2,7 @@
namespace App\Http\Controllers\PackingLists\Packages;
use App\Classes\Modules\ControllersLogic\Packages\CreatePackageLogic;
use App\Classes\Modules\PackingLists\ControllersLogic\Packages\CreatePackageLogic;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
@@ -2,7 +2,7 @@
namespace App\Http\Controllers\PackingLists\Packages;
use App\Classes\Modules\ControllersLogic\Packages\DeletePackageLogic;
use App\Classes\Modules\PackingLists\ControllersLogic\Packages\DeletePackageLogic;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
@@ -2,7 +2,7 @@
namespace App\Http\Controllers\PackingLists\Packages;
use App\Classes\Modules\ControllersLogic\Packages\FetchPackageLogic;
use App\Classes\Modules\PackingLists\ControllersLogic\Packages\FetchPackageLogic;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
@@ -2,7 +2,7 @@
namespace App\Http\Controllers\PackingLists\Packages;
use App\Classes\Modules\ControllersLogic\Packages\ListPackagesLogic;
use App\Classes\Modules\PackingLists\ControllersLogic\Packages\ListPackagesLogic;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
@@ -0,0 +1,20 @@
<?php
namespace App\Http\Controllers\PackingLists\Packages;
use App\Classes\Modules\PackingLists\ControllersLogic\Packages\SwitchPackagePackingListLogic;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
class SwitchPackagePackingListController
{
/**
* @param Request $request
* @param SwitchPackagePackingListLogic $logic
* @return JsonResponse
*/
public function switch(Request $request, SwitchPackagePackingListLogic $logic): JsonResponse {
return $logic->execute($request);
}
}
@@ -2,7 +2,7 @@
namespace App\Http\Controllers\PackingLists\Packages;
use App\Classes\Modules\ControllersLogic\Packages\UpdatePackageLogic;
use App\Classes\Modules\PackingLists\ControllersLogic\Packages\UpdatePackageLogic;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
@@ -0,0 +1,20 @@
<?php
namespace App\Http\Controllers\PackingLists;
use App\Classes\Modules\PackingLists\ControllersLogic\UpdatePackingListStatusLogic;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
class UpdatePackingListStatusController
{
/**
* @param Request $request
* @param UpdatePackingListStatusLogic $logic
* @return JsonResponse
*/
public function update(Request $request, UpdatePackingListStatusLogic $logic): JsonResponse {
return $logic->execute($request);
}
}
@@ -0,0 +1,18 @@
<?php
namespace App\Http\Controllers\Reports;
use App\Classes\Modules\Reports\ControllersLogic\CustomcClearanceLogic;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Maatwebsite\Excel\Facades\Excel;
class CustomcClearanceReportController
{
public function download(int $orderId, Request $request, CustomcClearanceLogic $customClearancelogic) {
$request->merge(['orderId' => $orderId]);
$filename = date("Y-m-d H:i:s")." - Custom cleared report ";
$customClearancelogic->logic($request);
return Excel::download( $customClearancelogic->getExcelCollection(), $filename.'.xlsx');
}
}
+13 -1
View File
@@ -2,6 +2,8 @@
namespace App\Http\Resources;
use App\Classes\ValueObjects\Constants\ApprovalStatus;
use App\Models\Order;
use Illuminate\Http\Resources\Json\JsonResource;
class AddressResource extends JsonResource
@@ -14,6 +16,7 @@ class AddressResource extends JsonResource
*/
public function toArray($request)
{
return [
'id' => $this->id,
'reference' => $this->reference,
@@ -23,7 +26,16 @@ class AddressResource extends JsonResource
'state' => $this->state,
'post_code' => $this->postcode,
'country' => $this->country,
'default' => (int) $this->default
'default' => (int) $this->default,
'status' => (int) $this->status,
$this->mergeWhen($this->relationLoaded('owner'), [
'owner' => $this->when($this->owner instanceof Order, [
'reference' => $this->owner->reference,
'company_module' => new CompanyModuleResource($this->owner->companyModule),
'address' => new AddressResource($this->owner->addresses()->where('status', '=', ApprovalStatus::APPROVED)->first())
])
])
];
}
}
+3
View File
@@ -11,6 +11,7 @@ use App\Models\CompanyModule;
use App\Models\Currency;
use App\Models\SegmentConstant;
use Illuminate\Http\Resources\Json\JsonResource;
use Illuminate\Support\Facades\Crypt;
class CompanyResource extends JsonResource
{
@@ -25,6 +26,7 @@ class CompanyResource extends JsonResource
$companyModule = $this->companyModules()->where('type', '=', BusinessType::IMPORTER)->first();
return [
'id' => $this->id,
'hash_id' => Crypt::encryptString($this->id),
'name' => $this->name,
'reference' => $this->reference,
'type' => (int) $this->type,
@@ -35,6 +37,7 @@ class CompanyResource extends JsonResource
'company_module' => new CompanyModuleResource($companyModule),
'last_order' => new OrderResource($companyModule ? $companyModule->orders()->orderBy('id', 'DESC')->first(): null),
'identification' => new DocumentResource($this->documents->whereIn('document_type', DocumentType::IDENTIFICATION_DOCUMENTS)->first()),
'created_at' => $this->created_at->format('d-m-Y')
];
+7 -2
View File
@@ -2,6 +2,7 @@
namespace App\Http\Resources;
use App\Classes\ValueObjects\Constants\ContainerTypes;
use Illuminate\Http\Resources\Json\JsonResource;
class ContainerResource extends JsonResource
@@ -17,10 +18,14 @@ class ContainerResource extends JsonResource
return [
'id' => $this->id,
'container_reference' => $this->reference,
'container_type' => $this->container_type,
'container_specification' => ContainerTypes::CONTAINER_SPECIFICATION[$this->container_type],
'container_number' => $this->container_number,
'seal_reference' => $this->seal_reference,
'transport' => TransportResource::collection($this->transports),
'transport' => new TransportResource($this->transports()->first()),
'packing_lists' => PackingListResource::collection($this->whenLoaded('packingLists', function(){
return $this->packingLists()->whereHas('packages')->get();
})),
'status' => $this->status
];
}
}
+60 -54
View File
@@ -19,65 +19,71 @@ class OrderResource extends JsonResource
*/
public function toArray($request)
{
return [
'id' => $this->id,
'reference' => $this->reference,
'reference_contract' => (int) $this->type,
'type' => (int) $this->type,
'status' => (int) $this->status,
'company_module' => new CompanyModuleResource($this->companyModule),
'warehouse' => new CompanyModuleResource($this->orderRoles()->where('role_id', '=', OrderRoleTypes::ORIGIN_WAREHOUSE)->first()->appointee),
'address' => new AddressResource($this->addresses()->first()),
$this->mergeWhen($this->relationLoaded('parcels'), [
'origin_warehouse_packages' => PackageResource::collection($this->parcels()->whereHas('packingList', function($query){
return $query->where('type', PackingListType::SHIPPING_PACKING_LIST)->whereDoesntHave('containers', function($query) {
return $query->whereHas('transports', function($query){
return $query->whereHas('schedules', function($query){
try {
return [
'id' => $this->id,
'reference' => $this->reference,
'reference_contract' => (int) $this->type,
'type' => (int) $this->type,
'status' => (int) $this->status,
'company_module' => new CompanyModuleResource($this->companyModule),
'warehouse' => new CompanyModuleResource($this->orderRoles()->where('role_id', '=', OrderRoleTypes::ORIGIN_WAREHOUSE)->first()->appointee),
'address' => new AddressResource($this->addresses()->where('status', '=', ApprovalStatus::APPROVED)->first()),
'address_change_request' => new AddressResource($this->addressesPendingVerification()->first()),
$this->mergeWhen($this->relationLoaded('parcels'), [
'origin_warehouse_packages' => PackageResource::collection($this->parcels()->whereHas('packingList', function($query){
return $query->where('type', PackingListType::SHIPPING_PACKING_LIST)->whereDoesntHave('containers', function($query) {
return $query->whereHas('transports', function($query){
return $query->whereHas('schedules', function($query){
return $query->where('etd', '<', Carbon::now());
});
});
});
})->get()),
'in_transit_packages' => PackageResource::collection($this->parcels()->whereHas('packingList', function($query){
return $query->where('type', PackingListType::SHIPPING_PACKING_LIST)->whereHas('containers', function($query) {
return $query->whereHas('transports', function($query){
return $query->where('status', '=', ApprovalStatus::APPROVED)->whereHas('schedules', function($query){
return $query->where('etd', '<', Carbon::now());
});
});
});
})->get()),
'destination_warehouse_packages' => PackageResource::collection($this->parcels()->whereHas('packingList', function($query){
return $query->where('type', PackingListType::SHIPPING_PACKING_LIST)->whereHas('containers', function($query) {
return $query->whereHas('transports', function($query){
return $query->where('type', '=', TransportType::SEA)->where('status', '=', ApprovalStatus::COMPLETED)->whereHas('schedules', function($query){
return $query->where('etd', '<', Carbon::now());
});
});
})->whereDoesntHave('transports', function($query){
return $query->where('type', '=', TransportType::LAND)->where('status', '=', ApprovalStatus::APPROVED)->whereHas('schedules', function($query){
return $query->where('etd', '<', Carbon::now());
});
});
});
})->get()),
'in_transit_packages' => PackageResource::collection($this->parcels()->whereHas('packingList', function($query){
return $query->where('type', PackingListType::SHIPPING_PACKING_LIST)->whereHas('containers', function($query) {
return $query->whereHas('transports', function($query){
return $query->where('status', '=', ApprovalStatus::APPROVED)->whereHas('schedules', function($query){
})->get()),
'delivered_packages' => PackageResource::collection($this->parcels()->whereHas('packingList', function($query){
return $query->where('type', PackingListType::SHIPPING_PACKING_LIST)->whereHas('containers', function($query) {
return $query->whereHas('transports', function($query){
return $query->where('type', '=', TransportType::SEA)->where('status', '=', ApprovalStatus::COMPLETED)->whereHas('schedules', function($query){
return $query->where('etd', '<', Carbon::now());
});
});
})->whereHas('transports', function($query){
return $query->where('type', '=', TransportType::LAND)->where('status', '=', ApprovalStatus::APPROVED)->whereHas('schedules', function($query){
return $query->where('etd', '<', Carbon::now());
});
});
});
})->get()),
'destination_warehouse_packages' => PackageResource::collection($this->parcels()->whereHas('packingList', function($query){
return $query->where('type', PackingListType::SHIPPING_PACKING_LIST)->whereHas('containers', function($query) {
return $query->whereHas('transports', function($query){
return $query->where('type', '=', TransportType::SEA)->where('status', '=', ApprovalStatus::COMPLETED)->whereHas('schedules', function($query){
return $query->where('etd', '<', Carbon::now());
});
});
})->whereDoesntHave('transports', function($query){
return $query->where('type', '=', TransportType::LAND)->where('status', '=', ApprovalStatus::APPROVED)->whereHas('schedules', function($query){
return $query->where('etd', '<', Carbon::now());
});
});
})->get()),
'delivered_packages' => PackageResource::collection($this->parcels()->whereHas('packingList', function($query){
return $query->where('type', PackingListType::SHIPPING_PACKING_LIST)->whereHas('containers', function($query) {
return $query->whereHas('transports', function($query){
return $query->where('type', '=', TransportType::SEA)->where('status', '=', ApprovalStatus::COMPLETED)->whereHas('schedules', function($query){
return $query->where('etd', '<', Carbon::now());
});
});
})->whereHas('transports', function($query){
return $query->where('type', '=', TransportType::LAND)->where('status', '=', ApprovalStatus::APPROVED)->whereHas('schedules', function($query){
return $query->where('etd', '<', Carbon::now());
});
});
})->get()),
'parcels' => PackageResource::collection($this->parcels()->whereHas('packingList', function($query){
return $query->where('type', PackingListType::WAREHOUSE_RECEIVE_LIST);
})->get()),
]),
'created_at' => $this->created_at->format('d-m-Y')
];
})->get()),
'parcels' => PackageResource::collection($this->parcels()->whereHas('packingList', function($query){
return $query->where('type', PackingListType::WAREHOUSE_RECEIVE_LIST);
})->get()),
]),
'created_at' => $this->created_at->format('d-m-Y')
];
} catch (\Exception $exception){
$this->id;
}
}
}
+1 -1
View File
@@ -23,7 +23,7 @@ class PackageResource extends JsonResource
'length' => floatval($this->length),
'weight' => $this->weight,
'quantity' => $this->quantity,
'cbm' => (($this->width / 100) * ($this->width / 100) * ($this->width / 100)) * $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->packingList->containers()->first()),
@@ -21,6 +21,7 @@ class PackingListResource extends JsonResource
'status' => $this->status,
'transport' => new TransportResource($this->transports()->first()),
'packages' => PackageResource::collection($this->packages),
'order' => New OrderResource($this->owner)
];
}
}
+1 -1
View File
@@ -24,7 +24,7 @@ class TransportResource extends JsonResource
'drop_date' => $this->drop_date ? $this->drop_date->format('d-m-Y') : $this->drop_date,
'status' => $this->status,
'current_schedule' => new ScheduleResource($this->schedules()->where('status', '=', ApprovalStatus::APPROVED)->first()),
'schedule_history' => ScheduleResource::collection($this->schedules()->where('status', '!=', ApprovalStatus::APPROVED)->get())
'schedule_history' => ScheduleResource::collection($this->schedules()->where('status', '=', ApprovalStatus::EXPIRED)->get())
];
}
}
+36
View File
@@ -0,0 +1,36 @@
<?php
namespace App\Models\Exchange;
use App\Models\AbstractModel;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
/**
* Class Company
* @package App\Models
*
* @property \App\Models\Country country_id
* @property \App\Models\State state_id
* @property \App\Models\District district_id
* @property string postcode
* @property string street_one
* @property string street_two
* @property integer billing_type
*/
class Company extends AbstractModel
{
protected $connection = 'exchange_db';
protected $table = 'companies';
/**
* @return belongsToMany
*/
public function employees(): belongsToMany
{
return $this->belongsToMany(User::class, (new Employee())->getTable(), 'company_id','user_id');
}
}
+37
View File
@@ -0,0 +1,37 @@
<?php
namespace App\Models\Exchange;
use App\Models\AbstractModel;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\Relations\HasOne;
/**
* Class CompanyEmployee
* @package App\Models
*
* @property \App\Models\Company company_id
* @property \App\Models\User user_id
*/
class Employee extends AbstractModel
{
protected $connection = 'exchange_db';
protected $table = 'employees';
/**
* @return HasMany
*/
public function company(): HasMany
{
return $this->HasMany(Company::class, 'company_id', 'id');
}
/**
* @return \Illuminate\Database\Eloquent\Relations\HasOne
**/
public function user(): HasOne
{
return $this->hasOne(User::class, 'user_id', 'id');
}
}
+19
View File
@@ -0,0 +1,19 @@
<?php
namespace App\Models\Exchange;
use App\Models\AbstractModel;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
class User extends AbstractModel {
protected $connection = 'exchange_db';
/**
* @return belongsToMany
*/
public function company(): belongsToMany
{
return $this->belongsToMany(Company::class, (new Employee())->getTable(), 'user_id', 'company_id');
}
}
+1 -1
View File
@@ -17,7 +17,7 @@ class OldOrders extends Model
*/
public function address(): hasOne
{
return $this->hasOne(OldAddress::class, 'reference_id', 'address_id')->where('type', '=', 1);
return $this->hasOne(OldAddress::class, 'id', 'address_id')->where('type', '=', 1);
}
/**
+11
View File
@@ -6,6 +6,7 @@ use App\Classes\General\Interfaces\Addressable;
use App\Classes\General\Interfaces\Contactable;
use App\Classes\General\Interfaces\Packable;
use App\Classes\ValueObjects\Constants\RoleTypes;
use App\Classes\ValueObjects\Constants\ApprovalStatus;
use App\Scopes\CustomerOrdersScope;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\Relations\HasManyThrough;
@@ -77,4 +78,14 @@ class Order extends AbstractModel implements Addressable, Packable
// static::addGlobalScope(new CustomerOrdersScope);
// }
}
public function addressesPendingVerification()
{
return $this->addresses()->where('status','=',ApprovalStatus::PENDING_VERIFICATION);
}
public function addressesApproved()
{
return $this->addresses()->where('status','=',ApprovalStatus::APPROVED);
}
}
+1
View File
@@ -17,6 +17,7 @@
"intervention/image": "^2.5",
"laravel/framework": "^8.40",
"laravel/tinker": "^2.5",
"maatwebsite/excel": "^3.1",
"rinvex/countries": "^6.1",
"spatie/laravel-activitylog": "^3.14",
"spatie/laravel-permission": "^4.2",
+3 -1
View File
@@ -178,7 +178,8 @@ return [
// Third Parties
Spatie\Permission\PermissionServiceProvider::class,
Barryvdh\DomPDF\ServiceProvider::class,
Meneses\LaravelMpdf\LaravelMpdfServiceProvider::class
Meneses\LaravelMpdf\LaravelMpdfServiceProvider::class,
Maatwebsite\Excel\ExcelServiceProvider::class,
],
/*
@@ -233,6 +234,7 @@ return [
'View' => Illuminate\Support\Facades\View::class,
'PDF' => Barryvdh\DomPDF\Facade::class,
'MPDF' => Meneses\LaravelMpdf\Facades\LaravelMpdf::class,
'Excel' => Maatwebsite\Excel\Facades\Excel::class,
],
];
+19 -1
View File
@@ -82,7 +82,25 @@ return [
PDO::MYSQL_ATTR_SSL_CA => env('MYSQL_ATTR_SSL_CA'),
]) : [],
],
'exchange_db' => [
'driver' => 'mysql',
'url' => env('DATABASE_URL'),
'host' => env('DB_HOST', '127.0.0.1'),
'port' => env('DB_PORT', '3306'),
'database' => env('DB_DATABASE_EXCHANGE', 'forge'),
'username' => env('DB_USERNAME', 'forge'),
'password' => env('DB_PASSWORD', ''),
'unix_socket' => env('DB_SOCKET_IZYIM', ''),
'charset' => 'utf8mb4',
'collation' => 'utf8mb4_unicode_ci',
'prefix' => '',
'prefix_indexes' => true,
'strict' => true,
'engine' => null,
'options' => extension_loaded('pdo_mysql') ? array_filter([
PDO::MYSQL_ATTR_SSL_CA => env('MYSQL_ATTR_SSL_CA'),
]) : [],
],
'pgsql' => [
'driver' => 'pgsql',
'url' => env('DATABASE_URL'),
+328
View File
@@ -0,0 +1,328 @@
<?php
use Maatwebsite\Excel\Excel;
return [
'exports' => [
/*
|--------------------------------------------------------------------------
| Chunk size
|--------------------------------------------------------------------------
|
| When using FromQuery, the query is automatically chunked.
| Here you can specify how big the chunk should be.
|
*/
'chunk_size' => 1000,
/*
|--------------------------------------------------------------------------
| Pre-calculate formulas during export
|--------------------------------------------------------------------------
*/
'pre_calculate_formulas' => false,
/*
|--------------------------------------------------------------------------
| Enable strict null comparison
|--------------------------------------------------------------------------
|
| When enabling strict null comparison empty cells ('') will
| be added to the sheet.
*/
'strict_null_comparison' => false,
/*
|--------------------------------------------------------------------------
| CSV Settings
|--------------------------------------------------------------------------
|
| Configure e.g. delimiter, enclosure and line ending for CSV exports.
|
*/
'csv' => [
'delimiter' => ',',
'enclosure' => '"',
'line_ending' => PHP_EOL,
'use_bom' => false,
'include_separator_line' => false,
'excel_compatibility' => false,
],
/*
|--------------------------------------------------------------------------
| Worksheet properties
|--------------------------------------------------------------------------
|
| Configure e.g. default title, creator, subject,...
|
*/
'properties' => [
'creator' => '',
'lastModifiedBy' => '',
'title' => '',
'description' => '',
'subject' => '',
'keywords' => '',
'category' => '',
'manager' => '',
'company' => '',
],
],
'imports' => [
/*
|--------------------------------------------------------------------------
| Read Only
|--------------------------------------------------------------------------
|
| When dealing with imports, you might only be interested in the
| data that the sheet exists. By default we ignore all styles,
| however if you want to do some logic based on style data
| you can enable it by setting read_only to false.
|
*/
'read_only' => true,
/*
|--------------------------------------------------------------------------
| Ignore Empty
|--------------------------------------------------------------------------
|
| When dealing with imports, you might be interested in ignoring
| rows that have null values or empty strings. By default rows
| containing empty strings or empty values are not ignored but can be
| ignored by enabling the setting ignore_empty to true.
|
*/
'ignore_empty' => false,
/*
|--------------------------------------------------------------------------
| Heading Row Formatter
|--------------------------------------------------------------------------
|
| Configure the heading row formatter.
| Available options: none|slug|custom
|
*/
'heading_row' => [
'formatter' => 'slug',
],
/*
|--------------------------------------------------------------------------
| CSV Settings
|--------------------------------------------------------------------------
|
| Configure e.g. delimiter, enclosure and line ending for CSV imports.
|
*/
'csv' => [
'delimiter' => ',',
'enclosure' => '"',
'escape_character' => '\\',
'contiguous' => false,
'input_encoding' => 'UTF-8',
],
/*
|--------------------------------------------------------------------------
| Worksheet properties
|--------------------------------------------------------------------------
|
| Configure e.g. default title, creator, subject,...
|
*/
'properties' => [
'creator' => '',
'lastModifiedBy' => '',
'title' => '',
'description' => '',
'subject' => '',
'keywords' => '',
'category' => '',
'manager' => '',
'company' => '',
],
],
/*
|--------------------------------------------------------------------------
| Extension detector
|--------------------------------------------------------------------------
|
| Configure here which writer/reader type should be used when the package
| needs to guess the correct type based on the extension alone.
|
*/
'extension_detector' => [
'xlsx' => Excel::XLSX,
'xlsm' => Excel::XLSX,
'xltx' => Excel::XLSX,
'xltm' => Excel::XLSX,
'xls' => Excel::XLS,
'xlt' => Excel::XLS,
'ods' => Excel::ODS,
'ots' => Excel::ODS,
'slk' => Excel::SLK,
'xml' => Excel::XML,
'gnumeric' => Excel::GNUMERIC,
'htm' => Excel::HTML,
'html' => Excel::HTML,
'csv' => Excel::CSV,
'tsv' => Excel::TSV,
/*
|--------------------------------------------------------------------------
| PDF Extension
|--------------------------------------------------------------------------
|
| Configure here which Pdf driver should be used by default.
| Available options: Excel::MPDF | Excel::TCPDF | Excel::DOMPDF
|
*/
'pdf' => Excel::DOMPDF,
],
/*
|--------------------------------------------------------------------------
| Value Binder
|--------------------------------------------------------------------------
|
| PhpSpreadsheet offers a way to hook into the process of a value being
| written to a cell. In there some assumptions are made on how the
| value should be formatted. If you want to change those defaults,
| you can implement your own default value binder.
|
| Possible value binders:
|
| [x] Maatwebsite\Excel\DefaultValueBinder::class
| [x] PhpOffice\PhpSpreadsheet\Cell\StringValueBinder::class
| [x] PhpOffice\PhpSpreadsheet\Cell\AdvancedValueBinder::class
|
*/
'value_binder' => [
'default' => Maatwebsite\Excel\DefaultValueBinder::class,
],
'cache' => [
/*
|--------------------------------------------------------------------------
| Default cell caching driver
|--------------------------------------------------------------------------
|
| By default PhpSpreadsheet keeps all cell values in memory, however when
| dealing with large files, this might result into memory issues. If you
| want to mitigate that, you can configure a cell caching driver here.
| When using the illuminate driver, it will store each value in a the
| cache store. This can slow down the process, because it needs to
| store each value. You can use the "batch" store if you want to
| only persist to the store when the memory limit is reached.
|
| Drivers: memory|illuminate|batch
|
*/
'driver' => 'memory',
/*
|--------------------------------------------------------------------------
| Batch memory caching
|--------------------------------------------------------------------------
|
| When dealing with the "batch" caching driver, it will only
| persist to the store when the memory limit is reached.
| Here you can tweak the memory limit to your liking.
|
*/
'batch' => [
'memory_limit' => 60000,
],
/*
|--------------------------------------------------------------------------
| Illuminate cache
|--------------------------------------------------------------------------
|
| When using the "illuminate" caching driver, it will automatically use
| your default cache store. However if you prefer to have the cell
| cache on a separate store, you can configure the store name here.
| You can use any store defined in your cache config. When leaving
| at "null" it will use the default store.
|
*/
'illuminate' => [
'store' => null,
],
],
/*
|--------------------------------------------------------------------------
| Transaction Handler
|--------------------------------------------------------------------------
|
| By default the import is wrapped in a transaction. This is useful
| for when an import may fail and you want to retry it. With the
| transactions, the previous import gets rolled-back.
|
| You can disable the transaction handler by setting this to null.
| Or you can choose a custom made transaction handler here.
|
| Supported handlers: null|db
|
*/
'transactions' => [
'handler' => 'db',
],
'temporary_files' => [
/*
|--------------------------------------------------------------------------
| Local Temporary Path
|--------------------------------------------------------------------------
|
| When exporting and importing files, we use a temporary file, before
| storing reading or downloading. Here you can customize that path.
|
*/
'local_path' => storage_path('framework/laravel-excel'),
/*
|--------------------------------------------------------------------------
| Remote Temporary Disk
|--------------------------------------------------------------------------
|
| When dealing with a multi server setup with queues in which you
| cannot rely on having a shared local temporary path, you might
| want to store the temporary file on a shared disk. During the
| queue executing, we'll retrieve the temporary file from that
| location instead. When left to null, it will always use
| the local path. This setting only has effect when using
| in conjunction with queued imports and exports.
|
*/
'remote_disk' => null,
'remote_prefix' => null,
/*
|--------------------------------------------------------------------------
| Force Resync
|--------------------------------------------------------------------------
|
| When dealing with a multi server setup as above, it's possible
| for the clean up that occurs after entire queue has been run to only
| cleanup the server that the last AfterImportJob runs on. The rest of the server
| would still have the local temporary file stored on it. In this case your
| local storage limits can be exceeded and future imports won't be processed.
| To mitigate this you can set this config value to be true, so that after every
| queued chunk is processed the local temporary file is deleted on the server that
| processed it.
|
*/
'force_resync_remote' => null,
],
];
+30 -30
View File
@@ -172,49 +172,49 @@ class CompaniesTableSeeder extends Seeder
}
if(true){
$companies = OldCompany::all();
// if(true){
// $companies = OldCompany::all();
foreach($companies as $company){
// foreach($companies as $company){
$marking = explode("CIEF/", $company->marking);
// $marking = explode("CIEF/", $company->marking);
if(count($marking) < 2){
continue;
}
// if(count($marking) < 2){
// continue;
// }
$marking = str_replace(' ', '', str_replace('/', '', $marking[1]));
// $marking = str_replace(' ', '', str_replace('/', '', $marking[1]));
/** @var Company $newCompany */
$newCompany = $this->createCompanyProcessor->execute($company->name, CompanyType::COMPANY_BUSINESS, ApprovalStatus::PENDING_SUBMISSION);
// /** @var Company $newCompany */
// $newCompany = $this->createCompanyProcessor->execute($company->name, CompanyType::COMPANY_BUSINESS, ApprovalStatus::PENDING_SUBMISSION);
$this->updatesCompanyStatus->execute($newCompany, ApprovalStatus::APPROVED);
// $this->updatesCompanyStatus->execute($newCompany, ApprovalStatus::APPROVED);
/** @var CompanyModule $companyModule */
$companyModule = $this->createCompanyModuleProcessor->execute($newCompany, BusinessType::IMPORTER);
// /** @var CompanyModule $companyModule */
// $companyModule = $this->createCompanyModuleProcessor->execute($newCompany, BusinessType::IMPORTER);
$connectionObject = new CompanyConnectionObject($companyModule, 'CIEF', $marking);
// $connectionObject = new CompanyConnectionObject($companyModule, 'CIEF', $marking);
$connection = $this->createsCompanyConnection->execute($connectionObject);
$this->approvesCompanyConnection->execute($connection);
// $connection = $this->createsCompanyConnection->execute($connectionObject);
// $this->approvesCompanyConnection->execute($connection);
$i = 0;
foreach($company->addresses as $address){
$this->createAddressFromOldAddressProcessor->execute($address, $companyModule);
$contact = preg_replace("/[^0-9.]/", "", $address->contact);
if($contact){
$i++;
if($i === 1) {
$contactObject = new ContactObject('', $contact, $company->email, '',);
$this->createContactProcessor->execute($contactObject, $newCompany);
}
}
// $i = 0;
// foreach($company->addresses as $address){
// $this->createAddressFromOldAddressProcessor->execute($address, $companyModule);
// $contact = preg_replace("/[^0-9.]/", "", $address->contact);
// if($contact){
// $i++;
// if($i === 1) {
// $contactObject = new ContactObject('', $contact, $company->email, '',);
// $this->createContactProcessor->execute($contactObject, $newCompany);
// }
// }
}
}
}
// }
// }
// }
}
@@ -0,0 +1,76 @@
<?php
namespace Database\Seeders;
use App\Classes\Modules\Companies\DataTransferObjects\EmploymentObject;
use App\Classes\Modules\Companies\Processors\AssignEmployeeProcessor;
use App\Models\CompanyConnection;
use App\Models\Exchange\Company as ExchangeCompany;
use App\Models\User;
use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\DB;
class CompanyEmployeesTableSeeder extends Seeder
{
/** @var AssignEmployeeProcessor */
private $assignEmployeeProcessor;
/**
* CompanyEmployeesTableSeeder constructor.
* @param AssignEmployeeProcessor $assignEmployeeProcessor
*/
public function __construct(AssignEmployeeProcessor $assignEmployeeProcessor)
{
$this->assignEmployeeProcessor = $assignEmployeeProcessor;
}
/**
* Run the database seeds.
*
* @return void
* @throws \App\Classes\Exceptions\AccessForbiddenException
* @throws \App\Classes\Exceptions\MalformedRequestException
* @throws \App\Classes\Exceptions\RequestValidationException
*/
public function run()
{
DB::beginTransaction();
foreach(ExchangeCompany::all() as $company) {
if($connection = CompanyConnection::where('invitee_reference', $company->reference)->first()){
$companyModule = $connection->invitee;
if($companyModule->employees()->exists()) {
continue;
}
$exchangeUser = $company->employees()->first();
if(User::where('email', '=', $exchangeUser->email)->count()){
continue;
}
$user = new User();
$user->name = $exchangeUser->name;
$user->email = $exchangeUser->email;
$user->password = $exchangeUser->password;
$user->type = $exchangeUser->type;
$user->status = $exchangeUser->status;
$user->save();
$Object = new EmploymentObject($companyModule, $user);
$this->assignEmployeeProcessor->execute($Object);
}
}
DB::commit();
}
}
@@ -0,0 +1,54 @@
<?php
namespace Database\Seeders;
use App\Classes\Jobs\FetchContainersStatusUpdateFromVTPortalJob;
use App\Classes\Jobs\FetchDeliveryListFromVTPortalJob;
use App\Classes\Jobs\FetchLoadedContainersFromVTPortalJob;
use App\Classes\Jobs\FetchPackingListFromVTPortalJob;
use App\Classes\Jobs\FetchWarehouseReceiveListFromVTPortalJob;
use App\Classes\Modules\PackingLists\Processors\FetchContainersStatusUpdateFromVTPortalProcessor;
use App\Models\Address;
use App\Models\Container;
use App\Models\ContainerPackingList;
use App\Models\OldOrders;
use App\Models\Order;
use App\Models\Package;
use App\Models\PackingList;
use App\Models\Schedule;
use App\Models\Step;
use App\Models\Transport;
use Illuminate\Database\Seeder;
class DeleteOldOrdersSeeder extends Seeder
{
/**
* Run the database seeds.
*
* @return void
*/
public function run()
{
Container::truncate();
ContainerPackingList::truncate();
Transport::truncate();
Schedule::truncate();
PackingList::truncate();
Package::truncate();
Step::truncate();
foreach (Order::all() as $order){
$oldOrder = OldOrders::where('marking', '=', $order->reference)->first();
if($oldOrder){
$order->addresses()->forceDelete();
$order->packingLists()->forceDelete();
$order->OrderRoles()->forceDelete();
$order->orderSteps()->forceDelete();
$order->forceDelete();
}
}
}
}
-1
View File
@@ -21,7 +21,6 @@ class OrdersTableSeeder extends Seeder
*/
public function run()
{
FetchWarehouseReceiveListFromVTPortalJob::withChain([
new FetchLoadedContainersFromVTPortalJob,
new FetchPackingListFromVTPortalJob,
+1 -1
View File
@@ -269,7 +269,7 @@ body.modal-open {
box-shadow: none;
}
.modal-dialog {
width: 600px;
width: 1140px;
}
.modal-sm {
width: 300px;
@@ -0,0 +1,101 @@
<template>
<div class="row">
<div class="col">
<div class="row text-left" @keyup.enter="submitForm">
<div class="col">
<error-message-component class="m-b-20" :error="error"></error-message-component>
<div class="row">
<div class="col">
<div class="row" >
<div class="col">
<div class="row">
<div class="col">
<p class="bold fs-11 all-caps muted">Personal Information</p>
</div>
</div>
<div class="row m-b-15">
<div class="col p-r-5">
<validation-wrapper-component :validator="$v.parameters.name">
<label>Full Name</label>
<input class="form-control" v-model="parameters.name">
</validation-wrapper-component>
</div>
<div class="col p-l-5">
<validation-wrapper-component :validator="$v.parameters.phone">
<label>Phone</label>
<input class="form-control" v-model="parameters.phone">
</validation-wrapper-component>
</div>
</div>
<div class="row m-b-15">
<div class="col">
<validation-wrapper-component :validator="$v.parameters.email">
<label>Email</label>
<input class="form-control" v-model="parameters.email">
</validation-wrapper-component>
</div>
</div>
<div class="row m-b-15">
<div class="col p-r-5">
<validation-wrapper-component :validator="$v.parameters.password">
<label>Password</label>
<input class="form-control" type="password" v-model="parameters.password">
</validation-wrapper-component>
</div>
<div class="col p-l-5">
<validation-wrapper-component :validator="$v.parameters.password_confirmation">
<label>Password Confirmation</label>
<input class="form-control" type="password" v-model="parameters.password_confirmation">
</validation-wrapper-component>
</div>
</div>
<div class="row">
<div class="col-auto">
<button type="button" class="btn btn-sm p-t-10 p-b-10 btn-default bg-master-lighter b-rad-none" @click="$store.dispatch('toggleSection', {name: 'registrationForm', status: false})">
<div class="row align-items-center">
<div class="col-auto p-r-10">
<i class="fa fa-angle-left fs-16" style="margin-top: 1px;"></i>
</div>
<div class="col p-l-5">I already have an account</div>
</div>
</button>
</div>
<div class="col text-right">
<button type="button" class="btn btn-sm btn-block p-t-10 p-b-10 p-r-35 p-l-35 btn-primary b-rad-none p-r-30" @click="submit(route('api.account.registration.invite.register'), 'post', section, false, false)"><i class="fa fa-check fs-18 m-r-10"></i>Complete Registration</button>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
import inviteRegistrationFormValidation from '../../../general/mixins/accounts/validation/inviteRegistrationFormValidation';
export default {
props: {
id: {
required: true,
type: Number
}
},
data() {
return {
error: '',
parameters : {
company_id: this.id,
name: '',
email: '',
phone: '',
password: '',
password_confirmation: '',
}
}
},
mixins: [inviteRegistrationFormValidation]
}
</script>
@@ -38,7 +38,6 @@
</template>
<script>
import registrationCheckEmailValidation from '../../../general/mixins/accounts/validation/registrationCheckEmailValidation';
import stepNavi from '../../../general/mixins/stepNavi';
export default {
data() {
return {
@@ -257,7 +257,6 @@
</template>
<script>
import registrationFormValidation from '../../../general/mixins/accounts/validation/registrationFormValidation';
import stepNavi from '../../../general/mixins/stepNavi';
export default {
data() {
return {
@@ -1,33 +0,0 @@
<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 address?</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.address.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>
@@ -1,145 +0,0 @@
<template>
<div class="row p-t-25 text-left">
<div class="col">
<div class="shadow p-3 bg-white rounded">
<div class="d-flex flex-row align-items-center">
<input v-show="!isEdit" type="radio" name="answer" id="answer-2"
v-model="computeAddressId"
:value='-1'
:checked="new_address == true"
>
<label for="answer-2" data-question-number="2" class="mb-0 pl-2 pl-md-2 bold">{{isEdit?'Edit ':'Add New '}}Address</label>
</div>
<div class="col-0" v-if="computeAddressId==-1">
<div class="d-flex flex-column flex-sm-row">
<div class="col px-0 pr-sm-2">
<validation-wrapper-component selecatable :validator="$v.parameters.district_id">
<label class="text-primary fs-12">District</label>
<div class="controls">
<selectable-component :endpoint="route('api.address.district.list')" section="districtListSection" valueColumn="id" :labelColumn="['city']" v-model="parameters.district_id"></selectable-component>
</div>
</validation-wrapper-component>
</div>
<div class="col px-0 pl-sm-2">
<validation-wrapper-component :validator="$v.parameters.post_code">
<label class="text-primary fs-12">Post Code</label>
<div class="controls">
<input type="text" class="form-control fs-12" v-model="parameters.post_code">
</div>
</validation-wrapper-component>
</div>
</div>
<div class="d-flex flex-column flex-sm-row">
<div class="col px-0 pr-sm-2">
<validation-wrapper-component :validator="$v.parameters.street_one">
<label class="text-primary fs-12">Street one</label>
<div class="controls">
<input type="text" class="form-control fs-12"
v-model="parameters.street_one"
>
</div>
</validation-wrapper-component>
</div>
<div class="col px-0 pl-sm-2">
<validation-wrapper-component :validator="$v.parameters.street_two">
<label class="text-primary fs-12">Street two</label>
<div class="controls">
<input type="text" class="form-control fs-12"
v-model="parameters.street_two"
>
</div>
</validation-wrapper-component>
</div>
</div>
<div class="row m-t-25">
<div class="col">
<div class="row">
<div class="col text-right">
<button type="button" class="btn btn-sm btn-primary b-rad-none" @click="submitForm()">{{isEdit?'Update':'Create'}}</button>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
import { required ,requiredIf } from "vuelidate/lib/validators";
export default {
props: {
section: {
default: 'addressForm'
},
isEdit:{
default: false
},
populateWith: {
type: Object,
default: () => ({ empty: true })
},
address_id: null
},
watch: {
},
data() {
return {
parameters : {
company_module_id:this.$store.getters.getCompanyModuleId,
street_one: '',
street_two: '',
district_id: '',
post_code: '',
},
new_address:false
}
},
computed: {
computeAddressId:{
get() {
if (!this.populateWith.empty) {
this.parameters = this.populateWith;
this.parameters.district_id = this.populateWith.district.id;
this.parameters.id = this.populateWith.id;
}
return this.address_id;
},
set(val) {
this.$emit('input', val);
}
},
},
validations: {
parameters: {
street_one: { required:requiredIf(function () { return this.computeAddressId === -1 }) },
street_two: {},
district_id: { required },
post_code: { required },
}
},
methods:{
submitForm(){
if(!this.validate()){
return;
}
this.isLoading = true;
this.isEdit?this.submit(route('api.address.update', this.parameters.id), 'put', this.section, true, true):this.submit((this.route('api.address.create')), 'post', 'addressList', true, true);
},
successHandler(response){
this.$emit('input', response.payload.data.id);
this.resetForm();
this.closeModal();
this.isLoading = false;
this.updateList();
}
}
}
</script>
@@ -0,0 +1,135 @@
<template>
<div class="row m-b-10 bg-master-lightest">
<div class="col">
<loading-component style="height: 200px; top: 0;" key="1" color="success" v-show="isLoading"></loading-component>
<div class="row" v-show="!isLoading">
<div class="col">
<div class="row align-items-center">
<div class="col p-t-10 p-b-10">
<div class="row">
<div class="col">
<h5 class="text-primary no-margin"><a :href="route('order.show', item.owner.reference)">{{item.owner.reference}}</a></h5>
</div>
</div>
<div class="row align-items-center">
<div class="col">
<h6 class="no-margin"><a :href="route('customer.profile', item.owner.company_module.marking)">{{item.owner.company_module.marking}}</a></h6>
</div>
</div>
</div>
</div>
<div class="row b-t b-grey">
<div class="col p-t-10">
<div class="row m-b-15">
<div class="col">
<div class="row m-b-5">
<div class="col">
<div class="fs-8 all-caps muted">Original Address</div>
</div>
</div>
<div class="row">
<div class="col">
<div class="fs-11 bold">{{item.owner.address.street_one+' '+(item.owner.address.street_two ? item.owner.address.street_two : '')+', '+ item.owner.address.district.name+', '+item.owner.address.post_code+' '+item.owner.address.state.name+', '+item.owner.address.country.name}}</div>
</div>
</div>
</div>
</div>
<div class="row m-b-15">
<div class="col">
<div class="row m-b-5">
<div class="col">
<div class="fs-8 all-caps muted">New Address</div>
</div>
</div>
<div class="row">
<div class="col">
<div class="fs-11 bold">{{item.street_one+' '+(item.street_two ? item.street_two : '')+', '+ item.district.name+', '+item.post_code+' '+item.state.name+', '+item.country.name}}</div>
</div>
</div>
</div>
</div>
<div class="row m-t-20 parentContainer">
<div class="col">
<div class="row">
<div class="col no-padding">
<button class="btn btn-md btn-block btn-outline-danger b-rad-none p-t-10 p-b-10 requestModal" data-type="rejectAddress">
Reject
</button>
</div>
<modal-component small type="rejectAddress">
<div class="row">
<div class="col text-center">
<div class="row">
<div class="col text-center">
<div class="row m-b-20">
<div class="col">
<h5 class="all-caps">Reject Address Change Request</h5>
<div class="fs-11">Are you sure you want to reject order delivery address change request?</div>
</div>
</div>
<div class="row">
<div class="col p-r-5">
<div data-dismiss="modal" class="btn btn-sm btn-default bg-master-lighter btn-block b-rad-none">Cancel</div>
</div>
<div class="col p-l-5">
<div data-dismiss="modal" class="btn btn-sm btn-danger btn-block b-rad-none" @click="approveAddress(6)">Reject</div>
</div>
</div>
</div>
</div>
</div>
</div>
</modal-component>
<div class="col no-padding ml-auto">
<button class="btn btn-md btn-block btn-outline-success b-rad-none p-t-10 p-b-10 requestModal" data-type="approveAddress">
Approve
</button>
</div>
<modal-component small type="approveAddress">
<div class="row">
<div class="col text-center">
<div class="row">
<div class="col text-center">
<div class="row m-b-20">
<div class="col">
<h5 class="all-caps">Approve Address Change Request</h5>
<div class="fs-11">Are you sure you want to approve this order delivery address change request?</div>
</div>
</div>
<div class="row">
<div class="col p-r-5">
<div data-dismiss="modal" class="btn btn-sm btn-default bg-master-lighter btn-block b-rad-none">Cancel</div>
</div>
<div class="col p-l-5">
<div data-dismiss="modal" class="btn btn-sm btn-success btn-block b-rad-none" @click="approveAddress(2)">Approve</div>
</div>
</div>
</div>
</div>
</div>
</div>
</modal-component>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
import componentHandler from '../../../general/mixins/componentHandler';
import staticFormHandler from '../../../general/mixins/staticFormHandler'
export default {
methods: {
approveAddress(status){
this.isLoading = true;
this.submit((this.route('api.order.address.status.update', this.item.id, status)), 'put', 'addressVerificationSection', true, true);
},
},
mixins: [componentHandler, staticFormHandler]
}
</script>
@@ -5,10 +5,10 @@
<div class="col-auto p-r-0">
<i class="fa fs-20 p-t-5" :class="{'fa-circle-o': value !== item.id, 'fa-check-circle': value === item.id, 'text-primary': value === item.id}"></i>
</div>
<div class="col-2">
<div class="col-3">
<h6 class="no-margin bold fs-12">{{item.reference}}</h6>
</div>
<div class="col">
<div class="col text-left">
<h6 class="no-margin fs-12">{{item.street_one}} {{item.street_two}}, {{item.district.name}}, {{item.post_code}} {{item.state.name}}, {{item.country.name}}</h6>
</div>
<div class="col-auto">

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