|
@@ -0,0 +1,374 @@
|
|
|
+const billsCompareField = [
|
|
|
+ 'quantity', 'total_price',
|
|
|
+ 'contract_qty', 'contract_tp', 'qc_qty', 'qc_tp', 'gather_qty', 'gather_tp',
|
|
|
+ 'end_contract_qty', 'end_contract_tp', 'end_qc_qty', 'end_qc_tp', 'end_gather_qty', 'end_gather_tp',
|
|
|
+];
|
|
|
+const posCompareField = [
|
|
|
+ 'quantity',
|
|
|
+ 'contract_qty', 'qc_qty', 'gather_qty',
|
|
|
+ 'end_contract_qty', 'end_qc_qty', 'end_gather_qty',
|
|
|
+];
|
|
|
+
|
|
|
+$(document).ready(() => {
|
|
|
+ autoFlashHeight();
|
|
|
+ const billsSpreadSetting = {
|
|
|
+ cols: [
|
|
|
+ {title: '项目节编号', colSpan: '1', rowSpan: '3', field: 'code', hAlign: 0, width: 185, formatter: '@', cellType: 'tree'},
|
|
|
+ {title: '清单编号', colSpan: '1', rowSpan: '3', field: 'b_code', hAlign: 0, width: 100, formatter: '@'},
|
|
|
+ {title: '名称', colSpan: '1', rowSpan: '3', field: 'name', hAlign: 0, width: 235, formatter: '@'},
|
|
|
+ {title: '单位', colSpan: '1', rowSpan: '3', field: 'unit', hAlign: 1, width: 60, formatter: '@'},
|
|
|
+ {title: '单价', colSpan: '1', rowSpan: '3', field: 'unit_price', hAlign: 2, width: 60, type: 'Number'},
|
|
|
+ {title: '合计||数量', colSpan: '2||1', rowSpan: '2||1', field: 'sum_qty', hAlign: 2, width: 80, type: 'Number'},
|
|
|
+ {title: '||金额', colSpan: '|1', rowSpan: '|1', field: 'sum_tp', hAlign: 2, width: 80, type: 'Number'},
|
|
|
+ ],
|
|
|
+ baseCols: [
|
|
|
+ {title: '项目节编号', colSpan: '1', rowSpan: '3', field: 'code', hAlign: 0, width: 185, formatter: '@', cellType: 'tree'},
|
|
|
+ {title: '清单编号', colSpan: '1', rowSpan: '3', field: 'b_code', hAlign: 0, width: 100, formatter: '@'},
|
|
|
+ {title: '名称', colSpan: '1', rowSpan: '3', field: 'name', hAlign: 0, width: 235, formatter: '@'},
|
|
|
+ {title: '单位', colSpan: '1', rowSpan: '3', field: 'unit', hAlign: 1, width: 60, formatter: '@'},
|
|
|
+ {title: '单价', colSpan: '1', rowSpan: '3', field: 'unit_price', hAlign: 2, width: 60, type: 'Number'},
|
|
|
+ ],
|
|
|
+ extraCols: [
|
|
|
+ {title: '标段1|第1期|数量', colSpan: '2|2|1', rowSpan: '1|1|1', field: 'quantity_1', hAlign: 2, width: 80, type: 'Number', formatTitle: '%s|%f|数量', formatField: 'gather_qty_%d'},
|
|
|
+ {title: '||金额', colSpan: '|1', rowSpan: '|1', field: 'total_price_1', hAlign: 2, width: 80, type: 'Number', formatField: 'gather_tp_%d'},
|
|
|
+ ],
|
|
|
+ endCols: [
|
|
|
+ {title: '合计||数量', colSpan: '2||1', rowSpan: '2||1', field: 'sum_qty', hAlign: 2, width: 80, type: 'Number'},
|
|
|
+ {title: '||金额', colSpan: '|1', rowSpan: '|1', field: 'sum_tp', hAlign: 2, width: 80, type: 'Number'},
|
|
|
+ ],
|
|
|
+ emptyRows: 0,
|
|
|
+ headRows: 3,
|
|
|
+ headRowHeight: [32, 25, 25],
|
|
|
+ defaultRowHeight: 21,
|
|
|
+ headerFont: '12px 微软雅黑',
|
|
|
+ font: '12px 微软雅黑',
|
|
|
+ readOnly: true,
|
|
|
+ };
|
|
|
+ const posSpreadSetting = {
|
|
|
+ cols: [
|
|
|
+ {title: '名称', colSpan: '1', rowSpan: '2', field: 'name', hAlign: 0, width: 235, formatter: '@'},
|
|
|
+ {title: '差值', colSpan: '1', rowSpan: '2', field: 'sum_qty', hAlign: 2, width: 100, type: 'Number'},
|
|
|
+ ],
|
|
|
+ baseCols: [
|
|
|
+ {title: '名称', colSpan: '1', rowSpan: '2', field: 'name', hAlign: 0, width: 235, formatter: '@'},
|
|
|
+ ],
|
|
|
+ extraCols: [
|
|
|
+ {title: '标段1|第1期', colSpan: '1|1', rowSpan: '1|1', field: 'quantity_1', hAlign: 2, width: 100, type: 'Number', formatTitle: '%s|%f', formatField: 'gather_qty_%d'},
|
|
|
+ ],
|
|
|
+ endCols: [
|
|
|
+ {title: '合计', colSpan: '1', rowSpan: '2', field: 'sum_qty', hAlign: 2, width: 100, type: 'Number'},
|
|
|
+ ],
|
|
|
+ emptyRows: 0,
|
|
|
+ headRows: 2,
|
|
|
+ headRowHeight: [32, 25],
|
|
|
+ defaultRowHeight: 21,
|
|
|
+ headerFont: '12px 微软雅黑',
|
|
|
+ font: '12px 微软雅黑',
|
|
|
+ readOnly: true,
|
|
|
+ };
|
|
|
+
|
|
|
+ const billsSpread = SpreadJsObj.createNewSpread($('#bills-spread')[0]);
|
|
|
+ const billsSheet = billsSpread.getActiveSheet();
|
|
|
+ sjsSettingObj.setFxTreeStyle(billsSpreadSetting, sjsSettingObj.FxTreeStyle.jz);
|
|
|
+ SpreadJsObj.initSheet(billsSheet, billsSpreadSetting);
|
|
|
+
|
|
|
+ const posSpread = SpreadJsObj.createNewSpread($('#pos-spread')[0]);
|
|
|
+ const posSheet = posSpread.getActiveSheet();
|
|
|
+ SpreadJsObj.initSheet(posSheet, posSpreadSetting);
|
|
|
+
|
|
|
+ const treeSetting = {
|
|
|
+ id: 'ledger_id',
|
|
|
+ pid: 'ledger_pid',
|
|
|
+ order: 'order',
|
|
|
+ level: 'level',
|
|
|
+ full_path: 'full_path',
|
|
|
+ rootId: -1,
|
|
|
+ keys: ['id', 'tender_id', 'ledger_id'],
|
|
|
+ calcFields: ['sum_tp'],
|
|
|
+ // todo 判断同一清单时,是否应区分 清单是否含计量单元?
|
|
|
+ // findNode: function(tree, node, parent, source) {
|
|
|
+ // const siblings = parent ? parent.children : tree.children;
|
|
|
+ // const checkData = { code: node.code || '', b_code: node.b_code || '', name: node.name || '', unit: node.unit || '', unit_price: node.unit_price || 0 };
|
|
|
+ // return siblings.find(function (x) {
|
|
|
+ // if (!checkData.b_code) return x.code === checkData.code && x.name === checkData.name;
|
|
|
+ // const posRange = source.pos.getLedgerPos(node.id);
|
|
|
+ // const hasPos = posRange && posRange.length > 0;
|
|
|
+ // const xHasPos = x.pos && x.pos.length > 0;
|
|
|
+ // return hasPos === xHasPos && x.b_code === checkData.b_code && x.name === checkData.name && x.unit === checkData.unit && x.unit_price === checkData.unit_price;
|
|
|
+ // });
|
|
|
+ // },
|
|
|
+ loadInfo: function (node, sourceNode, index, source) {
|
|
|
+ for (const f of billsCompareField) {
|
|
|
+ node[f + '_' + index] = sourceNode[f];
|
|
|
+ }
|
|
|
+ const posRange = source.pos.getLedgerPos(sourceNode.id);
|
|
|
+ if (posRange && posRange.length > 0) {
|
|
|
+ if (!node.pos) node.pos = [];
|
|
|
+ for (const p of posRange) {
|
|
|
+ let nP = _.find(node.pos, {name: p.name || ''});
|
|
|
+ if (!nP) {
|
|
|
+ nP = {name: p.name || ''};
|
|
|
+ node.pos.push(nP);
|
|
|
+ }
|
|
|
+ for (const f of posCompareField) {
|
|
|
+ nP[f + '_' + index] = p[f];
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ calcSum: function(data, count) {
|
|
|
+ for (const f of billsCompareField) {
|
|
|
+ data['sum_' + f] = 0;
|
|
|
+ for (let i = 1; i <= count; i++) {
|
|
|
+ data['sum_' + f] = ZhCalc.add(data['sum_' + f], data[f + '_' + i]);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ for (const p of data.pos) {
|
|
|
+ for (const f of posCompareField) {
|
|
|
+ p['sum_' + f] = 0;
|
|
|
+ for (let i = 1; i <= count; i++) {
|
|
|
+ p['sum_' + f] = ZhCalc.add(p['sum_' + f], p[f + '_' + i]);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ };
|
|
|
+ const billsTree = createNewPathTree('tree-gather', treeSetting);
|
|
|
+
|
|
|
+ const billsTreeSpreadObj = {
|
|
|
+ selectionChanged: function (e, info) {
|
|
|
+ if (info.newSelections) {
|
|
|
+ if (!info.oldSelections || info.newSelections[0].row !== info.oldSelections[0].row) {
|
|
|
+ posSpreadObj.loadCurPosData();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ loadShowData: function() {
|
|
|
+ const field = $('[name=compare-data]:checked').val();
|
|
|
+ for (const node of billsTree.nodes) {
|
|
|
+ for (let i = 1; i < billsTree.count; i++) {
|
|
|
+ node['gather_qty_' + i] = node[field + '_qty_' + i];
|
|
|
+ node['gather_tp_' + i] = node[field + '_tp_' + i];
|
|
|
+ }
|
|
|
+ node.sum_qty = node['sum_' + field + '_qty'];
|
|
|
+ node.sum_tp = node['sum_' + field + '_tp'];
|
|
|
+ for (const p of node.pos) {
|
|
|
+ for (let i = 1; i < billsTree.count; i++) {
|
|
|
+ p['gather_qty_' + i] = p[field + '_qty_' + i];
|
|
|
+ }
|
|
|
+ p.sum_qty = p['sum_' + field + '_qty'];
|
|
|
+ }
|
|
|
+ }
|
|
|
+ this.compareData = field;
|
|
|
+ },
|
|
|
+ rebuildSpreadSetting(tenders) {
|
|
|
+ if(tenders.length > 0) {
|
|
|
+ if (tenders[0].filter.indexOf('~') > 0) {
|
|
|
+ $('[datatype=end]').hide();
|
|
|
+ } else {
|
|
|
+ $('[datatype=end]').show();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ billsSpreadSetting.cols = [...billsSpreadSetting.baseCols];
|
|
|
+ posSpreadSetting.cols = [...posSpreadSetting.baseCols];
|
|
|
+ for (const [i, tender] of tenders.entries()) {
|
|
|
+ for (const col of billsSpreadSetting.extraCols) {
|
|
|
+ const newCol = JSON.parse(JSON.stringify(col));
|
|
|
+ if (newCol.formatTitle) newCol.title = newCol.formatTitle.replace('%s', tender.name).replace('%f', tender.filter);
|
|
|
+ if (newCol.formatField) newCol.field = newCol.formatField.replace('%d', i + 1);
|
|
|
+ billsSpreadSetting.cols.push(newCol);
|
|
|
+ }
|
|
|
+ for (const col of posSpreadSetting.extraCols) {
|
|
|
+ const newCol = JSON.parse(JSON.stringify(col));
|
|
|
+ if (newCol.formatTitle) newCol.title = newCol.formatTitle.replace('%s', tender.name).replace('%f', tender.filter);
|
|
|
+ if (newCol.formatField) newCol.field = newCol.formatField.replace('%d', i + 1);
|
|
|
+ posSpreadSetting.cols.push(newCol)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ billsSpreadSetting.cols.push(...billsSpreadSetting.endCols);
|
|
|
+ posSpreadSetting.cols.push(...posSpreadSetting.endCols);
|
|
|
+ },
|
|
|
+ refreshShowData: function() {
|
|
|
+ const field = $('[name=compare-data]:checked').val();
|
|
|
+ if (field === this.compareData) return;
|
|
|
+
|
|
|
+ this.loadShowData();
|
|
|
+ SpreadJsObj.reloadColData(billsSheet, 5, billsSpreadSetting.cols.length - 5);
|
|
|
+ SpreadJsObj.reloadColData(posSheet, 1, posSpreadSetting.cols.length - 1);
|
|
|
+ }
|
|
|
+ };
|
|
|
+ billsSpread.bind(spreadNS.Events.SelectionChanged, billsTreeSpreadObj.selectionChanged);
|
|
|
+ const posSpreadObj = {
|
|
|
+ loadCurPosData: function () {
|
|
|
+ const node = SpreadJsObj.getSelectObject(billsSheet);
|
|
|
+ if (node) {
|
|
|
+ console.log(node);
|
|
|
+ SpreadJsObj.loadSheetData(posSheet, 'data', node.pos || []);
|
|
|
+ } else {
|
|
|
+ SpreadJsObj.loadSheetData(posSheet, 'data', []);
|
|
|
+ }
|
|
|
+ },
|
|
|
+ };
|
|
|
+
|
|
|
+ const tenderSelect = TenderSelectMulti({
|
|
|
+ title: '汇总标段',
|
|
|
+ type: 'gather',
|
|
|
+ dataType: 'stage',
|
|
|
+ afterSelect: function(select) {
|
|
|
+ const data = { filter: 'stage', tender: select };
|
|
|
+ postData(`/sp/${spid}/spss/load`, data, function(result) {
|
|
|
+ billsTreeSpreadObj.rebuildSpreadSetting(result);
|
|
|
+ SpreadJsObj.reLoadSheetHeader(billsSheet, true);
|
|
|
+ SpreadJsObj.reLoadSheetHeader(posSheet, true);
|
|
|
+
|
|
|
+ treeSetting.calcFields = ['sum_total_price'];
|
|
|
+ for (let i = 1; i <= result.length; i++) {
|
|
|
+ treeSetting.calcFields.push('total_price_' + i, 'contract_tp_' + i, 'qc_tp_' + i, 'gather_tp_' + i, 'end_contract_tp_' + i, 'end_qc_tp_' + i, 'end_gather_tp_' + i);
|
|
|
+ }
|
|
|
+
|
|
|
+ const tenderTreeSetting = {
|
|
|
+ id: 'ledger_id', pid: 'ledger_pid', order: 'order', level: 'level',
|
|
|
+ rootId: -1,
|
|
|
+ keys: ['id', 'tender_id', 'ledger_id'],
|
|
|
+ calcFields: ['total_price', 'contract_tp', 'qc_tp', 'gather_tp', 'end_contract_tp', 'end_qc_tp', 'end_gather_tp'],
|
|
|
+ calcFun: function(node) {
|
|
|
+ if (!node.children || node.children.length === 0) {
|
|
|
+ node.pre_gather_qty = ZhCalc.add(node.pre_contract_qty, node.pre_qc_qty);
|
|
|
+ node.gather_qty = ZhCalc.add(node.contract_qty, node.qc_qty);
|
|
|
+ node.end_contract_qty = ZhCalc.add(node.pre_contract_qty, node.contract_qty);
|
|
|
+ node.end_gather_qty = ZhCalc.add(node.pre_gather_qty, node.gather_qty);
|
|
|
+ node.end_qc_qty = ZhCalc.add(node.pre_qc_qty, node.qc_qty);
|
|
|
+ node.end_qc_minus_qty = ZhCalc.add(node.pre_qc_minus_qty, node.qc_minus_qty);
|
|
|
+ }
|
|
|
+ node.pre_gather_tp = ZhCalc.add(node.pre_contract_tp, node.pre_qc_tp);
|
|
|
+ node.gather_tp = ZhCalc.sum([node.contract_tp, node.qc_tp, node.pc_tp]);
|
|
|
+ node.end_contract_tp = ZhCalc.sum([node.pre_contract_tp, node.contract_tp, node.contract_pc_tp]);
|
|
|
+ node.end_qc_tp = ZhCalc.sum([node.pre_qc_tp, node.qc_tp, node.qc_pc_tp]);
|
|
|
+ node.end_gather_tp = ZhCalc.add(node.pre_gather_tp, node.gather_tp);
|
|
|
+ }
|
|
|
+ };
|
|
|
+ const posSetting = {
|
|
|
+ id: 'id', ledgerId: 'lid',
|
|
|
+ calcFun: function(pos) {
|
|
|
+ pos.pre_gather_qty = ZhCalc.add(pos.pre_contract_qty, pos.pre_qc_qty);
|
|
|
+ pos.gather_qty = ZhCalc.add(pos.contract_qty, pos.qc_qty);
|
|
|
+ pos.end_contract_qty = ZhCalc.add(pos.pre_contract_qty, pos.contract_qty);
|
|
|
+ pos.end_qc_qty = ZhCalc.add(pos.pre_qc_qty, pos.qc_qty);
|
|
|
+ pos.end_qc_minus_qty = ZhCalc.add(pos.pre_qc_minus_qty, pos.qc_minus_qty);
|
|
|
+ pos.end_gather_qty = ZhCalc.add(pos.pre_gather_qty, pos.gather_qty);
|
|
|
+ }
|
|
|
+ };
|
|
|
+ const tenders = [];
|
|
|
+ for (const t of result) {
|
|
|
+ const tender = {
|
|
|
+ billsTree: createNewPathTree('ledger', tenderTreeSetting),
|
|
|
+ pos: new PosData(posSetting),
|
|
|
+ };
|
|
|
+ tender.billsTree.loadDatas(t.bills);
|
|
|
+ treeCalc.calculateAll(tender.billsTree);
|
|
|
+ tender.pos.loadDatas(t.pos);
|
|
|
+ tender.pos.calculateAll();
|
|
|
+ tenders.push(tender);
|
|
|
+ }
|
|
|
+
|
|
|
+ billsTree.clearDatas();
|
|
|
+ billsTree.loadGatherData(tenders);
|
|
|
+ treeCalc.calculateAll(billsTree);
|
|
|
+ billsTreeSpreadObj.loadShowData();
|
|
|
+ SpreadJsObj.loadSheetData(billsSheet, SpreadJsObj.DataType.Tree, billsTree);
|
|
|
+ SpreadJsObj.locateRow(billsSheet, 0);
|
|
|
+ posSpreadObj.loadCurPosData();
|
|
|
+ SpreadJsObj.locateRow(posSheet, 0);
|
|
|
+ });
|
|
|
+ },
|
|
|
+ });
|
|
|
+ $('#gather-select').click(tenderSelect.showSelect);
|
|
|
+
|
|
|
+ $('[name=compare-data]').click(function() {
|
|
|
+ billsTreeSpreadObj.refreshShowData();
|
|
|
+ });
|
|
|
+
|
|
|
+ $('#export-excel').click(function() {
|
|
|
+ const excelData = [];
|
|
|
+ for (const node of billsTree.nodes) {
|
|
|
+ const data = {};
|
|
|
+ for (const c of billsSpreadSetting.cols) {
|
|
|
+ data[c.field] = node[c.field];
|
|
|
+ }
|
|
|
+ excelData.push(data);
|
|
|
+ for (const p of node.pos) {
|
|
|
+ const pData = {};
|
|
|
+ for (const c of posSpreadSetting.cols) {
|
|
|
+ pData[c.field] = p[c.field];
|
|
|
+ }
|
|
|
+ excelData.push(pData);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ SpreadExcelObj.exportSimpleXlsxSheet(billsSpreadSetting, excelData, "台账汇总.xlsx");
|
|
|
+ });
|
|
|
+ $.divResizer({
|
|
|
+ select: '#pos-resize',
|
|
|
+ callback: function () {
|
|
|
+ billsSpread.refresh();
|
|
|
+ let bcontent = $(".bcontent-wrap") ? $(".bcontent-wrap").height() : 0;
|
|
|
+ $(".sp-wrap").height(bcontent-30);
|
|
|
+ posSpread.refresh();
|
|
|
+ }
|
|
|
+ });
|
|
|
+ // 显示层次
|
|
|
+ (function (select, sheet) {
|
|
|
+ $(select).click(function () {
|
|
|
+ if (!sheet.zh_tree) return;
|
|
|
+ const tag = $(this).attr('tag');
|
|
|
+ const tree = sheet.zh_tree;
|
|
|
+ switch (tag) {
|
|
|
+ case "1":
|
|
|
+ case "2":
|
|
|
+ case "3":
|
|
|
+ case "4":
|
|
|
+ case "5":
|
|
|
+ tree.expandByLevel(parseInt(tag));
|
|
|
+ SpreadJsObj.refreshTreeRowVisible(sheet);
|
|
|
+ break;
|
|
|
+ case "last":
|
|
|
+ tree.expandByCustom(() => { return true; });
|
|
|
+ SpreadJsObj.refreshTreeRowVisible(sheet);
|
|
|
+ break;
|
|
|
+ case "leafXmj":
|
|
|
+ tree.expandToLeafXmj();
|
|
|
+ SpreadJsObj.refreshTreeRowVisible(sheet);
|
|
|
+ break;
|
|
|
+ case "differ":
|
|
|
+ tree.expandByCustom(function (x) {
|
|
|
+ const posterity = tree.getPosterity(x);
|
|
|
+ if (posterity.length === 0) return x.differ_qty || x.differ_tp;
|
|
|
+ for (const p of posterity) {
|
|
|
+ if (x.differ_qty || x.differ_tp) return true;
|
|
|
+ }
|
|
|
+ return false;
|
|
|
+ });
|
|
|
+ SpreadJsObj.refreshTreeRowVisible(sheet);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ })('a[name=showLevel]', billsSheet);
|
|
|
+ $.subMenu({
|
|
|
+ menu: '#sub-menu', miniMenu: '#sub-mini-menu', miniMenuList: '#mini-menu-list',
|
|
|
+ toMenu: '#to-menu', toMiniMenu: '#to-mini-menu',
|
|
|
+ key: 'menu.1.0.0',
|
|
|
+ miniHint: '#sub-mini-hint', hintKey: 'menu.hint.1.0.1',
|
|
|
+ callback: function (info) {
|
|
|
+ if (info.mini) {
|
|
|
+ $('.panel-title').addClass('fluid');
|
|
|
+ $('#sub-menu').removeClass('panel-sidebar');
|
|
|
+ $('.c-body table thead').css('left', '56px');
|
|
|
+ } else {
|
|
|
+ $('.panel-title').removeClass('fluid');
|
|
|
+ $('#sub-menu').addClass('panel-sidebar');
|
|
|
+ $('.c-body table thead').css('left', '176px');
|
|
|
+ }
|
|
|
+ autoFlashHeight();
|
|
|
+ billsSpread.refresh();
|
|
|
+ posSpread.refresh();
|
|
|
+ }
|
|
|
+ });
|
|
|
+});
|