Odoo開發(fā)案例-從SO帶入資訊到財務(wù)憑證

近日接到財務(wù)需求秉氧,要從銷售訂單增加部門眷昆,并將部門與原始的合約帶入到會計憑證以便進行財務(wù)分析。
首先厘清需求:

  1. SO新增部門欄位
  2. 會計憑證增加部門及合約欄位
  3. 出貨單驗證后會產(chǎn)生憑證
  4. 開立發(fā)票后產(chǎn)生憑證

開發(fā)步驟:

  1. 在sale_order先增加department_id(Odoo本身就已經(jīng)在SO上面存在project_id了)
  2. 在stock.picking增加department_id和project_id汁咏,以便于產(chǎn)生會計憑證時可以取得欄位
  3. 在account_move增加department_id和project_id

代碼追蹤及功能實現(xiàn):

  • Odoo在確認訂單的時候會產(chǎn)生Picking亚斋,所以追蹤到此按鈕的對應(yīng)method: action_button_confirm
  • 此方法啟動了order_confirm的workflow signal
self.signal_workflow(cr, uid, ids, 'order_confirm')
  • 進入workflow的編輯頁面,沿著流程找下去攘滩,下一步到了route伞访,此階段執(zhí)行了action_wait(),但此方法中沒有產(chǎn)生picking相關(guān)的部分
  • 此時流程尚未結(jié)束轰驳,繼續(xù)沿著流程找到了wait_ship節(jié)點厚掷,此節(jié)點未執(zhí)行動作
  • 繼續(xù)沿著節(jié)點找下去,到了ship節(jié)點级解,此節(jié)點執(zhí)行了action_ship_create()冒黑,但此方法僅產(chǎn)生了procurement,然后執(zhí)行了procurement中run的動作勤哗,追蹤的動作到這里卡住了抡爹,因為沒有任何關(guān)于產(chǎn)生picking的代碼判斷,雖然憑經(jīng)驗知道picking應(yīng)該是在run procurement的時候產(chǎn)生芒划。不過我們不需要繼續(xù)看下去就可以切入了冬竟,我們知道SO和Picking是通過procurement_group_id來關(guān)聯(lián)欧穴,因此可以繼承此方法,用procurement來找到SO對應(yīng)的picking泵殴,并更新我們剛剛新增的department_id及project_id兩個欄位
    def action_ship_create(self):
        res = super(BelstarSaleOrderExtend, self).action_ship_create()
        picking = self.env['stock.picking'].search([('group_id', '=', self.procurement_group_id.id)])
        picking.write({'department_id': self.department_id.id, 'project_id': self.project_id.id})
        return res
  • 在驗證出貨單的時候又遇到了問題涮帘,追蹤頁面驗收功能,從do_detailed_transfer到do_transfer的執(zhí)行流程中都沒有找到產(chǎn)生會計憑證的相關(guān)代碼笑诅,于是調(diào)整追蹤代碼的方向调缨,我們知道warehouse的模塊名稱是stock,那么就去stock模塊里面查找會計憑證相關(guān)的模塊account.move吆你,但查詢結(jié)果顯示stock模塊里面沒有出現(xiàn)account.move的任何內(nèi)容弦叶。但跟stock相關(guān)的模塊還有stock_account,根據(jù)模塊名可判斷出此模塊為warehouse中對account的擴展妇多,在此模塊中繼續(xù)搜尋account.move伤哺,bingo! 找到目標出現(xiàn)在_create_account_move_line方法中,原來是在stock.quants的model下面者祖,通過查看此段代碼知道最終寫入的資料來自于另一個輔助方法_prepare_account_move_line
move_lines = self._prepare_account_move_line(cr, uid, move, qty, cost, credit_account_id, debit_account_id, context=context)
  • 至此終于找到了最關(guān)鍵的代碼片段

debit_line_vals = {
    'name': move.name,
    'product_id': move.product_id.id,
    'quantity': qty,
    'product_uom_id': move.product_id.uom_id.id,
    'ref': move.picking_id and move.picking_id.name or False,
    'date': fields.date.context_today(self, cr, uid, context=context),
    'partner_id': partner_id,
    'debit': valuation_amount > 0 and valuation_amount or 0,
    'credit': valuation_amount < 0 and -valuation_amount or 0,
    'account_id': debit_account_id,
}


