From 20ecbee99c4e68f3cafda02daa304f91f9a518c5 Mon Sep 17 00:00:00 2001 From: Jordi Ballester Date: Thu, 27 Jul 2017 18:17:19 +0200 Subject: [PATCH 01/42] init branch --- rma_purchase/README.rst | 37 +++++++ rma_purchase/__init__.py | 5 + rma_purchase/__openerp__.py | 20 ++++ rma_purchase/models/__init__.py | 5 + rma_purchase/models/rma_order.py | 62 +++++++++++ rma_purchase/models/rma_order_line.py | 72 +++++++++++++ rma_purchase/views/rma_order_line_view.xml | 33 ++++++ rma_purchase/views/rma_order_view.xml | 33 ++++++ rma_purchase/wizards/__init__.py | 6 ++ rma_purchase/wizards/rma_add_purchase.py | 114 +++++++++++++++++++++ rma_purchase/wizards/rma_add_purchase.xml | 77 ++++++++++++++ rma_purchase/wizards/rma_make_picking.py | 38 +++++++ 12 files changed, 502 insertions(+) create mode 100644 rma_purchase/README.rst create mode 100644 rma_purchase/__init__.py create mode 100644 rma_purchase/__openerp__.py create mode 100644 rma_purchase/models/__init__.py create mode 100644 rma_purchase/models/rma_order.py create mode 100644 rma_purchase/models/rma_order_line.py create mode 100644 rma_purchase/views/rma_order_line_view.xml create mode 100644 rma_purchase/views/rma_order_view.xml create mode 100644 rma_purchase/wizards/__init__.py create mode 100644 rma_purchase/wizards/rma_add_purchase.py create mode 100644 rma_purchase/wizards/rma_add_purchase.xml create mode 100644 rma_purchase/wizards/rma_make_picking.py diff --git a/rma_purchase/README.rst b/rma_purchase/README.rst new file mode 100644 index 00000000..49fbc152 --- /dev/null +++ b/rma_purchase/README.rst @@ -0,0 +1,37 @@ +.. image:: https://img.shields.io/badge/licence-LGPL--3-blue.svg + :alt: License LGPL-3 + +RMA Purchase +=========== + +Purchase as RMA source + +Usage +===== + +select add_purchase_id to fill rma from RMA purchase + + +Bug Tracker +=========== + +Bugs are tracked on `GitHub Issues +`_. In case of trouble, please +check there if your issue has already been reported. If you spotted it first, +help us smashing it by providing a detailed and welcomed feedback. + + +Credits +======= + +Contributors +------------ + +* Jordi Ballester Alomar +* Aaron Henriquez + + +Maintainer +---------- + +This module is maintained by Eficent. diff --git a/rma_purchase/__init__.py b/rma_purchase/__init__.py new file mode 100644 index 00000000..4105ff51 --- /dev/null +++ b/rma_purchase/__init__.py @@ -0,0 +1,5 @@ +# -*- coding: utf-8 -*- +# © 2017 Eficent Business and IT Consulting Services S.L. +# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html) +from . import models +from . import wizards diff --git a/rma_purchase/__openerp__.py b/rma_purchase/__openerp__.py new file mode 100644 index 00000000..6d287e68 --- /dev/null +++ b/rma_purchase/__openerp__.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- +# © 2017 Eficent Business and IT Consulting Services S.L. +# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html) +{ + 'name': 'RMA Purchase', + 'version': '9.0.1.0.0', + 'category': 'RMA', + 'summary': 'RMA from PO', + 'description': """ + RMA from PO +""", + 'author': 'Eficent', + 'website': 'http://www.github.com/OCA/rma', + 'depends': ['rma_account', 'purchase'], + 'data': ['views/rma_order_view.xml', + 'views/rma_order_line_view.xml', + 'wizards/rma_add_purchase.xml'], + 'installable': True, + 'auto_install': True, +} diff --git a/rma_purchase/models/__init__.py b/rma_purchase/models/__init__.py new file mode 100644 index 00000000..a3a08e5e --- /dev/null +++ b/rma_purchase/models/__init__.py @@ -0,0 +1,5 @@ +# -*- coding: utf-8 -*- +# © 2017 Eficent Business and IT Consulting Services S.L. +# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html) +from . import rma_order +from . import rma_order_line diff --git a/rma_purchase/models/rma_order.py b/rma_purchase/models/rma_order.py new file mode 100644 index 00000000..3b21983e --- /dev/null +++ b/rma_purchase/models/rma_order.py @@ -0,0 +1,62 @@ +# -*- coding: utf-8 -*- +# © 2017 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.addons import decimal_precision as dp +from random import randint +from datetime import datetime + + +class RmaOrder(models.Model): + _inherit = "rma.order" + + @api.depends('rma_line_ids', 'rma_line_ids.procurement_ids') + @api.multi + def _compute_po_count(self): + for rec in self: + purchase_list = [] + for line in rec.rma_line_ids: + for procurement_id in line.procurement_ids: + if procurement_id.purchase_id and procurement_id.purchase_id.id: + purchase_list.append(procurement_id.purchase_id.id) + rec.po_count = len(list(set(purchase_list))) + + @api.one + def _compute_origin_po_count(self): + po_list = [] + for rma_line in self.rma_line_ids: + if rma_line.purchase_order_line_id and \ + rma_line.purchase_order_line_id.id: + po_list.append(rma_line.purchase_order_line_id.order_id.id) + self.origin_po_count = len(list(set(po_list))) + + po_count = fields.Integer(compute=_compute_po_count, + string='# of PO', + copy=False, default=0) + + origin_po_count = fields.Integer(compute=_compute_origin_po_count, + string='# of Origin PO', copy=False, + default=0) + + @api.multi + def action_view_purchase_order(self): + action = self.env.ref('purchase.purchase_rfq') + result = action.read()[0] + order_ids = [] + for line in self.rma_line_ids: + for procurement_id in line.procurement_ids: + order_ids.append(procurement_id.purchase_id.id) + result['domain'] = [('id', 'in', order_ids)] + return result + + @api.multi + def action_view_origin_purchase_order(self): + action = self.env.ref('purchase.purchase_rfq') + result = action.read()[0] + order_ids = [] + for rma_line in self.rma_line_ids: + if rma_line.purchase_order_line_id and \ + rma_line.purchase_order_line_id.id: + order_ids.append(rma_line.purchase_order_line_id.order_id.id) + result['domain'] = [('id', 'in', order_ids)] + return result diff --git a/rma_purchase/models/rma_order_line.py b/rma_purchase/models/rma_order_line.py new file mode 100644 index 00000000..f87c5eb3 --- /dev/null +++ b/rma_purchase/models/rma_order_line.py @@ -0,0 +1,72 @@ +# -*- coding: utf-8 -*- +# © 2017 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.addons import decimal_precision as dp +from random import randint + + +class RmaOrderLine(models.Model): + _inherit = "rma.order.line" + + @api.one + def _compute_purchase_count(self): + purchase_list = [] + for procurement_id in self.procurement_ids: + if procurement_id.purchase_id and procurement_id.purchase_id.id: + purchase_list.append(procurement_id.purchase_id.id) + self.purchase_count = len(list(set(purchase_list))) + + @api.one + @api.depends('procurement_ids.purchase_line_id') + def _get_purchase_order_lines(self): + purchase_list = [] + for procurement_id in self.procurement_ids: + if procurement_id.purchase_line_id and \ + procurement_id.purchase_line_id.id: + purchase_list.append(procurement_id.purchase_line_id.id) + self.purchase_order_line_ids = [(6, 0, purchase_list)] + + @api.one + @api.depends('procurement_ids.purchase_line_id') + def _compute_qty_purchased(self): + self.qty_purchased = self._get_rma_purchased_qty() + + purchase_count = fields.Integer(compute=_compute_purchase_count, + string='# of Purchases', copy=False, + default=0) + purchase_order_line_id = fields.Many2one('purchase.order.line', + string='Origin Purchase Line', + ondelete='restrict') + purchase_order_line_ids = fields.Many2many( + 'purchase.order.line', 'purchase_line_rma_line_rel', + 'rma_order_line_id', 'purchase_order_line_id', + string='Purchase Order Lines', compute=_get_purchase_order_lines) + + qty_purchased = fields.Float( + string='Qty Purchased', copy=False, + digits=dp.get_precision('Product Unit of Measure'), + readonly=True, compute=_compute_qty_purchased, + store=True) + + @api.multi + def action_view_purchase_order(self): + action = self.env.ref('purchase.purchase_rfq') + result = action.read()[0] + order_ids = [] + for procurement_id in self.procurement_ids: + order_ids.append(procurement_id.purchase_id.id) + result['domain'] = [('id', 'in', order_ids)] + return result + + @api.multi + def _get_rma_purchased_qty(self): + self.ensure_one() + qty = 0.0 + for procurement_id in self.procurement_ids: + purchase_line = procurement_id.purchase_line_id + if self.type == 'supplier': + qty += purchase_line.product_qty + else: + qty = 0.0 + return qty diff --git a/rma_purchase/views/rma_order_line_view.xml b/rma_purchase/views/rma_order_line_view.xml new file mode 100644 index 00000000..e57b4939 --- /dev/null +++ b/rma_purchase/views/rma_order_line_view.xml @@ -0,0 +1,33 @@ + + + + + + rma.order.line.supplier.form + rma.order.line + + +
+ +
+ + + + + + + + + + +
+
+ +
+
diff --git a/rma_purchase/views/rma_order_view.xml b/rma_purchase/views/rma_order_view.xml new file mode 100644 index 00000000..1875c5e8 --- /dev/null +++ b/rma_purchase/views/rma_order_view.xml @@ -0,0 +1,33 @@ + + + + + + rma.order.supplier.form + rma.order + + +
+ +
+
+ +
+
+
+ +
+
diff --git a/rma_purchase/wizards/__init__.py b/rma_purchase/wizards/__init__.py new file mode 100644 index 00000000..716f361c --- /dev/null +++ b/rma_purchase/wizards/__init__.py @@ -0,0 +1,6 @@ +# -*- coding: utf-8 -*- +# © 2017 Eficent Business and IT Consulting Services S.L. +# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html) + +from . import rma_make_picking +from . import rma_add_purchase diff --git a/rma_purchase/wizards/rma_add_purchase.py b/rma_purchase/wizards/rma_add_purchase.py new file mode 100644 index 00000000..c31a99ec --- /dev/null +++ b/rma_purchase/wizards/rma_add_purchase.py @@ -0,0 +1,114 @@ +# -*- coding: utf-8 -*- +# © 2017 Eficent Business and IT Consulting Services S.L. +# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html) + +import time +from openerp import models, fields, exceptions, api, _ +from openerp.exceptions import ValidationError +from openerp.tools import DEFAULT_SERVER_DATETIME_FORMAT as DT_FORMAT +import openerp.addons.decimal_precision as dp + + +class RmaAddPurchase(models.TransientModel): + _name = 'rma_add_purchase' + _description = 'Wizard to add rma lines' + + @api.model + def default_get(self, fields): + res = super(RmaAddPurchase, self).default_get(fields) + rma_obj = self.env['rma.order'] + rma_id = self.env.context['active_ids'] or [] + active_model = self.env.context['active_model'] + if not rma_id: + return res + assert active_model == 'rma.order', 'Bad context propagation' + + rma = rma_obj.browse(rma_id) + res['rma_id'] = rma.id + res['partner_id'] = rma.partner_id.id + res['purchase_id'] = False + res['purchase_line_ids'] = False + return res + + rma_id = fields.Many2one('rma.order', + string='RMA Order', + readonly=True, + ondelete='cascade') + + partner_id = fields.Many2one(comodel_name='res.partner', string='Partner', + readonly=True) + purchase_id = fields.Many2one(comodel_name='purchase.order', string='Order') + purchase_line_ids = fields.Many2many('purchase.order.line', + 'rma_add_purchase_add_line_rel', + 'purchase_line_id', 'rma_add_purchase_id', + readonly=False, + string='Purcahse Order Lines') + + def _prepare_rma_line_from_po_line(self, line): + operation = line.product_id.rma_operation_id and \ + line.product_id.rma_operation_id.id or False + if not operation: + operation = line.product_id.categ_id.rma_operation_id and \ + line.product_id.categ_id.rma_operation_id.id or False + data = { + 'purchase_order_line_id': line.id, + 'product_id': line.product_id.id, + 'origin': line.order_id.name, + 'uom_id': line.product_uom.id, + 'operation_id': operation, + 'product_qty': line.product_qty, + 'price_unit': line.currency_id.compute( + line.price_unit, line.currency_id, round=False), + 'rma_id': self.rma_id.id + } + if not operation: + operation = self.env['rma.operation'].search( + [('type', '=', self.rma_id.type)], limit=1) + if not operation: + raise ValidationError("Please define an operation first") + if not operation.in_route_id or not operation.out_route_id: + route = self.env['stock.location.route'].search( + [('rma_selectable', '=', True)], limit=1) + if not route: + raise ValidationError("Please define an rma route") + data.update( + {'in_route_id': operation.in_route_id.id or route, + 'out_route_id': operation.out_route_id.id or route, + 'receipt_policy': operation.receipt_policy, + 'location_id': operation.location_id.id or + self.env.ref('stock.stock_location_stock').id, + 'operation_id': operation.id, + 'refund_policy': operation.refund_policy, + 'delivery_policy': operation.delivery_policy + }) + return data + + @api.model + def _get_rma_data(self): + data = { + 'date_rma': fields.Datetime.now(), + 'delivery_address_id': self.purchase_id.partner_id.id, + 'invoice_address_id': self.purchase_id.partner_id.id + } + return data + + @api.model + def _get_existing_purchase_lines(self): + existing_purchase_lines = [] + for rma_line in self.rma_id.rma_line_ids: + existing_purchase_lines.append(rma_line.purchase_order_line_id) + return existing_purchase_lines + + @api.multi + def add_lines(self): + rma_line_obj = self.env['rma.order.line'] + existing_purchase_lines = self._get_existing_purchase_lines() + for line in self.purchase_line_ids: + # Load a PO line only once + if line not in existing_purchase_lines: + data = self._prepare_rma_line_from_po_line(line) + rma_line_obj.create(data) + rma = self.rma_id + data_rma = self._get_rma_data() + rma.write(data_rma) + return {'type': 'ir.actions.act_window_close'} diff --git a/rma_purchase/wizards/rma_add_purchase.xml b/rma_purchase/wizards/rma_add_purchase.xml new file mode 100644 index 00000000..f131f7e6 --- /dev/null +++ b/rma_purchase/wizards/rma_add_purchase.xml @@ -0,0 +1,77 @@ + + + + + rma.add.purchase + rma_add_purchase + +
+ + + + + + + + + + + + + + + + + + + + + +
+
+ +
+
+ + + Add Purchase Order + ir.actions.act_window + rma_add_purchase + rma.order + form + form + new + + + + + + rma.order.line.supplier.form + rma.order + + + + + + + +
diff --git a/rma_purchase/wizards/rma_make_picking.py b/rma_purchase/wizards/rma_make_picking.py new file mode 100644 index 00000000..f80204c9 --- /dev/null +++ b/rma_purchase/wizards/rma_make_picking.py @@ -0,0 +1,38 @@ +# -*- coding: utf-8 -*- +# © 2017 Eficent Business and IT Consulting Services S.L. +# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html) +from openerp import models, fields, exceptions, api, _ + + +class RmaMakePicking(models.TransientModel): + _inherit = 'rma_make_picking.wizard' + + @api.returns('rma.order.line') + def _prepare_item(self, line): + res = super(RmaMakePicking, self)._prepare_item(line) + res['purchase_order_line_id'] = line.purchase_order_line_id.id + return res + + @api.model + def _get_action(self, pickings, procurements): + po_list = [] + for procurement in procurements: + if procurement.purchase_id and \ + procurement.purchase_id.id: + po_list.append(procurement.purchase_id.id) + if len(po_list): + action = self.env.ref('purchase.purchase_rfq') + result = action.read()[0] + result['domain'] = [('id', 'in', po_list)] + return result + else: + action = super(RmaMakePicking, self)._get_action(pickings, + procurements) + return action + + +class RmaMakePickingItem(models.TransientModel): + _inherit = "rma_make_picking.wizard.item" + + purchase_order_line_id = fields.Many2one('purchase.order.line', + string='Purchase Line') From 6068d720a454e4685cb9efd23367e955c0eaf912 Mon Sep 17 00:00:00 2001 From: lreficent Date: Wed, 2 Aug 2017 17:05:58 +0200 Subject: [PATCH 02/42] [9.0][FIX] rma: * fix assignment of moves. * default qty in rma lines. * remove account dependency. * test and flake8 fixes. --- rma_purchase/models/rma_order.py | 12 +++++------ rma_purchase/models/rma_order_line.py | 1 - rma_purchase/wizards/rma_add_purchase.py | 26 ++++++++++++------------ rma_purchase/wizards/rma_make_picking.py | 2 +- 4 files changed, 19 insertions(+), 22 deletions(-) diff --git a/rma_purchase/models/rma_order.py b/rma_purchase/models/rma_order.py index 3b21983e..54121cc0 100644 --- a/rma_purchase/models/rma_order.py +++ b/rma_purchase/models/rma_order.py @@ -2,9 +2,6 @@ # © 2017 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.addons import decimal_precision as dp -from random import randint -from datetime import datetime class RmaOrder(models.Model): @@ -17,7 +14,8 @@ class RmaOrder(models.Model): purchase_list = [] for line in rec.rma_line_ids: for procurement_id in line.procurement_ids: - if procurement_id.purchase_id and procurement_id.purchase_id.id: + if procurement_id.purchase_id and \ + procurement_id.purchase_id.id: purchase_list.append(procurement_id.purchase_id.id) rec.po_count = len(list(set(purchase_list))) @@ -26,7 +24,7 @@ class RmaOrder(models.Model): po_list = [] for rma_line in self.rma_line_ids: if rma_line.purchase_order_line_id and \ - rma_line.purchase_order_line_id.id: + rma_line.purchase_order_line_id.id: po_list.append(rma_line.purchase_order_line_id.order_id.id) self.origin_po_count = len(list(set(po_list))) @@ -35,8 +33,8 @@ class RmaOrder(models.Model): copy=False, default=0) origin_po_count = fields.Integer(compute=_compute_origin_po_count, - string='# of Origin PO', copy=False, - default=0) + string='# of Origin PO', copy=False, + default=0) @api.multi def action_view_purchase_order(self): diff --git a/rma_purchase/models/rma_order_line.py b/rma_purchase/models/rma_order_line.py index f87c5eb3..8cd51869 100644 --- a/rma_purchase/models/rma_order_line.py +++ b/rma_purchase/models/rma_order_line.py @@ -3,7 +3,6 @@ # License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html) from openerp import api, fields, models from openerp.addons import decimal_precision as dp -from random import randint class RmaOrderLine(models.Model): diff --git a/rma_purchase/wizards/rma_add_purchase.py b/rma_purchase/wizards/rma_add_purchase.py index c31a99ec..e80357f9 100644 --- a/rma_purchase/wizards/rma_add_purchase.py +++ b/rma_purchase/wizards/rma_add_purchase.py @@ -3,10 +3,8 @@ # License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html) import time -from openerp import models, fields, exceptions, api, _ +from openerp import _, api, fields, models from openerp.exceptions import ValidationError -from openerp.tools import DEFAULT_SERVER_DATETIME_FORMAT as DT_FORMAT -import openerp.addons.decimal_precision as dp class RmaAddPurchase(models.TransientModel): @@ -31,18 +29,20 @@ class RmaAddPurchase(models.TransientModel): return res rma_id = fields.Many2one('rma.order', - string='RMA Order', - readonly=True, - ondelete='cascade') + string='RMA Order', + readonly=True, + ondelete='cascade') partner_id = fields.Many2one(comodel_name='res.partner', string='Partner', readonly=True) - purchase_id = fields.Many2one(comodel_name='purchase.order', string='Order') - purchase_line_ids = fields.Many2many('purchase.order.line', - 'rma_add_purchase_add_line_rel', - 'purchase_line_id', 'rma_add_purchase_id', - readonly=False, - string='Purcahse Order Lines') + purchase_id = fields.Many2one( + comodel_name='purchase.order', string='Order') + purchase_line_ids = fields.Many2many( + 'purchase.order.line', + 'rma_add_purchase_add_line_rel', + 'purchase_line_id', 'rma_add_purchase_id', + readonly=False, + string='Purcahse Order Lines') def _prepare_rma_line_from_po_line(self, line): operation = line.product_id.rma_operation_id and \ @@ -75,7 +75,7 @@ class RmaAddPurchase(models.TransientModel): {'in_route_id': operation.in_route_id.id or route, 'out_route_id': operation.out_route_id.id or route, 'receipt_policy': operation.receipt_policy, - 'location_id': operation.location_id.id or + 'location_id': operation.location_id.id or \ self.env.ref('stock.stock_location_stock').id, 'operation_id': operation.id, 'refund_policy': operation.refund_policy, diff --git a/rma_purchase/wizards/rma_make_picking.py b/rma_purchase/wizards/rma_make_picking.py index f80204c9..38e40f95 100644 --- a/rma_purchase/wizards/rma_make_picking.py +++ b/rma_purchase/wizards/rma_make_picking.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- # © 2017 Eficent Business and IT Consulting Services S.L. # License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html) -from openerp import models, fields, exceptions, api, _ +from openerp import _, api, fields, models class RmaMakePicking(models.TransientModel): From d106a49ce28b9c66d3a44618fd26ee60a7863534 Mon Sep 17 00:00:00 2001 From: aheficent Date: Wed, 16 Aug 2017 12:52:35 +0200 Subject: [PATCH 03/42] [IMP] default operation in product and product_categ for customer and supplier [IMP]Separate menus for customer and supplier operations * Add active field to rma operation * Added tests * Fix travis * Fix create supplier rma from customer rma --- rma_purchase/README.rst | 2 +- rma_purchase/__openerp__.py | 4 +-- rma_purchase/models/rma_order.py | 11 ++++---- rma_purchase/models/rma_order_line.py | 34 +++++++++++++----------- rma_purchase/wizards/rma_add_purchase.py | 18 ++++++------- rma_purchase/wizards/rma_make_picking.py | 2 +- 6 files changed, 37 insertions(+), 34 deletions(-) diff --git a/rma_purchase/README.rst b/rma_purchase/README.rst index 49fbc152..9c0f713e 100644 --- a/rma_purchase/README.rst +++ b/rma_purchase/README.rst @@ -2,7 +2,7 @@ :alt: License LGPL-3 RMA Purchase -=========== +============ Purchase as RMA source diff --git a/rma_purchase/__openerp__.py b/rma_purchase/__openerp__.py index 6d287e68..19292925 100644 --- a/rma_purchase/__openerp__.py +++ b/rma_purchase/__openerp__.py @@ -6,9 +6,7 @@ 'version': '9.0.1.0.0', 'category': 'RMA', 'summary': 'RMA from PO', - 'description': """ - RMA from PO -""", + 'license': 'LGPL-3', 'author': 'Eficent', 'website': 'http://www.github.com/OCA/rma', 'depends': ['rma_account', 'purchase'], diff --git a/rma_purchase/models/rma_order.py b/rma_purchase/models/rma_order.py index 54121cc0..d10086df 100644 --- a/rma_purchase/models/rma_order.py +++ b/rma_purchase/models/rma_order.py @@ -19,13 +19,14 @@ class RmaOrder(models.Model): purchase_list.append(procurement_id.purchase_id.id) rec.po_count = len(list(set(purchase_list))) - @api.one + @api.multi def _compute_origin_po_count(self): po_list = [] - for rma_line in self.rma_line_ids: - if rma_line.purchase_order_line_id and \ - rma_line.purchase_order_line_id.id: - po_list.append(rma_line.purchase_order_line_id.order_id.id) + for rec in self: + for rma_line in rec.rma_line_ids: + if rma_line.purchase_order_line_id and \ + rma_line.purchase_order_line_id.id: + po_list.append(rma_line.purchase_order_line_id.order_id.id) self.origin_po_count = len(list(set(po_list))) po_count = fields.Integer(compute=_compute_po_count, diff --git a/rma_purchase/models/rma_order_line.py b/rma_purchase/models/rma_order_line.py index 8cd51869..e2d124de 100644 --- a/rma_purchase/models/rma_order_line.py +++ b/rma_purchase/models/rma_order_line.py @@ -8,28 +8,32 @@ from openerp.addons import decimal_precision as dp class RmaOrderLine(models.Model): _inherit = "rma.order.line" - @api.one + @api.multi def _compute_purchase_count(self): - purchase_list = [] - for procurement_id in self.procurement_ids: - if procurement_id.purchase_id and procurement_id.purchase_id.id: - purchase_list.append(procurement_id.purchase_id.id) - self.purchase_count = len(list(set(purchase_list))) + for rec in self: + 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))) - @api.one + @api.multi @api.depends('procurement_ids.purchase_line_id') def _get_purchase_order_lines(self): - purchase_list = [] - for procurement_id in self.procurement_ids: - if procurement_id.purchase_line_id and \ - procurement_id.purchase_line_id.id: - purchase_list.append(procurement_id.purchase_line_id.id) - self.purchase_order_line_ids = [(6, 0, purchase_list)] + for rec in self: + purchase_list = [] + for procurement_id in rec.procurement_ids: + if procurement_id.purchase_line_id and \ + procurement_id.purchase_line_id.id: + purchase_list.append(procurement_id.purchase_line_id.id) + rec.purchase_order_line_ids = [(6, 0, purchase_list)] - @api.one + @api.multi @api.depends('procurement_ids.purchase_line_id') def _compute_qty_purchased(self): - self.qty_purchased = self._get_rma_purchased_qty() + for rec in self: + rec.qty_purchased = rec._get_rma_purchased_qty() purchase_count = fields.Integer(compute=_compute_purchase_count, string='# of Purchases', copy=False, diff --git a/rma_purchase/wizards/rma_add_purchase.py b/rma_purchase/wizards/rma_add_purchase.py index e80357f9..8ed0b436 100644 --- a/rma_purchase/wizards/rma_add_purchase.py +++ b/rma_purchase/wizards/rma_add_purchase.py @@ -2,8 +2,7 @@ # © 2017 Eficent Business and IT Consulting Services S.L. # License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html) -import time -from openerp import _, api, fields, models +from openerp import api, fields, models from openerp.exceptions import ValidationError @@ -45,11 +44,12 @@ class RmaAddPurchase(models.TransientModel): string='Purcahse Order Lines') def _prepare_rma_line_from_po_line(self, line): - operation = line.product_id.rma_operation_id and \ - line.product_id.rma_operation_id.id or False - if not operation: - operation = line.product_id.categ_id.rma_operation_id and \ - line.product_id.categ_id.rma_operation_id.id or False + if self.env.context.get('customer'): + operation = line.product_id.rma_customer_operation_id or \ + line.product_id.categ_id.rma_customer_operation_id + else: + operation = line.product_id.rma_supplier_operation_id or \ + line.product_id.categ_id.rma_supplier_operation_id data = { 'purchase_order_line_id': line.id, 'product_id': line.product_id.id, @@ -75,8 +75,8 @@ class RmaAddPurchase(models.TransientModel): {'in_route_id': operation.in_route_id.id or route, 'out_route_id': operation.out_route_id.id or route, 'receipt_policy': operation.receipt_policy, - 'location_id': operation.location_id.id or \ - self.env.ref('stock.stock_location_stock').id, + 'location_id': operation.location_id.id or + self.env.ref('stock.stock_location_stock').id, 'operation_id': operation.id, 'refund_policy': operation.refund_policy, 'delivery_policy': operation.delivery_policy diff --git a/rma_purchase/wizards/rma_make_picking.py b/rma_purchase/wizards/rma_make_picking.py index 38e40f95..be77fcbd 100644 --- a/rma_purchase/wizards/rma_make_picking.py +++ b/rma_purchase/wizards/rma_make_picking.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- # © 2017 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 import api, fields, models class RmaMakePicking(models.TransientModel): From b95bee0e6a686300ed5df42a4a93e4d3c1c9cc93 Mon Sep 17 00:00:00 2001 From: lreficent Date: Fri, 25 Aug 2017 17:03:25 +0200 Subject: [PATCH 04/42] [9.0][IMP] rma_purchase: * remove unneded copy and ondelete attributes. * simplify action_view methods. * fix rma line supplier view. * fix wizard. * extend README. * minor extra fixes. --- rma_purchase/README.rst | 16 +++-- rma_purchase/models/rma_order.py | 47 +++++--------- rma_purchase/models/rma_order_line.py | 22 +++---- rma_purchase/views/rma_order_line_view.xml | 56 ++++++++--------- rma_purchase/views/rma_order_view.xml | 58 +++++++++--------- rma_purchase/wizards/rma_add_purchase.py | 71 +++++++++++----------- 6 files changed, 129 insertions(+), 141 deletions(-) diff --git a/rma_purchase/README.rst b/rma_purchase/README.rst index 9c0f713e..5ae429f1 100644 --- a/rma_purchase/README.rst +++ b/rma_purchase/README.rst @@ -1,16 +1,25 @@ .. image:: https://img.shields.io/badge/licence-LGPL--3-blue.svg :alt: License LGPL-3 +============ RMA Purchase ============ -Purchase as RMA source +This modules extend the RMA functionality allowing to use Purchase Orders as +a RMA source. Usage ===== -select add_purchase_id to fill rma from RMA purchase +To add lines to a RMA from PO act as follows: +#. Go to a supplier RMA. +#. Fill the *Supplier* field. +#. Click on *Add From Purchase Order*. +#. Select the Purchase Order. +#. Click on *Add an item* and select the lines you would like to add to the + RMA. +#. Hit *Confirm*. Bug Tracker =========== @@ -20,7 +29,6 @@ Bugs are tracked on `GitHub Issues check there if your issue has already been reported. If you spotted it first, help us smashing it by providing a detailed and welcomed feedback. - Credits ======= @@ -29,7 +37,7 @@ Contributors * Jordi Ballester Alomar * Aaron Henriquez - +* Lois Rilo Maintainer ---------- diff --git a/rma_purchase/models/rma_order.py b/rma_purchase/models/rma_order.py index d10086df..7d762722 100644 --- a/rma_purchase/models/rma_order.py +++ b/rma_purchase/models/rma_order.py @@ -11,51 +11,34 @@ class RmaOrder(models.Model): @api.multi def _compute_po_count(self): for rec in self: - purchase_list = [] - for line in rec.rma_line_ids: - for procurement_id in line.procurement_ids: - if procurement_id.purchase_id and \ - procurement_id.purchase_id.id: - purchase_list.append(procurement_id.purchase_id.id) - rec.po_count = len(list(set(purchase_list))) + purchases = rec.mapped('rma_line_ids.procurement_ids.purchase_id') + rec.po_count = len(purchases) @api.multi def _compute_origin_po_count(self): - po_list = [] - for rec in self: - for rma_line in rec.rma_line_ids: - if rma_line.purchase_order_line_id and \ - rma_line.purchase_order_line_id.id: - po_list.append(rma_line.purchase_order_line_id.order_id.id) - self.origin_po_count = len(list(set(po_list))) + for rma in self: + purchases = rma.mapped( + 'rma_line_ids.purchase_order_line_id.order_id') + rma.origin_po_count = len(purchases) - po_count = fields.Integer(compute=_compute_po_count, - string='# of PO', - copy=False, default=0) - - origin_po_count = fields.Integer(compute=_compute_origin_po_count, - string='# of Origin PO', copy=False, - default=0) + po_count = fields.Integer( + compute='_compute_po_count', string='# of PO') + origin_po_count = fields.Integer( + compute='_compute_origin_po_count', string='# of Origin PO') @api.multi def action_view_purchase_order(self): action = self.env.ref('purchase.purchase_rfq') result = action.read()[0] - order_ids = [] - for line in self.rma_line_ids: - for procurement_id in line.procurement_ids: - order_ids.append(procurement_id.purchase_id.id) - result['domain'] = [('id', 'in', order_ids)] + po_ids = self.mapped('rma_line_ids.procurement_ids.purchase_id').ids + result['domain'] = [('id', 'in', po_ids)] return result @api.multi def action_view_origin_purchase_order(self): action = self.env.ref('purchase.purchase_rfq') result = action.read()[0] - order_ids = [] - for rma_line in self.rma_line_ids: - if rma_line.purchase_order_line_id and \ - rma_line.purchase_order_line_id.id: - order_ids.append(rma_line.purchase_order_line_id.order_id.id) - result['domain'] = [('id', 'in', order_ids)] + po_ids = self.mapped( + 'rma_line_ids.purchase_order_line_id.order_id').ids + result['domain'] = [('id', 'in', po_ids)] return result diff --git a/rma_purchase/models/rma_order_line.py b/rma_purchase/models/rma_order_line.py index e2d124de..dde77b39 100644 --- a/rma_purchase/models/rma_order_line.py +++ b/rma_purchase/models/rma_order_line.py @@ -35,22 +35,20 @@ class RmaOrderLine(models.Model): for rec in self: rec.qty_purchased = rec._get_rma_purchased_qty() - purchase_count = fields.Integer(compute=_compute_purchase_count, - string='# of Purchases', copy=False, - default=0) - purchase_order_line_id = fields.Many2one('purchase.order.line', - string='Origin Purchase Line', - ondelete='restrict') + purchase_count = fields.Integer( + compute='_compute_purchase_count', string='# of Purchases') + purchase_order_line_id = fields.Many2one( + comodel_name='purchase.order.line', string='Origin Purchase Line', + ondelete='restrict') purchase_order_line_ids = fields.Many2many( - 'purchase.order.line', 'purchase_line_rma_line_rel', - 'rma_order_line_id', 'purchase_order_line_id', - string='Purchase Order Lines', compute=_get_purchase_order_lines) - + comodel_name='purchase.order.line', + relation='purchase_line_rma_line_rel', + column1='rma_order_line_id', column2='purchase_order_line_id', + string='Purchase Order Lines', compute='_get_purchase_order_lines') qty_purchased = fields.Float( string='Qty Purchased', copy=False, digits=dp.get_precision('Product Unit of Measure'), - readonly=True, compute=_compute_qty_purchased, - store=True) + readonly=True, compute='_compute_qty_purchased', store=True) @api.multi def action_view_purchase_order(self): diff --git a/rma_purchase/views/rma_order_line_view.xml b/rma_purchase/views/rma_order_line_view.xml index e57b4939..690a5bc6 100644 --- a/rma_purchase/views/rma_order_line_view.xml +++ b/rma_purchase/views/rma_order_line_view.xml @@ -1,33 +1,31 @@ - - + - - rma.order.line.supplier.form - rma.order.line - - -
- -
- - - - + + rma.order.line.supplier.form + rma.order.line + + +
+ +
+ + + - - - - - -
-
+
+ + + + + +
+
-
-
+ diff --git a/rma_purchase/views/rma_order_view.xml b/rma_purchase/views/rma_order_view.xml index 1875c5e8..685a4029 100644 --- a/rma_purchase/views/rma_order_view.xml +++ b/rma_purchase/views/rma_order_view.xml @@ -1,33 +1,31 @@ - - + - - rma.order.supplier.form - rma.order - - -
- -
-
- -
-
-
+ + rma.order.supplier.form + rma.order + + +
+ +
+
+ +
+
+
-
-
+ diff --git a/rma_purchase/wizards/rma_add_purchase.py b/rma_purchase/wizards/rma_add_purchase.py index 8ed0b436..b03eaefd 100644 --- a/rma_purchase/wizards/rma_add_purchase.py +++ b/rma_purchase/wizards/rma_add_purchase.py @@ -27,21 +27,17 @@ class RmaAddPurchase(models.TransientModel): res['purchase_line_ids'] = False return res - rma_id = fields.Many2one('rma.order', - string='RMA Order', - readonly=True, - ondelete='cascade') - - partner_id = fields.Many2one(comodel_name='res.partner', string='Partner', - readonly=True) + rma_id = fields.Many2one( + comodel_name='rma.order', string='RMA Order', readonly=True) + partner_id = fields.Many2one( + comodel_name='res.partner', string='Partner', readonly=True) purchase_id = fields.Many2one( comodel_name='purchase.order', string='Order') purchase_line_ids = fields.Many2many( - 'purchase.order.line', - 'rma_add_purchase_add_line_rel', - 'purchase_line_id', 'rma_add_purchase_id', - readonly=False, - string='Purcahse Order Lines') + comodel_name='purchase.order.line', + relation='rma_add_purchase_add_line_rel', + column1='rma_add_purchase_id', column2='purchase_line_id', + readonly=False, string='Purchase Order Lines') def _prepare_rma_line_from_po_line(self, line): if self.env.context.get('customer'): @@ -50,17 +46,6 @@ class RmaAddPurchase(models.TransientModel): else: operation = line.product_id.rma_supplier_operation_id or \ line.product_id.categ_id.rma_supplier_operation_id - data = { - 'purchase_order_line_id': line.id, - 'product_id': line.product_id.id, - 'origin': line.order_id.name, - 'uom_id': line.product_uom.id, - 'operation_id': operation, - 'product_qty': line.product_qty, - 'price_unit': line.currency_id.compute( - line.price_unit, line.currency_id, round=False), - 'rma_id': self.rma_id.id - } if not operation: operation = self.env['rma.operation'].search( [('type', '=', self.rma_id.type)], limit=1) @@ -70,17 +55,35 @@ class RmaAddPurchase(models.TransientModel): route = self.env['stock.location.route'].search( [('rma_selectable', '=', True)], limit=1) if not route: - raise ValidationError("Please define an rma route") - data.update( - {'in_route_id': operation.in_route_id.id or route, - 'out_route_id': operation.out_route_id.id or route, - 'receipt_policy': operation.receipt_policy, - 'location_id': operation.location_id.id or - self.env.ref('stock.stock_location_stock').id, - 'operation_id': operation.id, - 'refund_policy': operation.refund_policy, - 'delivery_policy': operation.delivery_policy - }) + raise ValidationError("Please define a rma route.") + if not operation.in_warehouse_id or not operation.out_warehouse_id: + warehouse = self.env['stock.warehouse'].search( + [('company_id', '=', self.rma_id.company_id.id), + ('lot_rma_id', '!=', False)], limit=1) + if not warehouse: + raise ValidationError("Please define a warehouse with a " + "default rma location.") + data = { + 'purchase_order_line_id': line.id, + 'product_id': line.product_id.id, + 'origin': line.order_id.name, + 'uom_id': line.product_uom.id, + 'operation_id': operation.id, + 'product_qty': line.product_qty, + 'price_unit': line.currency_id.compute( + line.price_unit, line.currency_id, round=False), + 'rma_id': self.rma_id.id, + 'in_route_id': operation.in_route_id.id or route, + 'out_route_id': operation.out_route_id.id or route, + 'receipt_policy': operation.receipt_policy, + 'location_id': (operation.location_id.id or + operation.in_warehouse_id.lot_rma_id.id or + warehouse.lot_rma_id.id), + 'refund_policy': operation.refund_policy, + 'delivery_policy': operation.delivery_policy, + 'in_warehouse_id': operation.in_warehouse_id.id or warehouse.id, + 'out_warehouse_id': operation.out_warehouse_id.id or warehouse.id, + } return data @api.model From c0596b41e2d2a1406194689ceac2501f92a0830d Mon Sep 17 00:00:00 2001 From: lreficent Date: Wed, 18 Oct 2017 17:52:18 +0200 Subject: [PATCH 05/42] [9.0][REW] rma_purchase: adapt --- rma_purchase/models/rma_order_line.py | 87 ++++++++++++++++++++-- rma_purchase/views/rma_order_line_view.xml | 5 ++ rma_purchase/wizards/rma_add_purchase.xml | 7 +- 3 files changed, 89 insertions(+), 10 deletions(-) diff --git a/rma_purchase/models/rma_order_line.py b/rma_purchase/models/rma_order_line.py index dde77b39..5403d012 100644 --- a/rma_purchase/models/rma_order_line.py +++ b/rma_purchase/models/rma_order_line.py @@ -1,7 +1,8 @@ # -*- coding: utf-8 -*- # © 2017 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 import api, fields, models, _ +from openerp.exceptions import ValidationError from openerp.addons import decimal_precision as dp @@ -36,19 +37,93 @@ class RmaOrderLine(models.Model): rec.qty_purchased = rec._get_rma_purchased_qty() purchase_count = fields.Integer( - compute='_compute_purchase_count', string='# of Purchases') + compute='_compute_purchase_count', string='# of Purchases', + ) purchase_order_line_id = fields.Many2one( - comodel_name='purchase.order.line', string='Origin Purchase Line', - ondelete='restrict') + comodel_name='purchase.order.line', string='Originating Purchase Line', + ondelete='restrict', + readonly=True, states={'draft': [('readonly', False)]}, + ) purchase_order_line_ids = fields.Many2many( comodel_name='purchase.order.line', relation='purchase_line_rma_line_rel', column1='rma_order_line_id', column2='purchase_order_line_id', - string='Purchase Order Lines', compute='_get_purchase_order_lines') + string='Purchase Order Lines', compute='_get_purchase_order_lines', + ) qty_purchased = fields.Float( string='Qty Purchased', copy=False, digits=dp.get_precision('Product Unit of Measure'), - readonly=True, compute='_compute_qty_purchased', store=True) + readonly=True, compute='_compute_qty_purchased', store=True, + ) + + @api.multi + def _prepare_rma_line_from_po_line(self, line): + self.ensure_one() + if not self.type: + self.type = self._get_default_type() + if self.type == 'customer': + operation = line.product_id.rma_customer_operation_id or \ + line.product_id.categ_id.rma_customer_operation_id + else: + operation = line.product_id.rma_supplier_operation_id or \ + line.product_id.categ_id.rma_supplier_operation_id + if not operation: + operation = self.env['rma.operation'].search( + [('type', '=', self.type)], limit=1) + if not operation: + raise ValidationError(_("Please define an operation first")) + + if not operation.in_route_id or not operation.out_route_id: + route = self.env['stock.location.route'].search( + [('rma_selectable', '=', True)], limit=1) + if not route: + raise ValidationError(_("Please define a rma route.")) + + if not operation.in_warehouse_id or not operation.out_warehouse_id: + warehouse = self.env['stock.warehouse'].search( + [('company_id', '=', self.company_id.id), + ('lot_rma_id', '!=', False)], limit=1) + if not warehouse: + raise ValidationError(_( + "Please define a warehouse with a default rma location.")) + + data = { + 'product_id': line.product_id.id, + 'origin': line.order_id.name, + 'uom_id': line.product_uom.id, + 'operation_id': operation.id, + 'product_qty': line.product_qty, + 'price_unit': line.currency_id.compute( + line.price_unit, line.currency_id, round=False), + 'in_route_id': operation.in_route_id.id or route, + 'out_route_id': operation.out_route_id.id or route, + 'receipt_policy': operation.receipt_policy, + 'location_id': (operation.location_id.id or + operation.in_warehouse_id.lot_rma_id.id or + warehouse.lot_rma_id.id), + 'refund_policy': operation.refund_policy, + 'delivery_policy': operation.delivery_policy, + 'in_warehouse_id': operation.in_warehouse_id.id or warehouse.id, + 'out_warehouse_id': operation.out_warehouse_id.id or warehouse.id, + } + return data + + @api.onchange('purchase_order_line_id') + def _onchange_purchase_order_line_id(self): + if not self.purchase_order_line_id: + return + data = self._prepare_rma_line_from_po_line( + self.purchase_order_line_id) + self.update(data) + self._remove_other_data_origin('purchase_order_line_id') + + @api.multi + def _remove_other_data_origin(self, exception): + res = super(RmaOrderLine, self)._remove_other_data_origin(exception) + if not exception == 'purchase_order_line_id': + self.purchase_order_line_id = False + return res + @api.multi def action_view_purchase_order(self): diff --git a/rma_purchase/views/rma_order_line_view.xml b/rma_purchase/views/rma_order_line_view.xml index 690a5bc6..a33da379 100644 --- a/rma_purchase/views/rma_order_line_view.xml +++ b/rma_purchase/views/rma_order_line_view.xml @@ -15,6 +15,11 @@ string="Purchase Orders"/> + + + diff --git a/rma_purchase/wizards/rma_add_purchase.xml b/rma_purchase/wizards/rma_add_purchase.xml index f131f7e6..ee6c4a3b 100644 --- a/rma_purchase/wizards/rma_add_purchase.xml +++ b/rma_purchase/wizards/rma_add_purchase.xml @@ -64,12 +64,11 @@ rma.order - + type="action"/> + From 14a6b5b7e2a5440ef253f203e2a4a7b295408e4e Mon Sep 17 00:00:00 2001 From: lreficent Date: Thu, 19 Oct 2017 10:10:19 +0200 Subject: [PATCH 06/42] [9.0][IMP] rma: add constrains --- rma_purchase/models/rma_order_line.py | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/rma_purchase/models/rma_order_line.py b/rma_purchase/models/rma_order_line.py index 5403d012..f9aeba0e 100644 --- a/rma_purchase/models/rma_order_line.py +++ b/rma_purchase/models/rma_order_line.py @@ -117,6 +117,17 @@ class RmaOrderLine(models.Model): self.update(data) self._remove_other_data_origin('purchase_order_line_id') + @api.multi + @api.constrains('purchase_order_line_id', 'partner_id') + def _check_purchase_partner(self): + for rec in self: + if (rec.purchase_order_line_id and + rec.purchase_order_line_id.order_id.partner_id != + rec.partner_id): + raise ValidationError(_( + "RMA customer and originating purchase line customer " + "doesn't match.")) + @api.multi def _remove_other_data_origin(self, exception): res = super(RmaOrderLine, self)._remove_other_data_origin(exception) From 08f767986a5c2483a9a4538506dcd0fd7db0b209 Mon Sep 17 00:00:00 2001 From: lreficent Date: Thu, 19 Oct 2017 11:29:08 +0200 Subject: [PATCH 07/42] [9.0][FIX] wizards need to specify partner. --- rma_purchase/wizards/rma_add_purchase.py | 1 + 1 file changed, 1 insertion(+) diff --git a/rma_purchase/wizards/rma_add_purchase.py b/rma_purchase/wizards/rma_add_purchase.py index b03eaefd..ee0ddc5a 100644 --- a/rma_purchase/wizards/rma_add_purchase.py +++ b/rma_purchase/wizards/rma_add_purchase.py @@ -64,6 +64,7 @@ class RmaAddPurchase(models.TransientModel): raise ValidationError("Please define a warehouse with a " "default rma location.") data = { + 'partner_id': self.partner_id.id, 'purchase_order_line_id': line.id, 'product_id': line.product_id.id, 'origin': line.order_id.name, From 58e0b6d931bc3cf5603a517133d8d0ca7bc61c25 Mon Sep 17 00:00:00 2001 From: lreficent Date: Wed, 8 Nov 2017 16:12:14 +0100 Subject: [PATCH 08/42] [9.0][IMP] rma_purchase: allow to search by order reference --- rma_purchase/models/__init__.py | 3 ++- rma_purchase/models/purchase_order_line.py | 28 ++++++++++++++++++++++ 2 files changed, 30 insertions(+), 1 deletion(-) create mode 100644 rma_purchase/models/purchase_order_line.py diff --git a/rma_purchase/models/__init__.py b/rma_purchase/models/__init__.py index a3a08e5e..5c53c7a9 100644 --- a/rma_purchase/models/__init__.py +++ b/rma_purchase/models/__init__.py @@ -1,5 +1,6 @@ # -*- coding: utf-8 -*- -# © 2017 Eficent Business and IT Consulting Services S.L. # License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html) + from . import rma_order from . import rma_order_line +from . import purchase_order_line diff --git a/rma_purchase/models/purchase_order_line.py b/rma_purchase/models/purchase_order_line.py new file mode 100644 index 00000000..03f593ed --- /dev/null +++ b/rma_purchase/models/purchase_order_line.py @@ -0,0 +1,28 @@ +# -*- coding: utf-8 -*- +# Copyright 2017 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 PurchaseOrderLine(models.Model): + _inherit = "purchase.order.line" + + @api.model + def name_search(self, name='', args=None, operator='ilike', limit=100): + """Allows to search by PO reference.""" + if not args: + args = [] + args += ['|', + (self._rec_name, operator, name), + ('order_id.name', operator, name)] + return super(PurchaseOrderLine, self).name_search( + name=name, args=args, operator=operator, limit=limit) + + @api.model + def _name_search(self, name='', args=None, operator='ilike', + limit=100, name_get_uid=None): + """Typed text is cleared here for better extensibility.""" + return super(PurchaseOrderLine, self)._name_search( + name='', args=args, operator=operator, limit=limit, + name_get_uid=name_get_uid) From 4502e6d18d53b3c3774b6c630d7168bde5e15056 Mon Sep 17 00:00:00 2001 From: lreficent Date: Mon, 13 Nov 2017 14:05:26 +0100 Subject: [PATCH 09/42] [FIX] allow child partners too --- rma_purchase/views/rma_order_line_view.xml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/rma_purchase/views/rma_order_line_view.xml b/rma_purchase/views/rma_order_line_view.xml index a33da379..7ed0fc57 100644 --- a/rma_purchase/views/rma_order_line_view.xml +++ b/rma_purchase/views/rma_order_line_view.xml @@ -18,7 +18,9 @@ + domain="['|', + ('order_id.partner_id', '=', partner_id), + ('order_id.partner_id', 'child_of', partner_id)]"/> From 72cd3c533ef920018ae91732bccf512e8cf09594 Mon Sep 17 00:00:00 2001 From: lreficent Date: Mon, 13 Nov 2017 15:23:33 +0100 Subject: [PATCH 10/42] [9.0][IMP] rma: add link to source SO and PO --- rma_purchase/models/rma_order_line.py | 5 +++++ rma_purchase/views/rma_order_line_view.xml | 4 ++++ 2 files changed, 9 insertions(+) diff --git a/rma_purchase/models/rma_order_line.py b/rma_purchase/models/rma_order_line.py index f9aeba0e..06d6d40c 100644 --- a/rma_purchase/models/rma_order_line.py +++ b/rma_purchase/models/rma_order_line.py @@ -44,6 +44,11 @@ class RmaOrderLine(models.Model): ondelete='restrict', readonly=True, states={'draft': [('readonly', False)]}, ) + purchase_id = fields.Many2one( + string="Source Purchase Order", + related='purchase_order_line_id.order_id', + readonly=True, + ) purchase_order_line_ids = fields.Many2many( comodel_name='purchase.order.line', relation='purchase_line_rma_line_rel', diff --git a/rma_purchase/views/rma_order_line_view.xml b/rma_purchase/views/rma_order_line_view.xml index 7ed0fc57..81d45512 100644 --- a/rma_purchase/views/rma_order_line_view.xml +++ b/rma_purchase/views/rma_order_line_view.xml @@ -27,6 +27,10 @@ + + + From 50dfc856cf4c6b0397fab57679899b7a68974c77 Mon Sep 17 00:00:00 2001 From: aheficent Date: Wed, 20 Dec 2017 13:48:26 +0100 Subject: [PATCH 11/42] [MIG]rma_purchase v10 --- rma_purchase/{__openerp__.py => __manifest__.py} | 0 rma_purchase/models/purchase_order_line.py | 2 +- rma_purchase/models/rma_order.py | 2 +- rma_purchase/models/rma_order_line.py | 6 +++--- rma_purchase/wizards/rma_add_purchase.py | 4 ++-- rma_purchase/wizards/rma_make_picking.py | 2 +- 6 files changed, 8 insertions(+), 8 deletions(-) rename rma_purchase/{__openerp__.py => __manifest__.py} (100%) diff --git a/rma_purchase/__openerp__.py b/rma_purchase/__manifest__.py similarity index 100% rename from rma_purchase/__openerp__.py rename to rma_purchase/__manifest__.py diff --git a/rma_purchase/models/purchase_order_line.py b/rma_purchase/models/purchase_order_line.py index 03f593ed..8f429635 100644 --- a/rma_purchase/models/purchase_order_line.py +++ b/rma_purchase/models/purchase_order_line.py @@ -2,7 +2,7 @@ # Copyright 2017 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 odoo import api, fields, models class PurchaseOrderLine(models.Model): diff --git a/rma_purchase/models/rma_order.py b/rma_purchase/models/rma_order.py index 7d762722..fcf07403 100644 --- a/rma_purchase/models/rma_order.py +++ b/rma_purchase/models/rma_order.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- # © 2017 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 odoo import api, fields, models class RmaOrder(models.Model): diff --git a/rma_purchase/models/rma_order_line.py b/rma_purchase/models/rma_order_line.py index 06d6d40c..4ba3680d 100644 --- a/rma_purchase/models/rma_order_line.py +++ b/rma_purchase/models/rma_order_line.py @@ -1,9 +1,9 @@ # -*- coding: utf-8 -*- # © 2017 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 -from openerp.addons import decimal_precision as dp +from odoo import api, fields, models, _ +from odoo.exceptions import ValidationError +from odoo.addons import decimal_precision as dp class RmaOrderLine(models.Model): diff --git a/rma_purchase/wizards/rma_add_purchase.py b/rma_purchase/wizards/rma_add_purchase.py index ee0ddc5a..81fe340b 100644 --- a/rma_purchase/wizards/rma_add_purchase.py +++ b/rma_purchase/wizards/rma_add_purchase.py @@ -2,8 +2,8 @@ # © 2017 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 +from odoo import api, fields, models +from odoo.exceptions import ValidationError class RmaAddPurchase(models.TransientModel): diff --git a/rma_purchase/wizards/rma_make_picking.py b/rma_purchase/wizards/rma_make_picking.py index be77fcbd..76a8cbfc 100644 --- a/rma_purchase/wizards/rma_make_picking.py +++ b/rma_purchase/wizards/rma_make_picking.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- # © 2017 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 odoo import api, fields, models class RmaMakePicking(models.TransientModel): From 5a21c51677199fbb9bb555264ab40b4d73bc46ab Mon Sep 17 00:00:00 2001 From: Nikul Chaudhary Date: Fri, 10 Nov 2017 12:48:55 +0530 Subject: [PATCH 12/42] [IMP] Improved Unit Test Case and Fixed Travis --- rma_purchase/__manifest__.py | 2 +- rma_purchase/models/rma_order_line.py | 5 +- rma_purchase/tests/__init__.py | 6 + rma_purchase/tests/test_rma.py | 440 ++++++++++++++++++++++++ rma_purchase/tests/test_rma_dropship.py | 96 ++++++ rma_purchase/tests/test_supplier_rma.py | 156 +++++++++ 6 files changed, 701 insertions(+), 4 deletions(-) create mode 100644 rma_purchase/tests/__init__.py create mode 100644 rma_purchase/tests/test_rma.py create mode 100644 rma_purchase/tests/test_rma_dropship.py create mode 100644 rma_purchase/tests/test_supplier_rma.py diff --git a/rma_purchase/__manifest__.py b/rma_purchase/__manifest__.py index 19292925..f91228b4 100644 --- a/rma_purchase/__manifest__.py +++ b/rma_purchase/__manifest__.py @@ -7,7 +7,7 @@ 'category': 'RMA', 'summary': 'RMA from PO', 'license': 'LGPL-3', - 'author': 'Eficent', + 'author': 'Eficent, Odoo Community Association (OCA)', 'website': 'http://www.github.com/OCA/rma', 'depends': ['rma_account', 'purchase'], 'data': ['views/rma_order_view.xml', diff --git a/rma_purchase/models/rma_order_line.py b/rma_purchase/models/rma_order_line.py index 4ba3680d..b2cf3e50 100644 --- a/rma_purchase/models/rma_order_line.py +++ b/rma_purchase/models/rma_order_line.py @@ -21,7 +21,7 @@ class RmaOrderLine(models.Model): @api.multi @api.depends('procurement_ids.purchase_line_id') - def _get_purchase_order_lines(self): + def _compute_purchase_order_lines(self): for rec in self: purchase_list = [] for procurement_id in rec.procurement_ids: @@ -53,7 +53,7 @@ class RmaOrderLine(models.Model): comodel_name='purchase.order.line', relation='purchase_line_rma_line_rel', column1='rma_order_line_id', column2='purchase_order_line_id', - string='Purchase Order Lines', compute='_get_purchase_order_lines', + string='Purchase Order Lines', compute='_compute_purchase_order_lines', ) qty_purchased = fields.Float( string='Qty Purchased', copy=False, @@ -140,7 +140,6 @@ class RmaOrderLine(models.Model): self.purchase_order_line_id = False return res - @api.multi def action_view_purchase_order(self): action = self.env.ref('purchase.purchase_rfq') diff --git a/rma_purchase/tests/__init__.py b/rma_purchase/tests/__init__.py new file mode 100644 index 00000000..dfa77946 --- /dev/null +++ b/rma_purchase/tests/__init__.py @@ -0,0 +1,6 @@ +# -*- coding: utf-8 -*- +# © 2017 Eficent Business and IT Consulting Services S.L. +# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html) +from . import test_rma +from . import test_supplier_rma +from . import test_rma_dropship diff --git a/rma_purchase/tests/test_rma.py b/rma_purchase/tests/test_rma.py new file mode 100644 index 00000000..4a435c73 --- /dev/null +++ b/rma_purchase/tests/test_rma.py @@ -0,0 +1,440 @@ +# -*- coding: utf-8 -*- +# © 2017 Eficent Business and IT Consulting Services S.L. +# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html) + +from openerp.tests import common +from openerp import fields + + +class TestRma(common.TransactionCase): + + """ Test the routes and the quantities """ + + def setUp(self): + super(TestRma, self).setUp() + + self.rma_make_picking = self.env['rma_make_picking.wizard'] + self.make_supplier_rma = self.env["rma.order.line.make.supplier.rma"] + self.rma_add_stock_move = self.env['rma_add_stock_move'] + self.stockpicking = self.env['stock.picking'] + self.rma = self.env['rma.order'] + self.rma_line = self.env['rma.order.line'] + self.rma_op = self.env['rma.operation'] + self.rma_cust_replace_op_id = self.env.ref( + 'rma.rma_operation_customer_replace') + self.rma_sup_replace_op_id = self.env.ref( + 'rma.rma_operation_supplier_replace') + self.product_id = self.env.ref('product.product_product_4') + self.product_id.product_tmpl_id.categ_id.\ + property_stock_account_input_categ_id =\ + self.env.ref('account.data_account_type_receivable').id + self.product_id.product_tmpl_id.categ_id.\ + property_stock_account_output_categ_id =\ + self.env.ref('account.data_account_type_expenses').id + self.product_1 = self.env.ref('product.product_product_25') + self.product_2 = self.env.ref('product.product_product_30') + self.product_3 = self.env.ref('product.product_product_33') + self.uom_unit = self.env.ref('product.product_uom_unit') + # assign an operation + self.product_1.write( + {'rma_customer_operation_id': self.rma_cust_replace_op_id.id, + 'rma_supplier_operation_id': self.rma_sup_replace_op_id.id}) + self.product_2.write( + {'rma_customer_operation_id': self.rma_cust_replace_op_id.id, + 'rma_supplier_operation_id': self.rma_sup_replace_op_id.id}) + self.product_3.write( + {'rma_customer_operation_id': self.rma_cust_replace_op_id.id, + 'rma_supplier_operation_id': self.rma_sup_replace_op_id.id}) + self.partner_id = self.env.ref('base.res_partner_12') + self.stock_location = self.env.ref('stock.stock_location_stock') + self.stock_rma_location = self.env.ref('rma.location_rma') + self.customer_location = self.env.ref( + 'stock.stock_location_customers') + self.supplier_location = self.env.ref( + 'stock.stock_location_suppliers') + self.product_uom_id = self.env.ref('product.product_uom_unit') + products2move = [(self.product_1, 3), (self.product_2, 5), + (self.product_3, 2)] + self.rma_customer_id = self._create_rma_from_move( + products2move, 'customer', self.env.ref('base.res_partner_2'), + dropship=False) + + def _create_picking(self, partner): + return self.stockpicking.create({ + 'partner_id': partner.id, + 'picking_type_id': self.env.ref('stock.picking_type_in').id, + 'location_id': self.stock_location.id, + 'location_dest_id': self.supplier_location.id + }) + + def _create_rma_from_move(self, products2move, type, partner, dropship, + supplier_address_id=None): + picking_in = self._create_picking(partner) + + moves = [] + if type == 'customer': + for item in products2move: + move_values = self._prepare_move( + item[0], item[1], self.stock_location, + self.customer_location, picking_in) + moves.append(self.env['stock.move'].create(move_values)) + else: + for item in products2move: + move_values = self._prepare_move( + item[0], item[1], self.supplier_location, + self.stock_rma_location, picking_in) + moves.append(self.env['stock.move'].create(move_values)) + # Create the RMA from the stock_move + rma_id = self.rma.create( + { + 'reference': '0001', + 'type': type, + 'partner_id': partner.id, + 'company_id': self.env.ref('base.main_company').id + }) + rma_id._compute_invoice_refund_count() + rma_id._compute_invoice_count() + + data = {'add_invoice_id': self._create_invoice().id} + new_line = self.rma.new(data) + new_line.on_change_invoice() + + rma_id.action_view_invoice_refund() + rma_id.action_view_invoice() + + for move in moves: + if type == 'customer': + wizard = self.rma_add_stock_move.with_context( + {'stock_move_id': move.id, 'customer': True, + 'active_ids': rma_id.id, + 'active_model': 'rma.order', + } + ).create({}) + data = wizard._prepare_rma_line_from_stock_move(move) + else: + wizard = self.rma_add_stock_move.with_context( + {'stock_move_id': move.id, 'supplier': True, + 'active_ids': rma_id.id, + 'active_model': 'rma.order', + } + ).create({}) + data = wizard._prepare_rma_line_from_stock_move(move) + if dropship: + data.update(customer_to_supplier=dropship, + supplier_address_id=supplier_address_id.id) + self.line = self.rma_line.create(data) + # approve the RMA Line + self.rma_line.action_rma_to_approve() + + self.line.action_rma_approve() + self.line.action_view_invoice() + self.line.action_view_refunds() + + # approve the RMA +# rma_id.action_rma_to_approve() +# rma_id.action_rma_approve() + return rma_id + + def _prepare_move(self, product, qty, src, dest, picking_in): + res = { + 'partner_id': self.partner_id.id, + 'product_id': product.id, + 'name': product.partner_ref, + 'state': 'confirmed', + 'product_uom': self.product_uom_id.id or product.uom_id.id, + 'product_uom_qty': qty, + 'origin': 'Test RMA', + 'location_id': src.id, + 'location_dest_id': dest.id, + 'picking_id': picking_in.id + } + return res + + def test_rma_refund(self): + + self.rma_refund_item = self.env['rma.refund.item'] + self.rma_refund = self.env['rma.refund'] + + self.product_id.income =\ + self.env.ref('account.data_account_type_receivable').id + self.product_id.expense =\ + self.env.ref('account.data_account_type_expenses').id + + for line in self.rma_customer_id.rma_line_ids: + line.refund_policy = 'ordered' + + refund = self.rma_refund.with_context({ + 'active_ids': self.rma_customer_id.rma_line_ids.ids, + 'active_model': 'rma.order.line', + 'active_id': 1 + }).create({'description': 'Test Reason', + 'date_invoice': fields.datetime.now() + }) + self.rma_refund_item.create({ + 'line_id': self.rma_customer_id.rma_line_ids[0].id, + 'rma_id': self.rma_customer_id.id, + 'product_id': self.product_id.id, + 'name': 'Test RMA Refund', + 'product_qty': self.rma_customer_id.rma_line_ids[0].product_qty, + 'wiz_id': refund.id + }) + refund.invoice_refund() + + def test_rma_add_invoice_wizard(self): + + wizard = self.env['rma_add_invoice'].with_context({ + 'active_ids': self.rma_customer_id.ids, + 'active_model': 'rma.order', + 'active_id': self.rma_customer_id.id + }).create({'partner_id': self.partner_id.id, + 'rma_id': self.rma_customer_id.id, + 'invoice_line_ids': + [(6, 0, [self._create_invoice().invoice_line_ids.id])], + }) + wizard.add_lines() + + def _create_invoice(self): + self.Account = self.env['account.account'] + self.AccountInvoice = self.env['account.invoice'] + self.AccountInvoiceLine = self.env['account.invoice.line'] + + self.account_receivable =\ + self.env.ref('account.data_account_type_receivable') + self.account_expenses =\ + self.env.ref('account.data_account_type_expenses') + invoice_account = self.Account.\ + search([('user_type_id', '=', self.account_receivable.id)], limit=1 + ).id + invoice_line_account = self.Account.\ + search([('user_type_id', '=', self.account_expenses.id)], limit=1 + ).id + + invoice = self.AccountInvoice.create({ + 'partner_id': self.partner_id.id, + 'account_id': invoice_account, + 'type': 'in_invoice', + }) + + invoice_line = self.AccountInvoiceLine.create({ + 'product_id': self.product_1.id, + 'quantity': 1.0, + 'price_unit': 100.0, + 'invoice_id': invoice.id, + 'uom_id': 1, + 'name': 'product that cost 100', + 'account_id': invoice_line_account, + }) + invoice._compute_rma_count() + invoice_line._compute_rma_count() + invoice.action_view_rma_customer() + invoice.action_view_rma_supplier() + return invoice + + def test_rma_make_picking(self): + + wizard = self.rma_make_picking.with_context({ + 'active_ids': self.rma_customer_id.rma_line_ids.ids, + 'active_model': 'rma.order.line', + 'picking_type': 'incoming', + 'active_id': 1 + }).create({}) + + wizard.action_create_picking() + data = {'purchase_order_line_id': + self._create_purchase_order().order_line.id} + new_line = self.rma_line.new(data) + new_line._onchange_purchase_order_line_id() + + self.rma_customer_id._compute_po_count() + self.rma_customer_id._compute_origin_po_count() + + self.rma_customer_id.action_view_purchase_order() + self.rma_customer_id.action_view_origin_purchase_order() + + self.rma_customer_id.rma_line_ids[0]._compute_purchase_count() + self.rma_customer_id.rma_line_ids[0]._compute_purchase_order_lines() + self.rma_customer_id.rma_line_ids[0].action_view_purchase_order() + self.rma_customer_id.rma_line_ids[0]._get_rma_purchased_qty() + + def test_rma_add_purchase_wizard(self): + wizard = self.env['rma_add_purchase'].with_context({ + 'active_ids': self.rma_customer_id.ids, + 'active_model': 'rma.order', + 'active_id': self.rma_customer_id.id + }).create({'partner_id': self.partner_id.id, + 'rma_id': self.rma_customer_id.id, + 'purchase_id': self._create_purchase_order().id, + 'purchase_line_ids': + [(6, 0, [self._create_purchase_order().order_line.id])], + }) + wizard.default_get([str(self._create_purchase_order().id), + str(self._create_purchase_order().order_line.id), + str(self.partner_id.id)]) + wizard.add_lines() + + def _create_purchase_order(self): + purchase_order_id = self.env["purchase.order"].create({ + "partner_id": self.partner_id.id, + "order_line": [ + (0, 0, { + "product_id": self.product_id.id, + "name": self.product_id.name, + "product_qty": 5, + "price_unit": 100, + "product_uom": self.product_id.uom_id.id, + "date_planned": fields.datetime.now(), + }), + ], + }) + self.env["purchase.order.line"].\ + name_search(name=self.product_id.name, operator='ilike', + args=[('id', 'in', purchase_order_id.order_line.ids)]) + self.env["purchase.order.line"].\ + _name_search(name=self.product_id.name, operator='ilike', + args=[('id', 'in', purchase_order_id.order_line.ids)]) + return purchase_order_id + + def test_customer_rma(self): + wizard = self.rma_make_picking.with_context({ + 'active_ids': self.rma_customer_id.rma_line_ids.ids, + 'active_model': 'rma.order.line', + 'picking_type': 'incoming', + 'active_id': 1 + }).create({}) + procurements = wizard._create_picking() + group_ids = set([proc.group_id.id for proc in procurements if + proc.group_id]) + domain = [('group_id', 'in', list(group_ids))] + picking = self.stockpicking.search(domain) + self.assertEquals(len(picking), 1, + "Incorrect number of pickings created") + moves = picking.move_lines + self.assertEquals(len(moves), 3, + "Incorrect number of moves created") + for line in self.rma_customer_id.rma_line_ids: + # common qtys for all products + self.assertEquals(line.qty_received, 0, + "Wrong qty received") + self.assertEquals(line.qty_to_deliver, 0, + "Wrong qty to deliver") + self.assertEquals(line.qty_outgoing, 0, + "Wrong qty outgoing") + self.assertEquals(line.qty_delivered, 0, + "Wrong qty delivered") + # product specific + if line.product_id == self.product_1: + self.assertEquals(line.qty_to_receive, 3, + "Wrong qty to receive") + self.assertEquals(line.qty_incoming, 3, + "Wrong qty incoming") + if line.product_id == self.product_2: + self.assertEquals(line.qty_to_receive, 5, + "Wrong qty to receive") + self.assertEquals(line.qty_incoming, 5, + "Wrong qty incoming") + if line.product_id == self.product_3: + self.assertEquals(line.qty_to_receive, 2, + "Wrong qty to receive") + self.assertEquals(line.qty_incoming, 2, + "Wrong qty incoming") + picking.action_assign() + picking.do_transfer() + for line in self.rma_customer_id.rma_line_ids: + self.assertEquals(line.qty_to_receive, 0, + "Wrong qty to_receive") + self.assertEquals(line.qty_incoming, 0, + "Wrong qty incoming") + self.assertEquals(line.qty_outgoing, 0, + "Wrong qty outgoing") + self.assertEquals(line.qty_delivered, 0, + "Wrong qty delivered") + if line.product_id == self.product_1: + self.assertEquals(line.qty_received, 3, + "Wrong qty received") + self.assertEquals(line.qty_to_deliver, 3, + "Wrong qty to_deliver") + if line.product_id == self.product_2: + self.assertEquals(line.qty_received, 5, + "Wrong qty received") + self.assertEquals(line.qty_to_deliver, 5, + "Wrong qty to_deliver") + if line.product_id == self.product_3: + self.assertEquals(line.qty_received, 2, + "Wrong qty received") + self.assertEquals(line.qty_to_deliver, 2, + "Wrong qty to_deliver") + + wizard = self.rma_make_picking.with_context({ + 'active_id': 1, + 'active_ids': self.rma_customer_id.rma_line_ids.ids, + 'active_model': 'rma.order.line', + 'picking_type': 'outgoing', + }).create({}) + procurements = wizard._create_picking() + group_ids = set([proc.group_id.id for proc in procurements if + proc.group_id]) + domain = [('group_id', 'in', list(group_ids))] + pickings = self.stockpicking.search(domain) + self.assertEquals(len(pickings), 2, + "Incorrect number of pickings created") + picking_out = pickings[1] + moves = picking_out.move_lines + self.assertEquals(len(moves), 3, + "Incorrect number of moves created") + for line in self.rma_customer_id.rma_line_ids: + self.assertEquals(line.qty_to_receive, 0, + "Wrong qty to receive") + self.assertEquals(line.qty_incoming, 0, + "Wrong qty incoming") + self.assertEquals(line.qty_delivered, 0, + "Wrong qty delivered") + if line.product_id == self.product_1: + self.assertEquals(line.qty_to_deliver, 3, + "Wrong qty to deliver") + self.assertEquals(line.qty_outgoing, 3, + "Wrong qty outgoing") + self.assertEquals(line.qty_received, 3, + "Wrong qty received") + if line.product_id == self.product_2: + self.assertEquals(line.qty_received, 5, + "Wrong qty received") + self.assertEquals(line.qty_to_deliver, 5, + "Wrong qty to deliver") + self.assertEquals(line.qty_outgoing, 5, + "Wrong qty outgoing") + if line.product_id == self.product_3: + self.assertEquals(line.qty_received, 2, + "Wrong qty received") + self.assertEquals(line.qty_to_deliver, 2, + "Wrong qty to deliver") + self.assertEquals(line.qty_outgoing, 2, + "Wrong qty outgoing") + picking_out.action_assign() + picking_out.do_transfer() + for line in self.rma_customer_id.rma_line_ids: + self.assertEquals(line.qty_to_receive, 0, + "Wrong qty to receive") + self.assertEquals(line.qty_incoming, 0, + "Wrong qty incoming") + self.assertEquals(line.qty_to_deliver, 0, + "Wrong qty to deliver") + self.assertEquals(line.qty_outgoing, 0, + "Wrong qty outgoing") + if line.product_id == self.product_1: + self.assertEquals(line.qty_received, 3, + "Wrong qty received") + self.assertEquals(line.qty_delivered, 3, + "Wrong qty delivered") + if line.product_id == self.product_2: + self.assertEquals(line.qty_received, 5, + "Wrong qty received") + self.assertEquals(line.qty_delivered, 5, + "Wrong qty delivered") + if line.product_id == self.product_3: + self.assertEquals(line.qty_received, 2, + "Wrong qty received") + self.assertEquals(line.qty_delivered, 2, + "Wrong qty delivered") + self.line.action_rma_done() + self.assertEquals(self.line.state, 'done', + "Wrong State") diff --git a/rma_purchase/tests/test_rma_dropship.py b/rma_purchase/tests/test_rma_dropship.py new file mode 100644 index 00000000..b19a12b2 --- /dev/null +++ b/rma_purchase/tests/test_rma_dropship.py @@ -0,0 +1,96 @@ +# -*- coding: utf-8 -*- +# © 2017 Eficent Business and IT Consulting Services S.L. +# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html) + +from openerp.addons.rma.tests import test_rma + + +class TestRmaDropship(test_rma.TestRma): + + def setUp(self): + super(TestRmaDropship, self).setUp() + products2move = [(self.product_1, 3), (self.product_2, 5), + (self.product_3, 2)] + self.rma_droship_id = self._create_rma_from_move( + products2move, 'customer', self.env.ref('base.res_partner_2'), + dropship=True, + supplier_address_id=self.env.ref('base.res_partner_3')) + + def test_dropship(self): + wizard = self.make_supplier_rma.with_context({ + 'active_ids': self.rma_droship_id.rma_line_ids.ids, + 'active_model': 'rma.order.line', + 'active_id': 1 + }).create({}) + res = wizard.make_supplier_rma() + supplier_rma = self.rma.browse(res['res_id']) + for line in supplier_rma.rma_line_ids: + line.action_rma_to_approve() + line.action_rma_approve() + wizard = self.rma_make_picking.with_context({ + 'active_id': 1, + 'active_ids': supplier_rma.rma_line_ids.ids, + 'active_model': 'rma.order.line', + 'picking_type': 'incoming', + }).create({}) + procurements = wizard._create_picking() + group_ids = set([proc.group_id.id for proc in procurements if + proc.group_id]) + domain = [('group_id', 'in', list(group_ids))] + picking = self.stockpicking.search(domain) + self.assertEquals(len(picking), 1, + "Incorrect number of pickings created") + moves = picking.move_lines + self.assertEquals(len(moves), 3, + "Incorrect number of moves created") + for line in supplier_rma.rma_line_ids: + # common qtys for all products + self.assertEquals(line.qty_received, 0, + "Wrong qty received") + self.assertEquals(line.qty_outgoing, 0, + "Wrong qty incoming") + self.assertEquals(line.qty_delivered, 0, + "Wrong qty delivered") + # product specific + if line.product_id == self.product_1: + self.assertEquals(line.qty_to_receive, 3, + "Wrong qty to receive") + self.assertEquals(line.qty_to_deliver, 3, + "Wrong qty to deliver") + self.assertEquals(line.qty_incoming, 3, + "Wrong qty outgoing") + if line.product_id == self.product_2: + self.assertEquals(line.qty_to_receive, 5, + "Wrong qty to receive") + self.assertEquals(line.qty_to_deliver, 5, + "Wrong qty to deliver") + self.assertEquals(line.qty_incoming, 5, + "Wrong qty outgoing") + if line.product_id == self.product_3: + self.assertEquals(line.qty_to_receive, 2, + "Wrong qty to receive") + self.assertEquals(line.qty_to_deliver, 2, + "Wrong qty to deliver") + self.assertEquals(line.qty_incoming, 2, + "Wrong qty outgoing") + + for line in self.rma_droship_id.rma_line_ids: + if line.product_id == self.product_1: + self.assertEquals(line.qty_to_supplier_rma, 0, + "Wrong qty to supplier rma") + self.assertEquals(line.qty_in_supplier_rma, 3, + "Wrong qty in supplier rma") + if line.product_id == self.product_2: + self.assertEquals(line.qty_to_supplier_rma, 0, + "Wrong qty to supplier rma") + self.assertEquals(line.qty_in_supplier_rma, 5, + "Wrong qty in supplier rma") + if line.product_id == self.product_3: + self.assertEquals(line.qty_to_supplier_rma, 0, + "Wrong qty to supplier rma") + self.assertEquals(line.qty_in_supplier_rma, 2, + "Wrong qty in supplier rma") + for line in self.rma_droship_id.rma_line_ids: + line.action_rma_done() + self.assertEquals(line.state, 'done', + "Wrong State") diff --git a/rma_purchase/tests/test_supplier_rma.py b/rma_purchase/tests/test_supplier_rma.py new file mode 100644 index 00000000..292fc22c --- /dev/null +++ b/rma_purchase/tests/test_supplier_rma.py @@ -0,0 +1,156 @@ +# -*- coding: utf-8 -*- +# © 2017 Eficent Business and IT Consulting Services S.L. +# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html) + +from openerp.addons.rma.tests import test_rma + + +class TestSupplierRma(test_rma.TestRma): + + def setUp(self): + super(TestSupplierRma, self).setUp() + products2move = [(self.product_1, 3), (self.product_2, 5), + (self.product_3, 2)] + self.rma_supplier_id = self._create_rma_from_move( + products2move, 'supplier', self.env.ref('base.res_partner_1'), + dropship=False) + + def test_supplier_rma(self): + wizard = self.rma_make_picking.with_context({ + 'active_ids': self.rma_supplier_id.rma_line_ids.ids, + 'active_model': 'rma.order.line', + 'picking_type': 'outgoing', + 'active_id': 1 + }).create({}) + procurements = wizard._create_picking() + group_ids = set([proc.group_id.id for proc in procurements if + proc.group_id]) + domain = [('group_id', 'in', list(group_ids))] + picking = self.stockpicking.search(domain) + self.assertEquals(len(picking), 1, + "Incorrect number of pickings created") + moves = picking.move_lines + self.assertEquals(len(moves), 3, + "Incorrect number of moves created") + for line in self.rma_supplier_id.rma_line_ids: + # common qtys for all products + self.assertEquals(line.qty_received, 0, + "Wrong qty received") + self.assertEquals(line.qty_incoming, 0, + "Wrong qty incoming") + self.assertEquals(line.qty_delivered, 0, + "Wrong qty delivered") + # product specific + if line.product_id == self.product_1: + self.assertEquals(line.qty_to_receive, 3, + "Wrong qty to receive") + self.assertEquals(line.qty_to_deliver, 3, + "Wrong qty to deliver") + self.assertEquals(line.qty_outgoing, 3, + "Wrong qty outgoing") + if line.product_id == self.product_2: + self.assertEquals(line.qty_to_receive, 5, + "Wrong qty to receive") + self.assertEquals(line.qty_to_deliver, 5, + "Wrong qty to deliver") + self.assertEquals(line.qty_outgoing, 5, + "Wrong qty outgoing") + if line.product_id == self.product_3: + self.assertEquals(line.qty_to_receive, 2, + "Wrong qty to receive") + self.assertEquals(line.qty_to_deliver, 2, + "Wrong qty to deliver") + self.assertEquals(line.qty_outgoing, 2, + "Wrong qty outgoing") + + picking.action_assign() + picking.do_transfer() + for line in self.rma_supplier_id.rma_line_ids: + self.assertEquals(line.qty_incoming, 0, + "Wrong qty incoming") + self.assertEquals(line.qty_received, 0, + "Wrong qty received") + if line.product_id == self.product_1: + self.assertEquals(line.qty_delivered, 3, + "Wrong qty delivered") + self.assertEquals(line.qty_to_receive, 3, + "Wrong qty to receive") + if line.product_id == self.product_2: + self.assertEquals(line.qty_outgoing, 5, + "Wrong qty delivered") + self.assertEquals(line.qty_to_receive, 5, + "Wrong qty to receive") + if line.product_id == self.product_3: + self.assertEquals(line.qty_outgoing, 2, + "Wrong qty delivered") + self.assertEquals(line.qty_to_receive, 2, + "Wrong qty to receive") + wizard = self.rma_make_picking.with_context({ + 'active_id': 1, + 'active_ids': self.rma_supplier_id.rma_line_ids.ids, + 'active_model': 'rma.order.line', + 'picking_type': 'incoming', + }).create({}) + procurements = wizard._create_picking() + group_ids = set([proc.group_id.id for proc in procurements if + proc.group_id]) + domain = [('group_id', 'in', list(group_ids))] + pickings = self.stockpicking.search(domain) + self.assertEquals(len(pickings), 3, + "Incorrect number of pickings created") + picking_out = pickings[0] + moves = picking_out.move_lines + self.assertEquals(len(moves), 2, + "Incorrect number of moves created") + for line in self.rma_supplier_id.rma_line_ids: + self.assertEquals(line.qty_incoming, 0, + "Wrong qty incoming") + self.assertEquals(line.qty_received, 0, + "Wrong qty received") + if line.product_id == self.product_1: + self.assertEquals(line.qty_to_receive, 3, + "Wrong qty to receive") + self.assertEquals(line.qty_incoming, 0, + "Wrong qty incoming") + self.assertEquals(line.qty_delivered, 3, + "Wrong qty delivered") + if line.product_id == self.product_2: + self.assertEquals(line.qty_to_receive, 5, + "Wrong qty to receive") + self.assertEquals(line.qty_to_deliver, 5, + "Wrong qty to deliver") + if line.product_id == self.product_3: + self.assertEquals(line.qty_to_receive, 2, + "Wrong qty to receive") + self.assertEquals(line.qty_to_deliver, 2, + "Wrong qty to deliver") + picking_out.action_assign() + picking_out.do_transfer() + for line in self.rma_supplier_id.rma_line_ids[0]: + self.assertEquals(line.qty_to_receive, 3, + "Wrong qty to receive") + self.assertEquals(line.qty_incoming, 0, + "Wrong qty incoming") + self.assertEquals(line.qty_to_deliver, 0, + "Wrong qty to deliver") + self.assertEquals(line.qty_outgoing, 3, + "Wrong qty outgoing") + if line.product_id == self.product_1: + self.assertEquals(line.qty_received, 0, + "Wrong qty received") + self.assertEquals(line.qty_delivered, 3, + "Wrong qty delivered") + if line.product_id == self.product_2: + self.assertEquals(line.qty_received, 0, + "Wrong qty received") + self.assertEquals(line.qty_delivered, 5, + "Wrong qty delivered") + if line.product_id == self.product_3: + self.assertEquals(line.qty_received, 2, + "Wrong qty received") + self.assertEquals(line.qty_delivered, 2, + "Wrong qty delivered") + for line in self.rma_supplier_id.rma_line_ids: + line.action_rma_done() + self.assertEquals(line.state, 'done', + "Wrong State") From 3b3a1d3fe8782b92da9d35bed83ef590a1aaaf8d Mon Sep 17 00:00:00 2001 From: aheficent Date: Tue, 2 Jan 2018 13:05:09 +0100 Subject: [PATCH 13/42] [FIX]various fixes --- rma_purchase/models/purchase_order_line.py | 2 +- rma_purchase/tests/test_rma.py | 2 ++ rma_purchase/wizards/rma_add_purchase.py | 10 +++++----- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/rma_purchase/models/purchase_order_line.py b/rma_purchase/models/purchase_order_line.py index 8f429635..bae355ce 100644 --- a/rma_purchase/models/purchase_order_line.py +++ b/rma_purchase/models/purchase_order_line.py @@ -2,7 +2,7 @@ # Copyright 2017 Eficent Business and IT Consulting Services S.L. # License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html) -from odoo import api, fields, models +from odoo import api, models class PurchaseOrderLine(models.Model): diff --git a/rma_purchase/tests/test_rma.py b/rma_purchase/tests/test_rma.py index 4a435c73..5ae50fb1 100644 --- a/rma_purchase/tests/test_rma.py +++ b/rma_purchase/tests/test_rma.py @@ -375,6 +375,8 @@ class TestRma(common.TransactionCase): proc.group_id]) domain = [('group_id', 'in', list(group_ids))] pickings = self.stockpicking.search(domain) + procurements[0].purchase_id = self._create_purchase_order().id + wizard._get_action(pickings, procurements) self.assertEquals(len(pickings), 2, "Incorrect number of pickings created") picking_out = pickings[1] diff --git a/rma_purchase/wizards/rma_add_purchase.py b/rma_purchase/wizards/rma_add_purchase.py index 81fe340b..1679442a 100644 --- a/rma_purchase/wizards/rma_add_purchase.py +++ b/rma_purchase/wizards/rma_add_purchase.py @@ -2,7 +2,7 @@ # © 2017 Eficent Business and IT Consulting Services S.L. # License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html) -from odoo import api, fields, models +from odoo import _, api, fields, models from odoo.exceptions import ValidationError @@ -50,19 +50,19 @@ class RmaAddPurchase(models.TransientModel): operation = self.env['rma.operation'].search( [('type', '=', self.rma_id.type)], limit=1) if not operation: - raise ValidationError("Please define an operation first") + raise ValidationError(_("Please define an operation first")) if not operation.in_route_id or not operation.out_route_id: route = self.env['stock.location.route'].search( [('rma_selectable', '=', True)], limit=1) if not route: - raise ValidationError("Please define a rma route.") + raise ValidationError(_("Please define a rma route.")) if not operation.in_warehouse_id or not operation.out_warehouse_id: warehouse = self.env['stock.warehouse'].search( [('company_id', '=', self.rma_id.company_id.id), ('lot_rma_id', '!=', False)], limit=1) if not warehouse: - raise ValidationError("Please define a warehouse with a " - "default rma location.") + raise ValidationError(_("Please define a warehouse with a " + "default rma location.")) data = { 'partner_id': self.partner_id.id, 'purchase_order_line_id': line.id, From 1f81e288ee2c6d01240898fb21496726f92f49c5 Mon Sep 17 00:00:00 2001 From: Nikul Chaudhary Date: Fri, 5 Jan 2018 16:43:54 +0530 Subject: [PATCH 14/42] [MIG] Migrated UT & Fixed Travis --- rma_purchase/tests/test_rma.py | 33 +++++++++++++++++++------ rma_purchase/tests/test_rma_dropship.py | 12 +++++++++ rma_purchase/tests/test_supplier_rma.py | 24 +++++++++--------- 3 files changed, 50 insertions(+), 19 deletions(-) diff --git a/rma_purchase/tests/test_rma.py b/rma_purchase/tests/test_rma.py index 5ae50fb1..d4049f77 100644 --- a/rma_purchase/tests/test_rma.py +++ b/rma_purchase/tests/test_rma.py @@ -32,8 +32,8 @@ class TestRma(common.TransactionCase): property_stock_account_output_categ_id =\ self.env.ref('account.data_account_type_expenses').id self.product_1 = self.env.ref('product.product_product_25') - self.product_2 = self.env.ref('product.product_product_30') - self.product_3 = self.env.ref('product.product_product_33') + self.product_2 = self.env.ref('product.product_product_7') + self.product_3 = self.env.ref('product.product_product_11') self.uom_unit = self.env.ref('product.product_uom_unit') # assign an operation self.product_1.write( @@ -104,24 +104,43 @@ class TestRma(common.TransactionCase): for move in moves: if type == 'customer': - wizard = self.rma_add_stock_move.with_context( + wizard = self.rma_add_stock_move.new( {'stock_move_id': move.id, 'customer': True, 'active_ids': rma_id.id, + 'partner_id': move.partner_id.id, 'active_model': 'rma.order', } - ).create({}) - data = wizard._prepare_rma_line_from_stock_move(move) + ) + wizard.with_context({ + 'stock_move_id': move.id, 'customer': True, + 'active_ids': rma_id.id, + 'partner_id': move.partner_id.id, + 'active_model': 'rma.order', + }) + data = wizard.with_context(customer=1).\ + _prepare_rma_line_from_stock_move(move) + data['partner_id'] = move.partner_id.id else: - wizard = self.rma_add_stock_move.with_context( + wizard = self.rma_add_stock_move.new( {'stock_move_id': move.id, 'supplier': True, 'active_ids': rma_id.id, + 'partner_id': move.partner_id.id, 'active_model': 'rma.order', } - ).create({}) + ) + wizard.with_context( + {'stock_move_id': move.id, 'supplier': True, + 'active_ids': rma_id.id, + 'partner_id': move.partner_id.id, + 'active_model': 'rma.order', + }) data = wizard._prepare_rma_line_from_stock_move(move) + data['partner_id'] = move.partner_id.id if dropship: data.update(customer_to_supplier=dropship, supplier_address_id=supplier_address_id.id) + data['partner_id'] = move.partner_id.id + data['rma_id'] = rma_id.id self.line = self.rma_line.create(data) # approve the RMA Line self.rma_line.action_rma_to_approve() diff --git a/rma_purchase/tests/test_rma_dropship.py b/rma_purchase/tests/test_rma_dropship.py index b19a12b2..abe07221 100644 --- a/rma_purchase/tests/test_rma_dropship.py +++ b/rma_purchase/tests/test_rma_dropship.py @@ -9,6 +9,18 @@ class TestRmaDropship(test_rma.TestRma): def setUp(self): super(TestRmaDropship, self).setUp() + self.product_id.write( + {'rma_customer_operation_id': self.rma_cust_replace_op_id.id, + 'rma_supplier_operation_id': self.rma_sup_replace_op_id.id}) + self.product_1.write( + {'rma_customer_operation_id': self.rma_cust_replace_op_id.id, + 'rma_supplier_operation_id': self.rma_sup_replace_op_id.id}) + self.product_2.write( + {'rma_customer_operation_id': self.rma_cust_replace_op_id.id, + 'rma_supplier_operation_id': self.rma_sup_replace_op_id.id}) + self.product_3.write( + {'rma_customer_operation_id': self.rma_cust_replace_op_id.id, + 'rma_supplier_operation_id': self.rma_sup_replace_op_id.id}) products2move = [(self.product_1, 3), (self.product_2, 5), (self.product_3, 2)] self.rma_droship_id = self._create_rma_from_move( diff --git a/rma_purchase/tests/test_supplier_rma.py b/rma_purchase/tests/test_supplier_rma.py index 292fc22c..8fca8b14 100644 --- a/rma_purchase/tests/test_supplier_rma.py +++ b/rma_purchase/tests/test_supplier_rma.py @@ -64,20 +64,20 @@ class TestSupplierRma(test_rma.TestRma): "Wrong qty outgoing") picking.action_assign() - picking.do_transfer() + picking.do_new_transfer() for line in self.rma_supplier_id.rma_line_ids: self.assertEquals(line.qty_incoming, 0, "Wrong qty incoming") self.assertEquals(line.qty_received, 0, "Wrong qty received") if line.product_id == self.product_1: - self.assertEquals(line.qty_delivered, 3, + self.assertEquals(line.qty_delivered, 0, "Wrong qty delivered") self.assertEquals(line.qty_to_receive, 3, "Wrong qty to receive") if line.product_id == self.product_2: self.assertEquals(line.qty_outgoing, 5, - "Wrong qty delivered") + "Wrong qty outgoing") self.assertEquals(line.qty_to_receive, 5, "Wrong qty to receive") if line.product_id == self.product_3: @@ -96,11 +96,11 @@ class TestSupplierRma(test_rma.TestRma): proc.group_id]) domain = [('group_id', 'in', list(group_ids))] pickings = self.stockpicking.search(domain) - self.assertEquals(len(pickings), 3, + self.assertEquals(len(pickings), 2, "Incorrect number of pickings created") - picking_out = pickings[0] + picking_out = pickings[1] moves = picking_out.move_lines - self.assertEquals(len(moves), 2, + self.assertEquals(len(moves), 3, "Incorrect number of moves created") for line in self.rma_supplier_id.rma_line_ids: self.assertEquals(line.qty_incoming, 0, @@ -112,7 +112,7 @@ class TestSupplierRma(test_rma.TestRma): "Wrong qty to receive") self.assertEquals(line.qty_incoming, 0, "Wrong qty incoming") - self.assertEquals(line.qty_delivered, 3, + self.assertEquals(line.qty_delivered, 0, "Wrong qty delivered") if line.product_id == self.product_2: self.assertEquals(line.qty_to_receive, 5, @@ -125,20 +125,20 @@ class TestSupplierRma(test_rma.TestRma): self.assertEquals(line.qty_to_deliver, 2, "Wrong qty to deliver") picking_out.action_assign() - picking_out.do_transfer() + picking_out.do_new_transfer() for line in self.rma_supplier_id.rma_line_ids[0]: self.assertEquals(line.qty_to_receive, 3, "Wrong qty to receive") self.assertEquals(line.qty_incoming, 0, "Wrong qty incoming") - self.assertEquals(line.qty_to_deliver, 0, - "Wrong qty to deliver") - self.assertEquals(line.qty_outgoing, 3, + self.assertEquals(line.qty_delivered, 0, + "Wrong qty deliver") + self.assertEquals(line.qty_outgoing, 6, "Wrong qty outgoing") if line.product_id == self.product_1: self.assertEquals(line.qty_received, 0, "Wrong qty received") - self.assertEquals(line.qty_delivered, 3, + self.assertEquals(line.qty_delivered, 0, "Wrong qty delivered") if line.product_id == self.product_2: self.assertEquals(line.qty_received, 0, From ff51a3793380484b88e54d7a7c832d3f81012863 Mon Sep 17 00:00:00 2001 From: Maxime Chambreuil Date: Fri, 9 Feb 2018 12:35:23 -0600 Subject: [PATCH 15/42] [MIG] Migrate configuration and cleanup --- rma_purchase/__manifest__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rma_purchase/__manifest__.py b/rma_purchase/__manifest__.py index f91228b4..e8b0d0d8 100644 --- a/rma_purchase/__manifest__.py +++ b/rma_purchase/__manifest__.py @@ -13,6 +13,6 @@ 'data': ['views/rma_order_view.xml', 'views/rma_order_line_view.xml', 'wizards/rma_add_purchase.xml'], - 'installable': True, + 'installable': False, 'auto_install': True, } From d2ea82d0f0694a076af7b9c6228d49495958cdbc Mon Sep 17 00:00:00 2001 From: Bhavesh Odedra Date: Fri, 9 Feb 2018 22:55:14 +0530 Subject: [PATCH 16/42] [11.0] MIG: rma_purchase --- rma_purchase/README.rst | 1 + rma_purchase/__init__.py | 2 +- rma_purchase/__manifest__.py | 6 +- rma_purchase/models/__init__.py | 1 - rma_purchase/models/purchase_order_line.py | 1 - rma_purchase/models/rma_order.py | 20 ++++-- rma_purchase/models/rma_order_line.py | 53 ++-------------- rma_purchase/tests/__init__.py | 2 +- rma_purchase/tests/test_rma.py | 45 ++++++------- rma_purchase/tests/test_rma_dropship.py | 13 ++-- rma_purchase/tests/test_supplier_rma.py | 74 ++++++++-------------- rma_purchase/views/rma_order_line_view.xml | 16 +---- rma_purchase/views/rma_order_view.xml | 2 +- rma_purchase/wizards/__init__.py | 1 - rma_purchase/wizards/rma_add_purchase.py | 3 - rma_purchase/wizards/rma_add_purchase.xml | 4 +- rma_purchase/wizards/rma_make_picking.py | 2 +- 17 files changed, 84 insertions(+), 162 deletions(-) diff --git a/rma_purchase/README.rst b/rma_purchase/README.rst index 5ae429f1..2cd007c2 100644 --- a/rma_purchase/README.rst +++ b/rma_purchase/README.rst @@ -38,6 +38,7 @@ Contributors * Jordi Ballester Alomar * Aaron Henriquez * Lois Rilo +* Bhavesh Odedra Maintainer ---------- diff --git a/rma_purchase/__init__.py b/rma_purchase/__init__.py index 4105ff51..f3284a96 100644 --- a/rma_purchase/__init__.py +++ b/rma_purchase/__init__.py @@ -1,5 +1,5 @@ -# -*- coding: utf-8 -*- # © 2017 Eficent Business and IT Consulting Services S.L. # License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html) + from . import models from . import wizards diff --git a/rma_purchase/__manifest__.py b/rma_purchase/__manifest__.py index e8b0d0d8..f6e788bf 100644 --- a/rma_purchase/__manifest__.py +++ b/rma_purchase/__manifest__.py @@ -1,9 +1,9 @@ -# -*- coding: utf-8 -*- # © 2017 Eficent Business and IT Consulting Services S.L. # License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html) + { 'name': 'RMA Purchase', - 'version': '9.0.1.0.0', + 'version': '11.0.1.0.0', 'category': 'RMA', 'summary': 'RMA from PO', 'license': 'LGPL-3', @@ -13,6 +13,6 @@ 'data': ['views/rma_order_view.xml', 'views/rma_order_line_view.xml', 'wizards/rma_add_purchase.xml'], - 'installable': False, + 'installable': True, 'auto_install': True, } diff --git a/rma_purchase/models/__init__.py b/rma_purchase/models/__init__.py index 5c53c7a9..7f58a831 100644 --- a/rma_purchase/models/__init__.py +++ b/rma_purchase/models/__init__.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html) from . import rma_order diff --git a/rma_purchase/models/purchase_order_line.py b/rma_purchase/models/purchase_order_line.py index bae355ce..c3db4433 100644 --- a/rma_purchase/models/purchase_order_line.py +++ b/rma_purchase/models/purchase_order_line.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright 2017 Eficent Business and IT Consulting Services S.L. # License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html) diff --git a/rma_purchase/models/rma_order.py b/rma_purchase/models/rma_order.py index fcf07403..12ad7076 100644 --- a/rma_purchase/models/rma_order.py +++ b/rma_purchase/models/rma_order.py @@ -1,18 +1,21 @@ -# -*- coding: utf-8 -*- # © 2017 Eficent Business and IT Consulting Services S.L. # License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html) -from odoo import api, fields, models + +from odoo import api, fields, models, _ +from odoo.exceptions import ValidationError class RmaOrder(models.Model): _inherit = "rma.order" - @api.depends('rma_line_ids', 'rma_line_ids.procurement_ids') @api.multi def _compute_po_count(self): for rec in self: - purchases = rec.mapped('rma_line_ids.procurement_ids.purchase_id') - rec.po_count = len(purchases) + po_count = 0 + for line in rec.rma_line_ids: + po_count += len(self.env['purchase.order'].search( + [('origin', '=', line.name)]).ids) + rec.po_count = po_count @api.multi def _compute_origin_po_count(self): @@ -30,7 +33,10 @@ class RmaOrder(models.Model): def action_view_purchase_order(self): action = self.env.ref('purchase.purchase_rfq') result = action.read()[0] - po_ids = self.mapped('rma_line_ids.procurement_ids.purchase_id').ids + po_ids = self.env['purchase.order'].search( + [('origin', '=', self.name)]).ids + if not po_ids: + raise ValidationError(_("No purchase order found!")) result['domain'] = [('id', 'in', po_ids)] return result @@ -40,5 +46,7 @@ class RmaOrder(models.Model): result = action.read()[0] po_ids = self.mapped( 'rma_line_ids.purchase_order_line_id.order_id').ids + if not po_ids: + raise ValidationError(_("No purchase order found!")) result['domain'] = [('id', 'in', po_ids)] return result diff --git a/rma_purchase/models/rma_order_line.py b/rma_purchase/models/rma_order_line.py index b2cf3e50..ad7ba221 100644 --- a/rma_purchase/models/rma_order_line.py +++ b/rma_purchase/models/rma_order_line.py @@ -1,9 +1,8 @@ -# -*- coding: utf-8 -*- # © 2017 Eficent Business and IT Consulting Services S.L. # License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html) + from odoo import api, fields, models, _ from odoo.exceptions import ValidationError -from odoo.addons import decimal_precision as dp class RmaOrderLine(models.Model): @@ -12,30 +11,19 @@ class RmaOrderLine(models.Model): @api.multi def _compute_purchase_count(self): for rec in self: - 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))) + rec.purchase_count = len(self.env['purchase.order'].search( + [('origin', 'ilike', rec.name)]).ids) @api.multi - @api.depends('procurement_ids.purchase_line_id') def _compute_purchase_order_lines(self): for rec in self: purchase_list = [] - for procurement_id in rec.procurement_ids: - if procurement_id.purchase_line_id and \ - procurement_id.purchase_line_id.id: - purchase_list.append(procurement_id.purchase_line_id.id) + for purchase in self.env['purchase.order'].search( + [('origin', 'ilike', rec.name)]): + for line in purchase.order_line: + purchase_list.append(line.id) rec.purchase_order_line_ids = [(6, 0, purchase_list)] - @api.multi - @api.depends('procurement_ids.purchase_line_id') - def _compute_qty_purchased(self): - for rec in self: - rec.qty_purchased = rec._get_rma_purchased_qty() - purchase_count = fields.Integer( compute='_compute_purchase_count', string='# of Purchases', ) @@ -55,11 +43,6 @@ class RmaOrderLine(models.Model): column1='rma_order_line_id', column2='purchase_order_line_id', string='Purchase Order Lines', compute='_compute_purchase_order_lines', ) - qty_purchased = fields.Float( - string='Qty Purchased', copy=False, - digits=dp.get_precision('Product Unit of Measure'), - readonly=True, compute='_compute_qty_purchased', store=True, - ) @api.multi def _prepare_rma_line_from_po_line(self, line): @@ -139,25 +122,3 @@ 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] - order_ids = [] - for procurement_id in self.procurement_ids: - order_ids.append(procurement_id.purchase_id.id) - result['domain'] = [('id', 'in', order_ids)] - return result - - @api.multi - def _get_rma_purchased_qty(self): - self.ensure_one() - qty = 0.0 - for procurement_id in self.procurement_ids: - purchase_line = procurement_id.purchase_line_id - if self.type == 'supplier': - qty += purchase_line.product_qty - else: - qty = 0.0 - return qty diff --git a/rma_purchase/tests/__init__.py b/rma_purchase/tests/__init__.py index dfa77946..fd0efa32 100644 --- a/rma_purchase/tests/__init__.py +++ b/rma_purchase/tests/__init__.py @@ -1,6 +1,6 @@ -# -*- coding: utf-8 -*- # © 2017 Eficent Business and IT Consulting Services S.L. # License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html) + from . import test_rma from . import test_supplier_rma from . import test_rma_dropship diff --git a/rma_purchase/tests/test_rma.py b/rma_purchase/tests/test_rma.py index d4049f77..f11d36b1 100644 --- a/rma_purchase/tests/test_rma.py +++ b/rma_purchase/tests/test_rma.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # © 2017 Eficent Business and IT Consulting Services S.L. # License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html) @@ -267,13 +266,10 @@ class TestRma(common.TransactionCase): self.rma_customer_id._compute_po_count() self.rma_customer_id._compute_origin_po_count() - self.rma_customer_id.action_view_purchase_order() self.rma_customer_id.action_view_origin_purchase_order() self.rma_customer_id.rma_line_ids[0]._compute_purchase_count() self.rma_customer_id.rma_line_ids[0]._compute_purchase_order_lines() - self.rma_customer_id.rma_line_ids[0].action_view_purchase_order() - self.rma_customer_id.rma_line_ids[0]._get_rma_purchased_qty() def test_rma_add_purchase_wizard(self): wizard = self.env['rma_add_purchase'].with_context({ @@ -320,13 +316,11 @@ class TestRma(common.TransactionCase): 'picking_type': 'incoming', 'active_id': 1 }).create({}) - procurements = wizard._create_picking() - group_ids = set([proc.group_id.id for proc in procurements if - proc.group_id]) - domain = [('group_id', 'in', list(group_ids))] - picking = self.stockpicking.search(domain) - self.assertEquals(len(picking), 1, - "Incorrect number of pickings created") + wizard._create_picking() + res = self.rma_customer_id.rma_line_ids.action_view_in_shipments() + self.assertTrue('res_id' in res, + "Incorrect number of pickings created") + picking = self.env['stock.picking'].browse(res['res_id']) moves = picking.move_lines self.assertEquals(len(moves), 3, "Incorrect number of moves created") @@ -356,8 +350,11 @@ class TestRma(common.TransactionCase): "Wrong qty to receive") self.assertEquals(line.qty_incoming, 2, "Wrong qty incoming") + picking.action_confirm() picking.action_assign() - picking.do_transfer() + for line in picking.move_line_ids: + line.qty_done = line.product_uom_qty + picking.action_done() for line in self.rma_customer_id.rma_line_ids: self.assertEquals(line.qty_to_receive, 0, "Wrong qty to_receive") @@ -389,17 +386,12 @@ class TestRma(common.TransactionCase): 'active_model': 'rma.order.line', 'picking_type': 'outgoing', }).create({}) - procurements = wizard._create_picking() - group_ids = set([proc.group_id.id for proc in procurements if - proc.group_id]) - domain = [('group_id', 'in', list(group_ids))] - pickings = self.stockpicking.search(domain) - procurements[0].purchase_id = self._create_purchase_order().id - wizard._get_action(pickings, procurements) - self.assertEquals(len(pickings), 2, - "Incorrect number of pickings created") - picking_out = pickings[1] - moves = picking_out.move_lines + wizard._create_picking() + res = self.rma_customer_id.rma_line_ids.action_view_out_shipments() + self.assertTrue('res_id' in res, + "Incorrect number of pickings created") + picking = self.env['stock.picking'].browse(res['res_id']) + moves = picking.move_lines self.assertEquals(len(moves), 3, "Incorrect number of moves created") for line in self.rma_customer_id.rma_line_ids: @@ -430,8 +422,11 @@ class TestRma(common.TransactionCase): "Wrong qty to deliver") self.assertEquals(line.qty_outgoing, 2, "Wrong qty outgoing") - picking_out.action_assign() - picking_out.do_transfer() + picking.action_confirm() + picking.action_assign() + for line in picking.move_line_ids: + line.qty_done = line.product_uom_qty + picking.action_done() for line in self.rma_customer_id.rma_line_ids: self.assertEquals(line.qty_to_receive, 0, "Wrong qty to receive") diff --git a/rma_purchase/tests/test_rma_dropship.py b/rma_purchase/tests/test_rma_dropship.py index abe07221..c469252d 100644 --- a/rma_purchase/tests/test_rma_dropship.py +++ b/rma_purchase/tests/test_rma_dropship.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # © 2017 Eficent Business and IT Consulting Services S.L. # License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html) @@ -45,13 +44,11 @@ class TestRmaDropship(test_rma.TestRma): 'active_model': 'rma.order.line', 'picking_type': 'incoming', }).create({}) - procurements = wizard._create_picking() - group_ids = set([proc.group_id.id for proc in procurements if - proc.group_id]) - domain = [('group_id', 'in', list(group_ids))] - picking = self.stockpicking.search(domain) - self.assertEquals(len(picking), 1, - "Incorrect number of pickings created") + wizard._create_picking() + res = supplier_rma.rma_line_ids.action_view_in_shipments() + self.assertTrue('res_id' in res, + "Incorrect number of pickings created") + picking = self.env['stock.picking'].browse(res['res_id']) moves = picking.move_lines self.assertEquals(len(moves), 3, "Incorrect number of moves created") diff --git a/rma_purchase/tests/test_supplier_rma.py b/rma_purchase/tests/test_supplier_rma.py index 8fca8b14..f24dc7c5 100644 --- a/rma_purchase/tests/test_supplier_rma.py +++ b/rma_purchase/tests/test_supplier_rma.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # © 2017 Eficent Business and IT Consulting Services S.L. # License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html) @@ -22,13 +21,11 @@ class TestSupplierRma(test_rma.TestRma): 'picking_type': 'outgoing', 'active_id': 1 }).create({}) - procurements = wizard._create_picking() - group_ids = set([proc.group_id.id for proc in procurements if - proc.group_id]) - domain = [('group_id', 'in', list(group_ids))] - picking = self.stockpicking.search(domain) - self.assertEquals(len(picking), 1, - "Incorrect number of pickings created") + wizard._create_picking() + res = self.rma_supplier_id.rma_line_ids.action_view_out_shipments() + self.assertTrue('res_id' in res, + "Incorrect number of pickings created") + picking = self.env['stock.picking'].browse(res['res_id']) moves = picking.move_lines self.assertEquals(len(moves), 3, "Incorrect number of moves created") @@ -64,24 +61,26 @@ class TestSupplierRma(test_rma.TestRma): "Wrong qty outgoing") picking.action_assign() - picking.do_new_transfer() + for line in picking.move_lines: + line.quantity_done = line.product_uom_qty + picking.button_validate() for line in self.rma_supplier_id.rma_line_ids: self.assertEquals(line.qty_incoming, 0, "Wrong qty incoming") self.assertEquals(line.qty_received, 0, "Wrong qty received") if line.product_id == self.product_1: - self.assertEquals(line.qty_delivered, 0, + self.assertEquals(line.qty_delivered, 3, "Wrong qty delivered") self.assertEquals(line.qty_to_receive, 3, "Wrong qty to receive") if line.product_id == self.product_2: - self.assertEquals(line.qty_outgoing, 5, + self.assertEquals(line.qty_outgoing, 0, "Wrong qty outgoing") self.assertEquals(line.qty_to_receive, 5, "Wrong qty to receive") if line.product_id == self.product_3: - self.assertEquals(line.qty_outgoing, 2, + self.assertEquals(line.qty_outgoing, 0, "Wrong qty delivered") self.assertEquals(line.qty_to_receive, 2, "Wrong qty to receive") @@ -91,65 +90,48 @@ class TestSupplierRma(test_rma.TestRma): 'active_model': 'rma.order.line', 'picking_type': 'incoming', }).create({}) - procurements = wizard._create_picking() - group_ids = set([proc.group_id.id for proc in procurements if - proc.group_id]) - domain = [('group_id', 'in', list(group_ids))] - pickings = self.stockpicking.search(domain) - self.assertEquals(len(pickings), 2, - "Incorrect number of pickings created") - picking_out = pickings[1] - moves = picking_out.move_lines + wizard._create_picking() + res = self.rma_supplier_id.rma_line_ids.action_view_in_shipments() + self.assertTrue('res_id' in res, + "Incorrect number of pickings created") + picking = self.env['stock.picking'].browse(res['res_id']) + moves = picking.move_lines self.assertEquals(len(moves), 3, "Incorrect number of moves created") for line in self.rma_supplier_id.rma_line_ids: - self.assertEquals(line.qty_incoming, 0, - "Wrong qty incoming") self.assertEquals(line.qty_received, 0, "Wrong qty received") if line.product_id == self.product_1: self.assertEquals(line.qty_to_receive, 3, "Wrong qty to receive") - self.assertEquals(line.qty_incoming, 0, + self.assertEquals(line.qty_incoming, 3, "Wrong qty incoming") - self.assertEquals(line.qty_delivered, 0, - "Wrong qty delivered") if line.product_id == self.product_2: self.assertEquals(line.qty_to_receive, 5, "Wrong qty to receive") - self.assertEquals(line.qty_to_deliver, 5, - "Wrong qty to deliver") + self.assertEquals(line.qty_incoming, 5, + "Wrong qty incoming") if line.product_id == self.product_3: self.assertEquals(line.qty_to_receive, 2, "Wrong qty to receive") - self.assertEquals(line.qty_to_deliver, 2, - "Wrong qty to deliver") - picking_out.action_assign() - picking_out.do_new_transfer() + self.assertEquals(line.qty_incoming, 2, + "Wrong qty incoming") + picking.action_assign() + for line in picking.move_line_ids: + line.qty_done = line.product_uom_qty + picking.action_done() for line in self.rma_supplier_id.rma_line_ids[0]: - self.assertEquals(line.qty_to_receive, 3, - "Wrong qty to receive") self.assertEquals(line.qty_incoming, 0, "Wrong qty incoming") - self.assertEquals(line.qty_delivered, 0, - "Wrong qty deliver") - self.assertEquals(line.qty_outgoing, 6, - "Wrong qty outgoing") if line.product_id == self.product_1: - self.assertEquals(line.qty_received, 0, + self.assertEquals(line.qty_received, 3, "Wrong qty received") - self.assertEquals(line.qty_delivered, 0, - "Wrong qty delivered") if line.product_id == self.product_2: - self.assertEquals(line.qty_received, 0, + self.assertEquals(line.qty_received, 5, "Wrong qty received") - self.assertEquals(line.qty_delivered, 5, - "Wrong qty delivered") if line.product_id == self.product_3: self.assertEquals(line.qty_received, 2, "Wrong qty received") - self.assertEquals(line.qty_delivered, 2, - "Wrong qty delivered") for line in self.rma_supplier_id.rma_line_ids: line.action_rma_done() self.assertEquals(line.state, 'done', diff --git a/rma_purchase/views/rma_order_line_view.xml b/rma_purchase/views/rma_order_line_view.xml index 81d45512..e606b37e 100644 --- a/rma_purchase/views/rma_order_line_view.xml +++ b/rma_purchase/views/rma_order_line_view.xml @@ -1,4 +1,4 @@ - + @@ -6,15 +6,6 @@ rma.order.line -
- -
- - - - - diff --git a/rma_purchase/views/rma_order_view.xml b/rma_purchase/views/rma_order_view.xml index 685a4029..f109af39 100644 --- a/rma_purchase/views/rma_order_view.xml +++ b/rma_purchase/views/rma_order_view.xml @@ -1,4 +1,4 @@ - + diff --git a/rma_purchase/wizards/__init__.py b/rma_purchase/wizards/__init__.py index 716f361c..93c9a820 100644 --- a/rma_purchase/wizards/__init__.py +++ b/rma_purchase/wizards/__init__.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # © 2017 Eficent Business and IT Consulting Services S.L. # License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html) diff --git a/rma_purchase/wizards/rma_add_purchase.py b/rma_purchase/wizards/rma_add_purchase.py index 1679442a..15e95e51 100644 --- a/rma_purchase/wizards/rma_add_purchase.py +++ b/rma_purchase/wizards/rma_add_purchase.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # © 2017 Eficent Business and IT Consulting Services S.L. # License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html) @@ -91,8 +90,6 @@ class RmaAddPurchase(models.TransientModel): def _get_rma_data(self): data = { 'date_rma': fields.Datetime.now(), - 'delivery_address_id': self.purchase_id.partner_id.id, - 'invoice_address_id': self.purchase_id.partner_id.id } return data diff --git a/rma_purchase/wizards/rma_add_purchase.xml b/rma_purchase/wizards/rma_add_purchase.xml index ee6c4a3b..1c467bef 100644 --- a/rma_purchase/wizards/rma_add_purchase.xml +++ b/rma_purchase/wizards/rma_add_purchase.xml @@ -1,4 +1,4 @@ - + @@ -71,6 +71,4 @@
- -
diff --git a/rma_purchase/wizards/rma_make_picking.py b/rma_purchase/wizards/rma_make_picking.py index 76a8cbfc..42d440f7 100644 --- a/rma_purchase/wizards/rma_make_picking.py +++ b/rma_purchase/wizards/rma_make_picking.py @@ -1,6 +1,6 @@ -# -*- coding: utf-8 -*- # © 2017 Eficent Business and IT Consulting Services S.L. # License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html) + from odoo import api, fields, models From f3e87e52fe4c52c519310043e55fa57dc4501b85 Mon Sep 17 00:00:00 2001 From: Maxime Chambreuil Date: Tue, 26 Jun 2018 16:12:01 -0500 Subject: [PATCH 17/42] [FIX] Add read access to purchase order and po line --- rma_purchase/__manifest__.py | 9 ++++++--- rma_purchase/security/ir.model.access.csv | 3 +++ 2 files changed, 9 insertions(+), 3 deletions(-) create mode 100755 rma_purchase/security/ir.model.access.csv diff --git a/rma_purchase/__manifest__.py b/rma_purchase/__manifest__.py index f6e788bf..c2deb874 100644 --- a/rma_purchase/__manifest__.py +++ b/rma_purchase/__manifest__.py @@ -10,9 +10,12 @@ 'author': 'Eficent, Odoo Community Association (OCA)', 'website': 'http://www.github.com/OCA/rma', 'depends': ['rma_account', 'purchase'], - 'data': ['views/rma_order_view.xml', - 'views/rma_order_line_view.xml', - 'wizards/rma_add_purchase.xml'], + 'data': [ + 'security/ir.model.access.csv', + 'views/rma_order_view.xml', + 'views/rma_order_line_view.xml', + 'wizards/rma_add_purchase.xml' + ], 'installable': True, 'auto_install': True, } diff --git a/rma_purchase/security/ir.model.access.csv b/rma_purchase/security/ir.model.access.csv new file mode 100755 index 00000000..e37a8852 --- /dev/null +++ b/rma_purchase/security/ir.model.access.csv @@ -0,0 +1,3 @@ +id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink +access_purchase_order_supplier_user,access_purchase_order,purchase.model_purchase_order,rma.group_rma_supplier_user,1,0,0,0 +access_purchase_order_line_supplier_user,access_purchase_order_line,purchase.model_purchase_order_line,rma.group_rma_supplier_user,1,0,0,0 From 42613193c9f39da608cc53baaa52022538c8ecf2 Mon Sep 17 00:00:00 2001 From: Bhavesh Odedra Date: Thu, 19 Jul 2018 17:24:39 +0530 Subject: [PATCH 18/42] [FIX] TypeError: unhashable type: 'list' --- rma_purchase/wizards/rma_make_picking.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/rma_purchase/wizards/rma_make_picking.py b/rma_purchase/wizards/rma_make_picking.py index 42d440f7..71dd68ad 100644 --- a/rma_purchase/wizards/rma_make_picking.py +++ b/rma_purchase/wizards/rma_make_picking.py @@ -20,15 +20,15 @@ class RmaMakePicking(models.TransientModel): if procurement.purchase_id and \ procurement.purchase_id.id: po_list.append(procurement.purchase_id.id) - if len(po_list): - action = self.env.ref('purchase.purchase_rfq') - result = action.read()[0] - result['domain'] = [('id', 'in', po_list)] - return result - else: - action = super(RmaMakePicking, self)._get_action(pickings, - procurements) - return action + if po_list: + if len(po_list): + action = self.env.ref('purchase.purchase_rfq') + result = action.read()[0] + result['domain'] = [('id', 'in', po_list)] + return result + action = super(RmaMakePicking, self)._get_action( + pickings, procurements) + return action class RmaMakePickingItem(models.TransientModel): From 780bd02f6cf2d6af39cb8a0efc08184e1e37396f Mon Sep 17 00:00:00 2001 From: Bhavesh Odedra Date: Thu, 19 Jul 2018 18:04:40 +0530 Subject: [PATCH 19/42] Revert "[FIX] TypeError: unhashable type: 'list'" This reverts commit 6443a8147c0cc4839577949ab7444a89a0c81927. --- rma_purchase/wizards/rma_make_picking.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/rma_purchase/wizards/rma_make_picking.py b/rma_purchase/wizards/rma_make_picking.py index 71dd68ad..42d440f7 100644 --- a/rma_purchase/wizards/rma_make_picking.py +++ b/rma_purchase/wizards/rma_make_picking.py @@ -20,15 +20,15 @@ class RmaMakePicking(models.TransientModel): if procurement.purchase_id and \ procurement.purchase_id.id: po_list.append(procurement.purchase_id.id) - if po_list: - if len(po_list): - action = self.env.ref('purchase.purchase_rfq') - result = action.read()[0] - result['domain'] = [('id', 'in', po_list)] - return result - action = super(RmaMakePicking, self)._get_action( - pickings, procurements) - return action + if len(po_list): + action = self.env.ref('purchase.purchase_rfq') + result = action.read()[0] + result['domain'] = [('id', 'in', po_list)] + return result + else: + action = super(RmaMakePicking, self)._get_action(pickings, + procurements) + return action class RmaMakePickingItem(models.TransientModel): From 9eb3f3c1f8178b10cdd7caeaaec08a39806412f2 Mon Sep 17 00:00:00 2001 From: aaron Date: Fri, 25 May 2018 16:53:56 +0200 Subject: [PATCH 20/42] [IMP]name get when filling form purchase order lines Conflicts: rma_purchase/models/purchase_order_line.py --- rma_purchase/models/purchase_order_line.py | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/rma_purchase/models/purchase_order_line.py b/rma_purchase/models/purchase_order_line.py index c3db4433..be15088f 100644 --- a/rma_purchase/models/purchase_order_line.py +++ b/rma_purchase/models/purchase_order_line.py @@ -25,3 +25,24 @@ class PurchaseOrderLine(models.Model): return super(PurchaseOrderLine, self)._name_search( name='', args=args, operator=operator, limit=limit, name_get_uid=name_get_uid) + + @api.multi + def name_get(self): + res = [] + if self.env.context.get('rma'): + for purchase in self: + invoices = self.env['account.invoice.line'].search( + [('purchase_line_id', '=', purchase.id)]) + if purchase.order_id.name: + res.append((purchase.id, "%s %s %s qty:%s" % ( + purchase.order_id.name, + " ".join(str(x) for x in [ + inv.number for inv in invoices.mapped( + 'invoice_id')]), + purchase.product_id.name, purchase.product_qty))) + else: + res.append( + super(PurchaseOrderLine, purchase).name_get()[0]) + return res + else: + return super(PurchaseOrderLine, self).name_get() From e0647a73817764e16be81fad13bd7d2360bda248 Mon Sep 17 00:00:00 2001 From: Lois Rilo Date: Fri, 25 May 2018 16:30:36 +0200 Subject: [PATCH 21/42] [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)]"/>
+ + + + + + + + + From bd8da45abe4b222b600d4b6698cf5fae50d2d7f1 Mon Sep 17 00:00:00 2001 From: Bhavesh Odedra Date: Fri, 20 Jul 2018 20:12:02 +0530 Subject: [PATCH 22/42] [IMP] code --- rma_purchase/models/purchase_order.py | 7 +-- rma_purchase/models/purchase_order_line.py | 6 +-- rma_purchase/models/rma_order_line.py | 51 +--------------------- rma_purchase/views/rma_order_line_view.xml | 6 --- 4 files changed, 5 insertions(+), 65 deletions(-) diff --git a/rma_purchase/models/purchase_order.py b/rma_purchase/models/purchase_order.py index 9ced8f41..a0991b1a 100644 --- a/rma_purchase/models/purchase_order.py +++ b/rma_purchase/models/purchase_order.py @@ -1,8 +1,7 @@ -# -*- 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 +from odoo import api, models class PurchaseOrder(models.Model): @@ -20,10 +19,8 @@ class PurchaseOrder(models.Model): }) line.onchange_product_id() line.update({ - 'product_qty': rma_line.qty_to_purchase, + 'product_qty': rma_line.product_qty, '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 c858d122..fe08f86b 100644 --- a/rma_purchase/models/purchase_order_line.py +++ b/rma_purchase/models/purchase_order_line.py @@ -1,16 +1,12 @@ # Copyright 2017 Eficent Business and IT Consulting Services S.L. # License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html) -from odoo import api, models +from odoo import api, fields, 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', ) diff --git a/rma_purchase/models/rma_order_line.py b/rma_purchase/models/rma_order_line.py index 63da1482..1a8ee88b 100644 --- a/rma_purchase/models/rma_order_line.py +++ b/rma_purchase/models/rma_order_line.py @@ -11,14 +11,8 @@ class RmaOrderLine(models.Model): @api.multi def _compute_purchase_count(self): for rec in self: - 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'))) + rec.purchase_count = len(self.env['purchase.order'].search( + [('origin', 'ilike', rec.name)]).ids) @api.multi def _compute_purchase_order_lines(self): @@ -30,20 +24,6 @@ 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', ) @@ -75,16 +55,6 @@ class RmaOrderLine(models.Model): 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): @@ -180,20 +150,3 @@ class RmaOrderLine(models.Model): 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_order_line_view.xml b/rma_purchase/views/rma_order_line_view.xml index fb8926e9..23818b65 100644 --- a/rma_purchase/views/rma_order_line_view.xml +++ b/rma_purchase/views/rma_order_line_view.xml @@ -35,12 +35,6 @@ ('order_id.partner_id', '=', partner_id), ('order_id.partner_id', 'child_of', partner_id)]"/>
- - - - - - From dc2f9f87719d853323397fdc910b8cc7b8c3954e Mon Sep 17 00:00:00 2001 From: Bhavesh Odedra Date: Fri, 20 Jul 2018 20:30:20 +0530 Subject: [PATCH 23/42] [IMP] rma_operation --- rma_purchase/models/rma_operation.py | 5 ++--- rma_purchase/views/rma_operation_view.xml | 2 +- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/rma_purchase/models/rma_operation.py b/rma_purchase/models/rma_operation.py index 51ed3cdd..3892bad3 100644 --- a/rma_purchase/models/rma_operation.py +++ b/rma_purchase/models/rma_operation.py @@ -1,9 +1,8 @@ -# -*- 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 +from odoo import api, models, _ +from odoo.exceptions import ValidationError class RmaOperation(models.Model): diff --git a/rma_purchase/views/rma_operation_view.xml b/rma_purchase/views/rma_operation_view.xml index 9f4b5a86..1afff91d 100644 --- a/rma_purchase/views/rma_operation_view.xml +++ b/rma_purchase/views/rma_operation_view.xml @@ -1,4 +1,4 @@ - + From 0446f414d1f7c4abb4ad9ed1d3a453a597a2c8cb Mon Sep 17 00:00:00 2001 From: Bhavesh Odedra Date: Sun, 22 Jul 2018 13:13:07 +0530 Subject: [PATCH 24/42] Revert "[IMP] code" This reverts commit dfa54dadc9ee5c3946e86b4521474afb764d6710. --- rma_purchase/models/purchase_order.py | 7 ++- rma_purchase/models/purchase_order_line.py | 6 ++- rma_purchase/models/rma_order_line.py | 51 +++++++++++++++++++++- rma_purchase/views/rma_order_line_view.xml | 6 +++ 4 files changed, 65 insertions(+), 5 deletions(-) diff --git a/rma_purchase/models/purchase_order.py b/rma_purchase/models/purchase_order.py index a0991b1a..9ced8f41 100644 --- a/rma_purchase/models/purchase_order.py +++ b/rma_purchase/models/purchase_order.py @@ -1,7 +1,8 @@ +# -*- 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 odoo import api, models +from openerp import api, fields, models class PurchaseOrder(models.Model): @@ -19,8 +20,10 @@ class PurchaseOrder(models.Model): }) line.onchange_product_id() line.update({ - 'product_qty': rma_line.product_qty, + '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 fe08f86b..c858d122 100644 --- a/rma_purchase/models/purchase_order_line.py +++ b/rma_purchase/models/purchase_order_line.py @@ -1,12 +1,16 @@ # Copyright 2017 Eficent Business and IT Consulting Services S.L. # License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html) -from odoo import api, fields, models +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', ) diff --git a/rma_purchase/models/rma_order_line.py b/rma_purchase/models/rma_order_line.py index 1a8ee88b..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', ) @@ -55,6 +75,16 @@ class RmaOrderLine(models.Model): 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): @@ -150,3 +180,20 @@ class RmaOrderLine(models.Model): 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_order_line_view.xml b/rma_purchase/views/rma_order_line_view.xml index 23818b65..fb8926e9 100644 --- a/rma_purchase/views/rma_order_line_view.xml +++ b/rma_purchase/views/rma_order_line_view.xml @@ -35,6 +35,12 @@ ('order_id.partner_id', '=', partner_id), ('order_id.partner_id', 'child_of', partner_id)]"/> + + + + + + From d59834f518dff5f4a5dc7f0266195afcb6d6ff04 Mon Sep 17 00:00:00 2001 From: Bhavesh Odedra Date: Sun, 22 Jul 2018 13:15:55 +0530 Subject: [PATCH 25/42] Revert "[IMP] rma_operation" This reverts commit 044bb2461acdb88e1ef98b1563e5ea7cb354918c. --- rma_purchase/models/rma_operation.py | 5 +++-- rma_purchase/views/rma_operation_view.xml | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/rma_purchase/models/rma_operation.py b/rma_purchase/models/rma_operation.py index 3892bad3..51ed3cdd 100644 --- a/rma_purchase/models/rma_operation.py +++ b/rma_purchase/models/rma_operation.py @@ -1,8 +1,9 @@ +# -*- 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 odoo import api, models, _ -from odoo.exceptions import ValidationError +from openerp import api, fields, models, _ +from openerp.exceptions import ValidationError class RmaOperation(models.Model): diff --git a/rma_purchase/views/rma_operation_view.xml b/rma_purchase/views/rma_operation_view.xml index 1afff91d..9f4b5a86 100644 --- a/rma_purchase/views/rma_operation_view.xml +++ b/rma_purchase/views/rma_operation_view.xml @@ -1,4 +1,4 @@ - + From 7b4e40d959a7fc73d7b8185761e4dc507fcccada Mon Sep 17 00:00:00 2001 From: Bhavesh Odedra Date: Sun, 22 Jul 2018 16:02:54 +0530 Subject: [PATCH 26/42] [MIG] Purchase policy --- rma_purchase/models/purchase_order.py | 5 +-- rma_purchase/models/purchase_order_line.py | 6 +--- rma_purchase/models/rma_operation.py | 5 ++- rma_purchase/models/rma_order.py | 10 ++++-- rma_purchase/models/rma_order_line.py | 39 +++++++--------------- rma_purchase/views/rma_operation_view.xml | 2 +- 6 files changed, 25 insertions(+), 42 deletions(-) diff --git a/rma_purchase/models/purchase_order.py b/rma_purchase/models/purchase_order.py index 9ced8f41..66ec0277 100644 --- a/rma_purchase/models/purchase_order.py +++ b/rma_purchase/models/purchase_order.py @@ -1,8 +1,7 @@ -# -*- 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 +from odoo import api, models class PurchaseOrder(models.Model): @@ -24,6 +23,4 @@ class PurchaseOrder(models.Model): '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 c858d122..fe08f86b 100644 --- a/rma_purchase/models/purchase_order_line.py +++ b/rma_purchase/models/purchase_order_line.py @@ -1,16 +1,12 @@ # Copyright 2017 Eficent Business and IT Consulting Services S.L. # License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html) -from odoo import api, models +from odoo import api, fields, 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', ) diff --git a/rma_purchase/models/rma_operation.py b/rma_purchase/models/rma_operation.py index 51ed3cdd..8665dba6 100644 --- a/rma_purchase/models/rma_operation.py +++ b/rma_purchase/models/rma_operation.py @@ -1,9 +1,8 @@ -# -*- 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 +from odoo import api, fields, models, _ +from odoo.exceptions import ValidationError class RmaOperation(models.Model): diff --git a/rma_purchase/models/rma_order.py b/rma_purchase/models/rma_order.py index 12ad7076..d13b1d22 100644 --- a/rma_purchase/models/rma_order.py +++ b/rma_purchase/models/rma_order.py @@ -12,9 +12,12 @@ class RmaOrder(models.Model): def _compute_po_count(self): for rec in self: po_count = 0 + rma_line_po = [] for line in rec.rma_line_ids: - po_count += len(self.env['purchase.order'].search( - [('origin', '=', line.name)]).ids) + rma_line_po += self.env['purchase.order'].search( + [('origin', '=', line.name)]).ids + if rma_line_po: + po_count = len(list(set(rma_line_po))) rec.po_count = po_count @api.multi @@ -35,6 +38,9 @@ class RmaOrder(models.Model): result = action.read()[0] po_ids = self.env['purchase.order'].search( [('origin', '=', self.name)]).ids + for line in self.rma_line_ids: + po_ids += self.env['purchase.order'].search( + [('origin', '=', line.name)]).ids if not po_ids: raise ValidationError(_("No purchase order found!")) result['domain'] = [('id', 'in', po_ids)] diff --git a/rma_purchase/models/rma_order_line.py b/rma_purchase/models/rma_order_line.py index 63da1482..26351978 100644 --- a/rma_purchase/models/rma_order_line.py +++ b/rma_purchase/models/rma_order_line.py @@ -3,6 +3,7 @@ from odoo import api, fields, models, _ from odoo.exceptions import ValidationError +from odoo.addons import decimal_precision as dp class RmaOrderLine(models.Model): @@ -11,29 +12,19 @@ class RmaOrderLine(models.Model): @api.multi def _compute_purchase_count(self): for rec in self: - 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'))) + rec.purchase_count = len(self.env['purchase.order'].search( + [('origin', 'ilike', rec.name)]).ids) @api.multi def _compute_purchase_order_lines(self): for rec in self: purchase_list = [] - for purchase in self.env['purchase.order'].search( - [('origin', 'ilike', rec.name)]): - for line in purchase.order_line: - purchase_list.append(line.id) + for line in self.env['purchase.order.line'].search( + [('rma_line_id', '=', rec.id)]): + 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() @@ -78,12 +69,12 @@ class RmaOrderLine(models.Model): 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, + readonly=True, compute='_compute_qty_purchase' ) 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, + readonly=True, compute='_compute_qty_purchase' ) @api.onchange('operation_id') @@ -176,8 +167,7 @@ class RmaOrderLine(models.Model): 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') + orders = self.mapped('purchase_order_line_ids.order_id') result['domain'] = [('id', 'in', orders.ids)] return result @@ -187,13 +177,8 @@ class RmaOrderLine(models.Model): 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( + for line in self.purchase_order_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) + qty += self.uom_id._compute_quantity( + line.product_qty, line.product_uom) return qty diff --git a/rma_purchase/views/rma_operation_view.xml b/rma_purchase/views/rma_operation_view.xml index 9f4b5a86..1afff91d 100644 --- a/rma_purchase/views/rma_operation_view.xml +++ b/rma_purchase/views/rma_operation_view.xml @@ -1,4 +1,4 @@ - + From aa1954a9e9bf0398521274b0cb14b23ae37e6e4a Mon Sep 17 00:00:00 2001 From: Bhavesh Odedra Date: Thu, 26 Jul 2018 11:22:07 +0530 Subject: [PATCH 27/42] [RM] ValidationError message if there is no purchase order found --- rma_purchase/models/rma_order.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/rma_purchase/models/rma_order.py b/rma_purchase/models/rma_order.py index d13b1d22..8b5b8dc3 100644 --- a/rma_purchase/models/rma_order.py +++ b/rma_purchase/models/rma_order.py @@ -41,8 +41,6 @@ class RmaOrder(models.Model): for line in self.rma_line_ids: po_ids += self.env['purchase.order'].search( [('origin', '=', line.name)]).ids - if not po_ids: - raise ValidationError(_("No purchase order found!")) result['domain'] = [('id', 'in', po_ids)] return result @@ -52,7 +50,5 @@ class RmaOrder(models.Model): result = action.read()[0] po_ids = self.mapped( 'rma_line_ids.purchase_order_line_id.order_id').ids - if not po_ids: - raise ValidationError(_("No purchase order found!")) result['domain'] = [('id', 'in', po_ids)] return result From 6fe4f58fa32120651496e06791a241856d14b4f6 Mon Sep 17 00:00:00 2001 From: Bhavesh Odedra Date: Thu, 26 Jul 2018 11:28:48 +0530 Subject: [PATCH 28/42] [FIX] flake8 --- rma_purchase/models/rma_order.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/rma_purchase/models/rma_order.py b/rma_purchase/models/rma_order.py index 8b5b8dc3..d9fdcbf4 100644 --- a/rma_purchase/models/rma_order.py +++ b/rma_purchase/models/rma_order.py @@ -1,8 +1,7 @@ # © 2017 Eficent Business and IT Consulting Services S.L. # License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html) -from odoo import api, fields, models, _ -from odoo.exceptions import ValidationError +from odoo import api, fields, models class RmaOrder(models.Model): From ff9e003134cee45f6dff2df7244d390da1303fa7 Mon Sep 17 00:00:00 2001 From: Bhavesh Odedra Date: Fri, 27 Jul 2018 11:06:36 +0530 Subject: [PATCH 29/42] [FIX] issue of name_get purchase order line id --- rma_purchase/views/rma_order_line_view.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/rma_purchase/views/rma_order_line_view.xml b/rma_purchase/views/rma_order_line_view.xml index fb8926e9..a689d2fc 100644 --- a/rma_purchase/views/rma_order_line_view.xml +++ b/rma_purchase/views/rma_order_line_view.xml @@ -31,6 +31,7 @@ From 2b5f8d9a0c52f14e0f17e39eea122f9bec6a8327 Mon Sep 17 00:00:00 2001 From: aheficent Date: Fri, 27 Jul 2018 13:04:12 +0200 Subject: [PATCH 30/42] [IMP]create PO from wizard --- rma_purchase/__manifest__.py | 3 +- rma_purchase/views/rma_order_line_view.xml | 2 +- rma_purchase/wizards/__init__.py | 1 + .../rma_order_line_make_purchase_order.py | 146 ++++++++++++++++++ ...ma_order_line_make_purchase_order_view.xml | 61 ++++++++ 5 files changed, 211 insertions(+), 2 deletions(-) create mode 100644 rma_purchase/wizards/rma_order_line_make_purchase_order.py create mode 100644 rma_purchase/wizards/rma_order_line_make_purchase_order_view.xml diff --git a/rma_purchase/__manifest__.py b/rma_purchase/__manifest__.py index 70a5c252..a5a27eb1 100644 --- a/rma_purchase/__manifest__.py +++ b/rma_purchase/__manifest__.py @@ -11,11 +11,12 @@ 'website': 'http://www.github.com/OCA/rma', 'depends': ['rma_account', 'purchase'], 'data': [ + 'wizards/rma_order_line_make_purchase_order_view.xml', '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' + 'wizards/rma_add_purchase.xml', ], 'installable': True, 'auto_install': True, diff --git a/rma_purchase/views/rma_order_line_view.xml b/rma_purchase/views/rma_order_line_view.xml index a689d2fc..86dda2e6 100644 --- a/rma_purchase/views/rma_order_line_view.xml +++ b/rma_purchase/views/rma_order_line_view.xml @@ -15,7 +15,7 @@
- + Date: Fri, 27 Jul 2018 17:42:59 +0530 Subject: [PATCH 32/42] [ENH] change from customer to supplier domain and lable in Purchase wizard --- .../rma_order_line_make_purchase_order.py | 17 +++++++---------- .../rma_order_line_make_purchase_order_view.xml | 2 +- 2 files changed, 8 insertions(+), 11 deletions(-) diff --git a/rma_purchase/wizards/rma_order_line_make_purchase_order.py b/rma_purchase/wizards/rma_order_line_make_purchase_order.py index 8bd10ff1..f5f41ba8 100644 --- a/rma_purchase/wizards/rma_order_line_make_purchase_order.py +++ b/rma_purchase/wizards/rma_order_line_make_purchase_order.py @@ -2,8 +2,8 @@ # License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl-3.0). import odoo.addons.decimal_precision as dp -from odoo import _, api, exceptions, fields, models -from odoo.tools import DEFAULT_SERVER_DATETIME_FORMAT +from odoo import fields, models, api, _, exceptions +from odoo.tools import DEFAULT_SERVER_DATETIME_FORMAT as DF from datetime import datetime @@ -12,8 +12,8 @@ class RmaLineMakePurchaseOrder(models.TransientModel): _description = "Make Purchases Order from RMA Line" partner_id = fields.Many2one( - comodel_name='res.partner', string='Customer', required=False, - domain=[('customer', '=', True)]) + comodel_name='res.partner', string='Supplier', required=False, + domain=[('supplier', '=', True)]) item_ids = fields.One2many( comodel_name='rma.order.line.make.purchase.order.item', inverse_name='wiz_id', string='Items') @@ -69,7 +69,7 @@ class RmaLineMakePurchaseOrder(models.TransientModel): 'origin': '', 'partner_id': supplier.id, 'company_id': item.line_id.company_id.id, - } + } return data @api.model @@ -80,8 +80,7 @@ class RmaLineMakePurchaseOrder(models.TransientModel): 'order_id': po.id, 'product_id': product.id, 'price_unit': item.line_id.price_unit, - 'date_planned': datetime.today().strftime( - DEFAULT_SERVER_DATETIME_FORMAT), + 'date_planned': datetime.today().strftime(DF), 'product_uom': product.uom_po_id.id, 'product_qty': item.product_qty, 'rma_line_id': item.line_id.id @@ -95,15 +94,13 @@ class RmaLineMakePurchaseOrder(models.TransientModel): res = [] purchase_obj = self.env['purchase.order'] po_line_obj = self.env['purchase.order.line'] - purchase = False for item in self.item_ids: if item.product_qty <= 0.0: raise exceptions.Warning( _('Enter a positive quantity.')) - if self.purchase_order_id: - purchase = self.purchase_order_id + purchase = self.purchase_order_id if not purchase: po_data = self._prepare_purchase_order(item) purchase = purchase_obj.create(po_data) diff --git a/rma_purchase/wizards/rma_order_line_make_purchase_order_view.xml b/rma_purchase/wizards/rma_order_line_make_purchase_order_view.xml index d5475da4..48455623 100644 --- a/rma_purchase/wizards/rma_order_line_make_purchase_order_view.xml +++ b/rma_purchase/wizards/rma_order_line_make_purchase_order_view.xml @@ -1,4 +1,4 @@ - + RMA Line Make Purchase Order From 093a6258e0ff1d0aec6b8d46faf891445db83b16 Mon Sep 17 00:00:00 2001 From: Bhavesh Odedra Date: Fri, 27 Jul 2018 18:14:41 +0530 Subject: [PATCH 33/42] [ENH] make supplier readonly in Create Purchase Order wizard --- .../wizards/rma_order_line_make_purchase_order.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/rma_purchase/wizards/rma_order_line_make_purchase_order.py b/rma_purchase/wizards/rma_order_line_make_purchase_order.py index f5f41ba8..4d1c227d 100644 --- a/rma_purchase/wizards/rma_order_line_make_purchase_order.py +++ b/rma_purchase/wizards/rma_order_line_make_purchase_order.py @@ -13,7 +13,7 @@ class RmaLineMakePurchaseOrder(models.TransientModel): partner_id = fields.Many2one( comodel_name='res.partner', string='Supplier', required=False, - domain=[('supplier', '=', True)]) + domain=[('supplier', '=', True)], readonly=1) item_ids = fields.One2many( comodel_name='rma.order.line.make.purchase.order.item', inverse_name='wiz_id', string='Items') @@ -49,9 +49,9 @@ class RmaLineMakePurchaseOrder(models.TransientModel): lines = rma_line_obj.browse(rma_line_ids) for line in lines: items.append([0, 0, self._prepare_item(line)]) - customers = lines.mapped('partner_id') - if len(customers) == 1: - res['partner_id'] = customers.id + suppliers = lines.mapped('partner_id') + if len(suppliers) == 1: + res['partner_id'] = suppliers.id else: raise exceptions.Warning( _('Only RMA lines from the same partner can be processed at ' From f98fc3d3b111dda46f3f67f12eb823f870747b20 Mon Sep 17 00:00:00 2001 From: Lois Rilo Date: Thu, 17 May 2018 14:03:51 +0200 Subject: [PATCH 34/42] [9.0][REW] rma_purchase: complete rework of tests --- rma_purchase/tests/__init__.py | 6 +- rma_purchase/tests/test_rma.py | 456 ------------------------ rma_purchase/tests/test_rma_dropship.py | 105 ------ rma_purchase/tests/test_rma_purchase.py | 94 +++++ rma_purchase/tests/test_supplier_rma.py | 138 ------- 5 files changed, 96 insertions(+), 703 deletions(-) delete mode 100644 rma_purchase/tests/test_rma.py delete mode 100644 rma_purchase/tests/test_rma_dropship.py create mode 100644 rma_purchase/tests/test_rma_purchase.py delete mode 100644 rma_purchase/tests/test_supplier_rma.py diff --git a/rma_purchase/tests/__init__.py b/rma_purchase/tests/__init__.py index fd0efa32..061a9ecc 100644 --- a/rma_purchase/tests/__init__.py +++ b/rma_purchase/tests/__init__.py @@ -1,6 +1,4 @@ -# © 2017 Eficent Business and IT Consulting Services S.L. +# Copyright 2018 Eficent Business and IT Consulting Services S.L. # License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html) -from . import test_rma -from . import test_supplier_rma -from . import test_rma_dropship +from . import test_rma_purchase diff --git a/rma_purchase/tests/test_rma.py b/rma_purchase/tests/test_rma.py deleted file mode 100644 index f11d36b1..00000000 --- a/rma_purchase/tests/test_rma.py +++ /dev/null @@ -1,456 +0,0 @@ -# © 2017 Eficent Business and IT Consulting Services S.L. -# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html) - -from openerp.tests import common -from openerp import fields - - -class TestRma(common.TransactionCase): - - """ Test the routes and the quantities """ - - def setUp(self): - super(TestRma, self).setUp() - - self.rma_make_picking = self.env['rma_make_picking.wizard'] - self.make_supplier_rma = self.env["rma.order.line.make.supplier.rma"] - self.rma_add_stock_move = self.env['rma_add_stock_move'] - self.stockpicking = self.env['stock.picking'] - self.rma = self.env['rma.order'] - self.rma_line = self.env['rma.order.line'] - self.rma_op = self.env['rma.operation'] - self.rma_cust_replace_op_id = self.env.ref( - 'rma.rma_operation_customer_replace') - self.rma_sup_replace_op_id = self.env.ref( - 'rma.rma_operation_supplier_replace') - self.product_id = self.env.ref('product.product_product_4') - self.product_id.product_tmpl_id.categ_id.\ - property_stock_account_input_categ_id =\ - self.env.ref('account.data_account_type_receivable').id - self.product_id.product_tmpl_id.categ_id.\ - property_stock_account_output_categ_id =\ - self.env.ref('account.data_account_type_expenses').id - self.product_1 = self.env.ref('product.product_product_25') - self.product_2 = self.env.ref('product.product_product_7') - self.product_3 = self.env.ref('product.product_product_11') - self.uom_unit = self.env.ref('product.product_uom_unit') - # assign an operation - self.product_1.write( - {'rma_customer_operation_id': self.rma_cust_replace_op_id.id, - 'rma_supplier_operation_id': self.rma_sup_replace_op_id.id}) - self.product_2.write( - {'rma_customer_operation_id': self.rma_cust_replace_op_id.id, - 'rma_supplier_operation_id': self.rma_sup_replace_op_id.id}) - self.product_3.write( - {'rma_customer_operation_id': self.rma_cust_replace_op_id.id, - 'rma_supplier_operation_id': self.rma_sup_replace_op_id.id}) - self.partner_id = self.env.ref('base.res_partner_12') - self.stock_location = self.env.ref('stock.stock_location_stock') - self.stock_rma_location = self.env.ref('rma.location_rma') - self.customer_location = self.env.ref( - 'stock.stock_location_customers') - self.supplier_location = self.env.ref( - 'stock.stock_location_suppliers') - self.product_uom_id = self.env.ref('product.product_uom_unit') - products2move = [(self.product_1, 3), (self.product_2, 5), - (self.product_3, 2)] - self.rma_customer_id = self._create_rma_from_move( - products2move, 'customer', self.env.ref('base.res_partner_2'), - dropship=False) - - def _create_picking(self, partner): - return self.stockpicking.create({ - 'partner_id': partner.id, - 'picking_type_id': self.env.ref('stock.picking_type_in').id, - 'location_id': self.stock_location.id, - 'location_dest_id': self.supplier_location.id - }) - - def _create_rma_from_move(self, products2move, type, partner, dropship, - supplier_address_id=None): - picking_in = self._create_picking(partner) - - moves = [] - if type == 'customer': - for item in products2move: - move_values = self._prepare_move( - item[0], item[1], self.stock_location, - self.customer_location, picking_in) - moves.append(self.env['stock.move'].create(move_values)) - else: - for item in products2move: - move_values = self._prepare_move( - item[0], item[1], self.supplier_location, - self.stock_rma_location, picking_in) - moves.append(self.env['stock.move'].create(move_values)) - # Create the RMA from the stock_move - rma_id = self.rma.create( - { - 'reference': '0001', - 'type': type, - 'partner_id': partner.id, - 'company_id': self.env.ref('base.main_company').id - }) - rma_id._compute_invoice_refund_count() - rma_id._compute_invoice_count() - - data = {'add_invoice_id': self._create_invoice().id} - new_line = self.rma.new(data) - new_line.on_change_invoice() - - rma_id.action_view_invoice_refund() - rma_id.action_view_invoice() - - for move in moves: - if type == 'customer': - wizard = self.rma_add_stock_move.new( - {'stock_move_id': move.id, 'customer': True, - 'active_ids': rma_id.id, - 'partner_id': move.partner_id.id, - 'active_model': 'rma.order', - } - ) - wizard.with_context({ - 'stock_move_id': move.id, 'customer': True, - 'active_ids': rma_id.id, - 'partner_id': move.partner_id.id, - 'active_model': 'rma.order', - }) - data = wizard.with_context(customer=1).\ - _prepare_rma_line_from_stock_move(move) - data['partner_id'] = move.partner_id.id - else: - wizard = self.rma_add_stock_move.new( - {'stock_move_id': move.id, 'supplier': True, - 'active_ids': rma_id.id, - 'partner_id': move.partner_id.id, - 'active_model': 'rma.order', - } - ) - wizard.with_context( - {'stock_move_id': move.id, 'supplier': True, - 'active_ids': rma_id.id, - 'partner_id': move.partner_id.id, - 'active_model': 'rma.order', - }) - data = wizard._prepare_rma_line_from_stock_move(move) - data['partner_id'] = move.partner_id.id - if dropship: - data.update(customer_to_supplier=dropship, - supplier_address_id=supplier_address_id.id) - data['partner_id'] = move.partner_id.id - data['rma_id'] = rma_id.id - self.line = self.rma_line.create(data) - # approve the RMA Line - self.rma_line.action_rma_to_approve() - - self.line.action_rma_approve() - self.line.action_view_invoice() - self.line.action_view_refunds() - - # approve the RMA -# rma_id.action_rma_to_approve() -# rma_id.action_rma_approve() - return rma_id - - def _prepare_move(self, product, qty, src, dest, picking_in): - res = { - 'partner_id': self.partner_id.id, - 'product_id': product.id, - 'name': product.partner_ref, - 'state': 'confirmed', - 'product_uom': self.product_uom_id.id or product.uom_id.id, - 'product_uom_qty': qty, - 'origin': 'Test RMA', - 'location_id': src.id, - 'location_dest_id': dest.id, - 'picking_id': picking_in.id - } - return res - - def test_rma_refund(self): - - self.rma_refund_item = self.env['rma.refund.item'] - self.rma_refund = self.env['rma.refund'] - - self.product_id.income =\ - self.env.ref('account.data_account_type_receivable').id - self.product_id.expense =\ - self.env.ref('account.data_account_type_expenses').id - - for line in self.rma_customer_id.rma_line_ids: - line.refund_policy = 'ordered' - - refund = self.rma_refund.with_context({ - 'active_ids': self.rma_customer_id.rma_line_ids.ids, - 'active_model': 'rma.order.line', - 'active_id': 1 - }).create({'description': 'Test Reason', - 'date_invoice': fields.datetime.now() - }) - self.rma_refund_item.create({ - 'line_id': self.rma_customer_id.rma_line_ids[0].id, - 'rma_id': self.rma_customer_id.id, - 'product_id': self.product_id.id, - 'name': 'Test RMA Refund', - 'product_qty': self.rma_customer_id.rma_line_ids[0].product_qty, - 'wiz_id': refund.id - }) - refund.invoice_refund() - - def test_rma_add_invoice_wizard(self): - - wizard = self.env['rma_add_invoice'].with_context({ - 'active_ids': self.rma_customer_id.ids, - 'active_model': 'rma.order', - 'active_id': self.rma_customer_id.id - }).create({'partner_id': self.partner_id.id, - 'rma_id': self.rma_customer_id.id, - 'invoice_line_ids': - [(6, 0, [self._create_invoice().invoice_line_ids.id])], - }) - wizard.add_lines() - - def _create_invoice(self): - self.Account = self.env['account.account'] - self.AccountInvoice = self.env['account.invoice'] - self.AccountInvoiceLine = self.env['account.invoice.line'] - - self.account_receivable =\ - self.env.ref('account.data_account_type_receivable') - self.account_expenses =\ - self.env.ref('account.data_account_type_expenses') - invoice_account = self.Account.\ - search([('user_type_id', '=', self.account_receivable.id)], limit=1 - ).id - invoice_line_account = self.Account.\ - search([('user_type_id', '=', self.account_expenses.id)], limit=1 - ).id - - invoice = self.AccountInvoice.create({ - 'partner_id': self.partner_id.id, - 'account_id': invoice_account, - 'type': 'in_invoice', - }) - - invoice_line = self.AccountInvoiceLine.create({ - 'product_id': self.product_1.id, - 'quantity': 1.0, - 'price_unit': 100.0, - 'invoice_id': invoice.id, - 'uom_id': 1, - 'name': 'product that cost 100', - 'account_id': invoice_line_account, - }) - invoice._compute_rma_count() - invoice_line._compute_rma_count() - invoice.action_view_rma_customer() - invoice.action_view_rma_supplier() - return invoice - - def test_rma_make_picking(self): - - wizard = self.rma_make_picking.with_context({ - 'active_ids': self.rma_customer_id.rma_line_ids.ids, - 'active_model': 'rma.order.line', - 'picking_type': 'incoming', - 'active_id': 1 - }).create({}) - - wizard.action_create_picking() - data = {'purchase_order_line_id': - self._create_purchase_order().order_line.id} - new_line = self.rma_line.new(data) - new_line._onchange_purchase_order_line_id() - - self.rma_customer_id._compute_po_count() - self.rma_customer_id._compute_origin_po_count() - - self.rma_customer_id.action_view_origin_purchase_order() - - self.rma_customer_id.rma_line_ids[0]._compute_purchase_count() - self.rma_customer_id.rma_line_ids[0]._compute_purchase_order_lines() - - def test_rma_add_purchase_wizard(self): - wizard = self.env['rma_add_purchase'].with_context({ - 'active_ids': self.rma_customer_id.ids, - 'active_model': 'rma.order', - 'active_id': self.rma_customer_id.id - }).create({'partner_id': self.partner_id.id, - 'rma_id': self.rma_customer_id.id, - 'purchase_id': self._create_purchase_order().id, - 'purchase_line_ids': - [(6, 0, [self._create_purchase_order().order_line.id])], - }) - wizard.default_get([str(self._create_purchase_order().id), - str(self._create_purchase_order().order_line.id), - str(self.partner_id.id)]) - wizard.add_lines() - - def _create_purchase_order(self): - purchase_order_id = self.env["purchase.order"].create({ - "partner_id": self.partner_id.id, - "order_line": [ - (0, 0, { - "product_id": self.product_id.id, - "name": self.product_id.name, - "product_qty": 5, - "price_unit": 100, - "product_uom": self.product_id.uom_id.id, - "date_planned": fields.datetime.now(), - }), - ], - }) - self.env["purchase.order.line"].\ - name_search(name=self.product_id.name, operator='ilike', - args=[('id', 'in', purchase_order_id.order_line.ids)]) - self.env["purchase.order.line"].\ - _name_search(name=self.product_id.name, operator='ilike', - args=[('id', 'in', purchase_order_id.order_line.ids)]) - return purchase_order_id - - def test_customer_rma(self): - wizard = self.rma_make_picking.with_context({ - 'active_ids': self.rma_customer_id.rma_line_ids.ids, - 'active_model': 'rma.order.line', - 'picking_type': 'incoming', - 'active_id': 1 - }).create({}) - wizard._create_picking() - res = self.rma_customer_id.rma_line_ids.action_view_in_shipments() - self.assertTrue('res_id' in res, - "Incorrect number of pickings created") - picking = self.env['stock.picking'].browse(res['res_id']) - moves = picking.move_lines - self.assertEquals(len(moves), 3, - "Incorrect number of moves created") - for line in self.rma_customer_id.rma_line_ids: - # common qtys for all products - self.assertEquals(line.qty_received, 0, - "Wrong qty received") - self.assertEquals(line.qty_to_deliver, 0, - "Wrong qty to deliver") - self.assertEquals(line.qty_outgoing, 0, - "Wrong qty outgoing") - self.assertEquals(line.qty_delivered, 0, - "Wrong qty delivered") - # product specific - if line.product_id == self.product_1: - self.assertEquals(line.qty_to_receive, 3, - "Wrong qty to receive") - self.assertEquals(line.qty_incoming, 3, - "Wrong qty incoming") - if line.product_id == self.product_2: - self.assertEquals(line.qty_to_receive, 5, - "Wrong qty to receive") - self.assertEquals(line.qty_incoming, 5, - "Wrong qty incoming") - if line.product_id == self.product_3: - self.assertEquals(line.qty_to_receive, 2, - "Wrong qty to receive") - self.assertEquals(line.qty_incoming, 2, - "Wrong qty incoming") - picking.action_confirm() - picking.action_assign() - for line in picking.move_line_ids: - line.qty_done = line.product_uom_qty - picking.action_done() - for line in self.rma_customer_id.rma_line_ids: - self.assertEquals(line.qty_to_receive, 0, - "Wrong qty to_receive") - self.assertEquals(line.qty_incoming, 0, - "Wrong qty incoming") - self.assertEquals(line.qty_outgoing, 0, - "Wrong qty outgoing") - self.assertEquals(line.qty_delivered, 0, - "Wrong qty delivered") - if line.product_id == self.product_1: - self.assertEquals(line.qty_received, 3, - "Wrong qty received") - self.assertEquals(line.qty_to_deliver, 3, - "Wrong qty to_deliver") - if line.product_id == self.product_2: - self.assertEquals(line.qty_received, 5, - "Wrong qty received") - self.assertEquals(line.qty_to_deliver, 5, - "Wrong qty to_deliver") - if line.product_id == self.product_3: - self.assertEquals(line.qty_received, 2, - "Wrong qty received") - self.assertEquals(line.qty_to_deliver, 2, - "Wrong qty to_deliver") - - wizard = self.rma_make_picking.with_context({ - 'active_id': 1, - 'active_ids': self.rma_customer_id.rma_line_ids.ids, - 'active_model': 'rma.order.line', - 'picking_type': 'outgoing', - }).create({}) - wizard._create_picking() - res = self.rma_customer_id.rma_line_ids.action_view_out_shipments() - self.assertTrue('res_id' in res, - "Incorrect number of pickings created") - picking = self.env['stock.picking'].browse(res['res_id']) - moves = picking.move_lines - self.assertEquals(len(moves), 3, - "Incorrect number of moves created") - for line in self.rma_customer_id.rma_line_ids: - self.assertEquals(line.qty_to_receive, 0, - "Wrong qty to receive") - self.assertEquals(line.qty_incoming, 0, - "Wrong qty incoming") - self.assertEquals(line.qty_delivered, 0, - "Wrong qty delivered") - if line.product_id == self.product_1: - self.assertEquals(line.qty_to_deliver, 3, - "Wrong qty to deliver") - self.assertEquals(line.qty_outgoing, 3, - "Wrong qty outgoing") - self.assertEquals(line.qty_received, 3, - "Wrong qty received") - if line.product_id == self.product_2: - self.assertEquals(line.qty_received, 5, - "Wrong qty received") - self.assertEquals(line.qty_to_deliver, 5, - "Wrong qty to deliver") - self.assertEquals(line.qty_outgoing, 5, - "Wrong qty outgoing") - if line.product_id == self.product_3: - self.assertEquals(line.qty_received, 2, - "Wrong qty received") - self.assertEquals(line.qty_to_deliver, 2, - "Wrong qty to deliver") - self.assertEquals(line.qty_outgoing, 2, - "Wrong qty outgoing") - picking.action_confirm() - picking.action_assign() - for line in picking.move_line_ids: - line.qty_done = line.product_uom_qty - picking.action_done() - for line in self.rma_customer_id.rma_line_ids: - self.assertEquals(line.qty_to_receive, 0, - "Wrong qty to receive") - self.assertEquals(line.qty_incoming, 0, - "Wrong qty incoming") - self.assertEquals(line.qty_to_deliver, 0, - "Wrong qty to deliver") - self.assertEquals(line.qty_outgoing, 0, - "Wrong qty outgoing") - if line.product_id == self.product_1: - self.assertEquals(line.qty_received, 3, - "Wrong qty received") - self.assertEquals(line.qty_delivered, 3, - "Wrong qty delivered") - if line.product_id == self.product_2: - self.assertEquals(line.qty_received, 5, - "Wrong qty received") - self.assertEquals(line.qty_delivered, 5, - "Wrong qty delivered") - if line.product_id == self.product_3: - self.assertEquals(line.qty_received, 2, - "Wrong qty received") - self.assertEquals(line.qty_delivered, 2, - "Wrong qty delivered") - self.line.action_rma_done() - self.assertEquals(self.line.state, 'done', - "Wrong State") diff --git a/rma_purchase/tests/test_rma_dropship.py b/rma_purchase/tests/test_rma_dropship.py deleted file mode 100644 index c469252d..00000000 --- a/rma_purchase/tests/test_rma_dropship.py +++ /dev/null @@ -1,105 +0,0 @@ -# © 2017 Eficent Business and IT Consulting Services S.L. -# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html) - -from openerp.addons.rma.tests import test_rma - - -class TestRmaDropship(test_rma.TestRma): - - def setUp(self): - super(TestRmaDropship, self).setUp() - self.product_id.write( - {'rma_customer_operation_id': self.rma_cust_replace_op_id.id, - 'rma_supplier_operation_id': self.rma_sup_replace_op_id.id}) - self.product_1.write( - {'rma_customer_operation_id': self.rma_cust_replace_op_id.id, - 'rma_supplier_operation_id': self.rma_sup_replace_op_id.id}) - self.product_2.write( - {'rma_customer_operation_id': self.rma_cust_replace_op_id.id, - 'rma_supplier_operation_id': self.rma_sup_replace_op_id.id}) - self.product_3.write( - {'rma_customer_operation_id': self.rma_cust_replace_op_id.id, - 'rma_supplier_operation_id': self.rma_sup_replace_op_id.id}) - products2move = [(self.product_1, 3), (self.product_2, 5), - (self.product_3, 2)] - self.rma_droship_id = self._create_rma_from_move( - products2move, 'customer', self.env.ref('base.res_partner_2'), - dropship=True, - supplier_address_id=self.env.ref('base.res_partner_3')) - - def test_dropship(self): - wizard = self.make_supplier_rma.with_context({ - 'active_ids': self.rma_droship_id.rma_line_ids.ids, - 'active_model': 'rma.order.line', - 'active_id': 1 - }).create({}) - res = wizard.make_supplier_rma() - supplier_rma = self.rma.browse(res['res_id']) - for line in supplier_rma.rma_line_ids: - line.action_rma_to_approve() - line.action_rma_approve() - wizard = self.rma_make_picking.with_context({ - 'active_id': 1, - 'active_ids': supplier_rma.rma_line_ids.ids, - 'active_model': 'rma.order.line', - 'picking_type': 'incoming', - }).create({}) - wizard._create_picking() - res = supplier_rma.rma_line_ids.action_view_in_shipments() - self.assertTrue('res_id' in res, - "Incorrect number of pickings created") - picking = self.env['stock.picking'].browse(res['res_id']) - moves = picking.move_lines - self.assertEquals(len(moves), 3, - "Incorrect number of moves created") - for line in supplier_rma.rma_line_ids: - # common qtys for all products - self.assertEquals(line.qty_received, 0, - "Wrong qty received") - self.assertEquals(line.qty_outgoing, 0, - "Wrong qty incoming") - self.assertEquals(line.qty_delivered, 0, - "Wrong qty delivered") - # product specific - if line.product_id == self.product_1: - self.assertEquals(line.qty_to_receive, 3, - "Wrong qty to receive") - self.assertEquals(line.qty_to_deliver, 3, - "Wrong qty to deliver") - self.assertEquals(line.qty_incoming, 3, - "Wrong qty outgoing") - if line.product_id == self.product_2: - self.assertEquals(line.qty_to_receive, 5, - "Wrong qty to receive") - self.assertEquals(line.qty_to_deliver, 5, - "Wrong qty to deliver") - self.assertEquals(line.qty_incoming, 5, - "Wrong qty outgoing") - if line.product_id == self.product_3: - self.assertEquals(line.qty_to_receive, 2, - "Wrong qty to receive") - self.assertEquals(line.qty_to_deliver, 2, - "Wrong qty to deliver") - self.assertEquals(line.qty_incoming, 2, - "Wrong qty outgoing") - - for line in self.rma_droship_id.rma_line_ids: - if line.product_id == self.product_1: - self.assertEquals(line.qty_to_supplier_rma, 0, - "Wrong qty to supplier rma") - self.assertEquals(line.qty_in_supplier_rma, 3, - "Wrong qty in supplier rma") - if line.product_id == self.product_2: - self.assertEquals(line.qty_to_supplier_rma, 0, - "Wrong qty to supplier rma") - self.assertEquals(line.qty_in_supplier_rma, 5, - "Wrong qty in supplier rma") - if line.product_id == self.product_3: - self.assertEquals(line.qty_to_supplier_rma, 0, - "Wrong qty to supplier rma") - self.assertEquals(line.qty_in_supplier_rma, 2, - "Wrong qty in supplier rma") - for line in self.rma_droship_id.rma_line_ids: - line.action_rma_done() - self.assertEquals(line.state, 'done', - "Wrong State") diff --git a/rma_purchase/tests/test_rma_purchase.py b/rma_purchase/tests/test_rma_purchase.py new file mode 100644 index 00000000..a165c1ba --- /dev/null +++ b/rma_purchase/tests/test_rma_purchase.py @@ -0,0 +1,94 @@ +# 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.tests import common +from openerp.fields import Datetime + + +class TestRmaPurchase(common.SingleTransactionCase): + + @classmethod + def setUpClass(cls): + super(TestRmaPurchase, cls).setUpClass() + + cls.rma_obj = cls.env['rma.order'] + cls.rma_line_obj = cls.env['rma.order.line'] + cls.rma_op_obj = cls.env['rma.operation'] + cls.rma_add_purchase_wiz = cls.env['rma_add_purchase'] + cls.po_obj = cls.env['purchase.order'] + cls.pol_obj = cls.env['purchase.order.line'] + cls.product_obj = cls.env['product.product'] + cls.partner_obj = cls.env['res.partner'] + + cls.rma_route_cust = cls.env.ref('rma.route_rma_customer') + + # Create supplier + supplier1 = cls.partner_obj.create({'name': 'Supplier 1'}) + + # Create products + cls.product_1 = cls.product_obj.create({ + 'name': 'Test Product 1', + 'type': 'product', + }) + cls.product_2 = cls.product_obj.create({ + 'name': 'Test Product 2', + 'type': 'product', + }) + + # Create PO: + cls.po = cls.po_obj.create({ + 'partner_id': supplier1.id, + }) + cls.pol_1 = cls.pol_obj.create({ + 'name': cls.product_1.name, + 'order_id': cls.po.id, + 'product_id': cls.product_1.id, + 'product_qty': 20.0, + 'product_uom': cls.product_1.uom_id.id, + 'price_unit': 100.0, + 'date_planned': Datetime.now(), + }) + cls.pol_2 = cls.pol_obj.create({ + 'name': cls.product_2.name, + 'order_id': cls.po.id, + 'product_id': cls.product_2.id, + 'product_qty': 18.0, + 'product_uom': cls.product_2.uom_id.id, + 'price_unit': 150.0, + 'date_planned': Datetime.now(), + }) + + # Create RMA group: + cls.rma_group = cls.rma_obj.create({ + 'partner_id': supplier1.id, + 'type': 'supplier', + }) + + def test_01_add_from_purchase_order(self): + """Test wizard to create supplier RMA from Purchase Orders.""" + self.assertEqual(self.rma_group.origin_po_count, 0) + add_purchase = self.rma_add_purchase_wiz.with_context({ + 'supplier': True, + 'active_ids': self.rma_group.id, + 'active_model': 'rma.order', + }).create({ + 'purchase_id': self.po.id, + 'purchase_line_ids': [(6, 0, self.po.order_line.ids)], + }) + add_purchase.add_lines() + self.assertEqual(len(self.rma_group.rma_line_ids), 2) + for t in self.rma_group.rma_line_ids.mapped('type'): + self.assertEqual(t, 'supplier') + self.assertEqual(self.rma_group.origin_po_count, 1) + + def test_02_fill_rma_from_po_line(self): + """Test filling a RMA (line) from a Purchase Order line.""" + rma = self.rma_line_obj.new({ + 'partner_id': self.po.partner_id.id, + 'purchase_order_line_id': self.pol_1.id, + 'type': 'supplier', + }) + self.assertFalse(rma.product_id) + rma._onchange_purchase_order_line_id() + self.assertEqual(rma.product_id, self.product_1) + self.assertEqual(rma.product_qty, 20.0) diff --git a/rma_purchase/tests/test_supplier_rma.py b/rma_purchase/tests/test_supplier_rma.py deleted file mode 100644 index f24dc7c5..00000000 --- a/rma_purchase/tests/test_supplier_rma.py +++ /dev/null @@ -1,138 +0,0 @@ -# © 2017 Eficent Business and IT Consulting Services S.L. -# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html) - -from openerp.addons.rma.tests import test_rma - - -class TestSupplierRma(test_rma.TestRma): - - def setUp(self): - super(TestSupplierRma, self).setUp() - products2move = [(self.product_1, 3), (self.product_2, 5), - (self.product_3, 2)] - self.rma_supplier_id = self._create_rma_from_move( - products2move, 'supplier', self.env.ref('base.res_partner_1'), - dropship=False) - - def test_supplier_rma(self): - wizard = self.rma_make_picking.with_context({ - 'active_ids': self.rma_supplier_id.rma_line_ids.ids, - 'active_model': 'rma.order.line', - 'picking_type': 'outgoing', - 'active_id': 1 - }).create({}) - wizard._create_picking() - res = self.rma_supplier_id.rma_line_ids.action_view_out_shipments() - self.assertTrue('res_id' in res, - "Incorrect number of pickings created") - picking = self.env['stock.picking'].browse(res['res_id']) - moves = picking.move_lines - self.assertEquals(len(moves), 3, - "Incorrect number of moves created") - for line in self.rma_supplier_id.rma_line_ids: - # common qtys for all products - self.assertEquals(line.qty_received, 0, - "Wrong qty received") - self.assertEquals(line.qty_incoming, 0, - "Wrong qty incoming") - self.assertEquals(line.qty_delivered, 0, - "Wrong qty delivered") - # product specific - if line.product_id == self.product_1: - self.assertEquals(line.qty_to_receive, 3, - "Wrong qty to receive") - self.assertEquals(line.qty_to_deliver, 3, - "Wrong qty to deliver") - self.assertEquals(line.qty_outgoing, 3, - "Wrong qty outgoing") - if line.product_id == self.product_2: - self.assertEquals(line.qty_to_receive, 5, - "Wrong qty to receive") - self.assertEquals(line.qty_to_deliver, 5, - "Wrong qty to deliver") - self.assertEquals(line.qty_outgoing, 5, - "Wrong qty outgoing") - if line.product_id == self.product_3: - self.assertEquals(line.qty_to_receive, 2, - "Wrong qty to receive") - self.assertEquals(line.qty_to_deliver, 2, - "Wrong qty to deliver") - self.assertEquals(line.qty_outgoing, 2, - "Wrong qty outgoing") - - picking.action_assign() - for line in picking.move_lines: - line.quantity_done = line.product_uom_qty - picking.button_validate() - for line in self.rma_supplier_id.rma_line_ids: - self.assertEquals(line.qty_incoming, 0, - "Wrong qty incoming") - self.assertEquals(line.qty_received, 0, - "Wrong qty received") - if line.product_id == self.product_1: - self.assertEquals(line.qty_delivered, 3, - "Wrong qty delivered") - self.assertEquals(line.qty_to_receive, 3, - "Wrong qty to receive") - if line.product_id == self.product_2: - self.assertEquals(line.qty_outgoing, 0, - "Wrong qty outgoing") - self.assertEquals(line.qty_to_receive, 5, - "Wrong qty to receive") - if line.product_id == self.product_3: - self.assertEquals(line.qty_outgoing, 0, - "Wrong qty delivered") - self.assertEquals(line.qty_to_receive, 2, - "Wrong qty to receive") - wizard = self.rma_make_picking.with_context({ - 'active_id': 1, - 'active_ids': self.rma_supplier_id.rma_line_ids.ids, - 'active_model': 'rma.order.line', - 'picking_type': 'incoming', - }).create({}) - wizard._create_picking() - res = self.rma_supplier_id.rma_line_ids.action_view_in_shipments() - self.assertTrue('res_id' in res, - "Incorrect number of pickings created") - picking = self.env['stock.picking'].browse(res['res_id']) - moves = picking.move_lines - self.assertEquals(len(moves), 3, - "Incorrect number of moves created") - for line in self.rma_supplier_id.rma_line_ids: - self.assertEquals(line.qty_received, 0, - "Wrong qty received") - if line.product_id == self.product_1: - self.assertEquals(line.qty_to_receive, 3, - "Wrong qty to receive") - self.assertEquals(line.qty_incoming, 3, - "Wrong qty incoming") - if line.product_id == self.product_2: - self.assertEquals(line.qty_to_receive, 5, - "Wrong qty to receive") - self.assertEquals(line.qty_incoming, 5, - "Wrong qty incoming") - if line.product_id == self.product_3: - self.assertEquals(line.qty_to_receive, 2, - "Wrong qty to receive") - self.assertEquals(line.qty_incoming, 2, - "Wrong qty incoming") - picking.action_assign() - for line in picking.move_line_ids: - line.qty_done = line.product_uom_qty - picking.action_done() - for line in self.rma_supplier_id.rma_line_ids[0]: - self.assertEquals(line.qty_incoming, 0, - "Wrong qty incoming") - if line.product_id == self.product_1: - self.assertEquals(line.qty_received, 3, - "Wrong qty received") - if line.product_id == self.product_2: - self.assertEquals(line.qty_received, 5, - "Wrong qty received") - if line.product_id == self.product_3: - self.assertEquals(line.qty_received, 2, - "Wrong qty received") - for line in self.rma_supplier_id.rma_line_ids: - line.action_rma_done() - self.assertEquals(line.state, 'done', - "Wrong State") From e7d1ef6ef94101c7ff80a31ce212d2b2b900bd60 Mon Sep 17 00:00:00 2001 From: aheficent Date: Thu, 4 Oct 2018 16:27:11 +0200 Subject: [PATCH 35/42] [FIX]currency_id was not filled --- rma_purchase/models/rma_order_line.py | 1 + 1 file changed, 1 insertion(+) diff --git a/rma_purchase/models/rma_order_line.py b/rma_purchase/models/rma_order_line.py index ceef4985..8cc75280 100644 --- a/rma_purchase/models/rma_order_line.py +++ b/rma_purchase/models/rma_order_line.py @@ -127,6 +127,7 @@ class RmaOrderLine(models.Model): 'in_route_id': operation.in_route_id.id or route, 'out_route_id': operation.out_route_id.id or route, 'receipt_policy': operation.receipt_policy, + 'currency_id': line.currency_id.id, 'location_id': (operation.location_id.id or operation.in_warehouse_id.lot_rma_id.id or warehouse.lot_rma_id.id), From 0d719f7a9abf5897b20e3dcc063d08a72e95ac66 Mon Sep 17 00:00:00 2001 From: Murtuza Saleh Date: Wed, 20 Mar 2019 18:21:15 +0530 Subject: [PATCH 36/42] [WIP][MIG][12.0] rma_purchase --- rma_purchase/README.rst | 1 + rma_purchase/__manifest__.py | 2 +- rma_purchase/models/rma_order.py | 1 + rma_purchase/models/rma_order_line.py | 21 ++++++- rma_purchase/tests/test_rma_purchase.py | 59 +++++++++---------- rma_purchase/views/rma_order_view.xml | 10 ++-- rma_purchase/wizards/rma_add_purchase.py | 5 +- rma_purchase/wizards/rma_add_purchase.xml | 2 +- .../rma_order_line_make_purchase_order.py | 2 +- ...ma_order_line_make_purchase_order_view.xml | 2 +- 10 files changed, 61 insertions(+), 44 deletions(-) diff --git a/rma_purchase/README.rst b/rma_purchase/README.rst index 2cd007c2..a2335f81 100644 --- a/rma_purchase/README.rst +++ b/rma_purchase/README.rst @@ -39,6 +39,7 @@ Contributors * Aaron Henriquez * Lois Rilo * Bhavesh Odedra +* Serpent Consulting Services Pvt. Ltd. Maintainer ---------- diff --git a/rma_purchase/__manifest__.py b/rma_purchase/__manifest__.py index a5a27eb1..19b6d255 100644 --- a/rma_purchase/__manifest__.py +++ b/rma_purchase/__manifest__.py @@ -3,7 +3,7 @@ { 'name': 'RMA Purchase', - 'version': '11.0.1.0.0', + 'version': '12.0.1.0.0', 'category': 'RMA', 'summary': 'RMA from PO', 'license': 'LGPL-3', diff --git a/rma_purchase/models/rma_order.py b/rma_purchase/models/rma_order.py index d9fdcbf4..5fb4943c 100644 --- a/rma_purchase/models/rma_order.py +++ b/rma_purchase/models/rma_order.py @@ -20,6 +20,7 @@ class RmaOrder(models.Model): rec.po_count = po_count @api.multi + @api.depends('rma_line_ids') def _compute_origin_po_count(self): for rma in self: purchases = rma.mapped( diff --git a/rma_purchase/models/rma_order_line.py b/rma_purchase/models/rma_order_line.py index 8cc75280..fd79595d 100644 --- a/rma_purchase/models/rma_order_line.py +++ b/rma_purchase/models/rma_order_line.py @@ -78,6 +78,22 @@ class RmaOrderLine(models.Model): readonly=True, compute='_compute_qty_purchase' ) + @api.onchange('product_id', 'partner_id') + def _onchange_product_id(self): + """Domain for purchase_order_line_id is computed here to make + it dynamic.""" + res = super(RmaOrderLine, self)._onchange_product_id() + if not res.get('domain'): + res['domain'] = {} + domain = [ + '|', + ('order_id.partner_id', '=', self.partner_id.id), + ('order_id.partner_id', 'child_of', self.partner_id.id)] + if self.product_id: + domain.append(('product_id', '=', self.product_id.id)) + res['domain']['purchase_order_line_id'] = domain + return res + @api.onchange('operation_id') def _onchange_operation_id(self): res = super(RmaOrderLine, self)._onchange_operation_id() @@ -122,8 +138,9 @@ class RmaOrderLine(models.Model): 'uom_id': line.product_uom.id, 'operation_id': operation.id, 'product_qty': line.product_qty, - 'price_unit': line.currency_id.compute( - line.price_unit, line.currency_id, round=False), + 'price_unit': line.currency_id._convert( + line.price_unit, line.currency_id, + self.env.user.company_id, fields.Date.today(), round=False), 'in_route_id': operation.in_route_id.id or route, 'out_route_id': operation.out_route_id.id or route, 'receipt_policy': operation.receipt_policy, diff --git a/rma_purchase/tests/test_rma_purchase.py b/rma_purchase/tests/test_rma_purchase.py index a165c1ba..f7fdb5cf 100644 --- a/rma_purchase/tests/test_rma_purchase.py +++ b/rma_purchase/tests/test_rma_purchase.py @@ -1,65 +1,64 @@ # 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.tests import common -from openerp.fields import Datetime +from odoo.tests import common +from odoo.fields import Datetime -class TestRmaPurchase(common.SingleTransactionCase): +class TestRmaPurchase(common.TransactionCase): - @classmethod - def setUpClass(cls): - super(TestRmaPurchase, cls).setUpClass() + def setUp(self): + super(TestRmaPurchase, self).setUp() - cls.rma_obj = cls.env['rma.order'] - cls.rma_line_obj = cls.env['rma.order.line'] - cls.rma_op_obj = cls.env['rma.operation'] - cls.rma_add_purchase_wiz = cls.env['rma_add_purchase'] - cls.po_obj = cls.env['purchase.order'] - cls.pol_obj = cls.env['purchase.order.line'] - cls.product_obj = cls.env['product.product'] - cls.partner_obj = cls.env['res.partner'] + self.rma_obj = self.env['rma.order'] + self.rma_line_obj = self.env['rma.order.line'] + self.rma_op_obj = self.env['rma.operation'] + self.rma_add_purchase_wiz = self.env['rma_add_purchase'] + self.po_obj = self.env['purchase.order'] + self.pol_obj = self.env['purchase.order.line'] + self.product_obj = self.env['product.product'] + self.partner_obj = self.env['res.partner'] - cls.rma_route_cust = cls.env.ref('rma.route_rma_customer') + self.rma_route_cust = self.env.ref('rma.route_rma_customer') # Create supplier - supplier1 = cls.partner_obj.create({'name': 'Supplier 1'}) + supplier1 = self.partner_obj.create({'name': 'Supplier 1'}) # Create products - cls.product_1 = cls.product_obj.create({ + self.product_1 = self.product_obj.create({ 'name': 'Test Product 1', 'type': 'product', }) - cls.product_2 = cls.product_obj.create({ + self.product_2 = self.product_obj.create({ 'name': 'Test Product 2', 'type': 'product', }) # Create PO: - cls.po = cls.po_obj.create({ + self.po = self.po_obj.create({ 'partner_id': supplier1.id, }) - cls.pol_1 = cls.pol_obj.create({ - 'name': cls.product_1.name, - 'order_id': cls.po.id, - 'product_id': cls.product_1.id, + self.pol_1 = self.pol_obj.create({ + 'name': self.product_1.name, + 'order_id': self.po.id, + 'product_id': self.product_1.id, 'product_qty': 20.0, - 'product_uom': cls.product_1.uom_id.id, + 'product_uom': self.product_1.uom_id.id, 'price_unit': 100.0, 'date_planned': Datetime.now(), }) - cls.pol_2 = cls.pol_obj.create({ - 'name': cls.product_2.name, - 'order_id': cls.po.id, - 'product_id': cls.product_2.id, + self.pol_2 = self.pol_obj.create({ + 'name': self.product_2.name, + 'order_id': self.po.id, + 'product_id': self.product_2.id, 'product_qty': 18.0, - 'product_uom': cls.product_2.uom_id.id, + 'product_uom': self.product_2.uom_id.id, 'price_unit': 150.0, 'date_planned': Datetime.now(), }) # Create RMA group: - cls.rma_group = cls.rma_obj.create({ + self.rma_group = self.rma_obj.create({ 'partner_id': supplier1.id, 'type': 'supplier', }) diff --git a/rma_purchase/views/rma_order_view.xml b/rma_purchase/views/rma_order_view.xml index f109af39..f5f61ed2 100644 --- a/rma_purchase/views/rma_order_view.xml +++ b/rma_purchase/views/rma_order_view.xml @@ -11,18 +11,16 @@ class="oe_stat_button" icon="fa-shopping-cart" groups="purchase.group_purchase_user"> - + - -
diff --git a/rma_purchase/wizards/rma_add_purchase.py b/rma_purchase/wizards/rma_add_purchase.py index 15e95e51..f84a81ef 100644 --- a/rma_purchase/wizards/rma_add_purchase.py +++ b/rma_purchase/wizards/rma_add_purchase.py @@ -70,8 +70,9 @@ class RmaAddPurchase(models.TransientModel): 'uom_id': line.product_uom.id, 'operation_id': operation.id, 'product_qty': line.product_qty, - 'price_unit': line.currency_id.compute( - line.price_unit, line.currency_id, round=False), + 'price_unit': line.currency_id._convert( + line.price_unit, line.currency_id, + self.env.user.company_id, fields.Date.today(), round=False), 'rma_id': self.rma_id.id, 'in_route_id': operation.in_route_id.id or route, 'out_route_id': operation.out_route_id.id or route, diff --git a/rma_purchase/wizards/rma_add_purchase.xml b/rma_purchase/wizards/rma_add_purchase.xml index 1c467bef..e3337989 100644 --- a/rma_purchase/wizards/rma_add_purchase.xml +++ b/rma_purchase/wizards/rma_add_purchase.xml @@ -29,7 +29,7 @@ - + diff --git a/rma_purchase/wizards/rma_order_line_make_purchase_order.py b/rma_purchase/wizards/rma_order_line_make_purchase_order.py index 4d1c227d..cd34a4f1 100644 --- a/rma_purchase/wizards/rma_order_line_make_purchase_order.py +++ b/rma_purchase/wizards/rma_order_line_make_purchase_order.py @@ -139,5 +139,5 @@ class RmaLineMakePurchaseOrderItem(models.TransientModel): string='Quantity to purchase', digits=dp.get_precision('Product Unit of Measure'),) product_uom_id = fields.Many2one( - comodel_name='product.uom', string='UoM') + comodel_name='uom.uom', string='UoM') free_of_charge = fields.Boolean(string='Free of Charge') diff --git a/rma_purchase/wizards/rma_order_line_make_purchase_order_view.xml b/rma_purchase/wizards/rma_order_line_make_purchase_order_view.xml index 48455623..af9af097 100644 --- a/rma_purchase/wizards/rma_order_line_make_purchase_order_view.xml +++ b/rma_purchase/wizards/rma_order_line_make_purchase_order_view.xml @@ -30,7 +30,7 @@ + groups="uom.group_uom"/> From 83cd97aadfa3dca097375785d5d0d167693ad790 Mon Sep 17 00:00:00 2001 From: Bhavesh Odedra Date: Fri, 24 May 2019 13:28:54 +0530 Subject: [PATCH 37/42] [SET] Correct website URL for RMA modules --- rma_purchase/__manifest__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rma_purchase/__manifest__.py b/rma_purchase/__manifest__.py index 19b6d255..62f3a5b1 100644 --- a/rma_purchase/__manifest__.py +++ b/rma_purchase/__manifest__.py @@ -8,7 +8,7 @@ 'summary': 'RMA from PO', 'license': 'LGPL-3', 'author': 'Eficent, Odoo Community Association (OCA)', - 'website': 'http://www.github.com/OCA/rma', + 'website': 'https://github.com/Eficent/stock-rma', 'depends': ['rma_account', 'purchase'], 'data': [ 'wizards/rma_order_line_make_purchase_order_view.xml', From 6f10747011e1ab38ad75d1da7aaa942c83c1d8a3 Mon Sep 17 00:00:00 2001 From: ahenriquez Date: Tue, 29 Oct 2019 16:37:58 +0100 Subject: [PATCH 38/42] [FIX]remove autoinstall for rma_account, rma_sale and rma_purchase modules --- rma_purchase/__manifest__.py | 1 - 1 file changed, 1 deletion(-) diff --git a/rma_purchase/__manifest__.py b/rma_purchase/__manifest__.py index 62f3a5b1..c6ed73ad 100644 --- a/rma_purchase/__manifest__.py +++ b/rma_purchase/__manifest__.py @@ -19,5 +19,4 @@ 'wizards/rma_add_purchase.xml', ], 'installable': True, - 'auto_install': True, } From c607e40776bfe9354902c846d5a362ea7ecf40be Mon Sep 17 00:00:00 2001 From: ahenriquez Date: Fri, 29 Nov 2019 17:54:28 +0100 Subject: [PATCH 39/42] [FIX] action returned when creating purchase orders from rma --- .../wizards/rma_order_line_make_purchase_order.py | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/rma_purchase/wizards/rma_order_line_make_purchase_order.py b/rma_purchase/wizards/rma_order_line_make_purchase_order.py index cd34a4f1..bc40ce4d 100644 --- a/rma_purchase/wizards/rma_order_line_make_purchase_order.py +++ b/rma_purchase/wizards/rma_order_line_make_purchase_order.py @@ -109,16 +109,10 @@ class RmaLineMakePurchaseOrder(models.TransientModel): po_line_obj.create(po_line_data) res.append(purchase.id) - return { - 'domain': "[('id','in', ["+','.join(map(str, res))+"])]", - 'name': _('Request for Quotation'), - 'view_type': 'form', - 'view_mode': 'tree,form', - 'res_model': 'purchase.order', - 'view_id': False, - 'context': False, - 'type': 'ir.actions.act_window' - } + action = self.env.ref('purchase.purchase_rfq') + result = action.read()[0] + result['domain'] = "[('id','in', ["+','.join(map(str, res))+"])]" + return result class RmaLineMakePurchaseOrderItem(models.TransientModel): From e6a0cdcabcd5a1340dbcdbaa7ae20bc2d2980a43 Mon Sep 17 00:00:00 2001 From: mreficent Date: Fri, 29 Nov 2019 18:30:43 +0100 Subject: [PATCH 40/42] [FIX] default_gets: avoid using shadowname 'fields' --- rma_purchase/wizards/rma_add_purchase.py | 4 ++-- rma_purchase/wizards/rma_order_line_make_purchase_order.py | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/rma_purchase/wizards/rma_add_purchase.py b/rma_purchase/wizards/rma_add_purchase.py index f84a81ef..e4a89e91 100644 --- a/rma_purchase/wizards/rma_add_purchase.py +++ b/rma_purchase/wizards/rma_add_purchase.py @@ -10,8 +10,8 @@ class RmaAddPurchase(models.TransientModel): _description = 'Wizard to add rma lines' @api.model - def default_get(self, fields): - res = super(RmaAddPurchase, self).default_get(fields) + def default_get(self, fields_list): + res = super(RmaAddPurchase, self).default_get(fields_list) rma_obj = self.env['rma.order'] rma_id = self.env.context['active_ids'] or [] active_model = self.env.context['active_model'] diff --git a/rma_purchase/wizards/rma_order_line_make_purchase_order.py b/rma_purchase/wizards/rma_order_line_make_purchase_order.py index bc40ce4d..17d13bf0 100644 --- a/rma_purchase/wizards/rma_order_line_make_purchase_order.py +++ b/rma_purchase/wizards/rma_order_line_make_purchase_order.py @@ -34,9 +34,9 @@ class RmaLineMakePurchaseOrder(models.TransientModel): } @api.model - def default_get(self, fields): + def default_get(self, fields_list): res = super(RmaLineMakePurchaseOrder, self).default_get( - fields) + fields_list) rma_line_obj = self.env['rma.order.line'] rma_line_ids = self.env.context['active_ids'] or [] active_model = self.env.context['active_model'] From 55c0b05234786c59a49f1910cee28a752af8de4e Mon Sep 17 00:00:00 2001 From: Chanakya-SerpentCS Date: Tue, 15 Dec 2020 17:48:19 +0530 Subject: [PATCH 41/42] [FIX] Travis --- rma_purchase/__manifest__.py | 32 +-- rma_purchase/models/purchase_order.py | 20 +- rma_purchase/models/purchase_order_line.py | 68 ++++-- rma_purchase/models/rma_operation.py | 25 +- rma_purchase/models/rma_order.py | 35 ++- rma_purchase/models/rma_order_line.py | 220 ++++++++++-------- rma_purchase/security/ir.model.access.csv | 0 rma_purchase/tests/test_rma_purchase.py | 124 +++++----- rma_purchase/views/rma_operation_view.xml | 10 +- rma_purchase/views/rma_order_line_view.xml | 62 +++-- rma_purchase/views/rma_order_view.xml | 41 ++-- rma_purchase/wizards/rma_add_purchase.py | 133 ++++++----- rma_purchase/wizards/rma_add_purchase.xml | 80 ++++--- rma_purchase/wizards/rma_make_picking.py | 21 +- .../rma_order_line_make_purchase_order.py | 130 ++++++----- ...ma_order_line_make_purchase_order_view.xml | 71 +++--- 16 files changed, 608 insertions(+), 464 deletions(-) mode change 100755 => 100644 rma_purchase/security/ir.model.access.csv diff --git a/rma_purchase/__manifest__.py b/rma_purchase/__manifest__.py index c6ed73ad..0216b0c7 100644 --- a/rma_purchase/__manifest__.py +++ b/rma_purchase/__manifest__.py @@ -2,21 +2,21 @@ # License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html) { - 'name': 'RMA Purchase', - 'version': '12.0.1.0.0', - 'category': 'RMA', - 'summary': 'RMA from PO', - 'license': 'LGPL-3', - 'author': 'Eficent, Odoo Community Association (OCA)', - 'website': 'https://github.com/Eficent/stock-rma', - 'depends': ['rma_account', 'purchase'], - 'data': [ - 'wizards/rma_order_line_make_purchase_order_view.xml', - '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', + "name": "RMA Purchase", + "version": "13.0.1.0.0", + "category": "RMA", + "summary": "RMA from PO", + "license": "LGPL-3", + "author": "Eficent, Odoo Community Association (OCA)", + "website": "https://github.com/Eficent/stock-rma", + "depends": ["rma_account", "purchase"], + "data": [ + "wizards/rma_order_line_make_purchase_order_view.xml", + "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", ], - 'installable': True, + "installable": True, } diff --git a/rma_purchase/models/purchase_order.py b/rma_purchase/models/purchase_order.py index 66ec0277..5ef6ba45 100644 --- a/rma_purchase/models/purchase_order.py +++ b/rma_purchase/models/purchase_order.py @@ -11,16 +11,18 @@ class PurchaseOrder(models.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') + 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, - }) + 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, - }) + line.update( + { + "product_qty": rma_line.qty_to_purchase, + "product_uom": rma_line.uom_id.id, + } + ) res.order_line = line return res diff --git a/rma_purchase/models/purchase_order_line.py b/rma_purchase/models/purchase_order_line.py index fe08f86b..5856c459 100644 --- a/rma_purchase/models/purchase_order_line.py +++ b/rma_purchase/models/purchase_order_line.py @@ -7,53 +7,71 @@ from odoo import api, fields, models class PurchaseOrderLine(models.Model): _inherit = "purchase.order.line" - rma_line_id = fields.Many2one( - comodel_name='rma.order.line', string='RMA', - ) + 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): + def name_search(self, name="", args=None, operator="ilike", limit=100): """Allows to search by PO reference.""" if not args: args = [] - args += ['|', - (self._rec_name, operator, name), - ('order_id.name', operator, name)] + args += [ + "|", + (self._rec_name, operator, name), + ("order_id.name", operator, name), + ] return super(PurchaseOrderLine, self).name_search( - name=name, args=args, operator=operator, limit=limit) + name=name, args=args, operator=operator, limit=limit + ) @api.model - def _name_search(self, name='', args=None, operator='ilike', - limit=100, name_get_uid=None): + def _name_search( + self, name="", args=None, operator="ilike", limit=100, name_get_uid=None + ): """Typed text is cleared here for better extensibility.""" return super(PurchaseOrderLine, self)._name_search( - name='', args=args, operator=operator, limit=limit, - name_get_uid=name_get_uid) + name="", + args=args, + operator=operator, + limit=limit, + name_get_uid=name_get_uid, + ) @api.multi def name_get(self): res = [] - if self.env.context.get('rma'): + if self.env.context.get("rma"): for purchase in self: - invoices = self.env['account.invoice.line'].search( - [('purchase_line_id', '=', purchase.id)]) + invoices = self.env["account.invoice.line"].search( + [("purchase_line_id", "=", purchase.id)] + ) if purchase.order_id.name: - res.append((purchase.id, "%s %s %s qty:%s" % ( - purchase.order_id.name, - " ".join(str(x) for x in [ - inv.number for inv in invoices.mapped( - 'invoice_id')]), - purchase.product_id.name, purchase.product_qty))) - else: res.append( - super(PurchaseOrderLine, purchase).name_get()[0]) + ( + purchase.id, + "%s %s %s qty:%s" + % ( + purchase.order_id.name, + " ".join( + str(x) + for x in [ + inv.number + for inv in invoices.mapped("invoice_id") + ] + ), + purchase.product_id.name, + purchase.product_qty, + ), + ) + ) + else: + res.append(super(PurchaseOrderLine, purchase).name_get()[0]) 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') + rma_line_id = self.env.context.get("rma_line_id") if rma_line_id: - vals['rma_line_id'] = 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 index 8665dba6..2c9d6b3a 100644 --- a/rma_purchase/models/rma_operation.py +++ b/rma_purchase/models/rma_operation.py @@ -1,24 +1,27 @@ # Copyright 2018 Eficent Business and IT Consulting Services S.L. # License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html) -from odoo import api, fields, models, _ +from odoo import _, api, fields, models from odoo.exceptions import ValidationError class RmaOperation(models.Model): - _inherit = 'rma.operation' + _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', + 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') + @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')) + 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.py b/rma_purchase/models/rma_order.py index 5fb4943c..5e393367 100644 --- a/rma_purchase/models/rma_order.py +++ b/rma_purchase/models/rma_order.py @@ -13,42 +13,41 @@ class RmaOrder(models.Model): po_count = 0 rma_line_po = [] for line in rec.rma_line_ids: - rma_line_po += self.env['purchase.order'].search( - [('origin', '=', line.name)]).ids + rma_line_po += ( + self.env["purchase.order"].search([("origin", "=", line.name)]).ids + ) if rma_line_po: po_count = len(list(set(rma_line_po))) rec.po_count = po_count @api.multi - @api.depends('rma_line_ids') + @api.depends("rma_line_ids") def _compute_origin_po_count(self): for rma in self: - purchases = rma.mapped( - 'rma_line_ids.purchase_order_line_id.order_id') + purchases = rma.mapped("rma_line_ids.purchase_order_line_id.order_id") rma.origin_po_count = len(purchases) - po_count = fields.Integer( - compute='_compute_po_count', string='# of PO') + po_count = fields.Integer(compute="_compute_po_count", string="# of PO") origin_po_count = fields.Integer( - compute='_compute_origin_po_count', string='# of Origin PO') + compute="_compute_origin_po_count", string="# of Origin PO" + ) @api.multi def action_view_purchase_order(self): - action = self.env.ref('purchase.purchase_rfq') + action = self.env.ref("purchase.purchase_rfq") result = action.read()[0] - po_ids = self.env['purchase.order'].search( - [('origin', '=', self.name)]).ids + po_ids = self.env["purchase.order"].search([("origin", "=", self.name)]).ids for line in self.rma_line_ids: - po_ids += self.env['purchase.order'].search( - [('origin', '=', line.name)]).ids - result['domain'] = [('id', 'in', po_ids)] + po_ids += ( + self.env["purchase.order"].search([("origin", "=", line.name)]).ids + ) + result["domain"] = [("id", "in", po_ids)] return result @api.multi def action_view_origin_purchase_order(self): - action = self.env.ref('purchase.purchase_rfq') + action = self.env.ref("purchase.purchase_rfq") result = action.read()[0] - po_ids = self.mapped( - 'rma_line_ids.purchase_order_line_id.order_id').ids - result['domain'] = [('id', 'in', po_ids)] + po_ids = self.mapped("rma_line_ids.purchase_order_line_id.order_id").ids + result["domain"] = [("id", "in", po_ids)] return result diff --git a/rma_purchase/models/rma_order_line.py b/rma_purchase/models/rma_order_line.py index fd79595d..0a4a5eae 100644 --- a/rma_purchase/models/rma_order_line.py +++ b/rma_purchase/models/rma_order_line.py @@ -1,8 +1,9 @@ # © 2017 Eficent Business and IT Consulting Services S.L. # License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html) -from odoo import api, fields, models, _ +from odoo import _, api, fields, models from odoo.exceptions import ValidationError + from odoo.addons import decimal_precision as dp @@ -12,16 +13,18 @@ class RmaOrderLine(models.Model): @api.multi def _compute_purchase_count(self): for rec in self: - purchase_line_count = self.env['purchase.order.line'].search( - [('rma_line_id', '=', rec.id)]) - rec.purchase_count = len(purchase_line_count.mapped('order_id')) + purchase_line_count = self.env["purchase.order.line"].search( + [("rma_line_id", "=", rec.id)] + ) + rec.purchase_count = len(purchase_line_count.mapped("order_id")) @api.multi def _compute_purchase_order_lines(self): for rec in self: purchase_list = [] - for line in self.env['purchase.order.line'].search( - [('rma_line_id', '=', rec.id)]): + for line in self.env["purchase.order.line"].search( + [("rma_line_id", "=", rec.id)] + ): purchase_list.append(line.id) rec.purchase_order_line_ids = [(6, 0, purchase_list)] @@ -29,76 +32,90 @@ class RmaOrderLine(models.Model): def _compute_qty_purchase(self): for rec in self: rec.qty_purchased = rec._get_rma_purchased_qty() - if rec.purchase_policy == 'ordered': + if rec.purchase_policy == "ordered": rec.qty_to_purchase = rec.product_qty - rec.qty_purchased - elif rec.purchase_policy == 'delivered': + 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', + compute="_compute_purchase_count", string="# of Purchases", ) purchase_order_line_id = fields.Many2one( - comodel_name='purchase.order.line', string='Originating Purchase Line', - ondelete='restrict', - readonly=True, states={'draft': [('readonly', False)]}, + comodel_name="purchase.order.line", + string="Originating Purchase Line", + ondelete="restrict", + readonly=True, + states={"draft": [("readonly", False)]}, ) purchase_id = fields.Many2one( string="Source Purchase Order", - related='purchase_order_line_id.order_id', + related="purchase_order_line_id.order_id", readonly=True, ) purchase_order_line_ids = fields.Many2many( - comodel_name='purchase.order.line', - relation='purchase_line_rma_line_rel', - column1='rma_order_line_id', column2='purchase_order_line_id', - string='Purchase Order Lines', compute='_compute_purchase_order_lines', + comodel_name="purchase.order.line", + relation="purchase_line_rma_line_rel", + 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', + 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) + 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' + string="Qty To Purchase", + copy=False, + digits=dp.get_precision("Product Unit of Measure"), + readonly=True, + compute="_compute_qty_purchase", ) qty_purchased = fields.Float( - string='Qty Purchased', copy=False, - digits=dp.get_precision('Product Unit of Measure'), - readonly=True, compute='_compute_qty_purchase' + string="Qty Purchased", + copy=False, + digits=dp.get_precision("Product Unit of Measure"), + readonly=True, + compute="_compute_qty_purchase", ) - @api.onchange('product_id', 'partner_id') + @api.onchange("product_id", "partner_id") def _onchange_product_id(self): """Domain for purchase_order_line_id is computed here to make it dynamic.""" res = super(RmaOrderLine, self)._onchange_product_id() - if not res.get('domain'): - res['domain'] = {} + if not res.get("domain"): + res["domain"] = {} domain = [ - '|', - ('order_id.partner_id', '=', self.partner_id.id), - ('order_id.partner_id', 'child_of', self.partner_id.id)] + "|", + ("order_id.partner_id", "=", self.partner_id.id), + ("order_id.partner_id", "child_of", self.partner_id.id), + ] if self.product_id: - domain.append(('product_id', '=', self.product_id.id)) - res['domain']['purchase_order_line_id'] = domain + domain.append(("product_id", "=", self.product_id.id)) + res["domain"]["purchase_order_line_id"] = domain return res - @api.onchange('operation_id') + @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' + self.purchase_policy = self.operation_id.purchase_policy or "no" return res @api.multi @@ -106,98 +123,115 @@ class RmaOrderLine(models.Model): self.ensure_one() if not self.type: self.type = self._get_default_type() - if self.type == 'customer': - operation = line.product_id.rma_customer_operation_id or \ - line.product_id.categ_id.rma_customer_operation_id + if self.type == "customer": + operation = ( + line.product_id.rma_customer_operation_id + or line.product_id.categ_id.rma_customer_operation_id + ) else: - operation = line.product_id.rma_supplier_operation_id or \ - line.product_id.categ_id.rma_supplier_operation_id + operation = ( + line.product_id.rma_supplier_operation_id + or line.product_id.categ_id.rma_supplier_operation_id + ) if not operation: - operation = self.env['rma.operation'].search( - [('type', '=', self.type)], limit=1) + operation = self.env["rma.operation"].search( + [("type", "=", self.type)], limit=1 + ) if not operation: raise ValidationError(_("Please define an operation first")) if not operation.in_route_id or not operation.out_route_id: - route = self.env['stock.location.route'].search( - [('rma_selectable', '=', True)], limit=1) + route = self.env["stock.location.route"].search( + [("rma_selectable", "=", True)], limit=1 + ) if not route: raise ValidationError(_("Please define a rma route.")) if not operation.in_warehouse_id or not operation.out_warehouse_id: - warehouse = self.env['stock.warehouse'].search( - [('company_id', '=', self.company_id.id), - ('lot_rma_id', '!=', False)], limit=1) + warehouse = self.env["stock.warehouse"].search( + [("company_id", "=", self.company_id.id), ("lot_rma_id", "!=", False)], + limit=1, + ) if not warehouse: - raise ValidationError(_( - "Please define a warehouse with a default rma location.")) + raise ValidationError( + _("Please define a warehouse with a default rma location.") + ) data = { - 'product_id': line.product_id.id, - 'origin': line.order_id.name, - 'uom_id': line.product_uom.id, - 'operation_id': operation.id, - 'product_qty': line.product_qty, - 'price_unit': line.currency_id._convert( - line.price_unit, line.currency_id, - self.env.user.company_id, fields.Date.today(), round=False), - 'in_route_id': operation.in_route_id.id or route, - 'out_route_id': operation.out_route_id.id or route, - 'receipt_policy': operation.receipt_policy, - 'currency_id': line.currency_id.id, - 'location_id': (operation.location_id.id or - operation.in_warehouse_id.lot_rma_id.id or - warehouse.lot_rma_id.id), - 'refund_policy': operation.refund_policy, - 'delivery_policy': operation.delivery_policy, - 'in_warehouse_id': operation.in_warehouse_id.id or warehouse.id, - 'out_warehouse_id': operation.out_warehouse_id.id or warehouse.id, + "product_id": line.product_id.id, + "origin": line.order_id.name, + "uom_id": line.product_uom.id, + "operation_id": operation.id, + "product_qty": line.product_qty, + "price_unit": line.currency_id._convert( + line.price_unit, + line.currency_id, + self.env.user.company_id, + fields.Date.today(), + round=False, + ), + "in_route_id": operation.in_route_id.id or route, + "out_route_id": operation.out_route_id.id or route, + "receipt_policy": operation.receipt_policy, + "currency_id": line.currency_id.id, + "location_id": ( + operation.location_id.id + or operation.in_warehouse_id.lot_rma_id.id + or warehouse.lot_rma_id.id + ), + "refund_policy": operation.refund_policy, + "delivery_policy": operation.delivery_policy, + "in_warehouse_id": operation.in_warehouse_id.id or warehouse.id, + "out_warehouse_id": operation.out_warehouse_id.id or warehouse.id, } return data - @api.onchange('purchase_order_line_id') + @api.onchange("purchase_order_line_id") def _onchange_purchase_order_line_id(self): if not self.purchase_order_line_id: return - data = self._prepare_rma_line_from_po_line( - self.purchase_order_line_id) + data = self._prepare_rma_line_from_po_line(self.purchase_order_line_id) self.update(data) - self._remove_other_data_origin('purchase_order_line_id') + self._remove_other_data_origin("purchase_order_line_id") @api.multi - @api.constrains('purchase_order_line_id', 'partner_id') + @api.constrains("purchase_order_line_id", "partner_id") def _check_purchase_partner(self): for rec in self: - if (rec.purchase_order_line_id and - rec.purchase_order_line_id.order_id.partner_id != - rec.partner_id): - raise ValidationError(_( - "RMA customer and originating purchase line customer " - "doesn't match.")) + if ( + rec.purchase_order_line_id + and rec.purchase_order_line_id.order_id.partner_id != rec.partner_id + ): + raise ValidationError( + _( + "RMA customer and originating purchase line customer " + "doesn't match." + ) + ) @api.multi def _remove_other_data_origin(self, exception): res = super(RmaOrderLine, self)._remove_other_data_origin(exception) - if not exception == 'purchase_order_line_id': + 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') + action = self.env.ref("purchase.purchase_rfq") result = action.read()[0] - orders = self.mapped('purchase_order_line_ids.order_id') - result['domain'] = [('id', 'in', orders.ids)] + orders = self.mapped("purchase_order_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': + if self.type == "customer": return qty for line in self.purchase_order_line_ids.filtered( - lambda p: p.state not in ('draft', 'sent', 'cancel')): - qty += self.uom_id._compute_quantity( - line.product_qty, line.product_uom) + lambda p: p.state not in ("draft", "sent", "cancel") + ): + qty += self.uom_id._compute_quantity(line.product_qty, line.product_uom) return qty diff --git a/rma_purchase/security/ir.model.access.csv b/rma_purchase/security/ir.model.access.csv old mode 100755 new mode 100644 diff --git a/rma_purchase/tests/test_rma_purchase.py b/rma_purchase/tests/test_rma_purchase.py index f7fdb5cf..15aacdbb 100644 --- a/rma_purchase/tests/test_rma_purchase.py +++ b/rma_purchase/tests/test_rma_purchase.py @@ -1,92 +1,96 @@ # 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 odoo.tests import common from odoo.fields import Datetime +from odoo.tests import common class TestRmaPurchase(common.TransactionCase): - def setUp(self): super(TestRmaPurchase, self).setUp() - self.rma_obj = self.env['rma.order'] - self.rma_line_obj = self.env['rma.order.line'] - self.rma_op_obj = self.env['rma.operation'] - self.rma_add_purchase_wiz = self.env['rma_add_purchase'] - self.po_obj = self.env['purchase.order'] - self.pol_obj = self.env['purchase.order.line'] - self.product_obj = self.env['product.product'] - self.partner_obj = self.env['res.partner'] + self.rma_obj = self.env["rma.order"] + self.rma_line_obj = self.env["rma.order.line"] + self.rma_op_obj = self.env["rma.operation"] + self.rma_add_purchase_wiz = self.env["rma_add_purchase"] + self.po_obj = self.env["purchase.order"] + self.pol_obj = self.env["purchase.order.line"] + self.product_obj = self.env["product.product"] + self.partner_obj = self.env["res.partner"] - self.rma_route_cust = self.env.ref('rma.route_rma_customer') + self.rma_route_cust = self.env.ref("rma.route_rma_customer") # Create supplier - supplier1 = self.partner_obj.create({'name': 'Supplier 1'}) + supplier1 = self.partner_obj.create({"name": "Supplier 1"}) # Create products - self.product_1 = self.product_obj.create({ - 'name': 'Test Product 1', - 'type': 'product', - }) - self.product_2 = self.product_obj.create({ - 'name': 'Test Product 2', - 'type': 'product', - }) + self.product_1 = self.product_obj.create( + {"name": "Test Product 1", "type": "product"} + ) + self.product_2 = self.product_obj.create( + {"name": "Test Product 2", "type": "product"} + ) # Create PO: - self.po = self.po_obj.create({ - 'partner_id': supplier1.id, - }) - self.pol_1 = self.pol_obj.create({ - 'name': self.product_1.name, - 'order_id': self.po.id, - 'product_id': self.product_1.id, - 'product_qty': 20.0, - 'product_uom': self.product_1.uom_id.id, - 'price_unit': 100.0, - 'date_planned': Datetime.now(), - }) - self.pol_2 = self.pol_obj.create({ - 'name': self.product_2.name, - 'order_id': self.po.id, - 'product_id': self.product_2.id, - 'product_qty': 18.0, - 'product_uom': self.product_2.uom_id.id, - 'price_unit': 150.0, - 'date_planned': Datetime.now(), - }) + self.po = self.po_obj.create({"partner_id": supplier1.id}) + self.pol_1 = self.pol_obj.create( + { + "name": self.product_1.name, + "order_id": self.po.id, + "product_id": self.product_1.id, + "product_qty": 20.0, + "product_uom": self.product_1.uom_id.id, + "price_unit": 100.0, + "date_planned": Datetime.now(), + } + ) + self.pol_2 = self.pol_obj.create( + { + "name": self.product_2.name, + "order_id": self.po.id, + "product_id": self.product_2.id, + "product_qty": 18.0, + "product_uom": self.product_2.uom_id.id, + "price_unit": 150.0, + "date_planned": Datetime.now(), + } + ) # Create RMA group: - self.rma_group = self.rma_obj.create({ - 'partner_id': supplier1.id, - 'type': 'supplier', - }) + self.rma_group = self.rma_obj.create( + {"partner_id": supplier1.id, "type": "supplier"} + ) def test_01_add_from_purchase_order(self): """Test wizard to create supplier RMA from Purchase Orders.""" self.assertEqual(self.rma_group.origin_po_count, 0) - add_purchase = self.rma_add_purchase_wiz.with_context({ - 'supplier': True, - 'active_ids': self.rma_group.id, - 'active_model': 'rma.order', - }).create({ - 'purchase_id': self.po.id, - 'purchase_line_ids': [(6, 0, self.po.order_line.ids)], - }) + add_purchase = self.rma_add_purchase_wiz.with_context( + { + "supplier": True, + "active_ids": self.rma_group.id, + "active_model": "rma.order", + } + ).create( + { + "purchase_id": self.po.id, + "purchase_line_ids": [(6, 0, self.po.order_line.ids)], + } + ) add_purchase.add_lines() self.assertEqual(len(self.rma_group.rma_line_ids), 2) - for t in self.rma_group.rma_line_ids.mapped('type'): - self.assertEqual(t, 'supplier') + for t in self.rma_group.rma_line_ids.mapped("type"): + self.assertEqual(t, "supplier") self.assertEqual(self.rma_group.origin_po_count, 1) def test_02_fill_rma_from_po_line(self): """Test filling a RMA (line) from a Purchase Order line.""" - rma = self.rma_line_obj.new({ - 'partner_id': self.po.partner_id.id, - 'purchase_order_line_id': self.pol_1.id, - 'type': 'supplier', - }) + rma = self.rma_line_obj.new( + { + "partner_id": self.po.partner_id.id, + "purchase_order_line_id": self.pol_1.id, + "type": "supplier", + } + ) self.assertFalse(rma.product_id) rma._onchange_purchase_order_line_id() self.assertEqual(rma.product_id, self.product_1) diff --git a/rma_purchase/views/rma_operation_view.xml b/rma_purchase/views/rma_operation_view.xml index 1afff91d..c1a1cc9f 100644 --- a/rma_purchase/views/rma_operation_view.xml +++ b/rma_purchase/views/rma_operation_view.xml @@ -1,4 +1,4 @@ - + @@ -6,10 +6,10 @@ rma.operation.tree - rma_purchase rma.operation - + - + @@ -17,10 +17,10 @@ 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 2e8a8803..1b07fcaa 100644 --- a/rma_purchase/views/rma_order_line_view.xml +++ b/rma_purchase/views/rma_order_line_view.xml @@ -1,4 +1,4 @@ - + @@ -12,13 +12,17 @@ rma.order.line.supplier.form rma.order.line - +
-
@@ -26,41 +30,51 @@ rma.order.line.supplier.form rma.order.line - +
-
- + ('order_id.partner_id', 'child_of', partner_id)]" + /> - - + + - + - + - + diff --git a/rma_purchase/views/rma_order_view.xml b/rma_purchase/views/rma_order_view.xml index f5f61ed2..7a169b65 100644 --- a/rma_purchase/views/rma_order_view.xml +++ b/rma_purchase/views/rma_order_view.xml @@ -1,26 +1,37 @@ - + rma.order.supplier.form rma.order - +
- -
diff --git a/rma_purchase/wizards/rma_add_purchase.py b/rma_purchase/wizards/rma_add_purchase.py index e4a89e91..d09b458d 100644 --- a/rma_purchase/wizards/rma_add_purchase.py +++ b/rma_purchase/wizards/rma_add_purchase.py @@ -6,91 +6,112 @@ from odoo.exceptions import ValidationError class RmaAddPurchase(models.TransientModel): - _name = 'rma_add_purchase' - _description = 'Wizard to add rma lines' + _name = "rma_add_purchase" + _description = "Wizard to add rma lines" @api.model def default_get(self, fields_list): res = super(RmaAddPurchase, self).default_get(fields_list) - rma_obj = self.env['rma.order'] - rma_id = self.env.context['active_ids'] or [] - active_model = self.env.context['active_model'] + rma_obj = self.env["rma.order"] + rma_id = self.env.context["active_ids"] or [] + active_model = self.env.context["active_model"] if not rma_id: return res - assert active_model == 'rma.order', 'Bad context propagation' + assert active_model == "rma.order", "Bad context propagation" rma = rma_obj.browse(rma_id) - res['rma_id'] = rma.id - res['partner_id'] = rma.partner_id.id - res['purchase_id'] = False - res['purchase_line_ids'] = False + res["rma_id"] = rma.id + res["partner_id"] = rma.partner_id.id + res["purchase_id"] = False + res["purchase_line_ids"] = False return res rma_id = fields.Many2one( - comodel_name='rma.order', string='RMA Order', readonly=True) + comodel_name="rma.order", string="RMA Order", readonly=True + ) partner_id = fields.Many2one( - comodel_name='res.partner', string='Partner', readonly=True) - purchase_id = fields.Many2one( - comodel_name='purchase.order', string='Order') + comodel_name="res.partner", string="Partner", readonly=True + ) + purchase_id = fields.Many2one(comodel_name="purchase.order", string="Order") purchase_line_ids = fields.Many2many( - comodel_name='purchase.order.line', - relation='rma_add_purchase_add_line_rel', - column1='rma_add_purchase_id', column2='purchase_line_id', - readonly=False, string='Purchase Order Lines') + comodel_name="purchase.order.line", + relation="rma_add_purchase_add_line_rel", + column1="rma_add_purchase_id", + column2="purchase_line_id", + readonly=False, + string="Purchase Order Lines", + ) def _prepare_rma_line_from_po_line(self, line): - if self.env.context.get('customer'): - operation = line.product_id.rma_customer_operation_id or \ - line.product_id.categ_id.rma_customer_operation_id + if self.env.context.get("customer"): + operation = ( + line.product_id.rma_customer_operation_id + or line.product_id.categ_id.rma_customer_operation_id + ) else: - operation = line.product_id.rma_supplier_operation_id or \ - line.product_id.categ_id.rma_supplier_operation_id + operation = ( + line.product_id.rma_supplier_operation_id + or line.product_id.categ_id.rma_supplier_operation_id + ) if not operation: - operation = self.env['rma.operation'].search( - [('type', '=', self.rma_id.type)], limit=1) + operation = self.env["rma.operation"].search( + [("type", "=", self.rma_id.type)], limit=1 + ) if not operation: raise ValidationError(_("Please define an operation first")) if not operation.in_route_id or not operation.out_route_id: - route = self.env['stock.location.route'].search( - [('rma_selectable', '=', True)], limit=1) + route = self.env["stock.location.route"].search( + [("rma_selectable", "=", True)], limit=1 + ) if not route: raise ValidationError(_("Please define a rma route.")) if not operation.in_warehouse_id or not operation.out_warehouse_id: - warehouse = self.env['stock.warehouse'].search( - [('company_id', '=', self.rma_id.company_id.id), - ('lot_rma_id', '!=', False)], limit=1) + warehouse = self.env["stock.warehouse"].search( + [ + ("company_id", "=", self.rma_id.company_id.id), + ("lot_rma_id", "!=", False), + ], + limit=1, + ) if not warehouse: - raise ValidationError(_("Please define a warehouse with a " - "default rma location.")) + raise ValidationError( + _("Please define a warehouse with a " "default rma location.") + ) data = { - 'partner_id': self.partner_id.id, - 'purchase_order_line_id': line.id, - 'product_id': line.product_id.id, - 'origin': line.order_id.name, - 'uom_id': line.product_uom.id, - 'operation_id': operation.id, - 'product_qty': line.product_qty, - 'price_unit': line.currency_id._convert( - line.price_unit, line.currency_id, - self.env.user.company_id, fields.Date.today(), round=False), - 'rma_id': self.rma_id.id, - 'in_route_id': operation.in_route_id.id or route, - 'out_route_id': operation.out_route_id.id or route, - 'receipt_policy': operation.receipt_policy, - 'location_id': (operation.location_id.id or - operation.in_warehouse_id.lot_rma_id.id or - warehouse.lot_rma_id.id), - 'refund_policy': operation.refund_policy, - 'delivery_policy': operation.delivery_policy, - 'in_warehouse_id': operation.in_warehouse_id.id or warehouse.id, - 'out_warehouse_id': operation.out_warehouse_id.id or warehouse.id, + "partner_id": self.partner_id.id, + "purchase_order_line_id": line.id, + "product_id": line.product_id.id, + "origin": line.order_id.name, + "uom_id": line.product_uom.id, + "operation_id": operation.id, + "product_qty": line.product_qty, + "price_unit": line.currency_id._convert( + line.price_unit, + line.currency_id, + self.env.user.company_id, + fields.Date.today(), + round=False, + ), + "rma_id": self.rma_id.id, + "in_route_id": operation.in_route_id.id or route, + "out_route_id": operation.out_route_id.id or route, + "receipt_policy": operation.receipt_policy, + "location_id": ( + operation.location_id.id + or operation.in_warehouse_id.lot_rma_id.id + or warehouse.lot_rma_id.id + ), + "refund_policy": operation.refund_policy, + "delivery_policy": operation.delivery_policy, + "in_warehouse_id": operation.in_warehouse_id.id or warehouse.id, + "out_warehouse_id": operation.out_warehouse_id.id or warehouse.id, } return data @api.model def _get_rma_data(self): data = { - 'date_rma': fields.Datetime.now(), + "date_rma": fields.Datetime.now(), } return data @@ -103,7 +124,7 @@ class RmaAddPurchase(models.TransientModel): @api.multi def add_lines(self): - rma_line_obj = self.env['rma.order.line'] + rma_line_obj = self.env["rma.order.line"] existing_purchase_lines = self._get_existing_purchase_lines() for line in self.purchase_line_ids: # Load a PO line only once @@ -113,4 +134,4 @@ class RmaAddPurchase(models.TransientModel): rma = self.rma_id data_rma = self._get_rma_data() rma.write(data_rma) - return {'type': 'ir.actions.act_window_close'} + return {"type": "ir.actions.act_window_close"} diff --git a/rma_purchase/wizards/rma_add_purchase.xml b/rma_purchase/wizards/rma_add_purchase.xml index e3337989..e8644863 100644 --- a/rma_purchase/wizards/rma_add_purchase.xml +++ b/rma_purchase/wizards/rma_add_purchase.xml @@ -1,5 +1,4 @@ - - + rma.add.purchase @@ -7,41 +6,53 @@
- + - + - + context="{'partner_id': partner_id}" + /> - - + + - - + + - - - - - - + + + + + +
@@ -55,19 +66,24 @@ form form new - - + +
rma.order.line.supplier.form rma.order - + -