@acontplus/ng-customer 1.1.1 → 2.0.1

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.
@@ -1,504 +1,600 @@
1
- import { IdentificationNumberVo, SEPARADORES_REGEX, HttpClientFactory, isSuccessResponse, SRI_DOCUMENT_TYPE, SEPARATOR_KEY_CODE } from '@acontplus/core';
2
- import { DateFormatter, getValidId, isValidField, parseJSONSafe } from '@acontplus/utils';
3
1
  import * as i0 from '@angular/core';
4
- import { inject, signal, ChangeDetectionStrategy, Component, input, output, computed } from '@angular/core';
5
- import { from, forkJoin } from 'rxjs';
6
- import { NotificationService } from '@acontplus/ng-notifications';
7
- import { MatDialogRef, MAT_DIALOG_DATA, MatDialogContent, MatDialogActions } from '@angular/material/dialog';
8
- import { InputChip, ToUpperCase, Button, DynamicCard } from '@acontplus/ng-components';
9
- import { MatButtonModule } from '@angular/material/button';
2
+ import { InjectionToken, inject, Injectable, input, output, signal, Input, ChangeDetectionStrategy, ViewEncapsulation, Component } from '@angular/core';
10
3
  import * as i1 from '@angular/forms';
11
- import { FormGroup, FormControl, Validators, ReactiveFormsModule } from '@angular/forms';
12
- import * as i2 from '@angular/material/tabs';
13
- import { MatTabsModule } from '@angular/material/tabs';
14
- import * as i3 from '@angular/material/form-field';
4
+ import { FormBuilder, Validators, ReactiveFormsModule } from '@angular/forms';
5
+ import { HttpClient } from '@angular/common/http';
6
+ import { map } from 'rxjs';
7
+ import * as i2 from '@angular/material/form-field';
15
8
  import { MatFormFieldModule } from '@angular/material/form-field';
16
- import * as i4 from '@angular/material/input';
9
+ import * as i3 from '@angular/material/input';
17
10
  import { MatInputModule } from '@angular/material/input';
11
+ import * as i4 from '@angular/material/expansion';
12
+ import { MatExpansionModule } from '@angular/material/expansion';
13
+ import { MatIcon } from '@angular/material/icon';
14
+ import { Button, ToUpperCase, InputChip } from '@acontplus/ng-components';
18
15
  import * as i5 from '@angular/material/select';
19
16
  import { MatSelectModule } from '@angular/material/select';
20
- import * as i6 from '@angular/material/slide-toggle';
21
- import { MatSlideToggleModule } from '@angular/material/slide-toggle';
22
- import { MatCheckbox } from '@angular/material/checkbox';
23
- import { MatIcon } from '@angular/material/icon';
24
- import { MatTooltip } from '@angular/material/tooltip';
25
- import * as i7 from '@angular/material/datepicker';
26
- import { MatDatepickerModule } from '@angular/material/datepicker';
27
- import { provideNativeDateAdapter } from '@angular/material/core';
28
- import * as i1$1 from '@angular/material/card';
29
- import { MatCardModule } from '@angular/material/card';
30
- import { MatDividerModule } from '@angular/material/divider';
31
- import * as i2$1 from '@angular/material/chips';
32
- import { MatChipsModule } from '@angular/material/chips';
33
-
34
- class CustomerUseCase {
35
- repo;
36
- constructor(repo) {
37
- this.repo = repo;
38
- }
39
- getAll(params) {
40
- return this.repo.getAll(params);
41
- }
42
- getFormData() {
43
- return this.repo.getFormData();
44
- }
45
- getById(id) {
46
- return this.repo.getById(id);
47
- }
48
- checkExistence(identificationNumber) {
49
- return this.repo.checkExistence(identificationNumber);
50
- }
51
- create(params) {
52
- return this.repo.create(params);
53
- }
54
- update(params) {
55
- return this.repo.update(params);
56
- }
57
- updateState(id) {
58
- return this.repo.updateState(id);
59
- }
60
- search(filter) {
61
- return this.repo.search(filter);
62
- }
63
- }
64
-
65
- class CustomerExternalUseCase {
66
- repo;
67
- constructor(repo) {
68
- this.repo = repo;
69
- }
70
- getById(identification) {
71
- const idNumber = new IdentificationNumberVo(identification);
72
- return this.repo.getById(idNumber);
73
- }
74
- }
17
+ import * as i6 from '@angular/material/button';
18
+ import { MatButtonModule } from '@angular/material/button';
75
19
 
