tachybase_todo/packages/plugins/@hera/plugin-rental/src/server/services/settlement-service.ts

1109 lines
48 KiB
TypeScript
Raw Normal View History

2024-03-07 20:55:41 +08:00
import { Db, Service } from '@nocobase/utils';
import Database from '@nocobase/database';
import dayjs from 'dayjs';
import {
AddItemsCategory,
CalcDateType,
ConversionLogics,
Itemcategory,
RulesNumber,
countCource,
} from '../../utils/constants';
import { converDate } from '../../utils/daysUtils';
import { converUnitCount } from '../../utils/unitUtils';
import { Settlement } from '../interfaces/settlement';
import { FeeRule, LeaseRule } from '../interfaces/rule';
import { Record } from '../interfaces/record';
import { recordItems } from '../interfaces/records';
import { formatQuantity } from '../../utils/currencyUtils';
@Service()
export class SettlementService {
@Db()
private db: Database;
async calculate(settlementAbout: Settlement, settlementsId) {
/**
*
* 0: 计头不计尾
* 1.
* 2.
* 3.
*/
let createLeasDatas = [];
let createFeesDatas = [];
settlementAbout.contracts.rule_items?.forEach((ruleItem) => {
if (
dayjs(settlementAbout.start_date).isSameOrAfter(ruleItem.start_date, 'day') &&
dayjs(settlementAbout.end_date).isSameOrBefore(ruleItem.end_date, 'day')
) {
// lease_rules 租金规则[]
const lease_rules = ruleItem?.rule.lease_items;
// fee_rules 费用明细
const fee_rules = ruleItem?.rule.fee_item;
// 处理原始数据,适合后续租金数据成
if (settlementAbout.records === null) {
settlementAbout.records = [];
}
// 正常租赁数据
lease_rules?.forEach((rule) => {
if (rule) {
if (rule.products.length) {
rule.products.forEach((productRule) => {
const productCategory = productRule.product_id > RulesNumber ? 'category' : 'product';
settlementAbout.records.forEach((item) => {
//计算正常租赁订单
if (rule.conversion_logic_id === ConversionLogics.ActualWeight) {
if (item.weight_items.length) {
item.weight_items?.forEach((recordItem) => {
if (recordItem) {
if (
productRule.product_id > RulesNumber &&
productRule.product_id - RulesNumber === recordItem.product_category_id
) {
const productName = item.record_items.filter(
(value) => value.product.product_category.id === recordItem.product_category_id,
)[0].product;
const day =
dayjsDays(item.date) < dayjsDays(settlementAbout.start_date)
? getCalcDays(settlementAbout.start_date, settlementAbout.end_date)
: afterDays(
settlementAbout.contracts.calc_type,
item.movement,
item.date,
settlementAbout.end_date,
);
const movement = item.movement === '-1' ? '1' : '-1';
createLeasDatas.push({
settlement_id: settlementsId, //合同ID
movement: item.movement, //出入库状态
date: item.date, //时间
name: productName.name, //名称
label: productName.label, //规格
category: item.category, //费用类别
//租赁天数 历史订单就存开始日期到结束日期 当前订单存储订单日期到结束日期
days: day,
is_excluded: false,
count: recordItem.weight * Number(movement),
unit_price: rule.unit_price * 1000,
amount: recordItem.weight * (rule.unit_price * 1000) * day,
unit_name: '吨',
productCategory,
});
}
}
});
} else {
if (
(productRule.product_id > RulesNumber &&
productRule.product_id - RulesNumber === item.record_items[0]?.product.category_id) ||
productRule.product_id === item.record_items[0]?.product.id
) {
const day =
dayjsDays(item.date) < dayjsDays(settlementAbout.start_date)
? getCalcDays(settlementAbout.start_date, settlementAbout.end_date)
: afterDays(
settlementAbout.contracts.calc_type,
item.movement,
item.date,
settlementAbout.end_date,
);
const movement = item.movement === '-1' ? '1' : '-1';
createLeasDatas.push({
settlement_id: settlementsId, //合同ID
movement: item.movement, //出入库状态
date: item.date, //时间
name: item.record_items[0]?.product.name, //名称
label: item.record_items[0]?.product.label, //规格
category: item.category, //费用类别
//租赁天数 历史订单就存开始日期到结束日期 当前订单存储订单日期到结束日期
days: day,
is_excluded: false,
count: item.weight * Number(movement),
unit_price: rule.unit_price * 1000,
amount: item.weight * (rule.unit_price * 1000) * day,
unit_name: '吨',
productCategory,
});
}
}
} else {
item.record_items?.forEach((recordItem) => {
if (recordItem) {
if (
(productRule.product_id > RulesNumber &&
productRule.product_id - RulesNumber === recordItem.product.category_id) ||
productRule.product_id === recordItem.product.id
) {
const data = {
settlement_id: settlementsId, //合同ID
movement: item.movement, //出入库状态
date: item.date, //时间
name: recordItem.product.name, //名称
label: recordItem.product.label, //规格
category: item.category, //费用类别
//租赁天数 历史订单就存开始日期到结束日期 当前订单存储订单日期到结束日期
days:
dayjsDays(item.date) < dayjsDays(settlementAbout.start_date)
? getCalcDays(settlementAbout.start_date, settlementAbout.end_date)
: afterDays(
settlementAbout.contracts.calc_type,
item.movement,
item.date,
settlementAbout.end_date,
),
is_excluded: false,
productCategory,
};
// 要根据规则计算数量,单价,金额,确定单位
const price = rule.unit_price || 0;
const movement = item.movement === '-1' ? '1' : '-1';
const { count, unit } = ruleCount(rule, item, recordItem);
data['unit_name'] = unit;
data['count'] = count * Number(movement);
data['unit_price'] = price;
data['amount'] = data['count'] * price * (data.days || 0);
createLeasDatas.push(data);
}
}
});
}
//计算有关联产品费用订单
if (rule.product_fee.length) {
if (
dayjs(item.date).isBetween(ruleItem.start_date, ruleItem.end_date, 'day', '[]') &&
dayjs(item.date).isSameOrAfter(settlementAbout.start_date)
) {
rule.product_fee.forEach((rulefee) => {
if (rulefee.fee_product_id) {
const spec = rulefee.product.spec;
const name = rulefee.product.name;
if (rulefee.conversion_logic_id === ConversionLogics.ActualWeight) {
let data;
if (
rulefee.count_source === countCource.outProduct ||
rulefee.count_source === countCource.outItem
) {
if (item.movement === '-1') {
data = recordWeight(rule, item, settlementsId, productRule, rulefee);
if (data) {
data.movement = '-1';
}
}
} else if (
rulefee.count_source === countCource.enterProduct ||
rulefee.count_source === countCource.enterItem
) {
if (item.movement === '1') {
data = recordWeight(rule, item, settlementsId, productRule, rulefee);
if (data) {
data.movement = '1';
}
}
} else {
data = recordWeight(rule, item, settlementsId, productRule, rulefee);
if (data) {
data.movement = '0';
}
}
if (data) {
createFeesDatas.push({ ...data, productCategory });
}
} else {
item.record_items?.forEach((recordItem) => {
if (recordItem) {
if (
productRule.product_id - RulesNumber === recordItem.product.category_id ||
recordItem.product_id === productRule.product_id
) {
let productname;
switch (productCategory) {
case 'category':
productname = recordItem.product.name;
break;
case 'product':
productname = recordItem.product.label;
break;
}
//人工录入
if (rulefee.count_source === countCource.artificial) {
if (rulefee.conversion_logic_id !== ConversionLogics.ActualWeight) {
if (recordItem.record_item_fee_items.length) {
recordItem.record_item_fee_items.forEach((value) => {
if (value.product_id === rulefee.fee_product_id) {
const { count, unit } = ruleCount(
rule,
item,
recordItem,
value.count,
rulefee,
);
createFeesDatas.push({
settlement_id: settlementsId,
date: item.date,
name: productname + '-' + spec,
label: recordItem.product.label + '-' + spec,
category: name,
movement: item.movement,
count: count,
unit_price: rulefee.unit_price,
amount: rulefee.unit_price * count,
unit_name: unit,
is_excluded: value.is_excluded,
productCategory,
});
}
});
}
}
} //出库
else if (
rulefee.count_source === countCource.outProduct ||
rulefee.count_source === countCource.outItem
) {
if (item.movement === '-1') {
const { count, unit } = ruleCount(rule, item, recordItem, '', rulefee);
const recordCount = recordItemsFee(rule, item, recordItem, count, rulefee);
createFeesDatas.push({
settlement_id: settlementsId,
date: item.date,
name: productname + '-' + spec,
label: recordItem.product.label + '-' + spec,
category: name,
movement: '-1',
count: recordCount,
unit_price: rulefee.unit_price,
amount: count * rulefee.unit_price,
unit_name: unit,
is_excluded: false,
productCategory,
});
}
} //入库
else if (
rulefee.count_source === countCource.enterProduct ||
rulefee.count_source === countCource.enterItem
) {
if (item.movement === '1') {
const { count, unit } = ruleCount(rule, item, recordItem, '', rulefee);
const recordCount = recordItemsFee(rule, item, recordItem, count, rulefee);
createFeesDatas.push({
settlement_id: settlementsId,
date: item.date,
name: productname + '-' + spec,
label: recordItem.product.label + '-' + spec,
category: name,
movement: '1',
count: recordCount,
unit_price: rulefee.unit_price,
amount: count * rulefee.unit_price,
unit_name: unit,
is_excluded: false,
productCategory,
});
}
} //出入库
else if (
rulefee.count_source === countCource.product ||
rulefee.count_source === countCource.item
) {
const { count, unit } = ruleCount(rule, item, recordItem, '', rulefee);
const recordCount = recordItemsFee(rule, item, recordItem, count, rulefee);
createFeesDatas.push({
settlement_id: settlementsId,
date: item.date,
name: productname + '-' + spec,
label: recordItem.product.label + '-' + spec,
category: name,
movement: '0',
count: recordCount,
unit_price: rule.unit_price,
amount: count * rule.unit_price,
unit_name: unit,
is_excluded: false,
productCategory,
});
}
}
}
});
}
}
});
}
}
});
});
}
}
});
// 产品产生的费用
fee_rules?.forEach((rule) => {
let conversion = false;
const spec = rule.product.spec;
const name = rule.product.name;
const data = {
settlement_id: settlementsId,
date: dayjs(settlementAbout.end_date).add(1, 'day').add(-1, 'minute'),
name: spec,
label: spec,
category: name,
movement: '0',
count: 0,
unit_price: rule.unit_price,
amount: 0,
unit_name: rule.unit,
is_excluded: false,
};
if (rule.conversion_logic_id === ConversionLogics.ActualWeight) {
settlementAbout.records.forEach((item) => {
if (
dayjs(item.date).isBetween(ruleItem.start_date, ruleItem.end_date, 'day', '[]') &&
dayjs(item.date).isSameOrAfter(settlementAbout.start_date)
) {
if (rule.count_source === countCource.outProduct || rule.count_source === countCource.outItem) {
if (item.movement === '-1') {
data.movement = '-1';
data.count += item.weight_items.length
? item.weight_items.length
? item.weight_items.reduce((sum, curr) => {
return sum + curr.weight;
}, 0)
: 0
: item.weight;
if (item.fee_item.length) {
item.fee_item.forEach((value) => {
if (value.product_id === rule.fee_product_id) {
data.count = value.is_excluded ? data.count - value.count : data.count;
}
});
}
conversion = true;
}
} else if (
rule.count_source === countCource.enterProduct ||
rule.count_source === countCource.enterItem
) {
if (item.movement === '1') {
data.movement = '1';
data.count += item.weight_items.length
? item.weight_items.length
? item.weight_items.reduce((sum, curr) => {
return sum + curr.weight;
}, 0)
: 0
: item.weight;
if (item.fee_item.length) {
item.fee_item.forEach((value) => {
if (value.product_id === rule.fee_product_id) {
data.count = value.is_excluded ? data.count - value.count : data.count;
}
});
}
conversion = true;
}
} else if (rule.count_source === countCource.product || rule.count_source === countCource.item) {
data.count += item.weight_items.length
? item.weight_items.length
? item.weight_items.reduce((sum, curr) => {
return sum + curr.weight;
}, 0)
: 0
: item.weight;
if (item.fee_item.length) {
item.fee_item.forEach((value) => {
if (value.product_id === rule.fee_product_id) {
data.count = value.is_excluded ? data.count - value.count : data.count;
}
});
}
conversion = true;
}
}
});
} else {
//人工录入
if (rule.count_source === countCource.artificial) {
if (
rule.conversion_logic_id !== ConversionLogics.Product &&
rule.conversion_logic_id !== ConversionLogics.ActualWeight &&
rule.conversion_logic_id !== ConversionLogics.ProductWeight
) {
settlementAbout.records?.forEach((item) => {
if (
dayjs(item.date).isBetween(ruleItem.start_date, ruleItem.end_date, 'day', '[]') &&
dayjs(item.date).isSameOrAfter(settlementAbout.start_date)
) {
if (item.fee_item.length) {
item.fee_item.forEach((value) => {
if (value.product_id === rule.fee_product_id) {
data.count = value.is_excluded ? data.count - value.count : data.count + value.count;
data.is_excluded = value.is_excluded;
conversion = true;
}
});
}
}
});
}
} //出库
else if (rule.count_source === countCource.outProduct || rule.count_source === countCource.outItem) {
if (
rule.conversion_logic_id !== ConversionLogics.Keep &&
rule.conversion_logic_id !== ConversionLogics.Product
) {
settlementAbout.records?.forEach((item) => {
if (
dayjs(item.date).isBetween(ruleItem.start_date, ruleItem.end_date, 'day', '[]') &&
dayjs(item.date).isSameOrAfter(settlementAbout.start_date)
) {
if (item.movement === '-1') {
item.record_items?.forEach((recordItem) => {
if (recordItem) {
const { count } = ruleCount(rule, item, recordItem);
data.count += count;
data.movement = '-1';
conversion = true;
}
});
if (item.fee_item.length) {
item.fee_item.forEach((value) => {
if (value.product_id === rule.fee_product_id) {
data.count = value.is_excluded ? data.count - value.count * 1000 : data.count;
}
});
}
}
}
});
}
} //入库
else if (rule.count_source === countCource.enterProduct || rule.count_source === countCource.enterItem) {
if (
rule.conversion_logic_id !== ConversionLogics.Keep &&
rule.conversion_logic_id !== ConversionLogics.Product
) {
settlementAbout.records?.forEach((item) => {
if (
dayjs(item.date).isBetween(ruleItem.start_date, ruleItem.end_date, 'day', '[]') &&
dayjs(item.date).isSameOrAfter(settlementAbout.start_date)
) {
if (item.movement === '1') {
item.record_items?.forEach((recordItem) => {
if (recordItem) {
const { count } = ruleCount(rule, item, recordItem);
data.count += count;
data.movement = '1';
conversion = true;
}
});
if (item.fee_item.length) {
item.fee_item.forEach((value) => {
if (value.product_id === rule.fee_product_id) {
data.count = value.is_excluded ? data.count - value.count * 1000 : data.count;
}
});
}
}
}
});
}
} //出入库
else if (rule.count_source === countCource.product || rule.count_source === countCource.item) {
if (
rule.conversion_logic_id !== ConversionLogics.Keep &&
rule.conversion_logic_id !== ConversionLogics.Product
) {
settlementAbout.records?.forEach((item) => {
if (
dayjs(item.date).isBetween(ruleItem.start_date, ruleItem.end_date, 'day', '[]') &&
dayjs(item.date).isSameOrAfter(settlementAbout.start_date)
) {
item.record_items?.forEach((recordItem) => {
if (recordItem) {
const { count } = ruleCount(rule, item, recordItem);
data.count += count;
data.movement = '0';
conversion = true;
}
});
if (item.fee_item.length) {
item.fee_item.forEach((value) => {
if (value.product_id === rule.fee_product_id) {
data.count = value.is_excluded ? data.count - value.count * 1000 : data.count;
}
});
}
}
});
}
}
}
if (conversion) {
if (
rule.count_source !== countCource.artificial &&
rule.conversion_logic_id !== ConversionLogics.ActualWeight
) {
data.count = data.count / 1000;
}
data.amount = data.count * data.unit_price;
createFeesDatas.push(data);
}
});
}
});
createFeesDatas = createFeesDatas?.filter(Boolean);
createLeasDatas = createLeasDatas?.filter(Boolean);
const createCategoryDatasItem = screenData(createLeasDatas, settlementAbout, 'category');
const createProductDatasItem = screenData(createLeasDatas, settlementAbout, 'product');
const recordsCategoryFeeItem = feeData(createFeesDatas, settlementAbout, 'category');
const recordsProductFeeItem = feeData(createFeesDatas, settlementAbout, 'product');
//本期信息
let createDatas = [
...createCategoryDatasItem.list,
...createProductDatasItem.list,
...recordsCategoryFeeItem,
...recordsProductFeeItem,
];
createDatas.sort((a, b) => {
return new Date(a.date).getTime() - new Date(b.date).getTime();
});
createDatas = createDatas.filter((value) => value.count);
//筛选历史结存
createCategoryDatasItem.history = createCategoryDatasItem.history?.filter((value) => value.count);
createProductDatasItem.history = createProductDatasItem.history?.filter((value) => value.count);
//汇总项信息
const summaryCategoryItems = [];
for (const value in createCategoryDatasItem) {
createCategoryDatasItem[value].forEach((item) => {
if (!summaryCategoryItems.find((value) => value.name === item.name && item.category === '0')) {
summaryCategoryItems.push({
settlement_id: settlementsId,
name: item.name,
count: item.count,
unit_name: item.unit_name,
type: 'category',
});
} else {
summaryCategoryItems.forEach((value) => {
if (value.name === item.name) {
value.count += item.count;
}
});
}
});
}
const summaryProductItems = [];
for (const value in createProductDatasItem) {
createProductDatasItem[value].forEach((item) => {
if (!summaryProductItems.find((value) => value.name === item.name && item.category === '0')) {
summaryProductItems.push({
settlement_id: settlementsId,
name: item.name,
count: item.count,
unit_name: item.unit_name,
type: 'product',
});
} else {
summaryProductItems.forEach((value) => {
if (value.name === item.name) {
value.count += item.count;
}
});
}
});
}
const summaryItems = [...summaryCategoryItems, ...summaryProductItems];
//结算表信息
const summaryPeriod = {
rent: 0.0, //租金
maintenance: 0.0, //维修人工
n_compensate: 0.0, //无物赔偿
h_compensate: 0.0, //有物赔偿
loadfreight: 0.0, //装卸运费
current_expenses: 0.0, //本期费用
tax: 0.0, //税率
accumulate: 0.0, //累计费用
current_collection: 0.0, //本期收款
accumulate_collection: 0.0, //累计收款
status: '2',
};
// 结算表费用
recordsCategoryFeeItem.forEach((value) => {
switch (value.category) {
case Itemcategory.maintenance:
summaryPeriod.maintenance += value.amount;
break;
case Itemcategory.n_compensate:
summaryPeriod.n_compensate += value.amount;
break;
case Itemcategory.h_compensate:
summaryPeriod.h_compensate += value.amount;
break;
case Itemcategory.loadFreight:
summaryPeriod.loadfreight += value.amount;
break;
}
});
settlementAbout.settlement_add_items.forEach((value) => {
switch (value.category) {
case AddItemsCategory.rent:
summaryPeriod.rent += value.amount;
break;
case AddItemsCategory.maintenance:
summaryPeriod.maintenance += value.amount;
break;
case AddItemsCategory.n_compensate:
summaryPeriod.n_compensate += value.amount;
break;
case AddItemsCategory.h_compensate:
summaryPeriod.h_compensate += value.amount;
break;
case AddItemsCategory.loadFreight:
summaryPeriod.loadfreight += value.amount;
break;
}
});
summaryPeriod.rent = createCategoryDatasItem.list.reduce((sum, curr) => sum + curr.amount, summaryPeriod.rent);
summaryPeriod.rent = createCategoryDatasItem.history.reduce((sum, curr) => sum + curr.amount, summaryPeriod.rent);
summaryPeriod.tax = settlementAbout.contracts.tax_included ? 0 : settlementAbout.contracts.tax_rate;
summaryPeriod.current_expenses =
(summaryPeriod.rent +
summaryPeriod.maintenance +
summaryPeriod.n_compensate +
summaryPeriod.h_compensate +
summaryPeriod.loadfreight) *
(summaryPeriod.tax + 1);
const settlement = settlementAbout.settlements?.filter((value) =>
dayjs(value.end_date).isBefore(settlementAbout.start_date),
);
summaryPeriod.accumulate = settlement.length
? settlement.reduce((sum, curr) => sum + curr.current_expenses, summaryPeriod.current_expenses)
: summaryPeriod.current_expenses;
await this.db.sequelize.query(`delete from settlement_items where settlement_id=${settlementsId}`);
await this.db.sequelize.query(`delete from settlement_history_items where settlement_id=${settlementsId}`);
await this.db.sequelize.query(`delete from settlement_summary_items where settlement_id=${settlementsId}`);
//修改结算表数据
await this.db.getRepository('settlements').update({
values: summaryPeriod,
filter: {
id: settlementsId,
},
});
await this.db.getModel('settlement_items').bulkCreate(createDatas);
await this.db.getModel('settlement_history_items').bulkCreate(createCategoryDatasItem.history);
await this.db.getModel('settlement_history_items').bulkCreate(createProductDatasItem.history);
await this.db.getModel('settlement_summary_items').bulkCreate(summaryItems);
}
async settlement(settlementAbout: Settlement, utcOffset) {
const calc = {
start: settlementAbout.start_date, //开始时间
end: settlementAbout.end_date, //结束时间
rent: settlementAbout.rent,
maintenance: settlementAbout.maintenance, //维修人工
n_compensate: settlementAbout.n_compensate, //无物赔偿
h_compensate: settlementAbout.h_compensate, //有物赔偿
loadfreight: settlementAbout.loadfreight, //装卸运费
current_expenses: settlementAbout.current_expenses, //本期费用
tax: settlementAbout.tax, //税率
accumulate: settlementAbout.accumulate, //累计费用
current_collection: settlementAbout.current_collection, //本期收款
accumulate_collection: settlementAbout.accumulate_collection, //累计收款
history: settlementAbout.settlement_history_items, //历史订单
list: settlementAbout.settlement_items, //当前订单
addItems: settlementAbout.settlement_add_items, //人工增补项
summary: settlementAbout.settlement_summary_items, //汇总项
utcOffset: utcOffset,
};
calc.list = calc.list?.filter(Boolean);
const product = await this.db.getRepository('product').find();
calc.list.forEach((value) => {
const filterValue = product.filter((productValue) => {
const productName = value.category !== '0' ? (value.name as string).split('-')[0] : value.name;
return (
productName && (productValue.dataValues.name === productName || productValue.dataValues.label === productName)
);
});
value['productSort'] = filterValue.length ? filterValue[0].dataValues.sort : -1;
});
calc.list?.sort((a, b) => {
return new Date(a.date).getTime() - new Date(b.date).getTime();
});
let sortProduct = [];
let settlementDate = '';
calc.list.forEach((value) => {
const productDate = converDate(value.date, 'YYYY-MM-DD');
if (value.category === '0' || value.name.includes('-')) {
if (productDate === settlementDate) {
sortProduct.sort((a, b) => {
return a.productSort - b.productSort;
});
sortProduct.forEach((item, index) => {
item.date = dayjs(`${productDate} 00:${index}:00`);
});
value.date = dayjs(sortProduct[sortProduct.length - 1].date).add(1, 'minutes');
sortProduct.push(value);
} else {
settlementDate = productDate;
sortProduct = [];
sortProduct.push(value);
}
}
});
calc.list.forEach((value) => {
const productDate = converDate(value.date, 'YYYY-MM-DD');
if ((value.name as string).includes('-')) {
const name = value.name.split('-')[0];
const valueItem = calc.list.filter(
(item) => converDate(item.date, 'YYYY-MM-DD') === productDate && item.name === name,
)[0];
value.date = dayjs(valueItem.date).add(1, 'seconds');
}
});
calc.list?.sort((a, b) => {
return new Date(a.date).getTime() - new Date(b.date).getTime();
});
const contracts = settlementAbout.contracts;
return { calc, contracts };
}
}
/**
*
* @param rule
* @param item
* @param settlementsId
*/
const recordWeight = (rule, item, settlementsId, productRule, rulefee?) => {
const productCategory = productRule.product_id > RulesNumber ? 'category' : 'product';
const spec = rulefee.product.spec;
const name = rulefee.product.name;
if (item.weight_items.length) {
const itemWeight = item.weight_items.filter(
(weightItem) =>
(productRule.product_id > RulesNumber &&
productRule.product_id - RulesNumber === weightItem.product_category_id) ||
productRule.product_id === weightItem.product_category_id,
)[0];
const productsName = item.record_items?.filter(
(value) => value.product.category_id === itemWeight.product_category_id,
)[0].product;
const productName = productCategory === 'category' ? productsName.name : productsName.label;
return {
settlement_id: settlementsId,
date: item.date,
name: productName + '-' + spec,
label: productsName.label + '-' + spec,
category: rulefee ? name : rule.product.name,
movement: item.movement,
count: itemWeight.weight,
unit_price: rulefee.unit_price,
amount: itemWeight.weight * rulefee.unit_price,
unit_name: '吨',
is_excluded: false,
};
} else {
if (
(productRule.product_id > RulesNumber &&
productRule.product_id - RulesNumber === item.record_items[0]?.product.category_id) ||
productRule.product_id === item.record_items[0]?.product.category_id
) {
let count = item.weight;
item.record_items.forEach((recordItem) => {
if (recordItem.record_item_fee_items.length) {
const recordItemFee = recordItem.record_item_fee_items.filter(
(value) => value.product_id === rulefee.fee_product_id,
)[0];
count = recordItemFee.is_excluded ? count - recordItemFee.count : count;
}
});
const productsName = item.record_items[0].product;
const productName = productCategory === 'category' ? productsName.name : productsName.label;
return {
settlement_id: settlementsId,
date: item.date,
name: productName + '-' + spec,
label: productsName.label + '-' + spec,
category: name,
movement: item.movement,
count: count,
unit_price: rulefee.unit_price,
amount: item.weight * rulefee.unit_price,
unit_name: '吨',
is_excluded: false,
};
}
}
};
/**
*
* @param rules
* @param item
* @param itemCount
* @returns count,unit
*/
const ruleCount = (rules: FeeRule | LeaseRule, item: Record, recordItem: recordItems, valueCount?, rulefee?) => {
let count, unit;
const itemCount = valueCount ? valueCount : recordItem.count;
const conversion_logic_id = rulefee ? rulefee.conversion_logic_id : rules.conversion_logic_id;
if (conversion_logic_id === ConversionLogics.Product) {
// 换算:2
// 查产品分类,看产品分类是否需要换算
count = recordItem.product.product_category.convertible ? itemCount * recordItem.product.ratio : itemCount;
unit = recordItem.product.product_category.convertible
? recordItem.product.product_category.conversion_unit
: recordItem.product.product_category.unit;
} else if (conversion_logic_id === ConversionLogics.Keep) {
// 不换算:1
count = itemCount;
unit = recordItem.product.product_category.unit;
} else if (conversion_logic_id === ConversionLogics.ProductWeight) {
// 换算4 按照产品表重量
count = itemCount * recordItem.product.weight;
unit = recordItem.product.product_category.unit;
} else {
const rule = rules?.ucl?.weight_items.filter(
(value) =>
value.product_id === recordItem.product_id || value.product_id - RulesNumber === recordItem.product.category_id,
)[0];
// 按重量换算
if (rule && rule.conversion_logic_id === ConversionLogics.Keep) {
// 不换算
count = itemCount * rule.weight;
} else if (rule && rule.conversion_logic_id === ConversionLogics.Product) {
// 换算
count = recordItem.product.product_category.convertible
? itemCount * recordItem.product.ratio * rule.weight
: itemCount;
} else {
count = 0;
}
unit = recordItem.product.product_category.convertible
? recordItem.product.product_category.conversion_unit
: recordItem.product.product_category.unit;
}
unit = rulefee ? rulefee.unit : unit;
const { converCount, converUnit } = converUnitCount(count, unit);
count = converCount;
unit = converUnit;
return { count, unit };
};
/**
*
* @param { calc_type, movement, date }
* 2
* 3
* 0
*
* 1
* @returns days
*/
const getCalcDays = (start_date, end_date) => {
// 正常计算date到目前天数
const endDate = dayjs(end_date).startOf('day');
const startDate = dayjs(start_date).startOf('day');
const daysDiff = endDate.diff(startDate, 'day') + 1;
return daysDiff;
};
// 返回天数
const dayjsDays = (date) => {
return dayjs(date).startOf('day');
};
// 结存时间
/**
*
* @param { calc_type, movement, date }
* 2
* 3
* 0
*
* 1
* @returns days
*/
const afterDays = (calc_type, movement, start, end) => {
const l = dayjs(end).startOf('day');
const r = dayjs(start).startOf('day');
let ofterDays = l.diff(r, 'day');
switch (calc_type) {
case CalcDateType.countHeads:
ofterDays += 1;
break;
case CalcDateType.countTails:
break;
case CalcDateType.countHT:
if (movement === '-1') {
ofterDays += 1;
}
break;
case CalcDateType.withoutHT:
if (movement === '1') {
ofterDays += 1;
}
break;
}
return ofterDays;
};
const feeData = (data, settlementAbout: Settlement, type) => {
const feeItem = {};
const fee = [];
if (data.length) {
data.forEach((value) => {
let name = value.name;
if (value.productCategory === 'category') {
name = value.name;
} else if (value.productCategory === 'product') {
name = value.label;
}
let listKey = `${value.name}_${value.movement}_${converDate(value.date, 'YYYY-MM-DD')}`;
switch (type) {
case 'category':
listKey = `${value.name}_${value.movement}_${converDate(value.date, 'YYYY-MM-DD')}`;
break;
case 'product':
listKey = `${value.label}_${value.movement}_${converDate(value.date, 'YYYY-MM-DD')}`;
name = value.label;
}
if (!feeItem[listKey]) {
feeItem[listKey] = {
settlement_id: value.settlement_id,
movement: value.movement,
date: value.date,
amount: value.amount,
category: value.category,
count: value.count,
days: 0,
name: name,
unit_name: value.unit_name,
unit_price: value.unit_price,
is_excluded: value.is_excluded,
type: type,
};
} else {
feeItem[listKey].count = feeItem[listKey].count + value.count;
feeItem[listKey].amount = feeItem[listKey].amount + value.amount;
feeItem[listKey].unit_price = isNaN(feeItem[listKey].amount / feeItem[listKey].count)
? 0
: feeItem[listKey].amount / feeItem[listKey].count;
}
});
}
fee.push(...Object.values(feeItem));
return fee;
};
const recordItemsFee = (rule, item, recordItem, count, rulefee) => {
let recordCount = count;
if (recordItem.record_item_fee_items.length) {
const recordItemFee = recordItem.record_item_fee_items.filter(
(value) => value.product_id === rulefee.fee_product_id,
)[0];
if (recordItemFee) {
const { count, unit } = ruleCount(rule, item, recordItem, recordItemFee.count, rulefee);
recordCount = recordItemFee.is_excluded ? recordCount - count : recordCount;
}
}
return recordCount;
};
const formatNumber = (count) => {
const c = formatQuantity(count, 5);
return parseFloat(c.replace(/,/g, ''));
};
/**
*
* @param data
* @param settlementAbout
* @returns screenDatas
*/
const screenData = (data, settlementAbout, type) => {
const history = {};
const list = {};
const screenDatas = {
history: [],
list: [],
};
data.forEach((value) => {
let name = value.name;
if (value.productCategory === 'category') {
name = value.name;
} else if (value.productCategory === 'product') {
name = value.label;
}
let listKey = `${name}_${value.movement}_${converDate(value.date, 'YYYY-MM-DD')}`;
let historyKey = `${name}`;
switch (type) {
case 'category':
listKey = `${name}_${value.movement}_${converDate(value.date, 'YYYY-MM-DD')}`;
historyKey = `${name}`;
break;
case 'product':
listKey = `${value.label}_${value.movement}_${converDate(value.date, 'YYYY-MM-DD')}`;
historyKey = `${value.label}`;
name = value.label;
break;
}
if (dayjs(value.date).isBefore(settlementAbout.start_date)) {
if (!history[historyKey]) {
history[historyKey] = {
settlement_id: value.settlement_id,
amount: value.amount,
category: value.category,
count: value.count,
days: getCalcDays(settlementAbout.start_date, settlementAbout.end_date),
name: name,
unit_name: value.unit_name,
unit_price: value.unit_price,
is_excluded: value.is_excluded,
type: type,
};
} else {
history[historyKey].count = formatNumber(history[historyKey].count) + formatNumber(value.count);
history[historyKey].amount = formatNumber(history[historyKey].amount) + formatNumber(value.amount);
history[historyKey].unit_price =
history[historyKey].amount / history[historyKey].count / history[historyKey].days;
}
} else {
if (!list[listKey]) {
list[listKey] = {
settlement_id: value.settlement_id,
movement: value.movement,
date: value.date,
amount: value.amount,
category: value.category,
count: value.count,
days: value.days,
name: name,
unit_name: value.unit_name,
unit_price: value.unit_price,
is_excluded: value.is_excluded,
type: type,
};
} else {
list[listKey].count = formatNumber(list[listKey].count) + formatNumber(value.count);
list[listKey].amount = formatNumber(list[listKey].amount) + formatNumber(value.amount);
list[listKey].unit_price = isNaN(list[listKey].amount / list[listKey].count / list[listKey].days)
? 0
: list[listKey].amount / list[listKey].count / list[listKey].days;
}
}
});
screenDatas['history'].push(...Object.values(history));
screenDatas['list'].push(...Object.values(list));
return screenDatas;
};