platform-types 1.10.865 → 1.10.866

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.
@@ -34,7 +34,7 @@
34
34
  * A cancelled order can still have the device on the shelf.
35
35
  */
36
36
  Object.defineProperty(exports, "__esModule", { value: true });
37
- exports.SERVICE_ORDER_ERROR_CODES = exports.MAX_SERVICE_PICTURES = exports.SERVICE_CUSTODIES = exports.SERVICE_CUSTODY_TRANSITIONS = exports.SERVICE_TERMINAL_STATUSES = exports.SERVICE_STATUSES = exports.SERVICE_ORDER_DOCUMENTS = exports.SERVICE_TRANSITIONS = void 0;
37
+ exports.SERVICE_ORDER_ERROR_CODES = exports.SERVICE_QUOTE_COMPLETION_DAYS_MAX = exports.SERVICE_QUOTE_COMPLETION_DAYS_MIN = exports.MAX_SERVICE_PICTURES = exports.SERVICE_CUSTODIES = exports.SERVICE_CUSTODY_TRANSITIONS = exports.SERVICE_TERMINAL_STATUSES = exports.SERVICE_STATUSES = exports.SERVICE_ORDER_DOCUMENTS = exports.SERVICE_TRANSITIONS = void 0;
38
38
  /**
39
39
  * The legal moves on a service order. Exhaustive over `ServiceStatus` by
40
40
  * construction — adding a status to the union without a row here is a typecheck
@@ -167,6 +167,13 @@ exports.SERVICE_CUSTODIES = Object.keys(exports.SERVICE_CUSTODY_TRANSITIONS);
167
167
  * separately by {@link MAX_IMAGE_BASE64_CHARS}.
168
168
  */
169
169
  exports.MAX_SERVICE_PICTURES = 20;
170
+ /**
171
+ * The bounds of `ServiceQuote.completionDays` (art. 21(e), calendar days from
172
+ * approval). `POST /services { mode: 'quote', action: 'create' }` refuses a
173
+ * value outside them, or a fraction, with `400 VALIDATION_FAILED`.
174
+ */
175
+ exports.SERVICE_QUOTE_COMPLETION_DAYS_MIN = 1;
176
+ exports.SERVICE_QUOTE_COMPLETION_DAYS_MAX = 365;
170
177
  /**
171
178
  * `body.error` codes `/services` refuses with — every mode of `POST /services`
172
179
  * and every `GET /services` read (list, `?mode=unclaimed`, by id, `?mode=pdf`).
@@ -380,6 +387,8 @@ exports.SERVICE_ORDER_ERROR_CODES = [
380
387
  'SERVICE_QUOTE_CHANNEL_RESERVED',
381
388
  'SERVICE_QUOTE_CHANNEL_NOT_APPLICABLE',
382
389
  'SERVICE_QUOTE_REASON_NOT_APPLICABLE',
390
+ // The customer's online approval of a version that states no term (art. 21(e))
391
+ 'SERVICE_QUOTE_TERM_REQUIRED',
383
392
  'SERVICE_ORDER_QUOTE_CHANGED',
384
393
  // Renotify
385
394
  'SERVICE_ORDER_NOT_READY',
@@ -23,7 +23,7 @@
23
23
  * link minted earlier keeps reading (STORE_MODULES rule 4).
24
24
  */
25
25
  Object.defineProperty(exports, "__esModule", { value: true });
