@snett2019/factura-pdf 1.0.0
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/README.md +7 -0
- package/example/sample-order.json +170 -0
- package/package.json +29 -0
- package/salida/cliente_256.pdf +0 -0
- package/salida/cocina_256.pdf +0 -0
- package/salida/domiciliario_256.pdf +0 -0
- package/src/generateFacturas.js +11 -0
- package/src/index.js +6 -0
- package/src/templates/cliente.js +60 -0
- package/src/templates/cocina.js +50 -0
- package/src/templates/domiciliario.js +34 -0
- package/src/utils/formatDate.js +5 -0
- package/src/utils/formatMoney.js +6 -0
- package/test/test-generate.js +4 -0
package/README.md
ADDED
@@ -0,0 +1,170 @@
|
|
1
|
+
{
|
2
|
+
"items": [
|
3
|
+
{
|
4
|
+
"id": 41,
|
5
|
+
"name": "Jugo Natural de Cholupa",
|
6
|
+
"price": 7500,
|
7
|
+
"addons": [],
|
8
|
+
"quantity": 1,
|
9
|
+
"variants": [
|
10
|
+
{
|
11
|
+
"id": 65,
|
12
|
+
"name": "Preparado con ",
|
13
|
+
"options": []
|
14
|
+
}
|
15
|
+
]
|
16
|
+
},
|
17
|
+
{
|
18
|
+
"id": 44,
|
19
|
+
"name": "Coca Cola",
|
20
|
+
"price": 4000,
|
21
|
+
"addons": [],
|
22
|
+
"quantity": 1,
|
23
|
+
"variants": [
|
24
|
+
{
|
25
|
+
"id": 70,
|
26
|
+
"name": "Tamaño",
|
27
|
+
"options": []
|
28
|
+
}
|
29
|
+
]
|
30
|
+
},
|
31
|
+
{
|
32
|
+
"id": 43,
|
33
|
+
"name": "Deluxe ",
|
34
|
+
"price": 14500,
|
35
|
+
"addons": [],
|
36
|
+
"quantity": 1,
|
37
|
+
"variants": [
|
38
|
+
{
|
39
|
+
"id": 68,
|
40
|
+
"name": "Salsas",
|
41
|
+
"options": []
|
42
|
+
},
|
43
|
+
{
|
44
|
+
"id": 69,
|
45
|
+
"name": "base de la hamburguesa",
|
46
|
+
"options": [
|
47
|
+
{
|
48
|
+
"id": 52,
|
49
|
+
"name": "Pan",
|
50
|
+
"price_adjustment": 0
|
51
|
+
}
|
52
|
+
]
|
53
|
+
}
|
54
|
+
]
|
55
|
+
},
|
56
|
+
{
|
57
|
+
"id": 45,
|
58
|
+
"name": "La Cariñosa ",
|
59
|
+
"price": 16500,
|
60
|
+
"addons": [
|
61
|
+
{
|
62
|
+
"id": 19,
|
63
|
+
"name": "Extra queso",
|
64
|
+
"price": 2900,
|
65
|
+
"quantity": 1
|
66
|
+
},
|
67
|
+
{
|
68
|
+
"id": 20,
|
69
|
+
"name": "Carne",
|
70
|
+
"price": 5500,
|
71
|
+
"quantity": 1
|
72
|
+
},
|
73
|
+
{
|
74
|
+
"id": 21,
|
75
|
+
"name": "Huevo",
|
76
|
+
"price": 1900,
|
77
|
+
"quantity": 1
|
78
|
+
},
|
79
|
+
{
|
80
|
+
"id": 22,
|
81
|
+
"name": "Tocineta",
|
82
|
+
"price": 1000,
|
83
|
+
"quantity": 1
|
84
|
+
}
|
85
|
+
],
|
86
|
+
"quantity": 1,
|
87
|
+
"variants": [
|
88
|
+
{
|
89
|
+
"id": 71,
|
90
|
+
"name": "base de la hamburguesa",
|
91
|
+
"options": [
|
92
|
+
{
|
93
|
+
"id": 53,
|
94
|
+
"name": "platano maduro",
|
95
|
+
"price_adjustment": 2000
|
96
|
+
}
|
97
|
+
]
|
98
|
+
},
|
99
|
+
{
|
100
|
+
"id": 72,
|
101
|
+
"name": "Salsas",
|
102
|
+
"options": [
|
103
|
+
{
|
104
|
+
"id": 54,
|
105
|
+
"name": "ajo",
|
106
|
+
"price_adjustment": 0
|
107
|
+
},
|
108
|
+
{
|
109
|
+
"id": 55,
|
110
|
+
"name": "tártara",
|
111
|
+
"price_adjustment": 0
|
112
|
+
}
|
113
|
+
]
|
114
|
+
}
|
115
|
+
]
|
116
|
+
},
|
117
|
+
{
|
118
|
+
"id": 42,
|
119
|
+
"name": "La Cariñosa ",
|
120
|
+
"price": 16500,
|
121
|
+
"addons": [],
|
122
|
+
"quantity": 1,
|
123
|
+
"variants": [
|
124
|
+
{
|
125
|
+
"id": 66,
|
126
|
+
"name": "base de la hamburguesa",
|
127
|
+
"options": [
|
128
|
+
{
|
129
|
+
"id": 49,
|
130
|
+
"name": "platano maduro",
|
131
|
+
"price_adjustment": 2000
|
132
|
+
}
|
133
|
+
]
|
134
|
+
},
|
135
|
+
{
|
136
|
+
"id": 67,
|
137
|
+
"name": "Salsas",
|
138
|
+
"options": [
|
139
|
+
{
|
140
|
+
"id": 50,
|
141
|
+
"name": "ajo",
|
142
|
+
"price_adjustment": 0
|
143
|
+
},
|
144
|
+
{
|
145
|
+
"id": 51,
|
146
|
+
"name": "tártara",
|
147
|
+
"price_adjustment": 0
|
148
|
+
}
|
149
|
+
]
|
150
|
+
}
|
151
|
+
]
|
152
|
+
}
|
153
|
+
],
|
154
|
+
"order": {
|
155
|
+
"id": "f5c22e18-c91b-413e-87df-2c4cd4bb1da7",
|
156
|
+
"type": "delivery",
|
157
|
+
"number": 256,
|
158
|
+
"status": "processing",
|
159
|
+
"is_paid": false,
|
160
|
+
"created_at": "2025-04-19T19:25:09.664446+00:00",
|
161
|
+
"updated_at": "2025-04-19T19:25:09.664446+00:00",
|
162
|
+
"total_price": 74300,
|
163
|
+
"payment_type": "cash"
|
164
|
+
},
|
165
|
+
"customer": {
|
166
|
+
"name": "Nicolas Cuellar",
|
167
|
+
"phone": "573015609716",
|
168
|
+
"address": "Calle 1 # 2 - 3"
|
169
|
+
}
|
170
|
+
}
|
package/package.json
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
{
|
2
|
+
"name": "@snett2019/factura-pdf",
|
3
|
+
"version": "1.0.0",
|
4
|
+
"main": "src/index.js",
|
5
|
+
"type": "commonjs",
|
6
|
+
"scripts": {
|
7
|
+
"generar": "node test/test-generate.js"
|
8
|
+
},
|
9
|
+
"keywords": ["factura", "pdf", "generador", "facturación", "pdfkit"],
|
10
|
+
"author": "Santiago Trujillo Neuta",
|
11
|
+
"license": "MIT",
|
12
|
+
"description": "Generador de PDFs para facturación personalizada",
|
13
|
+
"dependencies": {
|
14
|
+
"currency-formatter": "^1.5.9",
|
15
|
+
"dayjs": "^1.11.13",
|
16
|
+
"moment": "^2.30.1",
|
17
|
+
"pdfkit": "^0.17.0"
|
18
|
+
},
|
19
|
+
"devDependencies": {
|
20
|
+
"open": "^10.1.2"
|
21
|
+
},
|
22
|
+
"repository": {
|
23
|
+
"type": "git",
|
24
|
+
"url": "https://github.com/Santiago-byte2002/factura-pdf.git"
|
25
|
+
},
|
26
|
+
"publishConfig": {
|
27
|
+
"access": "public"
|
28
|
+
}
|
29
|
+
}
|
Binary file
|
Binary file
|
Binary file
|
@@ -0,0 +1,11 @@
|
|
1
|
+
const generarDomiciliario = require('./templates/domiciliario');
|
2
|
+
const generarCliente = require('./templates/cliente');
|
3
|
+
const generarCocina = require('./templates/cocina');
|
4
|
+
|
5
|
+
async function generarFacturas(data, outputPath = './salida') {
|
6
|
+
generarDomiciliario(data, outputPath);
|
7
|
+
generarCliente(data, outputPath);
|
8
|
+
generarCocina(data, outputPath);
|
9
|
+
}
|
10
|
+
|
11
|
+
module.exports = { generarFacturas };
|
package/src/index.js
ADDED
@@ -0,0 +1,60 @@
|
|
1
|
+
const PDFDocument = require('pdfkit');
|
2
|
+
const fs = require('fs');
|
3
|
+
const formatMoney = require('../utils/formatMoney');
|
4
|
+
const formatDate = require('../utils/formatDate');
|
5
|
+
|
6
|
+
function generarCliente(data, outputPath) {
|
7
|
+
const doc = new PDFDocument({
|
8
|
+
size: [165, 1000], // Ancho de 58mm (165 puntos), alto libre
|
9
|
+
margin: 10 // Márgenes ajustados
|
10
|
+
});
|
11
|
+
const fileName = `${outputPath}/cliente_${data.order.number}.pdf`;
|
12
|
+
doc.pipe(fs.createWriteStream(fileName));
|
13
|
+
|
14
|
+
doc.fontSize(10).text('Recibo de Compra', { align: 'center' });
|
15
|
+
doc.moveDown();
|
16
|
+
|
17
|
+
doc.fontSize(8).text(`Cliente: ${data.customer.name}`);
|
18
|
+
doc.text(`Teléfono: ${data.customer.phone}`);
|
19
|
+
doc.text(`Dirección: ${data.customer.address}`);
|
20
|
+
doc.text(`Fecha: ${formatDate(data.order.created_at)}`);
|
21
|
+
doc.text(`Pedido #: ${data.order.number}`);
|
22
|
+
doc.text(`Forma de pago: ${data.order.payment_type}`);
|
23
|
+
doc.moveDown();
|
24
|
+
|
25
|
+
doc.fontSize(9).text('Detalle del Pedido:');
|
26
|
+
doc.moveDown(0.5);
|
27
|
+
|
28
|
+
data.items.forEach(item => {
|
29
|
+
const totalItem = item.price * item.quantity;
|
30
|
+
doc.text(`${item.quantity}x ${item.name} - ${formatMoney(totalItem)}`);
|
31
|
+
|
32
|
+
// Variantes
|
33
|
+
item.variants.forEach(variant => {
|
34
|
+
if (variant.options.length > 0) {
|
35
|
+
const optionsList = variant.options.map(opt => {
|
36
|
+
const priceText = opt.price_adjustment > 0 ? ` (+${formatMoney(opt.price_adjustment)})` : '';
|
37
|
+
return `${opt.name}${priceText}`;
|
38
|
+
}).join(', ');
|
39
|
+
doc.fontSize(8).text(` • ${variant.name}: ${optionsList}`);
|
40
|
+
}
|
41
|
+
});
|
42
|
+
|
43
|
+
// Addons (si existen)
|
44
|
+
if (item.addons.length > 0) {
|
45
|
+
doc.fontSize(9).text(` • Extras:`);
|
46
|
+
item.addons.forEach(addon => {
|
47
|
+
doc.text(` - ${addon.name} (${formatMoney(addon.price)})`);
|
48
|
+
});
|
49
|
+
}
|
50
|
+
|
51
|
+
doc.moveDown(0.5);
|
52
|
+
});
|
53
|
+
|
54
|
+
doc.moveDown();
|
55
|
+
doc.fontSize(9).text(`Total: ${formatMoney(data.order.total_price)}`, { align: 'right' });
|
56
|
+
|
57
|
+
doc.end();
|
58
|
+
}
|
59
|
+
|
60
|
+
module.exports = generarCliente;
|
@@ -0,0 +1,50 @@
|
|
1
|
+
const PDFDocument = require('pdfkit');
|
2
|
+
const fs = require('fs');
|
3
|
+
const formatDate = require('../utils/formatDate');
|
4
|
+
|
5
|
+
function generarCocina(data, outputPath) {
|
6
|
+
const doc = new PDFDocument({
|
7
|
+
size: [165, 1000], // Ancho de 58mm (165 puntos), alto libre
|
8
|
+
margin: 10 // Márgenes ajustados
|
9
|
+
});
|
10
|
+
const fileName = `${outputPath}/cocina_${data.order.number}.pdf`;
|
11
|
+
doc.pipe(fs.createWriteStream(fileName));
|
12
|
+
|
13
|
+
doc.fontSize(10).text('Orden para Cocina', { align: 'center' });
|
14
|
+
doc.moveDown();
|
15
|
+
|
16
|
+
doc.fontSize(8).text(`Cliente: ${data.customer.name}`);
|
17
|
+
doc.text(`Dirección: ${data.customer.address}`);
|
18
|
+
doc.text(`Fecha: ${formatDate(data.order.created_at)}`);
|
19
|
+
doc.text(`Pedido #: ${data.order.number}`);
|
20
|
+
doc.moveDown();
|
21
|
+
|
22
|
+
doc.fontSize(9).text('Preparar los siguientes productos:');
|
23
|
+
doc.moveDown(0.5);
|
24
|
+
|
25
|
+
data.items.forEach(item => {
|
26
|
+
doc.fontSize(8).text(`- ${item.quantity}x ${item.name}`);
|
27
|
+
|
28
|
+
// Variantes
|
29
|
+
item.variants.forEach(variant => {
|
30
|
+
if (variant.options.length > 0) {
|
31
|
+
const optionsList = variant.options.map(opt => opt.name).join(', ');
|
32
|
+
doc.fontSize(8).text(` • ${variant.name}: ${optionsList}`);
|
33
|
+
}
|
34
|
+
});
|
35
|
+
|
36
|
+
// Addons
|
37
|
+
if (item.addons.length > 0) {
|
38
|
+
doc.fontSize(9).text(` • Extras:`);
|
39
|
+
item.addons.forEach(addon => {
|
40
|
+
doc.text(` - ${addon.quantity}x ${addon.name}`);
|
41
|
+
});
|
42
|
+
}
|
43
|
+
|
44
|
+
doc.moveDown(0.5);
|
45
|
+
});
|
46
|
+
|
47
|
+
doc.end();
|
48
|
+
}
|
49
|
+
|
50
|
+
module.exports = generarCocina;
|
@@ -0,0 +1,34 @@
|
|
1
|
+
const PDFDocument = require('pdfkit');
|
2
|
+
const fs = require('fs');
|
3
|
+
const formatMoney = require('../utils/formatMoney');
|
4
|
+
const formatDate = require('../utils/formatDate');
|
5
|
+
|
6
|
+
function generarDomiciliario(data, outputPath) {
|
7
|
+
const doc = new PDFDocument({
|
8
|
+
size: [165, 1000], // Ancho de 58mm (165 puntos), alto libre
|
9
|
+
margin: 10 // Márgenes ajustados
|
10
|
+
});
|
11
|
+
const fileName = `${outputPath}/domiciliario_${data.order.number}.pdf`;
|
12
|
+
doc.pipe(fs.createWriteStream(fileName));
|
13
|
+
|
14
|
+
doc.fontSize(8).text('Factura para Domiciliario', { align: 'center' });
|
15
|
+
doc.moveDown();
|
16
|
+
|
17
|
+
doc.fontSize(8).text(`Cliente: ${data.customer.name}`);
|
18
|
+
doc.text(`Teléfono: ${data.customer.phone}`);
|
19
|
+
doc.text(`Dirección: ${data.customer.address}`);
|
20
|
+
doc.text(`Fecha: ${formatDate(data.order.created_at)}`);
|
21
|
+
doc.text(`Forma de pago: ${data.order.payment_type}`);
|
22
|
+
doc.moveDown();
|
23
|
+
|
24
|
+
doc.fontSize(8).text('Resumen del Pedido:');
|
25
|
+
doc.moveDown(0.5);
|
26
|
+
data.items.forEach(item => {
|
27
|
+
doc.text(`- ${item.quantity}x ${item.name}`);
|
28
|
+
});
|
29
|
+
|
30
|
+
doc.end();
|
31
|
+
}
|
32
|
+
|
33
|
+
module.exports = generarDomiciliario;
|
34
|
+
|