@escapenavigator/utils 2.1.27 → 2.1.28
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.
|
@@ -1,10 +1,15 @@
|
|
|
1
|
+
import { PromocodeDiscountTargetEnum } from '@escapenavigator/types/dist/promocode/emun/promocode-discount-target.enum';
|
|
1
2
|
import { PromocodeTypeEnum } from '@escapenavigator/types/dist/promocode/emun/promocode-type.enum';
|
|
2
3
|
import { OrderComposition, TariffCategory } from '@escapenavigator/types/dist/tariff/tariff-category';
|
|
3
4
|
import { ReducedPricingConfig } from './reduced-price';
|
|
4
|
-
export declare const getPromocodeDiscount: ({ slotId,
|
|
5
|
+
export declare const getPromocodeDiscount: ({ slotId, slotDiscountAmount, promocodeType, promocodeDiscount, discountTargets, upsellingsTotal, productsTotal, price, players, children, reducedPlayers, composition, categories, reducedRateMode, reducedRate, minGameAmount, }: ReducedPricingConfig & {
|
|
5
6
|
slotId: number;
|
|
6
7
|
children?: number;
|
|
7
8
|
total: number;
|
|
9
|
+
/** Явные части заказа; отсутствие временно мапится из legacy type. */
|
|
10
|
+
discountTargets?: PromocodeDiscountTargetEnum[] | null;
|
|
11
|
+
upsellingsTotal?: number;
|
|
12
|
+
productsTotal?: number;
|
|
8
13
|
players: number;
|
|
9
14
|
/** Сколько мест идёт по льготной ставке (снимок с заказа). */
|
|
10
15
|
reducedPlayers?: number | null;
|
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.getPromocodeDiscount = void 0;
|
|
4
|
+
const promocode_discount_target_enum_1 = require("@escapenavigator/types/dist/promocode/emun/promocode-discount-target.enum");
|
|
4
5
|
const promocode_type_enum_1 = require("@escapenavigator/types/dist/promocode/emun/promocode-type.enum");
|
|
5
6
|
const get_players_price_1 = require("./get-players-price");
|
|
6
|
-
const
|
|
7
|
-
const getPromocodeDiscount = ({ slotId, slotDiscount, slotDiscountAmount = 0, total, promocodeType, promocodeDiscount, price, players, children = 0, reducedPlayers = 0, composition, categories, reducedRateMode = null, reducedRate = 0, minGameAmount = 0, }) => {
|
|
8
|
-
const orderTotal = slotId ? total - slotDiscount : total;
|
|
7
|
+
const getPromocodeDiscount = ({ slotId, slotDiscountAmount = 0, promocodeType, promocodeDiscount, discountTargets, upsellingsTotal = 0, productsTotal = 0, price, players, children = 0, reducedPlayers = 0, composition, categories, reducedRateMode = null, reducedRate = 0, minGameAmount = 0, }) => {
|
|
9
8
|
const game = {
|
|
10
9
|
price,
|
|
11
10
|
players,
|
|
@@ -17,15 +16,28 @@ const getPromocodeDiscount = ({ slotId, slotDiscount, slotDiscountAmount = 0, to
|
|
|
17
16
|
reducedRate,
|
|
18
17
|
minGameAmount,
|
|
19
18
|
};
|
|
19
|
+
const targets = (0, promocode_discount_target_enum_1.resolvePromocodeDiscountTargets)(discountTargets, promocodeType);
|
|
20
|
+
const appliesToGame = targets.includes(promocode_discount_target_enum_1.PromocodeDiscountTargetEnum.GAME);
|
|
21
|
+
const gameBase = appliesToGame
|
|
22
|
+
? Math.max(0, (0, get_players_price_1.getPlayersPrice)(game) - (slotId ? slotDiscountAmount : 0))
|
|
23
|
+
: 0;
|
|
24
|
+
const nonGameBase = (targets.includes(promocode_discount_target_enum_1.PromocodeDiscountTargetEnum.UPSELLINGS) ? upsellingsTotal : 0) +
|
|
25
|
+
(targets.includes(promocode_discount_target_enum_1.PromocodeDiscountTargetEnum.PRODUCTS) ? productsTotal : 0);
|
|
26
|
+
const eligibleBase = gameBase + nonGameBase;
|
|
20
27
|
let amount = 0;
|
|
21
28
|
if (promocodeType === promocode_type_enum_1.PromocodeTypeEnum.PROMOTIONAL)
|
|
22
29
|
return 0;
|
|
23
30
|
if (promocodeType === promocode_type_enum_1.PromocodeTypeEnum.FIXED)
|
|
24
|
-
amount = promocodeDiscount;
|
|
25
|
-
if (promocodeType === promocode_type_enum_1.PromocodeTypeEnum.PERCENT_BASE_SUM
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
31
|
+
amount = Math.min(promocodeDiscount, eligibleBase);
|
|
32
|
+
if (promocodeType === promocode_type_enum_1.PromocodeTypeEnum.PERCENT_BASE_SUM ||
|
|
33
|
+
promocodeType === promocode_type_enum_1.PromocodeTypeEnum.PERCENT_ALL_SUM) {
|
|
34
|
+
const gameBudget = appliesToGame
|
|
35
|
+
? Math.max(0, (0, get_players_price_1.getMaxGameDiscount)(game) - (slotId ? slotDiscountAmount : 0))
|
|
36
|
+
: 0;
|
|
37
|
+
const gameDiscount = Math.min(Math.floor((gameBase / 10000) * promocodeDiscount), gameBudget);
|
|
38
|
+
const nonGameDiscount = Math.floor((nonGameBase / 10000) * promocodeDiscount);
|
|
39
|
+
return Math.max(0, gameDiscount + nonGameDiscount);
|
|
40
|
+
}
|
|
29
41
|
if (promocodeType === promocode_type_enum_1.PromocodeTypeEnum.FLASH_PRICE) {
|
|
30
42
|
// «Флеш цена»: promocodeDiscount хранит итоговую цену за игроков.
|
|
31
43
|
// Скидка = базовая цена за игроков (за вычетом слот-скидки) − флеш-цена.
|
|
@@ -35,13 +47,11 @@ const getPromocodeDiscount = ({ slotId, slotDiscount, slotDiscountAmount = 0, to
|
|
|
35
47
|
const playersPriceAfterSlot = playersPrice - (slotId ? slotDiscountAmount : 0);
|
|
36
48
|
amount = Math.max(0, playersPriceAfterSlot - promocodeDiscount);
|
|
37
49
|
}
|
|
38
|
-
//
|
|
39
|
-
//
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
}
|
|
45
|
-
return amount;
|
|
50
|
+
// Пол защищает только стоимость самой игры. Выбранные допуслуги и товары
|
|
51
|
+
// можно дисконтировать полностью, даже если игра уже упёрлась в минимум.
|
|
52
|
+
const gameBudget = appliesToGame
|
|
53
|
+
? Math.max(0, (0, get_players_price_1.getMaxGameDiscount)(game) - (slotId ? slotDiscountAmount : 0))
|
|
54
|
+
: 0;
|
|
55
|
+
return Math.max(0, Math.min(amount, gameBudget + nonGameBase));
|
|
46
56
|
};
|
|
47
57
|
exports.getPromocodeDiscount = getPromocodeDiscount;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const promocode_discount_target_enum_1 = require("@escapenavigator/types/dist/promocode/emun/promocode-discount-target.enum");
|
|
3
4
|
const promocode_type_enum_1 = require("@escapenavigator/types/dist/promocode/emun/promocode-type.enum");
|
|
4
5
|
const get_promocode_discount_1 = require("./get-promocode-discount");
|
|
5
6
|
// Тариф: 2 игрока — 100.00, 4 игрока — 180.00, ребёнок — 20.00 (minor units).
|
|
@@ -90,3 +91,59 @@ describe('getPromocodeDiscount / FLASH_PRICE', () => {
|
|
|
90
91
|
})).toBe(0);
|
|
91
92
|
});
|
|
92
93
|
});
|
|
94
|
+
describe('getPromocodeDiscount / discount targets', () => {
|
|
95
|
+
const percent = (discountTargets) => (0, get_promocode_discount_1.getPromocodeDiscount)({
|
|
96
|
+
...base,
|
|
97
|
+
total: 999_999,
|
|
98
|
+
promocodeType: promocode_type_enum_1.PromocodeTypeEnum.PERCENT_ALL_SUM,
|
|
99
|
+
promocodeDiscount: 1000,
|
|
100
|
+
discountTargets,
|
|
101
|
+
upsellingsTotal: 5000,
|
|
102
|
+
productsTotal: 3000,
|
|
103
|
+
});
|
|
104
|
+
it('считает процент только от выбранных частей и не использует общий total', () => {
|
|
105
|
+
expect(percent([promocode_discount_target_enum_1.PromocodeDiscountTargetEnum.GAME])).toBe(1000);
|
|
106
|
+
expect(percent([promocode_discount_target_enum_1.PromocodeDiscountTargetEnum.UPSELLINGS])).toBe(500);
|
|
107
|
+
expect(percent([promocode_discount_target_enum_1.PromocodeDiscountTargetEnum.PRODUCTS])).toBe(300);
|
|
108
|
+
expect(percent([
|
|
109
|
+
promocode_discount_target_enum_1.PromocodeDiscountTargetEnum.GAME,
|
|
110
|
+
promocode_discount_target_enum_1.PromocodeDiscountTargetEnum.UPSELLINGS,
|
|
111
|
+
promocode_discount_target_enum_1.PromocodeDiscountTargetEnum.PRODUCTS,
|
|
112
|
+
])).toBe(1800);
|
|
113
|
+
});
|
|
114
|
+
it('вычитает скидку слота только из игровой части', () => {
|
|
115
|
+
expect((0, get_promocode_discount_1.getPromocodeDiscount)({
|
|
116
|
+
...base,
|
|
117
|
+
slotDiscountAmount: 2000,
|
|
118
|
+
promocodeType: promocode_type_enum_1.PromocodeTypeEnum.PERCENT_ALL_SUM,
|
|
119
|
+
promocodeDiscount: 1000,
|
|
120
|
+
discountTargets: [
|
|
121
|
+
promocode_discount_target_enum_1.PromocodeDiscountTargetEnum.GAME,
|
|
122
|
+
promocode_discount_target_enum_1.PromocodeDiscountTargetEnum.UPSELLINGS,
|
|
123
|
+
],
|
|
124
|
+
upsellingsTotal: 5000,
|
|
125
|
+
})).toBe(1300);
|
|
126
|
+
});
|
|
127
|
+
it('ограничивает фиксированную скидку суммой выбранных частей', () => {
|
|
128
|
+
expect((0, get_promocode_discount_1.getPromocodeDiscount)({
|
|
129
|
+
...base,
|
|
130
|
+
promocodeType: promocode_type_enum_1.PromocodeTypeEnum.FIXED,
|
|
131
|
+
promocodeDiscount: 5000,
|
|
132
|
+
discountTargets: [promocode_discount_target_enum_1.PromocodeDiscountTargetEnum.PRODUCTS],
|
|
133
|
+
productsTotal: 3000,
|
|
134
|
+
})).toBe(3000);
|
|
135
|
+
});
|
|
136
|
+
it('минимальная цена игры не запрещает скидку на допуслуги', () => {
|
|
137
|
+
expect((0, get_promocode_discount_1.getPromocodeDiscount)({
|
|
138
|
+
...base,
|
|
139
|
+
minGameAmount: 10000,
|
|
140
|
+
promocodeType: promocode_type_enum_1.PromocodeTypeEnum.PERCENT_ALL_SUM,
|
|
141
|
+
promocodeDiscount: 5000,
|
|
142
|
+
discountTargets: [
|
|
143
|
+
promocode_discount_target_enum_1.PromocodeDiscountTargetEnum.GAME,
|
|
144
|
+
promocode_discount_target_enum_1.PromocodeDiscountTargetEnum.UPSELLINGS,
|
|
145
|
+
],
|
|
146
|
+
upsellingsTotal: 4000,
|
|
147
|
+
})).toBe(2000);
|
|
148
|
+
});
|
|
149
|
+
});
|
|
@@ -10,3 +10,7 @@ export declare const canAccessFinance: (role?: RoleFinancePermissions | null) =>
|
|
|
10
10
|
* `financePaymentsOnly` оставляет только платежи. На владельца не действует.
|
|
11
11
|
*/
|
|
12
12
|
export declare const canAccessFullFinance: (role?: RoleFinancePermissions | null) => boolean;
|
|
13
|
+
/** Payroll management follows full finance access; payment-only roles cannot manage it. */
|
|
14
|
+
export declare const canManagePayroll: (role?: RoleFinancePermissions | null, mode?: "user" | "admin") => boolean;
|
|
15
|
+
/** Company-level self view can expose only the current employee's own payroll. */
|
|
16
|
+
export declare const canViewOwnPayroll: (role?: RoleFinancePermissions | null, mode?: "user" | "admin", selfViewEnabled?: boolean | null) => boolean;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.canAccessFullFinance = exports.canAccessFinance = void 0;
|
|
3
|
+
exports.canViewOwnPayroll = exports.canManagePayroll = exports.canAccessFullFinance = exports.canAccessFinance = void 0;
|
|
4
4
|
/**
|
|
5
5
|
* Вкладка платежей и сам раздел бухгалтерии.
|
|
6
6
|
* Владелец (`totalAccess`) — как будто доступ включён.
|
|
@@ -13,3 +13,9 @@ exports.canAccessFinance = canAccessFinance;
|
|
|
13
13
|
*/
|
|
14
14
|
const canAccessFullFinance = (role) => !!role?.totalAccess || (!!role?.accessToFinanceSection && !role?.financePaymentsOnly);
|
|
15
15
|
exports.canAccessFullFinance = canAccessFullFinance;
|
|
16
|
+
/** Payroll management follows full finance access; payment-only roles cannot manage it. */
|
|
17
|
+
const canManagePayroll = (role, mode) => mode === 'admin' || (0, exports.canAccessFullFinance)(role);
|
|
18
|
+
exports.canManagePayroll = canManagePayroll;
|
|
19
|
+
/** Company-level self view can expose only the current employee's own payroll. */
|
|
20
|
+
const canViewOwnPayroll = (role, mode, selfViewEnabled) => (0, exports.canManagePayroll)(role, mode) || Boolean(selfViewEnabled);
|
|
21
|
+
exports.canViewOwnPayroll = canViewOwnPayroll;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@escapenavigator/utils",
|
|
3
|
-
"version": "2.1.
|
|
3
|
+
"version": "2.1.28",
|
|
4
4
|
"publishConfig": {
|
|
5
5
|
"access": "public"
|
|
6
6
|
},
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
"test": "jest"
|
|
15
15
|
},
|
|
16
16
|
"dependencies": {
|
|
17
|
-
"@escapenavigator/types": "^2.1.
|
|
17
|
+
"@escapenavigator/types": "^2.1.28",
|
|
18
18
|
"axios": "^0.21.4",
|
|
19
19
|
"class-transformer": "^0.5.1",
|
|
20
20
|
"class-validator": "^0.13.2",
|
|
@@ -29,5 +29,5 @@
|
|
|
29
29
|
"ts-jest": "^29.1.1",
|
|
30
30
|
"typescript": "^5.6"
|
|
31
31
|
},
|
|
32
|
-
"gitHead": "
|
|
32
|
+
"gitHead": "924b64647909d9ba40d926f6e678cb809b795935"
|
|
33
33
|
}
|