diff --git a/.env.example b/.env.example index 91c8e15c..d48eeb79 100644 --- a/.env.example +++ b/.env.example @@ -61,3 +61,5 @@ BILLPLZ_WALLET_COLLECTION_ID="t0cggbdd" PERFEXCRM_BASE_URL="" PERFEXCRM_API_KEY="" PERFEXCRM_IS_ENABLED="false" + +HONEY_TRAP_SEGMENT_ID='false' # set HONEY_TRAP_SEGMENT_ID 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..97fcb193 100644 --- a/app/Classes/Modules/Companies/ControllersLogic/AssignCompanyToSegmentLogic.php +++ b/app/Classes/Modules/Companies/ControllersLogic/AssignCompanyToSegmentLogic.php @@ -6,7 +6,11 @@ namespace App\Classes\Modules\Companies\ControllersLogic; 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,16 @@ class AssignCompanyToSegmentLogic extends AbstractControllerLogic $this->assignCompanyToSegmentProcessor->execute($company, $request->input('segment_id')); + if (env('HONEY_TRAP_SEGMENT_ID') && env('HONEY_TRAP_SEGMENT_ID') == $request->input('segment_id')) { + $start_date = $request->input('starting_on') ? $request->input('starting_on') : Carbon::now(); + $seasonalSegmentObject = new SeasonalSegmentObject($request->route('id'), $request->input('segment_id'), $start_date, $request->input('ending_on')); + // $seasonalSegmentObject = new SeasonalSegmentObject((int)$request->route('id'), $request->input('segment_id'), '01-01-2022', '01-01-2022'); + + $this->createsSeasonalSegment->execute($seasonalSegmentObject); + } else { + dd('d'); + } + return $this->resourceResponse(new CompanyResource($company)); } } \ No newline at end of file diff --git a/app/Classes/Modules/Imports/Services/ImportsBankRecord.php b/app/Classes/Modules/Imports/Services/ImportsBankRecord.php new file mode 100644 index 00000000..fa972e40 --- /dev/null +++ b/app/Classes/Modules/Imports/Services/ImportsBankRecord.php @@ -0,0 +1,62 @@ +where('type', TransactionType::PAYMENT)->where('owner_type', Booking::class) + ->WhereDate('created_at', $date->format('Y-m-d')) + ->where('amount', '>=', $credit)->where('amount', '<', ($credit + 0.01)) + ->get(); + + if(count($transaction)) { + $systemReference = $transaction->pluck('owner.marking')->flatten()->implode(', '); + } + + $matches = $systemReference === $collection['remarkreferences'] ? 'Yes' : 'No'; + + echo ' + '.$date->format('d-m-Y').' + '.$collection['description'].' + '.$credit.' + '.$systemReference.' + '.$collection['remarkreferences'].' + '.$matches.' + '; + + } + + public function batchSize(): int + { + return 100; + } + + public function rules(): array + { + return [ + + ]; + } +} diff --git a/app/Classes/Modules/Segments/DataTransferObjects/SeasonalSegmentObject.php b/app/Classes/Modules/Segments/DataTransferObjects/SeasonalSegmentObject.php new file mode 100644 index 00000000..5911a384 --- /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..dc6fdb49 --- /dev/null +++ b/app/Classes/Modules/Segments/Services/CreatesSeasonalSegment.php @@ -0,0 +1,27 @@ +company_id = $object->getSegmentId(); + $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/Classes/ValueObjects/Constants/ApprovalStatus.php b/app/Classes/ValueObjects/Constants/ApprovalStatus.php index 154db2ca..ba7660d4 100644 --- a/app/Classes/ValueObjects/Constants/ApprovalStatus.php +++ b/app/Classes/ValueObjects/Constants/ApprovalStatus.php @@ -19,4 +19,15 @@ final class ApprovalStatus { public const EXPIRED = 6; public const REFUNDED = 7; + + public const APPROVAL_STATUS_ID = [ + self::PENDING_SUBMISSION => "Pending Submission", + self::PENDING_VERIFICATION => "Pending Verification", + self::APPROVED => "Approved", + self::COMPLETED => "Completed", + self::REJECTED => "Rejected", + self::SUSPENDED => "Suspended", + self::EXPIRED => "Expired", + self::REFUNDED => "Refunded", + ]; } diff --git a/app/Console/Commands/RemoveSeasonalSegmentCompany.php b/app/Console/Commands/RemoveSeasonalSegmentCompany.php new file mode 100644 index 00000000..fd71d891 --- /dev/null +++ b/app/Console/Commands/RemoveSeasonalSegmentCompany.php @@ -0,0 +1,48 @@ +count(); + + SeasonalSegment::where('ending_on', '<=', Carbon::today())->delete(); + + $this->info(Carbon::now() . ' : Done soft delete on seasonal segment company. Total Deleted: ' . $count); + } +} diff --git a/app/Console/Commands/debugBillplzFailedPayment.php b/app/Console/Commands/debugBillplzFailedPayment.php new file mode 100644 index 00000000..ee1cf4b0 --- /dev/null +++ b/app/Console/Commands/debugBillplzFailedPayment.php @@ -0,0 +1,75 @@ +where('payment_method', PaymentMethodType::PAYMENT_GATEWAY)->whereNotIn('status', [ApprovalStatus::COMPLETED, ApprovalStatus::APPROVED])->get(); + + $i = 0; + $totalAmount = 0; + foreach ($transactions as $transaction){ + $response = Http::withBasicAuth(config('billplz.api_key').':', '')->get(config('billplz.base_url').'/api/v3/bills/'.$transaction->payment_reference); + + // dd($response); + + if($response->successful()){ + $data = $response->json(); + if($data['paid']){ + if (!in_array($transaction->status, [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED])) { + $this->returnLog('Paid transaction', $transaction); + } + } + // else { + // $totalAmount += $transaction->amount; + // $this->returnLog('Unpaid Transaction', $transaction); + // } + }else{ + $this->returnLog('billplz error', $transaction); + } + } + } + + public function returnLog($text, $transaction) { + $approvalStatusArray = ApprovalStatus::APPROVAL_STATUS_ID; + $this->info($text . ' - id: '. $transaction->id . '. Booking Marking: '. $transaction->owner->marking . ' - Date: '.$transaction->created_at->format('d-m-Y').' - Amount: '. $transaction->amount . '. Current Status: ' . $approvalStatusArray[$transaction->status]); + } +} diff --git a/app/Console/Kernel.php b/app/Console/Kernel.php index 8edaaa22..baf9a4cc 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') + ->hourly() + ->appendOutputTo (storage_path().'/logs/soft-delete-seasonal-segmant-company.log') + ->withoutOverlapping(); } /** diff --git a/app/Http/Controllers/Imports/ImportBankRecordController.php b/app/Http/Controllers/Imports/ImportBankRecordController.php new file mode 100644 index 00000000..effac446 --- /dev/null +++ b/app/Http/Controllers/Imports/ImportBankRecordController.php @@ -0,0 +1,102 @@ +input('files'), '', ApprovalStatus::APPROVED, 'imports'); + + echo ' + + + + + + + + + + + '; + + $collection = Excel::toCollection(new ImportsBankRecord(), 'daily_transaction_nov.xlsx'); + + $branches = [ + 0 => 'MBB Cyber', + 1 => 'MBB SS2' + ]; + + foreach ($collection as $key => $sheet){ + $branch = $branches[$key]; + foreach ($sheet as $row) { + $date = Date::excelToDateTimeObject($row['date']); + $credit = (float) $row['credit']; + $systemReference = null; + $multiple = 'No'; + + $transactions = Transaction::whereIn('status', [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED]) + ->where(function ($query){ + return $query->where(function ($query){ + return $query->where('type', TransactionType::PAYMENT)->where('owner_type', Booking::class)->where('payment_method', '!=', PaymentMethodType::WALLET); + })->orWhere(function ($query){ + $query->where('type', TransactionType::TOP_UP); + }); + }) + ->WhereDate('created_at', $date->format('Y-m-d')) + ->where('amount', '>=', $credit)->where('amount', '<', ($credit + 0.01)) + ->get(); + + if(count($transactions)) { + foreach ($transactions as $transaction){ + if($transaction->owner instanceof Booking){ + $systemReference[] = $transaction->owner->marking; + } + + if($transaction->owner instanceof Wallet){ + $systemReference[] = $transaction->bill_no; + } + } + + if(count($systemReference) > 1) { + $multiple = 'Yes'; + } + $systemReference = implode(',', $systemReference); + + } + + $matches = $systemReference == $row['remarkreferences'] ? 'Yes' : 'No'; + + echo ' + + + + + + + + + + '; + } + } +// return []; + } +} 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..06726269 --- /dev/null +++ b/resources/assets/vue/components/companies/elements/SeasonalSegmentComponent.vue @@ -0,0 +1,47 @@ + + + \ 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/views/pages/settings.blade.php b/resources/views/pages/settings.blade.php index 787c1616..7db89c75 100644 --- a/resources/views/pages/settings.blade.php +++ b/resources/views/pages/settings.blade.php @@ -54,6 +54,29 @@
+
+
+
+
+
+
+
+
+ +
+
+
Seasonal Segment
+
+
+
+
+
+
+
+
DateBankDescriptionCreditPay ForSystem ReferenceHuman ReferenceMultipleMatch?
'.$date->format('d-m-Y').''.$branch.''.$row['description'].''.$credit.''.$row['pay_for'].''.$systemReference.''.$row['remarkreferences'].''.$multiple.''.$matches.'