@mj-biz-apps/orders-ng 5.24.0 → 5.26.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. package/dist/checkout-element/main.js +32 -2
  2. package/dist/lib/checkout-widget/checkout-draft-line.d.ts +14 -0
  3. package/dist/lib/checkout-widget/checkout-draft-line.d.ts.map +1 -1
  4. package/dist/lib/checkout-widget/checkout-draft-line.js +18 -0
  5. package/dist/lib/checkout-widget/checkout-draft-line.js.map +1 -1
  6. package/dist/lib/checkout-widget/checkout-public-host.component.d.ts +9 -2
  7. package/dist/lib/checkout-widget/checkout-public-host.component.d.ts.map +1 -1
  8. package/dist/lib/checkout-widget/checkout-public-host.component.js +20 -4
  9. package/dist/lib/checkout-widget/checkout-public-host.component.js.map +1 -1
  10. package/dist/lib/custom/EventOrderLine/event-order-line-form.component.d.ts +10 -1
  11. package/dist/lib/custom/EventOrderLine/event-order-line-form.component.d.ts.map +1 -1
  12. package/dist/lib/custom/EventOrderLine/event-order-line-form.component.js +110 -53
  13. package/dist/lib/custom/EventOrderLine/event-order-line-form.component.js.map +1 -1
  14. package/dist/lib/custom/EventOrderLine/line-event-summary.d.ts +15 -0
  15. package/dist/lib/custom/EventOrderLine/line-event-summary.d.ts.map +1 -0
  16. package/dist/lib/custom/EventOrderLine/line-event-summary.js +15 -0
  17. package/dist/lib/custom/EventOrderLine/line-event-summary.js.map +1 -0
  18. package/dist/lib/custom/OrderHeader/order-header-form.component.d.ts +7 -0
  19. package/dist/lib/custom/OrderHeader/order-header-form.component.d.ts.map +1 -1
  20. package/dist/lib/custom/OrderHeader/order-header-form.component.js +278 -233
  21. package/dist/lib/custom/OrderHeader/order-header-form.component.js.map +1 -1
  22. package/dist/lib/custom/OrderHeader/order-lines-editor.component.d.ts +20 -1
  23. package/dist/lib/custom/OrderHeader/order-lines-editor.component.d.ts.map +1 -1
  24. package/dist/lib/custom/OrderHeader/order-lines-editor.component.js +222 -63
  25. package/dist/lib/custom/OrderHeader/order-lines-editor.component.js.map +1 -1
  26. package/dist/lib/data/orders-queries.d.ts +18 -0
  27. package/dist/lib/data/orders-queries.d.ts.map +1 -1
  28. package/dist/lib/data/orders-queries.js +30 -0
  29. package/dist/lib/data/orders-queries.js.map +1 -1
  30. package/dist/lib/generated/Entities/mjBizAppsOrdersEventOrderLine/mjbizappsorderseventorderline.form.component.js +8 -6
  31. package/dist/lib/generated/Entities/mjBizAppsOrdersEventOrderLine/mjbizappsorderseventorderline.form.component.js.map +1 -1
  32. package/dist/lib/generated/Entities/mjBizAppsOrdersOrderLine/mjbizappsordersorderline.form.component.js +95 -93
  33. package/dist/lib/generated/Entities/mjBizAppsOrdersOrderLine/mjbizappsordersorderline.form.component.js.map +1 -1
  34. package/dist/lib/pages/receivables/progress.page.d.ts +3 -3
  35. package/dist/lib/pages/receivables/progress.page.js +9 -9
  36. package/dist/lib/pages/receivables/progress.page.js.map +1 -1
  37. package/dist/public-api.d.ts +1 -1
  38. package/dist/public-api.d.ts.map +1 -1
  39. package/dist/public-api.js.map +1 -1
  40. package/package.json +2 -2
@@ -9,7 +9,7 @@ import { MJOConsequenceChipComponent, MJOPriceSourceBadgeComponent } from '../..
9
9
  import { MJOLinePricePickerComponent } from '../../panels/line-price-picker.component.js';
10
10
  import { FormatMoney, MJOMoneyPipe } from '../../panels/money-format.js';
11
11
  import { MJO_ENTITIES } from '../../data/entity-names.js';
12
- import { ContinuationStartFrom, GetCatalogOptions, GetDimensionOptions, GetDiscountAuthority, GetSubscriptionContinuation, RankCatalogMatches, } from '../../data/orders-queries.js';
12
+ import { ContinuationStartFrom, GetCatalogOptions, GetDimensionOptions, GetDiscountAuthority, GetExistingHolding, GetSubscriptionContinuation, RankCatalogMatches, } from '../../data/orders-queries.js';
13
13
  import { MJOOrderLineDetailsPanelComponent } from './order-line-details-panel.component.js';
14
14
  import { MJOPricingScheduler } from '../../services/pricing-scheduler.service.js';
15
15
  import { ExtensionCollapsedHint, ExtensionToggleLabel, } from './line-extension-fields.js';
@@ -341,17 +341,17 @@ function MJOOrderLinesEditorComponent_For_2_Conditional_31_Conditional_3_Templat
341
341
  } }
342
342
  function MJOOrderLinesEditorComponent_For_2_Conditional_31_Conditional_4_Conditional_1_Template(rf, ctx) { if (rf & 1) {
343
343
  const _r14 = i0.ɵɵgetCurrentView();
344
- i0.ɵɵelementStart(0, "button", 66);
344
+ i0.ɵɵelementStart(0, "button", 67);
345
345
  i0.ɵɵlistener("click", function MJOOrderLinesEditorComponent_For_2_Conditional_31_Conditional_4_Conditional_1_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r14); const line_r2 = i0.ɵɵnextContext(3).$implicit; const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.ResetTermStart(line_r2)); });
346
346
  i0.ɵɵtext(1, " Reset to order date ");
347
347
  i0.ɵɵelementEnd();
348
348
  } }
349
349
  function MJOOrderLinesEditorComponent_For_2_Conditional_31_Conditional_4_Template(rf, ctx) { if (rf & 1) {
350
350
  const _r13 = i0.ɵɵgetCurrentView();
351
- i0.ɵɵelementStart(0, "input", 64);
351
+ i0.ɵɵelementStart(0, "input", 65);
352
352
  i0.ɵɵlistener("change", function MJOOrderLinesEditorComponent_For_2_Conditional_31_Conditional_4_Template_input_change_0_listener($event) { i0.ɵɵrestoreView(_r13); const line_r2 = i0.ɵɵnextContext(2).$implicit; const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.SetTermStart(line_r2, $event)); });
353
353
  i0.ɵɵelementEnd();
354
- i0.ɵɵconditionalCreate(1, MJOOrderLinesEditorComponent_For_2_Conditional_31_Conditional_4_Conditional_1_Template, 2, 0, "button", 65);
354
+ i0.ɵɵconditionalCreate(1, MJOOrderLinesEditorComponent_For_2_Conditional_31_Conditional_4_Conditional_1_Template, 2, 0, "button", 66);
355
355
  } if (rf & 2) {
356
356
  const line_r2 = i0.ɵɵnextContext(2).$implicit;
357
357
  const ctx_r2 = i0.ɵɵnextContext();
@@ -379,6 +379,82 @@ function MJOOrderLinesEditorComponent_For_2_Conditional_31_Conditional_8_Templat
379
379
  function MJOOrderLinesEditorComponent_For_2_Conditional_31_Conditional_9_Template(rf, ctx) { if (rf & 1) {
380
380
  i0.ɵɵtext(0, " Stated on this line, so a later change to the order date leaves it alone. ");
381
381
  } }
382
+ function MJOOrderLinesEditorComponent_For_2_Conditional_31_Conditional_10_Conditional_3_Template(rf, ctx) { if (rf & 1) {
383
+ i0.ɵɵtext(0);
384
+ } if (rf & 2) {
385
+ const holding_r15 = i0.ɵɵnextContext();
386
+ const ctx_r2 = i0.ɵɵnextContext(3);
387
+ i0.ɵɵtextInterpolate1(" (covered through ", ctx_r2.HoldingCoverageEnd(holding_r15), ") ");
388
+ } }
389
+ function MJOOrderLinesEditorComponent_For_2_Conditional_31_Conditional_10_Conditional_5_Conditional_3_Template(rf, ctx) { if (rf & 1) {
390
+ i0.ɵɵtext(0);
391
+ } if (rf & 2) {
392
+ const holding_r15 = i0.ɵɵnextContext(2);
393
+ const ctx_r2 = i0.ɵɵnextContext(3);
394
+ i0.ɵɵtextInterpolate1(" (starts ", ctx_r2.HoldingContinuationStart(holding_r15), ") ");
395
+ } }
396
+ function MJOOrderLinesEditorComponent_For_2_Conditional_31_Conditional_10_Conditional_5_Template(rf, ctx) { if (rf & 1) {
397
+ const _r16 = i0.ɵɵgetCurrentView();
398
+ i0.ɵɵelementStart(0, "div", 69)(1, "button", 70);
399
+ i0.ɵɵlistener("click", function MJOOrderLinesEditorComponent_For_2_Conditional_31_Conditional_10_Conditional_5_Template_button_click_1_listener() { i0.ɵɵrestoreView(_r16); const line_r2 = i0.ɵɵnextContext(3).$implicit; const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.SetSubscriptionAction(line_r2, "ExtendExisting")); });
400
+ i0.ɵɵtext(2, " Add as next term ");
401
+ i0.ɵɵconditionalCreate(3, MJOOrderLinesEditorComponent_For_2_Conditional_31_Conditional_10_Conditional_5_Conditional_3_Template, 1, 1);
402
+ i0.ɵɵelementEnd();
403
+ i0.ɵɵelementStart(4, "button", 70);
404
+ i0.ɵɵlistener("click", function MJOOrderLinesEditorComponent_For_2_Conditional_31_Conditional_10_Conditional_5_Template_button_click_4_listener() { i0.ɵɵrestoreView(_r16); const line_r2 = i0.ɵɵnextContext(3).$implicit; const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.SetSubscriptionAction(line_r2, "CreateNew")); });
405
+ i0.ɵɵtext(5, " New subscription (keeps this line's dates) ");
406
+ i0.ɵɵelementEnd()();
407
+ } if (rf & 2) {
408
+ const holding_r15 = i0.ɵɵnextContext();
409
+ const line_r2 = i0.ɵɵnextContext(2).$implicit;
410
+ const ctx_r2 = i0.ɵɵnextContext();
411
+ i0.ɵɵadvance();
412
+ i0.ɵɵclassProp("is-selected", line_r2.SubscriptionAction === "ExtendExisting");
413
+ i0.ɵɵattribute("aria-pressed", line_r2.SubscriptionAction === "ExtendExisting");
414
+ i0.ɵɵadvance(2);
415
+ i0.ɵɵconditional(ctx_r2.HoldingContinuationStart(holding_r15) ? 3 : -1);
416
+ i0.ɵɵadvance();
417
+ i0.ɵɵclassProp("is-selected", line_r2.SubscriptionAction === "CreateNew");
418
+ i0.ɵɵattribute("aria-pressed", line_r2.SubscriptionAction === "CreateNew");
419
+ } }
420
+ function MJOOrderLinesEditorComponent_For_2_Conditional_31_Conditional_10_Conditional_7_Template(rf, ctx) { if (rf & 1) {
421
+ i0.ɵɵtext(0, " Confirm starts a separate subscription on this line's service period. ");
422
+ } }
423
+ function MJOOrderLinesEditorComponent_For_2_Conditional_31_Conditional_10_Conditional_8_Template(rf, ctx) { if (rf & 1) {
424
+ i0.ɵɵtext(0);
425
+ } if (rf & 2) {
426
+ const holding_r15 = i0.ɵɵnextContext();
427
+ i0.ɵɵtextInterpolate1(" Confirm adds a term to ", holding_r15.SubscriptionNumber, ", starting the day after its coverage ends. ");
428
+ } }
429
+ function MJOOrderLinesEditorComponent_For_2_Conditional_31_Conditional_10_Conditional_9_Template(rf, ctx) { if (rf & 1) {
430
+ i0.ɵɵtext(0, " Not chosen. The subscription type's rule will decide at confirm, and it may move this line's dates. ");
431
+ } }
432
+ function MJOOrderLinesEditorComponent_For_2_Conditional_31_Conditional_10_Template(rf, ctx) { if (rf & 1) {
433
+ i0.ɵɵelementStart(0, "div", 64)(1, "span", 68);
434
+ i0.ɵɵtext(2);
435
+ i0.ɵɵconditionalCreate(3, MJOOrderLinesEditorComponent_For_2_Conditional_31_Conditional_10_Conditional_3_Template, 1, 1);
436
+ i0.ɵɵtext(4, ". ");
437
+ i0.ɵɵelementEnd();
438
+ i0.ɵɵconditionalCreate(5, MJOOrderLinesEditorComponent_For_2_Conditional_31_Conditional_10_Conditional_5_Template, 6, 7, "div", 69);
439
+ i0.ɵɵelementStart(6, "span", 63);
440
+ i0.ɵɵconditionalCreate(7, MJOOrderLinesEditorComponent_For_2_Conditional_31_Conditional_10_Conditional_7_Template, 1, 0)(8, MJOOrderLinesEditorComponent_For_2_Conditional_31_Conditional_10_Conditional_8_Template, 1, 1)(9, MJOOrderLinesEditorComponent_For_2_Conditional_31_Conditional_10_Conditional_9_Template, 1, 0);
441
+ i0.ɵɵelementEnd()();
442
+ } if (rf & 2) {
443
+ const holding_r15 = ctx;
444
+ const line_r2 = i0.ɵɵnextContext(2).$implicit;
445
+ const ctx_r2 = i0.ɵɵnextContext();
446
+ i0.ɵɵattribute("aria-label", "Existing subscription " + holding_r15.SubscriptionNumber);
447
+ i0.ɵɵadvance(2);
448
+ i0.ɵɵtextInterpolate1(" The customer already holds ", holding_r15.SubscriptionNumber, " for this product ");
449
+ i0.ɵɵadvance();
450
+ i0.ɵɵconditional(ctx_r2.HoldingCoverageEnd(holding_r15) ? 3 : -1);
451
+ i0.ɵɵadvance(2);
452
+ i0.ɵɵconditional(ctx_r2.CanEditServicePeriod() ? 5 : -1);
453
+ i0.ɵɵadvance();
454
+ i0.ɵɵclassProp("is-error", !line_r2.SubscriptionAction);
455
+ i0.ɵɵadvance();
456
+ i0.ɵɵconditional(line_r2.SubscriptionAction === "CreateNew" ? 7 : line_r2.SubscriptionAction === "ExtendExisting" ? 8 : 9);
457
+ } }
382
458
  function MJOOrderLinesEditorComponent_For_2_Conditional_31_Template(rf, ctx) { if (rf & 1) {
383
459
  i0.ɵɵelementStart(0, "div", 27)(1, "label", 60);
384
460
  i0.ɵɵtext(2, " Term start ");
@@ -387,7 +463,9 @@ function MJOOrderLinesEditorComponent_For_2_Conditional_31_Template(rf, ctx) { i
387
463
  i0.ɵɵelementStart(6, "span", 63);
388
464
  i0.ɵɵconditionalCreate(7, MJOOrderLinesEditorComponent_For_2_Conditional_31_Conditional_7_Template, 1, 0)(8, MJOOrderLinesEditorComponent_For_2_Conditional_31_Conditional_8_Template, 1, 0)(9, MJOOrderLinesEditorComponent_For_2_Conditional_31_Conditional_9_Template, 1, 0);
389
465
  i0.ɵɵelementEnd()();
466
+ i0.ɵɵconditionalCreate(10, MJOOrderLinesEditorComponent_For_2_Conditional_31_Conditional_10_Template, 10, 7, "div", 64);
390
467
  } if (rf & 2) {
468
+ let tmp_14_0;
391
469
  const line_r2 = i0.ɵɵnextContext().$implicit;
392
470
  const ctx_r2 = i0.ɵɵnextContext();
393
471
  i0.ɵɵadvance();
@@ -396,17 +474,19 @@ function MJOOrderLinesEditorComponent_For_2_Conditional_31_Template(rf, ctx) { i
396
474
  i0.ɵɵconditional(ctx_r2.TermStartIsDictated(line_r2) ? 3 : ctx_r2.EditMode ? 4 : 5);
397
475
  i0.ɵɵadvance(4);
398
476
  i0.ɵɵconditional(ctx_r2.TermStartIsDictated(line_r2) ? 7 : ctx_r2.TermStartFollowsOrderDate(line_r2) ? 8 : 9);
477
+ i0.ɵɵadvance(3);
478
+ i0.ɵɵconditional((tmp_14_0 = ctx_r2.ExistingHoldingFor(line_r2)) ? 10 : -1, tmp_14_0);
399
479
  } }
400
480
  function MJOOrderLinesEditorComponent_For_2_Conditional_32_Conditional_3_Template(rf, ctx) { if (rf & 1) {
401
- const _r15 = i0.ɵɵgetCurrentView();
402
- i0.ɵɵelementStart(0, "input", 68);
403
- i0.ɵɵlistener("change", function MJOOrderLinesEditorComponent_For_2_Conditional_32_Conditional_3_Template_input_change_0_listener($event) { i0.ɵɵrestoreView(_r15); const line_r2 = i0.ɵɵnextContext(2).$implicit; const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.SetServicePeriod(line_r2, "Start", $event)); });
481
+ const _r17 = i0.ɵɵgetCurrentView();
482
+ i0.ɵɵelementStart(0, "input", 72);
483
+ i0.ɵɵlistener("change", function MJOOrderLinesEditorComponent_For_2_Conditional_32_Conditional_3_Template_input_change_0_listener($event) { i0.ɵɵrestoreView(_r17); const line_r2 = i0.ɵɵnextContext(2).$implicit; const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.SetServicePeriod(line_r2, "Start", $event)); });
404
484
  i0.ɵɵelementEnd();
405
- i0.ɵɵelementStart(1, "span", 69);
485
+ i0.ɵɵelementStart(1, "span", 73);
406
486
  i0.ɵɵtext(2, "to");
407
487
  i0.ɵɵelementEnd();
408
- i0.ɵɵelementStart(3, "input", 70);
409
- i0.ɵɵlistener("change", function MJOOrderLinesEditorComponent_For_2_Conditional_32_Conditional_3_Template_input_change_3_listener($event) { i0.ɵɵrestoreView(_r15); const line_r2 = i0.ɵɵnextContext(2).$implicit; const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.SetServicePeriod(line_r2, "End", $event)); });
488
+ i0.ɵɵelementStart(3, "input", 74);
489
+ i0.ɵɵlistener("change", function MJOOrderLinesEditorComponent_For_2_Conditional_32_Conditional_3_Template_input_change_3_listener($event) { i0.ɵɵrestoreView(_r17); const line_r2 = i0.ɵɵnextContext(2).$implicit; const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.SetServicePeriod(line_r2, "End", $event)); });
410
490
  i0.ɵɵelementEnd();
411
491
  } if (rf & 2) {
412
492
  const line_r2 = i0.ɵɵnextContext(2).$implicit;
@@ -426,7 +506,7 @@ function MJOOrderLinesEditorComponent_For_2_Conditional_32_Conditional_4_Templat
426
506
  i0.ɵɵtextInterpolate2(" ", ctx_r2.ServicePeriodValue(line_r2, "Start") || "\u2014", " to ", ctx_r2.ServicePeriodValue(line_r2, "End") || "\u2014", " ");
427
507
  } }
428
508
  function MJOOrderLinesEditorComponent_For_2_Conditional_32_Conditional_5_Template(rf, ctx) { if (rf & 1) {
429
- i0.ɵɵelementStart(0, "span", 67);
509
+ i0.ɵɵelementStart(0, "span", 71);
430
510
  i0.ɵɵtext(1, " End date must be on or after the start date. ");
431
511
  i0.ɵɵelementEnd();
432
512
  } }
@@ -440,7 +520,7 @@ function MJOOrderLinesEditorComponent_For_2_Conditional_32_Template(rf, ctx) { i
440
520
  i0.ɵɵtext(2, " Service period ");
441
521
  i0.ɵɵelementEnd();
442
522
  i0.ɵɵconditionalCreate(3, MJOOrderLinesEditorComponent_For_2_Conditional_32_Conditional_3_Template, 4, 3)(4, MJOOrderLinesEditorComponent_For_2_Conditional_32_Conditional_4_Template, 2, 2, "span", 62);
443
- i0.ɵɵconditionalCreate(5, MJOOrderLinesEditorComponent_For_2_Conditional_32_Conditional_5_Template, 2, 0, "span", 67)(6, MJOOrderLinesEditorComponent_For_2_Conditional_32_Conditional_6_Template, 2, 0, "span", 63);
523
+ i0.ɵɵconditionalCreate(5, MJOOrderLinesEditorComponent_For_2_Conditional_32_Conditional_5_Template, 2, 0, "span", 71)(6, MJOOrderLinesEditorComponent_For_2_Conditional_32_Conditional_6_Template, 2, 0, "span", 63);
444
524
  i0.ɵɵelementEnd();
445
525
  } if (rf & 2) {
446
526
  const line_r2 = i0.ɵɵnextContext().$implicit;
@@ -453,7 +533,7 @@ function MJOOrderLinesEditorComponent_For_2_Conditional_32_Template(rf, ctx) { i
453
533
  i0.ɵɵconditional(ctx_r2.ServicePeriodBackwards(line_r2) ? 5 : ctx_r2.ServicePeriodMissing(line_r2) ? 6 : -1);
454
534
  } }
455
535
  function MJOOrderLinesEditorComponent_For_2_Conditional_33_Conditional_5_Template(rf, ctx) { if (rf & 1) {
456
- i0.ɵɵelementStart(0, "span", 75);
536
+ i0.ɵɵelementStart(0, "span", 79);
457
537
  i0.ɵɵtext(1);
458
538
  i0.ɵɵelementEnd();
459
539
  } if (rf & 2) {
@@ -463,17 +543,17 @@ function MJOOrderLinesEditorComponent_For_2_Conditional_33_Conditional_5_Templat
463
543
  i0.ɵɵtextInterpolate(ctx_r2.ExtensionHint(line_r2));
464
544
  } }
465
545
  function MJOOrderLinesEditorComponent_For_2_Conditional_33_Template(rf, ctx) { if (rf & 1) {
466
- const _r16 = i0.ɵɵgetCurrentView();
467
- i0.ɵɵelementStart(0, "div", 71)(1, "button", 72);
468
- i0.ɵɵlistener("click", function MJOOrderLinesEditorComponent_For_2_Conditional_33_Template_button_click_1_listener() { i0.ɵɵrestoreView(_r16); const line_r2 = i0.ɵɵnextContext().$implicit; const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.ToggleExtension(line_r2)); });
469
- i0.ɵɵelement(2, "i", 73);
470
- i0.ɵɵelementStart(3, "span", 74);
546
+ const _r18 = i0.ɵɵgetCurrentView();
547
+ i0.ɵɵelementStart(0, "div", 75)(1, "button", 76);
548
+ i0.ɵɵlistener("click", function MJOOrderLinesEditorComponent_For_2_Conditional_33_Template_button_click_1_listener() { i0.ɵɵrestoreView(_r18); const line_r2 = i0.ɵɵnextContext().$implicit; const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.ToggleExtension(line_r2)); });
549
+ i0.ɵɵelement(2, "i", 77);
550
+ i0.ɵɵelementStart(3, "span", 78);
471
551
  i0.ɵɵtext(4);
