mirror of
https://github.com/Tria-plc/edr-platform.git
synced 2026-08-29 02:30:55 +00:00
fix issue
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
import { Injectable, NotFoundException, ConflictException } from '@nestjs/common';
|
||||
import { Injectable, NotFoundException, ConflictException, BadRequestException } from '@nestjs/common';
|
||||
import { InjectRepository } from '@nestjs/typeorm';
|
||||
import { FindOptionsOrder, FindOptionsWhere, ILike, Repository } from 'typeorm';
|
||||
import { FindOptionsOrder, FindOptionsWhere, ILike, Not, Repository } from 'typeorm';
|
||||
import { CreateCargoDto } from './dto/create-cargo.dto';
|
||||
import { UpdateCargoDto } from './dto/update-cargo.dto';
|
||||
import { LoadCargoDto } from './dto/load-cargo.dto';
|
||||
@@ -32,6 +32,7 @@ export class CargoesService {
|
||||
if (!container) {
|
||||
throw new NotFoundException(`Container ${dto.containerId} not found`);
|
||||
}
|
||||
await this.assertContainerCapacity(container, dto.weight);
|
||||
|
||||
if (dto.cargoTypeId) {
|
||||
const cargoType = await this.cargoTypeRepo.findOne({
|
||||
@@ -121,6 +122,10 @@ export class CargoesService {
|
||||
throw new ConflictException('Cargo already loaded or delivered');
|
||||
}
|
||||
|
||||
if (cargo.container) {
|
||||
await this.assertContainerCapacity(cargo.container, dto.weight, cargo.id);
|
||||
}
|
||||
|
||||
cargo.status = 'LOADED';
|
||||
cargo.loadedAt = new Date();
|
||||
cargo.quantity = dto.quantity;
|
||||
@@ -137,13 +142,31 @@ export class CargoesService {
|
||||
}
|
||||
|
||||
async unloadCargo(id: string): Promise<Cargo> {
|
||||
const cargo = await this.findById(id);
|
||||
const cargo = await this.cargoRepo.findOne({
|
||||
where: { id },
|
||||
relations: { container: true },
|
||||
});
|
||||
if (!cargo) throw new NotFoundException('Cargo not found');
|
||||
if (cargo.status !== 'LOADED') {
|
||||
throw new ConflictException('Cargo is not loaded');
|
||||
}
|
||||
cargo.status = 'UNLOADED';
|
||||
cargo.unloadedAt = new Date();
|
||||
return this.cargoRepo.save(cargo);
|
||||
const saved = await this.cargoRepo.save(cargo);
|
||||
|
||||
// loadCargo flips the container to LOADED; on unload, free it back to
|
||||
// AVAILABLE once no other LOADED cargo still references the container.
|
||||
if (cargo.containerId != null && cargo.container) {
|
||||
const remaining = await this.cargoRepo.count({
|
||||
where: { containerId: cargo.containerId, status: 'LOADED', id: Not(cargo.id) },
|
||||
});
|
||||
if (remaining === 0) {
|
||||
cargo.container.status = 'AVAILABLE';
|
||||
await this.containerRepo.save(cargo.container);
|
||||
}
|
||||
}
|
||||
|
||||
return saved;
|
||||
}
|
||||
|
||||
async deliverCargo(id: string, dto?: DeliverCargoDto): Promise<Cargo> {
|
||||
@@ -161,10 +184,13 @@ export class CargoesService {
|
||||
if (dto?.receiverName) cargo.receiverName = dto.receiverName;
|
||||
if (dto?.deliveryRemarks) cargo.deliveryRemarks = dto.deliveryRemarks;
|
||||
|
||||
// Exclude the cargo being delivered — it is still LOADED in the DB until the
|
||||
// save below, so counting it would keep `remaining` > 0 and never free the
|
||||
// container.
|
||||
const remaining =
|
||||
cargo.containerId != null
|
||||
? await this.cargoRepo.count({
|
||||
where: { containerId: cargo.containerId, status: 'LOADED' },
|
||||
where: { containerId: cargo.containerId, status: 'LOADED', id: Not(cargo.id) },
|
||||
})
|
||||
: 0;
|
||||
if (remaining === 0 && cargo.container) {
|
||||
@@ -174,4 +200,34 @@ export class CargoesService {
|
||||
|
||||
return this.cargoRepo.save(cargo);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reject when placing `newWeightKg` on the container would exceed its max gross
|
||||
* weight. All values are kilograms: cargoes.weight is kg (entity), and the
|
||||
* container's tare_weight / max_gross_weight are kg (entity). Capacity check is
|
||||
* tare + already-LOADED cargo + new cargo <= max gross weight.
|
||||
*/
|
||||
private async assertContainerCapacity(
|
||||
container: Container,
|
||||
newWeightKg: number,
|
||||
excludeCargoId?: string,
|
||||
): Promise<void> {
|
||||
const qb = this.cargoRepo
|
||||
.createQueryBuilder('c')
|
||||
.select('COALESCE(SUM(c.weight), 0)', 'sum')
|
||||
.where('c.containerId = :containerId', { containerId: container.id })
|
||||
.andWhere('c.status = :status', { status: 'LOADED' });
|
||||
if (excludeCargoId) qb.andWhere('c.id != :excludeCargoId', { excludeCargoId });
|
||||
const raw = await qb.getRawOne<{ sum: string }>();
|
||||
|
||||
const loadedKg = Number(raw?.sum ?? 0);
|
||||
const tareKg = Number(container.tareWeight);
|
||||
const maxGrossKg = Number(container.maxGrossWeight);
|
||||
if (tareKg + loadedKg + newWeightKg > maxGrossKg) {
|
||||
throw new BadRequestException(
|
||||
`Cargo weight exceeds container capacity: tare ${tareKg}kg + loaded ${loadedKg}kg + ` +
|
||||
`new ${newWeightKg}kg > max gross ${maxGrossKg}kg`,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user