/** * * 折扣率 含税金额 不含税金额 * * 含税折扣额 = -1 * (含税金额 * 折扣率) * 不含税扣额 = 含税折扣额 / (1+税率) * 折扣税额 = 含税折扣额 - 不含税扣额 */ import { v4 as uuidv4 } from 'uuid'; import { chain, bignumber } from 'mathjs'; import { InvoiceControllerState } from '../'; import LineAttributeType from '../InvoiceControllerState/GoodsListState/LineAttributeType'; import idGenerator from '../../tools/idGenerator'; import { format2 } from '../../../Invoice/tools/calculate'; export interface IOptions { /** 需要添加的 索引列表 */ indexList: string[]; /** 折扣 */ discount: number; /** 折扣 金额 */ discolineAmountunt: number; } /** * 给一组货物添加折扣行 */ export default async (state: InvoiceControllerState, options?: IOptions) => { if (!options) return; const { indexList = [] } = options; const discount = chain(bignumber(options.discount || 0)).dotDivide(bignumber(100)).done(); const goodsMap = state.goodsListState.goodsMap; const goodsList = state.goodsListState.goodsList; const discountGroup = uuidv4(); let amountSum = bignumber(0); for (let t = 0; t < indexList.length; t++) { const $index = indexList[t]; const good = goodsMap.get($index); if (!good || good.lineAttribute !== LineAttributeType.正常) continue; const i = goodsList.indexOf(good); let lineAmountIncludeTax = 0; let lineAmountExcludeTax = 0; const taxRate = chain(bignumber(good.taxRate)).dotDivide(bignumber(100)).done(); if (state.goodsListState.isTaxIncluded) { /** 金额(含税) -1 * ${good.lineAmountIncludeTax} * ${discount}*/ lineAmountIncludeTax = (() => { if (t === indexList.length - 1) { return chain(bignumber(options.discolineAmountunt)).add(amountSum).multiply(-1).done().toNumber(); } else { return chain(bignumber(-1)) .multiply(bignumber(good.lineAmountIncludeTax)) .multiply(discount) .done() .toNumber() .toFixed(2); } })() amountSum = amountSum.add(bignumber(lineAmountIncludeTax)); /** 金额(不含税) ${lineAmountIncludeTax} / (1+${good.taxRate}/100)*/ lineAmountExcludeTax = 1 * chain(bignumber(lineAmountIncludeTax)) .dotDivide(chain(bignumber(1)).add(taxRate).done()) .done() .toNumber() .toFixed(2) } else { /** 金额(不含税) -1 * ${good.lineAmountIncludeTax} * ${discount}*/ lineAmountExcludeTax = (() => { if (t === indexList.length - 1) { return chain(bignumber(options.discolineAmountunt)).add(amountSum).multiply(-1).done().toNumber(); } else { return chain(bignumber(-1)) .multiply(bignumber(good.lineAmountExcludeTax)) .multiply(discount) .done() .toNumber() .toFixed(2); } })() amountSum = amountSum.add(bignumber(lineAmountExcludeTax)); /** 金额(含税) lineAmountExcludeTax * (1+${good.taxRate}/100)*/ lineAmountIncludeTax = format2(chain(bignumber(lineAmountExcludeTax)) .multiply(chain(bignumber(1)).add(taxRate).done()) .done().toNumber()) as number } /** 税额 */ const taxAmount = chain(bignumber(lineAmountIncludeTax)) .subtract(bignumber(lineAmountExcludeTax)) .done() .toNumber(); good.discountGroup = discountGroup; good.lineAttribute = LineAttributeType.被折扣行; goodsList.splice(i + 1, 0, { $index: idGenerator(), lineAttribute: LineAttributeType.折扣行, taxClassificationCode: good.taxClassificationCode, taxRate: good.taxRate, itemName: good.itemName, shorthand: good.shorthand, itemNameSelf: good.itemNameSelf, favouredPolicyMark: good.favouredPolicyMark, favouredPolicyName: good.favouredPolicyName, taxFreeType: good.taxFreeType, discountGroup, lineAmountIncludeTax, lineAmountExcludeTax, taxAmount, }); } state.goodsListState.goodsList = goodsList.slice(); };