UPO 4.3, fixes for invoices
This commit is contained in:
@@ -1,12 +1,13 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<Potwierdzenie xmlns="http://upo.schematy.mf.gov.pl/KSeF/v4-2">
|
<Potwierdzenie xmlns="http://upo.schematy.mf.gov.pl/KSeF/v4-3">
|
||||||
<NazwaPodmiotuPrzyjmujacego>Ministerstwo Finansów</NazwaPodmiotuPrzyjmujacego>
|
<NazwaPodmiotuPrzyjmujacego>Ministerstwo Finansów</NazwaPodmiotuPrzyjmujacego>
|
||||||
<NumerReferencyjnySesji>36950822-93-9D5A28BFDA-47C899773E-5C</NumerReferencyjnySesji>
|
<NumerReferencyjnySesji>36950822-93-9D5A28BFDA-47C899773E-5C</NumerReferencyjnySesji>
|
||||||
<Uwierzytelnienie>
|
<Uwierzytelnienie>
|
||||||
<IdKontekstu>
|
<IdKontekstu>
|
||||||
<IdZlozonyVatUE>5265877635-ATU12345678</IdZlozonyVatUE>
|
<IdZlozonyVatUE>5265877635-ATU12345678</IdZlozonyVatUE>
|
||||||
</IdKontekstu>
|
</IdKontekstu>
|
||||||
<SkrotDokumentuUwierzytelniajacego>kyqH+QUgP8ATWd/95IY632mP4uqibwG66Oqclq9+qno=</SkrotDokumentuUwierzytelniajacego>
|
<SkrotDokumentuUwierzytelniajacego>kyqH+QUgP8ATWd/95IY632mP4uqibwG66Oqclq9+qno=
|
||||||
|
</SkrotDokumentuUwierzytelniajacego>
|
||||||
</Uwierzytelnienie>
|
</Uwierzytelnienie>
|
||||||
<NazwaStrukturyLogicznej>1-0E</NazwaStrukturyLogicznej>
|
<NazwaStrukturyLogicznej>1-0E</NazwaStrukturyLogicznej>
|
||||||
<KodFormularza>FA (3)</KodFormularza>
|
<KodFormularza>FA (3)</KodFormularza>
|
||||||
@@ -18,5 +19,6 @@
|
|||||||
<DataPrzeslaniaDokumentu>2025-09-16T11:05:40.841+02:00</DataPrzeslaniaDokumentu>
|
<DataPrzeslaniaDokumentu>2025-09-16T11:05:40.841+02:00</DataPrzeslaniaDokumentu>
|
||||||
<DataNadaniaNumeruKSeF>2025-09-16T11:05:41.045+02:00</DataNadaniaNumeruKSeF>
|
<DataNadaniaNumeruKSeF>2025-09-16T11:05:41.045+02:00</DataNadaniaNumeruKSeF>
|
||||||
<SkrotDokumentu>GZMGNVzs3krF6URKgvaw77OOeG3nJ+WGziT5xguliQ8=</SkrotDokumentu>
|
<SkrotDokumentu>GZMGNVzs3krF6URKgvaw77OOeG3nJ+WGziT5xguliQ8=</SkrotDokumentu>
|
||||||
|
<TrybWysylki>Offline</TrybWysylki>
|
||||||
</Dokument>
|
</Dokument>
|
||||||
</Potwierdzenie>
|
</Potwierdzenie>
|
||||||
1303
package-lock.json
generated
1303
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@akmf/ksef-fe-invoice-converter",
|
"name": "@akmf/ksef-fe-invoice-converter",
|
||||||
"version": "0.0.32",
|
"version": "0.0.42",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "vite --mode public --config vite.config.ts",
|
"dev": "vite --mode public --config vite.config.ts",
|
||||||
"build": "vite build --mode production",
|
"build": "vite build --mode production",
|
||||||
|
|||||||
@@ -1,19 +1,29 @@
|
|||||||
<!DOCTYPE html>
|
<!doctype html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8" />
|
<meta charset="UTF-8" />
|
||||||
<title>KSEF PDF GENERATOR</title>
|
<title>XML Parser</title>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<h1 style="margin: auto;width: fit-content">📄 KSEF PDF GENERATOR</h1>
|
<h1>📄 XML Parser</h1>
|
||||||
|
|
||||||
<h1> Wygeneruj wizualizacje faktury PDF </h1>
|
<h2>Wygeneruj fakture:</h2>
|
||||||
<input accept=".xml" id="xmlInput" type="file" />
|
<input
|
||||||
|
accept=".xml"
|
||||||
|
id="xmlInput"
|
||||||
|
type="file"
|
||||||
|
/>
|
||||||
|
|
||||||
<h1> Wygeneruj wizualizacje UPO PDF</h1>
|
<h2>Wygeneruj UPO:</h2>
|
||||||
<input accept=".xml" id="xmlInputUPO" type="file" />
|
<input
|
||||||
|
accept=".xml"
|
||||||
|
id="xmlInputUPO"
|
||||||
|
type="file"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<script
|
||||||
<script src="./main.ts" type="module"></script>
|
src="./main.ts"
|
||||||
</body>
|
type="module"
|
||||||
|
></script>
|
||||||
|
</body>
|
||||||
</html>
|
</html>
|
||||||
@@ -15,7 +15,7 @@ inputInvoice.addEventListener('change', async (): Promise<void> => {
|
|||||||
const additionalData: AdditionalDataTypes = {
|
const additionalData: AdditionalDataTypes = {
|
||||||
nrKSeF: '5555555555-20250808-9231003CA67B-BE',
|
nrKSeF: '5555555555-20250808-9231003CA67B-BE',
|
||||||
qrCode:
|
qrCode:
|
||||||
'https://ksef-test.mf.gov.pl/client-app/invoice/5265877635/26-10-2025/HS5E1zrA8WVjDNq_xMVIN5SD6nyRymmQ-BcYHReUAa0',
|
'https://qr-test.ksef.mf.gov.pl/invoice/5265877635/26-10-2025/HS5E1zrA8WVjDNq_xMVIN5SD6nyRymmQ-BcYHReUAa0',
|
||||||
};
|
};
|
||||||
|
|
||||||
generateInvoice(file, additionalData, 'blob').then((data: Blob): void => {
|
generateInvoice(file, additionalData, 'blob').then((data: Blob): void => {
|
||||||
|
|||||||
@@ -1 +1,8 @@
|
|||||||
export { generateInvoice, generatePDFUPO } from './lib-public';
|
export { generateInvoice, generatePDFUPO } from './lib-public';
|
||||||
|
export { generateFA1 } from './lib-public/FA1-generator';
|
||||||
|
export { generateFA2 } from './lib-public/FA2-generator';
|
||||||
|
export { generateFA3 } from './lib-public/FA3-generator';
|
||||||
|
export { generateNaglowekUPO } from './lib-public/generators/UPO4_3/Naglowek';
|
||||||
|
export { generateDokumentUPO } from './lib-public/generators/UPO4_3/Dokumenty';
|
||||||
|
export { generateStyle } from './shared/PDF-functions';
|
||||||
|
export * from './shared/enums/common.enum';
|
||||||
|
|||||||
65
src/lib-public/UPO-generator.spec.ts
Normal file
65
src/lib-public/UPO-generator.spec.ts
Normal file
@@ -0,0 +1,65 @@
|
|||||||
|
import pdfMake from 'pdfmake/build/pdfmake';
|
||||||
|
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
|
||||||
|
import { generatePDFUPO } from './UPO-generator';
|
||||||
|
import * as XMLParser from '../shared/XML-parser';
|
||||||
|
|
||||||
|
describe('generatePDFUPO', () => {
|
||||||
|
const dummyFile = new File(['dummy'], 'dummy.xml', { type: 'text/xml' });
|
||||||
|
const dummyUpo = {
|
||||||
|
Potwierdzenie: {
|
||||||
|
field1: 'value1',
|
||||||
|
field2: 'value2',
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
vi.spyOn(XMLParser, 'parseXML').mockResolvedValue(dummyUpo);
|
||||||
|
|
||||||
|
vi.spyOn(pdfMake, 'createPdf').mockImplementation(
|
||||||
|
() =>
|
||||||
|
({
|
||||||
|
getBlob: (callback: (blob: Blob | null) => void) => {
|
||||||
|
const blob = new Blob(['PDF content'], { type: 'application/pdf' });
|
||||||
|
|
||||||
|
callback(blob);
|
||||||
|
},
|
||||||
|
}) as any
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
vi.restoreAllMocks();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('successfully generates a PDF blob', async () => {
|
||||||
|
const blob = await generatePDFUPO(dummyFile);
|
||||||
|
|
||||||
|
expect(blob).toBeInstanceOf(Blob);
|
||||||
|
const text = await new Promise<string>((resolve, reject) => {
|
||||||
|
const reader = new FileReader();
|
||||||
|
|
||||||
|
reader.onload = (): void => resolve(reader.result as string);
|
||||||
|
reader.onerror = (): void => reject(reader.error);
|
||||||
|
reader.readAsText(blob);
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(text).toContain('PDF content');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('rejects promise if pdfMake returns null blob', async () => {
|
||||||
|
vi.spyOn(pdfMake, 'createPdf').mockReturnValue({
|
||||||
|
getBlob: (callback: (blob: Blob | null) => void) => {
|
||||||
|
callback(null);
|
||||||
|
},
|
||||||
|
} as any);
|
||||||
|
|
||||||
|
await expect(generatePDFUPO(dummyFile)).rejects.toEqual('Error');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('calls parseXML with the input file', async () => {
|
||||||
|
const parseXMLSpy = vi.spyOn(XMLParser, 'parseXML');
|
||||||
|
|
||||||
|
await generatePDFUPO(dummyFile);
|
||||||
|
expect(parseXMLSpy).toHaveBeenCalledWith(dummyFile);
|
||||||
|
});
|
||||||
|
});
|
||||||
35
src/lib-public/UPO-generator.ts
Normal file
35
src/lib-public/UPO-generator.ts
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
import pdfMake from 'pdfmake/build/pdfmake';
|
||||||
|
import { Upo } from './types/upo-v4_2.types';
|
||||||
|
import { TDocumentDefinitions } from 'pdfmake/interfaces';
|
||||||
|
import { generateStyle } from '../shared/PDF-functions';
|
||||||
|
import { parseXML } from '../shared/XML-parser';
|
||||||
|
import { Position } from '../shared/enums/common.enum';
|
||||||
|
import { generateDokumentUPO } from './generators/UPO4_3/Dokumenty';
|
||||||
|
import { generateNaglowekUPO } from './generators/UPO4_3/Naglowek';
|
||||||
|
|
||||||
|
export async function generatePDFUPO(file: File): Promise<Blob> {
|
||||||
|
const upo = (await parseXML(file)) as Upo;
|
||||||
|
const docDefinition: TDocumentDefinitions = {
|
||||||
|
content: [generateNaglowekUPO(upo.Potwierdzenie!), generateDokumentUPO(upo.Potwierdzenie!)],
|
||||||
|
...generateStyle(),
|
||||||
|
pageSize: 'A4',
|
||||||
|
pageOrientation: 'landscape',
|
||||||
|
footer: function (currentPage: number, pageCount: number) {
|
||||||
|
return {
|
||||||
|
text: currentPage.toString() + ' z ' + pageCount,
|
||||||
|
alignment: Position.RIGHT,
|
||||||
|
margin: [0, 0, 20, 0],
|
||||||
|
};
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
return new Promise((resolve, reject): void => {
|
||||||
|
pdfMake.createPdf(docDefinition).getBlob((blob: Blob): void => {
|
||||||
|
if (blob) {
|
||||||
|
resolve(blob);
|
||||||
|
} else {
|
||||||
|
reject('Error');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
@@ -52,7 +52,7 @@ export function generatePlatnosc(platnosc: Platnosc | undefined): Content {
|
|||||||
|
|
||||||
if (platnosc.Zaplacono?._text === '1') {
|
if (platnosc.Zaplacono?._text === '1') {
|
||||||
table.push(createLabelText('Informacja o płatności: ', 'Zapłacono'));
|
table.push(createLabelText('Informacja o płatności: ', 'Zapłacono'));
|
||||||
table.push(createLabelText('Data zapłaty: ', platnosc.DataZaplaty));
|
table.push(createLabelText('Data zapłaty: ', platnosc.DataZaplaty, FormatTyp.Date));
|
||||||
} else if (platnosc.ZaplataCzesciowa?._text === '1') {
|
} else if (platnosc.ZaplataCzesciowa?._text === '1') {
|
||||||
table.push(createLabelText('Informacja o płatności: ', 'Zapłata częściowa'));
|
table.push(createLabelText('Informacja o płatności: ', 'Zapłata częściowa'));
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -36,8 +36,11 @@ export function generatePodmiot2Podmiot2K(podmiot2: Podmiot2, podmiot2K: Podmiot
|
|||||||
columnGap: 20,
|
columnGap: 20,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
if(podmiot2K.Adres?.AdresPol || podmiot2K.Adres?.AdresZagr) {
|
||||||
firstColumn = generateCorrectedContent(podmiot2K, 'Treść korygowana');
|
firstColumn = generateCorrectedContent(podmiot2K, 'Treść korygowana');
|
||||||
secondColumn = generateCorrectedContent(podmiot2, 'Treść korygująca');
|
secondColumn = generateCorrectedContent(podmiot2, 'Treść korygująca');
|
||||||
|
}
|
||||||
|
|
||||||
if (podmiot2.AdresKoresp) {
|
if (podmiot2.AdresKoresp) {
|
||||||
secondColumn.push(
|
secondColumn.push(
|
||||||
generatePodmiotAdres(podmiot2.AdresKoresp, 'Adres do korespondencji', true, [0, 12, 0, 1.3])
|
generatePodmiotAdres(podmiot2.AdresKoresp, 'Adres do korespondencji', true, [0, 12, 0, 1.3])
|
||||||
|
|||||||
@@ -79,6 +79,7 @@ describe('getSummaryTaxRate', () => {
|
|||||||
gross: '123.00',
|
gross: '123.00',
|
||||||
});
|
});
|
||||||
expect(summary[1].taxRateString).toBe('8% lub 7%');
|
expect(summary[1].taxRateString).toBe('8% lub 7%');
|
||||||
|
expect(summary[3].taxRateString).toBe('4% lub 3%');
|
||||||
expect(summary[4].taxRateString).toBe('');
|
expect(summary[4].taxRateString).toBe('');
|
||||||
expect(summary[5].taxRateString).toBe('zwolnione z opodatkowania');
|
expect(summary[5].taxRateString).toBe('zwolnione z opodatkowania');
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -153,7 +153,7 @@ export function getSummaryTaxRate(fa: Fa): TaxSummaryTypes[] {
|
|||||||
gross: (getNumberRounded(fa.P_13_4) + getNumberRounded(fa.P_14_4)).toFixed(2),
|
gross: (getNumberRounded(fa.P_13_4) + getNumberRounded(fa.P_14_4)).toFixed(2),
|
||||||
tax: getNumberRounded(fa.P_14_4).toFixed(2),
|
tax: getNumberRounded(fa.P_14_4).toFixed(2),
|
||||||
taxPLN: getNumberRounded(fa.P_14_4W).toFixed(2),
|
taxPLN: getNumberRounded(fa.P_14_4W).toFixed(2),
|
||||||
taxRateString: '4% lub 3% lub oo',
|
taxRateString: '4% lub 3%',
|
||||||
});
|
});
|
||||||
no++;
|
no++;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -82,7 +82,7 @@ describe(generateRabat.name, () => {
|
|||||||
|
|
||||||
expect(PDFFunctions.getContentTable).toHaveBeenCalledWith(
|
expect(PDFFunctions.getContentTable).toHaveBeenCalledWith(
|
||||||
expect.arrayContaining([
|
expect.arrayContaining([
|
||||||
expect.objectContaining({ name: 'NrWierszaFay', title: 'Lp.' }),
|
expect.objectContaining({ name: 'NrWierszaFa', title: 'Lp.' }),
|
||||||
expect.objectContaining({ name: 'P_7', title: 'Nazwa towaru lub usługi' }),
|
expect.objectContaining({ name: 'P_7', title: 'Nazwa towaru lub usługi' }),
|
||||||
expect.objectContaining({ name: 'P_8B', title: 'Ilość' }),
|
expect.objectContaining({ name: 'P_8B', title: 'Ilość' }),
|
||||||
expect.objectContaining({ name: 'P_8A', title: 'Miara' }),
|
expect.objectContaining({ name: 'P_8A', title: 'Miara' }),
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ export function generateRabat(invoice: Fa): Content[] {
|
|||||||
const faRows: Record<string, FP>[] = getTable(invoice!.FaWiersze?.FaWiersz);
|
const faRows: Record<string, FP>[] = getTable(invoice!.FaWiersze?.FaWiersz);
|
||||||
const result: Content[] = [];
|
const result: Content[] = [];
|
||||||
const definedHeader: HeaderDefine[] = [
|
const definedHeader: HeaderDefine[] = [
|
||||||
{ name: 'NrWierszaFay', title: 'Lp.', format: FormatTyp.Default },
|
{ name: 'NrWierszaFa', title: 'Lp.', format: FormatTyp.Default },
|
||||||
{ name: 'P_7', title: 'Nazwa towaru lub usługi', format: FormatTyp.Default },
|
{ name: 'P_7', title: 'Nazwa towaru lub usługi', format: FormatTyp.Default },
|
||||||
{ name: 'P_8B', title: 'Ilość', format: FormatTyp.Default },
|
{ name: 'P_8B', title: 'Ilość', format: FormatTyp.Default },
|
||||||
{ name: 'P_8A', title: 'Miara', format: FormatTyp.Default },
|
{ name: 'P_8A', title: 'Miara', format: FormatTyp.Default },
|
||||||
|
|||||||
@@ -67,14 +67,19 @@ describe(generateSzczegoly.name, () => {
|
|||||||
describe('P_6 label', () => {
|
describe('P_6 label', () => {
|
||||||
it('uses "Data otrzymania zapłaty" for ZAL', () => {
|
it('uses "Data otrzymania zapłaty" for ZAL', () => {
|
||||||
generateSzczegoly({ ...mockFaVat, RodzajFaktury: TRodzajFaktury.ZAL } as any);
|
generateSzczegoly({ ...mockFaVat, RodzajFaktury: TRodzajFaktury.ZAL } as any);
|
||||||
expect(PDFFunctions.createLabelText).toHaveBeenCalledWith('Data otrzymania zapłaty: ', mockFaVat.P_6);
|
expect(PDFFunctions.createLabelText).toHaveBeenCalledWith(
|
||||||
|
'Data otrzymania zapłaty: ',
|
||||||
|
mockFaVat.P_6,
|
||||||
|
FormatTyp.Date
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('uses "Data dokonania lub zakończenia dostawy" for VAT', () => {
|
it('uses "Data dokonania lub zakończenia dostawy" for VAT', () => {
|
||||||
generateSzczegoly(mockFaVat);
|
generateSzczegoly(mockFaVat);
|
||||||
expect(PDFFunctions.createLabelText).toHaveBeenCalledWith(
|
expect(PDFFunctions.createLabelText).toHaveBeenCalledWith(
|
||||||
'Data dokonania lub zakończenia dostawy towarów lub wykonania usługi: ',
|
'Data dokonania lub zakończenia dostawy towarów lub wykonania usługi: ',
|
||||||
mockFaVat.P_6
|
mockFaVat.P_6,
|
||||||
|
FormatTyp.Date
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -82,10 +82,14 @@ export function generateSzczegoly(faVat: Fa): Content[] {
|
|||||||
|
|
||||||
const forColumns: Content[][] = [
|
const forColumns: Content[][] = [
|
||||||
createLabelText('Numer faktury: ', faVat.P_2),
|
createLabelText('Numer faktury: ', faVat.P_2),
|
||||||
createLabelText('Data wystawienia, z zastrzeżeniem art. 106na ust. 1 ustawy: ', faVat.P_1),
|
createLabelText(
|
||||||
|
'Data wystawienia, z zastrzeżeniem art. 106na ust. 1 ustawy: ',
|
||||||
|
faVat.P_1,
|
||||||
|
FormatTyp.Date
|
||||||
|
),
|
||||||
createLabelText('Miejsce wystawienia: ', faVat.P_1M),
|
createLabelText('Miejsce wystawienia: ', faVat.P_1M),
|
||||||
createLabelText('Okres, którego dotyczy rabat: ', faVat.OkresFaKorygowanej),
|
createLabelText('Okres, którego dotyczy rabat: ', faVat.OkresFaKorygowanej),
|
||||||
createLabelText(LabelP_6, faVat.P_6),
|
createLabelText(LabelP_6, faVat.P_6, FormatTyp.Date),
|
||||||
P_6Scope,
|
P_6Scope,
|
||||||
cenyLabel1,
|
cenyLabel1,
|
||||||
cenyLabel2,
|
cenyLabel2,
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { describe, it, expect, vi, beforeEach } from 'vitest';
|
import { describe, it, expect, vi, beforeEach } from 'vitest';
|
||||||
import * as PDFFunctions from '../../../shared/PDF-functions';
|
import * as PDFFunctions from '../../../shared/PDF-functions';
|
||||||
import FormatTyp from '../../../shared/enums/common.enum';
|
import FormatTyp from '../../../shared/enums/common.enum';
|
||||||
import { TRodzajFaktury } from '../../../shared/consts/const';
|
import {TRodzajFaktury} from '../../../shared/consts/const';
|
||||||
import { Fa } from '../../types/fa1.types';
|
import { Fa } from '../../types/fa1.types';
|
||||||
import { generateWiersze } from './Wiersze';
|
import { generateWiersze } from './Wiersze';
|
||||||
|
|
||||||
@@ -13,6 +13,7 @@ vi.mock('../../../shared/PDF-functions', () => ({
|
|||||||
getContentTable: vi.fn(),
|
getContentTable: vi.fn(),
|
||||||
getTable: vi.fn(),
|
getTable: vi.fn(),
|
||||||
getValue: vi.fn(),
|
getValue: vi.fn(),
|
||||||
|
getTStawkaPodatku: vi.fn()
|
||||||
}));
|
}));
|
||||||
|
|
||||||
describe(generateWiersze.name, () => {
|
describe(generateWiersze.name, () => {
|
||||||
@@ -27,6 +28,7 @@ describe(generateWiersze.name, () => {
|
|||||||
P_7: { _text: 'Product 1' },
|
P_7: { _text: 'Product 1' },
|
||||||
P_9A: { _text: '100' },
|
P_9A: { _text: '100' },
|
||||||
P_8B: { _text: '2' },
|
P_8B: { _text: '2' },
|
||||||
|
P_12: { _text: '23' },
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
KodWaluty: { _text: 'PLN' },
|
KodWaluty: { _text: 'PLN' },
|
||||||
@@ -106,7 +108,7 @@ describe(generateWiersze.name, () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should display "brutto" when P_11 is not in fieldsWithValue', () => {
|
it('should display "brutto" when P_11 is not in fieldsWithValue', () => {
|
||||||
vi.mocked(PDFFunctions.getTable).mockReturnValue([{ NrWierszaFa: { _text: '1' } }] as any);
|
vi.mocked(PDFFunctions.getTable).mockReturnValue([{ NrWierszaFa: { _text: '1' }, P_12: {_text: '23'} }] as any);
|
||||||
|
|
||||||
vi.mocked(PDFFunctions.getContentTable).mockReturnValue({
|
vi.mocked(PDFFunctions.getContentTable).mockReturnValue({
|
||||||
content: { table: {} } as any,
|
content: { table: {} } as any,
|
||||||
@@ -117,6 +119,7 @@ describe(generateWiersze.name, () => {
|
|||||||
vi.mocked(PDFFunctions.formatText).mockReturnValue('formatted text' as any);
|
vi.mocked(PDFFunctions.formatText).mockReturnValue('formatted text' as any);
|
||||||
vi.mocked(PDFFunctions.createHeader).mockReturnValue(['Header'] as any);
|
vi.mocked(PDFFunctions.createHeader).mockReturnValue(['Header'] as any);
|
||||||
vi.mocked(PDFFunctions.createSection).mockReturnValue({ section: 'content' } as any);
|
vi.mocked(PDFFunctions.createSection).mockReturnValue({ section: 'content' } as any);
|
||||||
|
vi.mocked(PDFFunctions.getTStawkaPodatku).mockReturnValue('23');
|
||||||
|
|
||||||
generateWiersze(mockFaVat);
|
generateWiersze(mockFaVat);
|
||||||
|
|
||||||
@@ -148,7 +151,7 @@ describe(generateWiersze.name, () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should generate two tables when fieldsWithValue.length > 8', () => {
|
it('should generate two tables when fieldsWithValue.length > 8', () => {
|
||||||
vi.mocked(PDFFunctions.getTable).mockReturnValue([{ NrWierszaFa: { _text: '1' } }] as any);
|
vi.mocked(PDFFunctions.getTable).mockReturnValue([{ NrWierszaFa: { _text: '1' }, P_12: {_text: '23'} }] as any);
|
||||||
|
|
||||||
vi.mocked(PDFFunctions.getContentTable)
|
vi.mocked(PDFFunctions.getContentTable)
|
||||||
.mockReturnValueOnce({
|
.mockReturnValueOnce({
|
||||||
@@ -175,7 +178,7 @@ describe(generateWiersze.name, () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should not add second table if it has only 1 field with value', () => {
|
it('should not add second table if it has only 1 field with value', () => {
|
||||||
vi.mocked(PDFFunctions.getTable).mockReturnValue([{ NrWierszaFa: { _text: '1' } }] as any);
|
vi.mocked(PDFFunctions.getTable).mockReturnValue([{ NrWierszaFa: { _text: '1' }, P_12: {_text: '23'} }] as any);
|
||||||
|
|
||||||
vi.mocked(PDFFunctions.getContentTable)
|
vi.mocked(PDFFunctions.getContentTable)
|
||||||
.mockReturnValueOnce({
|
.mockReturnValueOnce({
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import {
|
|||||||
formatText,
|
formatText,
|
||||||
getContentTable,
|
getContentTable,
|
||||||
getTable,
|
getTable,
|
||||||
|
getTStawkaPodatku,
|
||||||
getValue,
|
getValue,
|
||||||
} from '../../../shared/PDF-functions';
|
} from '../../../shared/PDF-functions';
|
||||||
import { HeaderDefine } from '../../../shared/types/pdf-types';
|
import { HeaderDefine } from '../../../shared/types/pdf-types';
|
||||||
@@ -13,16 +14,20 @@ import { Procedura, TRodzajFaktury } from '../../../shared/consts/const';
|
|||||||
import { Fa, FP } from '../../types/fa1.types';
|
import { Fa, FP } from '../../types/fa1.types';
|
||||||
import FormatTyp, { Position } from '../../../shared/enums/common.enum';
|
import FormatTyp, { Position } from '../../../shared/enums/common.enum';
|
||||||
import { FormContentState } from '../../../shared/types/additional-data.types';
|
import { FormContentState } from '../../../shared/types/additional-data.types';
|
||||||
import { shouldAddMarza } from '../common/Wiersze';
|
import { addMarza } from '../common/Wiersze';
|
||||||
|
|
||||||
export function generateWiersze(faVat: Fa): Content {
|
export function generateWiersze(faVat: Fa): Content {
|
||||||
const table: Content[] = [];
|
const table: Content[] = [];
|
||||||
const rodzajFaktury: string | number | undefined = getValue(faVat.RodzajFaktury);
|
const rodzajFaktury: string | number | undefined = getValue(faVat.RodzajFaktury);
|
||||||
const isP_PMarzy: boolean = Boolean(Number(getValue(faVat.Adnotacje?.P_PMarzy)));
|
const isP_PMarzy = Boolean(Number(getValue(faVat.Adnotacje?.P_PMarzy)));
|
||||||
const faWiersze: Record<string, FP>[] = getTable(faVat.FaWiersze?.FaWiersz).map(
|
const faWiersze: Record<string, FP>[] = getTable(faVat.FaWiersze?.FaWiersz).map(
|
||||||
(wiersz: Record<string, FP>): Record<string, FP> => {
|
(wiersz: Record<string, FP>): Record<string, FP> => {
|
||||||
const marza: Record<string, FP> = shouldAddMarza(rodzajFaktury, isP_PMarzy, wiersz)!;
|
const marza: Record<string, FP> = addMarza(rodzajFaktury, isP_PMarzy, wiersz)!;
|
||||||
return marza ? { ...wiersz, ...marza } : wiersz;
|
|
||||||
|
if (getValue(wiersz.P_12)) {
|
||||||
|
wiersz.P_12._text = getTStawkaPodatku(getValue(wiersz.P_12) as string, 1);
|
||||||
|
}
|
||||||
|
return { ...wiersz, ...marza };
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
const definedHeaderLp: HeaderDefine[] = [
|
const definedHeaderLp: HeaderDefine[] = [
|
||||||
@@ -33,7 +38,7 @@ export function generateWiersze(faVat: Fa): Content {
|
|||||||
{ name: 'P_7', title: 'Nazwa towaru lub usługi', format: FormatTyp.Default, width: '*' },
|
{ name: 'P_7', title: 'Nazwa towaru lub usługi', format: FormatTyp.Default, width: '*' },
|
||||||
{ name: 'P_9A', title: 'Cena jedn. netto', format: FormatTyp.Currency, width: 'auto' },
|
{ name: 'P_9A', title: 'Cena jedn. netto', format: FormatTyp.Currency, width: 'auto' },
|
||||||
{ name: 'P_9B', title: 'Cena jedn. brutto', format: FormatTyp.Currency, width: 'auto' },
|
{ name: 'P_9B', title: 'Cena jedn. brutto', format: FormatTyp.Currency, width: 'auto' },
|
||||||
{ name: 'P_8B', title: 'Ilość', format: FormatTyp.Right, width: 'auto' },
|
{ name: 'P_8B', title: 'Ilość', format: FormatTyp.Number, width: 'auto' },
|
||||||
{ name: 'P_8A', title: 'Miara', format: FormatTyp.Default, width: 'auto' },
|
{ name: 'P_8A', title: 'Miara', format: FormatTyp.Default, width: 'auto' },
|
||||||
{ name: 'P_10', title: 'Rabat', format: FormatTyp.Currency, width: 'auto' },
|
{ name: 'P_10', title: 'Rabat', format: FormatTyp.Currency, width: 'auto' },
|
||||||
{ name: 'P_12', title: 'Stawka podatku', format: FormatTyp.Default, width: 'auto' },
|
{ name: 'P_12', title: 'Stawka podatku', format: FormatTyp.Default, width: 'auto' },
|
||||||
|
|||||||
@@ -12,6 +12,8 @@ vi.mock('../../../shared/PDF-functions', () => ({
|
|||||||
formatText: vi.fn(),
|
formatText: vi.fn(),
|
||||||
getContentTable: vi.fn(),
|
getContentTable: vi.fn(),
|
||||||
getTable: vi.fn(),
|
getTable: vi.fn(),
|
||||||
|
getValue: vi.fn(),
|
||||||
|
getTStawkaPodatku: vi.fn()
|
||||||
}));
|
}));
|
||||||
|
|
||||||
describe(generateZamowienie.name, () => {
|
describe(generateZamowienie.name, () => {
|
||||||
|
|||||||
@@ -5,6 +5,8 @@ import {
|
|||||||
formatText,
|
formatText,
|
||||||
getContentTable,
|
getContentTable,
|
||||||
getTable,
|
getTable,
|
||||||
|
getTStawkaPodatku,
|
||||||
|
getValue,
|
||||||
} from '../../../shared/PDF-functions';
|
} from '../../../shared/PDF-functions';
|
||||||
import { HeaderDefine } from '../../../shared/types/pdf-types';
|
import { HeaderDefine } from '../../../shared/types/pdf-types';
|
||||||
import { Procedura, TRodzajFaktury } from '../../../shared/consts/const';
|
import { Procedura, TRodzajFaktury } from '../../../shared/consts/const';
|
||||||
@@ -29,6 +31,9 @@ export function generateZamowienie(
|
|||||||
if (!el.NrWierszaZam._text) {
|
if (!el.NrWierszaZam._text) {
|
||||||
el.NrWierszaZam._text = (index + 1).toString();
|
el.NrWierszaZam._text = (index + 1).toString();
|
||||||
}
|
}
|
||||||
|
if (getValue(el.P_12)) {
|
||||||
|
el.P_12._text = getTStawkaPodatku(getValue(el.P_12) as string, 1);
|
||||||
|
}
|
||||||
return el;
|
return el;
|
||||||
});
|
});
|
||||||
const definedHeaderLp: HeaderDefine[] = [
|
const definedHeaderLp: HeaderDefine[] = [
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ vi.mock('../../../shared/PDF-functions', () => ({
|
|||||||
formatText: vi.fn((text: string) => ({ text })),
|
formatText: vi.fn((text: string) => ({ text })),
|
||||||
getTable: vi.fn(() => []),
|
getTable: vi.fn(() => []),
|
||||||
hasValue: vi.fn((v) => !!v?._text),
|
hasValue: vi.fn((v) => !!v?._text),
|
||||||
|
getValue: vi.fn((v) => v?._text || v),
|
||||||
verticalSpacing: vi.fn((n: number) => ({ text: `space-${n}` })),
|
verticalSpacing: vi.fn((n: number) => ({ text: `space-${n}` })),
|
||||||
generateColumns: vi.fn((left, right) => ({ columns: [left, right] })),
|
generateColumns: vi.fn((left, right) => ({ columns: [left, right] })),
|
||||||
}));
|
}));
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import {
|
|||||||
formatText,
|
formatText,
|
||||||
generateColumns,
|
generateColumns,
|
||||||
getTable,
|
getTable,
|
||||||
|
getValue,
|
||||||
hasValue,
|
hasValue,
|
||||||
verticalSpacing,
|
verticalSpacing,
|
||||||
} from '../../../shared/PDF-functions';
|
} from '../../../shared/PDF-functions';
|
||||||
@@ -169,6 +170,19 @@ export function generateDostawy(noweSrodkiTransportu: NoweSrodkiTransportu): Con
|
|||||||
} else if (anyP22D) {
|
} else if (anyP22D) {
|
||||||
value.push('Dostawa dotyczy statków powietrznych, o których mowa w art. 2 pkt 10 lit. c ustawy');
|
value.push('Dostawa dotyczy statków powietrznych, o których mowa w art. 2 pkt 10 lit. c ustawy');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const transportProperties = [
|
||||||
|
getValue(item.P_22BMK),
|
||||||
|
getValue(item.P_22BMD),
|
||||||
|
getValue(item.P_22BK),
|
||||||
|
getValue(item.P_22BNR),
|
||||||
|
getValue(item.P_22BRP),
|
||||||
|
].filter((prop) => !!prop);
|
||||||
|
|
||||||
|
if (transportProperties.length) {
|
||||||
|
value.push(transportProperties.join(', '));
|
||||||
|
}
|
||||||
|
|
||||||
if (item.DetailsString?._text) {
|
if (item.DetailsString?._text) {
|
||||||
value.push(item.DetailsString._text);
|
value.push(item.DetailsString._text);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ export function generatePlatnosc(platnosc: Platnosc | undefined): Content {
|
|||||||
|
|
||||||
if (platnosc.Zaplacono?._text === '1') {
|
if (platnosc.Zaplacono?._text === '1') {
|
||||||
table.push(createLabelText('Informacja o płatności: ', 'Zapłacono'));
|
table.push(createLabelText('Informacja o płatności: ', 'Zapłacono'));
|
||||||
table.push(createLabelText('Data zapłaty: ', platnosc.DataZaplaty));
|
table.push(createLabelText('Data zapłaty: ', platnosc.DataZaplaty, FormatTyp.Date));
|
||||||
} else if (platnosc.ZnacznikZaplatyCzesciowej?._text === '1') {
|
} else if (platnosc.ZnacznikZaplatyCzesciowej?._text === '1') {
|
||||||
table.push(createLabelText('Informacja o płatności: ', 'Zapłata częściowa'));
|
table.push(createLabelText('Informacja o płatności: ', 'Zapłata częściowa'));
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -36,8 +36,12 @@ export function generatePodmiot2Podmiot2K(podmiot2: Podmiot2, podmiot2K: Podmiot
|
|||||||
columnGap: 20,
|
columnGap: 20,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(podmiot2K.Adres?.AdresL1?._text) {
|
||||||
firstColumn = generateCorrectedContent(podmiot2K, 'Treść korygowana');
|
firstColumn = generateCorrectedContent(podmiot2K, 'Treść korygowana');
|
||||||
secondColumn = generateCorrectedContent(podmiot2, 'Treść korygująca');
|
secondColumn = generateCorrectedContent(podmiot2, 'Treść korygująca');
|
||||||
|
}
|
||||||
|
|
||||||
if (podmiot2.AdresKoresp) {
|
if (podmiot2.AdresKoresp) {
|
||||||
secondColumn.push(
|
secondColumn.push(
|
||||||
formatText('Adres do korespondencji', [FormatTyp.Label, FormatTyp.LabelMargin]),
|
formatText('Adres do korespondencji', [FormatTyp.Label, FormatTyp.LabelMargin]),
|
||||||
|
|||||||
@@ -140,7 +140,7 @@ describe(generatePodsumowanieStawekPodatkuVat.name, () => {
|
|||||||
expect(summary[0].taxRateString).toBe('23% lub 22%');
|
expect(summary[0].taxRateString).toBe('23% lub 22%');
|
||||||
expect(summary[1].taxRateString).toBe('8% lub 7%');
|
expect(summary[1].taxRateString).toBe('8% lub 7%');
|
||||||
expect(summary[2].taxRateString).toBe('5%');
|
expect(summary[2].taxRateString).toBe('5%');
|
||||||
expect(summary[3].taxRateString).toBe('4% lub 3% lub oo');
|
expect(summary[3].taxRateString).toBe('4% lub 3%');
|
||||||
expect(summary[4].taxRateString).toBe('');
|
expect(summary[4].taxRateString).toBe('');
|
||||||
expect(summary[5].taxRateString).toBe('0% - krajowe');
|
expect(summary[5].taxRateString).toBe('0% - krajowe');
|
||||||
expect(summary[6].taxRateString).toBe('0% - wdt');
|
expect(summary[6].taxRateString).toBe('0% - wdt');
|
||||||
@@ -148,6 +148,7 @@ describe(generatePodsumowanieStawekPodatkuVat.name, () => {
|
|||||||
expect(summary[8].taxRateString).toBe('zwolnione z opodatkowania');
|
expect(summary[8].taxRateString).toBe('zwolnione z opodatkowania');
|
||||||
expect(summary[9].taxRateString).toBe('np z wyłączeniem art. 100 ust 1 pkt 4 ustawy');
|
expect(summary[9].taxRateString).toBe('np z wyłączeniem art. 100 ust 1 pkt 4 ustawy');
|
||||||
expect(summary[10].taxRateString).toBe('np na podstawie art. 100 ust. 1 pkt 4 ustawy');
|
expect(summary[10].taxRateString).toBe('np na podstawie art. 100 ust. 1 pkt 4 ustawy');
|
||||||
|
expect(summary[11].taxRateString).toBe('odwrotne obciążenie');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('handles reverse charge and margin', () => {
|
it('handles reverse charge and margin', () => {
|
||||||
|
|||||||
@@ -173,7 +173,7 @@ export function getSummaryTaxRate(fa: Fa): TaxSummaryTypes[] {
|
|||||||
gross: (getNumberRounded(fa.P_13_4) + getNumberRounded(fa.P_14_4)).toFixed(2),
|
gross: (getNumberRounded(fa.P_13_4) + getNumberRounded(fa.P_14_4)).toFixed(2),
|
||||||
tax: getNumberRounded(fa.P_14_4).toFixed(2),
|
tax: getNumberRounded(fa.P_14_4).toFixed(2),
|
||||||
taxPLN: getNumberRounded(fa.P_14_4W).toFixed(2),
|
taxPLN: getNumberRounded(fa.P_14_4W).toFixed(2),
|
||||||
taxRateString: '4% lub 3% lub oo',
|
taxRateString: '4% lub 3%',
|
||||||
});
|
});
|
||||||
no++;
|
no++;
|
||||||
}
|
}
|
||||||
@@ -217,8 +217,8 @@ export function getSummaryTaxRate(fa: Fa): TaxSummaryTypes[] {
|
|||||||
if (AnyP13_6_3Diff0) {
|
if (AnyP13_6_3Diff0) {
|
||||||
summary.push({
|
summary.push({
|
||||||
no,
|
no,
|
||||||
net: getNumberRounded(fa.P_13_6_2).toFixed(2),
|
net: getNumberRounded(fa.P_13_6_3).toFixed(2),
|
||||||
gross: getNumberRounded(fa.P_13_6_2).toFixed(2),
|
gross: getNumberRounded(fa.P_13_6_3).toFixed(2),
|
||||||
tax: '0.00',
|
tax: '0.00',
|
||||||
taxPLN: '',
|
taxPLN: '',
|
||||||
taxRateString: '0% - eksport',
|
taxRateString: '0% - eksport',
|
||||||
|
|||||||
@@ -82,7 +82,7 @@ describe(generateRabat.name, () => {
|
|||||||
|
|
||||||
expect(PDFFunctions.getContentTable).toHaveBeenCalledWith(
|
expect(PDFFunctions.getContentTable).toHaveBeenCalledWith(
|
||||||
expect.arrayContaining([
|
expect.arrayContaining([
|
||||||
expect.objectContaining({ name: 'NrWierszaFay', title: 'Lp.' }),
|
expect.objectContaining({ name: 'NrWierszaFa', title: 'Lp.' }),
|
||||||
expect.objectContaining({ name: 'P_7', title: 'Nazwa towaru lub usługi' }),
|
expect.objectContaining({ name: 'P_7', title: 'Nazwa towaru lub usługi' }),
|
||||||
expect.objectContaining({ name: 'P_8B', title: 'Ilość' }),
|
expect.objectContaining({ name: 'P_8B', title: 'Ilość' }),
|
||||||
expect.objectContaining({ name: 'P_8A', title: 'Miara' }),
|
expect.objectContaining({ name: 'P_8A', title: 'Miara' }),
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ export function generateRabat(invoice: Fa): Content[] {
|
|||||||
const faRows: Record<string, FP>[] = getTable(invoice!.FaWiersz);
|
const faRows: Record<string, FP>[] = getTable(invoice!.FaWiersz);
|
||||||
const result: Content[] = [];
|
const result: Content[] = [];
|
||||||
const definedHeader: HeaderDefine[] = [
|
const definedHeader: HeaderDefine[] = [
|
||||||
{ name: 'NrWierszaFay', title: 'Lp.', format: FormatTyp.Default },
|
{ name: 'NrWierszaFa', title: 'Lp.', format: FormatTyp.Default },
|
||||||
{ name: 'P_7', title: 'Nazwa towaru lub usługi', format: FormatTyp.Default },
|
{ name: 'P_7', title: 'Nazwa towaru lub usługi', format: FormatTyp.Default },
|
||||||
{ name: 'P_8B', title: 'Ilość', format: FormatTyp.Default },
|
{ name: 'P_8B', title: 'Ilość', format: FormatTyp.Default },
|
||||||
{ name: 'P_8A', title: 'Miara', format: FormatTyp.Default },
|
{ name: 'P_8A', title: 'Miara', format: FormatTyp.Default },
|
||||||
|
|||||||
@@ -96,7 +96,11 @@ describe(generateSzczegoly.name, () => {
|
|||||||
|
|
||||||
generateSzczegoly(data);
|
generateSzczegoly(data);
|
||||||
|
|
||||||
expect(PDFFunctions.createLabelText).toHaveBeenCalledWith('Data otrzymania zapłaty: ', data.P_6);
|
expect(PDFFunctions.createLabelText).toHaveBeenCalledWith(
|
||||||
|
'Data otrzymania zapłaty: ',
|
||||||
|
data.P_6,
|
||||||
|
FormatTyp.Date
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should use "Data otrzymania zapłaty" label for KOR_ZAL invoice', () => {
|
it('should use "Data otrzymania zapłaty" label for KOR_ZAL invoice', () => {
|
||||||
@@ -107,7 +111,11 @@ describe(generateSzczegoly.name, () => {
|
|||||||
|
|
||||||
generateSzczegoly(data);
|
generateSzczegoly(data);
|
||||||
|
|
||||||
expect(PDFFunctions.createLabelText).toHaveBeenCalledWith('Data otrzymania zapłaty: ', data.P_6);
|
expect(PDFFunctions.createLabelText).toHaveBeenCalledWith(
|
||||||
|
'Data otrzymania zapłaty: ',
|
||||||
|
data.P_6,
|
||||||
|
FormatTyp.Date
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should use "Data dokonania lub zakończenia dostawy" label for other invoice types', () => {
|
it('should use "Data dokonania lub zakończenia dostawy" label for other invoice types', () => {
|
||||||
@@ -120,7 +128,8 @@ describe(generateSzczegoly.name, () => {
|
|||||||
|
|
||||||
expect(PDFFunctions.createLabelText).toHaveBeenCalledWith(
|
expect(PDFFunctions.createLabelText).toHaveBeenCalledWith(
|
||||||
'Data dokonania lub zakończenia dostawy towarów lub wykonania usługi: ',
|
'Data dokonania lub zakończenia dostawy towarów lub wykonania usługi: ',
|
||||||
data.P_6
|
data.P_6,
|
||||||
|
FormatTyp.Date
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -386,7 +395,8 @@ describe(generateSzczegoly.name, () => {
|
|||||||
|
|
||||||
expect(PDFFunctions.createLabelText).toHaveBeenCalledWith(
|
expect(PDFFunctions.createLabelText).toHaveBeenCalledWith(
|
||||||
'Data wystawienia, z zastrzeżeniem art. 106na ust. 1 ustawy: ',
|
'Data wystawienia, z zastrzeżeniem art. 106na ust. 1 ustawy: ',
|
||||||
mockFaVat.P_1
|
mockFaVat.P_1,
|
||||||
|
FormatTyp.Date
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -546,7 +556,7 @@ describe(generateSzczegoly.name, () => {
|
|||||||
expect(PDFFunctions.getContentTable).toHaveBeenCalledWith(
|
expect(PDFFunctions.getContentTable).toHaveBeenCalledWith(
|
||||||
expect.arrayContaining([
|
expect.arrayContaining([
|
||||||
expect.objectContaining({
|
expect.objectContaining({
|
||||||
name: 'NrKSeFFaZaliczkowej',
|
name: 'NrFaZaliczkowej',
|
||||||
title: 'Numery wcześniejszych faktur zaliczkowych',
|
title: 'Numery wcześniejszych faktur zaliczkowych',
|
||||||
}),
|
}),
|
||||||
]),
|
]),
|
||||||
|
|||||||
@@ -74,10 +74,14 @@ export function generateSzczegoly(faVat: Fa): Content[] {
|
|||||||
const tpLabel2: Content[] = [];
|
const tpLabel2: Content[] = [];
|
||||||
|
|
||||||
const forColumns: Content[][] = [
|
const forColumns: Content[][] = [
|
||||||
createLabelText('Data wystawienia, z zastrzeżeniem art. 106na ust. 1 ustawy: ', faVat.P_1),
|
createLabelText(
|
||||||
|
'Data wystawienia, z zastrzeżeniem art. 106na ust. 1 ustawy: ',
|
||||||
|
faVat.P_1,
|
||||||
|
FormatTyp.Date
|
||||||
|
),
|
||||||
createLabelText('Miejsce wystawienia: ', faVat.P_1M),
|
createLabelText('Miejsce wystawienia: ', faVat.P_1M),
|
||||||
createLabelText('Okres, którego dotyczy rabat: ', faVat.OkresFaKorygowanej),
|
createLabelText('Okres, którego dotyczy rabat: ', faVat.OkresFaKorygowanej),
|
||||||
createLabelText(LabelP_6, faVat.P_6),
|
createLabelText(LabelP_6, faVat.P_6, FormatTyp.Date),
|
||||||
P_6Scope,
|
P_6Scope,
|
||||||
cenyLabel1,
|
cenyLabel1,
|
||||||
cenyLabel2,
|
cenyLabel2,
|
||||||
@@ -163,11 +167,22 @@ function generateFakturaZaliczkowa(fakturaZaliczkowaData: ObjectKeysOfFP[] | und
|
|||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
const fakturaZaliczkowa = getTable(fakturaZaliczkowaData) as unknown as FA2FakturaZaliczkowaData[];
|
const fakturaZaliczkowa = getTable(fakturaZaliczkowaData) as unknown as FA2FakturaZaliczkowaData[];
|
||||||
|
const fakturaZaliczkowaMapped = fakturaZaliczkowa.map(item => {
|
||||||
|
const fp =
|
||||||
|
(
|
||||||
|
'NrFaZaliczkowej' in item && item.NrFaZaliczkowej
|
||||||
|
) ? item.NrFaZaliczkowej : ('NrKSeFFaZaliczkowej' in item ? item.NrKSeFFaZaliczkowej : undefined );
|
||||||
|
|
||||||
|
return{
|
||||||
|
...item,
|
||||||
|
NrFaZaliczkowej : fp ?? { _text: ''},
|
||||||
|
};
|
||||||
|
})
|
||||||
const table: Content[] = [];
|
const table: Content[] = [];
|
||||||
|
|
||||||
const fakturaZaliczkowaHeader: HeaderDefine[] = [
|
const fakturaZaliczkowaHeader: HeaderDefine[] = [
|
||||||
{
|
{
|
||||||
name: 'NrKSeFFaZaliczkowej',
|
name: 'NrFaZaliczkowej',
|
||||||
title: 'Numery wcześniejszych faktur zaliczkowych',
|
title: 'Numery wcześniejszych faktur zaliczkowych',
|
||||||
format: FormatTyp.Default,
|
format: FormatTyp.Default,
|
||||||
},
|
},
|
||||||
@@ -175,7 +190,7 @@ function generateFakturaZaliczkowa(fakturaZaliczkowaData: ObjectKeysOfFP[] | und
|
|||||||
|
|
||||||
const tableFakturaZaliczkowa: TableWithFields = getContentTable<(typeof fakturaZaliczkowa)[0]>(
|
const tableFakturaZaliczkowa: TableWithFields = getContentTable<(typeof fakturaZaliczkowa)[0]>(
|
||||||
fakturaZaliczkowaHeader,
|
fakturaZaliczkowaHeader,
|
||||||
fakturaZaliczkowa,
|
fakturaZaliczkowaMapped,
|
||||||
'auto',
|
'auto',
|
||||||
[0, 4, 0, 0]
|
[0, 4, 0, 0]
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ vi.mock('../../../shared/PDF-functions', () => ({
|
|||||||
getContentTable: vi.fn(),
|
getContentTable: vi.fn(),
|
||||||
getTable: vi.fn(),
|
getTable: vi.fn(),
|
||||||
getValue: vi.fn(),
|
getValue: vi.fn(),
|
||||||
|
getTStawkaPodatku: vi.fn()
|
||||||
}));
|
}));
|
||||||
|
|
||||||
describe(generateWiersze.name, () => {
|
describe(generateWiersze.name, () => {
|
||||||
@@ -27,6 +28,7 @@ describe(generateWiersze.name, () => {
|
|||||||
P_7: { _text: 'Product 1' },
|
P_7: { _text: 'Product 1' },
|
||||||
P_9A: { _text: '100' },
|
P_9A: { _text: '100' },
|
||||||
P_8B: { _text: '2' },
|
P_8B: { _text: '2' },
|
||||||
|
P_12: { _text: '23' },
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
KodWaluty: { _text: 'PLN' },
|
KodWaluty: { _text: 'PLN' },
|
||||||
@@ -106,7 +108,7 @@ describe(generateWiersze.name, () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should display "brutto" when P_11 is not in fieldsWithValue', () => {
|
it('should display "brutto" when P_11 is not in fieldsWithValue', () => {
|
||||||
vi.mocked(PDFFunctions.getTable).mockReturnValue([{ NrWierszaFa: { _text: '1' } }] as any);
|
vi.mocked(PDFFunctions.getTable).mockReturnValue([{ NrWierszaFa: { _text: '1' }, P_12: {_text: '23'} }] as any);
|
||||||
|
|
||||||
vi.mocked(PDFFunctions.getContentTable).mockReturnValue({
|
vi.mocked(PDFFunctions.getContentTable).mockReturnValue({
|
||||||
content: { table: {} } as any,
|
content: { table: {} } as any,
|
||||||
@@ -148,7 +150,7 @@ describe(generateWiersze.name, () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should generate two tables when fieldsWithValue.length > 8', () => {
|
it('should generate two tables when fieldsWithValue.length > 8', () => {
|
||||||
vi.mocked(PDFFunctions.getTable).mockReturnValue([{ NrWierszaFa: { _text: '1' } }] as any);
|
vi.mocked(PDFFunctions.getTable).mockReturnValue([{ NrWierszaFa: { _text: '1' }, P_12: {_text: '23'} }] as any);
|
||||||
|
|
||||||
vi.mocked(PDFFunctions.getContentTable)
|
vi.mocked(PDFFunctions.getContentTable)
|
||||||
.mockReturnValueOnce({
|
.mockReturnValueOnce({
|
||||||
@@ -175,7 +177,7 @@ describe(generateWiersze.name, () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should not add second table if it has only 1 field with value', () => {
|
it('should not add second table if it has only 1 field with value', () => {
|
||||||
vi.mocked(PDFFunctions.getTable).mockReturnValue([{ NrWierszaFa: { _text: '1' } }] as any);
|
vi.mocked(PDFFunctions.getTable).mockReturnValue([{ NrWierszaFa: { _text: '1' }, P_12: {_text: '23'} }] as any);
|
||||||
|
|
||||||
vi.mocked(PDFFunctions.getContentTable)
|
vi.mocked(PDFFunctions.getContentTable)
|
||||||
.mockReturnValueOnce({
|
.mockReturnValueOnce({
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import {
|
|||||||
formatText,
|
formatText,
|
||||||
getContentTable,
|
getContentTable,
|
||||||
getTable,
|
getTable,
|
||||||
|
getTStawkaPodatku,
|
||||||
getValue,
|
getValue,
|
||||||
} from '../../../shared/PDF-functions';
|
} from '../../../shared/PDF-functions';
|
||||||
import { HeaderDefine } from '../../../shared/types/pdf-types';
|
import { HeaderDefine } from '../../../shared/types/pdf-types';
|
||||||
@@ -13,15 +14,19 @@ import { TRodzajFaktury } from '../../../shared/consts/const';
|
|||||||
import { Fa, FP } from '../../types/fa2.types';
|
import { Fa, FP } from '../../types/fa2.types';
|
||||||
import FormatTyp, { Position } from '../../../shared/enums/common.enum';
|
import FormatTyp, { Position } from '../../../shared/enums/common.enum';
|
||||||
import { TableWithFields } from '../../types/fa1-additional-types';
|
import { TableWithFields } from '../../types/fa1-additional-types';
|
||||||
import { shouldAddMarza } from '../common/Wiersze';
|
import { addMarza } from '../common/Wiersze';
|
||||||
|
|
||||||
export function generateWiersze(faVat: Fa): Content {
|
export function generateWiersze(faVat: Fa): Content {
|
||||||
const table: Content[] = [];
|
const table: Content[] = [];
|
||||||
const rodzajFaktury: string | number | undefined = getValue(faVat.RodzajFaktury);
|
const rodzajFaktury: string | number | undefined = getValue(faVat.RodzajFaktury);
|
||||||
const isP_PMarzy: boolean = Boolean(Number(getValue(faVat.Adnotacje?.PMarzy?.P_PMarzy)));
|
const isP_PMarzy = Boolean(Number(getValue(faVat.Adnotacje?.PMarzy?.P_PMarzy)));
|
||||||
const faWiersze: Record<string, FP>[] = getTable(faVat.FaWiersz).map((wiersz) => {
|
const faWiersze: Record<string, FP>[] = getTable(faVat.FaWiersz).map((wiersz) => {
|
||||||
const marza: Record<string, FP> = shouldAddMarza(rodzajFaktury, isP_PMarzy, wiersz)!;
|
const marza: Record<string, FP> = addMarza(rodzajFaktury, isP_PMarzy, wiersz)!;
|
||||||
return marza ? { ...wiersz, ...marza } : wiersz;
|
|
||||||
|
if (getValue(wiersz.P_12)) {
|
||||||
|
wiersz.P_12._text = getTStawkaPodatku(getValue(wiersz.P_12) as string, 2);
|
||||||
|
}
|
||||||
|
return { ...wiersz, ...marza };
|
||||||
});
|
});
|
||||||
|
|
||||||
const definedHeaderLp: HeaderDefine[] = [
|
const definedHeaderLp: HeaderDefine[] = [
|
||||||
@@ -32,7 +37,7 @@ export function generateWiersze(faVat: Fa): Content {
|
|||||||
{ name: 'P_7', title: 'Nazwa towaru lub usługi', format: FormatTyp.Default, width: '*' },
|
{ name: 'P_7', title: 'Nazwa towaru lub usługi', format: FormatTyp.Default, width: '*' },
|
||||||
{ name: 'P_9A', title: 'Cena jedn. netto', format: FormatTyp.Currency, width: 'auto' },
|
{ name: 'P_9A', title: 'Cena jedn. netto', format: FormatTyp.Currency, width: 'auto' },
|
||||||
{ name: 'P_9B', title: 'Cena jedn. brutto', format: FormatTyp.Currency, width: 'auto' },
|
{ name: 'P_9B', title: 'Cena jedn. brutto', format: FormatTyp.Currency, width: 'auto' },
|
||||||
{ name: 'P_8B', title: 'Ilość', format: FormatTyp.Right, width: 'auto' },
|
{ name: 'P_8B', title: 'Ilość', format: FormatTyp.Number, width: 'auto' },
|
||||||
{ name: 'P_8A', title: 'Miara', format: FormatTyp.Default, width: 'auto' },
|
{ name: 'P_8A', title: 'Miara', format: FormatTyp.Default, width: 'auto' },
|
||||||
{ name: 'P_10', title: 'Rabat', format: FormatTyp.Currency, width: 'auto' },
|
{ name: 'P_10', title: 'Rabat', format: FormatTyp.Currency, width: 'auto' },
|
||||||
{ name: 'P_12', title: 'Stawka podatku', format: FormatTyp.Default, width: 'auto' },
|
{ name: 'P_12', title: 'Stawka podatku', format: FormatTyp.Default, width: 'auto' },
|
||||||
|
|||||||
@@ -12,6 +12,8 @@ vi.mock('../../../shared/PDF-functions', () => ({
|
|||||||
formatText: vi.fn(),
|
formatText: vi.fn(),
|
||||||
getContentTable: vi.fn(),
|
getContentTable: vi.fn(),
|
||||||
getTable: vi.fn(),
|
getTable: vi.fn(),
|
||||||
|
getValue: vi.fn(),
|
||||||
|
getTStawkaPodatku: vi.fn()
|
||||||
}));
|
}));
|
||||||
|
|
||||||
describe(generateZamowienie.name, () => {
|
describe(generateZamowienie.name, () => {
|
||||||
|
|||||||
@@ -5,6 +5,8 @@ import {
|
|||||||
formatText,
|
formatText,
|
||||||
getContentTable,
|
getContentTable,
|
||||||
getTable,
|
getTable,
|
||||||
|
getTStawkaPodatku,
|
||||||
|
getValue,
|
||||||
} from '../../../shared/PDF-functions';
|
} from '../../../shared/PDF-functions';
|
||||||
import { HeaderDefine } from '../../../shared/types/pdf-types';
|
import { HeaderDefine } from '../../../shared/types/pdf-types';
|
||||||
import { TRodzajFaktury } from '../../../shared/consts/const';
|
import { TRodzajFaktury } from '../../../shared/consts/const';
|
||||||
@@ -29,6 +31,9 @@ export function generateZamowienie(
|
|||||||
if (!el.NrWierszaZam._text) {
|
if (!el.NrWierszaZam._text) {
|
||||||
el.NrWierszaZam._text = (index + 1).toString();
|
el.NrWierszaZam._text = (index + 1).toString();
|
||||||
}
|
}
|
||||||
|
if (getValue(el.P_12)) {
|
||||||
|
el.P_12._text = getTStawkaPodatku(getValue(el.P_12) as string, 2);
|
||||||
|
}
|
||||||
return el;
|
return el;
|
||||||
});
|
});
|
||||||
const definedHeaderLp: HeaderDefine[] = [
|
const definedHeaderLp: HeaderDefine[] = [
|
||||||
@@ -56,6 +61,7 @@ export function generateZamowienie(
|
|||||||
{ name: 'P_11NettoZ', title: 'Wartość sprzedaży netto', format: formatAbs, width: 'auto' },
|
{ name: 'P_11NettoZ', title: 'Wartość sprzedaży netto', format: formatAbs, width: 'auto' },
|
||||||
{ name: 'P_11VatZ', title: 'Kwota podatku', format: formatAbs, width: 'auto' },
|
{ name: 'P_11VatZ', title: 'Kwota podatku', format: formatAbs, width: 'auto' },
|
||||||
];
|
];
|
||||||
|
|
||||||
const definedHeader2: HeaderDefine[] = [
|
const definedHeader2: HeaderDefine[] = [
|
||||||
{ name: 'UU_IDZ', title: 'Numer umowy / Zamów.', format: FormatTyp.Default, width: 'auto' },
|
{ name: 'UU_IDZ', title: 'Numer umowy / Zamów.', format: FormatTyp.Default, width: 'auto' },
|
||||||
{ name: 'GTINZ', title: 'GTIN', format: FormatTyp.Default, width: 'auto' },
|
{ name: 'GTINZ', title: 'GTIN', format: FormatTyp.Default, width: 'auto' },
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ vi.mock('../../../shared/PDF-functions', () => ({
|
|||||||
formatText: vi.fn((text: string) => ({ text })),
|
formatText: vi.fn((text: string) => ({ text })),
|
||||||
getTable: vi.fn(() => []),
|
getTable: vi.fn(() => []),
|
||||||
hasValue: vi.fn((v) => !!v?._text),
|
hasValue: vi.fn((v) => !!v?._text),
|
||||||
|
getValue: vi.fn((v) => v?._text || v),
|
||||||
verticalSpacing: vi.fn((n: number) => ({ text: `space-${n}` })),
|
verticalSpacing: vi.fn((n: number) => ({ text: `space-${n}` })),
|
||||||
generateColumns: vi.fn((left, right) => ({ columns: [left, right] })),
|
generateColumns: vi.fn((left, right) => ({ columns: [left, right] })),
|
||||||
}));
|
}));
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import {
|
|||||||
formatText,
|
formatText,
|
||||||
generateColumns,
|
generateColumns,
|
||||||
getTable,
|
getTable,
|
||||||
|
getValue,
|
||||||
hasValue,
|
hasValue,
|
||||||
verticalSpacing,
|
verticalSpacing,
|
||||||
} from '../../../shared/PDF-functions';
|
} from '../../../shared/PDF-functions';
|
||||||
@@ -199,6 +200,19 @@ export function generateDostawy(noweSrodkiTransportu: NoweSrodkiTransportu): Con
|
|||||||
} else if (anyP22D) {
|
} else if (anyP22D) {
|
||||||
value.push('Dostawa dotyczy statków powietrznych, o których mowa w art. 2 pkt 10 lit. c ustawy');
|
value.push('Dostawa dotyczy statków powietrznych, o których mowa w art. 2 pkt 10 lit. c ustawy');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const transportProperties = [
|
||||||
|
getValue(item.P_22BMK),
|
||||||
|
getValue(item.P_22BMD),
|
||||||
|
getValue(item.P_22BK),
|
||||||
|
getValue(item.P_22BNR),
|
||||||
|
getValue(item.P_22BRP),
|
||||||
|
].filter((prop) => !!prop);
|
||||||
|
|
||||||
|
if (transportProperties.length) {
|
||||||
|
value.push(transportProperties.join(', '));
|
||||||
|
}
|
||||||
|
|
||||||
if (item.DetailsString?._text) {
|
if (item.DetailsString?._text) {
|
||||||
value.push(item.DetailsString._text);
|
value.push(item.DetailsString._text);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ export function generatePlatnosc(platnosc: Platnosc | undefined): Content {
|
|||||||
// TODO: Add to FA2 and FA1? (KSEF20-15289)
|
// TODO: Add to FA2 and FA1? (KSEF20-15289)
|
||||||
if (getValue(platnosc.Zaplacono) === '1') {
|
if (getValue(platnosc.Zaplacono) === '1') {
|
||||||
table.push(createLabelText('Informacja o płatności: ', 'Zapłacono'));
|
table.push(createLabelText('Informacja o płatności: ', 'Zapłacono'));
|
||||||
table.push(createLabelText('Data zapłaty: ', platnosc.DataZaplaty));
|
table.push(createLabelText('Data zapłaty: ', platnosc.DataZaplaty, FormatTyp.Date));
|
||||||
} else if (
|
} else if (
|
||||||
getValue(platnosc.ZnacznikZaplatyCzesciowej) === '1' ||
|
getValue(platnosc.ZnacznikZaplatyCzesciowej) === '1' ||
|
||||||
getValue(platnosc.ZnacznikZaplatyCzesciowej) === '2'
|
getValue(platnosc.ZnacznikZaplatyCzesciowej) === '2'
|
||||||
|
|||||||
@@ -38,8 +38,11 @@ export function generatePodmiot2Podmiot2K(podmiot2: Podmiot2, podmiot2K: Podmiot
|
|||||||
columnGap: 20,
|
columnGap: 20,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(podmiot2K.Adres?.AdresL1?._text){
|
||||||
firstColumn = generateCorrectedContent(podmiot2K, 'Treść korygowana');
|
firstColumn = generateCorrectedContent(podmiot2K, 'Treść korygowana');
|
||||||
secondColumn = generateCorrectedContent(podmiot2, 'Treść korygująca');
|
secondColumn = generateCorrectedContent(podmiot2, 'Treść korygująca');
|
||||||
|
}
|
||||||
|
|
||||||
if (podmiot2.AdresKoresp) {
|
if (podmiot2.AdresKoresp) {
|
||||||
secondColumn.push(
|
secondColumn.push(
|
||||||
|
|||||||
@@ -139,14 +139,15 @@ describe(generatePodsumowanieStawekPodatkuVat.name, () => {
|
|||||||
expect(summary[0].taxRateString).toBe('23% lub 22%');
|
expect(summary[0].taxRateString).toBe('23% lub 22%');
|
||||||
expect(summary[1].taxRateString).toBe('8% lub 7%');
|
expect(summary[1].taxRateString).toBe('8% lub 7%');
|
||||||
expect(summary[2].taxRateString).toBe('5%');
|
expect(summary[2].taxRateString).toBe('5%');
|
||||||
expect(summary[3].taxRateString).toBe('4% lub 3% lub oo');
|
expect(summary[3].taxRateString).toBe('4% lub 3%');
|
||||||
expect(summary[4].taxRateString).toBe('');
|
expect(summary[4].taxRateString).toBe('');
|
||||||
expect(summary[5].taxRateString).toBe('0% - krajowe');
|
expect(summary[5].taxRateString).toBe('0% w przypadku sprzedaży towarów i świadczenia usług na terytorium kraju (z wyłączeniem WDT i eksportu)');
|
||||||
expect(summary[6].taxRateString).toBe('0% - wdt');
|
expect(summary[6].taxRateString).toBe('0% w przypadku wewnątrzwspólnotowej dostawy towarów (WDT)');
|
||||||
expect(summary[7].taxRateString).toBe('0% - eksport');
|
expect(summary[7].taxRateString).toBe('0% w przypadku eksportu towarów');
|
||||||
expect(summary[8].taxRateString).toBe('zwolnione z opodatkowania');
|
expect(summary[8].taxRateString).toBe('zwolnione od podatku');
|
||||||
expect(summary[9].taxRateString).toBe('np z wyłączeniem art. 100 ust 1 pkt 4 ustawy');
|
expect(summary[9].taxRateString).toBe('np z wyłączeniem art. 100 ust 1 pkt 4 ustawy');
|
||||||
expect(summary[10].taxRateString).toBe('np na podstawie art. 100 ust. 1 pkt 4 ustawy');
|
expect(summary[10].taxRateString).toBe('np na podstawie art. 100 ust. 1 pkt 4 ustawy');
|
||||||
|
expect(summary[11].taxRateString).toBe('odwrotne obciążenie');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('handles reverse charge and margin', () => {
|
it('handles reverse charge and margin', () => {
|
||||||
|
|||||||
@@ -177,7 +177,7 @@ export function getSummaryTaxRate(fa: Fa): TaxSummaryTypes[] {
|
|||||||
gross: (getNumberRounded(fa.P_13_4) + getNumberRounded(fa.P_14_4)).toFixed(2),
|
gross: (getNumberRounded(fa.P_13_4) + getNumberRounded(fa.P_14_4)).toFixed(2),
|
||||||
tax: getNumberRounded(fa.P_14_4).toFixed(2),
|
tax: getNumberRounded(fa.P_14_4).toFixed(2),
|
||||||
taxPLN: getNumberRounded(fa.P_14_4W).toFixed(2),
|
taxPLN: getNumberRounded(fa.P_14_4W).toFixed(2),
|
||||||
taxRateString: '4% lub 3% lub oo',
|
taxRateString: '4% lub 3%',
|
||||||
});
|
});
|
||||||
no++;
|
no++;
|
||||||
}
|
}
|
||||||
@@ -201,7 +201,7 @@ export function getSummaryTaxRate(fa: Fa): TaxSummaryTypes[] {
|
|||||||
gross: getNumberRounded(fa.P_13_6_1).toFixed(2),
|
gross: getNumberRounded(fa.P_13_6_1).toFixed(2),
|
||||||
tax: '0.00',
|
tax: '0.00',
|
||||||
taxPLN: '',
|
taxPLN: '',
|
||||||
taxRateString: '0% - krajowe',
|
taxRateString: '0% w przypadku sprzedaży towarów i świadczenia usług na terytorium kraju (z wyłączeniem WDT i eksportu)',
|
||||||
});
|
});
|
||||||
no++;
|
no++;
|
||||||
}
|
}
|
||||||
@@ -213,7 +213,7 @@ export function getSummaryTaxRate(fa: Fa): TaxSummaryTypes[] {
|
|||||||
gross: getNumberRounded(fa.P_13_6_2).toFixed(2),
|
gross: getNumberRounded(fa.P_13_6_2).toFixed(2),
|
||||||
tax: '0.00',
|
tax: '0.00',
|
||||||
taxPLN: '',
|
taxPLN: '',
|
||||||
taxRateString: '0% - wdt',
|
taxRateString: '0% w przypadku wewnątrzwspólnotowej dostawy towarów (WDT)',
|
||||||
});
|
});
|
||||||
no++;
|
no++;
|
||||||
}
|
}
|
||||||
@@ -221,11 +221,11 @@ export function getSummaryTaxRate(fa: Fa): TaxSummaryTypes[] {
|
|||||||
if (AnyP13_6_3Diff0) {
|
if (AnyP13_6_3Diff0) {
|
||||||
summary.push({
|
summary.push({
|
||||||
no,
|
no,
|
||||||
net: getNumberRounded(fa.P_13_6_2).toFixed(2),
|
net: getNumberRounded(fa.P_13_6_3).toFixed(2),
|
||||||
gross: getNumberRounded(fa.P_13_6_2).toFixed(2),
|
gross: getNumberRounded(fa.P_13_6_3).toFixed(2),
|
||||||
tax: '0.00',
|
tax: '0.00',
|
||||||
taxPLN: '',
|
taxPLN: '',
|
||||||
taxRateString: '0% - eksport',
|
taxRateString: '0% w przypadku eksportu towarów',
|
||||||
});
|
});
|
||||||
no++;
|
no++;
|
||||||
}
|
}
|
||||||
@@ -237,7 +237,7 @@ export function getSummaryTaxRate(fa: Fa): TaxSummaryTypes[] {
|
|||||||
gross: getNumberRounded(fa.P_13_7).toFixed(2),
|
gross: getNumberRounded(fa.P_13_7).toFixed(2),
|
||||||
tax: '0.00',
|
tax: '0.00',
|
||||||
taxPLN: '',
|
taxPLN: '',
|
||||||
taxRateString: 'zwolnione z opodatkowania',
|
taxRateString: 'zwolnione od podatku',
|
||||||
});
|
});
|
||||||
no++;
|
no++;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -83,7 +83,7 @@ describe(generateRabat.name, () => {
|
|||||||
|
|
||||||
expect(PDFFunctions.getContentTable).toHaveBeenCalledWith(
|
expect(PDFFunctions.getContentTable).toHaveBeenCalledWith(
|
||||||
expect.arrayContaining([
|
expect.arrayContaining([
|
||||||
expect.objectContaining({ name: 'NrWierszaFay', title: 'Lp.' }),
|
expect.objectContaining({ name: 'NrWierszaFa', title: 'Lp.' }),
|
||||||
expect.objectContaining({ name: 'P_7', title: 'Nazwa towaru lub usługi' }),
|
expect.objectContaining({ name: 'P_7', title: 'Nazwa towaru lub usługi' }),
|
||||||
expect.objectContaining({ name: 'P_8B', title: 'Ilość' }),
|
expect.objectContaining({ name: 'P_8B', title: 'Ilość' }),
|
||||||
expect.objectContaining({ name: 'P_8A', title: 'Miara' }),
|
expect.objectContaining({ name: 'P_8A', title: 'Miara' }),
|
||||||
|
|||||||
@@ -16,12 +16,13 @@ export function generateRabat(invoice: Fa): Content[] {
|
|||||||
const faRows = getTable(invoice!.FaWiersz);
|
const faRows = getTable(invoice!.FaWiersz);
|
||||||
const result: Content[] = [];
|
const result: Content[] = [];
|
||||||
const definedHeader: HeaderDefine[] = [
|
const definedHeader: HeaderDefine[] = [
|
||||||
{ name: 'NrWierszaFay', title: 'Lp.', format: FormatTyp.Default },
|
{ name: 'NrWierszaFa', title: 'Lp.', format: FormatTyp.Default },
|
||||||
{ name: 'P_7', title: 'Nazwa towaru lub usługi', format: FormatTyp.Default },
|
{ name: 'P_7', title: 'Nazwa towaru lub usługi', format: FormatTyp.Default },
|
||||||
{ name: 'P_8B', title: 'Ilość', format: FormatTyp.Default },
|
{ name: 'P_8B', title: 'Ilość', format: FormatTyp.Default },
|
||||||
{ name: 'P_8A', title: 'Miara', format: FormatTyp.Default },
|
{ name: 'P_8A', title: 'Miara', format: FormatTyp.Default },
|
||||||
];
|
];
|
||||||
const tabRabat = getContentTable<(typeof faRows)[0]>(definedHeader, faRows, '*');
|
const tabRabat = getContentTable<(typeof faRows)[0]>(definedHeader, faRows, '*');
|
||||||
|
|
||||||
const isNrWierszaFa = tabRabat.fieldsWithValue.includes('NrWierszaFa');
|
const isNrWierszaFa = tabRabat.fieldsWithValue.includes('NrWierszaFa');
|
||||||
|
|
||||||
result.push(
|
result.push(
|
||||||
|
|||||||
@@ -96,7 +96,11 @@ describe(generateSzczegoly.name, () => {
|
|||||||
|
|
||||||
generateSzczegoly(data);
|
generateSzczegoly(data);
|
||||||
|
|
||||||
expect(PDFFunctions.createLabelText).toHaveBeenCalledWith('Data otrzymania zapłaty: ', data.P_6);
|
expect(PDFFunctions.createLabelText).toHaveBeenCalledWith(
|
||||||
|
'Data otrzymania zapłaty: ',
|
||||||
|
data.P_6,
|
||||||
|
FormatTyp.Date
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should use "Data otrzymania zapłaty" label for KOR_ZAL invoice', () => {
|
it('should use "Data otrzymania zapłaty" label for KOR_ZAL invoice', () => {
|
||||||
@@ -107,7 +111,11 @@ describe(generateSzczegoly.name, () => {
|
|||||||
|
|
||||||
generateSzczegoly(data);
|
generateSzczegoly(data);
|
||||||
|
|
||||||
expect(PDFFunctions.createLabelText).toHaveBeenCalledWith('Data otrzymania zapłaty: ', data.P_6);
|
expect(PDFFunctions.createLabelText).toHaveBeenCalledWith(
|
||||||
|
'Data otrzymania zapłaty: ',
|
||||||
|
data.P_6,
|
||||||
|
FormatTyp.Date
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should use "Data dokonania lub zakończenia dostawy" label for other invoice types', () => {
|
it('should use "Data dokonania lub zakończenia dostawy" label for other invoice types', () => {
|
||||||
@@ -120,7 +128,8 @@ describe(generateSzczegoly.name, () => {
|
|||||||
|
|
||||||
expect(PDFFunctions.createLabelText).toHaveBeenCalledWith(
|
expect(PDFFunctions.createLabelText).toHaveBeenCalledWith(
|
||||||
'Data dokonania lub zakończenia dostawy towarów lub wykonania usługi: ',
|
'Data dokonania lub zakończenia dostawy towarów lub wykonania usługi: ',
|
||||||
data.P_6
|
data.P_6,
|
||||||
|
FormatTyp.Date
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -386,7 +395,8 @@ describe(generateSzczegoly.name, () => {
|
|||||||
|
|
||||||
expect(PDFFunctions.createLabelText).toHaveBeenCalledWith(
|
expect(PDFFunctions.createLabelText).toHaveBeenCalledWith(
|
||||||
'Data wystawienia, z zastrzeżeniem art. 106na ust. 1 ustawy: ',
|
'Data wystawienia, z zastrzeżeniem art. 106na ust. 1 ustawy: ',
|
||||||
mockFaVat.P_1
|
mockFaVat.P_1,
|
||||||
|
FormatTyp.Date
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -546,7 +556,7 @@ describe(generateSzczegoly.name, () => {
|
|||||||
expect(PDFFunctions.getContentTable).toHaveBeenCalledWith(
|
expect(PDFFunctions.getContentTable).toHaveBeenCalledWith(
|
||||||
expect.arrayContaining([
|
expect.arrayContaining([
|
||||||
expect.objectContaining({
|
expect.objectContaining({
|
||||||
name: 'NrKSeFFaZaliczkowej',
|
name: 'NrFaZaliczkowej',
|
||||||
title: 'Numery wcześniejszych faktur zaliczkowych',
|
title: 'Numery wcześniejszych faktur zaliczkowych',
|
||||||
}),
|
}),
|
||||||
]),
|
]),
|
||||||
|
|||||||
@@ -71,10 +71,14 @@ export function generateSzczegoly(faVat: Fa): Content[] {
|
|||||||
const tpLabel2: Content[] = [];
|
const tpLabel2: Content[] = [];
|
||||||
|
|
||||||
const forColumns = [
|
const forColumns = [
|
||||||
createLabelText('Data wystawienia, z zastrzeżeniem art. 106na ust. 1 ustawy: ', faVat.P_1),
|
createLabelText(
|
||||||
|
'Data wystawienia, z zastrzeżeniem art. 106na ust. 1 ustawy: ',
|
||||||
|
faVat.P_1,
|
||||||
|
FormatTyp.Date
|
||||||
|
),
|
||||||
createLabelText('Miejsce wystawienia: ', faVat.P_1M),
|
createLabelText('Miejsce wystawienia: ', faVat.P_1M),
|
||||||
createLabelText('Okres, którego dotyczy rabat: ', faVat.OkresFaKorygowanej),
|
createLabelText('Okres, którego dotyczy rabat: ', faVat.OkresFaKorygowanej),
|
||||||
createLabelText(LabelP_6, faVat.P_6),
|
createLabelText(LabelP_6, faVat.P_6, FormatTyp.Date),
|
||||||
P_6Scope,
|
P_6Scope,
|
||||||
cenyLabel1,
|
cenyLabel1,
|
||||||
cenyLabel2,
|
cenyLabel2,
|
||||||
@@ -160,11 +164,22 @@ function generateFakturaZaliczkowa(fakturaZaliczkowaData: ObjectKeysOfFP[] | und
|
|||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
const fakturaZaliczkowa = getTable(fakturaZaliczkowaData) as unknown as FA3FakturaZaliczkowaData[];
|
const fakturaZaliczkowa = getTable(fakturaZaliczkowaData) as unknown as FA3FakturaZaliczkowaData[];
|
||||||
|
const fakturaZaliczkowaMapped = fakturaZaliczkowa.map(item => {
|
||||||
|
const fp =
|
||||||
|
(
|
||||||
|
'NrFaZaliczkowej' in item && item.NrFaZaliczkowej
|
||||||
|
) ? item.NrFaZaliczkowej : ('NrKSeFFaZaliczkowej' in item ? item.NrKSeFFaZaliczkowej : undefined );
|
||||||
|
|
||||||
|
return{
|
||||||
|
...item,
|
||||||
|
NrFaZaliczkowej : fp ?? { _text: ''},
|
||||||
|
};
|
||||||
|
})
|
||||||
const table: Content[] = [];
|
const table: Content[] = [];
|
||||||
|
|
||||||
const fakturaZaliczkowaHeader: HeaderDefine[] = [
|
const fakturaZaliczkowaHeader: HeaderDefine[] = [
|
||||||
{
|
{
|
||||||
name: 'NrKSeFFaZaliczkowej',
|
name: 'NrFaZaliczkowej',
|
||||||
title: 'Numery wcześniejszych faktur zaliczkowych',
|
title: 'Numery wcześniejszych faktur zaliczkowych',
|
||||||
format: FormatTyp.Default,
|
format: FormatTyp.Default,
|
||||||
},
|
},
|
||||||
@@ -172,7 +187,7 @@ function generateFakturaZaliczkowa(fakturaZaliczkowaData: ObjectKeysOfFP[] | und
|
|||||||
|
|
||||||
const tableFakturaZaliczkowa = getContentTable<(typeof fakturaZaliczkowa)[0]>(
|
const tableFakturaZaliczkowa = getContentTable<(typeof fakturaZaliczkowa)[0]>(
|
||||||
fakturaZaliczkowaHeader,
|
fakturaZaliczkowaHeader,
|
||||||
fakturaZaliczkowa,
|
fakturaZaliczkowaMapped,
|
||||||
'auto',
|
'auto',
|
||||||
[0, 4, 0, 0]
|
[0, 4, 0, 0]
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -12,7 +12,8 @@ vi.mock('../../../shared/PDF-functions', () => ({
|
|||||||
formatText: vi.fn(),
|
formatText: vi.fn(),
|
||||||
getContentTable: vi.fn(),
|
getContentTable: vi.fn(),
|
||||||
getTable: vi.fn(),
|
getTable: vi.fn(),
|
||||||
getValue: vi.fn(),
|
getValue: vi.fn((v) => v?._text || v),
|
||||||
|
getTStawkaPodatku: vi.fn()
|
||||||
}));
|
}));
|
||||||
|
|
||||||
describe(generateWiersze.name, () => {
|
describe(generateWiersze.name, () => {
|
||||||
@@ -27,6 +28,7 @@ describe(generateWiersze.name, () => {
|
|||||||
P_7: { _text: 'Product 1' },
|
P_7: { _text: 'Product 1' },
|
||||||
P_9A: { _text: '100' },
|
P_9A: { _text: '100' },
|
||||||
P_8B: { _text: '2' },
|
P_8B: { _text: '2' },
|
||||||
|
P_12: { _text: '23' },
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
KodWaluty: { _text: 'PLN' },
|
KodWaluty: { _text: 'PLN' },
|
||||||
@@ -59,6 +61,8 @@ describe(generateWiersze.name, () => {
|
|||||||
vi.mocked(PDFFunctions.createHeader).mockReturnValue(['Header'] as any);
|
vi.mocked(PDFFunctions.createHeader).mockReturnValue(['Header'] as any);
|
||||||
vi.mocked(PDFFunctions.createSection).mockReturnValue({ section: 'content' } as any);
|
vi.mocked(PDFFunctions.createSection).mockReturnValue({ section: 'content' } as any);
|
||||||
vi.mocked(PDFFunctions.createLabelTextArray).mockReturnValue(['Label', 'Value'] as any);
|
vi.mocked(PDFFunctions.createLabelTextArray).mockReturnValue(['Label', 'Value'] as any);
|
||||||
|
vi.mocked(PDFFunctions.getTStawkaPodatku).mockReturnValue('0' as any);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
describe('when no invoice lines exist', () => {
|
describe('when no invoice lines exist', () => {
|
||||||
@@ -106,11 +110,11 @@ describe(generateWiersze.name, () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should display "brutto" when P_11 is not in fieldsWithValue', () => {
|
it('should display "brutto" when P_11 is not in fieldsWithValue', () => {
|
||||||
vi.mocked(PDFFunctions.getTable).mockReturnValue([{ NrWierszaFa: { _text: '1' } }] as any);
|
vi.mocked(PDFFunctions.getTable).mockReturnValue([{ NrWierszaFa: { _text: '1' }, P_12: {_text: '23'} }] as any);
|
||||||
|
|
||||||
vi.mocked(PDFFunctions.getContentTable).mockReturnValue({
|
vi.mocked(PDFFunctions.getContentTable).mockReturnValue({
|
||||||
content: { table: {} } as any,
|
content: { table: {} } as any,
|
||||||
fieldsWithValue: ['P_11A', 'P_7'],
|
fieldsWithValue: ['P_11A', 'P_7', 'P12'],
|
||||||
});
|
});
|
||||||
|
|
||||||
vi.mocked(PDFFunctions.getValue).mockReturnValue('0');
|
vi.mocked(PDFFunctions.getValue).mockReturnValue('0');
|
||||||
@@ -148,7 +152,7 @@ describe(generateWiersze.name, () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should generate two tables when fieldsWithValue.length > 8', () => {
|
it('should generate two tables when fieldsWithValue.length > 8', () => {
|
||||||
vi.mocked(PDFFunctions.getTable).mockReturnValue([{ NrWierszaFa: { _text: '1' } }] as any);
|
vi.mocked(PDFFunctions.getTable).mockReturnValue([{ NrWierszaFa: { _text: '1' }, P_12: {_text: '23'} }] as any);
|
||||||
|
|
||||||
vi.mocked(PDFFunctions.getContentTable)
|
vi.mocked(PDFFunctions.getContentTable)
|
||||||
.mockReturnValueOnce({
|
.mockReturnValueOnce({
|
||||||
@@ -175,7 +179,7 @@ describe(generateWiersze.name, () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should not add second table if it has only 1 field with value', () => {
|
it('should not add second table if it has only 1 field with value', () => {
|
||||||
vi.mocked(PDFFunctions.getTable).mockReturnValue([{ NrWierszaFa: { _text: '1' } }] as any);
|
vi.mocked(PDFFunctions.getTable).mockReturnValue([{ NrWierszaFa: { _text: '1' }, P_12: {_text: '23'} }] as any);
|
||||||
|
|
||||||
vi.mocked(PDFFunctions.getContentTable)
|
vi.mocked(PDFFunctions.getContentTable)
|
||||||
.mockReturnValueOnce({
|
.mockReturnValueOnce({
|
||||||
|
|||||||
@@ -6,22 +6,27 @@ import {
|
|||||||
formatText,
|
formatText,
|
||||||
getContentTable,
|
getContentTable,
|
||||||
getTable,
|
getTable,
|
||||||
|
getTStawkaPodatku,
|
||||||
getValue,
|
getValue,
|
||||||
} from '../../../shared/PDF-functions';
|
} from '../../../shared/PDF-functions';
|
||||||
import { HeaderDefine } from '../../../shared/types/pdf-types';
|
import { HeaderDefine } from '../../../shared/types/pdf-types';
|
||||||
import { TRodzajFaktury } from '../../../shared/consts/const';
|
import { TRodzajFaktury } from '../../../shared/consts/const';
|
||||||
import { Fa, FP } from '../../types/fa3.types';
|
import { Fa, FP } from '../../types/fa3.types';
|
||||||
import FormatTyp, { Position } from '../../../shared/enums/common.enum';
|
import FormatTyp, { Position } from '../../../shared/enums/common.enum';
|
||||||
import { shouldAddMarza } from '../common/Wiersze';
|
import { addMarza } from '../common/Wiersze';
|
||||||
|
|
||||||
export function generateWiersze(faVat: Fa): Content {
|
export function generateWiersze(faVat: Fa): Content {
|
||||||
const table: Content[] = [];
|
const table: Content[] = [];
|
||||||
const rodzajFaktury: string | number | undefined = getValue(faVat.RodzajFaktury);
|
const rodzajFaktury: string | number | undefined = getValue(faVat.RodzajFaktury);
|
||||||
const isP_PMarzy: boolean = Boolean(Number(getValue(faVat.Adnotacje?.PMarzy?.P_PMarzy)));
|
const isP_PMarzy = Boolean(Number(getValue(faVat.Adnotacje?.PMarzy?.P_PMarzy)));
|
||||||
const faWiersze: Record<string, FP>[] = getTable(faVat.FaWiersz).map(
|
const faWiersze: Record<string, FP>[] = getTable(faVat.FaWiersz).map(
|
||||||
(wiersz: Record<string, FP>): Record<string, FP> => {
|
(wiersz: Record<string, FP>): Record<string, FP> => {
|
||||||
const marza: Record<string, FP> = shouldAddMarza(rodzajFaktury, isP_PMarzy, wiersz)!;
|
const marza: Record<string, FP> = addMarza(rodzajFaktury, isP_PMarzy, wiersz)!;
|
||||||
return marza ? { ...wiersz, ...marza } : wiersz;
|
|
||||||
|
if (getValue(wiersz.P_12)) {
|
||||||
|
wiersz.P_12._text = getTStawkaPodatku(getValue(wiersz.P_12) as string, 3);
|
||||||
|
}
|
||||||
|
return { ...wiersz, ...marza };
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
const definedHeaderLp: HeaderDefine[] = [
|
const definedHeaderLp: HeaderDefine[] = [
|
||||||
@@ -32,7 +37,7 @@ export function generateWiersze(faVat: Fa): Content {
|
|||||||
{ name: 'P_7', title: 'Nazwa towaru lub usługi', format: FormatTyp.Default, width: '*' },
|
{ name: 'P_7', title: 'Nazwa towaru lub usługi', format: FormatTyp.Default, width: '*' },
|
||||||
{ name: 'P_9A', title: 'Cena jedn. netto', format: FormatTyp.Currency, width: 'auto' },
|
{ name: 'P_9A', title: 'Cena jedn. netto', format: FormatTyp.Currency, width: 'auto' },
|
||||||
{ name: 'P_9B', title: 'Cena jedn. brutto', format: FormatTyp.Currency, width: 'auto' },
|
{ name: 'P_9B', title: 'Cena jedn. brutto', format: FormatTyp.Currency, width: 'auto' },
|
||||||
{ name: 'P_8B', title: 'Ilość', format: FormatTyp.Right, width: 'auto' },
|
{ name: 'P_8B', title: 'Ilość', format: FormatTyp.Number, width: 'auto' },
|
||||||
{ name: 'P_8A', title: 'Miara', format: FormatTyp.Default, width: 'auto' },
|
{ name: 'P_8A', title: 'Miara', format: FormatTyp.Default, width: 'auto' },
|
||||||
{ name: 'P_10', title: 'Rabat', format: FormatTyp.Currency, width: 'auto' },
|
{ name: 'P_10', title: 'Rabat', format: FormatTyp.Currency, width: 'auto' },
|
||||||
{ name: 'P_12', title: 'Stawka podatku', format: FormatTyp.Default, width: 'auto' },
|
{ name: 'P_12', title: 'Stawka podatku', format: FormatTyp.Default, width: 'auto' },
|
||||||
|
|||||||
@@ -12,6 +12,8 @@ vi.mock('../../../shared/PDF-functions', () => ({
|
|||||||
formatText: vi.fn(),
|
formatText: vi.fn(),
|
||||||
getContentTable: vi.fn(),
|
getContentTable: vi.fn(),
|
||||||
getTable: vi.fn(),
|
getTable: vi.fn(),
|
||||||
|
getValue: vi.fn(),
|
||||||
|
getTStawkaPodatku: vi.fn()
|
||||||
}));
|
}));
|
||||||
|
|
||||||
describe(generateZamowienie.name, () => {
|
describe(generateZamowienie.name, () => {
|
||||||
|
|||||||
@@ -5,6 +5,8 @@ import {
|
|||||||
formatText,
|
formatText,
|
||||||
getContentTable,
|
getContentTable,
|
||||||
getTable,
|
getTable,
|
||||||
|
getTStawkaPodatku,
|
||||||
|
getValue,
|
||||||
} from '../../../shared/PDF-functions';
|
} from '../../../shared/PDF-functions';
|
||||||
import { HeaderDefine } from '../../../shared/types/pdf-types';
|
import { HeaderDefine } from '../../../shared/types/pdf-types';
|
||||||
import { TRodzajFaktury } from '../../../shared/consts/const';
|
import { TRodzajFaktury } from '../../../shared/consts/const';
|
||||||
@@ -28,6 +30,9 @@ export function generateZamowienie(
|
|||||||
if (!el.NrWierszaZam._text) {
|
if (!el.NrWierszaZam._text) {
|
||||||
el.NrWierszaZam._text = (index + 1).toString();
|
el.NrWierszaZam._text = (index + 1).toString();
|
||||||
}
|
}
|
||||||
|
if (getValue(el.P_12Z)) {
|
||||||
|
el.P_12Z._text = getTStawkaPodatku(getValue(el.P_12Z) as string, 3);
|
||||||
|
}
|
||||||
return el;
|
return el;
|
||||||
});
|
});
|
||||||
const definedHeaderLp: HeaderDefine[] = [
|
const definedHeaderLp: HeaderDefine[] = [
|
||||||
|
|||||||
123
src/lib-public/generators/UPO4_3/Dokumenty.spec.ts
Normal file
123
src/lib-public/generators/UPO4_3/Dokumenty.spec.ts
Normal file
@@ -0,0 +1,123 @@
|
|||||||
|
import { beforeEach, describe, expect, it, vi } from 'vitest';
|
||||||
|
import * as PDFFunctions from '../../../shared/PDF-functions';
|
||||||
|
import FormatTyp from '../../../shared/enums/common.enum';
|
||||||
|
import { Potwierdzenie } from '../../types/upo-v4_3.types';
|
||||||
|
import { generateDokumentUPO } from './Dokumenty';
|
||||||
|
|
||||||
|
vi.mock('../../../shared/PDF-functions', () => ({
|
||||||
|
formatText: vi.fn(),
|
||||||
|
generateLine: vi.fn(),
|
||||||
|
getContentTable: vi.fn(),
|
||||||
|
getTable: vi.fn(),
|
||||||
|
getValue: vi.fn(),
|
||||||
|
hasValue: vi.fn(),
|
||||||
|
verticalSpacing: vi.fn(),
|
||||||
|
}));
|
||||||
|
|
||||||
|
describe(generateDokumentUPO.name, () => {
|
||||||
|
let mockPotwierdzenie: Potwierdzenie;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
vi.clearAllMocks();
|
||||||
|
|
||||||
|
mockPotwierdzenie = {
|
||||||
|
NumerReferencyjnySesji: { _text: 'NR123' },
|
||||||
|
OpisPotwierdzenia: {
|
||||||
|
Strona: { _text: '1' },
|
||||||
|
LiczbaStron: { _text: '2' },
|
||||||
|
ZakresDokumentowOd: { _text: 'FA001' },
|
||||||
|
ZakresDokumentowDo: { _text: 'FA002' },
|
||||||
|
CalkowitaLiczbaDokumentow: { _text: '2' },
|
||||||
|
},
|
||||||
|
Uwierzytelnienie: {
|
||||||
|
IdKontekstu: {
|
||||||
|
NIP: { _text: '1234567890' },
|
||||||
|
},
|
||||||
|
SkrotDokumentuUwierzytelniajacego: { _text: 'ABC123' },
|
||||||
|
},
|
||||||
|
NazwaStrukturyLogicznej: { _text: 'XSD' },
|
||||||
|
KodFormularza: { _text: 'K123' },
|
||||||
|
Dokument: [
|
||||||
|
{
|
||||||
|
NumerKSeFDokumentu: 'D001',
|
||||||
|
NumerFaktury: 'F001',
|
||||||
|
NipSprzedawcy: '123',
|
||||||
|
DataWystawieniaFaktury: '2024-01-01',
|
||||||
|
DataPrzeslaniaDokumentu: '2024-01-02',
|
||||||
|
DataNadaniaNumeruKSeF: '2024-01-03',
|
||||||
|
SkrotDokumentu: 'XYZ',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
} as any;
|
||||||
|
|
||||||
|
vi.mocked(PDFFunctions.getTable).mockReturnValue(mockPotwierdzenie.Dokument as any);
|
||||||
|
vi.mocked(PDFFunctions.hasValue).mockReturnValue(true);
|
||||||
|
vi.mocked(PDFFunctions.formatText).mockImplementation((text) => text as any);
|
||||||
|
vi.mocked(PDFFunctions.generateLine).mockReturnValue('line' as any);
|
||||||
|
vi.mocked(PDFFunctions.verticalSpacing).mockImplementation((val) => `space${val}` as any);
|
||||||
|
vi.mocked(PDFFunctions.getContentTable).mockReturnValue({
|
||||||
|
content: 'tableContent',
|
||||||
|
fieldsWithValue: [],
|
||||||
|
} as any);
|
||||||
|
vi.mocked(PDFFunctions.getValue).mockImplementation((val: any) => val?._text);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should generate basic UPO structure', () => {
|
||||||
|
const result = generateDokumentUPO(mockPotwierdzenie);
|
||||||
|
|
||||||
|
expect(result[0]).toBe('space4');
|
||||||
|
expect(result[1]).toBe('line');
|
||||||
|
expect(result[2]).toBe('space8');
|
||||||
|
expect(result[3]).toBe('Urzędowe poświadczenie odbioru dokumentu elektronicznego KSeF');
|
||||||
|
expect(result[4]).toBe('space8');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should include all UPO fields when hasValue returns true', () => {
|
||||||
|
generateDokumentUPO(mockPotwierdzenie);
|
||||||
|
|
||||||
|
expect(PDFFunctions.formatText).toHaveBeenCalledWith(
|
||||||
|
'Numer referencyjny sesji: ',
|
||||||
|
FormatTyp.GrayBoldTitle
|
||||||
|
);
|
||||||
|
expect(PDFFunctions.formatText).toHaveBeenCalledWith('Strona dokumentu UPO: ', FormatTyp.GrayBoldTitle);
|
||||||
|
expect(PDFFunctions.formatText).toHaveBeenCalledWith(
|
||||||
|
'Całkowita liczba stron dokumentu UPO: ',
|
||||||
|
FormatTyp.GrayBoldTitle
|
||||||
|
);
|
||||||
|
expect(PDFFunctions.formatText).toHaveBeenCalledWith('Zakres dokumentów od: ', FormatTyp.GrayBoldTitle);
|
||||||
|
expect(PDFFunctions.formatText).toHaveBeenCalledWith('Zakres dokumentów do: ', FormatTyp.GrayBoldTitle);
|
||||||
|
expect(PDFFunctions.formatText).toHaveBeenCalledWith(
|
||||||
|
'Całkowita liczba dokumentów: ',
|
||||||
|
FormatTyp.GrayBoldTitle
|
||||||
|
);
|
||||||
|
expect(PDFFunctions.formatText).toHaveBeenCalledWith('Typ kontekstu: ', FormatTyp.GrayBoldTitle);
|
||||||
|
expect(PDFFunctions.formatText).toHaveBeenCalledWith(
|
||||||
|
'Identyfikator kontekstu uwierzytelnienia: ',
|
||||||
|
FormatTyp.GrayBoldTitle
|
||||||
|
);
|
||||||
|
expect(PDFFunctions.formatText).toHaveBeenCalledWith(
|
||||||
|
'Skrót dokumentu uwierzytelniającego: ',
|
||||||
|
FormatTyp.GrayBoldTitle
|
||||||
|
);
|
||||||
|
expect(PDFFunctions.formatText).toHaveBeenCalledWith(
|
||||||
|
'Nazwa pliku XSD struktury logicznej dotycząca przesłanego dokumentu:',
|
||||||
|
FormatTyp.GrayBoldTitle
|
||||||
|
);
|
||||||
|
expect(PDFFunctions.formatText).toHaveBeenCalledWith(
|
||||||
|
'Kod formularza przedłożonego dokumentu elektronicznego:',
|
||||||
|
FormatTyp.GrayBoldTitle
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not add document table if getContentTable.content is null', () => {
|
||||||
|
vi.mocked(PDFFunctions.getContentTable).mockReturnValue({ content: null, fieldsWithValue: [] });
|
||||||
|
const result = generateDokumentUPO(mockPotwierdzenie);
|
||||||
|
|
||||||
|
expect(result).not.toContain('null');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should call getTable with Dokument', () => {
|
||||||
|
generateDokumentUPO(mockPotwierdzenie);
|
||||||
|
expect(PDFFunctions.getTable).toHaveBeenCalledWith(mockPotwierdzenie.Dokument);
|
||||||
|
});
|
||||||
|
});
|
||||||
183
src/lib-public/generators/UPO4_3/Dokumenty.ts
Normal file
183
src/lib-public/generators/UPO4_3/Dokumenty.ts
Normal file
@@ -0,0 +1,183 @@
|
|||||||
|
import { Content } from 'pdfmake/interfaces';
|
||||||
|
import {
|
||||||
|
formatText,
|
||||||
|
generateLine,
|
||||||
|
getContentTable,
|
||||||
|
getTable,
|
||||||
|
getValue,
|
||||||
|
hasValue,
|
||||||
|
verticalSpacing,
|
||||||
|
} from '../../../shared/PDF-functions';
|
||||||
|
import { HeaderDefine } from '../../../shared/types/pdf-types';
|
||||||
|
import FormatTyp from '../../../shared/enums/common.enum';
|
||||||
|
import { FormContentState } from '../../../shared/types/additional-data.types';
|
||||||
|
import { DEFAULT_TABLE_LAYOUT } from '../../../shared/consts/const';
|
||||||
|
import { Dokument, IDKontekstu, Potwierdzenie } from '../../types/upo-v4_3.types';
|
||||||
|
|
||||||
|
export function generateDokumentUPO(potwierdzenie: Potwierdzenie): Content[] {
|
||||||
|
const dokumenty: Dokument[] = getTable(potwierdzenie.Dokument);
|
||||||
|
|
||||||
|
const result: Content[] = [];
|
||||||
|
const table: Content[] = [];
|
||||||
|
|
||||||
|
result.push(verticalSpacing(4));
|
||||||
|
result.push(generateLine());
|
||||||
|
result.push(verticalSpacing(8));
|
||||||
|
result.push(
|
||||||
|
formatText('Urzędowe poświadczenie odbioru dokumentu elektronicznego KSeF', FormatTyp.HeaderPosition)
|
||||||
|
);
|
||||||
|
result.push(verticalSpacing(8));
|
||||||
|
if (hasValue(potwierdzenie.NumerReferencyjnySesji)) {
|
||||||
|
table.push([
|
||||||
|
formatText('Numer referencyjny sesji: ', FormatTyp.GrayBoldTitle),
|
||||||
|
formatText(potwierdzenie.NumerReferencyjnySesji?._text, FormatTyp.Default),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
if (hasValue(potwierdzenie.OpisPotwierdzenia?.Strona)) {
|
||||||
|
table.push([
|
||||||
|
formatText('Strona dokumentu UPO: ', FormatTyp.GrayBoldTitle),
|
||||||
|
formatText(potwierdzenie.OpisPotwierdzenia?.Strona?._text, FormatTyp.Default),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
if (hasValue(potwierdzenie.OpisPotwierdzenia?.LiczbaStron)) {
|
||||||
|
table.push([
|
||||||
|
formatText('Całkowita liczba stron dokumentu UPO: ', FormatTyp.GrayBoldTitle),
|
||||||
|
formatText(potwierdzenie.OpisPotwierdzenia?.LiczbaStron?._text, FormatTyp.Default),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
if (hasValue(potwierdzenie.OpisPotwierdzenia?.ZakresDokumentowOd)) {
|
||||||
|
table.push([
|
||||||
|
formatText('Zakres dokumentów od: ', FormatTyp.GrayBoldTitle),
|
||||||
|
formatText(potwierdzenie.OpisPotwierdzenia?.ZakresDokumentowOd?._text, FormatTyp.Default),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
if (hasValue(potwierdzenie.OpisPotwierdzenia?.ZakresDokumentowDo)) {
|
||||||
|
table.push([
|
||||||
|
formatText('Zakres dokumentów do: ', FormatTyp.GrayBoldTitle),
|
||||||
|
formatText(potwierdzenie.OpisPotwierdzenia?.ZakresDokumentowDo?._text, FormatTyp.Default),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
if (hasValue(potwierdzenie.OpisPotwierdzenia?.CalkowitaLiczbaDokumentow)) {
|
||||||
|
table.push([
|
||||||
|
formatText('Całkowita liczba dokumentów: ', FormatTyp.GrayBoldTitle),
|
||||||
|
formatText(potwierdzenie.OpisPotwierdzenia?.CalkowitaLiczbaDokumentow?._text, FormatTyp.Default),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
const idKontekstu: IDKontekstu | undefined = potwierdzenie?.Uwierzytelnienie?.IdKontekstu;
|
||||||
|
|
||||||
|
if (idKontekstu) {
|
||||||
|
let typKontekstu = '';
|
||||||
|
let id: string | number | undefined;
|
||||||
|
|
||||||
|
if (hasValue(idKontekstu.IdDostawcyUslugPeppol)) {
|
||||||
|
typKontekstu = 'Identyfikator Peppol';
|
||||||
|
id = getValue(idKontekstu.IdDostawcyUslugPeppol);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hasValue(idKontekstu.Nip)) {
|
||||||
|
typKontekstu = 'NIP';
|
||||||
|
id = getValue(idKontekstu.Nip);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hasValue(idKontekstu.IdWewnetrzny)) {
|
||||||
|
typKontekstu = 'Identyfikator wewnętrzny';
|
||||||
|
id = getValue(idKontekstu.IdWewnetrzny);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hasValue(idKontekstu.IdZlozonyVatUE)) {
|
||||||
|
typKontekstu = 'Identyfikator złożony';
|
||||||
|
id = getValue(idKontekstu.IdZlozonyVatUE);
|
||||||
|
}
|
||||||
|
table.push([
|
||||||
|
formatText('Typ kontekstu: ', FormatTyp.GrayBoldTitle),
|
||||||
|
formatText(typKontekstu, FormatTyp.Default),
|
||||||
|
]);
|
||||||
|
table.push([
|
||||||
|
formatText('Identyfikator kontekstu uwierzytelnienia: ', FormatTyp.GrayBoldTitle),
|
||||||
|
formatText(id, FormatTyp.Default),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
if (hasValue(potwierdzenie.Uwierzytelnienie?.SkrotDokumentuUwierzytelniajacego)) {
|
||||||
|
table.push([
|
||||||
|
formatText('Skrót dokumentu uwierzytelniającego: ', FormatTyp.GrayBoldTitle),
|
||||||
|
formatText(potwierdzenie.Uwierzytelnienie?.SkrotDokumentuUwierzytelniajacego?._text, FormatTyp.Default),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
if (hasValue(potwierdzenie.NazwaStrukturyLogicznej)) {
|
||||||
|
table.push([
|
||||||
|
formatText(
|
||||||
|
'Nazwa pliku XSD struktury logicznej dotycząca przesłanego dokumentu:',
|
||||||
|
FormatTyp.GrayBoldTitle
|
||||||
|
),
|
||||||
|
formatText(potwierdzenie.NazwaStrukturyLogicznej?._text, FormatTyp.Default),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
if (hasValue(potwierdzenie.KodFormularza)) {
|
||||||
|
table.push([
|
||||||
|
formatText('Kod formularza przedłożonego dokumentu elektronicznego:', FormatTyp.GrayBoldTitle),
|
||||||
|
formatText(potwierdzenie.KodFormularza?._text, FormatTyp.Default),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
result.push([
|
||||||
|
{
|
||||||
|
unbreakable: true,
|
||||||
|
table: {
|
||||||
|
body: table,
|
||||||
|
widths: ['auto', '*'],
|
||||||
|
},
|
||||||
|
layout: DEFAULT_TABLE_LAYOUT,
|
||||||
|
} as Content,
|
||||||
|
]);
|
||||||
|
result.push(verticalSpacing(8));
|
||||||
|
const definedHeader: HeaderDefine[] = [
|
||||||
|
{ name: 'lp', title: 'Lp.', format: FormatTyp.Default },
|
||||||
|
{
|
||||||
|
name: 'NumerKSeFDokumentu',
|
||||||
|
title: 'Numer identyfikujący fakturę w KSeF',
|
||||||
|
format: FormatTyp.Default,
|
||||||
|
},
|
||||||
|
{ name: 'NumerFaktury', title: 'Numer faktury', format: FormatTyp.Default },
|
||||||
|
{ name: 'NipSprzedawcy', title: 'NIP Sprzedawcy', format: FormatTyp.Default },
|
||||||
|
{
|
||||||
|
name: 'DataWystawieniaFaktury',
|
||||||
|
title: 'Data wystawienia faktury',
|
||||||
|
format: FormatTyp.Date,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'DataPrzeslaniaDokumentu',
|
||||||
|
title: 'Data przesłania do KSeF',
|
||||||
|
format: FormatTyp.DateTime,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'DataNadaniaNumeruKSeF',
|
||||||
|
title: 'Data nadania numeru KSeF',
|
||||||
|
format: FormatTyp.DateTime,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'SkrotDokumentu',
|
||||||
|
title: 'Wartość funkcji skrótu złożonego dokumentu',
|
||||||
|
format: FormatTyp.Default,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'TrybWysylki',
|
||||||
|
title: 'Tryb wysyłki',
|
||||||
|
format: FormatTyp.Default,
|
||||||
|
width: '*',
|
||||||
|
},
|
||||||
|
];
|
||||||
|
const documentData: Dokument[] =
|
||||||
|
dokumenty.map((doc: Dokument, index: number): Dokument => {
|
||||||
|
return { ...doc, lp: index + 1 };
|
||||||
|
}) ?? [];
|
||||||
|
|
||||||
|
const tabDocument: FormContentState = getContentTable<(typeof documentData)[0]>(
|
||||||
|
definedHeader,
|
||||||
|
documentData,
|
||||||
|
'auto'
|
||||||
|
);
|
||||||
|
|
||||||
|
if (tabDocument.content) {
|
||||||
|
result.push(tabDocument.content);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
34
src/lib-public/generators/UPO4_3/Naglowek.ts
Normal file
34
src/lib-public/generators/UPO4_3/Naglowek.ts
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
import { Content } from 'pdfmake/interfaces';
|
||||||
|
import { Potwierdzenie } from '../../types/upo-v4_3.types';
|
||||||
|
import { createLabelText, generateTwoColumns } from '../../../shared/PDF-functions';
|
||||||
|
import { Position } from '../../../shared/enums/common.enum';
|
||||||
|
|
||||||
|
export function generateNaglowekUPO(potwierdzenie: Potwierdzenie): Content[] {
|
||||||
|
return [
|
||||||
|
generateTwoColumns(
|
||||||
|
{
|
||||||
|
text: [
|
||||||
|
{ text: 'Krajowy System ', fontSize: 18 },
|
||||||
|
{ text: 'e', color: 'red', bold: true, fontSize: 18 },
|
||||||
|
{ text: '-Faktur', bold: true, fontSize: 18 },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
[
|
||||||
|
{
|
||||||
|
text: createLabelText(
|
||||||
|
'Nazwa pełna podmiotu, któremu doręczono dokument elektroniczny: ',
|
||||||
|
potwierdzenie!.NazwaPodmiotuPrzyjmujacego
|
||||||
|
),
|
||||||
|
alignment: Position.RIGHT,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: createLabelText(
|
||||||
|
'Informacja o dokumencie: ',
|
||||||
|
'Dokument został zarejestrowany w systemie teleinformatycznym Ministerstwa Finansów'
|
||||||
|
),
|
||||||
|
alignment: Position.RIGHT,
|
||||||
|
},
|
||||||
|
]
|
||||||
|
),
|
||||||
|
];
|
||||||
|
}
|
||||||
@@ -46,7 +46,7 @@ export function generateStopka(
|
|||||||
createSection(
|
createSection(
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
stack: createLabelText('Wytworzona w:', naglowek?.SystemInfo),
|
stack: createLabelText('Wytworzona w: ', naglowek?.SystemInfo),
|
||||||
margin: [0, 8, 0, 0],
|
margin: [0, 8, 0, 0],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
@@ -147,9 +147,13 @@ function generateQRCodeData(additionalData?: AdditionalDataTypes): Content[] {
|
|||||||
'Nie możesz zeskanować kodu z obrazka? Kliknij w link weryfikacyjny i przejdź do weryfikacji faktury!',
|
'Nie możesz zeskanować kodu z obrazka? Kliknij w link weryfikacyjny i przejdź do weryfikacji faktury!',
|
||||||
FormatTyp.Value
|
FormatTyp.Value
|
||||||
),
|
),
|
||||||
{ stack: [formatText(additionalData.qrCode, FormatTyp.Link)], marginTop: 5 },
|
{
|
||||||
],
|
stack: [formatText(additionalData.qrCode, FormatTyp.Link)],
|
||||||
|
marginTop: 5,
|
||||||
link: additionalData.qrCode,
|
link: additionalData.qrCode,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
|
||||||
margin: [10, (qrCode.fit ?? 120) / 2 - 30, 0, 0],
|
margin: [10, (qrCode.fit ?? 120) / 2 - 30, 0, 0],
|
||||||
width: 'auto',
|
width: 'auto',
|
||||||
} as ContentStack,
|
} as ContentStack,
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { describe, expect, it } from 'vitest';
|
import { describe, expect, it } from 'vitest';
|
||||||
import { shouldAddMarza } from './Wiersze';
|
import { addMarza } from './Wiersze';
|
||||||
import { TRodzajFaktury } from '../../../shared/consts/const';
|
import { TRodzajFaktury } from '../../../shared/consts/const';
|
||||||
|
|
||||||
const getMockFaVat = (mockedObjects?: Record<string, any>) =>
|
const getMockFaVat = (mockedObjects?: Record<string, any>) =>
|
||||||
@@ -13,34 +13,40 @@ const getMockFaVat = (mockedObjects?: Record<string, any>) =>
|
|||||||
|
|
||||||
describe('shouldAddMarza', () => {
|
describe('shouldAddMarza', () => {
|
||||||
it('returns P_12 when VAT type and P_12/P_12_XII are empty', () => {
|
it('returns P_12 when VAT type and P_12/P_12_XII are empty', () => {
|
||||||
const result = shouldAddMarza(TRodzajFaktury.VAT, true, getMockFaVat());
|
const result = addMarza(TRodzajFaktury.VAT, true, getMockFaVat());
|
||||||
|
|
||||||
expect(result).toEqual({ P_12: { _text: 'marża' } });
|
expect(result).toEqual({ P_12: { _text: 'marża' } });
|
||||||
});
|
});
|
||||||
|
|
||||||
it('returns P_12Z when ZAL type and P_12Z/P_12Z_XII are empty', () => {
|
it('returns P_12Z when ZAL type and P_12Z/P_12Z_XII are empty', () => {
|
||||||
const result = shouldAddMarza(TRodzajFaktury.ZAL, true, getMockFaVat());
|
const result = addMarza(TRodzajFaktury.ZAL, true, getMockFaVat());
|
||||||
|
|
||||||
expect(result).toEqual({ P_12Z: { _text: 'marża' } });
|
expect(result).toEqual({ P_12Z: { _text: 'marża' } });
|
||||||
});
|
});
|
||||||
|
|
||||||
it('returns null when rodzajFaktury is not a string', () => {
|
it('returns empty object when rodzajFaktury is not a string', () => {
|
||||||
const result = shouldAddMarza(undefined, true, getMockFaVat());
|
const result = addMarza(undefined, true, getMockFaVat());
|
||||||
expect(result).toBeNull();
|
|
||||||
|
expect(result).toMatchObject({});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('returns null when isP_PMarzy is false', () => {
|
it('returns empty object when isP_PMarzy is false', () => {
|
||||||
const mockP_12 = { P_12: { _text: '23' } };
|
const mockP_12 = { P_12: { _text: '23' } };
|
||||||
const result = shouldAddMarza(TRodzajFaktury.VAT, false, getMockFaVat(mockP_12));
|
const result = addMarza(TRodzajFaktury.VAT, false, getMockFaVat(mockP_12));
|
||||||
expect(result).toBeNull();
|
|
||||||
|
expect(result).toMatchObject({});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('returns null when P_12 already has value', () => {
|
it('returns null when P_12 already has value', () => {
|
||||||
const mockP_12 = { P_12: { _text: '23' } };
|
const mockP_12 = { P_12: { _text: '23' } };
|
||||||
const result = shouldAddMarza(TRodzajFaktury.VAT, true, getMockFaVat(mockP_12));
|
const result = addMarza(TRodzajFaktury.VAT, true, getMockFaVat(mockP_12));
|
||||||
expect(result).toBeNull();
|
|
||||||
|
expect(result).toEqual({});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('returns null when rodzajFaktury is not VAT or ZAL type', () => {
|
it('returns null when rodzajFaktury is not VAT or ZAL type', () => {
|
||||||
const result = shouldAddMarza(TRodzajFaktury.UPR, true, getMockFaVat());
|
const result = addMarza(TRodzajFaktury.UPR, true, getMockFaVat());
|
||||||
expect(result).toBeNull();
|
|
||||||
|
expect(result).toEqual({});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import { TRodzajFaktury } from '../../../shared/consts/const';
|
|||||||
import { FP } from '../../types/fa1.types';
|
import { FP } from '../../types/fa1.types';
|
||||||
import { getValue } from '../../../shared/PDF-functions';
|
import { getValue } from '../../../shared/PDF-functions';
|
||||||
|
|
||||||
export function shouldAddMarza(
|
export function addMarza(
|
||||||
rodzajFaktury: string | number | undefined,
|
rodzajFaktury: string | number | undefined,
|
||||||
isP_PMarzy: boolean,
|
isP_PMarzy: boolean,
|
||||||
wiersz: Record<string, FP>
|
wiersz: Record<string, FP>
|
||||||
@@ -23,10 +23,10 @@ export function shouldAddMarza(
|
|||||||
} else if (isZALType && !getValue(wiersz.P_12Z) && !getValue(wiersz.P_12Z_XII)) {
|
} else if (isZALType && !getValue(wiersz.P_12Z) && !getValue(wiersz.P_12Z_XII)) {
|
||||||
return { P_12Z: { _text: 'marża' } };
|
return { P_12Z: { _text: 'marża' } };
|
||||||
} else {
|
} else {
|
||||||
return null;
|
return {};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return {};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -128,13 +128,13 @@ function generateTable(tabela: Tabela): Content[] {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
function createTable(cols: Kol[], rows: Wiersz[], subTableIndex: number, totalLength: number): ContentTable {
|
function createTable(cols: Kol[], rows: Wiersz | Wiersz[], subTableIndex: number, totalLength: number): ContentTable {
|
||||||
const definedHeader: Content[] = cols.map((item: Kol): string | ContentText =>
|
const definedHeader: Content[] = cols.map((item: Kol): string | ContentText =>
|
||||||
formatText(item.NKom?._text, FormatTyp.GrayBoldTitle)
|
formatText(item.NKom?._text, FormatTyp.GrayBoldTitle)
|
||||||
);
|
);
|
||||||
const tableBody: TableCell[] = [];
|
const tableBody: TableCell[] = [];
|
||||||
|
|
||||||
rows.forEach((item: Wiersz): void => {
|
getTable(rows).forEach((item: Wiersz): void => {
|
||||||
const WKom: FP[] = getTable(item.WKom);
|
const WKom: FP[] = getTable(item.WKom);
|
||||||
|
|
||||||
while (WKom.length < totalLength) {
|
while (WKom.length < totalLength) {
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { generateInvoice } from './generate-invoice';
|
import { generateInvoice } from './generate-invoice';
|
||||||
import { generatePDFUPO } from './UPO-4_2-generators';
|
import { generatePDFUPO } from './UPO-generator';
|
||||||
|
|
||||||
export { generateInvoice, generatePDFUPO };
|
export { generateInvoice, generatePDFUPO };
|
||||||
|
|||||||
@@ -343,7 +343,7 @@ export interface Tabela {
|
|||||||
TMetaDane?: TMetaDane[];
|
TMetaDane?: TMetaDane[];
|
||||||
Opis?: FP;
|
Opis?: FP;
|
||||||
TNaglowek?: TNaglowek;
|
TNaglowek?: TNaglowek;
|
||||||
Wiersz?: Wiersz[];
|
Wiersz?: Wiersz | Wiersz[];
|
||||||
Suma?: Suma;
|
Suma?: Suma;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
69
src/lib-public/types/upo-v4_3.types.ts
Normal file
69
src/lib-public/types/upo-v4_3.types.ts
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
export interface Upo {
|
||||||
|
_declaration?: Declaration;
|
||||||
|
_comment?: string;
|
||||||
|
Potwierdzenie?: Potwierdzenie;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Potwierdzenie {
|
||||||
|
_attributes?: PotwierdzenieAttributes;
|
||||||
|
NazwaPodmiotuPrzyjmujacego?: KodFormularza;
|
||||||
|
NumerReferencyjnySesji?: KodFormularza;
|
||||||
|
Uwierzytelnienie?: Uwierzytelnienie;
|
||||||
|
OpisPotwierdzenia?: OpisPotwierdzenia;
|
||||||
|
NazwaStrukturyLogicznej?: KodFormularza;
|
||||||
|
KodFormularza?: KodFormularza;
|
||||||
|
Dokument?: Dokument[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Dokument {
|
||||||
|
lp?: number;
|
||||||
|
NipSprzedawcy?: KodFormularza;
|
||||||
|
NumerKSeFDokumentu?: KodFormularza;
|
||||||
|
NumerFaktury?: KodFormularza;
|
||||||
|
DataWystawieniaFaktury?: KodFormularza;
|
||||||
|
DataPrzeslaniaDokumentu?: KodFormularza;
|
||||||
|
DataNadaniaNumeruKSeF?: KodFormularza;
|
||||||
|
SkrotDokumentu?: KodFormularza;
|
||||||
|
TrybWysylki?: KodFormularza;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface KodFormularza {
|
||||||
|
_text?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface OpisPotwierdzenia {
|
||||||
|
Strona?: KodFormularza;
|
||||||
|
LiczbaStron?: KodFormularza;
|
||||||
|
ZakresDokumentowOd?: KodFormularza;
|
||||||
|
ZakresDokumentowDo?: KodFormularza;
|
||||||
|
CalkowitaLiczbaDokumentow?: KodFormularza;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Uwierzytelnienie {
|
||||||
|
IdKontekstu?: IDKontekstu;
|
||||||
|
NumerReferencyjnyTokenaKSeF?: KodFormularza;
|
||||||
|
SkrotDokumentuUwierzytelniajacego?: KodFormularza;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface IDKontekstu {
|
||||||
|
Nip?: KodFormularza;
|
||||||
|
IdWewnetrzny?: KodFormularza;
|
||||||
|
IdZlozonyVatUE?: KodFormularza;
|
||||||
|
IdDostawcyUslugPeppol?: KodFormularza;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface PotwierdzenieAttributes {
|
||||||
|
upo?: string;
|
||||||
|
xsi?: string;
|
||||||
|
wersjaSchemy?: string;
|
||||||
|
schemaLocation?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Declaration {
|
||||||
|
_attributes?: DeclarationAttributes;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface DeclarationAttributes {
|
||||||
|
version?: string;
|
||||||
|
encoding?: string;
|
||||||
|
}
|
||||||
@@ -10,6 +10,8 @@ import {
|
|||||||
getNumberRounded,
|
getNumberRounded,
|
||||||
getValue,
|
getValue,
|
||||||
hasValue,
|
hasValue,
|
||||||
|
normalizeCurrencySeparator,
|
||||||
|
replaceDotWithCommaIfNeeded,
|
||||||
verticalSpacing,
|
verticalSpacing,
|
||||||
} from './PDF-functions';
|
} from './PDF-functions';
|
||||||
import FormatTyp, { Position } from './enums/common.enum';
|
import FormatTyp, { Position } from './enums/common.enum';
|
||||||
@@ -126,3 +128,37 @@ describe('generateLine', () => {
|
|||||||
expect(lineContent).toHaveProperty('layout');
|
expect(lineContent).toHaveProperty('layout');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('normalized currency separator', () => {
|
||||||
|
it('should correctly add zeros ', () => {
|
||||||
|
const normalized = normalizeCurrencySeparator(43);
|
||||||
|
|
||||||
|
expect(normalized).toBe('43,00');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should correctyl add zero', () => {
|
||||||
|
const normalized = normalizeCurrencySeparator(43.7);
|
||||||
|
|
||||||
|
expect(normalized).toBe('43,70');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should correctly displa value', () => {
|
||||||
|
const normalized = normalizeCurrencySeparator('444,9999');
|
||||||
|
|
||||||
|
expect(normalized).toBe('444,9999');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('replaceDotWithCommaIfNeeded', () => {
|
||||||
|
it('shuold change comma to dot if needed', () => {
|
||||||
|
const dotToComma = replaceDotWithCommaIfNeeded(44.5);
|
||||||
|
|
||||||
|
expect(dotToComma).toBe('44,5');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('do nothing if do not find comma', () => {
|
||||||
|
const dotToComma = replaceDotWithCommaIfNeeded(3);
|
||||||
|
|
||||||
|
expect(dotToComma).toBe('3');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|||||||
@@ -10,8 +10,14 @@ import {
|
|||||||
TableCell,
|
TableCell,
|
||||||
TDocumentDefinitions,
|
TDocumentDefinitions,
|
||||||
} from 'pdfmake/interfaces';
|
} from 'pdfmake/interfaces';
|
||||||
import { DEFAULT_TABLE_LAYOUT, Kraj } from './consts/const';
|
import {
|
||||||
import { formatDateTime, getFormaPlatnosciString } from './generators/common/functions';
|
DEFAULT_TABLE_LAYOUT,
|
||||||
|
Kraj,
|
||||||
|
TStawkaPodatku_FA1,
|
||||||
|
TStawkaPodatku_FA2,
|
||||||
|
TStawkaPodatku_FA3,
|
||||||
|
} from './consts/const';
|
||||||
|
import {formatDateTime, formatTime, getFormaPlatnosciString} from './generators/common/functions';
|
||||||
import { HeaderDefine, PdfFP, PdfOptionField } from './types/pdf-types';
|
import { HeaderDefine, PdfFP, PdfOptionField } from './types/pdf-types';
|
||||||
import { FP } from '../lib-public/types/fa3.types';
|
import { FP } from '../lib-public/types/fa3.types';
|
||||||
import { DifferentValues, FilteredKeysOfValues, TypesOfValues } from './types/universal.types';
|
import { DifferentValues, FilteredKeysOfValues, TypesOfValues } from './types/universal.types';
|
||||||
@@ -77,7 +83,7 @@ function formatValue(
|
|||||||
case FormatTyp.Currency:
|
case FormatTyp.Currency:
|
||||||
result.text = isNaN(Number(value))
|
result.text = isNaN(Number(value))
|
||||||
? (value as string)
|
? (value as string)
|
||||||
: `${dotToComma(Number(value).toFixed(2))} ${currency}`;
|
: `${normalizeCurrencySeparator(value)} ${currency}`;
|
||||||
result.alignment = Position.RIGHT;
|
result.alignment = Position.RIGHT;
|
||||||
break;
|
break;
|
||||||
case FormatTyp.CurrencyAbs:
|
case FormatTyp.CurrencyAbs:
|
||||||
@@ -104,6 +110,9 @@ function formatValue(
|
|||||||
case FormatTyp.Date:
|
case FormatTyp.Date:
|
||||||
result.text = formatDateTime(value as string, false, true);
|
result.text = formatDateTime(value as string, false, true);
|
||||||
break;
|
break;
|
||||||
|
case FormatTyp.Time:
|
||||||
|
result.text = formatTime(value as string);
|
||||||
|
break;
|
||||||
case FormatTyp.FormOfPayment:
|
case FormatTyp.FormOfPayment:
|
||||||
result.text = getFormaPlatnosciString({ _text: value as string });
|
result.text = getFormaPlatnosciString({ _text: value as string });
|
||||||
break;
|
break;
|
||||||
@@ -113,9 +122,43 @@ function formatValue(
|
|||||||
case FormatTyp.Percentage:
|
case FormatTyp.Percentage:
|
||||||
result.text = `${value}%`;
|
result.text = `${value}%`;
|
||||||
break;
|
break;
|
||||||
|
case FormatTyp.Number:
|
||||||
|
result.text = replaceDotWithCommaIfNeeded(value);
|
||||||
|
result.alignment = Position.RIGHT;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function normalizeCurrencySeparator(value: string | number | undefined): string {
|
||||||
|
if (!value) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
const numberWithComma = dotToComma(typeof value === 'string' ? value : value.toString());
|
||||||
|
|
||||||
|
if (numberWithComma.includes(',')) {
|
||||||
|
const parts = numberWithComma.split(',');
|
||||||
|
|
||||||
|
return parts[1].length > 1 ? numberWithComma : numberWithComma + '0';
|
||||||
|
} else {
|
||||||
|
return numberWithComma + ',00';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function replaceDotWithCommaIfNeeded(value: string | number | undefined): string {
|
||||||
|
let copyValue = '';
|
||||||
|
|
||||||
|
if (typeof value === 'number') {
|
||||||
|
copyValue = value.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof value === 'string') {
|
||||||
|
copyValue = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
return copyValue.includes('.') ? dotToComma(copyValue) : copyValue;
|
||||||
|
}
|
||||||
|
|
||||||
function dotToComma(value: string): string {
|
function dotToComma(value: string): string {
|
||||||
return value.replace('.', ',');
|
return value.replace('.', ',');
|
||||||
}
|
}
|
||||||
@@ -466,11 +509,32 @@ export function verticalSpacing(height: number): ContentText {
|
|||||||
return { text: '\n', fontSize: height };
|
return { text: '\n', fontSize: height };
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getKraj(kod: string): string {
|
export function getKraj(code: string): string {
|
||||||
if (Kraj[kod]) {
|
if (Kraj[code]) {
|
||||||
return Kraj[kod];
|
return Kraj[code];
|
||||||
}
|
}
|
||||||
return kod;
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getTStawkaPodatku(code: string, version: 1 | 2 | 3): string {
|
||||||
|
let TStawkaPodatkuVersioned: Record<string, string> = {};
|
||||||
|
|
||||||
|
switch (version) {
|
||||||
|
case 1:
|
||||||
|
TStawkaPodatkuVersioned = TStawkaPodatku_FA1;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
TStawkaPodatkuVersioned = TStawkaPodatku_FA2;
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
TStawkaPodatkuVersioned = TStawkaPodatku_FA3;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (TStawkaPodatkuVersioned[code]) {
|
||||||
|
return TStawkaPodatkuVersioned[code];
|
||||||
|
}
|
||||||
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function generateLine(): Content {
|
export function generateLine(): Content {
|
||||||
|
|||||||
@@ -16,6 +16,59 @@ export const TypKorekty: Record<string, string> = {
|
|||||||
'2': 'Korekta skutkująca w dacie wystawienia faktury korygującej',
|
'2': 'Korekta skutkująca w dacie wystawienia faktury korygującej',
|
||||||
'3': 'Korekta skutkująca w dacie innej, w tym gdy dla różnych pozycji faktury korygującej daty te są różne',
|
'3': 'Korekta skutkująca w dacie innej, w tym gdy dla różnych pozycji faktury korygującej daty te są różne',
|
||||||
};
|
};
|
||||||
|
export const TStawkaPodatku_FA1: Record<string, string> = {
|
||||||
|
'23': '23%',
|
||||||
|
'22': '22%',
|
||||||
|
'8': '8%',
|
||||||
|
'7': '7%',
|
||||||
|
'5': '5%',
|
||||||
|
'4': '4% lub 3% lub oo',
|
||||||
|
'3': '4% lub 3% lub oo',
|
||||||
|
'0': '0%',
|
||||||
|
|
||||||
|
zw: 'zwolnione z opodatkowania',
|
||||||
|
oo: '4% lub 3% lub oo\n' +
|
||||||
|
'UWAGA: oo jest wykazywane łącznie z 4% lub 3%',
|
||||||
|
np: 'niepodlegające opodatkowaniu-transakcje dostawy towarów oraz świadczenia usług poza terytorium kraju',
|
||||||
|
};
|
||||||
|
|
||||||
|
export const TStawkaPodatku_FA2: Record<string, string> = {
|
||||||
|
'23': '23%',
|
||||||
|
'22': '22%',
|
||||||
|
'8': '8%',
|
||||||
|
'7': '7%',
|
||||||
|
'5': '5%',
|
||||||
|
'4': '4%',
|
||||||
|
'3': '3%',
|
||||||
|
'0': '0%',
|
||||||
|
|
||||||
|
zw: 'zwolnione od podatku',
|
||||||
|
oo: 'odwrotne obciążenie',
|
||||||
|
np: 'niepodlegające opodatkowaniu-transakcje dostawy towarów oraz świadczenia usług poza terytorium kraju',
|
||||||
|
};
|
||||||
|
|
||||||
|
export const TStawkaPodatku_FA3: Record<string, string> = {
|
||||||
|
'23': '23%',
|
||||||
|
'22': '22%',
|
||||||
|
'8': '8%',
|
||||||
|
'7': '7%',
|
||||||
|
'5': '5%',
|
||||||
|
'4': '4%',
|
||||||
|
'3': '3%',
|
||||||
|
|
||||||
|
'0 KR':
|
||||||
|
'0% - KR',
|
||||||
|
'0 WDT': '0% - WDT',
|
||||||
|
'0 EX': '0% - EX',
|
||||||
|
|
||||||
|
zw: 'zw',
|
||||||
|
oo: 'oo',
|
||||||
|
|
||||||
|
'np I':
|
||||||
|
'np I',
|
||||||
|
'np II':
|
||||||
|
'np II',
|
||||||
|
};
|
||||||
|
|
||||||
export const Kraj: Record<string, string> = {
|
export const Kraj: Record<string, string> = {
|
||||||
AF: 'Afganistan',
|
AF: 'Afganistan',
|
||||||
@@ -362,11 +415,11 @@ export const Procedura: Record<string, string> = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const TableDataType: Record<string, FormatTyp> = {
|
export const TableDataType: Record<string, FormatTyp> = {
|
||||||
date: FormatTyp.DateTime,
|
date: FormatTyp.Date,
|
||||||
datetime: FormatTyp.DateTime,
|
datetime: FormatTyp.DateTime,
|
||||||
dec: FormatTyp.Currency,
|
dec: FormatTyp.Currency,
|
||||||
int: FormatTyp.Currency,
|
int: FormatTyp.Currency,
|
||||||
time: FormatTyp.DateTime,
|
time: FormatTyp.Time,
|
||||||
txt: FormatTyp.Value,
|
txt: FormatTyp.Value,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -38,8 +38,10 @@ export enum FormatTyp {
|
|||||||
Right = 'Right',
|
Right = 'Right',
|
||||||
DateTime = 'DateTime',
|
DateTime = 'DateTime',
|
||||||
Date = 'Date',
|
Date = 'Date',
|
||||||
|
Time = 'Time',
|
||||||
FormOfPayment = 'FormOfPayment',
|
FormOfPayment = 'FormOfPayment',
|
||||||
Percentage = 'Percentage',
|
Percentage = 'Percentage',
|
||||||
|
Number = 'Number',
|
||||||
}
|
}
|
||||||
|
|
||||||
export default FormatTyp;
|
export default FormatTyp;
|
||||||
|
|||||||
@@ -29,21 +29,21 @@ describe('getRolaString', () => {
|
|||||||
|
|
||||||
it('returns correct string for FA=1', () => {
|
it('returns correct string for FA=1', () => {
|
||||||
const key = Object.keys(FA1RolaPodmiotu3)[0];
|
const key = Object.keys(FA1RolaPodmiotu3)[0];
|
||||||
const expected = FA1RolaPodmiotu3[key as keyof typeof FA1RolaPodmiotu3].split('-')[0];
|
const expected = FA1RolaPodmiotu3[key as keyof typeof FA1RolaPodmiotu3];
|
||||||
|
|
||||||
expect(getRolaString({ _text: key } as any, 1)).toBe(expected);
|
expect(getRolaString({ _text: key } as any, 1)).toBe(expected);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('returns correct string for FA=2', () => {
|
it('returns correct string for FA=2', () => {
|
||||||
const key = Object.keys(FA2RolaPodmiotu3)[0];
|
const key = Object.keys(FA2RolaPodmiotu3)[0];
|
||||||
const expected = FA2RolaPodmiotu3[key as keyof typeof FA2RolaPodmiotu3].split('-')[0];
|
const expected = FA2RolaPodmiotu3[key as keyof typeof FA2RolaPodmiotu3];
|
||||||
|
|
||||||
expect(getRolaString({ _text: key } as any, 2)).toBe(expected);
|
expect(getRolaString({ _text: key } as any, 2)).toBe(expected);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('returns correct string for FA=3', () => {
|
it('returns correct string for FA=3', () => {
|
||||||
const key = Object.keys(FA3RolaPodmiotu3)[0];
|
const key = Object.keys(FA3RolaPodmiotu3)[0];
|
||||||
const expected = FA3RolaPodmiotu3[key as keyof typeof FA3RolaPodmiotu3].split('-')[0];
|
const expected = FA3RolaPodmiotu3[key as keyof typeof FA3RolaPodmiotu3];
|
||||||
|
|
||||||
expect(getRolaString({ _text: key } as any, 3)).toBe(expected);
|
expect(getRolaString({ _text: key } as any, 3)).toBe(expected);
|
||||||
});
|
});
|
||||||
@@ -131,13 +131,13 @@ describe('formatDateTime', () => {
|
|||||||
it('formats date with seconds by default', () => {
|
it('formats date with seconds by default', () => {
|
||||||
const date = '2025-10-03T12:15:30Z';
|
const date = '2025-10-03T12:15:30Z';
|
||||||
|
|
||||||
expect(formatDateTime(date)).toBe('2025-10-03 14:15:30');
|
expect(formatDateTime(date)).toBe('03.10.2025 14:15:30');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('formats date without seconds if withoutSeconds true', () => {
|
it('formats date without seconds if withoutSeconds true', () => {
|
||||||
const date = '2025-10-03T12:15:30Z';
|
const date = '2025-10-03T12:15:30Z';
|
||||||
|
|
||||||
expect(formatDateTime(date, true)).toBe('2025-10-03 14:15');
|
expect(formatDateTime(date, true)).toBe('03.10.2025 14:15');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -150,6 +150,6 @@ describe('getDateTimeWithoutSeconds', () => {
|
|||||||
it('returns formatted date without seconds if _text present', () => {
|
it('returns formatted date without seconds if _text present', () => {
|
||||||
const isoDate = { _text: '2025-10-03T12:15:30Z' } as any;
|
const isoDate = { _text: '2025-10-03T12:15:30Z' } as any;
|
||||||
|
|
||||||
expect(getDateTimeWithoutSeconds(isoDate)).toBe('2025-10-03 14:15');
|
expect(getDateTimeWithoutSeconds(isoDate)).toBe('03.10.2025 14:15');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -18,11 +18,11 @@ export function getRolaString(rola: FP2 | undefined, FA: 1 | 2 | 3): string {
|
|||||||
}
|
}
|
||||||
switch (FA) {
|
switch (FA) {
|
||||||
case 1:
|
case 1:
|
||||||
return FA1RolaPodmiotu3[rola._text as keyof typeof FA1RolaPodmiotu3].split('-')[0] ?? '';
|
return FA1RolaPodmiotu3[rola._text as keyof typeof FA1RolaPodmiotu3];
|
||||||
case 2:
|
case 2:
|
||||||
return FA2RolaPodmiotu3[rola._text as keyof typeof FA2RolaPodmiotu3].split('-')[0] ?? '';
|
return FA2RolaPodmiotu3[rola._text as keyof typeof FA2RolaPodmiotu3];
|
||||||
case 3:
|
case 3:
|
||||||
return FA3RolaPodmiotu3[rola._text as keyof typeof FA3RolaPodmiotu3].split('-')[0] ?? '';
|
return FA3RolaPodmiotu3[rola._text as keyof typeof FA3RolaPodmiotu3];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -86,11 +86,11 @@ export function formatDateTime(data?: string, withoutSeconds?: boolean, withoutT
|
|||||||
const seconds: string = dateTime.getSeconds().toString().padStart(2, '0');
|
const seconds: string = dateTime.getSeconds().toString().padStart(2, '0');
|
||||||
|
|
||||||
if (withoutTime) {
|
if (withoutTime) {
|
||||||
return `${year}-${month}-${day}`;
|
return `${day}.${month}.${year}`;
|
||||||
} else if (withoutSeconds) {
|
} else if (withoutSeconds) {
|
||||||
return `${year}-${month}-${day} ${hours}:${minutes}`;
|
return `${day}.${month}.${year} ${hours}:${minutes}`;
|
||||||
}
|
}
|
||||||
return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
|
return `${day}.${month}.${year} ${hours}:${minutes}:${seconds}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getDateTimeWithoutSeconds(isoDate?: FP2): string {
|
export function getDateTimeWithoutSeconds(isoDate?: FP2): string {
|
||||||
@@ -99,3 +99,22 @@ export function getDateTimeWithoutSeconds(isoDate?: FP2): string {
|
|||||||
}
|
}
|
||||||
return formatDateTime(isoDate._text, true);
|
return formatDateTime(isoDate._text, true);
|
||||||
}
|
}
|
||||||
|
export function formatTime(data?: string, withoutSeconds?: boolean): string {
|
||||||
|
if (!data) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
const dateTime: Date = new Date(data);
|
||||||
|
|
||||||
|
if (isNaN(dateTime.getTime())) {
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
const hours: string = dateTime.getHours().toString().padStart(2, '0');
|
||||||
|
const minutes: string = dateTime.getMinutes().toString().padStart(2, '0');
|
||||||
|
const seconds: string = dateTime.getSeconds().toString().padStart(2, '0');
|
||||||
|
|
||||||
|
if (withoutSeconds) {
|
||||||
|
return `${hours}:${minutes}`;
|
||||||
|
}
|
||||||
|
return `${hours}:${minutes}:${seconds}`;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user