UNPKG

@pisell/pisellos

Version:

一个可扩展的前端模块化SDK框架,支持插件系统

812 lines (810 loc) 36.1 kB
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 });