mirror of
https://github.com/Tria-plc/edr-platform.git
synced 2026-08-28 05:30:55 +00:00
Bulk contract templates are now unique per (cargo type, trade direction, customs option) instead of (cargo type, customs option). Intercity is domestic and crosses no border, so it carries no customs variant: with_customs stays null there, enforced by a check constraint. Contract resolution already passed the trade direction through but the bulk lookup dropped it, so one template served all three directions. Container templates are unchanged — cargo_type_id is null on those rows, which keeps them out of both the new index and the constraint. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
146 lines
4.3 KiB
TypeScript
146 lines
4.3 KiB
TypeScript
import {
|
|
Body,
|
|
Controller,
|
|
Delete,
|
|
Get,
|
|
HttpCode,
|
|
HttpStatus,
|
|
Param,
|
|
Patch,
|
|
Post,
|
|
Put,
|
|
} from "@nestjs/common";
|
|
import { ApiOperation, ApiTags } from "@nestjs/swagger";
|
|
|
|
import { BookingStaff } from "../../common/booking-guards";
|
|
import { FREIGHT_PERMS } from "../../seed/freight-permissions.registry";
|
|
import { ContractTemplatesService } from "./contract-templates.service";
|
|
import {
|
|
CreateArticleDto,
|
|
CreateContractTemplateDto,
|
|
PreviewContractTemplateDto,
|
|
ReplaceArticlesDto,
|
|
UpdateArticleDto,
|
|
UpdateContractTemplateDto,
|
|
} from "./dto/contract-template.dto";
|
|
|
|
// `view` opens the Templates page; `read` is API-read-only for other pages
|
|
// that show template data; create/update/delete gate each write. `manage` is
|
|
// the legacy write key and keeps working for roles that already hold it.
|
|
const TEMPLATE_READ = [
|
|
FREIGHT_PERMS.settings.contractTemplates.view,
|
|
FREIGHT_PERMS.settings.contractTemplates.read,
|
|
FREIGHT_PERMS.settings.contractTemplates.update,
|
|
FREIGHT_PERMS.settings.contractTemplates.manage,
|
|
FREIGHT_PERMS.admin,
|
|
];
|
|
|
|
const TEMPLATE_UPDATE = [
|
|
FREIGHT_PERMS.settings.contractTemplates.update,
|
|
FREIGHT_PERMS.settings.contractTemplates.manage,
|
|
FREIGHT_PERMS.admin,
|
|
];
|
|
|
|
@ApiTags("contract-templates")
|
|
@Controller("contract-templates")
|
|
export class ContractTemplatesController {
|
|
constructor(private readonly service: ContractTemplatesService) {}
|
|
|
|
@Get()
|
|
@BookingStaff(TEMPLATE_READ)
|
|
@ApiOperation({ summary: "List contract templates (system container + staff-created bulk)" })
|
|
list() {
|
|
return this.service.list();
|
|
}
|
|
|
|
@Post()
|
|
@BookingStaff([
|
|
FREIGHT_PERMS.settings.contractTemplates.create,
|
|
FREIGHT_PERMS.settings.contractTemplates.manage,
|
|
FREIGHT_PERMS.admin,
|
|
])
|
|
@ApiOperation({
|
|
summary:
|
|
"Create a bulk contract template for a (cargo type, trade direction, customs option) combination",
|
|
})
|
|
create(@Body() dto: CreateContractTemplateDto) {
|
|
return this.service.create(dto);
|
|
}
|
|
|
|
@Get(":code")
|
|
@BookingStaff(TEMPLATE_READ)
|
|
@ApiOperation({ summary: "Get one contract template by code" })
|
|
getByCode(@Param("code") code: string) {
|
|
return this.service.getByCode(code);
|
|
}
|
|
|
|
@Patch(":code")
|
|
@BookingStaff(TEMPLATE_UPDATE)
|
|
@ApiOperation({ summary: "Update template metadata (name, title, recitals, active flag)" })
|
|
update(@Param("code") code: string, @Body() dto: UpdateContractTemplateDto) {
|
|
return this.service.update(code, dto);
|
|
}
|
|
|
|
@Delete(":code")
|
|
@BookingStaff([
|
|
FREIGHT_PERMS.settings.contractTemplates.delete,
|
|
FREIGHT_PERMS.admin,
|
|
])
|
|
@HttpCode(HttpStatus.NO_CONTENT)
|
|
@ApiOperation({
|
|
summary: "Delete a staff-created bulk template (system templates refuse)",
|
|
})
|
|
remove(@Param("code") code: string) {
|
|
return this.service.remove(code);
|
|
}
|
|
|
|
@Post(":code/preview")
|
|
@BookingStaff(TEMPLATE_READ)
|
|
@ApiOperation({
|
|
summary: "Render an HTML preview of the template against mock contract data",
|
|
})
|
|
preview(
|
|
@Param("code") code: string,
|
|
@Body() dto: PreviewContractTemplateDto,
|
|
) {
|
|
return this.service.preview(code, dto);
|
|
}
|
|
|
|
/* ------------------------- article routes ------------------------- */
|
|
|
|
@Put(":code/articles")
|
|
@BookingStaff(TEMPLATE_UPDATE)
|
|
@ApiOperation({ summary: "Replace the full ordered article list (used for reorder)" })
|
|
replaceArticles(@Param("code") code: string, @Body() dto: ReplaceArticlesDto) {
|
|
return this.service.replaceArticles(code, dto.articles);
|
|
}
|
|
|
|
@Post(":code/articles")
|
|
@BookingStaff(TEMPLATE_UPDATE)
|
|
@ApiOperation({ summary: "Add an article to the template" })
|
|
addArticle(@Param("code") code: string, @Body() dto: CreateArticleDto) {
|
|
return this.service.addArticle(code, dto);
|
|
}
|
|
|
|
@Patch(":code/articles/:articleId")
|
|
@BookingStaff(TEMPLATE_UPDATE)
|
|
@ApiOperation({ summary: "Update an article's title or body" })
|
|
updateArticle(
|
|
@Param("code") code: string,
|
|
@Param("articleId") articleId: string,
|
|
@Body() dto: UpdateArticleDto,
|
|
) {
|
|
return this.service.updateArticle(code, articleId, dto);
|
|
}
|
|
|
|
@Delete(":code/articles/:articleId")
|
|
@BookingStaff(TEMPLATE_UPDATE)
|
|
@ApiOperation({ summary: "Remove an article from the template" })
|
|
removeArticle(
|
|
@Param("code") code: string,
|
|
@Param("articleId") articleId: string,
|
|
) {
|
|
return this.service.removeArticle(code, articleId);
|
|
}
|
|
}
|