472
552
  i0.ɵɵelementEnd();
473
- i0.ɵɵconditionalCreate(5, MJOOrderLinesEditorComponent_For_2_Conditional_33_Conditional_5_Template, 2, 1, "span", 75);
553
+ i0.ɵɵconditionalCreate(5, MJOOrderLinesEditorComponent_For_2_Conditional_33_Conditional_5_Template, 2, 1, "span", 79);
474
554
  i0.ɵɵelementEnd();
475
- i0.ɵɵelementStart(6, "div", 76)(7, "div", 77)(8, "mj-entity-form-host", 78);
476
- i0.ɵɵlistener("FormCreated", function MJOOrderLinesEditorComponent_For_2_Conditional_33_Template_mj_entity_form_host_FormCreated_8_listener($event) { i0.ɵɵrestoreView(_r16); const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.OnExtensionFormCreated($event)); })("Navigate", function MJOOrderLinesEditorComponent_For_2_Conditional_33_Template_mj_entity_form_host_Navigate_8_listener($event) { i0.ɵɵrestoreView(_r16); const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.OnExtensionNavigate($event)); });
555
+ i0.ɵɵelementStart(6, "div", 80)(7, "div", 81)(8, "mj-entity-form-host", 82);
556
+ i0.ɵɵlistener("FormCreated", function MJOOrderLinesEditorComponent_For_2_Conditional_33_Template_mj_entity_form_host_FormCreated_8_listener($event) { i0.ɵɵrestoreView(_r18); const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.OnExtensionFormCreated($event)); })("Navigate", function MJOOrderLinesEditorComponent_For_2_Conditional_33_Template_mj_entity_form_host_Navigate_8_listener($event) { i0.ɵɵrestoreView(_r18); const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.OnExtensionNavigate($event)); });
477
557
  i0.ɵɵelementEnd()()()();
478
558
  } if (rf & 2) {
479
559
  const line_r2 = i0.ɵɵnextContext().$implicit;
@@ -529,7 +609,7 @@ function MJOOrderLinesEditorComponent_For_2_Template(rf, ctx) { if (rf & 1) {
529
609
  i0.ɵɵconditionalCreate(29, MJOOrderLinesEditorComponent_For_2_Conditional_29_Template, 3, 3);
530
610
  i0.ɵɵelementEnd();
531
611
  i0.ɵɵconditionalCreate(30, MJOOrderLinesEditorComponent_For_2_Conditional_30_Template, 2, 1, "div", 26);
532
- i0.ɵɵconditionalCreate(31, MJOOrderLinesEditorComponent_For_2_Conditional_31_Template, 10, 3, "div", 27);
612
+ i0.ɵɵconditionalCreate(31, MJOOrderLinesEditorComponent_For_2_Conditional_31_Template, 11, 4);
533
613
  i0.ɵɵconditionalCreate(32, MJOOrderLinesEditorComponent_For_2_Conditional_32_Template, 7, 3, "div", 27);
534
614
  i0.ɵɵconditionalCreate(33, MJOOrderLinesEditorComponent_For_2_Conditional_33_Template, 9, 12, "div", 28);
535
615
  i0.ɵɵelementEnd();
@@ -586,8 +666,8 @@ function MJOOrderLinesEditorComponent_For_2_Template(rf, ctx) { if (rf & 1) {
586
666
  } }
587
667
  function MJOOrderLinesEditorComponent_ForEmpty_3_Template(rf, ctx) { if (rf & 1) {
588
668
  i0.ɵɵelementStart(0, "div", 3);
589
- i0.ɵɵelement(1, "i", 79);
590
- i0.ɵɵelementStart(2, "div", 80);
669
+ i0.ɵɵelement(1, "i", 83);
670
+ i0.ɵɵelementStart(2, "div", 84);
591
671
  i0.ɵɵtext(3, "Nothing on this order yet");
592
672
  i0.ɵɵelementEnd();
593
673
  i0.ɵɵelementStart(4, "div");
@@ -595,53 +675,53 @@ function MJOOrderLinesEditorComponent_ForEmpty_3_Template(rf, ctx) { if (rf & 1)
595
675
  i0.ɵɵelementEnd()();
596
676
  } }
597
677
  function MJOOrderLinesEditorComponent_Conditional_4_Conditional_5_For_2_Conditional_7_Template(rf, ctx) { if (rf & 1) {
598
- i0.ɵɵelementStart(0, "span", 96);
599
- i0.ɵɵelement(1, "i", 97);
678
+ i0.ɵɵelementStart(0, "span", 100);
679
+ i0.ɵɵelement(1, "i", 101);
600
680
  i0.ɵɵtext(2);
601
681
  i0.ɵɵelementEnd();
602
682
  } if (rf & 2) {
603
- const product_r19 = i0.ɵɵnextContext().$implicit;
683
+ const product_r21 = i0.ɵɵnextContext().$implicit;
604
684
  const ctx_r2 = i0.ɵɵnextContext(3);
605
- i0.ɵɵclassProp("is-foreign", ctx_r2.IsForeignCompany(product_r19));
606
- i0.ɵɵattribute("title", ctx_r2.IsForeignCompany(product_r19) ? "Sold by " + product_r19.CompanyName + ", not this order's company" : product_r19.CompanyName);
685
+ i0.ɵɵclassProp("is-foreign", ctx_r2.IsForeignCompany(product_r21));
686
+ i0.ɵɵattribute("title", ctx_r2.IsForeignCompany(product_r21) ? "Sold by " + product_r21.CompanyName + ", not this order's company" : product_r21.CompanyName);
607
687
  i0.ɵɵadvance(2);
608
- i0.ɵɵtextInterpolate1(" ", product_r19.CompanyName, " ");
688
+ i0.ɵɵtextInterpolate1(" ", product_r21.CompanyName, " ");
609
689
  } }
610
690
  function MJOOrderLinesEditorComponent_Conditional_4_Conditional_5_For_2_Template(rf, ctx) { if (rf & 1) {
611
- const _r18 = i0.ɵɵgetCurrentView();
612
- i0.ɵɵelementStart(0, "button", 88);
613
- i0.ɵɵlistener("mousedown", function MJOOrderLinesEditorComponent_Conditional_4_Conditional_5_For_2_Template_button_mousedown_0_listener() { const product_r19 = i0.ɵɵrestoreView(_r18).$implicit; const ctx_r2 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r2.AddProduct(product_r19)); });
614
- i0.ɵɵelementStart(1, "span", 89)(2, "span", 90);
691
+ const _r20 = i0.ɵɵgetCurrentView();
692
+ i0.ɵɵelementStart(0, "button", 92);
693
+ i0.ɵɵlistener("mousedown", function MJOOrderLinesEditorComponent_Conditional_4_Conditional_5_For_2_Template_button_mousedown_0_listener() { const product_r21 = i0.ɵɵrestoreView(_r20).$implicit; const ctx_r2 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r2.AddProduct(product_r21)); });
694
+ i0.ɵɵelementStart(1, "span", 93)(2, "span", 94);
615
695
  i0.ɵɵtext(3);
616
696
  i0.ɵɵelementEnd();
617
- i0.ɵɵelementStart(4, "span", 91)(5, "span", 92);
697
+ i0.ɵɵelementStart(4, "span", 95)(5, "span", 96);
618
698
  i0.ɵɵtext(6);
619
699
  i0.ɵɵelementEnd();
620
- i0.ɵɵconditionalCreate(7, MJOOrderLinesEditorComponent_Conditional_4_Conditional_5_For_2_Conditional_7_Template, 3, 4, "span", 93);
700
+ i0.ɵɵconditionalCreate(7, MJOOrderLinesEditorComponent_Conditional_4_Conditional_5_For_2_Conditional_7_Template, 3, 4, "span", 97);
621
701
  i0.ɵɵelementEnd()();
622
- i0.ɵɵelementStart(8, "span", 94)(9, "span", 95);
702
+ i0.ɵɵelementStart(8, "span", 98)(9, "span", 99);
623
703
  i0.ɵɵtext(10);
624
704
  i0.ɵɵpipe(11, "mjoMoney");
625
705
  i0.ɵɵelementEnd();
626
- i0.ɵɵelementStart(12, "span", 92);
706
+ i0.ɵɵelementStart(12, "span", 96);
627
707
  i0.ɵɵtext(13);
628
708
  i0.ɵɵelementEnd()()();
629
709
  } if (rf & 2) {
630
- const product_r19 = ctx.$implicit;
631
- const ɵ$index_272_r20 = ctx.$index;
710
+ const product_r21 = ctx.$implicit;
711
+ const ɵ$index_300_r22 = ctx.$index;
632
712
  const ctx_r2 = i0.ɵɵnextContext(3);
633
- i0.ɵɵclassProp("is-cursor", ɵ$index_272_r20 === ctx_r2.PickerCursor);
634
- i0.ɵɵattribute("aria-selected", ɵ$index_272_r20 === ctx_r2.PickerCursor);
713
+ i0.ɵɵclassProp("is-cursor", ɵ$index_300_r22 === ctx_r2.PickerCursor);
714
+ i0.ɵɵattribute("aria-selected", ɵ$index_300_r22 === ctx_r2.PickerCursor);
635
715
  i0.ɵɵadvance(3);
636
- i0.ɵɵtextInterpolate(product_r19.Name);
716
+ i0.ɵɵtextInterpolate(product_r21.Name);
637
717
  i0.ɵɵadvance(3);
638
- i0.ɵɵtextInterpolate2("", product_r19.SKU, " \u00B7 ", product_r19.TypeName);
718
+ i0.ɵɵtextInterpolate2("", product_r21.SKU, " \u00B7 ", product_r21.TypeName);
639
719
  i0.ɵɵadvance();
640
- i0.ɵɵconditional(product_r19.CompanyName ? 7 : -1);
720
+ i0.ɵɵconditional(product_r21.CompanyName ? 7 : -1);
641
721
  i0.ɵɵadvance(3);
642
- i0.ɵɵtextInterpolate(i0.ɵɵpipeBind1(11, 9, product_r19.ListPrice));
722
+ i0.ɵɵtextInterpolate(i0.ɵɵpipeBind1(11, 9, product_r21.ListPrice));
643
723
  i0.ɵɵadvance(3);
644
- i0.ɵɵtextInterpolate(product_r19.Taxable ? "taxable" : "untaxable");
724
+ i0.ɵɵtextInterpolate(product_r21.Taxable ? "taxable" : "untaxable");
645
725
  } }
646
726
  function MJOOrderLinesEditorComponent_Conditional_4_Conditional_5_ForEmpty_3_Conditional_2_Template(rf, ctx) { if (rf & 1) {
647
727
  i0.ɵɵtext(0);
@@ -656,7 +736,7 @@ function MJOOrderLinesEditorComponent_Conditional_4_Conditional_5_ForEmpty_3_Con
656
736
  i0.ɵɵtext(0, " No product matches that. ");
657
737
  } }
658
738
  function MJOOrderLinesEditorComponent_Conditional_4_Conditional_5_ForEmpty_3_Template(rf, ctx) { if (rf & 1) {
659
- i0.ɵɵelementStart(0, "div", 87)(1, "span", 98);
739
+ i0.ɵɵelementStart(0, "div", 91)(1, "span", 102);
660
740
  i0.ɵɵconditionalCreate(2, MJOOrderLinesEditorComponent_Conditional_4_Conditional_5_ForEmpty_3_Conditional_2_Template, 1, 1)(3, MJOOrderLinesEditorComponent_Conditional_4_Conditional_5_ForEmpty_3_Conditional_3_Template, 1, 0)(4, MJOOrderLinesEditorComponent_Conditional_4_Conditional_5_ForEmpty_3_Conditional_4_Template, 1, 0);
661
741
  i0.ɵɵelementEnd()();
662
742
  } if (rf & 2) {
@@ -665,8 +745,8 @@ function MJOOrderLinesEditorComponent_Conditional_4_Conditional_5_ForEmpty_3_Tem
665
745
  i0.ɵɵconditional(ctx_r2.CatalogError ? 2 : ctx_r2.Catalog.length === 0 ? 3 : 4);
666
746
  } }
667
747
  function MJOOrderLinesEditorComponent_Conditional_4_Conditional_5_Template(rf, ctx) { if (rf & 1) {
668
- i0.ɵɵelementStart(0, "div", 85);
669
- i0.ɵɵrepeaterCreate(1, MJOOrderLinesEditorComponent_Conditional_4_Conditional_5_For_2_Template, 14, 11, "button", 86, _forTrack0, false, MJOOrderLinesEditorComponent_Conditional_4_Conditional_5_ForEmpty_3_Template, 5, 1, "div", 87);
748
+ i0.ɵɵelementStart(0, "div", 89);
749
+ i0.ɵɵrepeaterCreate(1, MJOOrderLinesEditorComponent_Conditional_4_Conditional_5_For_2_Template, 14, 11, "button", 90, _forTrack0, false, MJOOrderLinesEditorComponent_Conditional_4_Conditional_5_ForEmpty_3_Template, 5, 1, "div", 91);
670
750
  i0.ɵɵelementEnd();
671
751
  } if (rf & 2) {
672
752
  const ctx_r2 = i0.ɵɵnextContext(2);
@@ -675,14 +755,14 @@ function MJOOrderLinesEditorComponent_Conditional_4_Conditional_5_Template(rf, c
675
755
  i0.ɵɵrepeater(ctx_r2.PickerResults);
676
756
  } }
677
757
  function MJOOrderLinesEditorComponent_Conditional_4_Template(rf, ctx) { if (rf & 1) {
678
- const _r17 = i0.ɵɵgetCurrentView();
679
- i0.ɵɵelementStart(0, "div", 4, 0)(2, "div", 81);
680
- i0.ɵɵelement(3, "i", 82);
681
- i0.ɵɵelementStart(4, "input", 83);
682
- i0.ɵɵtwoWayListener("ngModelChange", function MJOOrderLinesEditorComponent_Conditional_4_Template_input_ngModelChange_4_listener($event) { i0.ɵɵrestoreView(_r17); const ctx_r2 = i0.ɵɵnextContext(); i0.ɵɵtwoWayBindingSet(ctx_r2.ProductQuery, $event) || (ctx_r2.ProductQuery = $event); return i0.ɵɵresetView($event); });
683
- i0.ɵɵlistener("ngModelChange", function MJOOrderLinesEditorComponent_Conditional_4_Template_input_ngModelChange_4_listener() { i0.ɵɵrestoreView(_r17); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.OnProductQueryChange()); })("focus", function MJOOrderLinesEditorComponent_Conditional_4_Template_input_focus_4_listener() { i0.ɵɵrestoreView(_r17); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.OpenPicker()); })("blur", function MJOOrderLinesEditorComponent_Conditional_4_Template_input_blur_4_listener() { i0.ɵɵrestoreView(_r17); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.ClosePickerSoon()); })("keydown", function MJOOrderLinesEditorComponent_Conditional_4_Template_input_keydown_4_listener($event) { i0.ɵɵrestoreView(_r17); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.OnPickerKey($event)); });
758
+ const _r19 = i0.ɵɵgetCurrentView();
759
+ i0.ɵɵelementStart(0, "div", 4, 0)(2, "div", 85);
760
+ i0.ɵɵelement(3, "i", 86);
761
+ i0.ɵɵelementStart(4, "input", 87);
762
+ i0.ɵɵtwoWayListener("ngModelChange", function MJOOrderLinesEditorComponent_Conditional_4_Template_input_ngModelChange_4_listener($event) { i0.ɵɵrestoreView(_r19); const ctx_r2 = i0.ɵɵnextContext(); i0.ɵɵtwoWayBindingSet(ctx_r2.ProductQuery, $event) || (ctx_r2.ProductQuery = $event); return i0.ɵɵresetView($event); });
763
+ i0.ɵɵlistener("ngModelChange", function MJOOrderLinesEditorComponent_Conditional_4_Template_input_ngModelChange_4_listener() { i0.ɵɵrestoreView(_r19); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.OnProductQueryChange()); })("focus", function MJOOrderLinesEditorComponent_Conditional_4_Template_input_focus_4_listener() { i0.ɵɵrestoreView(_r19); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.OpenPicker()); })("blur", function MJOOrderLinesEditorComponent_Conditional_4_Template_input_blur_4_listener() { i0.ɵɵrestoreView(_r19); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.ClosePickerSoon()); })("keydown", function MJOOrderLinesEditorComponent_Conditional_4_Template_input_keydown_4_listener($event) { i0.ɵɵrestoreView(_r19); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.OnPickerKey($event)); });
684
764
  i0.ɵɵelementEnd()();
685
- i0.ɵɵconditionalCreate(5, MJOOrderLinesEditorComponent_Conditional_4_Conditional_5_Template, 4, 3, "div", 84);
765
+ i0.ɵɵconditionalCreate(5, MJOOrderLinesEditorComponent_Conditional_4_Conditional_5_Template, 4, 3, "div", 88);
686
766
  i0.ɵɵelementEnd();
