fix(rates): render stored rate currency, default last mile to birr

The rate matrix currency cell hardcoded USD, so a last-mile rate
priced in ETB still displayed as dollars. formatCell now takes the
row and reads its currency code, falling back to USD.

Last-mile currency select gets defaultValue ETB (new generic
FormFieldDef.defaultValue for create-time pre-selection) and lists
ETB (Birr) first; USD stays selectable. Backend already persisted
and validated the chosen currency.
This commit is contained in:
Hagernesh
2026-08-06 08:01:52 +00:00
parent b4ac92e14e
commit 69f6fd36a9
7 changed files with 39 additions and 7 deletions

View File

@@ -460,8 +460,21 @@ export class LastMileService {
@OnEvent("last_mile.invoice.paid")
async onBookingInvoicePaid(payload: InvoiceEventPayload): Promise<void> {
try {
// Invoice paid → the delivery is complete. Route through update() so it
// also frees the trucks + records history (same as "Mark Delivered").
if (payload.type === 'LAST_MILE_ADVANCE') {
// Advance paid → the leg becomes dispatchable, not delivered.
await this.update(payload.sourceId, {
status: 'READY_TO_TRANSIT',
advancedPayment: payload.totalAmount,
} as unknown as UpdateLastMileDto);
this.logger.log(
`Last-mile ${payload.sourceId} READY_TO_TRANSIT on advance invoice ${payload.invoiceId} payment`,
);
return;
}
if (payload.type !== 'DELIVERY_FEE') return;
// Delivery-fee invoice paid → the delivery is complete. Route through
// update() so it also frees the trucks + records history (same as
// "Mark Delivered").
await this.update(payload.sourceId, { status: 'DELIVERED', paid: true } as unknown as UpdateLastMileDto);
this.logger.log(`Last-mile ${payload.sourceId} marked DELIVERED on invoice ${payload.invoiceId} payment`);
} catch (err) {

View File

@@ -43,6 +43,12 @@ export class YardsRepository implements IYardsRepository {
findPaged(query: ListYardsQueryDto): Promise<PaginatedResponse<Yard>> {
const qb = this.repo
.createQueryBuilder('yard')
// createQueryBuilder does NOT auto-apply the soft-delete filter that
// repo.find()/findOne() get for free — without this, a renamed/replaced
// yard (e.g. an old "DMP" superseded by a new one) still shows up
// alongside the live one in every picker built off this endpoint, and a
// route picked against the dead yard id never matches any LIVE rate.
.where('yard.deleted_at IS NULL')
.orderBy(`yard.${query.sortBy ?? 'displayOrder'}`, query.sortOrder ?? 'ASC')
.addOrderBy('yard.label', 'ASC');