From 80104557a1d355488e0699a88e01af902b3031aa Mon Sep 17 00:00:00 2001 From: Lois Rilo Date: Fri, 25 May 2018 16:30:36 +0200 Subject: [PATCH] [9.0] rma_purchase: add purchase_policy cherry-pick 2100329188e45bf465d43b47c7e45cdb5041bc11 --- rma_purchase/__manifest__.py | 1 + rma_purchase/models/__init__.py | 2 + rma_purchase/models/purchase_order.py | 29 ++++++++ rma_purchase/models/purchase_order_line.py | 15 ++++ rma_purchase/models/rma_operation.py | 25 +++++++ rma_purchase/models/rma_order_line.py | 79 +++++++++++++++++++++- rma_purchase/views/rma_operation_view.xml | 28 ++++++++ rma_purchase/views/rma_order_line_view.xml | 31 +++++++++ 8 files changed, 208 insertions(+), 2 deletions(-) create mode 100644 rma_purchase/models/purchase_order.py create mode 100644 rma_purchase/models/rma_operation.py create mode 100644 rma_purchase/views/rma_operation_view.xml diff --git a/rma_purchase/__manifest__.py b/rma_purchase/__manifest__.py index c2deb874..70a5c252 100644 --- a/rma_purchase/__manifest__.py +++ b/rma_purchase/__manifest__.py @@ -12,6 +12,7 @@ 'depends': ['rma_account', 'purchase'], 'data': [ 'security/ir.model.access.csv', + 'views/rma_operation_view.xml', 'views/rma_order_view.xml', 'views/rma_order_line_view.xml', 'wizards/rma_add_purchase.xml' diff --git a/rma_purchase/models/__init__.py b/rma_purchase/models/__init__.py index 7f58a831..d41e378c 100644 --- a/rma_purchase/models/__init__.py +++ b/rma_purchase/models/__init__.py @@ -2,4 +2,6 @@ from . import rma_order from . import rma_order_line +from . import purchase_order from . import purchase_order_line +from . import rma_operation diff --git a/rma_purchase/models/purchase_order.py b/rma_purchase/models/purchase_order.py new file mode 100644 index 00000000..9ced8f41 --- /dev/null +++ b/rma_purchase/models/purchase_order.py @@ -0,0 +1,29 @@ +# -*- coding: utf-8 -*- +# Copyright 2017-18 Eficent Business and IT Consulting Services S.L. +# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html) + +from openerp import api, fields, models + + +class PurchaseOrder(models.Model): + _inherit = "purchase.order" + + @api.model + def new(self, vals): + """Allows to propose a line based on the RMA information.""" + res = super(PurchaseOrder, self).new(vals) + rma_line_id = self.env.context.get('rma_line_id') + if rma_line_id: + rma_line = self.env['rma.order.line'].browse(rma_line_id) + line = self.env['purchase.order.line'].new({ + 'product_id': rma_line.product_id.id, + }) + line.onchange_product_id() + line.update({ + 'product_qty': rma_line.qty_to_purchase, + 'product_uom': rma_line.uom_id.id, + }) + res.order_line = line + # TODO: maybe this line is not needed in v10: + res.date_planned = res._compute_date_planned() + return res diff --git a/rma_purchase/models/purchase_order_line.py b/rma_purchase/models/purchase_order_line.py index be15088f..c858d122 100644 --- a/rma_purchase/models/purchase_order_line.py +++ b/rma_purchase/models/purchase_order_line.py @@ -7,6 +7,14 @@ from odoo import api, models class PurchaseOrderLine(models.Model): _inherit = "purchase.order.line" + # TODO: to be removed on migration to v10: + # This is needed because odoo misspelled `store` in v9 :facepalm: + state = fields.Selection(related='order_id.state', store=True) + + rma_line_id = fields.Many2one( + comodel_name='rma.order.line', string='RMA', + ) + @api.model def name_search(self, name='', args=None, operator='ilike', limit=100): """Allows to search by PO reference.""" @@ -46,3 +54,10 @@ class PurchaseOrderLine(models.Model): return res else: return super(PurchaseOrderLine, self).name_get() + + @api.model + def create(self, vals): + rma_line_id = self.env.context.get('rma_line_id') + if rma_line_id: + vals['rma_line_id'] = rma_line_id + return super(PurchaseOrderLine, self).create(vals) diff --git a/rma_purchase/models/rma_operation.py b/rma_purchase/models/rma_operation.py new file mode 100644 index 00000000..51ed3cdd --- /dev/null +++ b/rma_purchase/models/rma_operation.py @@ -0,0 +1,25 @@ +# -*- coding: utf-8 -*- +# Copyright 2018 Eficent Business and IT Consulting Services S.L. +# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html) + +from openerp import api, fields, models, _ +from openerp.exceptions import ValidationError + + +class RmaOperation(models.Model): + _inherit = 'rma.operation' + + purchase_policy = fields.Selection( + selection=[('no', 'Not required'), + ('ordered', 'Based on Ordered Quantities'), + ('delivered', 'Based on Delivered Quantities')], + string="Purchase Policy", default='no', + ) + + @api.multi + @api.constrains('purchase_policy') + def _check_purchase_policy(self): + if self.filtered( + lambda r: r.purchase_policy != 'no' and r.type != 'supplier'): + raise ValidationError(_( + 'Purchase Policy can only apply to supplier operations')) diff --git a/rma_purchase/models/rma_order_line.py b/rma_purchase/models/rma_order_line.py index ad7ba221..63da1482 100644 --- a/rma_purchase/models/rma_order_line.py +++ b/rma_purchase/models/rma_order_line.py @@ -11,8 +11,14 @@ class RmaOrderLine(models.Model): @api.multi def _compute_purchase_count(self): for rec in self: - rec.purchase_count = len(self.env['purchase.order'].search( - [('origin', 'ilike', rec.name)]).ids) + purchase_list = [] + for procurement_id in rec.procurement_ids: + if procurement_id.purchase_id and \ + procurement_id.purchase_id.id: + purchase_list.append(procurement_id.purchase_id.id) + rec.purchase_count = ( + len(list(set(purchase_list))) + + len(rec.manual_purchase_line_ids.mapped('order_id'))) @api.multi def _compute_purchase_order_lines(self): @@ -24,6 +30,20 @@ class RmaOrderLine(models.Model): purchase_list.append(line.id) rec.purchase_order_line_ids = [(6, 0, purchase_list)] + @api.multi + @api.depends('procurement_ids.purchase_line_id', + 'manual_purchase_line_ids', + 'manual_purchase_line_ids.state', 'qty_delivered') + def _compute_qty_purchase(self): + for rec in self: + rec.qty_purchased = rec._get_rma_purchased_qty() + if rec.purchase_policy == 'ordered': + rec.qty_to_purchase = rec.product_qty - rec.qty_purchased + elif rec.purchase_policy == 'delivered': + rec.qty_to_purchase = rec.qty_delivered - rec.qty_purchased + else: + rec.qty_to_purchase = 0.0 + purchase_count = fields.Integer( compute='_compute_purchase_count', string='# of Purchases', ) @@ -43,6 +63,35 @@ class RmaOrderLine(models.Model): column1='rma_order_line_id', column2='purchase_order_line_id', string='Purchase Order Lines', compute='_compute_purchase_order_lines', ) + purchase_policy = fields.Selection( + selection=[('no', 'Not required'), + ('ordered', 'Based on Ordered Quantities'), + ('delivered', 'Based on Delivered Quantities')], + string="Purchase Policy", default='no', + required=True, + ) + manual_purchase_line_ids = fields.One2many( + comodel_name='purchase.order.line', + inverse_name='rma_line_id', + string='Manual Purchase Order Lines', + readonly=True, copy=False) + qty_to_purchase = fields.Float( + string='Qty To Purchase', copy=False, + digits=dp.get_precision('Product Unit of Measure'), + readonly=True, compute='_compute_qty_purchase', store=True, + ) + qty_purchased = fields.Float( + string='Qty Purchased', copy=False, + digits=dp.get_precision('Product Unit of Measure'), + readonly=True, compute='_compute_qty_purchase', store=True, + ) + + @api.onchange('operation_id') + def _onchange_operation_id(self): + res = super(RmaOrderLine, self)._onchange_operation_id() + if self.operation_id: + self.purchase_policy = self.operation_id.purchase_policy or 'no' + return res @api.multi def _prepare_rma_line_from_po_line(self, line): @@ -122,3 +171,29 @@ class RmaOrderLine(models.Model): if not exception == 'purchase_order_line_id': self.purchase_order_line_id = False return res + + @api.multi + def action_view_purchase_order(self): + action = self.env.ref('purchase.purchase_rfq') + result = action.read()[0] + orders = self.mapped('procurement_ids.purchase_id') + orders += self.mapped('manual_purchase_line_ids.order_id') + result['domain'] = [('id', 'in', orders.ids)] + return result + + @api.multi + def _get_rma_purchased_qty(self): + self.ensure_one() + qty = 0.0 + if self.type == 'customer': + return qty + uom_obj = self.env['product.uom'] + for procurement_id in self.procurement_ids: + purchase_line = procurement_id.purchase_line_id + qty += purchase_line.product_qty + + for line in self.manual_purchase_line_ids.filtered( + lambda p: p.state not in ('draft', 'sent', 'cancel')): + qty += uom_obj._compute_qty( + self.uom_id.id, line.product_qty, line.product_uom.id) + return qty diff --git a/rma_purchase/views/rma_operation_view.xml b/rma_purchase/views/rma_operation_view.xml new file mode 100644 index 00000000..9f4b5a86 --- /dev/null +++ b/rma_purchase/views/rma_operation_view.xml @@ -0,0 +1,28 @@ + + + + + + rma.operation.tree - rma_purchase + rma.operation + + + + + + + + + + rma.operation.form - rma_purchase + rma.operation + + + + + + + + + diff --git a/rma_purchase/views/rma_order_line_view.xml b/rma_purchase/views/rma_order_line_view.xml index e606b37e..fb8926e9 100644 --- a/rma_purchase/views/rma_order_line_view.xml +++ b/rma_purchase/views/rma_order_line_view.xml @@ -1,6 +1,28 @@ + + Purchase Order + purchase.order + form + current + form,tree + + + + rma.order.line.supplier.form + rma.order.line + + +
+
+
+
+ rma.order.line.supplier.form rma.order.line @@ -13,6 +35,15 @@ ('order_id.partner_id', '=', partner_id), ('order_id.partner_id', 'child_of', partner_id)]"/> + + + + + + + + +