原文來自:http://shine-it.net/index.php/topic,16409.0.html
庫存移動(Stock Move)新玩法
Odoo的庫存移動不僅僅是存貨在兩個“存貨地點”之間的移動的基本概念了,他們可以被“串聯”在一起,可以用來生成或改變其對應的揀貨單(Picking)。鏈式庫存移動被廣泛應用在各類庫存操作中比如:多步收貨或多步發貨操作,多倉庫間的配、補貨操作等;而不僅限於之前OpenERP中MTO供貨類型產品的發貨等待對應供應商收貨這樣的鏈式庫存移動的應用場景了。我們會描述如何通過“推”,“拉”規則來創建這些鏈式庫存移動。
庫存移動與揀貨單的關聯
倉管人員手動進行的庫存操作的一般順序是:先創建揀貨單然后在明細中選擇不同的產品及數量從而創建相應的庫存移動。但是在確認銷售訂單時,Odoo則是自動創建對應銷售訂單明細的庫存移動在先,然后才會去將這些庫存移動與一個現有的揀貨單關聯或創建一個新的揀貨單。
庫存移動與揀貨單關聯的前提條件是庫存移動設置了揀貨類型(比如:我的公司:發貨單)。如果庫存移動有設置揀貨類型,Odoo則會嘗試搜索揀貨單並與之關聯。搜索的條件是這個揀貨單要與庫存移動有一致的狀態,揀貨類型,需求組(Procurement group, 即一組相關需求,比如來自同一訂單), 源貨位和目的貨位。如果沒有找到相應的揀貨單則會新建一個揀貨單並與之關聯。
這種機制大大增加了靈活性。比如某些貨品需要進入包裝車間再包裝,有些貨品不需要的情況,訂單中需包裝的產品會被組合到一個揀貨單中而不需要包裝的產品會被組合進另一個揀貨單中,而在發貨時所有的貨品又被重新組合到一個新的揀貨單中。
揀貨單幾乎完全由其所含的庫存移動決定。其狀態由庫存移動的狀態和揀貨類型決定,源貨位和目的貨位與其所含的庫存移動的一致。預期揀貨時間由所有庫存移動指定日期中的最小日期決定。
揀貨單的狀態主要尤其所包含的庫存移動決定:
如果所有的移動都是草稿狀態,則揀貨單也為草稿狀態
如果所有的移動都是完成或取消,則揀貨單也為完成或取消。
其他狀態則同時取決於移動類型。移動類型用於決定客戶是希望一次性完成全部產品的發貨(一次性發貨all at once)還是希望盡快收貨(分批發貨partial)。這種移動類型可以手動選擇,也可以來自銷售訂單通過需求組傳入。
如果是分批發貨,則有一個特殊的狀態:部分可用。當一個庫存移動處於“確認/等待”狀態時,部分庫存已預留,這樣的情況在Odoo中是允許的。該庫存會仍然處於“確認/等待”的狀態,但是會有一個“部分可用”的標簽。這種情況下,揀貨單的狀態不再是“確認/等待"狀態而會變為“部分可用”狀態,這使得分批發貨成為可能。另外,當揀貨單中的部分庫存移動處於預留可用狀態,而其他庫存移動仍然不可用時,揀貨單也會變為“部分可用”狀態。
有時一個庫存移動並不會指定揀貨類型,這意味着沒有關聯的揀貨單。比如盤點操作及生產操作中所對應的庫存移動。
創建鏈式庫存移動的拉式(需求)和推式規則
推式規則:
根據一個庫存移動的目標庫位激發創建另一個庫存移動的規則。新創建的庫存移動的源庫位與原庫存移動的目標庫位相同。
例如:當貨品到達“收貨”庫位時,設定的推式規則將它們移動到“庫存”庫位。
所以,當“供應商庫位”->"收貨“庫位的庫存移動確認時,該規則會創建另一個庫存移動:“收貨庫位“->“庫存庫位”。規則允許3中模式:自動(第二個庫存移動會被自動確認),手動(第二個庫存移動必須手動確認),手動不添加步驟(不創建第二個庫存移動而是將第一個庫存移動的目標庫位替換為指定庫位)
推式規則一般用於當采購訂單確認后的收貨操作,貨品需要移入庫存庫位。
需求 (=拉式)規則:
拉式規則並非推式規則的反向操作!他們的基本不同點在於推式規則影響的是庫存移動,而拉式規則影響的是需求。實際上稱他們為需求規則更准確。但是,我們也可以這么說:推式規則作用於目標庫位,而拉式規則作用於源庫位。
當庫存移動確認后,如果其需求方式(procurement method)為‘高級:應用需求規則’,則會在其源庫位創建一個跟庫存移動數量一致的需求單。需求規則會作用於該需求單用以滿足需求。不同類型的需求規則會導致需求單運行后產生不同的結果,比如:從其他庫位移動產品到原庫存移動對應的源庫位以滿足其對產品的需求,或者通過采購收貨到源庫位以滿足其對產品的需求,也或者通過生產入庫到源庫位來滿足其對產品的需求。參見下圖及說明:
這是一個"庫存移動“的表單視圖,默認情況下其“供應方式”(Supply Method)是“取自庫存”(Default:Take from Stock),表示當該庫存移動確定時將檢查“源庫位”是否有足夠庫存,如果庫存不足則進入“等待可用”狀態。而當我們將“供應方式”設為:”高級:應用需求規則時“,Odoo就會去檢查與該庫存移動的”源庫位“相關的”需求規則“, 見下圖:
上圖中可以看到“需求規則”中有定義“需求庫位”(Procurement Location), 並且在“動作”(action)中可以選擇“采購”,“生產”,和“從其他庫位移動存貨“(選擇此項會顯示更多選項),根據“動作”的選擇不同會產生對應的需求單,在需求單運行后會產生對應的采購或生產,或其他庫存移動來滿足“需求庫位”的存貨需求。
但是需求單也不必一定由庫存移動產生。用戶可以手動創建需求單,或在確認銷售訂單時,Odoo為每一個銷售訂單明細在“客戶”貨位創建需求單。事實上這個由需求單,庫存移動單和需求規則所構建的體系在Odoo系統里是貫徹始終的。比如在最簡單的庫存管理設置中,當我們運行這些由銷售訂單創建的需求單時,這些需求規則就會創建出發運單。
在正常情況下需求單會經歷下列狀態:
已確認:需求單創建之后的狀態
運行中:成功應用了一個需求規則(導致創建一個庫存移動或報價單或生產單)
完成: 需求規則已應用並且產品已經轉運到或已經在需求單所對應的貨位了。
當不能找到需求規則或無法應用需求規則(比如產品上沒有定義供應商)時,需求單會進入“出錯”(Exception)狀態。如果對產品的需求不再需要,也可以取消需求單。
默認情況下,Odoo會安裝JIT計划模塊。Odoo會在需求單確認時自動運算該需求。如果這導致了系統性能問題,我們也可以卸載該模塊。這樣只有銷售訂單創建的需求單會被立刻自動運行從而創建出發運單,而由庫存移動創建的需求單則不會立即自動運算,而會由計划運行(Scheduler)統一安排運算時間。
由拉式規則生成的規則不能再應用推式規則了,所以拉式規則優先於推式規則。
需求規則和庫存移動的需求方式
庫存移動確認后是否會在其源庫位創建需求單並應用需求規則取決於其需求方式的設置。只有設置了需求方式為“高級:應用需求規則”的庫存移動會生成需求單。
當用戶創建一個在揀貨單時,其中的庫存移動將使用默認的需求方式:“默認:取自庫存”。這表示該庫存移動不會在其源庫位創建一個需求單,而會在源庫位查找是否有足夠的可用庫存。這也是諸如“移動呆滯庫存產品到滯銷庫位“這樣的內部移庫的基本邏輯。
但是如果用戶將庫存移動的需求方式改變為”高級:應用需求規則“,Odoo就會在該庫存移動的源庫位創建需求單。(譯者:寫文檔的人這一通反反復復,是怕自己忘了嗎:-) 比如,創建發貨單可以導致一個與該發貨單對應的采購訂單的生成。
當我們設置了“揀貨->包裝->發貨“這樣的需求規則時。應用該需求規則,Odoo會自動生成從倉庫貨位向包裝貨位的庫存移動。這樣即使你手動創建一個從倉庫的發貨單,Odoo也會自動創建揀貨/包裝流程。
需求方式只對內部調撥,和發貨有意義。收貨操作不需要預留庫存,所以他們總是使用默認設置”默認:來自庫存“。
你可能會想是否可以連續創建多個這樣的鏈式庫存移動呢。事實上,當一個需求規則創建一個新的庫存移動時,新的庫存移動的需求方式可以被事先定義好。也就是說,需求規則可以決定新創建的庫存移動是尋找並應用與其匹配的需求規則還是使用默認“來自庫存”的設置。
這樣就可以創建出下例表述的庫存移動的長鏈。假設我們有設置了揀貨-包裝-發貨的需求規則的MTS需求類型的產品,當包含該產品的銷售訂單確認時,“鏈式反應“啟動。首先銷售訂單會在客戶庫位創建需求單,該需求單的運行會創建從倉庫出貨庫位到客戶庫位的庫存移動,而該庫存移動的”需求方式“為”高級:應用需求規則“,這樣就會在在”出貨庫位“創建一個需求單,如此循環直到在”包裝貨位“的需求單創建庫存移動單,並且該庫存移動單的需求方式為”默認:來自庫存“。