26
- exports.SERVICE_TRACKING_HANDLE_RE = exports.SERVICE_TRACKING_PATH_PREFIX = exports.SERVICE_TRACKING_LINK_ACTIONS = exports.SERVICE_TRACKING_CODE_RE = exports.SERVICE_TRACKING_CHALLENGE_HANDLE_RE = exports.SERVICE_TRACKING_QUOTE_DECISIONS = exports.SERVICE_TRACKING_CODE_VIAS = exports.SERVICE_TRACKING_DECISION_ERROR_CODES = exports.SERVICE_TRACKING_OPERATOR_ERROR_CODES = exports.SERVICE_TRACKING_ACCOUNT_ERROR_CODES = exports.SERVICE_TRACKING_ERROR_CODES = void 0;
26
+ exports.SERVICE_TRACKING_HANDLE_RE = exports.SERVICE_TRACKING_PATH_PREFIX = exports.SERVICE_TRACKING_LINK_ACTIONS = exports.SERVICE_TRACKING_CODE_RE = exports.SERVICE_TRACKING_CHALLENGE_HANDLE_RE = exports.SERVICE_TRACKING_QUOTE_DECISIONS = exports.SERVICE_TRACKING_APPROVE_BLOCKS = exports.SERVICE_TRACKING_CODE_VIAS = exports.SERVICE_TRACKING_DECISION_ERROR_CODES = exports.SERVICE_TRACKING_OPERATOR_ERROR_CODES = exports.SERVICE_TRACKING_ACCOUNT_ERROR_CODES = exports.SERVICE_TRACKING_ERROR_CODES = void 0;
27
27
  /**
28
28
  * The refusals the PUBLIC tracking routes answer themselves.
29
29
  *
@@ -81,6 +81,11 @@ exports.SERVICE_TRACKING_OPERATOR_ERROR_CODES = [
81
81
  * (the same decision again answers 200 with the current view and writes nothing).
82
82
  * - SERVICE_QUOTE_LAPSED (409, approve only): past `expiresAt`. A rejection is
83
83
  * still accepted.
84
+ * - SERVICE_QUOTE_TERM_REQUIRED (409, approve only): the version states no term
85
+ * (Ley 24.240 art. 21(e)) — neither `completionDays` nor a FUTURE
86
+ * `promisedAt`. Checked before the code, so it spends no attempt. A rejection
87
+ * is still accepted; the shop re-quotes with a term or sets a future
88
+ * `promisedAt`.
84
89
  * - SERVICE_ORDER_QUOTE_CHANGED (409): the order moved under the decision — retry.
85
90
  * - SERVICE_ORDER_TERMINAL / SERVICE_ORDER_DISABLED (409): the ticket is closed
86
91
  * or deleted.
@@ -96,6 +101,7 @@ exports.SERVICE_TRACKING_DECISION_ERROR_CODES = [
96
101
  'SERVICE_QUOTE_SUPERSEDED',
97
102
  'SERVICE_QUOTE_ALREADY_RESOLVED',
98
103
  'SERVICE_QUOTE_LAPSED',
104
+ 'SERVICE_QUOTE_TERM_REQUIRED',
99
105
  'SERVICE_ORDER_QUOTE_CHANGED',
100
106
  'SERVICE_ORDER_TERMINAL',
101
107
  'SERVICE_ORDER_DISABLED',
@@ -103,6 +109,12 @@ exports.SERVICE_TRACKING_DECISION_ERROR_CODES = [
103
109
  ];
104
110
  /** Where the 6-digit decision code is sent: the phone or the email on file. */
105
111
  exports.SERVICE_TRACKING_CODE_VIAS = ['sms', 'email'];
112
+ /**
113
+ * Why `ServiceTrackingDecision.canApprove` is false while `canDecide` is true,
114
+ * in the order they are checked: `lapsed` (past `expiresAt`), then
115
+ * `term_required` (no `completionDays` and no future `promisedAt`).
116
+ */
117
+ exports.SERVICE_TRACKING_APPROVE_BLOCKS = ['lapsed', 'term_required'];
106
118
  /** The customer's two online answers to a presupuesto. */
107
119
  exports.SERVICE_TRACKING_QUOTE_DECISIONS = ['approve', 'reject'];
108
120
  /** A decision challenge handle: 16 random bytes, base64url (22 characters). */
