Merge branch 'development' into 'transaction-invoice'

# Conflicts:
#   app/Classes/Modules/Transactions/ControllersLogic/CreateShippingInvoiceTransactionLogic.php
This commit is contained in:
omair saleh
2022-03-24 05:18:17 +00:00
27 changed files with 663 additions and 105 deletions
@@ -1,20 +0,0 @@
<?php
namespace App\Classes\General\Eloquent\Filters;
use Illuminate\Database\Eloquent\Builder;
class OwnerId implements Filter
{
/**
* @param Builder $builder
* @param $value
* @return Builder|mixed
*/
public static function apply(Builder $builder, $value)
{
return $builder->where('owner_id', $value);
}
}
@@ -181,16 +181,38 @@ class FetchOrderListsFromYdPortalProcessor
$eta = Carbon::parse($tracking[2]);
}
if (strpos($trackingRow->tracking, '预计船时间为') !== false) {
$tracking = explode('预计船时间为', $trackingRow->tracking);
$delayDate = Carbon::parse(explode('日', $tracking[1])[0]);
$rescheduleETD = strpos($trackingRow->remark, '') || strpos($trackingRow->remark, '到港');
$rescheduleETA = strpos($trackingRow->remark, '到港');
if (($rescheduleETD !== false || $rescheduleETA !== false) && strpos($trackingRow->tracking, '货物装柜完成。') === false) {
preg_match_all('/([0-9]+.{3})/', $trackingRow->remark, $matches);
$dates = collect();
foreach($matches[0] as $date){
try {
$dates->push(Carbon::parse(str_replace('.', '/', $date).Carbon::now()->format('Y')));
} catch (\Exception $exception) {
continue;
}
}
$rescheduleDate = $dates->sortDesc()->first();
if(!$delayDate || $rescheduleDate > $delayDate){
/** @var Carbon $delayDate */
$delayDate = $rescheduleDate;
if($rescheduleETA === false && $delayDate) {
$delayDate = $delayDate->addDays('5');
}
}
}
if (strpos($trackingRow->tracking, '预计开船') !== false) {
$tracking = explode('预计开船为', $trackingRow->tracking);
$delayDate = Carbon::parse(explode('日', $tracking[1])[0]);
if ($trackingRow->tracking === '开船') {
$delayDate = Carbon::parse($trackingRow->trackingtime)->addDays('5');
}
if ($trackingRow->tracking === '货物已进目的港仓库') {
$unstuffingDate = Carbon::parse($trackingRow->trackingtime);
}
@@ -344,7 +366,7 @@ class FetchOrderListsFromYdPortalProcessor
$transport = $container->transports()->first();
if(!$transport->schedules()->where('eta', '=', $delayDate)->first()) {
if(!$transport->schedules()->whereDate('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));
@@ -76,7 +76,7 @@ class UpdateConstantLogic extends AbstractControllerLogic
public function logic(Request $request) : JsonResponse
{
$object = new ConstantObject($request->input('name'), $request->input('reference'), $request->input('detail'));
$object = new ConstantObject($request->input('reference'), $request->input('value'));
$segment = $this->fetchesSegment->execute(['id' => $request->route('id')]);
@@ -0,0 +1,99 @@
<?php
namespace App\Classes\Modules\Segments\ControllersLogic;
use Illuminate\Http\Request;
use Illuminate\Http\JsonResponse;
use App\Http\Resources\ConstantResource;
use App\Classes\ValueObjects\Constants\SegmentConstants;
use App\Classes\Modules\Segments\Services\FetchesSegment;
use App\Classes\General\Abstracts\AbstractControllerLogic;
use App\Classes\Modules\Segments\Services\FetchesConstant;
use App\Classes\Modules\Segments\Services\UpdatesConstant;
use App\Classes\Modules\Segments\Standards\Rules\CanUpdateConstant;
use App\Classes\Modules\Segments\DataTransferObjects\ConstantObject;
use App\Classes\Modules\Segments\Services\AddItemToConstantValueArray;
use App\Classes\Modules\Segments\Services\RemoveItemFromConstantValueArray;
class UpdateConstantPostcodeLogic extends AbstractControllerLogic
{
/**
* @return array
*/
protected function notification():array {
return [
'title' => 'Updated Segment Constant',
'message' => 'You have successfully updated the Segment Constant'
];
}
/** @var CanUpdateConstant */
private $canUpdateConstant;
/** @var UpdatesConstant */
private $updatesConstant;
/** @var FetchesSegment */
private $fetchesSegment;
/** @var FetchesConstant */
private $fetchesConstant;
/** @var AddItemToConstantValueArray */
private $addItemToConstantValueArray;
/** @var RemoveItemFromConstantValueArray */
private $removeItemFromConstantValueArray;
/**
* UpdateConstantLogic constructor.
* @param CanUpdateConstant $canUpdateConstant
* @param UpdatesConstant $updatesConstant
* @param FetchesSegment $fetchesSegment
* @param FetchesConstant $fetchesConstant
* @param AddItemToConstantValueArray $addItemToConstantValueArray
* @param RemoveItemFromConstantValueArray $removeItemFromConstantValueArray
*/
public function __construct(CanUpdateConstant $canUpdateConstant, UpdatesConstant $updatesConstant, FetchesSegment $fetchesSegment, FetchesConstant $fetchesConstant,AddItemToConstantValueArray $addItemToConstantValueArray, RemoveItemFromConstantValueArray $removeItemFromConstantValueArray)
{
$this->canUpdateConstant = $canUpdateConstant;
$this->updatesConstant = $updatesConstant;
$this->fetchesSegment = $fetchesSegment;
$this->fetchesConstant = $fetchesConstant;
$this->addItemToConstantValueArray = $addItemToConstantValueArray;
$this->removeItemFromConstantValueArray = $removeItemFromConstantValueArray;
}
/**
* @param Request $request
* @return JsonResponse
* @throws \App\Classes\Exceptions\AccessForbiddenException
* @throws \App\Classes\Exceptions\MalformedRequestException
* @throws \App\Classes\Exceptions\RequestValidationException
*/
public function logic(Request $request) : JsonResponse
{
$segment = $this->fetchesSegment->execute(['id' => $request->route('id')]);
$constant = $this->fetchesConstant->execute(['segment_id' => $segment->id, 'reference' => $request->input('reference')]);
$object = new ConstantObject($constant->reference, $this->addItemToConstantValueArray->execute($constant->value, $request->input('postcode')));
$this->canUpdateConstant->passes($object);
$constant = $this->updatesConstant->execute($constant, $object);
$oppositeConstant = $this->fetchesConstant->execute(['segment_id' => $segment->id, 'reference' => $request->input('reference') == SegmentConstants::CENTER_POSTCODE ? SegmentConstants::OUTSTATION_POSTCODE : SegmentConstants::CENTER_POSTCODE]);
$oppositeObject = new ConstantObject($request->input('reference') == SegmentConstants::CENTER_POSTCODE ? SegmentConstants::OUTSTATION_POSTCODE : SegmentConstants::CENTER_POSTCODE, $this->removeItemFromConstantValueArray->execute($oppositeConstant->value, $request->input('postcode')));
$oppositeConstant = $this->updatesConstant->execute($oppositeConstant, $oppositeObject);
return $this->response([
'CENTER_POSTCODE' => $constant->reference == SegmentConstants::CENTER_POSTCODE ? new ConstantResource($constant) : New ConstantResource($oppositeConstant),
'OUTSTATION_POSTCODE' => $constant->reference == SegmentConstants::OUTSTATION_POSTCODE ? new ConstantResource($constant) : New ConstantResource($oppositeConstant),
]);
}
}
@@ -0,0 +1,87 @@
<?php
namespace App\Classes\Modules\Segments\ControllersLogic;
use Illuminate\Http\Request;
use App\Models\SegmentConstant;
use Illuminate\Http\JsonResponse;
use App\Http\Resources\ConstantResource;
use App\Classes\ValueObjects\Constants\SegmentConstants;
use App\Classes\Modules\Segments\Services\FetchesSegment;
use App\Classes\General\Abstracts\AbstractControllerLogic;
use App\Classes\Modules\Segments\Services\FetchesConstant;
use App\Classes\Modules\Segments\Services\UpdatesConstant;
use App\Classes\Modules\Segments\Standards\Rules\CanUpdateConstant;
use App\Classes\Modules\Segments\DataTransferObjects\ConstantObject;
use App\Classes\Modules\Segments\Services\UpdatesConstantValueByState;
class UpdateConstantStateLogic extends AbstractControllerLogic
{
/**
* @return array
*/
protected function notification():array {
return [
'title' => 'Updated Segment Constant',
'message' => 'You have successfully updated the Segment Constant'
];
}
/** @var CanUpdateConstant */
private $canUpdateConstant;
/** @var UpdatesConstant */
private $updatesConstant;
/** @var FetchesSegment */
private $fetchesSegment;
/** @var FetchesConstant */
private $fetchesConstant;
/** @var UpdatesConstantValueByState */
private $updatesConstantValueByState;
/**
* UpdateConstantLogic constructor.
* @param CanUpdateConstant $canUpdateConstant
* @param UpdatesConstant $updatesConstant
* @param FetchesSegment $fetchesSegment
* @param FetchesConstant $fetchesConstant
* @param UpdatesConstantValueByState $updatesConstantValueByState
*/
public function __construct(CanUpdateConstant $canUpdateConstant, UpdatesConstant $updatesConstant, FetchesSegment $fetchesSegment, FetchesConstant $fetchesConstant,UpdatesConstantValueByState $updatesConstantValueByState)
{
$this->canUpdateConstant = $canUpdateConstant;
$this->updatesConstant = $updatesConstant;
$this->fetchesSegment = $fetchesSegment;
$this->fetchesConstant = $fetchesConstant;
$this->updatesConstantValueByState = $updatesConstantValueByState;
}
/**
* @param Request $request
* @return JsonResponse
* @throws \App\Classes\Exceptions\AccessForbiddenException
* @throws \App\Classes\Exceptions\MalformedRequestException
* @throws \App\Classes\Exceptions\RequestValidationException
*/
public function logic(Request $request) : JsonResponse
{
$segment = $this->fetchesSegment->execute(['id' => $request->route('id')]);
$constant = $this->fetchesConstant->execute(['segment_id' => $segment->id, 'reference' => SegmentConstants::STATE_RATE]);
$constantValue = $this->updatesConstantValueByState->execute($constant->value, $request->input('status_id'), $request->input('rate'));
$object = new ConstantObject(SegmentConstants::STATE_RATE, (array) $constantValue);
$this->canUpdateConstant->passes($object);
$constant = $this->updatesConstant->execute($constant, $object);
return $this->resourceResponse(new ConstantResource($constant));
}
}
@@ -7,34 +7,22 @@ use App\Classes\General\Interfaces\DataTransferObject;
class ConstantObject implements DataTransferObject
{
/** @var string */
private $name;
/** @var string */
private $reference;
/** @var array */
private $detail;
private $value;
/**
* ConstantObject constructor.
* @param string $name
* @param string $reference
* @param array $detail
* @param array $value
*/
public function __construct(string $name, string $reference, array $detail)
public function __construct(string $reference, array $value)
{
$this->name = $name;
$this->reference = $reference;
$this->detail = $detail;
}
/**
* @return string
*/
public function getName(): string
{
return $this->name;
$this->value = $value;
}
/**
@@ -48,9 +36,9 @@ class ConstantObject implements DataTransferObject
/**
* @return array
*/
public function getDetail(): array
public function getValue(): array
{
return $this->detail;
return $this->value;
}
@@ -0,0 +1,19 @@
<?php
namespace App\Classes\Modules\Segments\Services;
class AddItemToConstantValueArray
{
/**
* @param array $array
* @param $item
* @return array
*/
public function execute($array, $item): array {
$array[] = $item;
sort($array);
return $array;
}
}
@@ -27,11 +27,11 @@ class ConvertsConstantDetailsToResource
public function execute(SegmentConstant $constant){
if($constant->reference === SegmentConstants::SUPPLIER_CURRENCIES) {
return property_exists($constant->detail, 'id') ? new CurrencyResource($this->fetchesCurrency->execute(['id' => $constant->detail->id])) : '';
}
// if($constant->reference === SegmentConstants::SUPPLIER_CURRENCIES) {
// return property_exists($constant->detail, 'id') ? new CurrencyResource($this->fetchesCurrency->execute(['id' => $constant->detail->id])) : '';
// }
return $constant->detail;
return $constant->value;
}
@@ -18,9 +18,8 @@ class CreatesConstant extends AbstractUpdateRelationshipRecord
public function execute(Segment $segment, ConstantObject $object)
{
$model = new SegmentConstant();
$model->name = $object->getName();
$model->reference = $object->getReference();
$model->detail = json_encode($object->getDetail());
$model->value = json_encode($object->getValue());
return $this->handler($segment->constants(), $model);
}
@@ -0,0 +1,22 @@
<?php
namespace App\Classes\Modules\Segments\Services;
class RemoveItemFromConstantValueArray
{
/**
* @param array $array
* @param $item
* @return array
*/
public function execute($array, $item): array {
foreach($array as $key => $value){
if($array[$key] == $item){
unset($array[$key]);
}
}
return array_values($array);
}
}
@@ -17,9 +17,8 @@ class UpdatesConstant extends AbstractUpdateRecord
*/
public function execute(SegmentConstant $model, ConstantObject $object)
{
$model->name = $object->getName();
$model->reference = $object->getReference();
$model->detail = json_encode($object->getDetail());
$model->value = json_encode($object->getValue());
return $this->handler($model);
}
@@ -0,0 +1,32 @@
<?php
namespace App\Classes\Modules\Segments\Services;
class UpdatesConstantValueByState
{
/**
* @param $json
* @param int $status_id
* @param int $rate
* @return string
*/
public function execute($json, int $status_id, int $rate) {
$newArray = $json;
foreach($json->config as $key => $object){
if($object->status_id == $status_id){
$newArray->config[$key] = (object) [
'rate' => $rate,
'status_id' => $object->status_id,
'outstation_rate' => $object->outstation_rate,
];
}else{
$newArray->config[$key] = $object;
}
}
return $newArray;
}
}
@@ -15,9 +15,8 @@ class ConstantValidation extends AbstractValidation
protected function data($object): array {
$data = [
'name' => $object->getName(),
'reference' => $object->getReference(),
'detail' => $object->getDetail()
'value' => $object->getValue()
];
return $data;
@@ -28,9 +27,8 @@ class ConstantValidation extends AbstractValidation
*/
protected function rules(): array {
return [
'name' => 'required',
'reference' => 'required',
'detail' => 'required'
'value' => 'required'
];
}
@@ -24,7 +24,7 @@ class DownloadOrderQrPdfController
$warehousePrefix = '';
$deliveryPrefix = '';
$customerMarking = '';
$remark = $warehouse->remarks()->first()->content;
$remark = $warehouse->remarks()->first();
if($warehouse->reference === WarehouseReferences::VT_GUANG_ZHOU || $warehouse->reference === WarehouseReferences::VT_YIWU) {
$customerMarking = $order->companyModule->connections()->first()->invitee_reference.'/';
@@ -44,11 +44,11 @@ class DownloadOrderQrPdfController
if($warehouse->reference === WarehouseReferences::YD_GUANG_ZHOU){
$warehousePrefix = 'YD/';
if(strtolower($deliveryAddress->state->name) === 'sabah' || strtolower($deliveryAddress->state->name) === 'labuan') {
if(strtolower($deliveryAddress->state->name) === 'sabah' || strtolower($deliveryAddress->state->name) === 'labuan' || in_array(strtolower($deliveryAddress->district->name), ['limbang', 'lawas'])) {
$warehousePrefix = 'KK/';
}
if(strtolower($deliveryAddress->state->name) === 'sarawak') {
if(strtolower($deliveryAddress->state->name) === 'sarawak' && !in_array(strtolower($deliveryAddress->district->name), ['limbang', 'lawas'])) {
$warehousePrefix = 'KU/';
}
}
@@ -60,7 +60,7 @@ class DownloadOrderQrPdfController
'delivery_address' => $deliveryAddress,
'warehouse_address' => $warehouseAddress,
'warehouse_contacts' => $warehouseContacts,
'remark' => $remark
'remark' => $remark ? $remark->content : ''
];
$pdf = LaravelMpdf::loadView('pdfs.qr', $data, [], [
@@ -200,4 +200,62 @@ class MonthlyReportController
})->sum('quantity'),
]]))->handler();
}
public function customerActivityReport(Request $request): JsonResponse {
$active_start = $request->input('active_start');
$active_end = $request->input('active_end');
$inactive_start = $request->input('inactive_start');
$inactive_end = $request->input('inactive_end');
$minCbm = $request->input('cbm');
$minOrders = $request->input('minOrders');
$activeCompanies = CompanyModule::where('type', \App\Classes\ValueObjects\Constants\BusinessType::IMPORTER)->whereHas('orderPackingLists', function($query) use($inactive_start, $inactive_end) {
return $query->where('packing_lists.type', \App\Classes\ValueObjects\Constants\PackingListType::WAREHOUSE_RECEIVE_LIST)->whereHas('transports', function ($query) use ($inactive_start, $inactive_end) {
return $query->where('drop_date', '>=', \Carbon\Carbon::parse($inactive_start))->where('drop_date', '<=', \Carbon\Carbon::parse($inactive_end)->addDay());
});
})->pluck('id');
$companies = CompanyModule::where('type', \App\Classes\ValueObjects\Constants\BusinessType::IMPORTER)->whereHas('orderPackingLists', function($query) use($active_start, $active_end) {
return $query->where('packing_lists.type', \App\Classes\ValueObjects\Constants\PackingListType::WAREHOUSE_RECEIVE_LIST)->whereHas('transports', function ($query) use ($active_start, $active_end) {
return $query->whereDate('drop_date', '>=', \Carbon\Carbon::parse($active_start))->whereDate('drop_date', '<=', \Carbon\Carbon::parse($active_end)->addDay());
});
})->whereNotIn('id', $activeCompanies)->get();
$customerActivityData = [];
$counter = 1;
foreach ($companies as $key => $company){
$connection = $company->inviters()->withPivot('invitee_reference')->first();
$marking = $connection ? $connection->pivot->invitee_reference:'';
$packingList = $company->orderPackingLists()->where('packing_lists.type', \App\Classes\ValueObjects\Constants\PackingListType::SHIPPING_PACKING_LIST)->get();
$totalCbm = $packingList->flatMap(function ($packingList) {
return $packingList->packages;
})->sum(function($package){
return (( (float) $package->width / 100) * ( (float) $package->length / 100) * ( (float) $package->height / 100)) * $package->quantity;
});
if ($minCbm != 'null' && $totalCbm < $minCbm) { continue; }
if ($minOrders != 'null' && $packingList->count() < $minOrders) { continue; }
array_push($customerActivityData, array(
'key' => $counter,
'marking' => $marking,
'packingListCount'=> $packingList->count(),
'totalCbm'=> $totalCbm,
));
$counter ++;
}
return (new ApiResponseObject('fetch service report Successful',
'',
HttpStatus::OK_WITH_MESSAGE, ['data' => [
'active_start' => Carbon::parse($active_start)->format('d/m/Y'),
'active_end' => Carbon::parse($active_end)->format('d/m/Y'),
'inactive_start' => Carbon::parse($inactive_start)->format('d/m/Y'),
'inactive_end' => Carbon::parse($inactive_end)->format('d/m/Y'),
'customerActivityData' => $customerActivityData,
]]))->handler();
}
}
@@ -0,0 +1,20 @@
<?php
namespace App\Http\Controllers\Segments;
use App\Classes\Modules\Segments\ControllersLogic\UpdateConstantPostcodeLogic;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
class UpdateConstantPostcodeController
{
/**
* @param Request $request
* @param UpdateConstantPostcodeLogic $logic
* @return JsonResponse
*/
public function update(Request $request, UpdateConstantPostcodeLogic $logic): JsonResponse {
return $logic->execute($request);
}
}
@@ -0,0 +1,20 @@
<?php
namespace App\Http\Controllers\Segments;
use App\Classes\Modules\Segments\ControllersLogic\UpdateConstantStateLogic;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
class UpdateConstantStateController
{
/**
* @param Request $request
* @param UpdateConstantStateLogic $logic
* @return JsonResponse
*/
public function update(Request $request, UpdateConstantStateLogic $logic): JsonResponse {
return $logic->execute($request);
}
}
+1 -2
View File
@@ -19,9 +19,8 @@ class ConstantResource extends JsonResource
{
return [
'id' => $this->id,
'name' => $this->name,
'reference' => $this->reference,
'detail' => (App()->make(ConvertsConstantDetailsToResource::class))->execute($this->resource)
'value' => (App()->make(ConvertsConstantDetailsToResource::class))->execute($this->resource)
];
}
}
@@ -0,0 +1,145 @@
<template>
<div class="row m-b-20">
<div class="col">
<div class="row">
<div class="col">
<div class="row m-l-0 m-r-0 bg-master-light padding-10" @keyup.enter="submitSearch()">
<div class="col-12 col-md mb-2 mb-md-0">
<div class="row">
<div class="col p-r-0 h-100">
<validation-wrapper-component :validator="$v.numOrders">
<label class="all-caps">Number Of Orders</label>
<input class="form-control" v-model.lazy="numOrders">
</validation-wrapper-component>
</div>
<div class="col p-l-0 h-100">
<validation-wrapper-component :validator="$v.cbm">
<label class="all-caps">CBM</label>
<input class="form-control" v-model.lazy="cbm">
</validation-wrapper-component>
</div>
</div>
</div>
<div class="col-12 col-md mb-2 mb-md-0">
<div class="row">
<div class="col p-r-0 h-100">
<validation-wrapper-component :validator="$v.activeDateFrom">
<label class="all-caps">Active Date From</label>
<date-picker-component v-model.lazy="activeDateFrom"></date-picker-component>
</validation-wrapper-component>
</div>
<div class="col p-l-0 h-100">
<validation-wrapper-component :validator="$v.activeDateTo">
<label class="all-caps">Active Date To</label>
<date-picker-component v-model.lazy="activeDateTo"></date-picker-component>
</validation-wrapper-component>
</div>
</div>
</div>
<div class="col-12 col-md mb-2 mb-md-0">
<div class="row">
<div class="col p-r-0 h-100">
<validation-wrapper-component :validator="$v.inactiveDateFrom">
<label class="all-caps">Inactive Date From</label>
<date-picker-component v-model.lazy="inactiveDateFrom"></date-picker-component>
</validation-wrapper-component>
</div>
<div class="col p-l-0 h-100">
<validation-wrapper-component :validator="$v.inactiveDateTo">
<label class="all-caps">Inactive Date To</label>
<date-picker-component v-model.lazy="inactiveDateTo"></date-picker-component>
</validation-wrapper-component>
</div>
</div>
</div>
<div class="col-12 col-md-auto mb-2 mb-md-0">
<div class="row h-100">
<div class="col p-r-0 h-100">
<div class="btn btn-primary b-rad-none w-100 h-100 d-flex justify-content-center align-items-center p-l-30 p-r-30" @click="submitSearch()">
Search
</div>
</div>
<div class="col p-l-0 h-100">
<div class="btn btn-secondary b-rad-none w-100 h-100 d-flex justify-content-center align-items-center p-l-30 p-r-30" @click="resetSearch()">
Reset
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<loading-component style="height: 100%; top: 0;" key="1" color="success" v-show="isLoading"></loading-component>
<div class="row" v-show="!isLoading" v-if="activityData">
<div class="col">
<h4>List of customers active between <span style="color: green; font-weight: bold">{{ activityData.active_start }} - {{ activityData.active_end }}</span> & inactive between <span style="color: red; font-weight: bold">{{ activityData.active_start }} - {{ activityData.active_end }}</span></h4>
<table>
<tr>
<th>#</th>
<th>marking</th>
<th>Number of Orders</th>
<th>CBM</th>
</tr>
<tr v-for="item in activityData.customerActivityData" >
<td>{{item.key}}</td>
<td><a :href="route('customer.profile', item.marking)" target="_blank">{{ item.marking }}</a></td>
<td>{{ item.packingListCount }}</td>
<td>{{ item.totalCbm }} </td>
</tr>
</table>
</div>
</div>
</div>
</div>
</template>
<script>
import componentHandler from "../../../general/mixins/componentHandler";
import { required } from "vuelidate/lib/validators";
export default {
data(){
return {
section: 'customerActivityReportSection',
isLoading: false,
cbm: null,
numOrders: null,
activeDateFrom: '',
activeDateTo: '',
inactiveDateFrom: '',
inactiveDateTo: '',
activityData: null,
}
},
methods: {
submitSearch(){
this.$store.dispatch('toggleSection', {name: this.section, status: true});
this.submit(route('api.report.customerActivity') + '?active_start=' + this.activeDateFrom + '&active_end=' + this.activeDateTo + '&inactive_start=' + this.inactiveDateFrom + '&inactive_end=' + this.inactiveDateTo + '&cbm=' + this.cbm + '&minOrders=' + this.numOrders, 'get', this.section, false, false);
this.isLoading = true;
},
resetSearch() {
this.$store.dispatch('toggleSection', {name: this.section, status: false});
this.cbm = null;
this.numOrders = null;
this.activeDateFrom = '';
this.activeDateTo = '';
this.inactiveDateFrom = '';
this.inactiveDateTo = '';
this.activityData = null;
},
successHandler(response){
this.activityData = response.payload.data;
this.isLoading = false;
}
},
validations: {
cbm: { },
numOrders: { },
activeDateFrom: { required },
activeDateTo: { required },
inactiveDateFrom: { required },
inactiveDateTo: { required }
},
mixins: [componentHandler]
};
</script>
@@ -15,7 +15,7 @@
</div>
<div class="row">
<div class="col">
<div class="font-heading all-caps">{{data.name}}</div>
<div class="font-heading all-caps">{{data.reference}}</div>
</div>
</div>
</div>
+35 -30
View File
@@ -2,37 +2,42 @@
@section('inner_content')
<div class="row">
<div class="col">
<customer-report-section-component></customer-report-section-component>
<div class="row d-none" :class="[{'d-flex': $store.getters.isAdmin}]" v-if="$store.getters.isAdmin">
<div class="col-6">
<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>
<customer-activity-report-section-component></customer-activity-report-section-component>
<div class="row" v-show="!$store.getters.isShowing('customerActivityReportSection')">
<div class="col">
<customer-report-section-component></customer-report-section-component>
<div class="row d-none" :class="[{'d-flex': $store.getters.isAdmin}]" v-if="$store.getters.isAdmin">
<div class="col-6">
<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 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 class="col-6">
<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 Without Confirmed Orders</h6>
</div>
</div>
<div class="row m-l-0 m-r-0">
<div class="col">
<list-component key="2" section="customerWithoutConfirmedOrdersListSection" :endpoint="route('api.company.list')" :options="{'has_business_module_type': 1, 'created_after': '18-09-2021','without_confirmed_orders': true}">
<template slot="list" slot-scope="{data}">
<company-component :data="data"></company-component>
</template>
</list-component>
<div class="col-6">
<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 Without Confirmed Orders</h6>
</div>
</div>
<div class="row m-l-0 m-r-0">
<div class="col">
<list-component key="2" section="customerWithoutConfirmedOrdersListSection" :endpoint="route('api.company.list')" :options="{'has_business_module_type': 1, 'created_after': '18-09-2021','without_confirmed_orders': true}">
<template slot="list" slot-scope="{data}">
<company-component :data="data"></company-component>
</template>
</list-component>
</div>
</div>
</div>
</div>
</div>
@@ -85,7 +85,7 @@
<div class="col">Delivery Date</div>
<div class="col text-right">Action</div>
</div>
<list-component section="activeContainerListSection" :endpoint="route('api.packing_list.list')" :options="{type: 2, 'packing_list_delivery_status': 1, 'per_page': 30}">
<list-component section="activeContainerListSection" :endpoint="route('api.packing_list.list')" :options="{packing_list_type: 2, 'packing_list_delivery_status': 1, with_arrival_date: true ,'per_page': 30, order_by: {column: 'arrival_date', DESC: true}}">
<template slot="list" slot-scope="{data}">
<warehouse-packing-list-component :data="data"></warehouse-packing-list-component>
</template>
@@ -103,7 +103,7 @@
<div class="col">status</div>
<div class="col">Delivery Date</div>
</div>
<list-component section="arrivedContainerListSection" :endpoint="route('api.packing_list.list')" :options="{type: 2, 'packing_list_delivery_status': 2,'per_page': 30}">
<list-component section="arrivedContainerListSection" :endpoint="route('api.packing_list.list')" :options="{packing_list_type: 2, 'packing_list_delivery_status': 2, with_arrival_date: true ,'per_page': 30, order_by: {column: 'arrival_date', DESC: true}}">
<template slot="list" slot-scope="{data}">
<warehouse-packing-list-component :data="data"></warehouse-packing-list-component>
</template>
@@ -121,7 +121,7 @@
<div class="col">status</div>
<div class="col">Delivery Date</div>
</div>
<list-component section="completeContainerListSection" :endpoint="route('api.packing_list.list')" :options="{type: 2, 'packing_list_delivery_status': 3, 'per_page': 30}">
<list-component section="completeContainerListSection" :endpoint="route('api.packing_list.list')" :options="{packing_list_type: 2, 'packing_list_delivery_status': 3, with_arrival_date: true ,'per_page': 30, order_by: {column: 'arrival_date', DESC: true}}">
<template slot="list" slot-scope="{data}">
<warehouse-packing-list-component :data="data"></warehouse-packing-list-component>
</template>
@@ -7,12 +7,14 @@
<h6>Arrived Parcel</h6>
</div>
</div>
<list-component section="warehouseListSection" :endpoint="route('api.packing_list.list')" :options="{packing_list_type: 1, packing_list_status: 2, per_page: 5, order_by: {column: 'arrival_date', DESC: true}, with_arrival_date: true}">
<list-component section="warehouseListSection" :endpoint="route('api.packing_list.list')" :options="{packing_list_type: 1, packing_list_status: 2, per_page: 20, order_by: {column: 'arrival_date', DESC: true}, with_arrival_date: true}" >
<template slot="list" slot-scope="{data}">
<parcel-component v-for="packages in data.packages" :data="packages" :key="packages.id"></parcel-component>
</template>
</list-component>
</div>
</div>
<div class="row">
<div class="col">
<div class="row p-b-5 b-b b-grey m-b-10 m-l-0 m-r-0">
<div class="col no-padding">
@@ -29,7 +31,7 @@
<div class="col">Delivery Date</div>
<div class="col"></div>
</div>
<list-component section="onHoldParcel" :endpoint="route('api.packing_list.list')" :options="{status_in: [5, 0], per_page: 5}">
<list-component section="onHoldParcel" :endpoint="route('api.packing_list.list')" :options="{status_in: [5], packing_list_type: 2, per_page: 20}">
<template slot="list" slot-scope="{data}">
<warehouse-packing-list-component :data="data"></warehouse-packing-list-component>
</template>
+1 -1
View File
@@ -40,7 +40,7 @@
<p style="font-size: 30px; margin-bottom: 0 !important; margin-top: 10px !important;">仓库地址:</p>
<p style="margin-top: 5px !important; margin-bottom: 5px !important; word-wrap: break-word; font-size: 30px;">{{$warehouse_address->state->name.' '.$warehouse_address->district->name.' '.$warehouse_address->street_one.' '.$warehouse_address->street_two.' 邮编:'.$warehouse_address->postcode}}</p>
<p style="margin-top: 5px !important; margin-bottom: 0px !important; font-size: 30px;">联系:@foreach($warehouse_contacts as $contact){{ $loop->first ? '' : ' / ' }}{{ $contact->phone.' '.$contact->reference }}@endforeach</p>
<p style="margin-top: 5px !important; margin-bottom: 0px !important; font-size: 30px;">{{$remark}}</p>
<p style="margin-top: 5px !important; margin-bottom: 0px !important; font-size: 30px;">{!! $remark !!}</p>
</td>
</tr>
</tbody>
+2
View File
@@ -10,4 +10,6 @@ Route::group(['prefix' => 'report', 'as' => 'report.', 'namespace' => 'Reports']
Route::get('/profit/{model}/{value}/{from?}/{to?}', 'MonthlyReportController@profitModelReport')->name('profit');
Route::get('/service', 'MonthlyReportController@serviceReport')->name('service');
Route::get('/customers/active', 'MonthlyReportController@customerActivityReport')->name('customerActivity');
});
+2
View File
@@ -13,5 +13,7 @@ Route::group(['prefix' => 'segment', 'as' => 'segment.', 'namespace' => 'Segment
Route::put('/service/update', 'UpdateCustomServiceConstantController@update')->name('service.update');
Route::put('/update', 'UpdateConstantController@update')->name('update');
Route::get('/show/{reference}', 'FetchConstantController@fetch')->name('show');
Route::put('/update/state', 'UpdateConstantStateController@update')->name('update.state');
Route::put('/update/postcode', 'UpdateConstantPostcodeController@update')->name('update.postcode');
});
});
+64 -4
View File
@@ -239,6 +239,54 @@ Route::get('/settings', function () {
return view('pages.settings');
})->name('settings');
Route::get('/customer/summary/monthly', function () {
// $containers = Container::whereMonth('loading_date', 1)->where('owner_id', 3)->get();
$containers = Container::whereIn('reference', ['SM21-166', 'SM21-168', 'SM21-170', 'SM21-171', 'SM21-172', 'SM21-173', 'EPS-3833'])->get();
foreach ($containers as $container){
$packingLists = $container->packingLists()->get()->filter(function ($packingList) {
return $packingList->owner->company_module_id === 248;
});
if (!count($packingLists)) continue;
echo '<table>
<tr>
<th>Date</th>
<th>Full Marking</th>
<th>Container</th>
<th>Description</th>
<th>Ctns</th>
<th>L (cm)</th>
<th>H (cm)</th>
<th>W (cm)</th>
<th>CBM</th>
</tr>';
foreach ($packingLists as $packingList){
if($packingList->packingLists->first()){
$packingList = $packingList->packingLists->first();
}
$packages = $packingList->packages;
foreach ($packages as $package){
echo '<tr>
<td>-</td>
<td>MS/CIEF/769SMC/'.$packingList->owner->reference.'</td>
<td>'.$container->reference.'</td>
<td>'.$package->description.'</td>
<td>'.$package->quantity.'</td>
<td>'.$package->length.'</td>
<td>'.$package->height.'</td>
<td>'.$package->width.'</td>
<td>'.((($package->length / 100) * ($package->height / 100) * ($package->width / 100)) * $package->quantity).'</td>
</tr>';
}
}
echo '</table>';
}
});
Route::get('/customers/active/{active_start}/{active_end}/{inactive_start?}/{inactive_end?}/{with_cbm?}', function ($active_start, $active_end, $inactive_start=null, $inactive_end=null, $with_cbm = false) {
$activeCompanies = CompanyModule::where('type', \App\Classes\ValueObjects\Constants\BusinessType::IMPORTER)->whereHas('orderPackingLists', function($query) use($inactive_start, $inactive_end) {
return $query->where('packing_lists.type', \App\Classes\ValueObjects\Constants\PackingListType::WAREHOUSE_RECEIVE_LIST)->whereHas('transports', function ($query) use ($inactive_start, $inactive_end) {
@@ -253,10 +301,18 @@ Route::get('/customers/active/{active_start}/{active_end}/{inactive_start?}/{ina
})->whereNotIn('id', $activeCompanies)->get();
echo '<h4>List of customers active between <span style="color: green; font-weight: bold">'.\Carbon\Carbon::parse($active_start)->format('d/m/Y'). ' - '.\Carbon\Carbon::parse($active_end)->format('d/m/Y').'</span> & inactive between <span style="color: red; font-weight: bold">'.\Carbon\Carbon::parse($inactive_start)->format('d/m/Y'). ' - '.\Carbon\Carbon::parse($inactive_end)->format('d/m/Y').'</span></h4>';
echo '<table>
<tr>
<th>#</th>
<th>marking</th>
<th>Number of Orders</th>
<th>CBM</th>
</tr>';
foreach ($companies as $key => $company){
$connection = $company->inviters()->withPivot('invitee_reference')->first();
$marking = $connection ? $connection->pivot->invitee_reference:'';
$packingList = collect();
$totalCbm = 0;
if($with_cbm){
$packingList = $company->orderPackingLists()->where('packing_lists.type', \App\Classes\ValueObjects\Constants\PackingListType::SHIPPING_PACKING_LIST)->get();
$totalCbm = $packingList->flatMap(function ($packingList) {
@@ -266,10 +322,14 @@ Route::get('/customers/active/{active_start}/{active_end}/{inactive_start?}/{ina
});
}
$totalCbm = ($with_cbm ? '['. $packingList->count().'] ('. $totalCbm .')' : '');
echo $key + 1 .'. <a href="'.\route('customer.profile', $marking).'" target="_blank">'.$marking.'</a> '.$totalCbm.'<br><br>';
echo '<tr>
<td>'.$key.'</td>
<td><a href="'.route('customer.profile', $marking).'" target="_blank">'.$marking.'</a></td>
<td>'. $packingList->count() .'</td>
<td>'. $totalCbm .'</td>
</tr>';
}
echo '</table>';
});