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 '
+
+ | Date |
+ Bank |
+ Description |
+ Credit |
+ Pay For |
+ System Reference |
+ Human Reference |
+ Multiple |
+ Match? |
+
';
+
+ $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 '
+ | '.$date->format('d-m-Y').' |
+ '.$branch.' |
+ '.$row['description'].' |
+ '.$credit.' |
+ '.$row['pay_for'].' |
+ '.$systemReference.' |
+ '.$row['remarkreferences'].' |
+ '.$multiple.' |
+ '.$matches.' |
+
';
+ }
+ }
+// 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 @@
+
+
+
+
+
+
+
+
+
+
{{item.name}} - {{item.reference}}
+
+
+
+
+
+
+
+
+
+
\ 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 @@
+
+
diff --git a/routes/web.php b/routes/web.php
index 7b3e817e..8621914a 100644
--- a/routes/web.php
+++ b/routes/web.php
@@ -558,4 +558,7 @@ Route::get('/currency-rate-history', function () {
return view('pages.rate_histories')->with('paymentMethods', $paymentMethods);
})->name('currency_rate.history');
+Route::get('/bank-record', 'Imports\ImportBankRecordController@import');
+
+