687
767
  } if (rf & 2) {
688
768
  const ctx_r2 = i0.ɵɵnextContext();
@@ -930,8 +1010,10 @@ export class MJOOrderLinesEditorComponent {
930
1010
  */
931
1011
  ContinuationStartFor(line) {
932
1012
  const subscriptionID = line.RenewsSubscriptionID;
933
- if (!subscriptionID)
934
- return null;
1013
+ // A line that chose to extend what the customer already holds is a continuation too.
1014
+ if (!subscriptionID) {
1015
+ return line.SubscriptionAction === 'ExtendExisting' ? ContinuationStartFrom(this.ExistingHoldingFor(line)) : null;
1016
+ }
935
1017
  if (this.continuationStarts.has(subscriptionID)) {
936
1018
  return this.continuationStarts.get(subscriptionID) ?? null;
937
1019
  }
@@ -976,6 +1058,83 @@ export class MJOOrderLinesEditorComponent {
976
1058
  this.loadingContinuations.delete(subscriptionID);
977
1059
  }
978
1060
  }
1061
+ /* ── The customer already holds this product (golive #299) ──
1062
+ *
1063
+ * At confirm, a subscription line whose subscriber already holds a live subscription to the
1064
+ * product follows the type's ConcurrencyMode, and under ExtendExisting it becomes the next term
1065
+ * and starts the day after current coverage ends, whatever start the line states. So when such a
1066
+ * subscription exists, the card asks which is meant and stores the answer on the line
1067
+ * (`SubscriptionAction`), which the server applies: add a term to the existing subscription, or
1068
+ * start a separate one on this line's dates.
1069
+ *
1070
+ * Renewal lines are left out: they name the subscription they continue.
1071
+ */
1072
+ /** Holdings by `product|org|person`. A present key with `null` means "holds none". */
1073
+ holdings = new Map();
1074
+ loadingHoldings = new Set();
1075
+ /** Who this line is for, resolved the way the server does: the line's ship-to, then the order's. */
1076
+ holdingKey(line) {
1077
+ if (!line.ProductID)
1078
+ return null;
1079
+ const order = this._order;
1080
+ const org = line.ShipToOrganizationID ?? order?.ShipToOrganizationID ?? order?.BillToOrganizationID ?? null;
1081
+ const person = line.ShipToPersonID ?? order?.ShipToPersonID ?? order?.BillToPersonID ?? null;
1082
+ if (!org && !person)
1083
+ return null;
1084
+ return { key: `${line.ProductID}|${org ?? ''}|${person ?? ''}`.toLowerCase(), org, person };
1085
+ }
1086
+ /**
1087
+ * The live subscription this line's subscriber already holds for its product, or null.
1088
+ *
1089
+ * Sync for the template, cached per subscriber and product like `ContinuationStartFor`: an
1090
+ * unseen key starts one read, and a cached `null` is a real answer that is not retried.
1091
+ */
1092
+ ExistingHoldingFor(line) {
1093
+ // Draft lines only. Once booked, the subscriber "holds" the subscription this very line created.
1094
+ if (this._order?.MoneyLocked || line.RenewsSubscriptionID || !this.IsSubscriptionLine(line))
1095
+ return null;
1096
+ const who = this.holdingKey(line);
1097
+ if (!who)
1098
+ return null;
1099
+ if (this.holdings.has(who.key))
1100
+ return this.holdings.get(who.key) ?? null;
1101
+ void this.loadHolding(who.key, line.ProductID, who.org, who.person);
1102
+ return null;
1103
+ }
1104
+ async loadHolding(key, productID, org, person) {
1105
+ if (this.loadingHoldings.has(key))
1106
+ return;
1107
+ this.loadingHoldings.add(key);
1108
+ try {
1109
+ let holding = null;
1110
+ try {
1111
+ holding = await GetExistingHolding(productID, org, person);
1112
+ }
1113
+ finally {
1114
+ // Cached even on failure, so a failing read does not restart on every change
1115
+ // detection. The server still applies its rule, and the confirm reports a moved start.
1116
+ this.holdings.set(key, holding);
1117
+ }
1118
+ this.cdr.detectChanges();
1119
+ }
1120
+ finally {
1121
+ this.loadingHoldings.delete(key);
1122
+ }
1123
+ }
1124
+ /** Where the existing coverage ends, for the prompt. */
1125
+ HoldingCoverageEnd(holding) {
1126
+ return this.dateInputValue(holding.LatestTermEnd);
1127
+ }
1128
+ /** The start an extension would get: the day after the existing coverage ends. */
1129
+ HoldingContinuationStart(holding) {
1130
+ return this.dateInputValue(ContinuationStartFrom(holding));
1131
+ }
1132
+ /** Store the line's answer. Editable while the order's money is; a booked line's answer is history. */
1133
+ SetSubscriptionAction(line, action) {
1134
+ if (!this.EditMode || this._order?.MoneyLocked)
1135
+ return;
1136
+ line.SubscriptionAction = action;
1137
+ }
979
1138
  SetTermStart(line, event) {
980
1139
  if (!this.EditMode)
981
1140
  return;
@@ -1780,7 +1939,7 @@ export class MJOOrderLinesEditorComponent {
1780
1939
  } if (rf & 2) {
1781
1940
  let _t;
1782
1941
  i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.pickerHost = _t.first);
1783
- } }, inputs: { Provider: "Provider", EditMode: "EditMode", Order: "Order" }, outputs: { PricingChanged: "PricingChanged", Navigate: "Navigate" }, decls: 6, vars: 8, consts: [["pickerHost", ""], [1, "mjo-ol"], [1, "mjo-ol-card"], [1, "mjo-ol-empty"], [1, "mj-typeahead", "mjo-ol-picker"], [3, "Closed", "Line", "ProductName", "ProductSKU", "ProductType", "Dimensions", "EditMode"], [1, "mjo-ol-card__top"], [1, "mjo-ol-card__id"], ["type", "button", 1, "mjo-ol-card__name", 3, "click"], [1, "mjo-ol-card__meta"], [1, "mjo-ol-qty"], [1, "mjo-ol-qty__value"], [1, "mjo-ol-card__price"], [1, "mjo-ol-card__price-row"], [1, "mjo-ol-card__amt"], ["type", "button", 1, "mjo-ol-iconbtn", "mjo-ol-price__pencil"], [1, "mjo-ol-overpill"], [3, "Source", "Settled", "Overridden"], ["title", "Discount on this line", 1, "mjo-ol-discpill"], [1, "mjo-ol-card__err"], [1, "mjo-ol-card__tot"], ["type", "button", 1, "mjo-ol-iconbtn", 3, "click"], ["aria-hidden", "true", 1, "fa-solid", "fa-sliders"], ["type", "button", 1, "mjo-ol-iconbtn"], ["role", "region", 1, "mjo-ol-override"], [1, "mjo-ol-card__conseq"], [1, "mjo-ol-card__why"], [1, "mjo-ol-term"], [1, "mjo-ol-ext", 3, "is-open"], ["type", "button", "aria-label", "Decrease quantity", 3, "click"], ["aria-label", "Quantity", 3, "change", "value"], ["type", "button", "aria-label", "Increase quantity", 3, "click", "disabled"], ["type", "button", 1, "mjo-ol-iconbtn", "mjo-ol-price__pencil", 3, "click"], ["aria-hidden", "true", 1, "fa-solid", "fa-pencil"], ["aria-hidden", "true", 1, "fa-regular", "fa-trash-can"], [3, "Line", "OverrideKind", "Applicable", "EngineDefault", "DefaultUnit", "PriceSource", "PricedUnit"], ["role", "group", 1, "mjo-ol-discount"], [1, "mjo-ol-discount__note"], [1, "mjo-ol-override__actions"], ["type", "button", 1, "mjo-ol-override__done", 3, "click", "disabled"], ["type", "button", 1, "mjo-ol-override__reset", 3, "disabled"], [3, "PriceChanged", "Line", "OverrideKind", "Applicable", "EngineDefault", "DefaultUnit", "PriceSource", "PricedUnit"], [1, "mjo-ol-discount__head"], [1, "mjo-ol-discount__title"], [1, "mjo-ol-discount__cap"], [1, "mjo-ol-discount__row"], ["role", "radiogroup", "aria-label", "Discount expressed as", 1, "mjo-ol-discount__mode"], ["type", "button", "role", "radio", 3, "click"], ["type", "number", "step", "0.01", "min", "0", 1, "mjo-ol-discount__val", 3, "input", "value"], [1, "mjo-ol-discount__calc"], [1, "mjo-ol-discount__reason"], ["aria-hidden", "true", 1, "mjo-ol-override__req"], ["rows", "2", "placeholder", "Required \u2014 why value was given away on this line", 3, "input", "value"], ["role", "alert", 1, "mjo-ol-discount__err"], [1, "mjo-ol-discount__staged"], ["type", "button", 1, "mjo-ol-discount__clear", 3, "click"], ["type", "button", 1, "mjo-ol-override__reset", 3, "click", "disabled"], ["Kind", "fulfillment"], ["Kind", "untaxable"], ["Kind", "company"], [1, "mjo-ol-term__label"], [1, "mjo-ol-term__value", "is-dictated"], [1, "mjo-ol-term__value"], [1, "mjo-ol-term__hint"], ["type", "date", 1, "mjo-ol-term__input", 3, "change", "id", "value"], ["type", "button", 1, "mjo-ol-term__reset"], ["type", "button", 1, "mjo-ol-term__reset", 3, "click"], ["role", "alert", 1, "mjo-ol-term__hint", "is-error"], ["type", "date", "aria-label", "Service period start", 1, "mjo-ol-term__input", 3, "change", "id", "value"], ["aria-hidden", "true", 1, "mjo-ol-term__label"], ["type", "date", "aria-label", "Service period end", 1, "mjo-ol-term__input", 3, "change", "value"], [1, "mjo-ol-ext"], ["type", "button", 1, "mjo-ol-ext__toggle", 3, "click"], ["aria-hidden", "true", 1, "fa-solid", "fa-chevron-right", "mjo-ol-ext__chev"], [1, "mjo-ol-ext__label"], [1, "mjo-ol-ext__hint"], [1, "mjo-ol-ext__body", 3, "id"], [1, "mjo-ol-ext__clip"], [3, "FormCreated", "Navigate", "Record", "EditMode", "Config"], ["aria-hidden", "true", 1, "fa-solid", "fa-cart-plus"], [1, "mjo-ol-empty__title"], [1, "mjo-search"], ["aria-hidden", "true", 1, "fa-solid", "fa-plus"], ["placeholder", "Add product \u2014 type a name or SKU\u2026", "autocomplete", "off", "role", "combobox", "aria-label", "Add a product", 3, "ngModelChange", "focus", "blur", "keydown", "ngModel"], ["role", "listbox", 1, "mj-typeahead-list", "is-open", 3, "is-up"], ["role", "listbox", 1, "mj-typeahead-list", "is-open"], ["type", "button", "role", "option", 1, "mj-typeahead-item", "mjo-ol-pick", 3, "is-cursor"], [1, "mj-typeahead-item"], ["type", "button", "role", "option", 1, "mj-typeahead-item", "mjo-ol-pick", 3, "mousedown"], [1, "mjo-ol-pick__body"], [1, "name"], [1, "mjo-ol-pick__meta"], [1, "sub"], [1, "mjo-ol-pick__company", 3, "is-foreign"], [1, "end"], [1, "mjo-ol-pick__price"], [1, "mjo-ol-pick__company"], ["aria-hidden", "true", 1, "fa-solid", "fa-building"], [1, "muted", "small"]], template: function MJOOrderLinesEditorComponent_Template(rf, ctx) { if (rf & 1) {
1942
+ } }, inputs: { Provider: "Provider", EditMode: "EditMode", Order: "Order" }, outputs: { PricingChanged: "PricingChanged", Navigate: "Navigate" }, decls: 6, vars: 8, consts: [["pickerHost", ""], [1, "mjo-ol"], [1, "mjo-ol-card"], [1, "mjo-ol-empty"], [1, "mj-typeahead", "mjo-ol-picker"], [3, "Closed", "Line", "ProductName", "ProductSKU", "ProductType", "Dimensions", "EditMode"], [1, "mjo-ol-card__top"], [1, "mjo-ol-card__id"], ["type", "button", 1, "mjo-ol-card__name", 3, "click"], [1, "mjo-ol-card__meta"], [1, "mjo-ol-qty"], [1, "mjo-ol-qty__value"], [1, "mjo-ol-card__price"], [1, "mjo-ol-card__price-row"], [1, "mjo-ol-card__amt"], ["type", "button", 1, "mjo-ol-iconbtn", "mjo-ol-price__pencil"], [1, "mjo-ol-overpill"], [3, "Source", "Settled", "Overridden"], ["title", "Discount on this line", 1, "mjo-ol-discpill"], [1, "mjo-ol-card__err"], [1, "mjo-ol-card__tot"], ["type", "button", 1, "mjo-ol-iconbtn", 3, "click"], ["aria-hidden", "true", 1, "fa-solid", "fa-sliders"], ["type", "button", 1, "mjo-ol-iconbtn"], ["role", "region", 1, "mjo-ol-override"], [1, "mjo-ol-card__conseq"], [1, "mjo-ol-card__why"], [1, "mjo-ol-term"], [1, "mjo-ol-ext", 3, "is-open"], ["type", "button", "aria-label", "Decrease quantity", 3, "click"], ["aria-label", "Quantity", 3, "change", "value"], ["type", "button", "aria-label", "Increase quantity", 3, "click", "disabled"], ["type", "button", 1, "mjo-ol-iconbtn", "mjo-ol-price__pencil", 3, "click"], ["aria-hidden", "true", 1, "fa-solid", "fa-pencil"], ["aria-hidden", "true", 1, "fa-regular", "fa-trash-can"], [3, "Line", "OverrideKind", "Applicable", "EngineDefault", "DefaultUnit", "PriceSource", "PricedUnit"], ["role", "group", 1, "mjo-ol-discount"], [1, "mjo-ol-discount__note"], [1, "mjo-ol-override__actions"], ["type", "button", 1, "mjo-ol-override__done", 3, "click", "disabled"], ["type", "button", 1, "mjo-ol-override__reset", 3, "disabled"], [3, "PriceChanged", "Line", "OverrideKind", "Applicable", "EngineDefault", "DefaultUnit", "PriceSource", "PricedUnit"], [1, "mjo-ol-discount__head"], [1, "mjo-ol-discount__title"], [1, "mjo-ol-discount__cap"], [1, "mjo-ol-discount__row"], ["role", "radiogroup", "aria-label", "Discount expressed as", 1, "mjo-ol-discount__mode"], ["type", "button", "role", "radio", 3, "click"], ["type", "number", "step", "0.01", "min", "0", 1, "mjo-ol-discount__val", 3, "input", "value"], [1, "mjo-ol-discount__calc"], [1, "mjo-ol-discount__reason"], ["aria-hidden", "true", 1, "mjo-ol-override__req"], ["rows", "2", "placeholder", "Required \u2014 why value was given away on this line", 3, "input", "value"], ["role", "alert", 1, "mjo-ol-discount__err"], [1, "mjo-ol-discount__staged"], ["type", "button", 1, "mjo-ol-discount__clear", 3, "click"], ["type", "button", 1, "mjo-ol-override__reset", 3, "click", "disabled"], ["Kind", "fulfillment"], ["Kind", "untaxable"], ["Kind", "company"], [1, "mjo-ol-term__label"], [1, "mjo-ol-term__value", "is-dictated"], [1, "mjo-ol-term__value"], [1, "mjo-ol-term__hint"], ["role", "group", 1, "mjo-ol-holding"], ["type", "date", 1, "mjo-ol-term__input", 3, "change", "id", "value"], ["type", "button", 1, "mjo-ol-term__reset"], ["type", "button", 1, "mjo-ol-term__reset", 3, "click"], [1, "mjo-ol-holding__text"], [1, "mjo-ol-holding__choices"], ["type", "button", 1, "mjo-ol-holding__choice", 3, "click"], ["role", "alert", 1, "mjo-ol-term__hint", "is-error"], ["type", "date", "aria-label", "Service period start", 1, "mjo-ol-term__input", 3, "change", "id", "value"], ["aria-hidden", "true", 1, "mjo-ol-term__label"], ["type", "date", "aria-label", "Service period end", 1, "mjo-ol-term__input", 3, "change", "value"], [1, "mjo-ol-ext"], ["type", "button", 1, "mjo-ol-ext__toggle", 3, "click"], ["aria-hidden", "true", 1, "fa-solid", "fa-chevron-right", "mjo-ol-ext__chev"], [1, "mjo-ol-ext__label"], [1, "mjo-ol-ext__hint"], [1, "mjo-ol-ext__body", 3, "id"], [1, "mjo-ol-ext__clip"], [3, "FormCreated", "Navigate", "Record", "EditMode", "Config"], ["aria-hidden", "true", 1, "fa-solid", "fa-cart-plus"], [1, "mjo-ol-empty__title"], [1, "mjo-search"], ["aria-hidden", "true", 1, "fa-solid", "fa-plus"], ["placeholder", "Add product \u2014 type a name or SKU\u2026", "autocomplete", "off", "role", "combobox", "aria-label", "Add a product", 3, "ngModelChange", "focus", "blur", "keydown", "ngModel"], ["role", "listbox", 1, "mj-typeahead-list", "is-open", 3, "is-up"], ["role", "listbox", 1, "mj-typeahead-list", "is-open"], ["type", "button", "role", "option", 1, "mj-typeahead-item", "mjo-ol-pick", 3, "is-cursor"], [1, "mj-typeahead-item"], ["type", "button", "role", "option", 1, "mj-typeahead-item", "mjo-ol-pick", 3, "mousedown"], [1, "mjo-ol-pick__body"], [1, "name"], [1, "mjo-ol-pick__meta"], [1, "sub"], [1, "mjo-ol-pick__company", 3, "is-foreign"], [1, "end"], [1, "mjo-ol-pick__price"], [1, "mjo-ol-pick__company"], ["aria-hidden", "true", 1, "fa-solid", "fa-building"], [1, "muted", "small"]], template: function MJOOrderLinesEditorComponent_Template(rf, ctx) { if (rf & 1) {
1784
1943
  i0.ɵɵelementStart(0, "div", 1);
1785
1944
  i0.ɵɵrepeaterCreate(1, MJOOrderLinesEditorComponent_For_2_Template, 34, 25, "div", 2, _forTrack0, false, MJOOrderLinesEditorComponent_ForEmpty_3_Template, 6, 0, "div", 3);
1786
1945
  i0.ɵɵconditionalCreate(4, MJOOrderLinesEditorComponent_Conditional_4_Template, 6, 3, "div", 4);
@@ -1802,7 +1961,7 @@ export class MJOOrderLinesEditorComponent {
1802
1961
  MJOPriceSourceBadgeComponent,
1803
1962
  MJOLinePricePickerComponent,
1804
1963
  MJOOrderLineDetailsPanelComponent,
1805
- MJOMoneyPipe], styles: ["[_nghost-%COMP%] { display: block; }\n\n.mjo-ol[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: var(--mj-space-2);\n}\n\n.mjo-ol-card[_ngcontent-%COMP%] {\n border: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface);\n border-radius: var(--mj-radius-md);\n padding: var(--mj-space-3);\n}\n\n.mjo-ol-card[_ngcontent-%COMP%]:has(.mjo-ol-ext.is-open) {\n padding-bottom: var(--mj-space-1);\n}\n\n.mjo-ol-card__top[_ngcontent-%COMP%] {\n display: flex;\n align-items: flex-start;\n gap: var(--mj-space-3);\n}\n\n.mjo-ol-card__id[_ngcontent-%COMP%] { flex: 1; min-width: 0; }\n\n.mjo-ol-card__name[_ngcontent-%COMP%] {\n display: inline;\n padding: 0;\n border: 0;\n background: transparent;\n font: inherit;\n font-size: var(--mj-text-sm);\n font-weight: var(--mj-font-semibold);\n color: var(--mj-text-link);\n text-align: left;\n cursor: pointer;\n text-decoration: none;\n}\n\n.mjo-ol-card__name[_ngcontent-%COMP%]:hover { text-decoration: underline; }\n\n.mjo-ol-card__meta[_ngcontent-%COMP%] {\n font-size: var(--mj-text-xs);\n color: var(--mj-text-muted);\n margin-top: 2px;\n}\n\n.mjo-ol-qty[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n border: 1px solid var(--mj-border-strong);\n border-radius: var(--mj-radius-md);\n overflow: hidden;\n background: var(--mj-bg-surface);\n flex: none;\n}\n\n.mjo-ol-qty[_ngcontent-%COMP%] button[_ngcontent-%COMP%] {\n border: 0;\n background: transparent;\n cursor: pointer;\n color: var(--mj-text-secondary);\n width: 26px;\n height: 28px;\n font-size: 11px;\n}\n\n.mjo-ol-qty[_ngcontent-%COMP%] button[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: var(--mj-bg-surface-hover);\n color: var(--mj-text-primary);\n}\n\n.mjo-ol-qty[_ngcontent-%COMP%] button[_ngcontent-%COMP%]:disabled {\n cursor: default;\n color: var(--mj-text-disabled);\n}\n\n.mjo-ol-qty[_ngcontent-%COMP%] input[_ngcontent-%COMP%] {\n border: 0;\n outline: 0;\n background: transparent;\n width: 46px;\n text-align: center;\n font: inherit;\n font-variant-numeric: tabular-nums;\n color: inherit;\n}\n\n.mjo-ol-qty.is-locked[_ngcontent-%COMP%] {\n border-color: var(--mj-border-default);\n background: transparent;\n}\n\n.mjo-ol-qty__value[_ngcontent-%COMP%] {\n min-width: 46px;\n padding: 0 10px;\n height: 28px;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n font-variant-numeric: tabular-nums;\n}\n\n.mjo-ol-card__price[_ngcontent-%COMP%] {\n flex: none;\n min-width: 108px;\n display: flex;\n flex-direction: column;\n align-items: center;\n}\n\n.mjo-ol-card__price-row[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 2px;\n height: 28px;\n}\n\n.mjo-ol-price__pencil[_ngcontent-%COMP%] {\n flex: none;\n color: var(--mj-text-muted);\n}\n\n.mjo-ol-price__pencil[_ngcontent-%COMP%]:hover {\n color: var(--mj-text-link);\n background: var(--mj-bg-surface-hover);\n}\n\n.mjo-ol-override[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: var(--mj-space-2);\n margin-top: var(--mj-space-2);\n padding: var(--mj-space-2);\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-md);\n background: var(--mj-bg-surface-subtle, var(--mj-bg-surface));\n}\n\n.mjo-ol-override__req[_ngcontent-%COMP%] {\n font-style: normal;\n color: var(--mj-status-danger-text, #b42318);\n margin-left: 2px;\n}\n\n.mjo-ol-override__actions[_ngcontent-%COMP%] {\n display: flex;\n gap: var(--mj-space-2);\n justify-content: flex-end;\n}\n\n.mjo-ol-override__done[_ngcontent-%COMP%], \n.mjo-ol-override__reset[_ngcontent-%COMP%] {\n border: 0;\n background: transparent;\n cursor: pointer;\n font: inherit;\n font-size: var(--mj-text-xs);\n font-weight: var(--mj-font-semibold);\n padding: 4px 8px;\n border-radius: var(--mj-radius-sm);\n}\n\n.mjo-ol-override__done[_ngcontent-%COMP%] {\n color: var(--mj-text-link);\n}\n\n.mjo-ol-override__reset[_ngcontent-%COMP%] {\n color: var(--mj-text-muted);\n}\n\n.mjo-ol-override__done[_ngcontent-%COMP%]:hover, \n.mjo-ol-override__reset[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-hover);\n}\n\n.mjo-ol-override__done[_ngcontent-%COMP%]:disabled {\n color: var(--mj-text-muted);\n cursor: not-allowed;\n background: transparent;\n}\n\n.mjo-ol-card__amt[_ngcontent-%COMP%] {\n font-variant-numeric: tabular-nums;\n font-weight: var(--mj-font-semibold);\n font-size: var(--mj-text-sm);\n line-height: 28px;\n}\n\n.mjo-ol-overpill[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n margin-top: 4px;\n padding: 1px 8px;\n border-radius: 999px;\n font-size: 10px;\n font-weight: 600;\n letter-spacing: 0.02em;\n color: var(--mj-status-warning-text);\n background: color-mix(in srgb, var(--mj-status-warning-text) 16%, transparent);\n}\n\n.mjo-ol-card__err[_ngcontent-%COMP%] {\n font-size: var(--mj-text-xs);\n color: var(--mj-status-error-text);\n margin-top: 2px;\n}\n\n.mjo-ol-card__tot[_ngcontent-%COMP%] {\n flex: none;\n min-width: 104px;\n height: 28px;\n display: flex;\n align-items: center;\n justify-content: flex-end;\n text-align: right;\n font-variant-numeric: tabular-nums;\n font-weight: var(--mj-font-semibold);\n font-size: var(--mj-text-sm);\n line-height: 28px;\n}\n\n.mjo-ol-iconbtn[_ngcontent-%COMP%] {\n border: 0;\n background: transparent;\n color: var(--mj-text-muted);\n cursor: pointer;\n width: 28px;\n height: 28px;\n border-radius: var(--mj-radius-sm);\n}\n\n.mjo-ol-iconbtn[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-hover);\n color: var(--mj-status-error);\n}\n\n.mjo-ol-card__conseq[_ngcontent-%COMP%] {\n display: flex;\n gap: 6px;\n flex-wrap: wrap;\n margin-top: var(--mj-space-2);\n}\n\n\n\n\n.mjo-ol-term[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: var(--mj-space-2);\n flex-wrap: wrap;\n margin-top: var(--mj-space-2);\n}\n\n.mjo-ol-term__label[_ngcontent-%COMP%] {\n font-size: var(--mj-text-xs);\n color: var(--mj-text-muted);\n}\n\n.mjo-ol-term__input[_ngcontent-%COMP%] {\n height: 28px;\n padding: 0 var(--mj-space-2);\n border: 1px solid var(--mj-border-strong);\n border-radius: var(--mj-radius-md);\n background: var(--mj-bg-surface);\n color: var(--mj-text-primary);\n font: inherit;\n font-size: var(--mj-text-sm);\n}\n\n\n\n\n.mjo-ol-term__input.is-default[_ngcontent-%COMP%] {\n border-color: var(--mj-border-default);\n color: var(--mj-text-secondary);\n}\n\n.mjo-ol-term__value[_ngcontent-%COMP%] {\n font-size: var(--mj-text-sm);\n color: var(--mj-text-primary);\n font-variant-numeric: tabular-nums;\n}\n\n\n\n\n.mjo-ol-term__value.is-dictated[_ngcontent-%COMP%] {\n color: var(--mj-text-secondary);\n}\n\n.mjo-ol-term__reset[_ngcontent-%COMP%] {\n border: 0;\n background: transparent;\n padding: 0;\n color: var(--mj-text-link);\n font-size: var(--mj-text-xs);\n cursor: pointer;\n}\n\n.mjo-ol-term__reset[_ngcontent-%COMP%]:hover {\n text-decoration: underline;\n}\n\n.mjo-ol-term__hint[_ngcontent-%COMP%] {\n font-size: var(--mj-text-xs);\n color: var(--mj-text-muted);\n}\n\n.mjo-ol-term__hint.is-error[_ngcontent-%COMP%] {\n color: var(--mj-status-error-text);\n}\n\n.mjo-ol-card__why[_ngcontent-%COMP%] {\n margin-top: 6px;\n font-size: var(--mj-text-xs);\n color: var(--mj-text-secondary);\n line-height: 1.35;\n}\n\n.mjo-ol-empty[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n gap: var(--mj-space-1);\n padding: var(--mj-space-4) var(--mj-space-3);\n color: var(--mj-text-muted);\n font-size: var(--mj-text-sm);\n text-align: center;\n}\n\n.mjo-ol-empty[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: var(--mj-text-2xl);\n color: var(--mj-brand-primary);\n}\n\n.mjo-ol-empty__title[_ngcontent-%COMP%] {\n font-weight: var(--mj-font-semibold);\n color: var(--mj-text-primary);\n}\n\n.mjo-ol-picker[_ngcontent-%COMP%] {\n position: relative;\n z-index: 20;\n}\n\n.mjo-ol-picker[_ngcontent-%COMP%]:has(.mj-typeahead-list.is-open) {\n z-index: 40;\n}\n\n.mjo-search[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: var(--mj-space-2);\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-strong);\n border-radius: var(--mj-radius-md);\n padding: 8px 10px;\n}\n\n.mjo-search[_ngcontent-%COMP%] i[_ngcontent-%COMP%] { color: var(--mj-text-muted); font-size: 12px; }\n\n.mjo-search[_ngcontent-%COMP%] input[_ngcontent-%COMP%] {\n border: 0;\n outline: 0;\n background: transparent;\n font: inherit;\n font-size: var(--mj-text-sm);\n color: inherit;\n width: 100%;\n}\n\n.mj-typeahead-list[_ngcontent-%COMP%] {\n display: none;\n position: absolute;\n left: 0;\n right: 0;\n top: calc(100% + 4px);\n max-height: 240px;\n overflow: auto;\n background: var(--mj-bg-surface-elevated);\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-md);\n box-shadow: var(--mj-shadow-md, 0 8px 24px rgba(0, 0, 0, 0.18));\n z-index: 30;\n}\n\n.mj-typeahead-list.is-open[_ngcontent-%COMP%] { display: block; }\n\n.mj-typeahead-list.is-up[_ngcontent-%COMP%] {\n top: auto;\n bottom: calc(100% + 4px);\n}\n\n.mj-typeahead-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: var(--mj-space-3);\n width: 100%;\n padding: 8px 12px;\n border: 0;\n border-bottom: 1px solid var(--mj-border-subtle);\n background: transparent;\n color: inherit;\n text-align: left;\n cursor: pointer;\n font: inherit;\n}\n\n.mj-typeahead-item[_ngcontent-%COMP%]:last-child { border-bottom: 0; }\n\n.mj-typeahead-item[_ngcontent-%COMP%]:hover, \n.mj-typeahead-item.is-cursor[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface-hover);\n}\n\n.mjo-ol-pick__body[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 1px;\n min-width: 0;\n}\n\n.mjo-ol-pick[_ngcontent-%COMP%] .name[_ngcontent-%COMP%] { font-size: 13px; font-weight: var(--mj-font-semibold); }\n.mjo-ol-pick[_ngcontent-%COMP%] .sub[_ngcontent-%COMP%] { font-size: 11.5px; color: var(--mj-text-muted); }\n\n\n\n\n\n\n\n\n.mjo-ol-pick__meta[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: var(--mj-space-2);\n min-width: 0;\n}\n\n.mjo-ol-pick__company[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n flex: 0 0 auto;\n font-size: 11px;\n line-height: 1.2;\n padding: 2px 6px;\n border: 1px solid var(--mj-border-subtle);\n border-radius: var(--mj-radius-sm);\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-secondary);\n}\n\n.mjo-ol-pick__company[_ngcontent-%COMP%] i[_ngcontent-%COMP%] { font-size: 9.5px; color: var(--mj-text-muted); }\n\n\n\n.mjo-ol-pick__company.is-foreign[_ngcontent-%COMP%] i[_ngcontent-%COMP%] { color: var(--mj-status-info); }\n.mjo-ol-pick__company.is-foreign[_ngcontent-%COMP%] {\n color: var(--mj-text-primary);\n border-color: var(--mj-border-default);\n}\n.mjo-ol-pick[_ngcontent-%COMP%] .end[_ngcontent-%COMP%] {\n margin-left: auto;\n text-align: right;\n display: flex;\n flex-direction: column;\n gap: 1px;\n flex: 0 0 auto;\n}\n.mjo-ol-pick__price[_ngcontent-%COMP%] {\n font-variant-numeric: tabular-nums;\n font-weight: var(--mj-font-semibold);\n}\n\n.mjo-ol-ext-err[_ngcontent-%COMP%] {\n font-size: var(--mj-text-xs);\n color: var(--mj-status-error-text);\n}\n\n.mjo-ol-ext[_ngcontent-%COMP%] {\n margin-top: var(--mj-space-2);\n padding-top: var(--mj-space-1);\n border-top: 1px dashed var(--mj-border-subtle);\n}\n\n.mjo-ol-ext__toggle[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: var(--mj-space-2);\n width: 100%;\n padding: var(--mj-space-1) 0;\n border: 0;\n background: transparent;\n color: inherit;\n font: inherit;\n text-align: left;\n cursor: pointer;\n border-radius: var(--mj-radius-sm);\n}\n\n.mjo-ol-ext__toggle[_ngcontent-%COMP%]:hover {\n color: var(--mj-text-primary);\n}\n\n.mjo-ol-ext__toggle[_ngcontent-%COMP%]:focus-visible {\n outline: 2px solid var(--mj-border-focus);\n outline-offset: 2px;\n}\n\n.mjo-ol-ext__chev[_ngcontent-%COMP%] {\n flex: none;\n width: 12px;\n font-size: 10px;\n color: var(--mj-text-muted);\n transition: transform 160ms ease;\n}\n\n.mjo-ol-ext.is-open[_ngcontent-%COMP%] .mjo-ol-ext__chev[_ngcontent-%COMP%] {\n transform: rotate(90deg);\n}\n\n.mjo-ol-ext__label[_ngcontent-%COMP%] {\n font-size: var(--mj-text-xs);\n font-weight: var(--mj-font-semibold);\n color: var(--mj-text-secondary);\n letter-spacing: 0.01em;\n}\n\n.mjo-ol-ext__hint[_ngcontent-%COMP%] {\n margin-left: auto;\n font-size: var(--mj-text-xs);\n color: var(--mj-text-muted);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.mjo-ol-ext__body[_ngcontent-%COMP%] {\n display: grid;\n grid-template-rows: 0fr;\n transition: grid-template-rows 180ms ease;\n}\n\n.mjo-ol-ext.is-open[_ngcontent-%COMP%] .mjo-ol-ext__body[_ngcontent-%COMP%] {\n grid-template-rows: 1fr;\n}\n\n.mjo-ol-ext__clip[_ngcontent-%COMP%] {\n overflow: hidden;\n min-height: 0;\n}\n\n\n\n.mjo-ol-ext[_ngcontent-%COMP%] mj-record-form-container, \n.mjo-ol-ext[_ngcontent-%COMP%] .mj-record-form-container, \n.mjo-ol-ext[_ngcontent-%COMP%] .mj-forms-container {\n display: block;\n padding: 0;\n margin: 0;\n border: 0;\n background: transparent;\n box-shadow: none;\n}\n\n.mjo-ol-ext[_ngcontent-%COMP%] .mj-forms-toolbar, \n.mjo-ol-ext[_ngcontent-%COMP%] mj-form-toolbar {\n display: none;\n}\n\n.mjo-ol-ext[_ngcontent-%COMP%] .mj-forms-panel {\n border: 0;\n background: transparent;\n box-shadow: none;\n margin: 0;\n padding: 0;\n}\n\n.mjo-ol-ext[_ngcontent-%COMP%] mj-collapsible-panel + mj-collapsible-panel .mj-forms-panel {\n margin-top: calc(-1 * var(--mj-space-1));\n}\n\n.mjo-ol-ext[_ngcontent-%COMP%] .mj-forms-panel-header {\n display: none;\n}\n\n.mjo-ol-ext[_ngcontent-%COMP%] .mj-forms-panel-body, \n.mjo-ol-ext[_ngcontent-%COMP%] .mj-forms-panel-content {\n max-height: none;\n overflow: visible;\n padding: 0;\n margin: 0;\n}\n\n.mjo-ol-ext[_ngcontent-%COMP%] mj-form-field:last-child, \n.mjo-ol-ext[_ngcontent-%COMP%] .mj-form-field:last-child {\n margin-bottom: 0;\n}\n\n@media (max-width: 720px) {\n .mjo-ol-card__top[_ngcontent-%COMP%] { flex-wrap: wrap; }\n .mjo-ol-card__price[_ngcontent-%COMP%], .mjo-ol-card__tot[_ngcontent-%COMP%] { width: auto; }\n}\n\n\n\n\n\n\n\n.mjo-ol-discount[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: var(--mj-space-2);\n padding-top: var(--mj-space-2);\n border-top: 1px solid var(--mj-border-default);\n}\n\n.mjo-ol-discount__head[_ngcontent-%COMP%] {\n display: flex;\n align-items: baseline;\n justify-content: space-between;\n gap: var(--mj-space-2);\n flex-wrap: wrap;\n}\n\n.mjo-ol-discount__title[_ngcontent-%COMP%] {\n font-size: var(--mj-text-xs);\n font-weight: var(--mj-font-semibold);\n color: var(--mj-text-primary);\n}\n\n.mjo-ol-discount__cap[_ngcontent-%COMP%] {\n font-size: var(--mj-text-xs);\n color: var(--mj-text-muted);\n}\n\n.mjo-ol-discount__row[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: var(--mj-space-2);\n flex-wrap: wrap;\n}\n\n\n\n.mjo-ol-discount__mode[_ngcontent-%COMP%] {\n display: inline-flex;\n border: 1px solid var(--mj-border-strong);\n border-radius: var(--mj-radius-sm);\n overflow: hidden;\n}\n\n.mjo-ol-discount__mode[_ngcontent-%COMP%] button[_ngcontent-%COMP%] {\n border: 0;\n background: var(--mj-bg-surface);\n color: var(--mj-text-muted);\n font: inherit;\n font-size: var(--mj-text-xs);\n padding: 0 10px;\n height: 28px;\n cursor: pointer;\n}\n\n.mjo-ol-discount__mode[_ngcontent-%COMP%] button[_ngcontent-%COMP%] + button[_ngcontent-%COMP%] {\n border-left: 1px solid var(--mj-border-strong);\n}\n\n.mjo-ol-discount__mode[_ngcontent-%COMP%] button.is-on[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface-hover);\n color: var(--mj-text-primary);\n font-weight: var(--mj-font-semibold);\n}\n\n.mjo-ol-discount__val[_ngcontent-%COMP%] {\n width: 96px;\n height: 28px;\n box-sizing: border-box;\n padding: 0 8px;\n border: 1px solid var(--mj-border-strong);\n border-radius: var(--mj-radius-sm);\n background: var(--mj-bg-surface);\n color: inherit;\n font: inherit;\n font-size: var(--mj-text-xs);\n font-variant-numeric: tabular-nums;\n text-align: right;\n}\n\n.mjo-ol-discount__calc[_ngcontent-%COMP%] {\n font-size: var(--mj-text-xs);\n color: var(--mj-text-muted);\n font-variant-numeric: tabular-nums;\n}\n\n.mjo-ol-discount__reason[_ngcontent-%COMP%] span[_ngcontent-%COMP%] {\n display: block;\n font-size: var(--mj-text-xs);\n color: var(--mj-text-muted);\n margin-bottom: 4px;\n}\n\n.mjo-ol-discount__reason[_ngcontent-%COMP%] textarea[_ngcontent-%COMP%] {\n display: block;\n width: 100%;\n box-sizing: border-box;\n resize: vertical;\n min-height: 48px;\n padding: 6px 8px;\n border: 1px solid var(--mj-border-strong);\n border-radius: var(--mj-radius-sm);\n background: var(--mj-bg-surface);\n color: inherit;\n font: inherit;\n font-size: var(--mj-text-xs);\n}\n\n.mjo-ol-discount__reason.is-required[_ngcontent-%COMP%] textarea[_ngcontent-%COMP%] {\n border-color: var(--mj-status-danger-text, #b42318);\n}\n\n.mjo-ol-discount__err[_ngcontent-%COMP%] {\n font-size: var(--mj-text-xs);\n color: var(--mj-status-error-text);\n}\n\n.mjo-ol-discount__note[_ngcontent-%COMP%] {\n font-size: var(--mj-text-xs);\n color: var(--mj-text-muted);\n}\n\n.mjo-ol-discount__staged[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: var(--mj-space-2);\n font-size: var(--mj-text-xs);\n color: var(--mj-text-muted);\n}\n\n.mjo-ol-discount__clear[_ngcontent-%COMP%] {\n border: 1px solid var(--mj-border-strong);\n border-radius: var(--mj-radius-sm);\n background: var(--mj-bg-surface);\n color: inherit;\n font: inherit;\n font-size: var(--mj-text-xs);\n height: 24px;\n padding: 0 10px;\n cursor: pointer;\n}\n\n\n\n\n.mjo-ol-discpill[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n margin-top: 4px;\n padding: 1px 8px;\n border-radius: 999px;\n font-size: 10px;\n font-weight: 600;\n letter-spacing: 0.02em;\n font-variant-numeric: tabular-nums;\n color: var(--mj-status-success-text);\n background: color-mix(in srgb, var(--mj-status-success-text) 16%, transparent);\n}"] });
1964
+ MJOMoneyPipe], styles: ["[_nghost-%COMP%] { display: block; }\n\n.mjo-ol[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: var(--mj-space-2);\n}\n\n.mjo-ol-card[_ngcontent-%COMP%] {\n border: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface);\n border-radius: var(--mj-radius-md);\n padding: var(--mj-space-3);\n}\n\n.mjo-ol-card[_ngcontent-%COMP%]:has(.mjo-ol-ext.is-open) {\n padding-bottom: var(--mj-space-1);\n}\n\n.mjo-ol-card__top[_ngcontent-%COMP%] {\n display: flex;\n align-items: flex-start;\n gap: var(--mj-space-3);\n}\n\n.mjo-ol-card__id[_ngcontent-%COMP%] { flex: 1; min-width: 0; }\n\n.mjo-ol-card__name[_ngcontent-%COMP%] {\n display: inline;\n padding: 0;\n border: 0;\n background: transparent;\n font: inherit;\n font-size: var(--mj-text-sm);\n font-weight: var(--mj-font-semibold);\n color: var(--mj-text-link);\n text-align: left;\n cursor: pointer;\n text-decoration: none;\n}\n\n.mjo-ol-card__name[_ngcontent-%COMP%]:hover { text-decoration: underline; }\n\n.mjo-ol-card__meta[_ngcontent-%COMP%] {\n font-size: var(--mj-text-xs);\n color: var(--mj-text-muted);\n margin-top: 2px;\n}\n\n.mjo-ol-qty[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n border: 1px solid var(--mj-border-strong);\n border-radius: var(--mj-radius-md);\n overflow: hidden;\n background: var(--mj-bg-surface);\n flex: none;\n}\n\n.mjo-ol-qty[_ngcontent-%COMP%] button[_ngcontent-%COMP%] {\n border: 0;\n background: transparent;\n cursor: pointer;\n color: var(--mj-text-secondary);\n width: 26px;\n height: 28px;\n font-size: 11px;\n}\n\n.mjo-ol-qty[_ngcontent-%COMP%] button[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: var(--mj-bg-surface-hover);\n color: var(--mj-text-primary);\n}\n\n.mjo-ol-qty[_ngcontent-%COMP%] button[_ngcontent-%COMP%]:disabled {\n cursor: default;\n color: var(--mj-text-disabled);\n}\n\n.mjo-ol-qty[_ngcontent-%COMP%] input[_ngcontent-%COMP%] {\n border: 0;\n outline: 0;\n background: transparent;\n width: 46px;\n text-align: center;\n font: inherit;\n font-variant-numeric: tabular-nums;\n color: inherit;\n}\n\n.mjo-ol-qty.is-locked[_ngcontent-%COMP%] {\n border-color: var(--mj-border-default);\n background: transparent;\n}\n\n.mjo-ol-qty__value[_ngcontent-%COMP%] {\n min-width: 46px;\n padding: 0 10px;\n height: 28px;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n font-variant-numeric: tabular-nums;\n}\n\n.mjo-ol-card__price[_ngcontent-%COMP%] {\n flex: none;\n min-width: 108px;\n display: flex;\n flex-direction: column;\n align-items: center;\n}\n\n.mjo-ol-card__price-row[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 2px;\n height: 28px;\n}\n\n.mjo-ol-price__pencil[_ngcontent-%COMP%] {\n flex: none;\n color: var(--mj-text-muted);\n}\n\n.mjo-ol-price__pencil[_ngcontent-%COMP%]:hover {\n color: var(--mj-text-link);\n background: var(--mj-bg-surface-hover);\n}\n\n.mjo-ol-override[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: var(--mj-space-2);\n margin-top: var(--mj-space-2);\n padding: var(--mj-space-2);\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-md);\n background: var(--mj-bg-surface-subtle, var(--mj-bg-surface));\n}\n\n.mjo-ol-override__req[_ngcontent-%COMP%] {\n font-style: normal;\n color: var(--mj-status-danger-text, #b42318);\n margin-left: 2px;\n}\n\n.mjo-ol-override__actions[_ngcontent-%COMP%] {\n display: flex;\n gap: var(--mj-space-2);\n justify-content: flex-end;\n}\n\n.mjo-ol-override__done[_ngcontent-%COMP%], \n.mjo-ol-override__reset[_ngcontent-%COMP%] {\n border: 0;\n background: transparent;\n cursor: pointer;\n font: inherit;\n font-size: var(--mj-text-xs);\n font-weight: var(--mj-font-semibold);\n padding: 4px 8px;\n border-radius: var(--mj-radius-sm);\n}\n\n.mjo-ol-override__done[_ngcontent-%COMP%] {\n color: var(--mj-text-link);\n}\n\n.mjo-ol-override__reset[_ngcontent-%COMP%] {\n color: var(--mj-text-muted);\n}\n\n.mjo-ol-override__done[_ngcontent-%COMP%]:hover, \n.mjo-ol-override__reset[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-hover);\n}\n\n.mjo-ol-override__done[_ngcontent-%COMP%]:disabled {\n color: var(--mj-text-muted);\n cursor: not-allowed;\n background: transparent;\n}\n\n.mjo-ol-card__amt[_ngcontent-%COMP%] {\n font-variant-numeric: tabular-nums;\n font-weight: var(--mj-font-semibold);\n font-size: var(--mj-text-sm);\n line-height: 28px;\n}\n\n.mjo-ol-overpill[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n margin-top: 4px;\n padding: 1px 8px;\n border-radius: 999px;\n font-size: 10px;\n font-weight: 600;\n letter-spacing: 0.02em;\n color: var(--mj-status-warning-text);\n background: color-mix(in srgb, var(--mj-status-warning-text) 16%, transparent);\n}\n\n.mjo-ol-card__err[_ngcontent-%COMP%] {\n font-size: var(--mj-text-xs);\n color: var(--mj-status-error-text);\n margin-top: 2px;\n}\n\n.mjo-ol-card__tot[_ngcontent-%COMP%] {\n flex: none;\n min-width: 104px;\n height: 28px;\n display: flex;\n align-items: center;\n justify-content: flex-end;\n text-align: right;\n font-variant-numeric: tabular-nums;\n font-weight: var(--mj-font-semibold);\n font-size: var(--mj-text-sm);\n line-height: 28px;\n}\n\n.mjo-ol-iconbtn[_ngcontent-%COMP%] {\n border: 0;\n background: transparent;\n color: var(--mj-text-muted);\n cursor: pointer;\n width: 28px;\n height: 28px;\n border-radius: var(--mj-radius-sm);\n}\n\n.mjo-ol-iconbtn[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-hover);\n color: var(--mj-status-error);\n}\n\n.mjo-ol-card__conseq[_ngcontent-%COMP%] {\n display: flex;\n gap: 6px;\n flex-wrap: wrap;\n margin-top: var(--mj-space-2);\n}\n\n\n\n\n.mjo-ol-term[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: var(--mj-space-2);\n flex-wrap: wrap;\n margin-top: var(--mj-space-2);\n}\n\n.mjo-ol-term__label[_ngcontent-%COMP%] {\n font-size: var(--mj-text-xs);\n color: var(--mj-text-muted);\n}\n\n.mjo-ol-term__input[_ngcontent-%COMP%] {\n height: 28px;\n padding: 0 var(--mj-space-2);\n border: 1px solid var(--mj-border-strong);\n border-radius: var(--mj-radius-md);\n background: var(--mj-bg-surface);\n color: var(--mj-text-primary);\n font: inherit;\n font-size: var(--mj-text-sm);\n}\n\n\n\n\n.mjo-ol-term__input.is-default[_ngcontent-%COMP%] {\n border-color: var(--mj-border-default);\n color: var(--mj-text-secondary);\n}\n\n.mjo-ol-term__value[_ngcontent-%COMP%] {\n font-size: var(--mj-text-sm);\n color: var(--mj-text-primary);\n font-variant-numeric: tabular-nums;\n}\n\n\n\n\n.mjo-ol-term__value.is-dictated[_ngcontent-%COMP%] {\n color: var(--mj-text-secondary);\n}\n\n.mjo-ol-term__reset[_ngcontent-%COMP%] {\n border: 0;\n background: transparent;\n padding: 0;\n color: var(--mj-text-link);\n font-size: var(--mj-text-xs);\n cursor: pointer;\n}\n\n.mjo-ol-term__reset[_ngcontent-%COMP%]:hover {\n text-decoration: underline;\n}\n\n.mjo-ol-term__hint[_ngcontent-%COMP%] {\n font-size: var(--mj-text-xs);\n color: var(--mj-text-muted);\n}\n\n.mjo-ol-term__hint.is-error[_ngcontent-%COMP%] {\n color: var(--mj-status-error-text);\n}\n\n.mjo-ol-card__why[_ngcontent-%COMP%] {\n margin-top: 6px;\n font-size: var(--mj-text-xs);\n color: var(--mj-text-secondary);\n line-height: 1.35;\n}\n\n.mjo-ol-empty[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n gap: var(--mj-space-1);\n padding: var(--mj-space-4) var(--mj-space-3);\n color: var(--mj-text-muted);\n font-size: var(--mj-text-sm);\n text-align: center;\n}\n\n.mjo-ol-empty[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: var(--mj-text-2xl);\n color: var(--mj-brand-primary);\n}\n\n.mjo-ol-empty__title[_ngcontent-%COMP%] {\n font-weight: var(--mj-font-semibold);\n color: var(--mj-text-primary);\n}\n\n.mjo-ol-picker[_ngcontent-%COMP%] {\n position: relative;\n z-index: 20;\n}\n\n.mjo-ol-picker[_ngcontent-%COMP%]:has(.mj-typeahead-list.is-open) {\n z-index: 40;\n}\n\n.mjo-search[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: var(--mj-space-2);\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-strong);\n border-radius: var(--mj-radius-md);\n padding: 8px 10px;\n}\n\n.mjo-search[_ngcontent-%COMP%] i[_ngcontent-%COMP%] { color: var(--mj-text-muted); font-size: 12px; }\n\n.mjo-search[_ngcontent-%COMP%] input[_ngcontent-%COMP%] {\n border: 0;\n outline: 0;\n background: transparent;\n font: inherit;\n font-size: var(--mj-text-sm);\n color: inherit;\n width: 100%;\n}\n\n.mj-typeahead-list[_ngcontent-%COMP%] {\n display: none;\n position: absolute;\n left: 0;\n right: 0;\n top: calc(100% + 4px);\n max-height: 240px;\n overflow: auto;\n background: var(--mj-bg-surface-elevated);\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-md);\n box-shadow: var(--mj-shadow-md, 0 8px 24px rgba(0, 0, 0, 0.18));\n z-index: 30;\n}\n\n.mj-typeahead-list.is-open[_ngcontent-%COMP%] { display: block; }\n\n.mj-typeahead-list.is-up[_ngcontent-%COMP%] {\n top: auto;\n bottom: calc(100% + 4px);\n}\n\n.mj-typeahead-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: var(--mj-space-3);\n width: 100%;\n padding: 8px 12px;\n border: 0;\n border-bottom: 1px solid var(--mj-border-subtle);\n background: transparent;\n color: inherit;\n text-align: left;\n cursor: pointer;\n font: inherit;\n}\n\n.mj-typeahead-item[_ngcontent-%COMP%]:last-child { border-bottom: 0; }\n\n.mj-typeahead-item[_ngcontent-%COMP%]:hover, \n.mj-typeahead-item.is-cursor[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface-hover);\n}\n\n.mjo-ol-pick__body[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 1px;\n min-width: 0;\n}\n\n.mjo-ol-pick[_ngcontent-%COMP%] .name[_ngcontent-%COMP%] { font-size: 13px; font-weight: var(--mj-font-semibold); }\n.mjo-ol-pick[_ngcontent-%COMP%] .sub[_ngcontent-%COMP%] { font-size: 11.5px; color: var(--mj-text-muted); }\n\n\n\n\n\n\n\n\n.mjo-ol-pick__meta[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: var(--mj-space-2);\n min-width: 0;\n}\n\n.mjo-ol-pick__company[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n flex: 0 0 auto;\n font-size: 11px;\n line-height: 1.2;\n padding: 2px 6px;\n border: 1px solid var(--mj-border-subtle);\n border-radius: var(--mj-radius-sm);\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-secondary);\n}\n\n.mjo-ol-pick__company[_ngcontent-%COMP%] i[_ngcontent-%COMP%] { font-size: 9.5px; color: var(--mj-text-muted); }\n\n\n\n.mjo-ol-pick__company.is-foreign[_ngcontent-%COMP%] i[_ngcontent-%COMP%] { color: var(--mj-status-info); }\n.mjo-ol-pick__company.is-foreign[_ngcontent-%COMP%] {\n color: var(--mj-text-primary);\n border-color: var(--mj-border-default);\n}\n.mjo-ol-pick[_ngcontent-%COMP%] .end[_ngcontent-%COMP%] {\n margin-left: auto;\n text-align: right;\n display: flex;\n flex-direction: column;\n gap: 1px;\n flex: 0 0 auto;\n}\n.mjo-ol-pick__price[_ngcontent-%COMP%] {\n font-variant-numeric: tabular-nums;\n font-weight: var(--mj-font-semibold);\n}\n\n.mjo-ol-ext-err[_ngcontent-%COMP%] {\n font-size: var(--mj-text-xs);\n color: var(--mj-status-error-text);\n}\n\n.mjo-ol-ext[_ngcontent-%COMP%] {\n margin-top: var(--mj-space-2);\n padding-top: var(--mj-space-1);\n border-top: 1px dashed var(--mj-border-subtle);\n}\n\n.mjo-ol-ext__toggle[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: var(--mj-space-2);\n width: 100%;\n padding: var(--mj-space-1) 0;\n border: 0;\n background: transparent;\n color: inherit;\n font: inherit;\n text-align: left;\n cursor: pointer;\n border-radius: var(--mj-radius-sm);\n}\n\n.mjo-ol-ext__toggle[_ngcontent-%COMP%]:hover {\n color: var(--mj-text-primary);\n}\n\n.mjo-ol-ext__toggle[_ngcontent-%COMP%]:focus-visible {\n outline: 2px solid var(--mj-border-focus);\n outline-offset: 2px;\n}\n\n.mjo-ol-ext__chev[_ngcontent-%COMP%] {\n flex: none;\n width: 12px;\n font-size: 10px;\n color: var(--mj-text-muted);\n transition: transform 160ms ease;\n}\n\n.mjo-ol-ext.is-open[_ngcontent-%COMP%] .mjo-ol-ext__chev[_ngcontent-%COMP%] {\n transform: rotate(90deg);\n}\n\n.mjo-ol-ext__label[_ngcontent-%COMP%] {\n font-size: var(--mj-text-xs);\n font-weight: var(--mj-font-semibold);\n color: var(--mj-text-secondary);\n letter-spacing: 0.01em;\n}\n\n.mjo-ol-ext__hint[_ngcontent-%COMP%] {\n margin-left: auto;\n font-size: var(--mj-text-xs);\n color: var(--mj-text-muted);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.mjo-ol-ext__body[_ngcontent-%COMP%] {\n display: grid;\n grid-template-rows: 0fr;\n transition: grid-template-rows 180ms ease;\n}\n\n.mjo-ol-ext.is-open[_ngcontent-%COMP%] .mjo-ol-ext__body[_ngcontent-%COMP%] {\n grid-template-rows: 1fr;\n}\n\n.mjo-ol-ext__clip[_ngcontent-%COMP%] {\n overflow: hidden;\n min-height: 0;\n}\n\n\n\n.mjo-ol-ext[_ngcontent-%COMP%] mj-record-form-container, \n.mjo-ol-ext[_ngcontent-%COMP%] .mj-record-form-container, \n.mjo-ol-ext[_ngcontent-%COMP%] .mj-forms-container {\n display: block;\n padding: 0;\n margin: 0;\n border: 0;\n background: transparent;\n box-shadow: none;\n}\n\n.mjo-ol-ext[_ngcontent-%COMP%] .mj-forms-toolbar, \n.mjo-ol-ext[_ngcontent-%COMP%] mj-form-toolbar {\n display: none;\n}\n\n.mjo-ol-ext[_ngcontent-%COMP%] .mj-forms-panel {\n border: 0;\n background: transparent;\n box-shadow: none;\n margin: 0;\n padding: 0;\n}\n\n.mjo-ol-ext[_ngcontent-%COMP%] mj-collapsible-panel + mj-collapsible-panel .mj-forms-panel {\n margin-top: calc(-1 * var(--mj-space-1));\n}\n\n.mjo-ol-ext[_ngcontent-%COMP%] .mj-forms-panel-header {\n display: none;\n}\n\n.mjo-ol-ext[_ngcontent-%COMP%] .mj-forms-panel-body, \n.mjo-ol-ext[_ngcontent-%COMP%] .mj-forms-panel-content {\n max-height: none;\n overflow: visible;\n padding: 0;\n margin: 0;\n}\n\n.mjo-ol-ext[_ngcontent-%COMP%] mj-form-field:last-child, \n.mjo-ol-ext[_ngcontent-%COMP%] .mj-form-field:last-child {\n margin-bottom: 0;\n}\n\n@media (max-width: 720px) {\n .mjo-ol-card__top[_ngcontent-%COMP%] { flex-wrap: wrap; }\n .mjo-ol-card__price[_ngcontent-%COMP%], .mjo-ol-card__tot[_ngcontent-%COMP%] { width: auto; }\n}\n\n\n\n\n\n\n\n.mjo-ol-discount[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: var(--mj-space-2);\n padding-top: var(--mj-space-2);\n border-top: 1px solid var(--mj-border-default);\n}\n\n.mjo-ol-discount__head[_ngcontent-%COMP%] {\n display: flex;\n align-items: baseline;\n justify-content: space-between;\n gap: var(--mj-space-2);\n flex-wrap: wrap;\n}\n\n.mjo-ol-discount__title[_ngcontent-%COMP%] {\n font-size: var(--mj-text-xs);\n font-weight: var(--mj-font-semibold);\n color: var(--mj-text-primary);\n}\n\n.mjo-ol-discount__cap[_ngcontent-%COMP%] {\n font-size: var(--mj-text-xs);\n color: var(--mj-text-muted);\n}\n\n.mjo-ol-discount__row[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: var(--mj-space-2);\n flex-wrap: wrap;\n}\n\n\n\n.mjo-ol-discount__mode[_ngcontent-%COMP%] {\n display: inline-flex;\n border: 1px solid var(--mj-border-strong);\n border-radius: var(--mj-radius-sm);\n overflow: hidden;\n}\n\n.mjo-ol-discount__mode[_ngcontent-%COMP%] button[_ngcontent-%COMP%] {\n border: 0;\n background: var(--mj-bg-surface);\n color: var(--mj-text-muted);\n font: inherit;\n font-size: var(--mj-text-xs);\n padding: 0 10px;\n height: 28px;\n cursor: pointer;\n}\n\n.mjo-ol-discount__mode[_ngcontent-%COMP%] button[_ngcontent-%COMP%] + button[_ngcontent-%COMP%] {\n border-left: 1px solid var(--mj-border-strong);\n}\n\n.mjo-ol-discount__mode[_ngcontent-%COMP%] button.is-on[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface-hover);\n color: var(--mj-text-primary);\n font-weight: var(--mj-font-semibold);\n}\n\n.mjo-ol-discount__val[_ngcontent-%COMP%] {\n width: 96px;\n height: 28px;\n box-sizing: border-box;\n padding: 0 8px;\n border: 1px solid var(--mj-border-strong);\n border-radius: var(--mj-radius-sm);\n background: var(--mj-bg-surface);\n color: inherit;\n font: inherit;\n font-size: var(--mj-text-xs);\n font-variant-numeric: tabular-nums;\n text-align: right;\n}\n\n.mjo-ol-discount__calc[_ngcontent-%COMP%] {\n font-size: var(--mj-text-xs);\n color: var(--mj-text-muted);\n font-variant-numeric: tabular-nums;\n}\n\n.mjo-ol-discount__reason[_ngcontent-%COMP%] span[_ngcontent-%COMP%] {\n display: block;\n font-size: var(--mj-text-xs);\n color: var(--mj-text-muted);\n margin-bottom: 4px;\n}\n\n.mjo-ol-discount__reason[_ngcontent-%COMP%] textarea[_ngcontent-%COMP%] {\n display: block;\n width: 100%;\n box-sizing: border-box;\n resize: vertical;\n min-height: 48px;\n padding: 6px 8px;\n border: 1px solid var(--mj-border-strong);\n border-radius: var(--mj-radius-sm);\n background: var(--mj-bg-surface);\n color: inherit;\n font: inherit;\n font-size: var(--mj-text-xs);\n}\n\n.mjo-ol-discount__reason.is-required[_ngcontent-%COMP%] textarea[_ngcontent-%COMP%] {\n border-color: var(--mj-status-danger-text, #b42318);\n}\n\n.mjo-ol-discount__err[_ngcontent-%COMP%] {\n font-size: var(--mj-text-xs);\n color: var(--mj-status-error-text);\n}\n\n.mjo-ol-discount__note[_ngcontent-%COMP%] {\n font-size: var(--mj-text-xs);\n color: var(--mj-text-muted);\n}\n\n.mjo-ol-discount__staged[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: var(--mj-space-2);\n font-size: var(--mj-text-xs);\n color: var(--mj-text-muted);\n}\n\n.mjo-ol-discount__clear[_ngcontent-%COMP%] {\n border: 1px solid var(--mj-border-strong);\n border-radius: var(--mj-radius-sm);\n background: var(--mj-bg-surface);\n color: inherit;\n font: inherit;\n font-size: var(--mj-text-xs);\n height: 24px;\n padding: 0 10px;\n cursor: pointer;\n}\n\n\n\n\n.mjo-ol-discpill[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n margin-top: 4px;\n padding: 1px 8px;\n border-radius: 999px;\n font-size: 10px;\n font-weight: 600;\n letter-spacing: 0.02em;\n font-variant-numeric: tabular-nums;\n color: var(--mj-status-success-text);\n background: color-mix(in srgb, var(--mj-status-success-text) 16%, transparent);\n}\n\n\n\n.mjo-ol-holding[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: var(--mj-space-2);\n margin-top: var(--mj-space-2);\n padding: var(--mj-space-2) var(--mj-space-3);\n border: 1px solid var(--mj-status-warning-border);\n border-radius: var(--mj-radius-md);\n background: var(--mj-status-warning-bg);\n font-size: var(--mj-text-sm);\n color: var(--mj-text-primary);\n}\n\n.mjo-ol-holding__choices[_ngcontent-%COMP%] {\n display: flex;\n flex-wrap: wrap;\n gap: var(--mj-space-2);\n}\n\n.mjo-ol-holding__choice[_ngcontent-%COMP%] {\n padding: 4px 10px;\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-full);\n background: var(--mj-bg-surface);\n color: var(--mj-text-primary);\n font: inherit;\n cursor: pointer;\n}\n\n.mjo-ol-holding__choice.is-selected[_ngcontent-%COMP%] {\n border-color: var(--mj-brand-primary);\n color: var(--mj-brand-primary);\n font-weight: var(--mj-font-semibold);\n}"] });
1806
1965
  }
