在上圖的情境中,點選右上角的「從…獲取項目」後,會出現途中的 Dialog,由於客戶要求在 Dialog 中可以有預設的 Filter,這在 Frappe 的 Dialog 物件中有類似的 function 能用,但 ERPNext 在產生這個 Dialog 時(utils.js #L705),雖然 map_current_doc 有回傳 Dialog 的物件,不過在purchase_invoice.js #L109中,並沒有變數去接這個物件,因此為了達成這個功能,就需要稍微修改一下 map_current_doc 才能夠達成。
新增一個 JS 檔,設定 Listen 「Purchase Invoice」(這邊能換成任何一個 Module,此部分以 Purchase Invoice 為例),以及一個 onload 事件。
因為主要目的是要存取到 map_current_doc 所回傳的 dialog 物件,因此將 map_current_doc 的原始碼貼過來後,只需要在建立 Dialog 後,將 Dialog 存在 frappe 這個全域變數中。(Frappe 建立的專案基本上都會有這個全域變數)
Frappe 的 Dialog 是基於 Bootstrap 的 Modal 建立的,因此需要 Listen Bootstrap Modal 的 shown.bs.modal
事件,才能在使用者開啟 Dialog 後,執行我們要做的事情。
由於 JS 非同步的特性,在新增 filter 時,可能會出現 filter 還沒產生完,但是 JS 已經在執行後續的 Code 的情況,因此為了確保流程一定會等到 filter 都產生完,才執行後續的程式,所以這邊需要使用 Async/Await 的方式去處理。
該流程會先執行 step2,而 step2 則會等待 step1 的 Promise 被 resolve,在 step1 中,會使用到 Step.3 中所存放的 frappe.mulit_seleect_dialge,在這個 Dialog 物件下的 filter_group 中,有一個 method 叫 add_filter,透過這個方式,傳入 doctype / 欄位名稱 / 條件 / 值 後,便可以新增一個 filter。
當 filter 新增完成之後,就會 resolve 當前的 promise,接著 step2 便會繼續往下執行,執行完畢後便會呼叫 on_change() 事件去更新 Dialog 中的資料了。