mirror of
https://gitlab.com/CIEFWorldwideSdnBhd/exchange-2.0.git
synced 2026-08-19 04:23:55 +00:00
Merge branch 'vapor/production' into dillon/90-e-invoice-f-3
This commit is contained in:
@@ -0,0 +1,44 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\Jobs\Commands\V2;
|
||||
|
||||
use App\Classes\Modules\Bookings\Processors\RegenerateInvoiceBookingProcessor;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
use Illuminate\Foundation\Bus\Dispatchable;
|
||||
use Illuminate\Queue\InteractsWithQueue;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
use App\Models\Booking;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
|
||||
class OneTimeBatchProcessEInvoicesV2CommandJob implements ShouldQueue
|
||||
{
|
||||
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
|
||||
|
||||
/** @var Booking */
|
||||
private $booking;
|
||||
|
||||
/**
|
||||
* OneTimeBatchProcessEInvoicesV2CommandJob constructor.
|
||||
* @param Booking $booking
|
||||
*/
|
||||
public function __construct(Booking $booking)
|
||||
{
|
||||
$this->booking = $booking;
|
||||
}
|
||||
|
||||
public function handle()
|
||||
{
|
||||
Log::info(Carbon::now() . ': Start job - Processing single booking for E-Invoices for July 2025.');
|
||||
$start = new Carbon();
|
||||
|
||||
$isAllowNormalInvoice = true;
|
||||
(App()->make(RegenerateInvoiceBookingProcessor::class))->execute($this->booking, $isAllowNormalInvoice);
|
||||
|
||||
$end = new Carbon();
|
||||
$elapsedTime = $start->diff($end)->format('%H:%I:%S');
|
||||
Log::info(Carbon::now() . ': End job - Processing single booking for E-Invoices for July 2025. ElapsedTime: ' . $elapsedTime . '.');
|
||||
}
|
||||
}
|
||||
@@ -8,9 +8,10 @@ use App\Classes\Modules\Banks\Services\FetchesBank;
|
||||
use App\Classes\Modules\Banks\Standards\Rules\CanDeleteBank;
|
||||
use App\Classes\Modules\Banks\Services\DeletesBank;
|
||||
use App\Classes\Modules\Banks\Services\CreatesBankLog;
|
||||
use App\Http\Resources\BankResource;
|
||||
use App\Classes\ValueObjects\Constants\RoleTypes;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
|
||||
class DeleteBankLogic extends AbstractControllerLogic
|
||||
{
|
||||
@@ -66,20 +67,30 @@ class DeleteBankLogic extends AbstractControllerLogic
|
||||
*/
|
||||
public function logic(Request $request) : JsonResponse
|
||||
{
|
||||
|
||||
$this->canDeleteBank->passes();
|
||||
|
||||
$bank = $this->fetchesBank->execute(['id' => $request->route('id')]);
|
||||
|
||||
$proceed = false;
|
||||
if($bank->default){
|
||||
throw new RequestValidationException('You can\'t delete bank account when it set to default');
|
||||
$isAuthorized = in_array(Auth::user()->type, RoleTypes::ADMIN_ROLES);
|
||||
if($isAuthorized) {
|
||||
$banks = $bank->company->banks()->where('default', 1)->get();
|
||||
if(count($banks) > 1) {
|
||||
//User should be able to delete themselves, but sometimes there are more than 1 bank set as default (different type, why??!), we need to allow admin to do the delete
|
||||
$proceed = true;
|
||||
}
|
||||
else{
|
||||
$proceed = false;
|
||||
}
|
||||
}
|
||||
|
||||
if(!$proceed){
|
||||
throw new RequestValidationException('You can\'t delete bank account when it set to default');
|
||||
}
|
||||
}
|
||||
|
||||
$bank = $this->deletesBank->execute($bank);
|
||||
|
||||
// $bankLog = $this->createsBankLog->execute($bank);
|
||||
|
||||
// $bankLog = $this->createsBankLog->execute($bank);
|
||||
return $this->response([]);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -69,8 +69,9 @@ class RegenerateInvoiceBookingLogic extends AbstractControllerLogic
|
||||
'with_transactions' => true
|
||||
]
|
||||
);
|
||||
$normalInvoice = $request->input('normal_invoice', false);
|
||||
|
||||
$this->regenerateInvoiceBookingProcessor->execute($booking);
|
||||
$this->regenerateInvoiceBookingProcessor->execute($booking, $normalInvoice);
|
||||
|
||||
return $this->resourceResponse(new BookingResource($booking));
|
||||
}
|
||||
|
||||
@@ -86,7 +86,9 @@ class UpdateBookingAmountWithPOLogic extends AbstractControllerLogic
|
||||
return $product['quantity'] * floatval(str_replace(',', '', $product['unit_price']));
|
||||
});
|
||||
$bookingAmountUpdate = (float)$bookingAttribute->value;
|
||||
$isTally = $total === $bookingAmountUpdate ? true : false;
|
||||
// $isTally = ($total === $bookingAmountUpdate) ? true : false;
|
||||
$isTally = bccomp($total, $bookingAmountUpdate, 3) === 0;
|
||||
|
||||
if(!$isTally){
|
||||
throw new MalformedRequestException('Purchase Order total not tally with updated booking amount of ' . $bookingAmountUpdate);
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@ use App\Classes\ValueObjects\Constants\TransactionType;
|
||||
use App\Models\Booking;
|
||||
use App\Models\Transaction;
|
||||
use Illuminate\Support\Carbon;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
class RegenerateInvoiceBookingProcessor
|
||||
{
|
||||
@@ -48,7 +49,7 @@ class RegenerateInvoiceBookingProcessor
|
||||
$this->createInvoiceTransactionProcessor = $createInvoiceTransactionProcessor;
|
||||
}
|
||||
|
||||
public function execute(Booking $booking)
|
||||
public function execute(Booking $booking, bool $isAllowNormalInvoice = false)
|
||||
{
|
||||
$this->updatesBookingStatus->execute($booking, ApprovalStatus::APPROVED);
|
||||
|
||||
@@ -58,6 +59,8 @@ class RegenerateInvoiceBookingProcessor
|
||||
->orderBy('created_at', 'asc')
|
||||
->first();
|
||||
|
||||
Log::info('RegenerateInvoiceBookingProcessor booking: ' . json_encode($booking->marking));
|
||||
|
||||
// get the first bill_no
|
||||
if($firstInvoice){
|
||||
$firstBillNo = $firstInvoice->bill_no;
|
||||
@@ -90,10 +93,10 @@ class RegenerateInvoiceBookingProcessor
|
||||
$this->deletesDocument->execute($row);
|
||||
}
|
||||
|
||||
$this->createInvoiceTransactionProcessor->execute($booking, $firstBillNo, true);
|
||||
$this->createInvoiceTransactionProcessor->execute($booking, $firstBillNo, true, $isAllowNormalInvoice);
|
||||
}
|
||||
else {
|
||||
$this->createInvoiceTransactionProcessor->execute($booking);
|
||||
$this->createInvoiceTransactionProcessor->execute($booking, "", false, $isAllowNormalInvoice);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,4 +15,14 @@ class CalculatesBookingPaidAmount
|
||||
return $booking->transactions()->payments()->complete()->sum('original_amount');
|
||||
}
|
||||
|
||||
public function executeUntilDate(Booking $booking, Carbon $cutOffDate = null){
|
||||
$amount = $booking->transactions()->payments()->complete();
|
||||
|
||||
if($cutOffDate){
|
||||
$amount->where('created_at', '<=', $cutOffDate);
|
||||
}
|
||||
|
||||
return $amount->sum('original_amount');
|
||||
}
|
||||
|
||||
}
|
||||
@@ -71,6 +71,8 @@ class ExportsNullDebtors implements FromQuery, WithHeadings, WithHeadingRow, Wit
|
||||
*/
|
||||
public function map($company): array
|
||||
{
|
||||
$employee = $company->employees()->orderBy('id', 'DESC')->first();
|
||||
|
||||
return [
|
||||
'<<New>>', // Code
|
||||
'300-0000', // DebtorControlAcc
|
||||
@@ -89,7 +91,7 @@ class ExportsNullDebtors implements FromQuery, WithHeadings, WithHeadingRow, Wit
|
||||
'', // DeliverAddr2
|
||||
'', // DeliverAddr3
|
||||
'', // DeliverPostCode
|
||||
'', // EmailAddress
|
||||
$employee->email, // EmailAddress
|
||||
'', // Attention
|
||||
'', // Phone1
|
||||
'', // Phone2
|
||||
|
||||
@@ -2,18 +2,17 @@
|
||||
|
||||
namespace App\Classes\Modules\Exports\Services;
|
||||
|
||||
use App\Classes\ValueObjects\Constants\PaymentMethodType;
|
||||
use App\Classes\ValueObjects\Constants\TransactionType;
|
||||
use App\Classes\ValueObjects\Constants\ApprovalStatus;
|
||||
use App\Models\Booking;
|
||||
use App\Models\Transaction;
|
||||
use Maatwebsite\Excel\Concerns\Exportable;
|
||||
use Maatwebsite\Excel\Concerns\FromQuery;
|
||||
use Maatwebsite\Excel\Concerns\ShouldAutoSize;
|
||||
use Maatwebsite\Excel\Concerns\WithHeadingRow;
|
||||
use Maatwebsite\Excel\Concerns\WithHeadings;
|
||||
use Maatwebsite\Excel\Concerns\WithMapping;
|
||||
use Illuminate\Http\Request;
|
||||
use App\Classes\Modules\Bookings\Services\CalculatesBookingRefundAmount;
|
||||
use App\Classes\Modules\Bookings\Services\CalculatesBookingRefundServiceCharge;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
@@ -71,6 +70,8 @@ class ExportsSalesInvoiceReport implements FromQuery, WithHeadings, WithHeadingR
|
||||
public function map($booking): array
|
||||
{
|
||||
$records = [];
|
||||
$averageCurrencyRate = 0;
|
||||
$currencyId = 0;
|
||||
|
||||
$purchaseOrder = $booking->transactions()->where('type', TransactionType::PURCHASE_ORDER)->first();
|
||||
$company = $booking->company()->first();
|
||||
@@ -79,15 +80,60 @@ class ExportsSalesInvoiceReport implements FromQuery, WithHeadings, WithHeadingR
|
||||
if(!$lastPaymentTransaction){
|
||||
return $records;
|
||||
}
|
||||
$documentDate = $lastPaymentTransaction->created_at;
|
||||
if(Carbon::parse($booking->updated_at)->isAfter($lastPaymentTransaction->created_at)){
|
||||
$documentDate = $booking->updated_at;
|
||||
|
||||
$invoiceTransaction = $booking->transactions()->where('type', TransactionType::INVOICE)->whereIn('status', [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED])->first();
|
||||
|
||||
$currencyId = $booking->fix_currency_id;
|
||||
|
||||
$subtotal = 0;
|
||||
$displayedSubtotal = 0;
|
||||
$totalPayment = 0;
|
||||
$averageCurrencyRate = $invoiceTransaction->currency_rate;
|
||||
$paymentSum = $booking->transactions()
|
||||
->where('type', TransactionType::PAYMENT)
|
||||
->where('status', ApprovalStatus::COMPLETED)
|
||||
->get()
|
||||
->sum(function ($transaction) {
|
||||
return round($transaction->amount, 2);
|
||||
});
|
||||
if ($paymentSum){
|
||||
$averageCurrencyRate = $booking->transactions()
|
||||
->where('type', TransactionType::PAYMENT)
|
||||
->where('status', ApprovalStatus::COMPLETED)
|
||||
->get()
|
||||
->sum(function ($transaction) {
|
||||
return $transaction->currency_rate;
|
||||
}) / $booking->transactions()
|
||||
->where('type', TransactionType::PAYMENT)
|
||||
->where('status', ApprovalStatus::COMPLETED)
|
||||
->count();
|
||||
|
||||
$refundedAmount = (App()->make(CalculatesBookingRefundAmount::class))->execute($booking, 1);
|
||||
$refundedServiceCharge = (App()->make(CalculatesBookingRefundServiceCharge::class))->execute($booking, 1);
|
||||
|
||||
$totalPayment = $paymentSum - $refundedAmount - $refundedServiceCharge;
|
||||
}
|
||||
|
||||
$documentDate = $lastPaymentTransaction->created_at;
|
||||
// if(Carbon::parse($booking->updated_at)->isAfter($lastPaymentTransaction->created_at)){ //cief todo: 90 - Report E-Invoice date incorrect
|
||||
// $documentDate = $booking->updated_at;
|
||||
// }
|
||||
$formattedDocumentDate = Carbon::parse($documentDate)->format('m/d/Y');
|
||||
|
||||
$firstItem = true;
|
||||
$transactionDetails = $purchaseOrder->transactionDetails;
|
||||
foreach ($transactionDetails as $detail) {
|
||||
$displayUnitPrice = 0;
|
||||
if($averageCurrencyRate && $currencyId){
|
||||
$exactUnitPrice = ($currencyId) === 1 ? $detail->price : bcdiv($detail->price, $averageCurrencyRate, 7);
|
||||
$displayUnitPrice = round($exactUnitPrice, 2);
|
||||
$itemTotal = bcmul($exactUnitPrice, $detail->quantity, 5);
|
||||
$displayedItemTotal = round(bcmul($displayUnitPrice, $detail->quantity, 7), 2);
|
||||
$displayedSubtotal = bcadd($displayedSubtotal, $displayedItemTotal, 2);
|
||||
$subtotal = bcadd($subtotal, $itemTotal, 5);
|
||||
}
|
||||
|
||||
|
||||
$records[] = [
|
||||
$firstItem ? '<<New>>' : '',
|
||||
$formattedDocumentDate,
|
||||
@@ -100,7 +146,7 @@ class ExportsSalesInvoiceReport implements FromQuery, WithHeadings, WithHeadingR
|
||||
'022',
|
||||
'C',
|
||||
$detail->quantity,
|
||||
number_format($detail->price, 2),
|
||||
$displayUnitPrice ? number_format($displayUnitPrice, 2): 0,
|
||||
$firstItem ? 'T' : '',
|
||||
$company->e_invoice ? 'F' : 'T'
|
||||
];
|
||||
@@ -109,6 +155,87 @@ class ExportsSalesInvoiceReport implements FromQuery, WithHeadings, WithHeadingR
|
||||
$firstItem = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Service Charge - Starts
|
||||
$serviceCharge = 0;
|
||||
if (!$totalPayment) {
|
||||
$serviceCharge = $invoiceTransaction->service_charge;
|
||||
}
|
||||
else {
|
||||
$serviceCharge = $booking->transactions()
|
||||
->where('type', TransactionType::PAYMENT)
|
||||
->where('status', ApprovalStatus::COMPLETED)
|
||||
->get()
|
||||
->sum(function ($transaction) {
|
||||
return $transaction->service_charge;
|
||||
});
|
||||
}
|
||||
|
||||
$records[] = [
|
||||
'',
|
||||
$formattedDocumentDate,
|
||||
$company->debtor,
|
||||
$booking->marking,
|
||||
$booking->marking,
|
||||
'500-0000',
|
||||
'PRODUCT NAME :',
|
||||
'Service Charge',
|
||||
'022',
|
||||
'C',
|
||||
'1',
|
||||
$serviceCharge ? number_format($serviceCharge, 2): '0',
|
||||
'',
|
||||
$company->e_invoice ? 'F' : 'T'
|
||||
];
|
||||
// Service Charge - Ends
|
||||
|
||||
// Adjustment - Starts
|
||||
$adjustment = 0;
|
||||
$voucherRedemption = $invoiceTransaction->voucherRedemption;
|
||||
$voucherDiscount = $voucherRedemption ? bcmul((string)$voucherRedemption->value, "-1", 2) : "0";
|
||||
|
||||
$displayedSubtotal = is_numeric($displayedSubtotal) ? sprintf('%F', $displayedSubtotal) : '0';
|
||||
$serviceCharge = is_numeric($serviceCharge) ? sprintf('%F', $serviceCharge) : '0';
|
||||
$tax = is_numeric($invoiceTransaction->tax) ? sprintf('%F', $invoiceTransaction->tax) : '0';
|
||||
$voucherDiscount = is_numeric($voucherDiscount) ? sprintf('%F', $voucherDiscount) : '0';
|
||||
|
||||
$displayedTotal = bcadd(
|
||||
bcadd(
|
||||
bcadd($displayedSubtotal, $serviceCharge, 5),
|
||||
$tax,
|
||||
5
|
||||
),
|
||||
$voucherDiscount,
|
||||
5
|
||||
);
|
||||
|
||||
$expectedTotal = bcadd(bcadd(bcadd($subtotal, $serviceCharge, 5), $invoiceTransaction->tax, 5), $voucherDiscount, 5);
|
||||
$adjustment = bcsub($expectedTotal, $displayedTotal, 5);
|
||||
|
||||
if ($totalPayment) {
|
||||
$expectedTotal = $totalPayment;
|
||||
$adjustment = bcsub($expectedTotal, $displayedTotal, 5);
|
||||
}
|
||||
|
||||
$records[] = [
|
||||
'',
|
||||
$formattedDocumentDate,
|
||||
$company->debtor,
|
||||
$booking->marking,
|
||||
$booking->marking,
|
||||
'500-0000',
|
||||
'PRODUCT NAME :',
|
||||
'Adjustment',
|
||||
'022',
|
||||
'C',
|
||||
'1',
|
||||
$adjustment ? number_format($adjustment, 2): '0',
|
||||
'',
|
||||
$company->e_invoice ? 'F' : 'T'
|
||||
];
|
||||
// Adjustment - Ends
|
||||
|
||||
return $records;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,7 +44,7 @@ class CreateInvoiceDocumentProcessor
|
||||
* @return void
|
||||
* @throws \App\Classes\Exceptions\MalformedRequestException
|
||||
*/
|
||||
public function execute($transaction, $purchaseOrder, $supplier, $document_type, $voucherRedemption = null)
|
||||
public function execute($transaction, $purchaseOrder, $supplier, $document_type, $voucherRedemption = null, $isAllowNormalInvoice = false)
|
||||
{
|
||||
// calculate current Paid Amount
|
||||
$booking = $transaction->owner_type == Booking::class ? $transaction->owner : null;
|
||||
@@ -63,9 +63,9 @@ class CreateInvoiceDocumentProcessor
|
||||
if ($bookingCreatedDate->isAfter($eInvoiceStartDate)) {
|
||||
$lastPaymentTransaction = $booking->transactions()->where('type', TransactionType::PAYMENT)->whereIn('status', [ApprovalStatus::COMPLETED, ApprovalStatus::APPROVED])->latest()->first();
|
||||
$documentDate = $lastPaymentTransaction->created_at;
|
||||
if(Carbon::parse($booking->updated_at)->isAfter($lastPaymentTransaction->created_at)){
|
||||
$documentDate = $booking->updated_at;
|
||||
}
|
||||
// if(Carbon::parse($booking->updated_at)->isAfter($lastPaymentTransaction->created_at)){ //cief todo: 90 - Batch generate E-Invoice date incorrect
|
||||
// $documentDate = $booking->updated_at;
|
||||
// }
|
||||
}
|
||||
|
||||
if($document_type === DocumentType::EINVOICE){
|
||||
@@ -88,6 +88,12 @@ class CreateInvoiceDocumentProcessor
|
||||
|
||||
$lowercaseDocumentType = strtolower($document_type);
|
||||
|
||||
if($document_type === DocumentType::EINVOICE){ //July 2025 workaround generate normal invoice instead of E-Invoice
|
||||
if($isAllowNormalInvoice){
|
||||
$lowercaseDocumentType = strtolower(DocumentType::INVOICE);
|
||||
}
|
||||
}
|
||||
|
||||
$order_pdf = LaravelMpdf::loadView('pages.pdfs.' . $lowercaseDocumentType,
|
||||
[
|
||||
'transaction' => $transaction,
|
||||
|
||||
@@ -21,6 +21,7 @@ use App\Classes\ValueObjects\Constants\DocumentType;
|
||||
use App\Models\Booking;
|
||||
use App\Models\SegmentConstant;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
class CreateInvoiceTransactionProcessor
|
||||
{
|
||||
@@ -89,7 +90,7 @@ class CreateInvoiceTransactionProcessor
|
||||
* @return void
|
||||
* @throws MalformedRequestException
|
||||
*/
|
||||
public function execute(Booking $booking, String $invoiceNo= "", bool $isAllowEInvoice = false)
|
||||
public function execute(Booking $booking, String $invoiceNo= "", bool $isAllowEInvoice = false, bool $isAllowNormalInvoice = false)
|
||||
{
|
||||
|
||||
if ($booking->status === ApprovalStatus::COMPLETED) {
|
||||
@@ -137,11 +138,18 @@ class CreateInvoiceTransactionProcessor
|
||||
}
|
||||
// $eInvoice = true; //cief todo: 90 - for testing
|
||||
|
||||
if($isAllowNormalInvoice){
|
||||
$invoiceNo = ""; //July 2025 workaround generate normal invoice instead of E-Invoice
|
||||
}
|
||||
|
||||
if($invoiceNo){
|
||||
$billNumber = $invoiceNo;
|
||||
}
|
||||
else{
|
||||
$billNUmberPrefix = $eInvoice ? 'EINV-' : 'INV-';
|
||||
if($isAllowNormalInvoice){
|
||||
$billNUmberPrefix = 'INV-'; //July 2025 workaround generate normal invoice instead of E-Invoice
|
||||
}
|
||||
$billNumber = $this->generatesTransactionBillNumber->execute($billNUmberPrefix);
|
||||
}
|
||||
|
||||
@@ -189,7 +197,7 @@ class CreateInvoiceTransactionProcessor
|
||||
if ($eInvoice)
|
||||
{
|
||||
if($isAllowEInvoice){
|
||||
$this->invoiceDocumentProcessor->execute($invoice_transaction, $purchaseOrder, $supplier, DocumentType::EINVOICE, $voucherRedemption);
|
||||
$this->invoiceDocumentProcessor->execute($invoice_transaction, $purchaseOrder, $supplier, DocumentType::EINVOICE, $voucherRedemption, $isAllowNormalInvoice);
|
||||
}
|
||||
}
|
||||
// invoice
|
||||
|
||||
+4
-2
@@ -151,7 +151,8 @@ class CreateProformaInvoiceTransactionProcessor
|
||||
|
||||
$payable_amount = $booking->transactions()->payments()->where(function ($query) {
|
||||
return $query->where(function ($query) {
|
||||
return $query->where('status', ApprovalStatus::PENDING_SUBMISSION)->whereDate('expires_on', '>=', Carbon::now())->where('expires_on', '>', Carbon::now()->toTimeString());
|
||||
// return $query->where('status', ApprovalStatus::PENDING_SUBMISSION)->whereDate('expires_on', '>=', Carbon::now())->where('expires_on', '>', Carbon::now()->toTimeString());
|
||||
return $query->where('status', ApprovalStatus::PENDING_SUBMISSION)->where('expires_on', '>=', Carbon::now());
|
||||
})->orWhere(function ($query) {
|
||||
return $query->whereIn('status', [ApprovalStatus::PENDING_VERIFICATION, ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED]);
|
||||
});
|
||||
@@ -164,7 +165,8 @@ class CreateProformaInvoiceTransactionProcessor
|
||||
|
||||
$paymentAmount = $booking->transactions()->payments()->where(function ($query) {
|
||||
return $query->where(function ($query) {
|
||||
return $query->where('status', ApprovalStatus::PENDING_SUBMISSION)->whereDate('expires_on', '>=', Carbon::now())->where('expires_on', '>', Carbon::now()->toTimeString());
|
||||
// return $query->where('status', ApprovalStatus::PENDING_SUBMISSION)->whereDate('expires_on', '>=', Carbon::now())->where('expires_on', '>', Carbon::now()->toTimeString());
|
||||
return $query->where('status', ApprovalStatus::PENDING_SUBMISSION)->where('expires_on', '>=', Carbon::now());
|
||||
})->orWhere(function ($query) {
|
||||
return $query->whereIn('status', [ApprovalStatus::PENDING_VERIFICATION, ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED]);
|
||||
});
|
||||
|
||||
@@ -12,4 +12,29 @@ final class BankAccountType {
|
||||
|
||||
public const ALIPAY_RECIPIENT = 4;
|
||||
|
||||
/**
|
||||
* Get all account type labels.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function labels(): array
|
||||
{
|
||||
return [
|
||||
self::PERSONAL => 'PERSONAL',
|
||||
self::EXTERNAL => 'EXTERNAL',
|
||||
self::ALIPAY_1688 => 'ALIPAY_1688',
|
||||
self::ALIPAY_RECIPIENT => 'ALIPAY_RECIPIENT',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get label for a specific account type.
|
||||
*
|
||||
* @param int|string $type
|
||||
* @return string
|
||||
*/
|
||||
public static function label($type): string
|
||||
{
|
||||
return self::labels()[(int) $type] ?? 'Unknown';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,81 @@
|
||||
<?php
|
||||
|
||||
namespace App\Console\Commands\V2;
|
||||
|
||||
|
||||
use App\Classes\Jobs\Commands\V2\OneTimeBatchProcessEInvoicesV2CommandJob;
|
||||
use App\Classes\ValueObjects\Constants\ApprovalStatus;
|
||||
use App\Classes\ValueObjects\Constants\DocumentType;
|
||||
use App\Classes\ValueObjects\Constants\TransactionType;
|
||||
use Illuminate\Console\Command;
|
||||
use App\Models\Booking;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
class OneTimeBatchProcessEInvoicesV2Command extends Command
|
||||
{
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
|
||||
protected $signature = 'one-time-batch-process-einvoices-command';
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'One time batch process E-Invoices for July 2025';
|
||||
|
||||
|
||||
/**
|
||||
* Create a new command instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
return;
|
||||
|
||||
$startDate = Carbon::create(2025, 7, 1)->startOfDay();
|
||||
$endDate = Carbon::create(2025, 7, 31)->endOfDay();
|
||||
|
||||
$bookings = Booking::where('status', ApprovalStatus::COMPLETED)
|
||||
->whereBetween('created_at', [$startDate, $endDate])
|
||||
->get();
|
||||
|
||||
$count = 0;
|
||||
foreach ($bookings as $booking) {
|
||||
$firstInvoice = $booking->transactions()
|
||||
->whereIn('type', [TransactionType::INVOICE])
|
||||
->withTrashed()
|
||||
->whereBetween('created_at', [$startDate, $endDate])
|
||||
->orderBy('created_at', 'asc')
|
||||
->first();
|
||||
|
||||
$normalInvoice = $booking->documents()->where('document_type', DocumentType::INVOICE)->first();
|
||||
$eInvoice = $booking->documents()->where('document_type', DocumentType::EINVOICE)->first();
|
||||
|
||||
// if($firstInvoice && !$normalInvoice && !$eInvoice){
|
||||
if(!$firstInvoice && !$normalInvoice && !$eInvoice){
|
||||
OneTimeBatchProcessEInvoicesV2CommandJob::dispatch($booking);
|
||||
$count++;
|
||||
Log::info('Processed: ' . $count);
|
||||
Log::info('Booking ID: ' . $booking->marking . ' | created_at: ' . $booking->created_at);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,155 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Reports;
|
||||
|
||||
use App\Classes\Modules\Bookings\Services\CalculatesBookingPaidAmount;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\Booking;
|
||||
use Illuminate\Http\Request;
|
||||
use Carbon\Carbon;
|
||||
|
||||
class UnfinishedPaymentOrders extends Controller
|
||||
{
|
||||
public function execute(Request $request)
|
||||
{
|
||||
$page = (int) $request->input('page', 1);
|
||||
$perPage = 2500;
|
||||
$offset = ($page - 1) * $perPage;
|
||||
$cutOffDate = $request->cut_off_date ? Carbon::parse($request->cut_off_date) : null;
|
||||
|
||||
$baseQuery = Booking::with('company')
|
||||
->when($cutOffDate, fn($q) => $q->where('created_at', '<=', $cutOffDate))
|
||||
->orderByDesc('id');
|
||||
|
||||
$total = $baseQuery->count();
|
||||
$bookings = $baseQuery->offset($offset)->limit($perPage)->get();
|
||||
|
||||
$calculator = new CalculatesBookingPaidAmount();
|
||||
|
||||
$filtered = $bookings->filter(function ($b) use ($calculator, $cutOffDate) {
|
||||
$paid = $calculator->executeUntilDate($b, $cutOffDate);
|
||||
$outstanding = $b->fix_amount - $paid;
|
||||
return $paid > 0 && $outstanding > 0;
|
||||
});
|
||||
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'current_page' => $page,
|
||||
'next_page' => ($offset + $perPage < $total) ? $page + 1 : null,
|
||||
'count' => $filtered->count(),
|
||||
'data' => $filtered->map(function ($b) use ($calculator, $cutOffDate) {
|
||||
$paid = $calculator->executeUntilDate($b, $cutOffDate);
|
||||
return [
|
||||
'id' => $b->id,
|
||||
'order_ref' => $b->marking ?? $b->id,
|
||||
'booking_amount' => number_format($b->fix_amount, 2),
|
||||
'paid_amount' => number_format($paid, 2),
|
||||
'outstanding_amount' => number_format($b->fix_amount - $paid, 2),
|
||||
'customer' => optional($b->company)->reference,
|
||||
'created_at' => $b->created_at->toDateTimeString(),
|
||||
];
|
||||
})->values(),
|
||||
]);
|
||||
}
|
||||
|
||||
public function loadView(Request $request)
|
||||
{
|
||||
$cutOffDateString = $request->cut_off_date ?? '';
|
||||
$cutOffDateParsed = $cutOffDateString ? Carbon::parse($cutOffDateString)->toDateString() : '-';
|
||||
|
||||
echo <<<HTML
|
||||
<p>Cut Off Date: {$cutOffDateParsed}</p>
|
||||
<div class="log">🔄 Processing... Total 0</div>
|
||||
<br>
|
||||
|
||||
<style>
|
||||
table {
|
||||
border-collapse: collapse;
|
||||
width: 100%;
|
||||
font-family: Arial, sans-serif;
|
||||
font-size: 14px;
|
||||
}
|
||||
th, td {
|
||||
padding: 6px 10px;
|
||||
border: 1px solid #ccc;
|
||||
}
|
||||
thead {
|
||||
background: #f1f1f1;
|
||||
}
|
||||
.log {
|
||||
margin-top: 15px;
|
||||
font-family: monospace;
|
||||
white-space: pre-line;
|
||||
}
|
||||
</style>
|
||||
|
||||
<table id="results-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Order Ref</th>
|
||||
<th>Booking Amount</th>
|
||||
<th>Paid Amount</th>
|
||||
<th>Outstanding Amount</th>
|
||||
<th>Customer</th>
|
||||
<th>Order Created Date</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody></tbody>
|
||||
</table>
|
||||
|
||||
<script>
|
||||
let currentPage = 1;
|
||||
const cutOffDate = encodeURIComponent("{$cutOffDateString}");
|
||||
const tableBody = document.querySelector('#results-table tbody');
|
||||
const log = document.querySelector('.log');
|
||||
const bookingUrlTemplate = "/transfer/__ORDER_REF__";
|
||||
const customerUrlTemplate = "/customer/__ORDER_REF__";
|
||||
let totalRows = 0;
|
||||
|
||||
function updateLogMessage() {
|
||||
log.textContent = `🔄 Processing... Total \${totalRows}`;
|
||||
}
|
||||
|
||||
function runNextBatch() {
|
||||
const url = `/run-batch-unfinished-payment-orders?page=\${currentPage}&cut_off_date=\${cutOffDate}`;
|
||||
fetch(url)
|
||||
.then(res => {
|
||||
if (!res.ok) throw new Error("404 or server error");
|
||||
return res.json();
|
||||
})
|
||||
.then(data => {
|
||||
if (data.success) {
|
||||
totalRows += data.count;
|
||||
updateLogMessage();
|
||||
|
||||
data.data.forEach(item => {
|
||||
const row = document.createElement('tr');
|
||||
row.innerHTML = `
|
||||
<td><a href="\${bookingUrlTemplate.replace('__ORDER_REF__', item.order_ref)}" target="_blank">\${item.order_ref}</a></td>
|
||||
<td>\${item.booking_amount}</td>
|
||||
<td>\${item.paid_amount}</td>
|
||||
<td>\${item.outstanding_amount}</td>
|
||||
<td><a href="\${customerUrlTemplate.replace('__ORDER_REF__', item.customer)}" target="_blank">\${item.customer ?? '-'}</a></td>
|
||||
<td>\${item.created_at}</td>
|
||||
`;
|
||||
tableBody.appendChild(row);
|
||||
});
|
||||
|
||||
if (data.next_page) {
|
||||
currentPage = data.next_page;
|
||||
runNextBatch();
|
||||
} else {
|
||||
log.textContent = `✅ Completed. Total \${totalRows}`;
|
||||
}
|
||||
}
|
||||
})
|
||||
.catch(err => {
|
||||
log.textContent = "❌ Error: " + err + "\\n";
|
||||
});
|
||||
}
|
||||
|
||||
runNextBatch();
|
||||
</script>
|
||||
HTML;
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
namespace App\Http\Resources;
|
||||
|
||||
use App\Classes\ValueObjects\Constants\BankAccountType;
|
||||
use Illuminate\Http\Resources\Json\JsonResource;
|
||||
|
||||
class BankResource extends JsonResource
|
||||
@@ -27,6 +28,7 @@ class BankResource extends JsonResource
|
||||
'country_id' => $this->country_id,
|
||||
'default' => $this->default,
|
||||
'status' => $this->status,
|
||||
'bank_account_type_label' => BankAccountType::label($this->type),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
<div class="col">
|
||||
<h3 class="all-caps">Are you Sure?</h3>
|
||||
<div class="fs-11">Are you sure you want to delete this bank account?</div>
|
||||
<!-- <div class="fs-11 text-danger" v-if="$store.getters.isAdmin">Note to Admin: Always make sure that Account Type 'EXTERNAL' has a default set before or after delete</div> -->
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
@@ -30,4 +31,4 @@
|
||||
mixins: [componentHandler, ModalFormHandler]
|
||||
|
||||
}
|
||||
</script>
|
||||
</script>
|
||||
|
||||
@@ -415,12 +415,17 @@
|
||||
<div class="col-2" v-if="showDownloadCreditNote && refund.status === 2">
|
||||
<div class="row no-margin justify-content-end">
|
||||
<div class="font-heading all-caps fs-10 m-b-5 text-right">Credit Note</div>
|
||||
<!-- cief todo: 90 - E Credit Note incomplete-->
|
||||
<a target=”_blank” @click="downloadCreditNote(refund.id)" v-if="$store.getters.isSuperAdmin">
|
||||
<!-- Allow Credit Note to be downloaded for company NOT opted in E-Invoice -->
|
||||
<a target=”_blank” @click="downloadCreditNote(refund.id)"
|
||||
v-if="
|
||||
refund.booking &&
|
||||
refund.booking.company &&
|
||||
!refund.booking.company.e_invoice">
|
||||
<div class="icon-thumbnail fs-11 text-white icon-25 bg-primary btn-rounded float-left m-r-0 pointer">
|
||||
<i class="fa fa-file-image-o fs-10"></i>
|
||||
</div>
|
||||
</a>
|
||||
<!-- cief todo: 90 - E Credit Note incomplete (for company opted in E-Invoice)-->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -202,7 +202,19 @@
|
||||
</div>
|
||||
<button class="btn btn-xs all-caps b-rad-none btn-default bg-master-lightest w-100" @click="submitted = false" v-if="allowPOEditing">Edit Purchase Order</button>
|
||||
<!-- <button class="btn btn-xs all-caps b-rad-none btn-default bg-master-lightest w-100" @click="submitted = false" >Edit Purchase Order</button> -->
|
||||
<button class="btn btn-xs all-caps b-rad-none btn-complete w-100 m-t-5" v-if="!data.documents.proforma_invoice && data.outstanding_amount != 0" @click="submit(route('api.booking.proforma.create', data.id), 'post', section, true, true)">Generate Proforma Invoice</button>
|
||||
<button class="btn btn-xs all-caps b-rad-none btn-complete w-100 m-t-5" v-if="!data.documents.proforma_invoice && data.outstanding_amount != 0" @click="handleGenerateProformaInvoice">Generate Proforma Invoice</button>
|
||||
<modal-component
|
||||
id="modal-einvoice-info"
|
||||
class="animate__animated animate__fast animate__fadeIn"
|
||||
styleType="fill-in" type="requestEInvoiceB" size="large">
|
||||
<e-invoice-info-form-component
|
||||
:section="section"
|
||||
:company-id="data.company.id"
|
||||
:company-type="data.company.type"
|
||||
v-on:eInvoiceInfoUpdated="updatedEInvoiceInfo($event)"
|
||||
v-on:eInvoiceChangeOfMindRequest="changeOfMindEInvoiceRequest()">
|
||||
</e-invoice-info-form-component>
|
||||
</modal-component>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -263,7 +275,7 @@
|
||||
//Condition 2
|
||||
const paymentsMade = Math.round((this.data.paid_amount + Number.EPSILON) * 100) / 100 > 0;
|
||||
const outstandingAmount = Math.round((this.data.outstanding_amount + Number.EPSILON) * 100) / 100 > 0;
|
||||
const allPaymentApproved = this.data.payment_history.every(payment => payment.status === 2);
|
||||
const allPaymentApproved = this.data.payment_history.every(payment => (payment.status === 2 || payment.status === 3));
|
||||
|
||||
//Condition 3
|
||||
const adminBeforeApproval = this.$store.getters.isAdmin && !(this.data.purchase_order.status === 2);
|
||||
@@ -321,11 +333,26 @@
|
||||
|
||||
this.submit(route('api.transaction.po.import', this.data.id), 'post', this.section, true, true);
|
||||
},
|
||||
successHandler(){
|
||||
if((Math.round((this.poTotal + Number.EPSILON) * 1000) / 1000).toFixed(3) === (Math.round((this.data.amount + Number.EPSILON) * 1000) / 1000).toFixed(3)){
|
||||
this.submitted = true;
|
||||
successHandler(response, section){
|
||||
if(section === this.section + 'CheckTransferRule'){
|
||||
this.checkEInvoiceRule();
|
||||
}
|
||||
else if(section === this.section + 'CheckEInvoiceRule'){
|
||||
if(response.payload.data.isPassed){
|
||||
this.submit(route('api.booking.proforma.create', this.data.id), 'post', this.section, true, true);
|
||||
}
|
||||
}
|
||||
else{
|
||||
if((Math.round((this.poTotal + Number.EPSILON) * 1000) / 1000).toFixed(3) === (Math.round((this.data.amount + Number.EPSILON) * 1000) / 1000).toFixed(3)){
|
||||
this.submitted = true;
|
||||
}
|
||||
this.updateList()
|
||||
}
|
||||
},
|
||||
errorHandler(error, statusCode, section) { //E-Invoice
|
||||
if(section === this.section + 'CheckEInvoiceRule' && statusCode === 422){
|
||||
$('#modal-einvoice-info').modal('show');
|
||||
}
|
||||
this.updateList()
|
||||
},
|
||||
addProduct(){
|
||||
this.products.push({
|
||||
@@ -354,6 +381,31 @@
|
||||
},
|
||||
removeProduct(index){
|
||||
this.products.splice(index, 1);
|
||||
},
|
||||
handleGenerateProformaInvoice(){
|
||||
this.checkTransferRule();
|
||||
},
|
||||
checkTransferRule(){
|
||||
this.error = '';
|
||||
this.parameters = {
|
||||
booking_id: this.data.id,
|
||||
company_id: this.data.company.id,
|
||||
};
|
||||
this.submit(route('api.rule.check.transfer'), 'post', this.section + 'CheckTransferRule', false, true);
|
||||
},
|
||||
checkEInvoiceRule(){
|
||||
this.error = '';
|
||||
this.parameters = {
|
||||
company_id: this.data.company.id,
|
||||
};
|
||||
this.submit(route('api.rule.check.einvoice'), 'post', this.section + 'CheckEInvoiceRule', false, true);
|
||||
},
|
||||
updatedEInvoiceInfo(info){
|
||||
this.$store.dispatch('reloadList', {'name': "bookingDetailSection"});
|
||||
},
|
||||
changeOfMindEInvoiceRequest(){
|
||||
this.parameters.e_invoice_request = false;
|
||||
this.submit((this.route('api.company.einvoice.request.change')), 'post', this.section + 'ChangeOfMind', true, true);
|
||||
}
|
||||
},
|
||||
mixins: [formHandler]
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
export default {
|
||||
methods: {
|
||||
submitForm() {
|
||||
this.parameters.normal_invoice = false;
|
||||
this.submit(this.route('api.booking.einvoice.regenerate', this.data.id), 'post', this.section, true, true);
|
||||
},
|
||||
successHandler(){
|
||||
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
<template>
|
||||
<div class="row">
|
||||
<div class="col bg-white padding-40 b-rad-lg">
|
||||
<loading-component style="height: 300px; top: 0;" key="1" color="success" v-show="isLoading" ></loading-component>
|
||||
<div class="row justify-content-center" v-show="!isLoading">
|
||||
<div class="col">
|
||||
<div class="row m-b-20">
|
||||
<div class="col">
|
||||
<h3 class="all-caps">Are you Sure?</h3>
|
||||
<div class="fs-11">Are you sure you want to regenerate normal invoice instead of e-invoice for this payment?</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col p-r-5">
|
||||
<div class="btn btn-sm btn-success btn-block b-rad-none" data-dismiss="modal">Cancel</div>
|
||||
</div>
|
||||
<div class="col p-l-5">
|
||||
<div class="btn btn-sm btn-danger btn-block b-rad-none" @click="submitForm()">Confirm</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import componentHandler from '../../../general/mixins/componentHandler';
|
||||
import ModalFormHandler from '../../../general/mixins/modalFormHandler';
|
||||
export default {
|
||||
methods: {
|
||||
submitForm() {
|
||||
this.parameters.normal_invoice = true;
|
||||
this.submit(this.route('api.booking.einvoice.regenerate', this.data.id), 'post', this.section, true, true);
|
||||
},
|
||||
successHandler(){
|
||||
this.closeModal();
|
||||
this.$store.dispatch('reloadList', {'name': "bookingDetailSection"});
|
||||
}
|
||||
},
|
||||
mixins: [componentHandler, ModalFormHandler]
|
||||
}
|
||||
</script>
|
||||
+11
-3
@@ -334,7 +334,7 @@
|
||||
</general-confirmation-form-component>
|
||||
</modal-component>
|
||||
</div>
|
||||
<div class="row m-t-15" v-if="booking.status === 3 && ($store.getters.isSuperAdmin || ($store.getters.isCustomer && $store.getters.getCompanyId === 199)) && booking.einvoice">
|
||||
<div class="row m-t-15" v-if="booking.status === 3 && ($store.getters.isSuperAdmin || ($store.getters.isCustomer && $store.getters.getCompanyId === 199)) && booking.einvoice">
|
||||
<div class="col-sm col-md-auto">
|
||||
<div class="btn btn-sm btn block all-caps b-rad-none btn-danger pointer requestModal equal-width-button" data-type="regenerateEInvoice">Regenerate E-Invoice</div>
|
||||
</div>
|
||||
@@ -342,6 +342,14 @@
|
||||
<regenerate-e-invoice-component :data="booking" :section="section" class="text-center"></regenerate-e-invoice-component>
|
||||
</modal-component>
|
||||
</div>
|
||||
<div class="row m-t-15" v-if="booking.status === 3 && ($store.getters.isSuperAdmin || ($store.getters.isCustomer && $store.getters.getCompanyId === 199)) && booking.einvoice">
|
||||
<div class="col-sm col-md-auto">
|
||||
<div class="btn btn-sm btn block all-caps b-rad-none btn-danger pointer requestModal equal-width-button" data-type="regenerateNormalInvoiceEInvoice">Regenerate Normal Inv</div>
|
||||
</div>
|
||||
<modal-component class="animate__animated animate__fast animate__fadeIn" styleType="fill-in" type="regenerateNormalInvoiceEInvoice">
|
||||
<regenerate-normal-invoice-e-invoice-component :data="booking" :section="section" class="text-center"></regenerate-normal-invoice-e-invoice-component>
|
||||
</modal-component>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 col-sm-12 col-md-5 mt-3 mt-sm-0">
|
||||
<!-- <booking-payment-quotation-component :data="booking" :section="section"></booking-payment-quotation-component> -->
|
||||
@@ -497,7 +505,7 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row m-t-5" v-if="$store.getters.isAdmin">
|
||||
<div class="row m-t-15" v-if="$store.getters.isAdmin">
|
||||
<div class="col">
|
||||
<div class="btn btn-xs all-caps b-rad-none btn-warning pointer requestModal equal-width-button" data-type="changeBookingOwner">Change Booking Owner</div>
|
||||
<modal-component type="changeBookingOwner">
|
||||
@@ -614,7 +622,7 @@
|
||||
</script>
|
||||
<style scoped>
|
||||
.equal-width-button {
|
||||
min-width: 180px;
|
||||
min-width: 200px;
|
||||
display: inline-block;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
@@ -24,6 +24,10 @@
|
||||
<div class="font-heading fs-10">{{item.holder_name}}</div>
|
||||
<div class="font-heading fs-11 text-complete m-b-5">{{item.type === 3 ? item.account_no : item.account_no.replace(/[^\dA-Z]/g, '').replace(/(.{4})/g, '$1 ').trim() }}</div>
|
||||
</div>
|
||||
<div class="col">
|
||||
<div class="font-heading fs-10">Account Type</div>
|
||||
<div class="font-heading fs-11">{{item.bank_account_type_label}}</div>
|
||||
</div>
|
||||
<div class="col-auto b-l b-grey">
|
||||
<div class="row h-100">
|
||||
<div class="col">
|
||||
@@ -37,7 +41,7 @@
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
<div class="col-auto m-l-10 d-flex align-items-center">
|
||||
<!-- <div class="col-auto m-l-10 d-flex align-items-center">
|
||||
<div class="row align-items-center">
|
||||
<div class="col-auto text-right p-t-5 p-b-5" :class="[{'bg-warning-lighter': item.default}, {'bg-master-light': !item.default}]">
|
||||
<div data-toggle="tooltip" class="row align-items-center justify-content-center" :class="{'link': !item.default}">
|
||||
@@ -50,6 +54,17 @@
|
||||
<small class="fs-12 all-caps bold" :class="[{'text-warning': item.default}, {'text-master': !item.default}]">Default Bank</small>
|
||||
</div>
|
||||
</div>
|
||||
</div> -->
|
||||
<div class="col-auto m-l-10 d-flex align-items-center requestModal" data-type="deleteBankModal">
|
||||
<div data-toggle="tooltip" title="" data-placement="bottom" class="row link align-items-center justify-content-center" data-original-title="Edit">
|
||||
<div class="btn btn-xs btn-outline-danger b-rad-none m-r-5 requestModalol">
|
||||
<i class="fa fa-times"></i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-auto m-l-10 d-flex align-items-center">
|
||||
<div class="btn btn-xs btn-outline-success b-rad-none pointer requestModal" data-type="defaultBankModal" v-if="item.company_business_type !== 1 && !item.default">Set As Default</div>
|
||||
<div class="bg-master-lighter p-t-10 p-b-10 p-r-15 p-l-15 muted hint-text fs-10" v-if="item.company_business_type !== 1 && item.default">Set As Default</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -58,6 +73,12 @@
|
||||
<modal-component class="animate__animated animate__fast animate__fadeIn" styleType="fill-in" type="editBankModal">
|
||||
<edit-bank-form-component :data="item" :section="section" :company_id="company_id"></edit-bank-form-component>
|
||||
</modal-component>
|
||||
<modal-component class="animate__animated animate__fast animate__fadeIn" styleType="fill-in" type="deleteBankModal">
|
||||
<delete-bank-account-form-component :data="item" :section="section" class="text-center"></delete-bank-account-form-component>
|
||||
</modal-component>
|
||||
<modal-component class="animate__animated animate__fast animate__fadeIn" styleType="fill-in" type="defaultBankModal">
|
||||
<set-bank-account-default-form-component :data="item" :section="section" class="text-center"></set-bank-account-default-form-component>
|
||||
</modal-component>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -75,4 +96,4 @@
|
||||
},
|
||||
mixins: [componentHandler]
|
||||
}
|
||||
</script>
|
||||
</script>
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<div class="container-fluid">
|
||||
<div class="row no-margin">
|
||||
<div class="col p-l-0 p-t-20 p-b-20 sm-text-center">
|
||||
<small class="small no-margin pull-left sm-pull-reset all-caps fs-10 muted" style=" letter-spacing: 1px; ">Copyright © {{ date('Y') }} CIEF Exchange. All rights reserved. Powered by Laravel Vapor.</small>
|
||||
<small class="small no-margin pull-left sm-pull-reset all-caps fs-10 muted" style=" letter-spacing: 1px; ">Copyright © {{ date('Y') }} CIEF Exchange. All rights reserved.</small>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -36,6 +36,7 @@ use App\Classes\Modules\Transactions\Services\DeletesTransaction;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use App\Classes\General\AWSS3Helper;
|
||||
use App\Http\Controllers\Reports\UnfinishedPaymentOrders;
|
||||
use Illuminate\Support\Facades\File;
|
||||
|
||||
|
||||
@@ -1369,3 +1370,12 @@ Route::get('/test-test', function () {
|
||||
Route::get('/maintenance', function () {
|
||||
return response()->view('errors.503', [], 503);
|
||||
});
|
||||
|
||||
// web route to view the result
|
||||
Route::get('/preview-unfinished-payment-orders', function (Request $request) {
|
||||
return (new UnfinishedPaymentOrders())->loadView($request);
|
||||
});
|
||||
// web route to run the logic
|
||||
Route::get('/run-batch-unfinished-payment-orders', function (Request $request) {
|
||||
return (new UnfinishedPaymentOrders())->execute($request);
|
||||
});
|
||||
Reference in New Issue
Block a user