Browse Source

Merge branch 'master' of http://192.168.1.41:3000/maixinrong/Calculation

TonyKang 5 years ago
parent
commit
e3dececadc

+ 5 - 0
app/controller/dashboard_controller.js

@@ -27,12 +27,14 @@ module.exports = app => {
             const auditStages = await ctx.service.stageAudit.getAuditStage(ctx.session.sessionUser.accountId);
             const auditChanges = await ctx.service.changeAudit.getAuditChange(ctx.session.sessionUser.accountId);
             const auditRevise = await ctx.service.reviseAudit.getAuditRevise(ctx.session.sessionUser.accountId);
+            const auditMaterial = await ctx.service.materialAudit.getAuditMaterial(ctx.session.sessionUser.accountId);
             const pa = await ctx.service.projectAccount.getDataById(ctx.session.sessionUser.accountId);
             const lastNotice = pa.last_notice ? pa.last_notice : (pa.last_notice === 0 ? new Date() : new Date(pa.last_login * 1000));
             const noticeLedger = await ctx.service.ledgerAudit.getNoticeTender(ctx.session.sessionProject.id, pa.id, lastNotice);
             const noticeStage = await ctx.service.stageAudit.getNoticeStage(ctx.session.sessionProject.id, pa.id, lastNotice);
             const noticeChange = await ctx.service.changeAudit.getNoticeChange(ctx.session.sessionProject.id, pa.id, lastNotice);
             const noticeRevise = await ctx.service.reviseAudit.getNoticeRevise(ctx.session.sessionProject.id, pa.id, lastNotice);
+            const noticeMaterial = await ctx.service.materialAudit.getNoticeMaterial(ctx.session.sessionProject.id, pa.id, lastNotice);
             const projectData = await ctx.service.project.getDataById(ctx.session.sessionProject.id);
             // 获取销售人员数据
             const salesmanData = await ctx.service.manager.getDataById(projectData.manager_id);
@@ -52,16 +54,19 @@ module.exports = app => {
                 auditStages,
                 auditChanges,
                 auditRevise,
+                auditMaterial,
                 role: pa.role,
                 authMobile: pa.auth_mobile,
                 acLedger: auditConst.ledger,
                 acStage: auditConst.stage,
                 acChange: auditConst.flow,
                 acRevise: auditConst.revise,
+                acMaterial: auditConst.material,
                 noticeLedger,
                 noticeStage,
                 noticeChange,
                 noticeRevise,
+                noticeMaterial,
                 projectData,
                 salesmanData,
                 officeName,

+ 1 - 1
app/controller/material_controller.js

@@ -198,7 +198,7 @@ module.exports = app => {
             const times = ctx.material.status === auditConst.status.checkNo ? ctx.material.times - 1 : ctx.material.times;
             ctx.material.user = await ctx.service.projectAccount.getAccountInfoById(ctx.material.user_id);
             ctx.material.auditHistory = [];
-            if (ctx.material.times > 1) {
+            if (ctx.material.times >= 1) {
                 for (let i = 1; i <= times; i++) {
                     ctx.material.auditHistory.push(await ctx.service.materialAudit.getAuditors(ctx.material.id, i));
                 }

+ 11 - 11
app/lib/material_calc.js

@@ -40,18 +40,18 @@ class MaterialCalculate {
     }
 
     _calculateExpr(expr) {
-        let formula = expr;
-        for (const b of this.bases) {
-            formula = formula.replace(b.reg, b.value);
-        }
-        const percent = formula.match(this.percentReg);
-        if (percent) {
-            for (const p of percent) {
-                const v = math.eval(p.replace('%', '/100'));
-                formula = formula.replace(p, v);
-            }
-        }
         try {
+            let formula = expr;
+            for (const b of this.bases) {
+                formula = formula.replace(b.reg, b.value);
+            }
+            const percent = formula.match(this.percentReg);
+            if (percent) {
+                for (const p of percent) {
+                    const v = math.eval(p.replace('%', '/100'));
+                    formula = formula.replace(p, v);
+                }
+            }
             const value = math.eval(formula);
             return value;
         } catch (err) {

+ 28 - 0
app/lib/rpt_data_analysis.js

@@ -10,6 +10,7 @@
 
 const math = require('mathjs');
 const standard = require('../const/standard');
+const moment = require('moment');
 
 // 通用方法
 const rdaUtils = {
@@ -957,6 +958,32 @@ const auditSelect = {
         }
     }
 };
+const datetimeFormat = {
+    name: '日期格式化',
+    hint: '参见帮助',
+    defaultSetting: {
+        tables: [
+            {name: 'mem_stage_bonus', fields: [
+                {field: 'real_time', formatter: 'yyyy-MM-DD'},
+                {field: 'create_time', formatter: 'yyyy-MM-DD'}
+            ]},
+        ]
+    },
+    fun: function (ctx, data, fieldsKey, options, csRela) {
+        if (!options.tables) return;
+        const tables = options.tables instanceof Array ? tables : [options.tables];
+        if (tables.length === 0) return;
+
+        for (const table of tables) {
+            const formatData = data[table.name];
+            for (const fd of formatData) {
+                for (const f of table.fields) {
+                    fd[f.field] = moment(fd[f.field]).format(f.formatter);
+                }
+            }
+        }
+    }
+};
 
 const analysisObj = {
     changeSort,
@@ -970,6 +997,7 @@ const analysisObj = {
     gatherStagePay,
     addSumChapter,
     auditSelect,
+    datetimeFormat,
 };
 const analysisDefine = (function (obj) {
     const result = [];

+ 4 - 0
app/middleware/stage_check.js

@@ -53,6 +53,10 @@ module.exports = options => {
             stage.highOrder = yield this.service.stage.count({
                 tid: this.tender.id,
             });
+            const materials = yield this.service.material.getAllDataByCondition({ columns: ['stage_id', 's_order'], where: { tid: this.tender.id } });
+            stage.hadMaterial = materials.find(function(item) {
+                return item.s_order.indexOf(stage.highOrder.toString()) !== -1;
+            });
             // 权限相关
             // todo 校验权限 (标段参与人、分享)
             const accountId = this.session.sessionUser.accountId,

+ 2 - 2
app/public/js/material.js

@@ -187,12 +187,12 @@ $(document).ready(() => {
     const materialCol = {
         getValue: {
             msg_spread: function (data) {
-                return ZhCalc.round(ZhCalc.sub(data.msg_tp, data.basic_price), 2);
+                return ZhCalc.round(ZhCalc.sub(data.msg_tp, data.basic_price), 3);
             },
             m_spread : function (data) {
                 const msg_spread = materialCol.getValue.msg_spread(data);
                 const cor = msg_spread >= 0 ? ZhCalc.mul(data.basic_price, ZhCalc.div(data.m_up_risk, 100)) : ZhCalc.mul(data.basic_price, ZhCalc.div(data.m_down_risk, 100));
-                return Math.abs(msg_spread) > Math.abs(cor) ? (msg_spread > 0 ? ZhCalc.round(ZhCalc.sub(msg_spread, cor), 2) : ZhCalc.round(ZhCalc.add(msg_spread, cor), 2)) : 0;
+                return Math.abs(msg_spread) > Math.abs(cor) ? (msg_spread > 0 ? ZhCalc.round(ZhCalc.sub(msg_spread, cor), 3) : ZhCalc.round(ZhCalc.add(msg_spread, cor), 3)) : 0;
             },
             m_tp: function (data) {
                 return ZhCalc.round(ZhCalc.mul(materialCol.getValue.m_spread(data), data.quantity), 2);

+ 29 - 5
app/service/material_audit.js

@@ -483,17 +483,41 @@ module.exports = app => {
          * @returns {Promise<*>}
          */
         async getAuditMaterial(auditorId) {
-            const sql = 'SELECT sa.`aid`, sa.`times`, sa.`order`, sa.`begin_time`, sa.`end_time`, sa.`tid`, sa.`mid`,' +
-                        '    s.`order` As `sorder`, s.`status` As `sstatus`,' +
+            const sql = 'SELECT ma.`aid`, ma.`times`, ma.`order`, ma.`begin_time`, ma.`end_time`, ma.`tid`, ma.`mid`,' +
+                        '    m.`order` As `morder`, m.`status` As `mstatus`,' +
                         '    t.`name`, t.`project_id`, t.`type`, t.`user_id` ' +
-                        '  FROM ?? AS sa, ?? AS s, ?? As t ' +
-                        '  WHERE ((sa.`aid` = ? and sa.`status` = ?) OR (s.`user_id` = ? and sa.`status` = ? and s.`status` = ? and sa.`times` = (s.`times`-1)))' +
-                        '    and sa.`mid` = s.`id` and sa.`tid` = t.`id`';
+                        '  FROM ?? AS ma, ?? AS m, ?? As t ' +
+                        '  WHERE ((ma.`aid` = ? and ma.`status` = ?) OR (m.`user_id` = ? and ma.`status` = ? and m.`status` = ? and ma.`times` = (m.`times`-1)))' +
+                        '    and ma.`mid` = m.`id` and ma.`tid` = t.`id`';
             const sqlParam = [this.tableName, this.ctx.service.material.tableName, this.ctx.service.tender.tableName, auditorId, auditConst.status.checking, auditorId, auditConst.status.checkNo, auditConst.status.checkNo];
             return await this.db.query(sql, sqlParam);
         }
 
         /**
+         * 获取 某时间后 审批进度 更新的期
+         * @param {Number} pid - 查询标段
+         * @param {Number} uid - 查询人
+         * @param {Date} time - 查询时间
+         * @returns {Promise<*>}
+         */
+        async getNoticeMaterial(pid, uid, time) {
+            const sql = 'SELECT t.`name`, t.`project_id`, t.`type`, t.`user_id`, ' +
+                '    m.`order` As `m_order`, m.`status` As `m_status`, ' +
+                '    ma.`aid`, ma.`times`, ma.`order`, ma.`end_time`, ma.`tid`, ma.`mid`, ma.`status`, ' +
+                '    pa.`name` As `su_name`, pa.role As `su_role`, pa.company As `su_company`' +
+                '  FROM ?? As t' +
+                '  LEFT JOIN ?? As m On t.`id` = m.`tid`' +
+                '  LEFT JOIN ?? As ma ON m.`id` = ma.`mid`' +
+                '  LEFT JOIN ?? As pa ON ma.`aid` = pa.`id`' +
+                '  WHERE ma.`aid` <> ? and ma.`end_time` > ? and t.`project_id` = ?' +
+                '  GROUP By t.`id`' +
+                '  ORDER By ma.`end_time`';
+            const sqlParam = [this.ctx.service.tender.tableName, this.ctx.service.material.tableName, this.tableName,
+                this.ctx.service.projectAccount.tableName, uid, time, pid];
+            return await this.db.query(sql, sqlParam);
+        }
+
+        /**
          * 获取审核人流程列表
          *
          * @param auditorId

+ 4 - 3
app/service/report.js

@@ -108,15 +108,16 @@ module.exports = app => {
                             runnableRst.push(service.changeAuditList.getChangeAuditBills(params.tender_id)); // 获取所有审核通过的变更清单
                             runnableKey.push(filter);
                             break;
-                        case 'stage_jgcl':
+                        case 'mem_stage_jgcl':
                             runnableRst.push(service.reportMemory.getStageJgcl(params.tender_id, params.stage_id, memFieldKeys[filter]));
                             runnableKey.push(filter);
                             break;
-                        case 'stage_bonus':
+                        case 'mem_stage_bonus':
                             runnableRst.push(service.reportMemory.getStageBonus(params.tender_id, params.stage_id, memFieldKeys[filter]));
                             runnableKey.push(filter);
                             break;
-                        case 'stage_other':
+                        case 'mem_stage_other':
+                        case 'mem_stage_other':
                             runnableRst.push(service.reportMemory.getStageOther(params.tender_id, params.stage_id, memFieldKeys[filter]));
                             runnableKey.push(filter);
                             break;

+ 1 - 1
app/service/stage_bonus.js

@@ -44,7 +44,7 @@ module.exports = app => {
         }
 
         async getEndStageData(sorder) {
-            const sql = 'SELECT * From ' + this.tableName + ' WHERE sorder <= ? And tid = ?';
+            const sql = 'SELECT * From ' + this.tableName + ' WHERE sorder <= ? And tid = ? ORDER BY `sorder`, `order`';
             const sqlParam = [sorder, this.ctx.tender.id];
             const data = await this.db.query(sql, sqlParam);
             return data;

+ 7 - 0
app/service/tender.js

@@ -283,6 +283,13 @@ module.exports = app => {
                 await transaction.delete(this.ctx.service.reviseBills.tableName, { tender_id: id });
                 await transaction.delete(this.ctx.service.revisePos.tableName, { tid: id });
 
+                await transaction.delete(this.ctx.service.material.tableName, { tid: id });
+                await transaction.delete(this.ctx.service.materialAudit.tableName, { tid: id });
+                await transaction.delete(this.ctx.service.materialBills.tableName, { tid: id });
+                await transaction.delete(this.ctx.service.materialBillsHistory.tableName, { tid: id });
+                await transaction.delete(this.ctx.service.materialList.tableName, { tid: id });
+                await transaction.delete(this.ctx.service.materialListNotjoin.tableName, { tid: id });
+
                 await transaction.delete(this.ctx.service.signatureUsed.tableName, { tender_id: id });
                 await transaction.delete(this.ctx.service.signatureRole.tableName, { tender_id: id });
                 // 先删除附件文件

+ 48 - 2
app/view/dashboard/index.ejs

@@ -28,7 +28,7 @@
                     <div class="card">
                         <div class="card-header">需要你处理</div>
                         <div class="card-body">
-                            <% if (auditTenders.length !== 0 || auditRevise.length !== 0 || auditStages.length !== 0 || auditChanges.length !== 0) { %>
+                            <% if (auditTenders.length !== 0 || auditRevise.length !== 0 || auditStages.length !== 0 || auditChanges.length !== 0 || auditMaterial.length !== 0) { %>
                                 <ul class="list-unstyled m-0">
                                     <% for (const t of auditTenders) { %>
                                         <% if (t.ledger_status === acLedger.status.checking) { %>
@@ -116,6 +116,35 @@
                                             </div>
                                         </li>
                                     <% } %>
+                                    <% for (const am of auditMaterial) { %>
+                                        <% if (am.mstatus !== acMaterial.status.checkNo) { %>
+                                            <li class="media pb-3 mb-3 border-bottom-1">
+                                                <div class="media-body">
+                                                    <div class="row">
+                                                        <div class="col-auto"><span class="badge badge-secondary">材料调差</span></div>
+                                                        <div class="col-6"><a href="/tender/<%- am.tid %>"><%- am.name %></a> 第<%- am.morder %>期</div>
+                                                        <div class="col-3 ml-auto text-right pl-0"><a href="/tender/<%- am.tid %>/measure/material/<%- am.morder %>" class="btn btn-sm btn-outline-primary">审批</a></div>
+                                                    </div>
+                                                    <p class="mt-1 mb-0"><%- ctx.session.sessionUser.name %><small class="ml-1 text-muted"><%- (role ? '- ' + role : '') %></small>
+                                                        <span class="pull-right text-muted"><%- am.begin_time.toLocaleString() %></span>
+                                                    </p>
+                                                </div>
+                                            </li>
+                                        <% } else { %>
+                                            <li class="media pb-3 mb-3 border-bottom-1">
+                                                <div class="media-body">
+                                                    <div class="row">
+                                                        <div class="col-auto"><span class="badge badge-secondary">材料调差</span></div>
+                                                        <div class="col-6"><a href="/tender/<%- am.tid %>"><%- am.name %></a> 第<%- am.morder %>期</div>
+                                                        <div class="col-3 ml-auto text-right pl-0"><a href="/tender/<%- am.tid %>/measure/material/<%- am.morder %>" class="btn btn-sm btn-outline-primary">重新上报</a></div>
+                                                    </div>
+                                                    <p class="mt-1 mb-0"><%- ctx.session.sessionUser.name %><small class="ml-1 text-muted"><%- (role ? '- ' + role : '') %></small>
+                                                        <span class="pull-right text-muted"><%- am.end_time.toLocaleString() %></span>
+                                                    </p>
+                                                </div>
+                                            </li>
+                                        <% } %>
+                                    <% } %>
                             </ul>
                             <% } else { %>
                             <!--没有处理信息-->
@@ -128,7 +157,7 @@
                     <div class="card">
                         <div class="card-header">需要你关注</div>
                         <div class="card-body">
-                            <% if (noticeLedger.length !== 0 || noticeRevise.length !== 0 || noticeStage.length !== 0 || noticeChange.length !== 0) { %>
+                            <% if (noticeLedger.length !== 0 || noticeRevise.length !== 0 || noticeStage.length !== 0 || noticeChange.length !== 0 || noticeMaterial.length !== 0) { %>
                                 <ul class="list-unstyled m-0">
                                     <% for (const nl of noticeLedger) { %>
                                         <li class="media pb-3 mb-3 border-bottom-1">
@@ -196,6 +225,23 @@
                                             </div>
                                         </li>
                                     <% } %>
+                                    <% for (const nm of noticeMaterial) { %>
+                                        <li class="media pb-3 mb-3 border-bottom-1">
+                                            <div class="media-body">
+                                                <div class="row">
+                                                    <div class="col-auto"><span class="badge badge-secondary">材料调差</span></div>
+                                                    <div class="col-6">
+                                                        <a href="/tender/<%- nm.tid %>"><%- nm.name %></a>
+                                                        <a href="/tender/<%- nm.tid %>/measure/stage/<%- nm.m_order %>">第<%- nm.m_order %>期 </a>
+                                                        <%- acStage.statusString[nm.status]%>
+                                                    </div>
+                                                </div>
+                                                <p class="mt-1 mb-0"><%- nm.su_name %><small class="ml-1 text-muted"><%- (nm.su_role ? '- ' + nm.su_role : '') %></small>
+                                                    <span class="pull-right text-muted"><%- nm.end_time.toLocaleString() %></span>
+                                                </p>
+                                            </div>
+                                        </li>
+                                    <% } %>
                                 </ul>
                                 <% } else { %>
                                 <!--没有关注信息-->

+ 36 - 18
app/view/stage/audit_modal.ejs

@@ -1223,24 +1223,42 @@
     </div>
 <% } %>
 <% if (ctx.stage.user_id === ctx.session.sessionUser.accountId && ctx.stage.order === ctx.stage.highOrder) { %>
-<!--删除期-->
-<div class="modal fade" id="del-qi" data-backdrop="static">
-    <div class="modal-dialog" role="document">
-        <form class="modal-content" action='/tender/<%= ctx.tender.id %>/measure/stage/delete' method="post">
-            <div class="modal-header">
-                <h5 class="modal-title">删除期</h5>
-            </div>
-            <div class="modal-body">
-                <h5>确认删除「第<%= ctx.stage.order %>期」?</h5>
-                <h5>删除后,数据无法恢复,请谨慎操作。</h5>
+    <!--删除期-->
+    <% if (ctx.stage.hadMaterial) { %>
+        <div class="modal fade" id="del-qi" data-backdrop="static">
+            <div class="modal-dialog" role="document">
+                <div class="modal-content">
+                    <div class="modal-header">
+                        <h5 class="modal-title">删除期</h5>
+                    </div>
+                    <div class="modal-body">
+                        <h5>材料调差已使用当前期,如需删除,请先删除材料调差相关期</h5>
+                    </div>
+                    <div class="modal-footer">
+                        <button type="button" class="btn btn-secondary btn-sm" data-dismiss="modal">取消</button>
+                    </div>
+                </div>
             </div>
-            <div class="modal-footer">
-                <input type="hidden" name="stage_id" value="<%= ctx.stage.id %>">
-                <input type="hidden" name="_csrf" value="<%= ctx.csrf %>" />
-                <button type="button" class="btn btn-secondary btn-sm" data-dismiss="modal">取消</button>
-                <button type="submit" class="btn btn-danger btn-sm">确定删除</button>
+        </div>
+    <% } else { %>
+        <div class="modal fade" id="del-qi" data-backdrop="static">
+            <div class="modal-dialog" role="document">
+                <form class="modal-content" action='/tender/<%= ctx.tender.id %>/measure/stage/delete' method="post">
+                    <div class="modal-header">
+                        <h5 class="modal-title">删除期</h5>
+                    </div>
+                    <div class="modal-body">
+                        <h5>确认删除「第<%= ctx.stage.order %>期」?</h5>
+                        <h5>删除后,数据无法恢复,请谨慎操作。</h5>
+                    </div>
+                    <div class="modal-footer">
+                        <input type="hidden" name="stage_id" value="<%= ctx.stage.id %>">
+                        <input type="hidden" name="_csrf" value="<%= ctx.csrf %>" />
+                        <button type="button" class="btn btn-secondary btn-sm" data-dismiss="modal">取消</button>
+                        <button type="submit" class="btn btn-danger btn-sm">确定删除</button>
+                    </div>
+                </form>
             </div>
-        </form>
-    </div>
-</div>
+        </div>
+    <% } %>
 <% } %>

+ 8 - 7
builder_report_index_define.js

@@ -27,7 +27,7 @@ const stage_jgcl = {
     name: '期-甲供材料(mem_stage_jgcl)',
     remark: '',
     id: 30,
-    key: 'stage_jgcl',
+    key: 'mem_stage_jgcl',
     prefix: '期-甲供材料',
     cols: [
         { name: 'id', field: 'id', type: dataType.int },
@@ -48,17 +48,17 @@ const stage_jgcl = {
         { name: '期历史记录', field: 'shistory', type: dataType.str },
         { name: '排序', field: 'order', type: dataType.int },
         { name: '往期是否已用', field: 'pre_used', type: dataType.int },
-        { name: '截止上期到场-数量', field: 'arrive_qty', type: dataType.currency, tag: { type: 'qty', unitKey: 4 } },
-        { name: '截止上期到场-金额', field: 'arrive_tp', type: dataType.currency, tag: { type: 'tp' } },
-        { name: '截止上期扣回-数量', field: 'deduct_qty', type: dataType.currency, tag: { type: 'qty', unitKey: 4 } },
-        { name: '截止上期扣回-金额', field: 'deduct_tp', type: dataType.currency, tag: { type: 'tp' } },
+        { name: '截止上期到场-数量', field: 'pre_arrive_qty', type: dataType.currency, tag: { type: 'qty', unitKey: 4 } },
+        { name: '截止上期到场-金额', field: 'pre_arrive_tp', type: dataType.currency, tag: { type: 'tp' } },
+        { name: '截止上期扣回-数量', field: 'pre_deduct_qty', type: dataType.currency, tag: { type: 'qty', unitKey: 4 } },
+        { name: '截止上期扣回-金额', field: 'pre_deduct_tp', type: dataType.currency, tag: { type: 'tp' } },
     ],
 };
 const stage_bonus = {
     name: '期-奖罚金(mem_stage_bonus)',
     remark: '',
     id: 31,
-    key: 'stage_bonus',
+    key: 'mem_stage_bonus',
     prefix: '期-奖罚金',
     cols: [
         { name: 'id', field: 'id', type: dataType.str },
@@ -74,13 +74,14 @@ const stage_bonus = {
         { name: '备注', field: 'memo', type: dataType.str },
         { name: '期历史记录', field: 'shistory', type: dataType.str },
         { name: '排序', field: 'order', type: dataType.int },
+        { name: '编号', field: 'code', type: dataType.str},
     ],
 };
 const stage_other = {
     name: '期-其他(mem_stage_other)',
     remark: '',
     id: 32,
-    key: 'stage_other',
+    key: 'mem_stage_other',
     prefix: '期-其他',
     cols: [
         { name: 'id', field: 'id', type: dataType.int },