digipay-utility-payment 0.0.12 → 0.0.13

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.
Binary file
@@ -2277,239 +2277,231 @@ class BillWorkflowComponent {
2277
2277
  };
2278
2278
  this.topupAndBillpaymentService.saveWorkflowData(workflowState);
2279
2279
  }
2280
- getExtraFieldsToShow(field) {
2281
- if (!field)
2282
- return undefined; // Early return for falsy field
2283
- let isReadOnly = false;
2284
- if (field?.external_field_key === "dial_code") {
2285
- isReadOnly = true;
2286
- this.fieldsModel = { "dial_code": this.currentUserDetails?.dial_code };
2287
- }
2288
- const validations = field?.field_validation || [];
2289
- let isRequired = false;
2290
- let minLength;
2291
- let maxLength;
2292
- let minValue;
2293
- let maxValue;
2294
- const validationMessages = {};
2295
- validations.forEach((validation) => {
2296
- const fieldType = validation?.field_types;
2297
- const fieldValue = validation?.field_values;
2298
- const fieldError = validation?.field_error;
2299
- if (fieldType === 1) {
2300
- isRequired = fieldValue === "true" || fieldValue === true || fieldValue === "1";
2301
- }
2302
- else if (fieldType === 2) {
2303
- maxLength = parseInt(fieldValue);
2304
- if (fieldError)
2305
- validationMessages.maxlength = fieldError;
2306
- }
2307
- else if (fieldType === 3) {
2308
- minValue = parseFloat(fieldValue);
2309
- if (fieldError)
2310
- validationMessages.min = fieldError;
2311
- }
2312
- else if (fieldType === 4) {
2313
- minLength = parseInt(fieldValue);
2314
- if (fieldError)
2315
- validationMessages.minlength = fieldError;
2316
- if (!isRequired)
2317
- isRequired = true;
2318
- }
2319
- else if (fieldType === 5) {
2320
- maxValue = parseFloat(fieldValue);
2321
- if (fieldError)
2322
- validationMessages.max = fieldError;
2323
- }
2324
- });
2325
- let res = {
2326
- key: field.external_field_key,
2327
- templateOptions: {},
2328
- className: "col-sm-6",
2329
- wrappers: ["form-field-horizontal"],
2330
- type: "input",
2331
- modelOptions: { updateOn: 'change' },
2332
- expressionProperties: {
2333
- 'templateOptions.disabled': 'formState.disabled',
2334
- },
2335
- hooks: {
2336
- onInit: (field) => {
2337
- const control = field.formControl;
2338
- if (control) {
2339
- control.valueChanges.subscribe(() => {
2340
- if (control.invalid && control.value !== null && control.value !== '') {
2341
- control.markAsTouched();
2342
- }
2343
- });
2344
- }
2345
- }
2346
- }
2347
- };
2348
- if (isRequired) {
2349
- validationMessages.required = `${field.field_title} ${this.translationService.translate("LABEL_IS_REQUIRED")}`;
2350
- }
2351
- if (Object.keys(validationMessages).length > 0) {
2352
- res["validation"] = { messages: validationMessages };
2353
- }
2354
- if (field.field_type == TOPUP_BILL_PAYMENT_FIELD_TYPE.TEXT_BOX) {
2355
- res["templateOptions"] = {
2356
- label: `${field.field_title} `,
2357
- placeholder: `${this.translationService.translate("COMMON_LABEL_PLEASE_ENTER")} ${field.field_title}`,
2358
- required: isRequired,
2359
- minLength: minLength,
2360
- maxLength: maxLength,
2361
- readonly: isReadOnly,
2362
- };
2363
- }
2364
- else if (field.field_type == TOPUP_BILL_PAYMENT_FIELD_TYPE.NUMERIC) {
2365
- res["templateOptions"] = {
2366
- label: `${field.field_title} `,
2367
- placeholder: `${this.translationService.translate("COMMON_LABEL_PLEASE_ENTER")} ${field.field_title}`,
2368
- required: isRequired,
2369
- min: minValue,
2370
- max: maxValue,
2371
- minLength: minLength,
2372
- maxLength: maxLength,
2373
- };
2374
- res["type"] = "number-field";
2375
- }
2376
- return res; // Always reached now
2377
- }
2378
- // getExtraFieldsToShow(field: any): FormlyFieldConfig | null {
2379
- // if (field) {
2380
- // let isReadOnly = false;
2381
- // let fieldValue: any = null;
2382
- // let customValidators: any = {};
2383
- // if (field?.external_field_key === "dial_code") {
2384
- // isReadOnly = true;
2385
- // fieldValue = this.currentUserDetails?.dial_code;
2386
- // this.fieldsModel = { "dial_code": fieldValue };
2280
+ // getExtraFieldsToShow(field: any): FormlyFieldConfig | undefined {
2281
+ // if (!field) return undefined; // Early return for falsy field
2282
+ // let isReadOnly = false;
2283
+ // if (field?.external_field_key === "dial_code") {
2284
+ // isReadOnly = true;
2285
+ // this.fieldsModel = { "dial_code": this.currentUserDetails?.dial_code };
2286
+ // }
2287
+ // const validations: Array<any> = field?.field_validation || [];
2288
+ // let isRequired: boolean = false;
2289
+ // let minLength: number | undefined;
2290
+ // let maxLength: number | undefined;
2291
+ // let minValue: number | undefined;
2292
+ // let maxValue: number | undefined;
2293
+ // const validationMessages: any = {};
2294
+ // validations.forEach((validation: any) => {
2295
+ // const fieldType = validation?.field_types;
2296
+ // const fieldValue = validation?.field_values;
2297
+ // const fieldError = validation?.field_error;
2298
+ // if (fieldType === 1) {
2299
+ // isRequired = fieldValue === "true" || fieldValue === true || fieldValue === "1";
2300
+ // } else if (fieldType === 2) {
2301
+ // maxLength = parseInt(fieldValue);
2302
+ // if (fieldError) validationMessages.maxlength = fieldError;
2303
+ // } else if (fieldType === 3) {
2304
+ // minValue = parseFloat(fieldValue);
2305
+ // if (fieldError) validationMessages.min = fieldError;
2306
+ // } else if (fieldType === 4) {
2307
+ // minLength = parseInt(fieldValue);
2308
+ // if (fieldError) validationMessages.minlength = fieldError;
2309
+ // if (!isRequired) isRequired = true;
2310
+ // } else if (fieldType === 5) {
2311
+ // maxValue = parseFloat(fieldValue);
2312
+ // if (fieldError) validationMessages.max = fieldError;
2387
2313
  // }