credit_line_vals = {
    'name': move.name,
    'product_id': move.product_id.id,
    'quantity': qty,
    'product_uom_id': move.product_id.uom_id.id,
    'ref': move.picking_id and move.picking_id.name or False,
    'date': fields.date.context_today(self, cr, uid, context=context),
    'partner_id': partner_id,
    'credit': valuation_amount > 0 and valuation_amount or 0,
    'debit': valuation_amount < 0 and -valuation_amount or 0,
    'account_id': credit_account_id,
}
  • 找到了需要修改的代碼片段立莉,就可以著手修改了,這邊還有2個小問題咸包,stock_account里面stock.quants是繼承stock模塊的桃序,我們也要繼承相同的代碼并覆蓋掉stock_account里面的代碼,因此需要確認odoo載入順序烂瘫,另一個問題是官方模塊是old api的代碼格式需要用old api的方式來繼承媒熊,比較不會有new api轉(zhuǎn)換上的問題。繼承順序的部分經(jīng)過google查詢之后坟比,只要在模塊聲明文件中depends stock_account就可以確保當前模塊在stock_account加載之后才加載芦鳍,以確保加載的順序。
  • 資訊從SO帶到出貨單再帶到會計憑證的部分沒有問題之后葛账,要開始看如何在發(fā)票驗證的時候把project_id和department_id帶入會計憑證的部分
  • 通過Odoo銷售訂單產(chǎn)生發(fā)票柠衅,當點了創(chuàng)建發(fā)票按鈕后我們會看到有幾種開票方式:整單建立發(fā)票,百分比建立發(fā)票籍琳,固定金額建立發(fā)票以及訂單行建立發(fā)票菲宴,通過開立發(fā)票按鈕的方法create_invoices我們追蹤到代碼,可以看到如果為整單建立發(fā)票趋急,Odoo會調(diào)用sale.order下面的方法manual_invoice喝峦,此發(fā)票又去觸發(fā)了workflow中的manual_invoice,此時節(jié)點會跑到invoice節(jié)點并觸發(fā)方法action_invoice_create()呜达,回過頭檢查sale_order里面的此方法找到發(fā)票建立是在其中調(diào)用_make_invoice方法谣蠢,而此方法中的發(fā)票數(shù)據(jù)處理是調(diào)用了_prepare_invoice,至此找到了整單建立發(fā)票的關(guān)鍵代碼片段
  • 如果是固定金額或百分比方式,回頭看create_invoices方法中眉踱,如果為固定金額或百分比挤忙,可以看到方法中會調(diào)用_prepare_advance_invoice_vals來準備發(fā)票的數(shù)據(jù),所以我們也找到了固定金額或百分比中建立發(fā)票的關(guān)鍵代碼片段
  • 如果是以發(fā)票明細行的方式開發(fā)票谈喳,系統(tǒng)會先導入到選擇發(fā)票明細行的頁面册烈,選擇之后按下開立發(fā)票按鈕,會觸發(fā)方法make_invoices叁执,實際追蹤發(fā)現(xiàn)此方法生效為sale_line_invoice.py中的同方法名茄厘,此方法中有一個子方法make_invoice矮冬,會調(diào)用_prepare_invoice準備數(shù)據(jù)谈宛,至此全部發(fā)票開立方式的關(guān)鍵代碼片段都已經(jīng)找到
  • 在開發(fā)發(fā)票的數(shù)據(jù)中寫入project_id及department_id之后,就可以從驗證發(fā)票并產(chǎn)生會計憑證這邊下手了胎署,先去跟蹤驗證發(fā)票按鈕吆录,進入Edit Form可以查看到驗證按鈕為workflow中invoice_open的觸發(fā)點,再進入發(fā)票的workflow查看節(jié)點會進入到open中琼牧,此節(jié)點共計執(zhí)行了4個方法action_date_assign() action_move_create() action_number() invoice_validate()恢筝,直接透過字面含義可知我們要修改的代碼存在于action_move_create中
  • 進入action_move_create中,分析了一下代碼發(fā)現(xiàn)我們修改的最終代碼片段就是在這個方法中巨坊,我們需要在account_move及account.move.line中增加project_id及department_id撬槽,于是我們繼承這個方法并進行修改
