mirror of
https://github.com/Tria-plc/edr-platform.git
synced 2026-09-08 19:28:17 +00:00
fix(warehouse): scope the arrival GRN stamp to EXPORT only
The previous commit made autoUnloadArrived and unloadBooking raise a GRN for any direction, which changed import behaviour. Import keeps its own GRN handling (autoUnloadArrivedBookings) and is left exactly as it was. Both paths now stamp a GRN only when the booking is EXPORT — the direction whose cargo needs one to be loaded onto a train. Import and domestic behave as before. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1032,8 +1032,8 @@ export class WarehouseInventoryService {
|
|||||||
result.results.push({ bookingId: booking.id, status: 'FAILED', reason: 'No warehouse/yard/zone configured' });
|
result.results.push({ bookingId: booking.id, status: 'FAILED', reason: 'No warehouse/yard/zone configured' });
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
// Goods reaching the warehouse always get a GRN, whichever path brought
|
// EXPORT goods get their GRN on arrival at the warehouse — nothing loads
|
||||||
// them in — nothing loads onto a train without one.
|
// onto a train without one. Import GRN handling is left untouched.
|
||||||
const saved = await this.inventoryRepository.create({
|
const saved = await this.inventoryRepository.create({
|
||||||
warehouseId: location.warehouseId,
|
warehouseId: location.warehouseId,
|
||||||
yardId: location.yardId,
|
yardId: location.yardId,
|
||||||
@@ -1043,11 +1043,9 @@ export class WarehouseInventoryService {
|
|||||||
weight: Number(booking.weight) || 0,
|
weight: Number(booking.weight) || 0,
|
||||||
status: 'RECEIVED',
|
status: 'RECEIVED',
|
||||||
arrivedAt: new Date(),
|
arrivedAt: new Date(),
|
||||||
grnNumber: this.generateGrnNumber(
|
...(booking.tradeDirection === 'EXPORT'
|
||||||
booking.tradeDirection ?? 'WH',
|
? { grnNumber: this.generateGrnNumber('EXPORT', booking.id, new Date()) }
|
||||||
booking.id,
|
: {}),
|
||||||
new Date(),
|
|
||||||
),
|
|
||||||
notes: allocated?.rule ? `Auto-unloaded → ${allocated.path}` : 'Auto-unloaded from arrival queue',
|
notes: allocated?.rule ? `Auto-unloaded → ${allocated.path}` : 'Auto-unloaded from arrival queue',
|
||||||
});
|
});
|
||||||
result.processedCount += 1;
|
result.processedCount += 1;
|
||||||
@@ -1068,14 +1066,14 @@ export class WarehouseInventoryService {
|
|||||||
/** Unload a single arrived booking into a chosen (or default) location. */
|
/** Unload a single arrived booking into a chosen (or default) location. */
|
||||||
async unloadBooking(bookingId: string, dto: UnloadBookingDto): Promise<WarehouseInventory> {
|
async unloadBooking(bookingId: string, dto: UnloadBookingDto): Promise<WarehouseInventory> {
|
||||||
const existing = await this.inventoryRepository.findAll({ where: { bookingId } });
|
const existing = await this.inventoryRepository.findAll({ where: { bookingId } });
|
||||||
// Goods reaching the warehouse always get a GRN, whichever path brought them
|
// EXPORT goods get their GRN on arrival at the warehouse — nothing loads onto
|
||||||
// in — nothing loads onto a train without one.
|
// a train without one. Import GRN handling is left untouched.
|
||||||
const [bookingRow]: Array<{ tradeDirection: string | null }> = await this.dataSource.query(
|
const [bookingRow]: Array<{ tradeDirection: string | null }> = await this.dataSource.query(
|
||||||
`SELECT trade_direction AS "tradeDirection"
|
`SELECT trade_direction AS "tradeDirection"
|
||||||
FROM freight.bookings WHERE id = $1 AND deleted_at IS NULL`,
|
FROM freight.bookings WHERE id = $1 AND deleted_at IS NULL`,
|
||||||
[bookingId],
|
[bookingId],
|
||||||
);
|
);
|
||||||
const grnDirection = bookingRow?.tradeDirection ?? 'WH';
|
const isExport = bookingRow?.tradeDirection === 'EXPORT';
|
||||||
|
|
||||||
let location: DefaultLocation | null =
|
let location: DefaultLocation | null =
|
||||||
dto.warehouseId && dto.yardId && dto.zoneId
|
dto.warehouseId && dto.yardId && dto.zoneId
|
||||||
@@ -1096,10 +1094,10 @@ export class WarehouseInventoryService {
|
|||||||
zoneId: location.zoneId,
|
zoneId: location.zoneId,
|
||||||
status: 'RECEIVED',
|
status: 'RECEIVED',
|
||||||
arrivedAt,
|
arrivedAt,
|
||||||
// Keep an already-issued GRN; only raise one if this row never got it.
|
// Export only, and keep an already-issued GRN rather than reissuing.
|
||||||
...(existing[0].grnNumber
|
...(isExport && !existing[0].grnNumber
|
||||||
? {}
|
? { grnNumber: this.generateGrnNumber('EXPORT', bookingId, arrivedAt) }
|
||||||
: { grnNumber: this.generateGrnNumber(grnDirection, bookingId, arrivedAt) }),
|
: {}),
|
||||||
notes: dto.notes ?? existing[0].notes ?? 'Unloaded',
|
notes: dto.notes ?? existing[0].notes ?? 'Unloaded',
|
||||||
});
|
});
|
||||||
return this.findById(existing[0].id);
|
return this.findById(existing[0].id);
|
||||||
@@ -1114,7 +1112,9 @@ export class WarehouseInventoryService {
|
|||||||
weight: 0,
|
weight: 0,
|
||||||
status: 'RECEIVED',
|
status: 'RECEIVED',
|
||||||
arrivedAt,
|
arrivedAt,
|
||||||
grnNumber: this.generateGrnNumber(grnDirection, bookingId, arrivedAt),
|
...(isExport
|
||||||
|
? { grnNumber: this.generateGrnNumber('EXPORT', bookingId, arrivedAt) }
|
||||||
|
: {}),
|
||||||
notes: dto.notes ?? 'Unloaded',
|
notes: dto.notes ?? 'Unloaded',
|
||||||
});
|
});
|
||||||
return this.findById(saved.id);
|
return this.findById(saved.id);
|
||||||
|
|||||||
Reference in New Issue
Block a user