2388
- // // Check if this is an amount field and we have a selected product
2389
- // const isAmountField = field?.external_field_key?.toLowerCase().includes("amount") ||
2390
- // field?.field_title?.toLowerCase().includes("amount");
2391
- // if (isAmountField && this.selectedProduct) {
2392
- // if (this.selectedProduct?.product_price_type === PRODUCT_PRICE_TYPE.FIXED) {
2393
- // // Fixed price: make field readonly and set the fixed price
2394
- // isReadOnly = true;
2395
- // fieldValue = this.selectedProduct?.product_fixed_price || 0;
2396
- // if (this.fieldsModel) {
2397
- // this.fieldsModel[field.external_field_key] = fieldValue;
2398
- // } else {
2399
- // this.fieldsModel = { [field.external_field_key]: fieldValue };
2314
+ // });
2315
+ // let res: FormlyFieldConfig = {
2316
+ // key: field.external_field_key,
2317
+ // templateOptions: {} as FormlyTemplateOptions,
2318
+ // className: "col-sm-6",
2319
+ // wrappers: ["form-field-horizontal"],
2320
+ // type: "input",
2321
+ // modelOptions: { updateOn: 'change' },
2322
+ // expressionProperties: {
2323
+ // 'templateOptions.disabled': 'formState.disabled',
2324
+ // },
2325
+ // hooks: {
2326
+ // onInit: (field: FormlyFieldConfig) => {
2327
+ // const control = field.formControl;
2328
+ // if (control) {
2329
+ // control.valueChanges.subscribe(() => {
2330
+ // if (control.invalid && control.value !== null && control.value !== '') {
2331
+ // control.markAsTouched();
2332
+ // }
2333
+ // });
2400
2334
  // }
2401
- // } else if (this.selectedProduct?.product_price_type === PRODUCT_PRICE_TYPE.RANGE) {
2402
- // const rangeMin = Number(this.selectedProduct?.product_range_price?.min) || 0;
2403
- // const rangeMax = Number(this.selectedProduct?.product_range_price?.max) || 0;
2404
- // customValidators = {
2405
- // // Range validator - checks if value is within the allowed range
2406
- // // Allows typing leading zeros (e.g., "01", "08") but validates the numeric value
2407
- // range: {
2408
- // expression: (control: any) => {
2409
- // const value = control?.value;
2410
- // if (value === null || value === undefined || value === '') {
2411
- // return true; // No error if empty
2412
- // }
2413
- // const valueStr = String(value).trim();
2414
- // // Convert string to number (handles leading zeros: "01" becomes 1, "08" becomes 8)
2415
- // const numValue = Number(valueStr);
2416
- // if (isNaN(numValue) || !isFinite(numValue)) {
2417
- // return true; // Skip validation for invalid numbers
2418
- // }
2419
- // // Return true if value is IN range (no error), false if out of range (error)
2420
- // return numValue >= rangeMin && numValue <= rangeMax;
2421
- // },
2422
- // message: () => `${this.translationService.translate("COMMON_LABEL_AMOUNT_MUST_BE_BETWEEN")} ${rangeMin} ${this.translationService.translate("COMMON_LABEL_AND")} ${rangeMax}`
2423
- // }
2424
- // };
2425
2335
  // }
