mirror of
https://github.com/Tria-plc/edr-platform.git
synced 2026-09-09 03:38:17 +00:00
94 lines
3.1 KiB
TypeScript
94 lines
3.1 KiB
TypeScript
import { Injectable, InternalServerErrorException } from "@nestjs/common";
|
|
import { InjectRepository } from "@nestjs/typeorm";
|
|
import { Repository } from "typeorm";
|
|
import { BaseRepository } from "@edr/api-common";
|
|
import { CompanyProfile, ProfileStatus, ProfileType } from "./entities/company-profile.entity";
|
|
|
|
const SEQUENCE_MAP: Record<ProfileType, string> = {
|
|
[ProfileType.exporter]: "seq_company_profile_ex",
|
|
[ProfileType.importer]: "seq_company_profile_im",
|
|
[ProfileType.freightForwarder]: "seq_company_profile_ffe",
|
|
[ProfileType.djFreightForwarder]: "seq_company_profile_fwj",
|
|
[ProfileType.transporter]: "seq_company_profile_tr",
|
|
};
|
|
|
|
const PREFIX_MAP: Record<ProfileType, string> = {
|
|
[ProfileType.exporter]: "EX",
|
|
[ProfileType.importer]: "IM",
|
|
[ProfileType.freightForwarder]: "FF",
|
|
[ProfileType.djFreightForwarder]: "FWJ",
|
|
[ProfileType.transporter]: "TR",
|
|
};
|
|
|
|
const SERIES_LETTERS = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
|
|
|
/** Numbers per series letter: A00001..A99999, then B00001. */
|
|
const SERIES_SIZE = 99_999;
|
|
|
|
@Injectable()
|
|
export class CompanyProfileRepository extends BaseRepository<CompanyProfile> {
|
|
constructor(
|
|
@InjectRepository(CompanyProfile)
|
|
repo: Repository<CompanyProfile>,
|
|
) {
|
|
super(repo);
|
|
}
|
|
|
|
async generateReference(type: ProfileType): Promise<string> {
|
|
// The sequences live in the same schema as the entity (e.g. "freight"), but
|
|
// the connection's search_path is "public" — so the sequence MUST be
|
|
// schema-qualified or `nextval` fails with "relation does not exist".
|
|
const schema = this.repository.metadata.schema ?? "public";
|
|
const seqName = `"${schema}".${SEQUENCE_MAP[type]}`;
|
|
const result = await this.repository.query(
|
|
`SELECT nextval('${seqName}') AS next_id`,
|
|
);
|
|
const nextId = Number(result[0].next_id);
|
|
const offset = nextId - 1;
|
|
const seriesIndex = Math.floor(offset / SERIES_SIZE);
|
|
|
|
if (seriesIndex >= SERIES_LETTERS.length) {
|
|
throw new InternalServerErrorException(
|
|
`Company profile reference series exhausted for type "${type}"`,
|
|
);
|
|
}
|
|
|
|
const letter = SERIES_LETTERS[seriesIndex];
|
|
const number = (offset % SERIES_SIZE) + 1;
|
|
const prefix = PREFIX_MAP[type];
|
|
return `${prefix}-${letter}${String(number).padStart(5, "0")}`;
|
|
}
|
|
|
|
async findByCompanyId(companyId: string): Promise<CompanyProfile[]> {
|
|
return this.repository.find({
|
|
where: { companyId },
|
|
relations: ["company"],
|
|
});
|
|
}
|
|
|
|
async findByType(
|
|
companyId: string,
|
|
type: ProfileType,
|
|
): Promise<CompanyProfile | null> {
|
|
return this.repository.findOne({
|
|
where: { companyId, type },
|
|
});
|
|
}
|
|
|
|
async findByReference(reference: string): Promise<CompanyProfile | null> {
|
|
return this.repository.findOne({ where: { reference } });
|
|
}
|
|
|
|
async findById(id: string): Promise<CompanyProfile | null> {
|
|
return this.repository.findOne({ where: { id } });
|
|
}
|
|
|
|
async updateStatus(
|
|
id: string,
|
|
status: ProfileStatus,
|
|
): Promise<CompanyProfile | null> {
|
|
await this.repository.update({ id }, { status });
|
|
return this.repository.findOne({ where: { id } });
|
|
}
|
|
}
|