mirror of
https://github.com/Tria-plc/edr-platform.git
synced 2026-08-30 09:58:12 +00:00
- Introduced a new step in the onboarding process to select company nationality (Ethiopian or Foreign). - Updated API and service layers to handle nationality data for companies. - Added support for uploading multiple business license files for each operational profile. - Refactored company and forwarder forms to include new license upload step. - Created a reusable RoleLicenseStep component for managing license file uploads. - Implemented utility functions for phone number handling. - Added migrations to update the database schema for nationality and business license files.
252 lines
7.1 KiB
TypeScript
252 lines
7.1 KiB
TypeScript
import { Injectable, Logger } from "@nestjs/common";
|
|
import { DataSource } from "typeorm";
|
|
|
|
import { FileUploadField } from "../modules/file-upload-settings/entities/file-upload-field.entity";
|
|
import { FileUploadSetting } from "../modules/file-upload-settings/entities/file-upload-setting.entity";
|
|
|
|
interface OnboardingField {
|
|
fileKey: string;
|
|
fileLabel: string;
|
|
helpText: string;
|
|
isRequired: boolean;
|
|
isMultiple: boolean;
|
|
maxFiles: number;
|
|
allowedExtensions: string[];
|
|
maxSizeMb: number;
|
|
displayOrder: number;
|
|
}
|
|
|
|
const DOC_EXTENSIONS = ["pdf", "jpg", "jpeg", "png"];
|
|
|
|
/** Documents required from an Ethiopian company at onboarding. */
|
|
const ETHIOPIAN_ONBOARDING_FIELDS: OnboardingField[] = [
|
|
{
|
|
fileKey: "tin_certificate",
|
|
fileLabel: "TIN Certificate",
|
|
helpText: "Verified against the TIN registry during registration.",
|
|
isRequired: true,
|
|
isMultiple: false,
|
|
maxFiles: 1,
|
|
allowedExtensions: DOC_EXTENSIONS,
|
|
maxSizeMb: 10,
|
|
displayOrder: 1,
|
|
},
|
|
{
|
|
fileKey: "commercial_license",
|
|
fileLabel: "Commercial License",
|
|
helpText: "Verified against the government trade system during registration.",
|
|
isRequired: true,
|
|
isMultiple: false,
|
|
maxFiles: 1,
|
|
allowedExtensions: DOC_EXTENSIONS,
|
|
maxSizeMb: 10,
|
|
displayOrder: 2,
|
|
},
|
|
{
|
|
fileKey: "national_id",
|
|
fileLabel: "National ID",
|
|
helpText: "Verified against the National ID API during registration.",
|
|
isRequired: true,
|
|
isMultiple: false,
|
|
maxFiles: 1,
|
|
allowedExtensions: DOC_EXTENSIONS,
|
|
maxSizeMb: 10,
|
|
displayOrder: 3,
|
|
},
|
|
];
|
|
|
|
/** Documents required from a Foreign company at onboarding. */
|
|
const FOREIGN_ONBOARDING_FIELDS: OnboardingField[] = [
|
|
{
|
|
fileKey: "tin_certificate",
|
|
fileLabel: "TIN Certificate",
|
|
helpText: "Verified against the TIN registry during registration.",
|
|
isRequired: true,
|
|
isMultiple: false,
|
|
maxFiles: 1,
|
|
allowedExtensions: DOC_EXTENSIONS,
|
|
maxSizeMb: 10,
|
|
displayOrder: 1,
|
|
},
|
|
{
|
|
fileKey: "investment_license",
|
|
fileLabel: "Investment License",
|
|
helpText: "Investment license issued for operating in Ethiopia.",
|
|
isRequired: true,
|
|
isMultiple: false,
|
|
maxFiles: 1,
|
|
allowedExtensions: DOC_EXTENSIONS,
|
|
maxSizeMb: 10,
|
|
displayOrder: 2,
|
|
},
|
|
{
|
|
fileKey: "national_id",
|
|
fileLabel: "National ID",
|
|
helpText: "National ID of the company's authorized representative.",
|
|
isRequired: true,
|
|
isMultiple: false,
|
|
maxFiles: 1,
|
|
allowedExtensions: DOC_EXTENSIONS,
|
|
maxSizeMb: 10,
|
|
displayOrder: 3,
|
|
},
|
|
{
|
|
fileKey: "passport",
|
|
fileLabel: "Passport",
|
|
helpText: "Passport of the company's authorized representative.",
|
|
isRequired: true,
|
|
isMultiple: false,
|
|
maxFiles: 1,
|
|
allowedExtensions: DOC_EXTENSIONS,
|
|
maxSizeMb: 10,
|
|
displayOrder: 4,
|
|
},
|
|
];
|
|
|
|
/** Legacy combined set, kept for the older per-company-type codes. */
|
|
const LEGACY_ONBOARDING_FIELDS: OnboardingField[] = [
|
|
{
|
|
fileKey: "business_license",
|
|
fileLabel: "Business License / Trade License",
|
|
helpText: "Verified against the government trade system during registration.",
|
|
isRequired: true,
|
|
isMultiple: false,
|
|
maxFiles: 1,
|
|
allowedExtensions: DOC_EXTENSIONS,
|
|
maxSizeMb: 10,
|
|
displayOrder: 1,
|
|
},
|
|
{
|
|
fileKey: "tin_certificate",
|
|
fileLabel: "TIN Certificate",
|
|
helpText: "Verified against the TIN registry during registration.",
|
|
isRequired: true,
|
|
isMultiple: false,
|
|
maxFiles: 1,
|
|
allowedExtensions: DOC_EXTENSIONS,
|
|
maxSizeMb: 10,
|
|
displayOrder: 2,
|
|
},
|
|
{
|
|
fileKey: "national_id_passport",
|
|
fileLabel: "National ID / Passport",
|
|
helpText: "Verified against the National ID API during registration.",
|
|
isRequired: true,
|
|
isMultiple: false,
|
|
maxFiles: 1,
|
|
allowedExtensions: DOC_EXTENSIONS,
|
|
maxSizeMb: 10,
|
|
displayOrder: 3,
|
|
},
|
|
];
|
|
|
|
interface OnboardingDocumentSetting {
|
|
code: string;
|
|
label: string;
|
|
entity: string;
|
|
fields: OnboardingField[];
|
|
}
|
|
|
|
const COMPANY_ONBOARDING_DOCUMENTS: OnboardingDocumentSetting[] = [
|
|
// Nationality-based sets — the document requirements depend only on whether
|
|
// the company is Ethiopian or Foreign (same for importer/exporter/forwarder).
|
|
{
|
|
code: "company_onboarding_documents_ethiopian",
|
|
label: "Ethiopian company onboarding documents",
|
|
entity: "customer",
|
|
fields: ETHIOPIAN_ONBOARDING_FIELDS,
|
|
},
|
|
{
|
|
code: "company_onboarding_documents_foreign",
|
|
label: "Foreign company onboarding documents",
|
|
entity: "customer",
|
|
fields: FOREIGN_ONBOARDING_FIELDS,
|
|
},
|
|
// Legacy per-company-type codes (kept for back-compat; no longer used by the portal).
|
|
{
|
|
code: "company_onboarding_documents_customer",
|
|
label: "Customer onboarding documents",
|
|
entity: "customer",
|
|
fields: LEGACY_ONBOARDING_FIELDS,
|
|
},
|
|
{
|
|
code: "company_onboarding_documents_forwarder",
|
|
label: "Forwarder onboarding documents",
|
|
entity: "other",
|
|
fields: LEGACY_ONBOARDING_FIELDS,
|
|
},
|
|
{
|
|
code: "company_onboarding_documents_transporter",
|
|
label: "Transporter onboarding documents",
|
|
entity: "other",
|
|
fields: LEGACY_ONBOARDING_FIELDS,
|
|
},
|
|
{
|
|
code: "company_onboarding_documents_forwarder_dj",
|
|
label: "Djibouti forwarder onboarding documents",
|
|
entity: "other",
|
|
fields: LEGACY_ONBOARDING_FIELDS,
|
|
},
|
|
];
|
|
|
|
const COMPANY_ONBOARDING_DESCRIPTION =
|
|
"Required documents for external company onboarding, by company nationality.";
|
|
|
|
@Injectable()
|
|
export class FileUploadSettingsSeeder {
|
|
private readonly logger = new Logger(FileUploadSettingsSeeder.name);
|
|
|
|
constructor(private readonly dataSource: DataSource) {}
|
|
|
|
async run() {
|
|
await this.dataSource.transaction(async (manager) => {
|
|
const settingRepository = manager.getRepository(FileUploadSetting);
|
|
const fieldRepository = manager.getRepository(FileUploadField);
|
|
|
|
for (const documentSetting of COMPANY_ONBOARDING_DOCUMENTS) {
|
|
await settingRepository.upsert(
|
|
{
|
|
code: documentSetting.code,
|
|
label: documentSetting.label,
|
|
description: COMPANY_ONBOARDING_DESCRIPTION,
|
|
entity: documentSetting.entity,
|
|
},
|
|
{
|
|
conflictPaths: { code: true },
|
|
},
|
|
);
|
|
|
|
const setting = await settingRepository.findOne({
|
|
where: { code: documentSetting.code },
|
|
select: { id: true, code: true },
|
|
});
|
|
|
|
if (!setting) {
|
|
throw new Error(`file_upload_setting_seed_failed:${documentSetting.code}`);
|
|
}
|
|
|
|
await fieldRepository.delete({ settingId: setting.id });
|
|
|
|
await fieldRepository.insert(
|
|
documentSetting.fields.map((field, index) => ({
|
|
settingId: setting.id,
|
|
fileKey: field.fileKey,
|
|
fileLabel: field.fileLabel,
|
|
helpText: field.helpText,
|
|
isRequired: field.isRequired,
|
|
isMultiple: field.isMultiple,
|
|
maxFiles: field.maxFiles,
|
|
allowedExtensions: [...field.allowedExtensions],
|
|
maxSizeMb: field.maxSizeMb,
|
|
displayOrder: field.displayOrder ?? index + 1,
|
|
})),
|
|
);
|
|
}
|
|
});
|
|
|
|
this.logger.log(
|
|
"Ensured company onboarding file upload settings for external companies",
|
|
);
|
|
}
|
|
}
|