@@ -484,6 +484,16 @@ declare global {
484
484
  quotedAt?: number;
485
485
  /** Unix ms the offer lapses (Ley 24.240 art. 21(g)). */
486
486
  expiresAt?: number;
487
+ /**
488
+ * Art. 21(e): calendar days the work takes, counted from approval. Integer
489
+ * {@link SERVICE_QUOTE_COMPLETION_DAYS_MIN}–{@link SERVICE_QUOTE_COMPLETION_DAYS_MAX}.
490
+ * Set on create only; absent when the version states none.
491
+ *
492
+ * An ONLINE approval needs a stated term: this, or a future
493
+ * `ServiceOrder.promisedAt` (`409 SERVICE_QUOTE_TERM_REQUIRED` otherwise).
494
+ * A staff resolve does not.
495
+ */
496
+ completionDays?: number;
487
497
  approval?: ServiceQuoteApproval;
488
498
  /**
489
499
  * Set when `status` is `rejected`. ⚠️ NOT set on `expired`: a lapse is
@@ -1444,6 +1454,13 @@ export declare const SERVICE_CUSTODIES: [ServiceCustody, ...ServiceCustody[]];
1444
1454
  * separately by {@link MAX_IMAGE_BASE64_CHARS}.
1445
1455
  */
1446
1456
  export declare const MAX_SERVICE_PICTURES = 20;
1457
+ /**
1458
+ * The bounds of `ServiceQuote.completionDays` (art. 21(e), calendar days from
1459
+ * approval). `POST /services { mode: 'quote', action: 'create' }` refuses a
1460
+ * value outside them, or a fraction, with `400 VALIDATION_FAILED`.
1461
+ */
1462
+ export declare const SERVICE_QUOTE_COMPLETION_DAYS_MIN = 1;
1463
+ export declare const SERVICE_QUOTE_COMPLETION_DAYS_MAX = 365;
1447
1464
  /**
1448
1465
  * `body.error` codes `/services` refuses with — every mode of `POST /services`
1449
1466
  * and every `GET /services` read (list, `?mode=unclaimed`, by id, `?mode=pdf`).
@@ -1552,6 +1569,6 @@ export declare const MAX_SERVICE_PICTURES = 20;
1552
1569
  * check `GATING_ERROR_CODES` in addition. The deposit's opt-in idempotency
1553
1570
  * refusals are included here.
1554
1571
  */
1555
- export declare const SERVICE_ORDER_ERROR_CODES: readonly ["UNIT_QUANTITY_NOT_WHOLE", "UNIT_REVISION_STALE", "ROLE_FORBIDDEN", "PARENT_FILTER_CONFLICT", "VALIDATION_FAILED", "INVALID_CURSOR", "INVALID_FROM_DATE", "INVALID_TO_DATE", "INVALID_DATE_RANGE", "REWORK_INDEX_UNAVAILABLE", "STORE_NOT_FOUND", "SERVICE_ORDER_NOT_FOUND", "PRINT_JOB_DOCUMENT_NOT_FOUND", "CUSTOMER_NOT_FOUND", "PARENT_SERVICE_ORDER_NOT_FOUND", "SERVICE_TEMPLATE_NOT_FOUND", "SERVICE_TYPE_REQUIRED", "INVALID_IMAGE_REFERENCE", "MISSING_STORE_CONTEXT", "WARRANTY_BELOW_LEGAL_MINIMUM", "TECHNICIAN_NOT_FOUND", "TECHNICIAN_NOT_ELIGIBLE", "SERVICE_TRACKING_DISABLED", "SERVICE_TRACKING_NO_ADDRESS", "SERVICE_TRACKING_LINK_LAPSED", "SERVICE_TRACKING_VERIFICATION_FAILED", "SERVICE_TRACKING_TOKEN_INVALID", "ADMIN_REQUIRED", "CUSTODY_ILLEGAL_TRANSITION", "SERVICE_ORDER_BILLABLE_FROZEN", "SERVICE_ORDER_EDIT_CHANGED", "SERVICE_ORDER_DISABLED_STATE_UNCHANGED", "APPOINTMENT_NOT_FOUND", "APPOINTMENT_NOT_LINKABLE", "APPOINTMENT_NOT_OPEN", "APPOINTMENT_CUSTOMER_MISMATCH", "APPOINTMENT_VERSION_CONFLICT", "SERVICE_ORDER_TERMINAL", "SERVICE_ORDER_DISABLED", "SERVICE_ORDER_ILLEGAL_TRANSITION", "SERVICE_ORDER_STATUS_CHANGED", "SERVICE_ORDER_OUTCOME_REQUIRED", "SERVICE_ORDER_OUTCOME_NOT_ALLOWED", "SERVICE_ORDER_CUSTODY_NOT_RECEIVED", "SERVICE_ORDER_BILLABLE_NOT_AT_THIS_TRANSITION", "PAYMENT_METHODS_NOT_CONFIGURED", "PAYMENT_METHOD_NOT_FOUND", "SERVICE_ORDER_DEPOSIT_CHANGED", "INVALID_IDEMPOTENCY_KEY", "IDEMPOTENCY_KEY_REUSE", "IDEMPOTENCY_IN_PROGRESS", "IDEMPOTENCY_KEY_FAILED", "IDEMPOTENCY_LOCK_CONTENTION", "SERVICE_DEPOSIT_CURRENCY_MISMATCH", "SERVICE_DEPOSIT_INVALID", "INVALID_AMOUNT", "DEFAULT_DRAWER_UNAVAILABLE", "CURRENCY_MISMATCH", "SHIFT_NOT_OPEN", "SERVICE_BILLING_PRODUCTS_UNAVAILABLE", "CATEGORY_NOT_FOUND", "CATEGORY_DISABLED", "CATEGORY_DISABLE_IN_PROGRESS", "SERVICE_BILLING_PRODUCT_IN_BASKET", "SERVICE_DELIVERY_BASKET_DECISION_REQUIRED", "SERVICE_DELIVERY_BASKET_CURRENCY_MISMATCH", "PRODUCT_NOT_AVAILABLE", "PRODUCT_SALE_LIMIT_EXCEEDED", "PRODUCT_SALE_LIMIT_INVALID", "FX_CONVERSION_UNAVAILABLE", "TRANSACT_ITEMS_LIMIT_EXCEEDED", "SERVICE_LINE_PRICE_TOO_LARGE", "SERVICE_PARTS_RESTORE_EXCEEDS_CONSUMED", "SERVICE_PARTS_RESTORE_EXCEEDS_AMOUNT", "SERVICE_PARTS_STOCK_INSUFFICIENT", "SERVICE_PARTS_PRODUCT_NOT_FOUND", "SERVICE_PARTS_LEDGER_FULL", "SERVICE_PARTS_TOO_MANY", "SERVICE_ORDER_PARTS_CHANGED", "SERVICE_QUOTE_NOT_FOUND", "SERVICE_QUOTE_NOT_OFFERABLE", "SERVICE_QUOTE_HOLDS_TOO_MANY", "SERVICE_QUOTE_SUPERSEDED", "SERVICE_QUOTE_ALREADY_RESOLVED", "SERVICE_QUOTE_LAPSED", "SERVICE_QUOTE_CHANNEL_RESERVED", "SERVICE_QUOTE_CHANNEL_NOT_APPLICABLE", "SERVICE_QUOTE_REASON_NOT_APPLICABLE", "SERVICE_ORDER_QUOTE_CHANGED", "SERVICE_ORDER_NOT_READY", "SERVICE_RENOTIFY_IMPERSONATED", "SERVICE_RENOTIFY_TOO_SOON", "SERVICE_RENOTIFY_CONFLICT", "SERVICE_RENOTIFY_NOT_RECORDED", "SERVICE_RENOTIFY_LEDGER_UNREADABLE", "SERVICE_RENOTIFY_NOT_DISPATCHED", "SERVICE_TIMER_ALREADY_RUNNING", "SERVICE_TIMER_NOT_RUNNING", "SERVICE_TIMER_STOP_CONFLICT", "TECHNICIAN_NOT_CLOCKED_IN", "SERVICE_ORDER_GONE", "SERVICE_WORKLOG_NOT_FOUND", "SERVICE_WORKLOG_NOT_REVERSIBLE", "SERVICE_WORKLOG_ALREADY_REVERSED", "SERVICE_ORDER_WORKLOG_CHANGED", "CART_PROMOTION_UNAVAILABLE", "COUPON_NOT_FOUND", "COUPON_NOT_ACTIVE", "COUPON_EXPIRED", "COUPON_EXHAUSTED", "COUPON_EXHAUSTED_AT_CHECKOUT", "COUPON_MIN_SUBTOTAL", "COUPON_REQUIRES_CUSTOMER", "COUPON_BUDGET_EXHAUSTED", "COUPON_CURRENCY_MISMATCH"];
1572
+ export declare const SERVICE_ORDER_ERROR_CODES: readonly ["UNIT_QUANTITY_NOT_WHOLE", "UNIT_REVISION_STALE", "ROLE_FORBIDDEN", "PARENT_FILTER_CONFLICT", "VALIDATION_FAILED", "INVALID_CURSOR", "INVALID_FROM_DATE", "INVALID_TO_DATE", "INVALID_DATE_RANGE", "REWORK_INDEX_UNAVAILABLE", "STORE_NOT_FOUND", "SERVICE_ORDER_NOT_FOUND", "PRINT_JOB_DOCUMENT_NOT_FOUND", "CUSTOMER_NOT_FOUND", "PARENT_SERVICE_ORDER_NOT_FOUND", "SERVICE_TEMPLATE_NOT_FOUND", "SERVICE_TYPE_REQUIRED", "INVALID_IMAGE_REFERENCE", "MISSING_STORE_CONTEXT", "WARRANTY_BELOW_LEGAL_MINIMUM", "TECHNICIAN_NOT_FOUND", "TECHNICIAN_NOT_ELIGIBLE", "SERVICE_TRACKING_DISABLED", "SERVICE_TRACKING_NO_ADDRESS", "SERVICE_TRACKING_LINK_LAPSED", "SERVICE_TRACKING_VERIFICATION_FAILED", "SERVICE_TRACKING_TOKEN_INVALID", "ADMIN_REQUIRED", "CUSTODY_ILLEGAL_TRANSITION", "SERVICE_ORDER_BILLABLE_FROZEN", "SERVICE_ORDER_EDIT_CHANGED", "SERVICE_ORDER_DISABLED_STATE_UNCHANGED", "APPOINTMENT_NOT_FOUND", "APPOINTMENT_NOT_LINKABLE", "APPOINTMENT_NOT_OPEN", "APPOINTMENT_CUSTOMER_MISMATCH", "APPOINTMENT_VERSION_CONFLICT", "SERVICE_ORDER_TERMINAL", "SERVICE_ORDER_DISABLED", "SERVICE_ORDER_ILLEGAL_TRANSITION", "SERVICE_ORDER_STATUS_CHANGED", "SERVICE_ORDER_OUTCOME_REQUIRED", "SERVICE_ORDER_OUTCOME_NOT_ALLOWED", "SERVICE_ORDER_CUSTODY_NOT_RECEIVED", "SERVICE_ORDER_BILLABLE_NOT_AT_THIS_TRANSITION", "PAYMENT_METHODS_NOT_CONFIGURED", "PAYMENT_METHOD_NOT_FOUND", "SERVICE_ORDER_DEPOSIT_CHANGED", "INVALID_IDEMPOTENCY_KEY", "IDEMPOTENCY_KEY_REUSE", "IDEMPOTENCY_IN_PROGRESS", "IDEMPOTENCY_KEY_FAILED", "IDEMPOTENCY_LOCK_CONTENTION", "SERVICE_DEPOSIT_CURRENCY_MISMATCH", "SERVICE_DEPOSIT_INVALID", "INVALID_AMOUNT", "DEFAULT_DRAWER_UNAVAILABLE", "CURRENCY_MISMATCH", "SHIFT_NOT_OPEN", "SERVICE_BILLING_PRODUCTS_UNAVAILABLE", "CATEGORY_NOT_FOUND", "CATEGORY_DISABLED", "CATEGORY_DISABLE_IN_PROGRESS", "SERVICE_BILLING_PRODUCT_IN_BASKET", "SERVICE_DELIVERY_BASKET_DECISION_REQUIRED", "SERVICE_DELIVERY_BASKET_CURRENCY_MISMATCH", "PRODUCT_NOT_AVAILABLE", "PRODUCT_SALE_LIMIT_EXCEEDED", "PRODUCT_SALE_LIMIT_INVALID", "FX_CONVERSION_UNAVAILABLE", "TRANSACT_ITEMS_LIMIT_EXCEEDED", "SERVICE_LINE_PRICE_TOO_LARGE", "SERVICE_PARTS_RESTORE_EXCEEDS_CONSUMED", "SERVICE_PARTS_RESTORE_EXCEEDS_AMOUNT", "SERVICE_PARTS_STOCK_INSUFFICIENT", "SERVICE_PARTS_PRODUCT_NOT_FOUND", "SERVICE_PARTS_LEDGER_FULL", "SERVICE_PARTS_TOO_MANY", "SERVICE_ORDER_PARTS_CHANGED", "SERVICE_QUOTE_NOT_FOUND", "SERVICE_QUOTE_NOT_OFFERABLE", "SERVICE_QUOTE_HOLDS_TOO_MANY", "SERVICE_QUOTE_SUPERSEDED", "SERVICE_QUOTE_ALREADY_RESOLVED", "SERVICE_QUOTE_LAPSED", "SERVICE_QUOTE_CHANNEL_RESERVED", "SERVICE_QUOTE_CHANNEL_NOT_APPLICABLE", "SERVICE_QUOTE_REASON_NOT_APPLICABLE", "SERVICE_QUOTE_TERM_REQUIRED", "SERVICE_ORDER_QUOTE_CHANGED", "SERVICE_ORDER_NOT_READY", "SERVICE_RENOTIFY_IMPERSONATED", "SERVICE_RENOTIFY_TOO_SOON", "SERVICE_RENOTIFY_CONFLICT", "SERVICE_RENOTIFY_NOT_RECORDED", "SERVICE_RENOTIFY_LEDGER_UNREADABLE", "SERVICE_RENOTIFY_NOT_DISPATCHED", "SERVICE_TIMER_ALREADY_RUNNING", "SERVICE_TIMER_NOT_RUNNING", "SERVICE_TIMER_STOP_CONFLICT", "TECHNICIAN_NOT_CLOCKED_IN", "SERVICE_ORDER_GONE", "SERVICE_WORKLOG_NOT_FOUND", "SERVICE_WORKLOG_NOT_REVERSIBLE", "SERVICE_WORKLOG_ALREADY_REVERSED", "SERVICE_ORDER_WORKLOG_CHANGED", "CART_PROMOTION_UNAVAILABLE", "COUPON_NOT_FOUND", "COUPON_NOT_ACTIVE", "COUPON_EXPIRED", "COUPON_EXHAUSTED", "COUPON_EXHAUSTED_AT_CHECKOUT", "COUPON_MIN_SUBTOTAL", "COUPON_REQUIRES_CUSTOMER", "COUPON_BUDGET_EXHAUSTED", "COUPON_CURRENCY_MISMATCH"];
1556
1573
  export type ServiceOrderErrorCode = (typeof SERVICE_ORDER_ERROR_CODES)[number];
1557
1574
  export {};
@@ -164,6 +164,13 @@ export const SERVICE_CUSTODIES = Object.keys(SERVICE_CUSTODY_TRANSITIONS);
164
164
  * separately by {@link MAX_IMAGE_BASE64_CHARS}.
165
165
  */
166
166
  export const MAX_SERVICE_PICTURES = 20;
167
+ /**
168
+ * The bounds of `ServiceQuote.completionDays` (art. 21(e), calendar days from
169
+ * approval). `POST /services { mode: 'quote', action: 'create' }` refuses a
170
+ * value outside them, or a fraction, with `400 VALIDATION_FAILED`.
171
+ */
172
+ export const SERVICE_QUOTE_COMPLETION_DAYS_MIN = 1;
173
+ export const SERVICE_QUOTE_COMPLETION_DAYS_MAX = 365;
167
174
  /**
168
175
  * `body.error` codes `/services` refuses with — every mode of `POST /services`
169
176
  * and every `GET /services` read (list, `?mode=unclaimed`, by id, `?mode=pdf`).
@@ -377,6 +384,8 @@ export const SERVICE_ORDER_ERROR_CODES = [
377
384
  'SERVICE_QUOTE_CHANNEL_RESERVED',
378
385
  'SERVICE_QUOTE_CHANNEL_NOT_APPLICABLE',
379
386
  'SERVICE_QUOTE_REASON_NOT_APPLICABLE',
387
+ // The customer's online approval of a version that states no term (art. 21(e))
388
+ 'SERVICE_QUOTE_TERM_REQUIRED',
380
389
  'SERVICE_ORDER_QUOTE_CHANGED',
381
390
  // Renotify
382
391
  'SERVICE_ORDER_NOT_READY',
@@ -76,16 +76,27 @@ export type ServiceTrackingOperatorErrorCode = (typeof SERVICE_TRACKING_OPERATOR
76
76
  * (the same decision again answers 200 with the current view and writes nothing).
77
77
  * - SERVICE_QUOTE_LAPSED (409, approve only): past `expiresAt`. A rejection is
78
78
  * still accepted.
79
+ * - SERVICE_QUOTE_TERM_REQUIRED (409, approve only): the version states no term
80
+ * (Ley 24.240 art. 21(e)) — neither `completionDays` nor a FUTURE
81
+ * `promisedAt`. Checked before the code, so it spends no attempt. A rejection
82
+ * is still accepted; the shop re-quotes with a term or sets a future
83
+ * `promisedAt`.
79
84
  * - SERVICE_ORDER_QUOTE_CHANGED (409): the order moved under the decision — retry.
80
85
  * - SERVICE_ORDER_TERMINAL / SERVICE_ORDER_DISABLED (409): the ticket is closed
81
86
  * or deleted.
82
87
  * - SERVICE_QUOTE_HOLDS_TOO_MANY (400, approve only): the version's parts cannot
83
88
  * be reserved in one write; the shop must re-quote.
84
89
  */
85
- export declare const SERVICE_TRACKING_DECISION_ERROR_CODES: readonly ["SERVICE_TRACKING_TOKEN_INVALID", "SERVICE_TRACKING_VERIFICATION_FAILED", "SERVICE_TRACKING_DISABLED", "SERVICE_ORDER_NOT_FOUND", "SERVICE_QUOTE_NOT_FOUND", "SERVICE_QUOTE_SUPERSEDED", "SERVICE_QUOTE_ALREADY_RESOLVED", "SERVICE_QUOTE_LAPSED", "SERVICE_ORDER_QUOTE_CHANGED", "SERVICE_ORDER_TERMINAL", "SERVICE_ORDER_DISABLED", "SERVICE_QUOTE_HOLDS_TOO_MANY"];
90
+ export declare const SERVICE_TRACKING_DECISION_ERROR_CODES: readonly ["SERVICE_TRACKING_TOKEN_INVALID", "SERVICE_TRACKING_VERIFICATION_FAILED", "SERVICE_TRACKING_DISABLED", "SERVICE_ORDER_NOT_FOUND", "SERVICE_QUOTE_NOT_FOUND", "SERVICE_QUOTE_SUPERSEDED", "SERVICE_QUOTE_ALREADY_RESOLVED", "SERVICE_QUOTE_LAPSED", "SERVICE_QUOTE_TERM_REQUIRED", "SERVICE_ORDER_QUOTE_CHANGED", "SERVICE_ORDER_TERMINAL", "SERVICE_ORDER_DISABLED", "SERVICE_QUOTE_HOLDS_TOO_MANY"];
86
91
  export type ServiceTrackingDecisionErrorCode = (typeof SERVICE_TRACKING_DECISION_ERROR_CODES)[number];
87
92
  /** Where the 6-digit decision code is sent: the phone or the email on file. */
88
93
  export declare const SERVICE_TRACKING_CODE_VIAS: readonly ["sms", "email"];
94
+ /**
95
+ * Why `ServiceTrackingDecision.canApprove` is false while `canDecide` is true,
96
+ * in the order they are checked: `lapsed` (past `expiresAt`), then
97
+ * `term_required` (no `completionDays` and no future `promisedAt`).
98
+ */
99
+ export declare const SERVICE_TRACKING_APPROVE_BLOCKS: readonly ["lapsed", "term_required"];
89
100
  /** The customer's two online answers to a presupuesto. */
90
101
  export declare const SERVICE_TRACKING_QUOTE_DECISIONS: readonly ["approve", "reject"];
91
102
  /** A decision challenge handle: 16 random bytes, base64url (22 characters). */
@@ -183,6 +194,8 @@ declare global {
183
194
  quotedAt?: number;
184
195
  /** Unix ms the offer lapses (Ley 24.240 art. 21(g)). */
185
196
  expiresAt?: number;
197
+ /** Art. 21(e): calendar days the work takes, counted from approval (`ServiceQuote.completionDays`). */
198
+ completionDays?: number;
186
199
  parts: ServiceTrackingQuotePart[];
187
200
  /** Unix ms of the approval or the rejection. */
188
201
  decidedAt?: number;
@@ -201,6 +214,14 @@ declare global {
201
214
  * `true` on the link, `false` signed in (the session is the proof).
202
215
  */
203
216
  approveNeedsCode: boolean;
217
+ /**
218
+ * `canDecide` && not lapsed && the quote states a term (`completionDays`,
219
+ * or a `promisedAt` later than now). False while `canDecide` is true means
220
+ * only a rejection is offered; the link sends no code then.
221
+ */
222
+ canApprove: boolean;
223
+ /** Present iff `canDecide && !canApprove`; `'lapsed'` is checked first. */
224
+ approveBlockedBy?: (typeof SERVICE_TRACKING_APPROVE_BLOCKS)[number];
204
225
  }
205
226
  type ServiceTrackingCodeVia = (typeof SERVICE_TRACKING_CODE_VIAS)[number];
206
227
  type ServiceTrackingQuoteDecision = (typeof SERVICE_TRACKING_QUOTE_DECISIONS)[number];
@@ -78,6 +78,11 @@ export const SERVICE_TRACKING_OPERATOR_ERROR_CODES = [
78
78
  * (the same decision again answers 200 with the current view and writes nothing).
79
79
  * - SERVICE_QUOTE_LAPSED (409, approve only): past `expiresAt`. A rejection is
80
80
  * still accepted.
81
+ * - SERVICE_QUOTE_TERM_REQUIRED (409, approve only): the version states no term
82
+ * (Ley 24.240 art. 21(e)) — neither `completionDays` nor a FUTURE
83
+ * `promisedAt`. Checked before the code, so it spends no attempt. A rejection
84
+ * is still accepted; the shop re-quotes with a term or sets a future
85
+ * `promisedAt`.
81
86
  * - SERVICE_ORDER_QUOTE_CHANGED (409): the order moved under the decision — retry.
82
87
  * - SERVICE_ORDER_TERMINAL / SERVICE_ORDER_DISABLED (409): the ticket is closed
83
88
  * or deleted.
@@ -93,6 +98,7 @@ export const SERVICE_TRACKING_DECISION_ERROR_CODES = [
93
98
  'SERVICE_QUOTE_SUPERSEDED',
94
99
  'SERVICE_QUOTE_ALREADY_RESOLVED',
95
100
  'SERVICE_QUOTE_LAPSED',
101
+ 'SERVICE_QUOTE_TERM_REQUIRED',
96
102
  'SERVICE_ORDER_QUOTE_CHANGED',
97
103
  'SERVICE_ORDER_TERMINAL',
98
104
  'SERVICE_ORDER_DISABLED',
@@ -100,6 +106,12 @@ export const SERVICE_TRACKING_DECISION_ERROR_CODES = [
100
106
  ];
101
107
  /** Where the 6-digit decision code is sent: the phone or the email on file. */
102
108
  export const SERVICE_TRACKING_CODE_VIAS = ['sms', 'email'];
109
+ /**
110
+ * Why `ServiceTrackingDecision.canApprove` is false while `canDecide` is true,
111
+ * in the order they are checked: `lapsed` (past `expiresAt`), then
112
+ * `term_required` (no `completionDays` and no future `promisedAt`).
113
+ */
114
+ export const SERVICE_TRACKING_APPROVE_BLOCKS = ['lapsed', 'term_required'];
103
115
  /** The customer's two online answers to a presupuesto. */
104
116
  export const SERVICE_TRACKING_QUOTE_DECISIONS = ['approve', 'reject'];
105
117
  /** A decision challenge handle: 16 random bytes, base64url (22 characters). */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "platform-types",
3
- "version": "1.10.865",
3
+ "version": "1.10.866",
4
4
  "description": "Shared wire and entity contracts for the platform.",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",