diff --git a/app/Classes/General/Eloquent/Filters/ReferenceLike.php b/app/Classes/General/Eloquent/Filters/ReferenceLike.php new file mode 100644 index 00000000..25f8373c --- /dev/null +++ b/app/Classes/General/Eloquent/Filters/ReferenceLike.php @@ -0,0 +1,20 @@ +where('reference', 'LIKE', '%'.$value.'%'); + } + +} \ No newline at end of file diff --git a/app/Classes/General/Eloquent/Filters/WhereHasSeasonalSegment.php b/app/Classes/General/Eloquent/Filters/WhereHasSeasonalSegment.php new file mode 100644 index 00000000..78905650 --- /dev/null +++ b/app/Classes/General/Eloquent/Filters/WhereHasSeasonalSegment.php @@ -0,0 +1,20 @@ +whereHas('seasonalSegments'); + } +} \ No newline at end of file diff --git a/app/Classes/Modules/Companies/ControllersLogic/AssignCompanyToSegmentLogic.php b/app/Classes/Modules/Companies/ControllersLogic/AssignCompanyToSegmentLogic.php index 17a6c900..f814057f 100644 --- a/app/Classes/Modules/Companies/ControllersLogic/AssignCompanyToSegmentLogic.php +++ b/app/Classes/Modules/Companies/ControllersLogic/AssignCompanyToSegmentLogic.php @@ -2,11 +2,15 @@ namespace App\Classes\Modules\Companies\ControllersLogic; - +use App\Classes\Exceptions\MalformedRequestException; use App\Classes\General\Abstracts\AbstractControllerLogic; use App\Classes\Modules\Companies\Processors\AssignSegmentProcessor; use App\Classes\Modules\Companies\Services\FetchesCompany; +use App\Classes\Modules\Segments\DataTransferObjects\SeasonalSegmentObject; +use App\Classes\Modules\Segments\Services\CreatesSeasonalSegment; use App\Http\Resources\CompanyResource; +use App\Models\SeasonalSegment; +use Carbon\Carbon; use Illuminate\Http\JsonResponse; use Illuminate\Http\Request; @@ -29,15 +33,20 @@ class AssignCompanyToSegmentLogic extends AbstractControllerLogic /** @var AssignSegmentProcessor */ private $assignCompanyToSegmentProcessor; + /** @var CreatesSeasonalSegment */ + private $createsSeasonalSegment; + /** * AssignCompanyToSegmentLogic constructor. * @param FetchesCompany $fetchesCompany * @param AssignSegmentProcessor $assignCompanyToSegmentProcessor + * @param CreatesSeasonalSegment $createsSeasonalSegment */ - public function __construct(FetchesCompany $fetchesCompany, AssignSegmentProcessor $assignCompanyToSegmentProcessor) + public function __construct(FetchesCompany $fetchesCompany, AssignSegmentProcessor $assignCompanyToSegmentProcessor, CreatesSeasonalSegment $createsSeasonalSegment) { $this->fetchesCompany = $fetchesCompany; $this->assignCompanyToSegmentProcessor = $assignCompanyToSegmentProcessor; + $this->createsSeasonalSegment = $createsSeasonalSegment; } /** @@ -54,6 +63,24 @@ class AssignCompanyToSegmentLogic extends AbstractControllerLogic $this->assignCompanyToSegmentProcessor->execute($company, $request->input('segment_id')); + if ($request->input('ending_on')) { + + if ($request->input('ending_on') && Carbon::parse($request->input('ending_on')) <= Carbon::now()) { + throw new MalformedRequestException('The Ending Date must be equal to or later than today\'s date.'); + } + + // todo-new + // if (count($company->seasonalSegments)) { + // throw new MalformedRequestException('System error. Please contact admin.'); + // } + + $start_date = $request->input('starting_on') ? $request->input('starting_on') : Carbon::now(); + + $seasonalSegmentObject = new SeasonalSegmentObject($company->id, $request->input('segment_id'), $start_date, $request->input('ending_on') ?? null); + + $this->createsSeasonalSegment->execute($seasonalSegmentObject); + } + return $this->resourceResponse(new CompanyResource($company)); } } \ No newline at end of file diff --git a/app/Classes/Modules/Companies/ControllersLogic/RemoveCompanyFromSegmentLogic.php b/app/Classes/Modules/Companies/ControllersLogic/RemoveCompanyFromSegmentLogic.php index 10623311..22c89a45 100644 --- a/app/Classes/Modules/Companies/ControllersLogic/RemoveCompanyFromSegmentLogic.php +++ b/app/Classes/Modules/Companies/ControllersLogic/RemoveCompanyFromSegmentLogic.php @@ -53,11 +53,12 @@ class RemoveCompanyFromSegmentLogic extends AbstractControllerLogic */ public function logic(Request $request) : JsonResponse { - $company = $this->fetchesCompany->execute(['id' => $request->route('id')]); $segment = $this->fetchesSegment->execute(['id' => $request->route('segment_id')]); + $company->seasonalSegments()->where('segment_id', $request->route('segment_id'))->delete(); + $this->removesCompanyFromSegment->execute($company, $segment); return $this->resourceResponse(new CompanyResource($company)); diff --git a/app/Classes/Modules/Segments/DataTransferObjects/SeasonalSegmentObject.php b/app/Classes/Modules/Segments/DataTransferObjects/SeasonalSegmentObject.php new file mode 100644 index 00000000..d045556e --- /dev/null +++ b/app/Classes/Modules/Segments/DataTransferObjects/SeasonalSegmentObject.php @@ -0,0 +1,74 @@ +companyId = $companyId; + $this->segmentId = $segmentId; + $this->starting_on = $starting_on; + $this->ending_on = $ending_on; + $this->status = $status; + } + + /** + * @return int + */ + public function getCompanyId(): int + { + return $this->companyId; + } + + /** + * @return int + */ + public function getSegmentId(): int + { + return $this->segmentId; + } + + + /** + * @return string + */ + public function getStartingOn(): string + { + return $this->starting_on; + } + + /** + * @return string + */ + public function getEndingOn(): ?string + { + return $this->ending_on; + } +} \ No newline at end of file diff --git a/app/Classes/Modules/Segments/Services/CreatesSeasonalSegment.php b/app/Classes/Modules/Segments/Services/CreatesSeasonalSegment.php new file mode 100644 index 00000000..0125a956 --- /dev/null +++ b/app/Classes/Modules/Segments/Services/CreatesSeasonalSegment.php @@ -0,0 +1,27 @@ +company_id = $object->getCompanyId(); + $model->segment_id = $object->getSegmentId(); + $model->starting_on = $object->getStartingOn(); + $model->ending_on = $object->getEndingOn(); + + return $this->handler($model); + + } +} \ No newline at end of file diff --git a/app/Console/Commands/RemoveSeasonalSegmentCompany.php b/app/Console/Commands/RemoveSeasonalSegmentCompany.php new file mode 100644 index 00000000..be41d05d --- /dev/null +++ b/app/Console/Commands/RemoveSeasonalSegmentCompany.php @@ -0,0 +1,57 @@ +removesCompanyFromSegment = $removesCompanyFromSegment; + } + + /** + * Execute the console command. + * + * @return int + */ + public function handle() + { + $seasonalSegment = SeasonalSegment::where('ending_on', '<=', Carbon::today())->get(); + + if (count($seasonalSegment)){ + foreach ($seasonalSegment as $seasonalSegmentCompany) { + $this->removesCompanyFromSegment->execute($seasonalSegmentCompany->company, $seasonalSegmentCompany->segment); + $seasonalSegmentCompany->delete(); + $this->info(Carbon::now() . ' : Deleted id: ' . $seasonalSegmentCompany->id); + } + } + } +} diff --git a/app/Console/Kernel.php b/app/Console/Kernel.php index 8edaaa22..e549a23a 100644 --- a/app/Console/Kernel.php +++ b/app/Console/Kernel.php @@ -34,6 +34,10 @@ class Kernel extends ConsoleKernel // $schedule->command('inspire')->hourly(); $schedule->command('mail:EmailDoToVTCommand')->dailyAt('10:00')->withoutOverlapping(); + $schedule->command('seasonalSegmantCompany:remove') + ->dailyAt('01:00') + ->appendOutputTo(storage_path().'/logs/soft-delete-seasonal-segmant-company.log') + ->withoutOverlapping(); } /** diff --git a/app/Http/Resources/CompanyResource.php b/app/Http/Resources/CompanyResource.php index 6d7cb2e4..85ecee16 100644 --- a/app/Http/Resources/CompanyResource.php +++ b/app/Http/Resources/CompanyResource.php @@ -61,6 +61,7 @@ class CompanyResource extends JsonResource 'default' => new BankResource($this->banks->where('type', BankAccountType::EXTERNAL)->where('default', true)->first()) ], 'segments' => SegmentResource::collection($this->segments), + 'seasonalSegment' => $this->whenLoaded('seasonalSegments', SeasonalSegmentResource::collection($this->seasonalSegments)), 'services' => (new FetchesCompanyServices())->getServices($this->servicesConfigurations()), 'wallet' => $this->whenLoaded('wallets', new WalletResource($this->wallets()->with('transactions')->first()), new WalletResource($this->wallets()->first())), 'created_at' => $this->created_at->format('d-m-Y'), diff --git a/app/Http/Resources/SeasonalSegmentResource.php b/app/Http/Resources/SeasonalSegmentResource.php new file mode 100644 index 00000000..8a38f5be --- /dev/null +++ b/app/Http/Resources/SeasonalSegmentResource.php @@ -0,0 +1,37 @@ + $this->id, + 'segment_name' => ucwords($this->segment->name), + 'ending_on' => $this->ending_on->format('d-m-Y'), + ]; + } +} diff --git a/app/Models/Company.php b/app/Models/Company.php index def72720..8b2e6081 100644 --- a/app/Models/Company.php +++ b/app/Models/Company.php @@ -62,6 +62,14 @@ class Company extends AbstractModel implements Documentable return $this->belongsToMany(Segment::class, (new SegmentCompany())->getTable(), 'company_id', 'segment_id'); } + /** + * @return belongsToMany + */ + public function seasonalSegments() + { + return $this->hasMany(SeasonalSegment::class); + } + /** * @return belongsToMany */ diff --git a/app/Models/SeasonalSegment.php b/app/Models/SeasonalSegment.php new file mode 100644 index 00000000..30bb1796 --- /dev/null +++ b/app/Models/SeasonalSegment.php @@ -0,0 +1,48 @@ +BelongsTo(Company::class, 'company_id', 'id'); + } + + public function segment() + { + return $this->belongsTo(Segment::class); + } +} diff --git a/database/migrations/2023_03_16_223623_seasonal_segment_table.php b/database/migrations/2023_03_16_223623_seasonal_segment_table.php new file mode 100644 index 00000000..4b804086 --- /dev/null +++ b/database/migrations/2023_03_16_223623_seasonal_segment_table.php @@ -0,0 +1,41 @@ +id(); + $table->foreignId('company_id')->unsigned(); + $table->string('status')->default(ApprovalStatus::APPROVED); + $table->foreignId('segment_id')->unsigned(); + $table->timestamp('starting_on')->nullable(); + $table->timestamp('ending_on')->nullable(); + $table->softDeletes(); + $table->timestamps(); + + $table->foreign('segment_id')->references('id')->on('segments'); + $table->foreign('company_id')->references('id')->on('companies'); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + // + } +} diff --git a/resources/assets/vue/components/companies/elements/SeasonalSegmentComponent.vue b/resources/assets/vue/components/companies/elements/SeasonalSegmentComponent.vue new file mode 100644 index 00000000..4e3dad78 --- /dev/null +++ b/resources/assets/vue/components/companies/elements/SeasonalSegmentComponent.vue @@ -0,0 +1,69 @@ + + + \ No newline at end of file diff --git a/resources/assets/vue/components/companies/forms/AssignSegmentFormComponent.vue b/resources/assets/vue/components/companies/forms/AssignSegmentFormComponent.vue index 667bc76f..af164001 100644 --- a/resources/assets/vue/components/companies/forms/AssignSegmentFormComponent.vue +++ b/resources/assets/vue/components/companies/forms/AssignSegmentFormComponent.vue @@ -23,6 +23,23 @@ + +
+
+ + + + +

