Merge branch 'master' of gitlab.com:CIEFWorldwideSdnBhd/shipping-portal into container-profile-ui

# Conflicts:
#	resources/assets/vue/components/containers/elements/ContainerProfileSectionComponent.vue
#	routes/web.php
This commit is contained in:
edmondlang
2021-10-03 18:13:20 +08:00
38 changed files with 1720 additions and 110 deletions
+2 -1
View File
@@ -24,4 +24,5 @@ db/*
docker-compose.yml
package-lock.json
public/*
/public/*
/public/*
storage/framework/laravel-excel/*
@@ -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);
@@ -62,6 +62,7 @@ class CreateContainerLogic extends AbstractControllerLogic
$request->input('container_number'),
$request->input('seal_reference'),
$request->input('container_type'),
$request->input('loading_date'),
$request->input('status')
);
@@ -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);
}
}
@@ -52,7 +52,9 @@ class UpdateContainerLogic extends AbstractControllerLogic
/**
* @param Request $request
* @return JsonResponse
* @throws ErrorException
* @throws \App\Classes\Exceptions\AccessForbiddenException
* @throws \App\Classes\Exceptions\MalformedRequestException
* @throws \App\Classes\Exceptions\RequestValidationException
*/
public function logic(Request $request) : JsonResponse
{
@@ -64,7 +66,8 @@ class UpdateContainerLogic extends AbstractControllerLogic
$container->container_number,
$request->input('container_type'),
$request->input('seal_reference'),
$container->status,
$request->input('loading_date'),
$container->status,
);
$this->canUpdateContainer->passes($object);
@@ -3,6 +3,7 @@
namespace App\Classes\Modules\PackingLists\DataTransferObjects;
use App\Classes\General\Interfaces\DataTransferObject;
use Carbon\Carbon;
class ContainerObject implements DataTransferObject
{
@@ -19,6 +20,9 @@ class ContainerObject implements DataTransferObject
/** @var int */
private $containerType;
/** @var Carbon */
private $loadingDate;
/** @var int */
private $status;
@@ -28,14 +32,16 @@ class ContainerObject implements DataTransferObject
* @param string $containerNumber
* @param string $sealReference
* @param int $containerType
* @param Carbon $loadingDate
* @param int $status
*/
public function __construct(string $reference, string $containerNumber, string $sealReference, int $containerType, int $status)
public function __construct(string $reference, string $containerNumber, string $sealReference, int $containerType, Carbon $loadingDate, int $status)
{
$this->reference = $reference;
$this->containerNumber = $containerNumber;
$this->sealReference = $sealReference;
$this->containerType = $containerType;
$this->loadingDate = $loadingDate;
$this->status = $status;
}
@@ -71,6 +77,14 @@ class ContainerObject implements DataTransferObject
return $this->containerType;
}
/**
* @return Carbon
*/
public function getLoadingDate(): Carbon
{
return $this->loadingDate;
}
/**
* @return int
*/
@@ -79,4 +93,5 @@ class ContainerObject implements DataTransferObject
return $this->status;
}
}
@@ -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 [];
}
}
@@ -6,7 +6,6 @@ use App\Classes\Exceptions\ResourceNotFoundException;
use App\Classes\Modules\Companies\Services\FetchesCompanyModule;
use App\Classes\Modules\Orders\Services\FetchesDataFromVTPortal;
use App\Classes\Modules\Orders\Services\FetchesOrder;
use App\Classes\Modules\PackingList\Processors\GenerateShippingOrderStepsProcessor;
use App\Classes\Modules\PackingLists\DataTransferObjects\ContainerObject;
use App\Classes\Modules\PackingLists\DataTransferObjects\PackingListObject;
use App\Classes\Modules\PackingLists\Services\Containers\FetchesContainer;
@@ -126,7 +125,7 @@ class FetchLoadedContainersFromVTPortalProcessor
DB::beginTransaction();
try {
$start = $start ? $start : Carbon::now()->subMonth();
$start = $start ? $start : Carbon::now()->subDays(5);
$startLimit = Carbon::parse('11-08-2021');
@@ -148,7 +147,7 @@ class FetchLoadedContainersFromVTPortalProcessor
$containerDetail = $this->fetchesDataFRomVTPortal->getResponseBody($containerDetailRequest);
$containerObject = new ContainerObject($container[0], str_replace(' ', '', $container[24]), str_replace(' ', '', $container[15]), ContainerTypes::FORTY_FEET_DRY_CONTAINER, ApprovalStatus::PENDING_VERIFICATION);
$containerObject = new ContainerObject($container[0], str_replace(' ', '', $container[24]), str_replace(' ', '', $container[15]), ContainerTypes::FORTY_FEET_DRY_CONTAINER, Carbon::parse($container[5]), ApprovalStatus::PENDING_VERIFICATION);
try {
$container = $this->fetchesContainer->execute(['reference' => $containerObject->getReference()]);
@@ -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;
}
}
@@ -23,6 +23,7 @@ class CreatesContainer extends AbstractUpdateRelationshipRecord
$model->container_number = $object->getContainerNumber();
$model->container_type = $object->getContainerType();
$model->seal_reference = $object->getSealReference();
$model->loading_date = $object->getLoadingDate();
$model->status = $object->getStatus();
return $this->handler($owner->containers(), $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"];
}
}
@@ -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);
}
}
@@ -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');
}
}
@@ -0,0 +1,66 @@
<?php
namespace App\Http\Controllers\Reports;
use App\Classes\ValueObjects\Constants\HttpStatus;
use App\Classes\ValueObjects\Response\ApiResponseObject;
use App\Models\Company;
use App\Models\Container;
use App\Models\Order;
use Carbon\Carbon;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
class MonthlyReportController
{
public function report(Request $request): JsonResponse {
$month = Carbon::now()->subMonth();
$containers = Container::whereMonth('loading_date', $month->format('m'))->whereYear('loading_date', '=', '2021')->orderBy('loading_date')->get();
$total = 0;
$customers = collect();
foreach ($containers as $container){
foreach($container->packingLists as $packingList){
$cbm = $packingList->packages->sum(function ($package){
return (( (float) $package->width / 100) * ( (float) $package->length / 100) * ( (float) $package->height / 100)) * $package->quantity;
});
$total += $cbm;
$marking = $packingList->owner->companyModule->inviters()->withPivot('invitee_reference')->first()->pivot->invitee_reference;
if(!$customers->has($marking)){
$customers->put($marking, collect([
'cbm' => $cbm,
'orders' => 1,
'packages' => $packingList->packages->sum('quantity')
]));
continue;
}
$customers[$marking]['cbm'] += $cbm;
$customers[$marking]['orders'] += 1;
$customers[$marking]['packages'] += $packingList->packages->sum('quantity');
}
}
$activeOrders = $customers->sum(function($customer){
return $customer['orders'];
});
return (new ApiResponseObject('fetch monthly report Successful',
'',
HttpStatus::OK_WITH_MESSAGE, ['data' => [
'containers' => count($containers),
'activated_orders' => $activeOrders,
'active_customers' => count($customers),
'new_customers' => Company::whereMonth('created_at', $month->format('m'))->count(),
'total_cbm' => $customers->sum(function($customer){
return $customer['cbm'];
}),
'packages' => $customers->sum(function($customer){
return $customer['packages'];
}),
'total_orders' => Order::whereMonth('created_at', $month->format('m'))->count()
]]))->handler();
}
}
+1
View File
@@ -21,6 +21,7 @@ class ContainerResource extends JsonResource
'container_specification' => ContainerTypes::CONTAINER_SPECIFICATION[$this->container_type],
'container_number' => $this->container_number,
'seal_reference' => $this->seal_reference,
'loading_date' => $this->loading_date ? $this->loading_date->format('d-m-Y') : $this->loading_date,
'transport' => new TransportResource($this->transports()->first()),
'packing_lists' => PackingListResource::collection($this->whenLoaded('packingLists', function(){
return $this->packingLists()->whereHas('packages')->get();
+2
View File
@@ -15,6 +15,8 @@ class Container extends AbstractModel implements Transportable
protected $fillable = ['status'];
protected $dates = ['loading_date'];
public function packingLists(): belongsToMany
{
return $this->belongsToMany(PackingList::class, ContainerPackingList::class, 'container_id', 'packing_list_id');
+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,
],
];
+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,
],
];
@@ -22,6 +22,7 @@ class CreateContainersTable extends Migration
$table->string('container_number')->nullable();
$table->integer('container_type')->default(ContainerTypes::FORTY_FEET_DRY_CONTAINER);
$table->string('seal_reference')->nullable();
$table->timestamp('loading_date')->nullable();
$table->integer('status')->default(ApprovalStatus::PENDING_SUBMISSION);
$table->softDeletes();
$table->timestamps();
+43 -43
View File
@@ -172,49 +172,49 @@ class CompaniesTableSeeder extends Seeder
}
// if(true){
// $companies = OldCompany::all();
// foreach($companies as $company){
// $marking = explode("CIEF/", $company->marking);
// if(count($marking) < 2){
// continue;
// }
// $marking = str_replace(' ', '', str_replace('/', '', $marking[1]));
// /** @var Company $newCompany */
// $newCompany = $this->createCompanyProcessor->execute($company->name, CompanyType::COMPANY_BUSINESS, ApprovalStatus::PENDING_SUBMISSION);
// $this->updatesCompanyStatus->execute($newCompany, ApprovalStatus::APPROVED);
// /** @var CompanyModule $companyModule */
// $companyModule = $this->createCompanyModuleProcessor->execute($newCompany, BusinessType::IMPORTER);
// $connectionObject = new CompanyConnectionObject($companyModule, 'CIEF', $marking);
// $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);
// }
// }
// }
// }
// }
// if(true){
// $companies = OldCompany::all();
//
// foreach($companies as $company){
//
// $marking = explode("CIEF/", $company->marking);
//
// if(count($marking) < 2){
// continue;
// }
//
// $marking = str_replace(' ', '', str_replace('/', '', $marking[1]));
//
//
// /** @var Company $newCompany */
// $newCompany = $this->createCompanyProcessor->execute($company->name, CompanyType::COMPANY_BUSINESS, ApprovalStatus::PENDING_SUBMISSION);
//
// $this->updatesCompanyStatus->execute($newCompany, ApprovalStatus::APPROVED);
//
// /** @var CompanyModule $companyModule */
// $companyModule = $this->createCompanyModuleProcessor->execute($newCompany, BusinessType::IMPORTER);
//
// $connectionObject = new CompanyConnectionObject($companyModule, 'CIEF', $marking);
//
// $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);
// }
// }
//
//
// }
// }
// }
}
@@ -14,11 +14,15 @@
<h6 class="no-margin bold">{{item.container_reference}}</h6>
<p class="no-margin">{{item.container_number}} / {{item.seal_reference}}</p>
</div>
<div class="col-2">
<div class="col-auto">
<p class="no-margin fs-10 all-caps">Loading Date</p>
<p class="no-margin">{{item.loading_date ? item.loading_date : 'n/a'}}</p>
</div>
<div class="col-auto">
<p class="no-margin fs-10 all-caps">ETD</p>
<p class="no-margin">{{item.transport ? item.transport.current_schedule.etd : 'n/a'}}</p>
</div>
<div class="col-2">
<div class="col">
<p class="no-margin fs-10 all-caps">ETA</p>
<p class="no-margin">{{item.transport ? item.transport.current_schedule.eta : 'n/a'}}</p>
</div>
@@ -26,7 +30,7 @@
<p class="no-margin fs-10 all-caps">Loaded CBM</p>
<p class="no-margin">{{ (Math.ceil((item.packing_lists.reduce((total, obj) => total + obj.packages.reduce((total, obj) => obj.cbm + total, 0), 0)) * 1000) / 1000).toFixed(3) }}</p>
</div>
<div class="col">
<div class="col-auto">
<p class="no-margin fs-10 all-caps">Status</p>
<p class="no-margin bold" :class="{'text-success': item.status === 3, 'text-complete': item.status !== 3}">{{item.status === 3 ? 'Un-stuffed' : 'In Progress'}}</p>
</div>
@@ -68,6 +72,14 @@
<div class="btn btn-xs btn-success pointer" v-if="packingList.status === 5" @click="updateStatus(index, item.status === 1 ? 1 : 2)"><i class="fa fa-check m-r-5"></i>Release</div>
<div class="btn btn-xs btn-danger pointer" v-if="packingList.status !== 5" @click="updateStatus(index, 5)"><i class="fa fa-hand-paper-o m-r-5"></i>Hold</div>
</div>
<div class="col-auto hide">
<a class="btn btn-xs btn-warning all-caps b-rad-none pointer" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
Report&nbsp;<i class="fa fa-download m-r-10"></i>
</a>
<div class="dropdown-menu">
<a class="dropdown-item" :href="route('report.customclearance',packingList.order.id)">Origin custom cleared</a>
</div>
</div>
</div>
</div>
</div>
@@ -103,4 +115,4 @@
},
mixins: [componentHandler]
}
</script>
</script>
@@ -2,7 +2,7 @@
<div class="row m-l-0 m-r-0 m-b-30 parentContainer">
<div class="col bg-white">
<div class="row align-items-center">
<div class="col no-padding">
<div class="col-6 no-padding">
<div class="row">
<div class="col">
<a :href="route('order.qr.download', item.id)" target="_blank">
@@ -13,7 +13,7 @@
</div>
</div>
</div>
<div class="col">
<div class="col-6">
<div class="row m-b-5">
<div class="col">
<small class="fs-10 all-caps muted">Order No.</small>
@@ -28,8 +28,20 @@
</div>
<div class="row m-b-5">
<div class="col">
<small class="fs-10 all-caps muted">Delivery Address</small>
<h6 class="no-margin small">{{item.address.reference}} <i class="fa fa-info-circle m-l-5" v-tooltip:right="item.address.street_one+' '+(item.address.street_two ? item.address.street_two : '')+', '+ item.address.district.name+', '+item.address.post_code+' '+item.address.state.name+', '+item.address.country.name" ></i></h6>
<div class="row">
<div class="col">
<small class="fs-10 all-caps muted">Delivery Address</small>
</div>
</div>
<div class="row">
<div class="col-9 p-r-0">
<h6 class="no-margin small" style="white-space: nowrap;overflow: hidden;text-overflow: ellipsis;">{{item.address.reference}}</h6>
</div>
<div class="col p-l-0">
<div class="row"><div class="col"><div class="row"><div class="col"></div></div><div class="row"><div class="col"></div></div></div></div>
<i class="fa fa-info-circle m-l-5" data-html="true" v-tooltip:right="'<h6 class=\'text-white text-left fs-13 m-t-0 m-b-5 semi-bold\'>'+item.address.reference+'</h6><p class=\'text-white text-left lh-17 no-margin\'>'+item.address.street_one+' '+(item.address.street_two ? item.address.street_two : '')+', '+ item.address.district.name+', '+item.address.post_code+' '+item.address.state.name+', '+item.address.country.name+'</p>'" ></i>
</div>
</div>
</div>
</div>
</div>
@@ -0,0 +1,131 @@
<template>
<div class="row m-b-15 m-l-5 m-r-10">
<div class="col bg-master-lightest rounded" :class="{'b-gray': !selected, 'b-primary': selected, 'bg-primary-lighter': selected}">
<div class="row">
<div class="col padding-20">
<div class="row align-items-center">
<div class="col-auto pointer align-items-center" @click="selected = !selected">
<i class="fa fs-30 fa-fw" :class="{'fa-square-o': !selected, 'fa-check-square': selected, 'text-primary':selected}" ></i>
</div>
<div class="col">
<h5 class="no-margin">{{item.country.id}}05052021</h5>
</div>
<div class="col">
<h5 class="no-margin">Invoice Date Invoice Date</h5>
</div>
<div class="col">
<h5 class="no-margin">Status</h5>
</div>
<div class="col">
<h5 class="no-margin">Amount</h5>
</div>
<div class="col-auto">
<div class="btn bg-grey no-border" @click="expanded = !expanded">
<i class="fa" :class="{'fa-angle-down': !expanded, 'fa-angle-up': expanded}" ></i>
</div>
</div>
</div>
</div>
</div>
<div class="row b-t b-grey p-t-10" v-show="expanded">
<div class="col p-b-10">
<div class="row">
<div class="col p-l-20 p-r-20 p-t-10 p-b-10">
<div class="row align-items-center">
<div class="col-auto invisible">
<i class="fa fs-30 fa-fw" :class="{'fa-square-o': !selected, 'fa-check-square': selected, 'text-primary':selected}" ></i>
</div>
<div class="col">
<div class="row">
<div class="col">
<h5 class="m-b-0">Carrier Tracking Number</h5>
</div>
</div>
<div class="row">
<div class="col">
<h5 class="semi-bold m-t-0 m-b-0 large-text">#1zbr06tw403742920</h5>
</div>
</div>
</div>
<div class="col">
<div class="row">
<div class="col">
<h5 class="m-b-0">Due Date</h5>
</div>
</div>
<div class="row">
<div class="col">
<h5 class="semi-bold m-t-0 m-b-0 large-text">11.04.2021</h5>
</div>
</div>
</div>
<div class="col">
<div class="row">
<div class="col">
<h5 class="semi-bold m-t-0 m-b-0 large-text">Outstanding</h5>
</div>
</div>
<div class="row">
<div class="col">
<h5 class="semi-bold m-t-0 m-b-0 large-text">RM0.00</h5>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col p-l-20 p-r-20 p-t-10 p-b-10">
<div class="row align-items-center">
<div class="col-auto invisible">
<i class="fa fs-30 fa-fw" :class="{'fa-square-o': !selected, 'fa-check-square': selected, 'text-primary':selected}" ></i>
</div>
<div class="col">
<div class="row">
<div class="col">
<h5 class="m-b-0 normal-text">This package was delivered by</h5>
</div>
</div>
<div class="row">
<div class="col">
<h5 class="semi-bold m-t-0 m-b-0 large-text">#1zbr06tw403742920</h5>
</div>
</div>
</div>
<div class="col">
<div class="row">
<div class="col">
<h5 class="m-b-0">Date Paid</h5>
</div>
</div>
<div class="row">
<div class="col">
<h5 class="semi-bold m-t-0 m-b-0 large-text">21.01.2021</h5>
</div>
</div>
</div>
<div class="col">
<div class="btn btn-outline-complete btn-lg">
Invoice Detail
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
import componentHandler from '../../../general/mixins/componentHandler';
export default {
data(){
return {
expanded: false,
selected: false,
}
},
mixins: [componentHandler]
}
</script>
@@ -0,0 +1,170 @@
<template>
<div class="row" >
<div class="col">
<loading-component v-if="isLoading"></loading-component>
<div class="row" v-if="report">
<div class="col">
<div class="card no-border bg-master-lightest widget-loader-bar m-b-10">
<div class="container-xs-height full-height">
<div class="row-xs-height">
<div class="col-xs-height col-top">
<div class="card-header top-left top-right">
<div class="card-title">
<span class="font-montserrat fs-11 all-caps">Total CBM</span>
</div>
</div>
</div>
</div>
<div class="row-xs-height">
<div class="col-xs-height col-top">
<div class="p-l-20 p-t-50 p-b-40 p-r-20">
<h3 class="no-margin p-b-5">{{(Math.ceil(report.total_cbm * 1000) / 1000).toFixed(3)}}</h3>
<span class="small hint-text pull-left">{{ Math.ceil((((report.total_cbm / 1000) * 100) * 100) / 100).toFixed(2)}}%</span>
<span class="pull-right small text-primary">Goal: 1000 CBM</span>
</div>
</div>
</div>
<div class="row-xs-height">
<div class="col-xs-height col-bottom">
<div class="progress progress-small m-b-0">
<div class="progress-bar progress-bar-primary" :style="{'width': Math.ceil((((report.total_cbm / 1000) * 100) * 100) / 100).toFixed(2)+'%'}"></div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="col">
<div class="card no-border bg-master-lightest widget-loader-bar m-b-10">
<div class="container-xs-height full-height">
<div class="row-xs-height">
<div class="col-xs-height col-top">
<div class="card-header top-left top-right">
<div class="card-title">
<span class="font-montserrat fs-11 all-caps">Activated Orders</span>
</div>
</div>
</div>
</div>
<div class="row-xs-height">
<div class="col-xs-height col-top">
<div class="p-l-20 p-t-50 p-b-40 p-r-20">
<h3 class="no-margin p-b-5">{{report.activated_orders}}</h3>
<span class="small hint-text pull-left">{{ Math.ceil((((report.activated_orders / report.total_orders) * 100) * 100) / 100).toFixed(2)}}%</span>
<span class="pull-right small text-primary">Created Orders: {{report.total_orders}}</span>
</div>
</div>
</div>
<div class="row-xs-height">
<div class="col-xs-height col-bottom">
<div class="progress progress-small m-b-0">
<div class="progress-bar progress-bar-primary" :style="{'width': Math.ceil((((report.activated_orders / report.total_orders) * 100) * 100) / 100).toFixed(2)+'%'}"></div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="col">
<div class="card no-border bg-master-lightest widget-loader-bar m-b-10">
<div class="container-xs-height full-height">
<div class="row-xs-height">
<div class="col-xs-height col-top">
<div class="card-header top-left top-right">
<div class="card-title">
<span class="font-montserrat fs-11 all-caps">Active Customers</span>
</div>
</div>
</div>
</div>
<div class="row-xs-height">
<div class="col-xs-height col-top">
<div class="p-l-20 p-t-50 p-b-40 p-r-20">
<h3 class="no-margin p-b-5">{{report.active_customers}}</h3>
<span class="small hint-text pull-left">{{ Math.ceil((((report.new_customers / report.active_customers) * 100) * 100) / 100).toFixed(2)}}%</span>
<span class="pull-right small text-primary">New Customers: {{report.new_customers}}</span>
</div>
</div>
</div>
<div class="row-xs-height">
<div class="col-xs-height col-bottom">
<div class="progress progress-small m-b-0">
<div class="progress-bar progress-bar-primary" :style="{'width': Math.ceil((((report.new_customers / report.active_customers) * 100) * 100) / 100).toFixed(2)+'%'}"></div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="col">
<div class="card no-border bg-master-lightest widget-loader-bar m-b-10">
<div class="container-xs-height full-height">
<div class="row-xs-height">
<div class="col-xs-height col-top">
<div class="card-header top-left top-right">
<div class="card-title">
<span class="font-montserrat fs-11 all-caps">Containers</span>
</div>
</div>
</div>
</div>
<div class="row-xs-height">
<div class="col-xs-height col-top">
<div class="p-l-20 p-t-50 p-b-40 p-r-20">
<h3 class="no-margin p-b-5">{{report.containers}}</h3>
</div>
</div>
</div>
<div class="row-xs-height">
<div class="col-xs-height col-bottom">
<div class="progress progress-small m-b-0">
<div class="progress-bar progress-bar-primary" style="width: 0"></div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
import LoadingComponent from "../../general/elements/LoadingComponent";
export default {
components: {LoadingComponent},
data(){
return {
section: 'monthlyReportSection',
isLoading: true,
report: null
}
},
computed: {
pendingQueue () {
return this.$store.getters.isInCompleteQueue(this.section);
}
},
watch: {
pendingQueue(inComplete){
if(inComplete){
this.fetchReport();
}
}
},
created(){
this.$store.dispatch('updateListQueue', {'name': this.section});
},
methods: {
fetchReport(){
this.isLoading = true;
this.submit(route('api.report'), 'get', this.section, false, false)
},
successHandler(response){
this.$store.dispatch('completeList', {'name': this.section, 'data': []});
this.isLoading = false;
this.report = response.payload.data;
}
}
}
</script>
@@ -0,0 +1,94 @@
<template>
<div class="row padding-15">
<div class="col rounded p-l-20 p-r-20">
<div class="row bg-master-light rounded align-items-center padding-20">
<div class="col">
<div class="row m-b-5">
<div class="col">
<div class="row">
<div class="col">
<h5 class="m-b-0 m-t-0 font-weight-normal">Package ID:</h5>
</div>
</div>
<div class="row">
<div class="col">
<h5 class="m-b-0 m-t-0">9956665659-MY5568978458</h5>
</div>
</div>
</div>
</div>
<div class="row m-b-5">
<div class="col">
<div class="row">
<div class="col">
<h5 class="m-b-0 m-t-0 font-weight-normal">Package Size:</h5>
</div>
</div>
<div class="row">
<div class="col">
<h5 class="m-b-0 m-t-0">52x65x35 CM / 10KG</h5>
</div>
</div>
</div>
</div>
</div>
<div class="col">
<div class="row m-b-5">
<div class="col">
<div class="row">
<div class="col">
<h5 class="m-b-0 m-t-0 font-weight-normal">Delivery Address</h5>
</div>
</div>
<div class="row">
<div class="col">
<h5 class="m-b-0 m-t-0">Home</h5>
</div>
</div>
</div>
</div>
<div class="row m-b-5">
<div class="col">
<div class="row">
<div class="col">
<h5 class="m-b-0 m-t-0 font-weight-normal">Delivery Estimation</h5>
</div>
</div>
<div class="row">
<div class="col">
<h5 class="m-b-0 m-t-0">05/05/2022</h5>
</div>
</div>
</div>
</div>
</div>
<div class="col">
<div class="row">
<div class="col">
<h5 class="m-b-0 m-t-0">Shipping Cost</h5>
</div>
</div>
<div class="row">
<div class="col">
<h3 class="m-b-0 m-t-0">RM2800</h3>
</div>
</div>
</div>
<div class="col-auto pointer">
<div class="btn btn-lg btn-default btn-rounded"><i class="fa fa-check lightest lh-50"></i></div>
</div>
</div>
</div>
</div>
</template>
<script>
import componentHandler from '../../../general/mixins/componentHandler';
export default {
data(){
return {
expanded: false,
}
},
mixins: [componentHandler]
}
</script>
@@ -21,6 +21,10 @@
<div class="col p-t-15 p-b-25">
<div class="row m-b-20" v-if="$store.getters.isAdmin">
<div class="col"></div>
<div class="col-auto p-r-0">
</div>
<div class="col-auto p-r-0">
<a href="{{route('orders.refresh')}}"><div class="btn btn-sm btn-warning all-caps b-rad-none pointer"><i class="fa fa-refresh m-r-10"></i>Refresh Orders</div></a>
</div>
@@ -108,4 +112,4 @@
</div>
</div>
@endsection
@endsection
@@ -8,6 +8,7 @@
<img class="w-100" src="{{asset('images/cief-izyim-logo.png')}}" alt="">
</div>
</div>
<div class="hide">{{$id}}</div>
<div class="row">
<div class="col">
<loading-component style="height: 350px;" key="1" color="primary" v-show="$store.getters.isLoading('loginSection')"></loading-component>
@@ -0,0 +1,25 @@
@extends('layouts.base_portal')
@section('inner_content')
<div class="row">
<div class="col">
<div class="row d-none" :class="[{'d-flex': $store.getters.isAdmin}]" v-if="$store.getters.isAdmin">
<div class="col-8">
<div class="row p-b-5 b-b b-grey m-b-10 m-l-0 m-r-0">
<div class="col no-padding">
<h6>Customers List</h6>
</div>
</div>
<div class="row m-l-0 m-r-0">
<div class="col">
<list-component key="2" section="customerListSection" :endpoint="route('api.company.list')" :options="{'has_business_module_type': 1}">
<template slot="list" slot-scope="{data}">
<company-component :data="data"></company-component>
</template>
</list-component>
</div>
</div>
</div>
</div>
</div>
</div>
@endsection
+34 -39
View File
@@ -1,47 +1,42 @@
<div class="row d-none" :class="[{'d-flex': $store.getters.isAdmin}]" v-if="$store.getters.isAdmin">
<div class="col-8">
<div class="row p-b-5 b-b b-grey m-b-10 m-l-0 m-r-0">
<div class="col no-padding">
<h6>Customers List</h6>
</div>
</div>
<div class="row m-l-0 m-r-0">
<div class="col">
<div class="row m-b-50">
<div class="col">
<list-component key="2" section="customerListSection" :endpoint="route('api.company.list')" :options="{'has_business_module_type': 1}">
<template slot="list" slot-scope="{data}">
<company-component :data="data"></company-component>
</template>
</list-component>
<monthly-report-section-component></monthly-report-section-component>
</div>
</div>
</div>
<div class="col-4">
<div class="row p-b-5 b-b b-grey m-b-10 m-l-0 m-r-0">
<div class="col no-padding">
<h6>Identification Verification</h6>
<div class="row">
<div class="col-4">
<div class="row p-b-5 b-b b-grey m-b-10 m-l-0 m-r-0">
<div class="col no-padding">
<h6>Identification Verification</h6>
</div>
</div>
<div class="row no-margin">
<div class="col">
<list-component key="2" section="identificationVerificationSection" :options="{'per_page': 10, 'document_type_in': ['SSM_REGISTRATION', 'IDENTITY_CARD'], 'status': 1, 'with_company': true}" :endpoint="route('api.document.list')">
<template slot="list" slot-scope="{data}">
<identification-verification-component section="identificationVerificationSection" :data="data"></identification-verification-component>
</template>
</list-component>
</div>
</div>
</div>
</div>
<div class="row no-margin">
<div class="col">
<list-component key="2" section="identificationVerificationSection" :options="{'per_page': 5, 'document_type_in': ['SSM_REGISTRATION', 'IDENTITY_CARD'], 'status': 1, 'with_company': true}" :endpoint="route('api.document.list')">
<template slot="list" slot-scope="{data}">
<identification-verification-component section="identificationVerificationSection" :data="data"></identification-verification-component>
</template>
</list-component>
</div>
</div>
<div class="row p-b-5 b-b b-grey m-b-10 m-l-0 m-r-0">
<div class="col no-padding">
<h6>Address Change Verification</h6>
</div>
</div>
<div class="row no-margin">
<div class="col">
<list-component key="2" section="addressVerificationSection" :options="{'per_page': 5, 'status': 1, 'with_owner': true}" :endpoint="route('api.address.list')">
<template slot="list" slot-scope="{data}">
<address-verification-component section="addressVerificationSection" :data="data"></address-verification-component>
</template>
</list-component>
<div class="col-4">
<div class="row p-b-5 b-b b-grey m-b-10 m-l-0 m-r-0">
<div class="col no-padding">
<h6>Address Change Verification</h6>
</div>
</div>
<div class="row no-margin">
<div class="col">
<list-component key="2" section="addressVerificationSection" :options="{'per_page': 10, 'status': 1, 'with_owner': true}" :endpoint="route('api.address.list')">
<template slot="list" slot-scope="{data}">
<address-verification-component section="addressVerificationSection" :data="data"></address-verification-component>
</template>
</list-component>
</div>
</div>
</div>
</div>
</div>
@@ -0,0 +1,128 @@
@extends('layouts.base_portal')
@section('inner_content')
<div class="row">
<div class="col">
<div class="row">
<div class="col-12 col-sm-12 col-md-9">
<div class="row m-b-15 m-l-5 m-r-10">
<div class="col b-a b-grey rounded bg-master-light">
<div class="row">
<div class="col padding-20">
<div class="row align-items-center justify-conten-center">
<div class="col-auto pointer">
<i class="fa fs-30 fa-fw fa-square-o"></i>
</div>
<div class="col">
<h5 class="no-margin font-heading">Invoice No</h5>
</div>
<div class="col">
<h5 class="no-margin">Invoice Date</h5>
</div>
<div class="col">
<h5 class="no-margin">Status</h5>
</div>
<div class="col">
<h5 class="no-margin">Amount</h5>
</div>
<div class="col-auto invisible">
<div class="btn btn-default no-border">
<i class="fa fa-angle-up"></i>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<list-component section="containerListSection" :endpoint="route('api.address.district.list')">
<template slot="list" slot-scope="{data}">
<payments-billing-components :data="data"></payments-billing-components>
</template>
</list-component>
</div>
<div class="col-12 col-sm-12 col-md-3">
<div class="row align-items-center">
<div class="col b-a b-grey rounded padding-25">
<div class="row">
<div class="col">
<h6 class="semi-bold muted">Payment Summary</h6>
</div>
</div>
<div class="row align-items-center justify-content-center">
<div class="col-auto">
<div class="padding-5">
<i class="fa fa-angle-up"></i>
</div>
</div>
<div class="col p-l-0">
<h6 class="semi-bold text-primary">2 Invoice Selected</h6>
</div>
</div>
<div class="row">
<div class="col">
<div class="row">
<div class="col-auto">
<h6 class="no-margin">x1</h6>
</div>
<div class="col">
<h6 class="no-margin">lorem ipsum</h6>
</div>
<div class="col-auto">
<h6 class="no-margin">52x62x635 CM</h6>
</div>
</div>
<div class="row">
<div class="col-auto">
<h6 class="no-margin">x1</h6>
</div>
<div class="col">
<h6 class="no-margin">lorem ipsum</h6>
</div>
<div class="col-auto">
<h6 class="no-margin">52x62x635 CM</h6>
</div>
</div>
</div>
</div>
<hr>
<div class="row">
<div class="col">
<h6 class="normal m-t-5 m-b-5">Shipping Fee</h6>
</div>
<div class="col-auto">
<h6 class="normal m-t-5 m-b-5">RM 212.15</h6>
</div>
</div>
<div class="row">
<div class="col">
<h6 class="normal m-t-5 m-b-5">Serrvice Fee</h6>
</div>
<div class="col-auto">
<h6 class="normal m-t-5 m-b-5">RM 41.25</h6>
</div>
</div>
<div class="row">
<div class="col">
<h6 class="normal m-t-5 m-b-5">Discount</h6>
</div>
<div class="col-auto">
<h6 class="normal m-t-5 m-b-5">RM 0.00</h6>
</div>
</div>
<hr>
<div class="row">
<div class="col">
<h6 class="normal">Total Payments</h6>
</div>
<div class="col-auto">
<h6 class="text-primary bold">RM 3300.00</h6>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
@endsection
@@ -0,0 +1,120 @@
@extends('layouts.base_portal')
@section('inner_content')
<div class="row">
<div class="col-12 col-sm-12 col-md-8">
<div class="row h-100 padding-15">
<div class="col rounded bg-master-lighter">
<div class="row align-items-center h-100 padding-20">
<div class="col">
<h2><span class="normal">Shipping ID:</span> 05052021-25-0100</h2>
</div>
</div>
</div>
</div>
</div>
<div class="col-12 col-sm-12 col-md-4">
<div class="row h-100 padding-15">
<div class="col rounded bg-master-lighter padding-20">
<h6 class="normal">Discount Code</h6>
<div class="row">
<div class="col bg-master-lightest rounded m-l-20 m-r-20 padding-15">
<div class="row align-items-center">
<div class="col">
<h6>Free 10</h6>
</div>
<div class="col-auto">
<div class="btn rounded bg-master-light">Removed</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-12 col-sm-12 col-md-8">
<list-component section="containerListSection" :endpoint="route('api.address.district.list')">
<template slot="list" slot-scope="{data}">
<shipping-queue-components :data="data"></shipping-queue-components>
</template>
</list-component>
</div>
<div class="col-12 col-sm-12 col-md-4">
<div class="row padding-15">
<div class="col rounded p-l-20 p-r-20">
<div class="row">
<div class="col bg-master-light rounded padding-30">
<div class="row">
<div class="col">
<h3 class="normal">Shipping cost estimation</h3>
</div>
</div>
<div class="row">
<div class="col m-t-10 m-b-10">
<div class="row">
<div class="col">
<h5 class="m-t-0 m-b-5">Shipping Cost: RM8400</h5>
</div>
</div>
<div class="row">
<div class="col">
<h5 class="m-t-0 m-b-5">SST(6%): RM600</h5>
</div>
</div>
<div class="row">
<div class="col">
<h5 class="m-t-0 m-b-5">Discount: RM100</h5>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col">
<div class="row">
<div class="col">
<h5 class="no-margin">Total Cost: </h5>
</div>
</div>
<div class="row">
<div class="col">
<h4 class="no-margin normal">RM7300</h4>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col p-t-20 p-b-20">
<div class="row align-items-center">
<div class="col">
<div class="row">
<div class="col">
<p class="no-margin normal-text">Group my products with same destination</p>
</div>
</div>
<div class="row">
<div class="col">
<p class="no-margin normal-text">You will get grouped package at once if possible</p>
</div>
</div>
</div>
<div class="col-auto">
<div class="btn bg-master-light"><i class="fa fa-check lightest"></i></div>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col">
<div class="btn w-100 bg-master text-white p-t-15 p-b-15 large-text">
Checkout
</div>
</div>
</div>
</div>
</div>
</div>
</div>
@endsection
File diff suppressed because one or more lines are too long
+49 -1
View File
@@ -107,6 +107,54 @@
}
}
},
"/packing_list/container/inbound-custom-cleared": {
"get": {
"tags": [
"Packing"
],
"produces": [
"application/json"
],
"operationId": "listPackingIn",
"summary": "List packing",
"description": "",
"parameters": [
{
"name": "filter",
"in": "query",
"description": "Filters",
"required": false,
"type": "array",
"items": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "successful operation",
"headers": {
"X-Expires-After": {
"type": "string",
"format": "date-time",
"description": "date in UTC when token expires"
},
"X-Rate-Limit": {
"type": "integer",
"format": "int32",
"description": "calls per hour allowed by the user"
}
},
"schema": {
"type": "string"
}
},
"422": {
"description": "Invalid input supplied"
}
}
}
},
"/packing_list/list": {
"get": {
"tags": [
@@ -2982,7 +3030,7 @@
}
}
},
"/account/registration/registration": {
"/account/registration": {
"post": {
"tags": [
"Account",
+2
View File
@@ -50,5 +50,7 @@ Route::group(['middleware' => 'api', 'prefix' => 'v1', 'as' => 'api.'], function
require __DIR__ . '/schedule.php';
Route::get('/report', 'Reports\MonthlyReportController@report')->name('report');
});
});
+1
View File
@@ -30,6 +30,7 @@ Route::group(['namespace' => 'PackingLists', 'as' => 'packing_list.', 'prefix' =
Route::post('/create', 'CreatePackageController@create')->name('create');
Route::put('/update/{id}', 'UpdatePackageController@update')->name('update');
Route::delete('/delete/{id}', 'DeletePackageController@delete')->name('delete');
Route::get('/inbound-custom-cleared', 'InboundCustomClearedController@list')->name('list.inbound.custom.cleared');
Route::put('/switch-packing-list/{id}', 'SwitchPackagePackingListController@switch')->name('switch.packing_list');
Route::group(['namespace' => 'PackageItems', 'prefix' => 'item', 'as' => 'item.'], function () {
+70 -9
View File
@@ -5,9 +5,11 @@ use App\Classes\Jobs\FetchDeliveryListFromVTPortalJob;
use App\Classes\Jobs\FetchLoadedContainersFromVTPortalJob;
use App\Classes\Jobs\FetchPackingListFromVTPortalJob;
use App\Classes\Jobs\FetchWarehouseReceiveListFromVTPortalJob;
use App\Classes\Modules\Orders\Services\FetchesDataFromVTPortal;
use App\Models\CompanyConnection;
use App\Models\Container;
use App\Models\Order;
use Illuminate\Support\Facades\Crypt;
use App\Models\Container;
use Illuminate\Support\Facades\Route;
/*
@@ -52,6 +54,10 @@ Route::get('/dashboard', function () {
return view('pages.dashboard');
})->name('dashboard');
Route::get('/customers', function () {
return view('pages.admin.customers');
})->name('customers');
Route::get('/orders', function () {
return view('pages.orders.index');
})->name('orders');
@@ -114,12 +120,67 @@ Route::get('/deliveries/refresh', function(){
Route::get('/order/{id}/download', 'Orders\DownloadOrderQrPdfController@download')->name('order.qr.download');
//Route::get('/test', function(){
// $addresses = \App\Models\Address::all();
// foreach ($addresses as $address){
// $address->street_one = (new \App\Classes\Modules\Addresses\Services\CleansOldAddress())->cleanAddress($address->street_one, $address->district, $address->postcode);
// $address->street_two = (new \App\Classes\Modules\Addresses\Services\CleansOldAddress())->cleanAddress($address->street_two, $address->district, $address->postcode);
// $address->save();
// }
//})->name('test');
Route::get('/report/customclearance', 'Reports\CustomcClearanceReportController@download')->name('report.customclearance');
Route::get('/report/customclearance/{orderid}', 'Reports\CustomcClearanceReportController@download')->name('report.customclearance');
Route::group(['prefix' => 'template', 'as' => 'template.'], function () {
Route::get('/payments-and-billing', function () {
return view('pages.templates.paymentsBilling');
})->name('payments-and-billing');
Route::get('/shipping-queue', function () {
return view('pages.templates.shippingQueue');
})->name('shipping-queue');
});
Route::get('/report', function(){
$containers = Container::whereMonth('loading_date', '=', '09')->whereYear('loading_date', '=', '2021')->orderBy('loading_date')->get();
$total = 0;
$customers = collect();
foreach ($containers as $container){
echo '<b>'.$container->reference.': </b>'.$container->packingLists->sum(function($packingList){
return $packingList->packages->sum(function ($package){
return (( (float) $package->width / 100) * ( (float) $package->length / 100) * ( (float) $package->height / 100)) * $package->quantity;
});
}).'CBM ('. $container->loading_date->format('d-m-Y') .')<br><br>';
foreach($container->packingLists as $packingList){
$cbm = $packingList->packages->sum(function ($package){
return (( (float) $package->width / 100) * ( (float) $package->length / 100) * ( (float) $package->height / 100)) * $package->quantity;
});
$total += $cbm;
$marking = $packingList->owner->companyModule->inviters()->withPivot('invitee_reference')->first()->pivot->invitee_reference;
if(!$customers->has($marking)){
$customers->put($marking, collect([
'cbm' => $cbm,
'orders' => 1,
'packages' => $packingList->packages->sum('quantity')
]));
continue;
}
$customers[$marking]['cbm'] += $cbm;
$customers[$marking]['orders'] += 1;
$customers[$marking]['packages'] += $packingList->packages->sum('quantity');
}
}
echo '<h1><b>total cbm:</b> '. $total . '</h1>';
echo '<h1><b>active customers:</b> '. count($customers) . '</h1><br><br>';
$i = 1;
foreach ($customers->sortByDesc(function($customer){
return $customer['cbm'];
}) as $marking => $customer) {
echo '<b>'.$i.'. '.$marking.': </b>'.$customer['cbm'].' CBM ('. $customer['orders'] .' - '.$customer['packages'].' ) CTNS <br><br>';
$i++;
}
});