line = inv.finalize_invoice_move_lines(line)

for el in line:
    el[2].update({'analytic_account_3': inv.department_id and inv.department_id.id or False,
                  'analytic_account': inv.project_id and inv.project_id.id or False
                  })

move_vals = {
    'ref': inv.reference or inv.name,
    'line_id': line,
    'journal_id': journal.id,
    'date': inv.date_invoice,
    'narration': inv.comment,
    'company_id': inv.company_id.id,
    'analytic_account': inv.project_id and inv.project_id.id or False,
    'analytic_account_3': inv.department_id and inv.department_id.id or False,
}

總結(jié):

  1. Odoo8同時存在的old api及new api對開發(fā)造成相當?shù)睦_,一個Model有時要開兩個文件來繼承修改以區(qū)分api/old api
  2. workflow在后續(xù)版本拿掉真的是必然趾撵,在debug的時候要從程式代碼和workflow切來切去很不方便侄柔,并且對版本管控來說workflow也不是良好的實現(xiàn)方式
  3. 當原生模塊就已經(jīng)繼承的時候,要找到關(guān)鍵的代碼片段也不是一件容易的事情
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末占调,一起剝皮案震驚了整個濱河市暂题,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌究珊,老刑警劉巖薪者,帶你破解...
    沈念sama閱讀 206,482評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異剿涮,居然都是意外死亡言津,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,377評論 2 382
  • 文/潘曉璐 我一進店門取试,熙熙樓的掌柜王于貴愁眉苦臉地迎上來悬槽,“玉大人,你說我怎么就攤上這事想括∠萜祝” “怎么了?”我有些...
    開封第一講書人閱讀 152,762評論 0 342
  • 文/不壞的土叔 我叫張陵,是天一觀的道長烟逊。 經(jīng)常有香客問我渣窜,道長,這世上最難降的妖魔是什么宪躯? 我笑而不...
    開封第一講書人閱讀 55,273評論 1 279
  • 正文 為了忘掉前任乔宿,我火速辦了婚禮,結(jié)果婚禮上访雪,老公的妹妹穿的比我還像新娘详瑞。我一直安慰自己,他們只是感情好臣缀,可當我...
    茶點故事閱讀 64,289評論 5 373
  • 文/花漫 我一把揭開白布坝橡。 她就那樣靜靜地躺著,像睡著了一般精置。 火紅的嫁衣襯著肌膚如雪计寇。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,046評論 1 285
  • 那天脂倦,我揣著相機與錄音番宁,去河邊找鬼。 笑死赖阻,一個胖子當著我的面吹牛蝶押,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播火欧,決...
    沈念sama閱讀 38,351評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼棋电,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了布隔?” 一聲冷哼從身側(cè)響起离陶,我...
    開封第一講書人閱讀 36,988評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎衅檀,沒想到半個月后招刨,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,476評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡哀军,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,948評論 2 324
  • 正文 我和宋清朗相戀三年沉眶,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片杉适。...
    茶點故事閱讀 38,064評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡谎倔,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出猿推,到底是詐尸還是另有隱情片习,我是刑警寧澤捌肴,帶...
    沈念sama閱讀 33,712評論 4 323
  • 正文 年R本政府宣布,位于F島的核電站藕咏,受9級特大地震影響状知,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜孽查,卻給世界環(huán)境...
    茶點故事閱讀 39,261評論 3 307
  • 文/蒙蒙 一饥悴、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧盲再,春花似錦西设、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,264評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至绿映,卻和暖如春擒滑,著一層夾襖步出監(jiān)牢的瞬間腐晾,已是汗流浹背叉弦。 一陣腳步聲響...
    開封第一講書人閱讀 31,486評論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留藻糖,地道東北人淹冰。 一個月前我還...
    沈念sama閱讀 45,511評論 2 354
  • 正文 我出身青樓,卻偏偏與公主長得像巨柒,于是被迫代替她去往敵國和親樱拴。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 42,802評論 2 345

推薦閱讀更多精彩內(nèi)容