|
@@ -8,6 +8,120 @@
|
|
|
* @version
|
|
|
*/
|
|
|
|
|
|
+class loadStageExcelTree {
|
|
|
+ constructor(ctx) {
|
|
|
+ this.ctx = ctx;
|
|
|
+
|
|
|
+ this.decimal = ctx.tender.info.decimal;
|
|
|
+
|
|
|
+ this.insertBills = [];
|
|
|
+ this.insertPos = [];
|
|
|
+ this.updateBills = [];
|
|
|
+ this.updatePos = [];
|
|
|
+ }
|
|
|
+ init(source) {
|
|
|
+ this.default = source.default;
|
|
|
+
|
|
|
+ const LedgerModel = require('../lib/ledger');
|
|
|
+ this.ledgerTree = new LedgerModel.billsTree(this.ctx, {
|
|
|
+ id: 'ledger_id', pid: 'ledger_pid', order: 'order', level: 'level', rootId: -1, calcFields: [],
|
|
|
+ });
|
|
|
+ this.pos = new LedgerModel.pos({ id: 'id', ledgerId: 'lid' });
|
|
|
+ this.ledgerTree.loadDatas(source.ledgerData);
|
|
|
+ this.pos.loadDatas(source.posData);
|
|
|
+
|
|
|
+ this.stageBills = source.stageBills;
|
|
|
+ this.stagePos = source.stagePos;
|
|
|
+ }
|
|
|
+ findNode(node, parent) {
|
|
|
+ const _ = this.ctx.helper._;
|
|
|
+ const sibling = parent ? parent.children : this.ledgerTree.children;
|
|
|
+ const self = this;
|
|
|
+ return sibling.find(x => {
|
|
|
+ if (node.is_leaf !== x.is_leaf) return false;
|
|
|
+
|
|
|
+ if (node.b_code) {
|
|
|
+ if (x.has_pos === undefined) {
|
|
|
+ const relaPos = self.pos.getLedgerPos(x.id);
|
|
|
+ x.has_pos = !!relaPos && relaPos.length > 0;
|
|
|
+ }
|
|
|
+ return node.b_code === _.trimEnd(x.b_code) && node.name === _.trimEnd(x.name) && node.unit === _.trimEnd(x.unit)
|
|
|
+ && node.unit_price === x.unit_price && node.has_pos === x.has_pos ;
|
|
|
+ } else {
|
|
|
+ return node.code === _.trimEnd(x.code) && node.name === _.trimEnd(x.name);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
+ loadLeaf(node, source) {
|
|
|
+ const curStageBills = this.stageBills.find(csb => { return csb.lid === source.id; });
|
|
|
+ if (node.has_pos) {
|
|
|
+ const sourcePos = this.pos.getLedgerPos(source.id);
|
|
|
+ const sourceStagePos = this.stagePos.filter(sp => { return sp.lid === source.id; });
|
|
|
+
|
|
|
+ let contract_qty = 0;
|
|
|
+ for (const p of node.pos) {
|
|
|
+ if (!p.contract_qty) continue;
|
|
|
+ const sp = sourcePos.find(x => { return x.name === p.name; });
|
|
|
+ if (!sp) continue;
|
|
|
+
|
|
|
+ contract_qty = this.ctx.helper.add(contract_qty, p.contract_qty);
|
|
|
+ let ssp = sourceStagePos.find(x => { return x.lid === sp.id; });
|
|
|
+ sourceStagePos.splice(sourceStagePos.indexOf(ssp), 1);
|
|
|
+ if (ssp) {
|
|
|
+ this.updatePos.push({ id: ssp.id, contract_qty: p.contract_qty });
|
|
|
+ } else {
|
|
|
+ this.insertPos.push({ tid: this.default.tid, sid: this.default.sid, said: this.default.said, times: 1, order: 0, lid: source.id, contract_qty: p.contract_qty });
|
|
|
+ }
|
|
|
+ }
|
|
|
+ for (const ssp of sourceStagePos) {
|
|
|
+ contract_qty = this.ctx.helper.add(contract_qty, ssp.contract_qty);
|
|
|
+ }
|
|
|
+ const contract_tp = this.ctx.helper.mul(contract_qty, source.unit_price, this.decimal.tp);
|
|
|
+ if (curStageBills) {
|
|
|
+ this.updateBills.push({ id: curStageBills.id, contract_qty, contract_tp });
|
|
|
+ } else {
|
|
|
+ this.insertBills.push({ tid: this.default.tid, sid: this.default.sid, said: this.default.said, times: 1, order: 0, lid: source.id, contract_qty, contract_tp });
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ if (!node.contract_qty && !node.contract_tp) return;
|
|
|
+ const contract_qty = node.contract_qty;
|
|
|
+ const contract_tp = contract_qty
|
|
|
+ ? this.ctx.helper.mul(contract_qty, source.unit_price, this.decimal.tp)
|
|
|
+ : this.ctx.helper.round(contract_tp, this.decimal.tp);
|
|
|
+
|
|
|
+ if (curStageBills) {
|
|
|
+ this.updateBills.push({ id: curStageBills.id, contract_qty: contract_qty, contract_tp: contract_tp });
|
|
|
+ } else {
|
|
|
+ this.insertBills.push({ tid: this.default.tid, sid: this.default.sid, said: this.default.said, times: 1, order: 0, lid: source.id, contract_qty: contract_qty, contract_tp: contract_tp });
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ loadNode(node, parent) {
|
|
|
+ node.is_leaf = !node.children || node.children.length === 0 ? 1 : 0;
|
|
|
+ node.has_pos = node.pos && node.pos.length > 0;
|
|
|
+ const cur = this.findNode(node, parent);
|
|
|
+ if (!cur) return;
|
|
|
+
|
|
|
+ if (cur) {
|
|
|
+ if (node.is_leaf) {
|
|
|
+ this.loadLeaf(node, cur);
|
|
|
+ } else {
|
|
|
+ for (const c of node.children) {
|
|
|
+ this.loadNode(c, cur);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ load(excelTree, source) {
|
|
|
+ this.init(source);
|
|
|
+
|
|
|
+ for (const node of excelTree.roots) {
|
|
|
+ this.loadNode(node, null);
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
module.exports = app => {
|
|
|
class StageStash extends app.BaseService {
|
|
|
/**
|
|
@@ -174,6 +288,55 @@ module.exports = app => {
|
|
|
throw err;
|
|
|
}
|
|
|
};
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 导入Excel期计量(仅导入合同计量)
|
|
|
+ * 该方法本应该独立或者在stage下,但是跟stage_stash业务非常类似,暂归类于此
|
|
|
+ * @param stage
|
|
|
+ * @param sheet
|
|
|
+ * @returns {Promise<void>}
|
|
|
+ */
|
|
|
+ async loadExcelSheet(stage, excelData) {
|
|
|
+ const AnalysisExcel = require('../lib/analysis_excel').AnalysisStageExcelTree;
|
|
|
+ const analysisExcel = new AnalysisExcel(this.ctx, this.ctx.service.ledger.setting);
|
|
|
+
|
|
|
+ try {
|
|
|
+ const templateId = await this.ctx.service.valuation.getValuationTemplate(
|
|
|
+ this.ctx.tender.data.valuation, this.ctx.tender.data.measure_type);
|
|
|
+ const tempData = await this.ctx.service.tenderNodeTemplate.getData(templateId, true);
|
|
|
+ const cacheTree = analysisExcel.analysisData(excelData, tempData, { filterZeroGcl: false });
|
|
|
+
|
|
|
+ const ledgerData = await this.ctx.service.ledger.getAllDataByCondition({
|
|
|
+ columns: ['id', 'ledger_id', 'ledger_pid', 'level', 'order', 'full_path', 'is_leaf', 'code', 'b_code', 'name', 'unit', 'unit_price', 'is_tp'],
|
|
|
+ where: { tender_id: stage.tid},
|
|
|
+ });
|
|
|
+ const posData = await this.ctx.service.pos.getAllDataByCondition({
|
|
|
+ columns: ['id', 'lid', 'name', 'porder'],
|
|
|
+ where: { tid: stage.tid },
|
|
|
+ });
|
|
|
+ const stageBills = await this.ctx.service.stageBills.getAllDataByCondition({ where: { tid: stage.tid }});
|
|
|
+ const stagePos = await this.ctx.service.stagePos.getAllDataByCondition({ where: { tid: stage.tid }});
|
|
|
+
|
|
|
+ const loadModal = new loadStageExcelTree(this.ctx);
|
|
|
+ loadModal.load(cacheTree, {ledgerData, posData, stageBills, stagePos, default: { tid: stage.tid, sid: stage.id, said: this.ctx.session.sessionUser.accountId } });
|
|
|
+
|
|
|
+ const conn = await this.db.beginTransaction();
|
|
|
+ try {
|
|
|
+ if (loadModal.insertBills.length > 0) conn.insert(this.ctx.service.stageBills.tableName, loadModal.insertBills);
|
|
|
+ if (loadModal.updateBills.length > 0) conn.updateRows(this.ctx.service.stageBills.tableName, loadModal.updateBills);
|
|
|
+ if (loadModal.insertPos.length > 0) conn.insert(this.ctx.service.stagePos.tableName, loadModal.insertPos);
|
|
|
+ if (loadModal.updatePos.length > 0) conn.updateRows(this.ctx.service.stagePos.tableName, loadModal.updatePos);
|
|
|
+ await conn.commit();
|
|
|
+ } catch (err) {
|
|
|
+ await conn.rollback();
|
|
|
+ this.ctx.log(err);
|
|
|
+ throw '保存导入数据失败';
|
|
|
+ }
|
|
|
+ } catch (err) {
|
|
|
+ this.ctx.log(err);
|
|
|
+ throw '解析Excel错误';
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
return StageStash;
|