From 2f791784964cda35d80809ffba907cc2e59a1e89 Mon Sep 17 00:00:00 2001 From: ghost2023 Date: Wed, 1 Jul 2026 16:11:47 +0300 Subject: [PATCH] fix: booking invoice issue --- .../bookings/booking-invoice.service.ts | 13 +-- .../bookings/booking-transition.service.ts | 8 +- .../src/modules/bookings/bookings.module.ts | 89 ++++++++++--------- 3 files changed, 56 insertions(+), 54 deletions(-) diff --git a/apps/edr-freight-api/src/modules/bookings/booking-invoice.service.ts b/apps/edr-freight-api/src/modules/bookings/booking-invoice.service.ts index a2eb29a5f..c70133ee7 100644 --- a/apps/edr-freight-api/src/modules/bookings/booking-invoice.service.ts +++ b/apps/edr-freight-api/src/modules/bookings/booking-invoice.service.ts @@ -65,7 +65,7 @@ export class BookingInvoiceService { async ensureInvoiceForBooking( booking: Booking, invoiceOptions: InvoiceOptions = {}, - ): Promise { + ): Promise { const existing = await this.billing.findPayable( Freight.InvoiceSource.Booking, booking.id, @@ -77,16 +77,9 @@ export class BookingInvoiceService { this.logger.warn( `Skipping invoice for booking ${booking.reference} (${booking.id}): no company to bill.`, ); - return null; } const input = this.buildInput(booking, invoiceOptions); - if (!input) { - this.logger.warn( - `Skipping invoice for booking ${booking.reference} (${booking.id}): no priced amount.`, - ); - return null; - } return this.billing.generateInvoice(input); } @@ -154,7 +147,7 @@ export class BookingInvoiceService { private buildInput( booking: Booking, invoiceOptions: InvoiceOptions = {}, - ): GenerateInvoiceInput | null { + ): GenerateInvoiceInput { const breakdown = (booking.pricingBreakdown ?? {}) as StoredPricingBreakdown; const currency = breakdown.currency ?? booking.paymentCurrency ?? "ETB"; @@ -172,7 +165,7 @@ export class BookingInvoiceService { // Fall back to a single freight line when no breakdown was snapshotted. if (lines.length === 0) { const amount = Number(booking.totalAmount); - if (!Number.isFinite(amount) || amount <= 0) return null; + if (!Number.isFinite(amount) || amount <= 0) throw new Error("No price"); lines.push({ chargeType: "FREIGHT", description: "Rail freight", diff --git a/apps/edr-freight-api/src/modules/bookings/booking-transition.service.ts b/apps/edr-freight-api/src/modules/bookings/booking-transition.service.ts index e77831d46..90ccd0118 100644 --- a/apps/edr-freight-api/src/modules/bookings/booking-transition.service.ts +++ b/apps/edr-freight-api/src/modules/bookings/booking-transition.service.ts @@ -3,6 +3,7 @@ import { forwardRef, Inject, Injectable, + Logger, } from "@nestjs/common"; import type { TCurrentUser } from "@tria-plc/api-common/modules/auth/types/current-user.type"; @@ -31,6 +32,7 @@ import { Freight } from "@edr/types"; @Injectable() export class BookingTransitionService { + private readonly logger = new Logger(BookingTransitionService.name); constructor( private readonly bookingsRepository: BookingsRepository, private readonly ruleEngineService: RuleEngineService, @@ -918,8 +920,10 @@ export class BookingTransitionService { private async acceptOperationRequest(booking: Booking): Promise { const now = new Date(); - const invoice = - (await this.invoiceService.ensureInvoiceForBooking(booking))!; + const invoice = await this.invoiceService.ensureInvoiceForBooking(booking); + this.logger.log( + `Generated invoice ${invoice.invoiceNumber} (${invoice.id}) for ${booking.reference}:${booking.id}`, + ); await this.invoiceService.updateStatus( invoice.id, Freight.InvoiceStatus.Pending, diff --git a/apps/edr-freight-api/src/modules/bookings/bookings.module.ts b/apps/edr-freight-api/src/modules/bookings/bookings.module.ts index 5d7e3b2c9..4cd5d10df 100644 --- a/apps/edr-freight-api/src/modules/bookings/bookings.module.ts +++ b/apps/edr-freight-api/src/modules/bookings/bookings.module.ts @@ -1,44 +1,44 @@ -import { Module, forwardRef } from '@nestjs/common'; -import { ConfigService } from '@nestjs/config'; -import { TypeOrmModule } from '@nestjs/typeorm'; -import { ExchangeModule, ExchangeOptions } from '@edr/api-common'; +import { Module, forwardRef } from "@nestjs/common"; +import { ConfigService } from "@nestjs/config"; +import { TypeOrmModule } from "@nestjs/typeorm"; +import { ExchangeModule, ExchangeOptions } from "@edr/api-common"; // import { CustomersModule } from '../customers/customers.module'; -import { CompaniesModule } from '../companies/companies.module'; -import { FilesModule } from '../files/files.module'; -import { MinioModule } from '../minio/minio.module'; -import { RuleEngineModule } from '../rule-engine/rule-engine.module'; -import { FileUploadSettingsModule } from '../file-upload-settings/file-upload-settings.module'; -import { SignaturesModule } from '../signatures/signatures.module'; -import { BillingModule } from '../billing/billing.module'; -import { FirstMileModule } from '../first-mile/first-mile.module'; -import { BookingContractService } from './booking-contract.service'; -import { BookingInvoiceService } from './booking-invoice.service'; -import { BookingPaymentController } from './booking-payment.controller'; -import { BookingPaymentService } from './booking-payment.service'; -import { BookingPricingService } from './booking-pricing.service'; -import { BookingReferenceDataService } from './booking-reference-data.service'; -import { BookingTransitionService } from './booking-transition.service'; -import { BookingsController } from './bookings.controller'; -import { PayController } from './pay.controller'; -import { BookingsRepository } from './bookings.repository'; -import { ConsolidationService } from './consolidation.service'; -import { BookingsService } from './bookings.service'; -import { BookingApprovalStep } from './entities/booking-approval-step.entity'; -import { BookingCargoModifier } from './entities/booking-cargo-modifier.entity'; -import { BookingDocumentReview } from './entities/booking-document-review.entity'; -import { BookingContainer } from './entities/booking-container.entity'; -import { BookingRateSnapshot } from './entities/booking-rate-snapshot.entity'; -import { BookingContractSignature } from './entities/booking-contract-signature.entity'; -import { BookingReviewNote } from './entities/booking-review-note.entity'; -import { Booking } from './entities/booking.entity'; -import { BookingContainerAllocation } from './entities/booking-container-allocation.entity'; -import { ContractPdfService } from '../../contracts/contract-pdf.service'; -import { ContractPricingScheduleBuilder } from '../../contracts/contract-pricing-schedule.builder'; -import { ContractRendererService } from '../../contracts/contract-renderer.service'; -import { ContractTemplateResolver } from '../../contracts/contract-template.resolver'; -import { ContractViewModelBuilder } from '../../contracts/contract-view-model.builder'; -import { TrainSchedulingModule } from '../train-scheduling/train-scheduling.module'; +import { CompaniesModule } from "../companies/companies.module"; +import { FilesModule } from "../files/files.module"; +import { MinioModule } from "../minio/minio.module"; +import { RuleEngineModule } from "../rule-engine/rule-engine.module"; +import { FileUploadSettingsModule } from "../file-upload-settings/file-upload-settings.module"; +import { SignaturesModule } from "../signatures/signatures.module"; +import { BillingModule } from "../billing/billing.module"; +import { FirstMileModule } from "../first-mile/first-mile.module"; +import { BookingContractService } from "./booking-contract.service"; +import { BookingInvoiceService } from "./booking-invoice.service"; +import { BookingPaymentController } from "./booking-payment.controller"; +import { BookingPaymentService } from "./booking-payment.service"; +import { BookingPricingService } from "./booking-pricing.service"; +import { BookingReferenceDataService } from "./booking-reference-data.service"; +import { BookingTransitionService } from "./booking-transition.service"; +import { BookingsController } from "./bookings.controller"; +import { PayController } from "./pay.controller"; +import { BookingsRepository } from "./bookings.repository"; +import { ConsolidationService } from "./consolidation.service"; +import { BookingsService } from "./bookings.service"; +import { BookingApprovalStep } from "./entities/booking-approval-step.entity"; +import { BookingCargoModifier } from "./entities/booking-cargo-modifier.entity"; +import { BookingDocumentReview } from "./entities/booking-document-review.entity"; +import { BookingContainer } from "./entities/booking-container.entity"; +import { BookingRateSnapshot } from "./entities/booking-rate-snapshot.entity"; +import { BookingContractSignature } from "./entities/booking-contract-signature.entity"; +import { BookingReviewNote } from "./entities/booking-review-note.entity"; +import { Booking } from "./entities/booking.entity"; +import { BookingContainerAllocation } from "./entities/booking-container-allocation.entity"; +import { ContractPdfService } from "../../contracts/contract-pdf.service"; +import { ContractPricingScheduleBuilder } from "../../contracts/contract-pricing-schedule.builder"; +import { ContractRendererService } from "../../contracts/contract-renderer.service"; +import { ContractTemplateResolver } from "../../contracts/contract-template.resolver"; +import { ContractViewModelBuilder } from "../../contracts/contract-view-model.builder"; +import { TrainSchedulingModule } from "../train-scheduling/train-scheduling.module"; @Module({ imports: [ @@ -66,7 +66,7 @@ import { TrainSchedulingModule } from '../train-scheduling/train-scheduling.modu ExchangeModule.forRootAsync({ inject: [ConfigService], useFactory: (config: ConfigService): ExchangeOptions => - config.get('app.cbeExchange') ?? {}, + config.get("app.cbeExchange") ?? {}, }), ], controllers: [BookingsController, PayController, BookingPaymentController], @@ -86,6 +86,11 @@ import { TrainSchedulingModule } from '../train-scheduling/train-scheduling.modu ContractRendererService, ContractPdfService, ], - exports: [BookingsService, BookingsRepository, BookingPricingService, BookingInvoiceService], + exports: [ + BookingsService, + BookingsRepository, + BookingPricingService, + BookingInvoiceService, + ], }) -export class BookingsModule {} +export class BookingsModule { }