Please leave End Date empty if the end date is not confirmed or there is no end date.

+
+
Not Now
@@ -49,7 +66,9 @@ data(){ return { parameters: { - segment_id: '' + segment_id: '', + // starting_on: '', + ending_on: '', } } }, @@ -57,7 +76,9 @@ parameters: { segment_id: { required - } + }, + // starting_on: {}, + ending_on: {}, } }, computed: { diff --git a/resources/assets/vue/components/companies/forms/DetachSegmentFormComponent.vue b/resources/assets/vue/components/companies/forms/DetachSegmentFormComponent.vue index 7e87816d..8a276393 100644 --- a/resources/assets/vue/components/companies/forms/DetachSegmentFormComponent.vue +++ b/resources/assets/vue/components/companies/forms/DetachSegmentFormComponent.vue @@ -38,7 +38,11 @@ type: Number } }, - + methods: { + successHandler(){ + window.location.reload(); + } + }, mixins: [componentHandler, ModalFormHandler] } \ No newline at end of file diff --git a/resources/assets/vue/components/companies/sections/SeasonalSegmentSectionComponent.vue b/resources/assets/vue/components/companies/sections/SeasonalSegmentSectionComponent.vue new file mode 100644 index 00000000..03ef8bba --- /dev/null +++ b/resources/assets/vue/components/companies/sections/SeasonalSegmentSectionComponent.vue @@ -0,0 +1,61 @@ + + + \ No newline at end of file diff --git a/resources/views/pages/settings.blade.php b/resources/views/pages/settings.blade.php index 787c1616..a242eec7 100644 --- a/resources/views/pages/settings.blade.php +++ b/resources/views/pages/settings.blade.php @@ -54,6 +54,29 @@
+
+
+
+
+
+
+
+
+ +
+
+
Seasonal Segment
+
+
+
+
+
+
+
+