Odoo开发案例-从SO带入资讯到财务凭证

近日接到财务需求,要从销售订单增加部门,并将部门与原始的合约带入到会计凭证以便进行财务分析。
首先厘清需求:

  1. SO新增部门栏位
  2. 会计凭证增加部门及合约栏位
  3. 出货单验证后会产生凭证
  4. 开立发票后产生凭证

开发步骤:

  1. 在sale_order先增加department_id(Odoo本身就已经在SO上面存在project_id了)
  2. 在stock.picking增加department_id和project_id,以便于产生会计凭证时可以取得栏位
  3. 在account_move增加department_id和project_id

代码追踪及功能实现:

  • Odoo在确认订单的时候会产生Picking,所以追踪到此按钮的对应method: action_button_confirm
  • 此方法启动了order_confirm的workflow signal
self.signal_workflow(cr, uid, ids, 'order_confirm')
  • 进入workflow的编辑页面,沿着流程找下去,下一步到了route,此阶段执行了action_wait(),但此方法中没有产生picking相关的部分
  • 此时流程尚未结束,继续沿着流程找到了wait_ship节点,此节点未执行动作
  • 继续沿着节点找下去,到了ship节点,此节点执行了action_ship_create(),但此方法仅产生了procurement,然后执行了procurement中run的动作,追踪的动作到这里卡住了,因为没有任何关于产生picking的代码判断,虽然凭经验知道picking应该是在run procurement的时候产生。不过我们不需要继续看下去就可以切入了,我们知道SO和Picking是通过procurement_group_id来关联,因此可以继承此方法,用procurement来找到SO对应的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的执行流程中都没有找到产生会计凭证的相关代码,于是调整追踪代码的方向,我们知道warehouse的模块名称是stock,那么就去stock模块里面查找会计凭证相关的模块account.move,但查询结果显示stock模块里面没有出现account.move的任何内容。但跟stock相关的模块还有stock_account,根据模块名可判断出此模块为warehouse中对account的扩展,在此模块中继续搜寻account.move,bingo! 找到目标出现在_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)
  • 至此终于找到了最关键的代码片段

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转换上的问题。继承顺序的部分经过google查询之后,只要在模块声明文件中depends stock_account就可以确保当前模块在stock_account加载之后才加载,以确保加载的顺序。
  • 资讯从SO带到出货单再带到会计凭证的部分没有问题之后,要开始看如何在发票验证的时候把project_id和department_id带入会计凭证的部分
  • 通过Odoo销售订单产生发票,当点了创建发票按钮后我们会看到有几种开票方式:整单建立发票,百分比建立发票,固定金额建立发票以及订单行建立发票,通过开立发票按钮的方法create_invoices我们追踪到代码,可以看到如果为整单建立发票,Odoo会调用sale.order下面的方法manual_invoice,此发票又去触发了workflow中的manual_invoice,此时节点会跑到invoice节点并触发方法action_invoice_create(),回过头检查sale_order里面的此方法找到发票建立是在其中调用_make_invoice方法,而此方法中的发票数据处理是调用了_prepare_invoice,至此找到了整单建立发票的关键代码片段
  • 如果是固定金额或百分比方式,回头看create_invoices方法中,如果为固定金额或百分比,可以看到方法中会调用_prepare_advance_invoice_vals来准备发票的数据,所以我们也找到了固定金额或百分比中建立发票的关键代码片段
  • 如果是以发票明细行的方式开发票,系统会先导入到选择发票明细行的页面,选择之后按下开立发票按钮,会触发方法make_invoices,实际追踪发现此方法生效为sale_line_invoice.py中的同方法名,此方法中有一个子方法make_invoice,会调用_prepare_invoice准备数据,至此全部发票开立方式的关键代码片段都已经找到
  • 在开发发票的数据中写入project_id及department_id之后,就可以从验证发票并产生会计凭证这边下手了,先去跟踪验证发票按钮,进入Edit Form可以查看到验证按钮为workflow中invoice_open的触发点,再进入发票的workflow查看节点会进入到open中,此节点共计执行了4个方法action_date_assign() action_move_create() action_number() invoice_validate(),直接透过字面含义可知我们要修改的代码存在于action_move_create中
  • 进入action_move_create中,分析了一下代码发现我们修改的最终代码片段就是在这个方法中,我们需要在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,
}

总结:

  1. Odoo8同时存在的old api及new api对开发造成相当的困扰,一个Model有时要开两个文件来继承修改以区分api/old api
  2. workflow在后续版本拿掉真的是必然,在debug的时候要从程式代码和workflow切来切去很不方便,并且对版本管控来说workflow也不是良好的实现方式
  3. 当原生模块就已经继承的时候,要找到关键的代码片段也不是一件容易的事情
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,377评论 6 496
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,390评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,967评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,344评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,441评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,492评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,497评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,274评论 0 269
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,732评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,008评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,184评论 1 342
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,837评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,520评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,156评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,407评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,056评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,074评论 2 352

推荐阅读更多精彩内容