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/122-1688-po-automation-project
This commit is contained in:
@@ -0,0 +1,42 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\Jobs\Commands\V2;
|
||||
|
||||
use App\Classes\Modules\Transactions\Processors\CreateInvoiceTransactionV2Processor;
|
||||
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 Illuminate\Support\Facades\Log;
|
||||
|
||||
class CreateInvoiceTransactionV2CommandJob implements ShouldQueue
|
||||
{
|
||||
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
|
||||
|
||||
/** @var object */
|
||||
private $booking;
|
||||
|
||||
/**
|
||||
* CreateInvoiceTransactionV2CommandJob constructor.
|
||||
* @param object $booking
|
||||
*/
|
||||
public function __construct($booking)
|
||||
{
|
||||
$this->booking = $booking;
|
||||
}
|
||||
|
||||
public function handle()
|
||||
{
|
||||
Log::info(Carbon::now() . ': Start job - Creating invoice for single booking.');
|
||||
$start = new Carbon();
|
||||
|
||||
(App()->make(CreateInvoiceTransactionV2Processor::class))->execute($this->booking);
|
||||
|
||||
$end = new Carbon();
|
||||
$elapsedTime = $start->diff($end)->format('%H:%I:%S');
|
||||
Log::info(Carbon::now() . ': End job - Creating invoice for single booking. ElapsedTime: ' . $elapsedTime . '.');
|
||||
}
|
||||
|
||||
}
|
||||
@@ -2,31 +2,32 @@
|
||||
|
||||
namespace App\Classes\Modules\Billplzs\ControllersLogic;
|
||||
|
||||
use App\Classes\Modules\Wallets\DataTransferObjects\WalletObject;
|
||||
use App\Classes\Modules\Wallets\Services\UpdatesWallet;
|
||||
use App\Classes\Exceptions\MalformedRequestException;
|
||||
use App\Classes\Exceptions\ResourceNotFoundException;
|
||||
use App\Classes\General\Abstracts\AbstractControllerLogic;
|
||||
use App\Classes\Jobs\Commands\V2\CreateInvoiceTransactionV2CommandJob;
|
||||
use App\Classes\Modules\Billplzs\DataTransferObjects\BillplzXSignatureObject;
|
||||
use App\Classes\Modules\Billplzs\Services\GetBillplzBill;
|
||||
use App\Classes\Modules\Transactions\Processors\CreateCashBackTransactionProcessor;
|
||||
use App\Classes\Modules\Transactions\Processors\CreateReceiptVoucherTransactionProcessor;
|
||||
|
||||
use App\Classes\Exceptions\ResourceNotFoundException;
|
||||
use App\Classes\Modules\Transactions\Services\FetchesTransaction;
|
||||
use App\Classes\Modules\Transactions\Services\UpdatesTransactionStatus;
|
||||
use App\Classes\Modules\Wallets\DataTransferObjects\WalletObject;
|
||||
use App\Classes\Modules\Wallets\Services\RecalculatesWalletBalance;
|
||||
use App\Classes\Modules\Wallets\Services\UpdatesWallet;
|
||||
use App\Classes\Modules\Wallets\Services\UpdatesWalletBalance;
|
||||
use App\Classes\ValueObjects\Constants\ApprovalStatus;
|
||||
use App\Classes\ValueObjects\Constants\TransactionType;
|
||||
use App\Http\Resources\TransactionResource;
|
||||
|
||||
use App\Models\Booking;
|
||||
use App\Models\User;
|
||||
use App\Models\Wallet;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
|
||||
use App\Classes\Exceptions\MalformedRequestException;
|
||||
use App\Classes\ValueObjects\Constants\ApprovalStatus;
|
||||
use App\Classes\ValueObjects\Constants\TransactionType;
|
||||
use App\Classes\Modules\Billplzs\Services\GetBillplzBill;
|
||||
use App\Classes\Modules\Billplzs\DataTransferObjects\BillplzXSignatureObject;
|
||||
use App\Classes\General\Abstracts\AbstractControllerLogic;
|
||||
use App\Classes\Modules\Transactions\Services\FetchesTransaction;
|
||||
use App\Classes\Modules\Transactions\Services\UpdatesTransactionStatus;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use App\Classes\Modules\Wallets\Services\RecalculatesWalletBalance;
|
||||
|
||||
class CallbackBillplzLogic
|
||||
{
|
||||
@@ -117,6 +118,10 @@ class CallbackBillplzLogic
|
||||
$this->createReceiptVoucherTransactionProcessor->execute($booking, $transaction);
|
||||
}
|
||||
|
||||
if($booking){
|
||||
CreateInvoiceTransactionV2CommandJob::dispatch($booking);
|
||||
}
|
||||
|
||||
// if ($transaction->type == TransactionType::PAYMENT) {
|
||||
// $cash_back_transaction = $this->createCashBackTransactionProcessor->execute($transaction);
|
||||
// }
|
||||
|
||||
@@ -67,7 +67,13 @@ class ApprovePurchaseOrderLogic extends AbstractControllerLogic
|
||||
|
||||
$this->updatesTransactionStatus->execute($purchaseOrder, ApprovalStatus::APPROVED);
|
||||
|
||||
$this->createInvoiceTransactionProcessor->execute($booking);
|
||||
$this->createInvoiceTransactionProcessor->execute($booking, "", null, [
|
||||
'generateEInvoice' => false,
|
||||
'generateEInvoiceWithNormalInvoiceTemplate' => false,
|
||||
'generateEInvoiceRefund' => false,
|
||||
'bookingOriginalStatus' => $booking->status
|
||||
]
|
||||
);
|
||||
|
||||
return $this->response([]);
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ namespace App\Classes\Modules\Bookings\ControllersLogic;
|
||||
use App\Classes\Exceptions\CriteriaNotFulfilledException;
|
||||
use App\Classes\Exceptions\MalformedRequestException;
|
||||
use App\Classes\General\Abstracts\AbstractControllerLogic;
|
||||
use App\Classes\Jobs\Commands\V2\CreateInvoiceTransactionV2CommandJob;
|
||||
use App\Classes\Modules\Bookings\Services\CalculatesBookingOutstanding;
|
||||
use App\Classes\Modules\Bookings\Services\FetchesBookingQuotation;
|
||||
use App\Classes\Modules\Companies\Services\FetchesCompanyPaymentAttemptLimit;
|
||||
@@ -238,6 +239,10 @@ class CreateBookingPaymentLogic extends AbstractControllerLogic
|
||||
$this->createReceiptVoucherTransactionProcessor->execute($booking, $transaction);
|
||||
}
|
||||
|
||||
if($booking){
|
||||
CreateInvoiceTransactionV2CommandJob::dispatch($booking);
|
||||
}
|
||||
|
||||
return $this->resourceResponse(new TransactionResource($transaction));
|
||||
}
|
||||
|
||||
|
||||
@@ -2,25 +2,24 @@
|
||||
|
||||
namespace App\Classes\Modules\Bookings\ControllersLogic;
|
||||
|
||||
use App\Classes\Exceptions\MalformedRequestException;
|
||||
use App\Classes\General\Abstracts\AbstractControllerLogic;
|
||||
use App\Classes\Jobs\Commands\V2\CreateInvoiceTransactionV2CommandJob;
|
||||
use App\Classes\Modules\Bookings\DataTransferObjects\BookingObject;
|
||||
use App\Classes\Modules\Bookings\DataTransferObjects\UpdateBookingInvoiceStatusObject;
|
||||
use App\Classes\Modules\Bookings\Services\CalculatesBookingOutstanding;
|
||||
use App\Classes\Modules\Bookings\Services\FetchesBooking;
|
||||
use App\Classes\Modules\Bookings\Services\UpdatesBookingInvoiceStatus;
|
||||
use App\Classes\Modules\Bookings\Services\UpdatesBookingFixedAmount;
|
||||
use App\Classes\Modules\Bookings\Standards\Rules\CanUpdateBooking;
|
||||
use App\Classes\Modules\Transactions\Processors\CreateInvoiceTransactionV2Processor;
|
||||
use App\Classes\Modules\Transactions\Services\UpdatesTransactionStatus;
|
||||
use App\Classes\ValueObjects\Constants\ApprovalStatus;
|
||||
use App\Classes\ValueObjects\Constants\TransactionType;
|
||||
use App\Http\Resources\BookingResource;
|
||||
|
||||
use App\Classes\General\Abstracts\AbstractControllerLogic;
|
||||
|
||||
use App\Classes\Modules\Bookings\Services\FetchesBooking;
|
||||
|
||||
use App\Classes\Modules\Bookings\Standards\Rules\CanUpdateBooking;
|
||||
use App\Classes\Modules\Bookings\DataTransferObjects\BookingObject;
|
||||
use App\Classes\Modules\Bookings\Services\CalculatesBookingOutstanding;
|
||||
|
||||
use ErrorException;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use App\Classes\Exceptions\MalformedRequestException;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
class UpdateBookingAmountLogic extends AbstractControllerLogic
|
||||
@@ -52,6 +51,12 @@ class UpdateBookingAmountLogic extends AbstractControllerLogic
|
||||
/** @var UpdatesTransactionStatus */
|
||||
private $updatesTransactionStatus;
|
||||
|
||||
/** @var UpdatesBookingInvoiceStatus */
|
||||
private $updatesBookingInvoiceStatus;
|
||||
|
||||
/** @var CreateInvoiceTransactionV2Processor */
|
||||
private $createInvoiceTransactionProcessor;
|
||||
|
||||
/**
|
||||
* UpdateBookingAmountLogic constructor.
|
||||
* @param CanUpdateBooking $canUpdateBooking
|
||||
@@ -59,14 +64,18 @@ class UpdateBookingAmountLogic extends AbstractControllerLogic
|
||||
* @param FetchesBooking $fetchesBooking
|
||||
* @param CalculatesBookingOutstanding $calculatesBookingOutstanding
|
||||
* @param UpdatesTransactionStatus $updatesTransactionStatus
|
||||
* @param UpdatesBookingInvoiceStatus $updatesBookingInvoiceStatus
|
||||
* @param CreateInvoiceTransactionV2Processor $createInvoiceTransactionProcessor
|
||||
*/
|
||||
public function __construct(CanUpdateBooking $canUpdateBooking, UpdatesBookingFixedAmount $updatesBookingFixedAmount, FetchesBooking $fetchesBooking, CalculatesBookingOutstanding $calculatesBookingOutstanding, UpdatesTransactionStatus $updatesTransactionStatus)
|
||||
public function __construct(CanUpdateBooking $canUpdateBooking, UpdatesBookingFixedAmount $updatesBookingFixedAmount, FetchesBooking $fetchesBooking, CalculatesBookingOutstanding $calculatesBookingOutstanding, UpdatesTransactionStatus $updatesTransactionStatus, UpdatesBookingInvoiceStatus $updatesBookingInvoiceStatus, CreateInvoiceTransactionV2Processor $createInvoiceTransactionProcessor)
|
||||
{
|
||||
$this->canUpdateBooking = $canUpdateBooking;
|
||||
$this->updatesBookingFixedAmount = $updatesBookingFixedAmount;
|
||||
$this->fetchesBooking = $fetchesBooking;
|
||||
$this->calculatesBookingOutstanding = $calculatesBookingOutstanding;
|
||||
$this->updatesTransactionStatus = $updatesTransactionStatus;
|
||||
$this->updatesBookingInvoiceStatus = $updatesBookingInvoiceStatus;
|
||||
$this->createInvoiceTransactionProcessor = $createInvoiceTransactionProcessor;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -81,7 +90,7 @@ class UpdateBookingAmountLogic extends AbstractControllerLogic
|
||||
$input_amount = number_format( floatval(str_replace(',', '', $request->input('fix_amount', $booking->fix_amount))), 5, '.', '');
|
||||
|
||||
$minimum_amount = $booking->fix_amount - $this->calculatesBookingOutstanding->execute($booking);
|
||||
|
||||
|
||||
if (((float)$input_amount + 0.01) < (float)$minimum_amount) {
|
||||
$input_amount = 0;
|
||||
// throw new MalformedRequestException('Booking Amount cannot be less than '. $minimum_amount .'.');
|
||||
@@ -97,7 +106,15 @@ class UpdateBookingAmountLogic extends AbstractControllerLogic
|
||||
|
||||
$booking = $this->updatesBookingFixedAmount->execute($booking, $input_amount);
|
||||
|
||||
if($booking->invoice_status === ApprovalStatus::APPROVED){
|
||||
$updateBookingInvoiceStatusObject = new UpdateBookingInvoiceStatusObject($booking->id, ApprovalStatus::PENDING_VERIFICATION);
|
||||
$this->updatesBookingInvoiceStatus->execute($booking, $updateBookingInvoiceStatusObject);
|
||||
}
|
||||
else{
|
||||
$this->createInvoiceTransactionProcessor->execute($booking);
|
||||
}
|
||||
|
||||
return $this->resourceResponse(new BookingResource($booking));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@ use App\Classes\ValueObjects\Constants\TransactionType;
|
||||
use App\Classes\Exceptions\MalformedRequestException;
|
||||
use App\Classes\General\Abstracts\AbstractControllerLogic;
|
||||
use App\Classes\Modules\Accounts\DataTransferObjects\KeyValuePairObject;
|
||||
use App\Classes\ValueObjects\Constants\KVPKey;
|
||||
use App\Http\Resources\BookingResource;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
@@ -90,9 +91,8 @@ class UpdateBookingAmountOnHoldLogic extends AbstractControllerLogic
|
||||
throw new MalformedRequestException('Booking Amount cannot be less than '. $minimum_amount .'.');
|
||||
}
|
||||
|
||||
$key = "BOOKING_AMOUNT_UPDATE";
|
||||
$keyValuePairObject = new KeyValuePairObject($key, $input_amount);
|
||||
$metadata = $booking->attributesKVP()->where('key', $key)->first();
|
||||
$keyValuePairObject = new KeyValuePairObject(KVPKey::BOOKING_AMOUNT_UPDATE, $input_amount);
|
||||
$metadata = $booking->attributesKVP()->where('key', KVPKey::BOOKING_AMOUNT_UPDATE)->first();
|
||||
if($metadata){
|
||||
$this->updatesKeyValuePair->execute($metadata, $keyValuePairObject);
|
||||
}
|
||||
|
||||
@@ -10,6 +10,11 @@ use App\Classes\Modules\Bookings\Services\UpdatesBookingFixedAmount;
|
||||
use App\Classes\Modules\Bookings\Services\CalculatesBookingOutstanding;
|
||||
use App\Classes\Modules\Bookings\Services\CalculatesBookingPayableAmount;
|
||||
use App\Classes\Modules\Bookings\Services\CalculatesBookingRefundAmount;
|
||||
use App\Classes\Modules\Bookings\Services\UpdatesBookingInvoiceStatus;
|
||||
use App\Classes\Modules\Transactions\Processors\CreateInvoiceTransactionV2Processor;
|
||||
use App\Classes\Modules\Bookings\DataTransferObjects\UpdateBookingInvoiceStatusObject;
|
||||
use App\Classes\ValueObjects\Constants\ApprovalStatus;
|
||||
use App\Classes\ValueObjects\Constants\KVPKey;
|
||||
use App\Classes\ValueObjects\Constants\TransactionType;
|
||||
use App\Http\Resources\BookingResource;
|
||||
use App\Models\Booking;
|
||||
@@ -45,6 +50,12 @@ class UpdateBookingAmountWithPOLogic extends AbstractControllerLogic
|
||||
/** @var CalculatesBookingRefundAmount */
|
||||
private $calculatesBookingRefundAmount;
|
||||
|
||||
/** @var UpdatesBookingInvoiceStatus */
|
||||
private $updatesBookingInvoiceStatus;
|
||||
|
||||
/** @var CreateInvoiceTransactionV2Processor */
|
||||
private $createInvoiceTransactionProcessor;
|
||||
|
||||
/**
|
||||
* UpdateBookingAmountWithPOLogic constructor.
|
||||
* @param FetchesBooking $fetchesBooking
|
||||
@@ -52,14 +63,18 @@ class UpdateBookingAmountWithPOLogic extends AbstractControllerLogic
|
||||
* @param CalculatesBookingOutstanding $calculatesBookingOutstanding
|
||||
* @param CalculatesBookingPayableAmount $calculatesBookingPayableAmount
|
||||
* @param CalculatesBookingRefundAmount $calculatesBookingRefundAmount
|
||||
* @param UpdatesBookingInvoiceStatus $updatesBookingInvoiceStatus
|
||||
* @param CreateInvoiceTransactionV2Processor $createInvoiceTransactionProcessor
|
||||
*/
|
||||
public function __construct(FetchesBooking $fetchesBooking, UpdatesBookingFixedAmount $updatesBookingFixedAmount, CalculatesBookingOutstanding $calculatesBookingOutstanding, CalculatesBookingPayableAmount $calculatesBookingPayableAmount, CalculatesBookingRefundAmount $calculatesBookingRefundAmount)
|
||||
public function __construct(FetchesBooking $fetchesBooking, UpdatesBookingFixedAmount $updatesBookingFixedAmount, CalculatesBookingOutstanding $calculatesBookingOutstanding, CalculatesBookingPayableAmount $calculatesBookingPayableAmount, CalculatesBookingRefundAmount $calculatesBookingRefundAmount, UpdatesBookingInvoiceStatus $updatesBookingInvoiceStatus, CreateInvoiceTransactionV2Processor $createInvoiceTransactionProcessor)
|
||||
{
|
||||
$this->fetchesBooking = $fetchesBooking;
|
||||
$this->updatesBookingFixedAmount = $updatesBookingFixedAmount;
|
||||
$this->calculatesBookingOutstanding = $calculatesBookingOutstanding;
|
||||
$this->calculatesBookingPayableAmount = $calculatesBookingPayableAmount;
|
||||
$this->calculatesBookingRefundAmount = $calculatesBookingRefundAmount;
|
||||
$this->updatesBookingInvoiceStatus = $updatesBookingInvoiceStatus;
|
||||
$this->createInvoiceTransactionProcessor = $createInvoiceTransactionProcessor;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -74,7 +89,7 @@ class UpdateBookingAmountWithPOLogic extends AbstractControllerLogic
|
||||
/** @var Booking $booking */
|
||||
$booking = $this->fetchesBooking->execute(['id' => $request->route('id') ?? $id]);
|
||||
$outstandingAmount = $this->calculatesBookingOutstanding->execute($booking);
|
||||
$bookingAttribute = $booking->attributesKVP()->where('key', "BOOKING_AMOUNT_UPDATE")->first();
|
||||
$bookingAttribute = $booking->attributesKVP()->where('key', KVPKey::BOOKING_AMOUNT_UPDATE)->first();
|
||||
|
||||
|
||||
// cief todo: 90 - BEFORE REVERT
|
||||
@@ -110,6 +125,14 @@ class UpdateBookingAmountWithPOLogic extends AbstractControllerLogic
|
||||
$booking->transactions()->where('type', TransactionType::PROFORMA)->delete();
|
||||
$booking = $this->updatesBookingFixedAmount->execute($booking, $bookingAmountUpdate);
|
||||
|
||||
if($booking->invoice_status === ApprovalStatus::APPROVED){
|
||||
$updateBookingInvoiceStatusObject = new UpdateBookingInvoiceStatusObject($booking->id, ApprovalStatus::PENDING_VERIFICATION);
|
||||
$this->updatesBookingInvoiceStatus->execute($booking, $updateBookingInvoiceStatusObject);
|
||||
}
|
||||
else{
|
||||
$this->createInvoiceTransactionProcessor->execute($booking);
|
||||
}
|
||||
|
||||
$request->merge(['is_privilleged_update' => true]);
|
||||
|
||||
$bookingAttribute->delete();
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\Modules\Bookings\DataTransferObjects;
|
||||
|
||||
use App\Classes\General\Interfaces\DataTransferObject;
|
||||
|
||||
class UpdateBookingInvoiceStatusObject implements DataTransferObject
|
||||
{
|
||||
|
||||
/** @var int */
|
||||
private $id;
|
||||
|
||||
/** @var int */
|
||||
private $invoiceStatus;
|
||||
|
||||
/**
|
||||
* UpdateBookingInvoiceStatusObject constructor.
|
||||
* @param int $id
|
||||
* @param int $invoiceStatus
|
||||
*/
|
||||
public function __construct(int $id, int $invoiceStatus)
|
||||
{
|
||||
$this->id = $id;
|
||||
$this->invoiceStatus = $invoiceStatus;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getId(): int
|
||||
{
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getInvoiceStatus(): int
|
||||
{
|
||||
return $this->invoiceStatus;
|
||||
}
|
||||
}
|
||||
+7
-1
@@ -88,7 +88,13 @@ class CreatePurchaseOrderFor1688OrderProcessor
|
||||
|
||||
if($purchaseOrder->amount === $booking->fix_amount){
|
||||
$this->updatesTransactionStatus->execute($purchaseOrder, ApprovalStatus::APPROVED);
|
||||
$this->createInvoiceTransactionProcessor->execute($booking);
|
||||
$this->createInvoiceTransactionProcessor->execute($booking, "", null, [
|
||||
'generateEInvoice' => false,
|
||||
'generateEInvoiceWithNormalInvoiceTemplate' => false,
|
||||
'generateEInvoiceRefund' => false,
|
||||
'bookingOriginalStatus' => ApprovalStatus::COMPLETED
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\Modules\Bookings\Services;
|
||||
|
||||
use App\Classes\General\Eloquent\AbstractUpdateRecord;
|
||||
use App\Classes\Modules\Bookings\DataTransferObjects\UpdateBookingInvoiceStatusObject;
|
||||
use App\Models\Booking;
|
||||
|
||||
class UpdatesBookingInvoiceStatus extends AbstractUpdateRecord
|
||||
{
|
||||
|
||||
/**
|
||||
* @param Booking $model
|
||||
* @param UpdateBookingInvoiceStatusObject $object
|
||||
* @return \Illuminate\Database\Eloquent\Model
|
||||
* @throws \App\Classes\Exceptions\MalformedRequestException
|
||||
*/
|
||||
public function execute(Booking $model, UpdateBookingInvoiceStatusObject $object)
|
||||
{
|
||||
$model->invoice_status = $object->getInvoiceStatus();
|
||||
return $this->handler($model);
|
||||
}
|
||||
}
|
||||
@@ -58,6 +58,7 @@ class FetchCompanyEInvoiceInfoLogic extends AbstractControllerLogic
|
||||
$eInvoiceInfo->tin = $company->tin;
|
||||
$eInvoiceInfo->msic_code = $company->msic_code;
|
||||
$eInvoiceInfo->e_invoice = $company->e_invoice;
|
||||
$eInvoiceInfo->e_invoice_requested_at = $company->e_invoice_requested_at;
|
||||
}
|
||||
else{
|
||||
return $this->response([]);
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
namespace App\Classes\Modules\Exports\Services;
|
||||
|
||||
use App\Classes\Jobs\Commands\V2\CreateInvoiceTransactionV2CommandJob;
|
||||
use App\Classes\ValueObjects\Constants\TransactionType;
|
||||
use App\Classes\ValueObjects\Constants\ApprovalStatus;
|
||||
use App\Models\Booking;
|
||||
@@ -71,7 +72,8 @@ class ExportsSalesInvoiceReport implements FromQuery, WithHeadings, WithHeadingR
|
||||
'transactions.voucherRedemption',
|
||||
'transactions.voucherRedemption.voucher.campaign'
|
||||
])
|
||||
->where('status', ApprovalStatus::COMPLETED)
|
||||
// ->whereIn('status', [ApprovalStatus::COMPLETED])
|
||||
->whereIn('invoice_status', [ApprovalStatus::APPROVED])
|
||||
->whereHas('transactions', function ($query) use ($startDate, $endDate) {
|
||||
$query->payments()
|
||||
->complete()
|
||||
@@ -115,6 +117,11 @@ class ExportsSalesInvoiceReport implements FromQuery, WithHeadings, WithHeadingR
|
||||
}
|
||||
|
||||
$invoiceTransaction = $booking->transactions->where('type', TransactionType::INVOICE)->whereIn('status', [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED])->first();
|
||||
if(!$invoiceTransaction){
|
||||
Log::info('ExportsSalesInvoiceReport booking with NO invoice: ' . json_encode($booking));
|
||||
// CreateInvoiceTransactionV2CommandJob::dispatch($booking);
|
||||
return $records;
|
||||
}
|
||||
|
||||
$currencyId = $booking->fix_currency_id;
|
||||
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\Modules\Rules\ControllersLogic;
|
||||
|
||||
|
||||
use App\Classes\Exceptions\CriteriaNotFulfilledException;
|
||||
use App\Classes\General\Abstracts\AbstractControllerLogic;
|
||||
use App\Classes\Modules\Rules\DataTransferObjects\CheckEInvoiceAmountLimitRuleDTO;
|
||||
use App\Classes\Modules\Rules\Services\RuleEvaluator;
|
||||
use App\Classes\Modules\Rules\Standards\Rules\CanPassMustEInvoiceAmountLimitRule;
|
||||
use App\Http\Resources\RuleResource;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class CheckEInvoiceAmountLimitLogic extends AbstractControllerLogic
|
||||
{
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
protected function notification():array {
|
||||
return [
|
||||
'title' => 'Rule Check E-Invoice Amount Limit',
|
||||
'message' => 'You have successfully passed all rules evaluated'
|
||||
];
|
||||
}
|
||||
|
||||
/** @var RuleEvaluator */
|
||||
private $ruleEvaluator;
|
||||
|
||||
|
||||
/** @var CanPassMustEInvoiceAmountLimitRule */
|
||||
private $canPassMustEInvoiceAmountLimitRule;
|
||||
|
||||
/**
|
||||
* CheckEInvoiceAmountLimitLogic constructor.
|
||||
* @param RuleEvaluator $ruleEvaluator
|
||||
* @param CanPassMustEInvoiceAmountLimitRule $canPassMustEInvoiceAmountLimitRule
|
||||
*/
|
||||
public function __construct(RuleEvaluator $ruleEvaluator, CanPassMustEInvoiceAmountLimitRule $canPassMustEInvoiceAmountLimitRule)
|
||||
{
|
||||
$this->ruleEvaluator = $ruleEvaluator;
|
||||
$this->canPassMustEInvoiceAmountLimitRule = $canPassMustEInvoiceAmountLimitRule;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Request $request
|
||||
* @return JsonResponse
|
||||
* @throws \App\Classes\Exceptions\AccessForbiddenException
|
||||
* @throws \App\Classes\Exceptions\MalformedRequestException
|
||||
* @throws \App\Classes\Exceptions\RequestValidationException
|
||||
* @throws \App\Classes\Exceptions\CriteriaNotFulfilledException
|
||||
*/
|
||||
public function logic(Request $request) : JsonResponse
|
||||
{
|
||||
$dto = new CheckEInvoiceAmountLimitRuleDTO($request->all());
|
||||
|
||||
$result = $this->ruleEvaluator->evaluate([
|
||||
$this->canPassMustEInvoiceAmountLimitRule
|
||||
], $dto);
|
||||
|
||||
if ($result->failed()) {
|
||||
throw new CriteriaNotFulfilledException("- " . implode("<br>- ", $result->messages()));
|
||||
}
|
||||
|
||||
return $this->resourceResponse(new RuleResource((object)$result));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\Modules\Rules\DataTransferObjects;
|
||||
|
||||
use App\Classes\General\Interfaces\DataTransferObject;
|
||||
|
||||
class CheckEInvoiceAmountLimitRuleDTO implements DataTransferObject
|
||||
{
|
||||
public int $bookingId;
|
||||
public int $companyId;
|
||||
public ?string $amount;
|
||||
public ?string $paymentMethod;
|
||||
public ?string $voucherCode;
|
||||
|
||||
|
||||
public function __construct(array $data)
|
||||
{
|
||||
$this->bookingId = $data['booking_id'];
|
||||
$this->companyId = $data['company_id'];
|
||||
|
||||
$this->amount = $data['amount'] ?? null;
|
||||
$this->paymentMethod = $data['payment_method'] ?? null;
|
||||
$this->voucherCode = $data['voucherCode'] ?? null;
|
||||
}
|
||||
|
||||
public function toArray(): array
|
||||
{
|
||||
return [
|
||||
'booking_id' => $this->bookingId,
|
||||
'company_id' => $this->companyId,
|
||||
'amount' => $this->amount,
|
||||
'payment_method' => $this->paymentMethod,
|
||||
'voucher_code' => $this->voucherCode,
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,102 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\Modules\Rules\Standards\Rules;
|
||||
|
||||
use App\Classes\Exceptions\CriteriaNotFulfilledException;
|
||||
use App\Classes\General\Abstracts\AbstractRule;
|
||||
use App\Classes\Modules\Bookings\Services\FetchesBooking;
|
||||
use App\Classes\Modules\Bookings\Services\CalculatesBookingOutstanding;
|
||||
use App\Classes\Modules\Bookings\Services\FetchesBookingQuotation;
|
||||
use App\Classes\Modules\Currencies\DataTransferObjects\CurrencyConversionObject;
|
||||
use App\Classes\ValueObjects\Constants\ApprovalStatus;
|
||||
use App\Classes\ValueObjects\Constants\PaymentMethodType;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
class CanPassMustEInvoiceAmountLimitRule extends AbstractRule
|
||||
{
|
||||
|
||||
/** @var FetchesBooking */
|
||||
private $fetchesBooking;
|
||||
|
||||
/** @var FetchesBookingQuotation */
|
||||
private $fetchesBookingQuotation;
|
||||
|
||||
/** @var CalculatesBookingOutstanding */
|
||||
private $calculatesBookingOutstanding;
|
||||
|
||||
|
||||
/**
|
||||
* CanPassMustEInvoiceAmountLimitRule constructor.
|
||||
* @param FetchesBooking $fetchesBooking
|
||||
* @param FetchesBookingQuotation $fetchesBookingQuotation
|
||||
* @param CalculatesBookingOutstanding $calculatesBookingOutstanding
|
||||
*/
|
||||
public function __construct(FetchesBooking $fetchesBooking, FetchesBookingQuotation $fetchesBookingQuotation, CalculatesBookingOutstanding $calculatesBookingOutstanding)
|
||||
{
|
||||
$this->fetchesBooking = $fetchesBooking;
|
||||
$this->fetchesBookingQuotation = $fetchesBookingQuotation;
|
||||
$this->calculatesBookingOutstanding = $calculatesBookingOutstanding;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
protected function authorized($object): bool
|
||||
{
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
protected function validators($object): bool
|
||||
{
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
protected function criteria($object): bool
|
||||
{
|
||||
//Check if booking amount is RM10,000 or more, than must opt-in E-Invoice
|
||||
$booking = $this->fetchesBooking->execute(['id' => $object->bookingId]);
|
||||
$company = $booking->company;
|
||||
|
||||
// $totalPayments = 0;
|
||||
|
||||
// if(isset($object->amount)){
|
||||
// $totalPayments = $booking->transactions()->payments()->whereIn('transactions.status', [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED])->sum('amount');
|
||||
|
||||
// $conversionObject = new CurrencyConversionObject(floatval(str_replace(',', '', floatval(str_replace(',', '', $object->amount)))), $booking->convertible_currency_id, $booking->service_id, $booking->fix_currency_id === 1 ? 0:1, PaymentMethodType::PAYMENT_METHODS[$object->paymentMethod]);
|
||||
// $voucherCode = $object->voucherCode ?? null;
|
||||
// $configurations = $this->fetchesBookingQuotation->execute($booking->company, $conversionObject, $voucherCode, null, $booking);
|
||||
// }
|
||||
// else{
|
||||
// $outstanding = $this->calculatesBookingOutstanding->execute($booking);
|
||||
// $conversionObject = new CurrencyConversionObject(floatval(str_replace(',', '', $outstanding)), $booking->convertible_currency_id, $booking->service_id, $booking->fix_currency_id === 1 ? 0 : 1, PaymentMethodType::CASH);
|
||||
// $configurations = $this->fetchesBookingQuotation->execute($booking->company, $conversionObject);
|
||||
// }
|
||||
|
||||
// $bookingAmountInMYR = $configurations->getTotal();
|
||||
// $bookingAmountInMYR = $bookingAmountInMYR + $totalPayments;
|
||||
|
||||
// if($bookingAmountInMYR >= 10000 && (!$company->e_invoice || !$company->tin) ){
|
||||
// throw new CriteriaNotFulfilledException("RM10,000 and above must opt-in for E-Invoice.");
|
||||
// }
|
||||
|
||||
//1 MYR, 2 CNY, 3 USD
|
||||
if((($booking->fix_amount >= 9000 && $booking->fix_currency_id === 1) ||
|
||||
($booking->fix_amount >= 12600 && $booking->fix_currency_id === 2) ||
|
||||
($booking->fix_amount >= 1920 && $booking->fix_currency_id === 3))
|
||||
&& (!$company->e_invoice || !$company->tin) ){
|
||||
throw new CriteriaNotFulfilledException("Booking amount above limit, must opt-in for E-Invoice.");
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
+7
-1
@@ -90,7 +90,13 @@ class CreatePaymentProofDocumentLogic extends AbstractControllerLogic
|
||||
|
||||
$this->updatesTransactionStatus->execute($transaction, ApprovalStatus::APPROVED);
|
||||
|
||||
$this->createInvoiceTransactionProcessor->execute($transaction->owner->booking);
|
||||
$this->createInvoiceTransactionProcessor->execute($transaction->owner->booking, "", null, [
|
||||
'generateEInvoice' => false,
|
||||
'generateEInvoiceWithNormalInvoiceTemplate' => false,
|
||||
'generateEInvoiceRefund' => false,
|
||||
'bookingOriginalStatus' => ApprovalStatus::COMPLETED
|
||||
]
|
||||
);
|
||||
|
||||
// send email to customer
|
||||
// todo: a function to send a proof to the receipiant, they have to give us a email of the receipiant and also need to submiited purchase order
|
||||
|
||||
+123
-102
@@ -104,14 +104,20 @@ class CreateInvoiceTransactionV2Processor
|
||||
$generateEInvoice = $options['generateEInvoice'] ?? false;
|
||||
$generateEInvoiceWithNormalInvoiceTemplate = $options['generateEInvoiceWithNormalInvoiceTemplate'] ?? false;
|
||||
$generateEInvoiceRefund = $options['generateEInvoiceRefund'] ?? false;
|
||||
$bookingOriginalStatus = $options['bookingOriginalStatus'] ?? ApprovalStatus::COMPLETED;
|
||||
$bookingOriginalStatus = $options['bookingOriginalStatus'] ?? ApprovalStatus::APPROVED;
|
||||
|
||||
// Log::info('CreateInvoiceTransactionV2Processor generateEInvoice:' . json_encode($generateEInvoice));
|
||||
// Log::info('CreateInvoiceTransactionV2Processor generateEInvoiceWithNormalInvoiceTemplate: ' . json_encode($generateEInvoiceWithNormalInvoiceTemplate));
|
||||
// Log::info('CreateInvoiceTransactionV2Processor generateEInvoiceRefund: ' . json_encode($generateEInvoiceRefund));
|
||||
// Log::info('CreateInvoiceTransactionV2Processor bookingOriginalStatus: ' . json_encode($bookingOriginalStatus));
|
||||
|
||||
if($generateEInvoiceRefund){
|
||||
$generateEInvoice = true; //With or without refund, these 2 flags are meant to Generate E-Invoice, so cannot have opposite indicator
|
||||
}
|
||||
|
||||
if ($booking->status === ApprovalStatus::COMPLETED && !$generateEInvoice) {
|
||||
return;
|
||||
if ($booking->status === ApprovalStatus::COMPLETED && !$generateEInvoiceRefund) {
|
||||
Log::info('CreateInvoiceTransactionV2Processor Check 1 Bypass New Business Logic Update for booking ' . $booking->id);
|
||||
// return;
|
||||
}
|
||||
|
||||
$payable_amount = $this->calculatesBookingPayableAmount->execute($booking, $booking->fix_currency_id, $generateEInvoiceRefund);
|
||||
@@ -128,31 +134,27 @@ class CreateInvoiceTransactionV2Processor
|
||||
}
|
||||
// confirm that all payments has been transferred
|
||||
if ($this->calculatesBookingTransferredAmount->execute($booking) !== $this->calculatesBookingPaidAmount->execute($booking)) {
|
||||
return;
|
||||
Log::info('CreateInvoiceTransactionV2Processor Check 2 Bypass New Business Logic Update for booking ' . $booking->id);
|
||||
// return;
|
||||
}
|
||||
|
||||
if($generateEInvoiceRefund){
|
||||
$purchaseOrder = $booking->transactions()
|
||||
->where('type', TransactionType::PURCHASE_ORDER)
|
||||
->complete()
|
||||
->first();
|
||||
|
||||
if(!$purchaseOrder){
|
||||
//was use for $generateEInvoiceRefund true
|
||||
$purchaseOrder = $booking->transactions()
|
||||
->where('type', TransactionType::PURCHASE_ORDER)
|
||||
->where('status', ApprovalStatus::PENDING_SUBMISSION)
|
||||
->first();
|
||||
}
|
||||
else{
|
||||
$purchaseOrder = $booking->transactions()
|
||||
->where('type', TransactionType::PURCHASE_ORDER)
|
||||
->complete()
|
||||
->first();
|
||||
}
|
||||
|
||||
$constants = SegmentConstant::where('reference', SegmentConstants::SERVICE_TYPE)->where('detail->id', $booking->service->id)->first();
|
||||
|
||||
if ($constants->detail->is_billable && !$purchaseOrder && !$generateEInvoiceRefund) {
|
||||
return;
|
||||
}
|
||||
|
||||
// $transaction = $booking->transactions()
|
||||
// ->where('type', TransactionType::PAYMENT)
|
||||
// ->first();
|
||||
// if ($constants->detail->is_billable && !$purchaseOrder && !$generateEInvoiceRefund) {
|
||||
// return;
|
||||
// }
|
||||
|
||||
$transaction = $booking->transactions()
|
||||
->where('type', TransactionType::PAYMENT)
|
||||
@@ -163,7 +165,8 @@ class CreateInvoiceTransactionV2Processor
|
||||
$eInvoice = false;
|
||||
$eInvoiceStartDate = Carbon::parse(env('E_INVOICE_START_DATE', '2025-07-01 00:00:00'));
|
||||
$bookingCreatedDate = Carbon::parse($booking->created_at);
|
||||
if ($bookingCreatedDate->isAfter($eInvoiceStartDate) && $supplier->e_invoice === 1) {
|
||||
$eInvoiceRequestedDate = Carbon::parse($supplier->e_invoice_requested_at);
|
||||
if ($bookingCreatedDate->isAfter($eInvoiceStartDate) && $bookingCreatedDate->isAfter($eInvoiceRequestedDate) && $supplier->e_invoice === 1) {
|
||||
$eInvoice = true;
|
||||
}
|
||||
$kvp = $booking->attributesKVP()->where('key', KVPKey::BOOKING_EINVOICE_ELIGIBLE)->first();
|
||||
@@ -211,84 +214,20 @@ class CreateInvoiceTransactionV2Processor
|
||||
->sum('tax');
|
||||
}
|
||||
|
||||
|
||||
|
||||
$transaction_object = new TransactionObject(
|
||||
$billNumber,
|
||||
TransactionType::INVOICE,
|
||||
$transaction->issuer,
|
||||
$transaction->receiver,
|
||||
$transaction->recipient_bank_account_id,
|
||||
$transaction->payment_method,
|
||||
$payable_amount,
|
||||
$booking_amount,
|
||||
$transaction->currency_id,
|
||||
$transaction->original_currency_id,
|
||||
$booking_currency_average_rate,
|
||||
$total_tax,
|
||||
$total_service_charge,
|
||||
null,
|
||||
ApprovalStatus::APPROVED
|
||||
);
|
||||
$invoice_transaction = $this->createsTransaction->execute($purchaseOrder->booking ?? $booking, $transaction_object);
|
||||
|
||||
if ($kvpCopies) {
|
||||
foreach ($kvpCopies as $kvp) {
|
||||
$invoice_transaction->attributesKVP()->save($kvp);
|
||||
}
|
||||
$invoice_transaction = null;
|
||||
if($booking->status === ApprovalStatus::APPROVED){
|
||||
//NEW INVOICE for non-einvoice user applicable only when booking is completed
|
||||
$invoice_transaction = $booking->transactions()
|
||||
->where('type', TransactionType::INVOICE)
|
||||
->complete()
|
||||
->latest()
|
||||
->first();
|
||||
}
|
||||
|
||||
$voucherRedemption = $transaction->voucherRedemption;
|
||||
|
||||
// purchase order
|
||||
if(!$generateEInvoiceRefund){
|
||||
$this->invoiceDocumentProcessor->execute($invoice_transaction, $purchaseOrder, $supplier, DocumentType::PURCHASE_ORDER, $voucherRedemption, $generateEInvoiceWithNormalInvoiceTemplate);
|
||||
}
|
||||
|
||||
// deliver order
|
||||
if(!$generateEInvoiceRefund){
|
||||
$this->invoiceDocumentProcessor->execute($invoice_transaction, $purchaseOrder, $supplier, DocumentType::DELIVER_ORDER, $voucherRedemption, $generateEInvoiceWithNormalInvoiceTemplate);
|
||||
}
|
||||
|
||||
// e-invoice
|
||||
if ($eInvoice)
|
||||
{
|
||||
if($generateEInvoice){
|
||||
$this->invoiceDocumentProcessor->execute($invoice_transaction, $purchaseOrder, $supplier, DocumentType::EINVOICE, $voucherRedemption, $generateEInvoiceWithNormalInvoiceTemplate, $generateEInvoiceRefund);
|
||||
}
|
||||
}
|
||||
// invoice
|
||||
else
|
||||
{
|
||||
$this->invoiceDocumentProcessor->execute($invoice_transaction, $purchaseOrder, $supplier, DocumentType::INVOICE, $voucherRedemption, $generateEInvoiceWithNormalInvoiceTemplate, $generateEInvoiceRefund);
|
||||
}
|
||||
|
||||
if(!$generateEInvoiceRefund){
|
||||
$billNumber = $this->generatesTransactionBillNumber->execute('SPDO-');
|
||||
|
||||
$booking_currency_average_rate = $this->calculatesBookingCurrencyAverageRate->execute($booking, TransactionType::BILL, $generateEInvoiceRefund);
|
||||
|
||||
$paymentTransaction = $booking->transactions()->payments()->where('status', ApprovalStatus::COMPLETED)->first();
|
||||
|
||||
$transaction = null;
|
||||
if($paymentTransaction){
|
||||
$transaction = $paymentTransaction->transactions()->where('type', TransactionType::BILL)->first();
|
||||
}
|
||||
else{ // Special handling for refund cases (When a refund is deleted via DeleteRefundTransactionLogic, a booking payment transaction is set to ApprovalStatus::APPROVED)
|
||||
$temp = $booking->transactions()->payments()->where('status', ApprovalStatus::APPROVED)->first();
|
||||
// Lets check if there is a refund case
|
||||
$refund = $temp->transactions()->refunds()->where('status', ApprovalStatus::APPROVED)->first();
|
||||
if($refund){
|
||||
$transaction = $temp;
|
||||
}
|
||||
else{
|
||||
throw new Exception("No payment found for booking '$booking->id'.");
|
||||
}
|
||||
}
|
||||
|
||||
if(!$invoice_transaction) {
|
||||
$transaction_object = new TransactionObject(
|
||||
$billNumber,
|
||||
TransactionType::SUPPLIER_DELIVER,
|
||||
TransactionType::INVOICE,
|
||||
$transaction->issuer,
|
||||
$transaction->receiver,
|
||||
$transaction->recipient_bank_account_id,
|
||||
@@ -303,19 +242,101 @@ class CreateInvoiceTransactionV2Processor
|
||||
null,
|
||||
ApprovalStatus::APPROVED
|
||||
);
|
||||
$supplier_deliver_order_transaction = $this->createsTransaction->execute($purchaseOrder->booking, $transaction_object);
|
||||
$invoice_transaction = $this->createsTransaction->execute($purchaseOrder->booking ?? $booking, $transaction_object);
|
||||
}
|
||||
|
||||
// supply deliver order
|
||||
$this->invoiceDocumentProcessor->execute($supplier_deliver_order_transaction, $purchaseOrder, $supplier, DocumentType::SUPPLIER_DELIVER_ORDER, null);
|
||||
//Update booking table, used on Export Sales Invoice Report
|
||||
$booking->invoice_status = ApprovalStatus::APPROVED;
|
||||
$booking->save();
|
||||
|
||||
if ($kvpCopies) {
|
||||
foreach ($kvpCopies as $kvp) {
|
||||
$invoice_transaction->attributesKVP()->save($kvp);
|
||||
}
|
||||
}
|
||||
|
||||
$voucherRedemption = $transaction->voucherRedemption;
|
||||
|
||||
if($purchaseOrder){
|
||||
// purchase order
|
||||
if(!$generateEInvoiceRefund){
|
||||
$this->invoiceDocumentProcessor->execute($invoice_transaction, $purchaseOrder, $supplier, DocumentType::PURCHASE_ORDER, $voucherRedemption, $generateEInvoiceWithNormalInvoiceTemplate);
|
||||
}
|
||||
|
||||
// deliver order
|
||||
if(!$generateEInvoiceRefund){
|
||||
$this->invoiceDocumentProcessor->execute($invoice_transaction, $purchaseOrder, $supplier, DocumentType::DELIVER_ORDER, $voucherRedemption, $generateEInvoiceWithNormalInvoiceTemplate);
|
||||
}
|
||||
|
||||
// e-invoice
|
||||
if ($eInvoice)
|
||||
{
|
||||
if($generateEInvoice){
|
||||
$this->invoiceDocumentProcessor->execute($invoice_transaction, $purchaseOrder, $supplier, DocumentType::EINVOICE, $voucherRedemption, $generateEInvoiceWithNormalInvoiceTemplate, $generateEInvoiceRefund);
|
||||
}
|
||||
}
|
||||
// invoice
|
||||
else
|
||||
{
|
||||
$this->invoiceDocumentProcessor->execute($invoice_transaction, $purchaseOrder, $supplier, DocumentType::INVOICE, $voucherRedemption, $generateEInvoiceWithNormalInvoiceTemplate, $generateEInvoiceRefund);
|
||||
}
|
||||
|
||||
if(!$generateEInvoiceRefund){
|
||||
$billNumber = $this->generatesTransactionBillNumber->execute('SPDO-');
|
||||
|
||||
$booking_currency_average_rate = $this->calculatesBookingCurrencyAverageRate->execute($booking, TransactionType::BILL, $generateEInvoiceRefund);
|
||||
|
||||
$paymentTransaction = $booking->transactions()->payments()->where('status', ApprovalStatus::COMPLETED)->first();
|
||||
|
||||
$transactionTypeBill= null;
|
||||
if($paymentTransaction){
|
||||
$transactionTypeBill = $paymentTransaction->transactions()->where('type', TransactionType::BILL)->first();
|
||||
}
|
||||
else{ // Special handling for refund cases (When a refund is deleted via DeleteRefundTransactionLogic, a booking payment transaction is set to ApprovalStatus::APPROVED)
|
||||
$paymentTransactionTemp = $booking->transactions()->payments()->where('status', ApprovalStatus::APPROVED)->first();
|
||||
// Lets check if there is a refund case
|
||||
$refund = $paymentTransactionTemp->transactions()->refunds()->where('status', ApprovalStatus::APPROVED)->first();
|
||||
if($refund){
|
||||
$transactionTypeBill = $paymentTransactionTemp->transactions()->where('type', TransactionType::BILL)->first();
|
||||
}
|
||||
else{
|
||||
Log::info("CreateInvoiceTransactionV2Processor NO completed payment transaction nor refund transaction found for booking '$booking->id'.");
|
||||
}
|
||||
}
|
||||
|
||||
if($transactionTypeBill){
|
||||
$transaction_object = new TransactionObject(
|
||||
$billNumber,
|
||||
TransactionType::SUPPLIER_DELIVER,
|
||||
$transactionTypeBill->issuer,
|
||||
$transactionTypeBill->receiver,
|
||||
$transactionTypeBill->recipient_bank_account_id,
|
||||
$transactionTypeBill->payment_method,
|
||||
$payable_amount,
|
||||
$booking_amount,
|
||||
$transactionTypeBill->currency_id,
|
||||
$transactionTypeBill->original_currency_id,
|
||||
$booking_currency_average_rate,
|
||||
$total_tax,
|
||||
$total_service_charge,
|
||||
null,
|
||||
ApprovalStatus::APPROVED
|
||||
);
|
||||
$supplier_deliver_order_transaction = $this->createsTransaction->execute($purchaseOrder->booking, $transaction_object);
|
||||
|
||||
// supply deliver order
|
||||
$this->invoiceDocumentProcessor->execute($supplier_deliver_order_transaction, $purchaseOrder, $supplier, DocumentType::SUPPLIER_DELIVER_ORDER, null);
|
||||
}
|
||||
}
|
||||
|
||||
// update perfex crm
|
||||
// if(config('perfexcrm.is_enabled') == 'true'){
|
||||
// CreatePerfexCRMInvoice::dispatch($invoice_transaction, $purchaseOrder, $supplier);
|
||||
// }
|
||||
}
|
||||
|
||||
//if(!$generateEInvoiceRefund){
|
||||
$this->updatesBookingStatus->execute($booking, $bookingOriginalStatus);
|
||||
//}
|
||||
|
||||
// update perfex crm
|
||||
// if(config('perfexcrm.is_enabled') == 'true'){
|
||||
// CreatePerfexCRMInvoice::dispatch($invoice_transaction, $purchaseOrder, $supplier);
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -86,6 +86,7 @@ class CreateSupplierTransactionProcessor
|
||||
$original_amount_after_refund = $payment->original_amount - $totalRefund;
|
||||
|
||||
$this->updatesTransactionStatus->execute($payment, ApprovalStatus::COMPLETED);
|
||||
|
||||
$billNumber = $this->generatesTransactionBillNumber->execute('SPLR-');
|
||||
$constant = SegmentConstant::where('reference', SegmentConstants::SERVICE_CHARGE)->where('detail->id', $supplier->id)->first();
|
||||
|
||||
|
||||
@@ -29,5 +29,5 @@ final class ApprovalStatus {
|
||||
self::SUSPENDED => "Suspended",
|
||||
self::EXPIRED => "Expired",
|
||||
self::REFUNDED => "Refunded",
|
||||
];
|
||||
];
|
||||
}
|
||||
|
||||
@@ -30,4 +30,7 @@ class KVPKey
|
||||
|
||||
public const CHATGPT_PROMPT_PREFIX = 'CHATGPT_PROMPT_';
|
||||
public const CLAUDE_PROMPT_PREFIX = 'CLAUDE_PROMPT_';
|
||||
|
||||
public const BOOKING_AMOUNT_UPDATE = 'BOOKING_AMOUNT_UPDATE';
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
<?php
|
||||
|
||||
namespace App\Console\Commands\V2;
|
||||
|
||||
|
||||
use App\Classes\Jobs\Commands\V2\OneTimeBatchProcessEInvoicesV2CommandJob;
|
||||
use App\Classes\Jobs\Commands\V2\ProcessBookingForEInvoiceV2CommandJob;
|
||||
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 OneTimeProcessBookingForEInvoiceV2Command extends Command
|
||||
{
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
|
||||
protected $signature = 'one-time-process-booking-for-einvoice-command';
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'One time batch process E-Invoices';
|
||||
|
||||
|
||||
/**
|
||||
* Create a new command instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
$bookings = Booking::whereIn('marking', ['821671', '773802','106426'])->get();
|
||||
|
||||
$count = 0;
|
||||
foreach ($bookings as $booking) {
|
||||
ProcessBookingForEInvoiceV2CommandJob::dispatch($booking);
|
||||
$count++;
|
||||
Log::info('Processed: ' . $count);
|
||||
Log::info('Booking ID: ' . $booking->marking . ' for E-Invoice ');
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5,6 +5,7 @@ namespace App\Http\Controllers\Rules;
|
||||
use App\Classes\Modules\Rules\ControllersLogic\CheckEInvoiceRuleLogic;
|
||||
use App\Classes\Modules\Rules\ControllersLogic\CheckPurchaseOrderRuleLogic;
|
||||
use App\Classes\Modules\Rules\ControllersLogic\CheckTransferRuleLogic;
|
||||
use App\Classes\Modules\Rules\ControllersLogic\CheckEInvoiceAmountLimitLogic;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
@@ -36,4 +37,13 @@ class CheckRuleController
|
||||
public function checkTransferRule(Request $request, CheckTransferRuleLogic $logic): JsonResponse {
|
||||
return $logic->execute($request);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Request $request
|
||||
* @param CheckEInvoiceAmountLimitLogic $logic
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function checkEInvoiceAmountLimitRule(Request $request, CheckEInvoiceAmountLimitLogic $logic): JsonResponse {
|
||||
return $logic->execute($request);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@ use App\Classes\ValueObjects\Constants\DocumentType;
|
||||
use App\Classes\ValueObjects\Constants\KVPKey;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Http\Resources\Json\JsonResource;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
class BookingResource extends JsonResource
|
||||
{
|
||||
@@ -30,7 +31,7 @@ class BookingResource extends JsonResource
|
||||
$bookingCreatedDate = Carbon::parse($this->created_at);
|
||||
$eInvoiceRequestedDate = Carbon::parse($this->company->e_invoice_requested_at);
|
||||
//cief todo: 90 - for testing
|
||||
if ($bookingCreatedDate->isAfter($eInvoiceStartDate) && $this->company->e_invoice === 1) { //&& $bookingCreatedDate->diffInMinutes($eInvoiceRequestedDate) <= 480 cief todo: 90
|
||||
if ($bookingCreatedDate->isAfter($eInvoiceStartDate) && $bookingCreatedDate->isAfter($eInvoiceRequestedDate) && $this->company->e_invoice === 1) { //&& $bookingCreatedDate->diffInMinutes($eInvoiceRequestedDate) <= 480 cief todo: 90
|
||||
$eInvoice = true;
|
||||
}
|
||||
|
||||
@@ -58,15 +59,13 @@ class BookingResource extends JsonResource
|
||||
'convertible_currency' => new CurrencyResource($this->convertibleCurrency),
|
||||
'conversion_currency' => new CurrencyResource($this->conversionCurrency),
|
||||
'documents' => [
|
||||
'purchase_order' => new DocumentResource($this->documents()->where('document_type', DocumentType::PURCHASE_ORDER)->first()),
|
||||
'delivery_order' => new DocumentResource($this->documents()->where('document_type', DocumentType::DELIVER_ORDER)->first()),
|
||||
'invoice' => new DocumentResource($this->documents()->where('document_type', DocumentType::INVOICE)->first()),
|
||||
'purchase_order' => new DocumentResource($this->documents()->where('document_type', DocumentType::PURCHASE_ORDER)->latest()->first()),
|
||||
'delivery_order' => new DocumentResource($this->documents()->where('document_type', DocumentType::DELIVER_ORDER)->latest()->first()),
|
||||
'invoice' => new DocumentResource($this->documents()->where('document_type', DocumentType::INVOICE)->latest()->first()),
|
||||
'e_invoice' => new DocumentResource($this->documents()->where('document_type', DocumentType::EINVOICE)->latest()->first()),
|
||||
'supplier_delivery_order' => new DocumentResource($this->documents()->where('document_type', DocumentType::SUPPLIER_DELIVER_ORDER)->first()),
|
||||
'proforma_invoice' => new DocumentResource($this->documents()->where('document_type', DocumentType::PROFORMA_INVOICE)->whereNotIn('status', [ApprovalStatus::REJECTED, ApprovalStatus::EXPIRED])->orderByDesc('id')->first()),
|
||||
'ecommerce_purchase_order' => new DocumentResource($this->documents()->where('document_type', DocumentType::ECOMMERCE_PURCHASE_ORDER)->first()),
|
||||
'banking_invoice' => new DocumentResource($this->documents()->where('document_type', DocumentType::BANKING_INVOICE)->whereNotIn('status', [ApprovalStatus::REJECTED, ApprovalStatus::EXPIRED])->orderByDesc('id')->first()),
|
||||
'delivery_order_banking' => new DocumentResource($this->documents()->where('document_type', DocumentType::DELIVER_ORDER_BANKING)->orderByDesc('id')->first()),
|
||||
'supplier_delivery_order' => new DocumentResource($this->documents()->where('document_type', DocumentType::SUPPLIER_DELIVER_ORDER)->latest()->first()),
|
||||
'proforma_invoice' => new DocumentResource($this->documents()->where('document_type', DocumentType::PROFORMA_INVOICE)->whereNotIn('status', [ApprovalStatus::REJECTED, ApprovalStatus::EXPIRED])->latest()->first()),
|
||||
'ecommerce_purchase_order' => new DocumentResource($this->documents()->where('document_type', DocumentType::ECOMMERCE_PURCHASE_ORDER)->latest()->first()),
|
||||
],
|
||||
'order_reference_no' => $this->modelAttributes()->where('name', BookingAttributeNames::ORDER_REFERENCE_NO)->get()->map(function ($attr) {
|
||||
return [
|
||||
@@ -100,6 +99,7 @@ class BookingResource extends JsonResource
|
||||
})->latest()->get())
|
||||
]),
|
||||
'einvoice' => $eInvoice,
|
||||
'invoice_status' => $this->invoice_status,
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
namespace App\Http\Resources;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Http\Resources\Json\JsonResource;
|
||||
|
||||
class EInvoiceInfoResource extends JsonResource
|
||||
@@ -26,6 +27,7 @@ class EInvoiceInfoResource extends JsonResource
|
||||
'msic_code' => (string) $this->msic_code,
|
||||
'tin' => (string) $this->tin,
|
||||
'e_invoice' => (int) $this->e_invoice,
|
||||
'e_invoice_requested_date' => $this->e_invoice_requested_at ? Carbon::parse($this->e_invoice_requested_at)->format('d-m-Y') : null,
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
class AddInvoiceStatusToBookingsTable extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::table('bookings', function (Blueprint $table) {
|
||||
$table->unsignedTinyInteger('invoice_status')
|
||||
->default(0)
|
||||
->after('status');
|
||||
|
||||
$table->index('invoice_status', 'bookings_invoice_status_index');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::table('bookings', function (Blueprint $table) {
|
||||
$table->dropIndex('bookings_invoice_status_index');
|
||||
$table->dropColumn('invoice_status');
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
class AddIsInvoiceGeneratedToBookingsTable extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::table('bookings', function (Blueprint $table) {
|
||||
$table->boolean('is_invoice_generated')
|
||||
->default(false)
|
||||
->after('status');
|
||||
|
||||
$table->index('is_invoice_generated', 'bookings_is_invoice_generated_index');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::table('bookings', function (Blueprint $table) {
|
||||
$table->dropIndex('bookings_is_invoice_generated_index');
|
||||
$table->dropColumn('is_invoice_generated');
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
class AddInvoiceStatusToBookingLogsTable extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::table('booking_logs', function (Blueprint $table) {
|
||||
$table->boolean('invoice_status')
|
||||
->default(false)
|
||||
->after('status');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::table('booking_logs', function (Blueprint $table) {
|
||||
$table->dropColumn('invoice_status');
|
||||
});
|
||||
}
|
||||
}
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
class AddIsInvoiceGeneratedToBookingLogsTable extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::table('booking_logs', function (Blueprint $table) {
|
||||
$table->boolean('is_invoice_generated')
|
||||
->default(false)
|
||||
->after('status');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::table('booking_logs', function (Blueprint $table) {
|
||||
$table->dropColumn('is_invoice_generated');
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -679,8 +679,13 @@ class DummyDataSeeder extends Seeder
|
||||
// once the invoice is generated the transaction table will include 2 new transaction type TransactionType::INVOICE, TransactionType::SUPPLIER_DELIVERY
|
||||
// and for documents will be generated and attached to the booking.
|
||||
// once this process is complete the booking status will update to ApprovalStatus::COMPLETED
|
||||
$this->createInvoiceTransactionProcessor->execute($booking);
|
||||
|
||||
$this->createInvoiceTransactionProcessor->execute($booking, "", null, [
|
||||
'generateEInvoice' => false,
|
||||
'generateEInvoiceWithNormalInvoiceTemplate' => false,
|
||||
'generateEInvoiceRefund' => false,
|
||||
'bookingOriginalStatus' => ApprovalStatus::COMPLETED
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -169,6 +169,7 @@
|
||||
</template>
|
||||
<script>
|
||||
import registrationFormValidation from '../../../general/mixins/accounts/validation/registrationFormValidation'
|
||||
import { track } from '../../../utils/tracking';
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
@@ -205,6 +206,17 @@
|
||||
},
|
||||
submitForm(){
|
||||
this.step === 2 ? this.submit(this.route('api.account.registration.register'), 'post', 'registrationSection', false, false) : this.changeStep('next');
|
||||
},
|
||||
successHandler(response){
|
||||
// fire to gtag manager for fb pixel tracking: CompleteRegistration
|
||||
track('exchange_complete_registration', {
|
||||
content_name: this.parameters.type === 1 ? 'Company' : 'Personal',
|
||||
currency: 'MYR'
|
||||
});
|
||||
|
||||
// Call parent success handler logic from authenticationHandler mixin
|
||||
this.formHandler('');
|
||||
this.$store.dispatch('userAuthentication', {access_token: response.payload.access_token, redirect_url: response.payload.redirect_url});
|
||||
}
|
||||
},
|
||||
mixins: [registrationFormValidation]
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
6. 01DRW - Sales Deposit by Wallet [AR PAYMENT ENTRY] → Filters by Created Date<br/>
|
||||
7. 01DRF - Sales Deposit by Wallet [AR REFUND ENTRY] → Filters by Created Date<br/>
|
||||
8. 01DD - Sales Deposit by Wallet [AR DEPOSIT ENTRY] → Filters by Created Date<br/>
|
||||
9. WALLET TOP UP REPORT [Wallet Deposit Received] → Filters by Top Up Date<br/>
|
||||
</div>
|
||||
">
|
||||
<i class="fa fa-info-circle"></i>
|
||||
@@ -52,6 +53,7 @@
|
||||
6. 01DRW - Sales Deposit by Wallet [AR PAYMENT ENTRY] → Filters by Created Date<br/>
|
||||
7. 01DRF - Sales Deposit by Wallet [AR REFUND ENTRY] → Filters by Created Date<br/>
|
||||
8. 01DD - Sales Deposit by Wallet [AR DEPOSIT ENTRY] → Filters by Created Date<br/>
|
||||
9. WALLET TOP UP REPORT [Wallet Deposit Received] → Filters by Top Up Date<br/>
|
||||
</div>
|
||||
">
|
||||
<i class="fa fa-info-circle"></i>
|
||||
@@ -196,10 +198,10 @@ export default {
|
||||
'01D - Sales Deposit Received [AR DEPOSIT ENTRY]',
|
||||
'01R - RECEIVE PAYMENT [AR RECEIVE PAYMENT]',
|
||||
'Credit Note Report',
|
||||
//'WALLET TOP UP REPORT [Wallet Deposit Received]',
|
||||
'01DRW - Sales Deposit by Wallet [AR PAYMENT ENTRY]',
|
||||
'01DRF - Sales Deposit by Wallet [AR REFUND ENTRY]',
|
||||
'01DD - Sales Deposit by Wallet [AR DEPOSIT ENTRY]'
|
||||
'01DD - Sales Deposit by Wallet [AR DEPOSIT ENTRY]',
|
||||
'WALLET TOP UP REPORT [Wallet Deposit Received]'
|
||||
];
|
||||
},
|
||||
handleExportClick(){
|
||||
@@ -215,10 +217,10 @@ export default {
|
||||
'01D - Sales Deposit Received [AR DEPOSIT ENTRY]': route('api.export.transactions.receive_payment_deposit_entry'),
|
||||
'01R - RECEIVE PAYMENT [AR RECEIVE PAYMENT]': route('api.export.transactions.receive_payment_for_booking'),
|
||||
'Credit Note Report': route('api.export.transactions.ar_credit_note'),
|
||||
//'WALLET TOP UP REPORT [Wallet Deposit Received]': route('api.export.transactions.wallet_top_up_deposit_entry'),
|
||||
'01DRW - Sales Deposit by Wallet [AR PAYMENT ENTRY]': route('api.export.transactions.sales_deposit_by_wallet_payment_entry'),
|
||||
'01DRF - Sales Deposit by Wallet [AR REFUND ENTRY]': route('api.export.transactions.sales_deposit_by_wallet_refund_entry'),
|
||||
'01DD - Sales Deposit by Wallet [AR DEPOSIT ENTRY]': route('api.export.transactions.sales_deposit_by_wallet_deposit_entry'),
|
||||
'WALLET TOP UP REPORT [Wallet Deposit Received]': route('api.export.transactions.wallet_top_up_deposit_entry'),
|
||||
};
|
||||
|
||||
let url = `${routesMap[reportType]}?startDate=${this.parameters.startDate}&endDate=${this.parameters.endDate}`;
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
<p class="muted">MSIC Code</p>
|
||||
<p class="m-b-0">{{ eInvoiceData.msic_code }}</p>
|
||||
</div>
|
||||
<div class="padding-15 bg-master-lightest">
|
||||
<div class="padding-15 bg-master-lightest m-b-10">
|
||||
<p class="muted">Billing Address</p>
|
||||
<p class="mb-0">
|
||||
<a data-toggle="collapse" href="#billingDetails" role="button" aria-expanded="false" aria-controls="billingDetails">
|
||||
@@ -35,6 +35,10 @@
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div class="padding-15 bg-master-lightest m-b-10" v-if="$store.getters.isAdmin">
|
||||
<p class="muted">Requested Date</p>
|
||||
<p class="m-b-0">{{ eInvoiceData.e_invoice_requested_date }} (d-m-Y)</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
+48
-24
@@ -162,29 +162,6 @@
|
||||
</modal-component>
|
||||
</div>
|
||||
</div>
|
||||
<modal-component
|
||||
id="modal-einvoice-request"
|
||||
class="animate__animated animate__fast animate__fadeIn"
|
||||
styleType="fill-in" type="requestEInvoiceA" size="large">
|
||||
<e-invoice-request-form-component
|
||||
class="text-center"
|
||||
:section="section"
|
||||
:company-id="data.company.id"
|
||||
@choice-made="handleEInvoiceRequestRespond"
|
||||
/>
|
||||
</modal-component>
|
||||
<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>
|
||||
<!-- E-Invoice - end -->
|
||||
</div>
|
||||
</div>
|
||||
@@ -622,7 +599,7 @@
|
||||
<!-- E-Invoice -->
|
||||
<button id="lock-booking" class="btn btn-sm all-caps b-rad-none btn-success btn-block"
|
||||
v-if="paymentMethod.id !== 'wallet' || walletOutstanding >= 0"
|
||||
@click.prevent="checkPurchaseOrderRule">Lock Booking</button>
|
||||
@click.prevent="checkEInvoiceAmountLimitRule">Lock Booking</button>
|
||||
</div>
|
||||
<modal-component id="confirm-booking-modal" v-if="calculation.total > 0" class="animate__animated animate__fast animate__fadeIn" styleType="fill-in" type="paymentSummary">
|
||||
<confirm-quotation-form-component v-on:cancelQuotation="cancelQuotation()" :calculation="calculation" :section="section" :id="item.id" :payment_method="paymentMethod.id" :bank_code="onlinePayment.id" :amount="amount" :company-id="item.company.id"></confirm-quotation-form-component>
|
||||
@@ -630,6 +607,31 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- E-Invoice - start -->
|
||||
<modal-component
|
||||
id="modal-einvoice-request"
|
||||
class="animate__animated animate__fast animate__fadeIn"
|
||||
styleType="fill-in" type="requestEInvoiceA" size="large">
|
||||
<e-invoice-request-form-component
|
||||
class="text-center"
|
||||
:section="section"
|
||||
:company-id="data.company.id"
|
||||
@choice-made="handleEInvoiceRequestRespond"
|
||||
/>
|
||||
</modal-component>
|
||||
<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>
|
||||
<!-- E-Invoice - end -->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -740,6 +742,9 @@
|
||||
$('#confirm-booking-modal').modal('show');
|
||||
}
|
||||
}
|
||||
else if(section === this.section + 'CheckEInvoiceAmountLimitRule'){
|
||||
this.checkPurchaseOrderRule();
|
||||
}
|
||||
else if(section === this.section + 'ChangeOfMind'){
|
||||
this.$store.dispatch('reloadList', {'name': "bookingDetailSection"});
|
||||
}
|
||||
@@ -767,6 +772,14 @@
|
||||
if(section === this.section + 'CheckEInvoiceRule' && statusCode === 422){
|
||||
$('#modal-einvoice-info').modal('show');
|
||||
}
|
||||
else if(section === this.section + 'CheckEInvoiceAmountLimitRule' && statusCode === 422){
|
||||
if(!this.data.company.e_invoice){
|
||||
$('#modal-einvoice-request').modal('show');
|
||||
}
|
||||
else if(!this.data.company.tin){
|
||||
$('#modal-einvoice-info').modal('show');
|
||||
}
|
||||
}
|
||||
this.error = error.message;
|
||||
},
|
||||
makePayment(){ //E-Invoice
|
||||
@@ -837,6 +850,17 @@
|
||||
};
|
||||
this.submit(route('api.rule.check.einvoice'), 'post', this.section + 'CheckEInvoiceRule', false, true);
|
||||
},
|
||||
checkEInvoiceAmountLimitRule(){
|
||||
this.error = '';
|
||||
this.parameters = {
|
||||
booking_id: this.data.id,
|
||||
company_id: this.data.company.id,
|
||||
payment_method: this.paymentMethod.id,
|
||||
voucherCode: this.voucherCode,
|
||||
amount: this.amount
|
||||
};
|
||||
this.submit(route('api.rule.check.einvoice.amount-limit'), 'post', this.section + 'CheckEInvoiceAmountLimitRule', false, true);
|
||||
},
|
||||
checkPurchaseOrderRule(){
|
||||
this.error = '';
|
||||
this.parameters = {
|
||||
|
||||
@@ -198,7 +198,20 @@
|
||||
<div class="col-12 col-md-5 pr-md-0" v-if="submitted && data.status !== 3">
|
||||
<div class="row m-b-15" v-if="($store.getters.isAdmin && data.purchase_order.status === 1) || ($store.getters.isCustomer && data.purchase_order.status === 1 && $store.getters.getCompanyId === 199)" >
|
||||
<div class="col">
|
||||
<button class="btn btn-sm btn-block btn-success b-rad-none" @click="submit(route('api.booking.po.approval', data.id), 'post', section, true, true)">Approve Purchase Order</button>
|
||||
<button class="btn btn-sm btn-block btn-success b-rad-none" :disabled="poProcessing" @click="handleRepprove()">Approve Purchase Order</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row m-b-15" v-if="$store.getters.isAdmin && data.purchase_order.status === 2" >
|
||||
<div class="col">
|
||||
<button class="btn btn-sm btn-block btn-success b-rad-none" :disabled="poProcessing" @click="handleRepprove()">
|
||||
Repprove Purchase Order
|
||||
<span class="badge badge-danger position-absolute" style="top:-5px; right:-5px;"
|
||||
data-toggle="tooltip"
|
||||
data-placement="right"
|
||||
data-html="true"
|
||||
data-custom-class="tooltip-report-export"
|
||||
title="Allow admin to rerun of 'Approve Purchase Order' to generate invoices, conditions apply">ADMIN</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -333,6 +346,7 @@
|
||||
products: [],
|
||||
files: [],
|
||||
uploadFiles: false,
|
||||
poProcessing: false,
|
||||
}
|
||||
},
|
||||
validations: {
|
||||
@@ -444,6 +458,9 @@
|
||||
this.checkEInvoiceRule();
|
||||
}
|
||||
else if(section === this.section + 'CheckEInvoiceRule'){
|
||||
this.checkEInvoiceAmountLimitRule();
|
||||
}
|
||||
else if(section === this.section + 'CheckEInvoiceAmountLimitRule'){
|
||||
if(response.payload.data.isPassed){
|
||||
if(this.data.service.id === 14 || this.data.service.id === 15 || this.data.service.id === 16 || this.data.service.id === 17 || this.data.service.id === 18 || this.data.service.id === 19){
|
||||
this.submit(route('api.booking.banking.create', this.data.id), 'post', this.section, true, true);
|
||||
@@ -459,11 +476,20 @@
|
||||
}
|
||||
this.updateList()
|
||||
}
|
||||
this.poProcessing = false;
|
||||
},
|
||||
errorHandler(error, statusCode, section) { //E-Invoice
|
||||
if(section === this.section + 'CheckEInvoiceRule' && statusCode === 422){
|
||||
$('#modal-einvoice-info').modal('show');
|
||||
}
|
||||
else if(section === this.section + 'CheckEInvoiceAmountLimitRule' && statusCode === 422){
|
||||
if(!this.data.company.e_invoice){
|
||||
$('#modal-einvoice-request').modal('show');
|
||||
}
|
||||
else if(!this.data.company.tin){
|
||||
$('#modal-einvoice-info').modal('show');
|
||||
}
|
||||
}
|
||||
},
|
||||
addProduct(){
|
||||
this.products.push({
|
||||
@@ -530,6 +556,14 @@
|
||||
};
|
||||
this.submit(route('api.rule.check.einvoice'), 'post', this.section + 'CheckEInvoiceRule', false, true);
|
||||
},
|
||||
checkEInvoiceAmountLimitRule(){
|
||||
this.error = '';
|
||||
this.parameters = {
|
||||
booking_id: this.data.id,
|
||||
company_id: this.data.company.id,
|
||||
};
|
||||
this.submit(route('api.rule.check.einvoice.amount-limit'), 'post', this.section + 'CheckEInvoiceAmountLimitRule', false, true);
|
||||
},
|
||||
updatedEInvoiceInfo(info){
|
||||
this.$store.dispatch('reloadList', {'name': "bookingDetailSection"});
|
||||
},
|
||||
@@ -540,8 +574,14 @@
|
||||
};
|
||||
this.parameters.e_invoice_request = false;
|
||||
this.submit((this.route('api.company.einvoice.request.change')), 'post', this.section + 'ChangeOfMind', true, true);
|
||||
},
|
||||
handleRepprove() {
|
||||
if (this.poProcessing) return;
|
||||
this.poProcessing = true;
|
||||
this.submit(route('api.booking.po.approval', this.data.id), 'post', this.section, true, true);
|
||||
}
|
||||
},
|
||||
mixins: [formHandler]
|
||||
}
|
||||
</script>
|
||||
<
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
|
||||
<script>
|
||||
import ModalFormHandler from '../../../general/mixins/modalFormHandler';
|
||||
import { track } from '../../../utils/tracking';
|
||||
export default {
|
||||
props:{
|
||||
order_reference_no: {
|
||||
@@ -26,6 +27,12 @@
|
||||
},
|
||||
methods: {
|
||||
submitForm(){
|
||||
// fire to gtag manager for fb pixel tracking: AddToCart — fired when the user clicks Confirm Order (user intent, OK even if API fails)
|
||||
track('exchange_add_to_cart', {
|
||||
value: Number(String(this.data.amount).replace(/,/g, '')),
|
||||
currency: 'MYR'
|
||||
});
|
||||
|
||||
this.parameters = {
|
||||
company_id: this.data.company.id,
|
||||
type: this.data.type,
|
||||
@@ -42,6 +49,13 @@
|
||||
this.submit(route('api.booking.create'), 'post', this.section, true, true)
|
||||
},
|
||||
successHandler(response){
|
||||
// fire to gtag manager for fb pixel tracking: InitiateCheckout — booking created
|
||||
track('exchange_checkout', {
|
||||
value: Number(String(this.data.amount).replace(/,/g, '')),
|
||||
currency: 'MYR',
|
||||
booking_id: response.payload.data.marking
|
||||
});
|
||||
|
||||
window.location.href = this.route('booking.details', response.payload.data.marking)
|
||||
|
||||
}
|
||||
|
||||
+2
-2
@@ -6,7 +6,7 @@
|
||||
<div class="col-md col-sm-12 m-b-20">
|
||||
<div class="row" v-if="booking">
|
||||
<div class="col" v-if="showDownloadPDFButtons">
|
||||
<div class="row m-b-50" v-if="booking.status === 3 || isBookingWithAFullRefund">
|
||||
<div class="row m-b-50" v-if="(booking.status === 3 || booking.invoice_status === 2) || isBookingWithAFullRefund">
|
||||
<div class="col no-padding">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
@@ -122,7 +122,7 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row m-b-10" v-if="booking.status !== 3 && !isBookingWithAFullRefund">
|
||||
<div class="row m-b-10" v-else>
|
||||
<div class="col">
|
||||
<div class="row text-center m-b-15">
|
||||
<div class="col">
|
||||
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
// resources/assets/vue/utils/tracking.js
|
||||
export function track(event, payload = {}) {
|
||||
if (typeof window === 'undefined') return;
|
||||
|
||||
// console.log('tracking', event, payload);
|
||||
|
||||
window.dataLayer = window.dataLayer || [];
|
||||
window.dataLayer.push({
|
||||
event,
|
||||
...payload,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -103,4 +103,21 @@
|
||||
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
||||
@endsection
|
||||
|
||||
@push('scripts')
|
||||
@if($status === 2 && isset($transaction) && $transaction)
|
||||
<script>
|
||||
(function() {
|
||||
// fire to gtag manager for fb pixel tracking: exchange_purchase
|
||||
window.dataLayer = window.dataLayer || [];
|
||||
window.dataLayer.push({
|
||||
event: 'exchange_purchase',
|
||||
transaction_id: @json($transaction->payment_reference ?? ''),
|
||||
value: {{ number_format((float)($transaction->amount ?? 0), 2, '.', '') }},
|
||||
currency: 'MYR'
|
||||
});
|
||||
})();
|
||||
</script>
|
||||
@endif
|
||||
@endpush
|
||||
@@ -9,4 +9,5 @@ Route::prefix('rule')
|
||||
Route::post('/check/eInvoice', [CheckRuleController::class, 'checkEInvoiceRule'])->name('check.einvoice');
|
||||
Route::post('/check/purchase-order', [CheckRuleController::class, 'checkPurchaseOrderRule'])->name('check.purchase.order');
|
||||
Route::post('/check/tranfer', [CheckRuleController::class, 'checkTransferRule'])->name('check.transfer');
|
||||
Route::post('/check/e-invoice/amount-limit', [CheckRuleController::class, 'checkEInvoiceAmountLimitRule'])->name('check.einvoice.amount-limit');
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user