Commit 766b3054 by 孙亚楠

dd

parent 4521fa81
{
// 使用 IntelliSense 了解相关属性。
// 悬停以查看现有属性的描述。
// 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"type": "node",
"request": "launch",
"name": "启动程序",
"program": "${workspaceFolder}/xggsve-invoice/main.js"
}
]
}
\ No newline at end of file
...@@ -24,7 +24,7 @@ var settings = { ...@@ -24,7 +24,7 @@ var settings = {
salt: "%iatpD1gcxz7iF#B", salt: "%iatpD1gcxz7iF#B",
defaultpwd: "987456", defaultpwd: "987456",
basepath: path.normalize(path.join(__dirname, '../..')), basepath: path.normalize(path.join(__dirname, '../..')),
port: process.env.NODE_PORT || 4001, port: process.env.NODE_PORT || 3105,
reqEsAddr: function () { reqEsAddr: function () {
if (this.env == "dev") { if (this.env == "dev") {
var localsettings = require("./localsettings"); var localsettings = require("./localsettings");
......
node_modules/
.idea
npm-debug.log
dump.rdb
.DS_Store
/.project
.package-lock.json
*.csv
.vscode/launch.json
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");
class ActionAPI extends APIBase { class ActionAPI extends APIBase {
constructor() { constructor() {
super(); super();
...@@ -27,74 +28,70 @@ class ActionAPI extends APIBase { ...@@ -27,74 +28,70 @@ class ActionAPI extends APIBase {
async sjbOpActionProcess(action_process, action_type, action_body) { async sjbOpActionProcess(action_process, action_type, action_body) {
var opResult = null; var opResult = null;
switch (action_type) { switch (action_type) {
case "verification": // 验证该商户是不是存在正在审核的发票
opResult = await this.applySve.apiVerificationByBusinessmenCreditCode(action_body); case "verificationAndCalculation": // 发票试算接口
break; opResult = await rule.dispatcher(action_body);
case "calcInvoice": // 发票试算接口
opResult = await this.applySve.apiCalcInvoice(action_body);
break; break;
case "saveInvoice": // 发票申请单提交接口 case "saveInvoice": // 发票保存
opResult = await this.applySve.apiSaveInvoice(action_body); opResult = await this.applySve.apiSaveInvoice(action_body);
break; break;
case "queryTxPayment": //查看完税证明
case "queryApplyInvoices": // 发票申请列表(平台) opResult = await this.invoiceSve.apiQueryTxPayment(action_body);
opResult = await this.applySve.apiQueryApplyInvoices(action_body);
break;
case "queryInvoices": // 发票列表(平台)
opResult = await this.invoiceSve.apiQueryInvoices(action_body);
break; break;
case "apiCancelInvoice": // 发票申请单撤回
case "delivererApplyInvoices": //发票申请列表(交付商) opResult = await this.applySve.apiCancelInvoice(action_body);
opResult = await this.delivererSve.apiDelivererApplyInvoices(action_body);
break; break;
case "delivererInvoices": //发票列表(交付商)
opResult = await this.delivererSve.apiDelInvs(action_body);
break;
case "queryInvoice": // 发票明细(平台) case "queryApplyInvoices": // 发票申请列表(平台)
opResult = await this.applySve.apiQueryInvoice(action_body); opResult = await this.applySve.apiQueryApplyInvoices(action_body);
break;
case "queryInvoiceDeliverer": // 发票明细(交付商)
opResult = await this.delivererSve.apiQueryInvoiceDeliverer(action_body);
break; break;
case "queryInvoices": // 发票列表(平台)
case "apiCancelInvoice": // 发票申请单撤回 opResult = await this.invoiceSve.apiQueryInvoices(action_body);
opResult = await this.applySve.apiCancelInvoice(action_body);
break; break;
case "queryProcess": // 查看业务办理(平台) case "queryInvoice": // 发票明细(平台)
opResult = await this.delivererSve.apiQueryProcess(action_body); opResult = await this.applySve.apiQueryInvoice(action_body);
break; break;
case "platformAssignment": // 平台审批 case "platformAssignment": // 平台审批
opResult = await this.applySve.apiAssignment(action_body); opResult = await this.applySve.apiAssignment(action_body);
break; break;
case "delivererAssignment": //交付商审批 case "updateEmail": //平台更新邮寄地址
opResult = await this.delivererSve.apiAssignment(action_body); opResult = await this.delivererSve.apiUpEmNo(action_body);
break;
case "txPayment": //完税证明更新
opResult = await this.invoiceSve.apiTxPayment(action_body);
break; break;
case "queryTxPayment": //完税证明更新 case "queryProcess": // 查看业务办理(平台)
opResult = await this.invoiceSve.apiQueryTxPayment(action_body); opResult = await this.delivererSve.apiQueryProcess(action_body);
break; break;
case "redRushInvoice": //红冲 case "redRushInvoice": //红冲
opResult = await this.applySve.apiRedRushInvoice(action_body); opResult = await this.applySve.apiRedRushInvoice(action_body);
break; break;
case "updateEmail": //平台更新邮寄地址 case "statTransData": //交易数据
opResult = await this.delivererSve.apiUpEmNo(action_body);
break;
case "statTransData": //交易数据
opResult = await this.applySve.apiStatTransData(action_body); opResult = await this.applySve.apiStatTransData(action_body);
break; break;
case "statBusinessData": //发票办理 case "statBusinessData": //发票办理
opResult = await this.applySve.apiStatBusinessData(action_body); opResult = await this.applySve.apiStatBusinessData(action_body);
break; break;
case "statDeliverData": //交付商业务概览 case "statDeliverData": //交付商业务概览
opResult = await this.delivererSve.apiStatDeliverData(action_body); opResult = await this.delivererSve.apiStatDeliverData(action_body);
break; break;
case "delStatTransData": //交易数据(交付商)
case "delivererApplyInvoices": //发票申请列表(交付商)
opResult = await this.delivererSve.apiDelivererApplyInvoices(action_body);
break;
case "delivererInvoices": //发票列表(交付商)
opResult = await this.delivererSve.apiDelInvs(action_body);
break;
case "queryInvoiceDeliverer": // 发票明细(交付商)
opResult = await this.delivererSve.apiQueryInvoiceDeliverer(action_body);
break;
case "delivererAssignment": //交付商审批
opResult = await this.delivererSve.apiAssignment(action_body);
break;
case "txPayment": //完税证明更新
opResult = await this.invoiceSve.apiTxPayment(action_body);
break;
case "delStatTransData": //交易数据(交付商)
opResult = await this.delivererSve.apiDelStatTransData(action_body); opResult = await this.delivererSve.apiDelStatTransData(action_body);
break; break;
case "delStatBusinessData": //发票办理(交付商) case "delStatBusinessData": //发票办理(交付商)
opResult = await this.delivererSve.apiDelStatBusinessData(action_body); opResult = await this.delivererSve.apiDelStatBusinessData(action_body);
break; break;
default: default:
......
...@@ -19,6 +19,7 @@ module.exports = (db, DataTypes) => { ...@@ -19,6 +19,7 @@ module.exports = (db, DataTypes) => {
merchantAccount: {type: DataTypes.STRING,field: 'merchant_account', allowNull: false, comment:'账号' }, merchantAccount: {type: DataTypes.STRING,field: 'merchant_account', allowNull: false, comment:'账号' },
//销售方信息 //销售方信息
businessmenType:{type: DataTypes.STRING,field: 'businessmen_type', allowNull: false, comment:'销售方类型 10 个体工商户 20 自然人' },
businessmenId:{type: DataTypes.STRING,field: 'businessmen_id', allowNull: false, comment:'销售方id' }, businessmenId:{type: DataTypes.STRING,field: 'businessmen_id', allowNull: false, comment:'销售方id' },
businessmenCreditCode:{type: DataTypes.STRING,field: 'businessmen_credit_code', allowNull: false, comment:'个体户社会统一信息用代码' }, businessmenCreditCode:{type: DataTypes.STRING,field: 'businessmen_credit_code', allowNull: false, comment:'个体户社会统一信息用代码' },
businessmenName:{type: DataTypes.STRING,field: 'businessmen_name', allowNull: false, comment:'销售方名称' }, businessmenName:{type: DataTypes.STRING,field: 'businessmen_name', allowNull: false, comment:'销售方名称' },
...@@ -32,6 +33,8 @@ module.exports = (db, DataTypes) => { ...@@ -32,6 +33,8 @@ module.exports = (db, DataTypes) => {
//发票信息 //发票信息
// invoiceNo:{type: DataTypes.STRING,field: 'invoice_no', allowNull: true, comment:'发票编号' }, // invoiceNo:{type: DataTypes.STRING,field: 'invoice_no', allowNull: true, comment:'发票编号' },
type:{type: DataTypes.INTEGER,field: 'type', allowNull: false, defaultValue:10, comment:'发票类型:10 普通发票 20 增值税专用发票 30 电子发票' }, type:{type: DataTypes.INTEGER,field: 'type', allowNull: false, defaultValue:10, comment:'发票类型:10 普通发票 20 增值税专用发票 30 电子发票' },
ruleCode:{type: DataTypes.STRING,field: 'rule_code', allowNull: false, comment:'算法编码 10 个体工商户算法 20 自然人算法 ...'},
ruleParams:{type: DataTypes.STRING,field: 'rule_params', allowNull: false, comment:'算法参数编码 10 个体工商户算法参数 20 自然人算法参数 ...'},
invoiceAmount:{type: DataTypes.BIGINT,field: 'invoice_amount', allowNull: false, comment:'发票总额' }, invoiceAmount:{type: DataTypes.BIGINT,field: 'invoice_amount', allowNull: false, comment:'发票总额' },
statements:{type: DataTypes.STRING,field: 'statements', allowNull: false, comment:'结算单' }, statements:{type: DataTypes.STRING,field: 'statements', allowNull: false, comment:'结算单' },
contract:{type: DataTypes.STRING,field: 'contract', allowNull: false, comment:'合同' }, contract:{type: DataTypes.STRING,field: 'contract', allowNull: false, comment:'合同' },
......
...@@ -8,18 +8,20 @@ module.exports = (db, DataTypes) => { ...@@ -8,18 +8,20 @@ module.exports = (db, DataTypes) => {
return db.define("invoice", { return db.define("invoice", {
applyNo:{type: DataTypes.STRING,field: 'apply_no', allowNull: false, comment:'发票申请号' }, applyNo:{type: DataTypes.STRING,field: 'apply_no', allowNull: false, comment:'发票申请号' },
merchantId: {type: DataTypes.STRING,field: 'merchant_id', allowNull: true, comment:'个体工商户id(购买方id)' }, merchantId: {type: DataTypes.STRING,field: 'merchant_id', allowNull: true, comment:'个体工商户id(购买方id)' },
businessmenType:{type: DataTypes.STRING,field: 'businessmen_type', allowNull: false, comment:'销售方类型 10 个体工商户 20 自然人' },
businessmenId:{type: DataTypes.STRING,field: 'businessmen_id', allowNull: false, comment:'销售方id' },
ruleCode:{type: DataTypes.STRING,field: 'rule_code', allowNull: false, comment:'算法编码 10 个体工商户算法 20 自然人算法 ...'},
ruleParams:{type: DataTypes.STRING,field: 'rule_params', allowNull: false, comment:'算法参数编码 10 个体工商户算法参数 20 自然人算法参数 ...'},
status:{ type: DataTypes.INTEGER, field: 'status', allowNull: true, comment:'审核状态 1030 待处理 1040 交付商关闭 1050 已开具 1060 代审核 1070 审核通过 1080 已邮寄'}, status:{ type: DataTypes.INTEGER, field: 'status', allowNull: true, comment:'审核状态 1030 待处理 1040 交付商关闭 1050 已开具 1060 代审核 1070 审核通过 1080 已邮寄'},
//已开具 //已开具
invoiceNo:{type: DataTypes.STRING,field: 'invoice_no', allowNull: true, comment:'发票编号' }, invoiceNo:{type: DataTypes.STRING,field: 'invoice_no', allowNull: true, comment:'发票编号' },
invoiceTime: { type: DataTypes.DATE, field: 'invoice_time', allowNull: true, defaultValue: DataTypes.NOW,comment:'开票时间', invoiceTime: { type: DataTypes.DATE, field: 'invoice_time', allowNull: true, defaultValue: DataTypes.NOW,comment:'开票时间'},
get() {
let res = moment(this.getDataValue('updatedAt')).add(8).format('YYYY-MM-DD HH:mm:ss');
return res;
}
},
invoiceImg:{type: DataTypes.STRING,field: 'invoice_img', allowNull: true, comment:'发票照片' }, invoiceImg:{type: DataTypes.STRING,field: 'invoice_img', allowNull: true, comment:'发票照片' },
//拒绝原因 //拒绝原因
//reason:{type: DataTypes.STRING,field: 'reason', allowNull: true, comment:'拒绝原因' }, //reason:{type: DataTypes.STRING,field: 'reason', allowNull: true, comment:'拒绝原因' },
//完税 //完税
taxNo:{type: DataTypes.STRING,field: 'tax_no', allowNull: true, comment:'完税批号'}, taxNo:{type: DataTypes.STRING,field: 'tax_no', allowNull: true, comment:'完税批号'},
complateTax: {type:DataTypes.INTEGER,field: 'complate_tax', allowNull: true, defaultValue:0,comment:'是否完税 0 未完成 1 已完成', complateTax: {type:DataTypes.INTEGER,field: 'complate_tax', allowNull: true, defaultValue:0,comment:'是否完税 0 未完成 1 已完成',
...@@ -28,30 +30,14 @@ module.exports = (db, DataTypes) => { ...@@ -28,30 +30,14 @@ module.exports = (db, DataTypes) => {
var v = isInvalid=='1'?"已完成":"未完成"; var v = isInvalid=='1'?"已完成":"未完成";
return v; return v;
},}, },},
taxTime: { type: DataTypes.DATE, field: 'tax_time', allowNull: true, defaultValue: DataTypes.NOW,comment:'完税时间', taxTime: { type: DataTypes.DATE, field: 'tax_time', allowNull: true, defaultValue: DataTypes.NOW,comment:'完税时间'},
get() {
let res = moment(this.getDataValue('taxTime')).add(8).format('YYYY-MM-DD HH:mm:ss');
return res;
}},
taxVoucher:{type: DataTypes.STRING,field: 'tax_voucher', allowNull: true, comment:'完税照片' }, taxVoucher:{type: DataTypes.STRING,field: 'tax_voucher', allowNull: true, comment:'完税照片' },
//邮寄相关 //邮寄相关
mailNo:{type: DataTypes.STRING,field: 'mail_no', allowNull: true, comment:'快递单号' }, mailNo:{type: DataTypes.STRING,field: 'mail_no', allowNull: true, comment:'快递单号' },
redStatus:{ type: DataTypes.STRING, field: 'red_status', allowNull: false, defaultValue: '1',comment:'红冲状态 1:未红冲 2:红冲中 3 红冲失败 4 红冲成功' },
redStatus:{ type: DataTypes.STRING, field: 'red_status', allowNull: false, defaultValue: '1', createdAt: { type: DataTypes.DATE, field: 'created_at', allowNull: false, defaultValue: DataTypes.NOW,comment:'发票创建时间'},
comment:'红冲状态 1:未红冲 2:红冲中 3 红冲失败 4 红冲成功' updatedAt: { type: DataTypes.DATE, field: 'updated_at', allowNull: false, defaultValue: DataTypes.NOW ,comment:'更新时间'},
},
createdAt: { type: DataTypes.DATE, field: 'created_at', allowNull: false, defaultValue: DataTypes.NOW,comment:'发票创建时间',
get() {
let res = moment(this.getDataValue('createdAt')).add(8).format('YYYY-MM-DD HH:mm:ss');
return res;
}},
updatedAt: { type: DataTypes.DATE, field: 'updated_at', allowNull: false, defaultValue: DataTypes.NOW ,comment:'更新时间',
get() {
let res = moment(this.getDataValue('updatedAt')).add(8).format('YYYY-MM-DD HH:mm:ss');
return res;
}},
deletedAt: { type: DataTypes.DATE, field: 'deleted_at', allowNull: true, comment:'删除时间'}, deletedAt: { type: DataTypes.DATE, field: 'deleted_at', allowNull: true, comment:'删除时间'},
},{ },{
timestamps: true, timestamps: true,
......
/**
* 1 算法文件命名规则 : calInvoice + 销售方编码
* 2 如果算法中途出现异常 则需直接return
* 3 如果算法顺利执行 返回参数中除包含必须的四个税值外,还需要包含一个累计不含税价字段 字段名称为 "x1"
*/
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 由于销售方类型不同 所以算法不同 需要对参数验证单独处理
*/
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 {*} 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 {*} 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 > 10000 || params.serviceRate > 10000 || params.taxCostPriRat > 10000) {
return system.getResult(-1,`参数错误 费率不合法`);
} else {
params.taxIncPriRat = new Decimal(params.taxIncPriRat).div(10000).toFixed(4);
params.taxCostPriRat = new Decimal(params.taxCostPriRat).div(10000).toFixed(4);
params.serviceRate = new Decimal(params.serviceRate).div(10000).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
},
"20":{
MAX_AMOUNT:400000000,
WARNING_AMOUNT:300000000
}
}
\ 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 businessmenType = common.trim(params.businessmenType);
let filePath =`./algorithm/calInvoice${businessmenType}`;
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
...@@ -24,7 +24,7 @@ var settings = { ...@@ -24,7 +24,7 @@ var settings = {
salt: "%iatpD1gcxz7iF#B", salt: "%iatpD1gcxz7iF#B",
defaultpwd: "987456", defaultpwd: "987456",
basepath: path.normalize(path.join(__dirname, '../..')), basepath: path.normalize(path.join(__dirname, '../..')),
port: process.env.NODE_PORT || 4001, port: process.env.NODE_PORT || 3105,
reqEsAddr: function () { reqEsAddr: function () {
if (this.env == "dev") { if (this.env == "dev") {
var localsettings = require("./localsettings"); var localsettings = require("./localsettings");
......
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