項(xiàng)目鏈接:https://gitee.com/duyang2903/quotationTools
本篇主要介紹匯總頁(yè)如何實(shí)現(xiàn)。
如下圖所示,本Sheet主要是把價(jià)格明細(xì)頁(yè)進(jìn)行同類項(xiàng)合并以后的結(jié)果
好處是:
可以看到每項(xiàng)散件的占比,找出哪一項(xiàng)對(duì)價(jià)格影響最大
合并以后核對(duì)更為簡(jiǎn)單

所以這一頁(yè)里面就沒有什么設(shè)備的概念了,大家都揉合在一起了。
代碼放在mergeModelClass.py
轉(zhuǎn)換數(shù)字列
xlrd不能讀Excel里面的公式(如果啟用格式選項(xiàng)會(huì)報(bào)錯(cuò))
不過沒有關(guān)系,可以曲線救國(guó),之前的數(shù)據(jù)反正是公式算出來(lái)的,我們?cè)诔绦蛑性偎阋话丫涂梢粤?/p>
def contvert2Value (self):
# processedArr = self.lists.copy();
processedArr = copy.deepcopy(self.lists);
# 轉(zhuǎn)換數(shù)量列
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'];
# 轉(zhuǎn)換單價(jià)列
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;
特別值得注意的是,需要先進(jìn)行深復(fù)制
因?yàn)槲覀儤?gòu)建的數(shù)據(jù)結(jié)構(gòu)本質(zhì)是個(gè)list,里面的每個(gè)元素是dict,如果dict改變,原來(lái)的list也會(huì)進(jìn)行改變。
刪除小計(jì)行
因?yàn)樵瓉?lái)的明細(xì)清單列表中有很多冗余的元素,我們需要把他們都干掉
# # **************刪除小計(jì)行**************
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;
合并同類項(xiàng)
下面才開始進(jìn)入合并同類項(xiàng)的主要算法里面。
我們可以利用python現(xiàn)有的數(shù)據(jù)結(jié)構(gòu)來(lái)完成。
比如說構(gòu)建一個(gè)dict:mergeMaps
這個(gè)字典的鍵值為每個(gè)散件的編碼,value為數(shù)量。
遍歷數(shù)組
-
對(duì)每一行,查看編碼,是否在mergeMaps的key里面出現(xiàn)過,
如果沒有出現(xiàn)過,則新建,value = 當(dāng)前的數(shù)量
如果出現(xiàn)過,則數(shù)量在之前的基礎(chǔ)上累加
# **************合并相同的BOM或者typeID**************
def mergeSimilar (self):
# 刪除標(biāo)題
remainLists = self.removeSubtotal();
# 將每一行的'BOM'或者'typeID'作為key,生成一個(gè)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沒有出現(xiàn),則新建
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 :
# 若是出現(xiàn)過,則數(shù)量增加
mergeMaps[val]['totalQuantity'] += arr['totalQuantity'];
except Exception as data:
error("原始的Excel格式有問題,可嘗試刪除有顏色的行再試")
return mergeMaps;
然后再加上公式以及總計(jì)行,于之前的清單頁(yè)和Summary頁(yè)相同,就不細(xì)講了。
調(diào)用
依舊可以在Controller中調(diào)用
iMerge = M('merge');
mergeFields = getattr(inputvar ,'mergeFields');
if 'typeID' not in outputParam.keys():
del mergeFields['typeID']
iMerge.assign(lists,mergeFields );
mergeLists = iMerge.getMergeLists();
#
