diff --git a/app/Classes/General/Eloquent/Filters/DoesNotHavePaymentStatusIn.php b/app/Classes/General/Eloquent/Filters/DoesNotHavePaymentStatusIn.php new file mode 100644 index 00000000..f8e9f214 --- /dev/null +++ b/app/Classes/General/Eloquent/Filters/DoesNotHavePaymentStatusIn.php @@ -0,0 +1,22 @@ +whereDoesntHave('transactions', function (Builder $query) use($value) { + $query->where('type', TransactionType::PAYMENT)->whereIn('status', $value); + }); + } +} \ No newline at end of file diff --git a/app/Classes/General/Eloquent/Filters/HavePaymentStatusNotIn.php b/app/Classes/General/Eloquent/Filters/HavePaymentStatusNotIn.php new file mode 100644 index 00000000..0b989f73 --- /dev/null +++ b/app/Classes/General/Eloquent/Filters/HavePaymentStatusNotIn.php @@ -0,0 +1,22 @@ +whereHas('transactions', function (Builder $query) use($value) { + $query->where('type', TransactionType::PAYMENT)->whereNotIn('status', $value); + }); + } +} \ No newline at end of file diff --git a/app/Classes/Jobs/UpdatePerfexCRMInvoice.php b/app/Classes/Jobs/UpdatePerfexCRMInvoice.php index 4f0c84ae..3cdedcbf 100644 --- a/app/Classes/Jobs/UpdatePerfexCRMInvoice.php +++ b/app/Classes/Jobs/UpdatePerfexCRMInvoice.php @@ -21,6 +21,7 @@ use Illuminate\Queue\SerializesModels; use Illuminate\Support\Facades\Log; use Carbon\Carbon; + class UpdatePerfexCRMInvoice implements ShouldQueue { use Dispatchable, InteractsWithQueue, Queueable, SerializesModels; @@ -60,6 +61,7 @@ class UpdatePerfexCRMInvoice implements ShouldQueue if($invoiceStatus != PerfexCRMInvoiceStatus::PAID){ //get project $projectId = ""; + $projectName = ""; if($transaction->owner instanceof Transaction){ $orderReference = $transaction->owner->owner->owner()->first()->reference; $packingListReference = $transaction->owner->owner->reference; @@ -70,6 +72,11 @@ class UpdatePerfexCRMInvoice implements ShouldQueue } } + if($projectId == ""){ + Log::error(json_encode('UpdatePerfexCRMInvoice debug: '.$projectName)); + Log::error(json_encode($transaction->owner)); + } + //update invoice (App()->make(UpdatesPerfexCRMInvoice::class))->execute($invoice, $projectId); } diff --git a/app/Classes/Modules/Billplzs/ControllersLogic/CallbackBillplzLogic.php b/app/Classes/Modules/Billplzs/ControllersLogic/CallbackBillplzLogic.php index e9daa5f1..18986b1d 100644 --- a/app/Classes/Modules/Billplzs/ControllersLogic/CallbackBillplzLogic.php +++ b/app/Classes/Modules/Billplzs/ControllersLogic/CallbackBillplzLogic.php @@ -106,11 +106,11 @@ class CallbackBillplzLogic $request->headers->set('Authorization', 'Bearer '.$token); // check if is wallet top up - if($transaction->owner instanceof Wallet && $transaction->status !== ApprovalStatus::APPROVED) { + if($transaction->owner instanceof Wallet && $status === ApprovalStatus::APPROVED) { $this->updatesWalletBalance->execute($transaction->owner, $transaction->amount); } - $this->updatesTransactionStatus->execute($transaction, ApprovalStatus::APPROVED); + $this->updatesTransactionStatus->execute($transaction, $status); if(($invoice->amount - $transaction->amount) < 0.01 && !$transaction->owner instanceof Wallet) { $this->updatesTransactionStatus->execute($invoice, ApprovalStatus::COMPLETED); @@ -124,7 +124,7 @@ class CallbackBillplzLogic } } - $company_module_marking = $transaction->owner->owner->connections->first()->invitee_reference; + $company_module_marking = $transaction->owner->owner->connections? $transaction->owner->owner->connections->first()->invitee_reference: null; return $request->method() === 'POST' ? true : view('pages.payments_redirect', ['marking' => $order->reference ?? null, 'company_module_marking' => $company_module_marking ?? null, 'transaction' => $transaction, 'status' => $status]); } diff --git a/app/Classes/Modules/PerfexCRM/Processors/CreatePerfexCRMInvoiceProcessor.php b/app/Classes/Modules/PerfexCRM/Processors/CreatePerfexCRMInvoiceProcessor.php index 806bb5dd..e3a3a4a5 100644 --- a/app/Classes/Modules/PerfexCRM/Processors/CreatePerfexCRMInvoiceProcessor.php +++ b/app/Classes/Modules/PerfexCRM/Processors/CreatePerfexCRMInvoiceProcessor.php @@ -14,6 +14,7 @@ use App\Classes\Modules\PerfexCRM\Services\CreatesPerfexCRMCustomerProject; use App\Classes\ValueObjects\Constants\PerfexCRMProjectStatus; use App\Models\PackingList; use Carbon\Carbon; +use Illuminate\Support\Facades\Log; class CreatePerfexCRMInvoiceProcessor { @@ -67,7 +68,7 @@ class CreatePerfexCRMInvoiceProcessor } $date = Carbon::parse($transaction->created_at)->format('Y-m-d'); - $dueDate = Carbon::parse($transaction->created_at)->format('Y-m-d'); + $dueDate = Carbon::parse($transaction->created_at)->addDays(6)->startOfDay()->format('Y-m-d'); $currency = 1; //cief TODO: To look into Malaysia and Chinese currency $subTotal = 0.00; $total = 0.00; @@ -99,6 +100,7 @@ class CreatePerfexCRMInvoiceProcessor //get project $projectId = ""; //Project only exist in CRM if the customer already made payment + $projectName = ""; if($isPaid){ if($transaction->owner instanceof PackingList){ $orderReference = $transaction->owner->owner->reference; @@ -115,6 +117,11 @@ class CreatePerfexCRMInvoiceProcessor } } } + + if($projectId == ""){ + Log::error(json_encode('CreatePerfexCRMInvoiceProcessor debug: '.$projectName)); + Log::error(json_encode($transaction->owner)); + } } //newitems diff --git a/app/Classes/Modules/PerfexCRM/Processors/PackingListToPerfexCRMProcessor.php b/app/Classes/Modules/PerfexCRM/Processors/PackingListToPerfexCRMProcessor.php index 775407ed..55d2e150 100644 --- a/app/Classes/Modules/PerfexCRM/Processors/PackingListToPerfexCRMProcessor.php +++ b/app/Classes/Modules/PerfexCRM/Processors/PackingListToPerfexCRMProcessor.php @@ -7,6 +7,7 @@ use App\Classes\ValueObjects\Constants\PerfexCRMTasks; use App\Classes\Jobs\UpdatePerfexCRM; use App\Models\PackingList; use App\Classes\ValueObjects\Constants\PerfexCRMProjectStatus; +use Illuminate\Support\Facades\Log; class PackingListToPerfexCRMProcessor { @@ -17,35 +18,41 @@ class PackingListToPerfexCRMProcessor */ public function execute(PackingList $packingList) { - $order = $packingList->owner; - $companyModule = $order->companyModule()->first(); - $connection = $companyModule->inviters()->withPivot('invitee_reference')->first(); - $companyName = $companyModule->name; - $companyReference = $connection ? $connection->pivot->invitee_reference:''; - $employee = $companyModule->employees()->first(); - $contactEmail = $employee->email; - $contactName = $employee->name; + try { + $order = $packingList->owner; + $companyModule = $order->companyModule()->first(); + $connection = $companyModule->inviters()->withPivot('invitee_reference')->first(); + $companyName = $companyModule->name; + $companyReference = $connection ? $connection->pivot->invitee_reference:''; + $employee = $companyModule->employees()->first(); + $contactEmail = $employee->email; + $contactName = $employee->name; - $orderReference = $packingList->owner->reference; - $packingListReference = $packingList->reference; - $projectName = 'IZYIM | X1 Shipping | '.$orderReference.' | '.$packingListReference; + $orderReference = $packingList->owner->reference; + $packingListReference = $packingList->reference; + $projectName = 'IZYIM | X1 Shipping | '.$orderReference.' | '.$packingListReference; - $updatePerfexCRMObject = new UpdatePerfexCRMObject( - $companyName, - $companyReference, - $contactName, - $contactEmail, - "", - $projectName, - PerfexCRMProjectStatus::NOT_STARTED, - [], - [ - PerfexCRMTasks::TASK_LOADED_CONTAINER_1, - PerfexCRMTasks::TASK_LOADED_CONTAINER_2, - ] - ); - UpdatePerfexCRM::dispatch($updatePerfexCRMObject); + $updatePerfexCRMObject = new UpdatePerfexCRMObject( + $companyName, + $companyReference, + $contactName, + $contactEmail, + "", + $projectName, + PerfexCRMProjectStatus::NOT_STARTED, + [], + [ + PerfexCRMTasks::TASK_LOADED_CONTAINER_1, + PerfexCRMTasks::TASK_LOADED_CONTAINER_2, + ] + ); + UpdatePerfexCRM::dispatch($updatePerfexCRMObject); + } catch (\Exception $exception){ + Log::error(json_encode('PackingListToPerfexCRMProcessor debug:')); + Log::error(json_encode($packingList)); + Log::error($exception); + } return true; } } diff --git a/app/Classes/Modules/PerfexCRM/Services/UpdatesPerfexCRMInvoice.php b/app/Classes/Modules/PerfexCRM/Services/UpdatesPerfexCRMInvoice.php index b7ab4b2a..b75b5cae 100644 --- a/app/Classes/Modules/PerfexCRM/Services/UpdatesPerfexCRMInvoice.php +++ b/app/Classes/Modules/PerfexCRM/Services/UpdatesPerfexCRMInvoice.php @@ -38,7 +38,7 @@ class UpdatesPerfexCRMInvoice $data = [ 'number' => $invoice->number, 'date' => $invoice->date, - 'duedate' => $invoice->date, + 'duedate' => $invoice->duedate, 'currency' => $invoice->currency, 'subtotal' => $invoice->subtotal, 'total' => $invoice->total, diff --git a/app/Console/Commands/AuditBillplz.php b/app/Console/Commands/AuditBillplz.php new file mode 100644 index 00000000..77540087 --- /dev/null +++ b/app/Console/Commands/AuditBillplz.php @@ -0,0 +1,77 @@ +info(Carbon::now() . ' : Audit Billplz cron started.'); + $start = new Carbon(); + + $transactions = Transaction::where('type', TransactionType::PAYMENT)->where('payment_method', PaymentMethodType::PAYMENT_GATEWAY)->whereIn('status', [ApprovalStatus::COMPLETED, ApprovalStatus::APPROVED])->get(); + $totalTransactions = count($transactions); + $counter = 1; + $totalAmount = 0; + foreach ($transactions as $transaction){ + $response = Http::withBasicAuth(config('billplz.api_key').':', '')->get(config('billplz.base_url').'/api/v3/bills/'.$transaction->payment_reference); + + if($response->successful()){ + $data = $response->json(); + if($data['paid']){ + + } else { + $totalAmount += $transaction->amount; + $this->info($counter . ' of ' . $totalTransactions . '. Order: '. $transaction->owner->owner->owner->reference . ' - Date: '.$transaction->owner->created_at->format('d-m-Y').' - Amount: '. $transaction->amount); + } + }else{ + $this->info("billplz error"); + } + $counter++; + } + + $end = new Carbon(); + $elapsedTime = $start->diff($end)->format('%H:%I:%S'); + + $this->info(Carbon::now() . ' : Done Audit Billplz. ElapsedTime: ' . $elapsedTime . '. Total: ' . $totalAmount); + } +} diff --git a/app/Console/Commands/debugBillplzFailedPayment.php b/app/Console/Commands/debugBillplzFailedPayment.php new file mode 100644 index 00000000..729ecfee --- /dev/null +++ b/app/Console/Commands/debugBillplzFailedPayment.php @@ -0,0 +1,77 @@ +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); + + // dd($transaction->owner->owner->owner->reference); + + 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 . '. Order Marking: '. $transaction->owner->owner->owner->reference . ' - Date: '.$transaction->created_at->format('d-m-Y').' - Amount: '. $transaction->amount . '. Current Status: ' . $approvalStatusArray[$transaction->status]); + } +} diff --git a/resources/assets/vue/components/companies/sections/CustomerPaymentBillingSectionComponent.vue b/resources/assets/vue/components/companies/sections/CustomerPaymentBillingSectionComponent.vue index 4ebdffaa..b594b3a5 100644 --- a/resources/assets/vue/components/companies/sections/CustomerPaymentBillingSectionComponent.vue +++ b/resources/assets/vue/components/companies/sections/CustomerPaymentBillingSectionComponent.vue @@ -27,6 +27,22 @@ +
Amount
Payment Date
+