enhance contract and train scheduling features

- Added pricing service integration to ContractsService for pre-persistence contract pricing.
- Updated LegCapacityPanel to display cargo weight instead of gross weight for better clarity on booked cargo.
- Enhanced train scheduling service to include cargo weight in booking details.
- Modified ClearanceDocumentsPage to include FULLY_EXECUTED status in booking status options.
- Refactored FileUploadSettingsPage to categorize file upload settings into tabs for better organization.
- Removed legacy onboarding fields and settings from file upload settings seeder.
- Improved type definitions for train scheduling to include cargo weight without wagon tare.
This commit is contained in:
Marshal
2026-08-01 05:37:46 +00:00
parent 6a4067ec42
commit a8788eb549
12 changed files with 511 additions and 463 deletions

View File

@@ -28,6 +28,7 @@ import { ContractCargoScope } from './entities/contract-cargo-scope.entity';
import { isEffectivelyExpired } from './utils/contract-expiry.util';
import { diffContractFields } from './contract-document-diff.util';
import { ContractDocumentHistoryService } from './contract-document-history.service';
import { ContractPricingService } from './contract-pricing.service';
import { FileRecord } from '../files/entities/file.entity';
/** Paginated contract list: flat `total` (backoffice) + `meta` block (portal). */
@@ -113,6 +114,7 @@ export class ContractsService {
private readonly filesService: FilesService,
private readonly minioService: MinioService,
private readonly documentHistory: ContractDocumentHistoryService,
private readonly pricingService: ContractPricingService,
) {}
/** Generate a unique contract reference number (CTR-YYYY-NNNNN). */
@@ -331,6 +333,33 @@ export class ContractsService {
);
}
// Price the contract BEFORE anything persists: a lane with no configured
// rate 422s here and the wizard shows its blocking modal — with no orphan
// DRAFT row left behind for the customer to trip over on retry. The probe
// carries exactly the fields buildBreakdown prices from; relation-only
// niceties (cargoType labels) are absent, which only affects display
// lines, never the missing-rate gates.
await this.pricingService.buildBreakdown({
tradeDirection: dto.tradeDirection,
freightType: dto.freightType,
paymentCurrency: 'USD',
customsClearingEnabled: includesCustoms,
isHazardous: dto.isHazardous ?? false,
isReefer: dto.isReefer ?? false,
equipmentReturn: dto.equipmentReturn ?? null,
firstMilePickupAddress: dto.firstMilePickupAddress ?? null,
lastMileDeliveryAddress: dto.lastMileDeliveryAddress ?? null,
routes: (dto.routes ?? []).map((r, i) => ({
originYardId: r.originYardId,
destinationYardId: r.destinationYardId,
sortOrder: r.sortOrder ?? i,
})),
cargoScope: (dto.cargoScope ?? []).map((c) => ({
containerSize: c.containerSize ?? null,
cargoTypeId: c.cargoTypeId ?? null,
})),
} as unknown as Contract);
// An explicit reference is caller-chosen — a collision there is a real
// conflict and should surface. Auto-generated references retry past a
// concurrent insert that grabbed the same sequence number.