UNPKG

@accounter/server

Version:
1,036 lines 56.8 kB
import { afterAll, beforeAll, describe, expect, it, vi } from 'vitest'; import { getEntryTypeByRecord, getHeaderDataFromRecords, getPcn874String, getReferenceForTransaction, getTotalVAT, getVatIdForTransaction, } from '../pcn.helper.js'; import { EntryType, validatePcn874 } from '../../../../../../pcn874-generator/src/index.js'; import { Currency } from '../../../../shared/enums.js'; import { getVatRecords } from '../../resolvers/get-vat-records.resolver.js'; vi.mock('../../resolvers/get-vat-records.resolver.js', () => ({ getVatRecords: vi.fn(), })); const FIXED_DATE = new Date('2024-01-15'); const FIXED_REPORT_MONTH = '2024-01-15'; const FIXED_VAT_NUMBER = '123456789'; const FIXED_BUSINESS_ID = 'test-business-123'; beforeAll(() => { vi.useFakeTimers(); vi.setSystemTime(FIXED_DATE); }); afterAll(() => { vi.useRealTimers(); }); function createMockVatRecord(overrides) { return { localAmountBeforeVAT: 1000, foreignAmountBeforeVAT: 0, businessId: FIXED_BUSINESS_ID, chargeAccountantStatus: 'PENDING', chargeDate: FIXED_DATE, chargeId: `charge-${Math.random().toString(36).substring(7)}`, currencyCode: Currency.Ils, documentAmount: '1170', documentId: `doc-${Math.random().toString(36).substring(7)}`, documentDate: FIXED_DATE, documentSerial: 'INV-001', documentUrl: null, eventLocalAmount: 1000, isExpense: false, isProperty: false, roundedVATToAdd: 0, foreignVat: 0, localVat: 170, foreignVatAfterDeduction: 0, localVatAfterDeduction: 170, vatNumber: FIXED_VAT_NUMBER, allocationNumber: null, pcn874RecordType: EntryType.SALE_REGULAR, ...overrides, }; } function createMockBusiness(vatNumber = FIXED_VAT_NUMBER) { return { id: FIXED_BUSINESS_ID, name: 'Test Business Ltd', hebrewName: 'חברת בדיקה בע"מ', address: 'Tel Aviv', country: 'IL', vat_number: vatNumber, }; } function createMockInjector(options = {}) { const { business, vatRecords } = options; const mockLoaders = { getFinancialEntityByIdLoader: { load: vi.fn().mockResolvedValue(business || createMockBusiness()), }, getIncomeAndExpenseVatRecordsForReportLoader: { load: vi.fn().mockResolvedValue(vatRecords || []), }, }; const mockProviders = { BusinessesProvider: { getBusinessByIdLoader: { load: vi.fn().mockResolvedValue(business || createMockBusiness()), }, }, }; return { get: vi.fn((token) => { const tokenName = typeof token === 'string' ? token : token.name; return (mockProviders[tokenName] || mockLoaders[tokenName]); }), }; } describe('pcn.helper', () => { describe('Mock Factories', () => { it('should create a mock VAT record with defaults', () => { const record = createMockVatRecord(); expect(record.vatNumber).toBe(FIXED_VAT_NUMBER); expect(record.pcn874RecordType).toBe(EntryType.SALE_REGULAR); }); it('should override defaults when provided', () => { const record = createMockVatRecord({ localVat: 200 }); expect(record.localVat).toBe(200); expect(record.localAmountBeforeVAT).toBe(1000); }); it('should create a mock business with VAT number', () => { const business = createMockBusiness('987654321'); expect(business.vat_number).toBe('987654321'); }); it('should create a mock context with loaders', () => { const business = createMockBusiness(); const vatRecords = [createMockVatRecord()]; const injector = createMockInjector({ business, vatRecords }); expect(injector).toBeDefined(); expect(vi.isMockFunction(injector.get)).toBe(true); }); }); describe('Helper Functions', () => { describe('getEntryTypeByRecord', () => { describe('Sales Entry Types', () => { it('should map S1 to S1', () => { const result = getEntryTypeByRecord({ pcn874RecordType: EntryType.SALE_REGULAR, isExpense: false, }); expect(result).toBe('S1'); }); it('should map S2 to S2', () => { const result = getEntryTypeByRecord({ pcn874RecordType: EntryType.SALE_ZERO_OR_EXEMPT, isExpense: false, }); expect(result).toBe('S2'); }); it('should map L1 to L1', () => { const result = getEntryTypeByRecord({ pcn874RecordType: EntryType.SALE_UNIDENTIFIED_CUSTOMER, isExpense: false, }); expect(result).toBe('L1'); }); it('should map L2 to L2', () => { const result = getEntryTypeByRecord({ pcn874RecordType: EntryType.SALE_UNIDENTIFIED_ZERO_OR_EXEMPT, isExpense: false, }); expect(result).toBe('L2'); }); it('should map M to M', () => { const result = getEntryTypeByRecord({ pcn874RecordType: EntryType.SALE_SELF_INVOICE, isExpense: false, }); expect(result).toBe('M'); }); it('should map Y to Y', () => { const result = getEntryTypeByRecord({ pcn874RecordType: EntryType.SALE_EXPORT, isExpense: false, }); expect(result).toBe('Y'); }); it('should map I to I', () => { const result = getEntryTypeByRecord({ pcn874RecordType: EntryType.SALE_PALESTINIAN_CUSTOMER, isExpense: false, }); expect(result).toBe('I'); }); }); describe('Input Entry Types', () => { it('should map T to T', () => { const result = getEntryTypeByRecord({ pcn874RecordType: EntryType.INPUT_REGULAR, isExpense: true, }); expect(result).toBe('T'); }); it('should map K to K', () => { const result = getEntryTypeByRecord({ pcn874RecordType: EntryType.INPUT_PETTY_CASH, isExpense: true, }); expect(result).toBe('K'); }); it('should map R to R', () => { const result = getEntryTypeByRecord({ pcn874RecordType: EntryType.INPUT_IMPORT, isExpense: true, }); expect(result).toBe('R'); }); it('should map P to P', () => { const result = getEntryTypeByRecord({ pcn874RecordType: EntryType.INPUT_PALESTINIAN_SUPPLIER, isExpense: true, }); expect(result).toBe('P'); }); it('should map H to H', () => { const result = getEntryTypeByRecord({ pcn874RecordType: EntryType.INPUT_SINGLE_DOC_BY_LAW, isExpense: true, }); expect(result).toBe('H'); }); it('should map C to C', () => { const result = getEntryTypeByRecord({ pcn874RecordType: EntryType.INPUT_SELF_INVOICE, isExpense: true, }); expect(result).toBe('C'); }); }); describe('Edge Cases', () => { it('should throw for unmapped types', () => { expect(() => getEntryTypeByRecord({ pcn874RecordType: 'UNKNOWN_TYPE', isExpense: false, })).toThrow(/Unhandled PCN874 Record Type/); }); it('should infer sale unidentified customer when VAT number exists', () => { const result = getEntryTypeByRecord({ isExpense: false, vatNumber: null, foreignVatAfterDeduction: 12, }); expect(result).toBe('L1'); }); it('should infer sale unidentified zero/exempt when foreign VAT is zero', () => { const result = getEntryTypeByRecord({ isExpense: false, vatNumber: null, foreignVatAfterDeduction: 0, }); expect(result).toBe('L2'); }); it('should infer sale regular when VAT number and foreign VAT exists', () => { const result = getEntryTypeByRecord({ isExpense: false, vatNumber: '123456789', foreignVatAfterDeduction: 12, }); expect(result).toBe('S1'); }); it('should infer input regular for expenses without explicit type', () => { const result = getEntryTypeByRecord({ isExpense: true, vatNumber: null, foreignVatAfterDeduction: 0, }); expect(result).toBe('T'); }); }); }); describe('getVatIdForTransaction', () => { it('should return "0" for unidentified customer (L1)', () => { const record = createMockVatRecord({ vatNumber: '123456789', pcn874RecordType: EntryType.SALE_UNIDENTIFIED_CUSTOMER, }); const result = getVatIdForTransaction(record); expect(result).toBe('0'); }); it('should return "0" for unidentified customer zero-rated (L2)', () => { const record = createMockVatRecord({ vatNumber: '123456789', pcn874RecordType: EntryType.SALE_UNIDENTIFIED_ZERO_OR_EXEMPT, }); const result = getVatIdForTransaction(record); expect(result).toBe('0'); }); it('should return "0" for petty cash (K)', () => { const record = createMockVatRecord({ vatNumber: '123456789', pcn874RecordType: EntryType.INPUT_PETTY_CASH, }); const result = getVatIdForTransaction(record); expect(result).toBe('0'); }); it('should return "999999999" for INPUT_REGULAR without VAT number', () => { const record = createMockVatRecord({ vatNumber: null, pcn874RecordType: EntryType.INPUT_REGULAR, }); const result = getVatIdForTransaction(record); expect(result).toBe('999999999'); }); it('should return record VAT number for regular sales', () => { const record = createMockVatRecord({ vatNumber: '123456789', pcn874RecordType: EntryType.SALE_REGULAR, }); const result = getVatIdForTransaction(record); expect(result).toBe('123456789'); }); it('should return record VAT number for foreign business with VAT', () => { const record = createMockVatRecord({ vatNumber: '987654321', pcn874RecordType: EntryType.SALE_PALESTINIAN_CUSTOMER, }); const result = getVatIdForTransaction(record); expect(result).toBe('987654321'); }); it('should handle undefined entry type gracefully', () => { const record = createMockVatRecord({ vatNumber: '123456789', pcn874RecordType: undefined, }); const result = getVatIdForTransaction(record); expect(result).toBe('123456789'); }); }); describe('getReferenceForTransaction', () => { it('should return "0" for import transactions (R)', () => { const record = createMockVatRecord({ documentSerial: 'INV-123', pcn874RecordType: EntryType.INPUT_IMPORT, }); const result = getReferenceForTransaction(record); expect(result).toBe('0'); }); it('should return document serial when available', () => { const record = createMockVatRecord({ documentSerial: 'INV-1234', pcn874RecordType: EntryType.SALE_REGULAR, }); const result = getReferenceForTransaction(record); expect(result).toBe('INV-1234'); }); it('should return "1" for unidentified customer (L1) without serial', () => { const record = createMockVatRecord({ documentSerial: null, pcn874RecordType: EntryType.SALE_UNIDENTIFIED_CUSTOMER, }); const result = getReferenceForTransaction(record); expect(result).toBe('1'); }); it('should return "1" for petty cash (K) without serial', () => { const record = createMockVatRecord({ documentSerial: null, pcn874RecordType: EntryType.INPUT_PETTY_CASH, }); const result = getReferenceForTransaction(record); expect(result).toBe('1'); }); it('should return "0" as fallback when no serial and standard type', () => { const record = createMockVatRecord({ documentSerial: null, pcn874RecordType: EntryType.SALE_REGULAR, }); const result = getReferenceForTransaction(record); expect(result).toBe('0'); }); }); describe('getTotalVAT', () => { it('should round positive VAT amount', () => { const record = createMockVatRecord({ roundedVATToAdd: 170.4, pcn874RecordType: EntryType.SALE_REGULAR, }); const result = getTotalVAT(record); expect(result).toBe(170); }); it('should take absolute value and round negative VAT', () => { const record = createMockVatRecord({ roundedVATToAdd: -170.6, pcn874RecordType: EntryType.SALE_REGULAR, }); const result = getTotalVAT(record); expect(result).toBe(171); }); it('should return 0 for exempt transactions (S2)', () => { const record = createMockVatRecord({ roundedVATToAdd: 170, pcn874RecordType: EntryType.SALE_ZERO_OR_EXEMPT, }); const result = getTotalVAT(record); expect(result).toBe(0); }); it('should return 0 for export transactions (Y)', () => { const record = createMockVatRecord({ roundedVATToAdd: 170, pcn874RecordType: EntryType.SALE_EXPORT, }); const result = getTotalVAT(record); expect(result).toBe(0); }); it('should return 0 for zero-rated transactions', () => { const record = createMockVatRecord({ roundedVATToAdd: 0, pcn874RecordType: EntryType.SALE_REGULAR, }); const result = getTotalVAT(record); expect(result).toBe(0); }); it.skip('should handle foreign VAT correctly', () => { const record = createMockVatRecord({ roundedVATToAdd: 85.3, pcn874RecordType: EntryType.SALE_PALESTINIAN_CUSTOMER, }); const result = getTotalVAT(record); expect(result).toBe(85); }); }); describe('getHeaderDataFromRecords', () => { const createPcnRecord = (overrides = {}) => ({ entryType: EntryType.SALE_REGULAR, vatId: '123456789', invoiceDate: '20240115', refGroup: '0000', refNumber: '1', totalVat: 170, invoiceSum: 1000, isProperty: false, allocationNumber: undefined, ...overrides, }); it('should return all zeros for empty array', () => { const result = getHeaderDataFromRecords([], ''); expect(result.taxableSalesAmount).toBe(0); expect(result.zeroValOrExemptSalesCount).toBe(0); expect(result.salesRecordCount).toBe(0); expect(result.inputsCount).toBe(0); expect(result.taxableSalesVat).toBe(0); expect(result.otherInputsVat).toBe(0); expect(result.equipmentInputsVat).toBe(0); }); it('should increment taxable sales for SALE_REGULAR (S1)', () => { const records = [ createPcnRecord({ entryType: EntryType.SALE_REGULAR, invoiceSum: 1000, totalVat: 170, }), ]; const result = getHeaderDataFromRecords(records, ''); expect(result.taxableSalesAmount).toBe(1000); expect(result.taxableSalesVat).toBe(170); expect(result.salesRecordCount).toBe(1); expect(result.zeroValOrExemptSalesCount).toBe(0); }); it('should increment zero-rated sales for SALE_UNIDENTIFIED_ZERO_OR_EXEMPT (L2)', () => { const records = [ createPcnRecord({ entryType: EntryType.SALE_UNIDENTIFIED_ZERO_OR_EXEMPT, invoiceSum: 1000, totalVat: 0, }), ]; const result = getHeaderDataFromRecords(records, ''); expect(result.zeroValOrExemptSalesCount).toBe(1000); expect(result.taxableSalesAmount).toBe(0); expect(result.salesRecordCount).toBe(1); }); describe.skip('Foreign Business with VAT', () => { it('should add SALE_FOREIGN_BUSINESS_WITH_VAT to exempt sales', () => { const records = [ createPcnRecord({ entryType: EntryType.SALE_PALESTINIAN_CUSTOMER, invoiceSum: 1170, totalVat: 170, }), ]; const result = getHeaderDataFromRecords(records, ''); expect(result.zeroValOrExemptSalesCount).toBe(1170); expect(result.taxableSalesAmount).toBe(0); expect(result.salesRecordCount).toBe(1); expect(result.taxableSalesVat).toBe(170); }); it('should separate foreign with VAT from regular sales', () => { const records = [ createPcnRecord({ entryType: EntryType.SALE_PALESTINIAN_CUSTOMER, invoiceSum: 1170, totalVat: 170, }), createPcnRecord({ entryType: EntryType.SALE_REGULAR, invoiceSum: 2340, totalVat: 340, }), ]; const result = getHeaderDataFromRecords(records, ''); expect(result.zeroValOrExemptSalesCount).toBe(1170); expect(result.taxableSalesAmount).toBe(2340); expect(result.salesRecordCount).toBe(2); expect(result.taxableSalesVat).toBe(510); }); }); describe.skip('Mixed Sales and Input Transactions', () => { it('should handle mixed transaction types correctly', () => { const records = [ createPcnRecord({ entryType: EntryType.SALE_REGULAR, invoiceSum: 1000, totalVat: 170 }), createPcnRecord({ entryType: EntryType.SALE_REGULAR, invoiceSum: 2000, totalVat: 340 }), createPcnRecord({ entryType: EntryType.SALE_PALESTINIAN_CUSTOMER, invoiceSum: 1170, totalVat: 170 }), createPcnRecord({ entryType: EntryType.INPUT_REGULAR, invoiceSum: 500, totalVat: 85, isProperty: false, }), ]; const result = getHeaderDataFromRecords(records, ''); expect(result.taxableSalesAmount).toBe(3000); expect(result.zeroValOrExemptSalesCount).toBe(1170); expect(result.salesRecordCount).toBe(3); expect(result.inputsCount).toBe(1); expect(result.taxableSalesVat).toBe(680); expect(result.otherInputsVat).toBe(85); }); it('should count input records correctly', () => { const records = [ createPcnRecord({ entryType: EntryType.INPUT_REGULAR, invoiceSum: 500, totalVat: 85 }), createPcnRecord({ entryType: EntryType.INPUT_PETTY_CASH, invoiceSum: 100, totalVat: 17 }), createPcnRecord({ entryType: EntryType.INPUT_IMPORT, invoiceSum: 300, totalVat: 51 }), ]; const result = getHeaderDataFromRecords(records, ''); expect(result.inputsCount).toBe(3); expect(result.salesRecordCount).toBe(0); expect(result.otherInputsVat).toBe(153); }); }); }); }); describe('Integration Tests', () => { describe('getPcn874String', () => { describe('Standard Mixed Report', () => { it('should generate valid PCN874 for typical monthly report', async () => { const vatRecords = [ createMockVatRecord({ pcn874RecordType: EntryType.SALE_REGULAR, localAmountBeforeVAT: 1000, localVat: 170, }), createMockVatRecord({ pcn874RecordType: EntryType.SALE_REGULAR, localAmountBeforeVAT: 2000, localVat: 340, }), createMockVatRecord({ pcn874RecordType: EntryType.INPUT_REGULAR, localAmountBeforeVAT: 500, localVat: 85, isExpense: true, }), createMockVatRecord({ pcn874RecordType: EntryType.INPUT_REGULAR, localAmountBeforeVAT: 300, localVat: 51, isExpense: true, }), createMockVatRecord({ pcn874RecordType: EntryType.SALE_EXPORT, localAmountBeforeVAT: 5000, localVat: 0, }), ]; const business = createMockBusiness(); const injector = createMockInjector({ business, vatRecords }); vi.mocked(getVatRecords).mockResolvedValue({ income: vatRecords, expenses: [], missingInfo: [], differentMonthDoc: [], businessTrips: [], }); const result = await getPcn874String(injector, FIXED_BUSINESS_ID, FIXED_REPORT_MONTH); expect(validatePcn874(result.reportContent)).toBe(true); const lines = result.reportContent.split('\n').filter((line) => line.length > 0); expect(lines[0].length).toBe(131); expect(lines[lines.length - 1].length).toBe(10); const transactionLines = lines.slice(1, -1); expect(transactionLines.length).toBe(5); transactionLines.forEach((line) => { expect(line.length).toBe(60); }); expect(result.reportMonth).toBe('202401'); expect(result.financialEntity.vat_number).toBe(FIXED_VAT_NUMBER); }); }); describe('Foreign Businesses with VAT', () => { it('should place foreign business with VAT in exempt sales', async () => { const vatRecords = [ createMockVatRecord({ pcn874RecordType: EntryType.SALE_PALESTINIAN_CUSTOMER, localAmountBeforeVAT: 1000, localVat: 170, vatNumber: '987654321', }), createMockVatRecord({ pcn874RecordType: EntryType.SALE_REGULAR, localAmountBeforeVAT: 2000, localVat: 340, }), ]; const business = createMockBusiness(); const injector = createMockInjector({ business, vatRecords }); vi.mocked(getVatRecords).mockResolvedValue({ income: vatRecords, expenses: [], missingInfo: [], differentMonthDoc: [], businessTrips: [], }); const result = await getPcn874String(injector, FIXED_BUSINESS_ID, FIXED_REPORT_MONTH); expect(validatePcn874(result.reportContent)).toBe(true); const lines = result.reportContent.split('\n').filter((line) => line.length > 0); const transactionLines = lines.slice(1, -1); const foreignTx = transactionLines.find((line) => line.startsWith('I')); expect(foreignTx).toBeDefined(); expect(foreignTx).toContain('987654321'); const regularTx = transactionLines.find((line) => line.startsWith('S')); expect(regularTx).toBeDefined(); }); }); describe('Edge Cases', () => { it('should handle zero-VAT transactions only', async () => { const vatRecords = [ createMockVatRecord({ pcn874RecordType: EntryType.SALE_ZERO_OR_EXEMPT, localVat: 0, localAmountBeforeVAT: 1000, }), createMockVatRecord({ pcn874RecordType: EntryType.SALE_EXPORT, localVat: 0, localAmountBeforeVAT: 2000, }), ]; const business = createMockBusiness(); const injector = createMockInjector({ business, vatRecords }); vi.mocked(getVatRecords).mockResolvedValue({ income: vatRecords, expenses: [], missingInfo: [], differentMonthDoc: [], businessTrips: [], }); const result = await getPcn874String(injector, FIXED_BUSINESS_ID, FIXED_REPORT_MONTH); expect(validatePcn874(result.reportContent)).toBe(true); const lines = result.reportContent.split('\n').filter((line) => line.length > 0); expect(lines.length).toBeGreaterThan(2); }); it('should handle negative amounts (credit invoices)', async () => { const vatRecords = [ createMockVatRecord({ localAmountBeforeVAT: -500, localVat: -85, }), ]; const business = createMockBusiness(); const injector = createMockInjector({ business, vatRecords }); vi.mocked(getVatRecords).mockResolvedValue({ income: vatRecords, expenses: [], missingInfo: [], differentMonthDoc: [], businessTrips: [], }); const result = await getPcn874String(injector, FIXED_BUSINESS_ID, FIXED_REPORT_MONTH); expect(validatePcn874(result.reportContent)).toBe(true); const lines = result.reportContent.split('\n').filter((line) => line.length > 0); expect(lines.length).toBe(3); }); it('should skip records with missing document dates', async () => { const vatRecords = [ createMockVatRecord({ documentDate: null }), createMockVatRecord({ documentDate: FIXED_DATE }), ]; const business = createMockBusiness(); const injector = createMockInjector({ business, vatRecords }); const consoleDebugSpy = vi.spyOn(console, 'debug').mockImplementation(() => undefined); vi.mocked(getVatRecords).mockResolvedValue({ income: vatRecords, expenses: [], missingInfo: [], differentMonthDoc: [], businessTrips: [], }); const result = await getPcn874String(injector, FIXED_BUSINESS_ID, FIXED_REPORT_MONTH); expect(validatePcn874(result.reportContent)).toBe(true); const lines = result.reportContent.split('\n').filter((line) => line.length > 0); const transactionLines = lines.slice(1, -1); expect(transactionLines.length).toBe(1); expect(consoleDebugSpy).toHaveBeenCalled(); consoleDebugSpy.mockRestore(); }); it('should generate minimal report for empty records', async () => { const vatRecords = []; const business = createMockBusiness(); const injector = createMockInjector({ business, vatRecords }); vi.mocked(getVatRecords).mockResolvedValue({ income: [], expenses: [], missingInfo: [], differentMonthDoc: [], businessTrips: [], }); const result = await getPcn874String(injector, FIXED_BUSINESS_ID, FIXED_REPORT_MONTH); expect(validatePcn874(result.reportContent)).toBe(false); // Header/footer only is not valid but should still be generated const lines = result.reportContent.split('\n').filter((line) => line.length > 0); expect(lines.length).toBe(2); expect(lines[0].length).toBe(131); expect(lines[1].length).toBe(10); }); }); describe('Error Handling', () => { it('should throw error when business has no VAT number', async () => { const vatRecords = [createMockVatRecord()]; const businessWithoutVAT = createMockBusiness(undefined); businessWithoutVAT.vatNumber = null; businessWithoutVAT.vat_number = null; const injector = createMockInjector({ business: businessWithoutVAT, vatRecords, }); await expect(getPcn874String(injector, FIXED_BUSINESS_ID, FIXED_REPORT_MONTH)).rejects.toThrow(/VAT/i); }); it('should validate report month format', async () => { const vatRecords = [createMockVatRecord()]; const business = createMockBusiness(); const injector = createMockInjector({ business, vatRecords }); vi.mocked(getVatRecords).mockResolvedValue({ income: vatRecords, expenses: [], missingInfo: [], differentMonthDoc: [], businessTrips: [], }); const result = await getPcn874String(injector, FIXED_BUSINESS_ID, '2024-1'); expect(result.reportMonth).toBe('202401'); }); }); }); }); describe('Snapshot Tests', () => { describe('PCN874 Format Snapshots', () => { it('should match snapshot for standard mixed report', async () => { const vatRecords = [ createMockVatRecord({ pcn874RecordType: EntryType.SALE_REGULAR, localAmountBeforeVAT: 1000, localVat: 170, documentSerial: 'INV-001', }), createMockVatRecord({ pcn874RecordType: EntryType.SALE_REGULAR, localAmountBeforeVAT: 2000, localVat: 340, documentSerial: 'INV-002', }), createMockVatRecord({ pcn874RecordType: EntryType.INPUT_REGULAR, localAmountBeforeVAT: 500, localVat: 85, isExpense: true, documentSerial: 'BILL-001', }), createMockVatRecord({ pcn874RecordType: EntryType.INPUT_REGULAR, localAmountBeforeVAT: 300, localVat: 51, isExpense: true, documentSerial: 'BILL-002', }), createMockVatRecord({ pcn874RecordType: EntryType.SALE_EXPORT, localAmountBeforeVAT: 5000, localVat: 0, documentSerial: 'EXP-001', }), ]; const business = createMockBusiness(); const injector = createMockInjector({ business, vatRecords }); vi.mocked(getVatRecords).mockResolvedValue({ income: vatRecords, expenses: [], missingInfo: [], differentMonthDoc: [], businessTrips: [], }); const result = await getPcn874String(injector, FIXED_BUSINESS_ID, FIXED_REPORT_MONTH); expect(validatePcn874(result.reportContent)).toBe(true); expect(result.reportContent).toMatchSnapshot(); }); it('should match snapshot for PR #2940 foreign businesses', async () => { const vatRecords = [ createMockVatRecord({ pcn874RecordType: EntryType.SALE_PALESTINIAN_CUSTOMER, localAmountBeforeVAT: 1000, localVat: 170, vatNumber: '987654321', documentSerial: 'INTL-001', }), createMockVatRecord({ pcn874RecordType: EntryType.SALE_REGULAR, localAmountBeforeVAT: 2000, localVat: 340, documentSerial: 'INV-001', }), ]; const business = createMockBusiness(); const injector = createMockInjector({ business, vatRecords }); vi.mocked(getVatRecords).mockResolvedValue({ income: vatRecords, expenses: [], missingInfo: [], differentMonthDoc: [], businessTrips: [], }); const result = await getPcn874String(injector, FIXED_BUSINESS_ID, FIXED_REPORT_MONTH); expect(validatePcn874(result.reportContent)).toBe(true); expect(result.reportContent).toMatchSnapshot(); }); it('should match snapshot for zero-VAT transactions', async () => { const vatRecords = [ createMockVatRecord({ pcn874RecordType: EntryType.SALE_ZERO_OR_EXEMPT, localAmountBeforeVAT: 1000, localVat: 0, documentSerial: 'EXEMPT-001', }), createMockVatRecord({ pcn874RecordType: EntryType.SALE_EXPORT, localAmountBeforeVAT: 2000, localVat: 0, documentSerial: 'EXP-001', }), ]; const business = createMockBusiness(); const injector = createMockInjector({ business, vatRecords }); vi.mocked(getVatRecords).mockResolvedValue({ income: vatRecords, expenses: [], missingInfo: [], differentMonthDoc: [], businessTrips: [], }); const result = await getPcn874String(injector, FIXED_BUSINESS_ID, FIXED_REPORT_MONTH); expect(validatePcn874(result.reportContent)).toBe(true); expect(result.reportContent).toMatchSnapshot(); }); it('should match snapshot for imports and exports', async () => { const vatRecords = [ createMockVatRecord({ pcn874RecordType: EntryType.INPUT_IMPORT, localAmountBeforeVAT: 3000, localVat: 510, isExpense: true, documentSerial: 'IMP-001', }), createMockVatRecord({ pcn874RecordType: EntryType.SALE_EXPORT, localAmountBeforeVAT: 5000, localVat: 0, documentSerial: 'EXP-001', }), createMockVatRecord({ pcn874RecordType: EntryType.SALE_REGULAR, localAmountBeforeVAT: 1000, localVat: 170, documentSerial: 'INV-001', }), ]; const business = createMockBusiness(); const injector = createMockInjector({ business, vatRecords }); vi.mocked(getVatRecords).mockResolvedValue({ income: vatRecords, expenses: [], missingInfo: [], differentMonthDoc: [], businessTrips: [], }); const result = await getPcn874String(injector, FIXED_BUSINESS_ID, FIXED_REPORT_MONTH); expect(validatePcn874(result.reportContent)).toBe(true); expect(result.reportContent).toMatchSnapshot(); }); it('should match snapshot for property expenses', async () => { const vatRecords = [ createMockVatRecord({ chargeAccountantStatus: "PENDING", currencyCode: Currency.Ils, documentSerial: "0101-0202", documentAmount: "4680", foreignVat: null, localVat: 713.9, isProperty: true, vatNumber: FIXED_VAT_NUMBER, isExpense: true, pcn874RecordType: undefined, foreignVatAfterDeduction: 475.9333333333333, localVatAfterDeduction: 475.9333333333333, foreignAmountBeforeVAT: 4204.066666666667, localAmountBeforeVAT: 4204.066666666667, roundedVATToAdd: 476, eventLocalAmount: 4680, }), ]; const business = createMockBusiness(); const injector = createMockInjector({ business, vatRecords }); vi.mocked(getVatRecords).mockResolvedValue({ income: [], expenses: vatRecords, missingInfo: [], differentMonthDoc: [], businessTrips: [], }); const result = await getPcn874String(injector, FIXED_BUSINESS_ID, FIXED_REPORT_MONTH); expect(validatePcn874(result.reportContent)).toBe(true); expect(result.reportContent).toMatchSnapshot(); }); it('should match snapshot for foreign customer, credit invoices (with & without VAT)', async () => { const vatRecords = [ createMockVatRecord({ chargeAccountantStatus: "PENDING", currencyCode: Currency.Usd, documentSerial: "10123", documentAmount: "6000", foreignVat: -1810.54, localVat: null, isProperty: false, vatNumber: null, isExpense: false, allocationNumber: null, pcn874RecordType: undefined, foreignVatAfterDeduction: -1810.54, localVatAfterDeduction: -2597.4086299999996, foreignAmountBeforeVAT: -5084.74, localAmountBeforeVAT: -16596.59136, roundedVATToAdd: -2598, eventLocalAmount: -10584, }), createMockVatRecord({ chargeAccountantStatus: "PENDING", currencyCode: Currency.Usd, documentSerial: "20123", documentAmount: "6000", foreignVat: 1810.54, localVat: null, isProperty: false, vatNumber: null, isExpense: false, allocationNumber: null, pcn874RecordType: undefined, foreignVatAfterDeduction: 1810.54, localVatAfterDeduction: 2597.4086299999996, foreignAmountBeforeVAT: 5084.74, localAmountBeforeVAT: 16596.59136, roundedVATToAdd: 2598, eventLocalAmount: 10584, }), createMockVatRecord({ chargeAccountantStatus: "PENDING", currencyCode: Currency.Ils, documentSerial: "80123", documentAmount: "2000.15", foreignVat: null, localVat: null, isProperty: false, vatNumber: null, isExpense: false, allocationNumber: null, pcn874RecordType: undefined, foreignVatAfterDeduction: undefined, localVatAfterDeduction: undefined, foreignAmountBeforeVAT: undefined, localAmountBeforeVAT: -2000.15, roundedVATToAdd: undefined, eventLocalAmount: -2000.15, }), createMockVatRecord({ chargeAccountantStatus: "PENDING", currencyCode: Currency.Ils, documentSerial: "90123", documentAmount: "2000.15", foreignVat: undefined, localVat: undefined, isProperty: false, vatNumber: undefined, isExpense: false, allocationNumber: undefined, pcn874RecordType: undefined, foreignVatAfterDeduction: undefined, localVatAfterDeduction: undefined, foreignAmountBeforeVAT: undefined, localAmountBeforeVAT: 2000.15, roundedVATToAdd: undefined, eventLocalAmount: 2000.15, }), ]; const business = createMockBusiness(); const injector = createMockInjector({ business, vatRecords }); vi.mocked(getVatRecords).mockResolvedValue({ income: [], expenses: vatRecords, missingInfo: [], differentMonthDoc: [], businessTrips: [], }); const result = await getPcn874String(injector, FIXED_BUSINESS_ID, FIXED_REPORT_MONTH); expect(validatePcn874(result.reportContent)).toBe(true); expect(result.reportContent).toMatchSnapshot(); }); it('should match snapshot for local customer, credit invoices with VAT', async () => { const vatRecords = [ createMockVatRecord({ chargeAccountantStatus: "PENDING", currencyCode: Currency.Ils, documentSerial: "10001", documentAmount: "4000", foreignVat: undefined, localVat: -610.17, isProperty: false, vatNumber: '191919191', isExpense: false, allocationNumber: null, pcn874RecordType: undefined, foreignVatAfterDeduction: undefined, localVatAfterDeduction: -610.17, foreignAmountBeforeVAT: undefined, localAmountBeforeVAT: -3389.83, roundedVATToAdd: -610, eventLocalAmount: -4000, }), createMockVatRecord({ chargeAccountantStatus: "PENDING", currencyCode: Currency.Ils, documentSerial: "20002", documentAmount: "4000", foreignVat: undefined, localVat: 610.17, isProperty: false, vatNumber: '191919191', isExpense: false, allocationNumber: null, pcn874RecordType: undefined, foreignVatAfterDeduction: undefined, localVatAfterDeduction: 610.17, foreignAmountBeforeVAT: undefined, localAmountBeforeVAT: 3389.83, roundedVATToAdd: 610, eventLocalAmount: 4000, }), ]; const business = createMockBusiness(); const injector = createMock