76
- const CUSTOMER_API = {
77
- BILLING: 'customers',
20
+ const MAIN_APP_COMPANY_CUSTOMER_CONFIG = {
21
+ fields: {
22
+ // IDs y referencias
23
+ idTipoIdentificacion: {
24
+ name: 'idTipoIdentificacion',
25
+ required: true,
26
+ visible: true,
27
+ label: 'Tipo de Identificación',
28
+ placeholder: 'Seleccione tipo',
29
+ },
30
+ idFormaPagoSri: {
31
+ name: 'idFormaPagoSri',
32
+ required: false,
33
+ visible: true,
34
+ label: 'Forma de Pago SRI',
35
+ placeholder: 'Seleccione forma de pago',
36
+ },
37
+ idTipoClienteProveedor: {
38
+ name: 'idTipoClienteProveedor',
39
+ required: false,
40
+ visible: true,
41
+ label: 'Tipo de Cliente/Proveedor',
42
+ placeholder: 'Seleccione tipo',
43
+ },
44
+ idSubContribuyente: {
45
+ name: 'idSubContribuyente',
46
+ required: false,
47
+ visible: true,
48
+ label: 'Sub-Contribuyente',
49
+ placeholder: 'Seleccione',
50
+ },
51
+ idTiempoCredito: {
52
+ name: 'idTiempoCredito',
53
+ required: false,
54
+ visible: true,
55
+ label: 'Tiempo de Crédito',
56
+ placeholder: 'Días de crédito',
57
+ },
58
+ idCiudad: {
59
+ name: 'idCiudad',
60
+ required: false,
61
+ visible: true,
62
+ label: 'Ciudad',
63
+ placeholder: 'Seleccione ciudad',
64
+ },
65
+ idCargo: {
66
+ name: 'idCargo',
67
+ required: false,
68
+ visible: true,
69
+ label: 'Cargo',
70
+ placeholder: 'Seleccione cargo',
71
+ },
72
+ idEmpleado: {
73
+ name: 'idEmpleado',
74
+ required: false,
75
+ visible: true,
76
+ label: 'Empleado Responsable',
77
+ placeholder: 'Seleccione empleado',
78
+ },
79
+ // Datos principales
80
+ numeroIdentificacion: {
81
+ name: 'numeroIdentificacion',
82
+ required: true,
83
+ visible: true,
84
+ label: 'RUC / Cédula',
85
+ placeholder: 'Ingrese número de identificación (13 dígitos para RUC)',
86
+ },
87
+ nombreFiscal: {
88
+ name: 'nombreFiscal',
89
+ required: true,
90
+ visible: true,
91
+ label: 'Razón Social / Nombre Fiscal',
92
+ placeholder: 'Ingrese razón social completa',
93
+ },
94
+ nombreComercial: {
95
+ name: 'nombreComercial',
96
+ required: false,
97
+ visible: true,
98
+ label: 'Nombre Comercial',
99
+ placeholder: 'Ingrese nombre comercial',
100
+ },
101
+ direccion: {
102
+ name: 'direccion',
103
+ required: true,
104
+ visible: true,
105
+ label: 'Dirección',
106
+ placeholder: 'Calle principal y secundaria',
107
+ },
108
+ correo: {
109
+ name: 'correo',
110
+ required: false,
111
+ visible: true,
112
+ label: 'Correo Electrónico',
113
+ placeholder: 'ejemplo@correo.com',
114
+ },
115
+ telefono: {
116
+ name: 'telefono',
117
+ required: false,
118
+ visible: true,
119
+ label: 'Teléfono',
120
+ placeholder: '0999999999',
121
+ },
122
+ placa: {
123
+ name: 'placa',
124
+ required: false,
125
+ visible: true,
126
+ label: 'Placa del Vehículo',
127
+ placeholder: 'ABC-1234',
128
+ },
129
+ nota: {
130
+ name: 'nota',
131
+ required: false,
132
+ visible: true,
133
+ label: 'Notas',
134
+ placeholder: 'Observaciones adicionales',
135
+ },
136
+ birthDate: {
137
+ name: 'birthDate',
138
+ required: false,
139
+ visible: true,
140
+ label: 'Fecha de Nacimiento',
141
+ placeholder: 'DD/MM/AAAA',
142
+ },
143
+ // Estados
144
+ estado: {
145
+ name: 'estado',
146
+ required: false,
147
+ visible: true,
148
+ label: 'Activo',
149
+ },
150
+ validationSri: {
151
+ name: 'validationSri',
152
+ required: false,
153
+ visible: true,
154
+ label: 'Validado en SRI',
155
+ },
156
+ configValorBruto: {
157
+ name: 'configValorBruto',
158
+ required: false,
159
+ visible: true,
160
+ label: 'Configurar Valor Bruto',
161
+ },
162
+ },
163
+ // Información de crédito
164
+ showCreditInfo: true,
165
+ creditFields: {
166
+ maritalStatusId: {
167
+ name: 'maritalStatusId',
168
+ required: false,
169
+ visible: true,
170
+ label: 'Estado Civil',
171
+ placeholder: 'Seleccione',
172
+ },
173
+ conyugeNombre: {
174
+ name: 'conyugeNombre',
175
+ required: false,
176
+ visible: true,
177
+ label: 'Nombre del Cónyuge',
178
+ placeholder: 'Ingrese nombre',
179
+ },
180
+ conyugeTel: {
181
+ name: 'conyugeTel',
182
+ required: false,
183
+ visible: true,
184
+ label: 'Teléfono del Cónyuge',
185
+ placeholder: '0999999999',
186
+ },
187
+ refFamNombre: {
188
+ name: 'refFamNombre',
189
+ required: false,
190
+ visible: true,
191
+ label: 'Referencia Familiar',
192
+ placeholder: 'Nombre',
193
+ },
194
+ refFamTel: {
195
+ name: 'refFamTel',
196
+ required: false,
197
+ visible: true,
198
+ label: 'Teléfono Referencia',
199
+ placeholder: '0999999999',
200
+ },
201
+ housingTypeId: {
202
+ name: 'housingTypeId',
203
+ required: false,
204
+ visible: true,
205
+ label: 'Tipo de Vivienda',
206
+ placeholder: 'Seleccione',
207
+ },
208
+ dirVivienda: {
209
+ name: 'dirVivienda',
210
+ required: false,
211
+ visible: true,
212
+ label: 'Dirección de Vivienda',
213
+ placeholder: 'Dirección completa',
214
+ },
215
+ refDomicilio: {
216
+ name: 'refDomicilio',
217
+ required: false,
218
+ visible: true,
219
+ label: 'Referencia de Domicilio',
220
+ placeholder: 'Referencia',
221
+ },
222
+ sector: {
223
+ name: 'sector',
224
+ required: false,
225
+ visible: true,
226
+ label: 'Sector',
227
+ placeholder: 'Ingrese sector',
228
+ },
229
+ barrio: {
230
+ name: 'barrio',
231
+ required: false,
232
+ visible: true,
233
+ label: 'Barrio',
234
+ placeholder: 'Ingrese barrio',
235
+ },
236
+ calle: {
237
+ name: 'calle',
238
+ required: false,
239
+ visible: true,
240
+ label: 'Calle',
241
+ placeholder: 'Calle principal',
242
+ },
243
+ },
244
+ submitButtonText: 'Guardar Cliente',
245
+ cancelButtonText: 'Cancelar',
246
+ };
247
+ // Configuración MÍNIMA para POS
248
+ const POS_COMPANY_CUSTOMER_CONFIG = {
249
+ fields: {
250
+ // Solo lo esencial
251
+ idTipoIdentificacion: {
252
+ name: 'idTipoIdentificacion',
253
+ required: true,
254
+ visible: true,
255
+ label: 'Tipo ID',
256
+ placeholder: 'Tipo',
257
+ },
258
+ numeroIdentificacion: {
259
+ name: 'numeroIdentificacion',
260
+ required: true,
261
+ visible: true,
262
+ label: 'Cédula/RUC',
263
+ placeholder: 'Número de identificación',
264
+ },
265
+ nombreFiscal: {
266
+ name: 'nombreFiscal',
267
+ required: true,
268
+ visible: true,
269
+ label: 'Nombre',
270
+ placeholder: 'Nombre del cliente',
271
+ },
272
+ nombreComercial: {
273
+ name: 'nombreComercial',
274
+ required: false,
275
+ visible: false,
276
+ },
277
+ direccion: {
278
+ name: 'direccion',
279
+ required: false,
280
+ visible: true,
281
+ label: 'Dirección',
282
+ placeholder: 'Dirección',
283
+ },
284
+ correo: {
285
+ name: 'correo',
286
+ required: false,
287
+ visible: false,
288
+ },
289
+ telefono: {
290
+ name: 'telefono',
291
+ required: false,
292
+ visible: true,
293
+ label: 'Teléfono',
294
+ placeholder: 'Teléfono',
295
+ },
296
+ // Resto oculto
297
+ idFormaPagoSri: { name: 'idFormaPagoSri', required: false, visible: false },
298
+ idTipoClienteProveedor: { name: 'idTipoClienteProveedor', required: false, visible: false },
299
+ idSubContribuyente: { name: 'idSubContribuyente', required: false, visible: false },
300
+ idTiempoCredito: { name: 'idTiempoCredito', required: false, visible: false },
301
+ idCiudad: { name: 'idCiudad', required: false, visible: false },
302
+ idCargo: { name: 'idCargo', required: false, visible: false },
303
+ idEmpleado: { name: 'idEmpleado', required: false, visible: false },
304
+ placa: { name: 'placa', required: false, visible: false },
305
+ nota: { name: 'nota', required: false, visible: false },
306
+ birthDate: { name: 'birthDate', required: false, visible: false },
307
+ estado: { name: 'estado', required: false, visible: false },
308
+ validationSri: { name: 'validationSri', required: false, visible: false },
309
+ configValorBruto: { name: 'configValorBruto', required: false, visible: false },
310
+ },
311
+ showCreditInfo: false, // Sin info de crédito en POS
312
+ submitButtonText: 'Agregar',
313
+ cancelButtonText: 'Cancelar',
78
314
  };
79
315
 
80
- class CompanySearchMapper {
81
- static toJson(params) {
82
- return JSON.stringify({
83
- textSearch: params.search,
84
- });
85
- }
86
- static fromJson(response) {
87
- let customers = [];
88
- if (response && response.code === '1') {
89
- const results = JSON.parse(response.payload) || [];
90
- customers = results.map((item) => ({
91
- id: item.idCliente,
92
- identificationTypeId: item.idTipoIdentificacion,
93
- creditTimeId: item.idTiempoCredito,
94
- customerId: item.customerId,
95
- status: item.estado,
96
- email: item.correo,
97
- phone: item.telefono,
98
- address: item.direccion,
99
- licensePlate: item.placa,
100
- creditDays: item.diasCredito,
101
- sriValidation: item.validationSri,
102
- businessName: item.nombreFiscal,
103
- tradeName: item.nombreComercial,
104
- identificationNumber: item.numeroIdentificacion,
105
- identificationType: item.tipoIdentificacion,
106
- sriCode: item.codigoSri,
107
- companyRuc: item.rucEmpresa,
108
- companyId: item.companyId,
109
- name: item.nombreFiscal,
110
- }));
111
- }
112
- return customers;
113
- }
114
- }
316
+ const CUSTOMER_SRI_SERVICE = new InjectionToken('CUSTOMER_SRI_SERVICE');
317
+ const COMPANY_CUSTOMER_MAPPER = new InjectionToken('COMPANY_CUSTOMER_MAPPER');
318
+ const COMPANY_CUSTOMER_FORM_CONFIG = new InjectionToken('COMPANY_CUSTOMER_FORM_CONFIG');
319
+ const COMPANY_CUSTOMER_SERVICE = new InjectionToken('COMPANY_CUSTOMER_SERVICE');
115
320
 
116
- class CustomerCreateUpdateMapper {
117
- static toJson(param) {
321
+ class CompanyCustomerDefaultMapper {
322
+ toModel(dto) {
118
323
  return {
119
- idCliente: getValidId(param.idCliente),
120
- idEmpleado: getValidId(param.idEmpleado),
121
- idTipoIdentificacion: param.idTipoIdentificacion,
122
- idTipoClienteProveedor: getValidId(param.idTipoClienteProveedor),
123
- idTipoEntidad: getValidId(param.idTipoEntidad),
124
- idCiudad: getValidId(param.idCiudad),
125
- idSubContribuyente: getValidId(param.idSubContribuyente),
126
- idTiempoCredito: getValidId(param.idTiempoCredito),
127
- idEmpresa: getValidId(param.idEmpresa),
128
- idCargo: getValidId(param.idCargo),
129
- numeroIdentificacion: param.numeroIdentificacion,
130
- nombreFiscal: param.nombreFiscal,
131
- nombreComercial: param.nombreComercial,
132
- direccion: isValidField(param.direccion),
133
- telefono: isValidField(param.telefono),
134
- correo: isValidField(param.correo),
135
- placa: isValidField(param.placa),
136
- montoCredito: isValidField(param.montoCredito),
137
- nota: isValidField(param.nota),
138
- validationSri: param.validationSri,
139
- idFormaPagoSri: getValidId(param.idFormaPagoSri),
140
- estado: param.estado ?? true,
141
- infoCrediticia: param.dataInfoCred && JSON.stringify(param.dataInfoCred),
142
- configValorBruto: param.configValorBruto ?? null,
143
- birthDate: DateFormatter.isValid(param.birthDate)
144
- ? DateFormatter.toUTCString(param.birthDate)
145
- : null,
146
- };
147
- }
148
- static fromJson(response) {
149
- if (!response)
150
- return response;
151
- const result = {
152
- id: 0,
153
- };
154
- if (response.code === '1' && typeof response.payload === 'string') {
155
- try {
156
- const parsed = JSON.parse(response.payload);
157
- if (Array.isArray(parsed) && parsed.length > 0) {
158
- const { idCliente } = parsed[0];
159
- result.id = idCliente;
324
+ name: `Esto de mapper default - ${dto.name}`,
325
+ id: dto.id,
326
+ idCliente: dto.id_cliente,
327
+ idEmpresa: dto.id_empresa,
328
+ idCargo: dto.id_cargo,
329
+ idFormaPagoSri: dto.id_forma_pago_sri,
330
+ idTipoClienteProveedor: dto.id_tipo_cliente_proveedor,
331
+ idTipoIdentificacion: dto.id_tipo_identificacion,
332
+ idSubContribuyente: dto.id_sub_contribuyente,
333
+ idTiempoCredito: dto.id_tiempo_credito,
334
+ idCiudad: dto.id_ciudad,
335
+ idEmpleado: dto.id_empleado,
336
+ numeroIdentificacion: dto.numero_identificacion,
337
+ nombreFiscal: dto.nombre_fiscal,
338
+ nombreComercial: dto.nombre_comercial,
339
+ direccion: dto.direccion,
340
+ correo: dto.correo,
341
+ telefono: dto.telefono,
342
+ placa: dto.placa,
343
+ nota: dto.nota,
344
+ birthDate: dto.birth_date ? new Date(dto.birth_date) : null,
345
+ estado: dto.estado,
346
+ validationSri: dto.validation_sri,
347
+ configValorBruto: dto.config_valor_bruto,
348
+ dataInfoCred: dto.data_info_cred
349
+ ? {
350
+ maritalStatusId: dto.data_info_cred.marital_status_id,
351
+ conyugeNombre: dto.data_info_cred.conyuge_nombre,
352
+ conyugeTel: dto.data_info_cred.conyuge_tel,
353
+ refFamNombre: dto.data_info_cred.ref_fam_nombre,
354
+ refFamTel: dto.data_info_cred.ref_fam_tel,
355
+ housingTypeId: dto.data_info_cred.housing_type_id,
356
+ dirVivienda: dto.data_info_cred.dir_vivienda,
357
+ refDomicilio: dto.data_info_cred.ref_domicilio,
358
+ sector: dto.data_info_cred.sector,
359
+ barrio: dto.data_info_cred.barrio,
360
+ calle: dto.data_info_cred.calle,
160
361
  }
161
- }
162
- catch (error) {
163
- console.error('Error parsing payload JSON:', error);
164
- }
165
- }
166
- return result;
362
+ : undefined,
363
+ };
167
364
  }
168
- }
169
-
170
- class CustomerFormDataMapper {
171
- static toJson() {
172
- return JSON.stringify({
173
- tipo: 2,
365
+ toModelList(response) {
366
+ const parsed = JSON.parse(response.payload);
367
+ const tempList = Array.isArray(parsed) ? parsed[0] : parsed.Table;
368
+ console.log(tempList);
369
+ const mapClient = (data) => ({
370
+ clientId: data.idCliente,
371
+ identificationTypeId: data.idTipoIdentificacion,
372
+ identificationNumber: data.numeroIdentificacion,
373
+ tradeName: data.nombreComercial,
374
+ legalName: data.nombreFiscal,
375
+ address: data.direccion,
376
+ phone: data.telefono,
377
+ email: data.correo,
378
+ finalConsumer: data.consumidorFinal,
379
+ sriValidation: data.validationSri,
380
+ identificationType: data.tipoIdentificacion,
381
+ identificationTypeCode: data.codTipoIdentificacion,
382
+ status: data.estado,
383
+ totalResults: data.totalResults,
174
384
  });
385
+ const list = tempList.map((item) => mapClient(item));
386
+ const totalRecords = response.totalRecords ?? (list[0]?.totalRecords || 0);
387
+ return {
388
+ data: list,
389
+ pagination: {
390
+ totalRecords,
391
+ },
392
+ };
175
393
  }
176
- static fromJson(response) {
177
- const result = {};
178
- if (response.code === '1') {
179
- const mainData = JSON.parse(response.payload);
180
- result.tipoIdentificacion = mainData[0];
181
- result.tipoContribuyentes = mainData[1];
182
- result.tiempoCreditos = mainData[2] || [];
183
- const ciudades = mainData[3];
184
- result.ciudades = ciudades.reduce((acc, ciudade) => {
185
- const dataExists = acc.find((c) => c.idProvincia === ciudade.idProvincia);
186
- if (!dataExists) {
187
- acc.push({
188
- idProvincia: ciudade.idProvincia,
189
- nombre: ciudade.provincia,
190
- ciudades: [
191
- {
192
- idCiudad: ciudade.idCiudad,
193
- nombre: ciudade.ciudad,
194
- },
195
- ],
196
- });
197
- }
198
- else {
199
- dataExists.ciudades.push({
200
- idCiudad: ciudade.idCiudad,
201
- nombre: ciudade.ciudad,
202
- });
394
+ toCreateDTO(customer) {
395
+ return {
396
+ id_tipo_identificacion: customer.idTipoIdentificacion,
397
+ numero_identificacion: customer.numeroIdentificacion,
398
+ nombre_fiscal: customer.nombreFiscal,
399
+ nombre_comercial: customer.nombreComercial,
400
+ direccion: customer.direccion,
401
+ correo: customer.correo,
402
+ telefono: customer.telefono,
403
+ placa: customer.placa,
404
+ nota: customer.nota,
405
+ birth_date: customer.birthDate?.toISOString(),
406
+ estado: customer.estado,
407
+ validation_sri: customer.validationSri,
408
+ config_valor_bruto: customer.configValorBruto,
409
+ id_forma_pago_sri: customer.idFormaPagoSri,
410
+ id_tipo_cliente_proveedor: customer.idTipoClienteProveedor,
411
+ id_sub_contribuyente: customer.idSubContribuyente,
412
+ id_tiempo_credito: customer.idTiempoCredito,
413
+ id_ciudad: customer.idCiudad,
414
+ id_cargo: customer.idCargo,
415
+ id_empleado: customer.idEmpleado,
416
+ data_info_cred: customer.dataInfoCred
417
+ ? {
418
+ marital_status_id: customer.dataInfoCred.maritalStatusId,
419
+ conyuge_nombre: customer.dataInfoCred.conyugeNombre,
420
+ conyuge_tel: customer.dataInfoCred.conyugeTel,
421
+ ref_fam_nombre: customer.dataInfoCred.refFamNombre,
422
+ ref_fam_tel: customer.dataInfoCred.refFamTel,
423
+ housing_type_id: customer.dataInfoCred.housingTypeId,
424
+ dir_vivienda: customer.dataInfoCred.dirVivienda,
425
+ ref_domicilio: customer.dataInfoCred.refDomicilio,
426
+ sector: customer.dataInfoCred.sector,
427
+ barrio: customer.dataInfoCred.barrio,
428
+ calle: customer.dataInfoCred.calle,
203
429
  }
204
- return acc;
205
- }, []);
206
- result.tiposCliente = mainData[4] || [];
207
- result.empresas = mainData[5] || [];
208
- result.cargos = mainData[6] || [];
209
- result.formasPagoSri = mainData[7] || [];
210
- result.housingTypes = mainData[8] || [];
211
- result.maritalStatuses = mainData[9] || [];
212
- result.employees = mainData[10] || [];
213
- }
214
- return result;
430
+ : null,
431
+ };
215
432
  }
216
- }
217
-
218
- class CustomerGetByIdMapper {
219
- static fromJson(response) {
220
- if (response.code !== '1' || !response.payload) {
221
- return {};
222
- }
223
- const data = JSON.parse(response.payload)[0];
433
+ toUpdateDTO(customer) {
224
434
  return {
225
- idCliente: data.idCliente,
226
- idTipoClienteProveedor: data.idTipoClienteProveedor,
227
- idTipoEntidad: data.idTipoEntidad,
228
- idSubContribuyente: data.idSubContribuyente,
229
- idTiempoCredito: data.idTiempoCredito,
230
- idTipoIdentificacion: data.idTipoIdentificacion,
231
- idCiudad: data.idCiudad,
232
- numeroIdentificacion: data.numeroIdentificacion,
233
- identificacionComprador: data.numeroIdentificacion,
234
- razonSocialComprador: data.nombreFiscal,
235
- nombreFiscal: data.nombreFiscal,
236
- montoCredito: data.montoCredito,
237
- nombreComercial: data.nombreComercial,
238
- direccion: data.direccion,
239
- telefono: data.telefono,
240
- correo: data.correo,
241
- estado: data.estado,
242
- idEmpleado: data.idEmpleado,
243
- diasCredito: data.diasCredito,
244
- empleado: data.empleado,
245
- idEmpresa: data.idEmpresa,
246
- idCargo: data.idCargo,
247
- placa: data.placa,
248
- validationSri: data.validationSri,
249
- codigoSri: data.codigoSri,
250
- correos: data.correo ? data.correo.split(SEPARADORES_REGEX) : [],
251
- telefonos: data.telefono ? data.telefono.split(SEPARADORES_REGEX) : [],
252
- placas: data.placa ? data.placa.split(SEPARADORES_REGEX) : [],
253
- idFormaPagoSri: data.idFormaPagoSri,
254
- dataInfoCred: parseJSONSafe(data.infoCrediticia, {}),
255
- nota: data.nota?.trim() ?? '',
256
- configValorBruto: data.configValorBruto ?? false,
435
+ id: customer.id,
436
+ ...this.toCreateDTO(customer),
257
437
  };
258
438
  }
259
439
  }
260
440
 
261
- class ListCustomerMapper {
262
- static toJson(params) {
263
- return JSON.stringify({
264
- ...params,
265
- type: 1,
266
- tipo: 1, // remove after
267
- pageIndex: params.pageIndex,
268
- pageSize: params.pageSize,
441
+ class CompanyCustomerService {
442
+ apiUrl = '/FactElect/CompanyCustomer/';
443
+ http = inject(HttpClient);
444
+ mapper = inject(COMPANY_CUSTOMER_MAPPER, { optional: true }) ?? new CompanyCustomerDefaultMapper();
445
+ list(params) {
446
+ console.log(params);
447
+ const json = JSON.stringify({
448
+ pageIndex: params.pageIndex || 1,
449
+ pageSize: params.pageSize || 10,
450
+ tipo: 1,
269
451
  });
452
+ return this.http
453
+ .get(`${this.apiUrl}?json=${json}`)
454
+ .pipe(map(dtos => this.mapper.toModelList(dtos)));
270
455
  }
271
- static fromJson(response) {
272
- // Initialize with backend-aligned shape (PageIndex is commonly 1-based server-side)
273
- const result = {
274
- items: [],
275
- pageIndex: 1,
276
- pageSize: 0,
277
- totalCount: 0,
278
- totalPages: 0,
279
- hasPreviousPage: false,
280
- hasNextPage: false,
281
- metadata: {},
282
- };
283
- // Parse payload (backend sends JSON string in payload)
284
- const parsed = typeof response?.payload === 'string' ? JSON.parse(response.payload) : response?.payload;
285
- const dataArray = Array.isArray(parsed)
286
- ? (parsed[0] ?? [])
287
- : Array.isArray(parsed?.items)
288
- ? parsed.items
289
- : [];
290
- // Map each item to UI-friendly fields, preserving source values
291
- result.items = dataArray.map((item, index) => ({
292
- index: index + 1,
293
- id: item.idCliente,
294
- identificationTypeId: item.idTipoIdentificacion,
295
- identification: item.numeroIdentificacion,
296
- businessName: item.nombreFiscal,
297
- tradeName: item.nombreComercial,
298
- address: item.direccion,
299
- phone: item.telefono,
300
- email: item.correo,
301
- finalConsumer: item.consumidorFinal,
302
- sriValidation: item.validacionSri ?? item.validationSri,
303
- sriValidationName: (item.validationSri ?? item.validacionSri) ? 'SI' : 'NO',
304
- identificationType: item.tipoIdentificacion,
305
- status: item.estado,
306
- statusName: item.estado ? 'Activo' : 'Inactivo',
307
- isFinalConsumer: item.codTipoIdentificacion === 'CF',
308
- totalRecords: item.totalRecords ?? item.TotalCount,
309
- }));
310
- // Flexible pagination extraction (prefer explicit backend values)
311
- const pageIndex = response?.PageIndex ?? response?.pageIndex ?? 1;
312
- const pageSize = response?.PageSize ?? response?.pageSize ?? result.items.length;
313
- const totalCountFromItem = result.items.length > 0 ? result.items[0].totalRecords : undefined;
314
- const totalCount = response?.TotalCount ?? response?.totalCount ?? totalCountFromItem ?? result.items.length;
315
- const metadata = response?.Metadata ?? response?.metadata ?? {};
316
- result.pageIndex = Number.isFinite(pageIndex) ? pageIndex : 1;
317
- result.pageSize = Number.isFinite(pageSize) ? pageSize : result.items.length;
318
- result.totalCount = Number.isFinite(totalCount) ? totalCount : result.items.length;
319
- result.totalPages = result.pageSize > 0 ? Math.ceil(result.totalCount / result.pageSize) : 0;
320
- // Backend semantics show HasPreviousPage as PageIndex > 1
321
- result.hasPreviousPage = result.pageIndex > 1;
322
- result.hasNextPage = result.pageIndex < result.totalPages;
323
- result.metadata = metadata;
324
- return result;
456
+ create(customer) {
457
+ return this.http.post(this.apiUrl, customer);
325
458
  }
326
- }
327
-
328
- class CustomerExternalHttpRepository {
329
- get http() {
330
- return HttpClientFactory.getClient(); // siempre toma el último cliente configurado
331
- }
332
- get url() {
333
- return `${CUSTOMER_API.BILLING}/Consultas/`;
334
- }
335
- getById(identification) {
336
- const id = identification.getId();
337
- let endpoint = '';
338
- if (identification.isValidRuc()) {
339
- endpoint = `GetRucSRI?Ruc=${id}`;
340
- }
341
- else if (identification.isValidCedula()) {
342
- endpoint = `GetCedulaSri?Ruc=${id}`;
459
+ update(id, customer) {
460
+ return this.http.put(`${this.apiUrl}/${id}`, customer);
461
+ }
462
+ getById(id) {
463
+ return this.http.get(`${this.apiUrl}/${id}`);
464
+ }
465
+ search(term) {
466
+ return this.http.get(`${this.apiUrl}/search?q=${term}`);
467
+ }
468
+ // Validación completa para app principal
469
+ validate(customer) {
470
+ const errors = {};
471
+ if (!customer.email || !this.isValidEmail(customer.email)) {
472
+ errors['email'] = 'Email inválido';
343
473
  }
344
- else {
345
- throw new Error('Número de identificación inválido para SRI');
474
+ if (customer.phone && !this.isValidPhone(customer.phone)) {
475
+ errors['phone'] = 'Teléfono inválido';
346
476
  }
347
- return this.http.get(`${this.url}${endpoint}`).then(response => {
348
- const idCard = response.numeroRuc ? response.numeroRuc : response.identificacion;
349
- const businessName = response.razonSocial ? response.razonSocial : response.nombreCompleto;
350
- const data = {
351
- phone: response.telefono,
352
- email: response.email,
353
- idCard,
354
- businessName,
355
- address: response.direccion,
356
- };
357
- return {
358
- status: response.error ? 'warning' : 'success',
359
- code: response.error ? 'EXTERNAL_API_ERROR' : 'SUCCESS',
360
- data,
361
- message: response.error ?? 'External API call completed',
362
- timestamp: new Date().toISOString(),
363
- };
364
- });
477
+ return Object.keys(errors).length > 0 ? errors : null;
365
478
  }
366
- }
367
-
368
- class CustomerHttpRepository {
369
- get http() {
370
- return HttpClientFactory.getClient(); // siempre toma el último cliente configurado
479
+ isValidEmail(email) {
480
+ return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email);
371
481
  }
372
- get url() {
373
- return `${CUSTOMER_API.BILLING}/CompanyCustomer/`;
482
+ isValidPhone(phone) {
483
+ return /^\d{10}$/.test(phone.replace(/\D/g, ''));
374
484
  }
375
- checkExistence(identificationNumber) {
376
- const searchPayload = JSON.stringify({
377
- textSearch: identificationNumber,
378
- tipo: 3,
379
- });
380
- return this.http.get(`${this.url}?json=${searchPayload}`).then(response => {
381
- const result = {
382
- status: 'warning',
383
- code: response.code ?? 'UNKNOWN_ERROR',
384
- data: null,
385
- message: response.message ?? 'Unknown error occurred',
386
- timestamp: new Date().toISOString(),
387
- };
388
- if (response.code === '1' && response.payload) {
389
- const parsedData = JSON.parse(response.payload);
390
- if (Array.isArray(parsedData) && parsedData.length > 0 && Array.isArray(parsedData[0])) {
391
- const [customer] = parsedData[0];
392
- if (customer) {
393
- result.status = 'success';
394
- result.data = customer;
395
- }
485
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: CompanyCustomerService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
486
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: CompanyCustomerService, providedIn: 'root' });
487
+ }
488
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: CompanyCustomerService, decorators: [{
489
+ type: Injectable,
490
+ args: [{
491
+ providedIn: 'root',
492
+ }]
493
+ }] });
494
+
495
+ class CustomerValidators {
496
+ // Validador para que termine en 001
497
+ static endsWith001() {
498
+ return (control) => {
499
+ const value = control.value;
500
+ if (value && value.length >= 3) {
501
+ if (!value.endsWith('001')) {
502
+ return { endsWith001: true };
396
503
  }
397
504
  }
398
- return result;
399
- });
400
- }
401
- getFormData() {
402
- const json = CustomerFormDataMapper.toJson();
403
- return this.http.get(`${this.url}?json=${json}`).then((response) => {
404
- const data = CustomerFormDataMapper.fromJson(response);
405
- return {
406
- status: 'success',
407
- code: response.code ?? 'SUCCESS',
408
- data,
409
- timestamp: new Date().toISOString(),
410
- };
411
- });
412
- }
413
- getAll(obj) {
414
- const json = ListCustomerMapper.toJson(obj);
415
- return this.http.get(`${this.url}?json=${json}`).then((response) => {
416
- const data = ListCustomerMapper.fromJson(response);
417
- return {
418
- status: 'success',
419
- code: response.code ?? 'SUCCESS',
420
- data,
421
- timestamp: new Date().toISOString(),
422
- };
423
- });
424
- }
425
- create(dto) {
426
- return this.http
427
- .post(this.url, { data: CustomerCreateUpdateMapper.toJson(dto.data) })
428
- .then(response => {
429
- console.log(response);
430
- const data = CustomerCreateUpdateMapper.fromJson(response);
431
- return {
432
- status: response.code === '1' ? 'success' : 'warning',
433
- code: response.code ?? 'OPERATION_FAILED',
434
- data,
435
- message: response.message ?? 'Operation completed with issues',
436
- timestamp: new Date().toISOString(),
437
- };
438
- });
505
+ return null;
506
+ };
439
507
  }
440
- update(dto) {
441
- return this.http
442
- .put(`${this.url}${dto.id}`, {
443
- data: CustomerCreateUpdateMapper.toJson(dto.data),
444
- })
445
- .then(response => {
446
- console.log(response);
447
- return {
448
- status: response.code === '1' ? 'success' : 'warning',
449
- code: response.code ?? 'OPERATION_FAILED',
450
- message: response.message ?? 'Operation completed with issues',
451
- timestamp: new Date().toISOString(),
452
- };
453
- });
508
+ // Validador para RUC ecuatoriano (13 dígitos)
509
+ static ecuadorianRuc() {
510
+ return (control) => {
511
+ const value = control.value;
512
+ if (!value)
513
+ return null;
514
+ // Debe ser exactamente 13 dígitos
515
+ if (!/^\d{13}$/.test(value)) {
516
+ return { invalidRuc: true };
517
+ }
518
+ // Debe terminar en 001
519
+ if (!value.endsWith('001')) {
520
+ return { rucMustEndWith001: true };
521
+ }
522
+ return null;
523
+ };
454
524
  }
455
- updateState(id) {
456
- return this.http.delete(`${this.url}${id}`).then(response => {
457
- return {
458
- status: response.code === '1' ? 'success' : 'warning',
459
- code: response.code,
460
- message: response.message,
461
- timestamp: new Date().toISOString(),
462
- };
463
- });
525
+ // Validador para cédula ecuatoriana (10 dígitos)
526
+ static ecuadorianCedula() {
527
+ return (control) => {
528
+ const value = control.value;
529
+ if (!value)
530
+ return null;
531
+ if (!/^\d{10}$/.test(value)) {
532
+ return { invalidCedula: true };
533
+ }
534
+ // Algoritmo de validación de cédula ecuatoriana
535
+ const provincia = parseInt(value.substring(0, 2));
536
+ if (provincia < 1 || provincia > 24) {
537
+ return { invalidProvince: true };
538
+ }
539
+ const coeficientes = [2, 1, 2, 1, 2, 1, 2, 1, 2];
540
+ let suma = 0;
541
+ for (let i = 0; i < 9; i++) {
542
+ let valor = parseInt(value.charAt(i)) * coeficientes[i];
543
+ if (valor >= 10)
544
+ valor -= 9;
545
+ suma += valor;
546
+ }
547
+ const digitoVerificador = parseInt(value.charAt(9));
548
+ const resultado = suma % 10 === 0 ? 0 : 10 - (suma % 10);
549
+ if (resultado !== digitoVerificador) {
550
+ return { invalidCheckDigit: true };
551
+ }
552
+ return null;
553
+ };
464
554
  }
465
- getById(id) {
466
- return this.http.get(`${this.url}GetId/${id}`).then(response => {
467
- const data = CustomerGetByIdMapper.fromJson(response);
468
- return {
469
- status: response.code === '1' ? 'success' : 'warning',
470
- code: response.code ?? 'OPERATION_FAILED',
471
- data,
472
- message: response.message ?? 'Operation completed with issues',
473
- timestamp: new Date().toISOString(),
474
- };
475
- });
555
+ // Validador de email
556
+ static email() {
557
+ return (control) => {
558
+ const value = control.value;
559
+ if (!value)
560
+ return null;
561
+ const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
562
+ if (!emailRegex.test(value)) {
563
+ return { invalidEmail: true };
564
+ }
565
+ return null;
566
+ };
476
567
  }
477
- search(params) {
478
- const json = CompanySearchMapper.toJson(params);
479
- return this.http.get(`${this.url}Search?json=${json}`).then(response => {
480
- const data = CompanySearchMapper.fromJson(response);
481
- return {
482
- status: response.code === '1' ? 'success' : 'warning',
483
- code: response.code,
484
- data,
485
- message: response.message,
486
- timestamp: new Date().toISOString(),
487
- };
488
- });
568
+ // Validador de teléfono ecuatoriano
569
+ static ecuadorianPhone() {
570
+ return (control) => {
571
+ const value = control.value;
572
+ if (!value)
573
+ return null;
574
+ // Debe empezar con 0 y tener 9-10 dígitos
575
+ if (!/^0\d{8,9}$/.test(value)) {
576
+ return { invalidPhone: true };
577
+ }
578
+ return null;
579
+ };
489
580
  }
490
581
  }
491
582
 
492
- class CustomerAddEditComponent {
493
- dialogRef = inject((MatDialogRef));
494
- customerUseCase = inject(CustomerUseCase);
495
- customerExternalUseCase = inject(CustomerExternalUseCase);
496
- btnText = signal('Guardar', ...(ngDevMode ? [{ debugName: "btnText" }] : []));
497
- paramsOptions = inject(MAT_DIALOG_DATA);
498
- params = this.paramsOptions.data;
499
- notificationService = inject(NotificationService);
500
- title = 'Nuevo Cliente';
501
- loading = false;
583
+ class CompanyCustomerFormComponent {
584
+ formId = input(...(ngDevMode ? [undefined, { debugName: "formId" }] : []));
585
+ customer;
586
+ mode = 'create';
587
+ showButtons = input(true, ...(ngDevMode ? [{ debugName: "showButtons" }] : []));
588
+ submitted = output();
589
+ cancelled = output();
590
+ panelOpenState = signal(false, ...(ngDevMode ? [{ debugName: "panelOpenState" }] : []));
591
+ fb = inject(FormBuilder);
592
+ config = inject(COMPANY_CUSTOMER_FORM_CONFIG, { optional: true }) ?? MAIN_APP_COMPANY_CUSTOMER_CONFIG;
593
+ customerService = inject(COMPANY_CUSTOMER_SERVICE, { optional: true }) ?? inject(CompanyCustomerService);
594
+ form;
595
+ isLoading = signal(false, ...(ngDevMode ? [{ debugName: "isLoading" }] : []));
596
+ errorMessage = null;
597
+ step = signal(0, ...(ngDevMode ? [{ debugName: "step" }] : []));
502
598
  emails = [];
503
599
  telephones = [];
504
600
  tiemposCredito = signal([], ...(ngDevMode ? [{ debugName: "tiemposCredito" }] : []));
@@ -514,373 +610,284 @@ class CustomerAddEditComponent {
514
610
  maritalStatuses = signal([], ...(ngDevMode ? [{ debugName: "maritalStatuses" }] : []));
515
611
  housingTypes = signal([], ...(ngDevMode ? [{ debugName: "housingTypes" }] : []));
516
612
  showRefresh = signal(true, ...(ngDevMode ? [{ debugName: "showRefresh" }] : []));
517
- endsWith001Validator(control) {
518
- const value = control.value;
519
- if (value && value.length >= 3) {
520
- if (!value.endsWith('001')) {
521
- return { endsWith001: true };
522
- }
613
+ setStep(index) {
614
+ this.step.set(index);
615
+ }
616
+ nextStep() {
617
+ this.step.update(i => i + 1);
618
+ }
619
+ prevStep() {
620
+ this.step.update(i => i - 1);
621
+ }
622
+ ngOnInit() {
623
+ this.buildForm();
624
+ if (this.customer) {
625
+ this.patchFormValue(this.customer);
523
626
  }
524
- return null;
525
- }
526
- customerForm = new FormGroup({
527
- direccion: new FormControl('', Validators.required),
528
- idCargo: new FormControl(0),
529
- idCliente: new FormControl(0),
530
- idEmpresa: new FormControl(0),
531
- idFormaPagoSri: new FormControl(0),
532
- idTipoClienteProveedor: new FormControl(0),
533
- idTipoIdentificacion: new FormControl(0, Validators.required),
534
- idSubContribuyente: new FormControl(0),
535
- idTiempoCredito: new FormControl(0),
536
- idCiudad: new FormControl(0),
537
- idEmpleado: new FormControl(0),
538
- nombreFiscal: new FormControl('', Validators.required),
539
- nombreComercial: new FormControl(''),
540
- numeroIdentificacion: new FormControl({ value: '', disabled: false }, [
541
- Validators.required,
542
- Validators.minLength(13),
543
- Validators.maxLength(13),
544
- this.endsWith001Validator,
545
- ]),
546
- correo: new FormControl(''),
547
- telefono: new FormControl(''),
548
- placa: new FormControl(''),
549
- nota: new FormControl(''),
550
- estado: new FormControl(false),
551
- birthDate: new FormControl(null),
552
- validationSri: new FormControl(false),
553
- configValorBruto: new FormControl(false),
554
- dataInfoCred: new FormGroup({
555
- maritalStatusId: new FormControl(null),
556
- conyugeNombre: new FormControl(null),
557
- conyugeTel: new FormControl(null),
558
- refFamNombre: new FormControl(null),
559
- refFamTel: new FormControl(null),
560
- housingTypeId: new FormControl(null),
561
- dirVivienda: new FormControl(null),
562
- refDomicilio: new FormControl(null),
563
- sector: new FormControl(null),
564
- barrio: new FormControl(null),
565
- calle: new FormControl(null),
566
- }),
567
- });
568
- getCustomer(codigo, id) {
569
- this.customerForm.patchValue({
570
- validationSri: false,
571
- });
572
- from(this.customerUseCase.checkExistence(id)).subscribe(response => {
573
- if (isSuccessResponse(response) && response.data) {
574
- alert('El cliente ya se encuentra registrado en su empresa');
575
- this.notificationService.toastr.show({
576
- type: 'warning',
577
- message: 'El cliente ya se encuentra registrado en su empresa',
578
- });
579
- this.customerForm.patchValue({ numeroIdentificacion: null });
580
- return;
581
- }
582
- if (codigo === SRI_DOCUMENT_TYPE.PASSPORT) {
583
- this.customerForm.patchValue({
584
- validationSri: true,
585
- });
586
- return;
587
- }
588
- from(this.customerExternalUseCase.getById(id)).subscribe(secondResponse => {
589
- if (!isSuccessResponse(secondResponse) || !secondResponse.data) {
590
- this.notificationService.toastr.show({
591
- type: 'info',
592
- message: ' No se encontró información en el SRI',
593
- });
594
- return;
595
- }
596
- const { phone, email, idCard, // numeroRuc
597
- businessName, // razonSocial
598
- address, // direccion
599
- } = secondResponse.data;
600
- if (phone && typeof phone === 'string') {
601
- this.telephones = phone.split(SEPARADORES_REGEX) || [];
602
- }
603
- if (email && typeof email === 'string') {
604
- this.emails = email.split(SEPARADORES_REGEX) || [];
605
- }
606
- if (idCard) {
607
- this.customerForm.patchValue({
608
- numeroIdentificacion: idCard,
609
- nombreFiscal: businessName,
610
- validationSri: true,
611
- direccion: address,
612
- nombreComercial: businessName,
613
- });
614
- }
627
+ }
628
+ getDefaultConfig() {
629
+ // Configuración por defecto
630
+ return {};
631
+ }
632
+ // Método mejorado para acceder a campos de crédito
633
+ getCreditFieldConfig(fieldName) {
634
+ return this.config.creditFields?.[fieldName];
635
+ }
636
+ isCreditFieldVisible(fieldName) {
637
+ const field = this.getCreditFieldConfig(fieldName);
638
+ return field?.visible || false;
639
+ }
640
+ isCreditFieldRequired(fieldName) {
641
+ const field = this.getCreditFieldConfig(fieldName);
642
+ return field?.required || false;
643
+ }
644
+ getCreditFieldLabel(fieldName) {
645
+ const field = this.getCreditFieldConfig(fieldName);
646
+ return field?.label || fieldName;
647
+ }
648
+ getCreditFieldPlaceholder(fieldName) {
649
+ const field = this.getCreditFieldConfig(fieldName);
650
+ return field?.placeholder || '';
651
+ }
652
+ // Método mejorado para construir el FormGroup de crédito
653
+ buildCreditFormGroup() {
654
+ if (!this.config.showCreditInfo || !this.config.creditFields) {
655
+ return this.fb.group({
656
+ maritalStatusId: [null],
657
+ conyugeNombre: [null],
658
+ conyugeTel: [null],
659
+ refFamNombre: [null],
660
+ refFamTel: [null],
661
+ housingTypeId: [null],
662
+ dirVivienda: [null],
663
+ refDomicilio: [null],
664
+ sector: [null],
665
+ barrio: [null],
666
+ calle: [null],
615
667
  });
668
+ }
669
+ // Construir dinámicamente basado en la config
670
+ const creditGroup = {};
671
+ const creditFields = this.config.creditFields;
672
+ Object.keys(creditFields).forEach(key => {
673
+ const fieldConfig = creditFields[key];
674
+ const validators = fieldConfig.required ? [Validators.required] : [];
675
+ creditGroup[key] = [null, validators];
676
+ });
677
+ return this.fb.group(creditGroup);
678
+ }
679
+ buildForm() {
680
+ this.form = this.fb.group({
681
+ // IDs
682
+ idCliente: [0],
683
+ idEmpresa: [0],
684
+ idCargo: [0],
685
+ idFormaPagoSri: [0],
686
+ idTipoClienteProveedor: [0],
687
+ idSubContribuyente: [0],
688
+ idTiempoCredito: [0],
689
+ idCiudad: [0],
690
+ idEmpleado: [0],
691
+ // Datos principales con validadores
692
+ idTipoIdentificacion: [
693
+ 0,
694
+ this.config.fields.idTipoIdentificacion.required ? [Validators.required] : [],
695
+ ],
696
+ numeroIdentificacion: ['', this.getValidatorsForField('numeroIdentificacion')],
697
+ nombreFiscal: ['', this.getValidatorsForField('nombreFiscal')],
698
+ nombreComercial: [''],
699
+ direccion: ['', this.getValidatorsForField('direccion')],
700
+ correo: ['', this.getValidatorsForField('correo')],
701
+ telefono: ['', this.getValidatorsForField('telefono')],
702
+ placa: [''],
703
+ nota: [''],
704
+ birthDate: [null],
705
+ // Estados
706
+ estado: [false],
707
+ validationSri: [false],
708
+ configValorBruto: [false],
709
+ // FormGroup anidado para info de crédito
710
+ dataInfoCred: this.buildCreditFormGroup(),
616
711
  });
617
712
  }
618
- getLoadData() {
619
- if (this.isUpdate()) {
620
- return forkJoin([
621
- from(this.customerUseCase.getFormData()),
622
- from(this.customerUseCase.getById(this.params.id)),
623
- ]);
624
- }
625
- return from(this.customerUseCase.getFormData());
713
+ patchFormValue(customer) {
714
+ this.form.patchValue({
715
+ idCliente: customer.idCliente || 0,
716
+ idEmpresa: customer.idEmpresa || 0,
717
+ idCargo: customer.idCargo || 0,
718
+ idFormaPagoSri: customer.idFormaPagoSri || 0,
719
+ idTipoClienteProveedor: customer.idTipoClienteProveedor || 0,
720
+ idTipoIdentificacion: customer.idTipoIdentificacion || 0,
721
+ idSubContribuyente: customer.idSubContribuyente || 0,
722
+ idTiempoCredito: customer.idTiempoCredito || 0,
723
+ idCiudad: customer.idCiudad || 0,
724
+ idEmpleado: customer.idEmpleado || 0,
725
+ numeroIdentificacion: customer.numeroIdentificacion || '',
726
+ nombreFiscal: customer.nombreFiscal || '',
727
+ nombreComercial: customer.nombreComercial || '',
728
+ direccion: customer.direccion || '',
729
+ correo: customer.correo || '',
730
+ telefono: customer.telefono || '',
731
+ placa: customer.placa || '',
732
+ nota: customer.nota || '',
733
+ birthDate: customer.birthDate || null,
734
+ estado: customer.estado || false,
735
+ validationSri: customer.validationSri || false,
736
+ configValorBruto: customer.configValorBruto || false,
737
+ dataInfoCred: customer.dataInfoCred || {},
738
+ });
626
739
  }
627
- ngOnInit() {
628
- try {
629
- this.getLoadData().subscribe(response => {
630
- let mainDataForm = {};
631
- let dataCompanyCustomer = {};
632
- if (Array.isArray(response)) {
633
- mainDataForm = response[0].data;
634
- dataCompanyCustomer = response[1];
635
- }
636
- else {
637
- mainDataForm = response.data;
638
- }
639
- this.tiposIdentificacion.set(mainDataForm.tipoIdentificacion);
640
- this.tiemposCredito.set(mainDataForm.tiempoCreditos);
641
- this.tipoContribuyentes.set(mainDataForm.tipoContribuyentes);
642
- this.formasPagoSri.set(mainDataForm.formasPagoSri);
643
- this.tiposCliente.set(mainDataForm.tiposCliente);
644
- this.ciudades.set(mainDataForm.ciudades);
645
- this.cargos.set(mainDataForm.cargos);
646
- this.empresas.set(mainDataForm.empresas);
647
- this.employees.set(mainDataForm.employees);
648
- this.maritalStatuses.set(mainDataForm.maritalStatuses);
649
- this.housingTypes.set(mainDataForm.housingTypes);
650
- if (this.isDataOfSri()) {
651
- const { codigoSri, numeroIdentificacion } = this.params;
652
- const dataIdentificacion = this.tiposIdentificacion().find((ti) => ti.codigoSri === codigoSri);
653
- if (dataIdentificacion) {
654
- const idTipoIdentificacionCtrl = this.customerForm.get('idTipoIdentificacion');
655
- idTipoIdentificacionCtrl?.setValue(dataIdentificacion.idTipoIdentificacion);
656
- const numeroIdentificacionCtrl = this.customerForm.get('numeroIdentificacion');
657
- numeroIdentificacionCtrl?.setValue(numeroIdentificacion);
658
- const idTiempoCreditoCtrl = this.customerForm.get('idTiempoCredito');
659
- idTiempoCreditoCtrl?.setValue(this.tiemposCredito().length > 0
660
- ? this.tiemposCredito()[0].idTiempoCredito
661
- : 0);
662
- this.updateFormControlNumeroIdentificacion(dataIdentificacion.codigoSri);
663
- this.onKeyDownGovernmentId();
664
- }
665
- return;
666
- }
667
- if (this.isCreate()) {
668
- const dataIdentificacion = this.tiposIdentificacion().find((ti) => ti.codigoSri === SRI_DOCUMENT_TYPE.RUC);
669
- if (dataIdentificacion) {
670
- const idTipoIdentificacionCtrl = this.customerForm.get('idTipoIdentificacion');
671
- idTipoIdentificacionCtrl?.setValue(dataIdentificacion.idTipoIdentificacion);
672
- this.setIdentificationTypeChange(dataIdentificacion.codigoSri);
673
- }
674
- const idTiempoCreditoCtrl = this.customerForm.get('idTiempoCredito');
675
- idTiempoCreditoCtrl?.setValue(this.tiemposCredito().length > 0
676
- ? this.tiemposCredito()[0].idTiempoCredito
677
- : 0);
740
+ // Método mejorado para obtener validadores
741
+ getValidatorsForField(fieldName) {
742
+ const validators = [];
743
+ const fieldConfig = this.config.fields[fieldName];
744
+ if (!fieldConfig)
745
+ return validators;
746
+ if (fieldConfig.required) {
747
+ validators.push(Validators.required);
748
+ }
749
+ // Validadores específicos por campo
750
+ switch (fieldName) {
751
+ case 'numeroIdentificacion':
752
+ validators.push(Validators.minLength(13));
753
+ validators.push(Validators.maxLength(13));
754
+ validators.push(CustomerValidators.endsWith001());
755
+ break;
756
+ case 'correo':
757
+ if (fieldConfig.visible) {
758
+ validators.push(CustomerValidators.email());
678
759
  }
679
- else {
680
- this.title = 'Editar Cliente';
681
- this.btnText.set('Actualizar');
682
- this.emails = dataCompanyCustomer.correos;
683
- this.telephones = dataCompanyCustomer.telefonos;
684
- this.placas.set(dataCompanyCustomer.placas);
685
- const { dataInfoCred, ...rest } = dataCompanyCustomer;
686
- this.customerForm.patchValue(rest);
687
- if (dataInfoCred) {
688
- this.customerForm.get('dataInfoCred')?.patchValue(dataInfoCred);
689
- }
690
- this.updateFormControlNumeroIdentificacion(rest.codigoSri);
760
+ break;
761
+ case 'telefono':
762
+ if (fieldConfig.visible) {
763
+ validators.push(CustomerValidators.ecuadorianPhone());
691
764
  }
692
- });
765
+ break;
693
766
  }
694
- catch {
695
- // Handle error appropriately
767
+ // Validadores custom del config
768
+ if (fieldConfig.validators) {
769
+ validators.push(...fieldConfig.validators);
696
770
  }
771
+ return validators;
697
772
  }
698
- identificationTypeChange(event) {
699
- const dt = this.tiposIdentificacion().find(item => item.idTipoIdentificacion === Number(event.value));
700
- this.setIdentificationTypeChange(dt.codigoSri);
701
- }
702
- updateFormControlNumeroIdentificacion(codigoSri) {
703
- const idNumberControl = this.customerForm.get('numeroIdentificacion');
704
- this.showRefresh.set(false);
705
- if ([SRI_DOCUMENT_TYPE.RUC, SRI_DOCUMENT_TYPE.CEDULA].includes(codigoSri)) {
706
- let lengthValidator;
707
- this.showRefresh.set(true);
708
- if (codigoSri === SRI_DOCUMENT_TYPE.CEDULA) {
709
- lengthValidator = [Validators.minLength(10), Validators.maxLength(10)];
710
- }
711
- else if (codigoSri === SRI_DOCUMENT_TYPE.RUC) {
712
- lengthValidator = [
713
- Validators.minLength(13),
714
- Validators.maxLength(13),
715
- this.endsWith001Validator,
716
- ];
717
- }
718
- if (lengthValidator) {
719
- idNumberControl?.setValidators([
720
- Validators.required,
721
- Validators.pattern(/^\d+$/), // Solo números
722
- ...lengthValidator,
723
- ]);
724
- }
725
- }
726
- else {
727
- idNumberControl?.setValidators([Validators.required]);
728
- }
729
- idNumberControl?.updateValueAndValidity();
773
+ // Métodos mejorados de acceso
774
+ isFieldVisible(fieldName) {
775
+ return this.config.fields[fieldName]?.visible || false;
730
776
  }
731
- setIdentificationTypeChange(codigoSri) {
732
- const idNumberControl = this.customerForm.get('numeroIdentificacion');
733
- idNumberControl?.reset();
734
- idNumberControl?.clearValidators();
735
- this.updateFormControlNumeroIdentificacion(codigoSri);
777
+ isFieldRequired(fieldName) {
778
+ return this.config.fields[fieldName]?.required || false;
736
779
  }
737
- get numeroIdentificacionControl() {
738
- return this.customerForm.get('numeroIdentificacion');
780
+ getFieldLabel(fieldName) {
781
+ return this.config.fields[fieldName]?.label || fieldName;
739
782
  }
740
- get birthDateCtrl() {
741
- return this.customerForm.get('birthDate');
783
+ getFieldPlaceholder(fieldName) {
784
+ return this.config.fields[fieldName]?.placeholder || '';
742
785
  }
743
- onKeyDownGovernmentId($event) {
744
- if ($event) {
745
- $event.preventDefault();
746
- }
747
- if (this.numeroIdentificacionControl?.invalid)
786
+ identificationTypeChange($ev) {
787
+ console.log($ev);
788
+ }
789
+ onSubmit() {
790
+ if (this.form.invalid) {
791
+ this.form.markAllAsTouched();
748
792
  return;
749
- const idTipoIdentificacion = this.customerForm.get('idTipoIdentificacion')?.value;
750
- const numeroIdentificacion = this.customerForm.get('numeroIdentificacion')?.value;
751
- const codigoSri = this.tiposIdentificacion().find((x) => x.idTipoIdentificacion == idTipoIdentificacion).codigoSri;
752
- if (numeroIdentificacion) {
753
- this.getCustomer(codigoSri, numeroIdentificacion);
754
793
  }
755
- }
756
- isDataOfSri = () => this.params.dataOfSri;
757
- isCreate = () => !(this.params.id > 0);
758
- isUpdate = () => this.params.id > 0;
759
- onSave() {
760
- this.customerForm.patchValue({
761
- telefono: this.telephones.length > 0 ? this.telephones.join(SEPARATOR_KEY_CODE.SLASH) : null,
762
- });
763
- this.customerForm.patchValue({
764
- correo: this.emails.length > 0 ? this.emails.join(SEPARATOR_KEY_CODE.SLASH) : null,
765
- });
766
- this.customerForm.patchValue({
767
- placa: this.placas().length > 0 ? this.placas().join(SEPARATOR_KEY_CODE.SLASH) : null,
794
+ const customerData = this.form.getRawValue();
795
+ if (this.customerService?.validate) {
796
+ const validationErrors = this.customerService.validate(customerData);
797
+ if (validationErrors) {
798
+ this.errorMessage = 'Por favor corrija los errores de validación';
799
+ return;
800
+ }
801
+ }
802
+ this.isLoading.set(true);
803
+ this.errorMessage = null;
804
+ const operation$ = this.mode === 'create'
805
+ ? this.customerService.create(customerData)
806
+ : this.customerService.update(this.customer.id, customerData);
807
+ operation$.subscribe({
808
+ next: (savedCustomer) => {
809
+ this.isLoading.set(false);
810
+ this.submitted.emit(savedCustomer);
811
+ },
812
+ error: (error) => {
813
+ this.isLoading.set(false);
814
+ this.errorMessage = error.message || 'Error al guardar el cliente';
815
+ },
768
816
  });
769
- const dataForm = {
770
- ...this.customerForm.value,
771
- };
772
- if (this.customerForm.invalid) {
773
- this.notificationService.toastr.show({
774
- type: 'warning',
775
- message: 'Ingrese todos datos requeridos',
776
- });
777
- return;
817
+ }
818
+ onCancel() {
819
+ this.cancelled.emit();
820
+ }
821
+ getErrorMessage(fieldName) {
822
+ const control = this.form.get(fieldName);
823
+ if (!control || !control.errors || !control.touched) {
824
+ return '';
778
825
  }
779
- if (this.isUpdate()) {
780
- const sendParams = {
781
- id: this.params.id,
782
- data: dataForm,
783
- };
784
- from(this.customerUseCase.update(sendParams)).subscribe(response => {
785
- this.notificationService.toastr.show({
786
- type: isSuccessResponse(response) ? 'success' : 'warning',
787
- message: `${response.message}`,
788
- });
789
- if (isSuccessResponse(response)) {
790
- this.dialogRef.close({
791
- id: this.params.id,
792
- });
793
- }
794
- });
826
+ if (control.errors['required']) {
827
+ return `${this.getFieldLabel(fieldName)} es requerido`;
795
828
  }
796
- if (this.isCreate()) {
797
- from(this.customerUseCase.create(dataForm)).subscribe(response => {
798
- this.notificationService.toastr.show({
799
- type: isSuccessResponse(response) ? 'success' : 'warning',
800
- message: `${response.message}`,
801
- });
802
- if (isSuccessResponse(response)) {
803
- this.dialogRef.close(response.data);
804
- }
805
- });
829
+ if (control.errors['minlength']) {
830
+ return `Mínimo ${control.errors['minlength'].requiredLength} caracteres`;
831
+ }
832
+ if (control.errors['maxlength']) {
833
+ return `Máximo ${control.errors['maxlength'].requiredLength} caracteres`;
834
+ }
835
+ if (control.errors['endsWith001']) {
836
+ return 'Debe terminar en 001';
837
+ }
838
+ if (control.errors['invalidRuc']) {
839
+ return 'RUC inválido';
840
+ }
841
+ if (control.errors['invalidCedula']) {
842
+ return 'Cédula inválida';
806
843
  }
844
+ if (control.errors['invalidEmail']) {
845
+ return 'Email inválido';
846
+ }
847
+ if (control.errors['invalidPhone']) {
848
+ return 'Teléfono inválido (debe empezar con 0)';
849
+ }
850
+ return 'Campo inválido';
807
851
  }
808
- close() {
809
- this.dialogRef.close();
852
+ // Getters para FormGroups anidados
853
+ get dataInfoCredForm() {
854
+ return this.form.get('dataInfoCred');
810
855
  }
811
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: CustomerAddEditComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
812
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.9", type: CustomerAddEditComponent, isStandalone: true, selector: "acp-customer-add-edit", providers: [
813
- provideNativeDateAdapter(),
814
- {
815
- provide: CustomerUseCase,
816
- useFactory: () => new CustomerUseCase(new CustomerHttpRepository()),
817
- },
818
- {
819
- provide: CustomerExternalUseCase,
820
- useFactory: () => new CustomerExternalUseCase(new CustomerExternalHttpRepository()),
821
- },
822
- ], ngImport: i0, template: "<mat-dialog-content>\n <form\n (ngSubmit)=\"onSave()\"\n id=\"formCompanyCustomer\"\n [formGroup]=\"customerForm\"\n autocomplete=\"off\"\n >\n <mat-tab-group>\n <mat-tab label=\"DATOS PRINCIPALES\">\n <div class=\"d-grid gap-2 mx-3 mt-2\">\n <div\n class=\"row row-cols-xxl-2 row-cols-xl-2 row-cols-lg-2 row-cols-md-2 row-cols-sm-2 row-cols-1 g-1\"\n >\n <div class=\"col\">\n <mat-form-field class=\"w-100\">\n <mat-label>Tipo Identificaci\u00F3n: </mat-label>\n <mat-select\n formControlName=\"idTipoIdentificacion\"\n (selectionChange)=\"identificationTypeChange($event)\"\n >\n @for (item of tiposIdentificacion(); track $index) {\n <mat-option [value]=\"item.idTipoIdentificacion\"\n >{{ item.descripcion }}</mat-option\n >\n }\n </mat-select>\n </mat-form-field>\n </div>\n <div class=\"col\">\n <mat-form-field class=\"w-100\">\n <mat-label>N\u00FAmero de Identificaci\u00F3n</mat-label>\n <input\n type=\"text\"\n matInput\n (keydown.enter)=\"onKeyDownGovernmentId($event)\"\n formControlName=\"numeroIdentificacion\"\n />\n @if ( numeroIdentificacionControl?.invalid && (numeroIdentificacionControl?.dirty ||\n numeroIdentificacionControl?.touched) ) { @if\n (numeroIdentificacionControl?.hasError('required')) {\n <mat-error> El n\u00FAmero de identificaci\u00F3n es obligatorio. </mat-error>\n } @if (numeroIdentificacionControl?.hasError('minlength')) {\n <mat-error>\n Debe tener al menos {{\n numeroIdentificacionControl?.errors?.['minlength'].requiredLength }} d\u00EDgitos.\n </mat-error>\n } @if (numeroIdentificacionControl?.hasError('maxlength')) {\n <mat-error>\n No puede tener m\u00E1s de {{\n numeroIdentificacionControl?.errors?.['maxlength'].requiredLength }} d\u00EDgitos.\n </mat-error>\n } @if (numeroIdentificacionControl?.hasError('pattern')) {\n <mat-error> Solo se permiten caracteres num\u00E9ricos. </mat-error>\n } @if (numeroIdentificacionControl?.hasError('endsWith001')) {\n <mat-error> Los \u00FAltimos tres d\u00EDgitos deben ser 001. </mat-error>\n } } @if (showRefresh()) {\n <ng-container matSuffix>\n <acp-button\n type=\"button\"\n matStyle=\"icon\"\n icon=\"refresh\"\n (handleClick)=\"onKeyDownGovernmentId($event)\"\n />\n </ng-container>\n }\n </mat-form-field>\n </div>\n </div>\n\n <div\n class=\"row row-cols-xxl-2 row-cols-xl-2 row-cols-lg-2 row-cols-md-2 row-cols-sm-2 row-cols-1 g-1\"\n >\n <div class=\"col\">\n <mat-form-field class=\"w-100\">\n <mat-label>Nombre Fiscal:</mat-label>\n <input\n matInput\n autocomplete=\"off\"\n formControlName=\"nombreFiscal\"\n id=\"nombreComercial\"\n placeholder=\"Ej: TECNOMEGA\"\n acpToUpperCase\n />\n </mat-form-field>\n </div>\n <div class=\"col\">\n <mat-form-field class=\"w-100\">\n <mat-label>Nombre Comercial:</mat-label>\n <input\n matInput\n autocomplete=\"off\"\n formControlName=\"nombreComercial\"\n placeholder=\"Ej: TECNOMEGA\"\n acpToUpperCase\n type=\"text\"\n />\n </mat-form-field>\n </div>\n </div>\n\n <div>\n <mat-form-field class=\"w-100\">\n <mat-label>Direcci\u00F3n:</mat-label>\n <input\n matInput\n formControlName=\"direccion\"\n placeholder=\"AV. 09 DE OCTUBRE...\"\n acpToUpperCase\n />\n </mat-form-field>\n </div>\n\n <div\n class=\"row row-cols-xxl-2 row-cols-xl-2 row-cols-lg-2 row-cols-md-2 row-cols-sm-2 row-cols-1 g-1\"\n >\n <div class=\"col\">\n <acp-input-chip [chips]=\"emails\" [labelText]=\"'Correo'\" />\n </div>\n <div class=\"col\">\n <acp-input-chip [chips]=\"telephones\" [labelText]=\"'Tel\u00E9fono'\" />\n </div>\n </div>\n\n @if (isUpdate()) {\n <div class=\"vstack gap-2 mt-2\">\n <span>Estado</span>\n <mat-slide-toggle formControlName=\"estado\">\n {{ customerForm.value.estado ? 'Activo' : 'Inactivo' }}\n </mat-slide-toggle>\n </div>\n }\n </div>\n </mat-tab>\n <mat-tab label=\"DATOS ADICIONALES\">\n <div class=\"d-grid gap-2 mx-3 mt-2\">\n <div\n class=\"row row-cols-xxl-2 row-cols-xl-2 row-cols-lg-2 row-cols-md-2 row-cols-sm-2 row-cols-1 g-1\"\n >\n <div class=\"col\">\n <acp-dynamic-card title=\"Informaci\u00F3n B\u00E1sica\" [isHeaderVisible]=\"true\">\n <div\n class=\"row row-cols-xxl-2 row-cols-xl-2 row-cols-lg-2 row-cols-md-2 row-cols-sm-2 row-cols-1 g-2\"\n >\n <div class=\"col\">\n <mat-form-field class=\"w-100\">\n <mat-label>Tipo Contribuyente: </mat-label>\n <mat-select formControlName=\"idSubContribuyente\">\n @for (item of tipoContribuyentes(); track $index) {\n <mat-option [value]=\"item.idSubContribuyente\">\n {{ item.descripcion }}\n </mat-option>\n }\n </mat-select>\n </mat-form-field>\n </div>\n\n <div class=\"col\">\n <mat-form-field class=\"w-100\">\n <mat-label>Tiempo Cr\u00E9dito: </mat-label>\n <mat-select formControlName=\"idTiempoCredito\">\n @for (item of tiemposCredito(); track $index) {\n <mat-option [value]=\"item.idTiempoCredito\">\n {{ item.descripcion }}\n </mat-option>\n }\n </mat-select>\n </mat-form-field>\n </div>\n\n <div class=\"col\">\n <mat-form-field class=\"w-100\">\n <mat-label>Ciudad</mat-label>\n <mat-select formControlName=\"idCiudad\">\n <mat-option [value]=\"0\">-- Ninguno --</mat-option>\n @for (group of ciudades(); track $index) {\n <mat-optgroup [label]=\"group.nombre\">\n @for (item of group.ciudades; track $index) {\n <mat-option [value]=\"item.idCiudad\">{{ item.nombre }}</mat-option>\n }\n </mat-optgroup>\n }\n </mat-select>\n </mat-form-field>\n </div>\n <div class=\"col\">\n <mat-form-field class=\"w-100\">\n <mat-label>Tipo Cliente: </mat-label>\n <mat-select formControlName=\"idTipoClienteProveedor\">\n <mat-option [value]=\"0\">--Ninguno--</mat-option>\n @for (item of tiposCliente(); track $index) {\n <mat-option [value]=\"item.idTipoClienteProveedor\">\n {{ item.descripcion }}\n </mat-option>\n }\n </mat-select>\n </mat-form-field>\n </div>\n\n <div class=\"col\">\n <mat-form-field class=\"w-100\">\n <mat-label>Empresa: </mat-label>\n <mat-select formControlName=\"idEmpresa\">\n <mat-option [value]=\"0\">--Ninguno--</mat-option>\n\n @for (item of empresas(); track $index) {\n <mat-option [value]=\"item.idEmpresa\"> {{ item.descripcion }} </mat-option>\n }\n </mat-select>\n </mat-form-field>\n </div>\n <div class=\"col\">\n <mat-form-field class=\"w-100\">\n <mat-label>Fecha Nacimiento</mat-label>\n <input matInput [matDatepicker]=\"birthDate\" formControlName=\"birthDate\" />\n <mat-hint>MM/DD/YYYY</mat-hint>\n <mat-datepicker-toggle matIconSuffix [for]=\"birthDate\" />\n <mat-datepicker #birthDate />\n @if (birthDateCtrl?.invalid && birthDateCtrl?.touched) {\n <mat-error> Fecha inv\u00E1lida </mat-error>\n }\n </mat-form-field>\n </div>\n </div>\n </acp-dynamic-card>\n </div>\n <div class=\"col\">\n <acp-dynamic-card title=\"Informaci\u00F3n Laboral\" [isHeaderVisible]=\"true\">\n <div\n class=\"row row-cols-xxl-2 row-cols-xl-2 row-cols-lg-2 row-cols-md-2 row-cols-sm-2 row-cols-1 g-1\"\n >\n <div class=\"col\">\n <mat-form-field class=\"w-100\">\n <mat-label>Empleado: </mat-label>\n <mat-select formControlName=\"idEmpleado\">\n <mat-option [value]=\"0\">--Ninguno--</mat-option>\n\n @for (item of employees(); track $index) {\n <mat-option [value]=\"item.idEmpleado\">\n {{ item.nombreCompleto }}\n </mat-option>\n }\n </mat-select>\n </mat-form-field>\n </div>\n\n <div class=\"col\">\n <mat-form-field class=\"w-100\">\n <mat-label>Cargo: </mat-label>\n <mat-select formControlName=\"idCargo\">\n <mat-option [value]=\"0\">--Ninguno--</mat-option>\n\n @for (item of cargos(); track $index) {\n <mat-option [value]=\"item.idCargo\"> {{ item.descripcion }} </mat-option>\n }\n </mat-select>\n </mat-form-field>\n </div>\n\n <div class=\"col w-100\">\n <mat-form-field class=\"w-100\">\n <mat-label>Observaci\u00F3n</mat-label>\n <textarea matInput placeholder=\"...\" formControlName=\"nota\"></textarea>\n </mat-form-field>\n </div>\n </div>\n </acp-dynamic-card>\n </div>\n </div>\n <div\n class=\"row row-cols-xxl-2 row-cols-xl-2 row-cols-lg-2 row-cols-md-2 row-cols-sm-2 row-cols-1 g-1\"\n >\n <div class=\"col\">\n <acp-dynamic-card title=\"Configuraci\u00F3n Financiera\" [isHeaderVisible]=\"true\">\n <div\n class=\"row row-cols-xxl-1 row-cols-xl-1 row-cols-lg-1 row-cols-md-1 row-cols-sm-1 row-cols-1 g-2 mt-2\"\n >\n <div class=\"col\">\n <mat-form-field class=\"w-100\">\n <mat-label>Forma de pago: </mat-label>\n <mat-select formControlName=\"idFormaPagoSri\">\n <mat-option [value]=\"0\">--Ninguno--</mat-option>\n\n @for (item of formasPagoSri(); track $index) {\n <mat-option [value]=\"item.idFormaPagoSri\">\n {{ item.descripcion }}\n </mat-option>\n }\n </mat-select>\n </mat-form-field>\n </div>\n\n <div class=\"col\">\n <acp-input-chip labelText=\"Placa\" [chips]=\"placas()\" />\n </div>\n\n <div class=\"col w-100\">\n <mat-checkbox formControlName=\"configValorBruto\"\n >Activar configuraci\u00F3n de valor bruto\n <mat-icon\n matTooltip=\"valor total de un bien o servicio sin incluir impuestos, deducciones o descuentos (uso dentro del reporte)\"\n >info</mat-icon\n ></mat-checkbox\n >\n </div>\n </div>\n </acp-dynamic-card>\n </div>\n <div class=\"col\"></div>\n </div>\n </div>\n </mat-tab>\n <mat-tab label=\"INFORMACI\u00D3N CREDITICIA\">\n <div class=\"d-grid gap-2 mx-3 mt-2\">\n <div\n class=\"row row-cols-xxl-2 row-cols-xl-2 row-cols-lg-2 row-cols-md-2 row-cols-sm-2 row-cols-1 g-1\"\n >\n <div class=\"col\">\n <acp-dynamic-card title=\"Informaci\u00F3n Personal\" [isHeaderVisible]=\"true\">\n <div\n formGroupName=\"dataInfoCred\"\n class=\"row row-cols-xxl-2 row-cols-xl-2 row-cols-lg-2 row-cols-md-2 row-cols-sm-1 row-cols-1 g-2 mt-2\"\n >\n <div class=\"col\">\n <mat-form-field class=\"w-100\">\n <mat-label>Estado Civil: </mat-label>\n <mat-select formControlName=\"maritalStatusId\">\n <mat-option [value]=\"0\">Seleccionar...</mat-option>\n\n @for (item of maritalStatuses(); track $index) {\n <mat-option [value]=\"item.id\"> {{ item.name }} </mat-option>\n }\n </mat-select>\n </mat-form-field>\n </div>\n <div class=\"col\">\n <mat-form-field class=\"w-100\">\n <mat-label>Esposo(a):</mat-label>\n <input\n matInput\n formControlName=\"conyugeNombre\"\n placeholder=\"Nombre del c\u00F3nyuge\"\n />\n </mat-form-field>\n </div>\n\n <div class=\"col\">\n <mat-form-field class=\"w-100\">\n <mat-label>Tel\u00E9fono Personal:</mat-label>\n <input matInput formControlName=\"conyugeTel\" placeholder=\"09xxxxxxxx\" />\n </mat-form-field>\n </div>\n <div class=\"col\">\n <mat-form-field class=\"w-100\">\n <mat-label>Tel\u00E9fono Referencia:</mat-label>\n <input matInput formControlName=\"refFamTel\" placeholder=\"09xxxxxxxx\" />\n </mat-form-field>\n </div>\n <div class=\"col w-100\">\n <mat-form-field class=\"w-100\">\n <mat-label>Referencia Familiar:</mat-label>\n <input\n matInput\n formControlName=\"refFamNombre\"\n placeholder=\"Nombre de referencia familiar\"\n />\n </mat-form-field>\n </div>\n </div>\n </acp-dynamic-card>\n </div>\n <div class=\"col\">\n <acp-dynamic-card title=\"Informaci\u00F3n de Vivienda\" [isHeaderVisible]=\"true\">\n <div\n formGroupName=\"dataInfoCred\"\n class=\"row row-cols-xxl-2 row-cols-xl-2 row-cols-lg-2 row-cols-md-2 row-cols-sm-1 row-cols-1 g-2 mt-2\"\n >\n <div class=\"col\">\n <mat-form-field class=\"w-100\">\n <mat-label>Tipo de Vivienda: </mat-label>\n <mat-select formControlName=\"housingTypeId\">\n <mat-option [value]=\"0\">Seleccionar...</mat-option>\n\n @for (item of housingTypes(); track $index) {\n <mat-option [value]=\"item.id\"> {{ item.name }} </mat-option>\n }\n </mat-select>\n </mat-form-field>\n </div>\n <div class=\"col\">\n <mat-form-field class=\"w-100\">\n <mat-label>Sector:</mat-label>\n <input matInput formControlName=\"sector\" placeholder=\"Nombre del sector\" />\n </mat-form-field>\n </div>\n\n <div class=\"col\">\n <mat-form-field class=\"w-100\">\n <mat-label>Barrio:</mat-label>\n <input matInput formControlName=\"barrio\" placeholder=\"Nombre del barrio\" />\n </mat-form-field>\n </div>\n <div class=\"col\">\n <mat-form-field class=\"w-100\">\n <mat-label>Calle:</mat-label>\n <input matInput formControlName=\"calle\" placeholder=\"Nombre de la calle\" />\n </mat-form-field>\n </div>\n <div class=\"col w-100\">\n <mat-form-field class=\"w-100\">\n <mat-label>Direcci\u00F3n Completa</mat-label>\n <textarea\n matInput\n formControlName=\"dirVivienda\"\n placeholder=\"Direcci\u00F3n completa de la vivienda (Sector, Barrio y Calle)\"\n ></textarea>\n </mat-form-field>\n </div>\n <div class=\"col w-100\">\n <mat-form-field class=\"w-100\">\n <mat-label>Descripci\u00F3n del Punto de Referencia:</mat-label>\n <textarea\n matInput\n formControlName=\"refDomicilio\"\n placeholder=\"Descripci\u00F3n detallada del punto de referencia\"\n ></textarea>\n </mat-form-field>\n </div>\n </div>\n </acp-dynamic-card>\n </div>\n </div>\n </div>\n </mat-tab>\n </mat-tab-group>\n </form>\n</mat-dialog-content>\n<mat-dialog-actions>\n <div class=\"hstack gap-2\">\n <acp-button type=\"submit\" form=\"formCompanyCustomer\" [text]=\"btnText()\" />\n <acp-button type=\"button\" variant=\"dark\" text=\"Cerrar\" (handleClick)=\"close()\" />\n </div>\n</mat-dialog-actions>\n", styles: [""], dependencies: [{ kind: "directive", type: MatDialogContent, selector: "[mat-dialog-content], mat-dialog-content, [matDialogContent]" }, { kind: "directive", type: MatDialogActions, selector: "[mat-dialog-actions], mat-dialog-actions, [matDialogActions]", inputs: ["align"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "directive", type: i1.FormGroupName, selector: "[formGroupName]", inputs: ["formGroupName"] }, { kind: "ngmodule", type: MatTabsModule }, { kind: "component", type: i2.MatTab, selector: "mat-tab", inputs: ["disabled", "label", "aria-label", "aria-labelledby", "labelClass", "bodyClass", "id"], exportAs: ["matTab"] }, { kind: "component", type: i2.MatTabGroup, selector: "mat-tab-group", inputs: ["color", "fitInkBarToContent", "mat-stretch-tabs", "mat-align-tabs", "dynamicHeight", "selectedIndex", "headerPosition", "animationDuration", "contentTabIndex", "disablePagination", "disableRipple", "preserveContent", "backgroundColor", "aria-label", "aria-labelledby"], outputs: ["selectedIndexChange", "focusChange", "animationDone", "selectedTabChange"], exportAs: ["matTabGroup"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i3.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i3.MatLabel, selector: "mat-label" }, { kind: "directive", type: i3.MatHint, selector: "mat-hint", inputs: ["align", "id"] }, { kind: "directive", type: i3.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "directive", type: i3.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i4.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "ngmodule", type: MatSelectModule }, { kind: "component", type: i5.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth", "canSelectNullableOptions"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "component", type: i5.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "component", type: i5.MatOptgroup, selector: "mat-optgroup", inputs: ["label", "disabled"], exportAs: ["matOptgroup"] }, { kind: "ngmodule", type: MatSlideToggleModule }, { kind: "component", type: i6.MatSlideToggle, selector: "mat-slide-toggle", inputs: ["name", "id", "labelPosition", "aria-label", "aria-labelledby", "aria-describedby", "required", "color", "disabled", "disableRipple", "tabIndex", "checked", "hideIcon", "disabledInteractive"], outputs: ["change", "toggleChange"], exportAs: ["matSlideToggle"] }, { kind: "component", type: InputChip, selector: "acp-input-chip", inputs: ["chips", "labelText", "placelholder"] }, { kind: "directive", type: ToUpperCase, selector: "[acpToUpperCase]" }, { kind: "component", type: MatCheckbox, selector: "mat-checkbox", inputs: ["aria-label", "aria-labelledby", "aria-describedby", "aria-expanded", "aria-controls", "aria-owns", "id", "required", "labelPosition", "name", "value", "disableRipple", "tabIndex", "color", "disabledInteractive", "checked", "disabled", "indeterminate"], outputs: ["change", "indeterminateChange"], exportAs: ["matCheckbox"] }, { kind: "component", type: MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "ngmodule", type: MatDatepickerModule }, { kind: "component", type: i7.MatDatepicker, selector: "mat-datepicker", exportAs: ["matDatepicker"] }, { kind: "directive", type: i7.MatDatepickerInput, selector: "input[matDatepicker]", inputs: ["matDatepicker", "min", "max", "matDatepickerFilter"], exportAs: ["matDatepickerInput"] }, { kind: "component", type: i7.MatDatepickerToggle, selector: "mat-datepicker-toggle", inputs: ["for", "tabIndex", "aria-label", "disabled", "disableRipple"], exportAs: ["matDatepickerToggle"] }, { kind: "component", type: Button, selector: "acp-button", inputs: ["variant", "text", "icon", "disabled", "type", "matStyle", "customClass", "reportFormat", "extended", "title", "ariaLabel", "name", "id", "form", "tabIndex", "testId"], outputs: ["handleClick"] }, { kind: "component", type: DynamicCard, selector: "acp-dynamic-card", inputs: ["cardTitle", "cardSubtitle", "avatarImageUrl", "isHeaderVisible", "contentPadding", "hasDivider", "areActionsVisible", "primaryButtonText", "secondaryButtonText", "primaryButtonIcon", "secondaryButtonIcon", "buttonsPosition"], outputs: ["primaryButtonClicked", "secondaryButtonClicked", "cardClicked"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
856
+ searchIdentificacion($event) {
857
+ $event.stopPropagation();
858
+ console.log('search');
859
+ }
860
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: CompanyCustomerFormComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
861
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.6", type: CompanyCustomerFormComponent, isStandalone: true, selector: "acp-company-customer-form", inputs: { formId: { classPropertyName: "formId", publicName: "formId", isSignal: true, isRequired: false, transformFunction: null }, customer: { classPropertyName: "customer", publicName: "customer", isSignal: false, isRequired: false, transformFunction: null }, mode: { classPropertyName: "mode", publicName: "mode", isSignal: false, isRequired: false, transformFunction: null }, showButtons: { classPropertyName: "showButtons", publicName: "showButtons", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { submitted: "submitted", cancelled: "cancelled" }, exportAs: ["acpCustomerForm"], ngImport: i0, template: "<form [formGroup]=\"form\" (ngSubmit)=\"onSubmit()\" [id]=\"formId()\" class=\"mb-2\">\n @if (errorMessage) {\n <div class=\"alert alert-error\">{{ errorMessage }}</div>\n }\n <mat-accordion class=\"mb-2\">\n <mat-expansion-panel [expanded]=\"step() === 0\" (opened)=\"setStep(0)\" hideToggle>\n <mat-expansion-panel-header>\n <mat-panel-title>\n <mat-icon>account_circle</mat-icon>\n Datos Principales\n </mat-panel-title>\n </mat-expansion-panel-header>\n\n <div class=\"d-grid gap-2 mx-3 mt-2\">\n <div\n class=\"row row-cols-xxl-2 row-cols-xl-2 row-cols-lg-2 row-cols-md-2 row-cols-sm-2 row-cols-1 g-1\"\n >\n <div class=\"col\">\n @if (isFieldVisible('idTipoIdentificacion')) {\n <mat-form-field class=\"w-100\">\n <mat-label> {{ getFieldLabel('idTipoIdentificacion') }} </mat-label>\n <mat-select\n formControlName=\"idTipoIdentificacion\"\n (selectionChange)=\"identificationTypeChange($event)\"\n >\n @for (item of tiposIdentificacion(); track $index) {\n <mat-option [value]=\"item.idTipoIdentificacion\">{{ item.descripcion }}</mat-option>\n }\n </mat-select>\n @if (form.get('idTipoIdentificacion')?.invalid &&\n form.get('idTipoIdentificacion')?.touched) {\n <mat-error> {{ getErrorMessage('idTipoIdentificacion') }}</mat-error>\n }\n </mat-form-field>\n }\n </div>\n\n <div class=\"col\">\n <!-- N\u00FAmero de Identificaci\u00F3n -->\n @if (isFieldVisible('numeroIdentificacion')) {\n <mat-form-field class=\"w-100\">\n <mat-label> {{ getFieldLabel('numeroIdentificacion') }} </mat-label>\n <input\n matInput\n formControlName=\"numeroIdentificacion\"\n [placeholder]=\"getFieldPlaceholder('numeroIdentificacion')\"\n />\n @if (form.get('numeroIdentificacion')?.invalid &&\n form.get('numeroIdentificacion')?.touched) {\n <mat-error> {{ getErrorMessage('numeroIdentificacion') }}</mat-error>\n }\n <ng-container matSuffix>\n <button type=\"button\" mat-icon-button (click)=\"searchIdentificacion($event)\">\n <mat-icon>search</mat-icon>\n </button>\n </ng-container>\n </mat-form-field>\n }\n </div>\n </div>\n\n <div\n class=\"row row-cols-xxl-2 row-cols-xl-2 row-cols-lg-2 row-cols-md-2 row-cols-sm-2 row-cols-1 g-1\"\n >\n @if (isFieldVisible('nombreFiscal')){\n <div class=\"col\">\n <mat-form-field class=\"w-100\">\n <mat-label> {{ getFieldLabel('nombreFiscal') }} </mat-label>\n <input\n matInput\n autocomplete=\"off\"\n formControlName=\"nombreFiscal\"\n [placeholder]=\"getFieldPlaceholder('nombreFiscal')\"\n acpToUpperCase\n />\n @if (form.get('nombreFiscal')?.invalid && form.get('nombreFiscal')?.touched) {\n <mat-error> {{ getErrorMessage('nombreFiscal') }}</mat-error>\n }\n </mat-form-field>\n </div>\n\n } @if (isFieldVisible('nombreComercial')) {\n <div class=\"col\">\n <mat-form-field class=\"w-100\">\n <mat-label> {{ getFieldLabel('nombreComercial') }} </mat-label>\n <input\n matInput\n autocomplete=\"off\"\n formControlName=\"nombreComercial\"\n [placeholder]=\"getFieldPlaceholder('nombreComercial')\"\n acpToUpperCase\n type=\"text\"\n />\n </mat-form-field>\n </div>\n\n }\n </div>\n\n @if (isFieldVisible('direccion')) {\n\n <mat-form-field class=\"w-100\">\n <mat-label> {{ getFieldLabel('direccion') }}:</mat-label>\n <input\n matInput\n formControlName=\"direccion\"\n [placeholder]=\"getFieldPlaceholder('direccion')\"\n acpToUpperCase\n />\n @if (form.get('direccion')?.invalid && form.get('direccion')?.touched) {\n <mat-error>{{ getErrorMessage('direccion') }}</mat-error>\n }\n </mat-form-field>\n }\n\n <div\n class=\"row row-cols-xxl-2 row-cols-xl-2 row-cols-lg-2 row-cols-md-2 row-cols-sm-2 row-cols-1 g-1\"\n >\n @if (isFieldVisible('correo')) {\n <div class=\"col\">\n <acp-input-chip [chips]=\"emails\" [labelText]=\"getFieldLabel('correo')\" />\n </div>\n } @if (isFieldVisible('telefono')) {\n <div class=\"col\">\n <acp-input-chip [chips]=\"telephones\" [labelText]=\"getFieldLabel('telefono')\" />\n </div>\n }\n </div>\n </div>\n <mat-action-row>\n <acp-button\n variant=\"info\"\n matStyle=\"filled\"\n type=\"button\"\n text=\"Siguiente\"\n (handleClick)=\"nextStep()\"\n />\n </mat-action-row>\n </mat-expansion-panel>\n\n <mat-expansion-panel [expanded]=\"step() === 1\" (opened)=\"setStep(1)\" hideToggle>\n <mat-expansion-panel-header>\n <mat-panel-title> Informaci\u00F3n Comercial </mat-panel-title>\n </mat-expansion-panel-header>\n <div class=\"d-grid gap-2 mx-3\">\n <div\n class=\"row row-cols-xxl-2 row-cols-xl-2 row-cols-lg-2 row-cols-md-2 row-cols-sm-2 row-cols-1 g-1\"\n >\n <div class=\"col\">\n <mat-form-field class=\"w-100\">\n <mat-label>Forma de pago: </mat-label>\n <mat-select formControlName=\"idFormaPagoSri\">\n <mat-option [value]=\"0\">--Ninguno--</mat-option>\n\n @for (item of formasPagoSri(); track $index) {\n <mat-option [value]=\"item.idFormaPagoSri\"> {{ item.descripcion }} </mat-option>\n }\n </mat-select>\n </mat-form-field>\n </div>\n <div class=\"col\">\n <mat-form-field class=\"w-100\">\n <mat-label>Tiempo Cr\u00E9dito: </mat-label>\n <mat-select formControlName=\"idTiempoCredito\">\n @for (item of tiemposCredito(); track $index) {\n <mat-option [value]=\"item.idTiempoCredito\"> {{ item.descripcion }} </mat-option>\n }\n </mat-select>\n </mat-form-field>\n </div>\n </div>\n\n <div\n class=\"row row-cols-xxl-2 row-cols-xl-2 row-cols-lg-2 row-cols-md-2 row-cols-sm-2 row-cols-1 g-1\"\n >\n <div class=\"col\">\n <mat-form-field class=\"w-100\">\n <mat-label>Tipo Cliente: </mat-label>\n <mat-select formControlName=\"idTipoClienteProveedor\">\n <mat-option [value]=\"0\">--Ninguno--</mat-option>\n @for (item of tiposCliente(); track $index) {\n <mat-option [value]=\"item.idTipoClienteProveedor\">\n {{ item.descripcion }}\n </mat-option>\n }\n </mat-select>\n </mat-form-field>\n </div>\n <div class=\"col\">\n <mat-form-field class=\"w-100\">\n <mat-label>Empleado: </mat-label>\n <mat-select formControlName=\"idEmpleado\">\n <mat-option [value]=\"0\">--Ninguno--</mat-option>\n\n @for (item of employees(); track $index) {\n <mat-option [value]=\"item.idEmpleado\"> {{ item.nombreCompleto }} </mat-option>\n }\n </mat-select>\n </mat-form-field>\n </div>\n </div>\n\n <mat-form-field>\n <mat-label>Country</mat-label>\n <input matInput />\n </mat-form-field>\n </div>\n\n <mat-action-row>\n <acp-button\n variant=\"info\"\n matStyle=\"filled\"\n type=\"button\"\n text=\"Atr\u00E1s\"\n (handleClick)=\"prevStep()\"\n />\n <acp-button\n variant=\"info\"\n matStyle=\"filled\"\n type=\"button\"\n text=\"Siguiente\"\n (handleClick)=\"nextStep()\"\n />\n </mat-action-row>\n </mat-expansion-panel>\n\n <mat-expansion-panel [expanded]=\"step() === 2\" (opened)=\"setStep(2)\" hideToggle>\n <mat-expansion-panel-header>\n <mat-panel-title> Informaci\u00F3n de Cr\u00E9dito </mat-panel-title>\n </mat-expansion-panel-header>\n\n <section class=\"d-grid gap-2 mx-2\" formGroupName=\"dataInfoCred\">\n <div\n class=\"row row-cols-xxl-2 row-cols-xl-2 row-cols-lg-2 row-cols-md-2 row-cols-sm-1 row-cols-1 g-1\"\n >\n <div class=\"col\">\n <mat-form-field class=\"w-100\">\n <mat-label>Estado Civil: </mat-label>\n <mat-select formControlName=\"maritalStatusId\">\n <mat-option [value]=\"0\">Seleccionar...</mat-option>\n\n @for (item of maritalStatuses(); track $index) {\n <mat-option [value]=\"item.id\"> {{ item.name }} </mat-option>\n }\n </mat-select>\n </mat-form-field>\n </div>\n <div class=\"col\">\n <mat-form-field class=\"w-100\">\n <mat-label>Tipo de Vivienda: </mat-label>\n <mat-select formControlName=\"housingTypeId\">\n <mat-option [value]=\"0\">Seleccionar...</mat-option>\n\n @for (item of housingTypes(); track $index) {\n <mat-option [value]=\"item.id\"> {{ item.name }} </mat-option>\n }\n </mat-select>\n </mat-form-field>\n </div>\n </div>\n\n <div\n class=\"row row-cols-xxl-2 row-cols-xl-2 row-cols-lg-2 row-cols-md-2 row-cols-sm-1 row-cols-1 g-1\"\n >\n <div class=\"col\">\n <mat-form-field class=\"w-100\">\n <mat-label>Nombre del C\u00F3nyuge:</mat-label>\n <input matInput formControlName=\"conyugeNombre\" placeholder=\"Nombre del c\u00F3nyuge\" />\n </mat-form-field>\n </div>\n <div class=\"col\">\n <mat-form-field class=\"w-100\">\n <mat-label>Tel\u00E9fono del C\u00F3nyuge:</mat-label>\n <input matInput formControlName=\"conyugeTel\" placeholder=\"09xxxxxxxx\" />\n </mat-form-field>\n </div>\n </div>\n\n <div\n class=\"row row-cols-xxl-2 row-cols-xl-2 row-cols-lg-2 row-cols-md-2 row-cols-sm-1 row-cols-1 g-1\"\n >\n <div class=\"col\">\n <mat-form-field class=\"w-100\">\n <mat-label>Referencia Familiar:</mat-label>\n <input matInput formControlName=\"refFamTel\" placeholder=\"09xxxxxxxx\" />\n </mat-form-field>\n </div>\n <div class=\"col\">\n <mat-form-field class=\"w-100\">\n <mat-label>Tel\u00E9fono Referencia:</mat-label>\n <input matInput formControlName=\"refFamTel\" placeholder=\"09xxxxxxxx\" />\n </mat-form-field>\n </div>\n </div>\n\n <mat-form-field class=\"w-100\">\n <mat-label>Direcci\u00F3n de Vivienda</mat-label>\n <textarea\n matInput\n formControlName=\"dirVivienda\"\n placeholder=\"Direcci\u00F3n completa de la vivienda (Sector, Barrio y Calle)\"\n ></textarea>\n </mat-form-field>\n\n <div\n class=\"row row-cols-xxl-3 row-cols-xl-3 row-cols-lg-3 row-cols-md-2 row-cols-sm-1 row-cols-1 g-1\"\n >\n <div class=\"col\">\n <mat-form-field class=\"w-100\">\n <mat-label>Sector:</mat-label>\n <input matInput formControlName=\"sector\" placeholder=\"Nombre del sector\" />\n </mat-form-field>\n </div>\n <div class=\"col\">\n <mat-form-field class=\"w-100\">\n <mat-label>Barrio:</mat-label>\n <input matInput formControlName=\"barrio\" placeholder=\"Nombre del barrio\" />\n </mat-form-field>\n </div>\n <div class=\"col\">\n <mat-form-field class=\"w-100\">\n <mat-label>Calle:</mat-label>\n <input matInput formControlName=\"calle\" placeholder=\"Nombre de la calle\" />\n </mat-form-field>\n </div>\n </div>\n\n <mat-form-field class=\"w-100\">\n <mat-label>Referencia de Domicilio</mat-label>\n <textarea\n matInput\n formControlName=\"refDomicilio\"\n placeholder=\"Descripci\u00F3n detallada del punto de referencia\"\n ></textarea>\n </mat-form-field>\n </section>\n\n <mat-action-row>\n <acp-button\n variant=\"info\"\n matStyle=\"filled\"\n type=\"button\"\n text=\"Atr\u00E1s\"\n (handleClick)=\"prevStep()\"\n />\n <acp-button\n variant=\"info\"\n matStyle=\"filled\"\n type=\"button\"\n text=\"Siguiente\"\n (handleClick)=\"nextStep()\"\n />\n </mat-action-row>\n </mat-expansion-panel>\n\n <mat-expansion-panel [expanded]=\"step() === 3\" (opened)=\"setStep(3)\" hideToggle>\n <mat-expansion-panel-header>\n <mat-panel-title> Notas</mat-panel-title>\n </mat-expansion-panel-header>\n\n @if (isFieldVisible('nota')) {\n\n <mat-form-field class=\"w-100\">\n <mat-label> {{ getFieldLabel('nota') }} </mat-label>\n <textarea\n matInput\n formControlName=\"nota\"\n [placeholder]=\"getFieldPlaceholder('nota')\"\n rows=\"3\"\n ></textarea>\n </mat-form-field>\n }\n <mat-action-row>\n <acp-button\n variant=\"info\"\n matStyle=\"filled\"\n type=\"button\"\n text=\"Atr\u00E1s\"\n (handleClick)=\"prevStep()\"\n />\n </mat-action-row>\n </mat-expansion-panel>\n </mat-accordion>\n\n <!-- Buttons -->\n @if (showButtons()){\n <div class=\"form-actions\">\n <button type=\"button\" class=\"btn btn-secondary\" (click)=\"onCancel()\" [disabled]=\"isLoading()\">\n {{ config.cancelButtonText }}\n </button>\n\n <button type=\"submit\" class=\"btn btn-primary\" [disabled]=\"isLoading() || form.invalid\">\n @if (!isLoading()) {\n <span>{{ config.submitButtonText }}</span>\n } @else {\n <span>Guardando...</span>\n }\n </button>\n </div>\n\n }\n</form>\n", styles: [".alert{padding:12px 16px;border-radius:6px;margin-bottom:20px;font-size:14px}.alert.alert-error{background-color:#fef2f2;border:1px solid #fecaca;color:#991b1b}\n"], dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "directive", type: i1.FormGroupName, selector: "[formGroupName]", inputs: ["formGroupName"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i2.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i2.MatLabel, selector: "mat-label" }, { kind: "directive", type: i2.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "directive", type: i2.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i3.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "ngmodule", type: MatExpansionModule }, { kind: "directive", type: i4.MatAccordion, selector: "mat-accordion", inputs: ["hideToggle", "displayMode", "togglePosition"], exportAs: ["matAccordion"] }, { kind: "component", type: i4.MatExpansionPanel, selector: "mat-expansion-panel", inputs: ["hideToggle", "togglePosition"], outputs: ["afterExpand", "afterCollapse"], exportAs: ["matExpansionPanel"] }, { kind: "directive", type: i4.MatExpansionPanelActionRow, selector: "mat-action-row" }, { kind: "component", type: i4.MatExpansionPanelHeader, selector: "mat-expansion-panel-header", inputs: ["expandedHeight", "collapsedHeight", "tabIndex"] }, { kind: "directive", type: i4.MatExpansionPanelTitle, selector: "mat-panel-title" }, { kind: "ngmodule", type: MatSelectModule }, { kind: "component", type: i5.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth", "canSelectNullableOptions"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "component", type: i5.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "component", type: MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: Button, selector: "acp-button", inputs: ["variant", "text", "icon", "disabled", "type", "matStyle", "customClass", "reportFormat", "extended", "title", "ariaLabel", "name", "id", "form", "tabIndex", "testId"], outputs: ["handleClick"] }, { kind: "directive", type: ToUpperCase, selector: "[acpToUpperCase]" }, { kind: "component", type: InputChip, selector: "acp-input-chip", inputs: ["chips", "labelText", "placelholder"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i6.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
823
862
  }
824
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: CustomerAddEditComponent, decorators: [{
863
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: CompanyCustomerFormComponent, decorators: [{
825
864
  type: Component,
826
- args: [{ selector: 'acp-customer-add-edit', imports: [
827
- MatDialogContent,
828
- MatDialogActions,
829
- MatButtonModule,
865
+ args: [{ selector: 'acp-company-customer-form', exportAs: 'acpCustomerForm', imports: [
830
866
  ReactiveFormsModule,
831
- MatTabsModule,
832
867
  MatFormFieldModule,
833
868
  MatInputModule,
869
+ MatExpansionModule,
834
870
  MatSelectModule,
835
- MatSlideToggleModule,
836
- InputChip,
837
- ToUpperCase,
838
- MatCheckbox,
839
871
  MatIcon,
840
- MatTooltip,
841
- MatDatepickerModule,
842
872
  Button,
843
- DynamicCard,
844
- ], providers: [
845
- provideNativeDateAdapter(),
846
- {
847
- provide: CustomerUseCase,
848
- useFactory: () => new CustomerUseCase(new CustomerHttpRepository()),
849
- },
850
- {
851
- provide: CustomerExternalUseCase,
852
- useFactory: () => new CustomerExternalUseCase(new CustomerExternalHttpRepository()),
853
- },
854
- ], changeDetection: ChangeDetectionStrategy.OnPush, template: "<mat-dialog-content>\n <form\n (ngSubmit)=\"onSave()\"\n id=\"formCompanyCustomer\"\n [formGroup]=\"customerForm\"\n autocomplete=\"off\"\n >\n <mat-tab-group>\n <mat-tab label=\"DATOS PRINCIPALES\">\n <div class=\"d-grid gap-2 mx-3 mt-2\">\n <div\n class=\"row row-cols-xxl-2 row-cols-xl-2 row-cols-lg-2 row-cols-md-2 row-cols-sm-2 row-cols-1 g-1\"\n >\n <div class=\"col\">\n <mat-form-field class=\"w-100\">\n <mat-label>Tipo Identificaci\u00F3n: </mat-label>\n <mat-select\n formControlName=\"idTipoIdentificacion\"\n (selectionChange)=\"identificationTypeChange($event)\"\n >\n @for (item of tiposIdentificacion(); track $index) {\n <mat-option [value]=\"item.idTipoIdentificacion\"\n >{{ item.descripcion }}</mat-option\n >\n }\n </mat-select>\n </mat-form-field>\n </div>\n <div class=\"col\">\n <mat-form-field class=\"w-100\">\n <mat-label>N\u00FAmero de Identificaci\u00F3n</mat-label>\n <input\n type=\"text\"\n matInput\n (keydown.enter)=\"onKeyDownGovernmentId($event)\"\n formControlName=\"numeroIdentificacion\"\n />\n @if ( numeroIdentificacionControl?.invalid && (numeroIdentificacionControl?.dirty ||\n numeroIdentificacionControl?.touched) ) { @if\n (numeroIdentificacionControl?.hasError('required')) {\n <mat-error> El n\u00FAmero de identificaci\u00F3n es obligatorio. </mat-error>\n } @if (numeroIdentificacionControl?.hasError('minlength')) {\n <mat-error>\n Debe tener al menos {{\n numeroIdentificacionControl?.errors?.['minlength'].requiredLength }} d\u00EDgitos.\n </mat-error>\n } @if (numeroIdentificacionControl?.hasError('maxlength')) {\n <mat-error>\n No puede tener m\u00E1s de {{\n numeroIdentificacionControl?.errors?.['maxlength'].requiredLength }} d\u00EDgitos.\n </mat-error>\n } @if (numeroIdentificacionControl?.hasError('pattern')) {\n <mat-error> Solo se permiten caracteres num\u00E9ricos. </mat-error>\n } @if (numeroIdentificacionControl?.hasError('endsWith001')) {\n <mat-error> Los \u00FAltimos tres d\u00EDgitos deben ser 001. </mat-error>\n } } @if (showRefresh()) {\n <ng-container matSuffix>\n <acp-button\n type=\"button\"\n matStyle=\"icon\"\n icon=\"refresh\"\n (handleClick)=\"onKeyDownGovernmentId($event)\"\n />\n </ng-container>\n }\n </mat-form-field>\n </div>\n </div>\n\n <div\n class=\"row row-cols-xxl-2 row-cols-xl-2 row-cols-lg-2 row-cols-md-2 row-cols-sm-2 row-cols-1 g-1\"\n >\n <div class=\"col\">\n <mat-form-field class=\"w-100\">\n <mat-label>Nombre Fiscal:</mat-label>\n <input\n matInput\n autocomplete=\"off\"\n formControlName=\"nombreFiscal\"\n id=\"nombreComercial\"\n placeholder=\"Ej: TECNOMEGA\"\n acpToUpperCase\n />\n </mat-form-field>\n </div>\n <div class=\"col\">\n <mat-form-field class=\"w-100\">\n <mat-label>Nombre Comercial:</mat-label>\n <input\n matInput\n autocomplete=\"off\"\n formControlName=\"nombreComercial\"\n placeholder=\"Ej: TECNOMEGA\"\n acpToUpperCase\n type=\"text\"\n />\n </mat-form-field>\n </div>\n </div>\n\n <div>\n <mat-form-field class=\"w-100\">\n <mat-label>Direcci\u00F3n:</mat-label>\n <input\n matInput\n formControlName=\"direccion\"\n placeholder=\"AV. 09 DE OCTUBRE...\"\n acpToUpperCase\n />\n </mat-form-field>\n </div>\n\n <div\n class=\"row row-cols-xxl-2 row-cols-xl-2 row-cols-lg-2 row-cols-md-2 row-cols-sm-2 row-cols-1 g-1\"\n >\n <div class=\"col\">\n <acp-input-chip [chips]=\"emails\" [labelText]=\"'Correo'\" />\n </div>\n <div class=\"col\">\n <acp-input-chip [chips]=\"telephones\" [labelText]=\"'Tel\u00E9fono'\" />\n </div>\n </div>\n\n @if (isUpdate()) {\n <div class=\"vstack gap-2 mt-2\">\n <span>Estado</span>\n <mat-slide-toggle formControlName=\"estado\">\n {{ customerForm.value.estado ? 'Activo' : 'Inactivo' }}\n </mat-slide-toggle>\n </div>\n }\n </div>\n </mat-tab>\n <mat-tab label=\"DATOS ADICIONALES\">\n <div class=\"d-grid gap-2 mx-3 mt-2\">\n <div\n class=\"row row-cols-xxl-2 row-cols-xl-2 row-cols-lg-2 row-cols-md-2 row-cols-sm-2 row-cols-1 g-1\"\n >\n <div class=\"col\">\n <acp-dynamic-card title=\"Informaci\u00F3n B\u00E1sica\" [isHeaderVisible]=\"true\">\n <div\n class=\"row row-cols-xxl-2 row-cols-xl-2 row-cols-lg-2 row-cols-md-2 row-cols-sm-2 row-cols-1 g-2\"\n >\n <div class=\"col\">\n <mat-form-field class=\"w-100\">\n <mat-label>Tipo Contribuyente: </mat-label>\n <mat-select formControlName=\"idSubContribuyente\">\n @for (item of tipoContribuyentes(); track $index) {\n <mat-option [value]=\"item.idSubContribuyente\">\n {{ item.descripcion }}\n </mat-option>\n }\n </mat-select>\n </mat-form-field>\n </div>\n\n <div class=\"col\">\n <mat-form-field class=\"w-100\">\n <mat-label>Tiempo Cr\u00E9dito: </mat-label>\n <mat-select formControlName=\"idTiempoCredito\">\n @for (item of tiemposCredito(); track $index) {\n <mat-option [value]=\"item.idTiempoCredito\">\n {{ item.descripcion }}\n </mat-option>\n }\n </mat-select>\n </mat-form-field>\n </div>\n\n <div class=\"col\">\n <mat-form-field class=\"w-100\">\n <mat-label>Ciudad</mat-label>\n <mat-select formControlName=\"idCiudad\">\n <mat-option [value]=\"0\">-- Ninguno --</mat-option>\n @for (group of ciudades(); track $index) {\n <mat-optgroup [label]=\"group.nombre\">\n @for (item of group.ciudades; track $index) {\n <mat-option [value]=\"item.idCiudad\">{{ item.nombre }}</mat-option>\n }\n </mat-optgroup>\n }\n </mat-select>\n </mat-form-field>\n </div>\n <div class=\"col\">\n <mat-form-field class=\"w-100\">\n <mat-label>Tipo Cliente: </mat-label>\n <mat-select formControlName=\"idTipoClienteProveedor\">\n <mat-option [value]=\"0\">--Ninguno--</mat-option>\n @for (item of tiposCliente(); track $index) {\n <mat-option [value]=\"item.idTipoClienteProveedor\">\n {{ item.descripcion }}\n </mat-option>\n }\n </mat-select>\n </mat-form-field>\n </div>\n\n <div class=\"col\">\n <mat-form-field class=\"w-100\">\n <mat-label>Empresa: </mat-label>\n <mat-select formControlName=\"idEmpresa\">\n <mat-option [value]=\"0\">--Ninguno--</mat-option>\n\n @for (item of empresas(); track $index) {\n <mat-option [value]=\"item.idEmpresa\"> {{ item.descripcion }} </mat-option>\n }\n </mat-select>\n </mat-form-field>\n </div>\n <div class=\"col\">\n <mat-form-field class=\"w-100\">\n <mat-label>Fecha Nacimiento</mat-label>\n <input matInput [matDatepicker]=\"birthDate\" formControlName=\"birthDate\" />\n <mat-hint>MM/DD/YYYY</mat-hint>\n <mat-datepicker-toggle matIconSuffix [for]=\"birthDate\" />\n <mat-datepicker #birthDate />\n @if (birthDateCtrl?.invalid && birthDateCtrl?.touched) {\n <mat-error> Fecha inv\u00E1lida </mat-error>\n }\n </mat-form-field>\n </div>\n </div>\n </acp-dynamic-card>\n </div>\n <div class=\"col\">\n <acp-dynamic-card title=\"Informaci\u00F3n Laboral\" [isHeaderVisible]=\"true\">\n <div\n class=\"row row-cols-xxl-2 row-cols-xl-2 row-cols-lg-2 row-cols-md-2 row-cols-sm-2 row-cols-1 g-1\"\n >\n <div class=\"col\">\n <mat-form-field class=\"w-100\">\n <mat-label>Empleado: </mat-label>\n <mat-select formControlName=\"idEmpleado\">\n <mat-option [value]=\"0\">--Ninguno--</mat-option>\n\n @for (item of employees(); track $index) {\n <mat-option [value]=\"item.idEmpleado\">\n {{ item.nombreCompleto }}\n </mat-option>\n }\n </mat-select>\n </mat-form-field>\n </div>\n\n <div class=\"col\">\n <mat-form-field class=\"w-100\">\n <mat-label>Cargo: </mat-label>\n <mat-select formControlName=\"idCargo\">\n <mat-option [value]=\"0\">--Ninguno--</mat-option>\n\n @for (item of cargos(); track $index) {\n <mat-option [value]=\"item.idCargo\"> {{ item.descripcion }} </mat-option>\n }\n </mat-select>\n </mat-form-field>\n </div>\n\n <div class=\"col w-100\">\n <mat-form-field class=\"w-100\">\n <mat-label>Observaci\u00F3n</mat-label>\n <textarea matInput placeholder=\"...\" formControlName=\"nota\"></textarea>\n </mat-form-field>\n </div>\n </div>\n </acp-dynamic-card>\n </div>\n </div>\n <div\n class=\"row row-cols-xxl-2 row-cols-xl-2 row-cols-lg-2 row-cols-md-2 row-cols-sm-2 row-cols-1 g-1\"\n >\n <div class=\"col\">\n <acp-dynamic-card title=\"Configuraci\u00F3n Financiera\" [isHeaderVisible]=\"true\">\n <div\n class=\"row row-cols-xxl-1 row-cols-xl-1 row-cols-lg-1 row-cols-md-1 row-cols-sm-1 row-cols-1 g-2 mt-2\"\n >\n <div class=\"col\">\n <mat-form-field class=\"w-100\">\n <mat-label>Forma de pago: </mat-label>\n <mat-select formControlName=\"idFormaPagoSri\">\n <mat-option [value]=\"0\">--Ninguno--</mat-option>\n\n @for (item of formasPagoSri(); track $index) {\n <mat-option [value]=\"item.idFormaPagoSri\">\n {{ item.descripcion }}\n </mat-option>\n }\n </mat-select>\n </mat-form-field>\n </div>\n\n <div class=\"col\">\n <acp-input-chip labelText=\"Placa\" [chips]=\"placas()\" />\n </div>\n\n <div class=\"col w-100\">\n <mat-checkbox formControlName=\"configValorBruto\"\n >Activar configuraci\u00F3n de valor bruto\n <mat-icon\n matTooltip=\"valor total de un bien o servicio sin incluir impuestos, deducciones o descuentos (uso dentro del reporte)\"\n >info</mat-icon\n ></mat-checkbox\n >\n </div>\n </div>\n </acp-dynamic-card>\n </div>\n <div class=\"col\"></div>\n </div>\n </div>\n </mat-tab>\n <mat-tab label=\"INFORMACI\u00D3N CREDITICIA\">\n <div class=\"d-grid gap-2 mx-3 mt-2\">\n <div\n class=\"row row-cols-xxl-2 row-cols-xl-2 row-cols-lg-2 row-cols-md-2 row-cols-sm-2 row-cols-1 g-1\"\n >\n <div class=\"col\">\n <acp-dynamic-card title=\"Informaci\u00F3n Personal\" [isHeaderVisible]=\"true\">\n <div\n formGroupName=\"dataInfoCred\"\n class=\"row row-cols-xxl-2 row-cols-xl-2 row-cols-lg-2 row-cols-md-2 row-cols-sm-1 row-cols-1 g-2 mt-2\"\n >\n <div class=\"col\">\n <mat-form-field class=\"w-100\">\n <mat-label>Estado Civil: </mat-label>\n <mat-select formControlName=\"maritalStatusId\">\n <mat-option [value]=\"0\">Seleccionar...</mat-option>\n\n @for (item of maritalStatuses(); track $index) {\n <mat-option [value]=\"item.id\"> {{ item.name }} </mat-option>\n }\n </mat-select>\n </mat-form-field>\n </div>\n <div class=\"col\">\n <mat-form-field class=\"w-100\">\n <mat-label>Esposo(a):</mat-label>\n <input\n matInput\n formControlName=\"conyugeNombre\"\n placeholder=\"Nombre del c\u00F3nyuge\"\n />\n </mat-form-field>\n </div>\n\n <div class=\"col\">\n <mat-form-field class=\"w-100\">\n <mat-label>Tel\u00E9fono Personal:</mat-label>\n <input matInput formControlName=\"conyugeTel\" placeholder=\"09xxxxxxxx\" />\n </mat-form-field>\n </div>\n <div class=\"col\">\n <mat-form-field class=\"w-100\">\n <mat-label>Tel\u00E9fono Referencia:</mat-label>\n <input matInput formControlName=\"refFamTel\" placeholder=\"09xxxxxxxx\" />\n </mat-form-field>\n </div>\n <div class=\"col w-100\">\n <mat-form-field class=\"w-100\">\n <mat-label>Referencia Familiar:</mat-label>\n <input\n matInput\n formControlName=\"refFamNombre\"\n placeholder=\"Nombre de referencia familiar\"\n />\n </mat-form-field>\n </div>\n </div>\n </acp-dynamic-card>\n </div>\n <div class=\"col\">\n <acp-dynamic-card title=\"Informaci\u00F3n de Vivienda\" [isHeaderVisible]=\"true\">\n <div\n formGroupName=\"dataInfoCred\"\n class=\"row row-cols-xxl-2 row-cols-xl-2 row-cols-lg-2 row-cols-md-2 row-cols-sm-1 row-cols-1 g-2 mt-2\"\n >\n <div class=\"col\">\n <mat-form-field class=\"w-100\">\n <mat-label>Tipo de Vivienda: </mat-label>\n <mat-select formControlName=\"housingTypeId\">\n <mat-option [value]=\"0\">Seleccionar...</mat-option>\n\n @for (item of housingTypes(); track $index) {\n <mat-option [value]=\"item.id\"> {{ item.name }} </mat-option>\n }\n </mat-select>\n </mat-form-field>\n </div>\n <div class=\"col\">\n <mat-form-field class=\"w-100\">\n <mat-label>Sector:</mat-label>\n <input matInput formControlName=\"sector\" placeholder=\"Nombre del sector\" />\n </mat-form-field>\n </div>\n\n <div class=\"col\">\n <mat-form-field class=\"w-100\">\n <mat-label>Barrio:</mat-label>\n <input matInput formControlName=\"barrio\" placeholder=\"Nombre del barrio\" />\n </mat-form-field>\n </div>\n <div class=\"col\">\n <mat-form-field class=\"w-100\">\n <mat-label>Calle:</mat-label>\n <input matInput formControlName=\"calle\" placeholder=\"Nombre de la calle\" />\n </mat-form-field>\n </div>\n <div class=\"col w-100\">\n <mat-form-field class=\"w-100\">\n <mat-label>Direcci\u00F3n Completa</mat-label>\n <textarea\n matInput\n formControlName=\"dirVivienda\"\n placeholder=\"Direcci\u00F3n completa de la vivienda (Sector, Barrio y Calle)\"\n ></textarea>\n </mat-form-field>\n </div>\n <div class=\"col w-100\">\n <mat-form-field class=\"w-100\">\n <mat-label>Descripci\u00F3n del Punto de Referencia:</mat-label>\n <textarea\n matInput\n formControlName=\"refDomicilio\"\n placeholder=\"Descripci\u00F3n detallada del punto de referencia\"\n ></textarea>\n </mat-form-field>\n </div>\n </div>\n </acp-dynamic-card>\n </div>\n </div>\n </div>\n </mat-tab>\n </mat-tab-group>\n </form>\n</mat-dialog-content>\n<mat-dialog-actions>\n <div class=\"hstack gap-2\">\n <acp-button type=\"submit\" form=\"formCompanyCustomer\" [text]=\"btnText()\" />\n <acp-button type=\"button\" variant=\"dark\" text=\"Cerrar\" (handleClick)=\"close()\" />\n </div>\n</mat-dialog-actions>\n" }]
855
- }] });
873
+ ToUpperCase,
874
+ InputChip,
875
+ MatButtonModule,
876
+ ], encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, template: "<form [formGroup]=\"form\" (ngSubmit)=\"onSubmit()\" [id]=\"formId()\" class=\"mb-2\">\n @if (errorMessage) {\n <div class=\"alert alert-error\">{{ errorMessage }}</div>\n }\n <mat-accordion class=\"mb-2\">\n <mat-expansion-panel [expanded]=\"step() === 0\" (opened)=\"setStep(0)\" hideToggle>\n <mat-expansion-panel-header>\n <mat-panel-title>\n <mat-icon>account_circle</mat-icon>\n Datos Principales\n </mat-panel-title>\n </mat-expansion-panel-header>\n\n <div class=\"d-grid gap-2 mx-3 mt-2\">\n <div\n class=\"row row-cols-xxl-2 row-cols-xl-2 row-cols-lg-2 row-cols-md-2 row-cols-sm-2 row-cols-1 g-1\"\n >\n <div class=\"col\">\n @if (isFieldVisible('idTipoIdentificacion')) {\n <mat-form-field class=\"w-100\">\n <mat-label> {{ getFieldLabel('idTipoIdentificacion') }} </mat-label>\n <mat-select\n formControlName=\"idTipoIdentificacion\"\n (selectionChange)=\"identificationTypeChange($event)\"\n >\n @for (item of tiposIdentificacion(); track $index) {\n <mat-option [value]=\"item.idTipoIdentificacion\">{{ item.descripcion }}</mat-option>\n }\n </mat-select>\n @if (form.get('idTipoIdentificacion')?.invalid &&\n form.get('idTipoIdentificacion')?.touched) {\n <mat-error> {{ getErrorMessage('idTipoIdentificacion') }}</mat-error>\n }\n </mat-form-field>\n }\n </div>\n\n <div class=\"col\">\n <!-- N\u00FAmero de Identificaci\u00F3n -->\n @if (isFieldVisible('numeroIdentificacion')) {\n <mat-form-field class=\"w-100\">\n <mat-label> {{ getFieldLabel('numeroIdentificacion') }} </mat-label>\n <input\n matInput\n formControlName=\"numeroIdentificacion\"\n [placeholder]=\"getFieldPlaceholder('numeroIdentificacion')\"\n />\n @if (form.get('numeroIdentificacion')?.invalid &&\n form.get('numeroIdentificacion')?.touched) {\n <mat-error> {{ getErrorMessage('numeroIdentificacion') }}</mat-error>\n }\n <ng-container matSuffix>\n <button type=\"button\" mat-icon-button (click)=\"searchIdentificacion($event)\">\n <mat-icon>search</mat-icon>\n </button>\n </ng-container>\n </mat-form-field>\n }\n </div>\n </div>\n\n <div\n class=\"row row-cols-xxl-2 row-cols-xl-2 row-cols-lg-2 row-cols-md-2 row-cols-sm-2 row-cols-1 g-1\"\n >\n @if (isFieldVisible('nombreFiscal')){\n <div class=\"col\">\n <mat-form-field class=\"w-100\">\n <mat-label> {{ getFieldLabel('nombreFiscal') }} </mat-label>\n <input\n matInput\n autocomplete=\"off\"\n formControlName=\"nombreFiscal\"\n [placeholder]=\"getFieldPlaceholder('nombreFiscal')\"\n acpToUpperCase\n />\n @if (form.get('nombreFiscal')?.invalid && form.get('nombreFiscal')?.touched) {\n <mat-error> {{ getErrorMessage('nombreFiscal') }}</mat-error>\n }\n </mat-form-field>\n </div>\n\n } @if (isFieldVisible('nombreComercial')) {\n <div class=\"col\">\n <mat-form-field class=\"w-100\">\n <mat-label> {{ getFieldLabel('nombreComercial') }} </mat-label>\n <input\n matInput\n autocomplete=\"off\"\n formControlName=\"nombreComercial\"\n [placeholder]=\"getFieldPlaceholder('nombreComercial')\"\n acpToUpperCase\n type=\"text\"\n />\n </mat-form-field>\n </div>\n\n }\n </div>\n\n @if (isFieldVisible('direccion')) {\n\n <mat-form-field class=\"w-100\">\n <mat-label> {{ getFieldLabel('direccion') }}:</mat-label>\n <input\n matInput\n formControlName=\"direccion\"\n [placeholder]=\"getFieldPlaceholder('direccion')\"\n acpToUpperCase\n />\n @if (form.get('direccion')?.invalid && form.get('direccion')?.touched) {\n <mat-error>{{ getErrorMessage('direccion') }}</mat-error>\n }\n </mat-form-field>\n }\n\n <div\n class=\"row row-cols-xxl-2 row-cols-xl-2 row-cols-lg-2 row-cols-md-2 row-cols-sm-2 row-cols-1 g-1\"\n >\n @if (isFieldVisible('correo')) {\n <div class=\"col\">\n <acp-input-chip [chips]=\"emails\" [labelText]=\"getFieldLabel('correo')\" />\n </div>\n } @if (isFieldVisible('telefono')) {\n <div class=\"col\">\n <acp-input-chip [chips]=\"telephones\" [labelText]=\"getFieldLabel('telefono')\" />\n </div>\n }\n </div>\n </div>\n <mat-action-row>\n <acp-button\n variant=\"info\"\n matStyle=\"filled\"\n type=\"button\"\n text=\"Siguiente\"\n (handleClick)=\"nextStep()\"\n />\n </mat-action-row>\n </mat-expansion-panel>\n\n <mat-expansion-panel [expanded]=\"step() === 1\" (opened)=\"setStep(1)\" hideToggle>\n <mat-expansion-panel-header>\n <mat-panel-title> Informaci\u00F3n Comercial </mat-panel-title>\n </mat-expansion-panel-header>\n <div class=\"d-grid gap-2 mx-3\">\n <div\n class=\"row row-cols-xxl-2 row-cols-xl-2 row-cols-lg-2 row-cols-md-2 row-cols-sm-2 row-cols-1 g-1\"\n >\n <div class=\"col\">\n <mat-form-field class=\"w-100\">\n <mat-label>Forma de pago: </mat-label>\n <mat-select formControlName=\"idFormaPagoSri\">\n <mat-option [value]=\"0\">--Ninguno--</mat-option>\n\n @for (item of formasPagoSri(); track $index) {\n <mat-option [value]=\"item.idFormaPagoSri\"> {{ item.descripcion }} </mat-option>\n }\n </mat-select>\n </mat-form-field>\n </div>\n <div class=\"col\">\n <mat-form-field class=\"w-100\">\n <mat-label>Tiempo Cr\u00E9dito: </mat-label>\n <mat-select formControlName=\"idTiempoCredito\">\n @for (item of tiemposCredito(); track $index) {\n <mat-option [value]=\"item.idTiempoCredito\"> {{ item.descripcion }} </mat-option>\n }\n </mat-select>\n </mat-form-field>\n </div>\n </div>\n\n <div\n class=\"row row-cols-xxl-2 row-cols-xl-2 row-cols-lg-2 row-cols-md-2 row-cols-sm-2 row-cols-1 g-1\"\n >\n <div class=\"col\">\n <mat-form-field class=\"w-100\">\n <mat-label>Tipo Cliente: </mat-label>\n <mat-select formControlName=\"idTipoClienteProveedor\">\n <mat-option [value]=\"0\">--Ninguno--</mat-option>\n @for (item of tiposCliente(); track $index) {\n <mat-option [value]=\"item.idTipoClienteProveedor\">\n {{ item.descripcion }}\n </mat-option>\n }\n </mat-select>\n </mat-form-field>\n </div>\n <div class=\"col\">\n <mat-form-field class=\"w-100\">\n <mat-label>Empleado: </mat-label>\n <mat-select formControlName=\"idEmpleado\">\n <mat-option [value]=\"0\">--Ninguno--</mat-option>\n\n @for (item of employees(); track $index) {\n <mat-option [value]=\"item.idEmpleado\"> {{ item.nombreCompleto }} </mat-option>\n }\n </mat-select>\n </mat-form-field>\n </div>\n </div>\n\n <mat-form-field>\n <mat-label>Country</mat-label>\n <input matInput />\n </mat-form-field>\n </div>\n\n <mat-action-row>\n <acp-button\n variant=\"info\"\n matStyle=\"filled\"\n type=\"button\"\n text=\"Atr\u00E1s\"\n (handleClick)=\"prevStep()\"\n />\n <acp-button\n variant=\"info\"\n matStyle=\"filled\"\n type=\"button\"\n text=\"Siguiente\"\n (handleClick)=\"nextStep()\"\n />\n </mat-action-row>\n </mat-expansion-panel>\n\n <mat-expansion-panel [expanded]=\"step() === 2\" (opened)=\"setStep(2)\" hideToggle>\n <mat-expansion-panel-header>\n <mat-panel-title> Informaci\u00F3n de Cr\u00E9dito </mat-panel-title>\n </mat-expansion-panel-header>\n\n <section class=\"d-grid gap-2 mx-2\" formGroupName=\"dataInfoCred\">\n <div\n class=\"row row-cols-xxl-2 row-cols-xl-2 row-cols-lg-2 row-cols-md-2 row-cols-sm-1 row-cols-1 g-1\"\n >\n <div class=\"col\">\n <mat-form-field class=\"w-100\">\n <mat-label>Estado Civil: </mat-label>\n <mat-select formControlName=\"maritalStatusId\">\n <mat-option [value]=\"0\">Seleccionar...</mat-option>\n\n @for (item of maritalStatuses(); track $index) {\n <mat-option [value]=\"item.id\"> {{ item.name }} </mat-option>\n }\n </mat-select>\n </mat-form-field>\n </div>\n <div class=\"col\">\n <mat-form-field class=\"w-100\">\n <mat-label>Tipo de Vivienda: </mat-label>\n <mat-select formControlName=\"housingTypeId\">\n <mat-option [value]=\"0\">Seleccionar...</mat-option>\n\n @for (item of housingTypes(); track $index) {\n <mat-option [value]=\"item.id\"> {{ item.name }} </mat-option>\n }\n </mat-select>\n </mat-form-field>\n </div>\n </div>\n\n <div\n class=\"row row-cols-xxl-2 row-cols-xl-2 row-cols-lg-2 row-cols-md-2 row-cols-sm-1 row-cols-1 g-1\"\n >\n <div class=\"col\">\n <mat-form-field class=\"w-100\">\n <mat-label>Nombre del C\u00F3nyuge:</mat-label>\n <input matInput formControlName=\"conyugeNombre\" placeholder=\"Nombre del c\u00F3nyuge\" />\n </mat-form-field>\n </div>\n <div class=\"col\">\n <mat-form-field class=\"w-100\">\n <mat-label>Tel\u00E9fono del C\u00F3nyuge:</mat-label>\n <input matInput formControlName=\"conyugeTel\" placeholder=\"09xxxxxxxx\" />\n </mat-form-field>\n </div>\n </div>\n\n <div\n class=\"row row-cols-xxl-2 row-cols-xl-2 row-cols-lg-2 row-cols-md-2 row-cols-sm-1 row-cols-1 g-1\"\n >\n <div class=\"col\">\n <mat-form-field class=\"w-100\">\n <mat-label>Referencia Familiar:</mat-label>\n <input matInput formControlName=\"refFamTel\" placeholder=\"09xxxxxxxx\" />\n </mat-form-field>\n </div>\n <div class=\"col\">\n <mat-form-field class=\"w-100\">\n <mat-label>Tel\u00E9fono Referencia:</mat-label>\n <input matInput formControlName=\"refFamTel\" placeholder=\"09xxxxxxxx\" />\n </mat-form-field>\n </div>\n </div>\n\n <mat-form-field class=\"w-100\">\n <mat-label>Direcci\u00F3n de Vivienda</mat-label>\n <textarea\n matInput\n formControlName=\"dirVivienda\"\n placeholder=\"Direcci\u00F3n completa de la vivienda (Sector, Barrio y Calle)\"\n ></textarea>\n </mat-form-field>\n\n <div\n class=\"row row-cols-xxl-3 row-cols-xl-3 row-cols-lg-3 row-cols-md-2 row-cols-sm-1 row-cols-1 g-1\"\n >\n <div class=\"col\">\n <mat-form-field class=\"w-100\">\n <mat-label>Sector:</mat-label>\n <input matInput formControlName=\"sector\" placeholder=\"Nombre del sector\" />\n </mat-form-field>\n </div>\n <div class=\"col\">\n <mat-form-field class=\"w-100\">\n <mat-label>Barrio:</mat-label>\n <input matInput formControlName=\"barrio\" placeholder=\"Nombre del barrio\" />\n </mat-form-field>\n </div>\n <div class=\"col\">\n <mat-form-field class=\"w-100\">\n <mat-label>Calle:</mat-label>\n <input matInput formControlName=\"calle\" placeholder=\"Nombre de la calle\" />\n </mat-form-field>\n </div>\n </div>\n\n <mat-form-field class=\"w-100\">\n <mat-label>Referencia de Domicilio</mat-label>\n <textarea\n matInput\n formControlName=\"refDomicilio\"\n placeholder=\"Descripci\u00F3n detallada del punto de referencia\"\n ></textarea>\n </mat-form-field>\n </section>\n\n <mat-action-row>\n <acp-button\n variant=\"info\"\n matStyle=\"filled\"\n type=\"button\"\n text=\"Atr\u00E1s\"\n (handleClick)=\"prevStep()\"\n />\n <acp-button\n variant=\"info\"\n matStyle=\"filled\"\n type=\"button\"\n text=\"Siguiente\"\n (handleClick)=\"nextStep()\"\n />\n </mat-action-row>\n </mat-expansion-panel>\n\n <mat-expansion-panel [expanded]=\"step() === 3\" (opened)=\"setStep(3)\" hideToggle>\n <mat-expansion-panel-header>\n <mat-panel-title> Notas</mat-panel-title>\n </mat-expansion-panel-header>\n\n @if (isFieldVisible('nota')) {\n\n <mat-form-field class=\"w-100\">\n <mat-label> {{ getFieldLabel('nota') }} </mat-label>\n <textarea\n matInput\n formControlName=\"nota\"\n [placeholder]=\"getFieldPlaceholder('nota')\"\n rows=\"3\"\n ></textarea>\n </mat-form-field>\n }\n <mat-action-row>\n <acp-button\n variant=\"info\"\n matStyle=\"filled\"\n type=\"button\"\n text=\"Atr\u00E1s\"\n (handleClick)=\"prevStep()\"\n />\n </mat-action-row>\n </mat-expansion-panel>\n </mat-accordion>\n\n <!-- Buttons -->\n @if (showButtons()){\n <div class=\"form-actions\">\n <button type=\"button\" class=\"btn btn-secondary\" (click)=\"onCancel()\" [disabled]=\"isLoading()\">\n {{ config.cancelButtonText }}\n </button>\n\n <button type=\"submit\" class=\"btn btn-primary\" [disabled]=\"isLoading() || form.invalid\">\n @if (!isLoading()) {\n <span>{{ config.submitButtonText }}</span>\n } @else {\n <span>Guardando...</span>\n }\n </button>\n </div>\n\n }\n</form>\n", styles: [".alert{padding:12px 16px;border-radius:6px;margin-bottom:20px;font-size:14px}.alert.alert-error{background-color:#fef2f2;border:1px solid #fecaca;color:#991b1b}\n"] }]
877
+ }], propDecorators: { formId: [{ type: i0.Input, args: [{ isSignal: true, alias: "formId", required: false }] }], customer: [{
878
+ type: Input
879
+ }], mode: [{
880
+ type: Input
881
+ }], showButtons: [{ type: i0.Input, args: [{ isSignal: true, alias: "showButtons", required: false }] }], submitted: [{ type: i0.Output, args: ["submitted"] }], cancelled: [{ type: i0.Output, args: ["cancelled"] }] } });
856
882
 
857
- class CustomerCard {
858
- customer = input.required(...(ngDevMode ? [{ debugName: "customer" }] : []));
859
- editCustomer = output();
860
- deleteCustomer = output();
861
- getLogoSliceBusinessName = computed(() => {
862
- const name = this.customer()?.businessName || '';
863
- return name.slice(0, 1);
864
- }, ...(ngDevMode ? [{ debugName: "getLogoSliceBusinessName" }] : []));
865
- onEditClick() {
866
- // Emits the customer object to the parent component
867
- this.editCustomer.emit(this.customer());
868
- }
869
- onDeleteClick() {
870
- // Emits the customer object to the parent component
871
- this.deleteCustomer.emit(this.customer());
872
- }
873
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: CustomerCard, deps: [], target: i0.ɵɵFactoryTarget.Component });
874
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.9", type: CustomerCard, isStandalone: true, selector: "acp-customer-card", inputs: { customer: { classPropertyName: "customer", publicName: "customer", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { editCustomer: "editCustomer", deleteCustomer: "deleteCustomer" }, ngImport: i0, template: "<div class=\"acp-customer-card\">\n <mat-card class=\"acp-customer-card-content\">\n <!-- Header -->\n <div class=\"acp-card-header\">\n <div class=\"acp-avatar\" aria-label=\"Logo de cliente\">{{ getLogoSliceBusinessName() }}</div>\n <h5 class=\"acp-business-name\">{{ customer().businessName }}</h5>\n <p class=\"acp-trade-name\">{{ customer().tradeName }}</p>\n </div>\n\n <!-- Card content -->\n <mat-card-content>\n <div class=\"acp-info\">\n <p><strong>ID:</strong> 1234567890 (RUC)</p>\n <p><strong>Email:</strong> {{ customer().email }}</p>\n <p><strong>Tel\u00E9fono:</strong> {{ customer().phone }}</p>\n <p><strong>Direcci\u00F3n:</strong>{{ customer().address }}</p>\n\n <div class=\"acp-chips\">\n <mat-chip-set>\n <mat-chip color=\"primary\">{{ customer().statusName }}</mat-chip>\n </mat-chip-set>\n </div>\n </div>\n </mat-card-content>\n\n <!-- Card actions -->\n @if (!customer().isFinalConsumer) {\n <mat-card-actions class=\"acp-actions gap-2\">\n <acp-button matStyle=\"icon\" icon=\"edit\" (handleClick)=\"onEditClick()\" />\n <acp-button matStyle=\"icon\" icon=\"delete\" variant=\"danger\" (handleClick)=\"onDeleteClick()\" />\n </mat-card-actions>\n }\n </mat-card>\n</div>\n", styles: [".acp-customer-card{display:block}.acp-customer-card .acp-customer-card-content{width:345px;border-radius:16px}.acp-customer-card .acp-card-header{display:flex;flex-direction:column;align-items:center;padding:16px;background-color:var(--mat-sys-primary-container, #e3f2fd);border-top-left-radius:16px;border-top-right-radius:16px}.acp-customer-card .acp-card-header .acp-business-name{text-align:center;font-size:14px;font-weight:500}.acp-customer-card .acp-card-header .acp-trade-name{text-align:center;font-size:12px;color:var(--mat-sys-on-surface-variant, #6c757d)}.acp-customer-card .acp-avatar{width:80px;height:80px;border-radius:50%;background-color:var(--mat-sys-primary, #1976d2);display:flex;justify-content:center;align-items:center;font-size:32px;color:var(--mat-sys-on-primary, white);margin-bottom:12px}.acp-customer-card .acp-info p{margin:4px 0}.acp-customer-card .acp-chips{margin-top:12px;display:flex;gap:8px}.acp-customer-card .acp-actions{justify-content:flex-end;padding:16px}\n"], dependencies: [{ kind: "ngmodule", type: MatCardModule }, { kind: "component", type: i1$1.MatCard, selector: "mat-card", inputs: ["appearance"], exportAs: ["matCard"] }, { kind: "directive", type: i1$1.MatCardActions, selector: "mat-card-actions", inputs: ["align"], exportAs: ["matCardActions"] }, { kind: "directive", type: i1$1.MatCardContent, selector: "mat-card-content" }, { kind: "ngmodule", type: MatDividerModule }, { kind: "ngmodule", type: MatChipsModule }, { kind: "component", type: i2$1.MatChip, selector: "mat-basic-chip, [mat-basic-chip], mat-chip, [mat-chip]", inputs: ["role", "id", "aria-label", "aria-description", "value", "color", "removable", "highlighted", "disableRipple", "disabled"], outputs: ["removed", "destroyed"], exportAs: ["matChip"] }, { kind: "component", type: i2$1.MatChipSet, selector: "mat-chip-set", inputs: ["disabled", "role", "tabIndex"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: Button, selector: "acp-button", inputs: ["variant", "text", "icon", "disabled", "type", "matStyle", "customClass", "reportFormat", "extended", "title", "ariaLabel", "name", "id", "form", "tabIndex", "testId"], outputs: ["handleClick"] }] });
875
- }
876
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: CustomerCard, decorators: [{
877
- type: Component,
878
- args: [{ selector: 'acp-customer-card', imports: [MatCardModule, MatDividerModule, MatChipsModule, MatButtonModule, Button], template: "<div class=\"acp-customer-card\">\n <mat-card class=\"acp-customer-card-content\">\n <!-- Header -->\n <div class=\"acp-card-header\">\n <div class=\"acp-avatar\" aria-label=\"Logo de cliente\">{{ getLogoSliceBusinessName() }}</div>\n <h5 class=\"acp-business-name\">{{ customer().businessName }}</h5>\n <p class=\"acp-trade-name\">{{ customer().tradeName }}</p>\n </div>\n\n <!-- Card content -->\n <mat-card-content>\n <div class=\"acp-info\">\n <p><strong>ID:</strong> 1234567890 (RUC)</p>\n <p><strong>Email:</strong> {{ customer().email }}</p>\n <p><strong>Tel\u00E9fono:</strong> {{ customer().phone }}</p>\n <p><strong>Direcci\u00F3n:</strong>{{ customer().address }}</p>\n\n <div class=\"acp-chips\">\n <mat-chip-set>\n <mat-chip color=\"primary\">{{ customer().statusName }}</mat-chip>\n </mat-chip-set>\n </div>\n </div>\n </mat-card-content>\n\n <!-- Card actions -->\n @if (!customer().isFinalConsumer) {\n <mat-card-actions class=\"acp-actions gap-2\">\n <acp-button matStyle=\"icon\" icon=\"edit\" (handleClick)=\"onEditClick()\" />\n <acp-button matStyle=\"icon\" icon=\"delete\" variant=\"danger\" (handleClick)=\"onDeleteClick()\" />\n </mat-card-actions>\n }\n </mat-card>\n</div>\n", styles: [".acp-customer-card{display:block}.acp-customer-card .acp-customer-card-content{width:345px;border-radius:16px}.acp-customer-card .acp-card-header{display:flex;flex-direction:column;align-items:center;padding:16px;background-color:var(--mat-sys-primary-container, #e3f2fd);border-top-left-radius:16px;border-top-right-radius:16px}.acp-customer-card .acp-card-header .acp-business-name{text-align:center;font-size:14px;font-weight:500}.acp-customer-card .acp-card-header .acp-trade-name{text-align:center;font-size:12px;color:var(--mat-sys-on-surface-variant, #6c757d)}.acp-customer-card .acp-avatar{width:80px;height:80px;border-radius:50%;background-color:var(--mat-sys-primary, #1976d2);display:flex;justify-content:center;align-items:center;font-size:32px;color:var(--mat-sys-on-primary, white);margin-bottom:12px}.acp-customer-card .acp-info p{margin:4px 0}.acp-customer-card .acp-chips{margin-top:12px;display:flex;gap:8px}.acp-customer-card .acp-actions{justify-content:flex-end;padding:16px}\n"] }]
879
- }], propDecorators: { customer: [{ type: i0.Input, args: [{ isSignal: true, alias: "customer", required: true }] }], editCustomer: [{ type: i0.Output, args: ["editCustomer"] }], deleteCustomer: [{ type: i0.Output, args: ["deleteCustomer"] }] } });
883
+ // export * from './lib/application';
884
+ // export * from './lib/domain';
885
+ // export * from './lib/infrastructure';
886
+ // export * from './lib/ui';
880
887
 
881
888
  /**
882
889
  * Generated bundle index. Do not edit.
883
890
  */
884
891
 
885
- export { CUSTOMER_API, CompanySearchMapper, CustomerAddEditComponent, CustomerCard, CustomerCreateUpdateMapper, CustomerExternalHttpRepository, CustomerExternalUseCase, CustomerFormDataMapper, CustomerGetByIdMapper, CustomerHttpRepository, CustomerUseCase, ListCustomerMapper };
892
+ export { COMPANY_CUSTOMER_FORM_CONFIG, COMPANY_CUSTOMER_MAPPER, COMPANY_CUSTOMER_SERVICE, CUSTOMER_SRI_SERVICE, CompanyCustomerDefaultMapper, CompanyCustomerFormComponent, CompanyCustomerService, CustomerValidators, MAIN_APP_COMPANY_CUSTOMER_CONFIG, POS_COMPANY_CUSTOMER_CONFIG };
886
893
  //# sourceMappingURL=acontplus-ng-customer.mjs.map