mirror of
https://gitlab.com/CIEFWorldwideSdnBhd/exchange-2.0.git
synced 2026-08-27 16:34:00 +00:00
Merge branch 'vapor/production' into dillon/90-e-invoice-f
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 . '.');
|
||||
}
|
||||
}
|
||||
+4
-3
@@ -8,6 +8,7 @@ use App\Classes\Jobs\Commands\V2\ProcessBookingForEInvoiceV2CommandJob;
|
||||
use App\Classes\ValueObjects\Constants\ApprovalStatus;
|
||||
use App\Models\Booking;
|
||||
use App\Classes\Modules\Bookings\Processors\RegenerateInvoiceBookingProcessor;
|
||||
use App\Classes\ValueObjects\Constants\KVPKey;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
@@ -27,7 +28,7 @@ class BatchBookingsGenerateEInvoiceLogic extends AbstractControllerLogic
|
||||
return [
|
||||
'title' => 'Generate Bookings E-Invoices',
|
||||
'message' => sprintf(
|
||||
'You have successfully submitted %d booking%s for E-Invoices.',
|
||||
'You have successfully submitted %d booking%s for E-Invoices processing.',
|
||||
$this->processedCount,
|
||||
$this->processedCount === 1 ? '' : 's'
|
||||
),
|
||||
@@ -83,10 +84,10 @@ class BatchBookingsGenerateEInvoiceLogic extends AbstractControllerLogic
|
||||
$bookings = Booking::where('status', ApprovalStatus::COMPLETED)
|
||||
->whereBetween('created_at', [$startDate, $endDate])
|
||||
->whereHas('attributesKVP', function (Builder $query) {
|
||||
$query->where('key', 'AUTOCOUNT_DOCNO');
|
||||
$query->where('key', KVPKey::AUTOCOUNT_DOCNO);
|
||||
})
|
||||
->with(['attributesKVP' => function ($query) {
|
||||
$query->where('key', 'AUTOCOUNT_DOCNO');
|
||||
$query->where('key', KVPKey::AUTOCOUNT_DOCNO);
|
||||
}])
|
||||
->get();
|
||||
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
@@ -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');
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,127 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\Modules\Exports\Services;
|
||||
|
||||
|
||||
use App\Classes\ValueObjects\Constants\TransactionType;
|
||||
use App\Classes\ValueObjects\Constants\ApprovalStatus;
|
||||
use App\Classes\ValueObjects\Constants\KVPKey;
|
||||
use App\Models\KeyValuePair;
|
||||
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 Carbon\Carbon;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
class ExportsARCreditNoteReport implements FromQuery, WithHeadings, WithHeadingRow, WithMapping, ShouldAutoSize
|
||||
{
|
||||
use Exportable;
|
||||
|
||||
protected $startDate;
|
||||
protected $endDate;
|
||||
|
||||
public function __construct($startDate = null, $endDate = null) {
|
||||
$this->startDate = $startDate ? Carbon::parse($startDate)->startOfDay() : Carbon::now()->subMonths(1);
|
||||
$this->endDate = $endDate ? Carbon::parse($endDate)->endOfDay() : Carbon::now();
|
||||
}
|
||||
|
||||
public function headings(): array
|
||||
{
|
||||
return [
|
||||
'DocNo',
|
||||
'DocDate',
|
||||
'DebtorCode',
|
||||
'Ref',
|
||||
'Description',
|
||||
'Reason',
|
||||
'DeptNo',
|
||||
'Qty',
|
||||
'UnitPrice',
|
||||
'AccNo',
|
||||
'submiteinvoice',
|
||||
'ConsolidatedEinvoice',
|
||||
'KnockOffDocNo',
|
||||
'KnockOffAmt',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Illuminate\Support\Collection|mixed
|
||||
*/
|
||||
public function query()
|
||||
{
|
||||
$type = TransactionType::CREDIT_NOTE;
|
||||
$query = Transaction::query();
|
||||
|
||||
$query->where('type', $type);
|
||||
// $query->where('owner_type', Wallet::class);
|
||||
$query->whereIn('status', [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED]);
|
||||
$query->whereBetween('created_at', [$this->startDate, $this->endDate]);
|
||||
|
||||
return $query;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Transaction $transaction
|
||||
* @return array
|
||||
*/
|
||||
public function map($transaction): array
|
||||
{
|
||||
$booking = null;
|
||||
$autoCountSalesInvoiceId = null;
|
||||
$formattedDocumentDate = null;
|
||||
$refundRemark = null;
|
||||
|
||||
$company = $transaction->owner->owner;
|
||||
$kvps = KeyValuePair::where('value', $transaction->id)
|
||||
->where('key', 'App\Models\Transaction')
|
||||
->orderByDesc('created_at')
|
||||
->get();
|
||||
|
||||
foreach ($kvps as $kvp) {
|
||||
if ($kvp && $kvp->owner && $kvp->owner->owner && $kvp->owner->owner->type === 1) {
|
||||
$refundTransaction = $kvp->owner;
|
||||
$refundRemark = $refundTransaction->remarks && $refundTransaction->remarks->first() ? $refundTransaction->remarks->first()->content : null;
|
||||
$booking = $refundTransaction->owner->booking;
|
||||
if($booking){
|
||||
$metadata = $booking->attributesKVP()->where('key', KVPKey::AUTOCOUNT_DOCNO)->first();
|
||||
if($metadata){
|
||||
$autoCountSalesInvoiceId = $metadata->value;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$documentDate = $transaction->created_at; //NEW 2025: default in case there is no approval date
|
||||
$metadata = $transaction->attributesKVP()->where('key', KVPKey::CREDIT_NOTE_APPROVAL_DATE)->latest('created_at')->first();
|
||||
if($metadata){
|
||||
$documentDate = Carbon::parse($metadata->value);
|
||||
}
|
||||
if($company->e_invoice === 1){
|
||||
$documentDate = $documentDate->copy()->endOfMonth();
|
||||
}
|
||||
$formattedDocumentDate = Carbon::parse($documentDate)->format('m/d/Y');
|
||||
|
||||
return [
|
||||
'<<New>>', //DocNo
|
||||
$formattedDocumentDate, //DocDate
|
||||
$company->debtor, //DebtorCode
|
||||
$booking ? $booking->marking : '', //Ref
|
||||
$refundRemark ?? '', //Description
|
||||
$refundRemark ?? '', //Reason
|
||||
'C', //DeptNo
|
||||
'1', //Qty
|
||||
number_format($transaction->amount, 2), //UnitPrice
|
||||
'511-0000', //AccNo
|
||||
'F', //submiteinvoice
|
||||
$company->e_invoice ? 'F' : 'T', //ConsolidatedEinvoice
|
||||
$autoCountSalesInvoiceId ?? '', //KnockOffDocNo
|
||||
number_format($transaction->amount, 2), //KnockOffAmt
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -10,6 +10,7 @@ use App\Classes\Modules\Accounts\Services\UpdatesKeyValuePair;
|
||||
use App\Classes\Modules\Documents\DataTransferObjects\DocumentObject;
|
||||
use App\Classes\Modules\Accounts\DataTransferObjects\KeyValuePairObject;
|
||||
use App\Classes\ValueObjects\Constants\ApprovalStatus;
|
||||
use App\Classes\ValueObjects\Constants\KVPKey;
|
||||
use App\Models\Booking;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
@@ -127,11 +128,13 @@ class ImportExcelLogic extends AbstractControllerLogic
|
||||
]);
|
||||
|
||||
$booking = Booking::where('marking', $ref)->first();
|
||||
if($docNo != "<<New>>"){
|
||||
$this->updateOrCreateKeyValuePair($booking, "AUTOCOUNT_DOCNO", $docNo);
|
||||
}
|
||||
if($eInvoiceValidationLink){
|
||||
$this->updateOrCreateKeyValuePair($booking, "AUTOCOUNT_EINVOICE_VALIDATION_LINK", $eInvoiceValidationLink);
|
||||
if($booking){
|
||||
if($docNo != "" && $docNo != "<<New>>"){
|
||||
$this->updateOrCreateKeyValuePair($booking, KVPKey::AUTOCOUNT_DOCNO, $docNo);
|
||||
}
|
||||
if($eInvoiceValidationLink){
|
||||
$this->updateOrCreateKeyValuePair($booking, KVPKey::AUTOCOUNT_EINVOICE_VALIDATION_LINK, $eInvoiceValidationLink);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@ use App\Classes\Modules\Transactions\Services\FetchesTransaction;
|
||||
use App\Classes\ValueObjects\Constants\TransactionType;
|
||||
use App\Classes\General\AWSS3Helper;
|
||||
use App\Classes\ValueObjects\Constants\DocumentType;
|
||||
use App\Classes\ValueObjects\Constants\KVPKey;
|
||||
use App\Models\KeyValuePair;
|
||||
use App\Models\Transaction;
|
||||
use Carbon\Carbon;
|
||||
@@ -49,9 +50,9 @@ class GenerateCreditNotePdfV2Logic
|
||||
if($transaction->type === TransactionType::REFUND){
|
||||
//Retrieve TransactionType::CREDIT_NOTE
|
||||
$booking = $transaction->owner->booking;
|
||||
$kvp = $transaction->attributesKVP()->latest()->first();
|
||||
$kvp = $transaction->attributesKVP()->where('key', KVPKey::TRANSACTION_MODEL_CLASS)->latest()->first();
|
||||
if($kvp){
|
||||
if($kvp->key === 'App\Models\Transaction'){
|
||||
if($kvp->key === KVPKey::TRANSACTION_MODEL_CLASS){
|
||||
$transaction = $this->fetchesTransaction->execute(['id' => $kvp->value ]);
|
||||
}
|
||||
}
|
||||
@@ -62,7 +63,7 @@ class GenerateCreditNotePdfV2Logic
|
||||
$pdfTemplateName = 'pages.pdfs.credit_note'; //default
|
||||
|
||||
//For New Cases with e-invoice: Retrieve the refund transaction for this credit note
|
||||
$kvp = KeyValuePair::where('key', 'App\Models\Transaction')->where('value', $transaction->id)->first();
|
||||
$kvp = KeyValuePair::where('key', KVPKey::TRANSACTION_MODEL_CLASS)->where('value', $transaction->id)->first();
|
||||
if($kvp){
|
||||
$kvpOwner = $kvp->owner;
|
||||
if($kvpOwner && $kvpOwner instanceof Transaction && $kvpOwner->type === TransactionType::REFUND){
|
||||
@@ -71,7 +72,12 @@ class GenerateCreditNotePdfV2Logic
|
||||
}
|
||||
}
|
||||
|
||||
$date = $transaction->created_at;
|
||||
$date = $transaction->created_at; //NEW 2025: default in case there is no approval date
|
||||
$metadata = $transaction->attributesKVP()->where('key', KVPKey::CREDIT_NOTE_APPROVAL_DATE)->latest('created_at')->first();
|
||||
if($metadata){
|
||||
$date = Carbon::parse($metadata->value);
|
||||
}
|
||||
|
||||
$supplier = $this->fetchesCompany->execute(['id' => $transaction->receiver]);
|
||||
$brn = $supplier->documents->where('document_type', DocumentType::SSM_REGISTRATION)->first();
|
||||
|
||||
@@ -82,13 +88,34 @@ class GenerateCreditNotePdfV2Logic
|
||||
if ($bookingCreatedDate->isAfter($eInvoiceStartDate)) {
|
||||
$eInvoiceStarted = true;
|
||||
}
|
||||
// $eInvoiceStarted = false; //cief todo: 90 - for testing
|
||||
|
||||
if($eInvoiceStarted) {
|
||||
$eInvoiceStarted = false; //reset to re-evaluate second time
|
||||
$autoCountInvoiceId = '';
|
||||
$autoCountEInvoiceValidationLink = '';
|
||||
|
||||
$metadata = $booking->attributesKVP()->where('key', KVPKey::AUTOCOUNT_DOCNO)->first();
|
||||
if($metadata){
|
||||
$autoCountInvoiceId = $metadata->value;
|
||||
}
|
||||
$metadata = $booking->attributesKVP()->where('key', KVPKey::AUTOCOUNT_EINVOICE_VALIDATION_LINK)->first();
|
||||
if($metadata){
|
||||
$autoCountEInvoiceValidationLink = $metadata->value;
|
||||
}
|
||||
|
||||
Log::info('autoCountInvoiceId: ' . $autoCountInvoiceId);
|
||||
Log::info('autoCountEInvoiceValidationLink: ' . $autoCountEInvoiceValidationLink);
|
||||
|
||||
if($autoCountInvoiceId && $autoCountEInvoiceValidationLink){
|
||||
$eInvoiceStarted = true;
|
||||
}
|
||||
}
|
||||
|
||||
if($eInvoiceStarted)
|
||||
{
|
||||
if($supplier->e_invoice === 1){
|
||||
Log::info('Based on booking created date, E-Credit Note started and company wants e-invoice ' . json_encode($booking));
|
||||
$date = $booking->updated_at->copy()->endOfMonth();
|
||||
$date = $date->copy()->endOfMonth();
|
||||
$pdfTemplateName = 'pages.pdfs.e_credit_note';
|
||||
}
|
||||
else{
|
||||
@@ -97,7 +124,7 @@ class GenerateCreditNotePdfV2Logic
|
||||
}
|
||||
}
|
||||
else{
|
||||
Log::info('Based on booking created date, E-Credit Note not yet started');
|
||||
Log::info('Based on booking created date, E-Credit Note not yet started. / Not Yet Ready.');
|
||||
}
|
||||
|
||||
$pdf = LaravelMpdf::loadView($pdfTemplateName, ['transaction' => $transaction, 'booking' => $booking, 'supplier' => $supplier, 'date' => $date, 'brn' => $brn,]);
|
||||
|
||||
@@ -7,6 +7,7 @@ use App\Classes\Modules\Documents\Services\CreatesFiles;
|
||||
use App\Classes\Modules\Documents\DataTransferObjects\DocumentObject;
|
||||
use App\Classes\ValueObjects\Constants\ApprovalStatus;
|
||||
use App\Classes\ValueObjects\Constants\DocumentType;
|
||||
use App\Classes\ValueObjects\Constants\KVPKey;
|
||||
use App\Classes\ValueObjects\Constants\TransactionType;
|
||||
use App\Models\Booking;
|
||||
use App\Models\Document;
|
||||
@@ -43,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;
|
||||
@@ -62,17 +63,17 @@ 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){
|
||||
$metadata = $booking->attributesKVP()->where('key', 'AUTOCOUNT_DOCNO')->first();
|
||||
$metadata = $booking->attributesKVP()->where('key', KVPKey::AUTOCOUNT_DOCNO)->first();
|
||||
if($metadata){
|
||||
$autoCountInvoiceId = $metadata->value;
|
||||
}
|
||||
$metadata = $booking->attributesKVP()->where('key', 'AUTOCOUNT_EINVOICE_VALIDATION_LINK')->first();
|
||||
$metadata = $booking->attributesKVP()->where('key', KVPKey::AUTOCOUNT_EINVOICE_VALIDATION_LINK)->first();
|
||||
if($metadata){
|
||||
$autoCountEInvoiceValidationLink = $metadata->value;
|
||||
}
|
||||
@@ -87,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
|
||||
|
||||
@@ -16,6 +16,8 @@ use App\Classes\Modules\Wallets\DataTransferObjects\WalletObject;
|
||||
use App\Classes\Modules\Transactions\DataTransferObjects\TransactionObject;
|
||||
use App\Classes\Modules\Transactions\Services\GeneratesTransactionBillNumber;
|
||||
use App\Classes\Modules\Accounts\Services\CreatesKeyValuePair;
|
||||
use App\Classes\Modules\Accounts\Services\UpdatesKeyValuePair;
|
||||
use App\Classes\ValueObjects\Constants\KVPKey;
|
||||
use App\Models\Transaction;
|
||||
|
||||
class CreditWalletProcessor
|
||||
@@ -38,6 +40,10 @@ class CreditWalletProcessor
|
||||
/** @var CreatesKeyValuePair */
|
||||
private $createsKeyValuePair;
|
||||
|
||||
/** @var UpdatesKeyValuePair */
|
||||
private $updatesKeyValuePair;
|
||||
|
||||
|
||||
/**
|
||||
* CreateWalletLogic constructor.
|
||||
* @param GeneratesWalletCode $generatesWalletCode
|
||||
@@ -46,6 +52,7 @@ class CreditWalletProcessor
|
||||
* @param CreatesTransaction $createsTransaction
|
||||
* @param UpdatesWallet $updatesWallet
|
||||
* @param CreatesKeyValuePair $createsKeyValuePair
|
||||
* @param UpdatesKeyValuePair $updatesKeyValuePair
|
||||
*/
|
||||
public function __construct(
|
||||
GeneratesWalletCode $generatesWalletCode,
|
||||
@@ -53,7 +60,8 @@ class CreditWalletProcessor
|
||||
GeneratesTransactionBillNumber $generatesTransactionBillNumber,
|
||||
CreatesTransaction $createsTransaction,
|
||||
UpdatesWallet $updatesWallet,
|
||||
CreatesKeyValuePair $createsKeyValuePair
|
||||
CreatesKeyValuePair $createsKeyValuePair,
|
||||
UpdatesKeyValuePair $updatesKeyValuePair
|
||||
)
|
||||
{
|
||||
$this->generatesWalletCode = $generatesWalletCode;
|
||||
@@ -62,6 +70,7 @@ class CreditWalletProcessor
|
||||
$this->createsTransaction = $createsTransaction;
|
||||
$this->updatesWallet = $updatesWallet;
|
||||
$this->createsKeyValuePair = $createsKeyValuePair;
|
||||
$this->updatesKeyValuePair = $updatesKeyValuePair;
|
||||
}
|
||||
|
||||
|
||||
@@ -86,9 +95,15 @@ class CreditWalletProcessor
|
||||
|
||||
$billNumber = $this->generatesTransactionBillNumber->execute($transactionType === 2 ? 'DEBIT-NOTE-' : 'CREDIT-NOTE-');
|
||||
|
||||
$transaction_object = new TransactionObject($billNumber, $transactionType === 2 ? TransactionType::DEBIT_NOTE : TransactionType::CREDIT_NOTE, 1, $wallet->owner->id, 1, PaymentMethodType::CASH, $amount, $amount, 1, 1, 1, 0, 0, null, ApprovalStatus::APPROVED, [], $reference);
|
||||
$status = ApprovalStatus::APPROVED;
|
||||
|
||||
$transaction_object = new TransactionObject($billNumber, $transactionType === 2 ? TransactionType::DEBIT_NOTE : TransactionType::CREDIT_NOTE, 1, $wallet->owner->id, 1, PaymentMethodType::CASH, $amount, $amount, 1, 1, 1, 0, 0, null, $status, [], $reference);
|
||||
$transaction = $this->createsTransaction->execute($wallet, $transaction_object);
|
||||
|
||||
if($status === ApprovalStatus::APPROVED){
|
||||
$this->updateOrCreateKeyValuePair($transaction, KVPKey::CREDIT_NOTE_APPROVAL_DATE, now());
|
||||
}
|
||||
|
||||
$updateWalletAmount = $transactionType === 2 ? ($wallet->amount - $transaction->amount) : ($wallet->amount + $transaction->amount);
|
||||
|
||||
$walletObject = new WalletObject($wallet->owner->id, $wallet->currency_id, $wallet->code, $updateWalletAmount);
|
||||
@@ -107,4 +122,16 @@ class CreditWalletProcessor
|
||||
}
|
||||
return $wallet;
|
||||
}
|
||||
|
||||
private function updateOrCreateKeyValuePair($transaction, $key, $value)
|
||||
{
|
||||
$keyValuePairObject = new KeyValuePairObject($key, $value);
|
||||
$metadata = $transaction->attributesKVP()->where('key', $key)->first();
|
||||
|
||||
if ($metadata) {
|
||||
$this->updatesKeyValuePair->execute($metadata, $keyValuePairObject);
|
||||
} else {
|
||||
$this->createsKeyValuePair->execute($transaction, $keyValuePairObject);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\ValueObjects\Constants;
|
||||
|
||||
|
||||
class KVPKey
|
||||
{
|
||||
|
||||
public const AUTOCOUNT_DOCNO = 'AUTOCOUNT_DOCNO';
|
||||
|
||||
public const AUTOCOUNT_EINVOICE_VALIDATION_LINK = 'AUTOCOUNT_EINVOICE_VALIDATION_LINK';
|
||||
|
||||
public const CREDIT_NOTE_APPROVAL_DATE = 'CREDIT_NOTE_APPROVAL_DATE';
|
||||
|
||||
public const TRANSACTION_MODEL_CLASS = 'App\Models\Transaction';
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -8,6 +8,7 @@ use Illuminate\Http\Request;
|
||||
use Maatwebsite\Excel\Excel;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use App\Classes\General\AWSS3Helper;
|
||||
use App\Classes\Modules\Exports\Services\ExportsARCreditNoteReport;
|
||||
use App\Classes\Modules\Exports\Services\ExportsCompanies;
|
||||
use Carbon\Carbon;
|
||||
|
||||
@@ -83,4 +84,39 @@ class ExportController
|
||||
}
|
||||
return $response;
|
||||
}
|
||||
|
||||
public function arCreditNote(Request $request){
|
||||
$validated = $request->validate([
|
||||
'startDate' => 'nullable|date_format:d-m-Y',
|
||||
'endDate' => 'nullable|date_format:d-m-Y|after_or_equal:startDate',
|
||||
]);
|
||||
|
||||
$startDate = null;
|
||||
$endDate = null;
|
||||
|
||||
if (isset($validated['startDate']) && $validated['startDate']) {
|
||||
$startDate = Carbon::createFromFormat('d-m-Y', $validated['startDate'])->startOfDay();
|
||||
} else {
|
||||
$startDate = Carbon::now()->subMonths(1)->startOfDay();
|
||||
}
|
||||
|
||||
if (isset($validated['endDate']) && $validated['endDate']) {
|
||||
$endDate = Carbon::createFromFormat('d-m-Y', $validated['endDate'])->endOfDay();
|
||||
} else {
|
||||
$endDate = Carbon::now()->endOfDay();
|
||||
}
|
||||
|
||||
$exportsTransactions = new ExportsARCreditNoteReport($startDate, $endDate);
|
||||
|
||||
$exportFileName = 'Exchange - AR Credit Note Report.xls';
|
||||
$filesystemDriver = Storage::getDefaultDriver();
|
||||
if($filesystemDriver === 's3'){
|
||||
return response([ 'src' => AWSS3Helper::S3Exportable($exportFileName, $exportsTransactions) ]);
|
||||
}
|
||||
else{
|
||||
$response = $exportsTransactions->download($exportFileName, Excel::XLS, ['Content-Type' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet']);
|
||||
ob_end_clean();
|
||||
}
|
||||
return $response;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -101,13 +101,6 @@ export default {
|
||||
generateEInvoicesUrl: null,
|
||||
}
|
||||
},
|
||||
mounted(){
|
||||
switch(this.section) {
|
||||
case 'paymentsReportSection':
|
||||
this.parameters.reportType = 'Sales Invoice Report'
|
||||
break;
|
||||
}
|
||||
},
|
||||
validations: {
|
||||
parameters: {
|
||||
startDate: {
|
||||
@@ -126,6 +119,7 @@ export default {
|
||||
return [
|
||||
'Sales Invoice Report',
|
||||
'Customers Report',
|
||||
'AR Credit Note Report',
|
||||
];
|
||||
},
|
||||
handleExportClick(){
|
||||
@@ -137,6 +131,7 @@ export default {
|
||||
const routesMap = {
|
||||
'Sales Invoice Report': route('api.export.bookings.sales-invoices'),
|
||||
'Customers Report': route('api.export.companies.customers-data'),
|
||||
'AR Credit Note Report': route('api.export.transactions.ar-credit-note'),
|
||||
};
|
||||
|
||||
let url = `${routesMap[reportType]}?startDate=${this.parameters.startDate}&endDate=${this.parameters.endDate}`;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -12,6 +12,9 @@ Route::group(['prefix' => 'export', 'as' => 'export.', 'namespace' => 'Exports']
|
||||
Route::group(['prefix' => 'companies', 'as' => 'companies.'], function () {
|
||||
Route::get('/customers-data', [ExportController::class, 'companies'])->name('customers-data');
|
||||
});
|
||||
Route::group(['prefix' => 'transactions', 'as' => 'transactions.'], function () {
|
||||
Route::get('/ar-credit-note', [ExportController::class, 'arCreditNote'])->name('ar-credit-note');
|
||||
});
|
||||
});
|
||||
|
||||
Route::group(['prefix' => 'import', 'as' => 'import.', 'namespace' => 'Imports'], function () {
|
||||
|
||||
@@ -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