Commit a06fbfa5 by 孙亚楠

dd

parent 1a95fd25
{
"lockfileVersion": 1
}
var APIBase = require("../../api.base"); var APIBase = require("../../api.base");
var system = require("../../../system"); var system = require("../../../system");
var settings = require("../../../../config/settings"); var settings = require("../../../../config/settings");
var rule =require("../../../utils/invoiceRule/rule");
var Context =require("../../../utils/stateChain/context");
var Calculation = require("../../../utils/strategies/calculation");
class ActionAPI extends APIBase { class ActionAPI extends APIBase {
constructor() { constructor() {
super(); super();
this.iinvoiceSve = system.getObject("service.invoice.iinvoiceSve"); this.iinvoiceSve = system.getObject("service.invoice.iinvoiceSve");
this.context=new Context();
} }
/** /**
* 接口跳转 * 接口跳转
...@@ -30,13 +26,13 @@ class ActionAPI extends APIBase { ...@@ -30,13 +26,13 @@ class ActionAPI extends APIBase {
var opResult = null; var opResult = null;
switch (action_type) { switch (action_type) {
case "invoiceApply": // 发票申请 case "invoiceApply": // 发票申请
opResult = await rule.dispatcher(action_body); opResult = await this.iinvoiceSve.invoiceApply(action_body);
break; break;
case "invoicePage": // 发票申请列表页(平台) case "invoicePage": // 发票申请列表页(平台)
opResult = await rule.dispatcher(action_body); opResult = await this.iinvoiceSve.invoicePage(action_body);
break; break;
case "deliverInvoicePage": // 发票申请列表页(交付商) case "deliverInvoicePage": // 发票申请列表页(交付商)
opResult = await rule.dispatcher(action_body); opResult = await this.iinvoiceSve.deliverInvoicePage(action_body);
break; break;
case "handleStatus": //进度处理 case "handleStatus": //进度处理
break; break;
......
...@@ -47,6 +47,7 @@ module.exports = (db, DataTypes) => { ...@@ -47,6 +47,7 @@ module.exports = (db, DataTypes) => {
deliver_id:{ type: DataTypes.STRING(32), allowNull: true, defaultValue: null,comment:"交付商ID common下的交付商ID" }, deliver_id:{ type: DataTypes.STRING(32), allowNull: true, defaultValue: null,comment:"交付商ID common下的交付商ID" },
bd_id:{ type: DataTypes.STRING(32), allowNull: true, defaultValue: null ,comment:"业务员Id"}, bd_id:{ type: DataTypes.STRING(32), allowNull: true, defaultValue: null ,comment:"业务员Id"},
bd_path:{ type: DataTypes.STRING(200), allowNull: true, defaultValue: null ,comment:"业务员权限"}, bd_path:{ type: DataTypes.STRING(200), allowNull: true, defaultValue: null ,comment:"业务员权限"},
channel_id:{ type: DataTypes.STRING(32), allowNull: true ,comment:"渠道ID"},
created_at: { type: DataTypes.DATE, allowNull: true }, created_at: { type: DataTypes.DATE, allowNull: true },
updated_at: { type: DataTypes.DATE, allowNull: true }, updated_at: { type: DataTypes.DATE, allowNull: true },
deleted_at: { type: DataTypes.DATE, allowNull: true }, deleted_at: { type: DataTypes.DATE, allowNull: true },
......
...@@ -16,7 +16,17 @@ class InvoiceService extends ServiceBase { ...@@ -16,7 +16,17 @@ class InvoiceService extends ServiceBase {
this.iinvoicedeliverDao = system.getObject("db.invoice.iinvoicedeliverDao"); this.iinvoicedeliverDao = system.getObject("db.invoice.iinvoicedeliverDao");
} }
/**
* 发票申请
* @param {*} params
*/
async invoiceApply(params){
}
//**********************************************以下是旧版本************************************************************ */
/** /**
* 构建产品流程对象 * 构建产品流程对象
* @param productPid * @param productPid
......
/**
* 1 算法文件命名规则 : calInvoice + 销售方编码
* 2 如果算法中途出现异常 则需直接return
* 3 如果算法顺利执行 返回参数中除包含必须的四个税值外,还需要包含一个累计不含税价字段 字段名称为 "x1"
* 4 此文件必须提供 calcInvoice 和 formatParams 方法
*/
const system = require("../../../system");
const applySve = system.getObject("service.invoice.applySve");
const Decimal = require('decimal.js');
const PER_TAX = 1; //个税
const VAL_TAX = 2; //增值税
/**
* 试算接口
* 注意:1 由于销售方类型不同 所以算法不同 需要对参数验证单独处理
*
* 税率的格式 传去除 %号的数值 比如:
* 96%, 则这个值就传 "taxCostPriRat"=96
*/
module.exports.calcInvoice = async (params) => {
try {
// 服务费率
let serviceRate = Number(params.serviceRate || 0);
let serviceCharge = Number((params.invoiceAmount * serviceRate) / 100).toFixed(0) || 0;
//计算累计不含税价 businessmenId,businessmenCreditCode,taxIncPriRat,invoiceAmount,type,valCalWay,perCalWay,invoiceTime
let x1 = await applySve.calAccumulatedPriceExcludingTax(params.businessmenId, params.businessmenType, params.businessmenCreditCode, params.taxIncPriRat, params.invoiceAmount, PER_TAX, null, params.perCalWay, params.invoiceTime);
console.log("个税 累计不含税价总额:" + x1);
//计算累计利润
let x2 = calAccumulatedProfit(x1, params.taxCostPriRat);
//根据 cumulativeProfit 查找对应梯度的个税税率和速算扣除数
let calRateRangeResForPer = calRateRange(x2, params.perIncTaxRange, PER_TAX);
let { taxPer, quiCalDed } = calRateRangeResForPer;
//计算年累计的个税
let cumulativeProfit = await applySve.calCumulativeProfit(params.businessmenId,params.businessmenType, PER_TAX, params.valCalWay);
//计算个税
let personalIncomeTax = calTaxPersonal(x2, taxPer, quiCalDed, cumulativeProfit);
/*计算增值税*/
//计算累计不含税价
let x3 = await applySve.calAccumulatedPriceExcludingTax(params.businessmenId,params.businessmenType, params.businessmenCreditCode, params.taxIncPriRat, params.invoiceAmount, VAL_TAX, params.valCalWay, null, params.invoiceTime);
console.log("增值税 累计不含税价总额:" + x3);
//根据 cumulativeProfitOfvalTax 查找对应梯度的个税税率
let calRateRangeResForVal = calRateRange(x3, params.valAddTaxRange, VAL_TAX);
let {valAddTaxRat,addTaxRat} = calRateRangeResForVal;
//计算年累计的增值税
let cumulativeProfitOfvalTax = await applySve.calCumulativeProfit(params.businessmenId,params.businessmenType, VAL_TAX, params.valCalWay);
//计算增值税
let valueAddedTax = calValTax(x3, valAddTaxRat, cumulativeProfitOfvalTax);
//附加税
let additionalTax = calAddTax(valueAddedTax, addTaxRat);
let res = {
x1: x1, //累计不含税价
serviceCharge: serviceCharge, //服务费
personalIncomeTax: personalIncomeTax, //个税
valueAddedTax: valueAddedTax, //附加税
additionalTax: additionalTax, //附加税
}
console.log("计算的各种税额:" + JSON.stringify(res));
return res;
} catch (error) {
return system.getResult(-1,`系统错误 错误信息 ${error}`);
}
}
/**
* 计算累计利润
* @param {*} x1 年累计金额
* @param {*} taxCostPriRat 核定成本费用率
*/
let calAccumulatedProfit = (x1, taxCostPriRat) => {
if (taxCostPriRat == 0) {
return 0;
} else {
return new Decimal(x1).mul(Decimal.sub(1, taxCostPriRat)).toFixed(2);
}
}
/**
* 计算税率值
* @param {*} amount 金额
* @param {*} taxRange 税率范围
* @param {*} type 类型 1:个税 2 增值税
*/
let calRateRange = (amount, taxRange, type) => {
let res = {};
if (type === PER_TAX) {
for (let item of taxRange) {
if (item.minValue <= amount && amount <= item.maxValue) {
res.taxPer = item.rate;
res.quiCalDed = item.quiCalDed;
break;
}
}
} else {
for (let item of taxRange) {
if (item.minValue <= amount && amount <= item.maxValue) {
res.valAddTaxRat = item.zengzhiRate;
res.addTaxRat = item.fujiaRate;
break;
}
}
}
return res;
}
/**
* 计算个税
* @param {*} x2 //累计利润
* @param {*} taxPer //个税税率
* @param {*} quiCalDed //速算扣除数
* @param {*} cumulativeProfit //累计缴纳的个税
*/
let calTaxPersonal=(x2, taxPer, quiCalDed, cumulativeProfit)=>{
x2 = x2 || 0;
quiCalDed = quiCalDed || 0;
taxPer = taxPer || 0;
cumulativeProfit = cumulativeProfit || 0;
if (taxPer == 0) {
return 0;
}
return (new Decimal(x2).mul(taxPer).div(100).sub(quiCalDed).sub(cumulativeProfit)).toFixed(2);
}
/**
* 计算增值税
* @param {*} x3 //累计不含说价
* @param {*} valAddTaxRat //增值税率
* @param {*} cumulativeProfitOfvalTax //累计缴纳的增值税
*/
let calValTax=(x3, valAddTaxRat, cumulativeProfitOfvalTax)=>{
if (valAddTaxRat == 0) {
return 0;
}
let res = new Decimal(x3).mul(valAddTaxRat).div(100).sub(cumulativeProfitOfvalTax).toFixed(2);
return res;
}
/**
* 计算附加税
* @param {*} valueAddedTax
* @param {*} addTaxRat
*/
let calAddTax=(valueAddedTax, addTaxRat)=>{
if (addTaxRat == 0) {
return 0
} else {
return new Decimal(valueAddedTax).mul(addTaxRat).div(100).toFixed(2);
}
}
/**
* 格式化参数
*/
module.exports.formatParams=(params)=>{
//后期添加格式化参数信息
params=verificationParams(params);
return params;
}
/**
* 校验各种费率 的合法性
* @param {*} params
* params
*/
let verificationParams = (params) => {
if (params.taxIncPriRat > 100 || params.serviceRate > 100 || params.taxCostPriRat > 100) {
return system.getResult(-1,`参数错误 费率不合法`);
} else {
params.taxIncPriRat = new Decimal(params.taxIncPriRat).div(100).toFixed(4);
params.taxCostPriRat = new Decimal(params.taxCostPriRat).div(100).toFixed(4);
params.serviceRate = new Decimal(params.serviceRate).div(100).toFixed(4);
}
return params;
}
\ No newline at end of file
//去除空格
module.exports.trim=(o)=> {
if(!o) {
return "";
}
return o.toString().trim();
}
\ No newline at end of file
/**
* 发票配置文件
*/
module.exports={
//根据销售方区别不同的配置信息
/**
* @MAX_AMOUNT 最大的金额 单位分
*
* 10:个体工商胡 20:自然人
*/
"10":{
MAX_AMOUNT:500000000,
WARNING_AMOUNT:400000000,
ruleCode:"10"
},
"20":{
MAX_AMOUNT:400000000,
WARNING_AMOUNT:300000000,
ruleCode:"10"
}
}
\ No newline at end of file
/**
* 发票计税算法-参数字典表
*/
const common = require("./common");
const system = require("../../system");
const valApi=require("./validate");
/**
* 算法分发器
*/
module.exports.dispatcher=async (params)=>{
try {
if(!params.businessmenType){
return system.getResult(-1,`参数错误 销售方类型不能为空`);
}
//加载算法类
let ruleCode = common.trim(params.ruleCode);
let filePath =`./algorithm/calInvoice${ruleCode}`;
console.log(filePath);
let calInvApi = require(filePath);
if(!calInvApi){
return system.getResult(-1,`系统错误 错误信息 算法不存在`);
}
let valCon ={};
//验证参数
valCon.businessmenType=common.trim(params.businessmenType);
valCon.businessmenId=common.trim(params.businessmenId);
valCon.businessmenCreditCode=common.trim(params.businessmenCreditCode);
valCon.invoiceAmount=common.trim(params.invoiceAmount);
//格式化参数
let calCon = calInvApi.formatParams(params);
if(calCon.hasOwnProperty("status")){
return calCon;
}
//计算参数
return await valApi.validate(valCon,calInvApi.calcInvoice,calCon);
} catch (error) {
console.log(error);
return system.getResult(-1,`参数错误 销售方类型不存在`);
}
}
const invoiceConfig = require("./invoiceConfig");
const system = require("../../system");
const common = require("./common");
const applySve = system.getObject("service.invoice.applySve");
const Decimal = require('decimal.js');
/**
* 开票验证
* 注意:验证和测试高度耦合(需要传入测试计算方法)
* @businessmenType 用户类别
* @businessmenId 销售方ID
* @businessmenCreditCode 非必添 销售方统一社会信用代码
* @invoiceAmount 开票金额
* @fn 试算方法
*/
module.exports.validate=async (params,fn,formate)=>{
let businessmenType = common.trim(params.businessmenType);
let businessmenId = common.trim(params.businessmenId);
let businessmenCreditCode = common.trim(params.businessmenCreditCode);
let invoiceAmount = Number(common.trim(params.invoiceAmount));
if(!businessmenType || !invoiceAmount || !businessmenId){
return system.getResult(-1,`参数错误 销售方信息参数有误 请核对参数`);
}
//获取配置文件信息
let busCon = invoiceConfig[businessmenType];
if(!busCon){
return system.getResult(-1,`参数错误 销售方类型不能为空`);
}
if(busCon.MAX_AMOUNT<params.invoiceAmount){
return system.getResult(-1,`开票金额超出最大范围`);
}
//试算获取累计含税价
let calAmount = await fn(formate);
if(calAmount.hasOwnProperty("status")){
return system.getResult(-1,`计算参数错误 请核对税率、金额以及销售方信息`);
}
_totalAmount = Decimal(calAmount.x1).plus(invoiceAmount).toNumber();
if(busCon.MAX_AMOUNT<_totalAmount){
return system.getResult(-1,`累计开票金额超出本年度最大金额`);
}
let warning = "";
if(busCon.WARNING_AMOUNT<_totalAmount){
warning=`累计开票金额达到${_totalAmount}`;
}
//查询发票状态 只有在状态为 '1000','0090' 或者信息不存在的情况下 验证成功 参考 applySve.verificationByBusinessmenCreditCode接口
let isLegal = await applySve.verificationInvoiceStatus(businessmenType,businessmenId,businessmenCreditCode);
if(!isLegal){
return system.getResult(-1,`验证失败 此用户存在未完成的发票`);
}
//移除累计税价
delete calAmount.x1;
if(warning){
calAmount.warning=warning;
}
return system.getResult(calAmount);
}
\ No newline at end of file
//平台审核发票申请失败 1010 但执行的状态是 1000
const system = require("../../../system");
const common = require("./common");
module.exports.auditFailForCustomer=async function (params){
console.log("第一次未审批 状态 1000");
let _apply = await common.applyVerification(params);
if(_apply.status==-1){return _apply;}
params.nextStatus = common.trim(params.nextStatus);
params.remark = common.trim(params.remark);
_apply.status = params.nextStatus;
_apply.customerStatus = params.nextStatus;
_apply.remark = params.remark;
if (params.nextStatus != "1010") {
return system.getResult(-1,`参数错误 请核对状态码`);
}
try {
await _apply.save();
return system.getResultSuccess();
} catch (error) {
return system.getResult(null, `系统错误 错误信息 ${error}`);
}
}
\ No newline at end of file
const common = require("./common");
const system = require("../../../system");
const applyDao = system.getObject("db.invoice.applyDao");
const invoiceDao = system.getObject("db.invoice.invoiceDao");
const delivererDao = system.getObject("db.invoice.delivererDao");
//审核通过 1070
module.exports.auditSuccessForDeliverer=async function (params){
console.log("审核通过 1070");
let _apply =await common.applyVerification(params);
if(_apply.status==-1){return _apply;}
let delivererData = {},
applyData = {},
invoiceData = {};
let _deliverer = await delivererDao.findOne({
id: _apply.delivererId
});
delivererData.auditContent = common.trim(params.auditContent);
delivererData.delivererContent = common.trim(params.delivererContent);
delivererData.mailAddr = common.trim(params.mailAddr);
delivererData.mailMobile = common.trim(params.mailMobile);
delivererData.mailTo = common.trim(params.mailTo);
delivererData.mailEmail = common.trim(params.mailEmail);
delivererData.id = common.trim(_deliverer.id);
applyData.status = common.trim(params.nextStatus);
applyData.id = common.trim(params.id);
invoiceData.status = common.trim(params.nextStatus);
invoiceData.id = common.trim(params.id);
await applyDao.db.transaction(async (t) => {
//更新deliverer信息
await delivererDao.update(delivererData, t);
//更新 申请单和发票单
await applyDao.update(applyData, t);
await invoiceDao.update(invoiceData, t);
if (_apply.parentId) {
await invoiceDao.update({ id: _apply.parentId, redStatus: '4' }, t);
}
}).catch(error => {
return system.getResult(null, `系统错误 错误信息 ${error}`);
});
return system.getResultSuccess();
}
\ No newline at end of file
const system = require("../../../system");
const applyDao = system.getObject("db.invoice.applyDao");
const invoiceDao = system.getObject("db.invoice.invoiceDao");
const is = system.getObject("util.invoiceStatus");
const invoiceStatus = is.status;
/**
* 平台状态验证
*/
module.exports.applyVerification=async (params) =>{
let _apply = await applyDao.findOne({
id: trim(params.id)
});
if (!_apply) {
return system.getResult(null, `此发票不存在`);
}
//获取当前状态 的对象
let _status = invoiceStatus[_apply.status];
//如果不符合状态则退出
if (params.nextStatus == "1300" || params.nextStatus == "1040" || params.nextStatus == "1010") {
return _apply;
}
if (!_status && _status.next != params.nextStatus) {
let name = invoiceStatus[invoiceStatus[_apply.status].next].name;
return system.getResult(null, `更新状态错误,提示:当前状态的下一个状态是 ${name}`);
}
return _apply;
}
/**
* 交付商转该验证
*/
module.exports.delivererVerification=async (params)=> {
let _apply = await applyDao.findOne({ id: params.id });
let _invoice = await invoiceDao.findOne({ id: params.id });
if (!_invoice) { return system.getResult(null, `此发票不存在`); }
//获取当前状态 的对象
let _status = invoiceStatus[_invoice.status];
//如果不符合状态则退出
if (params.nextStatus == "1300" || params.nextStatus == "1040" || params.nextStatus == "1010") {
let obj = {
_apply: _apply,
_invoice: _invoice
};
return obj;
} else if (!_status && _status.dstatus != params.nextStatus) {
let name = invoiceStatus[invoiceStatus[_invoice.status].dstatus].name;
return system.getResult(null, `更新状态错误,提示:当前状态的下一个状态是 ${name}`);
}
let obj = {
_apply: _apply,
_invoice: _invoice
};
return obj;
}
function trim(o) {
if(!o) {
return "";
}
return o.toString().trim();
}
module.exports.trim=(o)=>{
if(!o) {
return "";
}
return o.toString().trim();
}
const system = require("../../../system");
const applyDao = system.getObject("db.invoice.applyDao");
const invoiceDao = system.getObject("db.invoice.invoiceDao");
const delivererDao = system.getObject("db.invoice.delivererDao");
const common = require("./common");
//交付商关闭 1040
module.exports.delivererClose = async function (params) {
console.log("交付商关闭 1040");
let obj = await common.delivererVerification(params);
if (obj.status == -1) { return obj; }
let _apply = obj._apply;
let _invoice = obj._invoice;
//更改发票表信息
_invoice.status = common.trim(params.nextStatus);
//添加拒绝原因
let delivererData = {
breakReason: common.trim(params.breakReason) || "",
id: _apply.delivererId
};
//更改申请表信息
_apply.status = "1020";
_apply.delivererId = null;
let applyData = {};
applyData.id = _apply.id;
applyData.status = "1020";
applyData.delivererId = '';
let invoiceData = {};
invoiceData.status = "1020";
invoiceData.id=_apply.id;
await delivererDao.db.transaction(async (t) => {
//更新申请表状态
await applyDao.update(applyData, t);
//更新发票表状态
await invoiceDao.update(invoiceData, t);
//更新拒绝原因
await delivererDao.update(delivererData, t);
}).catch(error => {
return system.getResult(null, `系统错误 错误信息 ${error}`);
});
return system.getResultSuccess();
}
\ No newline at end of file
const common = require("./common");
const system = require("../../../system");
const applyDao = system.getObject("db.invoice.applyDao");
//完成 1090
module.exports.finish=async function (params){
console.log("完成 1090");
let _apply =await common.applyVerification(params);
if(_apply.status==-1){return _apply;}
let applyData = {};
applyData.status = common.trim(params.nextStatus);
applyData.customerStatus = common.trim(params.nextStatus);
applyData.id = common.trim(params.id);
// invoiceData.status = common.trim(params.nextStatus);
// invoiceData.id=common.trim(params.id);
await applyDao.db.transaction(async (t) => {
//更新 申请单和发票单
await applyDao.update(applyData, t);
// await this.invoiceDao.update(invoiceData,t);
}).catch(error => {
return system.getResult(null, `系统错误 错误信息 ${error}`);
});
return system.getResultSuccess();
}
\ No newline at end of file
module.exports={
//客户未付款 0090
unAuditForCustomer:require('./unAuditForCustomer'),
//客户提交审核 状态1000
unAuditForCustomer:require('./unAuditForCustomer'),
//平台审核发票申请失败 1010
auditFailForCustomer:require('./auditFailForCustomer'),
//待分配 1020
toBeAllocated:require('./toBeAllocated'),
//待处理 1030
pendingDisposal:require('./pendingDisposal'),
//交付商关闭 1040
delivererClose:require('./delivererClose'),
//已开具 1050
invoiced:require('./invoiced'),
//待审核 1060
unAuditedForDeliverer:require('./unAuditedForDeliverer'),
//审核失败(平台第二次审核) 1300
unAuditFailForDeliverer:require('./unAuditFailForDeliverer'),
//审核通过 1070
auditSuccessForDeliverer:require('./auditSuccessForDeliverer'),
//已邮寄 1080
mailed:require('./mailed'),
//完成 1090
finish:require('./finish'),
//发票撤回 1100
withdrawInvoice:require('./withdrawInvoice'),
//红冲 1200
redRush:require('./redRush'),
}
\ No newline at end of file
const system = require("../../../system");
const applyDao = system.getObject("db.invoice.applyDao");
const invoiceDao = system.getObject("db.invoice.invoiceDao");
const delivererDao = system.getObject("db.invoice.delivererDao");
const common = require("./common");
//已开具 1050
module.exports.invoiced=async function(params){
console.log("已开具 1050");
let obj = await common.delivererVerification(params);
if(obj.status==-1){return obj;}
//更改发票表信息
let invoiceData = {};
invoiceData.id = params.id;
invoiceData.invoiceNo = common.trim(params.invoiceNo);
invoiceData.invoiceTime = common.trim(params.invoiceTime);
invoiceData.invoiceImg = common.trim(params.invoiceImg);
invoiceData.status = common.trim(params.nextStatus);
//更改申请表信息
let applyData = {};
applyData.id = params.id;
applyData.status = common.trim(params.nextStatus);
applyData.customerStatus = common.trim(params.nextStatus);
await delivererDao.db.transaction(async (t) => {
//更新申请表状态
await applyDao.update(applyData, t);
//更新发票表状态
await invoiceDao.update(invoiceData, t);
}).catch(error => {
return system.getResult(null, `系统错误 错误信息 ${error}`);
});
return system.getResultSuccess();
}
\ No newline at end of file
const system = require("../../../system");
const applyDao = system.getObject("db.invoice.applyDao");
const invoiceDao = system.getObject("db.invoice.invoiceDao");
const delivererDao = system.getObject("db.invoice.delivererDao");
const common = require("./common");
//已邮寄 1080
module.exports.mailed=async (params)=>{
console.log("已邮寄 1080");
let obj = await common.delivererVerification(params);
if(obj.status==-1){return obj;}
let _apply = obj._apply;
let invoiceData = {}, applyData = {}, delivererData = {};
//更改发票表信息
invoiceData.status = common.trim(params.nextStatus);
invoiceData.mailNo = common.trim(params.mailNo);
invoiceData.id = common.trim(params.id);
//更改申请表信息
applyData.status = common.trim(params.nextStatus);
applyData.id = common.trim(params.id);
//交付商
let _deliverer = await delivererDao.findOne({ id: _apply.delivererId });
delivererData.delivererMailNo = params.mailNo;
delivererData.id = _deliverer.id;
await delivererDao.db.transaction(async (t) => {
//更新申请表状态
await applyDao.update(applyData, t);
//更新发票表状态
await invoiceDao.update(invoiceData, t);
//更新交付商信息
await delivererDao.update(delivererData, t);
}).catch(error => {
return system.getResult(null, `系统错误 错误信息 ${error}`);
});
return system.getResultSuccess();
}
\ No newline at end of file
const common = require("./common");
const system = require("../../../system");
const applyDao = system.getObject("db.invoice.applyDao");
const invoiceDao = system.getObject("db.invoice.invoiceDao");
const delivererDao = system.getObject("db.invoice.delivererDao");
//待处理 1030
module.exports.pendingDisposal=async function (params){
console.log("待处理 1030");
if (!params.id || !params.delivererName) {
return system.getResult(-1, `系统错误 错误信息 ${error}`);
}
let _apply =await common.applyVerification(params);
if(_apply.status==-1){return _apply;}
await applyDao.db.transaction(async (t) => {
let _deliverer = await delivererDao.create({
invoiceId: _apply.id,
applyNo: _apply.applyNo,
merchantId: _apply.merchantId,
delivererId: common.trim(params.delivererId),
delivererName: common.trim(params.delivererName),
delivererAmount: Number(common.trim(params.delivererAmount))
}, t);
let applyData = {};
applyData.status = common.trim(params.nextStatus);
applyData.customerStatus = common.trim(params.nextStatus);
applyData.delivererId = common.trim(_deliverer.id);
applyData.id = common.trim(params.id);
//更新申请发票内容
await applyDao.update(applyData, t);
//更改发票状态
let invoiceData = {};
invoiceData.status = common.trim(params.nextStatus);
invoiceData.id = common.trim(params.id);
await invoiceDao.update(invoiceData, t);
}).catch(error => {
return system.getResult(null, `系统错误 错误信息 ${error}`);
});
return system.getResultSuccess();
}
\ No newline at end of file
//红冲 1200
module.exports.redRush=async (params)=>{
console.log("红冲 1200");
}
\ No newline at end of file
const common = require("./common");
const system = require("../../../system");
//待分配 1020
module.exports.toBeAllocated=async function(params){
console.log("//待分配 1020");
let _apply =await common.applyVerification(params);
if(_apply.status==-1){return _apply;}
if (Number(params.isPay) != 1) {
return system.getResult(null, `参数错误 请核对付款信息`);
}
params.nextStatus = common.trim(params.nextStatus);
params.remark = common.trim(params.remark);
_apply.status = params.nextStatus;
_apply.remark = params.remark;
_apply.isPay = Number(params.isPay);
try {
await _apply.save();
return system.getResultSuccess();
} catch (error) {
return system.getResult(null, `系统错误 错误信息 ${error}`);
}
}
\ No newline at end of file
const system = require("../../../system");
const applyDao = system.getObject("db.invoice.applyDao");
const invoiceDao = system.getObject("db.invoice.invoiceDao");
const delivererDao = system.getObject("db.invoice.delivererDao");
const common = require("./common");
//待处理 1300(平台第二次审核失败)
module.exports.unAuditFailForDeliverer=async (params)=>{
console.log("待处理 1300");
let _apply =await common.applyVerification(params);
if(_apply.status==-1){return _apply;}
// let _apply = await applyDao.findOne({
// id: common.trim(params.id)
// });
if (!_apply) {
return system.getResult(null, `发票不存在,请核对发票ID`);
}
let _deliverer = await delivererDao.model.findOne({
where: {
id: _apply.delivererId
}
});
if (!_deliverer) {
return system.getResult(null, `交付商不存在,请联系管理员`);
}
await applyDao.db.transaction(async (t) => {
//更新 申请单和发票单
await applyDao.update({
status: "1300",
id: _apply.id
}, t);
await invoiceDao.update({
status: "1300",
id: _apply.id
}, t);
if (_deliverer.id) {
//提交审核信息
await delivererDao.update({
auditContent: common.trim(params.auditContent),
id: _deliverer.id
});
}
}).catch(error => {
return system.getResult(null, `系统错误 错误信息 ${error}`);
});
return system.getResultSuccess();
}
\ No newline at end of file
const applySve = require("../../../service/impl/invoice/applySve");
const common = require("./common");
//第一次未审批 状态 1000
module.exports.unAuditForCustomer=async function (params) {
console.log("第一次未审批 状态 1000");
let _apply =await common.applyVerification(params);
if(_apply.status==-1){return _apply;}
return applySve.examine1000(params, _apply);
}
\ No newline at end of file
const system = require("../../../system");
const applyDao = system.getObject("db.invoice.applyDao");
const invoiceDao = system.getObject("db.invoice.invoiceDao");
const delivererDao = system.getObject("db.invoice.delivererDao");
const common = require("./common");
//待审核 1060
module.exports.unAuditedForDeliverer=async (params)=>{
console.log("待审核 1060");
let obj = await common.delivererVerification(params);
if(obj.status==-1){return obj;}
let invoiceData = {}, applyData = {};
invoiceData.status = params.nextStatus;
invoiceData.id = params.id;
if (params.invoiceNo) {
invoiceData.invoiceNo = common.trim(params.invoiceNo);
}
if (params.invoiceTime) {
invoiceData.invoiceTime = common.trim(params.invoiceTime);
}
if (params.invoiceImg) {
invoiceData.invoiceImg = common.trim(params.invoiceImg);
}
applyData.status = params.nextStatus;
applyData.id = params.id;
await delivererDao.db.transaction(async (t) => {
//更新申请表状态
await applyDao.update(applyData, t);
//更新发票表状态
await invoiceDao.update(invoiceData, t);
}).catch(error => {
return system.getResult(null, `系统错误 错误信息 ${error}`);
});
return system.getResultSuccess();
}
\ No newline at end of file
module.exports = {
// "0090": "未付款",
// "1000": "待审核",
// "1010": "审核不通过",
// "1020": "待分配",
// "1030": "待处理",
// "1040": "交付商关闭",
// "1050": "已开具",
// "1060": "待审核",
// "1300": "审核失败(平台第二次审核)",
// "1070": "审核通过",
// "1080": "已邮寄",
// "1090": "完成",
// "1100": "发票撤回",
// "1200": "红冲",
"0090": "unAuditForCustomer",
"1000": "unAuditForCustomer",
"1010": "auditFailForCustomer",
"1020": "toBeAllocated",
"1030": "pendingDisposal",
"1040": "delivererClose",
"1050": "invoiced",
"1060": "unAuditedForDeliverer",
"1300": "unAuditFailForDeliverer",
"1070": "auditSuccessForDeliverer",
"1080": "mailed",
"1090": "finish",
"1100": "withdrawInvoice",
"1200": "redRush",
};
\ No newline at end of file
//发票撤回 1100
const applySve = require("../../../service/impl/invoice/applySve");
const common = require("./common");
module.exports.withdrawInvoice=async function(params){
console.log("发票撤回 1100 ");
}
\ No newline at end of file
const StateBase = require('./stateBase');
const API = require('./actions/index');
const AllState =require('./actions/util');
const system = require("../../system");
class Context {
constructor(){
this.stateBase=new StateBase(API);
this.allState=AllState;
}
async request(params){
let methodName = this.allState[params.nextStatus];
if(!methodName){
return system.getResult(-1,`参数错误 状态码错误`);
}
let _self = this.stateBase.setState(methodName);
return await _self.doAction(params);
}
}
module.exports=Context;
\ No newline at end of file
const system = require("../../system");
class StateBase{
constructor(api){
this.actions=api;
this.curState=null;
}
//改变状态
setState(curState){
this.curState=curState;
return this;
}
//执行操作
async doAction(params){
try {
if(this.actions[this.curState]){
return await this.actions[this.curState][this.curState].apply(this,[params]);
}else{
return system.getResult(-1,`系统错误 未找到处理器`);
}
} catch (error) {
return system.getResult(-1,`系统错误 错误信息 ${error}`);
}
}
}
module.exports = StateBase;
const strategies = require('./strategiesBase');
/**
* 增值税的环境类
*
* 将注册的说有增值税算法实现都通过环境类调用
* @param{*} businessmenType 销售方类型
* @param{*} params 算法的参数
*/
class ContextAdditionalTax{
constructor(){
console.log("初始化 附加税环境类 ContextAdditionalTax");
}
async doAction (businessmenType,params){
return await strategies[businessmenType]['calcInvoice'](params);
}
}
module.exports=ContextAdditionalTax;
\ No newline at end of file
const system = require("../../../../system");
const Decimal = require('decimal.js');
const PER_TAX = 1; //个税
/**
* 附加税算法
* 注意:1 由于销售方类型不同 所以算法不同 需要对参数验证单独处理
*
* 税率的格式 传去除 %号的数值 比如:
* 96%, 则这个值就传 "taxCostPriRat"=96
*/
module.exports.calcInvoice = (params) => {
try {
//根据 cumulativeProfitOfvalTax 查找对应梯度的个税税率
let calRateRangeResForVal = calRateRange(params.valueAddedTax, params.valAddTaxRange, null);
let {addTaxRat} = calRateRangeResForVal;
//参数验证
verificationParams(params.valueAddedTax,addTaxRat);
//附加税
let res = calAddTax(Number(params.valueAddedTax || 0), Number(addTaxRat || 0));
return system.getResult(res);
} catch (error) {
return system.getResult(-1,`系统错误 错误信息 ${error}`);
}
}
/**
* 计算附加税
* @param {*} valueAddedTax
* @param {*} addTaxRat
*/
let calAddTax=(valueAddedTax, addTaxRat)=>{
if (addTaxRat == 0) {
return 0
} else {
return new Decimal(valueAddedTax).mul(addTaxRat).div(100).toFixed(2);
}
}
/**
* 计算税率值
* @param {*} amount 金额
* @param {*} taxRange 税率范围
* @param {*} type 类型 1:个税 2 增值税
*/
let calRateRange = (amount, taxRange, type=2) => {
let res = {};
if (type === PER_TAX) {
for (let item of taxRange) {
if (item.minValue <= amount && amount <= item.maxValue) {
res.taxPer = item.rate;
res.quiCalDed = item.quiCalDed;
break;
}
}
} else {
for (let item of taxRange) {
if (item.minValue <= amount && amount <= item.maxValue) {
res.valAddTaxRat = item.zengzhiRate;
res.addTaxRat = item.fujiaRate;
break;
}
}
}
return res;
}
/**
* 校验各种费率 的合法性
* @param {*} params
* params
*/
let verificationParams = (valueAddedTax,addTaxRat) => {
if(addTaxRat > 100){
system.getResult(-1,`参数错误 销售方类型非法`);
}
}
\ No newline at end of file
const system = require("../../../../system");
const Decimal = require('decimal.js');
/**
* 附加税算法
* 注意:1 由于销售方类型不同 所以算法不同 需要对参数验证单独处理
*
* 税率的格式 传去除 %号的数值 比如:
* 96%, 则这个值就传 "taxCostPriRat"=96
*/
module.exports.calcInvoice = (valueAddedTax,addTaxRat) => {
try {
//参数验证
verificationParams(valueAddedTax,addTaxRat);
//附加税
return calAddTax(valueAddedTax, addTaxRat);
} catch (error) {
return system.getResult(-1,`系统错误 错误信息 ${error}`);
}
}
/**
* 计算附加税
* @param {*} valueAddedTax
* @param {*} addTaxRat
*/
let calAddTax=(valueAddedTax, addTaxRat)=>{
if (addTaxRat == 0) {
return 0
} else {
return new Decimal(valueAddedTax).mul(addTaxRat).div(100).toFixed(2);
}
}
/**
* 校验各种费率 的合法性
* @param {*} params
* params
*/
let verificationParams = (valueAddedTax,addTaxRat) => {
if(params.addTaxRat > 1){
system.getResult(-1,`参数错误 销售方类型非法`);
}
params.addTaxRat = Number(addTaxRat || 0);
params.valueAddedTax = Number(valueAddedTax || 0);
}
\ No newline at end of file
/**
* 导出所有的实现类
*/
module.exports={
//个体工商户
"calInvoice10":require("./calInvoice10"),
//自然人
"calInvoice20":require("./calInvoice20"),
}
\ No newline at end of file
/**
* 定义个增值税的所有接口
*
* 格式:JSON
* key: businessmenType (销售方类型)
* value:Fuction
*
* ps:如果要增加新的增值税算法,需要在此注册
*/
const impl = require('./impl');
module.exports={
//个体工商户
'10': impl.calInvoice10,
//自然人
'20': impl.calInvoice20
}
\ No newline at end of file
var Invoice = require("./invoice");
var system = require("../../system");
var ContextFactory = require("./contextFactory");
/**
* 计算类
*
* 组装的Invoice对象
*/
class Calculation{
constructor(params){
console.log("初始化计算类")
this.contextFactory = new ContextFactory();
this.invoice = new Invoice();
this.init(params);
}
getInvoice(){
return this.invoice;
}
/**
* @param {*} params
* calculation
* @param.calNames 计算种类 是 增值税:valueAddedTax 附加税:additionalTax
*/
init (params){
if(params.calNames instanceof Array){
for (let item of params.calNames) {
if(item=="valueAddedTax"){
this.invoice.setContextValueAddedTax(this.contextFactory.getInstance(system.trim(item)));
}else if(item=="additionalTax"){
this.invoice.setContextAdditionalTax(this.contextFactory.getInstance(system.trim(item)));
}else{
system.getResult(-1,`参数错误 非法的计算类型`);
}
}
}else {
if(system.trim(params.calNames) != "valueAddedTax" && system.trim(params.calNames) != "additionalTax"
&& system.trim(params.calNames) != "individualIncomeTax"){
system.getResult(-1,`参数错误 非法的计算类型`);
}else{
if(params.calNames=="valueAddedTax"){
this.invoice.setContextValueAddedTax(this.contextFactory.getInstance(system.trim(params.calNames)));
}else if(params.calNames=="additionalTax"){
this.invoice.setContextAdditionalTax(this.contextFactory.getInstance(system.trim(params.calNames)));
}else{
system.getResult(-1,`参数错误 非法的计算类型`);
}
}
}
}
}
module.exports=Calculation;
\ No newline at end of file
/**
* 环境工厂类
*/
const ContextAdditionalTax = require("./additionalTax/contextAdditionalTax");
const ContextValueAddedTax = require("./valueAddedTax/contextValueAddedTax");
class ContextFactory {
constructor() {
// this.context = context;
}
getInstance(context) {
let bean = null;
switch (context) {
case "additionalTax":
bean = new ContextAdditionalTax();
break;
case "valueAddedTax":
bean = new ContextValueAddedTax();
break;
default:
console.log("算法环境初始化失败");
bean = null
}
return bean;
}
}
module.exports=ContextFactory;
\ No newline at end of file
/**
* 发票类
*
* 构造器参数: contextAdditionalTax, //附加税上下文
* contextValueAddedTax, //增值税上下文
* contextIndividualIncomeTax //个人所得税上下文
*/
class Invoice {
constructor(contextAdditionalTax,contextValueAddedTax,contextIndividualIncomeTax){
this.contextAdditionalTax = contextAdditionalTax || null;
this.contextValueAddedTax = contextValueAddedTax || null;
// this.contextIndividualIncomeTax = contextIndividualIncomeTax;
}
setContextAdditionalTax(contextAdditionalTax){
this.contextAdditionalTax=contextAdditionalTax;
}
setContextValueAddedTax(contextValueAddedTax){
this.contextValueAddedTax=contextValueAddedTax;
}
//计算附加税
async doActionAddtitionalTax(params){
return await this.contextAdditionalTax.doAction(params.businessmenType,params);
}
//计算增值税
async doActionValueAddedTax(params){
return await this.contextValueAddedTax.doAction(params.businessmenType,params);
}
//计算个人所的税
// async doActionIndividualIncomeTax(params.businessmenType,params){
// }
}
module.exports=Invoice;
\ No newline at end of file
const strategies = require('./strategiesBase');
/**
* 增值税的环境类
*
* 将注册的说有增值税算法实现都通过环境类调用
* @param{*} businessmenType 销售方类型
* @param{*} params 算法的参数
*/
class ContextValueAddedTax{
constructor (){
console.log("初始化 增资税环境类 ContextValueAddedTax");
}
async doAction (businessmenType,params){
return await strategies[businessmenType]['calcInvoice'](params);
}
}
module.exports=ContextValueAddedTax
\ No newline at end of file
/**
* 1 算法文件命名规则 : calInvoice + 销售方编码
* 2 如果算法中途出现异常 则需直接return
* 3 如果算法顺利执行 返回参数中除包含必须的四个税值外,还需要包含一个累计不含税价字段 字段名称为 "x1"
* 4 此文件必须提供 calcInvoice 和 formatParams 方法
*/
const system = require("../../../../system");
const applySve = system.getObject("service.invoice.applySve");
const Decimal = require('decimal.js');
const VAL_TAX = 2; //增值税
const PER_TAX = 1; //个税
/**
* 增值税 businessmen10(个体工商户) 算法实现
* 注意:1 由于销售方类型不同 所以算法不同 需要对参数验证单独处理
*/
module.exports.calcInvoice = async (params) => {
try {
//校验参数
verificationParams(params);
//计算累计不含税价
/**
* 累计不含税价
* @param {*} businessmenId 商户id
* @param {*} businessmenType 商户类型
* @param {*} businessmenCreditCode 统一社会信用代码
* @param {*} taxIncPriRat 不含税价百分比
* @param {*} invoiceAmount 发票总额
* @param {*} type 计算类型 1:个税 2:增值税
* @param {*} valCalWay 增值税计算类型 1:月 2:季度 3:年
* @param {*} perCalWay 个人所的税计算类型 1:月 2:季度 3:年
* @param {*} invoiceTime 格式 YYYY-MM-DD hh:mm:ss
*/
let x3 = await applySve.calAccumulatedPriceExcludingTax(params.businessmenId,params.businessmenType, params.businessmenCreditCode,
params.taxIncPriRat, params.invoiceAmount, VAL_TAX, params.valCalWay, null, params.invoiceTime);
console.log("增值税 累计不含税价总额:" + x3);
//根据 cumulativeProfitOfvalTax 查找对应梯度的个税税率
let calRateRangeResForVal = calRateRange(x3, params.valAddTaxRange, VAL_TAX);
let {valAddTaxRat} = calRateRangeResForVal;
//计算年累计的增值税
let cumulativeProfitOfvalTax = await applySve.calCumulativeProfit(params.businessmenId,params.businessmenType, VAL_TAX, params.valCalWay);
//计算增值税
let valueAddedTax = calValTax(x3, valAddTaxRat, cumulativeProfitOfvalTax);
return system.getResult(valueAddedTax);
} catch (error) {
return system.getResult(-1,`系统错误 错误信息 ${error}`);
}
}
/**
* 计算税率值
* @param {*} amount 金额
* @param {*} taxRange 税率范围
* @param {*} type 类型 1:个税 2 增值税
*/
let calRateRange = (amount, taxRange, type) => {
let res = {};
if (type === PER_TAX) {
for (let item of taxRange) {
if (item.minValue <= amount && amount <= item.maxValue) {
res.taxPer = item.rate;
res.quiCalDed = item.quiCalDed;
break;
}
}
} else {
for (let item of taxRange) {
if (item.minValue <= amount && amount <= item.maxValue) {
res.valAddTaxRat = item.zengzhiRate;
res.addTaxRat = item.fujiaRate;
break;
}
}
}
return res;
}
/**
* 计算增值税
* @param {*} x3 //累计不含说价
* @param {*} valAddTaxRat //增值税率
* @param {*} cumulativeProfitOfvalTax //累计缴纳的增值税
*/
let calValTax=(x3, valAddTaxRat, cumulativeProfitOfvalTax)=>{
if (valAddTaxRat == 0) {
return 0;
}
let res = new Decimal(x3).mul(valAddTaxRat).div(100).sub(cumulativeProfitOfvalTax).toFixed(2);
return res;
}
/**
* 校验各种费率 的合法性
* @param {*} params
* params
*/
let verificationParams = (params) => {
if(params.businessmenType != "10"){
system.getResult(-1,`参数错误 销售方类型非法`);
}
if(!params.businessmenCreditCode){
system.getResult(-1,`参数错误 销售方统一社会信用代码非法`);
}
if(params.taxIncPriRat>1){
system.getResult(-1,`参数错误 不含税价百分比不能大于1 例如 3% ,请传 0.03`);
}
if(!params.invoiceAmount){
system.getResult(-1,`参数错误 发票金额非法`);
}
}
\ No newline at end of file
/**
* 1 算法文件命名规则 : calInvoice + 销售方编码
* 2 如果算法中途出现异常 则需直接return
* 3 如果算法顺利执行 返回参数中除包含必须的四个税值外,还需要包含一个累计不含税价字段 字段名称为 "x1"
* 4 此文件必须提供 calcInvoice 和 formatParams 方法
*/
const system = require("../../../../system");
const applySve = system.getObject("service.invoice.applySve");
const Decimal = require('decimal.js');
const VAL_TAX = 2; //增值税
/**
* 增值税 businessmen10(个体工商户) 算法实现
* 注意:1 由于销售方类型不同 所以算法不同 需要对参数验证单独处理
*/
module.exports.calcInvoice = async (params) => {
try {
//校验参数
verificationParams();
//计算累计不含税价
/**
* 累计不含税价
* @param {*} businessmenId 商户id
* @param {*} businessmenType 商户类型
* @param {*} businessmenCreditCode 统一社会信用代码
* @param {*} taxIncPriRat 不含税价百分比
* @param {*} invoiceAmount 发票总额
* @param {*} type 计算类型 1:个税 2:增值税
* @param {*} valCalWay 增值税计算类型 1:月 2:季度 3:年
* @param {*} perCalWay 个人所的税计算类型 1:月 2:季度 3:年
* @param {*} invoiceTime 格式 YYYY-MM-DD hh:mm:ss
*/
let x3 = await applySve.calAccumulatedPriceExcludingTax(params.businessmenId,params.businessmenType, params.businessmenCreditCode,
params.taxIncPriRat, params.invoiceAmount, VAL_TAX, params.valCalWay, null, params.invoiceTime);
console.log("增值税 累计不含税价总额:" + x3);
//根据 cumulativeProfitOfvalTax 查找对应梯度的个税税率
let calRateRangeResForVal = calRateRange(x3, params.valAddTaxRange, VAL_TAX);
let {valAddTaxRat} = calRateRangeResForVal;
//计算年累计的增值税
let cumulativeProfitOfvalTax = await applySve.calCumulativeProfit(params.businessmenId,params.businessmenType, VAL_TAX, params.valCalWay);
//计算增值税
let valueAddedTax = calValTax(x3, valAddTaxRat, cumulativeProfitOfvalTax);
return valueAddedTax;
} catch (error) {
return system.getResult(-1,`系统错误 错误信息 ${error}`);
}
}
/**
* 计算税率值
* @param {*} amount 金额
* @param {*} taxRange 税率范围
* @param {*} type 类型 1:个税 2 增值税
*/
let calRateRange = (amount, taxRange, type) => {
let res = {};
if (type === PER_TAX) {
for (let item of taxRange) {
if (item.minValue <= amount && amount <= item.maxValue) {
res.taxPer = item.rate;
res.quiCalDed = item.quiCalDed;
break;
}
}
} else {
for (let item of taxRange) {
if (item.minValue <= amount && amount <= item.maxValue) {
res.valAddTaxRat = item.zengzhiRate;
res.addTaxRat = item.fujiaRate;
break;
}
}
}
return res;
}
/**
* 计算增值税
* @param {*} x3 //累计不含说价
* @param {*} valAddTaxRat //增值税率
* @param {*} cumulativeProfitOfvalTax //累计缴纳的增值税
*/
let calValTax=(x3, valAddTaxRat, cumulativeProfitOfvalTax)=>{
if (valAddTaxRat == 0) {
return 0;
}
let res = new Decimal(x3).mul(valAddTaxRat).div(100).sub(cumulativeProfitOfvalTax).toFixed(2);
return res;
}
/**
* 校验各种费率 的合法性
* @param {*} params
* params
*/
let verificationParams = (params) => {
if(params.businessmenType != "10"){
system.getResult(-1,`参数错误 销售方类型非法`);
}
if(!params.businessmenCreditCode){
system.getResult(-1,`参数错误 销售方统一社会信用代码非法`);
}
if(params.taxIncPriRat>1){
system.getResult(-1,`参数错误 不含税价百分比不能大于1 例如 3% ,请传 0.03`);
}
if(!params.invoiceAmount){
system.getResult(-1,`参数错误 发票金额非法`);
}
}
\ No newline at end of file
/**
* 导出所有的实现类
*/
module.exports={
//个体工商户
"calInvoice10":require("./calInvoice10"),
//自然人
"calInvoice20":require("./calInvoice20"),
}
\ No newline at end of file
/**
* 定义个增值税的所有接口
*
* 格式:JSON
* key: businessmenType (销售方类型)
* value:Fuction
*
* ps:如果要增加新的增值税算法,需要在此注册
*/
const impl = require('./impl');
module.exports={
//个体工商户
'10': impl.calInvoice10,
//自然人
'20': impl.calInvoice20
}
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment