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; $this->createPerfexCRMInvoiceProcessor = $createPerfexCRMInvoiceProcessor; } /** * @param Booking $booking * @return void * @throws MalformedRequestException */ public function execute(Booking $booking) { 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(); $billNumber = $this->generatesTransactionBillNumber->execute('INV-'); $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); $supplier = $this->fetchesCompany->execute(['id' => $transaction->receiver]); // purchase order $this->invoiceDocumentProcessor->execute($invoice_transaction, $purchaseOrder, $supplier, DocumentType::PURCHASE_ORDER); // deliver order $this->invoiceDocumentProcessor->execute($invoice_transaction, $purchaseOrder, $supplier, DocumentType::DELIVER_ORDER); // invoice $this->invoiceDocumentProcessor->execute($invoice_transaction, $purchaseOrder, $supplier, DocumentType::INVOICE); $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); // update perfex crm $this->createPerfexCRMInvoiceProcessor->execute($invoice_transaction, $purchaseOrder, $supplier); $this->updatesBookingStatus->execute($booking, ApprovalStatus::COMPLETED); } }