mirror of
https://github.com/Tria-plc/edr-platform.git
synced 2026-08-26 18:42:49 +00:00
changes
This commit is contained in:
@@ -34,7 +34,7 @@ export class CreateServiceTypeDto {
|
||||
|
||||
@ApiPropertyOptional({
|
||||
default: false,
|
||||
description: 'Customs cleared on the Ethiopian side only — requires includesCustoms. Prices off the Ethiopian customs rate.',
|
||||
description: 'Customs cleared on the Ethiopian side only (alternative to full includesCustoms; implies it). Prices off the Ethiopian customs rate.',
|
||||
})
|
||||
@IsOptional()
|
||||
@IsBoolean()
|
||||
|
||||
@@ -28,9 +28,11 @@ export class ServiceType extends BaseEntity {
|
||||
includesCustoms!: boolean;
|
||||
|
||||
/**
|
||||
* EDR clears customs on the Ethiopian side only. Requires includesCustoms —
|
||||
* the clearance flow (GL review, duty) is identical; only the fee differs:
|
||||
* pricing looks up ETHIOPIAN_CUSTOMS_CLEARANCE instead of CUSTOMS_CLEARANCE.
|
||||
* EDR clears customs on the Ethiopian side only. The admin picks full customs
|
||||
* OR Ethiopian-only, never both; the API stores includesCustoms = true for
|
||||
* either so every clearance read (GL review, duty, docs) stays unchanged —
|
||||
* only the fee differs: pricing looks up ETHIOPIAN_CUSTOMS_CLEARANCE instead
|
||||
* of CUSTOMS_CLEARANCE.
|
||||
*/
|
||||
@Column({ name: 'includes_ethiopian_customs_only', type: 'boolean', default: false })
|
||||
includesEthiopianCustomsOnly!: boolean;
|
||||
|
||||
@@ -49,7 +49,10 @@ export class ServiceTypesService {
|
||||
const existing = await this.repository.findByCode(code);
|
||||
if (existing) throw new ConflictException(`Service type with name "${dto.serviceName}" conflicts with existing code "${code}"`);
|
||||
|
||||
this.assertCustomsFlags(dto.includesCustoms ?? false, dto.includesEthiopianCustomsOnly ?? false);
|
||||
const customs = this.resolveCustomsFlags(
|
||||
dto.includesCustoms ?? false,
|
||||
dto.includesEthiopianCustomsOnly ?? false,
|
||||
);
|
||||
const displayOrder = await this.displayOrder.resolveCreateOrder(ServiceType, 'displayOrder', {
|
||||
explicitOrder: dto.displayOrder,
|
||||
insertAfterId: dto.insertAfterId,
|
||||
@@ -62,8 +65,7 @@ export class ServiceTypesService {
|
||||
canBeBookedAlone: dto.canBeBookedAlone ?? true,
|
||||
includesFirstMile: dto.includesFirstMile ?? false,
|
||||
includesLastMile: dto.includesLastMile ?? false,
|
||||
includesCustoms: dto.includesCustoms ?? false,
|
||||
includesEthiopianCustomsOnly: dto.includesEthiopianCustomsOnly ?? false,
|
||||
...customs,
|
||||
isActive: dto.isActive ?? true,
|
||||
displayOrder,
|
||||
});
|
||||
@@ -72,23 +74,41 @@ export class ServiceTypesService {
|
||||
/** Update an existing service type. */
|
||||
async update(id: string, dto: UpdateServiceTypeDto): Promise<ServiceType> {
|
||||
const existing = await this.findById(id);
|
||||
this.assertCustomsFlags(
|
||||
dto.includesCustoms ?? existing.includesCustoms,
|
||||
dto.includesEthiopianCustomsOnly ?? existing.includesEthiopianCustomsOnly,
|
||||
);
|
||||
const { ...patch } = dto;
|
||||
const ethiopian = dto.includesEthiopianCustomsOnly ?? existing.includesEthiopianCustomsOnly;
|
||||
// The form sends both flags whenever either is touched; a payload with only
|
||||
// one is a plain edit (name, order…) that keeps the stored pair.
|
||||
const customs =
|
||||
dto.includesCustoms !== undefined || dto.includesEthiopianCustomsOnly !== undefined
|
||||
? this.resolveCustomsFlags(
|
||||
dto.includesCustoms ?? (existing.includesCustoms && !existing.includesEthiopianCustomsOnly),
|
||||
ethiopian,
|
||||
)
|
||||
: {};
|
||||
const patch = { ...dto, ...customs };
|
||||
const updated = await this.repository.update(id, patch);
|
||||
if (!updated) throw new NotFoundException(`Service type ${id} not found`);
|
||||
return updated;
|
||||
}
|
||||
|
||||
/** "Ethiopian customs only" narrows a customs service — it cannot stand alone. */
|
||||
private assertCustomsFlags(includesCustoms: boolean, ethiopianOnly: boolean): void {
|
||||
if (ethiopianOnly && !includesCustoms) {
|
||||
/**
|
||||
* Full customs and Ethiopian-only customs are alternatives: the admin picks
|
||||
* one. Ethiopian-only is still a customs service, so it is stored with
|
||||
* includesCustoms = true — every clearance read keeps working unchanged and
|
||||
* only pricing looks at the Ethiopian flag.
|
||||
*/
|
||||
private resolveCustomsFlags(
|
||||
includesCustoms: boolean,
|
||||
ethiopianOnly: boolean,
|
||||
): Pick<ServiceType, 'includesCustoms' | 'includesEthiopianCustomsOnly'> {
|
||||
if (includesCustoms && ethiopianOnly) {
|
||||
throw new BadRequestException(
|
||||
'"Ethiopian customs only" requires "Includes customs" to be enabled.',
|
||||
'Pick either "Includes customs" or "Ethiopian customs only", not both.',
|
||||
);
|
||||
}
|
||||
return {
|
||||
includesCustoms: includesCustoms || ethiopianOnly,
|
||||
includesEthiopianCustomsOnly: ethiopianOnly,
|
||||
};
|
||||
}
|
||||
|
||||
/** Soft-delete a service type. */
|
||||
|
||||
Reference in New Issue
Block a user