瀏覽代碼

调差计量来源功能no.1 up

ellisran 1 年之前
父節點
當前提交
2a485a5b22

+ 26 - 0
app/const/material.js

@@ -74,6 +74,30 @@ const is_summary = {
     no: 2,
 };
 
+const qty_source = [
+    {
+        value: 1,
+        name: '完成计量',
+        key: 'gather_qty',
+    },
+    {
+        value: 2,
+        name: '合同计量',
+        key: 'contract_qty',
+    },
+    {
+        value: 3,
+        name: '完成计量(含不计价变更)',
+        key: 'gather_minus_qty',
+    },
+];
+const qty_source_value = {
+    gather_qty: 1,
+    contract_qty: 2,
+    gather_minus_qty: 3,
+};
+
+
 module.exports = {
     t_type,
     m_type,
@@ -82,4 +106,6 @@ module.exports = {
     ex_calc,
     ex_basic_text,
     decimal,
+    qty_source,
+    qty_source_value,
 };

+ 16 - 6
app/controller/material_controller.js

@@ -55,6 +55,8 @@ module.exports = app => {
                     auditConst,
                     auditConst2: JSON.stringify(auditConst),
                     materialColShow: material_col_show,
+                    qtySourceConst: materialConst.qty_source,
+                    qtySourceValueConst: materialConst.qty_source_value,
                 };
                 let openMaterialTax = ctx.session.sessionProject.page_show.openMaterialTax;
                 let allMaterialTax = true;
@@ -280,6 +282,8 @@ module.exports = app => {
                 preUrl: '/tender/' + ctx.tender.id + '/measure/material/' + ctx.params.order,
                 material: ctx.material,
                 shenpiConst,
+                qtySourceConst: materialConst.qty_source,
+                qtySourceValueConst: materialConst.qty_source_value,
             };
             if ((ctx.material.status === auditConst.status.uncheck || ctx.material.status === auditConst.status.checkNo) && (ctx.session.sessionUser.accountId === ctx.material.user_id || ctx.tender.isTourist)) {
                 // data.accountGroup = accountGroup;
@@ -834,6 +838,7 @@ module.exports = app => {
                 const newDecimalUp = parseInt(data.up);
                 const newDecimalTp = parseInt(data.tp);
                 const newDecimalQty = parseInt(data.qty);
+                const newQtySource = parseInt(data.qty_source);
                 if (ctx.app._.isNaN(newDecimalUp) || newDecimalUp > 6 || newDecimalUp < 0) {
                     throw '单价小数位数设置不能大于6或小于0';
                 }
@@ -843,14 +848,19 @@ module.exports = app => {
                 if (ctx.app._.isNaN(newDecimalQty) || newDecimalQty > 6 || newDecimalQty < 0) {
                     throw '数量小数位数设置不能大于6或小于0';
                 }
-                if (ctx.material.decimal.up === newDecimalUp && ctx.material.decimal.tp === newDecimalTp && ctx.material.decimal.qty === newDecimalQty) {
-                    throw '小数位数设置未发生变化';
+                if (ctx.material.decimal.up === newDecimalUp && ctx.material.decimal.tp === newDecimalTp && ctx.material.decimal.qty === newDecimalQty && newQtySource === ctx.material.qty_source) {
+                    throw '设置内容未发生变化';
                 }
-                const result = await ctx.service.material.saveDecimal(newDecimalUp, newDecimalTp, newDecimalQty);
-                if (!result) {
-                    throw '小数位数设置失败';
+                if (ctx.material.decimal.up !== newDecimalUp || ctx.material.decimal.tp !== newDecimalTp || ctx.material.decimal.qty !== newDecimalQty) {
+                    const result = await ctx.service.material.saveDecimal(newDecimalUp, newDecimalTp, newDecimalQty);
+                    if (!result) {
+                        throw '小数位数设置失败';
+                    }
+                }
+                if (newQtySource !== ctx.material.qty_source) {
+                    const result = await ctx.service.material.saveQtySource(newQtySource);
                 }
-                this.setMessage('设置小数位数成功', this.messageType.SUCCESS);
+                this.setMessage('设置成功', this.messageType.SUCCESS);
             } catch (err) {
                 console.log(err);
                 this.log(err);

+ 18 - 0
app/extend/helper.js

@@ -26,6 +26,7 @@ const crypto = require('crypto');
 const jwt = require('jsonwebtoken');
 const sign = require('../const/sign');
 const xml2js = require('xml2js');
+const qtySourceValueConst = require('../const/material').qty_source_value;
 module.exports = {
     _,
 
@@ -1654,5 +1655,22 @@ module.exports = {
         } catch (err) {
             console.log(err);
         }
+    },
+    getQtySource(qty_source) {
+        let qty = '';
+        switch (qty_source) {
+            case qtySourceValueConst.gather_qty: qty = '`gather_qty`'; break;
+            case qtySourceValueConst.contract_qty: qty = '`contract_qty`'; break;
+            case qtySourceValueConst.gather_minus_qty: qty = '(`gather_qty`+`qc_minus_qty`)'; break;
+            default: throw '未配置计量来源出错';
+        }
+        return qty;
+    },
+    resetQtys(qtys) {
+        qtys.gather_qty = qtys.gather_qty ? qtys.gather_qty : null;
+        qtys.contract_qty = qtys.contract_qty ? qtys.contract_qty : null;
+        qtys.qc_qty = qtys.qc_qty ? qtys.qc_qty : null;
+        qtys.qc_minus_qty = qtys.qc_minus_qty ? qtys.qc_minus_qty : null;
+        return qtys;
     }
 };

+ 66 - 6
app/public/js/material.js

@@ -1230,7 +1230,7 @@ $(document).ready(() => {
                         gclGatherModel.loadLedgerData(_.cloneDeep(ledger), s);
                         gclGatherModel.loadPosData(_.cloneDeep(pos), result.posListData[index]);
                         const oneGclGatherData = gclGatherModel.gatherGclData().filter(item => {
-                            return item.qc_qty || item.contract_qty
+                            return item.qc_qty || item.contract_qty || item.qc_minus_qty
                         });
                         newGclGatherListData.push(oneGclGatherData);
                     }
@@ -1241,7 +1241,7 @@ $(document).ready(() => {
                 gclGatherModel.loadPosData(_.cloneDeep(pos), curPosData);
                 gclGatherData = gclGatherModel.gatherGclData();
                 gclGatherData = gclGatherData.filter(item => {
-                    return item.qc_qty || item.contract_qty
+                    return item.qc_qty || item.contract_qty || item.qc_minus_qty
                 });
                 if (openMaterialChecklist) {
                     // 取交集
@@ -1267,12 +1267,62 @@ $(document).ready(() => {
                 console.log(gclGatherData);
                 setCurBillSourceList(materialBillsData[0] ? materialBillsData[0].mb_id || materialBillsData[0].id : null, ms_id);
                 first = false;
+
+                // 判断是否需要更新contract_qty、qc_qty和qc_minus_qty
+                if (!materialIsNewQty && !readOnly && !editForAudit) {
+                    let needUpdateList = [];
+                    if (materialListData2.length > 0) {
+                        if (isStageSelf) {
+                            for (const msIndex in materialStageData) {
+                                const materialStageList = _.filter(materialListData2, { ms_id: materialStageData[msIndex].id });
+                                const gclIdList = _.uniq(_.map(materialListData2, 'gcl_id'));
+                                let leafXmjList = [];
+                                for (const id of gclIdList) {
+                                    const gcl = _.find(gclGatherListData[msIndex], function (item) {
+                                        return item.leafXmjs && item.leafXmjs.length > 0 && _.findIndex(item.leafXmjs, {gcl_id: id}) !== -1;
+                                    });
+                                    if (gcl) leafXmjList = [...leafXmjList, ...gcl.leafXmjs];
+                                }
+                                for (const ml of materialStageList) {
+                                    const leafXmjInfo = _.find(leafXmjList, function (item) {
+                                        return item.gcl_id === ml.gcl_id && item.id === ml.xmj_id && (item.mx_id === undefined || (item.mx_id !== undefined && item.mx_id === ml.mx_id));
+                                    });
+                                    if (leafXmjInfo) {
+                                        needUpdateList.push({ id: ml.id, contract_qty: leafXmjInfo.contract_qty, qc_qty: leafXmjInfo.qc_qty, qc_minus_qty: leafXmjInfo.qc_minus_qty });
+                                    }
+                                }
+                            }
+                        } else {
+                            // 找出所有gcl相同的,方便搜索gclGatherData值
+                            const gclIdList = _.uniq(_.map(materialListData2, 'gcl_id'));
+                            let leafXmjList = [];
+                            for (const id of gclIdList) {
+                                const gcl = _.find(gclGatherData, function (item) {
+                                    return item.leafXmjs && item.leafXmjs.length > 0 && _.findIndex(item.leafXmjs, {gcl_id: id}) !== -1;
+                                });
+                                if (gcl) leafXmjList = [...leafXmjList, ...gcl.leafXmjs];
+                            }
+                            for (const ml of materialListData2) {
+                                const leafXmjInfo = _.find(leafXmjList, function (item) {
+                                    return item.gcl_id === ml.gcl_id && item.id === ml.xmj_id && (item.mx_id === undefined || (item.mx_id !== undefined && item.mx_id === ml.mx_id));
+                                });
+                                if (leafXmjInfo) {
+                                    needUpdateList.push({ id: ml.id, contract_qty: leafXmjInfo.contract_qty, qc_qty: leafXmjInfo.qc_qty, qc_minus_qty: leafXmjInfo.qc_minus_qty });
+                                }
+                            }
+                        }
+                    }
+                    console.log(needUpdateList);
+                    // postData(window.location.pathname + '/save', needUpdateList, function (result) {
+                    //     materialListData2 = result.materialListData;
+                    // });
+                }
             });
         } else {
             const i = _.findIndex(materialStageData, { sid });
             gclGatherData = gclGatherListData[i];
             gclGatherData = gclGatherData.filter(item => {
-                return item.qc_qty || item.contract_qty
+                return item.qc_qty || item.contract_qty || item.qc_minus_qty
             });
             if (openMaterialChecklist) {
                 // 取交集
@@ -1346,7 +1396,6 @@ $(document).ready(() => {
                     const gcl = _.find(gclGatherData, function (item) {
                         return item.leafXmjs && item.leafXmjs.length > 0 && _.findIndex(item.leafXmjs, { gcl_id: l.gcl_id }) !== -1;
                     });
-                    console.log(gcl);
                     if (gcl) {
                         const index = _.findIndex(showSourceList, { code: gcl.b_code, name: gcl.name, unit: gcl.unit });
                         if (index === -1) {
@@ -1354,10 +1403,10 @@ $(document).ready(() => {
                                 code: gcl.b_code,
                                 name: gcl.name,
                                 unit: gcl.unit,
-                                quantity: ZhCalc.mul(l.gather_qty, l.quantity),
+                                quantity: ZhCalc.mul(calcQty(l), l.quantity),
                             });
                         } else {
-                            showSourceList[index].quantity = ZhCalc.add(showSourceList[index].quantity, ZhCalc.mul(l.gather_qty, l.quantity));
+                            showSourceList[index].quantity = ZhCalc.add(showSourceList[index].quantity, ZhCalc.mul(calcQty(l), l.quantity));
                         }
                     }
                 }
@@ -1366,6 +1415,17 @@ $(document).ready(() => {
         SpreadJsObj.loadSheetData(materialSourceSpread.getActiveSheet(), SpreadJsObj.DataType.Data, showSourceList);
     }
 
+    function calcQty(info) {
+        let qty = '';
+        switch (qtySource) {
+            case qtySourceValueConst.gather_qty: qty = info.gather_qty; break;
+            case qtySourceValueConst.contract_qty: qty = info.contract_qty; break;
+            case qtySourceValueConst.gather_minus_qty: qty = ZhCalc.add(info.gather_qty, info.qc_minus_qty); break;
+            default: throw '未配置计量来源出错';
+        }
+        return qty;
+    }
+
     if (!readOnly || editForAudit) {
         $('#expr_select button').on('click', function () {
             const code = $(this).text();

+ 32 - 11
app/public/js/material_checklist.js

@@ -153,7 +153,7 @@ $(document).ready(() => {
                 gclGatherModel.loadLedgerData(_.cloneDeep(ledger), s);
                 gclGatherModel.loadPosData(_.cloneDeep(pos), result.posListData[index]);
                 const oneGclGatherData = gclGatherModel.gatherGclData().filter(item => {
-                    return item.qc_qty || item.contract_qty
+                    return item.qc_qty || item.contract_qty || item.qc_minus_qty
                 });
                 newGclGatherListData.push(oneGclGatherData);
             }
@@ -444,7 +444,10 @@ $(document).ready(() => {
                 xmj_id: xmj.id,
                 gcl_id: xmj.gcl_id,
                 mx_id: xmj.mx_id !== undefined ? xmj.mx_id : '',
-                gather_qty: notx2 === undefined ? xmj.gather_qty : xmj.contract_qty,
+                contract_qty: xmj.contract_qty,
+                qc_qty: xmj.qc_qty,
+                qc_minus_qty: xmj.qc_minus_qty,
+                gather_qty: xmj.gather_qty,
                 is_join: notx === undefined ? 1 : 0,
             };
             if (ms_id) data.ms_id = ms_id;
@@ -457,7 +460,9 @@ $(document).ready(() => {
                 if (ms.id !== ms_id) {
                     const gclOther = _.find(gclGatherListData[index], { b_code: gclData.b_code, name: gclData.name, unit: gclData.unit, unit_price: gclData.unit_price });
                     if (gclOther) {
-                        const leafXmjs = gclOther.leafXmjs.filter(item => item.gather_qty !== null && item.gather_qty !== undefined);
+                        const leafXmjs = gclOther.leafXmjs.filter(item => {
+                            return item.qc_qty || item.contract_qty || item.qc_minus_qty
+                        });
                         for (const xmj of leafXmjs) {
                             const notx = findNotJoinLeafXmj(xmj);
                             const notx2 = findNotChangeLeafXmj(xmj);
@@ -465,7 +470,10 @@ $(document).ready(() => {
                                 xmj_id: xmj.id,
                                 gcl_id: xmj.gcl_id,
                                 mx_id: xmj.mx_id ? xmj.mx_id : '',
-                                gather_qty: notx2 === undefined ? xmj.gather_qty : xmj.contract_qty,
+                                contract_qty: xmj.contract_qty,
+                                qc_qty: xmj.qc_qty,
+                                qc_minus_qty: xmj.qc_minus_qty,
+                                gather_qty: xmj.gather_qty,
                                 is_join: notx === undefined ? 1 : 0,
                                 ms_id: ms.id,
                             };
@@ -516,7 +524,9 @@ $(document).ready(() => {
                         if (ms.id !== ms_id) {
                             const gclOther = _.find(gclGatherListData[index], { b_code: gclData.b_code, name: gclData.name, unit: gclData.unit, unit_price: gclData.unit_price });
                             if (gclOther) {
-                                const leafXmjs = gclOther.leafXmjs.filter(item => item.gather_qty !== null && item.gather_qty !== undefined);
+                                const leafXmjs = gclOther.leafXmjs.filter(item => {
+                                    return item.qc_qty || item.contract_qty || item.qc_minus_qty
+                                });
                                 for (const xmj of leafXmjs) {
                                     const data = {
                                         xmj_id: xmj.id,
@@ -626,7 +636,9 @@ $(document).ready(() => {
                             if (ms.id !== ms_id) {
                                 const gclOther = _.find(gclGatherListData[index], { b_code: gclData.b_code, name: gclData.name, unit: gclData.unit, unit_price: gclData.unit_price });
                                 if (gclOther) {
-                                    const leafXmjs = gclOther.leafXmjs.filter(item => item.gather_qty !== null && item.gather_qty !== undefined);
+                                    const leafXmjs = gclOther.leafXmjs.filter(item => {
+                                        return item.qc_qty || item.contract_qty || item.qc_minus_qty
+                                    });
                                     for (const xmj of leafXmjs) {
                                         const data = {
                                             xmj_id: xmj.id,
@@ -747,9 +759,10 @@ $(document).ready(() => {
                     for (const [index, ms] of materialStageData.entries()) {
                         if (ms.id !== ms_id) {
                             const gclOther = _.find(gclGatherListData[index], { b_code: gclData.b_code, name: gclData.name, unit: gclData.unit, unit_price: gclData.unit_price });
-                            console.log(gclOther);
                             if (gclOther) {
-                                const leafXmjs = gclOther.leafXmjs.filter(item => item.gather_qty !== null && item.gather_qty !== undefined);
+                                const leafXmjs = gclOther.leafXmjs.filter(item => {
+                                    return item.qc_qty || item.contract_qty || item.qc_minus_qty
+                                });
                                 for (const xmj of leafXmjs) {
                                     const data = {
                                         xmj_id: xmj.id,
@@ -1371,7 +1384,10 @@ $(document).ready(() => {
                         xmj_id: xmj.id,
                         gcl_id: xmj.gcl_id,
                         mx_id: xmj.mx_id !== undefined ? xmj.mx_id : '',
-                        gather_qty: notx2 === undefined ? xmj.gather_qty : xmj.contract_qty,
+                        contract_qty: xmj.contract_qty,
+                        qc_qty: xmj.qc_qty,
+                        qc_minus_qty: xmj.qc_minus_qty,
+                        gather_qty: xmj.gather_qty,
                         is_join: notx === undefined ? 1 : 0,
                     };
                     if (ms_id) data.ms_id = ms_id;
@@ -1387,7 +1403,9 @@ $(document).ready(() => {
                             if (!ignoreUnitPrice) gclFindObject.unit_price = gclData.unit_price;
                             const gclOther = _.find(gclGatherListData[index], gclFindObject);
                             if (gclOther) {
-                                const leafXmjs = gclOther.leafXmjs.filter(item => item.gather_qty !== null && item.gather_qty !== undefined);
+                                const leafXmjs = gclOther.leafXmjs.filter(item => {
+                                    return item.qc_qty || item.contract_qty || item.qc_minus_qty
+                                });
                                 for (const xmj of leafXmjs) {
                                     const notx = findNotJoinLeafXmj(xmj);
                                     const notx2 = findNotChangeLeafXmj(xmj);
@@ -1395,7 +1413,10 @@ $(document).ready(() => {
                                         xmj_id: xmj.id,
                                         gcl_id: xmj.gcl_id,
                                         mx_id: xmj.mx_id ? xmj.mx_id : '',
-                                        gather_qty: notx2 === undefined ? xmj.gather_qty : xmj.contract_qty,
+                                        contract_qty: xmj.contract_qty,
+                                        qc_qty: xmj.qc_qty,
+                                        qc_minus_qty: xmj.qc_minus_qty,
+                                        gather_qty: xmj.gather_qty,
                                         is_join: notx === undefined ? 1 : 0,
                                         ms_id: ms.id,
                                     };

+ 184 - 46
app/public/js/material_list.js

@@ -167,18 +167,39 @@ $(document).ready(() => {
     autoFlashHeight();
     // 清单table
     const ledgerSpread = SpreadJsObj.createNewSpread($('#ledger-spread')[0]);
+    const ledgerCols = [
+        {title: '清单编号', colSpan: '1', rowSpan: '2', field: 'b_code', hAlign: 0, width: 90, formatter: '@'},
+        {title: '名称', colSpan: '1', rowSpan: '2', field: 'name', hAlign: 0, width: 220, formatter: '@'},
+        {title: '单位', colSpan: '1', rowSpan: '2', field: 'unit', hAlign: 1, width: 80, formatter: '@'},
+        {title: '单价', colSpan: '1', rowSpan: '2', field: 'unit_price', hAlign: 2, width: 110, type: 'Number'},
+    ];
+    if (materialQtySource === 1) {
+        ledgerCols.push({title: '本期计量数量|合同', colSpan: '3|1', rowSpan: '1|1', field: 'contract_qty', hAlign: 2, width: 110, type: 'Number'});
+        ledgerCols.push({title: '|数量变更', colSpan: '|1', rowSpan: '|1', field: 'qc_qty', hAlign: 2, width: 110, type: 'Number'});
+        ledgerCols.push({title: '|小计', colSpan: '|1', rowSpan: '|1', field: 'gather_qty', hAlign: 2, width: 110, type: 'Number'});
+    } else if (materialQtySource === 2) {
+        ledgerCols.push({title: '本期计量数量|合同', colSpan: '1|1', rowSpan: '1|1', field: 'contract_qty', hAlign: 2, width: 110, type: 'Number'});
+    } else if (materialQtySource === 3) {
+        ledgerCols.push({title: '本期计量数量|合同', colSpan: '4|1', rowSpan: '1|1', field: 'contract_qty', hAlign: 2, width: 110, type: 'Number'});
+        ledgerCols.push({title: '|数量变更', colSpan: '|1', rowSpan: '|1', field: 'qc_qty', hAlign: 2, width: 110, type: 'Number'});
+        ledgerCols.push({title: '|不计价', colSpan: '|1', rowSpan: '|1', field: 'qc_minus_qty', hAlign: 2, width: 110, type: 'Number'});
+        ledgerCols.push({title: '|小计', colSpan: '|1', rowSpan: '|1', field: 'gather_qty', hAlign: 2, width: 110, type: 'Number', getValue: 'getValue.gather_qty'});
+    }
+    ledgerCols.push({title: '本期完成金额', colSpan: '1', rowSpan: '2', field: 'gather_tp', hAlign: 2, width: 110, type: 'Number'});
+    ledgerCols.push({title: '本期价差', colSpan: '1', rowSpan: '2', field: 'total_jiacha', hAlign:3, width: 110, type: 'Number'});
     const ledgerSpreadSetting = {
-        cols: [
-            {title: '清单编号', colSpan: '1', rowSpan: '2', field: 'b_code', hAlign: 0, width: 90, formatter: '@'},
-            {title: '名称', colSpan: '1', rowSpan: '2', field: 'name', hAlign: 0, width: 220, formatter: '@'},
-            {title: '单位', colSpan: '1', rowSpan: '2', field: 'unit', hAlign: 1, width: 80, formatter: '@'},
-            {title: '单价', colSpan: '1', rowSpan: '2', field: 'unit_price', hAlign: 2, width: 110, type: 'Number'},
-            {title: '本期计量数量|合同', colSpan: '3|1', rowSpan: '1|1', field: 'contract_qty', hAlign: 2, width: 110, type: 'Number'},
-            {title: '|数量变更', colSpan: '|1', rowSpan: '|1', field: 'qc_qty', hAlign: 2, width: 110, type: 'Number'},
-            {title: '|小计', colSpan: '|1', rowSpan: '|1', field: 'gather_qty', hAlign: 2, width: 110, type: 'Number'},
-            {title: '本期完成金额', colSpan: '1', rowSpan: '2', field: 'gather_tp', hAlign: 2, width: 110, type: 'Number'},
-            {title: '本期价差', colSpan: '1', rowSpan: '2', field: 'total_jiacha', hAlign:3, width: 110, type: 'Number'}
-        ],
+        // cols: [
+        //     {title: '清单编号', colSpan: '1', rowSpan: '2', field: 'b_code', hAlign: 0, width: 90, formatter: '@'},
+        //     {title: '名称', colSpan: '1', rowSpan: '2', field: 'name', hAlign: 0, width: 220, formatter: '@'},
+        //     {title: '单位', colSpan: '1', rowSpan: '2', field: 'unit', hAlign: 1, width: 80, formatter: '@'},
+        //     {title: '单价', colSpan: '1', rowSpan: '2', field: 'unit_price', hAlign: 2, width: 110, type: 'Number'},
+        //     {title: '本期计量数量|合同', colSpan: '4|1', rowSpan: '1|1', field: 'contract_qty', hAlign: 2, width: 110, type: 'Number'},
+        //     {title: '|数量变更', colSpan: '|1', rowSpan: '|1', field: 'qc_qty', hAlign: 2, width: 110, type: 'Number'},
+        //     {title: '|不计价', colSpan: '|1', rowSpan: '|1', field: 'qc_minus_qty', hAlign: 2, width: 110, type: 'Number'},
+        //     {title: '|小计', colSpan: '|1', rowSpan: '|1', field: 'gather_qty', hAlign: 2, width: 110, type: 'Number'},
+        //     {title: '本期完成金额', colSpan: '1', rowSpan: '2', field: 'gather_tp', hAlign: 2, width: 110, type: 'Number'},
+        //     {title: '本期价差', colSpan: '1', rowSpan: '2', field: 'total_jiacha', hAlign:3, width: 110, type: 'Number'}
+        // ],
         emptyRows: 0,
         headRows: 2,
         headRowHeight: [25, 25],
@@ -187,6 +208,16 @@ $(document).ready(() => {
         font: '12px 微软雅黑',
         readOnly: true,
     };
+    const ledgerCol = {
+        getValue: {
+            gather_qty: function (data) {
+                if (materialQtySource === 3) {
+                    return ZhCalc.add(data.gather_qty, data.qc_minus_qty);
+                }
+            },
+        }
+    }
+    ledgerSpreadSetting.cols = ledgerCols;
     // let gclGatherData = gclGatherModel.gatherGclData()
     // 获取项目节数据
     function loadLeafXmjData(iGclRow) {
@@ -210,24 +241,48 @@ $(document).ready(() => {
         }
         SpreadJsObj.initSheet(materialSpread.getActiveSheet(), materialSpreadSetting);
     }
+    SpreadJsObj.initSpreadSettingEvents(ledgerSpreadSetting, ledgerCol);
     SpreadJsObj.initSheet(ledgerSpread.getActiveSheet(), ledgerSpreadSetting);
 
     // 项目明细table
     const leafXmjSpread = SpreadJsObj.createNewSpread($('#leaf-xmj-spread')[0]);
+    const leafXmjCols = [
+        {title: '项目节|编号', colSpan: '2|1', rowSpan: '1|1', field: 'code', hAlign: 0, width: 80, formatter: '@'},
+        {title: '|项目节名称', colSpan: '|1', rowSpan: '|1', field: 'jldy', hAlign: 0, width: 100, formatter: '@'},
+        {title: '计量单元|计量单元', colSpan: '2|1', rowSpan: '1|1', field: 'bwmx', hAlign: 0, width: 100, formatter: '@'},
+        {title: '|复核数量', colSpan: '|1', rowSpan: '|1', field: 'quantity', hAlign: 0, width: 80, type: 'Number'},
+        {title: '部位信息|单位工程', colSpan: '3|1', rowSpan: '1|1', field: 'dwgc', hAlign: 0, width: 100, formatter: '@'},
+        {title: '|分部工程', colSpan: '|1', rowSpan: '|1', field: 'fbgc', hAlign: 0, width: 100, formatter: '@'},
+        {title: '|分项工程', colSpan: '|1', rowSpan: '|1', field: 'fxgc', hAlign: 0, width: 180, formatter: '@'},
+    ];
+    if (materialQtySource === 1) {
+        leafXmjCols.push({title: '本期计量数量|合同', colSpan: '3|1', rowSpan: '1|1', field: 'contract_qty', hAlign: 2, width: 60, type: 'Number'});
+        leafXmjCols.push({title: '|数量变更', colSpan: '|1', rowSpan: '|1', field: 'qc_qty', hAlign: 2, width: 60, type: 'Number'});
+        leafXmjCols.push({title: '|小计', colSpan: '|1', rowSpan: '|1', field: 'gather_qty', hAlign: 2, width: 60, type: 'Number'});
+    } else if (materialQtySource === 2) {
+        leafXmjCols.push({title: '本期计量数量|合同', colSpan: '1|1', rowSpan: '1|1', field: 'contract_qty', hAlign: 2, width: 100, type: 'Number'});
+    } else if (materialQtySource === 3) {
+        leafXmjCols.push({title: '本期计量数量|合同', colSpan: '4|1', rowSpan: '1|1', field: 'contract_qty', hAlign: 2, width: 60, type: 'Number'});
+        leafXmjCols.push({title: '|数量变更', colSpan: '|1', rowSpan: '|1', field: 'qc_qty', hAlign: 2, width: 60, type: 'Number'});
+        leafXmjCols.push({title: '|不计价', colSpan: '|1', rowSpan: '|1', field: 'qc_minus_qty', hAlign: 2, width: 60, type: 'Number'});
+        leafXmjCols.push({title: '|小计', colSpan: '|1', rowSpan: '|1', field: 'gather_qty', hAlign: 2, width: 60, type: 'Number', getValue: 'getValue.gather_qty'});
+    }
+    leafXmjCols.push({title: '本期价差', colSpan: '1', rowSpan: '2', field: 'jiacha', hAlign: 2, width: 80, type: 'Number'});
     const leafXmjSpreadSetting = {
-        cols: [
-            {title: '项目节|编号', colSpan: '2|1', rowSpan: '1|1', field: 'code', hAlign: 0, width: 80, formatter: '@'},
-            {title: '|项目节名称', colSpan: '|1', rowSpan: '|1', field: 'jldy', hAlign: 0, width: 100, formatter: '@'},
-            {title: '计量单元|计量单元', colSpan: '2|1', rowSpan: '1|1', field: 'bwmx', hAlign: 0, width: 100, formatter: '@'},
-            {title: '|复核数量', colSpan: '|1', rowSpan: '|1', field: 'quantity', hAlign: 0, width: 80, type: 'Number'},
-            {title: '部位信息|单位工程', colSpan: '3|1', rowSpan: '1|1', field: 'dwgc', hAlign: 0, width: 100, formatter: '@'},
-            {title: '|分部工程', colSpan: '|1', rowSpan: '|1', field: 'fbgc', hAlign: 0, width: 100, formatter: '@'},
-            {title: '|分项工程', colSpan: '|1', rowSpan: '|1', field: 'fxgc', hAlign: 0, width: 180, formatter: '@'},
-            {title: '本期计量数量|合同', colSpan: '3|1', rowSpan: '1|1', field: 'contract_qty', hAlign: 2, width: 60, type: 'Number'},
-            {title: '|数量变更', colSpan: '|1', rowSpan: '|1', field: 'qc_qty', hAlign: 2, width: 80, type: 'Number'},
-            {title: '|小计', colSpan: '|1', rowSpan: '|1', field: 'gather_qty', hAlign: 2, width: 60, type: 'Number'},
-            {title: '本期价差', colSpan: '1', rowSpan: '2', field: 'jiacha', hAlign: 2, width: 80, type: 'Number'},
-        ],
+        // cols: [
+        //     {title: '项目节|编号', colSpan: '2|1', rowSpan: '1|1', field: 'code', hAlign: 0, width: 80, formatter: '@'},
+        //     {title: '|项目节名称', colSpan: '|1', rowSpan: '|1', field: 'jldy', hAlign: 0, width: 100, formatter: '@'},
+        //     {title: '计量单元|计量单元', colSpan: '2|1', rowSpan: '1|1', field: 'bwmx', hAlign: 0, width: 100, formatter: '@'},
+        //     {title: '|复核数量', colSpan: '|1', rowSpan: '|1', field: 'quantity', hAlign: 0, width: 80, type: 'Number'},
+        //     {title: '部位信息|单位工程', colSpan: '3|1', rowSpan: '1|1', field: 'dwgc', hAlign: 0, width: 100, formatter: '@'},
+        //     {title: '|分部工程', colSpan: '|1', rowSpan: '|1', field: 'fbgc', hAlign: 0, width: 100, formatter: '@'},
+        //     {title: '|分项工程', colSpan: '|1', rowSpan: '|1', field: 'fxgc', hAlign: 0, width: 180, formatter: '@'},
+        //     {title: '本期计量数量|合同', colSpan: '4|1', rowSpan: '1|1', field: 'contract_qty', hAlign: 2, width: 60, type: 'Number'},
+        //     {title: '|数量变更', colSpan: '|1', rowSpan: '|1', field: 'qc_qty', hAlign: 2, width: 80, type: 'Number'},
+        //     {title: '|不计价', colSpan: '|1', rowSpan: '|1', field: 'qc_minus_qty', hAlign: 2, width: 80, type: 'Number'},
+        //     {title: '|小计', colSpan: '|1', rowSpan: '|1', field: 'gather_qty', hAlign: 2, width: 60, type: 'Number'},
+        //     {title: '本期价差', colSpan: '1', rowSpan: '2', field: 'jiacha', hAlign: 2, width: 80, type: 'Number'},
+        // ],
         emptyRows: 0,
         headRows: 2,
         headRowHeight: [25, 25],
@@ -251,6 +306,16 @@ $(document).ready(() => {
             },
         ],
     };
+    leafXmjSpreadSetting.cols = leafXmjCols;
+    const leafXmjCol = {
+        getValue: {
+            gather_qty: function (data) {
+                if (materialQtySource === 3) {
+                    return ZhCalc.add(data.gather_qty, data.qc_minus_qty);
+                }
+            },
+        }
+    }
     const needUpdateArray = ['quantity', 'msg_tp', 'msg_times', 'msg_spread', 'm_spread', 'm_tp', 'm_tax_tp', 'is_summary', 'remark'];
 
     function getGclList() {
@@ -263,7 +328,7 @@ $(document).ready(() => {
                 gclGatherModel.loadLedgerData(ledger, s);
                 gclGatherModel.loadPosData(pos, posListData[index]);
                 const oneGclGatherData = gclGatherModel.gatherGclData().filter(item => {
-                    return item.qc_qty || item.contract_qty
+                    return item.qc_qty || item.contract_qty || item.qc_minus_qty
                 });
                 newGclGatherListData.push(oneGclGatherData);
             }
@@ -292,7 +357,7 @@ $(document).ready(() => {
                         gclGatherModel.loadLedgerData(_.cloneDeep(ledger), s);
                         gclGatherModel.loadPosData(_.cloneDeep(pos), result.posListData[index]);
                         const oneGclGatherData = gclGatherModel.gatherGclData().filter(item => {
-                            return item.qc_qty || item.contract_qty
+                            return item.qc_qty || item.contract_qty || item.qc_minus_qty
                         });
                         newGclGatherListData.push(oneGclGatherData);
                     }
@@ -381,7 +446,7 @@ $(document).ready(() => {
                         // materialChecklistData = await postDataAsync('/tender/'+ tenderID +'/measure/material/'+ stage_order +'/checklist/save', { type: 'resetChecklist', pushData, removeData, updateData })
                     }
                     gclGatherData = gclGatherData.filter(item => {
-                        return item.qc_qty || item.contract_qty
+                        return item.qc_qty || item.contract_qty || item.qc_minus_qty
                     });
                     // 取交集
                     const selfListGcl = _.uniq(_.map(selfList, 'gcl_id'));
@@ -403,10 +468,11 @@ $(document).ready(() => {
                     });
                 } else {
                     gclGatherData = gclGatherData.filter(item => {
-                        return item.qc_qty || item.contract_qty
+                        return item.qc_qty || item.contract_qty || item.qc_minus_qty
                     });
                 }
                 calculateJiaCha(gclGatherData);
+                SpreadJsObj.initSpreadSettingEvents(leafXmjSpreadSetting, leafXmjCol);
                 SpreadJsObj.initSheet(leafXmjSpread.getActiveSheet(), leafXmjSpreadSetting);
                 // 加载清单数据
                 SpreadJsObj.loadSheetData(ledgerSpread.getActiveSheet(), SpreadJsObj.DataType.Data, gclGatherData);
@@ -423,6 +489,56 @@ $(document).ready(() => {
                 selfSheet.resumePaint();
                 checkNotJoinMaterialData();
                 first = false;
+
+                // 判断是否需要更新contract_qty、qc_qty和qc_minus_qty
+                if (!materialIsNewQty && !readOnly) {
+                    let needUpdateList = [];
+                    if (materialListData.length > 0) {
+                        if (isStageSelf) {
+                            for (const msIndex in materialStageData) {
+                                const materialStageList = _.filter(materialListData, { ms_id: materialStageData[msIndex].id });
+                                const gclIdList = _.uniq(_.map(materialListData, 'gcl_id'));
+                                let leafXmjList = [];
+                                for (const id of gclIdList) {
+                                    const gcl = _.find(gclGatherListData[msIndex], function (item) {
+                                        return item.leafXmjs && item.leafXmjs.length > 0 && _.findIndex(item.leafXmjs, {gcl_id: id}) !== -1;
+                                    });
+                                    if (gcl) leafXmjList = [...leafXmjList, ...gcl.leafXmjs];
+                                }
+                                for (const ml of materialStageList) {
+                                    const leafXmjInfo = _.find(leafXmjList, function (item) {
+                                        return item.gcl_id === ml.gcl_id && item.id === ml.xmj_id && (item.mx_id === undefined || (item.mx_id !== undefined && item.mx_id === ml.mx_id));
+                                    });
+                                    if (leafXmjInfo) {
+                                        needUpdateList.push({ id: ml.id, contract_qty: leafXmjInfo.contract_qty, qc_qty: leafXmjInfo.qc_qty, qc_minus_qty: leafXmjInfo.qc_minus_qty });
+                                    }
+                                }
+                            }
+                        } else {
+                            // 找出所有gcl相同的,方便搜索gclGatherData值
+                            const gclIdList = _.uniq(_.map(materialListData, 'gcl_id'));
+                            let leafXmjList = [];
+                            for (const id of gclIdList) {
+                                const gcl = _.find(gclGatherData, function (item) {
+                                    return item.leafXmjs && item.leafXmjs.length > 0 && _.findIndex(item.leafXmjs, {gcl_id: id}) !== -1;
+                                });
+                                if (gcl) leafXmjList = [...leafXmjList, ...gcl.leafXmjs];
+                            }
+                            for (const ml of materialListData) {
+                                const leafXmjInfo = _.find(leafXmjList, function (item) {
+                                    return item.gcl_id === ml.gcl_id && item.id === ml.xmj_id && (item.mx_id === undefined || (item.mx_id !== undefined && item.mx_id === ml.mx_id));
+                                });
+                                if (leafXmjInfo) {
+                                    needUpdateList.push({ id: ml.id, contract_qty: leafXmjInfo.contract_qty, qc_qty: leafXmjInfo.qc_qty, qc_minus_qty: leafXmjInfo.qc_minus_qty });
+                                }
+                            }
+                        }
+                    }
+                    console.log(needUpdateList);
+                    // postData(window.location.pathname + '/save', needUpdateList, function (result) {
+                    //     materialListData2 = result.materialListData;
+                    // });
+                }
             });
         } else {
             // 解析清单汇总数据
@@ -432,7 +548,7 @@ $(document).ready(() => {
             gclGatherData = gclGatherListData[i];
             if (openMaterialChecklist) {
                 gclGatherData = gclGatherData.filter(item => {
-                    return item.qc_qty || item.contract_qty
+                    return item.qc_qty || item.contract_qty || item.qc_minus_qty
                 });
                 // 取交集
                 const selfListGcl = _.uniq(_.map(selfList, 'gcl_id'));
@@ -454,7 +570,7 @@ $(document).ready(() => {
                 });
             } else {
                 gclGatherData = gclGatherData.filter(item => {
-                    return item.qc_qty || item.contract_qty
+                    return item.qc_qty || item.contract_qty || item.qc_minus_qty
                 });
             }
             if ($('#show_material_gcl').is(':checked')) {
@@ -478,6 +594,7 @@ $(document).ready(() => {
             }
             console.log(gclGatherData);
             calculateJiaCha(gclGatherData);
+            SpreadJsObj.initSpreadSettingEvents(leafXmjSpreadSetting, leafXmjCol);
             SpreadJsObj.initSheet(leafXmjSpread.getActiveSheet(), leafXmjSpreadSetting);
             // 加载清单数据
             SpreadJsObj.loadSheetData(ledgerSpread.getActiveSheet(), SpreadJsObj.DataType.Data, gclGatherData);
@@ -661,7 +778,7 @@ $(document).ready(() => {
         // 存在单独设置的才展示,不然隐藏
         const gcl = gclGatherData[iGclRow];
         const leafXmjs = gcl && gcl.leafXmjs ? gcl.leafXmjs.filter(item => {
-            return item.qc_qty || item.contract_qty
+            return item.qc_qty || item.contract_qty || item.qc_minus_qty
         }) : null;
         if (leafXmjs) {
             const xmj = leafXmjs[iLXmjRow];
@@ -710,7 +827,7 @@ $(document).ready(() => {
         const index = gclGatherData.indexOf(select);
         if (index !== -1) {
             const xmj = gclGatherData[index].leafXmjs.filter(item => {
-                return item.qc_qty || item.contract_qty
+                return item.qc_qty || item.contract_qty || item.qc_minus_qty
             });
             const leafXmjSheet = leafXmjSpread.getActiveSheet();
             for (const [iRow,x] of xmj.entries()) {
@@ -772,7 +889,10 @@ $(document).ready(() => {
                     xmj_id: xmj.id,
                     gcl_id: xmj.gcl_id,
                     mx_id: xmj.mx_id ? xmj.mx_id : '',
-                    gather_qty: notx2 === undefined ? xmj.gather_qty : xmj.contract_qty,
+                    contract_qty: xmj.contract_qty,
+                    qc_qty: xmj.qc_qty,
+                    qc_minus_qty: xmj.qc_minus_qty,
+                    gather_qty: xmj.gather_qty,
                     is_join: notx === undefined ? 1 : 0,
                 };
                 if (ms_id) data.ms_id = ms_id;
@@ -785,7 +905,10 @@ $(document).ready(() => {
                     if (ms.id !== ms_id) {
                         const gclOther = _.find(gclGatherListData[index], { b_code: gclData.b_code, name: gclData.name, unit: gclData.unit, unit_price: gclData.unit_price });
                         if (gclOther) {
-                            const leafXmjs = gclOther.leafXmjs.filter(item => item.gather_qty !== null && item.gather_qty !== undefined);
+                            const leafXmjs = gclOther.leafXmjs.filter(item => {
+                                return item.qc_qty || item.contract_qty || item.qc_minus_qty
+                            });
+                            // gclOther.leafXmjs.filter(item => item.gather_qty !== null && item.gather_qty !== undefined);
                             for (const xmj of leafXmjs) {
                                 const notx = findNotJoinLeafXmj(xmj);
                                 const notx2 = findNotChangeLeafXmj(xmj);
@@ -793,7 +916,10 @@ $(document).ready(() => {
                                     xmj_id: xmj.id,
                                     gcl_id: xmj.gcl_id,
                                     mx_id: xmj.mx_id ? xmj.mx_id : '',
-                                    gather_qty: notx2 === undefined ? xmj.gather_qty : xmj.contract_qty,
+                                    contract_qty: xmj.contract_qty,
+                                    qc_qty: xmj.qc_qty,
+                                    qc_minus_qty: xmj.qc_minus_qty,
+                                    gather_qty: xmj.gather_qty,
                                     is_join: notx === undefined ? 1 : 0,
                                     ms_id: ms.id,
                                 };
@@ -825,7 +951,9 @@ $(document).ready(() => {
             const index = gclGatherData.indexOf(select);
             const leafXmjSheet = leafXmjSpread.getActiveSheet();
             const leafXmjSelect = SpreadJsObj.getSelectObject(leafXmjSheet);
-            const gcl = gclGatherData[index].leafXmjs.filter(item => item.gather_qty !== null && item.gather_qty !== undefined);
+            const gcl = gclGatherData[index].leafXmjs.filter(item => {
+                return item.qc_qty || item.contract_qty || item.qc_minus_qty
+            });
             const leafXmjIndex = gcl.indexOf(leafXmjSelect);
             const xmj = gcl[leafXmjIndex];
             const notx = findNotJoinLeafXmj(xmj);
@@ -835,7 +963,10 @@ $(document).ready(() => {
                 gcl_id: xmj.gcl_id,
                 mx_id: xmj.mx_id ? xmj.mx_id : '',
                 mb_id: mb_id,
-                gather_qty: notx2 === undefined ? xmj.gather_qty : xmj.contract_qty,
+                contract_qty: xmj.contract_qty,
+                qc_qty: xmj.qc_qty,
+                qc_minus_qty: xmj.qc_minus_qty,
+                gather_qty: xmj.gather_qty,
                 is_join: notx === undefined ? 1 : 0,
             };
             console.log(data);
@@ -857,7 +988,7 @@ $(document).ready(() => {
             const leafXmjSelect = SpreadJsObj.getSelectObject(leafXmjSheet);
             const iRow = gclGatherData[index].leafXmjs.indexOf(leafXmjSelect);
             const leafXmjs = gclGatherData[index].leafXmjs.filter(item => {
-                return item.qc_qty || item.contract_qty
+                return item.qc_qty || item.contract_qty || item.qc_minus_qty
             });
             const nRow = leafXmjs.indexOf(leafXmjSelect);
             const leafXmjColor = findNotJoinLeafXmj(leafXmjSelect) ? '#d6d8db' : (findNotChangeLeafXmj(leafXmjSelect) ? '#FFE699' : '');
@@ -935,7 +1066,9 @@ $(document).ready(() => {
                         const gclOther = _.find(gclGatherListData[index], { b_code: gclData.b_code, name: gclData.name, unit: gclData.unit, unit_price: gclData.unit_price });
                         let gather_qty = null;
                         if (gclOther) {
-                            const leafXmjs = gclOther.leafXmjs.filter(item => item.gather_qty !== null && item.gather_qty !== undefined);
+                            const leafXmjs = gclOther.leafXmjs.filter(item => {
+                                return item.qc_qty || item.contract_qty || item.qc_minus_qty
+                            });
                             const oneXmj = _.find(leafXmjs, function (item) {
                                 return item.gcl_id === select.gcl_id && item.id === select.id && (select.mx_id === undefined || item.mx_id === select.mx_id);
                             });
@@ -1038,7 +1171,7 @@ $(document).ready(() => {
                                 return false;
                             }
                             const notx2 = findNotChangeLeafXmj(select);
-                            if (!readOnly && select && notx2 === undefined) {
+                            if (!readOnly && select && notx2 === undefined && materialQtySource !== qtySourceValueConst.contract_qty) {
                                 return true;
                             } else {
                                 return false;
@@ -1134,7 +1267,7 @@ $(document).ready(() => {
                             const [iGclRow, iRow, nRow, sheet, select, color] = leafXmjSpreadObj.getSelect();
                             const gcl = gclGatherData[iGclRow];
                             const leafXmjs = gcl && gcl.leafXmjs ? gcl.leafXmjs.filter(item => {
-                                return item.qc_qty || item.contract_qty
+                                return item.qc_qty || item.contract_qty || item.qc_minus_qty
                             }) : null;
                             let flag = false;
                             if (leafXmjs) {
@@ -1186,7 +1319,9 @@ $(document).ready(() => {
                         if (ms.id !== ms_id) {
                             const gclOther = _.find(gclGatherListData[index], { b_code: gclData.b_code, name: gclData.name, unit: gclData.unit, unit_price: gclData.unit_price });
                             if (gclOther) {
-                                const leafXmjs = gclOther.leafXmjs.filter(item => item.gather_qty !== null && item.gather_qty !== undefined);
+                                const leafXmjs = gclOther.leafXmjs.filter(item => {
+                                    return item.qc_qty || item.contract_qty || item.qc_minus_qty
+                                });
                                 for (const xmj of leafXmjs) {
                                     const data = {
                                         xmj_id: xmj.id,
@@ -1311,7 +1446,9 @@ $(document).ready(() => {
                             if (ms.id !== ms_id) {
                                 const gclOther = _.find(gclGatherListData[index], { b_code: gclData.b_code, name: gclData.name, unit: gclData.unit, unit_price: gclData.unit_price });
                                 if (gclOther) {
-                                    const leafXmjs = gclOther.leafXmjs.filter(item => item.gather_qty !== null && item.gather_qty !== undefined);
+                                    const leafXmjs = gclOther.leafXmjs.filter(item => {
+                                        return item.qc_qty || item.contract_qty || item.qc_minus_qty
+                                    });
                                     for (const xmj of leafXmjs) {
                                         const data = {
                                             xmj_id: xmj.id,
@@ -1462,9 +1599,10 @@ $(document).ready(() => {
                     for (const [index, ms] of materialStageData.entries()) {
                         if (ms.id !== ms_id) {
                             const gclOther = _.find(gclGatherListData[index], { b_code: gclData.b_code, name: gclData.name, unit: gclData.unit, unit_price: gclData.unit_price });
-                            console.log(gclOther);
                             if (gclOther) {
-                                const leafXmjs = gclOther.leafXmjs.filter(item => item.gather_qty !== null && item.gather_qty !== undefined);
+                                const leafXmjs = gclOther.leafXmjs.filter(item => {
+                                    return item.qc_qty || item.contract_qty || item.qc_minus_qty
+                                });
                                 for (const xmj of leafXmjs) {
                                     const data = {
                                         xmj_id: xmj.id,
@@ -2065,7 +2203,7 @@ $(document).ready(() => {
                 gclGatherModel.loadLedgerData(_.cloneDeep(ledger), curLedgerData);
                 gclGatherModel.loadPosData(_.cloneDeep(pos), curPosData);
                 gclGatherData = gclGatherModel.gatherGclData().filter(item => {
-                    return item.qc_qty || item.contract_qty
+                    return item.qc_qty || item.contract_qty || item.qc_minus_qty
                 });
             }
             if (openMaterialChecklist) {

+ 17 - 5
app/public/js/measure_material.js

@@ -266,6 +266,7 @@ $(function () {
             period: $('#add-qi input[name="period"]').val(),
             stage_id,
             is_stage_self,
+            qty_source: parseInt($('#add-qi input[name="qty_source"]:checked').val()),
         };
         if (lastMaterialListNum === 0) {
             console.log(newMaterialData);
@@ -341,8 +342,10 @@ $(function () {
                                             gcl_id: xmj.gcl_id,
                                             mx_id: xmj.mx_id ? xmj.mx_id : '',
                                             xmj_id: xmj.id ? xmj.id : null,
-                                            gather_qty: xmj.gather_qty,
                                             contract_qty: xmj.contract_qty,
+                                            qc_qty: xmj.qc_qty,
+                                            qc_minus_qty: xmj.qc_minus_qty,
+                                            gather_qty: xmj.gather_qty,
                                             quantity: bill.quantity,
                                             expr: bill.expr,
                                             mb_id: bill.mb_id,
@@ -357,8 +360,10 @@ $(function () {
                                             gcl_id: xmj.gcl_id,
                                             mx_id: xmj.mx_id ? xmj.mx_id : '',
                                             xmj_id: xmj.id ? xmj.id : null,
-                                            gather_qty: xmj.gather_qty,
                                             contract_qty: xmj.contract_qty,
+                                            qc_qty: xmj.qc_qty,
+                                            qc_minus_qty: xmj.qc_minus_qty,
+                                            gather_qty: xmj.gather_qty,
                                             quantity: bill.quantity,
                                             expr: bill.expr,
                                             mb_id: bill.mb_id,
@@ -406,7 +411,7 @@ $(function () {
                                 bills: [g],
                                 gcl,
                                 leafXmjs: _.filter(gcl.leafXmjs, function (item) {
-                                    return item.gather_qty !== undefined && item.gather_qty !== null
+                                    return item.gather_qty !== undefined && item.gather_qty !== null || (item.qc_minus_qty !== undefined && item.qc_minus_qty !== null)
                                 }),
                             })
                         }
@@ -426,8 +431,10 @@ $(function () {
                                         gcl_id: xmj.gcl_id,
                                         mx_id: xmj.mx_id ? xmj.mx_id : '',
                                         xmj_id: xmj.id ? xmj.id : null,
-                                        gather_qty: xmj.gather_qty,
                                         contract_qty: xmj.contract_qty,
+                                        qc_qty: xmj.qc_qty,
+                                        qc_minus_qty: xmj.qc_minus_qty,
+                                        gather_qty: xmj.gather_qty,
                                         quantity: bill.quantity,
                                         expr: bill.expr,
                                         mb_id: bill.mb_id,
@@ -441,8 +448,10 @@ $(function () {
                                         gcl_id: xmj.gcl_id,
                                         mx_id: xmj.mx_id ? xmj.mx_id : '',
                                         xmj_id: xmj.id ? xmj.id : null,
-                                        gather_qty: xmj.gather_qty,
                                         contract_qty: xmj.contract_qty,
+                                        qc_qty: xmj.qc_qty,
+                                        qc_minus_qty: xmj.qc_minus_qty,
+                                        gather_qty: xmj.gather_qty,
                                         quantity: bill.quantity,
                                         expr: bill.expr,
                                         mb_id: bill.mb_id,
@@ -473,6 +482,9 @@ $(function () {
                         gcl_id: ps.gcl_id,
                         mx_id: ps.mx_id,
                         xmj_id: ps.xmj_id,
+                        contract_qty: null,
+                        qc_qty: null,
+                        qc_minus_qty: null,
                         gather_qty: null,
                         quantity: ps.quantity,
                         expr: ps.expr,

+ 24 - 2
app/service/material.js

@@ -155,6 +155,8 @@ module.exports = app => {
                 decimal: preMaterial && preMaterial.decimal ? preMaterial.decimal : JSON.stringify(materialConst.decimal),
                 is_new: 1,
                 is_stage_self: data.is_stage_self,
+                qty_source: data.qty_source,
+                is_new_qty: 1,
             };
             const transaction = await this.db.beginTransaction();
             try {
@@ -214,9 +216,9 @@ module.exports = app => {
                     let m_tp = null;
                     let m_tax_tp = null;
                     if (data.is_stage_self) {
-                        [m_tp, m_tax_tp] = await this.ctx.service.materialStageBills.insertBills(transaction, this.ctx.tender.id, newMaterial.id, newMaterial.stage_id, insertMaterialStage, JSON.parse(newMaterial.decimal), preMaterial.is_stage_self);
+                        [m_tp, m_tax_tp] = await this.ctx.service.materialStageBills.insertBills(transaction, this.ctx.tender.id, newMaterial.id, newMaterial.stage_id, insertMaterialStage, JSON.parse(newMaterial.decimal), preMaterial.is_stage_self, data.qty_source);
                     } else {
-                        [m_tp, m_tax_tp] = await this.ctx.service.materialBills.updateNewMaterial(transaction, this.ctx.tender.id, newMaterial.id, this.ctx, newMaterial.stage_id, JSON.parse(newMaterial.decimal), preMaterial.is_stage_self);
+                        [m_tp, m_tax_tp] = await this.ctx.service.materialBills.updateNewMaterial(transaction, this.ctx.tender.id, newMaterial.id, this.ctx, newMaterial.stage_id, JSON.parse(newMaterial.decimal), preMaterial.is_stage_self, data.qty_source);
                     }
                     // 修改现行价格指数,并返回调差基数json
                     const ex_calc = await this.ctx.service.materialExponent.updateNewMaterial(transaction, newMaterial.id, this.ctx, newMaterial.stage_id, preMaterial.ex_calc, JSON.parse(newMaterial.decimal));
@@ -486,6 +488,26 @@ module.exports = app => {
                 return false;
             }
         }
+
+        async saveQtySource(newQtySource) {
+            const transaction = await this.db.beginTransaction();
+            try {
+                await this.ctx.service.materialBills.resetQuantityByQtySource(transaction, newQtySource);
+                this.ctx.material.qty_source = newQtySource;
+                const m_tp = await this.ctx.service.materialBills.calcMaterialMTp(transaction);
+                const updateData = {
+                    id: this.ctx.material.id,
+                    qty_source: newQtySource,
+                };
+                await transaction.update(this.tableName, updateData);
+                await transaction.commit();
+                return true;
+            } catch (err) {
+                console.log(err);
+                await transaction.rollback();
+                return false;
+            }
+        }
     }
 
     return Material;

+ 71 - 6
app/service/material_bills.js

@@ -582,13 +582,13 @@ module.exports = app => {
          * @param mid
          * @returns {Promise<number>}
          */
-        async updateNewMaterial(transaction, tid, mid, ctx, stage_id, decimal, pre_is_stage_self = 0) {
+        async updateNewMaterial(transaction, tid, mid, ctx, stage_id, decimal, pre_is_stage_self = 0, qty_source = 1) {
             const materialBillsData = await this.getAllDataByCondition({ where: { tid } });
             let m_tp = 0;
             let m_tax_tp = 0;
             const materialCalculator = new MaterialCalculator(ctx, stage_id, ctx.tender.info);
             for (const mb of materialBillsData) {
-                const [one_tp, one_tax_tp] = await this.calcQuantityByMB(transaction, mid, mb, materialCalculator, decimal, pre_is_stage_self);
+                const [one_tp, one_tax_tp] = await this.calcQuantityByMB(transaction, mid, mb, materialCalculator, decimal, pre_is_stage_self, qty_source);
                 m_tp = this.ctx.helper.add(m_tp, one_tp);
                 m_tax_tp = this.ctx.helper.add(m_tax_tp, one_tax_tp);
             }
@@ -602,10 +602,10 @@ module.exports = app => {
          * @param mb
          * @returns {Promise<*>}
          */
-        async calcQuantityByMB(transaction, mid, mb, materialCalculator, decimal, pre_is_stage_self) {
+        async calcQuantityByMB(transaction, mid, mb, materialCalculator, decimal, pre_is_stage_self, qty_source) {
             const [newmsg_spread, newm_spread] = await this.getSpread(mb, null, decimal.up);
             if (mb.t_type === materialConst.t_type[0].value) {
-                const sql = 'SELECT SUM(`gather_qty`*`quantity`) as quantity FROM ' + this.ctx.service.materialList.tableName + ' WHERE `mid`=? AND `mb_id`=? AND `is_join`=1';
+                const sql = 'SELECT SUM(' + this.ctx.helper.getQtySource(qty_source) + '*`quantity`) as quantity FROM ' + this.ctx.service.materialList.tableName + ' WHERE `mid`=? AND `mb_id`=? AND `is_join`=1';
                 const sqlParam = [mid, mb.id];
                 const mb_quantity = await transaction.queryOne(sql, sqlParam);
                 console.log(mb_quantity);
@@ -815,7 +815,7 @@ module.exports = app => {
                             // 通过管理重新算出quantity并保留小数位
                             if (mb.t_type === materialConst.t_type[0].value) {
                                 // 通过管理重新算出quantity并保留小数位
-                                const sql = 'SELECT SUM(`gather_qty`*`quantity`) as quantity FROM ' + this.ctx.service.materialList.tableName + ' WHERE `mid`=? AND `mb_id`=? AND `ms_id`=? AND `is_join`=1';
+                                const sql = 'SELECT SUM(' + this.ctx.helper.getQtySource(this.ctx.material.qty_source) + '*`quantity`) as quantity FROM ' + this.ctx.service.materialList.tableName + ' WHERE `mid`=? AND `mb_id`=? AND `ms_id`=? AND `is_join`=1';
                                 const sqlParam = [this.ctx.material.id, mb.id, ms.id];
                                 const mb_quantity = await transaction.queryOne(sql, sqlParam);
                                 const newQuantity = this.ctx.helper.round(mb_quantity.quantity, newDecimalQty);
@@ -893,7 +893,7 @@ module.exports = app => {
                     if (newDecimalQty !== this.ctx.material.decimal.qty) {
                         // 通过管理重新算出quantity并保留小数位
                         if (mb.t_type === materialConst.t_type[0].value) {
-                            const sql = 'SELECT SUM(`gather_qty`*`quantity`) as quantity FROM ' + this.ctx.service.materialList.tableName + ' WHERE `mid`=? AND `mb_id`=? AND `is_join`=1';
+                            const sql = 'SELECT SUM(' + this.ctx.helper.getQtySource(this.ctx.material.qty_source) + '*`quantity`) as quantity FROM ' + this.ctx.service.materialList.tableName + ' WHERE `mid`=? AND `mb_id`=? AND `is_join`=1';
                             const sqlParam = [this.ctx.material.id, mb.id];
                             const mb_quantity = await transaction.queryOne(sql, sqlParam);
                             const newQuantity = this.ctx.helper.round(mb_quantity.quantity, newDecimalQty);
@@ -921,6 +921,71 @@ module.exports = app => {
                 }
             }
         }
+        // 来源模式变化更新单价和金额
+        async resetQuantityByQtySource(transaction, newQtySource) {
+            const mbList = await transaction.select(this.tableName, { where: { tid: this.ctx.tender.id }, orders: [['order', 'asc']] });
+            const updateList = [];
+            const materialStageList = this.ctx.material.is_stage_self ? await transaction.select(this.ctx.service.materialStage.tableName, { where: { mid: this.ctx.material.id } }) : [];
+            for (const mb of mbList) {
+                if (mb.t_type === materialConst.t_type[0].value) {
+                    const updateData = {
+                        id: mb.id,
+                    };
+                    if (this.ctx.material.is_stage_self) {
+                        const updateStageBillsList = [];
+                        for (const ms of materialStageList) {
+                            const msb = await transaction.get(this.ctx.service.materialStageBills.tableName, {
+                                mid: this.ctx.material.id,
+                                mb_id: mb.id,
+                                ms_id: ms.id,
+                            });
+                            // 通过管理重新算出quantity并保留小数位
+                            const sql = 'SELECT SUM(' + this.ctx.helper.getQtySource(newQtySource) + '*`quantity`) as quantity FROM ' + this.ctx.service.materialList.tableName + ' WHERE `mid`=? AND `mb_id`=? AND `ms_id`=? AND `is_join`=1';
+                            const sqlParam = [this.ctx.material.id, mb.id, ms.id];
+                            const mb_quantity = await transaction.queryOne(sql, sqlParam);
+                            const newQuantity = this.ctx.helper.round(mb_quantity.quantity, this.ctx.material.decimal.qty);
+                            if (newQuantity !== msb.quantity) {
+                                const updateStageBillData = {
+                                    id: msb.id,
+                                    quantity: newQuantity,
+                                };
+                                msb.quantity = newQuantity;
+                                const newTp = this.ctx.helper.round(this.ctx.helper.mul(msb.quantity, msb.m_spread), this.ctx.material.decimal.tp);
+                                updateStageBillData.m_tp = newTp;
+                                updateStageBillData.m_tax_tp = this.ctx.helper.round(this.ctx.helper.mul(newTp, (1 + this.ctx.helper.div(mb.m_tax, 100))), this.ctx.material.decimal.tp);
+                                updateStageBillsList.push(updateStageBillData);
+                            }
+                        }
+                        if (updateStageBillsList.length > 0) await transaction.updateRows(this.ctx.service.materialStageBills.tableName, updateStageBillsList);
+                        const sql = 'SELECT SUM(`m_tp`) as total_price, SUM(IF(`m_tax_tp` is null, `m_tp`, `m_tax_tp`)) as tax_total_price FROM ' + this.ctx.service.materialStageBills.tableName + ' WHERE `tid` = ? AND `mid` = ? AND `mb_id` = ? AND `is_summary` = 1';
+                        const sqlParam = [this.ctx.tender.id, this.ctx.material.id, mb.id];
+                        const tp = await transaction.queryOne(sql, sqlParam);
+                        updateData.m_tp = this.ctx.helper.round(tp.total_price, this.ctx.material.decimal.tp);
+                        updateData.m_tax_tp = this.ctx.helper.round(tp.tax_total_price, this.ctx.material.decimal.tp);
+                        updateList.push(updateData);
+                    } else {
+                        const sql = 'SELECT SUM(' + this.ctx.helper.getQtySource(newQtySource) + '*`quantity`) as quantity FROM ' + this.ctx.service.materialList.tableName + ' WHERE `mid`=? AND `mb_id`=? AND `is_join`=1';
+                        const sqlParam = [this.ctx.material.id, mb.id];
+                        const mb_quantity = await transaction.queryOne(sql, sqlParam);
+                        const newQuantity = this.ctx.helper.round(mb_quantity.quantity, this.ctx.material.decimal.qty);
+                        if (newQuantity !== mb.quantity) {
+                            mb.quantity = newQuantity;
+                            updateData.quantity = newQuantity;
+                            const newTp = this.ctx.helper.round(this.ctx.helper.mul(mb.quantity, mb.m_spread), this.ctx.material.decimal.tp);
+                            updateData.m_tp = newTp;
+                            updateData.m_tax_tp = this.ctx.helper.round(this.ctx.helper.mul(newTp, (1 + this.ctx.helper.div(mb.m_tax, 100))), this.ctx.material.decimal.tp);
+                            updateList.push(updateData);
+                        }
+                    }
+                }
+            }
+            if (updateList.length > 0) await transaction.updateRows(this.tableName, updateList);
+            if (this.ctx.material.is_stage_self) {
+                for (const ms of materialStageList) {
+                    await this.ctx.service.materialStage.updateMtp(transaction, ms.id);
+                }
+            }
+        }
 
         async updateAllOrder(updateList) {
             await this.db.updateRows(this.tableName, updateList);

+ 23 - 11
app/service/material_list.js

@@ -224,7 +224,7 @@ module.exports = app => {
                 updateId = msbInfo.id;
             }
             const msSql = ms_id ? ' AND `ms_id` = ' + ms_id : '';
-            const sql = 'SELECT SUM(`gather_qty`*`quantity`) as quantity FROM ' + this.tableName + ' WHERE `mid`=? AND `mb_id`=?' + msSql + ' AND `is_join`=1';
+            const sql = 'SELECT SUM(' + this.ctx.helper.getQtySource(this.ctx.material.qty_source) + '*`quantity`) as quantity FROM ' + this.tableName + ' WHERE `mid`=? AND `mb_id`=?' + msSql + ' AND `is_join`=1';
             const sqlParam = [this.ctx.material.id, mb_id];
             const mb_quantity = await transaction.queryOne(sql, sqlParam);
             console.log(mb_quantity);
@@ -245,7 +245,7 @@ module.exports = app => {
                     const msbList = await transaction.select(this.ctx.service.materialStageBills.tableName, { where: { mid: this.ctx.material.id, mb_id } });
                     for (const msb of msbList) {
                         if (msb.ms_id !== parseInt(ms_id)) {
-                            const sql4 = 'SELECT SUM(`gather_qty`*`quantity`) as quantity FROM ' + this.tableName + ' WHERE `mid`=? AND `mb_id`=? AND `ms_id`=? AND `is_join`=1';
+                            const sql4 = 'SELECT SUM(' + this.ctx.helper.getQtySource(this.ctx.material.qty_source) + '*`quantity`) as quantity FROM ' + this.tableName + ' WHERE `mid`=? AND `mb_id`=? AND `ms_id`=? AND `is_join`=1';
                             const sqlParam4 = [this.ctx.material.id, mb_id, msb.ms_id];
                             const mb_quantity4 = await transaction.queryOne(sql4, sqlParam4);
                             const newQuantity4 = this.ctx.helper.round(mb_quantity4.quantity, this.ctx.material.decimal.qty);
@@ -325,7 +325,7 @@ module.exports = app => {
                     const updateMsIds = [];
                     const msbList = await transaction.select(this.ctx.service.materialStageBills.tableName, { where: { mid: this.ctx.material.id, mb_id: mbInfo.id } });
                     for (const msb of msbList) {
-                        const sql = 'SELECT SUM(`gather_qty`*`quantity`) as quantity FROM ' + this.tableName + ' WHERE `mid`=? AND `mb_id`=? AND `ms_id`=? AND `is_join`=1';
+                        const sql = 'SELECT SUM(' + this.ctx.helper.getQtySource(this.ctx.material.qty_source) + '*`quantity`) as quantity FROM ' + this.tableName + ' WHERE `mid`=? AND `mb_id`=? AND `ms_id`=? AND `is_join`=1';
                         const sqlParam = [this.ctx.material.id, mbInfo.id, msb.ms_id];
                         const mb_quantity = await transaction.queryOne(sql, sqlParam);
                         const newQuantity = this.ctx.helper.round(mb_quantity.quantity, this.ctx.material.decimal.qty);
@@ -356,7 +356,7 @@ module.exports = app => {
                     };
                     await transaction.update(this.ctx.service.materialBills.tableName, updateBillsData);
                 } else {
-                    const sql = 'SELECT SUM(`gather_qty`*`quantity`) as quantity FROM ' + this.tableName + ' WHERE `mid`=? AND `mb_id`=? AND `is_join`=1';
+                    const sql = 'SELECT SUM(' + this.ctx.helper.getQtySource(this.ctx.material.qty_source) + '*`quantity`) as quantity FROM ' + this.tableName + ' WHERE `mid`=? AND `mb_id`=? AND `is_join`=1';
                     const sqlParam = [this.ctx.material.id, mbInfo.id];
                     const mb_quantity = await transaction.queryOne(sql, sqlParam);
                     console.log(mb_quantity);
@@ -391,7 +391,7 @@ module.exports = app => {
          * @return {void}
          */
         async getMaterialData(tid, mid) {
-            const sql = 'SELECT ml.`id`, mb.`code`, mb.`name`, mb.`unit`, ml.`order`, ml.`gather_qty`, ml.`quantity`, ml.`expr`, ml.`mb_id`, ml.`gcl_id`, ml.`xmj_id`, ml.`mx_id`, ml.`ms_id`, ml.`tid`, ml.`mid`, mb.m_spread, ml.ms_id, ml.is_join' +
+            const sql = 'SELECT ml.`id`, mb.`code`, mb.`name`, mb.`unit`, ml.`order`, ml.`contract_qty`, ml.`qc_qty`, ml.`qc_minus_qty`, ml.`gather_qty`, ml.`quantity`, ml.`expr`, ml.`mb_id`, ml.`gcl_id`, ml.`xmj_id`, ml.`mx_id`, ml.`ms_id`, ml.`tid`, ml.`mid`, mb.m_spread, ml.ms_id, ml.is_join' +
                 ' FROM ' + this.tableName + ' as ml' +
                 ' LEFT JOIN ' + this.ctx.service.materialBills.tableName + ' as mb' +
                 ' ON ml.`mb_id` = mb.`id`' +
@@ -444,11 +444,11 @@ module.exports = app => {
             const copyMLArray = [];
             for (const ml of materialListData) {
                 // 获取小计值
-                let gather_qty = null;
+                let qtys = null;
                 if (ml.mx_id !== null && ml.mx_id !== '') {
-                    gather_qty = await this.ctx.service.stagePos.getGatherQtyByMaterial(ml.tid, newMaterial.stage_id, ml.gcl_id, ml.mx_id);
+                    qtys = await this.ctx.service.stagePos.getGatherQtyByMaterial(ml.tid, newMaterial.stage_id, ml.gcl_id, ml.mx_id);
                 } else {
-                    gather_qty = await this.ctx.service.stageBills.getGatherQtyByMaterial(ml.tid, newMaterial.stage_id, ml.gcl_id);
+                    qtys = await this.ctx.service.stageBills.getGatherQtyByMaterial(ml.tid, newMaterial.stage_id, ml.gcl_id);
                 }
                 const newMaterialList = {
                     tid: ml.tid,
@@ -458,7 +458,10 @@ module.exports = app => {
                     gcl_id: ml.gcl_id,
                     xmj_id: ml.xmj_id,
                     mx_id: ml.mx_id,
-                    gather_qty,
+                    contract_qty: qtys ? qtys.contract_qty : null,
+                    qc_qty: qtys ? qtys.qc_qty : null,
+                    qc_minus_qty: qtys ? qtys.qc_minus_qty : null,
+                    gather_qty: qtys ? qtys.gather_qty : null,
                     quantity: ml.quantity,
                     expr: ml.expr,
                     is_join: ml.is_join,
@@ -490,7 +493,10 @@ module.exports = app => {
                         gcl_id: ml.gcl_id,
                         xmj_id: ml.xmj_id,
                         mx_id: ml.mx_id,
-                        gather_qty: is_change ? ml.contract_qty : ml.gather_qty,
+                        contract_qty: ml.contract_qty,
+                        qc_qty: ml.qc_qty,
+                        qc_minus_qty: ml.qc_minus_qty,
+                        gather_qty: ml.gather_qty,
                         quantity: ml.quantity ? ml.quantity : 0,
                         expr: ml.expr ? ml.expr : '',
                         is_join: is_join ? 0 : 1,
@@ -517,7 +523,10 @@ module.exports = app => {
                         gcl_id: ml.gcl_id,
                         xmj_id: ml.xmj_id,
                         mx_id: ml.mx_id,
-                        gather_qty: is_change ? ml.contract_qty : ml.gather_qty,
+                        contract_qty: ml.contract_qty,
+                        qc_qty: ml.qc_qty,
+                        qc_minus_qty: ml.qc_minus_qty,
+                        gather_qty: ml.gather_qty,
                         quantity: ml.quantity ? ml.quantity : 0,
                         expr: ml.expr ? ml.expr : '',
                         is_join: is_join ? 0 : 1,
@@ -584,6 +593,9 @@ module.exports = app => {
                                     xmj_id: xmj.xmj_id,
                                     mx_id: xmj.mx_id,
                                     ms_id: xmj.ms_id ? xmj.ms_id : null,
+                                    contract_qty: xmj.contract_qty,
+                                    qc_qty: xmj.qc_qty,
+                                    qc_minus_qty: xmj.qc_minus_qty,
                                     gather_qty: xmj.gather_qty,
                                     quantity,
                                     in_time: new Date(),

+ 4 - 4
app/service/material_stage_bills.js

@@ -25,7 +25,7 @@ module.exports = app => {
             super(ctx);
             this.tableName = 'material_stage_bills';
         }
-        async insertBills(transaction, tid, mid, stage_id, materialStageData, decimal, pre_is_stage_self = 0) {
+        async insertBills(transaction, tid, mid, stage_id, materialStageData, decimal, pre_is_stage_self = 0, qty_source = 1) {
             let m_tp = 0;
             let m_tax_tp = 0;
             // 复制工料表并生成
@@ -42,7 +42,7 @@ module.exports = app => {
                             ms_id: ms.id,
                             is_summary: b.is_summary,
                         };
-                        const [one_tp, one_tax_tp] = await this.calcQuantityByMB(transaction, mid, b, oneStageBillsData, materialCalculator, decimal, pre_is_stage_self);
+                        const [one_tp, one_tax_tp] = await this.calcQuantityByMB(transaction, mid, b, oneStageBillsData, materialCalculator, decimal, pre_is_stage_self, qty_source);
                         insertStageBillsData.push(oneStageBillsData);
                         m_tp = this.ctx.helper.add(m_tp, one_tp);
                         m_tax_tp = this.ctx.helper.add(m_tax_tp, one_tax_tp);
@@ -220,10 +220,10 @@ module.exports = app => {
          * @param mb
          * @returns {Promise<*>}
          */
-        async calcQuantityByMB(transaction, mid, mb, msb, materialCalculator, decimal, pre_is_stage_self) {
+        async calcQuantityByMB(transaction, mid, mb, msb, materialCalculator, decimal, pre_is_stage_self, qty_source) {
             const [newmsg_spread, newm_spread] = await this.getSpread(mb, null, decimal.up);
             if (mb.t_type === materialConst.t_type[0].value) {
-                const sql = 'SELECT SUM(`gather_qty`*`quantity`) as quantity FROM ' + this.ctx.service.materialList.tableName + ' WHERE `mid`=? AND `ms_id`=? AND `mb_id`=? AND `is_join`=1';
+                const sql = 'SELECT SUM(' + this.ctx.helper.getQtySource(qty_source) + '*`quantity`) as quantity FROM ' + this.ctx.service.materialList.tableName + ' WHERE `mid`=? AND `ms_id`=? AND `mb_id`=? AND `is_join`=1';
                 const sqlParam = [mid, msb.ms_id, mb.id];
                 const mb_quantity = await transaction.queryOne(sql, sqlParam);
                 console.log(mb_quantity);

+ 12 - 3
app/service/stage_bills.js

@@ -452,6 +452,7 @@ module.exports = app => {
             const whereSql = this.ctx.helper.whereSql({tid: tid, sid: stage_id_list.split(',')});
             const sql = 'SELECT Bills.lid, Bills.tid, Bills.sid,' +
                 '    Sum(Bills.contract_qty) As contract_qty, Sum(Bills.contract_tp) As contract_tp,' +
+                '    Sum(Bills.qc_minus_qty) As qc_minus_qty,' +
                 '    Sum(Bills.qc_qty) As qc_qty, Sum(Bills.qc_tp) As qc_tp' +
                 '  FROM ' + this.tableName + ' As Bills ' +
                 '  INNER JOIN ( ' +
@@ -473,7 +474,12 @@ module.exports = app => {
          */
         async getGatherQtyByMaterial(tid, stage_id_list, lid) {
             stage_id_list = stage_id_list !== null ? stage_id_list.split(',') : [];
-            let gather_qty = 0;
+            const qtys = {
+                gather_qty: 0,
+                contract_qty: 0,
+                qc_qty: 0,
+                qc_minus_qty: 0,
+            };
             for (const sid of stage_id_list) {
                 const sql = 'SELECT Bills.* FROM ' + this.tableName + ' As Bills ' +
                     '  INNER JOIN ( ' +
@@ -486,10 +492,13 @@ module.exports = app => {
                 const sqlParam = [tid, sid, lid];
                 const result = await this.db.queryOne(sql, sqlParam);
                 if (result) {
-                    gather_qty = this.ctx.helper.add(gather_qty, this.ctx.helper.add(result.contract_qty, result.qc_qty));
+                    qtys.contract_qty = this.ctx.helper.add(qtys.contract_qty, result.contract_qty);
+                    qtys.qc_qty = this.ctx.helper.add(qtys.qc_qty, result.qc_qty);
+                    qtys.qc_minus_qty = this.ctx.helper.add(qtys.qc_minus_qty, result.qc_minus_qty);
+                    qtys.gather_qty = this.ctx.helper.add(qtys.gather_qty, this.ctx.helper.add(result.contract_qty, result.qc_qty));
                 }
             }
-            return gather_qty !== 0 ? gather_qty : null;
+            return this.ctx.helper.resetQtys(qtys);
         }
 
         async getSumTotalPriceByMaterial(stage_list) {

+ 15 - 6
app/service/stage_pos.js

@@ -639,7 +639,7 @@ module.exports = app => {
             const sids = stage_id_list.split(',');
             const result = [];
             for (const sid of sids) {
-                const sql = 'SELECT id, tid, sid, pid, lid, contract_qty, qc_qty, postil, `times`, `order`, `contract_expr`' +
+                const sql = 'SELECT id, tid, sid, pid, lid, contract_qty, qc_qty, `qc_minus_qty`, postil, `times`, `order`, `contract_expr`' +
                     '  FROM ' + this.tableName +
                     '  WHERE tid = ? And sid = ? ';
                 const sqlParam = [tid, sid];
@@ -650,10 +650,11 @@ module.exports = app => {
                     if (rsp) {
                         rsp.contract_qty = this.ctx.helper.add(rsp.contract_qty, sp.contract_qty);
                         rsp.qc_qty = this.ctx.helper.add(rsp.qc_qty, sp.qc_qty);
-                    } else if (!comefrom || (comefrom === 'list' && (sp.contract_qty || sp.qc_qty))) {
+                        rsp.qc_minus_qty = this.ctx.helper.add(rsp.qc_minus_qty, sp.qc_minus_qty);
+                    } else if (!comefrom || (comefrom === 'list' && (sp.contract_qty || sp.qc_qty || sp.qc_minus_qty))) {
                         result.push({
                             id: sp.id, tid: sp.tid, lid: sp.lid, pid: sp.pid,
-                            contract_qty: sp.contract_qty, qc_qty: sp.qc_qty,
+                            contract_qty: sp.contract_qty, qc_qty: sp.qc_qty, qc_minus_qty: sp.qc_minus_qty,
                         });
                     }
                 }
@@ -671,7 +672,12 @@ module.exports = app => {
          */
         async getGatherQtyByMaterial(tid, stage_id_list, lid, pid) {
             stage_id_list = stage_id_list !== null ? stage_id_list.split(',') : [];
-            let gather_qty = 0;
+            const qtys = {
+                gather_qty: 0,
+                contract_qty: 0,
+                qc_qty: 0,
+                qc_minus_qty: 0,
+            };
             for (const sid of stage_id_list) {
                 const sql = 'SELECT Pos.contract_qty, Pos.qc_qty FROM ' +
                     '  (SELECT * FROM ' + this.tableName + ' WHERE tid = ? AND sid = ?) As Pos ' +
@@ -685,10 +691,13 @@ module.exports = app => {
                 const sqlParam = [tid, sid, tid, sid, lid, pid];
                 const result = await this.db.queryOne(sql, sqlParam);
                 if (result) {
-                    gather_qty = this.ctx.helper.add(gather_qty, this.ctx.helper.add(result.contract_qty, result.qc_qty));
+                    qtys.contract_qty = this.ctx.helper.add(qtys.contract_qty, result.contract_qty);
+                    qtys.qc_qty = this.ctx.helper.add(qtys.qc_qty, result.qc_qty);
+                    qtys.qc_minus_qty = this.ctx.helper.add(qtys.qc_minus_qty, result.qc_minus_qty);
+                    qtys.gather_qty = this.ctx.helper.add(qtys.gather_qty, this.ctx.helper.add(result.contract_qty, result.qc_qty));
                 }
             }
-            return gather_qty !== 0 ? gather_qty : null;
+            return this.ctx.helper.resetQtys(qtys);
         }
     }
 

+ 21 - 3
app/view/material/audit_modal.ejs

@@ -691,11 +691,11 @@
     <div class="modal-dialog" role="document">
         <form action="/tender/<%- ctx.tender.id %>/measure/material/<%- ctx.material.order %>/save/decimal" method="post" onsubmit="return checkSetDecimal();" class="modal-content">
             <div class="modal-header">
-                <h5 class="modal-title">小数位数</h5>
+                <h5 class="modal-title">设置</h5>
             </div>
             <div class="modal-body">
-                <div class="form-group">
-
+                <div class="form-group mb-3">
+                    <h5>小数位数</h5>
                     <div class="row">
                         <div class="col-4">
                             <div class="input-group input-group-sm">
@@ -723,6 +723,24 @@
                         </div>
                     </div>
                 </div>
+                <div class="form-group">
+                    <h5>计量期数据来源</h5>
+                    <div>
+                        <% if ((material.status === auditConst.status.uncheck || material.status === auditConst.status.checkNo) && ctx.session.sessionUser.accountId === material.user_id && (material.is_new_qty || (!material.is_new_qty && !(ctx.url.indexOf('/file') !== -1 || ctx.url.indexOf('/exponent') !== -1)))) { %>
+                        <% for (const qs of qtySourceConst) { %>
+                            <div class="form-check form-check-inline">
+                            <input type="radio" name="qty_source" id="<%- qs.key %>_source" class="form-check-input" value="<%- qs.value %>" <% if (material.qty_source === qtySourceValueConst[qs.key]) { %>checked<% } %>>
+                            <label class="form-check-label" for="<%- qs.key %>_source"><%- qs.name %></label>
+                        </div>
+                        <% } %>
+                        <% } else { %>
+                        <div class="form-check form-check-inline">
+                            <input type="radio" class="form-check-input" checked disabled>
+                            <label class="form-check-label"><%- ctx.helper._.find(qtySourceConst, { value: material.qty_source }).name %></label>
+                        </div>
+                        <% } %>
+                    </div>
+                </div>
             </div>
             <div class="modal-footer">
                 <input type="hidden" name="_csrf_j" value="<%= ctx.csrf %>" />

+ 3 - 0
app/view/material/info.ejs

@@ -298,6 +298,9 @@
     const materialID = <%- material.id %>;
     const materialTax = <%- material.material_tax %>;
     let materialRate = parseInt('<%- material.rate %>');
+    const materialIsNewQty = parseInt('<%- material.is_new_qty %>');
+    const qtySource = parseInt('<%- material.qty_source %>');
+    const qtySourceValueConst = JSON.parse(unescape('<%- escape(JSON.stringify(qtySourceValueConst)) %>'));
     const materialDecimal = JSON.parse(unescape('<%- escape(JSON.stringify(material.decimal)) %>'));
     let m_tp = <%= material.m_tp !== null ? material.m_tp : 0 %>;
     let ex_tp = <%= material.ex_tp !== null ? material.ex_tp : 0 %>;

+ 3 - 0
app/view/material/list.ejs

@@ -109,6 +109,9 @@
     const stage_order = <%- material.order %>;
     const materialID = <%- material.id %>;
     const tenderID = <%- tender.id %>;
+    const materialQtySource = <%- material.qty_source %>;
+    const qtySourceValueConst = JSON.parse(unescape('<%- escape(JSON.stringify(qtySourceValueConst)) %>'));
+    const materialIsNewQty = parseInt('<%- material.is_new_qty %>');
     const materialDecimal = JSON.parse(unescape('<%- escape(JSON.stringify(material.decimal)) %>'));
     const openMaterialChecklist = parseInt(<%- ctx.session.sessionProject.page_show.openMaterialChecklist %>);
     let materialListData, materialChecklistData, notJoinList, notChangeList, ledger, curLedgerData, pos, curPosData, gclGatherData, gclList, selfList, gclGatherListData;

+ 16 - 4
app/view/material/modal.ejs

@@ -8,15 +8,15 @@
                 <h5 class="modal-title">添加新一期</h5>
             </div>
             <div class="modal-body">
-                <div class="form-group">
+                <div class="form-group mb-2">
                     <label>调差期</label>
                     <input class="form-control form-control-sm" value="第 <%- materials.length + 1 %> 期" type="text" readonly="">
                 </div>
-                <div class="form-group">
+                <div class="form-group mb-2">
                     <label>调差周期</label>
                     <input class="datepicker-here form-control form-control-sm" autocomplete="off" readonly name="period" placeholder="点击选择时间" data-range="true" data-multiple-dates-separator=" ~ " data-language="zh" type="text">
                 </div>
-                <div class="form-group">
+                <div class="form-group mb-2">
                     <label>本期调差,包含计量期<span class="ml-2 text-danger" id="show_order" style="display: none">第<b class="mx-2"></b>期</span></label>
                     <div class="row">
                         <% for (const stage of stages) { %>
@@ -29,7 +29,7 @@
                         <% } %>
                     </div>
                 </div>
-                <div class="form-group" id="material_unitPrice" style="display: none">
+                <div class="form-group mb-2" id="material_unitPrice" style="display: none">
                     <label>多期计量-材料单价使用</label>
                     <div>
                         <div class="form-check form-check-inline">
@@ -42,6 +42,18 @@
                         </div>
                     </div>
                 </div>
+                <div class="form-group mb-2">
+                    <label>计量期数据来源</label>
+                    <div>
+                        <% for (const qs of qtySourceConst) { %>
+                        <div class="form-check form-check-inline">
+                            <% console.log(materials.length) %>
+                            <input type="radio" name="qty_source" id="<%- qs.key %>_source" class="form-check-input" value="<%- qs.value %>" <% if (materials && materials.length === 0 && qs.value === 1) { %>checked<% } else if (materials && materials.length > 0 && materials[0].qty_source === qtySourceValueConst[qs.key]) { %>checked<% } %>>
+                            <label class="form-check-label" for="<%- qs.key %>_source"><%- qs.name %></label>
+                        </div>
+                        <% } %>
+                    </div>
+                </div>
             </div>
             <div class="modal-footer">
                 <input type="hidden" name="_csrf_j" value="<%= ctx.csrf %>" />

+ 13 - 1
sql/update.sql

@@ -76,7 +76,7 @@ ADD COLUMN `type` tinyint(1) NOT NULL DEFAULT 1 COMMENT '1为本期不参与调
 ALTER TABLE `zh_stage_bills_pc`
 MODIFY COLUMN `lid` varchar(36) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '项目节id' AFTER `sorder`;
 
-CREATE TABLE `calculation`.`zh_project_stopmsg`  (
+CREATE TABLE `zh_project_stopmsg`  (
   `id` int NOT NULL AUTO_INCREMENT,
   `pid` int NOT NULL COMMENT '项目id',
   `msg` varchar(255) NULL COMMENT '停用信息',
@@ -84,3 +84,15 @@ CREATE TABLE `calculation`.`zh_project_stopmsg`  (
   `in_time` datetime NULL COMMENT '创建时间',
   PRIMARY KEY (`id`)
 ) ENGINE = InnoDB CHARACTER SET = utf8 COMMENT = '用户账号停用提示表';
+
+ALTER TABLE `zh_material_list`
+ADD COLUMN `contract_qty` decimal(30, 8) NULL DEFAULT NULL COMMENT '本期合同数量' AFTER `mx_id`,
+ADD COLUMN `qc_qty` decimal(30, 8) NULL DEFAULT NULL COMMENT '本期数量变更数量' AFTER `contract_qty`,
+ADD COLUMN `qc_minus_qty` decimal(30, 8) NULL DEFAULT NULL COMMENT '本期不计价数量' AFTER `qc_qty`,
+MODIFY COLUMN `gather_qty` decimal(30, 8) NULL DEFAULT NULL COMMENT '本期完成数量' AFTER `qc_minus_qty`;
+
+ALTER TABLE `zh_material`
+ADD COLUMN `qty_source` tinyint(4) NOT NULL DEFAULT 1 COMMENT '计量本期计量数量来源,默认是完成计量1' AFTER `status`;
+
+ALTER TABLE `zh_material`
+ADD COLUMN `is_new_qty` tinyint(1) NOT NULL DEFAULT 0 COMMENT '是否是新建的调差期,用于qty值更新' AFTER `is_new`;