1807
1966
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(MJOOrderLinesEditorComponent, [{
1808
1967
  type: Component,
@@ -1815,7 +1974,7 @@ export class MJOOrderLinesEditorComponent {
1815
1974
  MJOLinePricePickerComponent,
1816
1975
  MJOMoneyPipe,
1817
1976
  MJOOrderLineDetailsPanelComponent,
1818
- ], template: "<div class=\"mjo-ol\">\n @for (line of Lines; track line.ID) {\n <div class=\"mjo-ol-card\">\n <div class=\"mjo-ol-card__top\">\n <div class=\"mjo-ol-card__id\">\n <button type=\"button\" class=\"mjo-ol-card__name\" (click)=\"OpenProduct(line, $event)\">\n {{ ProductFor(line)?.Name ?? 'Product' }}\n </button>\n <div class=\"mjo-ol-card__meta\">\n {{ ProductFor(line)?.SKU }}\n @if (ProductFor(line)?.TypeName) {\n \u00B7 {{ ProductFor(line)?.TypeName }}\n }\n </div>\n </div>\n\n <div class=\"mjo-ol-qty\" [class.is-locked]=\"!EditMode || QuantityCappedToOne(line)\">\n @if (EditMode && !QuantityCappedToOne(line)) {\n <button type=\"button\" (click)=\"Bump(line, -1)\" aria-label=\"Decrease quantity\">\u2212</button>\n <input\n [value]=\"line.Quantity\"\n (change)=\"SetQuantity(line, $event)\"\n aria-label=\"Quantity\">\n <button type=\"button\" (click)=\"Bump(line, 1)\" [disabled]=\"QuantityAtMax(line)\" aria-label=\"Increase quantity\">+</button>\n } @else {\n <span class=\"mjo-ol-qty__value\">{{ line.Quantity }}</span>\n }\n </div>\n\n <div class=\"mjo-ol-card__price\">\n <div class=\"mjo-ol-card__price-row\">\n <div class=\"mjo-ol-card__amt\">{{ DisplayUnit(line) | mjoMoney }}</div>\n <!-- The pencil opens the PRICE editor, the DISCOUNT editor, or both \u2014 a user\n may hold one authority without the other, and an order that can be\n discounted but not re-priced still needs a way in. -->\n @if (CanOverride || CanDiscount) {\n <button\n type=\"button\"\n class=\"mjo-ol-iconbtn mjo-ol-price__pencil\"\n (click)=\"ToggleOverrideEditor(line)\"\n [attr.aria-expanded]=\"IsOverrideEditorOpen(line)\"\n [attr.aria-label]=\"CanOverride ? (IsOverridden(line) ? 'Edit price override' : 'Override price or discount line') : 'Discount line'\">\n <i class=\"fa-solid fa-pencil\" aria-hidden=\"true\"></i>\n </button>\n }\n </div>\n @if (IsOverridden(line)) {\n <span class=\"mjo-ol-overpill\">overridden</span>\n } @else {\n <mjo-price-source-badge\n [Source]=\"PricedLine(line)?.PriceSource ?? null\"\n [Settled]=\"!Pricing.Loading\"\n [Overridden]=\"false\" />\n }\n <!-- A DISCOUNT IS NOT AN OVERRIDE, and the badge says so in its own words: the\n list price held and this much was given away. -->\n @if (HasDiscount(line)) {\n <span class=\"mjo-ol-discpill\" title=\"Discount on this line\">\u2212{{ AppliedDiscount(line) | mjoMoney }}</span>\n }\n @if (PricedLine(line)?.Error; as why) {\n <div class=\"mjo-ol-card__err\">{{ why }}</div>\n }\n </div>\n\n <div class=\"mjo-ol-card__tot\">{{ PricedLine(line)?.NetAmount | mjoMoney }}</div>\n\n <!-- Details, on every line and not just editable ones: a booked line's dimensions are\n what its journal entry carries, which is exactly when someone wants to look. -->\n <button\n type=\"button\"\n class=\"mjo-ol-iconbtn\"\n (click)=\"OpenDetails(line, $event)\"\n [attr.title]=\"DimensionSummary(line)\"\n [attr.aria-label]=\"'Details for ' + (ProductFor(line)?.Name ?? 'line')\">\n <i class=\"fa-solid fa-sliders\" aria-hidden=\"true\"></i>\n </button>\n\n @if (EditMode) {\n <button\n type=\"button\"\n class=\"mjo-ol-iconbtn\"\n (click)=\"Remove(line)\"\n [attr.aria-label]=\"'Remove ' + (ProductFor(line)?.Name ?? 'line')\">\n <i class=\"fa-regular fa-trash-can\" aria-hidden=\"true\"></i>\n </button>\n }\n </div>\n\n @if (IsOverrideEditorOpen(line)) {\n <div class=\"mjo-ol-override\" role=\"region\" [attr.aria-label]=\"'Price and discount for ' + (ProductFor(line)?.Name ?? 'line')\">\n @if (CanOverride) {\n <mjo-line-price-picker\n [Line]=\"line\"\n [OverrideKind]=\"OverrideKind\"\n [Applicable]=\"ApplicableFor(line)\"\n [EngineDefault]=\"PricedLine(line)?.Default\"\n [DefaultUnit]=\"DefaultUnit(line)\"\n [PriceSource]=\"PricedLine(line)?.PriceSource ?? null\"\n [PricedUnit]=\"PricedLine(line)?.UnitPrice ?? null\"\n (PriceChanged)=\"OnLinePriceChanged()\"></mjo-line-price-picker>\n }\n\n <!--\n DISCOUNT \u2014 deliberately its own block, below the price picker and labelled\n apart from it (golive #252). An override restates the price; a discount says\n the list price held and value was given away, and only the second reaches the\n Sales Discounts leg of the booking entry. Presenting them as one control is\n what left the whole discount concept unreachable from the product.\n -->\n @if (CanDiscount) {\n <div class=\"mjo-ol-discount\" role=\"group\" [attr.aria-label]=\"'Discount for ' + (ProductFor(line)?.Name ?? 'line')\">\n <div class=\"mjo-ol-discount__head\">\n <span class=\"mjo-ol-discount__title\">Discount</span>\n <span class=\"mjo-ol-discount__cap\">your authority: {{ DiscountCapLabel }}</span>\n </div>\n @if (CanDiscountLine(line)) {\n <div class=\"mjo-ol-discount__row\">\n <div class=\"mjo-ol-discount__mode\" role=\"radiogroup\" aria-label=\"Discount expressed as\">\n <button\n type=\"button\"\n role=\"radio\"\n [attr.aria-checked]=\"DiscountDraft(line).Mode === 'percent'\"\n [class.is-on]=\"DiscountDraft(line).Mode === 'percent'\"\n (click)=\"SetDiscountMode(line, 'percent')\">%</button>\n <button\n type=\"button\"\n role=\"radio\"\n [attr.aria-checked]=\"DiscountDraft(line).Mode === 'amount'\"\n [class.is-on]=\"DiscountDraft(line).Mode === 'amount'\"\n (click)=\"SetDiscountMode(line, 'amount')\">Amount</button>\n </div>\n <input\n class=\"mjo-ol-discount__val\"\n type=\"number\"\n step=\"0.01\"\n min=\"0\"\n [value]=\"DiscountDraft(line).Value\"\n (input)=\"SetDiscountValue(line, $event)\"\n [attr.placeholder]=\"DiscountDraft(line).Mode === 'percent' ? '0' : '0.00'\"\n [attr.aria-label]=\"DiscountDraft(line).Mode === 'percent' ? 'Discount percent' : 'Discount amount'\">\n <span class=\"mjo-ol-discount__calc\">\n @if (DraftDiscountAmount(line); as amount) {\n \u2212{{ amount | mjoMoney }} of {{ DiscountBase(line) | mjoMoney }}\n } @else {\n {{ DiscountBase(line) | mjoMoney }} left to discount\n }\n </span>\n </div>\n <label class=\"mjo-ol-discount__reason\" [class.is-required]=\"NeedsDiscountReason(line)\">\n <span>Discount Reason @if (DraftDiscountAmount(line)) {<em class=\"mjo-ol-override__req\" aria-hidden=\"true\">*</em>}</span>\n <textarea\n rows=\"2\"\n [value]=\"DiscountDraft(line).Reason\"\n (input)=\"SetDiscountReason(line, $event)\"\n placeholder=\"Required \u2014 why value was given away on this line\"></textarea>\n </label>\n @if (DiscountError(line); as problem) {\n <div class=\"mjo-ol-discount__err\" role=\"alert\">{{ problem }}</div>\n }\n @if (HasStagedDiscount(line)) {\n <div class=\"mjo-ol-discount__staged\">\n <span>Applies when this order is saved.</span>\n <button type=\"button\" class=\"mjo-ol-discount__clear\" (click)=\"ClearDiscount(line)\">Remove</button>\n </div>\n }\n } @else {\n <div class=\"mjo-ol-discount__note\">\n This line is booked, so its money is frozen. Reverse the line to re-sell it at a\n discounted price.\n </div>\n }\n </div>\n } @else if (DiscountUnavailableReason; as why) {\n <div class=\"mjo-ol-discount__note\">{{ why }}</div>\n }\n\n <div class=\"mjo-ol-override__actions\">\n <button\n type=\"button\"\n class=\"mjo-ol-override__done\"\n [disabled]=\"NeedsOverrideReason(line) || NeedsDiscountReason(line)\"\n [attr.title]=\"NeedsOverrideReason(line) ? 'Enter a reason for the price override' : (NeedsDiscountReason(line) ? 'Enter a reason for the discount' : null)\"\n (click)=\"DoneOverrideEditor(line)\">Done</button>\n @if (CanOverride) {\n <button type=\"button\" class=\"mjo-ol-override__reset\" [disabled]=\"!CanRestoreDefault(line)\" (click)=\"ResetOverride(line)\">Use Default Price</button>\n }\n </div>\n </div>\n }\n\n <div class=\"mjo-ol-card__conseq\">\n @if (ProductFor(line); as product) {\n @if (product.TypeName === 'Goods') {\n <mjo-consequence-chip Kind=\"fulfillment\">Ships \u2014 holds the order at Posted</mjo-consequence-chip>\n }\n @if (!product.Taxable) {\n <mjo-consequence-chip Kind=\"untaxable\">Untaxable</mjo-consequence-chip>\n }\n @if (ShowsForeignRevenue(line)) {\n <mjo-consequence-chip Kind=\"company\">Revenue to {{ product.CompanyName }}</mjo-consequence-chip>\n }\n }\n </div>\n @if (OverrideReasonText(line); as why) {\n <div class=\"mjo-ol-card__why\">{{ why }}</div>\n }\n\n <!--\n TERM START \u2014 subscription lines only (D-TERMSTART).\n The order date says when the sale was booked; this says when coverage begins, and an\n agreement settles the two independently. Shown on the card rather than behind the\n extension disclosure because it is a term fact, and not every subscription product\n type has an extension form to hide it in.\n -->\n @if (IsSubscriptionLine(line)) {\n <div class=\"mjo-ol-term\">\n <!-- `for` only when there IS an input to point at. A label targeting a missing\n id is a dead control to a screen reader. -->\n <label\n class=\"mjo-ol-term__label\"\n [attr.for]=\"EditMode && !TermStartIsDictated(line) ? 'mjo-ol-term-' + line.ID : null\">\n Term start\n </label>\n <!-- A renewal of LIVE coverage has no choice to offer: the term begins the day\n after the current one ends. Read-only rather than editable-and-ignored. -->\n @if (TermStartIsDictated(line)) {\n <span class=\"mjo-ol-term__value is-dictated\">{{ ContinuationStartValue(line) }}</span>\n } @else if (EditMode) {\n <input\n type=\"date\"\n class=\"mjo-ol-term__input\"\n [class.is-default]=\"TermStartFollowsOrderDate(line)\"\n [id]=\"'mjo-ol-term-' + line.ID\"\n [value]=\"TermStartValue(line)\"\n (change)=\"SetTermStart(line, $event)\">\n <!-- Offered only when there is something to reset. A button that clears a\n value the line never stated does nothing and invites the reader to\n wonder what it did. -->\n @if (!TermStartFollowsOrderDate(line)) {\n <button\n type=\"button\"\n class=\"mjo-ol-term__reset\"\n (click)=\"ResetTermStart(line)\">\n Reset to order date\n </button>\n }\n } @else {\n <span class=\"mjo-ol-term__value\">{{ TermStartValue(line) }}</span>\n }\n <span class=\"mjo-ol-term__hint\">\n @if (TermStartIsDictated(line)) {\n Continuing existing coverage, so the term begins the day after the current\n one ends \u2014 not something this line can set.\n } @else if (TermStartFollowsOrderDate(line)) {\n Following the order date. The subscription type's rules may still adjust\n the actual start.\n } @else {\n Stated on this line, so a later change to the order date leaves it alone.\n }\n </span>\n </div>\n }\n\n <!--\n SERVICE PERIOD \u2014 deferred lines that neither an event nor a subscription dates.\n The recognition type earns against this window, so the order cannot be confirmed\n without it.\n -->\n @if (NeedsStatedServicePeriod(line)) {\n <div class=\"mjo-ol-term\">\n <label\n class=\"mjo-ol-term__label\"\n [attr.for]=\"CanEditServicePeriod() ? 'mjo-ol-sp-start-' + line.ID : null\">\n Service period\n </label>\n @if (CanEditServicePeriod()) {\n <input\n type=\"date\"\n class=\"mjo-ol-term__input\"\n aria-label=\"Service period start\"\n [id]=\"'mjo-ol-sp-start-' + line.ID\"\n [value]=\"ServicePeriodValue(line, 'Start')\"\n (change)=\"SetServicePeriod(line, 'Start', $event)\">\n <span class=\"mjo-ol-term__label\" aria-hidden=\"true\">to</span>\n <input\n type=\"date\"\n class=\"mjo-ol-term__input\"\n aria-label=\"Service period end\"\n [value]=\"ServicePeriodValue(line, 'End')\"\n (change)=\"SetServicePeriod(line, 'End', $event)\">\n } @else {\n <span class=\"mjo-ol-term__value\">\n {{ ServicePeriodValue(line, 'Start') || '\u2014' }} to {{ ServicePeriodValue(line, 'End') || '\u2014' }}\n </span>\n }\n @if (ServicePeriodBackwards(line)) {\n <span class=\"mjo-ol-term__hint is-error\" role=\"alert\">\n End date must be on or after the start date.\n </span>\n } @else if (ServicePeriodMissing(line)) {\n <span class=\"mjo-ol-term__hint\">\n Needed to confirm: revenue on this line is recognized against these dates.\n </span>\n }\n </div>\n }\n\n @if (ExtensionFor(line); as ext) {\n <div class=\"mjo-ol-ext\" [class.is-open]=\"IsExtensionOpen(line)\">\n <button\n type=\"button\"\n class=\"mjo-ol-ext__toggle\"\n (click)=\"ToggleExtension(line)\"\n [attr.aria-expanded]=\"IsExtensionOpen(line)\"\n [attr.aria-controls]=\"'mjo-ol-ext-' + line.ID\">\n <i class=\"fa-solid fa-chevron-right mjo-ol-ext__chev\" aria-hidden=\"true\"></i>\n <span class=\"mjo-ol-ext__label\">{{ ExtensionLabel(line) }}</span>\n @if (!IsExtensionOpen(line)) {\n <span class=\"mjo-ol-ext__hint\">{{ ExtensionHint(line) }}</span>\n }\n </button>\n <div\n class=\"mjo-ol-ext__body\"\n [id]=\"'mjo-ol-ext-' + line.ID\"\n [attr.inert]=\"IsExtensionOpen(line) ? null : ''\"\n [attr.aria-hidden]=\"!IsExtensionOpen(line)\">\n <div class=\"mjo-ol-ext__clip\">\n <mj-entity-form-host\n [Record]=\"ext\"\n [EditMode]=\"EditMode\"\n [Config]=\"ExtensionFormConfigFor(line)\"\n (FormCreated)=\"OnExtensionFormCreated($event)\"\n (Navigate)=\"OnExtensionNavigate($event)\">\n </mj-entity-form-host>\n </div>\n </div>\n </div>\n }\n </div>\n } @empty {\n <div class=\"mjo-ol-empty\">\n <i class=\"fa-solid fa-cart-plus\" aria-hidden=\"true\"></i>\n <div class=\"mjo-ol-empty__title\">Nothing on this order yet</div>\n <div>Search the catalog to add the first line.</div>\n </div>\n }\n\n @if (EditMode) {\n <div class=\"mj-typeahead mjo-ol-picker\" #pickerHost>\n <div class=\"mjo-search\">\n <i class=\"fa-solid fa-plus\" aria-hidden=\"true\"></i>\n <input\n [(ngModel)]=\"ProductQuery\"\n (ngModelChange)=\"OnProductQueryChange()\"\n (focus)=\"OpenPicker()\"\n (blur)=\"ClosePickerSoon()\"\n (keydown)=\"OnPickerKey($event)\"\n placeholder=\"Add product \u2014 type a name or SKU\u2026\"\n autocomplete=\"off\"\n role=\"combobox\"\n aria-label=\"Add a product\"\n [attr.aria-expanded]=\"PickerOpen\">\n </div>\n\n @if (PickerOpen) {\n <div class=\"mj-typeahead-list is-open\" [class.is-up]=\"PickerOpensUp\" role=\"listbox\">\n @for (product of PickerResults; track product.ID; let i = $index) {\n <button\n type=\"button\"\n class=\"mj-typeahead-item mjo-ol-pick\"\n [class.is-cursor]=\"i === PickerCursor\"\n role=\"option\"\n [attr.aria-selected]=\"i === PickerCursor\"\n (mousedown)=\"AddProduct(product)\">\n <span class=\"mjo-ol-pick__body\">\n <span class=\"name\">{{ product.Name }}</span>\n <span class=\"mjo-ol-pick__meta\">\n <span class=\"sub\">{{ product.SKU }} \u00B7 {{ product.TypeName }}</span>\n @if (product.CompanyName) {\n <span\n class=\"mjo-ol-pick__company\"\n [class.is-foreign]=\"IsForeignCompany(product)\"\n [attr.title]=\"IsForeignCompany(product)\n ? 'Sold by ' + product.CompanyName + ', not this order\\'s company'\n : product.CompanyName\">\n <i class=\"fa-solid fa-building\" aria-hidden=\"true\"></i>\n {{ product.CompanyName }}\n </span>\n }\n </span>\n </span>\n <span class=\"end\">\n <span class=\"mjo-ol-pick__price\">{{ product.ListPrice | mjoMoney }}</span>\n <span class=\"sub\">{{ product.Taxable ? 'taxable' : 'untaxable' }}</span>\n </span>\n </button>\n } @empty {\n <div class=\"mj-typeahead-item\">\n <span class=\"muted small\">\n @if (CatalogError) { {{ CatalogError }} }\n @else if (Catalog.length === 0) { Loading catalog\u2026 }\n @else { No product matches that. }\n </span>\n </div>\n }\n </div>\n }\n </div>\n }\n\n <!-- Line details. Rendered once and handed whichever line is open, rather than one per card:\n the panel is modal, so a second instance could never be visible. -->\n <mjo-order-line-details-panel\n [Line]=\"DetailsLine\"\n [ProductName]=\"DetailsLine ? (ProductFor(DetailsLine)?.Name ?? '') : ''\"\n [ProductSKU]=\"DetailsLine ? (ProductFor(DetailsLine)?.SKU ?? '') : ''\"\n [ProductType]=\"DetailsLine ? (ProductFor(DetailsLine)?.TypeName ?? '') : ''\"\n [Dimensions]=\"DimensionCatalog\"\n [EditMode]=\"EditMode\"\n (Closed)=\"CloseDetails()\">\n </mjo-order-line-details-panel>\n</div>\n", styles: [":host { display: block; }\n\n.mjo-ol {\n display: flex;\n flex-direction: column;\n gap: var(--mj-space-2);\n}\n\n.mjo-ol-card {\n border: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface);\n border-radius: var(--mj-radius-md);\n padding: var(--mj-space-3);\n}\n\n.mjo-ol-card:has(.mjo-ol-ext.is-open) {\n padding-bottom: var(--mj-space-1);\n}\n\n.mjo-ol-card__top {\n display: flex;\n align-items: flex-start;\n gap: var(--mj-space-3);\n}\n\n.mjo-ol-card__id { flex: 1; min-width: 0; }\n\n.mjo-ol-card__name {\n display: inline;\n padding: 0;\n border: 0;\n background: transparent;\n font: inherit;\n font-size: var(--mj-text-sm);\n font-weight: var(--mj-font-semibold);\n color: var(--mj-text-link);\n text-align: left;\n cursor: pointer;\n text-decoration: none;\n}\n\n.mjo-ol-card__name:hover { text-decoration: underline; }\n\n.mjo-ol-card__meta {\n font-size: var(--mj-text-xs);\n color: var(--mj-text-muted);\n margin-top: 2px;\n}\n\n.mjo-ol-qty {\n display: inline-flex;\n align-items: center;\n border: 1px solid var(--mj-border-strong);\n border-radius: var(--mj-radius-md);\n overflow: hidden;\n background: var(--mj-bg-surface);\n flex: none;\n}\n\n.mjo-ol-qty button {\n border: 0;\n background: transparent;\n cursor: pointer;\n color: var(--mj-text-secondary);\n width: 26px;\n height: 28px;\n font-size: 11px;\n}\n\n.mjo-ol-qty button:hover:not(:disabled) {\n background: var(--mj-bg-surface-hover);\n color: var(--mj-text-primary);\n}\n\n.mjo-ol-qty button:disabled {\n cursor: default;\n color: var(--mj-text-disabled);\n}\n\n.mjo-ol-qty input {\n border: 0;\n outline: 0;\n background: transparent;\n width: 46px;\n text-align: center;\n font: inherit;\n font-variant-numeric: tabular-nums;\n color: inherit;\n}\n\n.mjo-ol-qty.is-locked {\n border-color: var(--mj-border-default);\n background: transparent;\n}\n\n.mjo-ol-qty__value {\n min-width: 46px;\n padding: 0 10px;\n height: 28px;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n font-variant-numeric: tabular-nums;\n}\n\n.mjo-ol-card__price {\n flex: none;\n min-width: 108px;\n display: flex;\n flex-direction: column;\n align-items: center;\n}\n\n.mjo-ol-card__price-row {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 2px;\n height: 28px;\n}\n\n.mjo-ol-price__pencil {\n flex: none;\n color: var(--mj-text-muted);\n}\n\n.mjo-ol-price__pencil:hover {\n color: var(--mj-text-link);\n background: var(--mj-bg-surface-hover);\n}\n\n.mjo-ol-override {\n display: flex;\n flex-direction: column;\n gap: var(--mj-space-2);\n margin-top: var(--mj-space-2);\n padding: var(--mj-space-2);\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-md);\n background: var(--mj-bg-surface-subtle, var(--mj-bg-surface));\n}\n\n.mjo-ol-override__req {\n font-style: normal;\n color: var(--mj-status-danger-text, #b42318);\n margin-left: 2px;\n}\n\n.mjo-ol-override__actions {\n display: flex;\n gap: var(--mj-space-2);\n justify-content: flex-end;\n}\n\n.mjo-ol-override__done,\n.mjo-ol-override__reset {\n border: 0;\n background: transparent;\n cursor: pointer;\n font: inherit;\n font-size: var(--mj-text-xs);\n font-weight: var(--mj-font-semibold);\n padding: 4px 8px;\n border-radius: var(--mj-radius-sm);\n}\n\n.mjo-ol-override__done {\n color: var(--mj-text-link);\n}\n\n.mjo-ol-override__reset {\n color: var(--mj-text-muted);\n}\n\n.mjo-ol-override__done:hover,\n.mjo-ol-override__reset:hover {\n background: var(--mj-bg-surface-hover);\n}\n\n.mjo-ol-override__done:disabled {\n color: var(--mj-text-muted);\n cursor: not-allowed;\n background: transparent;\n}\n\n.mjo-ol-card__amt {\n font-variant-numeric: tabular-nums;\n font-weight: var(--mj-font-semibold);\n font-size: var(--mj-text-sm);\n line-height: 28px;\n}\n\n.mjo-ol-overpill {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n margin-top: 4px;\n padding: 1px 8px;\n border-radius: 999px;\n font-size: 10px;\n font-weight: 600;\n letter-spacing: 0.02em;\n color: var(--mj-status-warning-text);\n background: color-mix(in srgb, var(--mj-status-warning-text) 16%, transparent);\n}\n\n.mjo-ol-card__err {\n font-size: var(--mj-text-xs);\n color: var(--mj-status-error-text);\n margin-top: 2px;\n}\n\n.mjo-ol-card__tot {\n flex: none;\n min-width: 104px;\n height: 28px;\n display: flex;\n align-items: center;\n justify-content: flex-end;\n text-align: right;\n font-variant-numeric: tabular-nums;\n font-weight: var(--mj-font-semibold);\n font-size: var(--mj-text-sm);\n line-height: 28px;\n}\n\n.mjo-ol-iconbtn {\n border: 0;\n background: transparent;\n color: var(--mj-text-muted);\n cursor: pointer;\n width: 28px;\n height: 28px;\n border-radius: var(--mj-radius-sm);\n}\n\n.mjo-ol-iconbtn:hover {\n background: var(--mj-bg-surface-hover);\n color: var(--mj-status-error);\n}\n\n.mjo-ol-card__conseq {\n display: flex;\n gap: 6px;\n flex-wrap: wrap;\n margin-top: var(--mj-space-2);\n}\n\n/* Term start \u2014 subscription lines only. One row that wraps, so the hint drops below the field on a\n narrow card rather than squeezing the date input. */\n.mjo-ol-term {\n display: flex;\n align-items: center;\n gap: var(--mj-space-2);\n flex-wrap: wrap;\n margin-top: var(--mj-space-2);\n}\n\n.mjo-ol-term__label {\n font-size: var(--mj-text-xs);\n color: var(--mj-text-muted);\n}\n\n.mjo-ol-term__input {\n height: 28px;\n padding: 0 var(--mj-space-2);\n border: 1px solid var(--mj-border-strong);\n border-radius: var(--mj-radius-md);\n background: var(--mj-bg-surface);\n color: var(--mj-text-primary);\n font: inherit;\n font-size: var(--mj-text-sm);\n}\n\n/* A DEFAULT reads quieter than a stated value \u2014 the same distinction the order header draws\n between a date somebody chose and one that fell out of a rule. */\n.mjo-ol-term__input.is-default {\n border-color: var(--mj-border-default);\n color: var(--mj-text-secondary);\n}\n\n.mjo-ol-term__value {\n font-size: var(--mj-text-sm);\n color: var(--mj-text-primary);\n font-variant-numeric: tabular-nums;\n}\n\n/* A dictated date is a FACT, not a disabled input: shown in the read-mode weight in edit mode too,\n so nothing on the card suggests a control that has been switched off. */\n.mjo-ol-term__value.is-dictated {\n color: var(--mj-text-secondary);\n}\n\n.mjo-ol-term__reset {\n border: 0;\n background: transparent;\n padding: 0;\n color: var(--mj-text-link);\n font-size: var(--mj-text-xs);\n cursor: pointer;\n}\n\n.mjo-ol-term__reset:hover {\n text-decoration: underline;\n}\n\n.mjo-ol-term__hint {\n font-size: var(--mj-text-xs);\n color: var(--mj-text-muted);\n}\n\n.mjo-ol-term__hint.is-error {\n color: var(--mj-status-error-text);\n}\n\n.mjo-ol-card__why {\n margin-top: 6px;\n font-size: var(--mj-text-xs);\n color: var(--mj-text-secondary);\n line-height: 1.35;\n}\n\n.mjo-ol-empty {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n gap: var(--mj-space-1);\n padding: var(--mj-space-4) var(--mj-space-3);\n color: var(--mj-text-muted);\n font-size: var(--mj-text-sm);\n text-align: center;\n}\n\n.mjo-ol-empty i {\n font-size: var(--mj-text-2xl);\n color: var(--mj-brand-primary);\n}\n\n.mjo-ol-empty__title {\n font-weight: var(--mj-font-semibold);\n color: var(--mj-text-primary);\n}\n\n.mjo-ol-picker {\n position: relative;\n z-index: 20;\n}\n\n.mjo-ol-picker:has(.mj-typeahead-list.is-open) {\n z-index: 40;\n}\n\n.mjo-search {\n display: flex;\n align-items: center;\n gap: var(--mj-space-2);\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-strong);\n border-radius: var(--mj-radius-md);\n padding: 8px 10px;\n}\n\n.mjo-search i { color: var(--mj-text-muted); font-size: 12px; }\n\n.mjo-search input {\n border: 0;\n outline: 0;\n background: transparent;\n font: inherit;\n font-size: var(--mj-text-sm);\n color: inherit;\n width: 100%;\n}\n\n.mj-typeahead-list {\n display: none;\n position: absolute;\n left: 0;\n right: 0;\n top: calc(100% + 4px);\n max-height: 240px;\n overflow: auto;\n background: var(--mj-bg-surface-elevated);\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-md);\n box-shadow: var(--mj-shadow-md, 0 8px 24px rgba(0, 0, 0, 0.18));\n z-index: 30;\n}\n\n.mj-typeahead-list.is-open { display: block; }\n\n.mj-typeahead-list.is-up {\n top: auto;\n bottom: calc(100% + 4px);\n}\n\n.mj-typeahead-item {\n display: flex;\n align-items: center;\n gap: var(--mj-space-3);\n width: 100%;\n padding: 8px 12px;\n border: 0;\n border-bottom: 1px solid var(--mj-border-subtle);\n background: transparent;\n color: inherit;\n text-align: left;\n cursor: pointer;\n font: inherit;\n}\n\n.mj-typeahead-item:last-child { border-bottom: 0; }\n\n.mj-typeahead-item:hover,\n.mj-typeahead-item.is-cursor {\n background: var(--mj-bg-surface-hover);\n}\n\n.mjo-ol-pick__body {\n display: flex;\n flex-direction: column;\n gap: 1px;\n min-width: 0;\n}\n\n.mjo-ol-pick .name { font-size: 13px; font-weight: var(--mj-font-semibold); }\n.mjo-ol-pick .sub { font-size: 11.5px; color: var(--mj-text-muted); }\n\n/*\n COMPANY IS ITS OWN ELEMENT, not the third item in a muted \"SKU \u00B7 type \u00B7 company\" run.\n Two similarly named products from different companies are exactly what this picker has to let\n someone tell apart before they pick, and a company set in the same muted grey as everything\n else, in third position, is not something anyone reads at speed.\n*/\n.mjo-ol-pick__meta {\n display: flex;\n align-items: center;\n gap: var(--mj-space-2);\n min-width: 0;\n}\n\n.mjo-ol-pick__company {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n flex: 0 0 auto;\n font-size: 11px;\n line-height: 1.2;\n padding: 2px 6px;\n border: 1px solid var(--mj-border-subtle);\n border-radius: var(--mj-radius-sm);\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-secondary);\n}\n\n.mjo-ol-pick__company i { font-size: 9.5px; color: var(--mj-text-muted); }\n\n/* Another company's product \u2014 offered on purpose (BCC sells SoundPost), so it is marked, not hidden. */\n.mjo-ol-pick__company.is-foreign i { color: var(--mj-status-info); }\n.mjo-ol-pick__company.is-foreign {\n color: var(--mj-text-primary);\n border-color: var(--mj-border-default);\n}\n.mjo-ol-pick .end {\n margin-left: auto;\n text-align: right;\n display: flex;\n flex-direction: column;\n gap: 1px;\n flex: 0 0 auto;\n}\n.mjo-ol-pick__price {\n font-variant-numeric: tabular-nums;\n font-weight: var(--mj-font-semibold);\n}\n\n.mjo-ol-ext-err {\n font-size: var(--mj-text-xs);\n color: var(--mj-status-error-text);\n}\n\n.mjo-ol-ext {\n margin-top: var(--mj-space-2);\n padding-top: var(--mj-space-1);\n border-top: 1px dashed var(--mj-border-subtle);\n}\n\n.mjo-ol-ext__toggle {\n display: flex;\n align-items: center;\n gap: var(--mj-space-2);\n width: 100%;\n padding: var(--mj-space-1) 0;\n border: 0;\n background: transparent;\n color: inherit;\n font: inherit;\n text-align: left;\n cursor: pointer;\n border-radius: var(--mj-radius-sm);\n}\n\n.mjo-ol-ext__toggle:hover {\n color: var(--mj-text-primary);\n}\n\n.mjo-ol-ext__toggle:focus-visible {\n outline: 2px solid var(--mj-border-focus);\n outline-offset: 2px;\n}\n\n.mjo-ol-ext__chev {\n flex: none;\n width: 12px;\n font-size: 10px;\n color: var(--mj-text-muted);\n transition: transform 160ms ease;\n}\n\n.mjo-ol-ext.is-open .mjo-ol-ext__chev {\n transform: rotate(90deg);\n}\n\n.mjo-ol-ext__label {\n font-size: var(--mj-text-xs);\n font-weight: var(--mj-font-semibold);\n color: var(--mj-text-secondary);\n letter-spacing: 0.01em;\n}\n\n.mjo-ol-ext__hint {\n margin-left: auto;\n font-size: var(--mj-text-xs);\n color: var(--mj-text-muted);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.mjo-ol-ext__body {\n display: grid;\n grid-template-rows: 0fr;\n transition: grid-template-rows 180ms ease;\n}\n\n.mjo-ol-ext.is-open .mjo-ol-ext__body {\n grid-template-rows: 1fr;\n}\n\n.mjo-ol-ext__clip {\n overflow: hidden;\n min-height: 0;\n}\n\n/* Flatten the embedded extension form so its fields sit in the line card. */\n.mjo-ol-ext ::ng-deep mj-record-form-container,\n.mjo-ol-ext ::ng-deep .mj-record-form-container,\n.mjo-ol-ext ::ng-deep .mj-forms-container {\n display: block;\n padding: 0;\n margin: 0;\n border: 0;\n background: transparent;\n box-shadow: none;\n}\n\n.mjo-ol-ext ::ng-deep .mj-forms-toolbar,\n.mjo-ol-ext ::ng-deep mj-form-toolbar {\n display: none;\n}\n\n.mjo-ol-ext ::ng-deep .mj-forms-panel {\n border: 0;\n background: transparent;\n box-shadow: none;\n margin: 0;\n padding: 0;\n}\n\n.mjo-ol-ext ::ng-deep mj-collapsible-panel + mj-collapsible-panel .mj-forms-panel {\n margin-top: calc(-1 * var(--mj-space-1));\n}\n\n.mjo-ol-ext ::ng-deep .mj-forms-panel-header {\n display: none;\n}\n\n.mjo-ol-ext ::ng-deep .mj-forms-panel-body,\n.mjo-ol-ext ::ng-deep .mj-forms-panel-content {\n max-height: none;\n overflow: visible;\n padding: 0;\n margin: 0;\n}\n\n.mjo-ol-ext ::ng-deep mj-form-field:last-child,\n.mjo-ol-ext ::ng-deep .mj-form-field:last-child {\n margin-bottom: 0;\n}\n\n@media (max-width: 720px) {\n .mjo-ol-card__top { flex-wrap: wrap; }\n .mjo-ol-card__price, .mjo-ol-card__tot { width: auto; }\n}\n\n/* \u2500\u2500 DISCOUNT \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n Its own bordered block inside the price editor, because a discount and a price\n override are different economics and the report that produced this control said\n so: presenting them as one thing is what made the discount concept unreachable.\n The rule above the block is the separator \u2014 the two never read as one form. */\n.mjo-ol-discount {\n display: flex;\n flex-direction: column;\n gap: var(--mj-space-2);\n padding-top: var(--mj-space-2);\n border-top: 1px solid var(--mj-border-default);\n}\n\n.mjo-ol-discount__head {\n display: flex;\n align-items: baseline;\n justify-content: space-between;\n gap: var(--mj-space-2);\n flex-wrap: wrap;\n}\n\n.mjo-ol-discount__title {\n font-size: var(--mj-text-xs);\n font-weight: var(--mj-font-semibold);\n color: var(--mj-text-primary);\n}\n\n.mjo-ol-discount__cap {\n font-size: var(--mj-text-xs);\n color: var(--mj-text-muted);\n}\n\n.mjo-ol-discount__row {\n display: flex;\n align-items: center;\n gap: var(--mj-space-2);\n flex-wrap: wrap;\n}\n\n/* Two buttons that behave as one control, so they are drawn as one. */\n.mjo-ol-discount__mode {\n display: inline-flex;\n border: 1px solid var(--mj-border-strong);\n border-radius: var(--mj-radius-sm);\n overflow: hidden;\n}\n\n.mjo-ol-discount__mode button {\n border: 0;\n background: var(--mj-bg-surface);\n color: var(--mj-text-muted);\n font: inherit;\n font-size: var(--mj-text-xs);\n padding: 0 10px;\n height: 28px;\n cursor: pointer;\n}\n\n.mjo-ol-discount__mode button + button {\n border-left: 1px solid var(--mj-border-strong);\n}\n\n.mjo-ol-discount__mode button.is-on {\n background: var(--mj-bg-surface-hover);\n color: var(--mj-text-primary);\n font-weight: var(--mj-font-semibold);\n}\n\n.mjo-ol-discount__val {\n width: 96px;\n height: 28px;\n box-sizing: border-box;\n padding: 0 8px;\n border: 1px solid var(--mj-border-strong);\n border-radius: var(--mj-radius-sm);\n background: var(--mj-bg-surface);\n color: inherit;\n font: inherit;\n font-size: var(--mj-text-xs);\n font-variant-numeric: tabular-nums;\n text-align: right;\n}\n\n.mjo-ol-discount__calc {\n font-size: var(--mj-text-xs);\n color: var(--mj-text-muted);\n font-variant-numeric: tabular-nums;\n}\n\n.mjo-ol-discount__reason span {\n display: block;\n font-size: var(--mj-text-xs);\n color: var(--mj-text-muted);\n margin-bottom: 4px;\n}\n\n.mjo-ol-discount__reason textarea {\n display: block;\n width: 100%;\n box-sizing: border-box;\n resize: vertical;\n min-height: 48px;\n padding: 6px 8px;\n border: 1px solid var(--mj-border-strong);\n border-radius: var(--mj-radius-sm);\n background: var(--mj-bg-surface);\n color: inherit;\n font: inherit;\n font-size: var(--mj-text-xs);\n}\n\n.mjo-ol-discount__reason.is-required textarea {\n border-color: var(--mj-status-danger-text, #b42318);\n}\n\n.mjo-ol-discount__err {\n font-size: var(--mj-text-xs);\n color: var(--mj-status-error-text);\n}\n\n.mjo-ol-discount__note {\n font-size: var(--mj-text-xs);\n color: var(--mj-text-muted);\n}\n\n.mjo-ol-discount__staged {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: var(--mj-space-2);\n font-size: var(--mj-text-xs);\n color: var(--mj-text-muted);\n}\n\n.mjo-ol-discount__clear {\n border: 1px solid var(--mj-border-strong);\n border-radius: var(--mj-radius-sm);\n background: var(--mj-bg-surface);\n color: inherit;\n font: inherit;\n font-size: var(--mj-text-xs);\n height: 24px;\n padding: 0 10px;\n cursor: pointer;\n}\n\n/* The discount's own badge on the line card. Deliberately NOT the override pill's\n warning colour: giving away value on purpose is not a caution. */\n.mjo-ol-discpill {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n margin-top: 4px;\n padding: 1px 8px;\n border-radius: 999px;\n font-size: 10px;\n font-weight: 600;\n letter-spacing: 0.02em;\n font-variant-numeric: tabular-nums;\n color: var(--mj-status-success-text);\n background: color-mix(in srgb, var(--mj-status-success-text) 16%, transparent);\n}\n"] }]
1977
+ ], template: "<div class=\"mjo-ol\">\n @for (line of Lines; track line.ID) {\n <div class=\"mjo-ol-card\">\n <div class=\"mjo-ol-card__top\">\n <div class=\"mjo-ol-card__id\">\n <button type=\"button\" class=\"mjo-ol-card__name\" (click)=\"OpenProduct(line, $event)\">\n {{ ProductFor(line)?.Name ?? 'Product' }}\n </button>\n <div class=\"mjo-ol-card__meta\">\n {{ ProductFor(line)?.SKU }}\n @if (ProductFor(line)?.TypeName) {\n \u00B7 {{ ProductFor(line)?.TypeName }}\n }\n </div>\n </div>\n\n <div class=\"mjo-ol-qty\" [class.is-locked]=\"!EditMode || QuantityCappedToOne(line)\">\n @if (EditMode && !QuantityCappedToOne(line)) {\n <button type=\"button\" (click)=\"Bump(line, -1)\" aria-label=\"Decrease quantity\">\u2212</button>\n <input\n [value]=\"line.Quantity\"\n (change)=\"SetQuantity(line, $event)\"\n aria-label=\"Quantity\">\n <button type=\"button\" (click)=\"Bump(line, 1)\" [disabled]=\"QuantityAtMax(line)\" aria-label=\"Increase quantity\">+</button>\n } @else {\n <span class=\"mjo-ol-qty__value\">{{ line.Quantity }}</span>\n }\n </div>\n\n <div class=\"mjo-ol-card__price\">\n <div class=\"mjo-ol-card__price-row\">\n <div class=\"mjo-ol-card__amt\">{{ DisplayUnit(line) | mjoMoney }}</div>\n <!-- The pencil opens the PRICE editor, the DISCOUNT editor, or both \u2014 a user\n may hold one authority without the other, and an order that can be\n discounted but not re-priced still needs a way in. -->\n @if (CanOverride || CanDiscount) {\n <button\n type=\"button\"\n class=\"mjo-ol-iconbtn mjo-ol-price__pencil\"\n (click)=\"ToggleOverrideEditor(line)\"\n [attr.aria-expanded]=\"IsOverrideEditorOpen(line)\"\n [attr.aria-label]=\"CanOverride ? (IsOverridden(line) ? 'Edit price override' : 'Override price or discount line') : 'Discount line'\">\n <i class=\"fa-solid fa-pencil\" aria-hidden=\"true\"></i>\n </button>\n }\n </div>\n @if (IsOverridden(line)) {\n <span class=\"mjo-ol-overpill\">overridden</span>\n } @else {\n <mjo-price-source-badge\n [Source]=\"PricedLine(line)?.PriceSource ?? null\"\n [Settled]=\"!Pricing.Loading\"\n [Overridden]=\"false\" />\n }\n <!-- A DISCOUNT IS NOT AN OVERRIDE, and the badge says so in its own words: the\n list price held and this much was given away. -->\n @if (HasDiscount(line)) {\n <span class=\"mjo-ol-discpill\" title=\"Discount on this line\">\u2212{{ AppliedDiscount(line) | mjoMoney }}</span>\n }\n @if (PricedLine(line)?.Error; as why) {\n <div class=\"mjo-ol-card__err\">{{ why }}</div>\n }\n </div>\n\n <div class=\"mjo-ol-card__tot\">{{ PricedLine(line)?.NetAmount | mjoMoney }}</div>\n\n <!-- Details, on every line and not just editable ones: a booked line's dimensions are\n what its journal entry carries, which is exactly when someone wants to look. -->\n <button\n type=\"button\"\n class=\"mjo-ol-iconbtn\"\n (click)=\"OpenDetails(line, $event)\"\n [attr.title]=\"DimensionSummary(line)\"\n [attr.aria-label]=\"'Details for ' + (ProductFor(line)?.Name ?? 'line')\">\n <i class=\"fa-solid fa-sliders\" aria-hidden=\"true\"></i>\n </button>\n\n @if (EditMode) {\n <button\n type=\"button\"\n class=\"mjo-ol-iconbtn\"\n (click)=\"Remove(line)\"\n [attr.aria-label]=\"'Remove ' + (ProductFor(line)?.Name ?? 'line')\">\n <i class=\"fa-regular fa-trash-can\" aria-hidden=\"true\"></i>\n </button>\n }\n </div>\n\n @if (IsOverrideEditorOpen(line)) {\n <div class=\"mjo-ol-override\" role=\"region\" [attr.aria-label]=\"'Price and discount for ' + (ProductFor(line)?.Name ?? 'line')\">\n @if (CanOverride) {\n <mjo-line-price-picker\n [Line]=\"line\"\n [OverrideKind]=\"OverrideKind\"\n [Applicable]=\"ApplicableFor(line)\"\n [EngineDefault]=\"PricedLine(line)?.Default\"\n [DefaultUnit]=\"DefaultUnit(line)\"\n [PriceSource]=\"PricedLine(line)?.PriceSource ?? null\"\n [PricedUnit]=\"PricedLine(line)?.UnitPrice ?? null\"\n (PriceChanged)=\"OnLinePriceChanged()\"></mjo-line-price-picker>\n }\n\n <!--\n DISCOUNT \u2014 deliberately its own block, below the price picker and labelled\n apart from it (golive #252). An override restates the price; a discount says\n the list price held and value was given away, and only the second reaches the\n Sales Discounts leg of the booking entry. Presenting them as one control is\n what left the whole discount concept unreachable from the product.\n -->\n @if (CanDiscount) {\n <div class=\"mjo-ol-discount\" role=\"group\" [attr.aria-label]=\"'Discount for ' + (ProductFor(line)?.Name ?? 'line')\">\n <div class=\"mjo-ol-discount__head\">\n <span class=\"mjo-ol-discount__title\">Discount</span>\n <span class=\"mjo-ol-discount__cap\">your authority: {{ DiscountCapLabel }}</span>\n </div>\n @if (CanDiscountLine(line)) {\n <div class=\"mjo-ol-discount__row\">\n <div class=\"mjo-ol-discount__mode\" role=\"radiogroup\" aria-label=\"Discount expressed as\">\n <button\n type=\"button\"\n role=\"radio\"\n [attr.aria-checked]=\"DiscountDraft(line).Mode === 'percent'\"\n [class.is-on]=\"DiscountDraft(line).Mode === 'percent'\"\n (click)=\"SetDiscountMode(line, 'percent')\">%</button>\n <button\n type=\"button\"\n role=\"radio\"\n [attr.aria-checked]=\"DiscountDraft(line).Mode === 'amount'\"\n [class.is-on]=\"DiscountDraft(line).Mode === 'amount'\"\n (click)=\"SetDiscountMode(line, 'amount')\">Amount</button>\n </div>\n <input\n class=\"mjo-ol-discount__val\"\n type=\"number\"\n step=\"0.01\"\n min=\"0\"\n [value]=\"DiscountDraft(line).Value\"\n (input)=\"SetDiscountValue(line, $event)\"\n [attr.placeholder]=\"DiscountDraft(line).Mode === 'percent' ? '0' : '0.00'\"\n [attr.aria-label]=\"DiscountDraft(line).Mode === 'percent' ? 'Discount percent' : 'Discount amount'\">\n <span class=\"mjo-ol-discount__calc\">\n @if (DraftDiscountAmount(line); as amount) {\n \u2212{{ amount | mjoMoney }} of {{ DiscountBase(line) | mjoMoney }}\n } @else {\n {{ DiscountBase(line) | mjoMoney }} left to discount\n }\n </span>\n </div>\n <label class=\"mjo-ol-discount__reason\" [class.is-required]=\"NeedsDiscountReason(line)\">\n <span>Discount Reason @if (DraftDiscountAmount(line)) {<em class=\"mjo-ol-override__req\" aria-hidden=\"true\">*</em>}</span>\n <textarea\n rows=\"2\"\n [value]=\"DiscountDraft(line).Reason\"\n (input)=\"SetDiscountReason(line, $event)\"\n placeholder=\"Required \u2014 why value was given away on this line\"></textarea>\n </label>\n @if (DiscountError(line); as problem) {\n <div class=\"mjo-ol-discount__err\" role=\"alert\">{{ problem }}</div>\n }\n @if (HasStagedDiscount(line)) {\n <div class=\"mjo-ol-discount__staged\">\n <span>Applies when this order is saved.</span>\n <button type=\"button\" class=\"mjo-ol-discount__clear\" (click)=\"ClearDiscount(line)\">Remove</button>\n </div>\n }\n } @else {\n <div class=\"mjo-ol-discount__note\">\n This line is booked, so its money is frozen. Reverse the line to re-sell it at a\n discounted price.\n </div>\n }\n </div>\n } @else if (DiscountUnavailableReason; as why) {\n <div class=\"mjo-ol-discount__note\">{{ why }}</div>\n }\n\n <div class=\"mjo-ol-override__actions\">\n <button\n type=\"button\"\n class=\"mjo-ol-override__done\"\n [disabled]=\"NeedsOverrideReason(line) || NeedsDiscountReason(line)\"\n [attr.title]=\"NeedsOverrideReason(line) ? 'Enter a reason for the price override' : (NeedsDiscountReason(line) ? 'Enter a reason for the discount' : null)\"\n (click)=\"DoneOverrideEditor(line)\">Done</button>\n @if (CanOverride) {\n <button type=\"button\" class=\"mjo-ol-override__reset\" [disabled]=\"!CanRestoreDefault(line)\" (click)=\"ResetOverride(line)\">Use Default Price</button>\n }\n </div>\n </div>\n }\n\n <div class=\"mjo-ol-card__conseq\">\n @if (ProductFor(line); as product) {\n @if (product.TypeName === 'Goods') {\n <mjo-consequence-chip Kind=\"fulfillment\">Ships \u2014 holds the order at Posted</mjo-consequence-chip>\n }\n @if (!product.Taxable) {\n <mjo-consequence-chip Kind=\"untaxable\">Untaxable</mjo-consequence-chip>\n }\n @if (ShowsForeignRevenue(line)) {\n <mjo-consequence-chip Kind=\"company\">Revenue to {{ product.CompanyName }}</mjo-consequence-chip>\n }\n }\n </div>\n @if (OverrideReasonText(line); as why) {\n <div class=\"mjo-ol-card__why\">{{ why }}</div>\n }\n\n <!--\n TERM START \u2014 subscription lines only (D-TERMSTART).\n The order date says when the sale was booked; this says when coverage begins, and an\n agreement settles the two independently. Shown on the card rather than behind the\n extension disclosure because it is a term fact, and not every subscription product\n type has an extension form to hide it in.\n -->\n @if (IsSubscriptionLine(line)) {\n <div class=\"mjo-ol-term\">\n <!-- `for` only when there IS an input to point at. A label targeting a missing\n id is a dead control to a screen reader. -->\n <label\n class=\"mjo-ol-term__label\"\n [attr.for]=\"EditMode && !TermStartIsDictated(line) ? 'mjo-ol-term-' + line.ID : null\">\n Term start\n </label>\n <!-- A renewal of LIVE coverage has no choice to offer: the term begins the day\n after the current one ends. Read-only rather than editable-and-ignored. -->\n @if (TermStartIsDictated(line)) {\n <span class=\"mjo-ol-term__value is-dictated\">{{ ContinuationStartValue(line) }}</span>\n } @else if (EditMode) {\n <input\n type=\"date\"\n class=\"mjo-ol-term__input\"\n [class.is-default]=\"TermStartFollowsOrderDate(line)\"\n [id]=\"'mjo-ol-term-' + line.ID\"\n [value]=\"TermStartValue(line)\"\n (change)=\"SetTermStart(line, $event)\">\n <!-- Offered only when there is something to reset. A button that clears a\n value the line never stated does nothing and invites the reader to\n wonder what it did. -->\n @if (!TermStartFollowsOrderDate(line)) {\n <button\n type=\"button\"\n class=\"mjo-ol-term__reset\"\n (click)=\"ResetTermStart(line)\">\n Reset to order date\n </button>\n }\n } @else {\n <span class=\"mjo-ol-term__value\">{{ TermStartValue(line) }}</span>\n }\n <span class=\"mjo-ol-term__hint\">\n @if (TermStartIsDictated(line)) {\n Continuing existing coverage, so the term begins the day after the current\n one ends \u2014 not something this line can set.\n } @else if (TermStartFollowsOrderDate(line)) {\n Following the order date. The subscription type's rules may still adjust\n the actual start.\n } @else {\n Stated on this line, so a later change to the order date leaves it alone.\n }\n </span>\n </div>\n\n <!-- The customer already holds this product (golive #299): ask whether this line\n extends that subscription or starts another, instead of letting the type's\n rule decide silently at confirm. -->\n @if (ExistingHoldingFor(line); as holding) {\n <div class=\"mjo-ol-holding\" role=\"group\" [attr.aria-label]=\"'Existing subscription ' + holding.SubscriptionNumber\">\n <span class=\"mjo-ol-holding__text\">\n The customer already holds {{ holding.SubscriptionNumber }} for this product\n @if (HoldingCoverageEnd(holding)) { (covered through {{ HoldingCoverageEnd(holding) }}) }.\n </span>\n @if (CanEditServicePeriod()) {\n <div class=\"mjo-ol-holding__choices\">\n <button\n type=\"button\"\n class=\"mjo-ol-holding__choice\"\n [class.is-selected]=\"line.SubscriptionAction === 'ExtendExisting'\"\n [attr.aria-pressed]=\"line.SubscriptionAction === 'ExtendExisting'\"\n (click)=\"SetSubscriptionAction(line, 'ExtendExisting')\">\n Add as next term\n @if (HoldingContinuationStart(holding)) { (starts {{ HoldingContinuationStart(holding) }}) }\n </button>\n <button\n type=\"button\"\n class=\"mjo-ol-holding__choice\"\n [class.is-selected]=\"line.SubscriptionAction === 'CreateNew'\"\n [attr.aria-pressed]=\"line.SubscriptionAction === 'CreateNew'\"\n (click)=\"SetSubscriptionAction(line, 'CreateNew')\">\n New subscription (keeps this line's dates)\n </button>\n </div>\n }\n <span class=\"mjo-ol-term__hint\" [class.is-error]=\"!line.SubscriptionAction\">\n @if (line.SubscriptionAction === 'CreateNew') {\n Confirm starts a separate subscription on this line's service period.\n } @else if (line.SubscriptionAction === 'ExtendExisting') {\n Confirm adds a term to {{ holding.SubscriptionNumber }}, starting the day after its coverage ends.\n } @else {\n Not chosen. The subscription type's rule will decide at confirm, and it may move this\n line's dates.\n }\n </span>\n </div>\n }\n }\n\n <!--\n SERVICE PERIOD \u2014 deferred lines that neither an event nor a subscription dates.\n The recognition type earns against this window, so the order cannot be confirmed\n without it.\n -->\n @if (NeedsStatedServicePeriod(line)) {\n <div class=\"mjo-ol-term\">\n <label\n class=\"mjo-ol-term__label\"\n [attr.for]=\"CanEditServicePeriod() ? 'mjo-ol-sp-start-' + line.ID : null\">\n Service period\n </label>\n @if (CanEditServicePeriod()) {\n <input\n type=\"date\"\n class=\"mjo-ol-term__input\"\n aria-label=\"Service period start\"\n [id]=\"'mjo-ol-sp-start-' + line.ID\"\n [value]=\"ServicePeriodValue(line, 'Start')\"\n (change)=\"SetServicePeriod(line, 'Start', $event)\">\n <span class=\"mjo-ol-term__label\" aria-hidden=\"true\">to</span>\n <input\n type=\"date\"\n class=\"mjo-ol-term__input\"\n aria-label=\"Service period end\"\n [value]=\"ServicePeriodValue(line, 'End')\"\n (change)=\"SetServicePeriod(line, 'End', $event)\">\n } @else {\n <span class=\"mjo-ol-term__value\">\n {{ ServicePeriodValue(line, 'Start') || '\u2014' }} to {{ ServicePeriodValue(line, 'End') || '\u2014' }}\n </span>\n }\n @if (ServicePeriodBackwards(line)) {\n <span class=\"mjo-ol-term__hint is-error\" role=\"alert\">\n End date must be on or after the start date.\n </span>\n } @else if (ServicePeriodMissing(line)) {\n <span class=\"mjo-ol-term__hint\">\n Needed to confirm: revenue on this line is recognized against these dates.\n </span>\n }\n </div>\n }\n\n @if (ExtensionFor(line); as ext) {\n <div class=\"mjo-ol-ext\" [class.is-open]=\"IsExtensionOpen(line)\">\n <button\n type=\"button\"\n class=\"mjo-ol-ext__toggle\"\n (click)=\"ToggleExtension(line)\"\n [attr.aria-expanded]=\"IsExtensionOpen(line)\"\n [attr.aria-controls]=\"'mjo-ol-ext-' + line.ID\">\n <i class=\"fa-solid fa-chevron-right mjo-ol-ext__chev\" aria-hidden=\"true\"></i>\n <span class=\"mjo-ol-ext__label\">{{ ExtensionLabel(line) }}</span>\n @if (!IsExtensionOpen(line)) {\n <span class=\"mjo-ol-ext__hint\">{{ ExtensionHint(line) }}</span>\n }\n </button>\n <div\n class=\"mjo-ol-ext__body\"\n [id]=\"'mjo-ol-ext-' + line.ID\"\n [attr.inert]=\"IsExtensionOpen(line) ? null : ''\"\n [attr.aria-hidden]=\"!IsExtensionOpen(line)\">\n <div class=\"mjo-ol-ext__clip\">\n <mj-entity-form-host\n [Record]=\"ext\"\n [EditMode]=\"EditMode\"\n [Config]=\"ExtensionFormConfigFor(line)\"\n (FormCreated)=\"OnExtensionFormCreated($event)\"\n (Navigate)=\"OnExtensionNavigate($event)\">\n </mj-entity-form-host>\n </div>\n </div>\n </div>\n }\n </div>\n } @empty {\n <div class=\"mjo-ol-empty\">\n <i class=\"fa-solid fa-cart-plus\" aria-hidden=\"true\"></i>\n <div class=\"mjo-ol-empty__title\">Nothing on this order yet</div>\n <div>Search the catalog to add the first line.</div>\n </div>\n }\n\n @if (EditMode) {\n <div class=\"mj-typeahead mjo-ol-picker\" #pickerHost>\n <div class=\"mjo-search\">\n <i class=\"fa-solid fa-plus\" aria-hidden=\"true\"></i>\n <input\n [(ngModel)]=\"ProductQuery\"\n (ngModelChange)=\"OnProductQueryChange()\"\n (focus)=\"OpenPicker()\"\n (blur)=\"ClosePickerSoon()\"\n (keydown)=\"OnPickerKey($event)\"\n placeholder=\"Add product \u2014 type a name or SKU\u2026\"\n autocomplete=\"off\"\n role=\"combobox\"\n aria-label=\"Add a product\"\n [attr.aria-expanded]=\"PickerOpen\">\n </div>\n\n @if (PickerOpen) {\n <div class=\"mj-typeahead-list is-open\" [class.is-up]=\"PickerOpensUp\" role=\"listbox\">\n @for (product of PickerResults; track product.ID; let i = $index) {\n <button\n type=\"button\"\n class=\"mj-typeahead-item mjo-ol-pick\"\n [class.is-cursor]=\"i === PickerCursor\"\n role=\"option\"\n [attr.aria-selected]=\"i === PickerCursor\"\n (mousedown)=\"AddProduct(product)\">\n <span class=\"mjo-ol-pick__body\">\n <span class=\"name\">{{ product.Name }}</span>\n <span class=\"mjo-ol-pick__meta\">\n <span class=\"sub\">{{ product.SKU }} \u00B7 {{ product.TypeName }}</span>\n @if (product.CompanyName) {\n <span\n class=\"mjo-ol-pick__company\"\n [class.is-foreign]=\"IsForeignCompany(product)\"\n [attr.title]=\"IsForeignCompany(product)\n ? 'Sold by ' + product.CompanyName + ', not this order\\'s company'\n : product.CompanyName\">\n <i class=\"fa-solid fa-building\" aria-hidden=\"true\"></i>\n {{ product.CompanyName }}\n </span>\n }\n </span>\n </span>\n <span class=\"end\">\n <span class=\"mjo-ol-pick__price\">{{ product.ListPrice | mjoMoney }}</span>\n <span class=\"sub\">{{ product.Taxable ? 'taxable' : 'untaxable' }}</span>\n </span>\n </button>\n } @empty {\n <div class=\"mj-typeahead-item\">\n <span class=\"muted small\">\n @if (CatalogError) { {{ CatalogError }} }\n @else if (Catalog.length === 0) { Loading catalog\u2026 }\n @else { No product matches that. }\n </span>\n </div>\n }\n </div>\n }\n </div>\n }\n\n <!-- Line details. Rendered once and handed whichever line is open, rather than one per card:\n the panel is modal, so a second instance could never be visible. -->\n <mjo-order-line-details-panel\n [Line]=\"DetailsLine\"\n [ProductName]=\"DetailsLine ? (ProductFor(DetailsLine)?.Name ?? '') : ''\"\n [ProductSKU]=\"DetailsLine ? (ProductFor(DetailsLine)?.SKU ?? '') : ''\"\n [ProductType]=\"DetailsLine ? (ProductFor(DetailsLine)?.TypeName ?? '') : ''\"\n [Dimensions]=\"DimensionCatalog\"\n [EditMode]=\"EditMode\"\n (Closed)=\"CloseDetails()\">\n </mjo-order-line-details-panel>\n</div>\n", styles: [":host { display: block; }\n\n.mjo-ol {\n display: flex;\n flex-direction: column;\n gap: var(--mj-space-2);\n}\n\n.mjo-ol-card {\n border: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface);\n border-radius: var(--mj-radius-md);\n padding: var(--mj-space-3);\n}\n\n.mjo-ol-card:has(.mjo-ol-ext.is-open) {\n padding-bottom: var(--mj-space-1);\n}\n\n.mjo-ol-card__top {\n display: flex;\n align-items: flex-start;\n gap: var(--mj-space-3);\n}\n\n.mjo-ol-card__id { flex: 1; min-width: 0; }\n\n.mjo-ol-card__name {\n display: inline;\n padding: 0;\n border: 0;\n background: transparent;\n font: inherit;\n font-size: var(--mj-text-sm);\n font-weight: var(--mj-font-semibold);\n color: var(--mj-text-link);\n text-align: left;\n cursor: pointer;\n text-decoration: none;\n}\n\n.mjo-ol-card__name:hover { text-decoration: underline; }\n\n.mjo-ol-card__meta {\n font-size: var(--mj-text-xs);\n color: var(--mj-text-muted);\n margin-top: 2px;\n}\n\n.mjo-ol-qty {\n display: inline-flex;\n align-items: center;\n border: 1px solid var(--mj-border-strong);\n border-radius: var(--mj-radius-md);\n overflow: hidden;\n background: var(--mj-bg-surface);\n flex: none;\n}\n\n.mjo-ol-qty button {\n border: 0;\n background: transparent;\n cursor: pointer;\n color: var(--mj-text-secondary);\n width: 26px;\n height: 28px;\n font-size: 11px;\n}\n\n.mjo-ol-qty button:hover:not(:disabled) {\n background: var(--mj-bg-surface-hover);\n color: var(--mj-text-primary);\n}\n\n.mjo-ol-qty button:disabled {\n cursor: default;\n color: var(--mj-text-disabled);\n}\n\n.mjo-ol-qty input {\n border: 0;\n outline: 0;\n background: transparent;\n width: 46px;\n text-align: center;\n font: inherit;\n font-variant-numeric: tabular-nums;\n color: inherit;\n}\n\n.mjo-ol-qty.is-locked {\n border-color: var(--mj-border-default);\n background: transparent;\n}\n\n.mjo-ol-qty__value {\n min-width: 46px;\n padding: 0 10px;\n height: 28px;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n font-variant-numeric: tabular-nums;\n}\n\n.mjo-ol-card__price {\n flex: none;\n min-width: 108px;\n display: flex;\n flex-direction: column;\n align-items: center;\n}\n\n.mjo-ol-card__price-row {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 2px;\n height: 28px;\n}\n\n.mjo-ol-price__pencil {\n flex: none;\n color: var(--mj-text-muted);\n}\n\n.mjo-ol-price__pencil:hover {\n color: var(--mj-text-link);\n background: var(--mj-bg-surface-hover);\n}\n\n.mjo-ol-override {\n display: flex;\n flex-direction: column;\n gap: var(--mj-space-2);\n margin-top: var(--mj-space-2);\n padding: var(--mj-space-2);\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-md);\n background: var(--mj-bg-surface-subtle, var(--mj-bg-surface));\n}\n\n.mjo-ol-override__req {\n font-style: normal;\n color: var(--mj-status-danger-text, #b42318);\n margin-left: 2px;\n}\n\n.mjo-ol-override__actions {\n display: flex;\n gap: var(--mj-space-2);\n justify-content: flex-end;\n}\n\n.mjo-ol-override__done,\n.mjo-ol-override__reset {\n border: 0;\n background: transparent;\n cursor: pointer;\n font: inherit;\n font-size: var(--mj-text-xs);\n font-weight: var(--mj-font-semibold);\n padding: 4px 8px;\n border-radius: var(--mj-radius-sm);\n}\n\n.mjo-ol-override__done {\n color: var(--mj-text-link);\n}\n\n.mjo-ol-override__reset {\n color: var(--mj-text-muted);\n}\n\n.mjo-ol-override__done:hover,\n.mjo-ol-override__reset:hover {\n background: var(--mj-bg-surface-hover);\n}\n\n.mjo-ol-override__done:disabled {\n color: var(--mj-text-muted);\n cursor: not-allowed;\n background: transparent;\n}\n\n.mjo-ol-card__amt {\n font-variant-numeric: tabular-nums;\n font-weight: var(--mj-font-semibold);\n font-size: var(--mj-text-sm);\n line-height: 28px;\n}\n\n.mjo-ol-overpill {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n margin-top: 4px;\n padding: 1px 8px;\n border-radius: 999px;\n font-size: 10px;\n font-weight: 600;\n letter-spacing: 0.02em;\n color: var(--mj-status-warning-text);\n background: color-mix(in srgb, var(--mj-status-warning-text) 16%, transparent);\n}\n\n.mjo-ol-card__err {\n font-size: var(--mj-text-xs);\n color: var(--mj-status-error-text);\n margin-top: 2px;\n}\n\n.mjo-ol-card__tot {\n flex: none;\n min-width: 104px;\n height: 28px;\n display: flex;\n align-items: center;\n justify-content: flex-end;\n text-align: right;\n font-variant-numeric: tabular-nums;\n font-weight: var(--mj-font-semibold);\n font-size: var(--mj-text-sm);\n line-height: 28px;\n}\n\n.mjo-ol-iconbtn {\n border: 0;\n background: transparent;\n color: var(--mj-text-muted);\n cursor: pointer;\n width: 28px;\n height: 28px;\n border-radius: var(--mj-radius-sm);\n}\n\n.mjo-ol-iconbtn:hover {\n background: var(--mj-bg-surface-hover);\n color: var(--mj-status-error);\n}\n\n.mjo-ol-card__conseq {\n display: flex;\n gap: 6px;\n flex-wrap: wrap;\n margin-top: var(--mj-space-2);\n}\n\n/* Term start \u2014 subscription lines only. One row that wraps, so the hint drops below the field on a\n narrow card rather than squeezing the date input. */\n.mjo-ol-term {\n display: flex;\n align-items: center;\n gap: var(--mj-space-2);\n flex-wrap: wrap;\n margin-top: var(--mj-space-2);\n}\n\n.mjo-ol-term__label {\n font-size: var(--mj-text-xs);\n color: var(--mj-text-muted);\n}\n\n.mjo-ol-term__input {\n height: 28px;\n padding: 0 var(--mj-space-2);\n border: 1px solid var(--mj-border-strong);\n border-radius: var(--mj-radius-md);\n background: var(--mj-bg-surface);\n color: var(--mj-text-primary);\n font: inherit;\n font-size: var(--mj-text-sm);\n}\n\n/* A DEFAULT reads quieter than a stated value \u2014 the same distinction the order header draws\n between a date somebody chose and one that fell out of a rule. */\n.mjo-ol-term__input.is-default {\n border-color: var(--mj-border-default);\n color: var(--mj-text-secondary);\n}\n\n.mjo-ol-term__value {\n font-size: var(--mj-text-sm);\n color: var(--mj-text-primary);\n font-variant-numeric: tabular-nums;\n}\n\n/* A dictated date is a FACT, not a disabled input: shown in the read-mode weight in edit mode too,\n so nothing on the card suggests a control that has been switched off. */\n.mjo-ol-term__value.is-dictated {\n color: var(--mj-text-secondary);\n}\n\n.mjo-ol-term__reset {\n border: 0;\n background: transparent;\n padding: 0;\n color: var(--mj-text-link);\n font-size: var(--mj-text-xs);\n cursor: pointer;\n}\n\n.mjo-ol-term__reset:hover {\n text-decoration: underline;\n}\n\n.mjo-ol-term__hint {\n font-size: var(--mj-text-xs);\n color: var(--mj-text-muted);\n}\n\n.mjo-ol-term__hint.is-error {\n color: var(--mj-status-error-text);\n}\n\n.mjo-ol-card__why {\n margin-top: 6px;\n font-size: var(--mj-text-xs);\n color: var(--mj-text-secondary);\n line-height: 1.35;\n}\n\n.mjo-ol-empty {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n gap: var(--mj-space-1);\n padding: var(--mj-space-4) var(--mj-space-3);\n color: var(--mj-text-muted);\n font-size: var(--mj-text-sm);\n text-align: center;\n}\n\n.mjo-ol-empty i {\n font-size: var(--mj-text-2xl);\n color: var(--mj-brand-primary);\n}\n\n.mjo-ol-empty__title {\n font-weight: var(--mj-font-semibold);\n color: var(--mj-text-primary);\n}\n\n.mjo-ol-picker {\n position: relative;\n z-index: 20;\n}\n\n.mjo-ol-picker:has(.mj-typeahead-list.is-open) {\n z-index: 40;\n}\n\n.mjo-search {\n display: flex;\n align-items: center;\n gap: var(--mj-space-2);\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-strong);\n border-radius: var(--mj-radius-md);\n padding: 8px 10px;\n}\n\n.mjo-search i { color: var(--mj-text-muted); font-size: 12px; }\n\n.mjo-search input {\n border: 0;\n outline: 0;\n background: transparent;\n font: inherit;\n font-size: var(--mj-text-sm);\n color: inherit;\n width: 100%;\n}\n\n.mj-typeahead-list {\n display: none;\n position: absolute;\n left: 0;\n right: 0;\n top: calc(100% + 4px);\n max-height: 240px;\n overflow: auto;\n background: var(--mj-bg-surface-elevated);\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-md);\n box-shadow: var(--mj-shadow-md, 0 8px 24px rgba(0, 0, 0, 0.18));\n z-index: 30;\n}\n\n.mj-typeahead-list.is-open { display: block; }\n\n.mj-typeahead-list.is-up {\n top: auto;\n bottom: calc(100% + 4px);\n}\n\n.mj-typeahead-item {\n display: flex;\n align-items: center;\n gap: var(--mj-space-3);\n width: 100%;\n padding: 8px 12px;\n border: 0;\n border-bottom: 1px solid var(--mj-border-subtle);\n background: transparent;\n color: inherit;\n text-align: left;\n cursor: pointer;\n font: inherit;\n}\n\n.mj-typeahead-item:last-child { border-bottom: 0; }\n\n.mj-typeahead-item:hover,\n.mj-typeahead-item.is-cursor {\n background: var(--mj-bg-surface-hover);\n}\n\n.mjo-ol-pick__body {\n display: flex;\n flex-direction: column;\n gap: 1px;\n min-width: 0;\n}\n\n.mjo-ol-pick .name { font-size: 13px; font-weight: var(--mj-font-semibold); }\n.mjo-ol-pick .sub { font-size: 11.5px; color: var(--mj-text-muted); }\n\n/*\n COMPANY IS ITS OWN ELEMENT, not the third item in a muted \"SKU \u00B7 type \u00B7 company\" run.\n Two similarly named products from different companies are exactly what this picker has to let\n someone tell apart before they pick, and a company set in the same muted grey as everything\n else, in third position, is not something anyone reads at speed.\n*/\n.mjo-ol-pick__meta {\n display: flex;\n align-items: center;\n gap: var(--mj-space-2);\n min-width: 0;\n}\n\n.mjo-ol-pick__company {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n flex: 0 0 auto;\n font-size: 11px;\n line-height: 1.2;\n padding: 2px 6px;\n border: 1px solid var(--mj-border-subtle);\n border-radius: var(--mj-radius-sm);\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-secondary);\n}\n\n.mjo-ol-pick__company i { font-size: 9.5px; color: var(--mj-text-muted); }\n\n/* Another company's product \u2014 offered on purpose (BCC sells SoundPost), so it is marked, not hidden. */\n.mjo-ol-pick__company.is-foreign i { color: var(--mj-status-info); }\n.mjo-ol-pick__company.is-foreign {\n color: var(--mj-text-primary);\n border-color: var(--mj-border-default);\n}\n.mjo-ol-pick .end {\n margin-left: auto;\n text-align: right;\n display: flex;\n flex-direction: column;\n gap: 1px;\n flex: 0 0 auto;\n}\n.mjo-ol-pick__price {\n font-variant-numeric: tabular-nums;\n font-weight: var(--mj-font-semibold);\n}\n\n.mjo-ol-ext-err {\n font-size: var(--mj-text-xs);\n color: var(--mj-status-error-text);\n}\n\n.mjo-ol-ext {\n margin-top: var(--mj-space-2);\n padding-top: var(--mj-space-1);\n border-top: 1px dashed var(--mj-border-subtle);\n}\n\n.mjo-ol-ext__toggle {\n display: flex;\n align-items: center;\n gap: var(--mj-space-2);\n width: 100%;\n padding: var(--mj-space-1) 0;\n border: 0;\n background: transparent;\n color: inherit;\n font: inherit;\n text-align: left;\n cursor: pointer;\n border-radius: var(--mj-radius-sm);\n}\n\n.mjo-ol-ext__toggle:hover {\n color: var(--mj-text-primary);\n}\n\n.mjo-ol-ext__toggle:focus-visible {\n outline: 2px solid var(--mj-border-focus);\n outline-offset: 2px;\n}\n\n.mjo-ol-ext__chev {\n flex: none;\n width: 12px;\n font-size: 10px;\n color: var(--mj-text-muted);\n transition: transform 160ms ease;\n}\n\n.mjo-ol-ext.is-open .mjo-ol-ext__chev {\n transform: rotate(90deg);\n}\n\n.mjo-ol-ext__label {\n font-size: var(--mj-text-xs);\n font-weight: var(--mj-font-semibold);\n color: var(--mj-text-secondary);\n letter-spacing: 0.01em;\n}\n\n.mjo-ol-ext__hint {\n margin-left: auto;\n font-size: var(--mj-text-xs);\n color: var(--mj-text-muted);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.mjo-ol-ext__body {\n display: grid;\n grid-template-rows: 0fr;\n transition: grid-template-rows 180ms ease;\n}\n\n.mjo-ol-ext.is-open .mjo-ol-ext__body {\n grid-template-rows: 1fr;\n}\n\n.mjo-ol-ext__clip {\n overflow: hidden;\n min-height: 0;\n}\n\n/* Flatten the embedded extension form so its fields sit in the line card. */\n.mjo-ol-ext ::ng-deep mj-record-form-container,\n.mjo-ol-ext ::ng-deep .mj-record-form-container,\n.mjo-ol-ext ::ng-deep .mj-forms-container {\n display: block;\n padding: 0;\n margin: 0;\n border: 0;\n background: transparent;\n box-shadow: none;\n}\n\n.mjo-ol-ext ::ng-deep .mj-forms-toolbar,\n.mjo-ol-ext ::ng-deep mj-form-toolbar {\n display: none;\n}\n\n.mjo-ol-ext ::ng-deep .mj-forms-panel {\n border: 0;\n background: transparent;\n box-shadow: none;\n margin: 0;\n padding: 0;\n}\n\n.mjo-ol-ext ::ng-deep mj-collapsible-panel + mj-collapsible-panel .mj-forms-panel {\n margin-top: calc(-1 * var(--mj-space-1));\n}\n\n.mjo-ol-ext ::ng-deep .mj-forms-panel-header {\n display: none;\n}\n\n.mjo-ol-ext ::ng-deep .mj-forms-panel-body,\n.mjo-ol-ext ::ng-deep .mj-forms-panel-content {\n max-height: none;\n overflow: visible;\n padding: 0;\n margin: 0;\n}\n\n.mjo-ol-ext ::ng-deep mj-form-field:last-child,\n.mjo-ol-ext ::ng-deep .mj-form-field:last-child {\n margin-bottom: 0;\n}\n\n@media (max-width: 720px) {\n .mjo-ol-card__top { flex-wrap: wrap; }\n .mjo-ol-card__price, .mjo-ol-card__tot { width: auto; }\n}\n\n/* \u2500\u2500 DISCOUNT \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n Its own bordered block inside the price editor, because a discount and a price\n override are different economics and the report that produced this control said\n so: presenting them as one thing is what made the discount concept unreachable.\n The rule above the block is the separator \u2014 the two never read as one form. */\n.mjo-ol-discount {\n display: flex;\n flex-direction: column;\n gap: var(--mj-space-2);\n padding-top: var(--mj-space-2);\n border-top: 1px solid var(--mj-border-default);\n}\n\n.mjo-ol-discount__head {\n display: flex;\n align-items: baseline;\n justify-content: space-between;\n gap: var(--mj-space-2);\n flex-wrap: wrap;\n}\n\n.mjo-ol-discount__title {\n font-size: var(--mj-text-xs);\n font-weight: var(--mj-font-semibold);\n color: var(--mj-text-primary);\n}\n\n.mjo-ol-discount__cap {\n font-size: var(--mj-text-xs);\n color: var(--mj-text-muted);\n}\n\n.mjo-ol-discount__row {\n display: flex;\n align-items: center;\n gap: var(--mj-space-2);\n flex-wrap: wrap;\n}\n\n/* Two buttons that behave as one control, so they are drawn as one. */\n.mjo-ol-discount__mode {\n display: inline-flex;\n border: 1px solid var(--mj-border-strong);\n border-radius: var(--mj-radius-sm);\n overflow: hidden;\n}\n\n.mjo-ol-discount__mode button {\n border: 0;\n background: var(--mj-bg-surface);\n color: var(--mj-text-muted);\n font: inherit;\n font-size: var(--mj-text-xs);\n padding: 0 10px;\n height: 28px;\n cursor: pointer;\n}\n\n.mjo-ol-discount__mode button + button {\n border-left: 1px solid var(--mj-border-strong);\n}\n\n.mjo-ol-discount__mode button.is-on {\n background: var(--mj-bg-surface-hover);\n color: var(--mj-text-primary);\n font-weight: var(--mj-font-semibold);\n}\n\n.mjo-ol-discount__val {\n width: 96px;\n height: 28px;\n box-sizing: border-box;\n padding: 0 8px;\n border: 1px solid var(--mj-border-strong);\n border-radius: var(--mj-radius-sm);\n background: var(--mj-bg-surface);\n color: inherit;\n font: inherit;\n font-size: var(--mj-text-xs);\n font-variant-numeric: tabular-nums;\n text-align: right;\n}\n\n.mjo-ol-discount__calc {\n font-size: var(--mj-text-xs);\n color: var(--mj-text-muted);\n font-variant-numeric: tabular-nums;\n}\n\n.mjo-ol-discount__reason span {\n display: block;\n font-size: var(--mj-text-xs);\n color: var(--mj-text-muted);\n margin-bottom: 4px;\n}\n\n.mjo-ol-discount__reason textarea {\n display: block;\n width: 100%;\n box-sizing: border-box;\n resize: vertical;\n min-height: 48px;\n padding: 6px 8px;\n border: 1px solid var(--mj-border-strong);\n border-radius: var(--mj-radius-sm);\n background: var(--mj-bg-surface);\n color: inherit;\n font: inherit;\n font-size: var(--mj-text-xs);\n}\n\n.mjo-ol-discount__reason.is-required textarea {\n border-color: var(--mj-status-danger-text, #b42318);\n}\n\n.mjo-ol-discount__err {\n font-size: var(--mj-text-xs);\n color: var(--mj-status-error-text);\n}\n\n.mjo-ol-discount__note {\n font-size: var(--mj-text-xs);\n color: var(--mj-text-muted);\n}\n\n.mjo-ol-discount__staged {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: var(--mj-space-2);\n font-size: var(--mj-text-xs);\n color: var(--mj-text-muted);\n}\n\n.mjo-ol-discount__clear {\n border: 1px solid var(--mj-border-strong);\n border-radius: var(--mj-radius-sm);\n background: var(--mj-bg-surface);\n color: inherit;\n font: inherit;\n font-size: var(--mj-text-xs);\n height: 24px;\n padding: 0 10px;\n cursor: pointer;\n}\n\n/* The discount's own badge on the line card. Deliberately NOT the override pill's\n warning colour: giving away value on purpose is not a caution. */\n.mjo-ol-discpill {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n margin-top: 4px;\n padding: 1px 8px;\n border-radius: 999px;\n font-size: 10px;\n font-weight: 600;\n letter-spacing: 0.02em;\n font-variant-numeric: tabular-nums;\n color: var(--mj-status-success-text);\n background: color-mix(in srgb, var(--mj-status-success-text) 16%, transparent);\n}\n\n/* The customer already holds this product (golive #299). */\n.mjo-ol-holding {\n display: flex;\n flex-direction: column;\n gap: var(--mj-space-2);\n margin-top: var(--mj-space-2);\n padding: var(--mj-space-2) var(--mj-space-3);\n border: 1px solid var(--mj-status-warning-border);\n border-radius: var(--mj-radius-md);\n background: var(--mj-status-warning-bg);\n font-size: var(--mj-text-sm);\n color: var(--mj-text-primary);\n}\n\n.mjo-ol-holding__choices {\n display: flex;\n flex-wrap: wrap;\n gap: var(--mj-space-2);\n}\n\n.mjo-ol-holding__choice {\n padding: 4px 10px;\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-full);\n background: var(--mj-bg-surface);\n color: var(--mj-text-primary);\n font: inherit;\n cursor: pointer;\n}\n\n.mjo-ol-holding__choice.is-selected {\n border-color: var(--mj-brand-primary);\n color: var(--mj-brand-primary);\n font-weight: var(--mj-font-semibold);\n}\n"] }]
1819
1978
  }], null, { Provider: [{
1820
1979
  type: Input
1821
1980
  }], EditMode: [{
@@ -1830,5 +1989,5 @@ export class MJOOrderLinesEditorComponent {
1830
1989
  type: ViewChild,
1831
1990
  args: ['pickerHost']
1832
1991
  }] }); })();
1833
- (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(MJOOrderLinesEditorComponent, { className: "MJOOrderLinesEditorComponent", filePath: "lib/custom/OrderHeader/order-lines-editor.component.ts", lineNumber: 134 }); })();
1992
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(MJOOrderLinesEditorComponent, { className: "MJOOrderLinesEditorComponent", filePath: "lib/custom/OrderHeader/order-lines-editor.component.ts", lineNumber: 136 }); })();
1834
1993
  //# sourceMappingURL=order-lines-editor.component.js.map