sahab-utils 1.9.4 → 1.10.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/constants/types.d.ts +8 -1
- package/dist/constants/types.js +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/ts/orderAdjustment.d.ts +44 -0
- package/dist/ts/orderAdjustment.js +62 -0
- package/package.json +2 -2
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { DocumentReference, GeoPoint, Timestamp } from 'firebase/firestore';
|
|
2
2
|
import type { PushTransport } from '../ts/push';
|
|
3
3
|
import type { TapLicenseType } from '../ts/tap';
|
|
4
|
+
import type { OrderSizeAdjustmentFields } from '../ts/orderAdjustment';
|
|
4
5
|
export type GeoPointType = GeoPoint;
|
|
5
6
|
export type TimestampType = Timestamp;
|
|
6
7
|
export type DistenceDueration = {
|
|
@@ -163,6 +164,11 @@ export type Order = {
|
|
|
163
164
|
payLinkDeadline?: TimestampType;
|
|
164
165
|
payLinkSmsCount?: number;
|
|
165
166
|
createdByStaff?: string;
|
|
167
|
+
sizeAdjustments?: Array<OrderSizeAdjustmentFields & {
|
|
168
|
+
createdAt?: TimestampType;
|
|
169
|
+
linkDeadline?: TimestampType;
|
|
170
|
+
paidAt?: TimestampType;
|
|
171
|
+
}>;
|
|
166
172
|
};
|
|
167
173
|
export type ReduxOrder = {
|
|
168
174
|
orderId?: string;
|
|
@@ -237,7 +243,8 @@ export declare enum MovementType {
|
|
|
237
243
|
SAHAB_PAYMENT_TO_PROVIDER = 5,
|
|
238
244
|
SAHAB_RECEIVE_FROM_PROVIDER = 6,
|
|
239
245
|
USING_BALANCE = 7,
|
|
240
|
-
CASHBACK = 8
|
|
246
|
+
CASHBACK = 8,
|
|
247
|
+
SIZE_ADJUSTMENT = 9
|
|
241
248
|
}
|
|
242
249
|
export declare enum ComplaintType {
|
|
243
250
|
BUG = 0,
|
package/dist/constants/types.js
CHANGED
|
@@ -44,6 +44,7 @@ var MovementType;
|
|
|
44
44
|
MovementType[MovementType["SAHAB_RECEIVE_FROM_PROVIDER"] = 6] = "SAHAB_RECEIVE_FROM_PROVIDER";
|
|
45
45
|
MovementType[MovementType["USING_BALANCE"] = 7] = "USING_BALANCE";
|
|
46
46
|
MovementType[MovementType["CASHBACK"] = 8] = "CASHBACK";
|
|
47
|
+
MovementType[MovementType["SIZE_ADJUSTMENT"] = 9] = "SIZE_ADJUSTMENT";
|
|
47
48
|
})(MovementType || (exports.MovementType = MovementType = {}));
|
|
48
49
|
var ComplaintType;
|
|
49
50
|
(function (ComplaintType) {
|
package/dist/index.d.ts
CHANGED
|
@@ -11,6 +11,7 @@ export * from './ts/iban';
|
|
|
11
11
|
export * from './ts/loyalty';
|
|
12
12
|
export * from './ts/offerings';
|
|
13
13
|
export * from './ts/orderActivity';
|
|
14
|
+
export * from './ts/orderAdjustment';
|
|
14
15
|
export * from './ts/payLink';
|
|
15
16
|
export * from './ts/tap';
|
|
16
17
|
export * from './ts/push';
|
package/dist/index.js
CHANGED
|
@@ -27,6 +27,7 @@ __exportStar(require("./ts/iban"), exports);
|
|
|
27
27
|
__exportStar(require("./ts/loyalty"), exports);
|
|
28
28
|
__exportStar(require("./ts/offerings"), exports);
|
|
29
29
|
__exportStar(require("./ts/orderActivity"), exports);
|
|
30
|
+
__exportStar(require("./ts/orderAdjustment"), exports);
|
|
30
31
|
__exportStar(require("./ts/payLink"), exports);
|
|
31
32
|
__exportStar(require("./ts/tap"), exports);
|
|
32
33
|
__exportStar(require("./ts/push"), exports);
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { CarService, CarSize, Provider } from '../constants/types';
|
|
2
|
+
export type OrderSizeAdjustmentStatus = 'unpaid' | 'paid' | 'cash';
|
|
3
|
+
/** The parts of a size adjustment with no Firestore dependency; the server adds its timestamps. */
|
|
4
|
+
export type OrderSizeAdjustmentFields = {
|
|
5
|
+
adjustmentId: string;
|
|
6
|
+
carId: string;
|
|
7
|
+
fromSize: CarSize;
|
|
8
|
+
toSize: CarSize;
|
|
9
|
+
oldTotal: number;
|
|
10
|
+
newTotal: number;
|
|
11
|
+
amountDue: number;
|
|
12
|
+
status: OrderSizeAdjustmentStatus;
|
|
13
|
+
providerDelta: number;
|
|
14
|
+
paymentLinkId?: string;
|
|
15
|
+
paymentLinkUrl?: string;
|
|
16
|
+
smsCount?: number;
|
|
17
|
+
paymentId?: string;
|
|
18
|
+
refundedPaymentIds?: string[];
|
|
19
|
+
createdBy: string;
|
|
20
|
+
};
|
|
21
|
+
export declare const ADJUSTMENT_REFERENCE_PREFIX = "adj_";
|
|
22
|
+
export declare const ADJUSTMENT_LINK_HOURS = 24;
|
|
23
|
+
export declare const MAX_ADJUSTMENT_SMS = 3;
|
|
24
|
+
export declare const isLargerSize: (from?: CarSize, to?: CarSize) => boolean;
|
|
25
|
+
/** Checkout's reference for a difference payment; under its 50-character limit for a Firestore id and a short adjustment id. */
|
|
26
|
+
export declare const adjustmentReference: (orderId: string, adjustmentId: string) => string;
|
|
27
|
+
export declare function parseAdjustmentReference(reference?: string): {
|
|
28
|
+
orderId: string;
|
|
29
|
+
adjustmentId: string;
|
|
30
|
+
} | undefined;
|
|
31
|
+
/** What the customer owes for a resize, to the halala; never negative. */
|
|
32
|
+
export declare const sizeAdjustmentAmountDue: (oldTotal: number, newTotal: number) => number;
|
|
33
|
+
export type ResizeRejection = 'not_larger' | 'car_not_found' | 'package' | 'line_unavailable' | 'line_not_priced';
|
|
34
|
+
export type ResizedLines = {
|
|
35
|
+
ok: true;
|
|
36
|
+
services: CarService[];
|
|
37
|
+
} | {
|
|
38
|
+
ok: false;
|
|
39
|
+
reason: ResizeRejection;
|
|
40
|
+
detail?: string;
|
|
41
|
+
};
|
|
42
|
+
/** The order's services with one car moved to `toSize`. Each of its lines keeps its stored price plus the catalogue
|
|
43
|
+
* difference between the two sizes, and keeps its stored discount; other cars are untouched. */
|
|
44
|
+
export declare function resizeCarLines(services: CarService[] | undefined, carId: string, toSize: CarSize, provider: Pick<Provider, 'services' | 'addons'>): ResizedLines;
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.sizeAdjustmentAmountDue = exports.adjustmentReference = exports.isLargerSize = exports.MAX_ADJUSTMENT_SMS = exports.ADJUSTMENT_LINK_HOURS = exports.ADJUSTMENT_REFERENCE_PREFIX = void 0;
|
|
4
|
+
exports.parseAdjustmentReference = parseAdjustmentReference;
|
|
5
|
+
exports.resizeCarLines = resizeCarLines;
|
|
6
|
+
const types_1 = require("../constants/types");
|
|
7
|
+
const offerings_1 = require("./offerings");
|
|
8
|
+
exports.ADJUSTMENT_REFERENCE_PREFIX = 'adj_';
|
|
9
|
+
exports.ADJUSTMENT_LINK_HOURS = 24;
|
|
10
|
+
exports.MAX_ADJUSTMENT_SMS = 3;
|
|
11
|
+
const isLargerSize = (from, to) => Number.isInteger(from) && Number.isInteger(to) && to > from && to <= types_1.CarSize.X_LARGE;
|
|
12
|
+
exports.isLargerSize = isLargerSize;
|
|
13
|
+
/** Checkout's reference for a difference payment; under its 50-character limit for a Firestore id and a short adjustment id. */
|
|
14
|
+
const adjustmentReference = (orderId, adjustmentId) => `${exports.ADJUSTMENT_REFERENCE_PREFIX}${orderId}_${adjustmentId}`;
|
|
15
|
+
exports.adjustmentReference = adjustmentReference;
|
|
16
|
+
// Firestore auto ids and adjustment ids never contain '_', so the last one splits the two.
|
|
17
|
+
function parseAdjustmentReference(reference) {
|
|
18
|
+
if (!reference || !reference.startsWith(exports.ADJUSTMENT_REFERENCE_PREFIX))
|
|
19
|
+
return undefined;
|
|
20
|
+
const rest = reference.slice(exports.ADJUSTMENT_REFERENCE_PREFIX.length);
|
|
21
|
+
const split = rest.lastIndexOf('_');
|
|
22
|
+
const orderId = rest.slice(0, split);
|
|
23
|
+
const adjustmentId = rest.slice(split + 1);
|
|
24
|
+
if (split <= 0 || !adjustmentId || /[/_]/.test(orderId) || /[/_]/.test(adjustmentId))
|
|
25
|
+
return undefined;
|
|
26
|
+
return { orderId, adjustmentId };
|
|
27
|
+
}
|
|
28
|
+
/** What the customer owes for a resize, to the halala; never negative. */
|
|
29
|
+
const sizeAdjustmentAmountDue = (oldTotal, newTotal) => Math.max(0, Math.round((newTotal - oldTotal) * 100) / 100);
|
|
30
|
+
exports.sizeAdjustmentAmountDue = sizeAdjustmentAmountDue;
|
|
31
|
+
/** The order's services with one car moved to `toSize`. Each of its lines keeps its stored price plus the catalogue
|
|
32
|
+
* difference between the two sizes, and keeps its stored discount; other cars are untouched. */
|
|
33
|
+
function resizeCarLines(services, carId, toSize, provider) {
|
|
34
|
+
var _a, _b, _c, _d, _e, _f;
|
|
35
|
+
const index = (services !== null && services !== void 0 ? services : []).findIndex((section) => { var _a; return ((_a = section === null || section === void 0 ? void 0 : section.car) === null || _a === void 0 ? void 0 : _a.carId) === carId; });
|
|
36
|
+
if (index < 0)
|
|
37
|
+
return { ok: false, reason: 'car_not_found' };
|
|
38
|
+
const section = services[index];
|
|
39
|
+
const car = section.car;
|
|
40
|
+
const fromSize = car.size;
|
|
41
|
+
if (!(0, exports.isLargerSize)(fromSize, toSize))
|
|
42
|
+
return { ok: false, reason: 'not_larger' };
|
|
43
|
+
const lines = [];
|
|
44
|
+
for (const line of (_a = section.services) !== null && _a !== void 0 ? _a : []) {
|
|
45
|
+
const { serviceId, addonId } = line;
|
|
46
|
+
if (line.numberOfVisits && line.numberOfVisits > 1)
|
|
47
|
+
return { ok: false, reason: 'package' };
|
|
48
|
+
const offering = serviceId ? (_b = provider.services) === null || _b === void 0 ? void 0 : _b.find((s) => s.serviceId === serviceId) : addonId ? (_c = provider.addons) === null || _c === void 0 ? void 0 : _c.find((a) => a.addonId === addonId) : undefined;
|
|
49
|
+
if (!offering)
|
|
50
|
+
return { ok: false, reason: 'line_unavailable', detail: serviceId !== null && serviceId !== void 0 ? serviceId : addonId };
|
|
51
|
+
const prices = (_d = offering.prices) !== null && _d !== void 0 ? _d : [];
|
|
52
|
+
const sold = (size) => prices.some((p) => (p === null || p === void 0 ? void 0 : p.size) === size && Number.isFinite(p === null || p === void 0 ? void 0 : p.price) && p.price > 0);
|
|
53
|
+
if (!sold(fromSize) || !sold(toSize))
|
|
54
|
+
return { ok: false, reason: 'line_not_priced', detail: `${serviceId !== null && serviceId !== void 0 ? serviceId : addonId} size ${toSize}` };
|
|
55
|
+
const difference = (0, offerings_1.setServicePrice)(prices, toSize) - (0, offerings_1.setServicePrice)(prices, fromSize);
|
|
56
|
+
const price = Math.round((((_f = (_e = line.price) === null || _e === void 0 ? void 0 : _e.price) !== null && _f !== void 0 ? _f : 0) + difference) * 100) / 100;
|
|
57
|
+
lines.push(Object.assign(Object.assign({}, line), { price: Object.assign(Object.assign({}, line.price), { size: toSize, price }) }));
|
|
58
|
+
}
|
|
59
|
+
const resized = [...services];
|
|
60
|
+
resized[index] = Object.assign(Object.assign({}, section), { car: Object.assign(Object.assign({}, car), { size: toSize }), services: lines });
|
|
61
|
+
return { ok: true, services: resized };
|
|
62
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "sahab-utils",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.10.0",
|
|
4
4
|
"description": "This package contains types and utils functions",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
"build": "tsc",
|
|
9
9
|
"prepublishOnly": "npm run build",
|
|
10
10
|
"deploy": "npm run build && npm publish",
|
|
11
|
-
"test": "npm run build && node tests/loyalty.test.js && node tests/gifts.test.js && node tests/cashback.test.js && node tests/utils.test.js && node tests/wheel.test.js && node tests/calcs.test.js && node tests/orderActivity.test.js && node tests/push.test.js && node tests/broadcast.test.js && node tests/iban.test.js && node tests/cash.test.js && node tests/workingHours.test.js && node tests/payLink.test.js && node tests/offerings.test.js && node tests/capacity.test.js && node tests/tap.test.js && node tests/adminNotifications.test.js && node tests/staffAccess.test.js"
|
|
11
|
+
"test": "npm run build && node tests/loyalty.test.js && node tests/gifts.test.js && node tests/cashback.test.js && node tests/utils.test.js && node tests/wheel.test.js && node tests/calcs.test.js && node tests/orderActivity.test.js && node tests/push.test.js && node tests/broadcast.test.js && node tests/iban.test.js && node tests/cash.test.js && node tests/workingHours.test.js && node tests/payLink.test.js && node tests/offerings.test.js && node tests/capacity.test.js && node tests/tap.test.js && node tests/orderAdjustment.test.js && node tests/adminNotifications.test.js && node tests/staffAccess.test.js"
|
|
12
12
|
},
|
|
13
13
|
"repository": {
|
|
14
14
|
"type": "git",
|