@accounter/shaam-uniform-format-generator
Version:
Fully typed application that generates, parses, and validates SHAAM uniform format tax reports (INI.TXT and BKMVDATA.TXT).
95 lines (94 loc) • 4.25 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.Z900InputSchema = exports.Z900Schema = void 0;
exports.encodeZ900 = encodeZ900;
exports.parseZ900 = parseZ900;
const zod_1 = require("zod");
const constants_js_1 = require("../../constants.js");
const index_js_1 = require("../../format/index.js");
const key_generator_js_1 = require("../../utils/key-generator.js");
const encoder_js_1 = require("../format/encoder.js");
/**
* Z900 Record Schema - Closing record
* Fields 1150-1156 based on SHAAM 1.31 specification
*/
exports.Z900Schema = zod_1.z.object({
code: zod_1.z.literal('Z900').describe('Record type code - always "Z900"'),
recordNumber: zod_1.z.number().int().min(1).max(999_999_999).describe('Sequential record number'),
vatId: zod_1.z.string().min(1).max(9).describe('VAT identification number - numeric field'),
uniqueId: zod_1.z.number().int().min(1).max(999_999_999_999_999).describe('Unique business identifier'),
totalRecords: zod_1.z
.number()
.int()
.min(1)
.max(999_999_999_999_999)
.describe('Total number of records in file'),
reserved: zod_1.z.string().max(50).default('').describe('Reserved field for future use'),
});
/**
* Z900 Input Schema - for user input (excludes auto-generated fields)
* Field 1153 (uniqueId) is automatically generated to match field 1103
*/
exports.Z900InputSchema = exports.Z900Schema.omit({
uniqueId: true,
code: true,
});
/**
* Encodes a Z900 record to fixed-width string format
* Total line width: 110 characters + CRLF
*/
function encodeZ900(input) {
const uniqueId = parseInt(key_generator_js_1.defaultKeyGenerator.getPrimaryIdentifier(), 10);
const fullRecord = {
code: 'Z900',
uniqueId,
...input,
};
const fields = [
(0, encoder_js_1.formatField)(fullRecord.code, 4, 'left'), // Field 1150: Record code (4) - Alphanumeric
(0, encoder_js_1.formatNumericField)(fullRecord.recordNumber.toString(), 9), // Field 1151: Record number (9) - Numeric
(0, encoder_js_1.formatNumericField)(fullRecord.vatId, 9), // Field 1152: VAT ID (9) - Numeric
(0, encoder_js_1.formatNumericField)(fullRecord.uniqueId.toString(), 15), // Field 1153: Unique ID (15) - Numeric
(0, encoder_js_1.formatField)(constants_js_1.SHAAM_VERSION, 8, 'left'), // Field 1154: SHAAM version (8) - Alphanumeric
(0, encoder_js_1.formatNumericField)(fullRecord.totalRecords.toString(), 15), // Field 1155: Total records (15) - Numeric
(0, encoder_js_1.formatField)(fullRecord.reserved, 50, 'left'), // Field 1156: Reserved (50) - Alphanumeric
];
return fields.join('') + index_js_1.CRLF;
}
/**
* Parses a fixed-width Z900 record line back to object
* Expected line length: 110 characters (excluding CRLF)
*/
function parseZ900(line) {
// Remove CRLF if present
const cleanLine = line.replace(/\r?\n$/, '');
if (cleanLine.length !== 110) {
throw new Error(`Invalid Z900 record length: expected 110 characters, got ${cleanLine.length}`);
}
// Extract fields at their fixed positions
const code = cleanLine.slice(0, 4).trim();
const recordNumber = parseInt(cleanLine.slice(4, 13).trim().replace(/^0+/, '') || '0', 10);
const vatId = cleanLine.slice(13, 22).trim().replace(/^0+/, '') || '0';
const uniqueId = parseInt(cleanLine.slice(22, 37).trim().replace(/^0+/, '') || '0', 10);
const systemCode = cleanLine.slice(37, 45).trim();
const totalRecords = parseInt(cleanLine.slice(45, 60).trim().replace(/^0+/, '') || '0', 10);
const reserved = cleanLine.slice(60, 110).trim();
// Validate the code field
if (code !== 'Z900') {
throw new Error(`Invalid Z900 record code: expected "Z900", got "${code}"`);
}
// Validate the SHAAM version field
if (systemCode !== constants_js_1.SHAAM_VERSION) {
throw new Error(`Invalid SHAAM version: expected "${constants_js_1.SHAAM_VERSION}", got "${systemCode}"`);
}
const parsed = {
code,
recordNumber,
vatId,
uniqueId,
totalRecords,
reserved,
};
// Validate against schema
return exports.Z900Schema.parse(parsed);
}