add company stamp upload functionality for contract signing

- Introduced StampUpload component for uploading company stamp images.
- Integrated stamp upload in contract signing modal, supporting PNG and JPG formats.
- Implemented validation for file type and size (max 5 MB).
- Added visual feedback for drag-and-drop functionality.
- Updated contract-related pages to handle duplicate contract alerts and pricing notices.
- Enhanced contract expiry management with a nightly sweep service.
- Added unit tests for new features and updated existing tests for contract handling.
This commit is contained in:
Marshal
2026-07-25 17:14:58 +00:00
parent 54b5882355
commit fde5e6de4b
68 changed files with 1858 additions and 289 deletions

View File

@@ -35,6 +35,8 @@ function toContractUnit(rateUnit: string): ContractUnitRateLineItem['unit'] {
switch (rateUnit) {
case 'PER_TON':
return 'per_ton';
case 'PER_ITEM':
return 'per_item';
case 'PER_KM':
return 'per_km';
case 'PER_WAGON':
@@ -115,9 +117,19 @@ export class ContractPricingService {
});
}
} else {
const bulkRate =
liveRates.find((r) => r.rateType === baseType && r.currency === 'USD') ?? null;
const cargoScope = (contract.cargoScope ?? []).find((c) => c.cargoTypeId);
// Freeze the rate for the contract's own commodity when one is configured
// — a per-item machinery rate and a per-ton wheat rate live side by side.
const bulkRates = liveRates.filter(
(r) => r.rateType === baseType && r.currency === 'USD',
);
const bulkRate =
(cargoScope?.cargoTypeId
? bulkRates.find((r) => r.cargoTypeId === cargoScope.cargoTypeId)
: undefined) ??
bulkRates.find((r) => !r.cargoTypeId) ??
bulkRates[0] ??
null;
if (bulkRate) {
lineItems.push({
code: 'BULK_FREIGHT',