pangea-server 3.3.144 → 3.3.145
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/helpers/arca.helpers.d.ts +2 -1
- package/dist/helpers/arca.helpers.js +102 -77
- package/dist/helpers/file-storage.helpers.d.ts +5 -3
- package/dist/helpers/file-storage.helpers.js +27 -7
- package/dist/helpers/multer.helpers.d.ts +2 -0
- package/dist/helpers/multer.helpers.js +6 -3
- package/dist/helpers/whatsapp.helpers.d.ts +2 -2
- package/dist/helpers/whatsapp.helpers.js +3 -3
- package/dist/router/call-controller.js +4 -2
- package/dist/types/arca.types.d.ts +4 -2
- package/dist/types/global.types.d.ts +1 -0
- package/package.json +1 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { ArcaConfig, ArcaVoucherType, ArcaVoucherInfo, ArcaCreateInvoiceCOptions, ArcaCreateVoucherRes } from '../types/arca.types';
|
|
1
|
+
import type { ArcaConfig, ArcaVoucherType, ArcaVoucherInfo, ArcaCreateInvoiceCOptions, ArcaCreateInvoiceCPdfOptions, ArcaCreateVoucherRes } from '../types/arca.types';
|
|
2
2
|
export declare class Arca {
|
|
3
3
|
private __cuit;
|
|
4
4
|
private __issuer;
|
|
@@ -7,4 +7,5 @@ export declare class Arca {
|
|
|
7
7
|
getLastVoucher(pointOfSale: number, voucherType: ArcaVoucherType): Promise<number>;
|
|
8
8
|
getVoucherInfo(voucherNumber: number, pointOfSale: number, voucherType: ArcaVoucherType): Promise<ArcaVoucherInfo | null>;
|
|
9
9
|
createInvoiceC(options: ArcaCreateInvoiceCOptions): Promise<ArcaCreateVoucherRes>;
|
|
10
|
+
createInvoiceCPdf(options: ArcaCreateInvoiceCPdfOptions): Promise<string>;
|
|
10
11
|
}
|
|
@@ -100,20 +100,19 @@ class Arca {
|
|
|
100
100
|
};
|
|
101
101
|
}
|
|
102
102
|
async createInvoiceC(options) {
|
|
103
|
-
const { pointOfSale, receiver, concept,
|
|
103
|
+
const { pointOfSale, receiver, concept, amount, service } = options;
|
|
104
104
|
const voucherType = '11_invoice_c';
|
|
105
105
|
const isConceptProducts = concept === '1_products';
|
|
106
106
|
if (!isConceptProducts && !service)
|
|
107
107
|
throw new Error('Service dates are required');
|
|
108
|
-
const
|
|
109
|
-
const receiverDocumentNumber = isFinalConsumer ? 0 : receiver.documentNumber || 0;
|
|
110
|
-
const receiverVatCondition = receiver.vatCondition || '5_final_consumer';
|
|
111
|
-
const receiverName = receiver.name || 'CONSUMIDOR FINAL';
|
|
108
|
+
const { receiverDocumentNumber, receiverVatCondition } = getReceiverFields(receiver);
|
|
112
109
|
const lastVoucherNumber = await this.getLastVoucher(pointOfSale, voucherType);
|
|
113
110
|
const voucherNumber = lastVoucherNumber + 1;
|
|
114
|
-
const
|
|
115
|
-
const
|
|
116
|
-
const
|
|
111
|
+
const localDate = getLocalDate();
|
|
112
|
+
const voucherDate = getArcaDate(localDate.toISOString().split('T')[0]);
|
|
113
|
+
const day = String(localDate.getDate()).padStart(2, '0');
|
|
114
|
+
const month = String(localDate.getMonth() + 1).padStart(2, '0');
|
|
115
|
+
const issueDate = `${localDate.getFullYear()}-${month}-${day}`;
|
|
117
116
|
const params = {
|
|
118
117
|
PtoVta: pointOfSale,
|
|
119
118
|
CbteTipo: voucherTypeIds[voucherType],
|
|
@@ -133,78 +132,18 @@ class Arca {
|
|
|
133
132
|
ImpTrib: 0,
|
|
134
133
|
MonId: 'PES',
|
|
135
134
|
MonCotiz: 1,
|
|
136
|
-
FchServDesde: isConceptProducts ? null :
|
|
137
|
-
FchServHasta: isConceptProducts ? null :
|
|
138
|
-
FchVtoPago: isConceptProducts ? null :
|
|
135
|
+
FchServDesde: isConceptProducts ? null : getArcaDate(service.from),
|
|
136
|
+
FchServHasta: isConceptProducts ? null : getArcaDate(service.to),
|
|
137
|
+
FchVtoPago: isConceptProducts ? null : getArcaDate(service.paymentDueDate),
|
|
139
138
|
};
|
|
140
139
|
try {
|
|
141
140
|
const res = await this.__afip.ElectronicBilling.createVoucher(params);
|
|
142
|
-
const finalRes = {
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
const caeDateStr = res.CAEFchVto.replace(/-/g, '');
|
|
149
|
-
const caeDueDate = `${caeDateStr.slice(6, 8)}/${caeDateStr.slice(4, 6)}/${caeDateStr.slice(0, 4)}`;
|
|
150
|
-
const timestamp = localDate
|
|
151
|
-
.toISOString()
|
|
152
|
-
.replace(/[-:T.]/g, '')
|
|
153
|
-
.slice(0, 14);
|
|
154
|
-
const clientName = receiverName.replace(/\s+/g, '_').toLowerCase();
|
|
155
|
-
const fileName = `${timestamp}_${clientName}.pdf`;
|
|
156
|
-
const pdfData = {
|
|
157
|
-
file_name: fileName,
|
|
158
|
-
send_to: receiver.email || undefined,
|
|
159
|
-
template: {
|
|
160
|
-
name: 'invoice-c',
|
|
161
|
-
params: {
|
|
162
|
-
voucher_number: voucherNumber,
|
|
163
|
-
sales_point: pointOfSale,
|
|
164
|
-
issue_date: issueDate,
|
|
165
|
-
cae_due_date: caeDueDate,
|
|
166
|
-
issuer_cuit: this.__cuit,
|
|
167
|
-
cae: res.CAE,
|
|
168
|
-
issuer_business_name: this.__issuer.businessName,
|
|
169
|
-
issuer_address: this.__issuer.address,
|
|
170
|
-
issuer_iva_condition: this.__issuer.vatCondition,
|
|
171
|
-
issuer_gross_income: this.__issuer.grossIncome,
|
|
172
|
-
issuer_activity_start_date: this.__issuer.activityStartDate.split('-').reverse().join('/'),
|
|
173
|
-
receiver_name: receiverName,
|
|
174
|
-
receiver_address: receiver.address || '-',
|
|
175
|
-
receiver_document_type: documentTypeIds[receiver.documentType],
|
|
176
|
-
receiver_document_number: receiverDocumentNumber,
|
|
177
|
-
receiver_iva_condition: vatConditionReceiverDescriptions[receiverVatCondition],
|
|
178
|
-
sale_condition: 'Contado',
|
|
179
|
-
currency_id: 'ARS',
|
|
180
|
-
currency_rate: 1,
|
|
181
|
-
concept: conceptIds[concept],
|
|
182
|
-
items: items.map((item) => ({
|
|
183
|
-
code: item.code,
|
|
184
|
-
description: item.description,
|
|
185
|
-
quantity: item.quantity,
|
|
186
|
-
unit_price: item.price,
|
|
187
|
-
subtotal: item.quantity * item.price,
|
|
188
|
-
})),
|
|
189
|
-
vat_amount: 0,
|
|
190
|
-
tributes_amount: 0,
|
|
191
|
-
total_amount: amount,
|
|
192
|
-
billing_from: isConceptProducts ? undefined : service.from.split('-').reverse().join('/'),
|
|
193
|
-
billing_to: isConceptProducts ? undefined : service.to.split('-').reverse().join('/'),
|
|
194
|
-
payment_due_date: isConceptProducts ? undefined : service.paymentDueDate.split('-').reverse().join('/'),
|
|
195
|
-
net_amount_taxed: amount,
|
|
196
|
-
net_amount_untaxed: 0,
|
|
197
|
-
exempt_amount: 0,
|
|
198
|
-
},
|
|
199
|
-
},
|
|
200
|
-
};
|
|
201
|
-
const pdfRes = await this.__afip.ElectronicBilling.createPDF(pdfData);
|
|
202
|
-
finalRes.file = pdfRes.file;
|
|
203
|
-
}
|
|
204
|
-
catch (pdfErr) {
|
|
205
|
-
(0, helpers_1.printDanger)('arca', 'Error creating PDF (voucher was created)');
|
|
206
|
-
console.log(JSON.stringify(pdfErr, null, 2));
|
|
207
|
-
}
|
|
141
|
+
const finalRes = {
|
|
142
|
+
voucherNumber,
|
|
143
|
+
issueDate,
|
|
144
|
+
cae: res.CAE,
|
|
145
|
+
caeExpirationDate: res.CAEFchVto,
|
|
146
|
+
};
|
|
208
147
|
(0, helpers_1.printSuccess)('arca', 'Voucher created successfully');
|
|
209
148
|
console.log('params:');
|
|
210
149
|
console.log(params);
|
|
@@ -220,5 +159,91 @@ class Arca {
|
|
|
220
159
|
helpers_1.AppError.Throw({ statusCodeName: 'INTERNAL_SERVER_ERROR', errorCode: 'VOUCHER_CREATION_FAILED' });
|
|
221
160
|
}
|
|
222
161
|
}
|
|
162
|
+
async createInvoiceCPdf(options) {
|
|
163
|
+
const { pointOfSale, receiver, concept, items, amount, service, voucherNumber, issueDate, cae, caeExpirationDate } = options;
|
|
164
|
+
const isConceptProducts = concept === '1_products';
|
|
165
|
+
const { receiverDocumentNumber, receiverVatCondition } = getReceiverFields(receiver);
|
|
166
|
+
const receiverName = receiver.name || 'CONSUMIDOR FINAL';
|
|
167
|
+
const caeDateStr = caeExpirationDate.replace(/-/g, '');
|
|
168
|
+
const caeDueDate = `${caeDateStr.slice(6, 8)}/${caeDateStr.slice(4, 6)}/${caeDateStr.slice(0, 4)}`;
|
|
169
|
+
const timestamp = getLocalDate()
|
|
170
|
+
.toISOString()
|
|
171
|
+
.replace(/[-:T.]/g, '')
|
|
172
|
+
.slice(0, 14);
|
|
173
|
+
const clientName = receiverName.replace(/\s+/g, '_').toLowerCase();
|
|
174
|
+
const fileName = `${timestamp}_${clientName}.pdf`;
|
|
175
|
+
const pdfData = {
|
|
176
|
+
file_name: fileName,
|
|
177
|
+
send_to: receiver.email || undefined,
|
|
178
|
+
template: {
|
|
179
|
+
name: 'invoice-c',
|
|
180
|
+
params: {
|
|
181
|
+
voucher_number: voucherNumber,
|
|
182
|
+
sales_point: pointOfSale,
|
|
183
|
+
issue_date: formatDateSlash(issueDate),
|
|
184
|
+
cae_due_date: caeDueDate,
|
|
185
|
+
issuer_cuit: this.__cuit,
|
|
186
|
+
cae,
|
|
187
|
+
issuer_business_name: this.__issuer.businessName,
|
|
188
|
+
issuer_address: this.__issuer.address,
|
|
189
|
+
issuer_iva_condition: this.__issuer.vatCondition,
|
|
190
|
+
issuer_gross_income: this.__issuer.grossIncome,
|
|
191
|
+
issuer_activity_start_date: formatDateSlash(this.__issuer.activityStartDate),
|
|
192
|
+
receiver_name: receiverName,
|
|
193
|
+
receiver_address: receiver.address || '-',
|
|
194
|
+
receiver_document_type: documentTypeIds[receiver.documentType],
|
|
195
|
+
receiver_document_number: receiverDocumentNumber,
|
|
196
|
+
receiver_iva_condition: vatConditionReceiverDescriptions[receiverVatCondition],
|
|
197
|
+
sale_condition: 'Contado',
|
|
198
|
+
currency_id: 'ARS',
|
|
199
|
+
currency_rate: 1,
|
|
200
|
+
concept: conceptIds[concept],
|
|
201
|
+
items: items.map((item) => ({
|
|
202
|
+
code: item.code,
|
|
203
|
+
description: item.description,
|
|
204
|
+
quantity: item.quantity,
|
|
205
|
+
unit_price: item.price,
|
|
206
|
+
subtotal: item.quantity * item.price,
|
|
207
|
+
})),
|
|
208
|
+
vat_amount: 0,
|
|
209
|
+
tributes_amount: 0,
|
|
210
|
+
total_amount: amount,
|
|
211
|
+
billing_from: isConceptProducts ? undefined : formatDateSlash(service.from),
|
|
212
|
+
billing_to: isConceptProducts ? undefined : formatDateSlash(service.to),
|
|
213
|
+
payment_due_date: isConceptProducts ? undefined : formatDateSlash(service.paymentDueDate),
|
|
214
|
+
net_amount_taxed: amount,
|
|
215
|
+
net_amount_untaxed: 0,
|
|
216
|
+
exempt_amount: 0,
|
|
217
|
+
},
|
|
218
|
+
},
|
|
219
|
+
};
|
|
220
|
+
try {
|
|
221
|
+
const pdfRes = await this.__afip.ElectronicBilling.createPDF(pdfData);
|
|
222
|
+
(0, helpers_1.printSuccess)('arca', 'PDF created successfully');
|
|
223
|
+
return pdfRes.file;
|
|
224
|
+
}
|
|
225
|
+
catch (err) {
|
|
226
|
+
(0, helpers_1.printDanger)('arca', 'Error creating PDF');
|
|
227
|
+
console.log(JSON.stringify(err, null, 2));
|
|
228
|
+
helpers_1.AppError.Throw({ statusCodeName: 'INTERNAL_SERVER_ERROR', errorCode: 'PDF_CREATION_FAILED' });
|
|
229
|
+
}
|
|
230
|
+
}
|
|
223
231
|
}
|
|
224
232
|
exports.Arca = Arca;
|
|
233
|
+
// internal functions
|
|
234
|
+
function getReceiverFields(receiver) {
|
|
235
|
+
const isFinalConsumer = receiver.documentType === '99_final_consumer';
|
|
236
|
+
return {
|
|
237
|
+
receiverDocumentNumber: isFinalConsumer ? 0 : receiver.documentNumber || 0,
|
|
238
|
+
receiverVatCondition: receiver.vatCondition || '5_final_consumer',
|
|
239
|
+
};
|
|
240
|
+
}
|
|
241
|
+
function getLocalDate() {
|
|
242
|
+
return new Date(Date.now() + -3 * 60 * 60000);
|
|
243
|
+
}
|
|
244
|
+
function getArcaDate(date) {
|
|
245
|
+
return Number(date.replace(/-/g, ''));
|
|
246
|
+
}
|
|
247
|
+
function formatDateSlash(date) {
|
|
248
|
+
return date.split('-').reverse().join('/');
|
|
249
|
+
}
|
|
@@ -5,10 +5,12 @@ type GeneralUploadParamsConfig = {
|
|
|
5
5
|
export declare abstract class FileStorage {
|
|
6
6
|
static GenerateDownloadUrl(fileName: string): Promise<string>;
|
|
7
7
|
static GenerateDownloadUrls(fileNames: string[]): Promise<string[]>;
|
|
8
|
-
static UploadImage(image: UploadableImage, folder: string,
|
|
8
|
+
static UploadImage(image: UploadableImage, folder: string, previousImage?: string | null): Promise<string>;
|
|
9
9
|
static UploadImages(images: UploadableImage[], folder: string): Promise<string[]>;
|
|
10
|
-
static UploadVideo(
|
|
11
|
-
static UploadVideos(
|
|
10
|
+
static UploadVideo(video: MulterFile, folder: string, previousVideo?: string | null): Promise<string>;
|
|
11
|
+
static UploadVideos(videos: MulterFile[], folder: string): Promise<string[]>;
|
|
12
|
+
static UploadFile(file: UploadableFile, folder: string, previousFile?: string | null): Promise<string>;
|
|
13
|
+
static UploadFiles(files: UploadableFile[], folder: string): Promise<string[]>;
|
|
12
14
|
static GenerateUploadUrl(config: GeneralUploadParamsConfig): Promise<{
|
|
13
15
|
url: string;
|
|
14
16
|
fileName: string;
|
|
@@ -27,18 +27,38 @@ class FileStorage {
|
|
|
27
27
|
static GenerateDownloadUrls(fileNames) {
|
|
28
28
|
return Promise.all(fileNames.map((fileName) => this.GenerateDownloadUrl(fileName)));
|
|
29
29
|
}
|
|
30
|
-
static async UploadImage(image, folder,
|
|
31
|
-
if (
|
|
32
|
-
await this.DeleteFile(
|
|
30
|
+
static async UploadImage(image, folder, previousImage) {
|
|
31
|
+
if (previousImage)
|
|
32
|
+
await this.DeleteFile(previousImage);
|
|
33
33
|
const isString = typeof image === 'string';
|
|
34
34
|
const buffer = isString ? await promises_1.default.readFile(path_1.default.join(process.cwd(), image)) : image.buffer;
|
|
35
35
|
const fileType = isString ? 'image/png' : image.mimetype;
|
|
36
36
|
return uploadFile(buffer, { folder, fileType });
|
|
37
37
|
}
|
|
38
|
-
static UploadImages(images, folder) {
|
|
38
|
+
static async UploadImages(images, folder) {
|
|
39
39
|
return Promise.all(images.map((image) => this.UploadImage(image, folder)));
|
|
40
40
|
}
|
|
41
|
-
static async UploadVideo(
|
|
41
|
+
static async UploadVideo(video, folder, previousVideo) {
|
|
42
|
+
if (previousVideo)
|
|
43
|
+
await this.DeleteFile(previousVideo);
|
|
44
|
+
const stream = fs_1.default.createReadStream(video.path);
|
|
45
|
+
try {
|
|
46
|
+
return await uploadFile(stream, { folder, fileType: video.mimetype });
|
|
47
|
+
}
|
|
48
|
+
finally {
|
|
49
|
+
promises_1.default.unlink(video.path);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
static UploadVideos(videos, folder) {
|
|
53
|
+
return Promise.all(videos.map((video) => this.UploadVideo(video, folder)));
|
|
54
|
+
}
|
|
55
|
+
static async UploadFile(file, folder, previousFile) {
|
|
56
|
+
if (previousFile)
|
|
57
|
+
await this.DeleteFile(previousFile);
|
|
58
|
+
if (typeof file === 'string') {
|
|
59
|
+
const buffer = await promises_1.default.readFile(path_1.default.join(process.cwd(), file));
|
|
60
|
+
return uploadFile(buffer, { folder, fileType: 'application/octet-stream' });
|
|
61
|
+
}
|
|
42
62
|
const stream = fs_1.default.createReadStream(file.path);
|
|
43
63
|
try {
|
|
44
64
|
return await uploadFile(stream, { folder, fileType: file.mimetype });
|
|
@@ -47,8 +67,8 @@ class FileStorage {
|
|
|
47
67
|
promises_1.default.unlink(file.path);
|
|
48
68
|
}
|
|
49
69
|
}
|
|
50
|
-
static
|
|
51
|
-
return Promise.all(files.map((file) => this.
|
|
70
|
+
static UploadFiles(files, folder) {
|
|
71
|
+
return Promise.all(files.map((file) => this.UploadFile(file, folder)));
|
|
52
72
|
}
|
|
53
73
|
static async GenerateUploadUrl(config) {
|
|
54
74
|
const params = { ...getGeneralUploadParams(config), Expires: expiresTime };
|
|
@@ -2,3 +2,5 @@ export declare const processImage: (req: Req, res: Res, next: Next) => void;
|
|
|
2
2
|
export declare const processImages: (req: Req, res: Res, next: Next) => void;
|
|
3
3
|
export declare const processVideo: (req: Req, res: Res, next: Next) => void;
|
|
4
4
|
export declare const processVideos: (req: Req, res: Res, next: Next) => void;
|
|
5
|
+
export declare const processFile: (req: Req, res: Res, next: Next) => void;
|
|
6
|
+
export declare const processFiles: (req: Req, res: Res, next: Next) => void;
|
|
@@ -3,23 +3,26 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.processVideos = exports.processVideo = exports.processImages = exports.processImage = void 0;
|
|
6
|
+
exports.processFiles = exports.processFile = exports.processVideos = exports.processVideo = exports.processImages = exports.processImage = void 0;
|
|
7
7
|
const multer_1 = __importDefault(require("multer"));
|
|
8
8
|
// helpers
|
|
9
9
|
const helpers_1 = require("../helpers");
|
|
10
10
|
const imageStorage = multer_1.default.memoryStorage();
|
|
11
11
|
const videoStorage = multer_1.default.diskStorage({});
|
|
12
|
+
const fileStorage = multer_1.default.diskStorage({});
|
|
12
13
|
const invalidInputDataError = new helpers_1.AppError({ statusCodeName: 'BAD_REQUEST', errorCode: 'INVALID_INPUT_DATA' });
|
|
13
14
|
exports.processImage = getProcessFn({ type: 'image', method: 'single' });
|
|
14
15
|
exports.processImages = getProcessFn({ type: 'image', method: 'array' });
|
|
15
16
|
exports.processVideo = getProcessFn({ type: 'video', method: 'single' });
|
|
16
17
|
exports.processVideos = getProcessFn({ type: 'video', method: 'array' });
|
|
18
|
+
exports.processFile = getProcessFn({ type: 'file', method: 'single' });
|
|
19
|
+
exports.processFiles = getProcessFn({ type: 'file', method: 'array' });
|
|
17
20
|
function getProcessFn({ type, method }) {
|
|
18
21
|
return (req, res, next) => {
|
|
19
22
|
const process = (0, multer_1.default)({
|
|
20
|
-
storage: type === 'image' ? imageStorage : videoStorage,
|
|
23
|
+
storage: type === 'image' ? imageStorage : type === 'video' ? videoStorage : fileStorage,
|
|
21
24
|
fileFilter: (_req, file, next) => {
|
|
22
|
-
if (!file.mimetype.startsWith(`${type}/`)) {
|
|
25
|
+
if (type !== 'file' && !file.mimetype.startsWith(`${type}/`)) {
|
|
23
26
|
next(invalidInputDataError);
|
|
24
27
|
return;
|
|
25
28
|
}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
export declare class Whatsapp {
|
|
2
2
|
private __accessToken;
|
|
3
|
-
private
|
|
3
|
+
private __phoneNumber;
|
|
4
4
|
constructor(config: {
|
|
5
5
|
accessToken: string;
|
|
6
|
-
|
|
6
|
+
phoneNumber: string;
|
|
7
7
|
});
|
|
8
8
|
sendText(to: string, text: string): Promise<import("@whatsapp-cloudapi/types/cloudapi", { with: { "resolution-mode": "import" } }).CloudAPIResponse>;
|
|
9
9
|
}
|
|
@@ -8,10 +8,10 @@ const client_1 = __importDefault(require("@whatsapp-cloudapi/client"));
|
|
|
8
8
|
class Whatsapp {
|
|
9
9
|
constructor(config) {
|
|
10
10
|
this.__accessToken = config.accessToken;
|
|
11
|
-
this.
|
|
11
|
+
this.__phoneNumber = config.phoneNumber;
|
|
12
12
|
}
|
|
13
|
-
|
|
14
|
-
return client_1.default.sendTextMessage({ accessToken: this.__accessToken, from: this.
|
|
13
|
+
sendText(to, text) {
|
|
14
|
+
return client_1.default.sendTextMessage({ accessToken: this.__accessToken, from: this.__phoneNumber, to, text });
|
|
15
15
|
}
|
|
16
16
|
}
|
|
17
17
|
exports.Whatsapp = Whatsapp;
|
|
@@ -60,10 +60,12 @@ async function setFilesUrls(data) {
|
|
|
60
60
|
const lowerKey = key.toLowerCase();
|
|
61
61
|
if (lowerKey.endsWith('url') || lowerKey.endsWith('urls'))
|
|
62
62
|
return;
|
|
63
|
-
if ((lowerKey.endsWith('image') || lowerKey.endsWith('video')
|
|
63
|
+
if ((lowerKey.endsWith('image') || lowerKey.endsWith('video') || key === 'file' || key.endsWith('File')) &&
|
|
64
|
+
(typeof val === 'string' || val === null)) {
|
|
64
65
|
return 'single';
|
|
65
66
|
}
|
|
66
|
-
if ((lowerKey.endsWith('images') || lowerKey.endsWith('videos')
|
|
67
|
+
if ((lowerKey.endsWith('images') || lowerKey.endsWith('videos') || key === 'files' || key.endsWith('Files')) &&
|
|
68
|
+
Array.isArray(val))
|
|
67
69
|
return 'plural';
|
|
68
70
|
}
|
|
69
71
|
function collect(node) {
|
|
@@ -62,7 +62,6 @@ export type ArcaCreateInvoiceCOptions = {
|
|
|
62
62
|
email?: string | null;
|
|
63
63
|
};
|
|
64
64
|
concept: ArcaConcept;
|
|
65
|
-
items: ArcaCreateInvoiceCOptionsItem[];
|
|
66
65
|
amount: number;
|
|
67
66
|
service?: {
|
|
68
67
|
from: string;
|
|
@@ -72,7 +71,10 @@ export type ArcaCreateInvoiceCOptions = {
|
|
|
72
71
|
};
|
|
73
72
|
export type ArcaCreateVoucherRes = {
|
|
74
73
|
voucherNumber: number;
|
|
74
|
+
issueDate: string;
|
|
75
75
|
cae: string;
|
|
76
76
|
caeExpirationDate: string;
|
|
77
|
-
|
|
77
|
+
};
|
|
78
|
+
export type ArcaCreateInvoiceCPdfOptions = ArcaCreateInvoiceCOptions & ArcaCreateVoucherRes & {
|
|
79
|
+
items: ArcaCreateInvoiceCOptionsItem[];
|
|
78
80
|
};
|