2426
2336
  // }
2427
- // const validations: Array<any> = field?.field_validation || [];
2428
- // const normalizedFieldType = this.normalizeFieldType(field?.field_type);
2429
- // const normalizedValidations = this.normalizeValidations(validations);
2430
- // const isRequired: boolean = normalizedValidations.isRequired;
2431
- // const minLength: number | undefined = normalizedValidations.minLength;
2432
- // const maxLength: number | undefined = normalizedValidations.maxLength;
2433
- // let minValue: number | undefined = normalizedValidations.minValue;
2434
- // let maxValue: number | undefined = normalizedValidations.maxValue;
2435
- // // For range products, don't set HTML5 min/max to allow typing any value
2436
- // // We'll validate using custom validator only
2437
- // // This prevents HTML5 from blocking input before validation
2438
- // if (isAmountField && this.selectedProduct?.product_price_type === PRODUCT_PRICE_TYPE.RANGE) {
2439
- // // Don't override min/max - let custom validator handle it
2440
- // // This allows users to type any value, then validate on blur/submit
2441
- // }
2442
- // let res: FormlyFieldConfig = {
2443
- // key: field.external_field_key,
2444
- // templateOptions: {} as any,
2445
- // className: "col-12",
2446
- // wrappers: ["form-field-horizontal"],
2447
- // type: "input",
2448
- // // Enable real-time validation on change/input
2449
- // modelOptions: {
2450
- // updateOn: 'change'
2451
- // },
2452
- // // Show errors in real-time (even when not touched)
2453
- // expressionProperties: {
2454
- // 'templateOptions.disabled': 'formState.disabled',
2455
- // },
2456
- // // Mark field as touched on value change to show errors immediately
2457
- // hooks: {
2458
- // onInit: (field: FormlyFieldConfig) => {
2459
- // const control = field.formControl;
2460
- // if (control) {
2461
- // // Subscribe to value changes and mark as touched to show errors immediately
2462
- // control.valueChanges.subscribe(() => {
2463
- // if (control.invalid && control.value !== null && control.value !== '') {
2464
- // control.markAsTouched();
2465
- // }
2466
- // });
2467
- // }
2468
- // }
2469
- // }
2337
+ // };
2338
+ // if (isRequired) {
2339
+ // validationMessages.required = `${field.field_title} ${this.translationService.translate("LABEL_IS_REQUIRED")}`;
2340
+ // }
2341
+ // if (Object.keys(validationMessages).length > 0) {
2342
+ // res["validation"] = { messages: validationMessages };
2343
+ // }
2344
+ // if (field.field_type == TOPUP_BILL_PAYMENT_FIELD_TYPE.TEXT_BOX) {
2345
+ // res["templateOptions"] = {
2346
+ // label: `${field.field_title} `,
2347
+ // placeholder: `${this.translationService.translate("COMMON_LABEL_PLEASE_ENTER")} ${field.field_title}`,
2348
+ // required: isRequired,
2349
+ // minLength: minLength,
2350
+ // maxLength: maxLength,
2351
+ // readonly: isReadOnly,
2470
2352
  // };
