zoukankan      html  css  js  c++  java
  • odoo 销售订单确认怎么触发的发货规则

    最近有需求需要调用库存补货规则,流程稍微有点复杂,在这里简单整理下

    # 1. 订单确认调用
        @api.multi
        def _action_confirm(self):
            for order in self:
                order.order_line._action_launch_stock_rule() # 调用规则了
            super(SaleOrder, self)._action_confirm()
    
    # 2.调用规则
        @api.multi
        def _action_launch_stock_rule(self):
            """
            Launch procurement group run method with required/custom fields genrated by a
            sale order line. procurement group will launch '_run_pull', '_run_buy' or '_run_manufacture'
            depending on the sale order line product rule.
            """
            precision = self.env['decimal.precision'].precision_get('Product Unit of Measure')
            errors = []
            for line in self:
                if line.state != 'sale' or not line.product_id.type in ('consu','product'):
                    continue
                qty = line._get_qty_procurement()
                if float_compare(qty, line.product_uom_qty, precision_digits=precision) >= 0:
                    continue
    
                group_id = line.order_id.procurement_group_id
                if not group_id:
                    group_id = self.env['procurement.group'].create({
                        'name': line.order_id.name, 'move_type': line.order_id.picking_policy,
                        'sale_id': line.order_id.id,
                        'partner_id': line.order_id.partner_shipping_id.id,
                    })
                    line.order_id.procurement_group_id = group_id
                else:
                    # In case the procurement group is already created and the order was
                    # cancelled, we need to update certain values of the group.
                    updated_vals = {}
                    if group_id.partner_id != line.order_id.partner_shipping_id:
                        updated_vals.update({'partner_id': line.order_id.partner_shipping_id.id})
                    if group_id.move_type != line.order_id.picking_policy:
                        updated_vals.update({'move_type': line.order_id.picking_policy})
                    if updated_vals:
                        group_id.write(updated_vals)
    
                values = line._prepare_procurement_values(group_id=group_id)
                product_qty = line.product_uom_qty - qty
    
                procurement_uom = line.product_uom
                quant_uom = line.product_id.uom_id
                get_param = self.env['ir.config_parameter'].sudo().get_param
                if procurement_uom.id != quant_uom.id and get_param('stock.propagate_uom') != '1':
                    product_qty = line.product_uom._compute_quantity(product_qty, quant_uom, rounding_method='HALF-UP')
                    procurement_uom = quant_uom
    
                try:
                    self.env['procurement.group'].run(line.product_id, product_qty, procurement_uom, line.order_id.partner_shipping_id.property_stock_customer, line.name, line.order_id.name, values) # 这块代码执行玩就生成出库单了
                except UserError as error:
                    errors.append(error.name)
            if errors:
                raise UserError('
    '.join(errors))
            return True
    
    # 3. 获取规则
        @api.model
        def run(self, product_id, product_qty, product_uom, location_id, name, origin, values):
            """ Method used in a procurement case. The purpose is to supply the
            product passed as argument in the location also given as an argument.
            In order to be able to find a suitable location that provide the product
            it will search among stock.rule.
            """
            values.setdefault('company_id', self.env['res.company']._company_default_get('procurement.group'))
            values.setdefault('priority', '1')
            values.setdefault('date_planned', fields.Datetime.now())
            rule = self._get_rule(product_id, location_id, values) # 获取规则记录
            if not rule:
                raise UserError(_('No procurement rule found in location "%s" for product "%s".
     Check routes configuration.') % (location_id.display_name, product_id.display_name))
            action = 'pull' if rule.action == 'pull_push' else rule.action
            if hasattr(rule, '_run_%s' % action):
                getattr(rule, '_run_%s' % action)(product_id, product_qty, product_uom, location_id, name, origin, values) # 使用规则生成调波单
            else:
                _logger.error("The method _run_%s doesn't exist on the procument rules" % action)
            return True
    
    # 4. 使用规则生成调拨单
        def _run_pull(self, product_id, product_qty, product_uom, location_id, name, origin, values):
            if not self.location_src_id:
                msg = _('No source location defined on stock rule: %s!') % (self.name, )
                raise UserError(msg)
    
            # create the move as SUPERUSER because the current user may not have the rights to do it (mto product launched by a sale for example)
            # Search if picking with move for it exists already:
            group_id = False
            if self.group_propagation_option == 'propagate':
                group_id = values.get('group_id', False) and values['group_id'].id
            elif self.group_propagation_option == 'fixed':
                group_id = self.group_id.id
    
            data = self._get_stock_move_values(product_id, product_qty, product_uom, location_id, name, origin, values, group_id)
            # Since action_confirm launch following procurement_group we should activate it.
            move = self.env['stock.move'].sudo().with_context(force_company=data.get('company_id', False)).create(data) # 在这里创建stock_move记录
            move._action_confirm() # stock.move 在确认时创建stock.picking
            return True
    
    # 5. stock.move 确认并创建picking
        def _action_confirm(self, merge=True, merge_into=False):
            """ Confirms stock move or put it in waiting if it's linked to another move.
            :param: merge: According to this boolean, a newly confirmed move will be merged
            in another move of the same picking sharing its characteristics.
            """
            move_create_proc = self.env['stock.move']
            move_to_confirm = self.env['stock.move']
            move_waiting = self.env['stock.move']
    
            to_assign = {}
            for move in self:
                # if the move is preceeded, then it's waiting (if preceeding move is done, then action_assign has been called already and its state is already available)
                if move.move_orig_ids:
                    move_waiting |= move
                else:
                    if move.procure_method == 'make_to_order':
                        move_create_proc |= move
                    else:
                        move_to_confirm |= move
                if move._should_be_assigned():
                    key = (move.group_id.id, move.location_id.id, move.location_dest_id.id)
                    if key not in to_assign:
                        to_assign[key] = self.env['stock.move']
                    to_assign[key] |= move
    
            # create procurements for make to order moves
            for move in move_create_proc:
                values = move._prepare_procurement_values()
                origin = (move.group_id and move.group_id.name or (move.origin or move.picking_id.name or "/"))
                self.env['procurement.group'].run(move.product_id, move.product_uom_qty, move.product_uom, move.location_id, move.rule_id and move.rule_id.name or "/", origin,
                                                  values)
    
            move_to_confirm.write({'state': 'confirmed'})
            (move_waiting | move_create_proc).write({'state': 'waiting'})
    
            # assign picking in batch for all confirmed move that share the same details
            for moves in to_assign.values():
                moves._assign_picking()
            self._push_apply()
            if merge:
                return self._merge_moves(merge_into=merge_into)
            return self
    

    懂得,原来世界如此简单!

  • 相关阅读:
    homework2
    一件关于Bug的小事
    软件测试作业三:有关控制流图、覆盖内容
    用CSS改变select框的样式
    lab1--ideal + junit
    软件测试作业二
    记一次曾经项目中遇到的错误
    02组_现代软件工程_第04次作业——利用4象限原理分析自身CanTool项目的构成
    02组_现代软件工程_第03次作业——对于自身评价(原有水平以及长远目标分析总结)
    02组_现代软件工程_第02次作业——初谈GitHub使用详解以及设计
  • 原文地址:https://www.cnblogs.com/qianxunman/p/15469739.html
Copyright © 2011-2022 走看看