项目链接:https://gitee.com/xyjtysk/quotationTools
本篇主要介绍汇总页如何实现。
如下图所示,本Sheet主要是把价格明细页进行同类项合并以后的结果
好处是:
-
可以看到每项散件的占比,找出哪一项对价格影响最大
-
合并以后核对更为简单
所以这一页里面就没有什么设备的概念了,大家都揉合在一起了。
代码放在mergeModelClass.py
转换数字列
xlrd不能读Excel里面的公式(如果启用格式选项会报错)
不过没有关系,可以曲线救国,之前的数据反正是公式算出来的,我们在程序中再算一把就可以了
def contvert2Value (self):
# processedArr = self.lists.copy();
processedArr = copy.deepcopy(self.lists);
# 转换数量列
if 'quantity' in processedArr[0].keys():
for i , s in enumerate(self.aSite):
# siteInitial = str(s + 1);
for j in range(s + 1 , self.aSubtotal[i]-1 + 1):
processedArr[j]['totalQuantity'] = processedArr[j]['quantity'] * processedArr[s]['quantity'];
# 转换单价列
if 'unitsNetListPrice' in processedArr[0].keys() and 'discount' in processedArr[0].keys() :
for i , s in enumerate(self.aSite):
for j in range(s+1 , self.aSubtotal[i]-1 + 1):
if isinstance(processedArr[j]['discount'] , float):
processedArr[j]['unitsNetPrice'] = processedArr[j]['discount'] * processedArr[j]['unitsNetListPrice'];
else:
processedArr[j]['discount'] = 1;
processedArr[j]['unitsNetPrice'] = processedArr[j]['unitsNetListPrice'];
return processedArr;
特别值得注意的是,需要先进行深复制
因为我们构建的数据结构本质是个list,里面的每个元素是dict,如果dict改变,原来的list也会进行改变。
删除小计行
因为原来的明细清单列表中有很多冗余的元素,我们需要把他们都干掉
# # **************删除小计行**************
def removeSubtotal(self):
remainLists = self.contvert2Value().copy();
for arr in remainLists[::-1]:
if arr['colorTag'] in ['total','header','subtotal','site']:
remainLists.remove(arr);
# debug('remainLists is ' + str (remainLists));
return remainLists;
合并同类项
下面才开始进入合并同类项的主要算法里面。
我们可以利用python现有的数据结构来完成。
比如说构建一个dict:mergeMaps
这个字典的键值为每个散件的编码,value为数量。
-
遍历数组
-
对每一行,查看编码,是否在mergeMaps的key里面出现过,
-
如果没有出现过,则新建,value = 当前的数量
-
如果出现过,则数量在之前的基础上累加
-
# **************合并相同的BOM或者typeID**************
def mergeSimilar (self):
# 删除标题
remainLists = self.removeSubtotal();
# 将每一行的'BOM'或者'typeID'作为key,生成一个dict,
types = [t for t in ['BOM','typeID'] if t in remainLists[0].keys()];
if types != []:
field = types[0];
mergeMaps = {};
removeDuplications = [];
try:
# 遍历每一行
for arr in remainLists:
val = arr[field];
# 若是BOM或者typeID没有出现,则新建
if arr[field] not in mergeMaps.keys():
mergeMaps[val] = arr;
removeDuplications.append(val);
if 'unitsNetListPrice' in arr.keys() and arr['unitsNetListPrice'] != 0:
arr['discount'] = arr['unitsNetPrice'] / arr['unitsNetListPrice'];
else :
# 若是出现过,则数量增加
mergeMaps[val]['totalQuantity'] += arr['totalQuantity'];
except Exception as data:
error("原始的Excel格式有问题,可尝试删除有颜色的行再试")
return mergeMaps;
然后再加上公式以及总计行,于之前的清单页和Summary页相同,就不细讲了。
调用
依旧可以在Controller中调用
iMerge = M('merge');
mergeFields = getattr(inputvar ,'mergeFields');
if 'typeID' not in outputParam.keys():
del mergeFields['typeID']
iMerge.assign(lists,mergeFields );
mergeLists = iMerge.getMergeLists();
#