feat(product): 实现产品目录单价自动计算与分配功能
新增 `calculateAndDistributeCataloguePrice` 方法,用于在添加或删除产品时, 根据业务规则自动计算并更新指定产品的目录单价。同时排除固定产品价格影响, 确保价格计算的准确性。支持多种产品编码的差异化计算逻辑,并在价格变更时重新计算单价、总价等关联字段。dev_1.0.0
parent
672ff91437
commit
92218dac59
|
|
@ -106,9 +106,12 @@
|
||||||
</style>
|
</style>
|
||||||
<!-- JS 函数引用或内联 -->
|
<!-- JS 函数引用或内联 -->
|
||||||
<script th:inline="javascript"> /*<![CDATA[*/
|
<script th:inline="javascript"> /*<![CDATA[*/
|
||||||
|
let canUpdateFlag=[[${canUpdate}]]
|
||||||
const updatePriceProductList=['8813A3YA','8813A3YB','8813A7U4','8813A7U2']
|
const updatePriceProductList=['8813A3YA','8813A3YB','8813A7U4','8813A7U2']
|
||||||
const quantityStep = ['3130A4TE']
|
const quantityStep = ['3130A4TE']
|
||||||
const FOLD_ON_FOLD = 0.988;
|
const FOLD_ON_FOLD = 0.988;
|
||||||
|
// 需要排除的固定产品常量
|
||||||
|
const EXCLUDED_PRODUCTS = ['3130A4NA', '3130A4N9', '3130A4N5', '0504A14F', '0202A1NU', '0504A14G', '0202A1NT', '0504A1JX', '0202A1NS'];
|
||||||
const productType=[{
|
const productType=[{
|
||||||
name:'softwareProjectProductInfoList',
|
name:'softwareProjectProductInfoList',
|
||||||
type:'1',
|
type:'1',
|
||||||
|
|
@ -144,6 +147,8 @@
|
||||||
$.modal.close(index);
|
$.modal.close(index);
|
||||||
$(that).parent().parent().remove();
|
$(that).parent().parent().remove();
|
||||||
updateIndices();
|
updateIndices();
|
||||||
|
// 删除产品后重新计算和分配目录单价
|
||||||
|
calculateAndDistributeCataloguePrice();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
function updateIndices() {
|
function updateIndices() {
|
||||||
|
|
@ -288,16 +293,19 @@
|
||||||
$('#productTable tbody').append(generatedTr(0,data,length))
|
$('#productTable tbody').append(generatedTr(0,data,length))
|
||||||
// initSearchProduct('1')
|
// initSearchProduct('1')
|
||||||
initPrice()
|
initPrice()
|
||||||
|
// 添加产品后重新计算和分配目录单价
|
||||||
|
calculateAndDistributeCataloguePrice()
|
||||||
}
|
}
|
||||||
|
|
||||||
function addProduct2(data) {
|
function addProduct2(data) {
|
||||||
let length = $('#productTable2 tbody').find('tr').length
|
let length = $('#productTable2 tbody').find('tr').length
|
||||||
$('#productTable2 tbody').append(generatedTr(1,data,length))
|
$('#productTable2 tbody').append(generatedTr(1,data,length))
|
||||||
initPrice()
|
initPrice()
|
||||||
|
// 添加产品后重新计算和分配目录单价
|
||||||
|
calculateAndDistributeCataloguePrice()
|
||||||
}
|
}
|
||||||
|
|
||||||
function generatedTr(index,data,length){
|
function generatedTr(index,data,length){
|
||||||
debugger
|
|
||||||
let flag=true
|
let flag=true
|
||||||
let productTypeParam=productType[index]
|
let productTypeParam=productType[index]
|
||||||
let queryParam=productTypeParam.type
|
let queryParam=productTypeParam.type
|
||||||
|
|
@ -367,6 +375,180 @@
|
||||||
$('#productTable3 tbody').append(generatedTr(2,data,length))
|
$('#productTable3 tbody').append(generatedTr(2,data,length))
|
||||||
|
|
||||||
initPrice()
|
initPrice()
|
||||||
|
// 添加产品后重新计算和分配目录单价
|
||||||
|
calculateAndDistributeCataloguePrice()
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 计算所有产品的目录总价之和并分配到updatePriceProductList产品的目录单价
|
||||||
|
*/
|
||||||
|
function calculateAndDistributeCataloguePrice() {
|
||||||
|
if (!canUpdateFlag){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// 1. 获取需要更新价格的产品行
|
||||||
|
let updatePriceRows = getUpdatePriceProductRows();
|
||||||
|
console.log(`需要更新价格产品行${updatePriceRows.length}`)
|
||||||
|
if (updatePriceRows.length === 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. 根据产品编码分配目录单价
|
||||||
|
updatePriceRows.each(function () {
|
||||||
|
let $row = $(this);
|
||||||
|
let productCode = $row.find('.productBomCode').val();
|
||||||
|
let newCataloguePrice = calculateCataloguePriceByProductCode(productCode, updatePriceRows.length);
|
||||||
|
// 更新目录单价
|
||||||
|
$row.find('.cataloguePrice').val(newCataloguePrice);
|
||||||
|
$row.find('.catalogue-price-format').val(formatAmountNumber(newCataloguePrice));
|
||||||
|
|
||||||
|
// 触发价格重新计算
|
||||||
|
recalculateRowPrices($row);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 计算排除固定产品后的目录总价之和(包括productTable和productTable2)
|
||||||
|
* @returns {number} 排除固定产品后的目录总价之和
|
||||||
|
*/
|
||||||
|
function calculateTotalCataloguePriceExcludingFixed() {
|
||||||
|
let total = 0;
|
||||||
|
// 计算软件产品表格(productTable)
|
||||||
|
$('#productTable tbody tr').each(function () {
|
||||||
|
let productCode = $(this).find('.productBomCode').val();
|
||||||
|
// 排除固定产品
|
||||||
|
if (!EXCLUDED_PRODUCTS.includes(productCode)) {
|
||||||
|
let catalogueAllPrice = parseFloat($(this).find('.catalogueAllPrice').val()) || 0;
|
||||||
|
total += catalogueAllPrice;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
// 计算终端产品表格(productTable2)
|
||||||
|
$('#productTable2 tbody tr').each(function () {
|
||||||
|
let productCode = $(this).find('.productBomCode').val();
|
||||||
|
// 排除固定产品
|
||||||
|
if (!EXCLUDED_PRODUCTS.includes(productCode)) {
|
||||||
|
let catalogueAllPrice = parseFloat($(this).find('.catalogueAllPrice').val()) || 0;
|
||||||
|
total += catalogueAllPrice;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return total;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取需要更新价格的产品行(包括productTable和productTable2)
|
||||||
|
* @returns {jQuery} 匹配的产品行集合
|
||||||
|
*/
|
||||||
|
function getUpdatePriceProductRows() {
|
||||||
|
let rows = $();
|
||||||
|
// 从软件产品表格(productTable)中获取
|
||||||
|
$('#productTable3 tbody tr').each(function () {
|
||||||
|
let productCode = $(this).find('.productBomCode').val();
|
||||||
|
if (updatePriceProductList.includes(productCode)) {
|
||||||
|
rows = rows.add($(this));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return rows;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据产品编码计算该产品的目录单价
|
||||||
|
* @param {string} productCode 产品编码
|
||||||
|
* @param {number} totalCataloguePrice 总的目录价格
|
||||||
|
* @param {number} updateProductCount 需要更新的产品数量
|
||||||
|
* @returns {number} 计算后的目录单价
|
||||||
|
*/
|
||||||
|
function calculateCataloguePriceByProductCode(productCode, updateProductCount) {
|
||||||
|
|
||||||
|
// 不同产品编码的计算规则不一样,需要根据具体业务逻辑实现
|
||||||
|
console.log(`产品编码为${productCode}`)
|
||||||
|
switch (productCode) {
|
||||||
|
case '8813A3YA':
|
||||||
|
return calculatePriceFor8813A3YA(updateProductCount);
|
||||||
|
case '8813A3YB':
|
||||||
|
return calculatePriceFor8813A3YB(updateProductCount);
|
||||||
|
case '8813A7U4':
|
||||||
|
return calculatePriceFor8813A7U4(updateProductCount);
|
||||||
|
case '8813A7U2':
|
||||||
|
return calculatePriceFor8813A7U2(updateProductCount);
|
||||||
|
|
||||||
|
default:
|
||||||
|
// 默认平均分配
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 计算产品 8813A3YA 的目录单价
|
||||||
|
* @param {number} totalCataloguePrice 总目录价格
|
||||||
|
* @param {number} updateProductCount 需要更新的产品数量
|
||||||
|
* @returns {number} 计算后的目录单价
|
||||||
|
*/
|
||||||
|
function calculatePriceFor8813A3YA(updateProductCount) {
|
||||||
|
// 计算规则:其它产品目录总价 * 5.33%,需要排除固定产品
|
||||||
|
let excludedTotalPrice = calculateTotalCataloguePriceExcludingFixed();
|
||||||
|
return (excludedTotalPrice * 0.0533).toFixed(2);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 计算产品 8813A3YB 的目录单价
|
||||||
|
* @param {number} totalCataloguePrice 总目录价格
|
||||||
|
* @param {number} updateProductCount 需要更新的产品数量
|
||||||
|
* @returns {number} 计算后的目录单价
|
||||||
|
*/
|
||||||
|
function calculatePriceFor8813A3YB(updateProductCount) {
|
||||||
|
// 计算规则:其它产品目录总价 * 5.33% * 3 * 0.8,需要排除固定产品
|
||||||
|
let excludedTotalPrice = calculateTotalCataloguePriceExcludingFixed();
|
||||||
|
return (excludedTotalPrice * 0.0533 * 3 * 0.8).toFixed(2);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 计算产品 8813A7U4 的目录单价
|
||||||
|
* @param {number} totalCataloguePrice 总目录价格
|
||||||
|
* @param {number} updateProductCount 需要更新的产品数量
|
||||||
|
* @returns {number} 计算后的目录单价
|
||||||
|
*/
|
||||||
|
function calculatePriceFor8813A7U4(updateProductCount) {
|
||||||
|
// 计算规则:目录总价 * 1.5%,需要排除固定产品
|
||||||
|
let excludedTotalPrice = calculateTotalCataloguePriceExcludingFixed();
|
||||||
|
return (excludedTotalPrice * 0.015).toFixed(2);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 计算产品 8813A7U2 的目录单价
|
||||||
|
* @param {number} totalCataloguePrice 总目录价格
|
||||||
|
* @param {number} updateProductCount 需要更新的产品数量
|
||||||
|
* @returns {number} 计算后的目录单价
|
||||||
|
*/
|
||||||
|
function calculatePriceFor8813A7U2(updateProductCount) {
|
||||||
|
// 计算规则:目录总价 * 1.5% * 3 * 0.8,需要排除固定产品
|
||||||
|
let excludedTotalPrice = calculateTotalCataloguePriceExcludingFixed();
|
||||||
|
return (excludedTotalPrice * 0.015 * 3 * 0.8).toFixed(2);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 重新计算某一行的价格相关数据
|
||||||
|
* @param {jQuery} $row 产品行的jQuery对象
|
||||||
|
*/
|
||||||
|
function recalculateRowPrices($row) {
|
||||||
|
let cataloguePrice = parseFloat($row.find('.cataloguePrice').val()) || 0;
|
||||||
|
let discount = parseFloat($row.find('.discount').val()) || 1;
|
||||||
|
let quantity = parseFloat($row.find('.quantity').val()) || 0;
|
||||||
|
|
||||||
|
// 重新计算单价
|
||||||
|
let price = (cataloguePrice * discount).toFixed(2);
|
||||||
|
$row.find('.price').val(price);
|
||||||
|
$row.find('.price-formmat').val(formatAmountNumber(price));
|
||||||
|
|
||||||
|
// 重新计算总价
|
||||||
|
let allPrice = (price * quantity).toFixed(2);
|
||||||
|
$row.find('.allPrice').val(allPrice);
|
||||||
|
$row.find('.allPrice-formmat').val(formatAmountNumber(allPrice));
|
||||||
|
|
||||||
|
// 重新计算目录总价
|
||||||
|
let catalogueAllPrice = (cataloguePrice * quantity).toFixed(2);
|
||||||
|
$row.find('.catalogueAllPrice').val(catalogueAllPrice);
|
||||||
|
$row.find('.catalogueAllPrice-formmat').val(formatAmountNumber(catalogueAllPrice));
|
||||||
}
|
}
|
||||||
function getData(that,name){
|
function getData(that,name){
|
||||||
let currentTd = $(that).closest('td'); // 获取当前 td 元素
|
let currentTd = $(that).closest('td'); // 获取当前 td 元素
|
||||||
|
|
@ -511,6 +693,37 @@
|
||||||
if (!quantityStepFlag && quantityElement.val()) {
|
if (!quantityStepFlag && quantityElement.val()) {
|
||||||
quantityElement.val(parseInt(quantityElement.val()))
|
quantityElement.val(parseInt(quantityElement.val()))
|
||||||
}
|
}
|
||||||
|
let $row = $(ele).parent().parent();
|
||||||
|
let cataloguePrice = parseFloat($row.find('.cataloguePrice').val()) || 0;
|
||||||
|
let discount = parseFloat($row.find('.discount').val()) || parseFloat($row.find('.guidanceDiscount').val()) || 1;
|
||||||
|
let quantity = parseFloat($row.find('.quantity').val()) || 0;
|
||||||
|
|
||||||
|
// Calculate unit price (单价)
|
||||||
|
let price = (cataloguePrice * discount).toFixed(2);
|
||||||
|
$row.find('.price').val(price);
|
||||||
|
$row.find('.price-formmat').val(formatAmountNumber(price));
|
||||||
|
|
||||||
|
// Calculate total price (总价) if quantity exists
|
||||||
|
if (quantity > 0) {
|
||||||
|
let allPrice = (price * quantity).toFixed(2);
|
||||||
|
$row.find('.allPrice').val(allPrice);
|
||||||
|
$row.find('.allPrice-formmat').val(formatAmountNumber(allPrice));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Calculate catalogue total price (目录总价) if quantity exists
|
||||||
|
if (quantity > 0) {
|
||||||
|
let catalogueAllPrice = (cataloguePrice * quantity).toFixed(2);
|
||||||
|
$row.find('.catalogueAllPrice').val(catalogueAllPrice);
|
||||||
|
$row.find('.catalogueAllPrice-formmat').val(formatAmountNumber(catalogueAllPrice));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update discount format display
|
||||||
|
let discountFormat = (discount * 100).toFixed(2);
|
||||||
|
$row.find('.discount').val(discount);
|
||||||
|
$row.find('.discount-format').val(discountFormat);
|
||||||
|
if (updatePriceProductList.includes(rows[0].productCode)){
|
||||||
|
calculateAndDistributeCataloguePrice()
|
||||||
|
}
|
||||||
$.modal.close(index);
|
$.modal.close(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue