@accounter/shaam6111-generator
Version:
Fully typed application that generates, parses, and validates SHAAM 6111 tax reports.
95 lines (94 loc) • 4.1 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.reportSchema = void 0;
const zod_1 = require("zod");
const index_js_1 = require("../types/index.js");
const specific_code_validations_js_1 = require("../validation/specific-code-validations.js");
const header_schema_js_1 = require("./header-schema.js");
const index_js_2 = require("./index.js");
/**
* Zod schema for the full report
* Enforces strict validation based on the specification.
*/
exports.reportSchema = zod_1.z
.object({
header: header_schema_js_1.headerSchema,
profitAndLoss: index_js_2.profitLossArraySchema,
taxAdjustment: index_js_2.taxAdjustmentArraySchema,
balanceSheet: index_js_2.balanceSheetArraySchema.optional(),
individualOrCompany: zod_1.z.nativeEnum(index_js_1.IndividualOrCompanyEnum),
})
.superRefine((data, ctx) => {
// validate balance sheet exists for companies
if (data.individualOrCompany === index_js_1.IndividualOrCompanyEnum.COMPANY && !data.balanceSheet) {
ctx.addIssue({
code: zod_1.z.ZodIssueCode.custom,
message: 'Balance sheet is required for companies',
});
}
if (data.header.profitLossEntryCount !== data.profitAndLoss.length) {
ctx.addIssue({
code: zod_1.z.ZodIssueCode.custom,
message: 'Profit and Loss entry count does not match the number of records',
});
}
if (data.header.taxAdjustmentEntryCount !== data.taxAdjustment.length) {
ctx.addIssue({
code: zod_1.z.ZodIssueCode.custom,
message: 'Tax Adjustment entry count does not match the number of records',
});
}
if (data.header.balanceSheetEntryCount !== (data.balanceSheet?.length ?? 0)) {
ctx.addIssue({
code: zod_1.z.ZodIssueCode.custom,
message: 'Balance Sheet entry count does not match the number of records',
});
}
// validate rule 3.7 profitAndLoss code 6666 equals to taxAdjustment code 100
const code6666Amount = data.profitAndLoss.find(item => item.code === 6666)?.amount || 0;
const code100Amount = data.taxAdjustment.find(item => item.code === 100)?.amount || 0;
if (code6666Amount !== code100Amount) {
ctx.addIssue({
code: zod_1.z.ZodIssueCode.custom,
message: 'Profit and Loss code 6666 must equal Tax Adjustment code 100',
});
}
const validationAmounts = {
100: 0,
103: 0,
104: 0,
370: 0,
383: 0,
400: 0,
};
data.taxAdjustment.map(record => {
if (record.code in validationAmounts) {
validationAmounts[record.code] = record.amount;
}
});
const ifrsReportingOption = data.header.ifrsReportingOption;
// validate code 104 according to rule 2.6
if (!(0, specific_code_validations_js_1.validateCode104)(validationAmounts, ifrsReportingOption)) {
ctx.addIssue({
code: zod_1.z.ZodIssueCode.custom,
message: (0, specific_code_validations_js_1.code104Description)(ifrsReportingOption),
});
}
// validate code 400 according to rule 2.7
if (!(0, specific_code_validations_js_1.validateCode400)(validationAmounts, ifrsReportingOption)) {
ctx.addIssue({
code: zod_1.z.ZodIssueCode.custom,
message: (0, specific_code_validations_js_1.code400Description)(ifrsReportingOption),
});
}
// validate rule 3.8 profitAndLoss sum of codes 1450 & 2095 equals to balanceSheet code 7800
const code1450Amount = data.profitAndLoss.find(item => item.code === 1450)?.amount || 0;
const code2095Amount = data.profitAndLoss.find(item => item.code === 2095)?.amount || 0;
const balanceSheet7800Amount = data.balanceSheet?.find(item => item.code === 7800)?.amount || 0;
if (code1450Amount + code2095Amount !== balanceSheet7800Amount) {
ctx.addIssue({
code: zod_1.z.ZodIssueCode.custom,
message: 'Sum of Profit and Loss codes 1450 and 2095 must equal Balance Sheet code 7800',
});
}
});