ERPNext用戶級腳本案例解析: 如何通過腳本統計專案相關採購成本
背景與問題
希望在專案表單中顯示與專案關聯總採購訂單費用。
使用者自己的嘗試

有好幾個問題,就不點評了。
參考解決方案
1.通過定製為專案單據類型新增總採購成本欄位

2.第一版:為專案單據類型新增兩個單據事件(提交后與取消后)內容相同的python腳本
for po_item in doc.items:
po_cost = frappe.get_list('Purchase Order',
fields = 'sum(grand_total)',
filters = {'project': po_item.project, 'docstatus': 1},
as_list = 1)[0][0]
if po_cost:
frappe.db.set_value('Project',po_item.project, 'total_po_cost', po_cost)
文稿說明:
- 遍歷採購訂單明細行,
- 通過get_list函數取滿足條件(專案等於當前採購訂單行的專案字段,採購訂單狀是已提交),採購金額總計(sum),返回類型為清單中套清單,最後取出匯總金額[0][0]
- 如果有匯總金額返回
- 更新到專案中的採購成本欄位


第二版: 考慮到專案是採購訂單行而非訂單頭上,實際上很可能不同採購訂單行分派相同專案,以上代碼每一行執行一次,相同專案會重複執行。 改進版代碼如下
projects = {po_item.project for po_item in doc.items}
for project in projects:
po_cost = frappe.get_list('Purchase Order',
fields = 'sum(grand_total)',
filters = {'project': project, 'docstatus': 1},
as_list = 1)[0][0]
frappe.db.set_value('Project',project, 'total_po_cost', po_cost or 0)
簡要說明,第一行是用清單解析抓取不重複的項目號清單(集合)。
分享時提到用括弧()作清單解析返回沒有重複項的集合是不正確的,括號返回的是元組,應該用花括號{},以上代碼已修正。 謝謝參與分享的高手指出以上錯誤。
效果

小提示,採購訂單提交或取消后,跳轉回專案表單刷新瀏覽器成本字段值才會更新。
其他思考 :
是否可以用用戶端腳本實現,需要考慮哪些問題? 與python腳本實現對比有啥優缺點?
以上伺服器端實現方式是系統標準功能的實現方式,即關聯了專案的單據提交時,自動更新專案上的統計字段,此方式好處是統計值保存在專案單據(資料庫表)中了,表單,清單及報表查詢時該字段都有值。 不足是原有歷史採購訂單的舊專案,無新採購訂單提交或舊採購訂單取消時,不會觸發以上代碼,變通的做法是創建一個虛擬採購訂單提交再取消觸發程序執行。
如果用戶端JS實現,類似計算欄位,在每次打開專案表單(詳情)時計算。 可解決舊項目問題,但清單或報表中該值不會更新。
用戶端實現方式參考

常見問題
fields參數寫成這樣就會報下面的錯,這種寫法在py代碼里是可以的
fields:"sum(grand_total)",

filter參數寫成這樣filters:{'project': project, 'docstatus': 1} python後台可運行,通過js rest調用會出以下錯誤,系統程式對外部調用參數檢查邏輯不完善,沒考慮到內部支援子表單字段直接作為篩選條件。