2471
- // // Add custom validators if any
2472
- // if (Object.keys(customValidators).length > 0) {
2473
- // res["validators"] = customValidators;
2474
- // }
2475
- // if (normalizedFieldType == TOPUP_BILL_PAYMENT_FIELD_TYPE.TEXT_BOX) {
2476
- // res["templateOptions"] = {
2477
- // label: `${field.field_title} `,
2478
- // placeholder: `${this.translationService.translate("COMMON_LABEL_PLEASE_ENTER")} ${field.field_title}`,
2479
- // required: isRequired,
2480
- // minLength: minLength,
2481
- // maxLength: maxLength,
2482
- // readonly: isReadOnly,
2483
- // };
2484
- // if (fieldValue !== null) {
2485
- // res["defaultValue"] = fieldValue;
2486
- // }
2487
- // } else if (normalizedFieldType == TOPUP_BILL_PAYMENT_FIELD_TYPE.NUMERIC) {
2488
- // // For range products, don't set min/max in templateOptions to allow typing
2489
- // // Custom validator will handle validation
2490
- // const templateOptions: any = {
2491
- // label: `${field.field_title} `,
2492
- // placeholder: `${this.translationService.translate("COMMON_LABEL_PLEASE_ENTER")} ${field.field_title}`,
2493
- // required: isRequired,
2494
- // minLength: minLength,
2495
- // maxLength: maxLength,
2496
- // readonly: isReadOnly,
2497
- // };
2498
- // // Only set min/max if NOT a range product (to allow typing any value for range products)
2499
- // if (!(isAmountField && this.selectedProduct?.product_price_type === PRODUCT_PRICE_TYPE.RANGE)) {
2500
- // templateOptions.min = minValue;
2501
- // templateOptions.max = maxValue;
2502
- // }
2503
- // res["templateOptions"] = templateOptions;
2504
- // res["type"] = "number-field";
2505
- // if (fieldValue !== null) {
2506
- // res["defaultValue"] = fieldValue;
2507
- // }
2508
- // }
2509
- // return res;
2353
+ // } else if (field.field_type == TOPUP_BILL_PAYMENT_FIELD_TYPE.NUMERIC) {
2354
+ // res["templateOptions"] = {
2355
+ // label: `${field.field_title} `,
2356
+ // placeholder: `${this.translationService.translate("COMMON_LABEL_PLEASE_ENTER")} ${field.field_title}`,
2357
+ // required: isRequired,
2358
+ // min: minValue,
2359
+ // max: maxValue,
2360
+ // minLength: minLength,
2361
+ // maxLength: maxLength,
2362
+ // };
2363
+ // res["type"] = "number-field";
2510
2364
  // }
2511
- // return null;
2365
+ // return res; // Always reached now
2512
2366
  // }
