@pisell/pisellos
Version:
一个可扩展的前端模块化SDK框架,支持插件系统
812 lines (810 loc) • 36.1 kB
JavaScript
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
// If the importer is in node compatibility mode or this is not an ESM
// file that has been converted to a CommonJS file using a Babel-
// compatible transform (i.e. "__esModule" has not been set), then set
// "default" to the CommonJS "module.exports" for node compatibility.
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
mod
));
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
// src/modules/Summary/utils.ts
var utils_exports = {};
__export(utils_exports, {
calcDiscountListDifference: () => calcDiscountListDifference,
calculateDeposit: () => calculateDeposit,
calculateOriginSubtotal: () => calculateOriginSubtotal,
calculatePriceDetails: () => calculatePriceDetails,
calculateSubtotal: () => calculateSubtotal,
calculateTaxFee: () => calculateTaxFee,
getBundleDiscountList: () => getBundleDiscountList,
getProductDiscountProductDiscountDifference: () => getProductDiscountProductDiscountDifference,
getSurcharge: () => getSurcharge,
getSurchargeAmount: () => getSurchargeAmount,
getTax: () => getTax
});
module.exports = __toCommonJS(utils_exports);
var import_decimal = __toESM(require("decimal.js"));
var import_utils = require("../Product/utils");
var import_dayjs = __toESM(require("dayjs"));
var calculatePriceDetails = (shopInfo, items, isInScheduleByDate, surchargeList, scheduleById) => {
const subtotal = new import_decimal.default(calculateSubtotal(items));
const subOriginTotal = new import_decimal.default(calculateOriginSubtotal(items));
const totalTaxFee = new import_decimal.default(calculateTaxFee(shopInfo, items));
const surcharge = getSurcharge({ service: items, addons: [], bookingDetail: null, bookingId: void 0 }, { isEdit: false, isInScheduleByDate, surcharge_list: surchargeList, scheduleById });
const surchargeAmount = new import_decimal.default(getSurchargeAmount({ bookingDetail: null, bookingId: void 0 }, surcharge, { isEdit: false }));
const { tax, originTax } = getTax({ service: items, bookingDetail: null, bookingId: void 0 }, {
computed: {
productExpectAmount: subtotal.toNumber(),
shopDiscount: 0
},
isEdit: false,
tax_rate: shopInfo == null ? void 0 : shopInfo.tax_rate,
is_price_include_tax: shopInfo == null ? void 0 : shopInfo.is_price_include_tax
});
const total = (shopInfo == null ? void 0 : shopInfo.is_price_include_tax) ? subtotal.plus(surchargeAmount) : subtotal.plus(tax).plus(surchargeAmount);
const originTotal = (shopInfo == null ? void 0 : shopInfo.is_price_include_tax) ? subOriginTotal.plus(surchargeAmount) : subOriginTotal.plus(totalTaxFee).plus(surchargeAmount);
const deposit = calculateDeposit(items);
return {
subtotal: subtotal.toFixed(2),
total: total.toFixed(2),
originTotal: originTotal.toFixed(2),
taxTitle: shopInfo == null ? void 0 : shopInfo.tax_title,
taxRate: shopInfo == null ? void 0 : shopInfo.tax_rate,
totalTaxFee: tax,
isPriceIncludeTax: shopInfo == null ? void 0 : shopInfo.is_price_include_tax,
surcharge,
surchargeAmount: surchargeAmount.toFixed(2),
deposit
};
};
var getBundleDiscountList = (bundle) => {
if (!bundle) {
return [];
}
let discountList = [];
bundle.forEach((d) => {
if (d.discount_list && Array.isArray(d.discount_list)) {
discountList.push(...d.discount_list.filter((item) => !item.id));
}
});
return discountList;
};
var calcDiscountListDifference = (discountList) => {
return discountList.reduce((pre, cur) => {
var _a;
return pre + (((_a = cur == null ? void 0 : cur.metadata) == null ? void 0 : _a.product_discount_difference) || 0);
}, 0);
};
var getProductDiscountProductDiscountDifference = (item) => {
var _a, _b, _c, _d;
const mainDiscountList = ((_b = (_a = item._origin) == null ? void 0 : _a.product) == null ? void 0 : _b.discount_list) || [];
const bundleDiscountList = getBundleDiscountList(((_d = (_c = item._origin) == null ? void 0 : _c.product) == null ? void 0 : _d.product_bundle) || []);
const discountList = [...mainDiscountList, ...bundleDiscountList];
return calcDiscountListDifference(discountList);
};
var getTax = ({ service, addons, bookingDetail, bookingId }, options) => {
const { isEdit, computed, tax_rate, is_price_include_tax } = options;
let totalOriginTax = new import_decimal.default(0);
let totalTax = new import_decimal.default(0);
if (service || addons) {
if (service == null ? void 0 : service.length) {
const serviceResult = processItemsTax(service.map((item) => {
return {
...item,
option: (item == null ? void 0 : item.option) || (item == null ? void 0 : item.options) || [],
bundle: (item == null ? void 0 : item.bundle) || (item == null ? void 0 : item.bundles) || []
};
}), { bookingDetail, bookingId }, {
tax_rate,
is_price_include_tax,
computed
});
totalOriginTax = totalOriginTax.plus(serviceResult.originTax);
totalTax = totalTax.plus(serviceResult.tax);
}
if (addons == null ? void 0 : addons.length) {
const addonsResult = processItemsTax(addons, { bookingDetail, bookingId }, {
tax_rate,
is_price_include_tax,
computed
});
totalOriginTax = totalOriginTax.plus(addonsResult.originTax);
totalTax = totalTax.plus(addonsResult.tax);
}
}
return {
originTax: totalOriginTax.toDecimalPlaces(2, import_decimal.default.ROUND_HALF_UP).toNumber(),
tax: totalTax.toDecimalPlaces(2, import_decimal.default.ROUND_HALF_UP).toNumber()
};
};
function getDiscountedTaxableBase(input) {
const { basePrice, discount, surchargeFee } = input;
if (surchargeFee.lte(0) && basePrice.lte(0))
return new import_decimal.default(0);
const discountedBase = basePrice.minus(discount);
if (discountedBase.lte(0))
return surchargeFee;
return discountedBase.plus(surchargeFee);
}
var processItemsTax = (items, { bookingDetail, bookingId }, options) => {
const { tax_rate, is_price_include_tax, computed } = options;
const { shopDiscount, productExpectAmount } = computed;
let preciseOriginTax = new import_decimal.default(0);
let preciseTax = new import_decimal.default(0);
let roundedOriginTax = new import_decimal.default(0);
let roundedTax = new import_decimal.default(0);
let lastTaxableItem = null;
for (let item of items) {
const quantity = new import_decimal.default(item.num || 1);
const unitPrice = new import_decimal.default(item.total || 0);
const mainProductPrice = new import_decimal.default(getMainProductTotal({
...item,
option: (item == null ? void 0 : item.option) || (item == null ? void 0 : item.options) || [],
bundle: (item == null ? void 0 : item.bundle) || (item == null ? void 0 : item.bundles) || []
}) || 0);
const originalTaxableBase = getDiscountedTaxableBase({
basePrice: mainProductPrice,
discount: new import_decimal.default(0),
surchargeFee: new import_decimal.default((item == null ? void 0 : item.surcharge_fee) || 0)
});
let originalTaxPerItemPrecise = getProductItemTax(
{
...item,
total: originalTaxableBase.toNumber(),
quantity: 1
},
{ bookingDetail, bookingId },
{ tax_rate, is_price_include_tax }
);
let itemDiscount = new import_decimal.default(0);
if (productExpectAmount > 0) {
itemDiscount = unitPrice.dividedBy(productExpectAmount).times(shopDiscount);
}
let mainItemDiscount = new import_decimal.default(0);
if (unitPrice.greaterThan(0)) {
mainItemDiscount = mainProductPrice.dividedBy(productExpectAmount).times(shopDiscount);
}
const mainItemDiscountedUnitPrice = getDiscountedTaxableBase({
basePrice: mainProductPrice,
discount: mainItemDiscount,
surchargeFee: new import_decimal.default((item == null ? void 0 : item.surcharge_fee) || 0)
});
const maxDiscountedTaxPerItemPrecise = getProductItemTax(
{
...item,
total: mainItemDiscountedUnitPrice.toNumber(),
price: item.total,
quantity: 1
},
{ bookingDetail, bookingId },
{ tax_rate, is_price_include_tax }
);
const maxDiscountedTaxPerItemRounded = maxDiscountedTaxPerItemPrecise.toDecimalPlaces(2, import_decimal.default.ROUND_HALF_UP);
item.main_product_attached_bundle_tax_fee = maxDiscountedTaxPerItemRounded.toNumber();
if (maxDiscountedTaxPerItemPrecise.gt(0)) {
lastTaxableItem = { type: "main", item };
}
let addTimePreciseTax = new import_decimal.default(0);
let addTimeRoundedTax = new import_decimal.default(0);
if (Array.isArray(item.relation_details)) {
for (let atItem of item.relation_details) {
const _originTotal = new import_decimal.default(
atItem.selling_price || atItem.price || 0
);
const addTimeDiscount = productExpectAmount > 0 ? _originTotal.dividedBy(productExpectAmount).times(shopDiscount) : new import_decimal.default(0);
const _discountedTotal = getDiscountedTaxableBase({
basePrice: _originTotal,
discount: addTimeDiscount,
surchargeFee: new import_decimal.default((atItem == null ? void 0 : atItem.surcharge_fee) || 0)
});
const addTimeTaxPerItemPrecise = getProductItemTax(
{
...atItem,
total: _discountedTotal.toNumber(),
quantity: atItem.product_quantity || atItem.num || 1
},
{ bookingDetail, bookingId },
{ tax_rate, is_price_include_tax }
);
const addTimeTaxPerItemRounded = addTimeTaxPerItemPrecise.toDecimalPlaces(2, import_decimal.default.ROUND_HALF_UP);
atItem.tax_fee = addTimeTaxPerItemRounded.toNumber();
addTimePreciseTax = addTimePreciseTax.plus(addTimeTaxPerItemPrecise);
addTimeRoundedTax = addTimeRoundedTax.plus(addTimeTaxPerItemRounded);
if (addTimeTaxPerItemPrecise.gt(0)) {
lastTaxableItem = { type: "addTime", item: atItem };
}
}
}
let bundlePreciseOriginTax = new import_decimal.default(0);
let bundlePreciseTax = new import_decimal.default(0);
let bundleRoundedOriginTax = new import_decimal.default(0);
let bundleRoundedTax = new import_decimal.default(0);
if (Array.isArray(item == null ? void 0 : item.bundle)) {
for (let bundleItem of item == null ? void 0 : item.bundle) {
if (getBundleItemIsOriginalPrice(bundleItem)) {
const bundleQuantity = new import_decimal.default(bundleItem.num || bundleItem.quantity || 1);
const bundleUnitPrice = new import_decimal.default(
bundleItem.bundle_selling_price ?? bundleItem.price ?? 0
);
const bundleOriginalTaxableBase = getDiscountedTaxableBase({
basePrice: bundleUnitPrice,
discount: new import_decimal.default(0),
surchargeFee: new import_decimal.default((bundleItem == null ? void 0 : bundleItem.surcharge_fee) || 0)
});
const bundleOriginalTaxPerItemPrecise = getProductItemTax(
{
...bundleItem,
total: bundleOriginalTaxableBase.toNumber(),
quantity: 1
},
{ bookingDetail, bookingId },
{ tax_rate, is_price_include_tax }
);
let bundleItemDiscount = new import_decimal.default(0);
if (productExpectAmount > 0) {
bundleItemDiscount = bundleUnitPrice.dividedBy(productExpectAmount).times(shopDiscount);
}
const bundleDiscountedUnitPrice = getDiscountedTaxableBase({
basePrice: bundleUnitPrice,
discount: bundleItemDiscount,
surchargeFee: new import_decimal.default((bundleItem == null ? void 0 : bundleItem.surcharge_fee) || 0)
});
const bundleDiscountedTaxPerItemPrecise = getProductItemTax(
{
...bundleItem,
total: bundleDiscountedUnitPrice.toNumber(),
quantity: 1
},
{ bookingDetail, bookingId },
{ tax_rate, is_price_include_tax }
);
const bundleOriginalTaxPerItemRounded = bundleOriginalTaxPerItemPrecise.toDecimalPlaces(2, import_decimal.default.ROUND_HALF_UP);
const bundleDiscountedTaxPerItemRounded = bundleDiscountedTaxPerItemPrecise.toDecimalPlaces(2, import_decimal.default.ROUND_HALF_UP);
bundleItem.original_tax_fee = bundleOriginalTaxPerItemRounded.toNumber();
bundleItem.tax_fee = bundleDiscountedTaxPerItemRounded.toNumber();
bundlePreciseOriginTax = bundlePreciseOriginTax.plus(bundleOriginalTaxPerItemPrecise.times(bundleQuantity));
bundlePreciseTax = bundlePreciseTax.plus(bundleDiscountedTaxPerItemPrecise.times(bundleQuantity));
bundleRoundedOriginTax = bundleRoundedOriginTax.plus(bundleOriginalTaxPerItemRounded.times(bundleQuantity));
bundleRoundedTax = bundleRoundedTax.plus(bundleDiscountedTaxPerItemRounded.times(bundleQuantity));
if (bundleDiscountedTaxPerItemPrecise.gt(0)) {
lastTaxableItem = { type: "bundle", item: bundleItem };
}
}
}
}
const originalTaxFeePrecise = originalTaxPerItemPrecise.plus(bundlePreciseOriginTax);
const taxFeePrecise = maxDiscountedTaxPerItemPrecise.plus(bundlePreciseTax);
const originalTaxFeeRounded = originalTaxPerItemPrecise.toDecimalPlaces(2, import_decimal.default.ROUND_HALF_UP).plus(bundleRoundedOriginTax);
const taxFeeRounded = maxDiscountedTaxPerItemRounded.plus(bundleRoundedTax);
item.original_tax_fee = originalTaxFeeRounded.toDecimalPlaces(2, import_decimal.default.ROUND_HALF_UP).toNumber();
item.tax_fee = taxFeeRounded.toDecimalPlaces(2, import_decimal.default.ROUND_HALF_UP).toNumber();
preciseOriginTax = preciseOriginTax.plus(originalTaxFeePrecise.times(quantity)).plus(addTimePreciseTax);
preciseTax = preciseTax.plus(taxFeePrecise.times(quantity)).plus(addTimePreciseTax);
roundedOriginTax = roundedOriginTax.plus(originalTaxFeeRounded.times(quantity)).plus(addTimeRoundedTax);
roundedTax = roundedTax.plus(taxFeeRounded.times(quantity)).plus(addTimeRoundedTax);
}
const expectedOriginTax = preciseOriginTax.toDecimalPlaces(2, import_decimal.default.ROUND_HALF_UP);
const expectedTax = preciseTax.toDecimalPlaces(2, import_decimal.default.ROUND_HALF_UP);
const originTaxRemainder = expectedOriginTax.minus(roundedOriginTax).toNumber();
const taxRemainder = expectedTax.minus(roundedTax).toNumber();
if (lastTaxableItem) {
if (originTaxRemainder !== 0) {
if (lastTaxableItem.type === "main") {
lastTaxableItem.item.original_tax_fee_rounding_remainder = originTaxRemainder;
} else {
lastTaxableItem.item.original_tax_fee_rounding_remainder = originTaxRemainder;
}
}
if (taxRemainder !== 0) {
if (lastTaxableItem.type === "main") {
lastTaxableItem.item.tax_fee_rounding_remainder = taxRemainder;
} else {
lastTaxableItem.item.tax_fee_rounding_remainder = taxRemainder;
}
}
}
return { originTax: expectedOriginTax, tax: expectedTax };
};
var getProductItemTax = (item, state, options) => {
const { bookingDetail } = state;
const { tax_rate, is_price_include_tax } = options;
const productDiscountPrice = new import_decimal.default(item.total || 0);
const quantity = new import_decimal.default(item.quantity ?? item.num ?? 1);
if (productDiscountPrice.lte(0)) {
return new import_decimal.default(0);
}
const currentTaxRate = new import_decimal.default(
(bookingDetail == null ? void 0 : bookingDetail.tax_rate) ?? (tax_rate ? tax_rate / 100 : 0)
);
const currentIsPriceIncludeTax = (bookingDetail == null ? void 0 : bookingDetail.is_price_include_tax) ?? is_price_include_tax ?? 0;
let singleItemTax = new import_decimal.default(0);
if (item.is_charge_tax === 0 || !item.is_charge_tax) {
singleItemTax = new import_decimal.default(0);
} else {
if (currentIsPriceIncludeTax === 0) {
singleItemTax = productDiscountPrice.times(currentTaxRate);
} else {
const divisor = new import_decimal.default(1).plus(currentTaxRate);
if (divisor.lte(0)) {
singleItemTax = new import_decimal.default(0);
} else {
singleItemTax = productDiscountPrice.dividedBy(divisor).times(currentTaxRate);
}
}
}
return singleItemTax.times(quantity);
};
var calculateSubtotal = (items) => {
if (!(items == null ? void 0 : items.length)) {
return "0.00";
}
const subtotal = items.reduce((sum, item) => {
const cartItemTotalPrice = new import_decimal.default(item.summaryTotal || 0);
const productDiscountProductDiscountDifference = getProductDiscountProductDiscountDifference(item);
return sum.plus(cartItemTotalPrice).sub(productDiscountProductDiscountDifference);
}, new import_decimal.default(0));
return subtotal.toFixed(2);
};
var calculateOriginSubtotal = (items) => {
if (!(items == null ? void 0 : items.length)) {
return "0.00";
}
const subtotal = items.reduce((sum, item) => {
const cartItemTotalPrice = new import_decimal.default(item.summaryOriginTotal || 0);
return sum.plus(cartItemTotalPrice);
}, new import_decimal.default(0));
return subtotal.toFixed(2);
};
var calculateTaxFee = (shopInfo, items) => {
if (!(items == null ? void 0 : items.length)) {
return "0.00";
}
const { is_price_include_tax, tax_rate } = shopInfo || {};
const totalTaxFee = items.reduce((sum, item) => {
const cartItemTotalPrice = new import_decimal.default(item.summaryTotal || 0);
const taxRate = new import_decimal.default(tax_rate || 0).div(100);
const productTaxRate = cartItemTotalPrice.times(taxRate).times((item == null ? void 0 : item.is_charge_tax) || 0).div(taxRate.times(is_price_include_tax || 0).plus(1));
return sum.plus(productTaxRate);
}, new import_decimal.default(0));
return totalTaxFee;
};
var calculateDeposit = (items) => {
if (!(items == null ? void 0 : items.length)) {
return void 0;
}
const protocols = [];
let hasDeposit = false;
const total = items.reduce((sum, item) => {
var _a, _b, _c;
if (item == null ? void 0 : item.deposit) {
hasDeposit = true;
const cartItemTotalPrice = new import_decimal.default(((_a = item == null ? void 0 : item.deposit) == null ? void 0 : _a.total) || 0);
(_c = (_b = item == null ? void 0 : item.deposit) == null ? void 0 : _b.protocols) == null ? void 0 : _c.forEach((protocol) => {
if (protocols.findIndex((p) => p.id === protocol.id) === -1) {
protocols.push(protocol);
}
});
return sum.plus(cartItemTotalPrice);
}
return sum;
}, new import_decimal.default(0));
if (hasDeposit) {
return { total: total.toFixed(2), protocols, hasDeposit };
}
return void 0;
};
var getSurchargeAmount = ({ bookingDetail, bookingId }, surcharge, options) => {
const { isEdit } = options;
if (!isEdit) {
if (bookingDetail && bookingId) {
return Number(bookingDetail.surcharge_fee);
}
}
if (!Array.isArray(surcharge))
return 0;
return surcharge.reduce((total, item) => {
return total + (item.value || 0);
}, 0);
};
var getBundleItemIsOriginalPrice = (item) => {
return (item == null ? void 0 : item.price_type) === "markup" && (item == null ? void 0 : item.price_type_ext) === "product_price";
};
var getBundleItemIsMarkupPrice = (item) => {
return (item == null ? void 0 : item.price_type) === "markup" && ((item == null ? void 0 : item.price_type_ext) === "" || !(item == null ? void 0 : item.price_type_ext));
};
var getBundleItemIsDiscountPrice = (item) => {
return (item == null ? void 0 : item.price_type) === "markdown" && ((item == null ? void 0 : item.price_type_ext) === "" || !(item == null ? void 0 : item.price_type_ext));
};
var getBundleItemIsMarkupOrDiscountPrice = (item) => {
return getBundleItemIsMarkupPrice(item) || getBundleItemIsDiscountPrice(item);
};
var getDiscountAmount = (discounts) => {
return (discounts || []).reduce((total, discount) => {
return total.add(new import_decimal.default(discount.amount || 0));
}, new import_decimal.default(0)).toNumber();
};
var getMainProductTotal = (item) => {
var _a, _b, _c, _d, _e, _f;
let total = new import_decimal.default((item == null ? void 0 : item.main_product_selling_price) ?? ((_a = item == null ? void 0 : item.metadata) == null ? void 0 : _a.main_product_selling_price) ?? item.price ?? 0);
const discount = ((_c = (_b = item == null ? void 0 : item._origin) == null ? void 0 : _b.product) == null ? void 0 : _c.discount_list) || ((_f = (_e = (_d = item == null ? void 0 : item._originData) == null ? void 0 : _d.product) == null ? void 0 : _e.discount_list) == null ? void 0 : _f.filter((item2) => {
var _a2;
return !((_a2 = item2 == null ? void 0 : item2.metadata) == null ? void 0 : _a2.custom_product_bundle_map_id);
})) || [];
const mainProductDiscountAmount = getDiscountAmount(discount);
total = total.minus(mainProductDiscountAmount);
if ((item == null ? void 0 : item.option) && Array.isArray(item == null ? void 0 : item.option)) {
total = total.add(item == null ? void 0 : item.option.reduce((t, option) => {
return t.add(new import_decimal.default(option.price || 0).mul(option.num || 1));
}, new import_decimal.default(0)));
}
for (let bundleItem of (item == null ? void 0 : item.bundle) || []) {
if (getBundleItemIsMarkupOrDiscountPrice(bundleItem)) {
const bundleItemTotal = new import_decimal.default(bundleItem.bundle_selling_price ?? bundleItem.price ?? 0);
total = total.add(bundleItemTotal);
}
}
return total.toNumber();
};
var isProductMatchSurchargeCondition = (item, options) => {
const isInScheduleByDate = options == null ? void 0 : options.isInScheduleByDate;
const { surchargeConfig, scheduleById = {} } = options;
const { startDate, product_id, isCustomItem } = item;
const {
open_product = 0,
// 1 | 0
is_all = 0,
// 0 | 1(所有商品)
available_product_ids = [],
// 指定商品
open_schedule = 0,
// 1 | 0
schedule_type,
// custom | all(所有日程)
available_schedule_ids = []
} = surchargeConfig;
let isProductMatch = false;
if (open_product === 0) {
isProductMatch = true;
} else {
if (is_all === 1) {
isProductMatch = true;
} else {
if (isCustomItem) {
isProductMatch = false;
} else {
isProductMatch = available_product_ids.includes(product_id);
}
}
}
let isScheduleMatch = false;
if (open_schedule === 0) {
isScheduleMatch = true;
} else {
if (schedule_type === "all") {
isScheduleMatch = true;
} else {
for (let j = 0; j < available_schedule_ids.length; j++) {
const scheduleId = available_schedule_ids[j];
const schedule = scheduleById[scheduleId];
if (schedule) {
const isInSchedule = isInScheduleByDate({
// date: startDate?.format('YYYY-MM-DD HH:mm:ss') || '',
date: startDate || "",
schedule
});
if (isInSchedule) {
isScheduleMatch = true;
break;
}
}
}
}
}
return isProductMatch && isScheduleMatch;
};
var getSurcharge = ({ service, addons, bookingDetail, bookingId }, options) => {
var _a, _b, _c, _d;
const { isEdit, isInScheduleByDate, surcharge_list, scheduleById } = options;
const firstAppointmentCartItem = (_a = service.filter(
(n) => !(0, import_utils.isNormalProduct)(n._productOrigin)
)) == null ? void 0 : _a[0];
let startDate = "";
if (firstAppointmentCartItem) {
startDate = firstAppointmentCartItem.start_date + " " + firstAppointmentCartItem.start_time + ":00";
} else {
startDate = (0, import_dayjs.default)().format("YYYY-MM-DD HH:mm:ss");
}
if (!isEdit && bookingId) {
if (Array.isArray(bookingDetail == null ? void 0 : bookingDetail.surcharge)) {
return ((bookingDetail == null ? void 0 : bookingDetail.surcharge) || []).filter((d) => Number(d.amount) > 0).map(
(d, index) => {
return {
key: `custom_surcharge_${index}`,
// label:
// d.name[state.locale || 'en'] ||
// d.name['en'] ||
// d.name['original'],
label: d.name,
value: d.amount,
name: d.name,
surcharge_id: d.id,
description: d.description,
// 后端说这个固定传 default
type: "default",
fixed: d.fixed,
amount: d.amount,
percentage: d.percentage
};
}
);
}
return [];
}
resetItemsSurchargeSideEffects({ service, addons });
if (!Array.isArray(surcharge_list) || !(surcharge_list == null ? void 0 : surcharge_list.length))
return [];
const surchargeWithAmount = [];
for (let i = 0; i < surcharge_list.length; i++) {
const surchargeConfig = surcharge_list[i];
const {
percentage = "0",
fixed = "0",
id,
type,
description,
open_product
} = surchargeConfig;
const matchedItems = [];
if (Array.isArray(service)) {
for (let item of service) {
if (isProductMatchSurchargeCondition(
{
isCustomItem: item.isCustomItem,
startDate,
product_id: item.id
},
{
surchargeConfig,
scheduleById: scheduleById || {},
isInScheduleByDate
}
)) {
const total = getMainProductTotal({
...item,
option: (item == null ? void 0 : item.option) || (item == null ? void 0 : item.options) || [],
bundle: (item == null ? void 0 : item.bundle) || (item == null ? void 0 : item.bundles) || []
});
const mainQuantity = item.num || 1;
matchedItems.push({
total,
// addTimeTotal: getRelationDetailsTotal(
// item._extend.relation_details || []
// ),
isMain: true,
quantity: mainQuantity,
item,
mainQuantity
// 主商品的mainQuantity等于自己的quantity
});
}
const arr = (item == null ? void 0 : item.bundle) || (item == null ? void 0 : item.bundles) || [];
for (let bundleItem of arr) {
if (getBundleItemIsOriginalPrice(bundleItem) && isProductMatchSurchargeCondition(
{
isCustomItem: false,
startDate,
product_id: bundleItem._bundle_product_id
},
{
surchargeConfig,
scheduleById: scheduleById || {},
isInScheduleByDate
}
)) {
const mainQuantity = item.num || 1;
matchedItems.push({
isMain: false,
total: Number(
bundleItem.bundle_selling_price ?? bundleItem.price ?? 0
),
quantity: bundleItem.num || bundleItem.quantity || 1,
item: bundleItem,
mainQuantity
// 子商品的mainQuantity是所属主商品的quantity
});
}
}
for (let relationDetail of item.relation_details || []) {
if (isProductMatchSurchargeCondition(
{
isCustomItem: false,
startDate,
product_id: relationDetail.product_id
},
{
surchargeConfig,
scheduleById: scheduleById || {},
isInScheduleByDate
}
)) {
matchedItems.push({
isMain: false,
total: Number(
(relationDetail == null ? void 0 : relationDetail.price) || ((_b = relationDetail == null ? void 0 : relationDetail.metadata) == null ? void 0 : _b.main_product_attached_bundle_selling_price)
),
quantity: relationDetail.num || relationDetail.quantity || 1,
item: relationDetail,
mainQuantity: 1
// 加时商品不受主商品数量影响
});
}
}
}
}
if (Array.isArray(addons == null ? void 0 : addons.value)) {
for (let item of addons.value) {
if (isProductMatchSurchargeCondition({ ...item, startDate }, {
surchargeConfig,
scheduleById: scheduleById || {},
isInScheduleByDate
})) {
matchedItems.push({
isMain: true,
total: Number(item.total),
quantity: item.num || 1,
item,
mainQuantity: 1
// addons独立商品,mainQuantity为1
});
}
}
}
let finalAmount = 0;
const productCount = matchedItems.reduce((total, item) => {
if (item.isMain) {
return total + (item.num || item.quantity || 1);
} else {
return total + (item.num || item.quantity || 1) * (item.mainQuantity || 1);
}
}, 0);
let fixedTotal = new import_decimal.default(0);
let productTotalSurcharge = new import_decimal.default(0);
if (matchedItems.length > 0) {
let configTotal = new import_decimal.default(0);
if (fixed && new import_decimal.default(fixed).gt(0)) {
configTotal = configTotal.plus(fixed);
}
if (percentage && new import_decimal.default(percentage).gt(0) || fixed) {
const percentageRate = new import_decimal.default(percentage);
for (let [index, item] of matchedItems.entries()) {
const isLast = index === matchedItems.length - 1;
const itemPrice = new import_decimal.default(Math.max(0, item.total || 0));
const itemQuantity = new import_decimal.default(item.isMain ? item.quantity || 1 : item.quantity * item.mainQuantity || 1);
const addTimeTotal = new import_decimal.default(item.addTimeTotal || 0);
const itemTotalSurcharge = itemPrice.times(itemQuantity).plus(addTimeTotal).times(percentageRate);
configTotal = configTotal.plus(itemTotalSurcharge);
const itemSurcharge = itemPrice.times(percentageRate);
const fixedSurcharge = new import_decimal.default(1).div(productCount).times(fixed).times(100).floor().div(100).toFixed(2);
const quantity = item.isMain ? item.quantity : item.quantity * item.mainQuantity;
fixedTotal = fixedTotal.plus(new import_decimal.default(fixedSurcharge).times(quantity).toNumber());
if (isLast && fixedTotal.gt(0)) {
const remaining = new import_decimal.default(fixed).minus(fixedTotal).toNumber();
if (remaining > 0) {
productTotalSurcharge = productTotalSurcharge.plus(remaining);
if (item.isMain) {
item.item.surcharge_rounding_remainder = remaining;
} else {
item.item.surcharge_rounding_remainder = remaining;
}
}
}
if (open_product !== 0) {
if (item.isMain) {
const originSurchargeFee = new import_decimal.default(item.item.surcharge_fee || 0);
const surchargeFee = originSurchargeFee.plus(itemSurcharge).plus(fixedSurcharge).toDecimalPlaces(2, import_decimal.default.ROUND_DOWN).toNumber();
productTotalSurcharge = productTotalSurcharge.plus(new import_decimal.default(surchargeFee).times(itemQuantity).toNumber());
item.item.surcharge_fee = surchargeFee;
item.item.relation_surcharge_ids = [...((_c = item.item) == null ? void 0 : _c.relation_surcharge_ids) || [], id];
} else {
const originSurchargeFee = new import_decimal.default(item.item.surcharge_fee || 0);
const surchargeFee = originSurchargeFee.plus(itemSurcharge).plus(fixedSurcharge).toDecimalPlaces(2, import_decimal.default.ROUND_DOWN).toNumber();
productTotalSurcharge = productTotalSurcharge.plus(new import_decimal.default(surchargeFee).times(itemQuantity).toNumber());
item.item.surcharge_fee = surchargeFee;
item.item.relation_surcharge_ids = [...((_d = item.item) == null ? void 0 : _d.relation_surcharge_ids) || [], id];
}
}
if (isLast && configTotal.minus(productTotalSurcharge).gt(0)) {
const configTotalRounded = configTotal.toDecimalPlaces(2, import_decimal.default.ROUND_HALF_UP);
if (item.isMain) {
let newRoundingRemainder = new import_decimal.default(item.item.surcharge_rounding_remainder || 0);
newRoundingRemainder = newRoundingRemainder.plus(configTotalRounded.minus(productTotalSurcharge));
item.item.surcharge_rounding_remainder = newRoundingRemainder.toNumber();
} else {
let newRoundingRemainder = new import_decimal.default(item.item.surcharge_rounding_remainder || 0);
newRoundingRemainder = newRoundingRemainder.plus(configTotalRounded.minus(productTotalSurcharge));
item.item.surcharge_rounding_remainder = newRoundingRemainder.toNumber();
}
}
}
}
finalAmount = configTotal.toDecimalPlaces(2, import_decimal.default.ROUND_HALF_UP).toNumber();
}
const name = surchargeConfig.name || {};
if (Number(finalAmount) <= 0) {
continue;
}
surchargeWithAmount.push({
key: `custom_surcharge_${i}`,
// label: name[state.locale || 'en'] || name['en'] || name['original'],
label: name,
name,
value: finalAmount,
surcharge_id: id,
description,
// 后端说固定传 default
type: "default",
fixed,
amount: finalAmount,
percentage,
metadata: {
open_product
}
});
}
return surchargeWithAmount;
};
function resetItemsSurchargeSideEffects({ service, addons }) {
const resetItem = (item) => {
if (!item)
return;
item.surcharge_fee = 0;
item.surcharge_rounding_remainder = 0;
item.relation_surcharge_ids = [];
};
if (Array.isArray(service)) {
for (let item of service) {
resetItem(item);
const arr = (item == null ? void 0 : item.bundle) || (item == null ? void 0 : item.bundles) || [];
for (let bundleItem of arr)
resetItem(bundleItem);
for (let relationDetail of (item == null ? void 0 : item.relation_details) || [])
resetItem(relationDetail);
}
}
if (Array.isArray(addons == null ? void 0 : addons.value)) {
for (let item of addons.value)
resetItem(item);
}
}
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
calcDiscountListDifference,
calculateDeposit,
calculateOriginSubtotal,
calculatePriceDetails,
calculateSubtotal,
calculateTaxFee,
getBundleDiscountList,
getProductDiscountProductDiscountDifference,
getSurcharge,
getSurchargeAmount,
getTax
});