@adminiumjs/add-on-contracts 0.3.16 → 0.3.18-rc.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/add-on-block.d.ts +82 -10
- package/dist/add-on-block.d.ts.map +1 -1
- package/dist/add-on-block.js +66 -10
- package/dist/add-on-block.js.map +1 -1
- package/dist/common.d.ts +17 -0
- package/dist/common.d.ts.map +1 -1
- package/dist/common.js +17 -0
- package/dist/common.js.map +1 -1
- package/dist/contracts.d.ts +13 -1
- package/dist/contracts.d.ts.map +1 -1
- package/dist/contracts.js +27 -1
- package/dist/contracts.js.map +1 -1
- package/dist/document-render.d.ts +8 -7
- package/dist/document-render.d.ts.map +1 -1
- package/dist/document-render.js +2 -2
- package/dist/document-render.js.map +1 -1
- package/dist/index.d.ts +4 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -1
- package/dist/index.js.map +1 -1
- package/dist/posting-rows.d.ts +234 -0
- package/dist/posting-rows.d.ts.map +1 -0
- package/dist/posting-rows.js +126 -0
- package/dist/posting-rows.js.map +1 -0
- package/dist/price-adjust.d.ts +274 -0
- package/dist/price-adjust.d.ts.map +1 -0
- package/dist/price-adjust.js +145 -0
- package/dist/price-adjust.js.map +1 -0
- package/dist/record-tabs.d.ts +141 -0
- package/dist/record-tabs.d.ts.map +1 -0
- package/dist/record-tabs.js +167 -0
- package/dist/record-tabs.js.map +1 -0
- package/dist/runtime/data-types.d.ts +240 -0
- package/dist/runtime/data-types.d.ts.map +1 -0
- package/dist/runtime/data-types.js +15 -0
- package/dist/runtime/data-types.js.map +1 -0
- package/dist/runtime/data.d.ts +61 -0
- package/dist/runtime/data.d.ts.map +1 -0
- package/dist/runtime/data.js +61 -0
- package/dist/runtime/data.js.map +1 -0
- package/dist/runtime/index.d.ts +51 -1
- package/dist/runtime/index.d.ts.map +1 -1
- package/dist/runtime/index.js +100 -1
- package/dist/runtime/index.js.map +1 -1
- package/dist/testing/index.d.ts +2 -0
- package/dist/testing/index.d.ts.map +1 -1
- package/dist/testing/index.js +2 -0
- package/dist/testing/index.js.map +1 -1
- package/dist/testing/posting-rows.d.ts +34 -0
- package/dist/testing/posting-rows.d.ts.map +1 -0
- package/dist/testing/posting-rows.js +225 -0
- package/dist/testing/posting-rows.js.map +1 -0
- package/dist/testing/price-adjust.d.ts +21 -0
- package/dist/testing/price-adjust.d.ts.map +1 -0
- package/dist/testing/price-adjust.js +71 -0
- package/dist/testing/price-adjust.js.map +1 -0
- package/package.json +5 -1
|
@@ -0,0 +1,274 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `price-adjust@1` — what an order's lines are reduced by.
|
|
3
|
+
*
|
|
4
|
+
* An add-on that keeps offers, discount codes and vouchers provides this
|
|
5
|
+
* contract once. Adminium calls `adjust(input)` with the order's lines, the
|
|
6
|
+
* codes typed on it (each already looked up), who is buying when that was
|
|
7
|
+
* proved, what staff took off by hand, and the offers it read; and writes
|
|
8
|
+
* what comes back itself — one reduction per line, the rows that say what was
|
|
9
|
+
* applied — inside the save.
|
|
10
|
+
*
|
|
11
|
+
* The provider reads nothing, writes nothing and keeps no clock: `now`,
|
|
12
|
+
* `today`, `weekday`, `time` and `zone` are inputs. The same input gives the
|
|
13
|
+
* same output. The call is synchronous.
|
|
14
|
+
*/
|
|
15
|
+
import { z } from 'zod';
|
|
16
|
+
import type { PostingScalar, PostingUse } from './posting-rows.js';
|
|
17
|
+
/** The most lines, typed codes and offers one question carries. */
|
|
18
|
+
export declare const ADJUST_LINES_MAX = 200;
|
|
19
|
+
export declare const ADJUST_CODES_MAX = 12;
|
|
20
|
+
export declare const ADJUST_OFFERS_MAX = 500;
|
|
21
|
+
/** `save` and `dry` price an order; `try` is staff's preview of an offer not yet saved; `refund` prices the lines kept. */
|
|
22
|
+
export declare const ADJUST_MODES: readonly ["save", "dry", "try", "refund"];
|
|
23
|
+
export type AdjustMode = (typeof ADJUST_MODES)[number];
|
|
24
|
+
/** Why a typed code, or a reduction staff gave, is refused. Adminium decides what the public is told of each. */
|
|
25
|
+
export declare const ADJUST_REASONS: readonly ["unknown", "used-up", "needs-minimum", "not-for-these-items", "needs-sign-in", "needs-customer", "over-ceiling", "expired", "inactive", "void", "not-yet", "over-limit"];
|
|
26
|
+
export type AdjustReason = (typeof ADJUST_REASONS)[number];
|
|
27
|
+
/** The reasons a guest is told by name; every other reason leaves as `unknown`. */
|
|
28
|
+
export declare const ADJUST_PUBLIC_REASONS: readonly ["unknown", "used-up", "needs-minimum", "not-for-these-items", "needs-sign-in"];
|
|
29
|
+
/** Why an offer did not apply, in staff's "why not" view. */
|
|
30
|
+
export declare const ADJUST_EXPLAIN_REASONS: readonly ["unknown", "used-up", "needs-minimum", "not-for-these-items", "needs-sign-in", "needs-customer", "over-ceiling", "expired", "inactive", "void", "not-yet", "over-limit", "not-combinable", "outside-hours", "outside-days", "needs-quantity", "not-in-group", "not-first-order", "ended", "paused", "draft", "no-code-typed"];
|
|
31
|
+
export type ExplainReason = (typeof ADJUST_EXPLAIN_REASONS)[number];
|
|
32
|
+
export declare const ADJUST_KINDS: readonly ["offer", "code", "voucher", "pack", "staff"];
|
|
33
|
+
export type AdjustKind = (typeof ADJUST_KINDS)[number];
|
|
34
|
+
export interface AdjustLine {
|
|
35
|
+
/** The line's key as text; the order's own key for a line that is the order itself. */
|
|
36
|
+
key: string;
|
|
37
|
+
/** Which line part of the host's rule the line belongs to, and its place in it. */
|
|
38
|
+
part: number;
|
|
39
|
+
index: number;
|
|
40
|
+
/** Decimals as text, at `AdjustInput.scale`. `amount` is price × quantity. */
|
|
41
|
+
price: string;
|
|
42
|
+
quantity: string;
|
|
43
|
+
amount: string;
|
|
44
|
+
/** What the line sells, each as a table's stored name and a row's key. */
|
|
45
|
+
what: {
|
|
46
|
+
as: 'item' | 'category' | 'type' | 'tag';
|
|
47
|
+
table: string;
|
|
48
|
+
row: string;
|
|
49
|
+
}[];
|
|
50
|
+
/** No offer reduces it (a gift card being loaded). */
|
|
51
|
+
excluded: boolean;
|
|
52
|
+
/** The code that pays for the line, or null. */
|
|
53
|
+
paidBy: string | null;
|
|
54
|
+
/** False for a line being returned (mode `refund`). */
|
|
55
|
+
kept: boolean;
|
|
56
|
+
/** A stay's nights, each with its own price. */
|
|
57
|
+
nights?: {
|
|
58
|
+
date: string;
|
|
59
|
+
price: string;
|
|
60
|
+
}[];
|
|
61
|
+
}
|
|
62
|
+
export interface AdjustCode {
|
|
63
|
+
/** As the customer typed it. */
|
|
64
|
+
typed: string;
|
|
65
|
+
/** Which of the add-on's tables the row came from; null when no row was found. */
|
|
66
|
+
kind: 'code' | 'voucher' | null;
|
|
67
|
+
row: Record<string, PostingScalar | null> | null;
|
|
68
|
+
}
|
|
69
|
+
/** One use of an offer, a code or a voucher, recorded once where the order is posted. */
|
|
70
|
+
export type AdjustUse = PostingUse;
|
|
71
|
+
export interface AdjustInput {
|
|
72
|
+
contract: 'price-adjust@1';
|
|
73
|
+
mode: AdjustMode;
|
|
74
|
+
/** `line`: a line was written; `post`: the order reached its posting point, and uses are reported. */
|
|
75
|
+
point: 'line' | 'post';
|
|
76
|
+
origin: 'staff' | 'public' | 'system';
|
|
77
|
+
now: string;
|
|
78
|
+
today: string;
|
|
79
|
+
weekday: 0 | 1 | 2 | 3 | 4 | 5 | 6;
|
|
80
|
+
time: string;
|
|
81
|
+
zone: string;
|
|
82
|
+
currency: string | null;
|
|
83
|
+
/** The decimals of every amount. */
|
|
84
|
+
scale: number;
|
|
85
|
+
locale: string;
|
|
86
|
+
lines: AdjustLine[];
|
|
87
|
+
/** In the order typed. */
|
|
88
|
+
codes: AdjustCode[];
|
|
89
|
+
/** The buyer, when their identity was proved: a keyed hash, never an address. */
|
|
90
|
+
customer: {
|
|
91
|
+
key: string;
|
|
92
|
+
groups: string[];
|
|
93
|
+
orders: number;
|
|
94
|
+
uses: Record<string, number>;
|
|
95
|
+
} | null;
|
|
96
|
+
/** True when no identity was proved. */
|
|
97
|
+
guest: boolean;
|
|
98
|
+
/** What staff took off by hand, with the ceiling Adminium read for whoever gave it. */
|
|
99
|
+
staff: {
|
|
100
|
+
kind: 'percent' | 'amount' | 'comp';
|
|
101
|
+
value: string;
|
|
102
|
+
reason: string | null;
|
|
103
|
+
ceiling: {
|
|
104
|
+
percent: string;
|
|
105
|
+
amount: string;
|
|
106
|
+
} | null;
|
|
107
|
+
judge: boolean;
|
|
108
|
+
} | null;
|
|
109
|
+
/** The adjuster's declared reads, by name. */
|
|
110
|
+
offers: Record<string, Record<string, PostingScalar | null>[]>;
|
|
111
|
+
/** The add-on's settings row. */
|
|
112
|
+
settings: Record<string, PostingScalar | null>;
|
|
113
|
+
/** The rows the order's own open round holds, so its own held use is not counted against it. */
|
|
114
|
+
held?: Record<string, Record<string, PostingScalar | null>[]>;
|
|
115
|
+
/** Mode `try` only: an offer not saved yet, considered with the stored ones. */
|
|
116
|
+
draft?: Record<string, PostingScalar | null>;
|
|
117
|
+
/** Whether to say, for every offer, whether it applies and why not. */
|
|
118
|
+
explain: boolean;
|
|
119
|
+
/** The add-on's installed version. */
|
|
120
|
+
version: string;
|
|
121
|
+
}
|
|
122
|
+
export interface AdjustApplied {
|
|
123
|
+
/** The line it reduces. */
|
|
124
|
+
line: string;
|
|
125
|
+
offer: string | null;
|
|
126
|
+
code: string | null;
|
|
127
|
+
voucher: string | null;
|
|
128
|
+
/** What it is called: per locale, or one string. */
|
|
129
|
+
name: Record<string, string> | string;
|
|
130
|
+
kind: AdjustKind;
|
|
131
|
+
amount: string;
|
|
132
|
+
/** Whether the customer typed it. */
|
|
133
|
+
typed: boolean;
|
|
134
|
+
reason?: string;
|
|
135
|
+
}
|
|
136
|
+
export interface AdjustOutput {
|
|
137
|
+
/** One entry for every line of the input, and no other: its reduction, as text, zero or more. */
|
|
138
|
+
lines: {
|
|
139
|
+
key: string;
|
|
140
|
+
discount: string;
|
|
141
|
+
}[];
|
|
142
|
+
/** The sum of the lines'. */
|
|
143
|
+
order: {
|
|
144
|
+
discount: string;
|
|
145
|
+
};
|
|
146
|
+
applied: AdjustApplied[];
|
|
147
|
+
/** Point `post` only. */
|
|
148
|
+
uses: AdjustUse[];
|
|
149
|
+
refused: {
|
|
150
|
+
typed: string;
|
|
151
|
+
reason: AdjustReason;
|
|
152
|
+
params?: {
|
|
153
|
+
amount?: string;
|
|
154
|
+
max?: string;
|
|
155
|
+
name?: string;
|
|
156
|
+
};
|
|
157
|
+
}[];
|
|
158
|
+
/** Said beside a typed code that was not needed. */
|
|
159
|
+
told?: {
|
|
160
|
+
typed: string;
|
|
161
|
+
note: 'better-offer-applied';
|
|
162
|
+
name: string;
|
|
163
|
+
}[];
|
|
164
|
+
/** With `explain`: every offer handed in (or `draft`). */
|
|
165
|
+
explain?: {
|
|
166
|
+
offer: string;
|
|
167
|
+
applies: boolean;
|
|
168
|
+
reason?: ExplainReason;
|
|
169
|
+
amount?: string;
|
|
170
|
+
}[];
|
|
171
|
+
}
|
|
172
|
+
/** What an add-on's server file exports under `adjust`. Synchronous. */
|
|
173
|
+
export interface PriceAdjustProvider {
|
|
174
|
+
adjust(input: AdjustInput): AdjustOutput;
|
|
175
|
+
}
|
|
176
|
+
export declare const adjustOutputSchema: z.ZodObject<{
|
|
177
|
+
lines: z.ZodArray<z.ZodObject<{
|
|
178
|
+
key: z.ZodString;
|
|
179
|
+
discount: z.ZodString;
|
|
180
|
+
}, z.core.$strict>>;
|
|
181
|
+
order: z.ZodObject<{
|
|
182
|
+
discount: z.ZodString;
|
|
183
|
+
}, z.core.$strict>;
|
|
184
|
+
applied: z.ZodArray<z.ZodObject<{
|
|
185
|
+
line: z.ZodString;
|
|
186
|
+
offer: z.ZodNullable<z.ZodString>;
|
|
187
|
+
code: z.ZodNullable<z.ZodString>;
|
|
188
|
+
voucher: z.ZodNullable<z.ZodString>;
|
|
189
|
+
name: z.ZodUnion<readonly [z.ZodString, z.ZodRecord<z.ZodString, z.ZodString>]>;
|
|
190
|
+
kind: z.ZodEnum<{
|
|
191
|
+
code: "code";
|
|
192
|
+
staff: "staff";
|
|
193
|
+
offer: "offer";
|
|
194
|
+
voucher: "voucher";
|
|
195
|
+
pack: "pack";
|
|
196
|
+
}>;
|
|
197
|
+
amount: z.ZodString;
|
|
198
|
+
typed: z.ZodBoolean;
|
|
199
|
+
reason: z.ZodOptional<z.ZodString>;
|
|
200
|
+
}, z.core.$strict>>;
|
|
201
|
+
uses: z.ZodArray<z.ZodObject<{
|
|
202
|
+
offer: z.ZodNullable<z.ZodString>;
|
|
203
|
+
code: z.ZodNullable<z.ZodString>;
|
|
204
|
+
voucher: z.ZodNullable<z.ZodString>;
|
|
205
|
+
amount: z.ZodString;
|
|
206
|
+
units: z.ZodOptional<z.ZodNumber>;
|
|
207
|
+
customer: z.ZodOptional<z.ZodString>;
|
|
208
|
+
}, z.core.$strict>>;
|
|
209
|
+
refused: z.ZodArray<z.ZodObject<{
|
|
210
|
+
typed: z.ZodString;
|
|
211
|
+
reason: z.ZodEnum<{
|
|
212
|
+
void: "void";
|
|
213
|
+
unknown: "unknown";
|
|
214
|
+
expired: "expired";
|
|
215
|
+
inactive: "inactive";
|
|
216
|
+
"used-up": "used-up";
|
|
217
|
+
"over-limit": "over-limit";
|
|
218
|
+
"needs-customer": "needs-customer";
|
|
219
|
+
"needs-minimum": "needs-minimum";
|
|
220
|
+
"not-for-these-items": "not-for-these-items";
|
|
221
|
+
"needs-sign-in": "needs-sign-in";
|
|
222
|
+
"over-ceiling": "over-ceiling";
|
|
223
|
+
"not-yet": "not-yet";
|
|
224
|
+
}>;
|
|
225
|
+
params: z.ZodOptional<z.ZodObject<{
|
|
226
|
+
amount: z.ZodOptional<z.ZodString>;
|
|
227
|
+
max: z.ZodOptional<z.ZodString>;
|
|
228
|
+
name: z.ZodOptional<z.ZodString>;
|
|
229
|
+
}, z.core.$strict>>;
|
|
230
|
+
}, z.core.$strict>>;
|
|
231
|
+
told: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
232
|
+
typed: z.ZodString;
|
|
233
|
+
note: z.ZodLiteral<"better-offer-applied">;
|
|
234
|
+
name: z.ZodString;
|
|
235
|
+
}, z.core.$strict>>>;
|
|
236
|
+
explain: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
237
|
+
offer: z.ZodString;
|
|
238
|
+
applies: z.ZodBoolean;
|
|
239
|
+
reason: z.ZodOptional<z.ZodEnum<{
|
|
240
|
+
void: "void";
|
|
241
|
+
unknown: "unknown";
|
|
242
|
+
expired: "expired";
|
|
243
|
+
inactive: "inactive";
|
|
244
|
+
"used-up": "used-up";
|
|
245
|
+
"over-limit": "over-limit";
|
|
246
|
+
"needs-customer": "needs-customer";
|
|
247
|
+
"needs-minimum": "needs-minimum";
|
|
248
|
+
"not-for-these-items": "not-for-these-items";
|
|
249
|
+
"needs-sign-in": "needs-sign-in";
|
|
250
|
+
"over-ceiling": "over-ceiling";
|
|
251
|
+
"not-yet": "not-yet";
|
|
252
|
+
"not-combinable": "not-combinable";
|
|
253
|
+
"outside-hours": "outside-hours";
|
|
254
|
+
"outside-days": "outside-days";
|
|
255
|
+
"needs-quantity": "needs-quantity";
|
|
256
|
+
"not-in-group": "not-in-group";
|
|
257
|
+
"not-first-order": "not-first-order";
|
|
258
|
+
ended: "ended";
|
|
259
|
+
paused: "paused";
|
|
260
|
+
draft: "draft";
|
|
261
|
+
"no-code-typed": "no-code-typed";
|
|
262
|
+
}>>;
|
|
263
|
+
amount: z.ZodOptional<z.ZodString>;
|
|
264
|
+
}, z.core.$strict>>>;
|
|
265
|
+
}, z.core.$strict>;
|
|
266
|
+
/**
|
|
267
|
+
* What is wrong with an answer for this input, beyond its shape: a line
|
|
268
|
+
* missing or invented, a reduction larger than its line or finer than the
|
|
269
|
+
* scale, an excluded line reduced, an order total that is not the lines'
|
|
270
|
+
* sum, uses reported where none are due, a reason a guest is never told.
|
|
271
|
+
* Adminium runs the same check before it writes.
|
|
272
|
+
*/
|
|
273
|
+
export declare function adjustAnswerIssues(input: AdjustInput, output: AdjustOutput): string[];
|
|
274
|
+
//# sourceMappingURL=price-adjust.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"price-adjust.d.ts","sourceRoot":"","sources":["../src/price-adjust.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
// SPDX-License-Identifier: AGPL-3.0-only
|
|
2
|
+
/**
|
|
3
|
+
* `price-adjust@1` — what an order's lines are reduced by.
|
|
4
|
+
*
|
|
5
|
+
* An add-on that keeps offers, discount codes and vouchers provides this
|
|
6
|
+
* contract once. Adminium calls `adjust(input)` with the order's lines, the
|
|
7
|
+
* codes typed on it (each already looked up), who is buying when that was
|
|
8
|
+
* proved, what staff took off by hand, and the offers it read; and writes
|
|
9
|
+
* what comes back itself — one reduction per line, the rows that say what was
|
|
10
|
+
* applied — inside the save.
|
|
11
|
+
*
|
|
12
|
+
* The provider reads nothing, writes nothing and keeps no clock: `now`,
|
|
13
|
+
* `today`, `weekday`, `time` and `zone` are inputs. The same input gives the
|
|
14
|
+
* same output. The call is synchronous.
|
|
15
|
+
*/
|
|
16
|
+
import { z } from 'zod';
|
|
17
|
+
/** The most lines, typed codes and offers one question carries. */
|
|
18
|
+
export const ADJUST_LINES_MAX = 200;
|
|
19
|
+
export const ADJUST_CODES_MAX = 12;
|
|
20
|
+
export const ADJUST_OFFERS_MAX = 500;
|
|
21
|
+
/** `save` and `dry` price an order; `try` is staff's preview of an offer not yet saved; `refund` prices the lines kept. */
|
|
22
|
+
export const ADJUST_MODES = ['save', 'dry', 'try', 'refund'];
|
|
23
|
+
/** Why a typed code, or a reduction staff gave, is refused. Adminium decides what the public is told of each. */
|
|
24
|
+
export const ADJUST_REASONS = [
|
|
25
|
+
'unknown',
|
|
26
|
+
'used-up',
|
|
27
|
+
'needs-minimum',
|
|
28
|
+
'not-for-these-items',
|
|
29
|
+
'needs-sign-in',
|
|
30
|
+
'needs-customer',
|
|
31
|
+
'over-ceiling',
|
|
32
|
+
'expired',
|
|
33
|
+
'inactive',
|
|
34
|
+
'void',
|
|
35
|
+
'not-yet',
|
|
36
|
+
'over-limit',
|
|
37
|
+
];
|
|
38
|
+
/** The reasons a guest is told by name; every other reason leaves as `unknown`. */
|
|
39
|
+
export const ADJUST_PUBLIC_REASONS = ['unknown', 'used-up', 'needs-minimum', 'not-for-these-items', 'needs-sign-in'];
|
|
40
|
+
/** Why an offer did not apply, in staff's "why not" view. */
|
|
41
|
+
export const ADJUST_EXPLAIN_REASONS = [
|
|
42
|
+
...ADJUST_REASONS,
|
|
43
|
+
'not-combinable',
|
|
44
|
+
'outside-hours',
|
|
45
|
+
'outside-days',
|
|
46
|
+
'needs-quantity',
|
|
47
|
+
'not-in-group',
|
|
48
|
+
'not-first-order',
|
|
49
|
+
'ended',
|
|
50
|
+
'paused',
|
|
51
|
+
'draft',
|
|
52
|
+
'no-code-typed',
|
|
53
|
+
];
|
|
54
|
+
export const ADJUST_KINDS = ['offer', 'code', 'voucher', 'pack', 'staff'];
|
|
55
|
+
// ── the shape Adminium checks before it reads an answer ──────────────────────
|
|
56
|
+
const amount = z.string().regex(/^\d+(\.\d+)?$/, 'an amount as text, zero or more');
|
|
57
|
+
const id = z.string().min(1).max(64);
|
|
58
|
+
export const adjustOutputSchema = z
|
|
59
|
+
.object({
|
|
60
|
+
lines: z.array(z.object({ key: z.string().max(64), discount: amount }).strict()).max(ADJUST_LINES_MAX),
|
|
61
|
+
order: z.object({ discount: amount }).strict(),
|
|
62
|
+
applied: z
|
|
63
|
+
.array(z
|
|
64
|
+
.object({
|
|
65
|
+
line: z.string().max(64),
|
|
66
|
+
offer: id.nullable(),
|
|
67
|
+
code: id.nullable(),
|
|
68
|
+
voucher: id.nullable(),
|
|
69
|
+
name: z.union([z.string().max(200), z.record(z.string(), z.string().max(200))]),
|
|
70
|
+
kind: z.enum(ADJUST_KINDS),
|
|
71
|
+
amount,
|
|
72
|
+
typed: z.boolean(),
|
|
73
|
+
reason: z.string().max(200).optional(),
|
|
74
|
+
})
|
|
75
|
+
.strict())
|
|
76
|
+
.max(ADJUST_LINES_MAX * 4),
|
|
77
|
+
uses: z.array(z.object({ offer: id.nullable(), code: id.nullable(), voucher: id.nullable(), amount, units: z.number().int().min(0).optional(), customer: z.string().max(64).optional() }).strict()).max(ADJUST_OFFERS_MAX),
|
|
78
|
+
refused: z
|
|
79
|
+
.array(z.object({ typed: z.string().max(64), reason: z.enum(ADJUST_REASONS), params: z.object({ amount: amount.optional(), max: amount.optional(), name: z.string().max(200).optional() }).strict().optional() }).strict())
|
|
80
|
+
.max(ADJUST_CODES_MAX + 1),
|
|
81
|
+
told: z.array(z.object({ typed: z.string().max(64), note: z.literal('better-offer-applied'), name: z.string().max(200) }).strict()).max(ADJUST_CODES_MAX).optional(),
|
|
82
|
+
explain: z.array(z.object({ offer: id, applies: z.boolean(), reason: z.enum(ADJUST_EXPLAIN_REASONS).optional(), amount: amount.optional() }).strict()).max(ADJUST_OFFERS_MAX + 1).optional(),
|
|
83
|
+
})
|
|
84
|
+
.strict();
|
|
85
|
+
/** An amount as a whole number of the smallest unit at `scale`, so sums are exact. */
|
|
86
|
+
function units(text, scale) {
|
|
87
|
+
const [whole = '0', fraction = ''] = text.split('.');
|
|
88
|
+
return BigInt(whole) * 10n ** BigInt(scale) + BigInt((fraction + '0'.repeat(scale)).slice(0, scale) || '0');
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* What is wrong with an answer for this input, beyond its shape: a line
|
|
92
|
+
* missing or invented, a reduction larger than its line or finer than the
|
|
93
|
+
* scale, an excluded line reduced, an order total that is not the lines'
|
|
94
|
+
* sum, uses reported where none are due, a reason a guest is never told.
|
|
95
|
+
* Adminium runs the same check before it writes.
|
|
96
|
+
*/
|
|
97
|
+
export function adjustAnswerIssues(input, output) {
|
|
98
|
+
const out = [];
|
|
99
|
+
const wanted = new Map(input.lines.map((line) => [line.key, line]));
|
|
100
|
+
const seen = new Set();
|
|
101
|
+
let sum = 0n;
|
|
102
|
+
for (const [i, line] of output.lines.entries()) {
|
|
103
|
+
const asked = wanted.get(line.key);
|
|
104
|
+
if (asked === undefined) {
|
|
105
|
+
out.push(`lines.${String(i)}: "${line.key}" is not a line of the question`);
|
|
106
|
+
continue;
|
|
107
|
+
}
|
|
108
|
+
if (seen.has(line.key))
|
|
109
|
+
out.push(`lines.${String(i)}: "${line.key}" is answered twice`);
|
|
110
|
+
seen.add(line.key);
|
|
111
|
+
if ((line.discount.split('.')[1] ?? '').length > input.scale)
|
|
112
|
+
out.push(`lines.${String(i)}: "${line.discount}" is finer than the order's ${String(input.scale)} decimals`);
|
|
113
|
+
const reduction = units(line.discount, input.scale);
|
|
114
|
+
if (reduction > units(asked.amount, input.scale))
|
|
115
|
+
out.push(`lines.${String(i)}: a reduction of ${line.discount} is more than the line's ${asked.amount}`);
|
|
116
|
+
if (asked.excluded && reduction !== 0n)
|
|
117
|
+
out.push(`lines.${String(i)}: "${line.key}" is excluded, so nothing reduces it`);
|
|
118
|
+
sum += reduction;
|
|
119
|
+
}
|
|
120
|
+
for (const key of wanted.keys())
|
|
121
|
+
if (!seen.has(key))
|
|
122
|
+
out.push(`lines: the line "${key}" has no answer`);
|
|
123
|
+
if (units(output.order.discount, input.scale) !== sum)
|
|
124
|
+
out.push(`order.discount: ${output.order.discount} is not the sum of the lines' reductions`);
|
|
125
|
+
if (input.point !== 'post' && output.uses.length > 0)
|
|
126
|
+
out.push('uses: uses are reported only where the order is posted');
|
|
127
|
+
for (const [i, applied] of output.applied.entries()) {
|
|
128
|
+
if (!wanted.has(applied.line))
|
|
129
|
+
out.push(`applied.${String(i)}: "${applied.line}" is not a line of the question`);
|
|
130
|
+
if (applied.kind === 'staff' && input.staff === null)
|
|
131
|
+
out.push(`applied.${String(i)}: staff took nothing off this order`);
|
|
132
|
+
}
|
|
133
|
+
for (const [i, refused] of output.refused.entries()) {
|
|
134
|
+
if (refused.reason === 'over-ceiling' && input.staff === null)
|
|
135
|
+
out.push(`refused.${String(i)}: "over-ceiling" is said of a reduction staff gave, and there is none`);
|
|
136
|
+
if (refused.reason === 'needs-sign-in' && !input.guest)
|
|
137
|
+
out.push(`refused.${String(i)}: "needs-sign-in" is said to a guest, and this customer is known`);
|
|
138
|
+
if (refused.reason === 'needs-customer' && input.origin !== 'staff')
|
|
139
|
+
out.push(`refused.${String(i)}: "needs-customer" is said to staff`);
|
|
140
|
+
}
|
|
141
|
+
if (input.explain && output.explain === undefined)
|
|
142
|
+
out.push('explain: the question asked why each offer applies or not');
|
|
143
|
+
return out;
|
|
144
|
+
}
|
|
145
|
+
//# sourceMappingURL=price-adjust.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"price-adjust.js","sourceRoot":"","sources":["../src/price-adjust.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A RECORD TAB — an add-on's rows shown on another table's record page.
|
|
3
|
+
*
|
|
4
|
+
* An add-on keeps rows that belong to rows of tables it does not own: the
|
|
5
|
+
* stock links of a menu item, the cards used on an order. It finds them by a
|
|
6
|
+
* pair it stores on each row — a table's stored name and a row's key — and a
|
|
7
|
+
* record tab is how those rows appear where their owner is looked at: a tab
|
|
8
|
+
* on that record's page, listing the add-on's rows for it.
|
|
9
|
+
*
|
|
10
|
+
* The tab is declared, not coded: which of the add-on's tables, which two
|
|
11
|
+
* columns hold the pair, which columns to show and which may be edited there.
|
|
12
|
+
* Adminium draws it with the page's own parts and the reader's own grants.
|
|
13
|
+
*
|
|
14
|
+
* This file is the shape, and the checks an add-on's manifest can make of it
|
|
15
|
+
* by itself.
|
|
16
|
+
*/
|
|
17
|
+
import { z } from 'zod';
|
|
18
|
+
/** The most tabs one add-on declares, and the most columns one tab shows. */
|
|
19
|
+
export declare const RECORD_TABS_MAX = 6;
|
|
20
|
+
export declare const RECORD_TAB_COLUMNS_MAX = 8;
|
|
21
|
+
export declare const recordTabSchema: z.ZodObject<{
|
|
22
|
+
id: z.ZodString;
|
|
23
|
+
label: z.ZodObject<{
|
|
24
|
+
key: z.ZodString;
|
|
25
|
+
fallback: z.ZodString;
|
|
26
|
+
}, z.core.$strict>;
|
|
27
|
+
labels: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
28
|
+
table: z.ZodString;
|
|
29
|
+
match: z.ZodObject<{
|
|
30
|
+
table: z.ZodString;
|
|
31
|
+
row: z.ZodString;
|
|
32
|
+
}, z.core.$strict>;
|
|
33
|
+
on: z.ZodUnion<readonly [z.ZodLiteral<"linked">, z.ZodArray<z.ZodString>]>;
|
|
34
|
+
columns: z.ZodArray<z.ZodString>;
|
|
35
|
+
edit: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
36
|
+
add: z.ZodOptional<z.ZodObject<{
|
|
37
|
+
pick: z.ZodUnion<readonly [z.ZodObject<{
|
|
38
|
+
table: z.ZodString;
|
|
39
|
+
label: z.ZodString;
|
|
40
|
+
}, z.core.$strict>, z.ZodArray<z.ZodObject<{
|
|
41
|
+
table: z.ZodString;
|
|
42
|
+
label: z.ZodString;
|
|
43
|
+
}, z.core.$strict>>]>;
|
|
44
|
+
}, z.core.$strict>>;
|
|
45
|
+
remove: z.ZodOptional<z.ZodLiteral<true>>;
|
|
46
|
+
form: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
47
|
+
empty: z.ZodOptional<z.ZodObject<{
|
|
48
|
+
key: z.ZodString;
|
|
49
|
+
fallback: z.ZodString;
|
|
50
|
+
}, z.core.$strict>>;
|
|
51
|
+
empties: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
52
|
+
summary: z.ZodOptional<z.ZodObject<{
|
|
53
|
+
words: z.ZodString;
|
|
54
|
+
}, z.core.$strict>>;
|
|
55
|
+
actions: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
56
|
+
id: z.ZodString;
|
|
57
|
+
label: z.ZodObject<{
|
|
58
|
+
key: z.ZodString;
|
|
59
|
+
fallback: z.ZodString;
|
|
60
|
+
}, z.core.$strict>;
|
|
61
|
+
labels: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
62
|
+
child: z.ZodObject<{
|
|
63
|
+
table: z.ZodString;
|
|
64
|
+
form: z.ZodArray<z.ZodString>;
|
|
65
|
+
}, z.core.$strict>;
|
|
66
|
+
}, z.core.$strict>>>;
|
|
67
|
+
}, z.core.$strict>;
|
|
68
|
+
export type RecordTab = z.infer<typeof recordTabSchema>;
|
|
69
|
+
export declare const recordTabsSchema: z.ZodArray<z.ZodObject<{
|
|
70
|
+
id: z.ZodString;
|
|
71
|
+
label: z.ZodObject<{
|
|
72
|
+
key: z.ZodString;
|
|
73
|
+
fallback: z.ZodString;
|
|
74
|
+
}, z.core.$strict>;
|
|
75
|
+
labels: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
76
|
+
table: z.ZodString;
|
|
77
|
+
match: z.ZodObject<{
|
|
78
|
+
table: z.ZodString;
|
|
79
|
+
row: z.ZodString;
|
|
80
|
+
}, z.core.$strict>;
|
|
81
|
+
on: z.ZodUnion<readonly [z.ZodLiteral<"linked">, z.ZodArray<z.ZodString>]>;
|
|
82
|
+
columns: z.ZodArray<z.ZodString>;
|
|
83
|
+
edit: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
84
|
+
add: z.ZodOptional<z.ZodObject<{
|
|
85
|
+
pick: z.ZodUnion<readonly [z.ZodObject<{
|
|
86
|
+
table: z.ZodString;
|
|
87
|
+
label: z.ZodString;
|
|
88
|
+
}, z.core.$strict>, z.ZodArray<z.ZodObject<{
|
|
89
|
+
table: z.ZodString;
|
|
90
|
+
label: z.ZodString;
|
|
91
|
+
}, z.core.$strict>>]>;
|
|
92
|
+
}, z.core.$strict>>;
|
|
93
|
+
remove: z.ZodOptional<z.ZodLiteral<true>>;
|
|
94
|
+
form: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
95
|
+
empty: z.ZodOptional<z.ZodObject<{
|
|
96
|
+
key: z.ZodString;
|
|
97
|
+
fallback: z.ZodString;
|
|
98
|
+
}, z.core.$strict>>;
|
|
99
|
+
empties: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
100
|
+
summary: z.ZodOptional<z.ZodObject<{
|
|
101
|
+
words: z.ZodString;
|
|
102
|
+
}, z.core.$strict>>;
|
|
103
|
+
actions: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
104
|
+
id: z.ZodString;
|
|
105
|
+
label: z.ZodObject<{
|
|
106
|
+
key: z.ZodString;
|
|
107
|
+
fallback: z.ZodString;
|
|
108
|
+
}, z.core.$strict>;
|
|
109
|
+
labels: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
110
|
+
child: z.ZodObject<{
|
|
111
|
+
table: z.ZodString;
|
|
112
|
+
form: z.ZodArray<z.ZodString>;
|
|
113
|
+
}, z.core.$strict>;
|
|
114
|
+
}, z.core.$strict>>>;
|
|
115
|
+
}, z.core.$strict>>;
|
|
116
|
+
/** What the checks read of one of the add-on's tables. */
|
|
117
|
+
export interface RecordTabTable {
|
|
118
|
+
ref: string;
|
|
119
|
+
columns: readonly {
|
|
120
|
+
ref: string;
|
|
121
|
+
type: string;
|
|
122
|
+
role?: string | undefined;
|
|
123
|
+
references?: string | undefined;
|
|
124
|
+
rules?: Readonly<Record<string, unknown>> | undefined;
|
|
125
|
+
}[];
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Everything wrong with an add-on's record tabs that its own manifest can
|
|
129
|
+
* see: a table or a column that is not its own, a pair that is not a stored
|
|
130
|
+
* table name and a row's key, a column edited that Adminium decides, a picker
|
|
131
|
+
* the table does not link to, a summary that names no words.
|
|
132
|
+
*/
|
|
133
|
+
export declare function recordTabIssues(m: {
|
|
134
|
+
tabs: readonly RecordTab[];
|
|
135
|
+
tables: readonly RecordTabTable[];
|
|
136
|
+
words: readonly string[];
|
|
137
|
+
}): {
|
|
138
|
+
path: (string | number)[];
|
|
139
|
+
message: string;
|
|
140
|
+
}[];
|
|
141
|
+
//# sourceMappingURL=record-tabs.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"record-tabs.d.ts","sourceRoot":"","sources":["../src/record-tabs.ts"],"names":[],"mappings":"AACA;;;;;;;;;;;;;;;GAeG;AACH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAOxB,6EAA6E;AAC7E,eAAO,MAAM,eAAe,IAAI,CAAC;AACjC,eAAO,MAAM,sBAAsB,IAAI,CAAC;AAQxC,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBA8BjB,CAAC;AACZ,MAAM,MAAM,SAAS,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,eAAe,CAAC,CAAC;AAExD,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;mBAI2F,CAAC;AAEzH,0DAA0D;AAC1D,MAAM,WAAW,cAAc;IAC7B,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,SAAS;QAChB,GAAG,EAAE,MAAM,CAAC;QACZ,IAAI,EAAE,MAAM,CAAC;QACb,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;QAC1B,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;QAChC,KAAK,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,GAAG,SAAS,CAAC;KACvD,EAAE,CAAC;CACL;AAKD;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,CAAC,EAAE;IAAE,IAAI,EAAE,SAAS,SAAS,EAAE,CAAC;IAAC,MAAM,EAAE,SAAS,cAAc,EAAE,CAAC;IAAC,KAAK,EAAE,SAAS,MAAM,EAAE,CAAA;CAAE,GAAG;IAAE,IAAI,EAAE,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,EAAE,CAiFhL"}
|