| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398 | 'use strict';const auditConst = require('../const/audit').stage;const paymentConst = require('../const/payment');module.exports = app => {    class PaymentDetail extends app.BaseService {        constructor(ctx) {            super(ctx);            this.tableName = 'payment_detail';        }        async getValidDetails(tr_id) {            const details = await this.db.select(this.tableName, {                column: ['id', 'in_time', 'tr_id', 'uid', 'status', 'order', 'times', 'code', 's_time'],                where: { tr_id },                orders: [['order', 'desc']],            });            if (details.length !== 0) {                const lastDetail = details[details.length - 1];                if (lastDetail.status === auditConst.status.uncheck && lastDetail.uid !== this.ctx.session.sessionUser.accountId) {                    details.splice(details.length - 1, 1);                }            }            // 最新一期计量(未审批完成),当前操作人的期详细数据,应实时计算            if (details.length > 0 && details[0].status !== auditConst.status.checked) {                const detail = details[0];                const curAuditor = await this.ctx.service.paymentDetailAudit.getCurAuditor(detail.id, detail.times);                const isActive = curAuditor ? curAuditor.id === this.ctx.session.sessionUser.accountId : detail.uid === this.ctx.session.sessionUser.accountId;                if (isActive) {                    detail.curTimes = detail.times;                    detail.curOrder = curAuditor ? curAuditor.order : 0;                }            }            return details;        }        async hadDetail(trId) {            const result = await this.count({ tr_id: trId });            return result !== 0;        }        async addCommomCheck(trInfo, code) {            const details = await this.getAllDataByCondition({                where: { tr_id: trInfo.id },                order: ['order'],            });            const preDetail = details[details.length - 1];            if (details.length > 0 && details[details.length - 1].status !== auditConst.status.checked) {                throw '上一期未审批通过,请等待上一期审批通过后,再新增';            }            if (this._.findIndex(details, { code }) !== -1) {                throw '编号不能重复';            }            trInfo.rpt_audit = JSON.parse(trInfo.rpt_audit);            if (this._.findIndex(trInfo.rpt_audit, { uid: null }) !== -1) {                throw '未配置好表单角色,无法新建';            }            return preDetail;        }        async addFormDetail(trInfo, code, s_time) {            const transaction = await this.db.beginTransaction();            try {                if (!(trInfo.is_del === 0 && trInfo.rpt_audit)) {                    throw '报表已删除或表单人员数据有误,无法新建';                }                const preDetail = await this.addCommomCheck(trInfo, code);                const rptTpl = await this.ctx.service.rptTpl.getDataById(trInfo.rpt_id);                const pageRst = this.ctx.service.jpcReport.getAllPreviewPagesCommon(rptTpl, 'A4');                const newDetail = {                    tender_id: this.ctx.paymentTender.id,                    tr_id: trInfo.id,                    order: preDetail && preDetail.order ? preDetail.order + 1 : 1,                    times: 1,                    status: auditConst.status.uncheck,                    uid: this.ctx.session.sessionUser.accountId,                    s_time,                    code,                    report_json: JSON.stringify(pageRst),                    in_time: new Date(),                };                const result = await transaction.insert(this.tableName, newDetail);                if (result.affectedRows === 1) {                    newDetail.id = result.insertId;                } else {                    throw '新增支付审批数据失败';                }                // 报表角色创建                const insertRptAudit = [];                for (const [i, r] of trInfo.rpt_audit.entries()) {                    insertRptAudit.push({                        tender_id: this.ctx.paymentTender.id,                        tr_id: trInfo.id,                        td_id: newDetail.id,                        uid: r.uid,                        signature_index: i,                        signature_name: r.rpt_name,                        in_time: new Date(),                    });                }                if (insertRptAudit.length > 0) await transaction.insert(this.ctx.service.paymentRptAudit.tableName, insertRptAudit);                // 存在上一期时,复制上一期审批流程                if (preDetail) {                    const auditResult = await this.ctx.service.paymentDetailAudit.copyPreDetailAuditors(transaction, preDetail, newDetail);                    if (!auditResult) {                        throw '复制上一期审批流程失败';                    }                }                // 更新is_change值                await transaction.update(this.ctx.service.paymentTenderRpt.tableName, { id: trInfo.id, is_change: 0 });                await transaction.commit();                return newDetail;            } catch (err) {                await transaction.rollback();                throw err;            }        }        async addSafeDetail(trInfo, code, s_time) {            const transaction = await this.db.beginTransaction();            try {                const preDetail = await this.addCommomCheck(trInfo, code);                const newDetail = {                    tender_id: this.ctx.paymentTender.id,                    tr_id: trInfo.id,                    order: preDetail && preDetail.order ? preDetail.order + 1 : 1,                    times: 1,                    status: auditConst.status.uncheck,                    uid: this.ctx.session.sessionUser.accountId,                    s_time,                    code,                    in_time: new Date(),                    type: paymentConst.modes_value_object.safe,                };                const result = await transaction.insert(this.tableName, newDetail);                if (result.affectedRows === 1) {                    newDetail.id = result.insertId;                } else {                    throw '新增支付审批数据失败';                }                // 初始化安全生产费                if (preDetail) {                    await this.ctx.service.paymentSafeBills.initByPre(newDetail, preDetail, transaction);                } else {                    await this.ctx.service.paymentSafeBills.init(newDetail, transaction);                }                // 存在上一期时,复制上一期审批流程                if (preDetail) {                    const auditResult = await this.ctx.service.paymentDetailAudit.copyPreDetailAuditors(transaction, preDetail, newDetail);                    if (!auditResult) {                        throw '复制上一期审批流程失败';                    }                }                // 更新is_change值                await transaction.update(this.ctx.service.paymentTenderRpt.tableName, { id: trInfo.id, is_change: 0 });                await transaction.commit();                return newDetail;            } catch (err) {                await transaction.rollback();                throw err;            }        }        async addDetail(trInfo, code, s_time) {            switch (trInfo.type) {                case paymentConst.modes_value_object.form:                    return this.addFormDetail(trInfo, code, s_time);                case paymentConst.modes_value_object.safe:                    return this.addSafeDetail(trInfo, code, s_time);                default:                    throw '未知类型,新建失败';            }        }        async updateReportJson(id, report_json) {            return await this.db.update(this.tableName, { id, report_json: JSON.stringify(report_json) });        }        async signOneSignatureData(report_json, signature_name, sign_msg) {            // 签名签章            const signCells = this._.find(report_json.items[0].signature_cells, { signature_name });            if (signCells && (sign_msg.sign_path || sign_msg.company_stamp || sign_msg.stamp_path)) {                const signArray = [];                sign_msg.sign_path ? signArray.push('/public/upload/sign/' + sign_msg.sign_path) : signArray.push('');                sign_msg.company_stamp ? signArray.push(sign_msg.company_stamp) : signArray.push('');                sign_msg.stamp_path ? signArray.push(sign_msg.stamp_path) : signArray.push('');                signCells.path = signArray.join('!;!');            }            // 日期            const dateCells = this._.find(report_json.items[0].signature_date_cells, { signature_name: signature_name + '_签字日期' });            if (dateCells && sign_msg.date) {                dateCells.Value = this.ctx.helper.dateTranChinese(sign_msg.date);            }            // 意见            const contentCells = this._.find(report_json.items[0].signature_audit_cells, { signature_name: signature_name + '_审核意见' });            if (contentCells && sign_msg.content) {                contentCells.Value = sign_msg.content;            }            return report_json;        }        async clearOneSignatureData(report_json, rptAudit) {            // 签名签章            const signCells = this._.find(report_json.items[0].signature_cells, { signature_name: rptAudit.signature_name });            if (signCells) {                signCells.path = null;            }            // 日期            const dateCells = this._.find(report_json.items[0].signature_date_cells, { signature_name: rptAudit.signature_name + '_签字日期' });            if (dateCells) {                dateCells.Value = '';            }            // 意见            const contentCells = this._.find(report_json.items[0].signature_audit_cells, { signature_name: rptAudit.signature_name + '_审核意见' });            if (contentCells) {                contentCells.Value = '';            }            return report_json;        }        async clearAllSignatureData(report_json) {            if (report_json.items[0].signature_cells.length > 0) {                for (const cell of report_json.items[0].signature_cells) {                    cell.path = null;                }            }            if (report_json.items[0].signature_audit_cells.length > 0) {                for (const cell of report_json.items[0].signature_audit_cells) {                    cell.Value = '';                }            }            if (report_json.items[0].signature_date_cells.length > 0) {                for (const cell of report_json.items[0].signature_date_cells) {                    cell.Value = '';                }            }            return report_json;        }        /**         * 删除报表表单详情         *         * @param {Number} id - 期Id         * @return {Promise<void>}         */        async deleteDetail(id) {            const transaction = await this.db.beginTransaction();            try {                await transaction.delete(this.ctx.service.paymentDetailAudit.tableName, { td_id: id });                await transaction.delete(this.ctx.service.paymentRptAudit.tableName, { td_id: id });                await transaction.delete(this.ctx.service.paymentSafeBills.tableName, { detail_id: id });                await transaction.delete(this.tableName, { id });                await transaction.commit();                return true;            } catch (err) {                await transaction.rollback();                throw err;            }        }        async haveNotice2Tender(tid, uid) {            const sql = 'SELECT pd.`id`, pd.`tr_id`, pd.`order` FROM ?? as pd LEFT JOIN ?? as pda' +                ' ON pd.`id` = pda.`td_id` LEFT JOIN ?? as pra ON pd.`id` = pra.`td_id` WHERE pd.`tender_id` = ? AND' +                ' ((pd.`uid` = ? AND (pd.`status` = ? OR pd.`status` = ?))' +                ' OR ((pd.`status` = ? OR pd.`status` = ?) AND pda.aid = ? AND pda.`status` = ?)' +                ' OR (pra.`uid` = ? AND pra.`signature_msg` is null AND pd.`status` != ? AND pd.`status` != ?))';            const params = [this.tableName, this.ctx.service.paymentDetailAudit.tableName, this.ctx.service.paymentRptAudit.tableName, tid,                uid, auditConst.status.uncheck, auditConst.status.checkNo,                auditConst.status.checking, auditConst.status.checkNoPre, uid, auditConst.status.checking,                uid, auditConst.status.uncheck, auditConst.status.checkNo];            const result = await this.db.query(sql, params);            if (result && result.length > 0) {                for (const one of this._.uniqBy(result, 'id')) {                    const maxOrder = await this.count({                        tr_id: one.tr_id,                    });                    if (one.order === maxOrder) {                        return 1;                    }                }            }            return 0;        }        async haveNotice2TenderRpt(tr_id, uid) {            const sql = 'SELECT pd.`id`, pd.`tr_id`, pd.`order` FROM ?? as pd LEFT JOIN ?? as pda' +                ' ON pd.`id` = pda.`td_id` LEFT JOIN ?? as pra ON pd.`id` = pra.`td_id` WHERE pd.`tr_id` = ? AND ((pd.`uid` = ? AND (pd.`status` = ? OR pd.`status` = ?))' +                ' OR ((pd.`status` = ? OR pd.`status` = ?) AND pda.aid = ? AND pda.`status` = ?)' +                ' OR (pra.`uid` = ? AND pra.`signature_msg` is null AND pd.`status` != ? AND pd.`status` != ?))';            const params = [this.tableName, this.ctx.service.paymentDetailAudit.tableName, this.ctx.service.paymentRptAudit.tableName, tr_id,                uid, auditConst.status.uncheck, auditConst.status.checkNo,                auditConst.status.checking, auditConst.status.checkNoPre, uid, auditConst.status.checking,                uid, auditConst.status.uncheck, auditConst.status.checkNo];            const result = await this.db.query(sql, params);            if (result && result.length > 0) {                for (const one of this._.uniqBy(result, 'id')) {                    const maxOrder = await this.count({                        tr_id: one.tr_id,                    });                    if (one.order === maxOrder) {                        return 1;                    }                }            }            return 0;        }        async haveDetail2Tender(tid) {            return this.count({ tender_id: tid });        }        async getCountByPidType(pid, type = 1) {            const sql = 'SELECT count(pd.`id`) as count FROM ?? as pd LEFT JOIN ?? as pt ON pd.`tender_id` = pt.`id` WHERE pid = ? AND type = ?';            const params = [this.tableName, this.ctx.service.paymentTender.tableName, pid, type];            const result = await this.db.queryOne(sql, params);            return result ? result.count : 0;        }        async updateReport(transaction, tr_id, uid) {            const details = await this.db.select(this.tableName, {                column: ['id', 'in_time', 'tr_id', 'uid', 'status', 'order', 'times', 'code', 's_time'],                where: { tr_id },                orders: [['order', 'desc']],            });            if (details && details.length > 0) {                const detailInfo = details[0];                if (detailInfo.status === auditConst.status.uncheck || detailInfo.status === auditConst.status.checkNo) {                    // 判断该人是否在审批流程里,是则移除并调整order                    const result2 = await this.ctx.service.paymentDetailAudit.updateAuditByReport(transaction, detailInfo.id, detailInfo.times, uid);                    // 更新为上报人                    return await transaction.update(this.tableName, { id: detailInfo.id, uid });                }            }            return true;        }        async doCheckDetail(id) {            const accountId = this.ctx.session.sessionUser.accountId;            const auditPermission = await this.service.paymentPermissionAudit.getOnePermission(this.ctx.session.sessionUser.is_admin, accountId);            if (!auditPermission) throw '权限不足';            const detail = await this.getDataById(id);            if (!detail) throw '支付审批表单不存在';            const trInfo = await this.ctx.service.paymentTenderRpt.getDataById(detail.tr_id);            if (!trInfo) throw '支付审批报表不存在';            // 读取原报、审核人数据            detail.auditors = await this.ctx.service.paymentDetailAudit.getAuditors(detail.id, detail.times);            detail.curAuditor = await this.ctx.service.paymentDetailAudit.getCurAuditor(detail.id, detail.times);            detail.rptAudits = await this.ctx.service.paymentRptAudit.getListByDetail(detail.id);            const auditorIds = _.map(detail.auditors, 'aid'), rptAuditIds = _.map(detail.rptAudits, 'uid');            if (accountId === detail.uid) { // 原报                detail.curTimes = detail.times;                if (detail.status === status.uncheck || detail.status === status.checkNo) {                    detail.curOrder = 0;                } else if (detail.status === status.checked) {                    detail.curOrder = _.max(_.map(detail.auditors, 'order'));                } else {                    detail.curOrder = detail.curAuditor.aid === accountId ? detail.curAuditor.order : detail.curAuditor.order - 1;                }                detail.filePermission = true;            } else if (auditorIds.indexOf(accountId) !== -1 || rptAuditIds.indexOf(accountId) !== -1 || auditPermission.view_all) { // 审批人及签署人及查看所有权人                if (detail.status === status.uncheck) {                    throw '您无权查看该数据';                }                detail.curTimes = detail.status === status.checkNo ? detail.times - 1 : detail.times;                if (detail.status === status.checked) {                    detail.curOrder = _.max(_.map(detail.auditors, 'order'));                } else if (detail.status === status.checkNo) {                    const audit = await this.ctx.service.paymentDetailAudit.getDataByCondition({                        td_id: detail.id, times: detail.times, status: status.checkNo,                    });                    detail.curOrder = audit.order;                } else {                    detail.curOrder = accountId === detail.curAuditor.aid ? detail.curAuditor.order : detail.curAuditor.order - 1;                }                detail.filePermission = auditorIds.indexOf(accountId) !== -1 || rptAuditIds.indexOf(accountId) !== -1;            } else { // 其他不可见                throw '您无权查看该数据';            }            // 获取最新的期            detail.highOrder = await this.service.paymentDetail.count({ tr_id: detail.tr_id });            detail.readOnly = !((detail.status === status.uncheck || detail.status === status.checkNo) && accountId === detail.uid);            if (detail.readOnly && detail.type === paymentConst.modes_value_object.safe) {                if ((detail.status === status.checking || detail.status === status.checkNoPre) && detail.curAuditor && detail.curAuditor.aid === accountId) {                    detail.readOnly = false;                }            }            return detail;        }    }    return PaymentDetail;};
 |