@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 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