@acontplus/ng-common 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 +357 -0
- package/fesm2022/acontplus-ng-common.mjs +1072 -0
- package/fesm2022/acontplus-ng-common.mjs.map +1 -0
- package/package.json +76 -0
- package/types/acontplus-ng-common.d.ts +455 -0
package/README.md
ADDED
|
@@ -0,0 +1,357 @@
|
|
|
1
|
+
# @acontplus/ng-common
|
|
2
|
+
|
|
3
|
+
Librería común para aplicaciones Angular con funcionalidades de WhatsApp Cloud API, reportes e impresión. Incluye utilidades para formateo de teléfonos, manejo de archivos y generación de parámetros de reportes.
|
|
4
|
+
|
|
5
|
+
## Instalación
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @acontplus/ng-common
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Configuración
|
|
12
|
+
|
|
13
|
+
### Tokens de Inyección
|
|
14
|
+
|
|
15
|
+
La librería utiliza tres tokens principales para la inyección de dependencias:
|
|
16
|
+
|
|
17
|
+
- `WHATSAPP_MESSAGING_PORT` - Para funcionalidades de WhatsApp
|
|
18
|
+
- `REPORT_PORT` - Para generación de reportes
|
|
19
|
+
- `PRINTER_PORT` - Para funcionalidades de impresión
|
|
20
|
+
|
|
21
|
+
### Configurar en tu app.config.ts
|
|
22
|
+
|
|
23
|
+
```typescript
|
|
24
|
+
import {
|
|
25
|
+
WHATSAPP_MESSAGING_PORT,
|
|
26
|
+
REPORT_PORT,
|
|
27
|
+
PRINTER_PORT,
|
|
28
|
+
MetaWhatsAppAdapter,
|
|
29
|
+
ReportGenerationAdapter,
|
|
30
|
+
PrinterAdapter,
|
|
31
|
+
} from '@acontplus/ng-common';
|
|
32
|
+
|
|
33
|
+
export const appConfig: ApplicationConfig = {
|
|
34
|
+
providers: [
|
|
35
|
+
// WhatsApp Cloud API
|
|
36
|
+
{ provide: WHATSAPP_MESSAGING_PORT, useClass: MetaWhatsAppAdapter },
|
|
37
|
+
|
|
38
|
+
// Reportes
|
|
39
|
+
{ provide: REPORT_PORT, useClass: ReportGenerationAdapter },
|
|
40
|
+
|
|
41
|
+
// Impresión
|
|
42
|
+
{ provide: PRINTER_PORT, useClass: PrinterAdapter },
|
|
43
|
+
],
|
|
44
|
+
};
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
## Uso
|
|
48
|
+
|
|
49
|
+
### WhatsApp Cloud API
|
|
50
|
+
|
|
51
|
+
```typescript
|
|
52
|
+
import { WhatsAppMessagingFacade } from '@acontplus/ng-common';
|
|
53
|
+
|
|
54
|
+
@Component({...})
|
|
55
|
+
export class MyComponent {
|
|
56
|
+
constructor(private whatsapp: WhatsAppMessagingFacade) {}
|
|
57
|
+
|
|
58
|
+
// 1. Enviar texto simple (requiere ventana 24h)
|
|
59
|
+
sendText() {
|
|
60
|
+
this.whatsapp.sendSimpleText('0987654321', 'Hola mundo!').subscribe();
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// 2. Enviar con template (funciona siempre - RECOMENDADO)
|
|
64
|
+
sendWithTemplate() {
|
|
65
|
+
this.whatsapp.sendTemplateText(
|
|
66
|
+
'0987654321',
|
|
67
|
+
'hello_world',
|
|
68
|
+
['Juan', 'Pérez'], // parámetros {{1}}, {{2}}
|
|
69
|
+
'es_EC'
|
|
70
|
+
).subscribe();
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// 3. Enviar documento por URL (requiere ventana 24h)
|
|
74
|
+
sendDocumentByUrl() {
|
|
75
|
+
this.whatsapp.sendDocument(
|
|
76
|
+
'0987654321',
|
|
77
|
+
'https://mi-servidor.com/documento.pdf',
|
|
78
|
+
'Tu factura está lista',
|
|
79
|
+
'factura-001.pdf'
|
|
80
|
+
).subscribe();
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// 4. Enviar documento con template (funciona siempre - RECOMENDADO)
|
|
84
|
+
sendDocumentWithFile(file: File) {
|
|
85
|
+
this.whatsapp.sendDocumentWithTemplate({
|
|
86
|
+
phone: '0987654321',
|
|
87
|
+
file: file,
|
|
88
|
+
templateName: 'notificacion_documento',
|
|
89
|
+
languageCode: 'es_EC',
|
|
90
|
+
bodyParams: ['Juan Pérez', 'Factura #001'],
|
|
91
|
+
filename: 'factura-001.pdf'
|
|
92
|
+
}).subscribe();
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
// Caso de uso completo: Entrega de documentos
|
|
96
|
+
deliverInvoice(file: File) {
|
|
97
|
+
this.whatsapp.deliverDocument({
|
|
98
|
+
phone: '0987654321',
|
|
99
|
+
file: file,
|
|
100
|
+
customerName: 'Juan Pérez',
|
|
101
|
+
establishmentName: 'Mi Empresa S.A.',
|
|
102
|
+
documentSeries: 'FAC-001-001-000001234',
|
|
103
|
+
documentType: 'FACTURA'
|
|
104
|
+
}).subscribe();
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
### Utilidades de Formateo de Teléfonos
|
|
110
|
+
|
|
111
|
+
```typescript
|
|
112
|
+
import { PhoneFormatterUtil } from '@acontplus/ng-common';
|
|
113
|
+
|
|
114
|
+
// Validar teléfono ecuatoriano
|
|
115
|
+
const validation = PhoneFormatterUtil.validateEcuadorianPhone('0987654321');
|
|
116
|
+
if (validation.isValid) {
|
|
117
|
+
console.log('Teléfono válido');
|
|
118
|
+
} else {
|
|
119
|
+
console.log(validation.errorMessage);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
// Formatear para WhatsApp API
|
|
123
|
+
const apiPhone = PhoneFormatterUtil.formatForWhatsAppApi('0987654321');
|
|
124
|
+
// Resultado: "593987654321@c.us"
|
|
125
|
+
|
|
126
|
+
// Formatear para WhatsApp Web
|
|
127
|
+
const webPhone = PhoneFormatterUtil.formatForWhatsAppWeb('0987654321');
|
|
128
|
+
// Resultado: "593987654321"
|
|
129
|
+
|
|
130
|
+
// Formatear para mostrar al usuario
|
|
131
|
+
const displayPhone = PhoneFormatterUtil.formatForDisplay('0987654321');
|
|
132
|
+
// Resultado: "+593 98 765 4321"
|
|
133
|
+
|
|
134
|
+
// Obtener hints dinámicos
|
|
135
|
+
const hint = PhoneFormatterUtil.getPhoneHint('0987654321');
|
|
136
|
+
// Resultado: "Se enviará a: +593 98 765 4321"
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
### Reportes con Builder Configurado
|
|
140
|
+
|
|
141
|
+
```typescript
|
|
142
|
+
import { ReportFacade, ReportParamsBuilder } from '@acontplus/ng-common';
|
|
143
|
+
|
|
144
|
+
@Component({...})
|
|
145
|
+
export class ReportsComponent {
|
|
146
|
+
constructor(
|
|
147
|
+
private reports: ReportFacade,
|
|
148
|
+
private reportBuilder: ReportParamsBuilder
|
|
149
|
+
) {}
|
|
150
|
+
|
|
151
|
+
// Generar reporte usando el builder (RECOMENDADO)
|
|
152
|
+
generateInvoiceReport(id: number, codEstab: string) {
|
|
153
|
+
const docData = {
|
|
154
|
+
codDoc: 'FV', // Factura
|
|
155
|
+
id,
|
|
156
|
+
codEstab
|
|
157
|
+
};
|
|
158
|
+
|
|
159
|
+
const reportOptions = this.reportBuilder.generateReportFor(docData, 'pdf', true);
|
|
160
|
+
|
|
161
|
+
this.reports.generate(reportOptions).subscribe(response => {
|
|
162
|
+
// Manejar respuesta
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
// Generar reporte de Nota de Entrega
|
|
167
|
+
generateDeliveryNote(id: number, codEstab: string) {
|
|
168
|
+
const docData = {
|
|
169
|
+
codDoc: 'NE', // Nota de Entrega
|
|
170
|
+
id,
|
|
171
|
+
codEstab
|
|
172
|
+
};
|
|
173
|
+
|
|
174
|
+
const reportOptions = this.reportBuilder.generateReportFor(docData, 'excel');
|
|
175
|
+
this.reports.generate(reportOptions);
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
// Generar reporte de Orden de Pedido
|
|
179
|
+
generateOrder(id: number, codEstab: string) {
|
|
180
|
+
const docData = {
|
|
181
|
+
codDoc: 'NORMAL', // Orden
|
|
182
|
+
id,
|
|
183
|
+
codEstab
|
|
184
|
+
};
|
|
185
|
+
|
|
186
|
+
const reportOptions = this.reportBuilder.generateReportFor(docData, 'word');
|
|
187
|
+
this.reports.generate(reportOptions);
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
// Verificar tipos soportados
|
|
191
|
+
checkSupportedTypes() {
|
|
192
|
+
const supportedTypes = this.reportBuilder.getSupportedDocumentTypes();
|
|
193
|
+
console.log('Tipos soportados:', supportedTypes);
|
|
194
|
+
// ['FV', 'NE', 'NORMAL', 'NC', 'ND', 'GR']
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
### Utilidades de Archivos
|
|
200
|
+
|
|
201
|
+
```typescript
|
|
202
|
+
import { FileMapperUtil } from '@acontplus/ng-common';
|
|
203
|
+
|
|
204
|
+
// Extraer nombre de archivo desde respuesta HTTP
|
|
205
|
+
const fileName = FileMapperUtil.extractFileName(httpResponse);
|
|
206
|
+
|
|
207
|
+
// Crear File desde respuesta HTTP
|
|
208
|
+
const file = FileMapperUtil.fromResponse(httpResponse);
|
|
209
|
+
|
|
210
|
+
// Descargar archivo
|
|
211
|
+
FileMapperUtil.downloadFile(blob, 'documento.pdf');
|
|
212
|
+
|
|
213
|
+
// Abrir archivo en nueva ventana (PDFs)
|
|
214
|
+
FileMapperUtil.openFile(blob, 'documento.pdf');
|
|
215
|
+
|
|
216
|
+
// Detectar navegador legacy
|
|
217
|
+
if (FileMapperUtil.isLegacyBrowser()) {
|
|
218
|
+
// Forzar descarga en navegadores antiguos
|
|
219
|
+
}
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
### Impresión
|
|
223
|
+
|
|
224
|
+
```typescript
|
|
225
|
+
import { PrinterFacade } from '@acontplus/ng-common';
|
|
226
|
+
|
|
227
|
+
@Component({...})
|
|
228
|
+
export class PrintingComponent {
|
|
229
|
+
constructor(private printer: PrinterFacade) {}
|
|
230
|
+
|
|
231
|
+
// Imprimir factura
|
|
232
|
+
printInvoice(orderId: number, documentId: number) {
|
|
233
|
+
this.printer.printInvoice(orderId, documentId);
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
// Impresión automática
|
|
237
|
+
autoPrint(data: any, docType: string) {
|
|
238
|
+
this.printer.autoPrint(data, docType);
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
### Componente UI para WhatsApp
|
|
244
|
+
|
|
245
|
+
```typescript
|
|
246
|
+
import { WhatsAppSender } from '@acontplus/ng-common';
|
|
247
|
+
|
|
248
|
+
@Component({
|
|
249
|
+
template: ` <acp-whatsapp-sender [config]="whatsappConfig"> </acp-whatsapp-sender> `,
|
|
250
|
+
imports: [WhatsAppSender],
|
|
251
|
+
})
|
|
252
|
+
export class MyComponent {
|
|
253
|
+
whatsappConfig = {
|
|
254
|
+
documentData: {
|
|
255
|
+
codDoc: 'FV',
|
|
256
|
+
id: 123,
|
|
257
|
+
codEstab: '001',
|
|
258
|
+
},
|
|
259
|
+
phoneNumbers: ['0987654321'],
|
|
260
|
+
defaultMessage: 'Su documento está listo',
|
|
261
|
+
establishmentName: 'Mi Empresa S.A.',
|
|
262
|
+
customerName: 'Juan Pérez',
|
|
263
|
+
};
|
|
264
|
+
}
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
## API de WhatsApp Cloud
|
|
268
|
+
|
|
269
|
+
### Endpoints utilizados (configurados en constants):
|
|
270
|
+
|
|
271
|
+
- `POST /api/common/whatsapp-cloud/text` - Texto directo
|
|
272
|
+
- `POST /api/common/whatsapp-cloud/text-template` - Texto con template
|
|
273
|
+
- `POST /api/common/whatsapp-cloud/document` - Documento por URL
|
|
274
|
+
- `POST /api/common/whatsapp-cloud/document-template` - Documento con template
|
|
275
|
+
- `GET /api/common/whatsapp-cloud/status` - Estado del proveedor
|
|
276
|
+
|
|
277
|
+
### Formato de FormData para documentos:
|
|
278
|
+
|
|
279
|
+
```typescript
|
|
280
|
+
// La librería maneja automáticamente el formato correcto:
|
|
281
|
+
formData.append('To', phoneNumber);
|
|
282
|
+
formData.append('File', file);
|
|
283
|
+
formData.append('TemplateName', templateName);
|
|
284
|
+
formData.append('LanguageCode', languageCode);
|
|
285
|
+
formData.append('Filename', filename);
|
|
286
|
+
// BodyParams como array indexado
|
|
287
|
+
formData.append('BodyParams[0]', param1);
|
|
288
|
+
formData.append('BodyParams[1]', param2);
|
|
289
|
+
```
|
|
290
|
+
|
|
291
|
+
## Configuración de Reportes
|
|
292
|
+
|
|
293
|
+
### Tipos de Documento Soportados:
|
|
294
|
+
|
|
295
|
+
El `ReportParamsBuilder` soporta múltiples tipos de documento configurados:
|
|
296
|
+
|
|
297
|
+
| Código | Descripción | API Version | ID Field | Características |
|
|
298
|
+
| -------- | ---------------- | ----------- | -------- | -------------------------------- |
|
|
299
|
+
| `FV` | Factura | v1 | `id` | Incluye establecimiento y código |
|
|
300
|
+
| `NE` | Nota de Entrega | v1 | `id` | Parámetros extra: `tipo: 1` |
|
|
301
|
+
| `NORMAL` | Orden de Pedido | v2 | `id` | Sin servicio adicional |
|
|
302
|
+
| `NC` | Nota de Crédito | v1 | `id` | Incluye establecimiento |
|
|
303
|
+
| `ND` | Nota de Débito | v1 | `id` | Incluye establecimiento |
|
|
304
|
+
| `GR` | Guía de Remisión | v2 | `id` | Con servicio |
|
|
305
|
+
|
|
306
|
+
### Agregar Nuevos Tipos:
|
|
307
|
+
|
|
308
|
+
Para agregar un nuevo tipo de documento, simplemente agrega la configuración:
|
|
309
|
+
|
|
310
|
+
```typescript
|
|
311
|
+
// En ReportParamsBuilder, agregar a reportConfigs:
|
|
312
|
+
RET: {
|
|
313
|
+
codigo: 'RET',
|
|
314
|
+
hasService: true,
|
|
315
|
+
useV1Api: true,
|
|
316
|
+
idField: 'id',
|
|
317
|
+
includeEstabInData: true,
|
|
318
|
+
}
|
|
319
|
+
```
|
|
320
|
+
|
|
321
|
+
## Arquitectura Limpia
|
|
322
|
+
|
|
323
|
+
### Separación de responsabilidades:
|
|
324
|
+
|
|
325
|
+
- **WhatsApp**: Solo mensajería
|
|
326
|
+
- **ReportGeneration**: Solo generación de reportes
|
|
327
|
+
- **Printer**: Solo impresión
|
|
328
|
+
- **Utils**: Utilidades estáticas sin dependencias
|
|
329
|
+
|
|
330
|
+
### Estructura optimizada:
|
|
331
|
+
|
|
332
|
+
```
|
|
333
|
+
ng-common/
|
|
334
|
+
├── constants/ # URLs y configuraciones
|
|
335
|
+
├── contracts/ # Puertos/Interfaces separados
|
|
336
|
+
├── models/ # DTOs alineados con tu API
|
|
337
|
+
├── adapters/ # Implementaciones limpias
|
|
338
|
+
├── facades/ # Servicios de alto nivel
|
|
339
|
+
├── tokens/ # Tokens de inyección
|
|
340
|
+
├── builders/ # Constructores y builders configurados
|
|
341
|
+
├── utils/ # Utilidades estáticas (sin Injectable)
|
|
342
|
+
└── ui/ # Componentes UI
|
|
343
|
+
```
|
|
344
|
+
|
|
345
|
+
## Características
|
|
346
|
+
|
|
347
|
+
- ✅ **Utilidades estáticas optimizadas** - Mejor performance, sin inyección de dependencias
|
|
348
|
+
- ✅ **Builder configurado para reportes** - Escalable sin switch statements
|
|
349
|
+
- ✅ **Formateo automático de teléfonos ecuatorianos** - 09xxxxxxxx → +593 automáticamente
|
|
350
|
+
- ✅ **Sin dependencias externas problemáticas** - No FileSaver, no SweetAlert2
|
|
351
|
+
- ✅ **Constants en lugar de ConfigService** - Más simple y directo
|
|
352
|
+
- ✅ **Separación clara** - Report ≠ Printer ≠ WhatsApp ≠ Utils
|
|
353
|
+
- ✅ **API completamente alineada** - Con tu implementación real
|
|
354
|
+
- ✅ **Código limpio** - Sin duplicación, principios DRY aplicados
|
|
355
|
+
- ✅ **TypeScript completo** - Tipado fuerte con validaciones
|
|
356
|
+
- ✅ **Fácil de mantener** - Estructura clara y coherente
|
|
357
|
+
- ✅ **Tree-shaking optimizado** - Mejor bundle size con utilidades estáticas
|