mirror of
https://github.com/Tria-plc/edr-platform.git
synced 2026-08-26 18:42:49 +00:00
fix: an issue
This commit is contained in:
@@ -256,11 +256,15 @@ export class CompaniesService {
|
||||
},
|
||||
];
|
||||
|
||||
/** The nationality-based document setting code for a company. */
|
||||
private documentSettingCodeFor(
|
||||
nationality: CompanyNationality | null | undefined,
|
||||
): string {
|
||||
return nationality === CompanyNationality.Foreign
|
||||
/**
|
||||
* The document setting code for a company: one of three mutually exclusive
|
||||
* sets. A co-operative union or farm resolves to its own set regardless of
|
||||
* nationality — it holds no business licence, so it owes a different list of
|
||||
* papers rather than the nationality list plus extras.
|
||||
*/
|
||||
private documentSettingCodeFor(company: Company): string {
|
||||
if (isCooperative(company)) return COOPERATIVE_ONBOARDING_CODE;
|
||||
return company.nationality === CompanyNationality.Foreign
|
||||
? "company_onboarding_documents_foreign"
|
||||
: "company_onboarding_documents_ethiopian";
|
||||
}
|
||||
@@ -387,13 +391,16 @@ export class CompaniesService {
|
||||
const current = needsCompany
|
||||
? await this.companiesRepo.findById(companyId)
|
||||
: null;
|
||||
this.assertRolesAllowedForCooperative(
|
||||
cooperative ?? isCooperative(current),
|
||||
roles,
|
||||
);
|
||||
const isCoop = cooperative ?? isCooperative(current);
|
||||
this.assertRolesAllowedForCooperative(isCoop, roles);
|
||||
this.assertNationalityAllowedForCooperative(isCoop, nationality);
|
||||
await this.syncCompanyProfiles(companyId, companyType, roles);
|
||||
const updates: Partial<Company> = {};
|
||||
if (nationality) updates.nationality = nationality;
|
||||
// Ticking the box on a draft that was saved as foreign has to correct the
|
||||
// stored nationality too, or the company keeps resolving to the foreign
|
||||
// document set.
|
||||
if (isCoop) updates.nationality = CompanyNationality.Ethiopian;
|
||||
if (cooperative !== undefined) {
|
||||
updates.attributes = {
|
||||
...(current?.attributes ?? {}),
|
||||
@@ -407,6 +414,7 @@ export class CompaniesService {
|
||||
}
|
||||
|
||||
this.assertRolesAllowedForCooperative(cooperative === true, roles);
|
||||
this.assertNationalityAllowedForCooperative(cooperative === true, nationality);
|
||||
const allowedTypes = this.getProfileTypeForCompanyType(companyType);
|
||||
const chosenTypes = roles.filter((t) => allowedTypes.includes(t));
|
||||
|
||||
@@ -458,6 +466,24 @@ export class CompaniesService {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A co-operative union or farm is registered in Ethiopia by the co-operative
|
||||
* promotion agency, so it is always an Ethiopian company — "foreign" is not a
|
||||
* combination that exists, and allowing it would resolve the company to a
|
||||
* document set built around an investment licence it cannot hold.
|
||||
*/
|
||||
private assertNationalityAllowedForCooperative(
|
||||
cooperative: boolean,
|
||||
nationality: CompanyNationality | undefined,
|
||||
): void {
|
||||
if (!cooperative) return;
|
||||
if (nationality === CompanyNationality.Foreign) {
|
||||
throw new BadRequestException(
|
||||
"A co-operative union or farm is registered in Ethiopia — it cannot onboard as a foreign company.",
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reconcile the company's operational profiles with the roles the user has
|
||||
* selected: create the missing ones, drop the ones they deselected.
|
||||
@@ -1252,7 +1278,7 @@ export class CompaniesService {
|
||||
uploaded: FileRecord[],
|
||||
): Promise<CompanyRevisionChange[]> {
|
||||
const setting = await this.fileUploadSettingsService
|
||||
.getByCode(this.documentSettingCodeFor(company.nationality))
|
||||
.getByCode(this.documentSettingCodeFor(company))
|
||||
.catch(() => null);
|
||||
const fields = setting?.fields ?? [];
|
||||
const singleFileCodes = new Set(
|
||||
@@ -2036,35 +2062,20 @@ export class CompaniesService {
|
||||
.filter((f) => !f.get(company))
|
||||
.map((f) => ({ key: f.key, label: f.label }));
|
||||
|
||||
// 2. Nationality-based company documents + which are already uploaded. A
|
||||
// co-operative adds its own set on top: it provides everything its
|
||||
// nationality demands, plus the papers standing in for the business licence
|
||||
// it does not hold.
|
||||
// 2. Company documents + which are already uploaded. One set applies: the
|
||||
// company's nationality set, or the co-operative set in its place — a union
|
||||
// or farm holds no business licence, so it owes its own list rather than the
|
||||
// nationality list plus extras.
|
||||
const cooperative = isCooperative(company);
|
||||
const documentSettingCode = this.documentSettingCodeFor(
|
||||
company.nationality,
|
||||
);
|
||||
const [setting, coopSetting, uploadedFiles] = await Promise.all([
|
||||
const documentSettingCode = this.documentSettingCodeFor(company);
|
||||
const [setting, uploadedFiles] = await Promise.all([
|
||||
this.fileUploadSettingsService
|
||||
.getByCode(documentSettingCode)
|
||||
.catch(() => null),
|
||||
cooperative
|
||||
? this.fileUploadSettingsService
|
||||
.getByCode(COOPERATIVE_ONBOARDING_CODE)
|
||||
.catch(() => null)
|
||||
: Promise.resolve(null),
|
||||
this.filesService.findByResource(company.id, "companies"),
|
||||
]);
|
||||
const uploadedCodes = new Set(uploadedFiles.map((f) => f.code));
|
||||
// The co-op set is admin-managed and could name a fileKey the nationality
|
||||
// set already carries; the nationality field wins so the same slot is never
|
||||
// rendered (or required) twice.
|
||||
const baseFields = setting?.fields ?? [];
|
||||
const baseKeys = new Set(baseFields.map((f) => f.fileKey));
|
||||
const documents = [
|
||||
...baseFields,
|
||||
...(coopSetting?.fields ?? []).filter((f) => !baseKeys.has(f.fileKey)),
|
||||
]
|
||||
const documents = (setting?.fields ?? [])
|
||||
.slice()
|
||||
.sort((a, b) => a.displayOrder - b.displayOrder)
|
||||
.map((f) => ({
|
||||
@@ -2203,9 +2214,6 @@ export class CompaniesService {
|
||||
|
||||
return new OnboardingRequirementsResponseDto({
|
||||
documentSettingCode,
|
||||
cooperativeDocumentSettingCode: cooperative
|
||||
? COOPERATIVE_ONBOARDING_CODE
|
||||
: null,
|
||||
nationality: company.nationality ?? CompanyNationality.Ethiopian,
|
||||
cooperative,
|
||||
companyInfo: {
|
||||
|
||||
@@ -66,15 +66,11 @@ export interface OnboardingPoaState {
|
||||
}
|
||||
|
||||
export class OnboardingRequirementsResponseDto {
|
||||
/** Resolved document setting code (by nationality) the docs were drawn from. */
|
||||
documentSettingCode: string;
|
||||
/**
|
||||
* The co-operative document set, merged on top of the nationality one — null
|
||||
* for every other company. `documents` below already carries the merged
|
||||
* result; this is only so the portal can fetch the same extra fields when it
|
||||
* renders the pickers from the file-settings endpoint.
|
||||
* Resolved document setting code the docs were drawn from: the company's
|
||||
* nationality set, or the co-operative set in its place.
|
||||
*/
|
||||
cooperativeDocumentSettingCode: string | null;
|
||||
documentSettingCode: string;
|
||||
nationality: string;
|
||||
/**
|
||||
* The company trades as a co-operative: no business licence, so no eTrade
|
||||
@@ -118,7 +114,6 @@ export class OnboardingRequirementsResponseDto {
|
||||
|
||||
constructor(init: Omit<OnboardingRequirementsResponseDto, never>) {
|
||||
this.documentSettingCode = init.documentSettingCode;
|
||||
this.cooperativeDocumentSettingCode = init.cooperativeDocumentSettingCode;
|
||||
this.nationality = init.nationality;
|
||||
this.cooperative = init.cooperative;
|
||||
this.companyInfo = init.companyInfo;
|
||||
|
||||
@@ -17,7 +17,6 @@ import {
|
||||
} from "./interfaces/file-upload-settings.repository.interface";
|
||||
import {
|
||||
COMPANY_ONBOARDING_CODE_PREFIX,
|
||||
COOPERATIVE_ONBOARDING_CODE,
|
||||
POA_DELEGATION_FILE_KEY,
|
||||
poaDelegationField,
|
||||
} from "./poa-delegation.constants";
|
||||
@@ -57,10 +56,6 @@ export class FileUploadSettingsService {
|
||||
*/
|
||||
private withPoaDelegationField(setting: FileUploadSetting): FileUploadSetting {
|
||||
if (!setting.code.startsWith(COMPANY_ONBOARDING_CODE_PREFIX)) return setting;
|
||||
// The co-operative set is merged ON TOP of a nationality set that already
|
||||
// carries the paper; injecting it here too would hand the portal the same
|
||||
// slot twice.
|
||||
if (setting.code === COOPERATIVE_ONBOARDING_CODE) return setting;
|
||||
const fields = setting.fields ?? [];
|
||||
if (fields.some((f) => f.fileKey === POA_DELEGATION_FILE_KEY)) return setting;
|
||||
|
||||
|
||||
@@ -27,10 +27,11 @@ export const POA_DELEGATION_LABEL = "DARS Delegation Paper";
|
||||
export const COMPANY_ONBOARDING_CODE_PREFIX = "company_onboarding_documents_";
|
||||
|
||||
/**
|
||||
* The co-operative onboarding set. Unlike the nationality sets it is ADDITIVE —
|
||||
* merged on top of the company's `_ethiopian`/`_foreign` set rather than
|
||||
* replacing it — which is why the delegation paper is not injected into it: the
|
||||
* set it is merged onto already carries one.
|
||||
* The co-operative onboarding set — the third alternative to `_ethiopian` and
|
||||
* `_foreign`, not an addition to them: a union or farm resolves to this set
|
||||
* INSTEAD of its nationality's, because it holds no business licence and so
|
||||
* owes a different list of papers. The delegation paper is injected into it
|
||||
* like any other company onboarding set.
|
||||
*/
|
||||
export const COOPERATIVE_ONBOARDING_CODE = `${COMPANY_ONBOARDING_CODE_PREFIX}cooperative`;
|
||||
|
||||
|
||||
@@ -155,16 +155,27 @@ const FOREIGN_ONBOARDING_FIELDS: OnboardingField[] = [
|
||||
// ];
|
||||
|
||||
/**
|
||||
* Extra documents a co-operative union or farm provides, merged on top of its
|
||||
* nationality set. It has a TIN but no business licence, so the papers that
|
||||
* evidence the co-operative itself stand in for the trade licence every other
|
||||
* company uploads.
|
||||
* Documents required from a co-operative union or farm — the third alternative
|
||||
* to the two nationality sets, not an addition to them. A co-op is always
|
||||
* registered in Ethiopia and has a TIN but no business licence, so its
|
||||
* registration certificate stands in for the commercial registration every
|
||||
* other Ethiopian company uploads.
|
||||
*
|
||||
* Only the registration certificate is seeded, and the set is admin-managed
|
||||
* like every other onboarding set — what these members must actually produce
|
||||
* is a backoffice decision, edited in the file-settings editor.
|
||||
* Admin-managed like every other onboarding set: what these members must
|
||||
* actually produce is a backoffice decision, edited in the file-settings editor.
|
||||
*/
|
||||
const COOPERATIVE_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: 50,
|
||||
displayOrder: 1,
|
||||
},
|
||||
{
|
||||
fileKey: "cooperative_registration_certificate",
|
||||
fileLabel: "Co-operative Union / Farm Registration Certificate",
|
||||
@@ -175,8 +186,20 @@ const COOPERATIVE_ONBOARDING_FIELDS: OnboardingField[] = [
|
||||
maxFiles: 1,
|
||||
allowedExtensions: DOC_EXTENSIONS,
|
||||
maxSizeMb: 50,
|
||||
displayOrder: 1,
|
||||
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: 50,
|
||||
displayOrder: 3,
|
||||
},
|
||||
poaDelegationDefault(4),
|
||||
];
|
||||
|
||||
interface OnboardingDocumentSetting {
|
||||
@@ -201,11 +224,11 @@ const COMPANY_ONBOARDING_DOCUMENTS: OnboardingDocumentSetting[] = [
|
||||
entity: "customer",
|
||||
fields: FOREIGN_ONBOARDING_FIELDS,
|
||||
},
|
||||
// Additive, not a nationality of its own: a union or farm still uploads
|
||||
// everything its nationality set demands, and these on top.
|
||||
// The third set: a union or farm resolves here INSTEAD of a nationality set
|
||||
// (it is always Ethiopian, and holds no business licence).
|
||||
{
|
||||
code: "company_onboarding_documents_cooperative",
|
||||
label: "Co-operative union / farm onboarding documents (additional)",
|
||||
label: "Co-operative union / farm onboarding documents",
|
||||
entity: "customer",
|
||||
fields: COOPERATIVE_ONBOARDING_FIELDS,
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user