2367
+ getExtraFieldsToShow(field) {
2368
+ if (field) {
2369
+ let isReadOnly = false;
2370
+ let fieldValue = null;
2371
+ let customValidators = {};
2372
+ if (field?.external_field_key === "dial_code") {
2373
+ isReadOnly = true;
2374
+ fieldValue = this.currentUserDetails?.dial_code;
2375
+ this.fieldsModel = { "dial_code": fieldValue };
2376
+ }
2377
+ // Check if this is an amount field and we have a selected product
2378
+ const isAmountField = field?.external_field_key?.toLowerCase().includes("amount") ||
2379
+ field?.field_title?.toLowerCase().includes("amount");
2380
+ if (isAmountField && this.selectedProduct) {
2381
+ if (this.selectedProduct?.product_price_type === PRODUCT_PRICE_TYPE.FIXED) {
2382
+ // Fixed price: make field readonly and set the fixed price
2383
+ isReadOnly = true;
2384
+ fieldValue = this.selectedProduct?.product_fixed_price || 0;
2385
+ if (this.fieldsModel) {
2386
+ this.fieldsModel[field.external_field_key] = fieldValue;
2387
+ }
2388
+ else {
2389
+ this.fieldsModel = { [field.external_field_key]: fieldValue };
2390
+ }
2391
+ }
2392
+ else if (this.selectedProduct?.product_price_type === PRODUCT_PRICE_TYPE.RANGE) {
2393
+ const rangeMin = Number(this.selectedProduct?.product_range_price?.min) || 0;
2394
+ const rangeMax = Number(this.selectedProduct?.product_range_price?.max) || 0;
2395
+ customValidators = {
2396
+ // Range validator - checks if value is within the allowed range
2397
+ // Allows typing leading zeros (e.g., "01", "08") but validates the numeric value
2398
+ range: {
2399
+ expression: (control) => {
2400
+ const value = control?.value;
2401
+ if (value === null || value === undefined || value === '') {
2402
+ return true; // No error if empty
2403
+ }
2404
+ const valueStr = String(value).trim();
2405
+ // Convert string to number (handles leading zeros: "01" becomes 1, "08" becomes 8)
2406
+ const numValue = Number(valueStr);
2407
+ if (isNaN(numValue) || !isFinite(numValue)) {
2408
+ return true; // Skip validation for invalid numbers
2409
+ }
2410
+ // Return true if value is IN range (no error), false if out of range (error)
2411
+ return numValue >= rangeMin && numValue <= rangeMax;
2412
+ },
2413
+ message: () => `${this.translationService.translate("COMMON_LABEL_AMOUNT_MUST_BE_BETWEEN")} ${rangeMin} ${this.translationService.translate("COMMON_LABEL_AND")} ${rangeMax}`
2414
+ }
2415
+ };
2416
+ }
2417
+ }
2418
+ const validations = field?.field_validation || [];
2419
+ const normalizedFieldType = this.normalizeFieldType(field?.field_type);
2420
+ const normalizedValidations = this.normalizeValidations(validations);
2421
+ const isRequired = normalizedValidations.isRequired;
2422
+ const minLength = normalizedValidations.minLength;
2423
+ const maxLength = normalizedValidations.maxLength;
2424
+ let minValue = normalizedValidations.minValue;
2425
+ let maxValue = normalizedValidations.maxValue;
2426
+ // For range products, don't set HTML5 min/max to allow typing any value
2427
+ // We'll validate using custom validator only
2428
+ // This prevents HTML5 from blocking input before validation
2429
+ if (isAmountField && this.selectedProduct?.product_price_type === PRODUCT_PRICE_TYPE.RANGE) {
2430
+ // Don't override min/max - let custom validator handle it
2431
+ // This allows users to type any value, then validate on blur/submit
2432
+ }
2433
+ let res = {
2434
+ key: field.external_field_key,
2435
+ templateOptions: {},
2436
+ className: "col-12",
2437
+ wrappers: ["form-field-horizontal"],
2438
+ type: "input",
2439
+ // Enable real-time validation on change/input
2440
+ modelOptions: {
2441
+ updateOn: 'change'
2442
+ },
2443
+ // Show errors in real-time (even when not touched)
2444
+ expressionProperties: {
2445
+ 'templateOptions.disabled': 'formState.disabled',
2446
+ },
2447
+ // Mark field as touched on value change to show errors immediately
2448
+ hooks: {
2449
+ onInit: (field) => {
2450
+ const control = field.formControl;
2451
+ if (control) {
2452
+ // Subscribe to value changes and mark as touched to show errors immediately
2453
+ control.valueChanges.subscribe(() => {
2454
+ if (control.invalid && control.value !== null && control.value !== '') {
2455
+ control.markAsTouched();
2456
+ }
2457
+ });
2458
+ }
2459
+ }
2460
+ }
2461
+ };
2462
+ // Add custom validators if any
2463
+ if (Object.keys(customValidators).length > 0) {
2464
+ res["validators"] = customValidators;
2465
+ }
2466
+ if (normalizedFieldType == TOPUP_BILL_PAYMENT_FIELD_TYPE.TEXT_BOX) {
2467
+ res["templateOptions"] = {
2468
+ label: `${field.field_title} `,
2469
+ placeholder: `${this.translationService.translate("COMMON_LABEL_PLEASE_ENTER")} ${field.field_title}`,
2470
+ required: isRequired,
2471
+ minLength: minLength,
2472
+ maxLength: maxLength,
2473
+ readonly: isReadOnly,
2474
+ };
2475
+ if (fieldValue !== null) {
2476
+ res["defaultValue"] = fieldValue;
2477
+ }
2478
+ }
2479
+ else if (normalizedFieldType == TOPUP_BILL_PAYMENT_FIELD_TYPE.NUMERIC) {
2480
+ // For range products, don't set min/max in templateOptions to allow typing
2481
+ // Custom validator will handle validation
2482
+ const templateOptions = {
2483
+ label: `${field.field_title} `,
2484
+ placeholder: `${this.translationService.translate("COMMON_LABEL_PLEASE_ENTER")} ${field.field_title}`,
2485
+ required: isRequired,
2486
+ minLength: minLength,
2487
+ maxLength: maxLength,
2488
+ readonly: isReadOnly,
2489
+ };
2490
+ // Only set min/max if NOT a range product (to allow typing any value for range products)
2491
+ if (!(isAmountField && this.selectedProduct?.product_price_type === PRODUCT_PRICE_TYPE.RANGE)) {
2492
+ templateOptions.min = minValue;
2493
+ templateOptions.max = maxValue;
2494
+ }
2495
+ res["templateOptions"] = templateOptions;
2496
+ res["type"] = "number-field";
2497
+ if (fieldValue !== null) {
2498
+ res["defaultValue"] = fieldValue;
2499
+ }
2500
+ }
2501
+ return res;
2502
+ }
2503
+ return null;
2504
+ }
2513
2505
  ngOnDestroy() {
2514
2506
  this.destroy$.next(true);
2515
2507
  this.destroy$.unsubscribe();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "digipay-utility-payment",
3
- "version": "0.0.12",
3
+ "version": "0.0.13",
4
4
  "peerDependencies": {
5
5
  "@angular/common": "^20.3.0",
6
6
  "@angular/core": "^20.3.0"