diff --git a/app/Actions/Fulfilment/Fulfilment/HydrateFulfilment.php b/app/Actions/Fulfilment/Fulfilment/HydrateFulfilment.php index a4102d8954..d5e8605f6c 100644 --- a/app/Actions/Fulfilment/Fulfilment/HydrateFulfilment.php +++ b/app/Actions/Fulfilment/Fulfilment/HydrateFulfilment.php @@ -7,6 +7,7 @@ namespace App\Actions\Fulfilment\Fulfilment; +use App\Actions\Fulfilment\Fulfilment\Hydrators\FulfilmentHydrateCustomers; use App\Actions\Fulfilment\Fulfilment\Hydrators\FulfilmentHydratePalletDeliveries; use App\Actions\Fulfilment\Fulfilment\Hydrators\FulfilmentHydratePalletReturns; use App\Actions\Fulfilment\Fulfilment\Hydrators\FulfilmentHydratePallets; @@ -29,6 +30,7 @@ public function handle(Fulfilment $fulfilment): void FulfilmentHydratePalletDeliveries::run($fulfilment); FulfilmentHydratePalletReturns::run($fulfilment); FulfilmentHydrateRecurringBills::run($fulfilment); + FulfilmentHydrateCustomers::run($fulfilment); } diff --git a/app/Actions/Fulfilment/Fulfilment/Hydrators/FulfilmentHydrateCustomers.php b/app/Actions/Fulfilment/Fulfilment/Hydrators/FulfilmentHydrateCustomers.php new file mode 100644 index 0000000000..ca9ed43274 --- /dev/null +++ b/app/Actions/Fulfilment/Fulfilment/Hydrators/FulfilmentHydrateCustomers.php @@ -0,0 +1,59 @@ + + * Created: Tue, 14 May 2024 15:19:54 British Summer Time, Sheffield, UK + * Copyright (c) 2024, Raul A Perusquia Flores + */ + +namespace App\Actions\Fulfilment\Fulfilment\Hydrators; + +use App\Actions\Traits\WithEnumStats; +use App\Enums\Fulfilment\FulfilmentCustomer\FulfilmentCustomerStatus; +use App\Models\Fulfilment\Fulfilment; +use App\Models\Fulfilment\FulfilmentCustomer; +use Illuminate\Queue\Middleware\WithoutOverlapping; +use Lorisleiva\Actions\Concerns\AsAction; + +class FulfilmentHydrateCustomers +{ + use AsAction; + use WithEnumStats; + + + private Fulfilment $fulfilment; + + public function __construct(Fulfilment $fulfilment) + { + $this->fulfilment = $fulfilment; + } + + public function getJobMiddleware(): array + { + return [(new WithoutOverlapping($this->fulfilment->id))->dontRelease()]; + } + + + public function handle(Fulfilment $fulfilment): void + { + $stats = [ + 'number_customers_interest_pallets_storage' => $fulfilment->fulfilmentCustomers()->where('pallets_storage', true)->count(), + 'number_customers_interest_items_storage' => $fulfilment->fulfilmentCustomers()->where('items_storage', true)->count(), + 'number_customers_interest_dropshipping' => $fulfilment->fulfilmentCustomers()->where('dropshipping', true)->count(), + + ]; + + $stats=array_merge($stats, $this->getEnumStats( + model:'customers', + field: 'status', + enum: FulfilmentCustomerStatus::class, + models: FulfilmentCustomer::class, + where: function ($q) use ($fulfilment) { + $q->where('fulfilment_id', $fulfilment->id); + } + )); + + $fulfilment->stats()->update($stats); + } + + +} diff --git a/app/Actions/Fulfilment/FulfilmentCustomer/HydrateFulfilmentCustomer.php b/app/Actions/Fulfilment/FulfilmentCustomer/HydrateFulfilmentCustomer.php index ed53c4ff40..7038d73bd9 100644 --- a/app/Actions/Fulfilment/FulfilmentCustomer/HydrateFulfilmentCustomer.php +++ b/app/Actions/Fulfilment/FulfilmentCustomer/HydrateFulfilmentCustomer.php @@ -11,6 +11,7 @@ use App\Actions\Fulfilment\FulfilmentCustomer\Hydrators\FulfilmentCustomerHydratePalletReturns; use App\Actions\Fulfilment\FulfilmentCustomer\Hydrators\FulfilmentCustomerHydratePallets; use App\Actions\Fulfilment\FulfilmentCustomer\Hydrators\FulfilmentCustomerHydrateRecurringBills; +use App\Actions\Fulfilment\FulfilmentCustomer\Hydrators\FulfilmentCustomerHydrateStatus; use App\Actions\Fulfilment\FulfilmentCustomer\Hydrators\FulfilmentCustomerHydrateStoredItems; use App\Actions\Fulfilment\PalletDelivery\Hydrators\PalletDeliveryHydratePallets; use App\Actions\Fulfilment\PalletReturn\Hydrators\HydratePalletReturns; @@ -39,6 +40,7 @@ public function handle(FulfilmentCustomer $fulfilmentCustomer): void } FulfilmentCustomerHydrateRecurringBills::run($fulfilmentCustomer); + FulfilmentCustomerHydrateStatus::run($fulfilmentCustomer); } protected function getModel(string $slug): FulfilmentCustomer diff --git a/app/Actions/Fulfilment/FulfilmentCustomer/Hydrators/FulfilmentCustomerHydrateStatus.php b/app/Actions/Fulfilment/FulfilmentCustomer/Hydrators/FulfilmentCustomerHydrateStatus.php new file mode 100644 index 0000000000..e0ce7d2dec --- /dev/null +++ b/app/Actions/Fulfilment/FulfilmentCustomer/Hydrators/FulfilmentCustomerHydrateStatus.php @@ -0,0 +1,51 @@ + + * Created: Tue, 14 May 2024 15:19:54 British Summer Time, Sheffield, UK + * Copyright (c) 2024, Raul A Perusquia Flores + */ + +namespace App\Actions\Fulfilment\FulfilmentCustomer\Hydrators; + +use App\Actions\Traits\WithEnumStats; +use App\Enums\Fulfilment\FulfilmentCustomer\FulfilmentCustomerStatus; +use App\Enums\Fulfilment\RentalAgreement\RentalAgreementStateEnum; +use App\Models\Fulfilment\FulfilmentCustomer; +use Illuminate\Queue\Middleware\WithoutOverlapping; +use Lorisleiva\Actions\Concerns\AsAction; + +class FulfilmentCustomerHydrateStatus +{ + use AsAction; + use WithEnumStats; + + private FulfilmentCustomer $fulfilmentCustomer; + + public function __construct(FulfilmentCustomer $fulfilmentCustomer) + { + $this->fulfilmentCustomer = $fulfilmentCustomer; + } + + public function getJobMiddleware(): array + { + return [(new WithoutOverlapping($this->fulfilmentCustomer->id))->dontRelease()]; + } + + public function handle(FulfilmentCustomer $fulfilmentCustomer): void + { + $status = FulfilmentCustomerStatus::NO_RENTAL_AGREEMENT; + + if ($fulfilmentCustomer->rentalAgreement) { + if ($fulfilmentCustomer->rentalAgreement->state == RentalAgreementStateEnum::ACTIVE) { + $status = FulfilmentCustomerStatus::ACTIVE; + + } elseif ($fulfilmentCustomer->rentalAgreement->state == RentalAgreementStateEnum::EXPIRED) { + $status = FulfilmentCustomerStatus::LOST; + } + } + $fulfilmentCustomer->update( + ['status' => $status] + ); + } + +} diff --git a/app/Actions/Fulfilment/FulfilmentCustomer/ShowFulfilmentCustomer.php b/app/Actions/Fulfilment/FulfilmentCustomer/ShowFulfilmentCustomer.php index 4d96712872..52851dead4 100644 --- a/app/Actions/Fulfilment/FulfilmentCustomer/ShowFulfilmentCustomer.php +++ b/app/Actions/Fulfilment/FulfilmentCustomer/ShowFulfilmentCustomer.php @@ -100,7 +100,7 @@ public function htmlResponse(FulfilmentCustomer $fulfilmentCustomer, ActionReque } return Inertia::render( - 'Org/Fulfilment/Customer', + 'Org/Fulfilment/FulfilmentCustomer', [ 'title' => __('customer'), 'breadcrumbs' => $this->getBreadcrumbs( diff --git a/app/Actions/Fulfilment/FulfilmentCustomer/StoreFulfilmentCustomer.php b/app/Actions/Fulfilment/FulfilmentCustomer/StoreFulfilmentCustomer.php index 38a195ac3d..5d8649e3e7 100644 --- a/app/Actions/Fulfilment/FulfilmentCustomer/StoreFulfilmentCustomer.php +++ b/app/Actions/Fulfilment/FulfilmentCustomer/StoreFulfilmentCustomer.php @@ -17,7 +17,6 @@ use App\Models\SysAdmin\Organisation; use App\Rules\IUnique; use App\Rules\ValidAddress; -use Illuminate\Support\Arr; use Illuminate\Validation\Rule; use Illuminate\Validation\Rules\Password; use Inertia\Inertia; @@ -44,21 +43,8 @@ public function authorize(ActionRequest $request): bool if ($this->asAction) { return true; } - return $request->user()->hasPermissionTo("fulfilment-shop.{$this->fulfilment->id}.edit"); - } - - - public function handle(Fulfilment $fulfilment, array $modelData): FulfilmentCustomer - { - data_set($modelData, 'pallets_storage', in_array('pallets_storage', $modelData['interest'])); - data_set($modelData, 'items_storage', in_array('items_storage', $modelData['interest'])); - data_set($modelData, 'dropshipping', in_array('dropshipping', $modelData['interest'])); - - $customer = StoreCustomer::make()->action($fulfilment->shop, $modelData); - - UpdateFulfilmentCustomer::run($customer->fulfilmentCustomer, Arr::except($modelData, 'interest')); - return $customer->fulfilmentCustomer; + return $request->user()->hasPermissionTo("fulfilment-shop.{$this->fulfilment->id}.edit"); } public function rules(): array @@ -78,7 +64,7 @@ public function rules(): array table: 'customers', extraConditions: [ ['column' => 'shop_id', 'value' => $this->shop->id], - ['column' => 'deleted_at', 'operator'=>'notNull'], + ['column' => 'deleted_at', 'operator' => 'notNull'], ] ), ], @@ -107,9 +93,9 @@ public function rules(): array public function htmlResponse(FulfilmentCustomer $fulfilmentCustomer): Response { return Inertia::location(route('grp.org.fulfilments.show.crm.customers.show', [ - 'organisation' => $fulfilmentCustomer->organisation->slug, - 'fulfilment' => $fulfilmentCustomer->fulfilment->slug, - 'fulfilmentCustomer' => $fulfilmentCustomer->slug + 'organisation' => $fulfilmentCustomer->organisation->slug, + 'fulfilment' => $fulfilmentCustomer->fulfilment->slug, + 'fulfilmentCustomer' => $fulfilmentCustomer->slug ])); } diff --git a/app/Actions/Fulfilment/FulfilmentCustomer/StoreFulfilmentCustomerFromCustomer.php b/app/Actions/Fulfilment/FulfilmentCustomer/StoreFulfilmentCustomerFromCustomer.php index 01676236c1..2b5082ba91 100644 --- a/app/Actions/Fulfilment/FulfilmentCustomer/StoreFulfilmentCustomerFromCustomer.php +++ b/app/Actions/Fulfilment/FulfilmentCustomer/StoreFulfilmentCustomerFromCustomer.php @@ -7,6 +7,7 @@ namespace App\Actions\Fulfilment\FulfilmentCustomer; +use App\Actions\Fulfilment\Fulfilment\Hydrators\FulfilmentHydrateCustomers; use App\Actions\Fulfilment\FulfilmentCustomer\Hydrators\FulfilmentCustomerHydrateUniversalSearch; use App\Actions\OrgAction; use App\Actions\Utils\Abbreviate; @@ -19,57 +20,59 @@ class StoreFulfilmentCustomerFromCustomer extends OrgAction { public function handle(Customer $customer, Shop $shop): FulfilmentCustomer { - /** @var FulfilmentCustomer $customerFulfilment */ - $customerFulfilment = $customer->fulfilmentCustomer()->create([ + /** @var FulfilmentCustomer $fulfilmentCustomer */ + $fulfilmentCustomer = $customer->fulfilmentCustomer()->create([ 'fulfilment_id' => $shop->fulfilment->id, 'group_id' => $customer->group_id, 'organisation_id' => $customer->organisation_id, ]); - $customerFulfilment->refresh(); + $fulfilmentCustomer->refresh(); - $customerFulfilment->serialReferences()->create( + $fulfilmentCustomer->serialReferences()->create( [ 'model' => SerialReferenceModelEnum::PALLET_DELIVERY, - 'organisation_id' => $customerFulfilment->organisation->id, - 'format' => Abbreviate::run($customerFulfilment->slug).'-%03d' + 'organisation_id' => $fulfilmentCustomer->organisation->id, + 'format' => Abbreviate::run($fulfilmentCustomer->slug).'-%03d' ] ); - $customerFulfilment->serialReferences()->create( + $fulfilmentCustomer->serialReferences()->create( [ 'model' => SerialReferenceModelEnum::PALLET_RETURN, - 'organisation_id' => $customerFulfilment->organisation->id, - 'format' => Abbreviate::run($customerFulfilment->slug).'-r%03d' + 'organisation_id' => $fulfilmentCustomer->organisation->id, + 'format' => Abbreviate::run($fulfilmentCustomer->slug).'-r%03d' ] ); - $customerFulfilment->serialReferences()->create( + $fulfilmentCustomer->serialReferences()->create( [ 'model' => SerialReferenceModelEnum::STORED_ITEM_RETURN, - 'organisation_id' => $customerFulfilment->organisation->id, - 'format' => Abbreviate::run($customerFulfilment->slug).'-sir%03d' + 'organisation_id' => $fulfilmentCustomer->organisation->id, + 'format' => Abbreviate::run($fulfilmentCustomer->slug).'-sir%03d' ] ); - $customerFulfilment->serialReferences()->create( + $fulfilmentCustomer->serialReferences()->create( [ 'model' => SerialReferenceModelEnum::PALLET, - 'organisation_id' => $customerFulfilment->organisation->id, - 'format' => Abbreviate::run($customerFulfilment->slug).'-p%04d' + 'organisation_id' => $fulfilmentCustomer->organisation->id, + 'format' => Abbreviate::run($fulfilmentCustomer->slug).'-p%04d' ] ); - $customerFulfilment->serialReferences()->create( + $fulfilmentCustomer->serialReferences()->create( [ 'model' => SerialReferenceModelEnum::RECURRING_BILL, - 'organisation_id' => $customerFulfilment->organisation->id, - 'format' => Abbreviate::run($customerFulfilment->slug).'-b%03d' + 'organisation_id' => $fulfilmentCustomer->organisation->id, + 'format' => Abbreviate::run($fulfilmentCustomer->slug).'-b%03d' ] ); - FulfilmentCustomerHydrateUniversalSearch::dispatch($customerFulfilment); + FulfilmentCustomerHydrateUniversalSearch::dispatch($fulfilmentCustomer); + FulfilmentHydrateCustomers::dispatch($fulfilmentCustomer->fulfilment); - return $customerFulfilment; + + return $fulfilmentCustomer; } } diff --git a/app/Actions/Fulfilment/FulfilmentCustomer/UI/IndexFulfilmentCustomers.php b/app/Actions/Fulfilment/FulfilmentCustomer/UI/IndexFulfilmentCustomers.php index 979bc47623..16aea2c24e 100644 --- a/app/Actions/Fulfilment/FulfilmentCustomer/UI/IndexFulfilmentCustomers.php +++ b/app/Actions/Fulfilment/FulfilmentCustomer/UI/IndexFulfilmentCustomers.php @@ -9,6 +9,7 @@ use App\Actions\Fulfilment\Fulfilment\UI\ShowFulfilment; use App\Actions\OrgAction; +use App\Enums\Fulfilment\FulfilmentCustomer\FulfilmentCustomerStatus; use App\Http\Resources\Fulfilment\FulfilmentCustomersResource; use App\InertiaTable\InertiaTable; use App\Models\Fulfilment\Fulfilment; @@ -17,7 +18,6 @@ use Closure; use Illuminate\Contracts\Pagination\LengthAwarePaginator; use Illuminate\Http\Resources\Json\AnonymousResourceCollection; -use Illuminate\Support\Str; use Inertia\Inertia; use Inertia\Response; use Lorisleiva\Actions\ActionRequest; @@ -26,22 +26,24 @@ class IndexFulfilmentCustomers extends OrgAction { - public function authorize(ActionRequest $request): bool + protected function getElementGroups(Fulfilment $parent): array { - $this->canEdit = $request->user()->hasPermissionTo("fulfilment-shop.{$this->fulfilment->id}.edit"); - - return $request->user()->hasPermissionTo("fulfilment-shop.{$this->fulfilment->id}.view"); - } + return [ + 'status' => [ + 'label' => __('State'), + 'elements' => array_merge_recursive( + FulfilmentCustomerStatus::labels(), + FulfilmentCustomerStatus::count($parent) + ), + 'engine' => function ($query, $elements) { + $query->whereIn('state', $elements); + } - public function asController(Organisation $organisation, Fulfilment $fulfilment, ActionRequest $request): LengthAwarePaginator - { - $this->initialisationFromFulfilment($fulfilment, $request); - - return $this->handle($fulfilment); + ] + ]; } - public function handle(Fulfilment $fulfilment, $prefix = null): LengthAwarePaginator { $globalSearch = AllowedFilter::callback('global', function ($query, $value) { @@ -59,11 +61,20 @@ public function handle(Fulfilment $fulfilment, $prefix = null): LengthAwarePagin $queryBuilder = QueryBuilder::for(FulfilmentCustomer::class); $queryBuilder->where('fulfilment_customers.fulfilment_id', $fulfilment->id); + foreach ($this->getElementGroups($fulfilment) as $key => $elementGroup) { + $queryBuilder->whereElementGroup( + key: $key, + allowedElements: array_keys($elementGroup['elements']), + engine: $elementGroup['engine'], + prefix: $prefix + ); + } return $queryBuilder ->defaultSort('fulfilment_customers.slug') ->select([ 'reference', + 'fulfilment_customers.status', 'customers.id', 'customers.name', 'fulfilment_customers.slug', @@ -72,7 +83,7 @@ public function handle(Fulfilment $fulfilment, $prefix = null): LengthAwarePagin ]) ->leftJoin('customers', 'customers.id', 'fulfilment_customers.customer_id') ->leftJoin('customer_stats', 'customers.id', 'customer_stats.customer_id') - ->allowedSorts(['reference', 'name', 'number_pallets', 'slug', 'number_pallets_status_storing']) + ->allowedSorts(['reference', 'name', 'number_pallets', 'slug', 'number_pallets_status_storing','status']) ->allowedFilters([$globalSearch]) ->withPaginator($prefix) ->withQueryString(); @@ -87,6 +98,13 @@ public function tableStructure(Fulfilment $fulfilment, ?array $modelOperations = ->pageName($prefix.'Page'); } + foreach ($this->getElementGroups($fulfilment) as $key => $elementGroup) { + $table->elementGroup( + key: $key, + label: $elementGroup['label'], + elements: $elementGroup['elements'] + ); + } $table ->withModelOperations($modelOperations) @@ -108,13 +126,28 @@ public function tableStructure(Fulfilment $fulfilment, ?array $modelOperations = ] ] ) - ->column(key: 'rental_agreement', label: __(''), canBeHidden: false, sortable: false, searchable: false, type: 'avatar') + ->column(key: 'status', label: __(''), canBeHidden: false, sortable: true, type: 'avatar') ->column(key: 'reference', label: __('reference'), canBeHidden: false, sortable: true, searchable: true) ->column(key: 'name', label: __('name'), canBeHidden: false, sortable: true, searchable: true) ->column(key: 'number_pallets_status_storing', label: ['type'=>'text', 'data'=>__('Pallets'), 'tooltip'=>__('Number of pallets in warehouse')], canBeHidden: false, sortable: true, searchable: false); }; } + public function authorize(ActionRequest $request): bool + { + $this->canEdit = $request->user()->hasPermissionTo("fulfilment-shop.{$this->fulfilment->id}.edit"); + + return $request->user()->hasPermissionTo("fulfilment-shop.{$this->fulfilment->id}.view"); + } + + + public function asController(Organisation $organisation, Fulfilment $fulfilment, ActionRequest $request): LengthAwarePaginator + { + $this->initialisationFromFulfilment($fulfilment, $request); + + return $this->handle($fulfilment); + } + public function jsonResponse(LengthAwarePaginator $customers): AnonymousResourceCollection { return FulfilmentCustomersResource::collection($customers); @@ -122,15 +155,9 @@ public function jsonResponse(LengthAwarePaginator $customers): AnonymousResource public function htmlResponse(LengthAwarePaginator $customers, ActionRequest $request): Response { - $container = [ - 'icon' => ['fal', 'fa-hand-holding-box'], - 'tooltip' => __('Fulfilment Shop'), - 'label' => Str::possessive($this->fulfilment->shop->name) - - ]; return Inertia::render( - 'Org/Fulfilment/Customers', + 'Org/Fulfilment/FulfilmentCustomers', [ 'breadcrumbs' => $this->getBreadcrumbs( $request->route()->originalParameters() @@ -138,7 +165,6 @@ public function htmlResponse(LengthAwarePaginator $customers, ActionRequest $req 'title' => __('customers'), 'pageHead' => [ 'title' => __('customers'), - 'container' => $container, 'iconRight' => [ 'icon' => ['fal', 'fa-user'], 'title' => __('customer') diff --git a/app/Actions/Fulfilment/FulfilmentCustomer/UpdateFulfilmentCustomer.php b/app/Actions/Fulfilment/FulfilmentCustomer/UpdateFulfilmentCustomer.php index 76c3f538aa..dbe5e08aee 100644 --- a/app/Actions/Fulfilment/FulfilmentCustomer/UpdateFulfilmentCustomer.php +++ b/app/Actions/Fulfilment/FulfilmentCustomer/UpdateFulfilmentCustomer.php @@ -8,6 +8,7 @@ namespace App\Actions\Fulfilment\FulfilmentCustomer; use App\Actions\CRM\Customer\UpdateCustomer; +use App\Actions\Fulfilment\Fulfilment\Hydrators\FulfilmentHydrateCustomers; use App\Actions\OrgAction; use App\Actions\Traits\WithActionUpdate; use App\Models\Fulfilment\Fulfilment; @@ -27,7 +28,10 @@ public function handle(FulfilmentCustomer $fulfilmentCustomer, array $modelData) $customerData = Arr::only($modelData, ['contact_name', 'company_name', 'email', 'phone']); UpdateCustomer::run($fulfilmentCustomer->customer, $customerData); Arr::forget($modelData, ['contact_name', 'company_name', 'email', 'phone']); - return $this->update($fulfilmentCustomer, $modelData, ['data']); + $fulfilmentCustomer = $this->update($fulfilmentCustomer, $modelData, ['data']); + FulfilmentHydrateCustomers::dispatch($fulfilmentCustomer->fulfilment); + + return $fulfilmentCustomer; } public function authorize(ActionRequest $request): bool @@ -66,9 +70,6 @@ public function asController( } public function action( - Organisation $organisation, - Shop $shop, - Fulfilment $fulfilment, FulfilmentCustomer $fulfilmentCustomer, array $modelData ): FulfilmentCustomer { diff --git a/app/Actions/Fulfilment/RentalAgreement/StoreRentalAgreement.php b/app/Actions/Fulfilment/RentalAgreement/StoreRentalAgreement.php index f93076bf0e..a8bd5e6544 100644 --- a/app/Actions/Fulfilment/RentalAgreement/StoreRentalAgreement.php +++ b/app/Actions/Fulfilment/RentalAgreement/StoreRentalAgreement.php @@ -7,6 +7,7 @@ namespace App\Actions\Fulfilment\RentalAgreement; +use App\Actions\Fulfilment\FulfilmentCustomer\Hydrators\FulfilmentCustomerHydrateStatus; use App\Actions\Fulfilment\RentalAgreementClause\StoreRentalAgreementClause; use App\Actions\Helpers\SerialReference\GetSerialReference; use App\Actions\OrgAction; @@ -53,16 +54,13 @@ public function handle(FulfilmentCustomer $fulfilmentCustomer, array $modelData) /** @var RentalAgreement $rentalAgreement */ $rentalAgreement = $fulfilmentCustomer->rentalAgreement()->create($modelData); - $fulfilmentCustomer->update( - [ - 'rental_agreement_state' => $rentalAgreement->state - ] - ); foreach ($causes as $causeData) { StoreRentalAgreementClause::run($rentalAgreement, $causeData); } + FulfilmentCustomerHydrateStatus::run($fulfilmentCustomer); + return $rentalAgreement; } diff --git a/app/Actions/Fulfilment/RentalAgreement/UpdateRentalAgreement.php b/app/Actions/Fulfilment/RentalAgreement/UpdateRentalAgreement.php index d8180387b6..dacb51d548 100644 --- a/app/Actions/Fulfilment/RentalAgreement/UpdateRentalAgreement.php +++ b/app/Actions/Fulfilment/RentalAgreement/UpdateRentalAgreement.php @@ -7,6 +7,7 @@ namespace App\Actions\Fulfilment\RentalAgreement; +use App\Actions\Fulfilment\FulfilmentCustomer\Hydrators\FulfilmentCustomerHydrateStatus; use App\Actions\OrgAction; use App\Actions\Traits\WithActionUpdate; use App\Enums\Fulfilment\RentalAgreement\RentalAgreementBillingCycleEnum; @@ -26,7 +27,7 @@ public function handle(RentalAgreement $rentalAgreement, array $modelData): Rent { /** @var RentalAgreement $rentalAgreement */ $rentalAgreement = $this->update($rentalAgreement, Arr::except($modelData, ['rental'])); - + FulfilmentCustomerHydrateStatus::run($rentalAgreement->fulfilmentCustomer); return $rentalAgreement; } diff --git a/app/Actions/HumanResources/JobPosition/UI/IndexJobPositions.php b/app/Actions/HumanResources/JobPosition/UI/IndexJobPositions.php index c142423ae0..7000a0afe2 100644 --- a/app/Actions/HumanResources/JobPosition/UI/IndexJobPositions.php +++ b/app/Actions/HumanResources/JobPosition/UI/IndexJobPositions.php @@ -41,11 +41,9 @@ public function handle(Organisation|Employee $parent, string $prefix = null): Le $queryBuilder = QueryBuilder::for(JobPosition::class); $queryBuilder->leftJoin('job_position_stats', 'job_positions.id', 'job_position_stats.job_position_id'); - // dd($parent); if ($parent instanceof Organisation) { $queryBuilder->where('organisation_id', $parent->id); - - } elseif ($parent instanceof Employee) { + } else { $queryBuilder->whereHas('employees', function ($query) use ($parent) { $query->where('job_positionable_id', $parent->id); $query->where('job_positionable_type', class_basename($parent)); @@ -64,7 +62,8 @@ public function handle(Organisation|Employee $parent, string $prefix = null): Le public function authorize(ActionRequest $request): bool { $this->canEdit = $request->user()->hasPermissionTo("org-supervisor.{$this->organisation->id}.human-resources"); - return $request->user()->hasPermissionTo("human-resources.{$this->organisation->id}.view"); + + return $request->user()->hasPermissionTo("human-resources.{$this->organisation->id}.view"); } @@ -124,13 +123,11 @@ public function htmlResponse(LengthAwarePaginator $jobPositions, ActionRequest $ } - public function asController(Organisation $organisation, ActionRequest $request, Employee $employee = null): LengthAwarePaginator + public function asController(Organisation $organisation, ActionRequest $request): LengthAwarePaginator { $this->initialisation($organisation, $request); - $parent = $employee ?? $organisation; - - return $this->handle($parent); + return $this->handle($organisation); } public function getBreadcrumbs(array $routeParameters): array diff --git a/app/Enums/Fulfilment/FulfilmentCustomer/FulfilmentCustomerStatus.php b/app/Enums/Fulfilment/FulfilmentCustomer/FulfilmentCustomerStatus.php new file mode 100644 index 0000000000..5c14339433 --- /dev/null +++ b/app/Enums/Fulfilment/FulfilmentCustomer/FulfilmentCustomerStatus.php @@ -0,0 +1,90 @@ + + * Created: Tue, 14 May 2024 15:19:54 British Summer Time, Sheffield, UK + * Copyright (c) 2024, Raul A Perusquia Flores + */ + +namespace App\Enums\Fulfilment\FulfilmentCustomer; + +use App\Enums\EnumHelperTrait; +use App\Models\Fulfilment\Fulfilment; + +enum FulfilmentCustomerStatus: string +{ + use EnumHelperTrait; + + case NO_RENTAL_AGREEMENT = 'no_rental_agreement'; + case INACTIVE = 'inactive'; + case ACTIVE = 'active'; + case LOST = 'lost'; + + public static function labels(): array + { + return [ + 'no_rental_agreement' => __('No Rental Agreement'), + 'inactive' => __('Inactive'), + 'active' => __('Active'), + 'lost' => __('Lost'), + ]; + } + + public static function count(Fulfilment $parent): array + { + $stats = $parent->stats; + + + return [ + 'no_rental_agreement' => $stats->number_customers_status_no_rental_agreement, + 'inactive' => $stats->number_customers_status_inactive, + 'active' => $stats->number_customers_status_active, + 'lost' => $stats->number_customers_status_lost, + ]; + } + + public static function statusIcon(): array + { + return [ + 'no_rental_agreement' => [ + 'tooltip' => __('No Rental Agreement'), + 'icon' => 'fal fa-seedling', + 'color' => 'lime', // Color for box (Retina) + 'app' => [ + 'name' => 'seedling', + 'type' => 'font-awesome-5' + ] + ], + 'inactive' => [ + 'tooltip' => __('Inactive'), + 'icon' => 'fal fa-share', + 'class' => 'text-indigo-400', + 'color' => 'grey', + 'app' => [ + 'name' => 'share', + 'type' => 'font-awesome-5' + ] + ], + 'active' => [ + 'tooltip' => __('Active'), + 'icon' => 'fal fa-check', + 'class' => 'text-green-500', + 'color' => 'green', + 'app' => [ + 'name' => 'check', + 'type' => 'font-awesome-5' + ] + ], + 'lost' => [ + 'tooltip' => __('Lost'), + 'icon' => 'fal fa-times', + 'class' => 'text-red-500', + 'color' => 'red', + 'app' => [ + 'name' => 'times', + 'type' => 'font-awesome-5' + ] + ] + ]; + } + +} diff --git a/app/Enums/SysAdmin/Authorisation/RolesEnum.php b/app/Enums/SysAdmin/Authorisation/RolesEnum.php index f61b969b22..8cf667ec6d 100644 --- a/app/Enums/SysAdmin/Authorisation/RolesEnum.php +++ b/app/Enums/SysAdmin/Authorisation/RolesEnum.php @@ -21,6 +21,13 @@ enum RolesEnum: string use EnumHelperTrait; case SUPER_ADMIN = 'super-admin'; + + case HUMAN_RESOURCES_SUPERVISOR = 'human-resources-supervisor'; + case HUMAN_RESOURCES_CLERK = 'human-resources-clerk'; + + + + case SYSTEM_ADMIN = 'system-admin'; case SUPPLY_CHAIN = 'supply-chain'; @@ -40,8 +47,6 @@ enum RolesEnum: string case DISPATCH_CLERK = 'dispatch-clerk'; case DISPATCH_SUPERVISOR = 'dispatch-supervisor'; - case HUMAN_RESOURCES_CLERK = 'human-resources-clerk'; - case HUMAN_RESOURCES_SUPERVISOR = 'human-resources-supervisor'; case ACCOUNTING_CLERK = 'accounting-clerk'; case ACCOUNTING_SUPERVISOR = 'accounting-supervisor'; @@ -49,6 +54,8 @@ enum RolesEnum: string case SHOP_ADMIN = 'shop-admin'; + + case FULFILMENT_SHOP_SUPERVISOR = 'fulfilment-shop-supervisor'; case FULFILMENT_SHOP_CLERK = 'fulfilment-shop-clerk'; diff --git a/app/Http/Resources/Fulfilment/FulfilmentCustomersResource.php b/app/Http/Resources/Fulfilment/FulfilmentCustomersResource.php index 4efe349a28..6bef66eca6 100644 --- a/app/Http/Resources/Fulfilment/FulfilmentCustomersResource.php +++ b/app/Http/Resources/Fulfilment/FulfilmentCustomersResource.php @@ -18,13 +18,13 @@ * @property string $contact_name * @property string $company_name * @property string $phone - * @property \App\Models\Fulfilment\RentalAgreement $rentalAgreement * @property string $shop_code * @property string $shop_slug * @property string $slug * @property int $number_pallets * @property int $id * @property int $number_pallets_status_storing + * @property mixed $status */ class FulfilmentCustomersResource extends JsonResource { @@ -39,7 +39,8 @@ public function toArray($request): array 'company_name' => $this->company_name, 'email' => $this->email, 'phone' => $this->phone, - 'rental_agreement' => (bool) $this->rentalAgreement, + 'status_label' => $this->status->labels()[$this->status->value], + 'status_icon' => $this->status->statusIcon()[$this->status->value], 'number_pallets_status_storing' => $this->number_pallets_status_storing ]; } diff --git a/app/Models/Fulfilment/Fulfilment.php b/app/Models/Fulfilment/Fulfilment.php index 94279bc1e8..6b922179b3 100644 --- a/app/Models/Fulfilment/Fulfilment.php +++ b/app/Models/Fulfilment/Fulfilment.php @@ -113,4 +113,10 @@ public function recurringBills(): HasMany return $this->hasMany(RecurringBill::class); } + public function fulfilmentCustomers(): HasMany + { + return $this->hasMany(FulfilmentCustomer::class); + } + + } diff --git a/app/Models/Fulfilment/FulfilmentCustomer.php b/app/Models/Fulfilment/FulfilmentCustomer.php index 97e5481ef9..86e9759923 100644 --- a/app/Models/Fulfilment/FulfilmentCustomer.php +++ b/app/Models/Fulfilment/FulfilmentCustomer.php @@ -7,7 +7,7 @@ namespace App\Models\Fulfilment; -use App\Enums\Fulfilment\RentalAgreement\RentalAgreementStateEnum; +use App\Enums\Fulfilment\FulfilmentCustomer\FulfilmentCustomerStatus; use App\Models\CRM\Customer; use App\Models\Helpers\SerialReference; use App\Models\SysAdmin\Group; @@ -92,7 +92,7 @@ * @property int $number_recurring_bills * @property int $number_recurring_bills_status_current * @property int $number_recurring_bills_status_former - * @property RentalAgreementStateEnum|null $rental_agreement_state + * @property FulfilmentCustomerStatus $status * @property array $data * @property \Illuminate\Support\Carbon|null $created_at * @property \Illuminate\Support\Carbon|null $updated_at @@ -130,8 +130,9 @@ class FulfilmentCustomer extends Model protected $guarded = []; protected $casts = [ - 'data' => 'array', - 'rental_agreement_state'=> RentalAgreementStateEnum::class + 'data' => 'array', + 'status' => FulfilmentCustomerStatus::class + ]; protected $attributes = [ diff --git a/app/Models/Fulfilment/FulfilmentStats.php b/app/Models/Fulfilment/FulfilmentStats.php index 22c902ff22..4d6fbfddf1 100644 --- a/app/Models/Fulfilment/FulfilmentStats.php +++ b/app/Models/Fulfilment/FulfilmentStats.php @@ -18,6 +18,10 @@ * @property int $number_customers_interest_pallets_storage * @property int $number_customers_interest_items_storage * @property int $number_customers_interest_dropshipping + * @property int $number_customers_status_no_rental_agreement + * @property int $number_customers_status_inactive + * @property int $number_customers_status_active + * @property int $number_customers_status_lost * @property int $number_customers_with_stored_items * @property int $number_customers_with_pallets * @property int $number_customers_with_stored_items_state_in_process diff --git a/app/Models/HumanResources/JobPosition.php b/app/Models/HumanResources/JobPosition.php index 6255d4fd93..51c0c486d0 100644 --- a/app/Models/HumanResources/JobPosition.php +++ b/app/Models/HumanResources/JobPosition.php @@ -40,6 +40,7 @@ * @property Carbon|null $created_at * @property Carbon|null $updated_at * @property-read \Illuminate\Database\Eloquent\Collection $audits + * @property-read \Illuminate\Database\Eloquent\Collection $employees * @property-read \App\Models\SysAdmin\Group $group * @property-read \App\Models\SysAdmin\Organisation $organisation * @property-read \Illuminate\Database\Eloquent\Collection $roles diff --git a/app/Models/Inventory/WarehouseAreaStats.php b/app/Models/Inventory/WarehouseAreaStats.php index 8efeba01c3..660b8d8e5a 100644 --- a/app/Models/Inventory/WarehouseAreaStats.php +++ b/app/Models/Inventory/WarehouseAreaStats.php @@ -82,6 +82,10 @@ * @property int $number_customers_interest_pallets_storage * @property int $number_customers_interest_items_storage * @property int $number_customers_interest_dropshipping + * @property int $number_customers_status_no_rental_agreement + * @property int $number_customers_status_inactive + * @property int $number_customers_status_active + * @property int $number_customers_status_lost * @property int $number_customers_with_stored_items * @property int $number_customers_with_pallets * @property int $number_customers_with_stored_items_state_in_process diff --git a/app/Models/Inventory/WarehouseStats.php b/app/Models/Inventory/WarehouseStats.php index 19c9764f95..5810a9771d 100644 --- a/app/Models/Inventory/WarehouseStats.php +++ b/app/Models/Inventory/WarehouseStats.php @@ -29,6 +29,10 @@ * @property int $number_customers_interest_pallets_storage * @property int $number_customers_interest_items_storage * @property int $number_customers_interest_dropshipping + * @property int $number_customers_status_no_rental_agreement + * @property int $number_customers_status_inactive + * @property int $number_customers_status_active + * @property int $number_customers_status_lost * @property int $number_customers_with_stored_items * @property int $number_customers_with_pallets * @property int $number_customers_with_stored_items_state_in_process diff --git a/app/Models/SysAdmin/GroupFulfilmentStats.php b/app/Models/SysAdmin/GroupFulfilmentStats.php index 3011951b4e..7821dca73d 100644 --- a/app/Models/SysAdmin/GroupFulfilmentStats.php +++ b/app/Models/SysAdmin/GroupFulfilmentStats.php @@ -18,6 +18,10 @@ * @property int $number_customers_interest_pallets_storage * @property int $number_customers_interest_items_storage * @property int $number_customers_interest_dropshipping + * @property int $number_customers_status_no_rental_agreement + * @property int $number_customers_status_inactive + * @property int $number_customers_status_active + * @property int $number_customers_status_lost * @property int $number_customers_with_stored_items * @property int $number_customers_with_pallets * @property int $number_customers_with_stored_items_state_in_process diff --git a/app/Models/SysAdmin/OrganisationFulfilmentStats.php b/app/Models/SysAdmin/OrganisationFulfilmentStats.php index 3b5584dc61..32376ea7ac 100644 --- a/app/Models/SysAdmin/OrganisationFulfilmentStats.php +++ b/app/Models/SysAdmin/OrganisationFulfilmentStats.php @@ -21,6 +21,10 @@ * @property int $number_customers_interest_pallets_storage * @property int $number_customers_interest_items_storage * @property int $number_customers_interest_dropshipping + * @property int $number_customers_status_no_rental_agreement + * @property int $number_customers_status_inactive + * @property int $number_customers_status_active + * @property int $number_customers_status_lost * @property int $number_customers_with_stored_items * @property int $number_customers_with_pallets * @property int $number_customers_with_stored_items_state_in_process diff --git a/app/Stubs/Migrations/HasFulfilmentStats.php b/app/Stubs/Migrations/HasFulfilmentStats.php index b9f55b0a4f..1ec70c5ebc 100644 --- a/app/Stubs/Migrations/HasFulfilmentStats.php +++ b/app/Stubs/Migrations/HasFulfilmentStats.php @@ -7,6 +7,7 @@ namespace App\Stubs\Migrations; +use App\Enums\Fulfilment\FulfilmentCustomer\FulfilmentCustomerStatus; use App\Enums\Fulfilment\Pallet\PalletStateEnum; use App\Enums\Fulfilment\Pallet\PalletStatusEnum; use App\Enums\Fulfilment\Pallet\PalletTypeEnum; @@ -77,9 +78,15 @@ public function containerFulfilmentStats(Blueprint $table): Blueprint $table->unsignedInteger('number_customers_interest_dropshipping')->default(0); + foreach (FulfilmentCustomerStatus::cases() as $case) { + $table->unsignedInteger("number_customers_status_{$case->snake()}")->default(0); + } + $table->unsignedInteger('number_customers_with_stored_items')->default(0); $table->unsignedInteger('number_customers_with_pallets')->default(0); + + foreach (StoredItemStateEnum::cases() as $state) { $table->unsignedInteger("number_customers_with_stored_items_state_{$state->snake()}")->default(0); } diff --git a/database/migrations/2024_01_24_054221_create_fulfilment_customers_table.php b/database/migrations/2024_01_24_054221_create_fulfilment_customers_table.php index 3ddf4e11a9..d612e5aba6 100644 --- a/database/migrations/2024_01_24_054221_create_fulfilment_customers_table.php +++ b/database/migrations/2024_01_24_054221_create_fulfilment_customers_table.php @@ -5,6 +5,7 @@ * Copyright (c) 2024, Raul A Perusquia Flores */ +use App\Enums\Fulfilment\FulfilmentCustomer\FulfilmentCustomerStatus; use App\Stubs\Migrations\HasFulfilmentStats; use App\Stubs\Migrations\HasGroupOrganisationRelationship; use App\Stubs\Migrations\HasSoftDeletes; @@ -33,7 +34,7 @@ public function up(): void $table->string('webhook_access_key')->nullable()->index(); $table->unsignedInteger('current_recurring_bill_id')->nullable()->index(); $table = $this->fulfilmentStats($table); - $table->string('rental_agreement_state')->nullable()->index(); + $table->string('status')->default(FulfilmentCustomerStatus::NO_RENTAL_AGREEMENT->value)->index(); $table->jsonb('data'); $table->timestampsTz(); $this->softDeletes($table); diff --git a/resources/js/Components/Tables/Grp/Org/Fulfilment/CRM/TableCustomers.vue b/resources/js/Components/Tables/Grp/Org/Fulfilment/CRM/TableFulfilmentCustomers.vue similarity index 72% rename from resources/js/Components/Tables/Grp/Org/Fulfilment/CRM/TableCustomers.vue rename to resources/js/Components/Tables/Grp/Org/Fulfilment/CRM/TableFulfilmentCustomers.vue index 731bd873a6..4308a31a52 100644 --- a/resources/js/Components/Tables/Grp/Org/Fulfilment/CRM/TableCustomers.vue +++ b/resources/js/Components/Tables/Grp/Org/Fulfilment/CRM/TableFulfilmentCustomers.vue @@ -12,6 +12,7 @@ import { FontAwesomeIcon } from '@fortawesome/vue-fontawesome' import { faCheck, faTimes } from '@fal' import { library } from '@fortawesome/fontawesome-svg-core' import { trans } from 'laravel-vue-i18n' +import warehouse from "@/Pages/Grp/Org/Warehouse/Warehouse.vue"; library.add(faCheck, faTimes) const props = defineProps<{ @@ -36,13 +37,10 @@ function customerRoute(customer: FulfilmentCustomer) {