Files
exchange-2.0/app/Classes/Modules/Transactions/Processors/CreateInvoiceTransactionProcessor.php
T

235 lines
10 KiB
PHP

<?php
namespace App\Classes\Modules\Transactions\Processors;
use App\Classes\Exceptions\MalformedRequestException;
use App\Classes\Modules\Bookings\Services\CalculatesBookingPayableAmount;
use App\Classes\Modules\Bookings\Services\CalculatesBookingTransferredAmount;
use App\Classes\Modules\ServiceTypes\Services\FetchesServiceConfigurations;
use App\Classes\Modules\Transactions\Services\ListsTransactions;
use App\Classes\Modules\Transactions\Services\CreatesTransaction;
use App\Classes\Modules\Transactions\Services\GeneratesTransactionBillNumber;
use App\Classes\Modules\Bookings\Services\CalculatesBookingPaidAmount;
use App\Classes\Modules\Bookings\Services\CalculatesBookingCurrencyAverageRate;
use App\Classes\Modules\Companies\Services\FetchesCompany;
use App\Classes\Modules\Bookings\Services\UpdatesBookingStatus;
use App\Classes\Modules\Transactions\DataTransferObjects\TransactionObject;
use App\Classes\ValueObjects\Constants\ApprovalStatus;
use App\Classes\ValueObjects\Constants\SegmentConstants;
use App\Classes\ValueObjects\Constants\TransactionType;
use App\Classes\ValueObjects\Constants\DocumentType;
use App\Models\Booking;
use App\Models\SegmentConstant;
use Carbon\Carbon;
class CreateInvoiceTransactionProcessor
{
/** @var CreatesTransaction */
private $createsTransaction;
/** @var GeneratesTransactionBillNumber */
private $generatesTransactionBillNumber;
/** @var CalculatesBookingPaidAmount */
private $calculatesBookingPaidAmount;
/** @var CalculatesBookingPayableAmount */
private $calculatesBookingPayableAmount;
/** @var CalculatesBookingTransferredAmount */
private $calculatesBookingTransferredAmount;
/** @var CalculatesBookingCurrencyAverageRate */
private $calculatesBookingCurrencyAverageRate;
/** @var FetchesCompany */
private $fetchesCompany;
/** @var UpdatesBookingStatus */
private $updatesBookingStatus;
/** @var CreateInvoiceDocumentProcessor */
private $invoiceDocumentProcessor;
/**
* CreateInvoiceTransactionProcessor constructor.
* @param ListsTransactions $listsTransactions
* @param CreatesTransaction $createsTransaction
* @param GeneratesTransactionBillNumber $generatesTransactionBillNumber
* @param CalculatesBookingPaidAmount $calculatesBookingPaidAmount
* @param CalculatesBookingPayableAmount $calculatesBookingPayableAmount
* @param CalculatesBookingTransferredAmount $calculatesBookingTransferredAmount
* @param FetchesServiceConfigurations $fetchesServiceConfigurations
* @param CalculatesBookingCurrencyAverageRate $calculatesBookingCurrencyAverageRate
* @param FetchesCompany $fetchesCompany
* @param UpdatesBookingStatus $updatesBookingStatus
* @param CreateInvoiceDocumentProcessor $invoiceDocumentProcessor
*/
public function __construct(ListsTransactions $listsTransactions, CreatesTransaction $createsTransaction, GeneratesTransactionBillNumber $generatesTransactionBillNumber, CalculatesBookingPaidAmount $calculatesBookingPaidAmount, CalculatesBookingPayableAmount $calculatesBookingPayableAmount, CalculatesBookingTransferredAmount $calculatesBookingTransferredAmount, FetchesServiceConfigurations $fetchesServiceConfigurations, CalculatesBookingCurrencyAverageRate $calculatesBookingCurrencyAverageRate, FetchesCompany $fetchesCompany, UpdatesBookingStatus $updatesBookingStatus, CreateInvoiceDocumentProcessor $invoiceDocumentProcessor)
{
$this->createsTransaction = $createsTransaction;
$this->generatesTransactionBillNumber = $generatesTransactionBillNumber;
$this->calculatesBookingPaidAmount = $calculatesBookingPaidAmount;
$this->calculatesBookingPayableAmount = $calculatesBookingPayableAmount;
$this->calculatesBookingTransferredAmount = $calculatesBookingTransferredAmount;
$this->calculatesBookingCurrencyAverageRate = $calculatesBookingCurrencyAverageRate;
$this->fetchesCompany = $fetchesCompany;
$this->updatesBookingStatus = $updatesBookingStatus;
$this->invoiceDocumentProcessor = $invoiceDocumentProcessor;
}
/**
* @param Booking $booking
* @param String $invoiceNo
* @return void
* @throws MalformedRequestException
*/
public function execute(Booking $booking, String $invoiceNo= "")
{
if ($booking->status === ApprovalStatus::COMPLETED) {
return;
}
$payable_amount = $this->calculatesBookingPayableAmount->execute($booking, $booking->fix_currency_id);
$booking_amount = $booking->fix_amount;
// confirm that booking amount has been fully paid
if ((float) $booking_amount > (float) $payable_amount) {
return;
}
// confirm that all payments has been transferred
if ($this->calculatesBookingTransferredAmount->execute($booking) !== $this->calculatesBookingPaidAmount->execute($booking)) {
return;
}
$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) {
return;
}
// $transaction = $booking->transactions()
// ->where('type', TransactionType::PAYMENT)
// ->first();
$transaction = $booking->transactions()
->where('type', TransactionType::PAYMENT)
->latest()->get()[0];
$supplier = $this->fetchesCompany->execute(['id' => $transaction->receiver]);
// Check if eInvoice implementation has started and company opted in for eInvoice
$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) {
$eInvoice = true;
}
// $eInvoice = true; //cief todo: 90 - for testing
if($invoiceNo){
$billNumber = $invoiceNo;
}
else{
$billNUmberPrefix = $eInvoice ? 'EINV-' : 'INV-';
$billNumber = $this->generatesTransactionBillNumber->execute($billNUmberPrefix);
}
$booking_currency_average_rate = $this->calculatesBookingCurrencyAverageRate->execute($booking, TransactionType::PAYMENT);
$total_service_charge = $booking->transactions()
->where('type', TransactionType::PAYMENT)
->whereIn('status', [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED])
->sum('service_charge');
$total_tax = $booking->transactions()
->where('type', TransactionType::PAYMENT)
->whereIn('status', [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED])
->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, $transaction_object);
$voucherRedemption = $transaction->voucherRedemption;
// purchase order
$this->invoiceDocumentProcessor->execute($invoice_transaction, $purchaseOrder, $supplier, DocumentType::PURCHASE_ORDER, $voucherRedemption);
// deliver order
$this->invoiceDocumentProcessor->execute($invoice_transaction, $purchaseOrder, $supplier, DocumentType::DELIVER_ORDER, $voucherRedemption);
// e-invoice
if ($eInvoice)
{
$this->invoiceDocumentProcessor->execute($invoice_transaction, $purchaseOrder, $supplier, DocumentType::EINVOICE, $voucherRedemption);
}
// invoice
else
{
$this->invoiceDocumentProcessor->execute($invoice_transaction, $purchaseOrder, $supplier, DocumentType::INVOICE, $voucherRedemption);
}
$billNumber = $this->generatesTransactionBillNumber->execute('SPDO-');
$booking_currency_average_rate = $this->calculatesBookingCurrencyAverageRate->execute($booking, TransactionType::BILL);
$transaction = $booking->transactions()->payments()->where('status', ApprovalStatus::COMPLETED)->first()
->transactions()->where('type', TransactionType::BILL)->first();
$transaction_object = new TransactionObject(
$billNumber,
TransactionType::SUPPLIER_DELIVER,
$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
);
$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);
$this->updatesBookingStatus->execute($booking, ApprovalStatus::COMPLETED);
// update perfex crm
// if(config('perfexcrm.is_enabled') == 'true'){
// CreatePerfexCRMInvoice::dispatch($invoice_transaction, $purchaseOrder, $supplier);
// }
}
}