@tillhub/schemas 6.187.0 → 6.188.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/CHANGELOG.md CHANGED
@@ -1,3 +1,10 @@
1
+ # [6.188.0](https://github.com/tillhub/schemas/compare/v6.187.0...v6.188.0) (2023-01-30)
2
+
3
+
4
+ ### Features
5
+
6
+ * **carts:** Protect cart PATCH call from wiping out important data ([fdcbe1b](https://github.com/tillhub/schemas/commit/fdcbe1b))
7
+
1
8
  # [6.187.0](https://github.com/tillhub/schemas/compare/v6.186.0...v6.187.0) (2023-01-24)
2
9
 
3
10
 
@@ -0,0 +1,699 @@
1
+ const { anyOf, oneOf } = require('../../../helpers/payload-or-null')
2
+ const productServiceAnswerObject = require('../../transactions/components/embedded/product_service_answer/base')
3
+ const addonObject = require('../../transactions/components/embedded/addon/base')
4
+ const returnReason = require('../../transactions/components/embedded/return/return_reason')
5
+ const voucherObject = require('../../transactions/components/embedded/voucher/base')
6
+ const customProperties = require('../../../common/custom_properties')
7
+
8
+ const masterData = {
9
+ salesman_staff: {
10
+ description: 'Staff person ID',
11
+ example: '68722313-4077-42eb-8cc2-bf3359940efc',
12
+ ...oneOf({
13
+ type: 'string',
14
+ format: 'uuid'
15
+ })
16
+ },
17
+ tax: {
18
+ description: 'Tax rate ID. If not present, the "vat_rate" must be present. The active tax with such ID must be defined in the system',
19
+ type: 'string',
20
+ format: 'uuid'
21
+ },
22
+ account: {
23
+ description: 'Account ID',
24
+ type: 'string',
25
+ format: 'uuid'
26
+ },
27
+ account_number: {
28
+ description: 'Account number. The only one active account with the same number must be defined in the system (does not apply when "account" value is present)',
29
+ ...oneOf({
30
+ type: 'string'
31
+ })
32
+ },
33
+ product_group: {
34
+ description: 'Product group ID',
35
+ ...oneOf({
36
+ type: 'string',
37
+ format: 'uuid'
38
+ })
39
+ }
40
+ }
41
+
42
+ const amount = {
43
+ description: 'The gross/net input price per quantity of 1.0 and before any discounts',
44
+ type: 'object',
45
+ additionalProperties: false,
46
+ anyOf: [
47
+ {
48
+ required: [
49
+ 'net',
50
+ 'gross'
51
+ ]
52
+ },
53
+ {
54
+ required: [
55
+ 'net'
56
+ ]
57
+ },
58
+ {
59
+ required: [
60
+ 'gross'
61
+ ]
62
+ }
63
+ ],
64
+ properties: {
65
+ net: {
66
+ description: 'A monetary value as .2Decimal excluding taxes, $10 = 10.00',
67
+ type: 'number',
68
+ minimum: -1000000,
69
+ maximum: 1000000,
70
+ multipleOf: 0.01
71
+ },
72
+ gross: {
73
+ description: 'A monetary value as .2Decimal including taxes, 10€ = 10.00',
74
+ type: 'number',
75
+ minimum: -1000000,
76
+ maximum: 1000000,
77
+ multipleOf: 0.01
78
+ }
79
+ }
80
+ }
81
+
82
+ const externalDiscounts = {
83
+ type: 'array',
84
+ description: 'external discounts that only take either discount format',
85
+ items: {
86
+ anyOf: [
87
+ {
88
+ description: 'discount based on rate, e.g. 10% = 0.1. Client should will apply this based on the volume of that cart item.',
89
+ additionalProperties: false,
90
+ type: 'object',
91
+ properties: {
92
+ rate: {
93
+ ...oneOf({
94
+ type: 'number',
95
+ minimum: 0,
96
+ maximum: 1
97
+ })
98
+ },
99
+ order_index: {
100
+ type: 'integer'
101
+ },
102
+ currency: {
103
+ type: 'string',
104
+ minLength: 3,
105
+ maxLength: 3
106
+ },
107
+ client_id: {
108
+ type: 'string',
109
+ maxLength: 128
110
+ },
111
+ group: {
112
+ type: 'string',
113
+ enum: [
114
+ 'customer',
115
+ 'staff',
116
+ 'cart',
117
+ 'product_set',
118
+ 'item'
119
+ ]
120
+ },
121
+ name: {
122
+ type: 'string',
123
+ minLength: 1,
124
+ maxLength: 128
125
+ }
126
+ },
127
+ required: [
128
+ 'currency',
129
+ 'name',
130
+ 'rate'
131
+ ]
132
+ },
133
+ {
134
+ description: 'discount based on value, e.g. 10 EUR = 10. Client should will subtract this from the volume of that cart item.',
135
+ additionalProperties: false,
136
+ type: 'object',
137
+ properties: {
138
+ value: {
139
+ ...oneOf({
140
+ type: 'number'
141
+ })
142
+ },
143
+ order_index: {
144
+ type: 'integer'
145
+ },
146
+ currency: {
147
+ type: 'string',
148
+ minLength: 3,
149
+ maxLength: 3
150
+ },
151
+ client_id: {
152
+ type: 'string',
153
+ maxLength: 128
154
+ },
155
+ group: {
156
+ type: 'string',
157
+ enum: [
158
+ 'customer',
159
+ 'staff',
160
+ 'cart',
161
+ 'product_set',
162
+ 'item'
163
+ ]
164
+ },
165
+ name: {
166
+ type: 'string',
167
+ minLength: 1,
168
+ maxLength: 128
169
+ }
170
+ },
171
+ required: [
172
+ 'currency',
173
+ 'name',
174
+ 'value'
175
+ ]
176
+ },
177
+ {
178
+ description: 'discount based on amount total, e.g. 10 EUR = 10. Clients do no calculations and will subtract this value from a cart item.',
179
+ additionalProperties: false,
180
+ properties: {
181
+ amount_total: {
182
+ type: 'number'
183
+ },
184
+ order_index: {
185
+ type: 'integer'
186
+ },
187
+ currency: {
188
+ type: 'string',
189
+ minLength: 3,
190
+ maxLength: 3
191
+ },
192
+ client_id: {
193
+ type: 'string',
194
+ maxLength: 128
195
+ },
196
+ group: {
197
+ type: 'string',
198
+ enum: [
199
+ 'customer',
200
+ 'staff',
201
+ 'cart',
202
+ 'product_set',
203
+ 'item'
204
+ ]
205
+ },
206
+ name: {
207
+ type: 'string',
208
+ minLength: 1,
209
+ maxLength: 128
210
+ }
211
+ },
212
+ required: [
213
+ 'currency',
214
+ 'name',
215
+ 'amount_total'
216
+ ]
217
+ },
218
+ {
219
+ description: 'discount based on amount per item, e.g. 10 EUR with qty 100 will be = 1000. Clientstake this value and multiply it by the qty.',
220
+ additionalProperties: false,
221
+ properties: {
222
+ amount: {
223
+ type: 'number'
224
+ },
225
+ order_index: {
226
+ type: 'integer'
227
+ },
228
+ currency: {
229
+ type: 'string',
230
+ minLength: 3,
231
+ maxLength: 3
232
+ },
233
+ client_id: {
234
+ type: 'string',
235
+ maxLength: 128
236
+ },
237
+ group: {
238
+ type: 'string',
239
+ enum: [
240
+ 'customer',
241
+ 'staff',
242
+ 'cart',
243
+ 'product_set',
244
+ 'item'
245
+ ]
246
+ },
247
+ name: {
248
+ type: 'string',
249
+ minLength: 1,
250
+ maxLength: 128
251
+ }
252
+ },
253
+ required: [
254
+ 'currency',
255
+ 'name',
256
+ 'amount'
257
+ ]
258
+ }
259
+ ]
260
+ }
261
+ }
262
+
263
+ const internalDiscounts = {
264
+ type: 'array',
265
+ items: {
266
+ additionalProperties: false,
267
+ properties: {
268
+ amount: {
269
+ type: 'number'
270
+ },
271
+ amount_total: {
272
+ type: 'number'
273
+ },
274
+ order_index: {
275
+ type: 'integer'
276
+ },
277
+ currency: {
278
+ type: 'string',
279
+ minLength: 3,
280
+ maxLength: 3
281
+ },
282
+ type_name: {
283
+ type: 'string',
284
+ enum: [
285
+ 'percentage',
286
+ 'value'
287
+ ],
288
+ description: 'The value interpretation type of the discount, needed to map from transaction legacy discounts and back, value and rate will be still respected'
289
+ },
290
+ group: {
291
+ type: 'string',
292
+ enum: [
293
+ 'customer',
294
+ 'staff',
295
+ 'cart',
296
+ 'product_set',
297
+ 'sconto',
298
+ 'item',
299
+ 'promotion',
300
+ 'voucher'
301
+ ],
302
+ description: 'The logical group type of the discount, reflecting it\'s origin.'
303
+ },
304
+ value: {
305
+ ...oneOf({
306
+ type: 'number'
307
+ })
308
+ },
309
+ rate: {
310
+ ...oneOf({
311
+ type: 'number',
312
+ minimum: 0,
313
+ maximum: 1
314
+ })
315
+ },
316
+ client_id: {
317
+ type: 'string',
318
+ maxLength: 128
319
+ },
320
+ external_reference_id: {
321
+ description: 'A caller defined custom ID for the purpose of syncing from external resources, or to use in analytics.',
322
+ ...oneOf({
323
+ type: 'string',
324
+ maxLength: 128
325
+ })
326
+ },
327
+ source_id: {
328
+ description: 'The Tillhub discount resource (if available)',
329
+ ...oneOf({
330
+ type: 'string',
331
+ format: 'uuid'
332
+ })
333
+ },
334
+ assignment_id: {
335
+ description: 'Identification of the process that created this discount',
336
+ ...oneOf({
337
+ type: 'string',
338
+ maxLength: 128
339
+ })
340
+ },
341
+ assignment_source: {
342
+ description: 'Identification of the source of the process that created this discount',
343
+ ...oneOf({
344
+ type: 'string',
345
+ enum: [
346
+ 'customer',
347
+ 'staff',
348
+ 'cart',
349
+ 'product_set',
350
+ 'sconto',
351
+ 'item',
352
+ 'promotion',
353
+ 'voucher',
354
+ 'product_voucher'
355
+ ]
356
+ })
357
+ },
358
+ name: {
359
+ type: 'string',
360
+ minLength: 1,
361
+ maxLength: 128
362
+ },
363
+ is_automatic: oneOf({
364
+ type: 'boolean',
365
+ default: false,
366
+ description: 'If true, this discount was trigger automatically.'
367
+ }),
368
+ order: oneOf({
369
+ type: 'string',
370
+ enum: [
371
+ 'first',
372
+ 'last'
373
+ ],
374
+ default: 'last'
375
+ }),
376
+ vat_rate_class: oneOf({
377
+ default: 'normal',
378
+ description: 'Rate class from \'taxes.rate_class\' according to international standards, used in Germany to map types for e.g. fiscalization',
379
+ type: 'string',
380
+ 'enum': [
381
+ 'normal',
382
+ 'reduced',
383
+ 'super_reduced'
384
+ ]
385
+ })
386
+ },
387
+ anyOf: [
388
+ {
389
+ required: [
390
+ 'amount',
391
+ 'amount_total',
392
+ 'currency',
393
+ 'name',
394
+ 'value'
395
+ ]
396
+ },
397
+ {
398
+ required: [
399
+ 'amount',
400
+ 'amount_total',
401
+ 'currency',
402
+ 'name',
403
+ 'rate'
404
+ ]
405
+ },
406
+ {
407
+ required: [
408
+ 'amount',
409
+ 'amount_total',
410
+ 'currency',
411
+ 'name',
412
+ 'value',
413
+ 'rate'
414
+ ]
415
+ }
416
+ ]
417
+ }
418
+ }
419
+
420
+ const base = {
421
+ name: {
422
+ description: 'Cart item display name',
423
+ type: 'string',
424
+ minLength: 1,
425
+ maxLength: 128
426
+ },
427
+ position: {
428
+ description: 'Cart item position',
429
+ type: 'number',
430
+ minimum: 0
431
+ },
432
+ comments: {
433
+ description: 'Additional comments',
434
+ ...anyOf({
435
+ type: 'string',
436
+ maxLength: 4096
437
+ }),
438
+ default: null
439
+ },
440
+ client_id: {
441
+ type: 'string',
442
+ maxLength: 128
443
+ },
444
+ custom_properties: {
445
+ ...customProperties.implementation
446
+ },
447
+ ...masterData
448
+ }
449
+
450
+ const addons = oneOf({
451
+ description: 'The list of applied addons',
452
+ type: 'array',
453
+ items: addonObject
454
+ })
455
+
456
+ const externalCartBase = {
457
+ product: {
458
+ description: 'The Tillhub product unique identifier',
459
+ example: 'aa165950-26f1-4a59-a85a-1c6017b3cb79',
460
+ type: 'string',
461
+ format: 'uuid'
462
+ },
463
+ custom_id: {
464
+ description: 'The product.custom_id as stated in https://tillhub.atlassian.net/browse/TM-5665',
465
+ example: '260620-727-DE',
466
+ type: 'string',
467
+ maxLength: 128
468
+ },
469
+ product_supplier_name: {
470
+ description: 'Custom identifier for the product\'s supplier',
471
+ ...oneOf({
472
+ type: 'string',
473
+ maxLength: 128
474
+ })
475
+ },
476
+ is_service: {
477
+ description: 'If true, this item represents a service and might come with answers to service questions',
478
+ default: false,
479
+ ...oneOf({
480
+ type: 'boolean'
481
+ })
482
+ },
483
+ discountable: {
484
+ description: 'Supports correct discount behavior without product lookup',
485
+ ...oneOf({
486
+ type: 'boolean'
487
+ })
488
+ },
489
+ qty: {
490
+ description: 'Product quantity in the cart',
491
+ example: 2,
492
+ type: 'number'
493
+ },
494
+ currency: {
495
+ description: 'Currency symbol',
496
+ example: 'EUR',
497
+ type: 'string',
498
+ minLength: 3,
499
+ maxLength: 3
500
+ },
501
+ amount: {
502
+ description: 'The currency / amount object combination is the Tillhub Money object. In this context it is the price of 1 item. The total will price * qty.',
503
+ ...amount
504
+ },
505
+ vat_rate: {
506
+ description: 'VAT rate in the range 0-1. Required when "tax" value is not present. The only one active VAT with the same rate must be defined in the system (does not apply when "tax" value is present)',
507
+ example: 0.12,
508
+ type: 'number',
509
+ minimum: 0,
510
+ maximum: 1
511
+ },
512
+ addons,
513
+ discounts: externalDiscounts,
514
+ ...base
515
+ }
516
+
517
+ const cartOfIdsBase = {
518
+ position: {
519
+ description: 'Cart item position',
520
+ type: 'number',
521
+ minimum: 0
522
+ },
523
+ discountable: {
524
+ description: 'Supports correct discount behavior without product lookup',
525
+ ...oneOf({
526
+ type: 'boolean'
527
+ })
528
+ },
529
+ product: {
530
+ description: 'Identifier of the product',
531
+ example: 'cd0a2886-e245-4ed9-a758-443e7e5b3a3f',
532
+ type: 'string'
533
+ // format: 'uuid'
534
+ },
535
+ qty: {
536
+ description: 'Product quantity in the cart',
537
+ example: 2,
538
+ type: 'number'
539
+ },
540
+ currency: {
541
+ description: 'Currency symbol',
542
+ example: 'EUR',
543
+ type: 'string',
544
+ minLength: 3,
545
+ maxLength: 3
546
+ },
547
+ client_id: {
548
+ type: 'string',
549
+ maxLength: 128
550
+ },
551
+ addons,
552
+ discounts: externalDiscounts
553
+ }
554
+
555
+ const internalCartBase = {
556
+ product: {
557
+ description: 'Identifier of the product',
558
+ example: 'cd0a2886-e245-4ed9-a758-443e7e5b3a3f',
559
+ type: 'string',
560
+ format: 'uuid'
561
+ },
562
+ product_supplier_name: {
563
+ description: 'Custom identifier for the product\'s supplier',
564
+ example: '00555kff34323',
565
+ ...oneOf({
566
+ type: 'string',
567
+ maxLength: 128
568
+ })
569
+ },
570
+ is_service: {
571
+ description: 'If true, this item represents a service and might come with answers to service questions',
572
+ ...oneOf({
573
+ type: 'boolean',
574
+ default: false
575
+ })
576
+ },
577
+ discountable: {
578
+ description: 'Supports correct discount behavior without product lookup',
579
+ ...oneOf({
580
+ type: 'boolean'
581
+ })
582
+ },
583
+ qty: {
584
+ description: 'Product quantity in the cart',
585
+ example: 2,
586
+ type: 'number'
587
+ },
588
+ custom_id: {
589
+ description: 'Custom cart item ID',
590
+ ...oneOf({
591
+ type: 'string',
592
+ maxLength: 128
593
+ })
594
+ },
595
+ vat_rate: {
596
+ description: 'VAT rate in the range 0-1. Required when "tax" value is not present. The only one active VAT with the same rate must be defined in the system (does not apply when "tax" value is present)',
597
+ example: 0.12,
598
+ type: 'number',
599
+ minimum: 0,
600
+ maximum: 1
601
+ },
602
+ vat_rate_class: {
603
+ description: 'Rate class from \'taxes.rate_class\' according to international standards, used in Germany to map types for e.g. fiscalization',
604
+ default: 'normal',
605
+ ...oneOf({
606
+ type: 'string',
607
+ 'enum': [
608
+ 'normal',
609
+ 'reduced',
610
+ 'super_reduced'
611
+ ]
612
+ })
613
+ },
614
+ currency: {
615
+ description: 'Currency symbol',
616
+ example: 'EUR',
617
+ type: 'string',
618
+ minLength: 3,
619
+ maxLength: 3
620
+ },
621
+ amount,
622
+ promotion_amount: oneOf({
623
+ description: 'The promotion amount on the per unit qty base of 1.',
624
+ type: 'number',
625
+ minimum: -1000000,
626
+ maximum: 1000000,
627
+ multipleOf: 0.01
628
+ }),
629
+ promotion_amount_total: oneOf({
630
+ description: 'The total promotion amount.',
631
+ type: 'number',
632
+ minimum: -1000000,
633
+ maximum: 1000000,
634
+ multipleOf: 0.01
635
+ }),
636
+ product_service_answers: oneOf({
637
+ type: 'array',
638
+ description: 'A list of answers to product service questions',
639
+ items: {
640
+ ...productServiceAnswerObject
641
+ }
642
+ }),
643
+ is_voucher: {
644
+ description: 'If true, this item represents a voucher and must come with voucher information in \'voucher\'',
645
+ default: false,
646
+ ...oneOf({
647
+ type: 'boolean'
648
+ })
649
+ },
650
+ voucher: {
651
+ ...oneOf({
652
+ ...voucherObject
653
+ }),
654
+ default: null
655
+ },
656
+ is_refund: {
657
+ description: 'If true, the item was created by (partially) refunding a previous sale.',
658
+ ...oneOf({
659
+ type: 'boolean'
660
+ })
661
+ },
662
+ return_reason: returnReason,
663
+ attributes_description: {
664
+ description: 'A short description of the child attributes in variant products',
665
+ example: 'red | big | 32',
666
+ ...oneOf({
667
+ type: 'string'
668
+ })
669
+ },
670
+ reference_cartitem_client_id: {
671
+ description: 'In cases of refund or cancellation, or invoicing a delivery note or selling a saved cart: the client_id of the origin item',
672
+ example: '01331B44-130B-45D4-97A7-401247FD5B68',
673
+ ...oneOf({
674
+ type: 'string'
675
+ })
676
+ },
677
+ used_barcode: {
678
+ description: 'The barcode used to trigger putting this item into the cart (defaults to the first available barcode from the product)',
679
+ example: '0E9761310XF',
680
+ ...oneOf({
681
+ type: 'string'
682
+ })
683
+ },
684
+ ...base,
685
+ addons,
686
+ discounts: internalDiscounts,
687
+ attributes: {
688
+ default: null,
689
+ ...anyOf({
690
+ type: 'object'
691
+ })
692
+ }
693
+ }
694
+
695
+ module.exports = {
696
+ internalCartBase,
697
+ externalCartBase,
698
+ cartOfIdsBase
699
+ }