MaiXinRong 1 год назад
Родитель
Сommit
ac8fdbf1c8

+ 0 - 7
app/controller/stage_controller.js

@@ -626,14 +626,7 @@ module.exports = app => {
                 let result;
                 switch (data.autoType) {
                     case 'bills':
-                        if (!data.cid || !data.cbid) throw '参数错误';
                         result = await ctx.service.stageChange.autoUseChangeBills(this.ctx.tender, this.ctx.stage, data.bills);
-                        result.change = { target: [] };
-                        for (const b of data.bills) {
-                            result.change.push({ lid: b.lid, pid: b.pid });
-                        }
-                        result.change.data = await ctx.service.stageChange.getLastestStageData(ctx.tender.id,
-                            ctx.stage.id, data.target.pos.lid, data.target.pos.id);
                         break;
                     case 'all':
                         result = await ctx.service.stageChange.autoUseAllChange(this.ctx.tender, this.ctx.stage);

+ 1 - 0
app/public/js/file_detail.js

@@ -391,6 +391,7 @@ $(document).ready(function() {
                 return !treeNode.source_node.is_fixed;
             },
             renameTitle: '编辑',
+            removeTitle: '删除',
             drag: {
                 isCopy: false,
                 isMove: true,

+ 68 - 68
app/public/js/stage.js

@@ -3900,39 +3900,39 @@ $(document).ready(() => {
                             return !changeBills;
                         }
                     },
-                    // 'autoUse': {
-                    //     name: '调用',
-                    //     icon: 'fa-play',
-                    //     callback: function (key, opt) {
-                    //         const curChange = SpreadJsObj.getSelectObject(self.changeSheet);
-                    //         const changeBills = SpreadJsObj.getSelectObject(self.changeBillsSheet);
-                    //         const billsPos = self.findBillsPos(curChange, changeBills);
-                    //         if (!billsPos) toastr.warning('无可调用的清单或计量单元');
-                    //
-                    //         const data = { autoType: 'bills', bills: [{ ...billsPos, cid: changeBills.cid, cbid: changeBills.cbid }] };
-                    //         postData(window.location.pathname + '/auto-change', data, function(result) {
-                    //             if (result.pos) {
-                    //                 stagePos.loadCurStageData(result.pos.curStageData);
-                    //             }
-                    //             const nodes = stageTree.loadPostStageData(result.bills);
-                    //             stageTreeSpreadObj.refreshTreeNodes(slSpread.getActiveSheet(), nodes);
-                    //             stagePosSpreadObj.loadCurPosData();
-                    //             if (detail) {
-                    //                 detail.loadStageChangeUpdateData(result, nodes);
-                    //             } else {
-                    //                 stageIm.loadUpdateChangeData(result, nodes)
-                    //             }
-                    //         });
-                    //     },
-                    //     disable: function (key, opt) {
-                    //         const curChange = SpreadJsObj.getSelectObject(self.changeSheet);
-                    //         const changeBills = SpreadJsObj.getSelectObject(self.changeBillsSheet);
-                    //         return !changeBills || curChange.is_import;
-                    //     },
-                    //     visible: function (key, opt) {
-                    //         return is_debug && stage.status === 1;
-                    //     }
-                    // },
+                    'autoUse': {
+                        name: '调用',
+                        icon: 'fa-play',
+                        callback: function (key, opt) {
+                            const curChange = SpreadJsObj.getSelectObject(self.changeSheet);
+                            const changeBills = SpreadJsObj.getSelectObject(self.changeBillsSheet);
+                            const billsPos = self.findBillsPos(curChange, changeBills);
+                            if (!billsPos) toastr.warning('无可调用的清单或计量单元');
+
+                            const data = { autoType: 'bills', bills: [{ ...billsPos, cid: changeBills.cid, cbid: changeBills.cbid }] };
+                            postData(window.location.pathname + '/auto-use-change', data, function(result) {
+                                if (result.pos) {
+                                    stagePos.loadCurStageData(result.pos.curStageData);
+                                }
+                                const nodes = stageTree.loadPostStageData(result.bills);
+                                stageTreeSpreadObj.refreshTreeNodes(slSpread.getActiveSheet(), nodes);
+                                stagePosSpreadObj.loadCurPosData();
+                                if (detail) {
+                                    detail.loadStageChangeUpdateData(result, nodes);
+                                } else {
+                                    stageIm.loadUpdateChangeData(result, nodes)
+                                }
+                            });
+                        },
+                        disable: function (key, opt) {
+                            const curChange = SpreadJsObj.getSelectObject(self.changeSheet);
+                            const changeBills = SpreadJsObj.getSelectObject(self.changeBillsSheet);
+                            return !changeBills || curChange.is_import;
+                        },
+                        visible: function (key, opt) {
+                            return is_debug && stage.status === 1;
+                        }
+                    },
                 }
             });
 
@@ -3943,40 +3943,40 @@ $(document).ready(() => {
                     return target.hitTestType === spreadNS.SheetArea.viewport || target.hitTestType === spreadNS.SheetArea.rowHeader;
                 },
                 items: {
-                    // 'autoUseCur': {
-                    //     name: '自动调用',
-                    //     icon: 'fa-play',
-                    //     callback: function (key, opt) {
-                    //         const curChange = SpreadJsObj.getSelectObject(self.changeSheet);
-                    //         const changeBills = SpreadJsObj.zh_data;
-                    //         const data = { bills: [], autoType: 'bills' };
-                    //         for (const cb of changeBills) {
-                    //             const billsPos = self.findBillsPos(curChange, cb);
-                    //             if (billsPos) data.push({ ...billsPos, cid: curChange.cid, cbid: cb.cbid })
-                    //         }
-                    //         postData(window.location.pathname + '/auto-use-change', data, function(result) {
-                    //             if (result.pos) {
-                    //                 stagePos.loadCurStageData(result.pos.curStageData);
-                    //             }
-                    //             const nodes = stageTree.loadPostStageData(result.bills);
-                    //             stageTreeSpreadObj.refreshTreeNodes(slSpread.getActiveSheet(), nodes);
-                    //             stagePosSpreadObj.loadCurPosData();
-                    //             if (detail) {
-                    //                 detail.loadStageChangeUpdateData(result, nodes);
-                    //             } else {
-                    //                 stageIm.loadUpdateChangeData(result, nodes)
-                    //             }
-                    //         });
-                    //     },
-                    //     disable: function (key, opt) {
-                    //         const curChange = SpreadJsObj.getSelectObject(self.changeSheet);
-                    //         const changeBills = SpreadJsObj.getSelectObject(self.changeBillsSheet);
-                    //         return !changeBills || curChange.is_import;
-                    //     },
-                    //     visible: function (key, opt) {
-                    //         return is_debug && stage.status === 1;
-                    //     }
-                    // },
+                    'autoUseCur': {
+                        name: '自动调用',
+                        icon: 'fa-play',
+                        callback: function (key, opt) {
+                            const curChange = SpreadJsObj.getSelectObject(self.changeSheet);
+                            const changeBills = self.changeBillsSheet.zh_data;
+                            const data = { bills: [], autoType: 'bills' };
+                            for (const cb of changeBills) {
+                                const billsPos = self.findBillsPos(curChange, cb);
+                                if (billsPos) data.bills.push({ ...billsPos, cid: cb.cid, cbid: cb.id })
+                            }
+                            postData(window.location.pathname + '/auto-use-change', data, function(result) {
+                                if (result.pos) {
+                                    stagePos.loadCurStageData(result.pos.curStageData);
+                                }
+                                const nodes = stageTree.loadPostStageData(result.bills);
+                                stageTreeSpreadObj.refreshTreeNodes(slSpread.getActiveSheet(), nodes);
+                                stagePosSpreadObj.loadCurPosData();
+                                if (detail) {
+                                    detail.loadStageChangeUpdateData(result, nodes);
+                                } else {
+                                    stageIm.loadUpdateChangeData(result, nodes)
+                                }
+                            });
+                        },
+                        disable: function (key, opt) {
+                            const curChange = SpreadJsObj.getSelectObject(self.changeSheet);
+                            const changeBills = SpreadJsObj.getSelectObject(self.changeBillsSheet);
+                            return !changeBills || curChange.is_import;
+                        },
+                        visible: function (key, opt) {
+                            return is_debug && stage.status === 1;
+                        }
+                    },
                     'autoUseAll': {
                         name: '自动调用(全部变更令)',
                         icon: 'fa-play',
@@ -4073,7 +4073,7 @@ $(document).ready(() => {
                 return null;
             } else if (changeBills.gcl_id) {
                 const node = stageTree.nodes.find(x => {return x.id === changeBills.gcl_id});
-                posData = stagePos.getLedgerPos(node.id);
+                posData = stagePos.getLedgerPos(node.id) || [];
                 const changePos = posData.find(x => { return x.name === changeBills.bwmx; });
                 return { lid: node.id, pid: changePos ? changePos.id : (posData.length > 0 ? posData[0].id : -1) };
             } else {

+ 138 - 35
app/service/stage_change.js

@@ -24,9 +24,11 @@ class autoUseChange {
         this.updateBills = [];
         this.updatePos = [];
         this.insertChange = [];
+        this.updateChange = [];
 
         this.changeBills = {};
         this.changePos = {};
+        this.changeDetail = [];
     }
 
     init(source) {
@@ -42,11 +44,12 @@ class autoUseChange {
 
         this.stageBills = source.stageBills;
         this.stagePos = source.stagePos;
+        this.stageChange = source.stageChange || [];
     }
 
     findBillsPos(changeBills){
         if (changeBills.gcl_id) {
-            const node = this.ledgerTree.nodes.find(x => {return x.id === changeBills.gcl_id});
+            const node = this.ledgerTree.datas.find(x => {return x.id === changeBills.gcl_id});
             const posData = this.pos.getLedgerPos(node.id) || [];
             const changePos = posData.find(x => { return x.name === changeBills.bwmx; });
             return { bills: node, lid: node.id, pid: changePos ? changePos.id : (posData.length > 0 ? posData[0].id : '-1') };
@@ -78,52 +81,116 @@ class autoUseChange {
     }
 
     useBills(bills) {
-        const billsPos = this.findBillsPos(bills);
+        if (bills.billsPos) bills.billsPos.bills = this.ledgerTree.datas.find(x => {return x.id === bills.billsPos.lid; });
+        const billsPos = bills.billsPos || this.findBillsPos(bills);
         if (!billsPos) return;
-        this.insertChange.push({
+        const bamount = parseFloat(bills.samount);
+        const minus = bamount < 0;
+        this.changeDetail.push({
             tid: this.default.tid, sid: this.default.sid,
             lid: billsPos.lid, pid: billsPos.pid, cid: bills.cid, cbid: bills.id,
-            qty: bills.valid_qty, stimes: 1, sorder: 0,
+            qty: bills.valid_qty, stimes: 1, sorder: 0, unit_price: bills.unit_price, minus, no_value: false,
         });
 
         if (billsPos.pid !== '-1') {
-            const cp = this.changePos[billsPos.pid];
+            let cp = this.changePos[billsPos.pid];
             if (!cp) {
-                this.changePos[billsPos.pid] = { lid: billsPos.lid, pid: billsPos.pid, qty: bills.valid_qty, bills: billsPos.bills };
+                cp = { lid: billsPos.lid, pid: billsPos.pid, qty: 0, bills: billsPos.bills };
+                this.changePos[billsPos.pid] = cp
+            }
+            cp.qty = this.helper.add(cp.qty, bills.valid_qty);
+            if (minus) {
+                cp.negative_qc_qty = cp.qty;
             } else {
-                cp.qty = this.helper.add(cp.qty, bills.valid_qty);
+                cp.positive_qc_qty = cp.qty;
             }
         } else {
-            const cb = this.changeBills[billsPos.lid];
+            let cb = this.changeBills[billsPos.lid];
             if (!cb) {
-                this.changeBills[billsPos.lid] = { lid: billsPos.lid, qty: bills.valid_qty, bills: billsPos.bills };
+                cb = { lid: billsPos.lid, qty: 0, bills: billsPos.bills };
+                this.changeBills[billsPos.lid] = cb;
+            }
+            cb.qty = this.helper.add(cb.qty, bills.valid_qty);
+            if (minus) {
+                cb.negative_qc_qty = this.helper.add(cb.negative_qc_qty, bills.valid_qty);
             } else {
-                cb.qty = this.helper.add(cb.qty, bills.valid_qty);
+                cb.positive_qc_qty = this.helper.add(cb.positive_qc_qty, bills.valid_qty);
             }
         }
     }
 
     calculateAll() {
+        for (const cd of this.changeDetail) {
+            const sci = this.stageChange.findIndex(x => {
+                return x.lid === cd.lid && x.pid === cd.pid && x.cbid === cd.cbid;
+            });
+            const sc = this.stageChange[sci];
+            if (sc) {
+                this.updateChange.push({ id: sc.id, qty: cd.qty });
+                this.stageChange.splice(sci, 1);
+            } else {
+                this.insertChange.push(cd);
+            }
+        }
+        for (const sc of this.stageChange) {
+            if (sc.no_value) continue;
+            const cp = this.changePos[sc.pid];
+            if (cp) {
+                cp.qty = this.helper.add(cp.qty, sc.qty);
+                if (sc.minus) {
+                    cp.negative_qc_qty = this.helper.add(cp.negative_qc_qty, sc.qty);
+                } else {
+                    cp.positive_qc_qty = this.helper.add(cp.positive_qc_qty, sc.qty);
+                }
+            }
+            const cb = this.changeBills[sc.lid];
+            if (cb) {
+                cb.qty = this.helper.add(cb.qty, sc.qty);
+                if (sc.minus) {
+                    cb.negative_qc_qty = this.helper.add(cb.negative_qc_qty, sc.qty);
+                } else {
+                    cb.positive_qc_qty = this.helper.add(cb.positive_qc_qty, sc.qty);
+                }
+            }
+        }
         for (const pid in this.changePos) {
             const cp = this.changePos[pid];
             if (!cp) continue;
 
             const precision = this.helper.findPrecision(this.precision, cp.bills.unit);
             const qc_qty = this.helper.round(cp.qty, precision.value);
+            const positive_qc_qty = this.helper.round(cp.positive_qc_qty || 0, precision.value);
+            const negative_qc_qty = this.helper.round(cp.negative_qc_qty || 0, precision.value);
             const sp = this.stagePos.find(x => {return x.pid === pid});
             if (sp) {
-                this.updatePos.push({ id: sp.id, qc_qty });
+                this.updatePos.push({ id: sp.id, qc_qty, positive_qc_qty, negative_qc_qty });
             } else {
                 this.insertPos.push({
                     tid: this.default.tid, sid: this.default.sid, said: this.default.said,
-                    lid: cp.lid, pid, qc_qty, times: 1, order: 0
+                    lid: cp.lid, pid, qc_qty, positive_qc_qty, negative_qc_qty, times: 1, order: 0
                 });
             }
             const cb = this.changeBills[cp.lid];
             if (!cb) {
-                this.changeBills[cp.lid] = { lid: cp.lid, qty: cp.qty, bills: cp.bills };
+                this.changeBills[cp.lid] = { lid: cp.lid, qty: qc_qty, positive_qc_qty, negative_qc_qty, bills: cp.bills };
             } else {
-                cb.qty = this.helper.add(cb.qty, cp.qty);
+                cb.qty = this.helper.add(cb.qty, qc_qty);
+                cb.positive_qc_qty = this.helper.add(cb.positive_qc_qty, positive_qc_qty);
+                cb.negative_qc_qty = this.helper.add(cb.negative_qc_qty, negative_qc_qty);
+            }
+        }
+        for (const sc of this.stageChange) {
+            if (sc.no_value) continue;
+            const cp = this.changePos[sc.pid];
+            if (cp) continue;
+            const cb = this.changeBills[sc.lid];
+            if (cb) {
+                cb.qty = this.helper.add(cb.qty, sc.qty);
+                if (sc.minus) {
+                    cb.negative_qc_qty = this.helper.add(cb.negative_qc_qty, sc.qty);
+                } else {
+                    cb.positive_qc_qty = this.helper.add(cb.positive_qc_qty, sc.qty);
+                }
             }
         }
         for (const lid in this.changeBills) {
@@ -132,13 +199,17 @@ class autoUseChange {
             const precision = this.helper.findPrecision(this.precision, cb.bills.unit);
             const qc_qty = this.helper.round(cb.qty, precision.value);
             const qc_tp = this.helper.mul(cb.qty, cb.bills.unit_price, this.decimal.tp);
+            const positive_qc_qty = this.helper.round(cb.positive_qc_qty || 0, precision.value);
+            const positive_qc_tp = this.helper.mul(positive_qc_qty, cb.bills.unit_price, this.decimal.tp);
+            const negative_qc_qty = this.helper.round(cb.negative_qc_qty || 0, precision.value);
+            const negative_qc_tp = this.helper.mul(negative_qc_qty, cb.bills.unit_price, this.decimal.tp);
             const sb = this.stageBills.find(x => {return x.lid === lid});
             if (sb) {
-                this.updateBills.push({ id: sb.id, qc_qty, qc_tp });
+                this.updateBills.push({ id: sb.id, qc_qty, qc_tp, positive_qc_qty, positive_qc_tp, negative_qc_qty, negative_qc_tp });
             } else {
                 this.insertBills.push({
                     tid: this.default.tid, sid: this.default.sid, said: this.default.said,
-                    lid, qc_qty, qc_tp, times: 1, order: 0
+                    lid, qc_qty, qc_tp, positive_qc_qty, positive_qc_tp, negative_qc_qty, negative_qc_tp, times: 1, order: 0
                 });
             }
         }
@@ -676,21 +747,53 @@ module.exports = app => {
         };
 
         async autoUseChangeBills(tender, stage, data) {
-            for (const d of data) {
-                const changeBills = await this.ctx.service.changeAuditList.getDataById(d.cbid);
-                const bills = await this.ctx.service.ledger.getDataById(data.lid);
-                const pos = await this.ctx.service.pos.getDataById(data.pid);
-                if (pos && pos.lid !== bills.id) throw '数据错误';
-
-                const allSc = await this.getAllDataByCondition({ where: { cbid: d.cbid, lid: data.lid, pid: data.pid } });
-                const curSc = this.ctx.helper.filterLastestData(allSc, ['lid', 'pid', 'cbid'], 'stimes', 'sorder');
-            }
-            const changeBills = await this.ctx.service.changeAuditList.getDataById(cbid);
-            const source = changeBills.gcl_id
-                ? await this.ctx.service.ledger.getDataByCondition({ where: { id: [changeBills.gcl_id] } })
-                : await this.ctx.service.ledger.getDataByCondition({ where: { tid: tender.id, b_code: changeBills.code, name: changeBills.name, unit: changeBills.unit, unit_price: changeBills.unit_price, is_leaf: true }});
-            if (source.length < 1) then
-            const pos = this.ctx.service.pos.getDataByCondition({ where: { lid: bills.id, name: changeBills.bwmx} });
+            const lid = [], cbid = [];
+            data.forEach(x => {
+                lid.push(x.lid);
+                cbid.push(x.cbid);
+            });
+            const validChangeBills = await this.ctx.service.stageChangeFinal.getListChangeBillsValidQty(tender.id, cbid);
+            validChangeBills.forEach(x => {
+                x.billsPos = data.find(y => { return x.id === y.cbid; });
+            });
+            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'],
+                where: { id: lid },
+            });
+            const extraData = await this.ctx.service.ledgerExtra.getData(this.ctx.tender.id, ['is_tp']);
+            this.ctx.helper.assignRelaData(ledgerData, [
+                { data: extraData, fields: ['is_tp'], prefix: '', relaId: 'id' },
+            ]);
+            const posData = await this.ctx.service.pos.getAllDataByCondition({
+                columns: ['id', 'lid', 'name', 'porder'],
+                where: { lid },
+            });
+            const stageBills = await this.ctx.service.stageBills.getAllDataByCondition({ where: { sid: stage.id } });
+            const stagePos = await this.ctx.service.stagePos.getAllDataByCondition({ where: { sid: stage.id } });
+            const stageChange = await this.ctx.service.stageChange.getAllDataByCondition({ where: { sid: stage.id, lid }});
+
+            const useModal = new autoUseChange(this.ctx.helper, tender.info);
+            useModal.use({ledgerData, posData, stageBills, stagePos, stageChange, default: { tid: stage.tid, sid: stage.id, said: this.ctx.session.sessionUser.accountId } }, validChangeBills);
+
+            const conn = await this.db.beginTransaction();
+            try {
+                if (useModal.insertBills.length > 0) await conn.insert(this.ctx.service.stageBills.tableName, useModal.insertBills);
+                if (useModal.updateBills.length > 0) await conn.updateRows(this.ctx.service.stageBills.tableName, useModal.updateBills);
+                if (useModal.insertPos.length > 0) await conn.insert(this.ctx.service.stagePos.tableName, useModal.insertPos);
+                if (useModal.updatePos.length > 0) await conn.updateRows(this.ctx.service.stagePos.tableName, useModal.updatePos);
+                if (useModal.insertChange.length > 0) await conn.insert(this.tableName, useModal.insertChange);
+                if (useModal.updateChange.length > 0) await conn.updateRows(this.tableName, useModal.updateChange);
+                await conn.commit();
+            } catch (err) {
+                await conn.rollback();
+                this.ctx.log(err);
+                throw '保存导入数据失败';
+            }
+
+            const rst = { bills: {}, pos: {} };
+            rst.bills.curStageData = await this.ctx.service.stageBills.getLastestStageData2(this.ctx.tender.id, this.ctx.stage.id, lid);
+            rst.pos.curStageData = await this.ctx.service.stagePos.getLastestStageData2(this.ctx.tender.id, this.ctx.stage.id, { lid });
+            return rst;
         };
 
         async autoUseAllChange(tender, stage) {
@@ -715,10 +818,10 @@ module.exports = app => {
 
             const conn = await this.db.beginTransaction();
             try {
-                if (useModal.insertBills.length > 0) conn.insert(this.ctx.service.stageBills.tableName, useModal.insertBills);
-                if (useModal.updateBills.length > 0) conn.updateRows(this.ctx.service.stageBills.tableName, useModal.updateBills);
-                if (useModal.insertPos.length > 0) conn.insert(this.ctx.service.stagePos.tableName, useModal.insertPos);
-                if (useModal.updatePos.length > 0) conn.updateRows(this.ctx.service.stagePos.tableName, useModal.updatePos);
+                if (useModal.insertBills.length > 0) await conn.insert(this.ctx.service.stageBills.tableName, useModal.insertBills);
+                if (useModal.updateBills.length > 0) await conn.updateRows(this.ctx.service.stageBills.tableName, useModal.updateBills);
+                if (useModal.insertPos.length > 0) await conn.insert(this.ctx.service.stagePos.tableName, useModal.insertPos);
+                if (useModal.updatePos.length > 0) await conn.updateRows(this.ctx.service.stagePos.tableName, useModal.updatePos);
                 await conn.delete(this.tableName, { sid: stage.id });
                 await conn.insert(this.tableName, useModal.insertChange);
                 await conn.commit();

+ 18 - 0
app/service/stage_change_final.js

@@ -89,6 +89,24 @@ module.exports = app => {
             return usedQty ? this.ctx.helper.sub(qty, usedQty.qty) : qty;
         }
 
+        async getListChangeBillsValidQty(tid, cbid) {
+            const self = this;
+            const sql = 'SELECT cal.*, scf.used_qty FROM ' + this.ctx.service.changeAuditList.tableName + ' cal' +
+                '  LEFT JOIN ' + this.ctx.service.change.tableName + ' c ON cal.cid = c.cid ' +
+                '  LEFT JOIN (' +
+                '    SELECT cbid, SUM(qty) as used_qty FROM ' + this.tableName + ' WHERE tid = ? GROUP BY cbid ' +
+                '  ) scf ON cal.id = scf.cbid ' +
+                '  ' + this.ctx.helper.whereSql({ id: cbid }, 'cal') + ' AND c.tid = ? AND c.valid AND c.status = ?';
+            const changeBills = await this.db.query(sql, [tid, tid, auditConst.status.checked]);
+            if (!changeBills || changeBills.length === 0) return [];
+
+            return changeBills.filter(cb => {
+                cb.qty = parseFloat(cb.samount);
+                cb.valid_qty = self.ctx.helper.sub(cb.qty, cb.used_qty);
+                return cb.valid_qty;
+            });
+        }
+
         async getAllChangeBillsValidQty(tid) {
             const self = this;
             const sql = 'SELECT cal.*, scf.used_qty FROM ' + this.ctx.service.changeAuditList.tableName + ' cal' +