@pisell/pisellos
Version:
一个可扩展的前端模块化SDK框架,支持插件系统
1,090 lines (991 loc) • 60.9 kB
JavaScript
function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : String(i); }
function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
function _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; }
function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); }
function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter); }
function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); }
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }
import Decimal from 'decimal.js';
/** 订单商品数量 */
export var getProductQuantity = function getProductQuantity(product) {
return product.quantity || product.product_quantity || 1;
};
/**
* 订单商品行唯一键,用于 maxPassesPerItem 按行、按件配额(同 SPU 不同规格视为不同行)。
*/
export function resolveWalletPassLineKey(product, indexInOrder) {
var m = (product === null || product === void 0 ? void 0 : product.metadata) || {};
var u1 = m.product_unique;
if (u1 != null && String(u1).length > 0) return String(u1);
var u2 = m.unique_identification_number;
if (u2 != null && String(u2).length > 0) return String(u2);
if ((product === null || product === void 0 ? void 0 : product.id) != null && String(product.id).length > 0) return "order_item:".concat(product.id);
if ((product === null || product === void 0 ? void 0 : product.product_unique_string) != null && String(product.product_unique_string).length > 0) {
return String(product.product_unique_string);
}
return "order_line_".concat(indexInOrder);
}
function getExpandedOrderLineQuantity(p) {
if ((p === null || p === void 0 ? void 0 : p._orderLineQuantity) != null && p._orderLineQuantity > 0) return p._orderLineQuantity;
return getProductQuantity(p);
}
/** 该行允许消耗的「券次」上限:maxPassesPerItem × 订单行件数 */
function getMaxPassSlotsForExpandedLine(maxPassesPerItem, p) {
if (maxPassesPerItem <= 0) return Infinity;
return maxPassesPerItem * getExpandedOrderLineQuantity(p);
}
/**
* 本次抵扣占用多少「券次」配额:有抵扣时至少占 1,并与按金额折算的件数挂钩,不超过剩余额度。
*/
function computePassSlotsIncrement(deductAmount, deductQty, maxPassesPerItem, orderLineQuantity, currentUsage) {
if (maxPassesPerItem <= 0 || !deductAmount.greaterThan(0)) return 0;
var cap = maxPassesPerItem * orderLineQuantity;
var room = Math.max(0, cap - currentUsage);
if (room <= 0) return 0;
var raw = Math.max(1, Math.ceil(Number(deductQty)) || 1);
return Math.min(raw, room);
}
function applyMaxPassUsageIncrements(usageMap, walletPassProductId, maxPassesPerItem, deductionDetails) {
deductionDetails.forEach(function (detail) {
var _usageMap$get;
var lineKey = detail.lineKey;
if (!lineKey || maxPassesPerItem <= 0) return;
var orderLineQty = detail.orderLineQuantity != null && detail.orderLineQuantity > 0 ? detail.orderLineQuantity : 1;
var cur = ((_usageMap$get = usageMap.get(walletPassProductId)) === null || _usageMap$get === void 0 ? void 0 : _usageMap$get.get(lineKey)) || 0;
var inc = computePassSlotsIncrement(new Decimal(detail.deductAmount), detail.deductQuantity, maxPassesPerItem, orderLineQty, cur);
if (inc <= 0) return;
if (!usageMap.has(walletPassProductId)) usageMap.set(walletPassProductId, new Map());
var inner = usageMap.get(walletPassProductId);
inner.set(lineKey, cur + inc);
});
}
// 辅助函数:根据 deductTaxAndFee 配置获取推荐使用金额
var getRecommendedAmount = function getRecommendedAmount(voucher) {
var _config$deductTaxAndF;
console.log('voucher312', voucher);
var config = voucher.config,
recommended_usage_amount = voucher.recommended_usage_amount,
recommended_pure_product_usage_amount = voucher.recommended_pure_product_usage_amount;
var deductTaxAndFee = (_config$deductTaxAndF = config === null || config === void 0 ? void 0 : config.deductTaxAndFee) !== null && _config$deductTaxAndF !== void 0 ? _config$deductTaxAndF : true; // 默认开启抵扣税费
// 如果开启抵扣税费,使用 recommended_usage_amount(包含税费)
// 如果关闭抵扣税费,使用 recommended_pure_product_usage_amount(仅商品金额)
return deductTaxAndFee ? recommended_usage_amount : recommended_pure_product_usage_amount !== null && recommended_pure_product_usage_amount !== void 0 ? recommended_pure_product_usage_amount : recommended_usage_amount;
};
// 辅助函数:获取适用商品ID列表
export var getApplicableProductIds = function getApplicableProductIds(voucher) {
var _ref = voucher,
available_product_type = _ref.available_product_type,
available_product_ids = _ref.available_product_ids;
// 如果没有 available_product_type,默认为 product_all
var productType = available_product_type || 'product_all';
// product_all 时,返回 null 表示适用所有商品
if (productType === 'product_all') {
return null;
}
// product_collection 或 products 时,返回指定的商品ID列表
if (productType === 'product_collection' || productType === 'products') {
return available_product_ids || [];
}
// 其他情况默认返回空数组(不适用任何商品)
return [];
};
// 辅助函数:计算适用商品的总金额(基于剩余金额)
var getApplicableProductsAmount = function getApplicableProductsAmount(voucher, productsData) {
var _config$deductTaxAndF2;
var applicableProductIds = getApplicableProductIds(voucher);
var config = voucher.config;
var deductTaxAndFee = (_config$deductTaxAndF2 = config === null || config === void 0 ? void 0 : config.deductTaxAndFee) !== null && _config$deductTaxAndF2 !== void 0 ? _config$deductTaxAndF2 : true;
// 根据券的配置选择使用哪个金额字段
var amountField = deductTaxAndFee ? 'remainingAmountWithTax' : 'remainingAmountPure';
// 如果为 null,适用于所有商品
if (applicableProductIds === null) {
return productsData.filter(function (p) {
return p[amountField].greaterThan(0);
}).reduce(function (sum, p) {
return sum.plus(p[amountField]);
}, new Decimal(0));
}
// 如果为空数组,不适用任何商品
if (applicableProductIds.length === 0) {
return new Decimal(0);
}
// 计算指定商品的总金额
return productsData.filter(function (p) {
return applicableProductIds.includes(p.product_id) && p[amountField].greaterThan(0);
}).reduce(function (sum, p) {
return sum.plus(p[amountField]);
}, new Decimal(0));
};
// 辅助函数:获取适用的商品列表
var getApplicableProducts = function getApplicableProducts(voucher, productsData) {
var applicableProductIds = getApplicableProductIds(voucher);
// 如果为 null,适用于所有商品
if (applicableProductIds === null) {
return productsData;
}
// 如果为空数组,不适用任何商品
if (applicableProductIds.length === 0) {
return [];
}
// 返回指定的商品列表
return productsData.filter(function (p) {
return applicableProductIds.includes(p.product_id);
});
};
/**
* 优惠券处理函数
* @param applicableVouchers 可用的券列表
* @param orderTotalAmount 订单总金额
* @param products 订单商品列表
* @returns 返回推荐券列表和全部列表,每个券包含 _available_max_amount 和 _unified_available_status
*/
export function processVouchers(applicableVouchers, orderTotalAmount, products) {
console.log(products, 'products123');
// 拆分商品数据,同时维护含税和不含税两个金额池
// remainingAmountWithTax: 含税费的剩余可抵扣金额
// remainingAmountPure: 纯商品金额(不含税费)的剩余可抵扣金额
// 在抵扣时,会根据券的 deductTaxAndFee 配置选择从哪个金额池扣除
var productsCopy = expandProductsWithBundleItems(products, true);
var remainingOrderAmount = new Decimal(orderTotalAmount); // 订单剩余应付金额
// ========== 辅助工具:maxPassesPerItem(按订单行 + 件数)追踪 ==========
var getItemPassUsage = function getItemPassUsage(usageMap, walletPassProductId, lineKey) {
var _usageMap$get2;
return ((_usageMap$get2 = usageMap.get(walletPassProductId)) === null || _usageMap$get2 === void 0 ? void 0 : _usageMap$get2.get(lineKey)) || 0;
};
// 按 maxPassesPerItem 过滤:排除已达到该行「券次」上限的展开行(按 _walletPassLineKey)
var filterByMaxPassesPerItem = function filterByMaxPassesPerItem(products, usageMap, walletPassProductId, maxPassesPerItem) {
if (maxPassesPerItem <= 0) return products;
return products.filter(function (p) {
var lineKey = p._walletPassLineKey;
if (!lineKey) return true;
return getItemPassUsage(usageMap, walletPassProductId, lineKey) < getMaxPassSlotsForExpandedLine(maxPassesPerItem, p);
});
};
// ================================================================
// 辅助函数:计算单张券的 _available_max_amount
var calculateAvailableMaxAmount = function calculateAvailableMaxAmount(voucher, productsData, itemPassUsage) {
var config = voucher.config;
var _ref2 = config !== null && config !== void 0 ? config : {},
_ref2$maxDeductionAmo = _ref2.maxDeductionAmount,
maxDeductionAmount = _ref2$maxDeductionAmo === void 0 ? 0 : _ref2$maxDeductionAmo,
_ref2$allowCrossProdu = _ref2.allowCrossProduct,
allowCrossProduct = _ref2$allowCrossProdu === void 0 ? true : _ref2$allowCrossProdu,
_ref2$applicableProdu = _ref2.applicableProductLimit,
applicableProductLimit = _ref2$applicableProdu === void 0 ? 0 : _ref2$applicableProdu,
_ref2$deductTaxAndFee = _ref2.deductTaxAndFee,
deductTaxAndFee = _ref2$deductTaxAndFee === void 0 ? true : _ref2$deductTaxAndFee,
_ref2$maxPassesPerIte = _ref2.maxPassesPerItem,
maxPassesPerItem = _ref2$maxPassesPerIte === void 0 ? 0 : _ref2$maxPassesPerIte;
// 根据 deductTaxAndFee 配置获取推荐金额
var recommendedAmount = getRecommendedAmount(voucher);
// 基础值 = min(recommendedAmount, maxDeductionAmount)
var baseAmount = Decimal.min(new Decimal(recommendedAmount), new Decimal(maxDeductionAmount));
// 根据券的配置选择使用哪个单价字段和金额字段
var unitPriceField = deductTaxAndFee ? 'unitPriceWithTax' : 'unitPricePure';
var amountField = deductTaxAndFee ? 'remainingAmountWithTax' : 'remainingAmountPure';
// 获取适用商品列表(只筛选有剩余金额的商品)
var applicableProducts = getApplicableProducts(voucher, productsData).filter(function (p) {
return p[amountField].greaterThan(0);
});
// 按 maxPassesPerItem 过滤:排除已达到单商品可用卡券上限的商品
if (itemPassUsage) {
applicableProducts = filterByMaxPassesPerItem(applicableProducts, itemPassUsage, voucher.product_id, maxPassesPerItem);
}
if (applicableProducts.length === 0) {
return new Decimal(0);
}
// 根据跨商品配置计算适用商品金额
var finalApplicableAmount = new Decimal(0);
if (allowCrossProduct) {
// 跨商品券:可以抵扣多个商品
if (applicableProductLimit > 0) {
// 有数量限制:按剩余金额从高到低排序,按动态计算的可抵扣数量累计直到达到 limit
var sortedProducts = _toConsumableArray(applicableProducts).sort(function (a, b) {
return a[amountField].comparedTo(b[amountField]) > 0 ? -1 : 1;
});
var remainingLimit = applicableProductLimit;
var _iterator = _createForOfIteratorHelper(sortedProducts),
_step;
try {
for (_iterator.s(); !(_step = _iterator.n()).done;) {
var product = _step.value;
if (remainingLimit <= 0) break;
// 动态计算当前可抵扣数量 = ceil(剩余金额 / 单价)
var currentAvailableQty = Math.ceil(product[amountField].dividedBy(product[unitPriceField]).toNumber());
var deductQty = Math.min(currentAvailableQty, remainingLimit);
// 实际可抵扣金额 = min(数量 * 单价, 剩余金额)
var deductAmount = Decimal.min(product[unitPriceField].times(deductQty), product[amountField]);
finalApplicableAmount = finalApplicableAmount.plus(deductAmount);
remainingLimit -= deductQty;
}
} catch (err) {
_iterator.e(err);
} finally {
_iterator.f();
}
} else {
// 无数量限制:所有适用商品的剩余金额总和
finalApplicableAmount = applicableProducts.reduce(function (sum, p) {
return sum.plus(p[amountField]);
}, new Decimal(0));
}
} else {
// 非跨商品券:选择单价最高的商品(优先抵扣高价商品)
var maxProduct = applicableProducts.reduce(function (max, p) {
return p[unitPriceField].greaterThan(max[unitPriceField]) ? p : max;
});
// maxPassesPerItem 限制每张券最多抵扣的单位数
if (maxPassesPerItem > 0) {
finalApplicableAmount = Decimal.min(maxProduct[unitPriceField].times(maxPassesPerItem), maxProduct[amountField]);
} else {
finalApplicableAmount = maxProduct[amountField];
}
}
// 返回最小值
return Decimal.min(baseAmount, finalApplicableAmount, remainingOrderAmount);
};
// 辅助函数:判断券是否可用,返回可用性和原因代码
var isVoucherAvailable = function isVoucherAvailable(voucher, productsData, usedVoucherCounts, itemPassUsage) {
var config = voucher.config,
id = voucher.id,
product_id = voucher.product_id;
// 根据 deductTaxAndFee 配置获取推荐金额
var recommendedAmount = getRecommendedAmount(voucher);
// 余额为 0
if (recommendedAmount <= 0) {
return {
isAvailable: false,
reasonCode: 'not_meet_the_required_conditions'
};
}
// 订单金额已抵扣完
if (remainingOrderAmount.lessThanOrEqualTo(0)) {
return {
isAvailable: false,
reasonCode: 'exceeds_the_maximum_deduction_limit'
};
}
// 适用商品金额已被抵扣完
var applicableAmount = getApplicableProductsAmount(voucher, productsData);
if (applicableAmount.lessThanOrEqualTo(0)) {
return {
isAvailable: false,
reasonCode: 'not_meet_the_required_conditions'
};
}
// 检查 maxUsagePerOrder(同 product_id 的券),0 表示不限制
if (((config === null || config === void 0 ? void 0 : config.maxUsagePerOrder) || 0) > 0) {
var usedCount = usedVoucherCounts.get(product_id) || 0;
if (usedCount >= ((config === null || config === void 0 ? void 0 : config.maxUsagePerOrder) || 0)) {
return {
isAvailable: false,
reasonCode: 'usage_limit_reached'
};
}
}
// 检查 maxPassesPerItem:如果所有适用商品都已达到单商品可用卡券上限,则不可用
var maxPassesPerItem = (config === null || config === void 0 ? void 0 : config.maxPassesPerItem) || 0;
if (maxPassesPerItem > 0 && itemPassUsage) {
var _config$deductTaxAndF3;
var deductTaxAndFee = (_config$deductTaxAndF3 = config === null || config === void 0 ? void 0 : config.deductTaxAndFee) !== null && _config$deductTaxAndF3 !== void 0 ? _config$deductTaxAndF3 : true;
var amountField = deductTaxAndFee ? 'remainingAmountWithTax' : 'remainingAmountPure';
var availableAfterPassLimit = getApplicableProducts(voucher, productsData).filter(function (p) {
return p[amountField].greaterThan(0);
}).filter(function (p) {
var lineKey = p._walletPassLineKey;
if (!lineKey) return true;
return getItemPassUsage(itemPassUsage, product_id, lineKey) < getMaxPassSlotsForExpandedLine(maxPassesPerItem, p);
});
if (availableAfterPassLimit.length === 0) {
return {
isAvailable: false,
reasonCode: 'max_passes_per_item_reached'
};
}
}
return {
isAvailable: true
};
};
// ========== 第一步:为所有券计算初始的 _available_max_amount 和 _unified_available_status ==========
var usedVoucherCountsForAll = new Map();
var allVouchersWithStatus = applicableVouchers.map(function (voucher) {
var _available_max_amount = calculateAvailableMaxAmount(voucher, productsCopy);
var availabilityResult = isVoucherAvailable(voucher, productsCopy, usedVoucherCountsForAll);
var _unified_available_status = availabilityResult.isAvailable ? 1 : 0;
return _objectSpread(_objectSpread({}, voucher), {}, {
_available_max_amount: _available_max_amount.toNumber(),
// 转换为数字
_unified_available_status: _unified_available_status
}, availabilityResult.reasonCode && {
reasonCode: availabilityResult.reasonCode
});
});
// ========== 第二步:计算推荐券列表 ==========
var recommendedVouchers = [];
var usedVoucherCounts = new Map(); // 跟踪每个券 ID 的使用次数
// 重置商品余额追踪(同时维护含税和不含税两个金额池)
var productsForRecommendation = expandProductsWithBundleItems(products, true);
remainingOrderAmount = new Decimal(orderTotalAmount);
// 追踪推荐阶段每个 Wallet Pass 商品对每个订单商品行的已使用卡券次数(按行唯一键)
var itemPassUsageMap = new Map();
/**
// 分类券:未跨商品券 vs 跨商品券
const nonCrossProductVouchers = applicableVouchers.filter(
(v) => !v.config?.allowCrossProduct,
);
const crossProductVouchers = applicableVouchers.filter(
(v) => v.config?.allowCrossProduct,
);
// 按 tag 分组
const groupByType = (vouchers: any[]) => {
const groups = new Map<string, any[]>();
vouchers.forEach((v) => {
const tag = v.tag;
if (!groups.has(tag)) {
groups.set(tag, []);
}
groups.get(tag)!.push(v);
});
return groups;
};
// 对每组券按金额(balance)从大到小排序
const sortVouchersByAmount = (vouchers: Voucher[]) => {
return [...vouchers].sort((a, b) => getRecommendedAmount(b) - getRecommendedAmount(a));
};
*/
// 处理单张券的抵扣
var applyVoucher = function applyVoucher(voucher) {
// 检查是否可用
var availabilityCheck = isVoucherAvailable(voucher, productsForRecommendation, usedVoucherCounts, itemPassUsageMap);
if (!availabilityCheck.isAvailable) {
return false;
}
var config = voucher.config,
id = voucher.id,
product_id = voucher.product_id;
var _ref3 = config !== null && config !== void 0 ? config : {},
_ref3$maxDeductionAmo = _ref3.maxDeductionAmount,
maxDeductionAmount = _ref3$maxDeductionAmo === void 0 ? 0 : _ref3$maxDeductionAmo,
_ref3$allowCrossProdu = _ref3.allowCrossProduct,
allowCrossProduct = _ref3$allowCrossProdu === void 0 ? true : _ref3$allowCrossProdu,
_ref3$applicableProdu = _ref3.applicableProductLimit,
applicableProductLimit = _ref3$applicableProdu === void 0 ? 0 : _ref3$applicableProdu,
_ref3$deductTaxAndFee = _ref3.deductTaxAndFee,
deductTaxAndFee = _ref3$deductTaxAndFee === void 0 ? true : _ref3$deductTaxAndFee,
_ref3$maxPassesPerIte = _ref3.maxPassesPerItem,
maxPassesPerItem = _ref3$maxPassesPerIte === void 0 ? 0 : _ref3$maxPassesPerIte;
// 根据券的配置选择使用哪个单价字段和金额字段
var unitPriceField = deductTaxAndFee ? 'unitPriceWithTax' : 'unitPricePure';
var amountField = deductTaxAndFee ? 'remainingAmountWithTax' : 'remainingAmountPure';
// 获取适用商品(只筛选有剩余金额的商品)
var applicableProducts = getApplicableProducts(voucher, productsForRecommendation).filter(function (p) {
return p[amountField].greaterThan(0);
});
// 按 maxPassesPerItem 过滤:排除已达到单商品可用卡券上限的商品
applicableProducts = filterByMaxPassesPerItem(applicableProducts, itemPassUsageMap, product_id, maxPassesPerItem);
if (applicableProducts.length === 0) return false;
// ========== 关键修改:在应用券之前,基于当前剩余金额计算 _available_max_amount ==========
// 优先使用用户手动编辑的金额,否则根据 deductTaxAndFee 配置获取推荐金额
var usageAmount = typeof voucher.edit_current_amount === 'number' ? voucher.edit_current_amount : getRecommendedAmount(voucher);
var baseAmount = Decimal.min(new Decimal(usageAmount), new Decimal(maxDeductionAmount));
var calculatedAvailableMaxAmount = new Decimal(0);
if (allowCrossProduct) {
// 跨商品券:按 quantity 限制计算可抵扣金额
if (applicableProductLimit > 0) {
// 按剩余金额从高到低排序
var sortedProducts = _toConsumableArray(applicableProducts).sort(function (a, b) {
return a[amountField].comparedTo(b[amountField]) > 0 ? -1 : 1;
});
var remainingLimit = applicableProductLimit;
var _iterator2 = _createForOfIteratorHelper(sortedProducts),
_step2;
try {
for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
var product = _step2.value;
if (remainingLimit <= 0) break;
// 动态计算当前可抵扣数量 = ceil(剩余金额 / 单价)
var currentAvailableQty = Math.ceil(product[amountField].dividedBy(product[unitPriceField]).toNumber());
var deductQty = Math.min(currentAvailableQty, remainingLimit);
// 实际可抵扣金额 = min(数量 * 单价, 剩余金额)
var deductAmount = Decimal.min(product[unitPriceField].times(deductQty), product[amountField]);
calculatedAvailableMaxAmount = calculatedAvailableMaxAmount.plus(deductAmount);
remainingLimit -= deductQty;
}
} catch (err) {
_iterator2.e(err);
} finally {
_iterator2.f();
}
} else {
// 无数量限制:所有适用商品的剩余金额总和
calculatedAvailableMaxAmount = applicableProducts.reduce(function (sum, p) {
return sum.plus(p[amountField]);
}, new Decimal(0));
}
} else {
// 非跨商品券:选择单价最高的商品(优先抵扣高价商品)
var maxProduct = applicableProducts.reduce(function (max, p) {
return p[unitPriceField].greaterThan(max[unitPriceField]) ? p : max;
});
// maxPassesPerItem 限制每张券最多抵扣的单位数
if (maxPassesPerItem > 0) {
calculatedAvailableMaxAmount = Decimal.min(maxProduct[unitPriceField].times(maxPassesPerItem), maxProduct[amountField]);
} else {
calculatedAvailableMaxAmount = maxProduct[amountField];
}
}
// 取最小值:min(recommended_usage_amount, maxDeductionAmount, 适用商品金额, 订单剩余金额)
var availableMaxAmount = Decimal.min(baseAmount, calculatedAvailableMaxAmount, remainingOrderAmount);
// ======================================================================================
// 计算本次抵扣金额(使用同样的 usageAmount)
var maxDeduction = Decimal.min(new Decimal(usageAmount), new Decimal(maxDeductionAmount));
var deductionLeft = maxDeduction;
var deductionDetails = [];
if (allowCrossProduct) {
// 跨商品券:按剩余金额从高到低抵扣,受 applicableProductLimit 限制
var _sortedProducts = _toConsumableArray(applicableProducts).sort(function (a, b) {
return a[amountField].comparedTo(b[amountField]) > 0 ? -1 : 1;
});
var _remainingLimit = applicableProductLimit > 0 ? applicableProductLimit : Infinity;
var _iterator3 = _createForOfIteratorHelper(_sortedProducts),
_step3;
try {
for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
var _product = _step3.value;
if (deductionLeft.lessThanOrEqualTo(0) || _remainingLimit <= 0) break;
// 动态计算当前可抵扣数量 = ceil(剩余金额 / 单价)
var _currentAvailableQty = Math.ceil(_product[amountField].dividedBy(_product[unitPriceField]).toNumber());
var availableQty = Math.min(_currentAvailableQty, _remainingLimit);
// 计算本商品最大可抵扣金额 = min(数量 * 单价, 剩余金额)
var maxDeductForProduct = Decimal.min(_product[unitPriceField].times(availableQty), _product[amountField]);
var actualDeductAmount = Decimal.min(deductionLeft, maxDeductForProduct);
// 计算实际抵扣的数量(用于记录和配额计算)
var actualDeductQty = Math.ceil(actualDeductAmount.dividedBy(_product[unitPriceField]).toNumber());
// 只更新商品的剩余金额,不更新 remainingQuantity
_product[amountField] = _product[amountField].minus(actualDeductAmount);
deductionLeft = deductionLeft.minus(actualDeductAmount);
_remainingLimit -= actualDeductQty;
deductionDetails.push({
product_id: _product.product_id,
parent_product_id: _product.parent_product_id || null,
is_bundle_item: _product.is_bundle_item || false,
lineKey: _product._walletPassLineKey,
orderLineQuantity: getExpandedOrderLineQuantity(_product),
deductAmount: actualDeductAmount.toNumber(),
// 转换为数字
deductQuantity: actualDeductQty // 抵扣涉及的数量(用于记录)
});
}
} catch (err) {
_iterator3.e(err);
} finally {
_iterator3.f();
}
} else {
// 非跨商品券:选择单价最高的商品(优先抵扣高价商品)
var targetProduct = applicableProducts.reduce(function (max, p) {
return p[unitPriceField].greaterThan(max[unitPriceField]) ? p : max;
});
// maxPassesPerItem 限制每张券最多抵扣的单位数
var _maxDeductForProduct = targetProduct[amountField];
if (maxPassesPerItem > 0) {
_maxDeductForProduct = Decimal.min(targetProduct[unitPriceField].times(maxPassesPerItem), targetProduct[amountField]);
}
var _actualDeductAmount = Decimal.min(deductionLeft, _maxDeductForProduct);
// 计算实际抵扣的数量
var _actualDeductQty = Math.ceil(_actualDeductAmount.dividedBy(targetProduct[unitPriceField]).toNumber());
// 只更新商品的剩余金额,不更新 remainingQuantity
targetProduct[amountField] = targetProduct[amountField].minus(_actualDeductAmount);
deductionLeft = deductionLeft.minus(_actualDeductAmount);
deductionDetails.push({
product_id: targetProduct.product_id,
parent_product_id: targetProduct.parent_product_id || null,
is_bundle_item: targetProduct.is_bundle_item || false,
lineKey: targetProduct._walletPassLineKey,
orderLineQuantity: getExpandedOrderLineQuantity(targetProduct),
deductAmount: _actualDeductAmount.toNumber(),
deductQuantity: _actualDeductQty
});
}
var totalDeducted = maxDeduction.minus(deductionLeft);
if (totalDeducted.greaterThan(0)) {
// 更新订单剩余金额
remainingOrderAmount = remainingOrderAmount.minus(totalDeducted);
// 更新券使用次数(按 product_id 统计)
usedVoucherCounts.set(product_id, (usedVoucherCounts.get(product_id) || 0) + 1);
applyMaxPassUsageIncrements(itemPassUsageMap, product_id, maxPassesPerItem, deductionDetails);
// 添加到推荐列表(包含基于当前剩余金额计算的 available_max_amount)
recommendedVouchers.push(_objectSpread(_objectSpread({}, voucher), {}, {
actualDeduction: totalDeducted.toNumber(),
// 转换为数字
deductionDetails: deductionDetails,
_available_max_amount: availableMaxAmount.toNumber(),
// 转换为数字
_unified_available_status: 1
}));
return true;
}
return false;
};
/**
// 第一轮:处理未跨商品券
const nonCrossGroups = groupByType(nonCrossProductVouchers);
nonCrossGroups.forEach((vouchersInGroup) => {
const sortedVouchers = sortVouchersByAmount(vouchersInGroup);
sortedVouchers.forEach((voucher) => {
applyVoucher(voucher);
});
});
// 第二轮:处理跨商品券
const crossGroups = groupByType(crossProductVouchers);
crossGroups.forEach((vouchersInGroup) => {
const sortedVouchers = sortVouchersByAmount(vouchersInGroup);
sortedVouchers.forEach((voucher) => {
applyVoucher(voucher);
});
});
*/
// 直接按 applicableVouchers 的顺序处理所有券
applicableVouchers.forEach(function (voucher) {
applyVoucher(voucher);
});
// recommendedVouchers 已经包含了基于应用时计算的 _available_max_amount 和 _unified_available_status
// ========== 第三步:构建 all 数组,以 recommended 为基础 ==========
// 创建 recommended 券的 Map,以 id 为 key
var recommendedMap = new Map();
recommendedVouchers.forEach(function (v) {
recommendedMap.set(v.id, v);
});
// 遍历所有券,如果在 recommended 中则使用增强数据,否则使用基础数据
var allWithEnhancedData = allVouchersWithStatus.map(function (voucher) {
if (recommendedMap.has(voucher.id)) {
// 使用 recommended 中的增强数据
return recommendedMap.get(voucher.id);
} else {
// 不在 recommended 中的券,补充基础字段
return _objectSpread(_objectSpread({}, voucher), {}, {
actualDeduction: 0,
deductionDetails: []
// 保留 reasonCode(如果不可用的话)
});
}
});
return {
recommended: recommendedVouchers,
transformList: allWithEnhancedData
};
}
/**
* 重新计算优惠券状态(基于已选券的增量计算)
* @param allVouchers 所有原始券列表
* @param selectedVouchers 已选中的券列表(按选中顺序)
* @param orderTotalAmount 订单总金额
* @param products 订单商品列表
* @returns 返回更新后的所有券列表和已选券的详细抵扣信息
*/
export function recalculateVouchers(allVouchers, selectedVouchers, orderTotalAmount, products) {
// 深拷贝并拆分商品列表(包含主商品和原价子商品,同时维护含税和不含税两个金额池),用于计算
var productsForCalc = expandProductsWithBundleItems(products, true);
var remainingOrderAmount = new Decimal(orderTotalAmount);
var selectedWithDetails = [];
// 追踪每个 Wallet Pass 商品对每个订单商品行的已使用卡券次数(按行唯一键)
var itemPassUsageMap = new Map();
var getItemPassUsageRecalc = function getItemPassUsageRecalc(walletPassProductId, lineKey) {
var _itemPassUsageMap$get;
return ((_itemPassUsageMap$get = itemPassUsageMap.get(walletPassProductId)) === null || _itemPassUsageMap$get === void 0 ? void 0 : _itemPassUsageMap$get.get(lineKey)) || 0;
};
var filterByMaxPassesPerItemRecalc = function filterByMaxPassesPerItemRecalc(products, walletPassProductId, maxPassesPerItem) {
if (maxPassesPerItem <= 0) return products;
return products.filter(function (p) {
var lineKey = p._walletPassLineKey;
if (!lineKey) return true;
return getItemPassUsageRecalc(walletPassProductId, lineKey) < getMaxPassSlotsForExpandedLine(maxPassesPerItem, p);
});
};
// 第一步:按顺序应用已选中的券,计算实际抵扣
selectedVouchers.forEach(function (selectedVoucher) {
var config = selectedVoucher.config,
id = selectedVoucher.id;
var maxDeductionAmount = config.maxDeductionAmount,
allowCrossProduct = config.allowCrossProduct,
applicableProductLimit = config.applicableProductLimit,
_config$deductTaxAndF4 = config.deductTaxAndFee,
deductTaxAndFee = _config$deductTaxAndF4 === void 0 ? true : _config$deductTaxAndF4,
_config$maxPassesPerI = config.maxPassesPerItem,
maxPassesPerItem = _config$maxPassesPerI === void 0 ? 0 : _config$maxPassesPerI;
// 根据券的配置选择使用哪个单价字段和金额字段
var unitPriceField = deductTaxAndFee ? 'unitPriceWithTax' : 'unitPricePure';
var amountField = deductTaxAndFee ? 'remainingAmountWithTax' : 'remainingAmountPure';
// 获取适用商品(只筛选有剩余金额的商品)
var applicableProducts = getApplicableProducts(selectedVoucher, productsForCalc).filter(function (p) {
return p[amountField].greaterThan(0);
});
// 按 maxPassesPerItem 过滤:排除已达到该行券次上限的展开行
applicableProducts = filterByMaxPassesPerItemRecalc(applicableProducts, selectedVoucher.product_id, maxPassesPerItem);
if (applicableProducts.length === 0) {
// 无适用商品,跳过
selectedWithDetails.push(_objectSpread(_objectSpread({}, selectedVoucher), {}, {
actualDeduction: 0,
deductionDetails: [],
_available_max_amount: 0,
_unified_available_status: 0,
reasonCode: 'not_meet_the_required_conditions'
}));
return;
}
// 计算本次抵扣金额
// 优先使用用户手动编辑的金额,否则根据 deductTaxAndFee 配置获取推荐金额
var usageAmount = typeof selectedVoucher.edit_current_amount === 'number' ? selectedVoucher.edit_current_amount : getRecommendedAmount(selectedVoucher);
var maxDeduction = Decimal.min(new Decimal(usageAmount), new Decimal(maxDeductionAmount), remainingOrderAmount);
var deductionLeft = maxDeduction;
var deductionDetails = [];
if (allowCrossProduct) {
// 跨商品券:按剩余金额从高到低抵扣,受 applicableProductLimit 限制
var sortedProducts = _toConsumableArray(applicableProducts).sort(function (a, b) {
return a[amountField].comparedTo(b[amountField]) > 0 ? -1 : 1;
});
var remainingLimit = applicableProductLimit > 0 ? applicableProductLimit : Infinity;
var _iterator4 = _createForOfIteratorHelper(sortedProducts),
_step4;
try {
for (_iterator4.s(); !(_step4 = _iterator4.n()).done;) {
var product = _step4.value;
if (deductionLeft.lessThanOrEqualTo(0) || remainingLimit <= 0) break;
// 动态计算当前可抵扣数量 = ceil(剩余金额 / 单价)
var currentAvailableQty = Math.ceil(product[amountField].dividedBy(product[unitPriceField]).toNumber());
var availableQty = Math.min(currentAvailableQty, remainingLimit);
// 计算本商品最大可抵扣金额 = min(数量 * 单价, 剩余金额)
var maxDeductForProduct = Decimal.min(product[unitPriceField].times(availableQty), product[amountField]);
var actualDeductAmount = Decimal.min(deductionLeft, maxDeductForProduct);
// 计算实际抵扣的数量(用于记录和配额计算)
var actualDeductQty = Math.ceil(actualDeductAmount.dividedBy(product[unitPriceField]).toNumber());
// 只更新商品的剩余金额,不更新 remainingQuantity
product[amountField] = product[amountField].minus(actualDeductAmount);
deductionLeft = deductionLeft.minus(actualDeductAmount);
remainingLimit -= actualDeductQty;
deductionDetails.push({
product_id: product.product_id,
parent_product_id: product.parent_product_id || null,
is_bundle_item: product.is_bundle_item || false,
lineKey: product._walletPassLineKey,
orderLineQuantity: getExpandedOrderLineQuantity(product),
deductAmount: actualDeductAmount.toNumber(),
// 转换为数字
deductQuantity: actualDeductQty // 抵扣涉及的数量(用于记录)
});
}
} catch (err) {
_iterator4.e(err);
} finally {
_iterator4.f();
}
} else {
// 非跨商品券:选择单价最高的商品(优先抵扣高价商品)
var targetProduct = applicableProducts.reduce(function (max, p) {
return p[unitPriceField].greaterThan(max[unitPriceField]) ? p : max;
});
// maxPassesPerItem 限制每张券最多抵扣的单位数
var _maxDeductForProduct2 = targetProduct[amountField];
if (maxPassesPerItem > 0) {
_maxDeductForProduct2 = Decimal.min(targetProduct[unitPriceField].times(maxPassesPerItem), targetProduct[amountField]);
}
var _actualDeductAmount2 = Decimal.min(deductionLeft, _maxDeductForProduct2);
// 计算实际抵扣的数量
var _actualDeductQty2 = Math.ceil(_actualDeductAmount2.dividedBy(targetProduct[unitPriceField]).toNumber());
// 只更新商品的剩余金额,不更新 remainingQuantity
targetProduct[amountField] = targetProduct[amountField].minus(_actualDeductAmount2);
deductionLeft = deductionLeft.minus(_actualDeductAmount2);
deductionDetails.push({
product_id: targetProduct.product_id,
parent_product_id: targetProduct.parent_product_id || null,
is_bundle_item: targetProduct.is_bundle_item || false,
lineKey: targetProduct._walletPassLineKey,
orderLineQuantity: getExpandedOrderLineQuantity(targetProduct),
deductAmount: _actualDeductAmount2.toNumber(),
deductQuantity: _actualDeductQty2
});
}
var totalDeducted = maxDeduction.minus(deductionLeft);
// 更新订单剩余金额
remainingOrderAmount = remainingOrderAmount.minus(totalDeducted);
applyMaxPassUsageIncrements(itemPassUsageMap, selectedVoucher.product_id, maxPassesPerItem, deductionDetails);
selectedWithDetails.push(_objectSpread(_objectSpread({}, selectedVoucher), {}, {
actualDeduction: totalDeducted.toNumber(),
// 转换为数字
deductionDetails: deductionDetails,
_available_max_amount: totalDeducted.toNumber(),
// 转换为数字
_unified_available_status: totalDeducted.greaterThan(0) ? 1 : 0
}));
});
// 第二步:为所有券重新计算 _available_max_amount 和 _unified_available_status
var selectedIds = new Set(selectedVouchers.map(function (v) {
return v.id;
}));
var usedVoucherCounts = new Map();
selectedVouchers.forEach(function (v) {
usedVoucherCounts.set(v.product_id, (usedVoucherCounts.get(v.product_id) || 0) + 1);
});
var allWithUpdatedStatus = allVouchers.map(function (voucher) {
// 如果是已选中的券,使用详细计算结果
if (selectedIds.has(voucher.id)) {
var selectedDetail = selectedWithDetails.find(function (v) {
return v.id === voucher.id;
});
return selectedDetail || voucher;
}
// 未选中的券,重新计算其可用状态
var config = voucher.config,
id = voucher.id,
product_id = voucher.product_id;
var maxDeductionAmount = config.maxDeductionAmount,
allowCrossProduct = config.allowCrossProduct,
applicableProductLimit = config.applicableProductLimit,
_config$deductTaxAndF5 = config.deductTaxAndFee,
deductTaxAndFee = _config$deductTaxAndF5 === void 0 ? true : _config$deductTaxAndF5,
_config$maxPassesPerI2 = config.maxPassesPerItem,
maxPassesPerItem = _config$maxPassesPerI2 === void 0 ? 0 : _config$maxPassesPerI2;
// 根据券的配置选择使用哪个单价字段和金额字段
var unitPriceField = deductTaxAndFee ? 'unitPriceWithTax' : 'unitPricePure';
var amountField = deductTaxAndFee ? 'remainingAmountWithTax' : 'remainingAmountPure';
// 根据 deductTaxAndFee 配置获取推荐金额
var recommendedAmount = getRecommendedAmount(voucher);
// 检查基本可用性
var isAvailable = true;
var calculatedMaxAmount = new Decimal(0);
var reasonCode;
if (recommendedAmount <= 0) {
isAvailable = false;
reasonCode = 'not_meet_the_required_conditions';
} else if (remainingOrderAmount.lessThanOrEqualTo(0)) {
isAvailable = false;
reasonCode = 'exceeds_the_maximum_deduction_limit';
} else {
// 检查 maxUsagePerOrder(按 product_id 统计),0 表示不限制
if (config.maxUsagePerOrder > 0) {
var usedCount = usedVoucherCounts.get(product_id) || 0;
if (usedCount >= config.maxUsagePerOrder) {
isAvailable = false;
reasonCode = 'usage_limit_reached';
}
}
if (isAvailable) {
// 获取适用商品(只筛选有剩余金额的商品)
var applicableProducts = getApplicableProducts(voucher, productsForCalc).filter(function (p) {
return p[amountField].greaterThan(0);
});
// 按 maxPassesPerItem 过滤:排除已达到单商品可用卡券上限的商品
applicableProducts = filterByMaxPassesPerItemRecalc(applicableProducts, product_id, maxPassesPerItem);
if (applicableProducts.length === 0) {
isAvailable = false;
reasonCode = 'not_meet_the_required_conditions';
} else {
// 计算 _available_max_amount
var baseAmount = Decimal.min(new Decimal(recommendedAmount), new Decimal(maxDeductionAmount));
if (allowCrossProduct) {
if (applicableProductLimit > 0) {
// 按剩余金额从高到低排序,按动态计算的可抵扣数量累计直到达到 limit
var sortedProducts = _toConsumableArray(applicableProducts).sort(function (a, b) {
return a[amountField].comparedTo(b[amountField]) > 0 ? -1 : 1;
});
var remainingLimit = applicableProductLimit;
var _iterator5 = _createForOfIteratorHelper(sortedProducts),
_step5;
try {
for (_iterator5.s(); !(_step5 = _iterator5.n()).done;) {
var product = _step5.value;
if (remainingLimit <= 0) break;
// 动态计算当前可抵扣数量 = ceil(剩余金额 / 单价)
var currentAvailableQty = Math.ceil(product[amountField].dividedBy(product[unitPriceField]).toNumber());
var deductQty = Math.min(currentAvailableQty, remainingLimit);
// 实际可抵扣金额 = min(数量 * 单价, 剩余金额)
var deductAmount = Decimal.min(product[unitPriceField].times(deductQty), product[amountField]);
calculatedMaxAmount = calculatedMaxAmount.plus(deductAmount);
remainingLimit -= deductQty;
}
} catch (err) {
_iterator5.e(err);
} finally {
_iterator5.f();
}
} else {
// 无数量限制:所有适用商品的剩余金额总和
calculatedMaxAmount = applicableProducts.reduce(function (sum, p) {
return sum.plus(p[amountField]);
}, new Decimal(0));
}
} else {
// 非跨商品券:选择单价最高的商品(优先抵扣高价商品)
var maxProduct = applicableProducts.reduce(function (max, p) {
return p[unitPriceField].greaterThan(max[unitPriceField]) ? p : max;
});
// maxPassesPerItem 限制每张券最多抵扣的单位数
if (maxPassesPerItem > 0) {
calculatedMaxAmount = Decimal.min(maxProduct[unitPriceField].times(maxPassesPerItem), maxProduct[amountField]);
} else {
calculatedMaxAmount = maxProduct[amountField];
}
}
calculatedMaxAmount = Decimal.min(baseAmount, calculatedMaxAmount, remainingOrderAmount);
if (calculatedMaxAmount.lessThanOrEqualTo(0)) {
isAvailable = false;
reasonCode = 'exceeds_the_maximum_deduction_limit';
}
}
}
}
return _objectSpread(_objectSpread({}, voucher), {}, {
_available_max_amount: calculatedMaxAmount.toNumber(),
// 转换为数字
_unified_available_status: isAvailable ? 1 : 0
}, reasonCode && {
reasonCode: reasonCode
});
});
return {
allWithUpdatedStatus: allWithUpdatedStatus,
selectedWithDetails: selectedWithDetails
};
}
/**
* 获取税费和附加费的舍入余数
* @param product 商品
* @param isDeductTaxAndFee 是否抵扣税费与附加费
* @returns 舍入余数(税费 + 附加费的舍入余数)
*/
export var getTaxAndFeeRoundingRemainder = function getTaxAndFeeRoundingRemainder(product, isDeductTaxAndFee) {
var _product$metadata2;
if (!isDeductTaxAndFee) {
return 0;
}
// 税费舍入余数(如果价格包含税则为0)
var taxFeeRoundingRemainder = new Decimal(0);
if (product.is_price_include_tax !== 1) {
var _product$metadata;
taxFeeRoundingRemainder = new Decimal((product === null || product === void 0 || (_product$metadata = product.metadata) === null || _product$metadata === void 0 ? void 0 : _product$metadata.tax_fee_rounding_remainder) || 0);
}
// 附加费舍入余数
var surchargeFeeRoundingRemainder = new Decimal((product === null || product === void 0 || (_product$metadata2 = product.metadata) === null || _product$metadata2 === void 0 ? void 0 : _product$metadata2.surcharge_rounding_remainder) || 0);
return taxFeeRoundingRemainder.add(surchargeFeeRoundingRemainder).toNumber();
};
/**
* 获取主商品的商品差额
* @param product 商品
* @returns 商品差额(与数量无关,计算总价时需要减去)
*/
export var getProductDiscountDifference = function getProductDiscountDifference(product) {
var _product$metadata3;
return new Decimal((product === null || product === void 0 || (_product$metadata3 = product.metadata) === null || _product$metadata3 === void 0 ? void 0 : _product$metadata3.product_discount_difference) || 0).toNumber();
};
/**
* 获取主商品价格(单价,不含舍入余数)
* @param product 商品
* @param isDeductTaxAndFee 是否抵扣税费与附加费
* @returns 商品单价
*/
export var getMainProductPrice = function getMainProductPrice(product, isDeductTaxAndFee) {
var _product$metadata4, _product$metadata5, _product$metadata6, _product$metadata7;
var mainProductPrice = new Decimal((product === null || product === void 0 ? void 0 : product.main_product_selling_price) || ((_product$metadata4 = product.metadata) === null || _product$metadata4 === void 0 ? void 0 : _product$metadata4.main_product_selling_price) || 0);
var _iterator6 = _createForOfIteratorHelper((product === null || product === void 0 ? void 0 : product.product_bundle) || []),
_step6;
try {
for (_iterator6.s(); !(_step6 = _iterator6.n()).done;) {
var bundleItem = _step6.value;
// 子商品是加价或减价才需要计算
if (getBundleItemIsMarkupOrDiscountPrice(bundleItem)) {
var _bundleItem$bundle_se;
// 子商品价格
var bundleItemPrice = new Decimal((_bundleItem$bundle_se = bundleItem.bundle_selling_price) !== null && _bundleItem$bundle_se !== void 0 ? _bundleItem$bundle_se : 0);
mainProductPrice = mainProductPrice.add(bundleItemPrice.times(bundleItem.num));
}
}
} catch (err) {
_iterator6.e(err);
} finally {
_iterator6.f();
}
var taxFee = new Decimal((product === null || product === void 0 ? void 0 : product.tax_fee) || (product === null || product === void 0 || (_product$metadata5 = product.metadata) === null || _product$metadata5 === void 0 ? void 0 : _product$metadata5.main_product_attached_bundle_tax_fee) || 0).add((product === null || product === void 0 || (_product$metadata6 = product.metadata) === null || _product$metadata6 === void 0 ? void 0 : _product$metadata6.tax_fee_rounding_remainder) || 0);
if (product.is_price_include_tax === 1) {
taxFee = new Decimal(0);
}
// 税费
// 附加费
var surchargeFee = new Decimal((product === null || product === void 0 || (_product$metadata7 = product.metadata) === null || _product$metadata7 === void 0 ? void 0 : _product$metadata7.main_product_attached_bundle_surcharge_fee) || 0);
// 税费附加费总额
var taxAndFeeTotal = taxFee.add(surchargeFee);
// 如果需要抵扣税费与附加费,则加上税费附加费总额
if (isDeductTaxAndFee) {
mainProductPrice = mainProductPrice.add(taxAndFeeTotal);
}
return mainProductPrice.toNumber();
};
/**
* 获取套餐子商品税费和附加费的舍入余数
* @param bundleItem 套餐子商品
* @param isDeductTaxAndFee 是否抵扣税费与附加费
* @returns 舍入余数(税费 + 附加费的舍入余数)
*/
export var getBundleItemTaxAndFeeRoundingRemainder = function getBundleItemTaxAndFeeRoundingRemainder(bundleItem, isDeductTaxAndFee) {
var _bundleItem$metadata2;
if (!isDeductTaxAndFee) {
return 0;
}
// 税费舍入余数(如果价格包含税则为0)
var taxFeeRoundingRemainder = new Decimal(0);
if (bundleItem.is_price_include_tax !== 1) {
var _bundleItem$metadata;
taxFeeRoundingRemainder = new Decimal(((_bundleItem$metadata = bundleItem.metadata) === null || _bundleItem$metadata === void 0 ? void 0 : _bundleItem$metadata.tax_fee_rounding_remainder) || 0);
}
// 附加费舍入余数
var surchargeFeeRoundingRemainder = new Decimal(((_bundleItem$metadata2 = bundleItem.metadata) === null || _bundleItem$metadata2 === void 0 ? void 0 : _bundleItem$metadata2.surcharge_rounding_remainder) || 0);
return taxFeeRoundingRemainder.add(surchargeFeeRoundingRemainder).toNumber();
};
/**
* 获取套餐子商品的商品差额
* @param bundleItem 套餐子商品
* @returns 商品差额(与数量无关,计算总价时需要减去)
*/
export var getBundleItemDiscountDifference = function getBundleItemDiscountDifference(bundleItem) {
var _bundleItem$metadata3;
return new Decimal(((_bundleItem$metadata3 = bundleItem.metadata) === null || _bundleItem$metadata3 === void 0 ? void 0 : _bundleItem$metadata3.product_discount_difference) || 0).toNumber();
};
/**
* 获取套餐子商品价格(不含舍入余数)
* @param bundleItem 套餐子商品
* @param parentQuantity 父商品数量
* @param isDeductTaxAndFee 是否抵扣税费与附加费
* @returns 子商品总价格(不含舍入余数)
*/
export var getBundleItemPrice = function getBundleItemPrice(bundleItem, parentQuantity, isDeductTaxAndFee) {
var _bundleItem$bundle_se2;
// 子商品基础价格 = bundle_selling_price * num * 主商品数量
var totalQuantity = bundleItem.num * parentQuantity;
var bundleItemPrice = new Decimal((_bundleItem$bundle_se2 = bundleItem.bundle_selling_price) !== null && _bundleItem$bundle_se2 !== void 0 ? _bundleItem$bundle_se2 : 0).times(totalQuantity);
// 根据 deductTaxAndFee 配置决定是否加上税费和附加费
if (isDeductTaxAndFee) {
var _bundleItem$tax_fee, _bundleItem$metadata$, _bundleItem$metadata4;
// 税费
var taxFee = new Decimal((_bundleItem$tax_fee = bundleItem.tax_fee) !== null && _bundleItem$tax_fee !== void 0 ? _bundleItem$tax_fee : 0).times(totalQuantity);
if (bundleItem.is_price_include_tax === 1) {
taxFee = new Decimal(0);
}
// 附加费
var surchargeFee = new Decimal((_bundleItem$metadata$ = (_bundleItem$metadata4 = bundleItem.metadata) === null || _bundleItem$metadata4 === void 0 ? void 0 : _bundleItem$metadata4.surcharge_fee) !== null && _bundleItem$metadata$ !== void 0 ? _bundleItem$metadata$ : 0).times(totalQuantity);
bundleItemPrice = bundleItemPrice.add(taxFee).add(surchargeFee);
}
return bundleItemPrice.toNumber();
};
/**
* 将商品数据拆分,包含主商品和原价子商品
* @param products 原始商品列表
* @param deductTaxAndFee 是否抵扣税费与附加费(已废弃,保留参数以兼容旧代码)
* @returns 拆分后的商品数据(包含主商品和子商品,同时维护含税和不含税两个金额池,以及单价和剩余数量)
*/
var expandProductsWithBundleItems = function expandPr