From 70aea6b24b082866ebfd65a34f2a8f2c7fb1c966 Mon Sep 17 00:00:00 2001 From: Jordi Ballester Date: Thu, 27 Jul 2017 18:17:19 +0200 Subject: [PATCH 01/52] init branch --- rma_account/README.rst | 51 +++++ rma_account/__init__.py | 5 + rma_account/__openerp__.py | 24 ++ rma_account/demo/rma_operation.xml | 44 ++++ rma_account/models/__init__.py | 7 + rma_account/models/invoice.py | 87 +++++++ rma_account/models/rma_operation.py | 13 ++ rma_account/models/rma_order.py | 145 ++++++++++++ rma_account/models/rma_order_line.py | 132 +++++++++++ rma_account/views/invoice_view.xml | 73 ++++++ rma_account/views/rma_operation_view.xml | 26 +++ rma_account/views/rma_order_line_view.xml | 89 ++++++++ rma_account/views/rma_order_view.xml | 68 ++++++ rma_account/wizards/__init__.py | 7 + rma_account/wizards/rma_add_invoice.py | 112 +++++++++ rma_account/wizards/rma_add_invoice.xml | 90 ++++++++ .../rma_order_line_make_supplier_rma.py | 19 ++ rma_account/wizards/rma_refund.py | 216 ++++++++++++++++++ rma_account/wizards/rma_refund.xml | 85 +++++++ 19 files changed, 1293 insertions(+) create mode 100644 rma_account/README.rst create mode 100644 rma_account/__init__.py create mode 100644 rma_account/__openerp__.py create mode 100644 rma_account/demo/rma_operation.xml create mode 100644 rma_account/models/__init__.py create mode 100644 rma_account/models/invoice.py create mode 100644 rma_account/models/rma_operation.py create mode 100644 rma_account/models/rma_order.py create mode 100644 rma_account/models/rma_order_line.py create mode 100644 rma_account/views/invoice_view.xml create mode 100644 rma_account/views/rma_operation_view.xml create mode 100644 rma_account/views/rma_order_line_view.xml create mode 100644 rma_account/views/rma_order_view.xml create mode 100644 rma_account/wizards/__init__.py create mode 100644 rma_account/wizards/rma_add_invoice.py create mode 100644 rma_account/wizards/rma_add_invoice.xml create mode 100644 rma_account/wizards/rma_order_line_make_supplier_rma.py create mode 100644 rma_account/wizards/rma_refund.py create mode 100644 rma_account/wizards/rma_refund.xml diff --git a/rma_account/README.rst b/rma_account/README.rst new file mode 100644 index 00000000..eadfe985 --- /dev/null +++ b/rma_account/README.rst @@ -0,0 +1,51 @@ +.. image:: https://img.shields.io/badge/licence-LGPL--3-blue.svg + :alt: License LGPL-3 + +=========== +RMA Account +=========== + +This module integrates Return Merchandise Authorizations (RMA) with invoices, + allowing to: + +#. Create complete RMA's using existing invoices as a reference. +#. Create refunds from RMA. + +Usage +===== + +RMA are accessible though Inventory menu. There's four menus, divided by type +. Users can access to the list of RMA or RMA lines. + +Create an RMA: +#. Select a partner. Fill the rma lines by selecting an invoice. +#. Request approval and approve. +#. Click on RMA Lines button. +#. Click on more and select an option: "Receive products", "Create Delivery + Order, Create Refund". +#. Go back to the RMA. Set the RMA to done if not further action is required. + + +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_account/__init__.py b/rma_account/__init__.py new file mode 100644 index 00000000..4105ff51 --- /dev/null +++ b/rma_account/__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_account/__openerp__.py b/rma_account/__openerp__.py new file mode 100644 index 00000000..43522ee7 --- /dev/null +++ b/rma_account/__openerp__.py @@ -0,0 +1,24 @@ +# -*- 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 Account', + 'version': '9.0.1.0.0', + 'license': 'LGPL-3', + 'category': 'RMA', + 'summary': 'Integrates RMA with Invoice Processing', + 'author': "Eficent", + 'website': 'http://www.github.com/OCA/rma', + 'depends': ['account', 'rma'], + 'demo': ['demo/rma_operation.xml'], + 'data': ['views/rma_order_view.xml', + 'views/rma_operation_view.xml', + 'views/rma_order_line_view.xml', + 'views/invoice_view.xml', + 'wizards/rma_add_invoice.xml', + 'wizards/rma_refund.xml', + ], + 'installable': True, + 'auto_install': True, +} diff --git a/rma_account/demo/rma_operation.xml b/rma_account/demo/rma_operation.xml new file mode 100644 index 00000000..a312d6db --- /dev/null +++ b/rma_account/demo/rma_operation.xml @@ -0,0 +1,44 @@ + + + + + no + + + + no + + + + Refund before receive + RFC + ordered + no + no + customer + + + + + Refund Before deliver + RFS + ordered + no + no + supplier + + + + + no + + + + no + + + + no + + + diff --git a/rma_account/models/__init__.py b/rma_account/models/__init__.py new file mode 100644 index 00000000..90fbe336 --- /dev/null +++ b/rma_account/models/__init__.py @@ -0,0 +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 . import rma_order +from . import rma_order_line +from . import rma_operation +from . import invoice diff --git a/rma_account/models/invoice.py b/rma_account/models/invoice.py new file mode 100644 index 00000000..9f33a501 --- /dev/null +++ b/rma_account/models/invoice.py @@ -0,0 +1,87 @@ +# -*- 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 + + +class AccountInvoice(models.Model): + + _inherit = "account.invoice" + + @api.one + def _compute_rma_count(self): + rma_list = [] + for invl in self.invoice_line_ids: + for rmal in invl.rma_line_ids: + rma_list.append(rmal.rma_id.id) + self.rma_count = len(list(set(rma_list))) + + rma_count = fields.Integer(compute=_compute_rma_count, + string='# of RMA', + copy=False) + + @api.multi + def action_view_rma_supplier(self): + action = self.env.ref('rma.action_rma_supplier') + result = action.read()[0] + rma_list = [] + for invl in self.invoice_line_ids: + for rmal in invl.rma_line_ids: + rma_list.append(rmal.rma_id.id) + self.rma_count = len(list(set(rma_list))) + # choose the view_mode accordingly + if len(rma_list) != 1: + result['domain'] = "[('id', 'in', " + \ + str(rma_list) + ")]" + elif len(rma_list) == 1: + res = self.env.ref('rma.view_rma_supplier_form', False) + result['views'] = [(res and res.id or False, 'form')] + result['res_id'] = rma_list[0] + return result + + @api.multi + def action_view_rma(self): + action = self.env.ref('rma.action_rma_customer') + result = action.read()[0] + rma_list = [] + for invl in self.invoice_line_ids: + for rmal in invl.rma_line_ids: + rma_list.append(rmal.rma_id.id) + self.rma_count = len(list(set(rma_list))) + # choose the view_mode accordingly + if len(rma_list) != 1: + result['domain'] = "[('id', 'in', " + \ + str(rma_list) + ")]" + elif len(rma_list) == 1: + res = self.env.ref('rma.view_rma_form', False) + result['views'] = [(res and res.id or False, 'form')] + result['res_id'] = rma_list[0] + return result + + +class AccountInvoiceLine(models.Model): + + _inherit = "account.invoice.line" + + @api.multi + def _compute_rma_count(self): + rma_list = [] + for invl in self: + for rmal in invl.rma_line_ids: + rma_list.append(rmal.rma_id.id) + invl.rma_count = len(list(set(rma_list))) + + rma_count = fields.Integer(compute=_compute_rma_count, + string='# of RMA', + copy=False) + rma_line_ids = fields.One2many( + comodel_name='rma.order.line', inverse_name='invoice_line_id', + string="RMA", readonly=True, + help="This will contain the RMA lines for the invoice line") + + rma_line_id = fields.Many2one( + comodel_name='rma.order.line', + string="RMA line refund", + ondelete="set null", + help="This will contain the rma line that originated the refund line") diff --git a/rma_account/models/rma_operation.py b/rma_account/models/rma_operation.py new file mode 100644 index 00000000..a42c69c7 --- /dev/null +++ b/rma_account/models/rma_operation.py @@ -0,0 +1,13 @@ +# -*- 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 + + +class RmaOperation(models.Model): + _inherit = 'rma.operation' + + refund_policy = fields.Selection([ + ('no', 'No refund'), ('ordered', 'Based on Ordered Quantities'), + ('received', 'Based on Received Quantities')], string="Refund Policy", + default='no') diff --git a/rma_account/models/rma_order.py b/rma_account/models/rma_order.py new file mode 100644 index 00000000..fdcba820 --- /dev/null +++ b/rma_account/models/rma_order.py @@ -0,0 +1,145 @@ +# -*- 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 openerp.exceptions import UserError +from dateutil.relativedelta import relativedelta +from openerp.tools import DEFAULT_SERVER_DATE_FORMAT +from datetime import datetime + + +class RmaOrder(models.Model): + _inherit = "rma.order" + + @api.multi + def _compute_invoice_refund_count(self): + self.ensure_one() + invoice_list = [] + for line in self.rma_line_ids: + for refund in line.refund_line_ids: + invoice_list.append(refund.invoice_id.id) + self.invoice_refund_count = len(list(set(invoice_list))) + + @api.multi + def _compute_invoice_count(self): + self.ensure_one() + invoice_list = [] + for line in self.rma_line_ids: + if line.invoice_line_id and line.invoice_line_id.id: + invoice_list.append(line.invoice_line_id.invoice_id.id) + self.invoice_count = len(list(set(invoice_list))) + + add_invoice_id = fields.Many2one('account.invoice', string='Add Invoice', + ondelete='set null', readonly=True, + states={'draft': [('readonly', False)]}) + invoice_refund_count = fields.Integer( + compute=_compute_invoice_refund_count, + string='# of Refunds', + copy=False) + invoice_count = fields.Integer(compute=_compute_invoice_count, + string='# of Incoming Shipments', + copy=False) + + def _prepare_rma_line_from_inv_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 = { + 'invoice_line_id': line.id, + 'product_id': line.product_id.id, + 'name': line.name, + 'origin': line.invoice_id.number, + 'uom_id': line.uom_id.id, + 'operation_id': operation, + 'product_qty': line.quantity, + 'price_unit': line.invoice_id.currency_id.compute( + line.price_unit, line.currency_id, round=False), + 'rma_id': self._origin.id + } + return data + + @api.onchange('add_invoice_id') + def on_change_invoice(self): + if not self.add_invoice_id: + return {} + if not self.partner_id: + self.partner_id = self.add_invoice_id.partner_id.id + new_lines = self.env['rma.order.line'] + for line in self.add_invoice_id.invoice_line_ids: + # Load a PO line only once + if line in self.rma_line_ids.mapped('invoice_line_id'): + continue + data = self._prepare_rma_line_from_inv_line(line) + new_line = new_lines.new(data) + new_lines += new_line + + self.rma_line_ids += new_lines + self.date_rma = fields.Datetime.now() + self.delivery_address_id = self.add_invoice_id.partner_id.id + self.invoice_address_id = self.add_invoice_id.partner_id.id + self.add_invoice_id = False + return {} + + @api.model + def prepare_rma_line(self, origin_rma, rma_id, line): + line_values = super(RmaOrder, self).prepare_rma_line( + origin_rma, rma_id, line) + line_values['invoice_address_id'] = line.invoice_address_id.id + return line_values + + @api.model + def _prepare_rma_data(self, partner, origin_rma): + res = super(RmaOrder, self)._prepare_rma_data(partner, origin_rma) + res['invoice_address_id'] = partner.id + return res + + @api.multi + def action_view_invoice_refund(self): + """ + This function returns an action that display existing vendor refund + bills of given purchase order id. + When only one found, show the vendor bill immediately. + """ + action = self.env.ref('account.action_invoice_tree2') + result = action.read()[0] + invoice_list = [] + for line in self.rma_line_ids: + for refund in line.refund_line_ids: + invoice_list.append(refund.invoice_id.id) + invoice_ids = list(set(invoice_list)) + # choose the view_mode accordingly + if len(invoice_ids) != 1: + result['domain'] = "[('id', 'in', " + \ + str(invoice_ids) + ")]" + elif len(invoice_ids) == 1: + res = self.env.ref('account.invoice_supplier_form', False) + result['views'] = [(res and res.id or False, 'form')] + result['res_id'] = invoice_ids[0] + return result + + @api.multi + def action_view_invoice(self): + if self.type == "supplier": + action = self.env.ref('account.action_invoice_tree2') + else: + action = self.env.ref('account.action_invoice_tree') + result = action.read()[0] + invoice_list = [] + for line in self.rma_line_ids: + invoice_list.append(line.invoice_id.id) + invoice_ids = list(set(invoice_list)) + # choose the view_mode accordingly + if len(invoice_ids) != 1: + result['domain'] = "[('id', 'in', " + \ + str(invoice_ids) + ")]" + elif len(invoice_ids) == 1: + if self.type == "supplier": + res = self.env.ref('account.invoice_supplier_form', False) + else: + res = self.env.ref('account.invoice_form', False) + result['views'] = [(res and res.id or False, 'form')] + result['res_id'] = invoice_ids[0] + return result diff --git a/rma_account/models/rma_order_line.py b/rma_account/models/rma_order_line.py new file mode 100644 index 00000000..9f396edd --- /dev/null +++ b/rma_account/models/rma_order_line.py @@ -0,0 +1,132 @@ +# -*- 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 openerp.exceptions import UserError + + +class RmaOrderLine(models.Model): + _inherit = "rma.order.line" + + @api.model + def _default_invoice_address(self): + partner_id = self.env.context.get('partner_id', False) + if partner_id: + return self.env['res.partner'].browse(partner_id) + return False + + @api.multi + @api.depends('refund_line_ids', 'refund_line_ids.invoice_id.state', + 'refund_policy', 'type') + def _compute_qty_refunded(self): + for rec in self: + rec.qty_refunded = sum(rec.refund_line_ids.filtered( + lambda i: i.invoice_id.state in ('open', 'paid')).mapped( + 'quantity')) + + @api.one + @api.depends('refund_line_ids', 'refund_line_ids.invoice_id.state', + 'refund_policy', 'move_ids', 'move_ids.state', 'type') + def _compute_qty_to_refund(self): + qty = 0.0 + if self.refund_policy == 'ordered': + qty = self.product_qty - self.qty_refunded + elif self.refund_policy == 'received': + qty = self.qty_received - self.qty_refunded + self.qty_to_refund = qty + + @api.multi + def _compute_refund_count(self): + for rec in self: + rec.refund_count = len(rec.refund_line_ids.mapped('invoice_id')) + + invoice_address_id = fields.Many2one( + 'res.partner', string='Partner invoice address', + default=_default_invoice_address, + help="Invoice address for current rma order.") + + refund_count = fields.Integer(compute=_compute_refund_count, + string='# of Refunds', copy=False, default=0) + + invoice_line_id = fields.Many2one('account.invoice.line', + string='Invoice Line', + ondelete='restrict', + index=True) + refund_line_ids = fields.One2many(comodel_name='account.invoice.line', + inverse_name='rma_line_id', + string='Refund Lines', + copy=False, index=True, readonly=True) + invoice_id = fields.Many2one('account.invoice', string='Source', + related='invoice_line_id.invoice_id', + index=True, readonly=True) + refund_policy = fields.Selection([ + ('no', 'No refund'), ('ordered', 'Based on Ordered Quantities'), + ('received', 'Based on Received Quantities')], string="Refund Policy", + required=True, default='no') + qty_to_refund = fields.Float( + string='Qty To Refund', copy=False, + digits=dp.get_precision('Product Unit of Measure'), readonly=True, + compute=_compute_qty_to_refund, store=True) + qty_refunded = fields.Float( + string='Qty Refunded', copy=False, + digits=dp.get_precision('Product Unit of Measure'), + readonly=True, compute=_compute_qty_refunded, store=True) + + @api.onchange('operation_id') + def _onchange_operation_id(self): + result = super(RmaOrderLine, self)._onchange_operation_id() + if not self.operation_id: + return result + self.refund_policy = self.operation_id.refund_policy + return result + + @api.onchange('invoice_line_id') + def _onchange_invoice_line_id(self): + result = {} + if not self.invoice_line_id: + return result + self.origin = self.invoice_id.number + return result + + @api.multi + @api.constrains('invoice_line_id') + def _check_duplicated_lines(self): + for line in self: + matching_inv_lines = self.env['account.invoice.line'].search([( + 'id', '=', line.invoice_line_id.id)]) + if len(matching_inv_lines) > 1: + raise UserError( + _("There's an rma for the invoice line %s " + "and invoice %s" % + (line.invoice_line_id, + line.invoice_line_id.invoice_id))) + return {} + + @api.multi + def action_view_invoice(self): + action = self.env.ref('account.action_invoice_tree') + result = action.read()[0] + res = self.env.ref('account.invoice_form', False) + result['views'] = [(res and res.id or False, 'form')] + result['view_id'] = res and res.id or False + result['res_id'] = self.invoice_line_id.invoice_id.id + + return result + + @api.multi + def action_view_refunds(self): + action = self.env.ref('account.action_invoice_tree2') + result = action.read()[0] + invoice_ids = [] + for inv_line in self.refund_line_ids: + invoice_ids.append(inv_line.invoice_id.id) + # choose the view_mode accordingly + if len(invoice_ids) != 1: + result['domain'] = "[('id', 'in', " + \ + str(invoice_ids) + ")]" + elif len(invoice_ids) == 1: + res = self.env.ref('account.invoice_supplier_form', False) + result['views'] = [(res and res.id or False, 'form')] + result['res_id'] = invoice_ids[0] + return result diff --git a/rma_account/views/invoice_view.xml b/rma_account/views/invoice_view.xml new file mode 100644 index 00000000..647c5043 --- /dev/null +++ b/rma_account/views/invoice_view.xml @@ -0,0 +1,73 @@ + + + + + + account.invoice.form + account.invoice + + + +
+ +
+
+
+
+ + + account.invoice.supplier.form + account.invoice + + + +
+ +
+
+
+
+ + + rma.invoice.line.form + account.invoice.line + + + + + + + + + + + + + + + + +
+ + + Invoice Line + account.invoice.line + form + form + + + +
diff --git a/rma_account/views/rma_operation_view.xml b/rma_account/views/rma_operation_view.xml new file mode 100644 index 00000000..671a2a0e --- /dev/null +++ b/rma_account/views/rma_operation_view.xml @@ -0,0 +1,26 @@ + + + + + rma.operation.tree + rma.operation + + + + + + + + + + rma.operation.form + rma.operation + + + + + + + + + diff --git a/rma_account/views/rma_order_line_view.xml b/rma_account/views/rma_order_line_view.xml new file mode 100644 index 00000000..0e8ba106 --- /dev/null +++ b/rma_account/views/rma_order_line_view.xml @@ -0,0 +1,89 @@ + + + + + rma.order.line.supplier.form + rma.order.line + + + + + + + + + + + + + + + + + + + + + + + + + + + rma.order.line.form + rma.order.line + + + + + + + + + + + + + + + + + + + + + + + + + + + rma.order.line.select + rma.order.line + + + + + + + + + + diff --git a/rma_account/views/rma_order_view.xml b/rma_account/views/rma_order_view.xml new file mode 100644 index 00000000..3e568fb4 --- /dev/null +++ b/rma_account/views/rma_order_view.xml @@ -0,0 +1,68 @@ + + + + + + rma.order.form + rma.order + + + + + + + + + + + rma.order.supplier.form + rma.order + + + + + + + + + + + diff --git a/rma_account/wizards/__init__.py b/rma_account/wizards/__init__.py new file mode 100644 index 00000000..0e1ebd69 --- /dev/null +++ b/rma_account/wizards/__init__.py @@ -0,0 +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 . import rma_refund +from . import rma_add_invoice +from . import rma_order_line_make_supplier_rma diff --git a/rma_account/wizards/rma_add_invoice.py b/rma_account/wizards/rma_add_invoice.py new file mode 100644 index 00000000..45a7e662 --- /dev/null +++ b/rma_account/wizards/rma_add_invoice.py @@ -0,0 +1,112 @@ +# -*- 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 RmaAddinvoice(models.TransientModel): + _name = 'rma_add_invoice' + _description = 'Wizard to add rma lines' + + @api.model + def default_get(self, fields): + res = super(RmaAddinvoice, 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['invoice_id'] = False + res['invoice_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) + invoice_id = fields.Many2one(comodel_name='account.invoice', + string='Invoice') + invoice_line_ids = fields.Many2many('account.invoice.line', + 'rma_add_invoice_add_line_rel', + 'invoice_line_id', + 'rma_add_invoice_id', + string='Invoice Lines') + + def _prepare_rma_line_from_inv_line(self, line): + operation = line.product_id.rma_operation_id or \ + line.product_id.categ_id.rma_operation_id + data = { + 'invoice_line_id': line.id, + 'product_id': line.product_id.id, + 'origin': line.invoice_id.number, + 'uom_id': line.uom_id.id, + 'operation_id': operation.id, + 'product_qty': line.quantity, + 'price_unit': line.invoice_id.currency_id.compute( + line.price_unit, line.currency_id, round=False), + 'delivery_address_id': self.invoice_id.partner_id.id, + 'invoice_address_id': self.invoice_id.partner_id.id, + '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, + 'out_route_id': operation.out_route_id.id, + 'in_warehouse_id': operation.in_warehouse_id.id, + 'out_warehouse_id': operation.out_warehouse_id.id, + 'receipt_policy': operation.receipt_policy, + 'location_id': operation.location_id.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.invoice_id.partner_id.id, + 'invoice_address_id': self.invoice_id.partner_id.id + } + return data + + @api.model + def _get_existing_invoice_lines(self): + existing_invoice_lines = [] + for rma_line in self.rma_id.rma_line_ids: + existing_invoice_lines.append(rma_line.invoice_line_id) + return existing_invoice_lines + + @api.multi + def add_lines(self): + rma_line_obj = self.env['rma.order.line'] + existing_invoice_lines = self._get_existing_invoice_lines() + for line in self.invoice_line_ids: + # Load a PO line only once + if line not in existing_invoice_lines: + data = self._prepare_rma_line_from_inv_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_account/wizards/rma_add_invoice.xml b/rma_account/wizards/rma_add_invoice.xml new file mode 100644 index 00000000..83446712 --- /dev/null +++ b/rma_account/wizards/rma_add_invoice.xml @@ -0,0 +1,90 @@ + + + + + rma.add.invoice + rma_add_invoice + +
+ + + + + + + + + + + + + + + + + + + + +
+
+ +
+
+ + + Add Invoice + ir.actions.act_window + rma_add_invoice + rma.order + form + form + new + + + + + + + rma.order.line.form + rma.order + + + + + + + + rma.order.line.supplier.form + rma.order + + + + + + + +
diff --git a/rma_account/wizards/rma_order_line_make_supplier_rma.py b/rma_account/wizards/rma_order_line_make_supplier_rma.py new file mode 100644 index 00000000..9315161a --- /dev/null +++ b/rma_account/wizards/rma_order_line_make_supplier_rma.py @@ -0,0 +1,19 @@ +# -*- coding: utf-8 -*- +# Copyright 2016 Eficent Business and IT Consulting Services S.L. +# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl-3.0). + +import openerp.addons.decimal_precision as dp +from openerp import _, api, exceptions, fields, models + + +class RmaLineMakeSupplierRma(models.TransientModel): + _inherit = "rma.order.line.make.supplier.rma" + + @api.model + def _prepare_supplier_rma_line(self, rma, item): + res = super(RmaLineMakeSupplierRma, self)._prepare_supplier_rma_line( + rma, item) + if res['operation_id']: + operation = self.env['rma.operation'].browse(res['operation_id']) + res['refund_policy'] = operation.refund_policy + return res diff --git a/rma_account/wizards/rma_refund.py b/rma_account/wizards/rma_refund.py new file mode 100644 index 00000000..1b76ee9e --- /dev/null +++ b/rma_account/wizards/rma_refund.py @@ -0,0 +1,216 @@ +# -*- 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, _ +import openerp.addons.decimal_precision as dp + + +class RmaRefund(models.TransientModel): + _name = "rma.refund" + + @api.model + def _get_reason(self): + context = dict(self._context or {}) + active_ids = context.get('active_ids', False) + if active_ids: + rma_lines = self.env['rma.order.line'].browse(active_ids[0]) + return rma_lines.rma_id.name + return '' + + @api.returns('rma.order.line') + def _prepare_item(self, line): + values = {'product_id': line.product_id.id, + 'name': line.name, + 'product_qty': line.product_qty, + 'uom_id': line.uom_id.id, + 'qty_to_refund': line.qty_to_refund, + 'refund_policy': line.refund_policy, + 'invoice_address_id': line.invoice_address_id.id, + 'line_id': line.id, + 'rma_id': line.rma_id.id, + 'wiz_id': self.env.context['active_id']} + return values + + @api.model + def default_get(self, fields): + """Default values for wizard, if there is more than one supplier on + lines the supplier field is empty otherwise is the unique line + supplier. + """ + res = super(RmaRefund, self).default_get( + fields) + rma_line_obj = self.env['rma.order.line'] + rma_line_ids = self.env.context['active_ids'] or [] + active_model = self.env.context['active_model'] + + if not rma_line_ids: + return res + assert active_model == 'rma.order.line', \ + 'Bad context propagation' + + items = [] + lines = rma_line_obj.browse(rma_line_ids) + if len(lines.mapped('partner_id')) > 1: + raise exceptions.Warning( + _('Only RMA lines from the same partner can be processed at ' + 'the same time')) + for line in lines: + items.append([0, 0, self._prepare_item(line)]) + res['item_ids'] = items + return res + + date_invoice = fields.Date(string='Refund Date', + default=fields.Date.context_today, + required=True) + date = fields.Date(string='Accounting Date') + description = fields.Char(string='Reason', required=True, + default=_get_reason) + item_ids = fields.One2many( + 'rma.refund.item', + 'wiz_id', string='Items') + + @api.multi + def compute_refund(self): + for wizard in self: + first = self.item_ids[0] + values = self._prepare_refund(wizard, first.rma_id) + if len(first.line_id.invoice_address_id): + values['partner_id'] = first.line_id.invoice_address_id.id + else: + values['partner_id'] = first.rma_id.partner_id.id + new_refund = self.env['account.invoice'].create(values) + for item in self.item_ids: + refund_line_values = self.prepare_refund_line(item, new_refund) + self.env['account.invoice.line'].create( + refund_line_values) + # Put the reason in the chatter + subject = _("Invoice refund") + body = self.item_ids[0].rma_id.name + new_refund.message_post(body=body, subject=subject) + return new_refund + + @api.multi + def invoice_refund(self): + rma_line_ids = self.env['rma.order.line'].browse( + self.env.context['active_ids']) + for line in rma_line_ids: + if line.refund_policy == 'no': + raise exceptions.Warning( + _('The operation is not refund for at least one line')) + if line.state != 'approved': + raise exceptions.Warning( + _('RMA %s is not approved') % + line.rma_id.name) + new_invoice = self.compute_refund() + action = 'action_invoice_tree1' if ( + new_invoice.type in ['out_refund', 'out_invoice']) \ + else 'action_invoice_tree2' + result = self.env.ref('account.%s' % action).read()[0] + invoice_domain = eval(result['domain']) + invoice_domain.append(('id', '=', new_invoice.id)) + result['domain'] = invoice_domain + return result + + @api.model + def prepare_refund_line(self, item, refund): + accounts = item.product_id.product_tmpl_id._get_product_accounts() + if item.line_id.type == 'customer': + account = accounts['stock_output'] + else: + account = accounts['stock_input'] + if not account: + raise exceptions.ValidationError("Accounts are not configure for " + "this product") + values = { + 'name': item.rma_id.name, + 'origin': item.rma_id.name, + 'account_id': account.id, + 'price_unit': item.line_id.price_unit, + 'uom_id': item.line_id.uom_id.id, + 'product_id': item.product_id.id, + 'rma_line_id': item.line_id.id, + 'quantity': item.qty_to_refund, + 'invoice_id': refund.id + } + return values + + @api.model + def _prepare_refund(self, wizard, order): + # origin_invoices = self._get_invoice(order) + if order.type == 'customer': + journal = self.env['account.journal'].search( + [('type', '=', 'sale')], limit=1) + else: + journal = self.env['account.journal'].search( + [('type', '=', 'purchase')], limit=1) + values = { + 'name': order.name, + 'origin': order.name, + 'reference': False, + # 'account_id': account.id, + 'journal_id': journal.id, + 'partner_id': order.partner_id.id, + 'currency_id': order.partner_id.company_id.currency_id.id, + 'payment_term_id': False, + 'fiscal_position_id': + order.partner_id.property_account_position_id.id, + } + team_ids = self.env['crm.team'].search( + ['|', ('user_id', '=', self.env.uid), + ('member_ids', '=', self.env.uid)], limit=1) + team_id = team_ids[0] if team_ids else False + if team_id: + values['team_id'] = team_id.id + if order.type == 'customer': + values['type'] = 'out_refund' + else: + values['type'] = 'in_refund' + values['state'] = 'draft' + values['number'] = False + values['date'] = wizard.date_invoice + values['date_invoice'] = wizard.date or wizard.date_invoice + return values + + @api.constrains('item_ids') + @api.one + def check_unique_invoice_address_id(self): + addresses = self.item_ids.mapped('invoice_address_id') + if len(addresses) > 1: + raise exceptions.ValidationError('The invoice address must be the ' + 'same for all the lines') + return True + + +class RmaRefundItem(models.TransientModel): + _name = "rma.refund.item" + _description = "RMA Lines to refund" + + wiz_id = fields.Many2one( + 'rma.refund', + string='Wizard', required=True) + line_id = fields.Many2one('rma.order.line', + string='RMA order Line', + required=True, + readonly=True, + ondelete='cascade') + rma_id = fields.Many2one('rma.order', + related='line_id.rma_id', + string='RMA', + readonly=True) + product_id = fields.Many2one('product.product', string='Product', + readonly=True) + name = fields.Char(string='Description', required=True) + product_qty = fields.Float( + string='Quantity Ordered', copy=False, + digits=dp.get_precision('Product Unit of Measure'), + readonly=True) + invoice_address_id = fields.Many2one('res.partner', 'Invoice Address') + qty_to_refund = fields.Float( + string='Quantity To Refund', + digits=dp.get_precision('Product Unit of Measure')) + uom_id = fields.Many2one('product.uom', string='Unit of Measure', + readonly=True) + refund_policy = fields.Selection([ + ('no', 'Not required'), ('ordered', 'Based on Ordered Quantities'), + ('received', 'Based on Received Quantities')], + string="Refund Policy") diff --git a/rma_account/wizards/rma_refund.xml b/rma_account/wizards/rma_refund.xml new file mode 100644 index 00000000..a2363c48 --- /dev/null +++ b/rma_account/wizards/rma_refund.xml @@ -0,0 +1,85 @@ + + + + + + rma.refund.form + rma.refund + +
+ + + + + + + + + + + + + + + + + + + +
+
+
+
+
+ + + Create Refund + rma.refund + form + tree,form + + + new + + + + rma.order.line.form + rma.order.line + + +
+
+
+
+ + + rma.order.line.supplier.form + rma.order.line + + +
+
+
+
+ + + + Create Refund + client_action_multi + + action + rma.order.line + + +
+
From 332b89c217fa5acbb98900e25fc92bd7417ad79a Mon Sep 17 00:00:00 2001 From: lreficent Date: Wed, 2 Aug 2017 17:05:58 +0200 Subject: [PATCH 02/52] [9.0][FIX] rma: * fix assignment of moves. * default qty in rma lines. * remove account dependency. * test and flake8 fixes. --- rma_account/models/rma_operation.py | 2 +- rma_account/models/rma_order.py | 7 +------ rma_account/wizards/rma_add_invoice.py | 4 +--- rma_account/wizards/rma_order_line_make_supplier_rma.py | 2 +- 4 files changed, 4 insertions(+), 11 deletions(-) diff --git a/rma_account/models/rma_operation.py b/rma_account/models/rma_operation.py index a42c69c7..201d1f46 100644 --- a/rma_account/models/rma_operation.py +++ b/rma_account/models/rma_operation.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 fields, models class RmaOperation(models.Model): diff --git a/rma_account/models/rma_order.py b/rma_account/models/rma_order.py index fdcba820..10ca3d08 100644 --- a/rma_account/models/rma_order.py +++ b/rma_account/models/rma_order.py @@ -1,12 +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.addons import decimal_precision as dp -from openerp.exceptions import UserError -from dateutil.relativedelta import relativedelta -from openerp.tools import DEFAULT_SERVER_DATE_FORMAT -from datetime import datetime +from openerp import api, fields, models class RmaOrder(models.Model): diff --git a/rma_account/wizards/rma_add_invoice.py b/rma_account/wizards/rma_add_invoice.py index 45a7e662..a81d1098 100644 --- a/rma_account/wizards/rma_add_invoice.py +++ b/rma_account/wizards/rma_add_invoice.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 RmaAddinvoice(models.TransientModel): diff --git a/rma_account/wizards/rma_order_line_make_supplier_rma.py b/rma_account/wizards/rma_order_line_make_supplier_rma.py index 9315161a..3f798c67 100644 --- a/rma_account/wizards/rma_order_line_make_supplier_rma.py +++ b/rma_account/wizards/rma_order_line_make_supplier_rma.py @@ -3,7 +3,7 @@ # License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl-3.0). import openerp.addons.decimal_precision as dp -from openerp import _, api, exceptions, fields, models +from openerp import api, models class RmaLineMakeSupplierRma(models.TransientModel): From f3851dc8fae6401ac68605abc69efc02d17c70ef Mon Sep 17 00:00:00 2001 From: aheficent Date: Wed, 16 Aug 2017 12:52:35 +0200 Subject: [PATCH 03/52] [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_account/models/rma_order.py | 35 +++++------ rma_account/views/rma_order_line_view.xml | 4 +- rma_account/wizards/rma_add_invoice.py | 49 +++++++++------ rma_account/wizards/rma_add_invoice.xml | 61 ++++++++++++++++--- .../rma_order_line_make_supplier_rma.py | 1 - rma_account/wizards/rma_refund.py | 2 +- 6 files changed, 104 insertions(+), 48 deletions(-) diff --git a/rma_account/models/rma_order.py b/rma_account/models/rma_order.py index 10ca3d08..ff751945 100644 --- a/rma_account/models/rma_order.py +++ b/rma_account/models/rma_order.py @@ -9,21 +9,21 @@ class RmaOrder(models.Model): @api.multi def _compute_invoice_refund_count(self): - self.ensure_one() - invoice_list = [] - for line in self.rma_line_ids: - for refund in line.refund_line_ids: - invoice_list.append(refund.invoice_id.id) - self.invoice_refund_count = len(list(set(invoice_list))) + for rec in self: + invoice_list = [] + for line in rec.rma_line_ids: + for refund in line.refund_line_ids: + invoice_list.append(refund.invoice_id.id) + rec.invoice_refund_count = len(list(set(invoice_list))) @api.multi def _compute_invoice_count(self): - self.ensure_one() - invoice_list = [] - for line in self.rma_line_ids: - if line.invoice_line_id and line.invoice_line_id.id: - invoice_list.append(line.invoice_line_id.invoice_id.id) - self.invoice_count = len(list(set(invoice_list))) + for rec in self: + invoice_list = [] + for line in rec.rma_line_ids: + if line.invoice_line_id and line.invoice_line_id.id: + invoice_list.append(line.invoice_line_id.invoice_id.id) + rec.invoice_count = len(list(set(invoice_list))) add_invoice_id = fields.Many2one('account.invoice', string='Add Invoice', ondelete='set null', readonly=True, @@ -37,11 +37,12 @@ class RmaOrder(models.Model): copy=False) def _prepare_rma_line_from_inv_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.type == 'customer': + operation = self.product_id.rma_customer_operation_id or \ + self.product_id.categ_id.rma_customer_operation_id + else: + operation = self.product_id.rma_supplier_operation_id or \ + self.product_id.categ_id.rma_supplier_operation_id data = { 'invoice_line_id': line.id, 'product_id': line.product_id.id, diff --git a/rma_account/views/rma_order_line_view.xml b/rma_account/views/rma_order_line_view.xml index 0e8ba106..ed32313c 100644 --- a/rma_account/views/rma_order_line_view.xml +++ b/rma_account/views/rma_order_line_view.xml @@ -28,7 +28,7 @@ - + @@ -64,7 +64,7 @@ - + diff --git a/rma_account/wizards/rma_add_invoice.py b/rma_account/wizards/rma_add_invoice.py index a81d1098..7efdc21c 100644 --- a/rma_account/wizards/rma_add_invoice.py +++ b/rma_account/wizards/rma_add_invoice.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 @@ -20,11 +19,9 @@ class RmaAddinvoice(models.TransientModel): 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['invoice_id'] = False res['invoice_line_ids'] = False return res @@ -32,8 +29,6 @@ class RmaAddinvoice(models.TransientModel): ondelete='cascade') partner_id = fields.Many2one(comodel_name='res.partner', string='Partner', readonly=True) - invoice_id = fields.Many2one(comodel_name='account.invoice', - string='Invoice') invoice_line_ids = fields.Many2many('account.invoice.line', 'rma_add_invoice_add_line_rel', 'invoice_line_id', @@ -41,8 +36,12 @@ class RmaAddinvoice(models.TransientModel): string='Invoice Lines') def _prepare_rma_line_from_inv_line(self, line): - operation = line.product_id.rma_operation_id or \ - line.product_id.categ_id.rma_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 data = { 'invoice_line_id': line.id, 'product_id': line.product_id.id, @@ -52,8 +51,8 @@ class RmaAddinvoice(models.TransientModel): 'product_qty': line.quantity, 'price_unit': line.invoice_id.currency_id.compute( line.price_unit, line.currency_id, round=False), - 'delivery_address_id': self.invoice_id.partner_id.id, - 'invoice_address_id': self.invoice_id.partner_id.id, + 'delivery_address_id': line.invoice_id.partner_id.id, + 'invoice_address_id': line.invoice_id.partner_id.id, 'rma_id': self.rma_id.id } if not operation: @@ -66,16 +65,26 @@ class RmaAddinvoice(models.TransientModel): [('rma_selectable', '=', True)], limit=1) if not route: raise ValidationError("Please define an 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.update( - {'in_route_id': operation.in_route_id.id, - 'out_route_id': operation.out_route_id.id, - 'in_warehouse_id': operation.in_warehouse_id.id, - 'out_warehouse_id': operation.out_warehouse_id.id, - 'receipt_policy': operation.receipt_policy, - 'location_id': operation.location_id.id, + {'receipt_policy': operation.receipt_policy, 'operation_id': operation.id, 'refund_policy': operation.refund_policy, - 'delivery_policy': operation.delivery_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, + 'in_route_id': operation.in_route_id.id or route.id, + 'out_route_id': operation.out_route_id.id or route.id, + 'location_id': (operation.location_id.id or + operation.in_warehouse_id.lot_rma_id.id or + warehouse.lot_rma_id.id) }) return data @@ -83,8 +92,10 @@ class RmaAddinvoice(models.TransientModel): def _get_rma_data(self): data = { 'date_rma': fields.Datetime.now(), - 'delivery_address_id': self.invoice_id.partner_id.id, - 'invoice_address_id': self.invoice_id.partner_id.id + 'delivery_address_id': + self.invoice_line_ids[0].invoice_id.partner_id.id, + 'invoice_address_id': + self.invoice_line_ids[0].invoice_id.partner_id.id } return data diff --git a/rma_account/wizards/rma_add_invoice.xml b/rma_account/wizards/rma_add_invoice.xml index 83446712..bbe64273 100644 --- a/rma_account/wizards/rma_add_invoice.xml +++ b/rma_account/wizards/rma_add_invoice.xml @@ -11,17 +11,51 @@ domain="[('customer','=',True)]" string="Customer"/> - + + + + + + + + + + + + + + +
+
+ +
+ + + + rma.add.invoice.supplier + rma_add_invoice + +
- + + domain="[('invoice_id.partner_id', '=', partner_id), + ('invoice_id.type', '=', 'in_invoice')]"> + @@ -54,9 +88,20 @@ form new - + + + Add Invoice + ir.actions.act_window + rma_add_invoice + rma.order + form + form + new + + + rma.order.line.form @@ -78,7 +123,7 @@ + + + - @@ -51,9 +55,13 @@ string="Refunds"/> + + + - diff --git a/rma_account/wizards/rma_add_invoice.xml b/rma_account/wizards/rma_add_invoice.xml index 9ecacff3..c0d9e412 100644 --- a/rma_account/wizards/rma_add_invoice.xml +++ b/rma_account/wizards/rma_add_invoice.xml @@ -109,12 +109,11 @@ rma.order - + type="action"/> + @@ -123,12 +122,11 @@ rma.order - + type="action"/> + diff --git a/rma_account/wizards/rma_refund.xml b/rma_account/wizards/rma_refund.xml index a2363c48..65b07fe0 100644 --- a/rma_account/wizards/rma_refund.xml +++ b/rma_account/wizards/rma_refund.xml @@ -50,11 +50,11 @@ rma.order.line -
+
+
@@ -63,11 +63,11 @@ rma.order.line -
+
+
From c425031c286ccaec6a308e7f4437082888ad489c Mon Sep 17 00:00:00 2001 From: lreficent Date: Thu, 19 Oct 2017 10:10:19 +0200 Subject: [PATCH 07/52] [9.0][IMP] rma: add constrains --- rma_account/models/rma_order_line.py | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/rma_account/models/rma_order_line.py b/rma_account/models/rma_order_line.py index 077b101e..e8b9cda8 100644 --- a/rma_account/models/rma_order_line.py +++ b/rma_account/models/rma_order_line.py @@ -140,6 +140,17 @@ class RmaOrderLine(models.Model): self.update(data) self._remove_other_data_origin('invoice_line_id') + @api.multi + @api.constrains('invoice_line_id', 'partner_id') + def _check_invoice_partner(self): + for rec in self: + if (rec.invoice_line_id and + rec.invoice_line_id.invoice_id.partner_id != + rec.partner_id): + raise ValidationError(_( + "RMA customer and originating invoice line customer " + "doesn't match.")) + @api.multi def _remove_other_data_origin(self, exception): res = super(RmaOrderLine, self)._remove_other_data_origin(exception) From 62e1905862516589f67307cbc813e32531b44403 Mon Sep 17 00:00:00 2001 From: lreficent Date: Thu, 19 Oct 2017 11:29:08 +0200 Subject: [PATCH 08/52] [9.0][FIX] wizards need to specify partner. --- rma_account/wizards/rma_add_invoice.py | 1 + 1 file changed, 1 insertion(+) diff --git a/rma_account/wizards/rma_add_invoice.py b/rma_account/wizards/rma_add_invoice.py index 08af166c..a2904943 100644 --- a/rma_account/wizards/rma_add_invoice.py +++ b/rma_account/wizards/rma_add_invoice.py @@ -61,6 +61,7 @@ class RmaAddInvoice(models.TransientModel): raise ValidationError("Please define a warehouse with a" " default rma location") data = { + 'partner_id': self.partner_id.id, 'invoice_line_id': line.id, 'product_id': line.product_id.id, 'origin': line.invoice_id.number, From 5ea076bd773bd8e1321e0b4d73a2579e48a0b7ff Mon Sep 17 00:00:00 2001 From: lreficent Date: Fri, 10 Nov 2017 10:31:45 +0100 Subject: [PATCH 09/52] [9.0][FIX] rma_account: refund wizard --- rma_account/models/rma_order_line.py | 9 ++- rma_account/wizards/rma_refund.py | 111 +++++++++++++-------------- 2 files changed, 57 insertions(+), 63 deletions(-) diff --git a/rma_account/models/rma_order_line.py b/rma_account/models/rma_order_line.py index e8b9cda8..c1209054 100644 --- a/rma_account/models/rma_order_line.py +++ b/rma_account/models/rma_order_line.py @@ -56,10 +56,11 @@ class RmaOrderLine(models.Model): index=True, readonly=True, states={'draft': [('readonly', False)]}, ) - refund_line_ids = fields.One2many(comodel_name='account.invoice.line', - inverse_name='rma_line_id', - string='Refund Lines', - copy=False, index=True, readonly=True) + refund_line_ids = fields.One2many( + comodel_name='account.invoice.line', + inverse_name='rma_line_id', string='Refund Lines', + copy=False, index=True, readonly=True, + ) invoice_id = fields.Many2one('account.invoice', string='Source', related='invoice_line_id.invoice_id', index=True, readonly=True) diff --git a/rma_account/wizards/rma_refund.py b/rma_account/wizards/rma_refund.py index 04c1b166..6180115e 100644 --- a/rma_account/wizards/rma_refund.py +++ b/rma_account/wizards/rma_refund.py @@ -1,7 +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, exceptions, fields, models + +from openerp import _, api, fields, models +from openerp.exceptions import ValidationError import openerp.addons.decimal_precision as dp @@ -10,12 +12,9 @@ class RmaRefund(models.TransientModel): @api.model def _get_reason(self): - context = dict(self._context or {}) - active_ids = context.get('active_ids', False) - if active_ids: - rma_lines = self.env['rma.order.line'].browse(active_ids[0]) - return rma_lines.rma_id.name - return '' + active_ids = self.env.context.get('active_ids', False) + return self.env['rma.order.line'].browse( + active_ids[0]).rma_id.name or '' @api.returns('rma.order.line') def _prepare_item(self, line): @@ -37,55 +36,48 @@ class RmaRefund(models.TransientModel): lines the supplier field is empty otherwise is the unique line supplier. """ - res = super(RmaRefund, self).default_get( - fields) + res = super(RmaRefund, self).default_get(fields) rma_line_obj = self.env['rma.order.line'] rma_line_ids = self.env.context['active_ids'] or [] active_model = self.env.context['active_model'] - if not rma_line_ids: return res - assert active_model == 'rma.order.line', \ - 'Bad context propagation' + assert active_model == 'rma.order.line', 'Bad context propagation' items = [] lines = rma_line_obj.browse(rma_line_ids) if len(lines.mapped('partner_id')) > 1: - raise exceptions.Warning( - _('Only RMA lines from the same partner can be processed at ' - 'the same time')) + raise ValidationError( + _("Only RMAs from the same partner can be processed at " + "the same time.")) for line in lines: items.append([0, 0, self._prepare_item(line)]) res['item_ids'] = items return res - date_invoice = fields.Date(string='Refund Date', - default=fields.Date.context_today, - required=True) + date_invoice = fields.Date( + string='Refund Date', + default=fields.Date.context_today, required=True, + ) date = fields.Date(string='Accounting Date') - description = fields.Char(string='Reason', required=True, - default=_get_reason) + description = fields.Char( + string='Reason', required=True, default=_get_reason, + ) item_ids = fields.One2many( - comodel_name='rma.refund.item', inverse_name='wiz_id', string='Items') + comodel_name='rma.refund.item', + inverse_name='wiz_id', string='Items', + ) @api.multi def compute_refund(self): for wizard in self: first = self.item_ids[0] - values = self._prepare_refund(wizard, first.rma_id) - if len(first.line_id.invoice_address_id): - values['partner_id'] = first.line_id.invoice_address_id.id - else: - values['partner_id'] = first.rma_id.partner_id.id + values = self._prepare_refund(wizard, first.line_id) new_refund = self.env['account.invoice'].create(values) for item in self.item_ids: refund_line_values = self.prepare_refund_line(item, new_refund) self.env['account.invoice.line'].create( refund_line_values) - # Put the reason in the chatter - subject = _("Invoice refund") - body = self.item_ids[0].rma_id.name - new_refund.message_post(body=body, subject=subject) return new_refund @api.multi @@ -94,12 +86,11 @@ class RmaRefund(models.TransientModel): self.env.context['active_ids']) for line in rma_line_ids: if line.refund_policy == 'no': - raise exceptions.Warning( + raise ValidationError( _('The operation is not refund for at least one line')) if line.state != 'approved': - raise exceptions.Warning( - _('RMA %s is not approved') % - line.rma_id.name) + raise ValidationError( + _('RMA %s is not approved') % line.name) new_invoice = self.compute_refund() action = 'action_invoice_tree1' if ( new_invoice.type in ['out_refund', 'out_invoice']) \ @@ -118,11 +109,11 @@ class RmaRefund(models.TransientModel): else: account = accounts['stock_input'] if not account: - raise exceptions.ValidationError("Accounts are not configure for " - "this product") + raise ValidationError(_( + "Accounts are not configure for this product.")) values = { - 'name': item.rma_id.name, - 'origin': item.rma_id.name, + 'name': item.line_id.name or item.rma_id.name, + 'origin': item.line_id.name or item.rma_id.name, 'account_id': account.id, 'price_unit': item.line_id.price_unit, 'uom_id': item.line_id.uom_id.id, @@ -134,40 +125,42 @@ class RmaRefund(models.TransientModel): return values @api.model - def _prepare_refund(self, wizard, order): - # origin_invoices = self._get_invoice(order) - if order.type == 'customer': + def _prepare_refund(self, wizard, rma_line): + # origin_invoices = self._get_invoice(rma_line) + if rma_line.type == 'customer': journal = self.env['account.journal'].search( [('type', '=', 'sale')], limit=1) else: journal = self.env['account.journal'].search( [('type', '=', 'purchase')], limit=1) values = { - 'name': order.name, - 'origin': order.name, + 'name': rma_line.rma_id.name or rma_line.name, + 'origin': rma_line.rma_id.name or rma_line.name, 'reference': False, # 'account_id': account.id, 'journal_id': journal.id, - 'partner_id': order.partner_id.id, - 'currency_id': order.partner_id.company_id.currency_id.id, + 'currency_id': rma_line.partner_id.company_id.currency_id.id, 'payment_term_id': False, 'fiscal_position_id': - order.partner_id.property_account_position_id.id, + rma_line.partner_id.property_account_position_id.id, + 'state': 'draft', + 'number': False, + 'date': wizard.date, + 'date_invoice': wizard.date_invoice, + 'partner_id': rma_line.invoice_address_id.id or + rma_line.partner_id.id, } - team_ids = self.env['crm.team'].search( - ['|', ('user_id', '=', self.env.uid), - ('member_ids', '=', self.env.uid)], limit=1) - team_id = team_ids[0] if team_ids else False - if team_id: - values['team_id'] = team_id.id - if order.type == 'customer': + if self.env.registry.models.get('crm.team', False): + team_ids = self.env['crm.team'].search( + ['|', ('user_id', '=', self.env.uid), + ('member_ids', '=', self.env.uid)], limit=1) + team_id = team_ids[0] if team_ids else False + if team_id: + values['team_id'] = team_id.id + if rma_line.type == 'customer': values['type'] = 'out_refund' else: values['type'] = 'in_refund' - values['state'] = 'draft' - values['number'] = False - values['date'] = wizard.date_invoice - values['date_invoice'] = wizard.date or wizard.date_invoice return values @api.constrains('item_ids') @@ -175,8 +168,8 @@ class RmaRefund(models.TransientModel): def check_unique_invoice_address_id(self): addresses = self.item_ids.mapped('invoice_address_id') if len(addresses) > 1: - raise exceptions.ValidationError('The invoice address must be the ' - 'same for all the lines') + raise ValidationError(_( + "The invoice address must be the same for all the lines.")) return True From b411bf0c7921280fe450fd8ff49bfb5cfe6446e3 Mon Sep 17 00:00:00 2001 From: lreficent Date: Mon, 13 Nov 2017 14:05:26 +0100 Subject: [PATCH 10/52] [FIX] allow child partners too --- rma_account/views/rma_order_line_view.xml | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/rma_account/views/rma_order_line_view.xml b/rma_account/views/rma_order_line_view.xml index 58b5b8ba..50b1b344 100644 --- a/rma_account/views/rma_order_line_view.xml +++ b/rma_account/views/rma_order_line_view.xml @@ -18,7 +18,9 @@ + domain="['|', + ('invoice_id.partner_id', '=', partner_id), + ('invoice_id.partner_id', 'child_of', partner_id)]"/> @@ -58,7 +60,9 @@ + domain="['|', + ('invoice_id.partner_id', '=', partner_id), + ('invoice_id.partner_id', 'child_of', partner_id)]"/> From 7f9db8827551fad56c1ff6e544115e2c9276dc7b Mon Sep 17 00:00:00 2001 From: aheficent Date: Tue, 19 Dec 2017 18:15:20 +0100 Subject: [PATCH 11/52] [MIG]rma account v10 --- rma_account/{__openerp__.py => __manifest__.py} | 0 rma_account/models/invoice.py | 2 +- rma_account/models/rma_operation.py | 2 +- rma_account/models/rma_order.py | 2 +- rma_account/models/rma_order_line.py | 6 +++--- rma_account/wizards/rma_add_invoice.py | 4 ++-- rma_account/wizards/rma_order_line_make_supplier_rma.py | 2 +- rma_account/wizards/rma_refund.py | 6 +++--- rma_account/wizards/rma_refund.xml | 4 ++-- 9 files changed, 14 insertions(+), 14 deletions(-) rename rma_account/{__openerp__.py => __manifest__.py} (100%) diff --git a/rma_account/__openerp__.py b/rma_account/__manifest__.py similarity index 100% rename from rma_account/__openerp__.py rename to rma_account/__manifest__.py diff --git a/rma_account/models/invoice.py b/rma_account/models/invoice.py index a834d551..d233b7d1 100644 --- a/rma_account/models/invoice.py +++ b/rma_account/models/invoice.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 openerp import api, fields, models +from odoo import api, fields, models class AccountInvoice(models.Model): diff --git a/rma_account/models/rma_operation.py b/rma_account/models/rma_operation.py index 201d1f46..55aeea40 100644 --- a/rma_account/models/rma_operation.py +++ b/rma_account/models/rma_operation.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 fields, models +from odoo import fields, models class RmaOperation(models.Model): diff --git a/rma_account/models/rma_order.py b/rma_account/models/rma_order.py index b925ee93..a92bb76b 100644 --- a/rma_account/models/rma_order.py +++ b/rma_account/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_account/models/rma_order_line.py b/rma_account/models/rma_order_line.py index c1209054..67dc13d2 100644 --- a/rma_account/models/rma_order_line.py +++ b/rma_account/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, UserError -from openerp.addons import decimal_precision as dp +from odoo import _, api, fields, models +from odoo.exceptions import ValidationError, UserError +from odoo.addons import decimal_precision as dp class RmaOrderLine(models.Model): diff --git a/rma_account/wizards/rma_add_invoice.py b/rma_account/wizards/rma_add_invoice.py index a2904943..44f352be 100644 --- a/rma_account/wizards/rma_add_invoice.py +++ b/rma_account/wizards/rma_add_invoice.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 RmaAddInvoice(models.TransientModel): diff --git a/rma_account/wizards/rma_order_line_make_supplier_rma.py b/rma_account/wizards/rma_order_line_make_supplier_rma.py index 08e9db96..ead4574d 100644 --- a/rma_account/wizards/rma_order_line_make_supplier_rma.py +++ b/rma_account/wizards/rma_order_line_make_supplier_rma.py @@ -2,7 +2,7 @@ # Copyright 2016 Eficent Business and IT Consulting Services S.L. # License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl-3.0). -from openerp import api, models +from odoo import api, models class RmaLineMakeSupplierRma(models.TransientModel): diff --git a/rma_account/wizards/rma_refund.py b/rma_account/wizards/rma_refund.py index 6180115e..436e946f 100644 --- a/rma_account/wizards/rma_refund.py +++ b/rma_account/wizards/rma_refund.py @@ -2,9 +2,9 @@ # © 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 -import openerp.addons.decimal_precision as dp +from odoo import _, api, fields, models +from odoo.exceptions import ValidationError +import odoo.addons.decimal_precision as dp class RmaRefund(models.TransientModel): diff --git a/rma_account/wizards/rma_refund.xml b/rma_account/wizards/rma_refund.xml index 65b07fe0..52efcd46 100644 --- a/rma_account/wizards/rma_refund.xml +++ b/rma_account/wizards/rma_refund.xml @@ -1,5 +1,5 @@ - + @@ -82,4 +82,4 @@ - + From f8120c4e2d5a3db224919e7301485fe15c7aad80 Mon Sep 17 00:00:00 2001 From: Nikul Chaudhary Date: Fri, 10 Nov 2017 12:48:55 +0530 Subject: [PATCH 12/52] [IMP] Improved Unit Test Case and Fixed Travis --- rma_account/__manifest__.py | 2 +- rma_account/models/invoice.py | 2 +- rma_account/models/rma_order.py | 12 +- rma_account/models/rma_order_line.py | 21 +- rma_account/tests/__init__.py | 6 + rma_account/tests/test_rma.py | 395 +++++++++++++++++++++++++ rma_account/tests/test_rma_dropship.py | 96 ++++++ rma_account/tests/test_supplier_rma.py | 156 ++++++++++ rma_account/wizards/rma_refund.py | 1 + 9 files changed, 673 insertions(+), 18 deletions(-) create mode 100644 rma_account/tests/__init__.py create mode 100644 rma_account/tests/test_rma.py create mode 100644 rma_account/tests/test_rma_dropship.py create mode 100644 rma_account/tests/test_supplier_rma.py diff --git a/rma_account/__manifest__.py b/rma_account/__manifest__.py index 07696111..93f226c5 100644 --- a/rma_account/__manifest__.py +++ b/rma_account/__manifest__.py @@ -8,7 +8,7 @@ 'license': 'LGPL-3', 'category': 'RMA', 'summary': 'Integrates RMA with Invoice Processing', - 'author': "Eficent", + 'author': "Eficent, Odoo Community Association (OCA)", 'website': 'http://www.github.com/OCA/rma', 'depends': ['account', 'rma'], 'demo': ['demo/rma_operation.xml'], diff --git a/rma_account/models/invoice.py b/rma_account/models/invoice.py index d233b7d1..233ec0d7 100644 --- a/rma_account/models/invoice.py +++ b/rma_account/models/invoice.py @@ -8,7 +8,7 @@ from odoo import api, fields, models class AccountInvoice(models.Model): _inherit = "account.invoice" - @api.one + @api.depends('invoice_line_ids.rma_line_ids') def _compute_rma_count(self): for inv in self: rmas = self.mapped('invoice_line_ids.rma_line_ids') diff --git a/rma_account/models/rma_order.py b/rma_account/models/rma_order.py index a92bb76b..7b710b47 100644 --- a/rma_account/models/rma_order.py +++ b/rma_account/models/rma_order.py @@ -31,11 +31,13 @@ class RmaOrder(models.Model): def _prepare_rma_line_from_inv_line(self, line): if self.type == 'customer': - operation = self.product_id.rma_customer_operation_id or \ - self.product_id.categ_id.rma_customer_operation_id + operation =\ + self.rma_line_ids.product_id.rma_customer_operation_id or \ + self.rma_line_ids.product_id.categ_id.rma_customer_operation_id else: - operation = self.product_id.rma_supplier_operation_id or \ - self.product_id.categ_id.rma_supplier_operation_id + operation =\ + self.rma_line_ids.product_id.rma_supplier_operation_id or \ + self.rma_line_ids.product_id.categ_id.rma_supplier_operation_id data = { 'invoice_line_id': line.id, 'product_id': line.product_id.id, @@ -46,7 +48,7 @@ class RmaOrder(models.Model): 'product_qty': line.quantity, 'price_unit': line.invoice_id.currency_id.compute( line.price_unit, line.currency_id, round=False), - 'rma_id': self._origin.id + 'rma_id': self.id } return data diff --git a/rma_account/models/rma_order_line.py b/rma_account/models/rma_order_line.py index 67dc13d2..5426bc2a 100644 --- a/rma_account/models/rma_order_line.py +++ b/rma_account/models/rma_order_line.py @@ -25,16 +25,16 @@ class RmaOrderLine(models.Model): lambda i: i.invoice_id.state in ('open', 'paid')).mapped( 'quantity')) - @api.one @api.depends('refund_line_ids', 'refund_line_ids.invoice_id.state', 'refund_policy', 'move_ids', 'move_ids.state', 'type') def _compute_qty_to_refund(self): qty = 0.0 - if self.refund_policy == 'ordered': - qty = self.product_qty - self.qty_refunded - elif self.refund_policy == 'received': - qty = self.qty_received - self.qty_refunded - self.qty_to_refund = qty + for res in self: + if res.refund_policy == 'ordered': + qty = res.product_qty - res.qty_refunded + elif res.refund_policy == 'received': + qty = res.qty_received - res.qty_refunded + res.qty_to_refund = qty @api.multi def _compute_refund_count(self): @@ -94,21 +94,21 @@ class RmaOrderLine(models.Model): operation = self.env['rma.operation'].search( [('type', '=', self.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 an rma route") + raise ValidationError(_("Please define an 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") + raise ValidationError(_("Please define a warehouse with a" + " default rma location")) data = { 'product_id': line.product_id.id, 'origin': line.invoice_id.number, @@ -189,7 +189,6 @@ class RmaOrderLine(models.Model): result['views'] = [(res and res.id or False, 'form')] result['view_id'] = res and res.id or False result['res_id'] = self.invoice_line_id.invoice_id.id - return result @api.multi diff --git a/rma_account/tests/__init__.py b/rma_account/tests/__init__.py new file mode 100644 index 00000000..dfa77946 --- /dev/null +++ b/rma_account/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_account/tests/test_rma.py b/rma_account/tests/test_rma.py new file mode 100644 index 00000000..2a5873f9 --- /dev/null +++ b/rma_account/tests/test_rma.py @@ -0,0 +1,395 @@ +# -*- 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.line._compute_refund_count() + 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() + + data = {'invoice_line_id': self._create_invoice().invoice_line_ids.id} + new_line = self.rma_line.new(data) + new_line._onchange_invoice_line_id() + self.rma_customer_id.action_view_invoice_refund() + self.rma_customer_id.action_view_invoice() + + def test_on_change_invoice_rma(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.default_get([str(self._create_invoice().id), + str(self._create_invoice().invoice_line_ids.id), + str(self.partner_id.id)]) + wizard.add_lines() + self.rma_customer_id.action_view_invoice_refund() + self.rma_customer_id.action_view_invoice() + self.rma_customer_id.rma_line_ids[0].\ + invoice_id = self._create_invoice().id + self.rma_customer_id.action_view_invoice() + self.rma_customer_id.add_invoice_id = self._create_invoice().id + for line in self.rma_customer_id.rma_line_ids: + line.invoice_id.action_view_rma_supplier() + line.invoice_id.action_view_rma_customer() + + 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_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_account/tests/test_rma_dropship.py b/rma_account/tests/test_rma_dropship.py new file mode 100644 index 00000000..b19a12b2 --- /dev/null +++ b/rma_account/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_account/tests/test_supplier_rma.py b/rma_account/tests/test_supplier_rma.py new file mode 100644 index 00000000..292fc22c --- /dev/null +++ b/rma_account/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") diff --git a/rma_account/wizards/rma_refund.py b/rma_account/wizards/rma_refund.py index 436e946f..2e8df72a 100644 --- a/rma_account/wizards/rma_refund.py +++ b/rma_account/wizards/rma_refund.py @@ -4,6 +4,7 @@ from odoo import _, api, fields, models from odoo.exceptions import ValidationError +from odoo.tools.safe_eval import safe_eval as eval import odoo.addons.decimal_precision as dp From e953962773f046e97056bde92f0772f51b713686 Mon Sep 17 00:00:00 2001 From: aheficent Date: Tue, 2 Jan 2018 13:05:09 +0100 Subject: [PATCH 13/52] [FIX]various fixes --- rma_account/wizards/rma_add_invoice.py | 10 +++++----- rma_account/wizards/rma_refund.py | 1 - 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/rma_account/wizards/rma_add_invoice.py b/rma_account/wizards/rma_add_invoice.py index 44f352be..db087c61 100644 --- a/rma_account/wizards/rma_add_invoice.py +++ b/rma_account/wizards/rma_add_invoice.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 @@ -46,20 +46,20 @@ class RmaAddInvoice(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 an rma route") + raise ValidationError(_("Please define an 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, 'invoice_line_id': line.id, diff --git a/rma_account/wizards/rma_refund.py b/rma_account/wizards/rma_refund.py index 2e8df72a..1efb7b6e 100644 --- a/rma_account/wizards/rma_refund.py +++ b/rma_account/wizards/rma_refund.py @@ -165,7 +165,6 @@ class RmaRefund(models.TransientModel): return values @api.constrains('item_ids') - @api.one def check_unique_invoice_address_id(self): addresses = self.item_ids.mapped('invoice_address_id') if len(addresses) > 1: From e059b3e272f8a8e9308a4eee3b7f7517194d02e2 Mon Sep 17 00:00:00 2001 From: Nikul Chaudhary Date: Fri, 5 Jan 2018 16:43:54 +0530 Subject: [PATCH 14/52] [MIG] Migrated UT & Fixed Travis --- rma_account/tests/test_rma.py | 33 ++++++++++++++++++++------ rma_account/tests/test_rma_dropship.py | 12 ++++++++++ rma_account/tests/test_supplier_rma.py | 22 ++++++++--------- 3 files changed, 49 insertions(+), 18 deletions(-) diff --git a/rma_account/tests/test_rma.py b/rma_account/tests/test_rma.py index 2a5873f9..d57c0090 100644 --- a/rma_account/tests/test_rma.py +++ b/rma_account/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.line._compute_refund_count() diff --git a/rma_account/tests/test_rma_dropship.py b/rma_account/tests/test_rma_dropship.py index b19a12b2..abe07221 100644 --- a/rma_account/tests/test_rma_dropship.py +++ b/rma_account/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_account/tests/test_supplier_rma.py b/rma_account/tests/test_supplier_rma.py index 292fc22c..321b46e1 100644 --- a/rma_account/tests/test_supplier_rma.py +++ b/rma_account/tests/test_supplier_rma.py @@ -76,12 +76,12 @@ class TestSupplierRma(test_rma.TestRma): 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 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, + self.assertEquals(line.qty_outgoing, 0, "Wrong qty delivered") self.assertEquals(line.qty_to_receive, 2, "Wrong qty to receive") @@ -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, @@ -117,12 +117,12 @@ class TestSupplierRma(test_rma.TestRma): 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, + self.assertEquals(line.qty_to_deliver, 0, "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, + self.assertEquals(line.qty_to_deliver, 0, "Wrong qty to deliver") picking_out.action_assign() picking_out.do_transfer() @@ -131,14 +131,14 @@ class TestSupplierRma(test_rma.TestRma): "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, 6, + "Wrong qty deliver") + self.assertEquals(line.qty_outgoing, 0, "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, 6, "Wrong qty delivered") if line.product_id == self.product_2: self.assertEquals(line.qty_received, 0, From d9f6966b091ae4e314714203b25fcc0765e320cd Mon Sep 17 00:00:00 2001 From: Maxime Chambreuil Date: Fri, 9 Feb 2018 12:35:23 -0600 Subject: [PATCH 15/52] [MIG] Migrate configuration and cleanup --- rma_account/__manifest__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rma_account/__manifest__.py b/rma_account/__manifest__.py index 93f226c5..df3f6b71 100644 --- a/rma_account/__manifest__.py +++ b/rma_account/__manifest__.py @@ -20,6 +20,6 @@ 'wizards/rma_add_invoice.xml', 'wizards/rma_refund.xml', ], - 'installable': True, + 'installable': False, 'auto_install': True, } From 5620e95df1209f3dc9231aa3db6d582a08867a9e Mon Sep 17 00:00:00 2001 From: Lois Rilo Date: Wed, 23 May 2018 19:13:03 +0200 Subject: [PATCH 16/52] [9.0][IMP] rma_sale and rma_account: consider product when filtering sources on rma lines --- rma_account/models/rma_order_line.py | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/rma_account/models/rma_order_line.py b/rma_account/models/rma_order_line.py index 5426bc2a..3230c1a7 100644 --- a/rma_account/models/rma_order_line.py +++ b/rma_account/models/rma_order_line.py @@ -79,6 +79,21 @@ class RmaOrderLine(models.Model): digits=dp.get_precision('Product Unit of Measure'), readonly=True, compute=_compute_qty_refunded, store=True) + @api.onchange('product_id') + def _onchange_product_id(self): + res = super(RmaOrderLine, self)._onchange_product_id() + if res.get('domain') and self.product_id: + res['domain']['invoice_line_id'] = [ + ('product_id', '=', self.product_id.id)] + elif res.get('domain') and self.product_id: + res['domain']['invoice_line_id'] = [()] + elif not res.get('domain') and self.product_id: + res['domain'] = { + 'invoice_line_id': [('product_id', '=', self.product_id.id)]} + else: + res['domain'] = {'invoice_line_id': []} + return res + @api.multi def _prepare_rma_line_from_inv_line(self, line): self.ensure_one() From da1979af482c05dc0d44db97cce79d06104720bc Mon Sep 17 00:00:00 2001 From: Lois Rilo Date: Thu, 17 May 2018 12:40:52 +0200 Subject: [PATCH 17/52] [9.0] rma_account: * fix view * small issue in wizard * modify data file * smaller issues --- rma_account/demo/rma_operation.xml | 2 ++ rma_account/models/rma_order_line.py | 5 ++--- rma_account/views/rma_order_line_view.xml | 19 ++++++++++++------- rma_account/wizards/rma_refund.py | 21 +++++++++++---------- 4 files changed, 27 insertions(+), 20 deletions(-) diff --git a/rma_account/demo/rma_operation.xml b/rma_account/demo/rma_operation.xml index a312d6db..be6fd118 100644 --- a/rma_account/demo/rma_operation.xml +++ b/rma_account/demo/rma_operation.xml @@ -17,6 +17,7 @@ no customer + @@ -26,6 +27,7 @@ no no supplier + diff --git a/rma_account/models/rma_order_line.py b/rma_account/models/rma_order_line.py index 3230c1a7..81789c18 100644 --- a/rma_account/models/rma_order_line.py +++ b/rma_account/models/rma_order_line.py @@ -177,9 +177,8 @@ class RmaOrderLine(models.Model): @api.onchange('operation_id') def _onchange_operation_id(self): result = super(RmaOrderLine, self)._onchange_operation_id() - if not self.operation_id: - return result - self.refund_policy = self.operation_id.refund_policy + if self.operation_id: + self.refund_policy = self.operation_id.refund_policy or 'no' return result @api.multi diff --git a/rma_account/views/rma_order_line_view.xml b/rma_account/views/rma_order_line_view.xml index 50b1b344..166b9c16 100644 --- a/rma_account/views/rma_order_line_view.xml +++ b/rma_account/views/rma_order_line_view.xml @@ -49,13 +49,18 @@ + + Date: Thu, 24 May 2018 13:27:13 +0200 Subject: [PATCH 18/52] [ADD] rma_account: add rma menu on the accounting app --- rma_account/__manifest__.py | 1 + rma_account/views/rma_account_menu.xml | 51 +++++++++++++++++++++++ rma_account/views/rma_order_line_view.xml | 11 ++++- 3 files changed, 62 insertions(+), 1 deletion(-) create mode 100644 rma_account/views/rma_account_menu.xml diff --git a/rma_account/__manifest__.py b/rma_account/__manifest__.py index df3f6b71..07fadf99 100644 --- a/rma_account/__manifest__.py +++ b/rma_account/__manifest__.py @@ -17,6 +17,7 @@ 'views/rma_operation_view.xml', 'views/rma_order_line_view.xml', 'views/invoice_view.xml', + 'views/rma_account_menu.xml', 'wizards/rma_add_invoice.xml', 'wizards/rma_refund.xml', ], diff --git a/rma_account/views/rma_account_menu.xml b/rma_account/views/rma_account_menu.xml new file mode 100644 index 00000000..a62c6e07 --- /dev/null +++ b/rma_account/views/rma_account_menu.xml @@ -0,0 +1,51 @@ + + + + + + + + + + Customer RMA + rma.order.line + [('type','=', 'customer')] + {"search_default_to_refund":1} + form + tree,form + + + + Supplier RMA + rma.order.line + [('type','=', 'supplier')] + {"search_default_to_refund":1, "supplier":1} + form + tree,form + + + + + + + + diff --git a/rma_account/views/rma_order_line_view.xml b/rma_account/views/rma_order_line_view.xml index 166b9c16..f686e5d5 100644 --- a/rma_account/views/rma_order_line_view.xml +++ b/rma_account/views/rma_order_line_view.xml @@ -93,12 +93,21 @@ rma.order.line.select rma.order.line - + + + + + + + + + From 2ce2939196bfba3ad35094d603fa93526036dbc3 Mon Sep 17 00:00:00 2001 From: Lois Rilo Date: Fri, 25 May 2018 10:13:47 +0200 Subject: [PATCH 19/52] fixup! rma account menus --- rma_account/views/rma_account_menu.xml | 20 ++++---------------- 1 file changed, 4 insertions(+), 16 deletions(-) diff --git a/rma_account/views/rma_account_menu.xml b/rma_account/views/rma_account_menu.xml index a62c6e07..7388a537 100644 --- a/rma_account/views/rma_account_menu.xml +++ b/rma_account/views/rma_account_menu.xml @@ -3,18 +3,6 @@ License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl-3.0) --> - - - - Customer RMA rma.order.line @@ -35,16 +23,16 @@ From 29e4f2953b8e02eb5e6453f77bd0db9c3bb50c8a Mon Sep 17 00:00:00 2001 From: aaron Date: Fri, 25 May 2018 18:25:54 +0200 Subject: [PATCH 20/52] [IMP]add rma lines to invoices as it is done with PO --- rma_account/models/invoice.py | 51 ++++++++++++++++++++++++++++ rma_account/models/rma_order_line.py | 13 +++++++ rma_account/views/invoice_view.xml | 36 ++++++++++++++++++++ 3 files changed, 100 insertions(+) diff --git a/rma_account/models/invoice.py b/rma_account/models/invoice.py index 233ec0d7..06d74042 100644 --- a/rma_account/models/invoice.py +++ b/rma_account/models/invoice.py @@ -3,6 +3,7 @@ # License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html) from odoo import api, fields, models +from odoo.tools.float_utils import float_compare class AccountInvoice(models.Model): @@ -14,9 +15,59 @@ class AccountInvoice(models.Model): rmas = self.mapped('invoice_line_ids.rma_line_ids') inv.rma_count = len(rmas) + def _prepare_invoice_line_from_rma_line(self, line): + qty = line.qty_to_refund + if float_compare( + qty, 0.0, precision_rounding=line.uom_id.rounding) <= 0: + qty = 0.0 + # Todo fill taxes from somewhere + invoice_line = self.env['account.invoice.line'] + data = { + 'purchase_line_id': line.id, + 'name': line.name + ': '+line.name, + 'origin': line.origin, + 'uom_id': line.uom_id.id, + 'product_id': line.product_id.id, + 'account_id': invoice_line.with_context( + {'journal_id': self.journal_id.id, + 'type': 'in_invoice'})._default_account(), + 'price_unit': line.company_id.currency_id.with_context( + date=self.date_invoice).compute( + line.price_unit, self.currency_id, round=False), + 'quantity': qty, + 'discount': 0.0, + 'account_analytic_id': line.analytic_account_id.id, + 'rma_line_ids': [(4, line.id)], + } + return data + + @api.onchange('add_rma_line_id') + def on_change_add_rma_line_id(self): + if not self.add_rma_line_id: + return {} + if not self.partner_id: + self.partner_id = self.add_rma_line_id.partner_id.id + + new_line = self.env['account.invoice.line'] + if self.add_rma_line_id not in ( + self.invoice_line_ids.mapped('rma_line_id')): + data = self._prepare_invoice_line_from_rma_line( + self.add_rma_line_id) + new_line = new_line.new(data) + new_line._set_additional_fields(self) + self.invoice_line_ids += new_line + self.add_rma_line_id = False + return {} + rma_count = fields.Integer( compute=_compute_rma_count, string='# of RMA') + add_rma_line_id = fields.Many2one( + comodel_name='rma.order.line', + string="Add from RMA line", + ondelete="set null", + help="Create a refund in based on an existing rma_line") + @api.multi def action_view_rma_supplier(self): action = self.env.ref('rma.action_rma_supplier_lines') diff --git a/rma_account/models/rma_order_line.py b/rma_account/models/rma_order_line.py index 81789c18..2d49f855 100644 --- a/rma_account/models/rma_order_line.py +++ b/rma_account/models/rma_order_line.py @@ -218,3 +218,16 @@ class RmaOrderLine(models.Model): result['views'] = [(res and res.id or False, 'form')] result['res_id'] = invoice_ids[0] return result + + @api.multi + def name_get(self): + res = [] + if self.env.context.get('rma'): + for rma in self: + res.append((rma.id, "%s %s qty:%s" % ( + rma.name, + rma.product_id.name, + rma.product_qty))) + return res + else: + return super(RmaOrderLine, self).name_get() diff --git a/rma_account/views/invoice_view.xml b/rma_account/views/invoice_view.xml index c1097905..8b24a07d 100644 --- a/rma_account/views/invoice_view.xml +++ b/rma_account/views/invoice_view.xml @@ -62,6 +62,42 @@ + + account.invoice.supplier.rma + account.invoice + + + + + + + + + + account.invoice.customer.rma + account.invoice + + + + + + + + Invoice Line account.invoice.line From 526b4d5dacf1aa43c9d9d1237fc33d516815fc31 Mon Sep 17 00:00:00 2001 From: aaron Date: Thu, 31 May 2018 10:30:21 +0200 Subject: [PATCH 21/52] [IMP]nicer name_get in the invoice --- rma_account/models/invoice.py | 49 +++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/rma_account/models/invoice.py b/rma_account/models/invoice.py index 06d74042..b7309659 100644 --- a/rma_account/models/invoice.py +++ b/rma_account/models/invoice.py @@ -100,6 +100,55 @@ class AccountInvoice(models.Model): class AccountInvoiceLine(models.Model): _inherit = "account.invoice.line" + @api.model + def name_search(self, name, args=None, operator='ilike', limit=100): + """Allows to search by Invoice number. This has to be done this way, + as Odoo adds extra args to name_search on _name_search method that + will make impossible to get the desired result.""" + if not args: + args = [] + lines = self.search( + [('invoice_id.number', operator, name)] + args, limit=limit, + ) + res = lines.name_get() + if limit: + limit_rest = limit - len(lines) + else: + # limit can be 0 or None representing infinite + limit_rest = limit + if limit_rest or not limit: + args += [('id', 'not in', lines.ids)] + res += super(AccountInvoiceLine, self).name_search( + name, args=args, operator=operator, limit=limit_rest, + ) + return res + + @api.multi + def name_get(self): + res = [] + if self.env.context.get('rma'): + for inv in self: + if inv.invoice_id.reference: + res.append( + (inv.id, + "INV:%s | REF:%s | ORIG:%s | PART:%s | QTY:%s" % ( + inv.invoice_id.number or '', + inv.origin or '', + inv.invoice_id.reference or "", + inv.product_id.name, inv.quantity))) + elif inv.invoice_id.number: + res.append( + (inv.id, + "INV:%s | ORIG:%s | PART:%s | QTY:%s" % ( + inv.invoice_id.number or '', + inv.origin or '', + inv.product_id.name, inv.quantity))) + else: + res.append(super(AccountInvoiceLine, inv).name_get()[0]) + return res + else: + return super(AccountInvoiceLine, self).name_get() + @api.multi def _compute_rma_count(self): for invl in self: From b3f75d4348fbf5b7c9488c58a13e91ac0d60e0d9 Mon Sep 17 00:00:00 2001 From: Bhavesh Odedra Date: Fri, 9 Feb 2018 22:47:33 +0530 Subject: [PATCH 22/52] [11.0] MIG: rma_account --- rma_account/README.rst | 1 + rma_account/__init__.py | 2 +- rma_account/__manifest__.py | 5 +- rma_account/demo/rma_operation.xml | 8 +- rma_account/models/__init__.py | 2 +- rma_account/models/invoice.py | 35 ++-- rma_account/models/rma_operation.py | 2 +- rma_account/models/rma_order.py | 20 +-- rma_account/models/rma_order_line.py | 8 +- rma_account/tests/__init__.py | 2 +- rma_account/tests/test_rma.py | 52 +++--- rma_account/tests/test_rma_dropship.py | 13 +- rma_account/tests/test_supplier_rma.py | 75 +++----- rma_account/views/invoice_view.xml | 6 +- rma_account/views/rma_operation_view.xml | 40 ++--- rma_account/views/rma_order_line_view.xml | 167 +++++++++--------- rma_account/views/rma_order_view.xml | 122 +++++++------ rma_account/wizards/__init__.py | 1 - rma_account/wizards/rma_add_invoice.py | 5 - .../rma_order_line_make_supplier_rma.py | 1 - rma_account/wizards/rma_refund.py | 17 +- rma_account/wizards/rma_refund.xml | 141 +++++++-------- 22 files changed, 339 insertions(+), 386 deletions(-) diff --git a/rma_account/README.rst b/rma_account/README.rst index 56f20fd3..c8003352 100644 --- a/rma_account/README.rst +++ b/rma_account/README.rst @@ -43,6 +43,7 @@ Contributors * Jordi Ballester Alomar * Aaron Henriquez * Lois Rilo +* Bhavesh Odedra Maintainer ---------- diff --git a/rma_account/__init__.py b/rma_account/__init__.py index 4105ff51..f3284a96 100644 --- a/rma_account/__init__.py +++ b/rma_account/__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_account/__manifest__.py b/rma_account/__manifest__.py index 07fadf99..dfd00108 100644 --- a/rma_account/__manifest__.py +++ b/rma_account/__manifest__.py @@ -1,10 +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 Account', - 'version': '9.0.1.0.0', + 'version': '11.0.1.0.0', 'license': 'LGPL-3', 'category': 'RMA', 'summary': 'Integrates RMA with Invoice Processing', @@ -21,6 +20,6 @@ 'wizards/rma_add_invoice.xml', 'wizards/rma_refund.xml', ], - 'installable': False, + 'installable': True, 'auto_install': True, } diff --git a/rma_account/demo/rma_operation.xml b/rma_account/demo/rma_operation.xml index be6fd118..9a4e5738 100644 --- a/rma_account/demo/rma_operation.xml +++ b/rma_account/demo/rma_operation.xml @@ -1,5 +1,5 @@ - - + + no @@ -35,10 +35,6 @@ no - - no - - no diff --git a/rma_account/models/__init__.py b/rma_account/models/__init__.py index 90fbe336..bdd70de6 100644 --- a/rma_account/models/__init__.py +++ b/rma_account/models/__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 rma_order from . import rma_order_line from . import rma_operation diff --git a/rma_account/models/invoice.py b/rma_account/models/invoice.py index b7309659..18eeeda7 100644 --- a/rma_account/models/invoice.py +++ b/rma_account/models/invoice.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) @@ -72,28 +71,30 @@ class AccountInvoice(models.Model): def action_view_rma_supplier(self): action = self.env.ref('rma.action_rma_supplier_lines') result = action.read()[0] - rma_list = self.mapped('invoice_line_ids.rma_line_ids').ids - # choose the view_mode accordingly - if len(rma_list) != 1: - result['domain'] = [('id', 'in', rma_list)] - elif len(rma_list) == 1: - res = self.env.ref('rma.view_rma_line_supplier_form', False) - result['views'] = [(res and res.id or False, 'form')] - result['res_id'] = rma_list[0] + rma_ids = self.mapped('invoice_line_ids.rma_line_ids').ids + if rma_ids: + # choose the view_mode accordingly + if len(rma_ids) > 1: + result['domain'] = [('id', 'in', rma_ids)] + else: + res = self.env.ref('rma.view_rma_line_supplier_form', False) + result['views'] = [(res and res.id or False, 'form')] + result['res_id'] = rma_ids[0] return result @api.multi def action_view_rma_customer(self): action = self.env.ref('rma.action_rma_customer_lines') result = action.read()[0] - rma_list = self.mapped('invoice_line_ids.rma_line_ids').ids - # choose the view_mode accordingly - if len(rma_list) != 1: - result['domain'] = [('id', 'in', rma_list)] - elif len(rma_list) == 1: - res = self.env.ref('rma.view_rma_line_form', False) - result['views'] = [(res and res.id or False, 'form')] - result['res_id'] = rma_list[0] + rma_ids = self.mapped('invoice_line_ids.rma_line_ids').ids + if rma_ids: + # choose the view_mode accordingly + if len(rma_ids) > 1: + result['domain'] = [('id', 'in', rma_ids)] + else: + res = self.env.ref('rma.view_rma_line_form', False) + result['views'] = [(res and res.id or False, 'form')] + result['res_id'] = rma_ids[0] return result diff --git a/rma_account/models/rma_operation.py b/rma_account/models/rma_operation.py index 55aeea40..043826c6 100644 --- a/rma_account/models/rma_operation.py +++ b/rma_account/models/rma_operation.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 fields, models diff --git a/rma_account/models/rma_order.py b/rma_account/models/rma_order.py index 7b710b47..e16f4ca3 100644 --- a/rma_account/models/rma_order.py +++ b/rma_account/models/rma_order.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 @@ -94,30 +94,28 @@ class RmaOrder(models.Model): invoice_ids = self.mapped( 'rma_line_ids.refund_line_ids.invoice_id').ids # choose the view_mode accordingly - if len(invoice_ids) != 1: + if len(invoice_ids) > 1: result['domain'] = [('id', 'in', invoice_ids)] - elif len(invoice_ids) == 1: + else: res = self.env.ref('account.invoice_supplier_form', False) result['views'] = [(res and res.id or False, 'form')] - result['res_id'] = invoice_ids[0] + result['res_id'] = invoice_ids and invoice_ids[0] return result @api.multi def action_view_invoice(self): if self.type == "supplier": action = self.env.ref('account.action_invoice_tree2') + res = self.env.ref('account.invoice_supplier_form', False) else: action = self.env.ref('account.action_invoice_tree') + res = self.env.ref('account.invoice_form', False) result = action.read()[0] invoice_ids = self.mapped('rma_line_ids.invoice_id').ids # choose the view_mode accordingly - if len(invoice_ids) != 1: + if len(invoice_ids) > 1: result['domain'] = [('id', 'in', invoice_ids)] - elif len(invoice_ids) == 1: - if self.type == "supplier": - res = self.env.ref('account.invoice_supplier_form', False) - else: - res = self.env.ref('account.invoice_form', False) + else: result['views'] = [(res and res.id or False, 'form')] - result['res_id'] = invoice_ids[0] + result['res_id'] = invoice_ids and invoice_ids[0] return result diff --git a/rma_account/models/rma_order_line.py b/rma_account/models/rma_order_line.py index 2d49f855..dc1eb29e 100644 --- a/rma_account/models/rma_order_line.py +++ b/rma_account/models/rma_order_line.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 odoo.exceptions import ValidationError, UserError from odoo.addons import decimal_precision as dp @@ -211,12 +211,12 @@ class RmaOrderLine(models.Model): result = action.read()[0] invoice_ids = self.mapped('refund_line_ids.invoice_id').ids # choose the view_mode accordingly - if len(invoice_ids) != 1: + if len(invoice_ids) > 1: result['domain'] = [('id', 'in', invoice_ids)] - elif len(invoice_ids) == 1: + else: res = self.env.ref('account.invoice_supplier_form', False) result['views'] = [(res and res.id or False, 'form')] - result['res_id'] = invoice_ids[0] + result['res_id'] = invoice_ids and invoice_ids[0] return result @api.multi diff --git a/rma_account/tests/__init__.py b/rma_account/tests/__init__.py index dfa77946..fd0efa32 100644 --- a/rma_account/tests/__init__.py +++ b/rma_account/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_account/tests/test_rma.py b/rma_account/tests/test_rma.py index d57c0090..78b96232 100644 --- a/rma_account/tests/test_rma.py +++ b/rma_account/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) @@ -275,13 +274,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") @@ -297,22 +294,31 @@ class TestRma(common.TransactionCase): "Wrong qty delivered") # product specific if line.product_id == self.product_1: + self.assertEquals(line.qty_to_deliver, 0, + "Wrong qty to deliver") 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_deliver, 0, + "Wrong qty to deliver") 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_deliver, 0, + "Wrong qty to deliver") 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() + 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") @@ -344,15 +350,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) - 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: @@ -383,13 +386,12 @@ 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() - 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") + 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[0]: self.assertEquals(line.qty_to_deliver, 0, "Wrong qty to deliver") self.assertEquals(line.qty_outgoing, 0, diff --git a/rma_account/tests/test_rma_dropship.py b/rma_account/tests/test_rma_dropship.py index abe07221..c469252d 100644 --- a/rma_account/tests/test_rma_dropship.py +++ b/rma_account/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_account/tests/test_supplier_rma.py b/rma_account/tests/test_supplier_rma.py index 321b46e1..8da1bd0c 100644 --- a/rma_account/tests/test_supplier_rma.py +++ b/rma_account/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") @@ -62,9 +59,10 @@ class TestSupplierRma(test_rma.TestRma): "Wrong qty to deliver") self.assertEquals(line.qty_outgoing, 2, "Wrong qty outgoing") - - picking.action_assign() - picking.do_transfer() + picking.force_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") @@ -76,12 +74,12 @@ class TestSupplierRma(test_rma.TestRma): self.assertEquals(line.qty_to_receive, 3, "Wrong qty to receive") if line.product_id == self.product_2: - self.assertEquals(line.qty_outgoing, 0, + self.assertEquals(line.qty_delivered, 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, 0, + self.assertEquals(line.qty_delivered, 2, "Wrong qty delivered") self.assertEquals(line.qty_to_receive, 2, "Wrong qty to receive") @@ -91,65 +89,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, 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, 0, - "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, 0, - "Wrong qty to deliver") - picking_out.action_assign() - picking_out.do_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, 6, - "Wrong qty deliver") - self.assertEquals(line.qty_outgoing, 0, - "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, 6, - "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_account/views/invoice_view.xml b/rma_account/views/invoice_view.xml index 8b24a07d..e984b90e 100644 --- a/rma_account/views/invoice_view.xml +++ b/rma_account/views/invoice_view.xml @@ -1,7 +1,5 @@ - + - - account.invoice.form account.invoice @@ -60,7 +58,6 @@ - account.invoice.supplier.rma @@ -105,5 +102,4 @@ form - diff --git a/rma_account/views/rma_operation_view.xml b/rma_account/views/rma_operation_view.xml index 671a2a0e..6f9c4062 100644 --- a/rma_account/views/rma_operation_view.xml +++ b/rma_account/views/rma_operation_view.xml @@ -1,26 +1,24 @@ - + - - - rma.operation.tree - rma.operation - - - - - + + rma.operation.tree + rma.operation + + + + - + + - - rma.operation.form - rma.operation - - - - - + + rma.operation.form + rma.operation + + + + - - + + diff --git a/rma_account/views/rma_order_line_view.xml b/rma_account/views/rma_order_line_view.xml index f686e5d5..883559ce 100644 --- a/rma_account/views/rma_order_line_view.xml +++ b/rma_account/views/rma_order_line_view.xml @@ -1,47 +1,40 @@ - + - - - rma.order.line.supplier.form - rma.order.line - - - - - - - - - - - - - - - - - - - - - - - - + + rma.order.line.supplier.form + rma.order.line + + + + + + + + + - + + + + + + + + + + rma.order.line.form @@ -69,47 +62,61 @@ ('invoice_id.partner_id', '=', partner_id), ('invoice_id.partner_id', 'child_of', partner_id)]"/> - - - - - - - + + + + + + rma.order.line.form + rma.order.line + + + + + + + + + + + + + - - - - - - - - - + + + - - - - rma.order.line.select - rma.order.line - - - - - - - - - + + + + - - + + + + + rma.order.line.select + rma.order.line + + + + - - - - + + diff --git a/rma_account/views/rma_order_view.xml b/rma_account/views/rma_order_view.xml index dbbe0658..270b1058 100644 --- a/rma_account/views/rma_order_view.xml +++ b/rma_account/views/rma_order_view.xml @@ -1,68 +1,64 @@ - + - - - - rma.order.form - rma_account - rma.order - - - - + + rma.order.form - rma_account + rma.order + + + - - - - - - rma.order.supplier.form - rma.order - - - - + - - - + + + + - + + rma.order.supplier.form + rma.order + + + + + + + + diff --git a/rma_account/wizards/__init__.py b/rma_account/wizards/__init__.py index 0e1ebd69..e3832b10 100644 --- a/rma_account/wizards/__init__.py +++ b/rma_account/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_account/wizards/rma_add_invoice.py b/rma_account/wizards/rma_add_invoice.py index db087c61..8c44205d 100644 --- a/rma_account/wizards/rma_add_invoice.py +++ b/rma_account/wizards/rma_add_invoice.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) @@ -90,10 +89,6 @@ class RmaAddInvoice(models.TransientModel): def _get_rma_data(self): data = { 'date_rma': fields.Datetime.now(), - 'delivery_address_id': - self.invoice_line_ids[0].invoice_id.partner_id.id, - 'invoice_address_id': - self.invoice_line_ids[0].invoice_id.partner_id.id } return data diff --git a/rma_account/wizards/rma_order_line_make_supplier_rma.py b/rma_account/wizards/rma_order_line_make_supplier_rma.py index ead4574d..bbd94cd1 100644 --- a/rma_account/wizards/rma_order_line_make_supplier_rma.py +++ b/rma_account/wizards/rma_order_line_make_supplier_rma.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright 2016 Eficent Business and IT Consulting Services S.L. # License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl-3.0). diff --git a/rma_account/wizards/rma_refund.py b/rma_account/wizards/rma_refund.py index d0b1ad76..57491a76 100644 --- a/rma_account/wizards/rma_refund.py +++ b/rma_account/wizards/rma_refund.py @@ -1,10 +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.tools.safe_eval import safe_eval as eval import odoo.addons.decimal_precision as dp @@ -38,6 +36,7 @@ class RmaRefund(models.TransientModel): lines the supplier field is empty otherwise is the unique line supplier. """ + context = self._context.copy() res = super(RmaRefund, self).default_get(fields) rma_line_obj = self.env['rma.order.line'] rma_line_ids = self.env.context['active_ids'] or [] @@ -55,6 +54,7 @@ class RmaRefund(models.TransientModel): for line in lines: items.append([0, 0, self._prepare_item(line)]) res['item_ids'] = items + context.update({'items_ids': items}) return res date_invoice = fields.Date( @@ -96,11 +96,11 @@ class RmaRefund(models.TransientModel): new_invoice = self.compute_refund() action = 'action_invoice_tree1' if ( new_invoice.type in ['out_refund', 'out_invoice']) \ - else 'action_invoice_tree2' + else 'action_invoice_in_refund' result = self.env.ref('account.%s' % action).read()[0] - invoice_domain = eval(result['domain']) - invoice_domain.append(('id', '=', new_invoice.id)) - result['domain'] = invoice_domain + form_view = self.env.ref('account.invoice_supplier_form', False) + result['views'] = [(form_view and form_view.id or False, 'form')] + result['res_id'] = new_invoice.id return result @api.model @@ -189,8 +189,9 @@ class RmaRefundItem(models.TransientModel): related='line_id.rma_id', string='RMA', readonly=True) - product_id = fields.Many2one('product.product', string='Product', - readonly=True) + product_id = fields.Many2one('product.product', string='Product') + product = fields.Many2one('product.product', string='Product', + readonly=True) name = fields.Char(string='Description', required=True) product_qty = fields.Float( string='Quantity Ordered', copy=False, diff --git a/rma_account/wizards/rma_refund.xml b/rma_account/wizards/rma_refund.xml index 52efcd46..df4c548a 100644 --- a/rma_account/wizards/rma_refund.xml +++ b/rma_account/wizards/rma_refund.xml @@ -1,85 +1,72 @@ - - - - rma.refund.form - rma.refund - - - - - - - - - - - - - - - - - - - - - -
-
- -
-
- - - Create Refund - rma.refund - form - tree,form - - - new - - - - rma.order.line.form - rma.order.line - - - - - - - - + + + + @@ -108,15 +84,4 @@ - - rma.order.line.select - rma.order.line - - - - - - -
diff --git a/rma_account/wizards/rma_add_invoice.xml b/rma_account/wizards/rma_add_invoice.xml index c0d9e412..0ecb13ab 100644 --- a/rma_account/wizards/rma_add_invoice.xml +++ b/rma_account/wizards/rma_add_invoice.xml @@ -1,4 +1,4 @@ - + diff --git a/rma_account/wizards/rma_refund.xml b/rma_account/wizards/rma_refund.xml index df4c548a..52285b66 100644 --- a/rma_account/wizards/rma_refund.xml +++ b/rma_account/wizards/rma_refund.xml @@ -1,4 +1,4 @@ - + rma.refund.form From e136c0e6e1afdde65596b8c824775b781fde535d Mon Sep 17 00:00:00 2001 From: Maxime Chambreuil Date: Tue, 24 Jul 2018 10:16:58 -0500 Subject: [PATCH 24/52] Update __manifest__.py --- rma_account/__manifest__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rma_account/__manifest__.py b/rma_account/__manifest__.py index 52ef3732..db64990b 100644 --- a/rma_account/__manifest__.py +++ b/rma_account/__manifest__.py @@ -22,5 +22,5 @@ 'wizards/rma_refund.xml', ], 'installable': True, - 'auto_install': False, + 'auto_install': True, } From 8ded2c6c762a003e579f9cadb15c545e2ef2ee30 Mon Sep 17 00:00:00 2001 From: Bhavesh Odedra Date: Wed, 25 Jul 2018 10:20:46 +0530 Subject: [PATCH 25/52] [FIX] navigation button issue TypeError: unhashable type: 'list' --- rma_account/models/rma_order.py | 28 +++++++++++++++------------- rma_account/models/rma_order_line.py | 15 ++++++++------- 2 files changed, 23 insertions(+), 20 deletions(-) diff --git a/rma_account/models/rma_order.py b/rma_account/models/rma_order.py index e16f4ca3..20d4f89b 100644 --- a/rma_account/models/rma_order.py +++ b/rma_account/models/rma_order.py @@ -93,13 +93,14 @@ class RmaOrder(models.Model): result = action.read()[0] invoice_ids = self.mapped( 'rma_line_ids.refund_line_ids.invoice_id').ids - # choose the view_mode accordingly - if len(invoice_ids) > 1: - result['domain'] = [('id', 'in', invoice_ids)] - else: - res = self.env.ref('account.invoice_supplier_form', False) - result['views'] = [(res and res.id or False, 'form')] - result['res_id'] = invoice_ids and invoice_ids[0] + if invoice_ids: + # choose the view_mode accordingly + if len(invoice_ids) > 1: + result['domain'] = [('id', 'in', invoice_ids)] + else: + res = self.env.ref('account.invoice_supplier_form', False) + result['views'] = [(res and res.id or False, 'form')] + result['res_id'] = invoice_ids[0] return result @api.multi @@ -112,10 +113,11 @@ class RmaOrder(models.Model): res = self.env.ref('account.invoice_form', False) result = action.read()[0] invoice_ids = self.mapped('rma_line_ids.invoice_id').ids - # choose the view_mode accordingly - if len(invoice_ids) > 1: - result['domain'] = [('id', 'in', invoice_ids)] - else: - result['views'] = [(res and res.id or False, 'form')] - result['res_id'] = invoice_ids and invoice_ids[0] + if invoice_ids: + # choose the view_mode accordingly + if len(invoice_ids) > 1: + result['domain'] = [('id', 'in', invoice_ids)] + else: + result['views'] = [(res and res.id or False, 'form')] + result['res_id'] = invoice_ids[0] return result diff --git a/rma_account/models/rma_order_line.py b/rma_account/models/rma_order_line.py index 4cc4ee82..66abd2d9 100644 --- a/rma_account/models/rma_order_line.py +++ b/rma_account/models/rma_order_line.py @@ -210,13 +210,14 @@ class RmaOrderLine(models.Model): action = self.env.ref('account.action_invoice_tree2') result = action.read()[0] invoice_ids = self.mapped('refund_line_ids.invoice_id').ids - # choose the view_mode accordingly - if len(invoice_ids) > 1: - result['domain'] = [('id', 'in', invoice_ids)] - else: - res = self.env.ref('account.invoice_supplier_form', False) - result['views'] = [(res and res.id or False, 'form')] - result['res_id'] = invoice_ids and invoice_ids[0] + if invoice_ids: + # choose the view_mode accordingly + if len(invoice_ids) > 1: + result['domain'] = [('id', 'in', invoice_ids)] + else: + res = self.env.ref('account.invoice_supplier_form', False) + result['views'] = [(res and res.id or False, 'form')] + result['res_id'] = invoice_ids[0] return result @api.multi From 7841120c92c91c53563c7db6d2bb175aa3e48d0d Mon Sep 17 00:00:00 2001 From: Bhavesh Odedra Date: Wed, 25 Jul 2018 17:35:33 +0530 Subject: [PATCH 26/52] [FIX] issue of 'Add from RMA Line' in Customer/Vendor invoice --- rma_account/models/invoice.py | 1 - rma_account/views/invoice_view.xml | 8 ++++---- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/rma_account/models/invoice.py b/rma_account/models/invoice.py index 18eeeda7..6a88d0cc 100644 --- a/rma_account/models/invoice.py +++ b/rma_account/models/invoice.py @@ -35,7 +35,6 @@ class AccountInvoice(models.Model): line.price_unit, self.currency_id, round=False), 'quantity': qty, 'discount': 0.0, - 'account_analytic_id': line.analytic_account_id.id, 'rma_line_ids': [(4, line.id)], } return data diff --git a/rma_account/views/invoice_view.xml b/rma_account/views/invoice_view.xml index e984b90e..e1f19fdc 100644 --- a/rma_account/views/invoice_view.xml +++ b/rma_account/views/invoice_view.xml @@ -70,8 +70,8 @@ domain="[('type', '=', 'supplier'), ('partner_id', '=', partner_id)]" attrs="{'readonly': [('state','not in',['draft'])], - 'invisible': ['|', ('state', '=', 'done'), - ('type', '=', 'in_invoice')]}" class="oe_edit_only" + 'invisible': ['|', ('state', '=', 'paid'), + ('type', '=', 'out_invoice')]}" class="oe_edit_only" options="{'no_create': True}"/>
@@ -88,8 +88,8 @@ domain="[('type', '=', 'customer'), ('partner_id', '=', partner_id)]" attrs="{'readonly': [('state','not in',['draft'])], - 'invisible': ['|', ('state', '=', 'done'), - ('type', '=', 'out_invoice')]}" class="oe_edit_only" + 'invisible': ['|', ('state', '=', 'paid'), + ('type', '=', 'in_invoice')]}" class="oe_edit_only" options="{'no_create': True}"/>
From ba83d3d7c2229b2ba2e1d29d0f12323340ad26cc Mon Sep 17 00:00:00 2001 From: Bhavesh Odedra Date: Wed, 25 Jul 2018 17:52:40 +0530 Subject: [PATCH 27/52] [FIX] issue of filters --- rma_account/views/rma_order_line_view.xml | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/rma_account/views/rma_order_line_view.xml b/rma_account/views/rma_order_line_view.xml index 8389265e..a3f50a57 100644 --- a/rma_account/views/rma_order_line_view.xml +++ b/rma_account/views/rma_order_line_view.xml @@ -84,4 +84,15 @@
+ + rma.order.line.select + rma.order.line + + + + + + + From 05d53644004e7edaf3c58db1d05926b7f3f06ffc Mon Sep 17 00:00:00 2001 From: Bhavesh Odedra Date: Wed, 25 Jul 2018 18:23:31 +0530 Subject: [PATCH 28/52] [FIX] issue of name_get when pull down list from 'Originating Invoice Line' --- rma_account/views/rma_order_line_view.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/rma_account/views/rma_order_line_view.xml b/rma_account/views/rma_order_line_view.xml index a3f50a57..09aaf60f 100644 --- a/rma_account/views/rma_order_line_view.xml +++ b/rma_account/views/rma_order_line_view.xml @@ -17,6 +17,7 @@ @@ -59,6 +60,7 @@ From d2afe5c0b25e9cfcd549d09de04f759c2632d9b0 Mon Sep 17 00:00:00 2001 From: Lois Rilo Date: Thu, 17 May 2018 12:43:06 +0200 Subject: [PATCH 29/52] [9.0][REW] rma_account: complete rework of tests --- rma_account/tests/__init__.py | 6 +- rma_account/tests/test_rma.py | 416 ------------------------- rma_account/tests/test_rma_account.py | 211 +++++++++++++ rma_account/tests/test_rma_dropship.py | 105 ------- rma_account/tests/test_supplier_rma.py | 137 -------- 5 files changed, 213 insertions(+), 662 deletions(-) delete mode 100644 rma_account/tests/test_rma.py create mode 100644 rma_account/tests/test_rma_account.py delete mode 100644 rma_account/tests/test_rma_dropship.py delete mode 100644 rma_account/tests/test_supplier_rma.py diff --git a/rma_account/tests/__init__.py b/rma_account/tests/__init__.py index fd0efa32..77af78d7 100644 --- a/rma_account/tests/__init__.py +++ b/rma_account/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_account diff --git a/rma_account/tests/test_rma.py b/rma_account/tests/test_rma.py deleted file mode 100644 index 78b96232..00000000 --- a/rma_account/tests/test_rma.py +++ /dev/null @@ -1,416 +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.line._compute_refund_count() - 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() - - data = {'invoice_line_id': self._create_invoice().invoice_line_ids.id} - new_line = self.rma_line.new(data) - new_line._onchange_invoice_line_id() - self.rma_customer_id.action_view_invoice_refund() - self.rma_customer_id.action_view_invoice() - - def test_on_change_invoice_rma(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.default_get([str(self._create_invoice().id), - str(self._create_invoice().invoice_line_ids.id), - str(self.partner_id.id)]) - wizard.add_lines() - self.rma_customer_id.action_view_invoice_refund() - self.rma_customer_id.action_view_invoice() - self.rma_customer_id.rma_line_ids[0].\ - invoice_id = self._create_invoice().id - self.rma_customer_id.action_view_invoice() - self.rma_customer_id.add_invoice_id = self._create_invoice().id - for line in self.rma_customer_id.rma_line_ids: - line.invoice_id.action_view_rma_supplier() - line.invoice_id.action_view_rma_customer() - - 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_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_deliver, 0, - "Wrong qty to deliver") - 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_deliver, 0, - "Wrong qty to deliver") - 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_deliver, 0, - "Wrong qty to deliver") - self.assertEquals(line.qty_to_receive, 2, - "Wrong qty to receive") - self.assertEquals(line.qty_incoming, 2, - "Wrong qty incoming") - picking.action_assign() - 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[0]: - 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_account/tests/test_rma_account.py b/rma_account/tests/test_rma_account.py new file mode 100644 index 00000000..0d8802bf --- /dev/null +++ b/rma_account/tests/test_rma_account.py @@ -0,0 +1,211 @@ +# -*- 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.tests import common + + +class TestRmaAccount(common.SingleTransactionCase): + + @classmethod + def setUpClass(cls): + super(TestRmaAccount, 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_invoice_wiz = cls.env['rma_add_invoice'] + cls.rma_refund_wiz = cls.env['rma.refund'] + cls.acc_obj = cls.env['account.account'] + cls.inv_obj = cls.env['account.invoice'] + cls.invl_obj = cls.env['account.invoice.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') + receivable_type = cls.env.ref('account.data_account_type_receivable') + payable_type = cls.env.ref('account.data_account_type_payable') + cls.cust_refund_op = cls.env.ref( + 'rma_account.rma_operation_customer_refund') + + # Create partners + customer1 = cls.partner_obj.create({'name': 'Customer 1'}) + supplier1 = cls.partner_obj.create({'name': 'Supplier 1'}) + + # Create RMA group and operation: + cls.rma_group_customer = cls.rma_obj.create({ + 'partner_id': customer1.id, + 'type': 'customer', + }) + cls.rma_group_supplier = cls.rma_obj.create({ + 'partner_id': supplier1.id, + 'type': 'supplier', + }) + cls.operation_1 = cls.rma_op_obj.create({ + 'code': 'TEST', + 'name': 'Refund and receive', + 'type': 'customer', + 'receipt_policy': 'ordered', + 'refund_policy': 'ordered', + 'in_route_id': cls.rma_route_cust.id, + 'out_route_id': cls.rma_route_cust.id, + }) + + # Create products + cls.product_1 = cls.product_obj.create({ + 'name': 'Test Product 1', + 'type': 'product', + 'list_price': 100.0, + 'rma_customer_operation_id': cls.cust_refund_op.id, + }) + cls.product_2 = cls.product_obj.create({ + 'name': 'Test Product 2', + 'type': 'product', + 'list_price': 150.0, + 'rma_customer_operation_id': cls.operation_1.id, + }) + cls.product_3 = cls.product_obj.create({ + 'name': 'Test Product 3', + 'type': 'product', + }) + cls.product_4 = cls.product_obj.create({ + 'name': 'Test Product 4', + 'type': 'product', + }) + + # Create Invoices: + customer_account = cls.acc_obj. search( + [('user_type_id', '=', receivable_type.id)], limit=1).id + cls.inv_customer = cls.inv_obj.create({ + 'partner_id': customer1.id, + 'account_id': customer_account, + 'type': 'out_invoice', + }) + cls.inv_line_1 = cls.invl_obj.create({ + 'name': cls.product_1.name, + 'product_id': cls.product_1.id, + 'quantity': 12.0, + 'price_unit': 100.0, + 'invoice_id': cls.inv_customer.id, + 'uom_id': cls.product_1.uom_id.id, + 'account_id': customer_account, + }) + cls.inv_line_2 = cls.invl_obj.create({ + 'name': cls.product_2.name, + 'product_id': cls.product_2.id, + 'quantity': 15.0, + 'price_unit': 150.0, + 'invoice_id': cls.inv_customer.id, + 'uom_id': cls.product_2.uom_id.id, + 'account_id': customer_account, + }) + + supplier_account = cls.acc_obj.search( + [('user_type_id', '=', payable_type.id)], limit=1).id + cls.inv_supplier = cls.inv_obj.create({ + 'partner_id': supplier1.id, + 'account_id': supplier_account, + 'type': 'in_invoice', + }) + cls.inv_line_3 = cls.invl_obj.create({ + 'name': cls.product_3.name, + 'product_id': cls.product_3.id, + 'quantity': 17.0, + 'price_unit': 250.0, + 'invoice_id': cls.inv_supplier.id, + 'uom_id': cls.product_3.uom_id.id, + 'account_id': supplier_account, + }) + cls.inv_line_4 = cls.invl_obj.create({ + 'name': cls.product_4.name, + 'product_id': cls.product_4.id, + 'quantity': 9.0, + 'price_unit': 300.0, + 'invoice_id': cls.inv_supplier.id, + 'uom_id': cls.product_4.uom_id.id, + 'account_id': supplier_account, + }) + + def test_01_add_from_invoice_customer(self): + """Test wizard to create RMA from a customer invoice.""" + add_inv = self.rma_add_invoice_wiz.with_context({ + 'customer': True, + 'active_ids': self.rma_group_customer.id, + 'active_model': 'rma.order', + }).create({ + 'invoice_line_ids': + [(6, 0, self.inv_customer.invoice_line_ids.ids)], + }) + add_inv.add_lines() + self.assertEqual(len(self.rma_group_customer.rma_line_ids), 2) + for t in self.rma_group_supplier.rma_line_ids.mapped('type'): + self.assertEqual(t, 'customer') + rma_1 = self.rma_group_customer.rma_line_ids.filtered( + lambda r: r.product_id == self.product_1) + self.assertEqual(rma_1.operation_id, self.cust_refund_op) + rma_2 = self.rma_group_customer.rma_line_ids.filtered( + lambda r: r.product_id == self.product_2) + self.assertEqual(rma_2.operation_id, self.operation_1) + + def test_02_add_from_invoice_supplier(self): + """Test wizard to create RMA from a vendor bill.""" + add_inv = self.rma_add_invoice_wiz.with_context({ + 'supplier': True, + 'active_ids': self.rma_group_supplier.id, + 'active_model': 'rma.order', + }).create({ + 'invoice_line_ids': + [(6, 0, self.inv_supplier.invoice_line_ids.ids)], + }) + add_inv.add_lines() + self.assertEqual(len(self.rma_group_supplier.rma_line_ids), 2) + for t in self.rma_group_supplier.rma_line_ids.mapped('type'): + self.assertEqual(t, 'supplier') + + def test_03_rma_refund_operation(self): + """Test RMA quantities using refund operations.""" + # Received refund_policy: + rma_1 = self.rma_group_customer.rma_line_ids.filtered( + lambda r: r.product_id == self.product_1) + self.assertEqual(rma_1.refund_policy, 'received') + self.assertEqual(rma_1.qty_to_refund, 0.0) + # TODO: receive and check qty_to_refund is 12.0 + # Ordered refund_policy: + rma_2 = self.rma_group_customer.rma_line_ids.filtered( + lambda r: r.product_id == self.product_2) + rma_2._onchange_operation_id() + self.assertEqual(rma_2.refund_policy, 'ordered') + self.assertEqual(rma_2.qty_to_refund, 15.0) + + def test_04_rma_create_refund(self): + """Generate a Refund from a customer RMA.""" + rma = self.rma_group_customer.rma_line_ids.filtered( + lambda r: r.product_id == self.product_2) + rma.action_rma_to_approve() + rma.action_rma_approve() + self.assertEqual(rma.refund_count, 0) + self.assertEqual(rma.qty_to_refund, 15.0) + self.assertEqual(rma.qty_refunded, 0.0) + make_refund = self.rma_refund_wiz.with_context({ + 'customer': True, + 'active_ids': rma.ids, + 'active_model': 'rma.order.line', + }).create({ + 'description': 'Test refund', + }) + make_refund.invoice_refund() + rma.refund_line_ids.invoice_id.invoice_validate() + self.assertEqual(rma.refund_count, 1) + self.assertEqual(rma.qty_to_refund, 0.0) + self.assertEqual(rma.qty_refunded, 15.0) + + def test_05_fill_rma_from_inv_line(self): + """Test filling a RMA (line) from a invoice line.""" + rma = self.rma_line_obj.new({ + 'partner_id': self.inv_customer.partner_id.id, + 'invoice_line_id': self.inv_line_1.id, + }) + self.assertFalse(rma.product_id) + rma._onchange_invoice_line_id() + self.assertEqual(rma.product_id, self.product_1) + self.assertEqual(rma.product_qty, 12.0) diff --git a/rma_account/tests/test_rma_dropship.py b/rma_account/tests/test_rma_dropship.py deleted file mode 100644 index c469252d..00000000 --- a/rma_account/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_account/tests/test_supplier_rma.py b/rma_account/tests/test_supplier_rma.py deleted file mode 100644 index 8da1bd0c..00000000 --- a/rma_account/tests/test_supplier_rma.py +++ /dev/null @@ -1,137 +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.force_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_delivered, 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_delivered, 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({}) - 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 53844504c9853b1122d5b21ad297c294936cb715 Mon Sep 17 00:00:00 2001 From: aheficent Date: Mon, 30 Jul 2018 18:38:48 +0200 Subject: [PATCH 30/52] [FIX]refund policy --- rma_account/demo/rma_operation.xml | 4 ++-- rma_account/models/rma_operation.py | 1 + rma_account/tests/test_rma_account.py | 1 - 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/rma_account/demo/rma_operation.xml b/rma_account/demo/rma_operation.xml index 9a4e5738..bda0529b 100644 --- a/rma_account/demo/rma_operation.xml +++ b/rma_account/demo/rma_operation.xml @@ -12,7 +12,7 @@ Refund before receive RFC - ordered + received no no customer @@ -23,7 +23,7 @@ Refund Before deliver RFS - ordered + delivered no no supplier diff --git a/rma_account/models/rma_operation.py b/rma_account/models/rma_operation.py index 043826c6..88085d85 100644 --- a/rma_account/models/rma_operation.py +++ b/rma_account/models/rma_operation.py @@ -9,5 +9,6 @@ class RmaOperation(models.Model): refund_policy = fields.Selection([ ('no', 'No refund'), ('ordered', 'Based on Ordered Quantities'), + ('delivered', 'Based on Delivered Quantities'), ('received', 'Based on Received Quantities')], string="Refund Policy", default='no') diff --git a/rma_account/tests/test_rma_account.py b/rma_account/tests/test_rma_account.py index 0d8802bf..a4f41fdb 100644 --- a/rma_account/tests/test_rma_account.py +++ b/rma_account/tests/test_rma_account.py @@ -1,4 +1,3 @@ -# -*- 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 f59c326da48939d51b743f618cbee3e83d3ff44a Mon Sep 17 00:00:00 2001 From: aheficent Date: Tue, 21 Aug 2018 17:07:44 +0200 Subject: [PATCH 31/52] [FIX]rma account operations is data --- rma_account/__manifest__.py | 2 +- rma_account/{demo => data}/rma_operation.xml | 14 +++++++------- 2 files changed, 8 insertions(+), 8 deletions(-) rename rma_account/{demo => data}/rma_operation.xml (78%) diff --git a/rma_account/__manifest__.py b/rma_account/__manifest__.py index db64990b..8d3dfdac 100644 --- a/rma_account/__manifest__.py +++ b/rma_account/__manifest__.py @@ -10,7 +10,7 @@ 'author': "Eficent, Odoo Community Association (OCA)", 'website': 'http://www.github.com/OCA/rma', 'depends': ['account', 'rma'], - 'demo': ['demo/rma_operation.xml'], + 'demo': ['data/rma_operation.xml'], 'data': [ 'security/ir.model.access.csv', 'views/rma_order_view.xml', diff --git a/rma_account/demo/rma_operation.xml b/rma_account/data/rma_operation.xml similarity index 78% rename from rma_account/demo/rma_operation.xml rename to rma_account/data/rma_operation.xml index bda0529b..f5a84ca0 100644 --- a/rma_account/demo/rma_operation.xml +++ b/rma_account/data/rma_operation.xml @@ -10,10 +10,10 @@ - Refund before receive - RFC + Refund after receive + RF-C received - no + ordered no customer @@ -21,11 +21,11 @@ - Refund Before deliver - RFS - delivered + Refund after deliver + RF-S + ordered no - no + ordered supplier From 1c58804a9032f7e605fbb6ce5ebe97da92002473 Mon Sep 17 00:00:00 2001 From: aheficent Date: Thu, 4 Oct 2018 16:27:11 +0200 Subject: [PATCH 32/52] [FIX]currency_id was not filled --- rma_account/models/rma_order_line.py | 1 + 1 file changed, 1 insertion(+) diff --git a/rma_account/models/rma_order_line.py b/rma_account/models/rma_order_line.py index 66abd2d9..95904737 100644 --- a/rma_account/models/rma_order_line.py +++ b/rma_account/models/rma_order_line.py @@ -137,6 +137,7 @@ class RmaOrderLine(models.Model): 'receipt_policy': operation.receipt_policy, 'refund_policy': operation.refund_policy, 'delivery_policy': operation.delivery_policy, + 'currency_id': line.currency_id.id, 'in_warehouse_id': operation.in_warehouse_id.id or warehouse.id, 'out_warehouse_id': operation.out_warehouse_id.id or warehouse.id, 'in_route_id': operation.in_route_id.id or route.id, From a0b76635480615f5b7552a552e05652beba12fb5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adri=C3=A0=20Gil=20Sorribes?= Date: Mon, 19 Nov 2018 16:55:31 +0100 Subject: [PATCH 33/52] [12.0][MIG] Migrate rma_account module to v12.0 --- rma_account/__manifest__.py | 4 ++-- rma_account/tests/test_rma_account.py | 3 ++- rma_account/wizards/rma_refund.py | 4 ++-- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/rma_account/__manifest__.py b/rma_account/__manifest__.py index 8d3dfdac..67ed41f6 100644 --- a/rma_account/__manifest__.py +++ b/rma_account/__manifest__.py @@ -3,13 +3,13 @@ { 'name': 'RMA Account', - 'version': '11.0.1.0.0', + 'version': '12.0.1.0.0', 'license': 'LGPL-3', 'category': 'RMA', 'summary': 'Integrates RMA with Invoice Processing', 'author': "Eficent, Odoo Community Association (OCA)", 'website': 'http://www.github.com/OCA/rma', - 'depends': ['account', 'rma'], + 'depends': ['stock_account', 'rma'], 'demo': ['data/rma_operation.xml'], 'data': [ 'security/ir.model.access.csv', diff --git a/rma_account/tests/test_rma_account.py b/rma_account/tests/test_rma_account.py index a4f41fdb..2f53a503 100644 --- a/rma_account/tests/test_rma_account.py +++ b/rma_account/tests/test_rma_account.py @@ -1,7 +1,7 @@ # 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 odoo.tests import common class TestRmaAccount(common.SingleTransactionCase): @@ -194,6 +194,7 @@ class TestRmaAccount(common.SingleTransactionCase): }) make_refund.invoice_refund() rma.refund_line_ids.invoice_id.invoice_validate() + rma._compute_refund_count() self.assertEqual(rma.refund_count, 1) self.assertEqual(rma.qty_to_refund, 0.0) self.assertEqual(rma.qty_refunded, 15.0) diff --git a/rma_account/wizards/rma_refund.py b/rma_account/wizards/rma_refund.py index 57491a76..48c72eeb 100644 --- a/rma_account/wizards/rma_refund.py +++ b/rma_account/wizards/rma_refund.py @@ -112,7 +112,7 @@ class RmaRefund(models.TransientModel): account = accounts['stock_input'] if not account: raise ValidationError(_( - "Accounts are not configure for this product.")) + "Accounts are not configured for this product.")) values = { 'name': item.line_id.name or item.rma_id.name, 'origin': item.line_id.name or item.rma_id.name, @@ -202,7 +202,7 @@ class RmaRefundItem(models.TransientModel): qty_to_refund = fields.Float( string='Quantity To Refund', digits=dp.get_precision('Product Unit of Measure')) - uom_id = fields.Many2one('product.uom', string='Unit of Measure', + uom_id = fields.Many2one('uom.uom', string='Unit of Measure', readonly=True) refund_policy = fields.Selection(selection=[ ('no', 'Not required'), ('ordered', 'Based on Ordered Quantities'), From a645238e0c569c1c6832aa3a6583e45afb6e7d20 Mon Sep 17 00:00:00 2001 From: Akim Juillerat Date: Tue, 12 Mar 2019 17:27:55 +0100 Subject: [PATCH 34/52] rma_account: Fix uom res.groups --- rma_account/wizards/rma_add_invoice.xml | 4 ++-- rma_account/wizards/rma_refund.xml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/rma_account/wizards/rma_add_invoice.xml b/rma_account/wizards/rma_add_invoice.xml index 0ecb13ab..76023bd8 100644 --- a/rma_account/wizards/rma_add_invoice.xml +++ b/rma_account/wizards/rma_add_invoice.xml @@ -21,7 +21,7 @@ - + @@ -60,7 +60,7 @@ - + diff --git a/rma_account/wizards/rma_refund.xml b/rma_account/wizards/rma_refund.xml index 52285b66..ab9019ef 100644 --- a/rma_account/wizards/rma_refund.xml +++ b/rma_account/wizards/rma_refund.xml @@ -21,7 +21,7 @@ - + From 80863323ada0dcd8615b57c0ee67442fa43ef2c1 Mon Sep 17 00:00:00 2001 From: Akim Juillerat Date: Tue, 12 Mar 2019 17:28:20 +0100 Subject: [PATCH 35/52] rma_account: Fix res.groups on discount --- rma_account/wizards/rma_add_invoice.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rma_account/wizards/rma_add_invoice.xml b/rma_account/wizards/rma_add_invoice.xml index 76023bd8..29e3fda9 100644 --- a/rma_account/wizards/rma_add_invoice.xml +++ b/rma_account/wizards/rma_add_invoice.xml @@ -23,7 +23,7 @@ - + @@ -62,7 +62,7 @@ - + From 9d8d282beb310d9978329d80f05d76055de21068 Mon Sep 17 00:00:00 2001 From: Akim Juillerat Date: Tue, 12 Mar 2019 18:31:43 +0100 Subject: [PATCH 36/52] rma_account: Fix test opening invoice before validating --- rma_account/tests/test_rma_account.py | 1 + 1 file changed, 1 insertion(+) diff --git a/rma_account/tests/test_rma_account.py b/rma_account/tests/test_rma_account.py index 2f53a503..75733cf3 100644 --- a/rma_account/tests/test_rma_account.py +++ b/rma_account/tests/test_rma_account.py @@ -193,6 +193,7 @@ class TestRmaAccount(common.SingleTransactionCase): 'description': 'Test refund', }) make_refund.invoice_refund() + rma.refund_line_ids.invoice_id.action_invoice_open() rma.refund_line_ids.invoice_id.invoice_validate() rma._compute_refund_count() self.assertEqual(rma.refund_count, 1) From dfd409fa3ee72b49e928d5668f5089c5c3680447 Mon Sep 17 00:00:00 2001 From: Akim Juillerat Date: Mon, 18 Mar 2019 17:31:56 +0100 Subject: [PATCH 37/52] Proxy fields defaults with lambda to allow inheritance --- rma_account/README.rst | 1 + rma_account/models/rma_order_line.py | 2 +- rma_account/wizards/rma_refund.py | 3 ++- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/rma_account/README.rst b/rma_account/README.rst index c8003352..8dfed892 100644 --- a/rma_account/README.rst +++ b/rma_account/README.rst @@ -44,6 +44,7 @@ Contributors * Aaron Henriquez * Lois Rilo * Bhavesh Odedra +* Akim Juillerat Maintainer ---------- diff --git a/rma_account/models/rma_order_line.py b/rma_account/models/rma_order_line.py index 95904737..bfe24b6c 100644 --- a/rma_account/models/rma_order_line.py +++ b/rma_account/models/rma_order_line.py @@ -43,7 +43,7 @@ class RmaOrderLine(models.Model): invoice_address_id = fields.Many2one( 'res.partner', string='Partner invoice address', - default=_default_invoice_address, + default=lambda self: self._default_invoice_address(), readonly=True, states={'draft': [('readonly', False)]}, help="Invoice address for current rma order.", ) diff --git a/rma_account/wizards/rma_refund.py b/rma_account/wizards/rma_refund.py index 48c72eeb..a77e0e1e 100644 --- a/rma_account/wizards/rma_refund.py +++ b/rma_account/wizards/rma_refund.py @@ -63,7 +63,8 @@ class RmaRefund(models.TransientModel): ) date = fields.Date(string='Accounting Date') description = fields.Char( - string='Reason', required=True, default=_get_reason, + string='Reason', required=True, + default=lambda self: self._get_reason(), ) item_ids = fields.One2many( comodel_name='rma.refund.item', From 83e55d32811bc274b989bcbbb7c4f09169683cd3 Mon Sep 17 00:00:00 2001 From: Akim Juillerat Date: Mon, 18 Mar 2019 17:38:46 +0100 Subject: [PATCH 38/52] Use strings on fields compute to allow inheritance --- rma_account/models/invoice.py | 4 ++-- rma_account/models/rma_order.py | 4 ++-- rma_account/models/rma_order_line.py | 6 +++--- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/rma_account/models/invoice.py b/rma_account/models/invoice.py index 6a88d0cc..1b8b9fa9 100644 --- a/rma_account/models/invoice.py +++ b/rma_account/models/invoice.py @@ -58,7 +58,7 @@ class AccountInvoice(models.Model): return {} rma_count = fields.Integer( - compute=_compute_rma_count, string='# of RMA') + compute='_compute_rma_count', string='# of RMA') add_rma_line_id = fields.Many2one( comodel_name='rma.order.line', @@ -156,7 +156,7 @@ class AccountInvoiceLine(models.Model): invl.rma_line_count = len(rma_lines) rma_line_count = fields.Integer( - compute=_compute_rma_count, string='# of RMA') + compute='_compute_rma_count', string='# of RMA') rma_line_ids = fields.One2many( comodel_name='rma.order.line', inverse_name='invoice_line_id', string="RMA", readonly=True, diff --git a/rma_account/models/rma_order.py b/rma_account/models/rma_order.py index 20d4f89b..82a4591b 100644 --- a/rma_account/models/rma_order.py +++ b/rma_account/models/rma_order.py @@ -25,9 +25,9 @@ class RmaOrder(models.Model): ondelete='set null', readonly=True, ) invoice_refund_count = fields.Integer( - compute=_compute_invoice_refund_count, string='# of Refunds') + compute='_compute_invoice_refund_count', string='# of Refunds') invoice_count = fields.Integer( - compute=_compute_invoice_count, string='# of Invoices') + compute='_compute_invoice_count', string='# of Invoices') def _prepare_rma_line_from_inv_line(self, line): if self.type == 'customer': diff --git a/rma_account/models/rma_order_line.py b/rma_account/models/rma_order_line.py index bfe24b6c..5f4d41f5 100644 --- a/rma_account/models/rma_order_line.py +++ b/rma_account/models/rma_order_line.py @@ -48,7 +48,7 @@ class RmaOrderLine(models.Model): help="Invoice address for current rma order.", ) refund_count = fields.Integer( - compute=_compute_refund_count, string='# of Refunds', default=0) + compute='_compute_refund_count', string='# of Refunds', default=0) invoice_line_id = fields.Many2one( comodel_name='account.invoice.line', string='Originating Invoice Line', @@ -73,11 +73,11 @@ class RmaOrderLine(models.Model): qty_to_refund = fields.Float( string='Qty To Refund', copy=False, digits=dp.get_precision('Product Unit of Measure'), readonly=True, - compute=_compute_qty_to_refund, store=True) + compute='_compute_qty_to_refund', store=True) qty_refunded = fields.Float( string='Qty Refunded', copy=False, digits=dp.get_precision('Product Unit of Measure'), - readonly=True, compute=_compute_qty_refunded, store=True) + readonly=True, compute='_compute_qty_refunded', store=True) @api.onchange('product_id') def _onchange_product_id(self): From 2b08ddae325b5020e1521fe25ca7172726ab8dd0 Mon Sep 17 00:00:00 2001 From: Bhavesh Odedra Date: Fri, 24 May 2019 13:28:54 +0530 Subject: [PATCH 39/52] [SET] Correct website URL for RMA modules --- rma_account/__manifest__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rma_account/__manifest__.py b/rma_account/__manifest__.py index 67ed41f6..c53aa567 100644 --- a/rma_account/__manifest__.py +++ b/rma_account/__manifest__.py @@ -8,7 +8,7 @@ 'category': 'RMA', 'summary': 'Integrates RMA with Invoice Processing', 'author': "Eficent, Odoo Community Association (OCA)", - 'website': 'http://www.github.com/OCA/rma', + 'website': 'https://github.com/Eficent/stock-rma', 'depends': ['stock_account', 'rma'], 'demo': ['data/rma_operation.xml'], 'data': [ From f6b5a2ccbb5412f3e6bbf2d766dcb25431d42e3e Mon Sep 17 00:00:00 2001 From: Maxime Chambreuil Date: Thu, 1 Aug 2019 15:00:40 -0500 Subject: [PATCH 40/52] [FIX] rma_account: The model rma.refund has no _description --- rma_account/wizards/rma_refund.py | 1 + 1 file changed, 1 insertion(+) diff --git a/rma_account/wizards/rma_refund.py b/rma_account/wizards/rma_refund.py index a77e0e1e..553b5449 100644 --- a/rma_account/wizards/rma_refund.py +++ b/rma_account/wizards/rma_refund.py @@ -8,6 +8,7 @@ import odoo.addons.decimal_precision as dp class RmaRefund(models.TransientModel): _name = "rma.refund" + _description = "Wizard for RMA Refund" @api.model def _get_reason(self): From 46677f09dede24c1d07caa5f1673f925d4d62cc7 Mon Sep 17 00:00:00 2001 From: ahenriquez Date: Wed, 24 Jul 2019 15:50:13 +0200 Subject: [PATCH 41/52] [FIX]refund policy consistency rma vs operation --- rma_account/models/rma_order_line.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/rma_account/models/rma_order_line.py b/rma_account/models/rma_order_line.py index 5f4d41f5..812a9d3a 100644 --- a/rma_account/models/rma_order_line.py +++ b/rma_account/models/rma_order_line.py @@ -34,6 +34,8 @@ class RmaOrderLine(models.Model): qty = res.product_qty - res.qty_refunded elif res.refund_policy == 'received': qty = res.qty_received - res.qty_refunded + elif res.refund_policy == 'delivered': + qty = res.qty_delivered - res.qty_refunded res.qty_to_refund = qty @api.multi @@ -66,6 +68,7 @@ class RmaOrderLine(models.Model): index=True, readonly=True) refund_policy = fields.Selection([ ('no', 'No refund'), ('ordered', 'Based on Ordered Quantities'), + ('delivered', 'Based on Delivered Quantities'), ('received', 'Based on Received Quantities')], string="Refund Policy", required=True, default='no', readonly=True, states={'draft': [('readonly', False)]}, From f403c06a080e58bb60682fddec54155958d6db95 Mon Sep 17 00:00:00 2001 From: ahenriquez Date: Mon, 5 Aug 2019 16:36:41 +0200 Subject: [PATCH 42/52] [MIG]account_move_line_rma_order_line to v12 --- rma_account/tests/test_rma_account.py | 1 - 1 file changed, 1 deletion(-) diff --git a/rma_account/tests/test_rma_account.py b/rma_account/tests/test_rma_account.py index 75733cf3..4da5c8cb 100644 --- a/rma_account/tests/test_rma_account.py +++ b/rma_account/tests/test_rma_account.py @@ -194,7 +194,6 @@ class TestRmaAccount(common.SingleTransactionCase): }) make_refund.invoice_refund() rma.refund_line_ids.invoice_id.action_invoice_open() - rma.refund_line_ids.invoice_id.invoice_validate() rma._compute_refund_count() self.assertEqual(rma.refund_count, 1) self.assertEqual(rma.qty_to_refund, 0.0) From 4c4d5b7afa9489c437b9d7f7345ef9088c6765b0 Mon Sep 17 00:00:00 2001 From: ahenriquez Date: Wed, 18 Sep 2019 10:39:13 +0200 Subject: [PATCH 43/52] [FIX]filter by partner --- rma_account/models/rma_order_line.py | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/rma_account/models/rma_order_line.py b/rma_account/models/rma_order_line.py index 812a9d3a..61e7a5fb 100644 --- a/rma_account/models/rma_order_line.py +++ b/rma_account/models/rma_order_line.py @@ -82,19 +82,19 @@ class RmaOrderLine(models.Model): digits=dp.get_precision('Product Unit of Measure'), readonly=True, compute='_compute_qty_refunded', store=True) - @api.onchange('product_id') + @api.onchange('product_id', 'partner_id') def _onchange_product_id(self): + """Domain for sale_line_id is computed here to make it dynamic.""" res = super(RmaOrderLine, self)._onchange_product_id() - if res.get('domain') and self.product_id: - res['domain']['invoice_line_id'] = [ - ('product_id', '=', self.product_id.id)] - elif res.get('domain') and self.product_id: - res['domain']['invoice_line_id'] = [()] - elif not res.get('domain') and self.product_id: - res['domain'] = { - 'invoice_line_id': [('product_id', '=', self.product_id.id)]} - else: - res['domain'] = {'invoice_line_id': []} + if not res.get('domain'): + res['domain'] = {} + domain = [ + '|', + ('invoice_id.partner_id', '=', self.partner_id.id), + ('invoice_id.partner_id', 'child_of', self.partner_id.id)] + if self.product_id: + domain.append(('product_id', '=', self.product_id.id)) + res['domain']['invoice_line_id'] = domain return res @api.multi From 363e1009bc79565cc83f87a518a174fd960d0f85 Mon Sep 17 00:00:00 2001 From: ahenriquez Date: Tue, 29 Oct 2019 16:37:58 +0100 Subject: [PATCH 44/52] [FIX]remove autoinstall for rma_account, rma_sale and rma_purchase modules --- rma_account/__manifest__.py | 1 - 1 file changed, 1 deletion(-) diff --git a/rma_account/__manifest__.py b/rma_account/__manifest__.py index c53aa567..47ddd0b0 100644 --- a/rma_account/__manifest__.py +++ b/rma_account/__manifest__.py @@ -22,5 +22,4 @@ 'wizards/rma_refund.xml', ], 'installable': True, - 'auto_install': True, } From c86a3bf221d9d0835be912b0ab499d1a1997b5b8 Mon Sep 17 00:00:00 2001 From: mreficent Date: Fri, 29 Nov 2019 18:30:43 +0100 Subject: [PATCH 45/52] [FIX] default_gets: avoid using shadowname 'fields' --- rma_account/wizards/rma_add_invoice.py | 4 ++-- rma_account/wizards/rma_refund.py | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/rma_account/wizards/rma_add_invoice.py b/rma_account/wizards/rma_add_invoice.py index 8c44205d..f766b6f6 100644 --- a/rma_account/wizards/rma_add_invoice.py +++ b/rma_account/wizards/rma_add_invoice.py @@ -10,8 +10,8 @@ class RmaAddInvoice(models.TransientModel): _description = 'Wizard to add rma lines' @api.model - def default_get(self, fields): - res = super(RmaAddInvoice, self).default_get(fields) + def default_get(self, fields_list): + res = super(RmaAddInvoice, 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_account/wizards/rma_refund.py b/rma_account/wizards/rma_refund.py index 553b5449..0e06ee16 100644 --- a/rma_account/wizards/rma_refund.py +++ b/rma_account/wizards/rma_refund.py @@ -32,13 +32,13 @@ class RmaRefund(models.TransientModel): return values @api.model - def default_get(self, fields): + def default_get(self, fields_list): """Default values for wizard, if there is more than one supplier on lines the supplier field is empty otherwise is the unique line supplier. """ context = self._context.copy() - res = super(RmaRefund, self).default_get(fields) + res = super(RmaRefund, self).default_get(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 9328d47d738444a3743fcf0615ea6e9743c308b4 Mon Sep 17 00:00:00 2001 From: ahenriquez Date: Wed, 22 Jan 2020 11:18:04 +0100 Subject: [PATCH 46/52] [IMP] : black, isort --- rma_account/__manifest__.py | 38 +-- rma_account/models/invoice.py | 144 +++++---- rma_account/models/rma_operation.py | 17 +- rma_account/models/rma_order.py | 96 +++--- rma_account/models/rma_order_line.py | 298 ++++++++++------- rma_account/tests/test_rma_account.py | 299 +++++++++--------- rma_account/wizards/rma_add_invoice.py | 134 ++++---- .../rma_order_line_make_supplier_rma.py | 9 +- rma_account/wizards/rma_refund.py | 246 +++++++------- 9 files changed, 698 insertions(+), 583 deletions(-) diff --git a/rma_account/__manifest__.py b/rma_account/__manifest__.py index 47ddd0b0..7ba3aebe 100644 --- a/rma_account/__manifest__.py +++ b/rma_account/__manifest__.py @@ -2,24 +2,24 @@ # License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html) { - 'name': 'RMA Account', - 'version': '12.0.1.0.0', - 'license': 'LGPL-3', - 'category': 'RMA', - 'summary': 'Integrates RMA with Invoice Processing', - 'author': "Eficent, Odoo Community Association (OCA)", - 'website': 'https://github.com/Eficent/stock-rma', - 'depends': ['stock_account', 'rma'], - 'demo': ['data/rma_operation.xml'], - 'data': [ - 'security/ir.model.access.csv', - 'views/rma_order_view.xml', - 'views/rma_operation_view.xml', - 'views/rma_order_line_view.xml', - 'views/invoice_view.xml', - 'views/rma_account_menu.xml', - 'wizards/rma_add_invoice.xml', - 'wizards/rma_refund.xml', + "name": "RMA Account", + "version": "12.0.1.0.0", + "license": "LGPL-3", + "category": "RMA", + "summary": "Integrates RMA with Invoice Processing", + "author": "Eficent, Odoo Community Association (OCA)", + "website": "https://github.com/Eficent/stock-rma", + "depends": ["stock_account", "rma"], + "demo": ["data/rma_operation.xml"], + "data": [ + "security/ir.model.access.csv", + "views/rma_order_view.xml", + "views/rma_operation_view.xml", + "views/rma_order_line_view.xml", + "views/invoice_view.xml", + "views/rma_account_menu.xml", + "wizards/rma_add_invoice.xml", + "wizards/rma_refund.xml", ], - 'installable': True, + "installable": True, } diff --git a/rma_account/models/invoice.py b/rma_account/models/invoice.py index 1b8b9fa9..3fadd0b4 100644 --- a/rma_account/models/invoice.py +++ b/rma_account/models/invoice.py @@ -8,92 +8,89 @@ from odoo.tools.float_utils import float_compare class AccountInvoice(models.Model): _inherit = "account.invoice" - @api.depends('invoice_line_ids.rma_line_ids') + @api.depends("invoice_line_ids.rma_line_ids") def _compute_rma_count(self): for inv in self: - rmas = self.mapped('invoice_line_ids.rma_line_ids') + rmas = self.mapped("invoice_line_ids.rma_line_ids") inv.rma_count = len(rmas) def _prepare_invoice_line_from_rma_line(self, line): qty = line.qty_to_refund - if float_compare( - qty, 0.0, precision_rounding=line.uom_id.rounding) <= 0: + if float_compare(qty, 0.0, precision_rounding=line.uom_id.rounding) <= 0: qty = 0.0 # Todo fill taxes from somewhere - invoice_line = self.env['account.invoice.line'] + invoice_line = self.env["account.invoice.line"] data = { - 'purchase_line_id': line.id, - 'name': line.name + ': '+line.name, - 'origin': line.origin, - 'uom_id': line.uom_id.id, - 'product_id': line.product_id.id, - 'account_id': invoice_line.with_context( - {'journal_id': self.journal_id.id, - 'type': 'in_invoice'})._default_account(), - 'price_unit': line.company_id.currency_id.with_context( - date=self.date_invoice).compute( - line.price_unit, self.currency_id, round=False), - 'quantity': qty, - 'discount': 0.0, - 'rma_line_ids': [(4, line.id)], + "purchase_line_id": line.id, + "name": line.name + ": " + line.name, + "origin": line.origin, + "uom_id": line.uom_id.id, + "product_id": line.product_id.id, + "account_id": invoice_line.with_context( + {"journal_id": self.journal_id.id, "type": "in_invoice"} + )._default_account(), + "price_unit": line.company_id.currency_id.with_context( + date=self.date_invoice + ).compute(line.price_unit, self.currency_id, round=False), + "quantity": qty, + "discount": 0.0, + "rma_line_ids": [(4, line.id)], } return data - @api.onchange('add_rma_line_id') + @api.onchange("add_rma_line_id") def on_change_add_rma_line_id(self): if not self.add_rma_line_id: return {} if not self.partner_id: self.partner_id = self.add_rma_line_id.partner_id.id - new_line = self.env['account.invoice.line'] - if self.add_rma_line_id not in ( - self.invoice_line_ids.mapped('rma_line_id')): - data = self._prepare_invoice_line_from_rma_line( - self.add_rma_line_id) + new_line = self.env["account.invoice.line"] + if self.add_rma_line_id not in (self.invoice_line_ids.mapped("rma_line_id")): + data = self._prepare_invoice_line_from_rma_line(self.add_rma_line_id) new_line = new_line.new(data) new_line._set_additional_fields(self) self.invoice_line_ids += new_line self.add_rma_line_id = False return {} - rma_count = fields.Integer( - compute='_compute_rma_count', string='# of RMA') + rma_count = fields.Integer(compute="_compute_rma_count", string="# of RMA") add_rma_line_id = fields.Many2one( - comodel_name='rma.order.line', + comodel_name="rma.order.line", string="Add from RMA line", ondelete="set null", - help="Create a refund in based on an existing rma_line") + help="Create a refund in based on an existing rma_line", + ) @api.multi def action_view_rma_supplier(self): - action = self.env.ref('rma.action_rma_supplier_lines') + action = self.env.ref("rma.action_rma_supplier_lines") result = action.read()[0] - rma_ids = self.mapped('invoice_line_ids.rma_line_ids').ids + rma_ids = self.mapped("invoice_line_ids.rma_line_ids").ids if rma_ids: # choose the view_mode accordingly if len(rma_ids) > 1: - result['domain'] = [('id', 'in', rma_ids)] + result["domain"] = [("id", "in", rma_ids)] else: - res = self.env.ref('rma.view_rma_line_supplier_form', False) - result['views'] = [(res and res.id or False, 'form')] - result['res_id'] = rma_ids[0] + res = self.env.ref("rma.view_rma_line_supplier_form", False) + result["views"] = [(res and res.id or False, "form")] + result["res_id"] = rma_ids[0] return result @api.multi def action_view_rma_customer(self): - action = self.env.ref('rma.action_rma_customer_lines') + action = self.env.ref("rma.action_rma_customer_lines") result = action.read()[0] - rma_ids = self.mapped('invoice_line_ids.rma_line_ids').ids + rma_ids = self.mapped("invoice_line_ids.rma_line_ids").ids if rma_ids: # choose the view_mode accordingly if len(rma_ids) > 1: - result['domain'] = [('id', 'in', rma_ids)] + result["domain"] = [("id", "in", rma_ids)] else: - res = self.env.ref('rma.view_rma_line_form', False) - result['views'] = [(res and res.id or False, 'form')] - result['res_id'] = rma_ids[0] + res = self.env.ref("rma.view_rma_line_form", False) + result["views"] = [(res and res.id or False, "form")] + result["res_id"] = rma_ids[0] return result @@ -101,15 +98,13 @@ class AccountInvoiceLine(models.Model): _inherit = "account.invoice.line" @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 Invoice number. This has to be done this way, as Odoo adds extra args to name_search on _name_search method that will make impossible to get the desired result.""" if not args: args = [] - lines = self.search( - [('invoice_id.number', operator, name)] + args, limit=limit, - ) + lines = self.search([("invoice_id.number", operator, name)] + args, limit=limit) res = lines.name_get() if limit: limit_rest = limit - len(lines) @@ -117,32 +112,44 @@ class AccountInvoiceLine(models.Model): # limit can be 0 or None representing infinite limit_rest = limit if limit_rest or not limit: - args += [('id', 'not in', lines.ids)] + args += [("id", "not in", lines.ids)] res += super(AccountInvoiceLine, self).name_search( - name, args=args, operator=operator, limit=limit_rest, + name, args=args, operator=operator, limit=limit_rest ) return res @api.multi def name_get(self): res = [] - if self.env.context.get('rma'): + if self.env.context.get("rma"): for inv in self: if inv.invoice_id.reference: res.append( - (inv.id, - "INV:%s | REF:%s | ORIG:%s | PART:%s | QTY:%s" % ( - inv.invoice_id.number or '', - inv.origin or '', - inv.invoice_id.reference or "", - inv.product_id.name, inv.quantity))) + ( + inv.id, + "INV:%s | REF:%s | ORIG:%s | PART:%s | QTY:%s" + % ( + inv.invoice_id.number or "", + inv.origin or "", + inv.invoice_id.reference or "", + inv.product_id.name, + inv.quantity, + ), + ) + ) elif inv.invoice_id.number: res.append( - (inv.id, - "INV:%s | ORIG:%s | PART:%s | QTY:%s" % ( - inv.invoice_id.number or '', - inv.origin or '', - inv.product_id.name, inv.quantity))) + ( + inv.id, + "INV:%s | ORIG:%s | PART:%s | QTY:%s" + % ( + inv.invoice_id.number or "", + inv.origin or "", + inv.product_id.name, + inv.quantity, + ), + ) + ) else: res.append(super(AccountInvoiceLine, inv).name_get()[0]) return res @@ -152,18 +159,21 @@ class AccountInvoiceLine(models.Model): @api.multi def _compute_rma_count(self): for invl in self: - rma_lines = invl.mapped('rma_line_ids') + rma_lines = invl.mapped("rma_line_ids") invl.rma_line_count = len(rma_lines) - rma_line_count = fields.Integer( - compute='_compute_rma_count', string='# of RMA') + rma_line_count = fields.Integer(compute="_compute_rma_count", string="# of RMA") rma_line_ids = fields.One2many( - comodel_name='rma.order.line', inverse_name='invoice_line_id', - string="RMA", readonly=True, - help="This will contain the RMA lines for the invoice line") + comodel_name="rma.order.line", + inverse_name="invoice_line_id", + string="RMA", + readonly=True, + help="This will contain the RMA lines for the invoice line", + ) rma_line_id = fields.Many2one( - comodel_name='rma.order.line', + comodel_name="rma.order.line", string="RMA line refund", ondelete="set null", - help="This will contain the rma line that originated the refund line") + help="This will contain the rma line that originated the refund line", + ) diff --git a/rma_account/models/rma_operation.py b/rma_account/models/rma_operation.py index 88085d85..53ce4ed3 100644 --- a/rma_account/models/rma_operation.py +++ b/rma_account/models/rma_operation.py @@ -5,10 +5,15 @@ from odoo import fields, models class RmaOperation(models.Model): - _inherit = 'rma.operation' + _inherit = "rma.operation" - refund_policy = fields.Selection([ - ('no', 'No refund'), ('ordered', 'Based on Ordered Quantities'), - ('delivered', 'Based on Delivered Quantities'), - ('received', 'Based on Received Quantities')], string="Refund Policy", - default='no') + refund_policy = fields.Selection( + [ + ("no", "No refund"), + ("ordered", "Based on Ordered Quantities"), + ("delivered", "Based on Delivered Quantities"), + ("received", "Based on Received Quantities"), + ], + string="Refund Policy", + default="no", + ) diff --git a/rma_account/models/rma_order.py b/rma_account/models/rma_order.py index 82a4591b..240ca011 100644 --- a/rma_account/models/rma_order.py +++ b/rma_account/models/rma_order.py @@ -10,58 +10,64 @@ class RmaOrder(models.Model): @api.multi def _compute_invoice_refund_count(self): for rec in self: - invoices = rec.mapped( - 'rma_line_ids.refund_line_ids.invoice_id') + invoices = rec.mapped("rma_line_ids.refund_line_ids.invoice_id") rec.invoice_refund_count = len(invoices) @api.multi def _compute_invoice_count(self): for rec in self: - invoices = rec.mapped('rma_line_ids.invoice_id') + invoices = rec.mapped("rma_line_ids.invoice_id") rec.invoice_count = len(invoices) add_invoice_id = fields.Many2one( - comodel_name='account.invoice', string='Add Invoice', - ondelete='set null', readonly=True, + comodel_name="account.invoice", + string="Add Invoice", + ondelete="set null", + readonly=True, ) invoice_refund_count = fields.Integer( - compute='_compute_invoice_refund_count', string='# of Refunds') + compute="_compute_invoice_refund_count", string="# of Refunds" + ) invoice_count = fields.Integer( - compute='_compute_invoice_count', string='# of Invoices') + compute="_compute_invoice_count", string="# of Invoices" + ) def _prepare_rma_line_from_inv_line(self, line): - if self.type == 'customer': - operation =\ - self.rma_line_ids.product_id.rma_customer_operation_id or \ - self.rma_line_ids.product_id.categ_id.rma_customer_operation_id + if self.type == "customer": + operation = ( + self.rma_line_ids.product_id.rma_customer_operation_id + or self.rma_line_ids.product_id.categ_id.rma_customer_operation_id + ) else: - operation =\ - self.rma_line_ids.product_id.rma_supplier_operation_id or \ - self.rma_line_ids.product_id.categ_id.rma_supplier_operation_id + operation = ( + self.rma_line_ids.product_id.rma_supplier_operation_id + or self.rma_line_ids.product_id.categ_id.rma_supplier_operation_id + ) data = { - 'invoice_line_id': line.id, - 'product_id': line.product_id.id, - 'name': line.name, - 'origin': line.invoice_id.number, - 'uom_id': line.uom_id.id, - 'operation_id': operation, - 'product_qty': line.quantity, - 'price_unit': line.invoice_id.currency_id.compute( - line.price_unit, line.currency_id, round=False), - 'rma_id': self.id + "invoice_line_id": line.id, + "product_id": line.product_id.id, + "name": line.name, + "origin": line.invoice_id.number, + "uom_id": line.uom_id.id, + "operation_id": operation, + "product_qty": line.quantity, + "price_unit": line.invoice_id.currency_id.compute( + line.price_unit, line.currency_id, round=False + ), + "rma_id": self.id, } return data - @api.onchange('add_invoice_id') + @api.onchange("add_invoice_id") def on_change_invoice(self): if not self.add_invoice_id: return {} if not self.partner_id: self.partner_id = self.add_invoice_id.partner_id.id - new_lines = self.env['rma.order.line'] + new_lines = self.env["rma.order.line"] for line in self.add_invoice_id.invoice_line_ids: # Load a PO line only once - if line in self.rma_line_ids.mapped('invoice_line_id'): + if line in self.rma_line_ids.mapped("invoice_line_id"): continue data = self._prepare_rma_line_from_inv_line(line) new_line = new_lines.new(data) @@ -76,48 +82,46 @@ class RmaOrder(models.Model): @api.model def prepare_rma_line(self, origin_rma, rma_id, line): - line_values = super(RmaOrder, self).prepare_rma_line( - origin_rma, rma_id, line) - line_values['invoice_address_id'] = line.invoice_address_id.id + line_values = super(RmaOrder, self).prepare_rma_line(origin_rma, rma_id, line) + line_values["invoice_address_id"] = line.invoice_address_id.id return line_values @api.model def _prepare_rma_data(self, partner, origin_rma): res = super(RmaOrder, self)._prepare_rma_data(partner, origin_rma) - res['invoice_address_id'] = partner.id + res["invoice_address_id"] = partner.id return res @api.multi def action_view_invoice_refund(self): - action = self.env.ref('account.action_invoice_tree2') + action = self.env.ref("account.action_invoice_tree2") result = action.read()[0] - invoice_ids = self.mapped( - 'rma_line_ids.refund_line_ids.invoice_id').ids + invoice_ids = self.mapped("rma_line_ids.refund_line_ids.invoice_id").ids if invoice_ids: # choose the view_mode accordingly if len(invoice_ids) > 1: - result['domain'] = [('id', 'in', invoice_ids)] + result["domain"] = [("id", "in", invoice_ids)] else: - res = self.env.ref('account.invoice_supplier_form', False) - result['views'] = [(res and res.id or False, 'form')] - result['res_id'] = invoice_ids[0] + res = self.env.ref("account.invoice_supplier_form", False) + result["views"] = [(res and res.id or False, "form")] + result["res_id"] = invoice_ids[0] return result @api.multi def action_view_invoice(self): if self.type == "supplier": - action = self.env.ref('account.action_invoice_tree2') - res = self.env.ref('account.invoice_supplier_form', False) + action = self.env.ref("account.action_invoice_tree2") + res = self.env.ref("account.invoice_supplier_form", False) else: - action = self.env.ref('account.action_invoice_tree') - res = self.env.ref('account.invoice_form', False) + action = self.env.ref("account.action_invoice_tree") + res = self.env.ref("account.invoice_form", False) result = action.read()[0] - invoice_ids = self.mapped('rma_line_ids.invoice_id').ids + invoice_ids = self.mapped("rma_line_ids.invoice_id").ids if invoice_ids: # choose the view_mode accordingly if len(invoice_ids) > 1: - result['domain'] = [('id', 'in', invoice_ids)] + result["domain"] = [("id", "in", invoice_ids)] else: - result['views'] = [(res and res.id or False, 'form')] - result['res_id'] = invoice_ids[0] + result["views"] = [(res and res.id or False, "form")] + result["res_id"] = invoice_ids[0] return result diff --git a/rma_account/models/rma_order_line.py b/rma_account/models/rma_order_line.py index 61e7a5fb..c6dd50ab 100644 --- a/rma_account/models/rma_order_line.py +++ b/rma_account/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.exceptions import ValidationError, UserError +from odoo import _, api, fields, models +from odoo.exceptions import UserError, ValidationError + from odoo.addons import decimal_precision as dp @@ -11,90 +12,125 @@ class RmaOrderLine(models.Model): @api.model def _default_invoice_address(self): - partner_id = self.env.context.get('partner_id') + partner_id = self.env.context.get("partner_id") if partner_id: - return self.env['res.partner'].browse(partner_id) - return self.env['res.partner'] + return self.env["res.partner"].browse(partner_id) + return self.env["res.partner"] @api.multi - @api.depends('refund_line_ids', 'refund_line_ids.invoice_id.state', - 'refund_policy', 'type') + @api.depends( + "refund_line_ids", "refund_line_ids.invoice_id.state", "refund_policy", "type" + ) def _compute_qty_refunded(self): for rec in self: - rec.qty_refunded = sum(rec.refund_line_ids.filtered( - lambda i: i.invoice_id.state in ('open', 'paid')).mapped( - 'quantity')) + rec.qty_refunded = sum( + rec.refund_line_ids.filtered( + lambda i: i.invoice_id.state in ("open", "paid") + ).mapped("quantity") + ) - @api.depends('refund_line_ids', 'refund_line_ids.invoice_id.state', - 'refund_policy', 'move_ids', 'move_ids.state', 'type') + @api.depends( + "refund_line_ids", + "refund_line_ids.invoice_id.state", + "refund_policy", + "move_ids", + "move_ids.state", + "type", + ) def _compute_qty_to_refund(self): qty = 0.0 for res in self: - if res.refund_policy == 'ordered': + if res.refund_policy == "ordered": qty = res.product_qty - res.qty_refunded - elif res.refund_policy == 'received': + elif res.refund_policy == "received": qty = res.qty_received - res.qty_refunded - elif res.refund_policy == 'delivered': + elif res.refund_policy == "delivered": qty = res.qty_delivered - res.qty_refunded res.qty_to_refund = qty @api.multi def _compute_refund_count(self): for rec in self: - rec.refund_count = len(rec.refund_line_ids.mapped('invoice_id')) + rec.refund_count = len(rec.refund_line_ids.mapped("invoice_id")) invoice_address_id = fields.Many2one( - 'res.partner', string='Partner invoice address', + "res.partner", + string="Partner invoice address", default=lambda self: self._default_invoice_address(), - readonly=True, states={'draft': [('readonly', False)]}, + readonly=True, + states={"draft": [("readonly", False)]}, help="Invoice address for current rma order.", ) refund_count = fields.Integer( - compute='_compute_refund_count', string='# of Refunds', default=0) + compute="_compute_refund_count", string="# of Refunds", default=0 + ) invoice_line_id = fields.Many2one( - comodel_name='account.invoice.line', - string='Originating Invoice Line', - ondelete='restrict', + comodel_name="account.invoice.line", + string="Originating Invoice Line", + ondelete="restrict", index=True, - readonly=True, states={'draft': [('readonly', False)]}, + readonly=True, + states={"draft": [("readonly", False)]}, ) refund_line_ids = fields.One2many( - comodel_name='account.invoice.line', - inverse_name='rma_line_id', string='Refund Lines', - copy=False, index=True, readonly=True, + comodel_name="account.invoice.line", + inverse_name="rma_line_id", + string="Refund Lines", + copy=False, + index=True, + readonly=True, ) - invoice_id = fields.Many2one('account.invoice', string='Source', - related='invoice_line_id.invoice_id', - index=True, readonly=True) - refund_policy = fields.Selection([ - ('no', 'No refund'), ('ordered', 'Based on Ordered Quantities'), - ('delivered', 'Based on Delivered Quantities'), - ('received', 'Based on Received Quantities')], string="Refund Policy", - required=True, default='no', - readonly=True, states={'draft': [('readonly', False)]}, + invoice_id = fields.Many2one( + "account.invoice", + string="Source", + related="invoice_line_id.invoice_id", + index=True, + readonly=True, + ) + refund_policy = fields.Selection( + [ + ("no", "No refund"), + ("ordered", "Based on Ordered Quantities"), + ("delivered", "Based on Delivered Quantities"), + ("received", "Based on Received Quantities"), + ], + string="Refund Policy", + required=True, + default="no", + readonly=True, + states={"draft": [("readonly", False)]}, ) qty_to_refund = fields.Float( - string='Qty To Refund', copy=False, - digits=dp.get_precision('Product Unit of Measure'), readonly=True, - compute='_compute_qty_to_refund', store=True) + string="Qty To Refund", + copy=False, + digits=dp.get_precision("Product Unit of Measure"), + readonly=True, + compute="_compute_qty_to_refund", + store=True, + ) qty_refunded = fields.Float( - string='Qty Refunded', copy=False, - digits=dp.get_precision('Product Unit of Measure'), - readonly=True, compute='_compute_qty_refunded', store=True) + string="Qty Refunded", + copy=False, + digits=dp.get_precision("Product Unit of Measure"), + readonly=True, + compute="_compute_qty_refunded", + store=True, + ) - @api.onchange('product_id', 'partner_id') + @api.onchange("product_id", "partner_id") def _onchange_product_id(self): """Domain for sale_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 = [ - '|', - ('invoice_id.partner_id', '=', self.partner_id.id), - ('invoice_id.partner_id', 'child_of', self.partner_id.id)] + "|", + ("invoice_id.partner_id", "=", self.partner_id.id), + ("invoice_id.partner_id", "child_of", self.partner_id.id), + ] if self.product_id: - domain.append(('product_id', '=', self.product_id.id)) - res['domain']['invoice_line_id'] = domain + domain.append(("product_id", "=", self.product_id.id)) + res["domain"]["invoice_line_id"] = domain return res @api.multi @@ -102,137 +138,157 @@ 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 an 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.invoice_id.number, - 'uom_id': line.uom_id.id, - 'operation_id': operation.id, - 'product_qty': line.quantity, - 'price_unit': line.invoice_id.currency_id.compute( - line.price_unit, line.currency_id, round=False), - 'delivery_address_id': line.invoice_id.partner_id.id, - 'invoice_address_id': line.invoice_id.partner_id.id, - 'receipt_policy': operation.receipt_policy, - 'refund_policy': operation.refund_policy, - 'delivery_policy': operation.delivery_policy, - 'currency_id': line.currency_id.id, - 'in_warehouse_id': operation.in_warehouse_id.id or warehouse.id, - 'out_warehouse_id': operation.out_warehouse_id.id or warehouse.id, - 'in_route_id': operation.in_route_id.id or route.id, - 'out_route_id': operation.out_route_id.id or route.id, - 'location_id': (operation.location_id.id or - operation.in_warehouse_id.lot_rma_id.id or - warehouse.lot_rma_id.id), + "product_id": line.product_id.id, + "origin": line.invoice_id.number, + "uom_id": line.uom_id.id, + "operation_id": operation.id, + "product_qty": line.quantity, + "price_unit": line.invoice_id.currency_id.compute( + line.price_unit, line.currency_id, round=False + ), + "delivery_address_id": line.invoice_id.partner_id.id, + "invoice_address_id": line.invoice_id.partner_id.id, + "receipt_policy": operation.receipt_policy, + "refund_policy": operation.refund_policy, + "delivery_policy": operation.delivery_policy, + "currency_id": line.currency_id.id, + "in_warehouse_id": operation.in_warehouse_id.id or warehouse.id, + "out_warehouse_id": operation.out_warehouse_id.id or warehouse.id, + "in_route_id": operation.in_route_id.id or route.id, + "out_route_id": operation.out_route_id.id or route.id, + "location_id": ( + operation.location_id.id + or operation.in_warehouse_id.lot_rma_id.id + or warehouse.lot_rma_id.id + ), } return data - @api.onchange('invoice_line_id') + @api.onchange("invoice_line_id") def _onchange_invoice_line_id(self): if not self.invoice_line_id: return - data = self._prepare_rma_line_from_inv_line( - self.invoice_line_id) + data = self._prepare_rma_line_from_inv_line(self.invoice_line_id) self.update(data) - self._remove_other_data_origin('invoice_line_id') + self._remove_other_data_origin("invoice_line_id") @api.multi - @api.constrains('invoice_line_id', 'partner_id') + @api.constrains("invoice_line_id", "partner_id") def _check_invoice_partner(self): for rec in self: - if (rec.invoice_line_id and - rec.invoice_line_id.invoice_id.partner_id != - rec.partner_id): - raise ValidationError(_( - "RMA customer and originating invoice line customer " - "doesn't match.")) + if ( + rec.invoice_line_id + and rec.invoice_line_id.invoice_id.partner_id != rec.partner_id + ): + raise ValidationError( + _( + "RMA customer and originating invoice 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 == 'invoice_line_id': + if not exception == "invoice_line_id": self.invoice_line_id = False return res - @api.onchange('operation_id') + @api.onchange("operation_id") def _onchange_operation_id(self): result = super(RmaOrderLine, self)._onchange_operation_id() if self.operation_id: - self.refund_policy = self.operation_id.refund_policy or 'no' + self.refund_policy = self.operation_id.refund_policy or "no" return result @api.multi - @api.constrains('invoice_line_id') + @api.constrains("invoice_line_id") def _check_duplicated_lines(self): for line in self: - matching_inv_lines = self.env['account.invoice.line'].search([( - 'id', '=', line.invoice_line_id.id)]) + matching_inv_lines = self.env["account.invoice.line"].search( + [("id", "=", line.invoice_line_id.id)] + ) if len(matching_inv_lines) > 1: - raise UserError( - _("There's an rma for the invoice line %s " - "and invoice %s" % - (line.invoice_line_id, - line.invoice_line_id.invoice_id))) + raise UserError( + _( + "There's an rma for the invoice line %s " + "and invoice %s" + % (line.invoice_line_id, line.invoice_line_id.invoice_id) + ) + ) return {} @api.multi def action_view_invoice(self): - action = self.env.ref('account.action_invoice_tree') + action = self.env.ref("account.action_invoice_tree") result = action.read()[0] - res = self.env.ref('account.invoice_form', False) - result['views'] = [(res and res.id or False, 'form')] - result['view_id'] = res and res.id or False - result['res_id'] = self.invoice_line_id.invoice_id.id + res = self.env.ref("account.invoice_form", False) + result["views"] = [(res and res.id or False, "form")] + result["view_id"] = res and res.id or False + result["res_id"] = self.invoice_line_id.invoice_id.id return result @api.multi def action_view_refunds(self): - action = self.env.ref('account.action_invoice_tree2') + action = self.env.ref("account.action_invoice_tree2") result = action.read()[0] - invoice_ids = self.mapped('refund_line_ids.invoice_id').ids + invoice_ids = self.mapped("refund_line_ids.invoice_id").ids if invoice_ids: # choose the view_mode accordingly if len(invoice_ids) > 1: - result['domain'] = [('id', 'in', invoice_ids)] + result["domain"] = [("id", "in", invoice_ids)] else: - res = self.env.ref('account.invoice_supplier_form', False) - result['views'] = [(res and res.id or False, 'form')] - result['res_id'] = invoice_ids[0] + res = self.env.ref("account.invoice_supplier_form", False) + result["views"] = [(res and res.id or False, "form")] + result["res_id"] = invoice_ids[0] return result @api.multi def name_get(self): res = [] - if self.env.context.get('rma'): + if self.env.context.get("rma"): for rma in self: - res.append((rma.id, "%s %s qty:%s" % ( - rma.name, - rma.product_id.name, - rma.product_qty))) + res.append( + ( + rma.id, + "%s %s qty:%s" + % (rma.name, rma.product_id.name, rma.product_qty), + ) + ) return res else: return super(RmaOrderLine, self).name_get() diff --git a/rma_account/tests/test_rma_account.py b/rma_account/tests/test_rma_account.py index 4da5c8cb..53c164fd 100644 --- a/rma_account/tests/test_rma_account.py +++ b/rma_account/tests/test_rma_account.py @@ -5,193 +5,206 @@ from odoo.tests import common class TestRmaAccount(common.SingleTransactionCase): - @classmethod def setUpClass(cls): super(TestRmaAccount, 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_invoice_wiz = cls.env['rma_add_invoice'] - cls.rma_refund_wiz = cls.env['rma.refund'] - cls.acc_obj = cls.env['account.account'] - cls.inv_obj = cls.env['account.invoice'] - cls.invl_obj = cls.env['account.invoice.line'] - cls.product_obj = cls.env['product.product'] - cls.partner_obj = cls.env['res.partner'] + 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_invoice_wiz = cls.env["rma_add_invoice"] + cls.rma_refund_wiz = cls.env["rma.refund"] + cls.acc_obj = cls.env["account.account"] + cls.inv_obj = cls.env["account.invoice"] + cls.invl_obj = cls.env["account.invoice.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') - receivable_type = cls.env.ref('account.data_account_type_receivable') - payable_type = cls.env.ref('account.data_account_type_payable') - cls.cust_refund_op = cls.env.ref( - 'rma_account.rma_operation_customer_refund') + cls.rma_route_cust = cls.env.ref("rma.route_rma_customer") + receivable_type = cls.env.ref("account.data_account_type_receivable") + payable_type = cls.env.ref("account.data_account_type_payable") + cls.cust_refund_op = cls.env.ref("rma_account.rma_operation_customer_refund") # Create partners - customer1 = cls.partner_obj.create({'name': 'Customer 1'}) - supplier1 = cls.partner_obj.create({'name': 'Supplier 1'}) + customer1 = cls.partner_obj.create({"name": "Customer 1"}) + supplier1 = cls.partner_obj.create({"name": "Supplier 1"}) # Create RMA group and operation: - cls.rma_group_customer = cls.rma_obj.create({ - 'partner_id': customer1.id, - 'type': 'customer', - }) - cls.rma_group_supplier = cls.rma_obj.create({ - 'partner_id': supplier1.id, - 'type': 'supplier', - }) - cls.operation_1 = cls.rma_op_obj.create({ - 'code': 'TEST', - 'name': 'Refund and receive', - 'type': 'customer', - 'receipt_policy': 'ordered', - 'refund_policy': 'ordered', - 'in_route_id': cls.rma_route_cust.id, - 'out_route_id': cls.rma_route_cust.id, - }) + cls.rma_group_customer = cls.rma_obj.create( + {"partner_id": customer1.id, "type": "customer"} + ) + cls.rma_group_supplier = cls.rma_obj.create( + {"partner_id": supplier1.id, "type": "supplier"} + ) + cls.operation_1 = cls.rma_op_obj.create( + { + "code": "TEST", + "name": "Refund and receive", + "type": "customer", + "receipt_policy": "ordered", + "refund_policy": "ordered", + "in_route_id": cls.rma_route_cust.id, + "out_route_id": cls.rma_route_cust.id, + } + ) # Create products - cls.product_1 = cls.product_obj.create({ - 'name': 'Test Product 1', - 'type': 'product', - 'list_price': 100.0, - 'rma_customer_operation_id': cls.cust_refund_op.id, - }) - cls.product_2 = cls.product_obj.create({ - 'name': 'Test Product 2', - 'type': 'product', - 'list_price': 150.0, - 'rma_customer_operation_id': cls.operation_1.id, - }) - cls.product_3 = cls.product_obj.create({ - 'name': 'Test Product 3', - 'type': 'product', - }) - cls.product_4 = cls.product_obj.create({ - 'name': 'Test Product 4', - 'type': 'product', - }) + cls.product_1 = cls.product_obj.create( + { + "name": "Test Product 1", + "type": "product", + "list_price": 100.0, + "rma_customer_operation_id": cls.cust_refund_op.id, + } + ) + cls.product_2 = cls.product_obj.create( + { + "name": "Test Product 2", + "type": "product", + "list_price": 150.0, + "rma_customer_operation_id": cls.operation_1.id, + } + ) + cls.product_3 = cls.product_obj.create( + {"name": "Test Product 3", "type": "product"} + ) + cls.product_4 = cls.product_obj.create( + {"name": "Test Product 4", "type": "product"} + ) # Create Invoices: - customer_account = cls.acc_obj. search( - [('user_type_id', '=', receivable_type.id)], limit=1).id - cls.inv_customer = cls.inv_obj.create({ - 'partner_id': customer1.id, - 'account_id': customer_account, - 'type': 'out_invoice', - }) - cls.inv_line_1 = cls.invl_obj.create({ - 'name': cls.product_1.name, - 'product_id': cls.product_1.id, - 'quantity': 12.0, - 'price_unit': 100.0, - 'invoice_id': cls.inv_customer.id, - 'uom_id': cls.product_1.uom_id.id, - 'account_id': customer_account, - }) - cls.inv_line_2 = cls.invl_obj.create({ - 'name': cls.product_2.name, - 'product_id': cls.product_2.id, - 'quantity': 15.0, - 'price_unit': 150.0, - 'invoice_id': cls.inv_customer.id, - 'uom_id': cls.product_2.uom_id.id, - 'account_id': customer_account, - }) + customer_account = cls.acc_obj.search( + [("user_type_id", "=", receivable_type.id)], limit=1 + ).id + cls.inv_customer = cls.inv_obj.create( + { + "partner_id": customer1.id, + "account_id": customer_account, + "type": "out_invoice", + } + ) + cls.inv_line_1 = cls.invl_obj.create( + { + "name": cls.product_1.name, + "product_id": cls.product_1.id, + "quantity": 12.0, + "price_unit": 100.0, + "invoice_id": cls.inv_customer.id, + "uom_id": cls.product_1.uom_id.id, + "account_id": customer_account, + } + ) + cls.inv_line_2 = cls.invl_obj.create( + { + "name": cls.product_2.name, + "product_id": cls.product_2.id, + "quantity": 15.0, + "price_unit": 150.0, + "invoice_id": cls.inv_customer.id, + "uom_id": cls.product_2.uom_id.id, + "account_id": customer_account, + } + ) supplier_account = cls.acc_obj.search( - [('user_type_id', '=', payable_type.id)], limit=1).id - cls.inv_supplier = cls.inv_obj.create({ - 'partner_id': supplier1.id, - 'account_id': supplier_account, - 'type': 'in_invoice', - }) - cls.inv_line_3 = cls.invl_obj.create({ - 'name': cls.product_3.name, - 'product_id': cls.product_3.id, - 'quantity': 17.0, - 'price_unit': 250.0, - 'invoice_id': cls.inv_supplier.id, - 'uom_id': cls.product_3.uom_id.id, - 'account_id': supplier_account, - }) - cls.inv_line_4 = cls.invl_obj.create({ - 'name': cls.product_4.name, - 'product_id': cls.product_4.id, - 'quantity': 9.0, - 'price_unit': 300.0, - 'invoice_id': cls.inv_supplier.id, - 'uom_id': cls.product_4.uom_id.id, - 'account_id': supplier_account, - }) + [("user_type_id", "=", payable_type.id)], limit=1 + ).id + cls.inv_supplier = cls.inv_obj.create( + { + "partner_id": supplier1.id, + "account_id": supplier_account, + "type": "in_invoice", + } + ) + cls.inv_line_3 = cls.invl_obj.create( + { + "name": cls.product_3.name, + "product_id": cls.product_3.id, + "quantity": 17.0, + "price_unit": 250.0, + "invoice_id": cls.inv_supplier.id, + "uom_id": cls.product_3.uom_id.id, + "account_id": supplier_account, + } + ) + cls.inv_line_4 = cls.invl_obj.create( + { + "name": cls.product_4.name, + "product_id": cls.product_4.id, + "quantity": 9.0, + "price_unit": 300.0, + "invoice_id": cls.inv_supplier.id, + "uom_id": cls.product_4.uom_id.id, + "account_id": supplier_account, + } + ) def test_01_add_from_invoice_customer(self): """Test wizard to create RMA from a customer invoice.""" - add_inv = self.rma_add_invoice_wiz.with_context({ - 'customer': True, - 'active_ids': self.rma_group_customer.id, - 'active_model': 'rma.order', - }).create({ - 'invoice_line_ids': - [(6, 0, self.inv_customer.invoice_line_ids.ids)], - }) + add_inv = self.rma_add_invoice_wiz.with_context( + { + "customer": True, + "active_ids": self.rma_group_customer.id, + "active_model": "rma.order", + } + ).create({"invoice_line_ids": [(6, 0, self.inv_customer.invoice_line_ids.ids)]}) add_inv.add_lines() self.assertEqual(len(self.rma_group_customer.rma_line_ids), 2) - for t in self.rma_group_supplier.rma_line_ids.mapped('type'): - self.assertEqual(t, 'customer') + for t in self.rma_group_supplier.rma_line_ids.mapped("type"): + self.assertEqual(t, "customer") rma_1 = self.rma_group_customer.rma_line_ids.filtered( - lambda r: r.product_id == self.product_1) + lambda r: r.product_id == self.product_1 + ) self.assertEqual(rma_1.operation_id, self.cust_refund_op) rma_2 = self.rma_group_customer.rma_line_ids.filtered( - lambda r: r.product_id == self.product_2) + lambda r: r.product_id == self.product_2 + ) self.assertEqual(rma_2.operation_id, self.operation_1) def test_02_add_from_invoice_supplier(self): """Test wizard to create RMA from a vendor bill.""" - add_inv = self.rma_add_invoice_wiz.with_context({ - 'supplier': True, - 'active_ids': self.rma_group_supplier.id, - 'active_model': 'rma.order', - }).create({ - 'invoice_line_ids': - [(6, 0, self.inv_supplier.invoice_line_ids.ids)], - }) + add_inv = self.rma_add_invoice_wiz.with_context( + { + "supplier": True, + "active_ids": self.rma_group_supplier.id, + "active_model": "rma.order", + } + ).create({"invoice_line_ids": [(6, 0, self.inv_supplier.invoice_line_ids.ids)]}) add_inv.add_lines() self.assertEqual(len(self.rma_group_supplier.rma_line_ids), 2) - for t in self.rma_group_supplier.rma_line_ids.mapped('type'): - self.assertEqual(t, 'supplier') + for t in self.rma_group_supplier.rma_line_ids.mapped("type"): + self.assertEqual(t, "supplier") def test_03_rma_refund_operation(self): """Test RMA quantities using refund operations.""" # Received refund_policy: rma_1 = self.rma_group_customer.rma_line_ids.filtered( - lambda r: r.product_id == self.product_1) - self.assertEqual(rma_1.refund_policy, 'received') + lambda r: r.product_id == self.product_1 + ) + self.assertEqual(rma_1.refund_policy, "received") self.assertEqual(rma_1.qty_to_refund, 0.0) # TODO: receive and check qty_to_refund is 12.0 # Ordered refund_policy: rma_2 = self.rma_group_customer.rma_line_ids.filtered( - lambda r: r.product_id == self.product_2) + lambda r: r.product_id == self.product_2 + ) rma_2._onchange_operation_id() - self.assertEqual(rma_2.refund_policy, 'ordered') + self.assertEqual(rma_2.refund_policy, "ordered") self.assertEqual(rma_2.qty_to_refund, 15.0) def test_04_rma_create_refund(self): """Generate a Refund from a customer RMA.""" rma = self.rma_group_customer.rma_line_ids.filtered( - lambda r: r.product_id == self.product_2) + lambda r: r.product_id == self.product_2 + ) rma.action_rma_to_approve() rma.action_rma_approve() self.assertEqual(rma.refund_count, 0) self.assertEqual(rma.qty_to_refund, 15.0) self.assertEqual(rma.qty_refunded, 0.0) - make_refund = self.rma_refund_wiz.with_context({ - 'customer': True, - 'active_ids': rma.ids, - 'active_model': 'rma.order.line', - }).create({ - 'description': 'Test refund', - }) + make_refund = self.rma_refund_wiz.with_context( + {"customer": True, "active_ids": rma.ids, "active_model": "rma.order.line"} + ).create({"description": "Test refund"}) make_refund.invoice_refund() rma.refund_line_ids.invoice_id.action_invoice_open() rma._compute_refund_count() @@ -201,10 +214,12 @@ class TestRmaAccount(common.SingleTransactionCase): def test_05_fill_rma_from_inv_line(self): """Test filling a RMA (line) from a invoice line.""" - rma = self.rma_line_obj.new({ - 'partner_id': self.inv_customer.partner_id.id, - 'invoice_line_id': self.inv_line_1.id, - }) + rma = self.rma_line_obj.new( + { + "partner_id": self.inv_customer.partner_id.id, + "invoice_line_id": self.inv_line_1.id, + } + ) self.assertFalse(rma.product_id) rma._onchange_invoice_line_id() self.assertEqual(rma.product_id, self.product_1) diff --git a/rma_account/wizards/rma_add_invoice.py b/rma_account/wizards/rma_add_invoice.py index f766b6f6..a97e37f6 100644 --- a/rma_account/wizards/rma_add_invoice.py +++ b/rma_account/wizards/rma_add_invoice.py @@ -6,90 +6,106 @@ from odoo.exceptions import ValidationError class RmaAddInvoice(models.TransientModel): - _name = 'rma_add_invoice' - _description = 'Wizard to add rma lines' + _name = "rma_add_invoice" + _description = "Wizard to add rma lines" @api.model def default_get(self, fields_list): res = super(RmaAddInvoice, 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['invoice_line_ids'] = False + res["rma_id"] = rma.id + res["partner_id"] = rma.partner_id.id + res["invoice_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) - invoice_line_ids = fields.Many2many('account.invoice.line', - 'rma_add_invoice_add_line_rel', - 'invoice_line_id', - 'rma_add_invoice_id', - string='Invoice Lines') + 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 + ) + invoice_line_ids = fields.Many2many( + "account.invoice.line", + "rma_add_invoice_add_line_rel", + "invoice_line_id", + "rma_add_invoice_id", + string="Invoice Lines", + ) def _prepare_rma_line_from_inv_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 an 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, - 'invoice_line_id': line.id, - 'product_id': line.product_id.id, - 'origin': line.invoice_id.number, - 'uom_id': line.uom_id.id, - 'operation_id': operation.id, - 'product_qty': line.quantity, - 'price_unit': line.invoice_id.currency_id.compute( - line.price_unit, line.currency_id, round=False), - 'delivery_address_id': line.invoice_id.partner_id.id, - 'invoice_address_id': line.invoice_id.partner_id.id, - 'rma_id': self.rma_id.id, - 'receipt_policy': operation.receipt_policy, - '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, - 'in_route_id': operation.in_route_id.id or route.id, - 'out_route_id': operation.out_route_id.id or route.id, - 'location_id': (operation.location_id.id or - operation.in_warehouse_id.lot_rma_id.id or - warehouse.lot_rma_id.id), + "partner_id": self.partner_id.id, + "invoice_line_id": line.id, + "product_id": line.product_id.id, + "origin": line.invoice_id.number, + "uom_id": line.uom_id.id, + "operation_id": operation.id, + "product_qty": line.quantity, + "price_unit": line.invoice_id.currency_id.compute( + line.price_unit, line.currency_id, round=False + ), + "delivery_address_id": line.invoice_id.partner_id.id, + "invoice_address_id": line.invoice_id.partner_id.id, + "rma_id": self.rma_id.id, + "receipt_policy": operation.receipt_policy, + "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, + "in_route_id": operation.in_route_id.id or route.id, + "out_route_id": operation.out_route_id.id or route.id, + "location_id": ( + operation.location_id.id + or operation.in_warehouse_id.lot_rma_id.id + or warehouse.lot_rma_id.id + ), } return data @api.model def _get_rma_data(self): - data = { - 'date_rma': fields.Datetime.now(), - } + data = {"date_rma": fields.Datetime.now()} return data @api.model @@ -101,7 +117,7 @@ class RmaAddInvoice(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_invoice_lines = self._get_existing_invoice_lines() for line in self.invoice_line_ids: # Load a PO line only once @@ -111,4 +127,4 @@ class RmaAddInvoice(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_account/wizards/rma_order_line_make_supplier_rma.py b/rma_account/wizards/rma_order_line_make_supplier_rma.py index bbd94cd1..e1c3fc78 100644 --- a/rma_account/wizards/rma_order_line_make_supplier_rma.py +++ b/rma_account/wizards/rma_order_line_make_supplier_rma.py @@ -9,9 +9,8 @@ class RmaLineMakeSupplierRma(models.TransientModel): @api.model def _prepare_supplier_rma_line(self, rma, item): - res = super(RmaLineMakeSupplierRma, self)._prepare_supplier_rma_line( - rma, item) - if res['operation_id']: - operation = self.env['rma.operation'].browse(res['operation_id']) - res['refund_policy'] = operation.refund_policy + res = super(RmaLineMakeSupplierRma, self)._prepare_supplier_rma_line(rma, item) + if res["operation_id"]: + operation = self.env["rma.operation"].browse(res["operation_id"]) + res["refund_policy"] = operation.refund_policy return res diff --git a/rma_account/wizards/rma_refund.py b/rma_account/wizards/rma_refund.py index 0e06ee16..d86a754c 100644 --- a/rma_account/wizards/rma_refund.py +++ b/rma_account/wizards/rma_refund.py @@ -3,6 +3,7 @@ from odoo import _, api, fields, models from odoo.exceptions import ValidationError + import odoo.addons.decimal_precision as dp @@ -12,22 +13,21 @@ class RmaRefund(models.TransientModel): @api.model def _get_reason(self): - active_ids = self.env.context.get('active_ids', False) - return self.env['rma.order.line'].browse( - active_ids[0]).rma_id.name or '' + active_ids = self.env.context.get("active_ids", False) + return self.env["rma.order.line"].browse(active_ids[0]).rma_id.name or "" - @api.returns('rma.order.line') + @api.returns("rma.order.line") def _prepare_item(self, line): values = { - 'product_id': line.product_id.id, - 'name': line.name, - 'product_qty': line.product_qty, - 'uom_id': line.uom_id.id, - 'qty_to_refund': line.qty_to_refund, - 'refund_policy': line.refund_policy, - 'invoice_address_id': line.invoice_address_id.id, - 'line_id': line.id, - 'rma_id': line.rma_id.id, + "product_id": line.product_id.id, + "name": line.name, + "product_qty": line.product_qty, + "uom_id": line.uom_id.id, + "qty_to_refund": line.qty_to_refund, + "refund_policy": line.refund_policy, + "invoice_address_id": line.invoice_address_id.id, + "line_id": line.id, + "rma_id": line.rma_id.id, } return values @@ -39,37 +39,37 @@ class RmaRefund(models.TransientModel): """ context = self._context.copy() res = super(RmaRefund, self).default_get(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'] + rma_line_obj = self.env["rma.order.line"] + rma_line_ids = self.env.context["active_ids"] or [] + active_model = self.env.context["active_model"] if not rma_line_ids: return res - assert active_model == 'rma.order.line', 'Bad context propagation' + assert active_model == "rma.order.line", "Bad context propagation" items = [] lines = rma_line_obj.browse(rma_line_ids) - if len(lines.mapped('partner_id')) > 1: + if len(lines.mapped("partner_id")) > 1: raise ValidationError( - _("Only RMAs from the same partner can be processed at " - "the same time.")) + _( + "Only RMAs from the same partner can be processed at " + "the same time." + ) + ) for line in lines: items.append([0, 0, self._prepare_item(line)]) - res['item_ids'] = items - context.update({'items_ids': items}) + res["item_ids"] = items + context.update({"items_ids": items}) return res date_invoice = fields.Date( - string='Refund Date', - default=fields.Date.context_today, required=True, + string="Refund Date", default=fields.Date.context_today, required=True ) - date = fields.Date(string='Accounting Date') + date = fields.Date(string="Accounting Date") description = fields.Char( - string='Reason', required=True, - default=lambda self: self._get_reason(), + string="Reason", required=True, default=lambda self: self._get_reason() ) item_ids = fields.One2many( - comodel_name='rma.refund.item', - inverse_name='wiz_id', string='Items', + comodel_name="rma.refund.item", inverse_name="wiz_id", string="Items" ) @api.multi @@ -77,102 +77,107 @@ class RmaRefund(models.TransientModel): for wizard in self: first = self.item_ids[0] values = self._prepare_refund(wizard, first.line_id) - new_refund = self.env['account.invoice'].create(values) + new_refund = self.env["account.invoice"].create(values) for item in self.item_ids: refund_line_values = self.prepare_refund_line(item, new_refund) - self.env['account.invoice.line'].create( - refund_line_values) + self.env["account.invoice.line"].create(refund_line_values) return new_refund @api.multi def invoice_refund(self): - rma_line_ids = self.env['rma.order.line'].browse( - self.env.context['active_ids']) + rma_line_ids = self.env["rma.order.line"].browse(self.env.context["active_ids"]) for line in rma_line_ids: - if line.refund_policy == 'no': + if line.refund_policy == "no": raise ValidationError( - _('The operation is not refund for at least one line')) - if line.state != 'approved': - raise ValidationError( - _('RMA %s is not approved') % line.name) + _("The operation is not refund for at least one line") + ) + if line.state != "approved": + raise ValidationError(_("RMA %s is not approved") % line.name) new_invoice = self.compute_refund() - action = 'action_invoice_tree1' if ( - new_invoice.type in ['out_refund', 'out_invoice']) \ - else 'action_invoice_in_refund' - result = self.env.ref('account.%s' % action).read()[0] - form_view = self.env.ref('account.invoice_supplier_form', False) - result['views'] = [(form_view and form_view.id or False, 'form')] - result['res_id'] = new_invoice.id + action = ( + "action_invoice_tree1" + if (new_invoice.type in ["out_refund", "out_invoice"]) + else "action_invoice_in_refund" + ) + result = self.env.ref("account.%s" % action).read()[0] + form_view = self.env.ref("account.invoice_supplier_form", False) + result["views"] = [(form_view and form_view.id or False, "form")] + result["res_id"] = new_invoice.id return result @api.model def prepare_refund_line(self, item, refund): accounts = item.product_id.product_tmpl_id._get_product_accounts() - if item.line_id.type == 'customer': - account = accounts['stock_output'] + if item.line_id.type == "customer": + account = accounts["stock_output"] else: - account = accounts['stock_input'] + account = accounts["stock_input"] if not account: - raise ValidationError(_( - "Accounts are not configured for this product.")) + raise ValidationError(_("Accounts are not configured for this product.")) values = { - 'name': item.line_id.name or item.rma_id.name, - 'origin': item.line_id.name or item.rma_id.name, - 'account_id': account.id, - 'price_unit': item.line_id.price_unit, - 'uom_id': item.line_id.uom_id.id, - 'product_id': item.product_id.id, - 'rma_line_id': item.line_id.id, - 'quantity': item.qty_to_refund, - 'invoice_id': refund.id + "name": item.line_id.name or item.rma_id.name, + "origin": item.line_id.name or item.rma_id.name, + "account_id": account.id, + "price_unit": item.line_id.price_unit, + "uom_id": item.line_id.uom_id.id, + "product_id": item.product_id.id, + "rma_line_id": item.line_id.id, + "quantity": item.qty_to_refund, + "invoice_id": refund.id, } return values @api.model def _prepare_refund(self, wizard, rma_line): # origin_invoices = self._get_invoice(rma_line) - if rma_line.type == 'customer': - journal = self.env['account.journal'].search( - [('type', '=', 'sale')], limit=1) + if rma_line.type == "customer": + journal = self.env["account.journal"].search( + [("type", "=", "sale")], limit=1 + ) else: - journal = self.env['account.journal'].search( - [('type', '=', 'purchase')], limit=1) + journal = self.env["account.journal"].search( + [("type", "=", "purchase")], limit=1 + ) values = { - 'name': rma_line.rma_id.name or rma_line.name, - 'origin': rma_line.rma_id.name or rma_line.name, - 'reference': False, + "name": rma_line.rma_id.name or rma_line.name, + "origin": rma_line.rma_id.name or rma_line.name, + "reference": False, # 'account_id': account.id, - 'journal_id': journal.id, - 'currency_id': rma_line.partner_id.company_id.currency_id.id, - 'payment_term_id': False, - 'fiscal_position_id': - rma_line.partner_id.property_account_position_id.id, - 'state': 'draft', - 'number': False, - 'date': wizard.date, - 'date_invoice': wizard.date_invoice, - 'partner_id': rma_line.invoice_address_id.id or - rma_line.partner_id.id, + "journal_id": journal.id, + "currency_id": rma_line.partner_id.company_id.currency_id.id, + "payment_term_id": False, + "fiscal_position_id": rma_line.partner_id.property_account_position_id.id, + "state": "draft", + "number": False, + "date": wizard.date, + "date_invoice": wizard.date_invoice, + "partner_id": rma_line.invoice_address_id.id or rma_line.partner_id.id, } - if self.env.registry.models.get('crm.team', False): - team_ids = self.env['crm.team'].search( - ['|', ('user_id', '=', self.env.uid), - ('member_ids', '=', self.env.uid)], limit=1) + if self.env.registry.models.get("crm.team", False): + team_ids = self.env["crm.team"].search( + [ + "|", + ("user_id", "=", self.env.uid), + ("member_ids", "=", self.env.uid), + ], + limit=1, + ) team_id = team_ids[0] if team_ids else False if team_id: - values['team_id'] = team_id.id - if rma_line.type == 'customer': - values['type'] = 'out_refund' + values["team_id"] = team_id.id + if rma_line.type == "customer": + values["type"] = "out_refund" else: - values['type'] = 'in_refund' + values["type"] = "in_refund" return values - @api.constrains('item_ids') + @api.constrains("item_ids") def check_unique_invoice_address_id(self): - addresses = self.item_ids.mapped('invoice_address_id') + addresses = self.item_ids.mapped("invoice_address_id") if len(addresses) > 1: - raise ValidationError(_( - "The invoice address must be the same for all the lines.")) + raise ValidationError( + _("The invoice address must be the same for all the lines.") + ) return True @@ -180,33 +185,38 @@ class RmaRefundItem(models.TransientModel): _name = "rma.refund.item" _description = "RMA Lines to refund" - wiz_id = fields.Many2one( - comodel_name='rma.refund', string='Wizard', required=True) - line_id = fields.Many2one('rma.order.line', - string='RMA order Line', - required=True, - readonly=True, - ondelete='cascade') - rma_id = fields.Many2one('rma.order', - related='line_id.rma_id', - string='RMA', - readonly=True) - product_id = fields.Many2one('product.product', string='Product') - product = fields.Many2one('product.product', string='Product', - readonly=True) - name = fields.Char(string='Description', required=True) + wiz_id = fields.Many2one(comodel_name="rma.refund", string="Wizard", required=True) + line_id = fields.Many2one( + "rma.order.line", + string="RMA order Line", + required=True, + readonly=True, + ondelete="cascade", + ) + rma_id = fields.Many2one( + "rma.order", related="line_id.rma_id", string="RMA", readonly=True + ) + product_id = fields.Many2one("product.product", string="Product") + product = fields.Many2one("product.product", string="Product", readonly=True) + name = fields.Char(string="Description", required=True) product_qty = fields.Float( - string='Quantity Ordered', copy=False, - digits=dp.get_precision('Product Unit of Measure'), - readonly=True) + string="Quantity Ordered", + copy=False, + digits=dp.get_precision("Product Unit of Measure"), + readonly=True, + ) invoice_address_id = fields.Many2one( - comodel_name='res.partner', string='Invoice Address') + comodel_name="res.partner", string="Invoice Address" + ) qty_to_refund = fields.Float( - string='Quantity To Refund', - digits=dp.get_precision('Product Unit of Measure')) - uom_id = fields.Many2one('uom.uom', string='Unit of Measure', - readonly=True) - refund_policy = fields.Selection(selection=[ - ('no', 'Not required'), ('ordered', 'Based on Ordered Quantities'), - ('received', 'Based on Received Quantities')], - string="Refund Policy") + string="Quantity To Refund", digits=dp.get_precision("Product Unit of Measure") + ) + uom_id = fields.Many2one("uom.uom", string="Unit of Measure", readonly=True) + refund_policy = fields.Selection( + selection=[ + ("no", "Not required"), + ("ordered", "Based on Ordered Quantities"), + ("received", "Based on Received Quantities"), + ], + string="Refund Policy", + ) From ac3f2941ac6eb9e3c4f7c868f7a6e88d7f34ab01 Mon Sep 17 00:00:00 2001 From: ahenriquez Date: Wed, 22 Jan 2020 11:23:04 +0100 Subject: [PATCH 47/52] [UPT]rebranding --- rma_account/README.rst | 10 +++++----- rma_account/__init__.py | 2 +- rma_account/__manifest__.py | 6 +++--- rma_account/models/__init__.py | 2 +- rma_account/models/invoice.py | 2 +- rma_account/models/rma_operation.py | 2 +- rma_account/models/rma_order.py | 2 +- rma_account/models/rma_order_line.py | 2 +- rma_account/tests/__init__.py | 2 +- rma_account/tests/test_rma_account.py | 2 +- rma_account/views/rma_account_menu.xml | 2 +- rma_account/wizards/__init__.py | 2 +- rma_account/wizards/rma_add_invoice.py | 2 +- .../wizards/rma_order_line_make_supplier_rma.py | 2 +- rma_account/wizards/rma_refund.py | 2 +- 15 files changed, 21 insertions(+), 21 deletions(-) diff --git a/rma_account/README.rst b/rma_account/README.rst index 8dfed892..c464cd70 100644 --- a/rma_account/README.rst +++ b/rma_account/README.rst @@ -30,7 +30,7 @@ Bug Tracker =========== Bugs are tracked on `GitHub Issues -`_. In case of trouble, please +`_. 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. @@ -40,13 +40,13 @@ Credits Contributors ------------ -* Jordi Ballester Alomar -* Aaron Henriquez -* Lois Rilo +* Jordi Ballester Alomar +* Aaron Henriquez +* Lois Rilo * Bhavesh Odedra * Akim Juillerat Maintainer ---------- -This module is maintained by Eficent. +This module is maintained by ForgeFlow. diff --git a/rma_account/__init__.py b/rma_account/__init__.py index f3284a96..d4a42780 100644 --- a/rma_account/__init__.py +++ b/rma_account/__init__.py @@ -1,4 +1,4 @@ -# © 2017 Eficent Business and IT Consulting Services S.L. +# Copyright 2017 ForgeFlow S.L. # License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html) from . import models diff --git a/rma_account/__manifest__.py b/rma_account/__manifest__.py index 7ba3aebe..12cbab86 100644 --- a/rma_account/__manifest__.py +++ b/rma_account/__manifest__.py @@ -1,4 +1,4 @@ -# © 2017 Eficent Business and IT Consulting Services S.L. +# Copyright 2017 ForgeFlow S.L. # License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html) { @@ -7,8 +7,8 @@ "license": "LGPL-3", "category": "RMA", "summary": "Integrates RMA with Invoice Processing", - "author": "Eficent, Odoo Community Association (OCA)", - "website": "https://github.com/Eficent/stock-rma", + "author": "ForgeFlow, Odoo Community Association (OCA)", + "website": "https://github.com/ForgeFlow/stock-rma", "depends": ["stock_account", "rma"], "demo": ["data/rma_operation.xml"], "data": [ diff --git a/rma_account/models/__init__.py b/rma_account/models/__init__.py index bdd70de6..5f6917c7 100644 --- a/rma_account/models/__init__.py +++ b/rma_account/models/__init__.py @@ -1,4 +1,4 @@ -# © 2017 Eficent Business and IT Consulting Services S.L. +# Copyright 2017 ForgeFlow S.L. # License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html) from . import rma_order diff --git a/rma_account/models/invoice.py b/rma_account/models/invoice.py index 3fadd0b4..f52efab4 100644 --- a/rma_account/models/invoice.py +++ b/rma_account/models/invoice.py @@ -1,4 +1,4 @@ -# © 2017 Eficent Business and IT Consulting Services S.L. +# Copyright 2017 ForgeFlow S.L. # License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html) from odoo import api, fields, models diff --git a/rma_account/models/rma_operation.py b/rma_account/models/rma_operation.py index 53ce4ed3..1e984810 100644 --- a/rma_account/models/rma_operation.py +++ b/rma_account/models/rma_operation.py @@ -1,4 +1,4 @@ -# © 2017 Eficent Business and IT Consulting Services S.L. +# Copyright 2017 ForgeFlow S.L. # License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html) from odoo import fields, models diff --git a/rma_account/models/rma_order.py b/rma_account/models/rma_order.py index 240ca011..5b323c41 100644 --- a/rma_account/models/rma_order.py +++ b/rma_account/models/rma_order.py @@ -1,4 +1,4 @@ -# © 2017 Eficent Business and IT Consulting Services S.L. +# Copyright 2017 ForgeFlow S.L. # License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html) from odoo import api, fields, models diff --git a/rma_account/models/rma_order_line.py b/rma_account/models/rma_order_line.py index c6dd50ab..fae7ff27 100644 --- a/rma_account/models/rma_order_line.py +++ b/rma_account/models/rma_order_line.py @@ -1,4 +1,4 @@ -# © 2017 Eficent Business and IT Consulting Services S.L. +# Copyright 2017 ForgeFlow S.L. # License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html) from odoo import _, api, fields, models diff --git a/rma_account/tests/__init__.py b/rma_account/tests/__init__.py index 77af78d7..4edd8b55 100644 --- a/rma_account/tests/__init__.py +++ b/rma_account/tests/__init__.py @@ -1,4 +1,4 @@ -# Copyright 2018 Eficent Business and IT Consulting Services S.L. +# Copyright 2018 ForgeFlow S.L. # License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html) from . import test_rma_account diff --git a/rma_account/tests/test_rma_account.py b/rma_account/tests/test_rma_account.py index 53c164fd..62678698 100644 --- a/rma_account/tests/test_rma_account.py +++ b/rma_account/tests/test_rma_account.py @@ -1,4 +1,4 @@ -# Copyright 2017-18 Eficent Business and IT Consulting Services S.L. +# Copyright 2017-18 ForgeFlow S.L. # License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html) from odoo.tests import common diff --git a/rma_account/views/rma_account_menu.xml b/rma_account/views/rma_account_menu.xml index 7388a537..ea117122 100644 --- a/rma_account/views/rma_account_menu.xml +++ b/rma_account/views/rma_account_menu.xml @@ -1,5 +1,5 @@ - diff --git a/rma_account/wizards/__init__.py b/rma_account/wizards/__init__.py index e3832b10..ec155b09 100644 --- a/rma_account/wizards/__init__.py +++ b/rma_account/wizards/__init__.py @@ -1,4 +1,4 @@ -# © 2017 Eficent Business and IT Consulting Services S.L. +# Copyright 2017 ForgeFlow S.L. # License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html) from . import rma_refund diff --git a/rma_account/wizards/rma_add_invoice.py b/rma_account/wizards/rma_add_invoice.py index a97e37f6..b38e00b7 100644 --- a/rma_account/wizards/rma_add_invoice.py +++ b/rma_account/wizards/rma_add_invoice.py @@ -1,4 +1,4 @@ -# © 2017 Eficent Business and IT Consulting Services S.L. +# Copyright 2017 ForgeFlow S.L. # License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html) from odoo import _, api, fields, models diff --git a/rma_account/wizards/rma_order_line_make_supplier_rma.py b/rma_account/wizards/rma_order_line_make_supplier_rma.py index e1c3fc78..48818da0 100644 --- a/rma_account/wizards/rma_order_line_make_supplier_rma.py +++ b/rma_account/wizards/rma_order_line_make_supplier_rma.py @@ -1,4 +1,4 @@ -# Copyright 2016 Eficent Business and IT Consulting Services S.L. +# Copyright 2016 ForgeFlow S.L. # License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl-3.0). from odoo import api, models diff --git a/rma_account/wizards/rma_refund.py b/rma_account/wizards/rma_refund.py index d86a754c..8faadb92 100644 --- a/rma_account/wizards/rma_refund.py +++ b/rma_account/wizards/rma_refund.py @@ -1,4 +1,4 @@ -# © 2017 Eficent Business and IT Consulting Services S.L. +# Copyright 2017 ForgeFlow S.L. # License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html) from odoo import _, api, fields, models From 81a79ac2a6e901b3833386804a5a9e8d3c7f87c6 Mon Sep 17 00:00:00 2001 From: ahenriquez Date: Wed, 22 Jan 2020 16:03:16 +0100 Subject: [PATCH 48/52] [MIG]rma_account to v13 --- rma_account/__manifest__.py | 8 +- rma_account/data/rma_operation.xml | 2 +- rma_account/models/__init__.py | 2 +- .../models/{invoice.py => account_move.py} | 57 +++++----- rma_account/models/rma_order.py | 62 +++++------ rma_account/models/rma_order_line.py | 89 +++++++-------- rma_account/security/ir.model.access.csv | 6 +- rma_account/tests/test_rma_account.py | 22 ++-- rma_account/views/account_move_view.xml | 69 ++++++++++++ rma_account/views/invoice_view.xml | 105 ------------------ rma_account/views/rma_account_menu.xml | 24 +++- rma_account/views/rma_order_line_view.xml | 24 ++-- rma_account/views/rma_order_view.xml | 4 +- rma_account/wizards/__init__.py | 2 +- ...add_invoice.py => rma_add_account_move.py} | 33 +++--- ...d_invoice.xml => rma_add_account_move.xml} | 55 +++++---- rma_account/wizards/rma_refund.py | 30 ++--- rma_account/wizards/rma_refund.xml | 6 +- 18 files changed, 288 insertions(+), 312 deletions(-) rename rma_account/models/{invoice.py => account_move.py} (77%) create mode 100644 rma_account/views/account_move_view.xml delete mode 100644 rma_account/views/invoice_view.xml rename rma_account/wizards/{rma_add_invoice.py => rma_add_account_move.py} (85%) rename rma_account/wizards/{rma_add_invoice.xml => rma_add_account_move.xml} (71%) diff --git a/rma_account/__manifest__.py b/rma_account/__manifest__.py index 12cbab86..48291782 100644 --- a/rma_account/__manifest__.py +++ b/rma_account/__manifest__.py @@ -3,11 +3,11 @@ { "name": "RMA Account", - "version": "12.0.1.0.0", + "version": "13.0.1.0.0", "license": "LGPL-3", "category": "RMA", "summary": "Integrates RMA with Invoice Processing", - "author": "ForgeFlow, Odoo Community Association (OCA)", + "author": "ForgeFlow", "website": "https://github.com/ForgeFlow/stock-rma", "depends": ["stock_account", "rma"], "demo": ["data/rma_operation.xml"], @@ -16,9 +16,9 @@ "views/rma_order_view.xml", "views/rma_operation_view.xml", "views/rma_order_line_view.xml", - "views/invoice_view.xml", + "views/account_move_view.xml", "views/rma_account_menu.xml", - "wizards/rma_add_invoice.xml", + "wizards/rma_add_account_move.xml", "wizards/rma_refund.xml", ], "installable": True, diff --git a/rma_account/data/rma_operation.xml b/rma_account/data/rma_operation.xml index f5a84ca0..139981df 100644 --- a/rma_account/data/rma_operation.xml +++ b/rma_account/data/rma_operation.xml @@ -1,5 +1,5 @@ - + no diff --git a/rma_account/models/__init__.py b/rma_account/models/__init__.py index 5f6917c7..09afbe77 100644 --- a/rma_account/models/__init__.py +++ b/rma_account/models/__init__.py @@ -4,4 +4,4 @@ from . import rma_order from . import rma_order_line from . import rma_operation -from . import invoice +from . import account_move diff --git a/rma_account/models/invoice.py b/rma_account/models/account_move.py similarity index 77% rename from rma_account/models/invoice.py rename to rma_account/models/account_move.py index f52efab4..602b0542 100644 --- a/rma_account/models/invoice.py +++ b/rma_account/models/account_move.py @@ -5,13 +5,13 @@ from odoo import api, fields, models from odoo.tools.float_utils import float_compare -class AccountInvoice(models.Model): - _inherit = "account.invoice" +class AccountMove(models.Model): + _inherit = "account.move" - @api.depends("invoice_line_ids.rma_line_ids") + @api.depends("line_ids.rma_line_ids") def _compute_rma_count(self): for inv in self: - rmas = self.mapped("invoice_line_ids.rma_line_ids") + rmas = self.mapped("line_ids.rma_line_ids") inv.rma_count = len(rmas) def _prepare_invoice_line_from_rma_line(self, line): @@ -19,18 +19,17 @@ class AccountInvoice(models.Model): if float_compare(qty, 0.0, precision_rounding=line.uom_id.rounding) <= 0: qty = 0.0 # Todo fill taxes from somewhere - invoice_line = self.env["account.invoice.line"] + invoice_line = self.env["account.move.line"] data = { "purchase_line_id": line.id, "name": line.name + ": " + line.name, - "origin": line.origin, - "uom_id": line.uom_id.id, + "product_uom_id": line.uom_id.id, "product_id": line.product_id.id, "account_id": invoice_line.with_context( {"journal_id": self.journal_id.id, "type": "in_invoice"} )._default_account(), "price_unit": line.company_id.currency_id.with_context( - date=self.date_invoice + date=self.date ).compute(line.price_unit, self.currency_id, round=False), "quantity": qty, "discount": 0.0, @@ -45,12 +44,12 @@ class AccountInvoice(models.Model): if not self.partner_id: self.partner_id = self.add_rma_line_id.partner_id.id - new_line = self.env["account.invoice.line"] - if self.add_rma_line_id not in (self.invoice_line_ids.mapped("rma_line_id")): + new_line = self.env["account.move.line"] + if self.add_rma_line_id not in (self.line_ids.mapped("rma_line_id")): data = self._prepare_invoice_line_from_rma_line(self.add_rma_line_id) new_line = new_line.new(data) new_line._set_additional_fields(self) - self.invoice_line_ids += new_line + self.line_ids += new_line self.add_rma_line_id = False return {} @@ -63,11 +62,10 @@ class AccountInvoice(models.Model): help="Create a refund in based on an existing rma_line", ) - @api.multi def action_view_rma_supplier(self): action = self.env.ref("rma.action_rma_supplier_lines") result = action.read()[0] - rma_ids = self.mapped("invoice_line_ids.rma_line_ids").ids + rma_ids = self.mapped("line_ids.rma_line_ids").ids if rma_ids: # choose the view_mode accordingly if len(rma_ids) > 1: @@ -78,11 +76,10 @@ class AccountInvoice(models.Model): result["res_id"] = rma_ids[0] return result - @api.multi def action_view_rma_customer(self): action = self.env.ref("rma.action_rma_customer_lines") result = action.read()[0] - rma_ids = self.mapped("invoice_line_ids.rma_line_ids").ids + rma_ids = self.mapped("line_ids.rma_line_ids").ids if rma_ids: # choose the view_mode accordingly if len(rma_ids) > 1: @@ -94,8 +91,8 @@ class AccountInvoice(models.Model): return result -class AccountInvoiceLine(models.Model): - _inherit = "account.invoice.line" +class AccountMoveLine(models.Model): + _inherit = "account.move.line" @api.model def name_search(self, name, args=None, operator="ilike", limit=100): @@ -104,7 +101,7 @@ class AccountInvoiceLine(models.Model): will make impossible to get the desired result.""" if not args: args = [] - lines = self.search([("invoice_id.number", operator, name)] + args, limit=limit) + lines = self.search([("move_id.name", operator, name)] + args, limit=limit) res = lines.name_get() if limit: limit_rest = limit - len(lines) @@ -113,50 +110,48 @@ class AccountInvoiceLine(models.Model): limit_rest = limit if limit_rest or not limit: args += [("id", "not in", lines.ids)] - res += super(AccountInvoiceLine, self).name_search( + res += super(AccountMoveLine, self).name_search( name, args=args, operator=operator, limit=limit_rest ) return res - @api.multi def name_get(self): res = [] if self.env.context.get("rma"): for inv in self: - if inv.invoice_id.reference: + if inv.move_id.ref: res.append( ( inv.id, "INV:%s | REF:%s | ORIG:%s | PART:%s | QTY:%s" % ( - inv.invoice_id.number or "", - inv.origin or "", - inv.invoice_id.reference or "", + inv.move_id.name or "", + inv.move_id.invoice_origin or "", + inv.move_id.ref or "", inv.product_id.name, inv.quantity, ), ) ) - elif inv.invoice_id.number: + elif inv.move_id.name: res.append( ( inv.id, "INV:%s | ORIG:%s | PART:%s | QTY:%s" % ( - inv.invoice_id.number or "", - inv.origin or "", + inv.move_id.name or "", + inv.move_id.invoice_origin or "", inv.product_id.name, inv.quantity, ), ) ) else: - res.append(super(AccountInvoiceLine, inv).name_get()[0]) + res.append(super(AccountMoveLine, inv).name_get()[0]) return res else: - return super(AccountInvoiceLine, self).name_get() + return super(AccountMoveLine, self).name_get() - @api.multi def _compute_rma_count(self): for invl in self: rma_lines = invl.mapped("rma_line_ids") @@ -165,7 +160,7 @@ class AccountInvoiceLine(models.Model): rma_line_count = fields.Integer(compute="_compute_rma_count", string="# of RMA") rma_line_ids = fields.One2many( comodel_name="rma.order.line", - inverse_name="invoice_line_id", + inverse_name="account_move_line_id", string="RMA", readonly=True, help="This will contain the RMA lines for the invoice line", diff --git a/rma_account/models/rma_order.py b/rma_account/models/rma_order.py index 5b323c41..15722a8f 100644 --- a/rma_account/models/rma_order.py +++ b/rma_account/models/rma_order.py @@ -7,20 +7,18 @@ from odoo import api, fields, models class RmaOrder(models.Model): _inherit = "rma.order" - @api.multi def _compute_invoice_refund_count(self): for rec in self: - invoices = rec.mapped("rma_line_ids.refund_line_ids.invoice_id") + invoices = rec.mapped("rma_line_ids.refund_line_ids.move_id") rec.invoice_refund_count = len(invoices) - @api.multi def _compute_invoice_count(self): for rec in self: - invoices = rec.mapped("rma_line_ids.invoice_id") + invoices = rec.mapped("rma_line_ids.move_id") rec.invoice_count = len(invoices) - add_invoice_id = fields.Many2one( - comodel_name="account.invoice", + add_move_id = fields.Many2one( + comodel_name="account.move", string="Add Invoice", ondelete="set null", readonly=True, @@ -44,30 +42,30 @@ class RmaOrder(models.Model): or self.rma_line_ids.product_id.categ_id.rma_supplier_operation_id ) data = { - "invoice_line_id": line.id, + "account_move_line_id": line.id, "product_id": line.product_id.id, "name": line.name, - "origin": line.invoice_id.number, - "uom_id": line.uom_id.id, + "origin": line.move_id.name, + "uom_id": line.product_uom_id.id, "operation_id": operation, "product_qty": line.quantity, - "price_unit": line.invoice_id.currency_id.compute( + "price_unit": line.move_id.currency_id.compute( line.price_unit, line.currency_id, round=False ), "rma_id": self.id, } return data - @api.onchange("add_invoice_id") + @api.onchange("add_move_id") def on_change_invoice(self): - if not self.add_invoice_id: + if not self.add_move_id: return {} if not self.partner_id: - self.partner_id = self.add_invoice_id.partner_id.id + self.partner_id = self.add_move_id.partner_id.id new_lines = self.env["rma.order.line"] - for line in self.add_invoice_id.invoice_line_ids: + for line in self.add_move_id.line_ids: # Load a PO line only once - if line in self.rma_line_ids.mapped("invoice_line_id"): + if line in self.rma_line_ids.mapped("account_move_line_id"): continue data = self._prepare_rma_line_from_inv_line(line) new_line = new_lines.new(data) @@ -75,9 +73,9 @@ class RmaOrder(models.Model): self.rma_line_ids += new_lines self.date_rma = fields.Datetime.now() - self.delivery_address_id = self.add_invoice_id.partner_id.id - self.invoice_address_id = self.add_invoice_id.partner_id.id - self.add_invoice_id = False + self.delivery_address_id = self.add_move_id.partner_id.id + self.invoice_address_id = self.add_move_id.partner_id.id + self.add_move_id = False return {} @api.model @@ -92,36 +90,34 @@ class RmaOrder(models.Model): res["invoice_address_id"] = partner.id return res - @api.multi def action_view_invoice_refund(self): action = self.env.ref("account.action_invoice_tree2") result = action.read()[0] - invoice_ids = self.mapped("rma_line_ids.refund_line_ids.invoice_id").ids - if invoice_ids: + move_ids = self.mapped("rma_line_ids.refund_line_ids.move_id").ids + if move_ids: # choose the view_mode accordingly - if len(invoice_ids) > 1: - result["domain"] = [("id", "in", invoice_ids)] + if len(move_ids) > 1: + result["domain"] = [("id", "in", move_ids)] else: - res = self.env.ref("account.invoice_supplier_form", False) + res = self.env.ref("account.move_supplier_form", False) result["views"] = [(res and res.id or False, "form")] - result["res_id"] = invoice_ids[0] + result["res_id"] = move_ids[0] return result - @api.multi def action_view_invoice(self): if self.type == "supplier": action = self.env.ref("account.action_invoice_tree2") - res = self.env.ref("account.invoice_supplier_form", False) + res = self.env.ref("account.move_supplier_form", False) else: action = self.env.ref("account.action_invoice_tree") - res = self.env.ref("account.invoice_form", False) + res = self.env.ref("account.view_move_form", False) result = action.read()[0] - invoice_ids = self.mapped("rma_line_ids.invoice_id").ids - if invoice_ids: + move_ids = self.mapped("rma_line_ids.move_id").ids + if move_ids: # choose the view_mode accordingly - if len(invoice_ids) > 1: - result["domain"] = [("id", "in", invoice_ids)] + if len(move_ids) > 1: + result["domain"] = [("id", "in", move_ids)] else: result["views"] = [(res and res.id or False, "form")] - result["res_id"] = invoice_ids[0] + result["res_id"] = move_ids[0] return result diff --git a/rma_account/models/rma_order_line.py b/rma_account/models/rma_order_line.py index fae7ff27..d49e879e 100644 --- a/rma_account/models/rma_order_line.py +++ b/rma_account/models/rma_order_line.py @@ -17,21 +17,20 @@ class RmaOrderLine(models.Model): return self.env["res.partner"].browse(partner_id) return self.env["res.partner"] - @api.multi @api.depends( - "refund_line_ids", "refund_line_ids.invoice_id.state", "refund_policy", "type" + "refund_line_ids", "refund_line_ids.move_id.state", "refund_policy", "type" ) def _compute_qty_refunded(self): for rec in self: rec.qty_refunded = sum( rec.refund_line_ids.filtered( - lambda i: i.invoice_id.state in ("open", "paid") + lambda i: i.move_id.state in ("open", "paid") ).mapped("quantity") ) @api.depends( "refund_line_ids", - "refund_line_ids.invoice_id.state", + "refund_line_ids.move_id.state", "refund_policy", "move_ids", "move_ids.state", @@ -48,10 +47,9 @@ class RmaOrderLine(models.Model): qty = res.qty_delivered - res.qty_refunded res.qty_to_refund = qty - @api.multi def _compute_refund_count(self): for rec in self: - rec.refund_count = len(rec.refund_line_ids.mapped("invoice_id")) + rec.refund_count = len(rec.refund_line_ids.mapped("move_id")) invoice_address_id = fields.Many2one( "res.partner", @@ -64,8 +62,8 @@ class RmaOrderLine(models.Model): refund_count = fields.Integer( compute="_compute_refund_count", string="# of Refunds", default=0 ) - invoice_line_id = fields.Many2one( - comodel_name="account.invoice.line", + account_move_line_id = fields.Many2one( + comodel_name="account.move.line", string="Originating Invoice Line", ondelete="restrict", index=True, @@ -73,17 +71,17 @@ class RmaOrderLine(models.Model): states={"draft": [("readonly", False)]}, ) refund_line_ids = fields.One2many( - comodel_name="account.invoice.line", + comodel_name="account.move.line", inverse_name="rma_line_id", string="Refund Lines", copy=False, index=True, readonly=True, ) - invoice_id = fields.Many2one( - "account.invoice", + move_id = fields.Many2one( + "account.move", string="Source", - related="invoice_line_id.invoice_id", + related="account_move_line_id.move_id", index=True, readonly=True, ) @@ -125,15 +123,14 @@ class RmaOrderLine(models.Model): res["domain"] = {} domain = [ "|", - ("invoice_id.partner_id", "=", self.partner_id.id), - ("invoice_id.partner_id", "child_of", self.partner_id.id), + ("move_id.partner_id", "=", self.partner_id.id), + ("move_id.partner_id", "child_of", self.partner_id.id), ] if self.product_id: domain.append(("product_id", "=", self.product_id.id)) - res["domain"]["invoice_line_id"] = domain + res["domain"]["account_move_line_id"] = domain return res - @api.multi def _prepare_rma_line_from_inv_line(self, line): self.ensure_one() if not self.type: @@ -173,15 +170,15 @@ class RmaOrderLine(models.Model): ) data = { "product_id": line.product_id.id, - "origin": line.invoice_id.number, - "uom_id": line.uom_id.id, + "origin": line.move_id.name, + "uom_id": line.product_uom_id.id, "operation_id": operation.id, "product_qty": line.quantity, - "price_unit": line.invoice_id.currency_id.compute( + "price_unit": line.move_id.currency_id.compute( line.price_unit, line.currency_id, round=False ), - "delivery_address_id": line.invoice_id.partner_id.id, - "invoice_address_id": line.invoice_id.partner_id.id, + "delivery_address_id": line.move_id.partner_id.id, + "invoice_address_id": line.move_id.partner_id.id, "receipt_policy": operation.receipt_policy, "refund_policy": operation.refund_policy, "delivery_policy": operation.delivery_policy, @@ -198,21 +195,20 @@ class RmaOrderLine(models.Model): } return data - @api.onchange("invoice_line_id") - def _onchange_invoice_line_id(self): - if not self.invoice_line_id: + @api.onchange("account_move_line_id") + def _onchange_account_move_line_id(self): + if not self.account_move_line_id: return - data = self._prepare_rma_line_from_inv_line(self.invoice_line_id) + data = self._prepare_rma_line_from_inv_line(self.account_move_line_id) self.update(data) - self._remove_other_data_origin("invoice_line_id") + self._remove_other_data_origin("account_move_line_id") - @api.multi - @api.constrains("invoice_line_id", "partner_id") + @api.constrains("account_move_line_id", "partner_id") def _check_invoice_partner(self): for rec in self: if ( - rec.invoice_line_id - and rec.invoice_line_id.invoice_id.partner_id != rec.partner_id + rec.account_move_line_id + and rec.account_move_line_id.move_id.partner_id != rec.partner_id ): raise ValidationError( _( @@ -221,11 +217,10 @@ class RmaOrderLine(models.Model): ) ) - @api.multi def _remove_other_data_origin(self, exception): res = super(RmaOrderLine, self)._remove_other_data_origin(exception) - if not exception == "invoice_line_id": - self.invoice_line_id = False + if not exception == "account_move_line_id": + self.account_move_line_id = False return res @api.onchange("operation_id") @@ -235,49 +230,45 @@ class RmaOrderLine(models.Model): self.refund_policy = self.operation_id.refund_policy or "no" return result - @api.multi - @api.constrains("invoice_line_id") + @api.constrains("account_move_line_id") def _check_duplicated_lines(self): for line in self: - matching_inv_lines = self.env["account.invoice.line"].search( - [("id", "=", line.invoice_line_id.id)] + matching_inv_lines = self.env["account.move.line"].search( + [("id", "=", line.account_move_line_id.id)] ) if len(matching_inv_lines) > 1: raise UserError( _( "There's an rma for the invoice line %s " "and invoice %s" - % (line.invoice_line_id, line.invoice_line_id.invoice_id) + % (line.account_move_line_id, line.account_move_line_id.move_id) ) ) return {} - @api.multi def action_view_invoice(self): action = self.env.ref("account.action_invoice_tree") result = action.read()[0] - res = self.env.ref("account.invoice_form", False) + res = self.env.ref("account.view_move_form", False) result["views"] = [(res and res.id or False, "form")] result["view_id"] = res and res.id or False - result["res_id"] = self.invoice_line_id.invoice_id.id + result["res_id"] = self.account_move_line_id.move_id.id return result - @api.multi def action_view_refunds(self): action = self.env.ref("account.action_invoice_tree2") result = action.read()[0] - invoice_ids = self.mapped("refund_line_ids.invoice_id").ids - if invoice_ids: + move_ids = self.mapped("refund_line_ids.move_id").ids + if move_ids: # choose the view_mode accordingly - if len(invoice_ids) > 1: - result["domain"] = [("id", "in", invoice_ids)] + if len(move_ids) > 1: + result["domain"] = [("id", "in", move_ids)] else: - res = self.env.ref("account.invoice_supplier_form", False) + res = self.env.ref("account.move_supplier_form", False) result["views"] = [(res and res.id or False, "form")] - result["res_id"] = invoice_ids[0] + result["res_id"] = move_ids[0] return result - @api.multi def name_get(self): res = [] if self.env.context.get("rma"): diff --git a/rma_account/security/ir.model.access.csv b/rma_account/security/ir.model.access.csv index b6fa0d93..74b1c356 100755 --- a/rma_account/security/ir.model.access.csv +++ b/rma_account/security/ir.model.access.csv @@ -1,3 +1,5 @@ id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink -access_account_invoice_customer_user,access_account_invoice,account.model_account_invoice,rma.group_rma_customer_user,1,0,0,0 -access_account_invoice_supplier_user,access_account_invoice,account.model_account_invoice,rma.group_rma_supplier_user,1,0,0,0 +access_account_move_customer_user,access_account_move,account.model_account_move,rma.group_rma_customer_user,1,0,0,0 +access_account_move_supplier_user,access_account_move,account.model_account_move,rma.group_rma_supplier_user,1,0,0,0 +access_account_move_line_customer_user,access_account_move_line,account.model_account_move_line,rma.group_rma_customer_user,1,0,0,0 +access_account_move_line_supplier_user,access_account_move_line,account.model_account_move_line,rma.group_rma_supplier_user,1,0,0,0 diff --git a/rma_account/tests/test_rma_account.py b/rma_account/tests/test_rma_account.py index 62678698..32243011 100644 --- a/rma_account/tests/test_rma_account.py +++ b/rma_account/tests/test_rma_account.py @@ -15,8 +15,8 @@ class TestRmaAccount(common.SingleTransactionCase): cls.rma_add_invoice_wiz = cls.env["rma_add_invoice"] cls.rma_refund_wiz = cls.env["rma.refund"] cls.acc_obj = cls.env["account.account"] - cls.inv_obj = cls.env["account.invoice"] - cls.invl_obj = cls.env["account.invoice.line"] + cls.inv_obj = cls.env["account.move"] + cls.invl_obj = cls.env["account.move.line"] cls.product_obj = cls.env["product.product"] cls.partner_obj = cls.env["res.partner"] @@ -89,7 +89,7 @@ class TestRmaAccount(common.SingleTransactionCase): "product_id": cls.product_1.id, "quantity": 12.0, "price_unit": 100.0, - "invoice_id": cls.inv_customer.id, + "move_id": cls.inv_customer.id, "uom_id": cls.product_1.uom_id.id, "account_id": customer_account, } @@ -100,7 +100,7 @@ class TestRmaAccount(common.SingleTransactionCase): "product_id": cls.product_2.id, "quantity": 15.0, "price_unit": 150.0, - "invoice_id": cls.inv_customer.id, + "move_id": cls.inv_customer.id, "uom_id": cls.product_2.uom_id.id, "account_id": customer_account, } @@ -122,7 +122,7 @@ class TestRmaAccount(common.SingleTransactionCase): "product_id": cls.product_3.id, "quantity": 17.0, "price_unit": 250.0, - "invoice_id": cls.inv_supplier.id, + "move_id": cls.inv_supplier.id, "uom_id": cls.product_3.uom_id.id, "account_id": supplier_account, } @@ -133,7 +133,7 @@ class TestRmaAccount(common.SingleTransactionCase): "product_id": cls.product_4.id, "quantity": 9.0, "price_unit": 300.0, - "invoice_id": cls.inv_supplier.id, + "move_id": cls.inv_supplier.id, "uom_id": cls.product_4.uom_id.id, "account_id": supplier_account, } @@ -147,7 +147,7 @@ class TestRmaAccount(common.SingleTransactionCase): "active_ids": self.rma_group_customer.id, "active_model": "rma.order", } - ).create({"invoice_line_ids": [(6, 0, self.inv_customer.invoice_line_ids.ids)]}) + ).create({"line_ids": [(6, 0, self.inv_customer.line_ids.ids)]}) add_inv.add_lines() self.assertEqual(len(self.rma_group_customer.rma_line_ids), 2) for t in self.rma_group_supplier.rma_line_ids.mapped("type"): @@ -169,7 +169,7 @@ class TestRmaAccount(common.SingleTransactionCase): "active_ids": self.rma_group_supplier.id, "active_model": "rma.order", } - ).create({"invoice_line_ids": [(6, 0, self.inv_supplier.invoice_line_ids.ids)]}) + ).create({"line_ids": [(6, 0, self.inv_supplier.line_ids.ids)]}) add_inv.add_lines() self.assertEqual(len(self.rma_group_supplier.rma_line_ids), 2) for t in self.rma_group_supplier.rma_line_ids.mapped("type"): @@ -206,7 +206,7 @@ class TestRmaAccount(common.SingleTransactionCase): {"customer": True, "active_ids": rma.ids, "active_model": "rma.order.line"} ).create({"description": "Test refund"}) make_refund.invoice_refund() - rma.refund_line_ids.invoice_id.action_invoice_open() + rma.refund_line_ids.move_id.action_invoice_open() rma._compute_refund_count() self.assertEqual(rma.refund_count, 1) self.assertEqual(rma.qty_to_refund, 0.0) @@ -217,10 +217,10 @@ class TestRmaAccount(common.SingleTransactionCase): rma = self.rma_line_obj.new( { "partner_id": self.inv_customer.partner_id.id, - "invoice_line_id": self.inv_line_1.id, + "account_move_line_id": self.inv_line_1.id, } ) self.assertFalse(rma.product_id) - rma._onchange_invoice_line_id() + rma._onchange_account_move_line_id() self.assertEqual(rma.product_id, self.product_1) self.assertEqual(rma.product_qty, 12.0) diff --git a/rma_account/views/account_move_view.xml b/rma_account/views/account_move_view.xml new file mode 100644 index 00000000..8c927540 --- /dev/null +++ b/rma_account/views/account_move_view.xml @@ -0,0 +1,69 @@ + + + + account.move.form + account.move + + + +
+ +
+
+
+
+ + + + rma.invoice.line.form + account.move.line + + + + + + + + + + + + + + + + + + + + account.move.customer.rma + account.move + + + + + + + + + + Invoice Line + account.move.line + form + + +
diff --git a/rma_account/views/invoice_view.xml b/rma_account/views/invoice_view.xml deleted file mode 100644 index e1f19fdc..00000000 --- a/rma_account/views/invoice_view.xml +++ /dev/null @@ -1,105 +0,0 @@ - - - - account.invoice.form - account.invoice - - - -
- -
-
-
-
- - - account.invoice.supplier.form - account.invoice - - - -
- -
-
-
-
- - - rma.invoice.line.form - account.invoice.line - - - - - - - - - - - - - - - - - - - account.invoice.supplier.rma - account.invoice - - - - - - - - - - account.invoice.customer.rma - account.invoice - - - - - - - - - - Invoice Line - account.invoice.line - form - form - - -
diff --git a/rma_account/views/rma_account_menu.xml b/rma_account/views/rma_account_menu.xml index ea117122..6f552638 100644 --- a/rma_account/views/rma_account_menu.xml +++ b/rma_account/views/rma_account_menu.xml @@ -8,7 +8,6 @@ rma.order.line [('type','=', 'customer')] {"search_default_to_refund":1} - form tree,form
@@ -17,11 +16,32 @@ rma.order.line [('type','=', 'supplier')] {"search_default_to_refund":1, "supplier":1} - form tree,form
+ + + + + + + + + - + ('move_id.partner_id', '=', partner_id), + ('move_id.partner_id', 'child_of', partner_id)]"/> @@ -49,6 +54,11 @@ - + ('move_id.partner_id', '=', partner_id), + ('move_id.partner_id', 'child_of', partner_id)]"/> diff --git a/rma_account/views/rma_order_view.xml b/rma_account/views/rma_order_view.xml index 270b1058..5c6b0e82 100644 --- a/rma_account/views/rma_order_view.xml +++ b/rma_account/views/rma_order_view.xml @@ -25,7 +25,7 @@ @@ -56,7 +56,7 @@ diff --git a/rma_account/wizards/__init__.py b/rma_account/wizards/__init__.py index ec155b09..52d1defb 100644 --- a/rma_account/wizards/__init__.py +++ b/rma_account/wizards/__init__.py @@ -2,5 +2,5 @@ # License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html) from . import rma_refund -from . import rma_add_invoice +from . import rma_add_account_move from . import rma_order_line_make_supplier_rma diff --git a/rma_account/wizards/rma_add_invoice.py b/rma_account/wizards/rma_add_account_move.py similarity index 85% rename from rma_account/wizards/rma_add_invoice.py rename to rma_account/wizards/rma_add_account_move.py index b38e00b7..1bd518f5 100644 --- a/rma_account/wizards/rma_add_invoice.py +++ b/rma_account/wizards/rma_add_account_move.py @@ -5,8 +5,8 @@ from odoo import _, api, fields, models from odoo.exceptions import ValidationError -class RmaAddInvoice(models.TransientModel): - _name = "rma_add_invoice" +class RmaAddAccountMove(models.TransientModel): + _name = "rma_add_account_move" _description = "Wizard to add rma lines" @api.model @@ -21,7 +21,7 @@ class RmaAddInvoice(models.TransientModel): rma = rma_obj.browse(rma_id) res["rma_id"] = rma.id res["partner_id"] = rma.partner_id.id - res["invoice_line_ids"] = False + res["line_ids"] = False return res rma_id = fields.Many2one( @@ -30,11 +30,11 @@ class RmaAddInvoice(models.TransientModel): partner_id = fields.Many2one( comodel_name="res.partner", string="Partner", readonly=True ) - invoice_line_ids = fields.Many2many( - "account.invoice.line", - "rma_add_invoice_add_line_rel", - "invoice_line_id", - "rma_add_invoice_id", + line_ids = fields.Many2many( + "account.move.line", + "rma_add_account_move_add_line_rel", + "account_move_line_id", + "rma_add_move_id", string="Invoice Lines", ) @@ -76,17 +76,17 @@ class RmaAddInvoice(models.TransientModel): ) data = { "partner_id": self.partner_id.id, - "invoice_line_id": line.id, + "account_move_line_id": line.id, "product_id": line.product_id.id, - "origin": line.invoice_id.number, - "uom_id": line.uom_id.id, + "origin": line.move_id.name, + "uom_id": line.product_uom_id.id, "operation_id": operation.id, "product_qty": line.quantity, - "price_unit": line.invoice_id.currency_id.compute( + "price_unit": line.move_id.currency_id.compute( line.price_unit, line.currency_id, round=False ), - "delivery_address_id": line.invoice_id.partner_id.id, - "invoice_address_id": line.invoice_id.partner_id.id, + "delivery_address_id": line.move_id.partner_id.id, + "invoice_address_id": line.move_id.partner_id.id, "rma_id": self.rma_id.id, "receipt_policy": operation.receipt_policy, "refund_policy": operation.refund_policy, @@ -112,14 +112,13 @@ class RmaAddInvoice(models.TransientModel): def _get_existing_invoice_lines(self): existing_invoice_lines = [] for rma_line in self.rma_id.rma_line_ids: - existing_invoice_lines.append(rma_line.invoice_line_id) + existing_invoice_lines.append(rma_line.account_move_line_id) return existing_invoice_lines - @api.multi def add_lines(self): rma_line_obj = self.env["rma.order.line"] existing_invoice_lines = self._get_existing_invoice_lines() - for line in self.invoice_line_ids: + for line in self.line_ids: # Load a PO line only once if line not in existing_invoice_lines: data = self._prepare_rma_line_from_inv_line(line) diff --git a/rma_account/wizards/rma_add_invoice.xml b/rma_account/wizards/rma_add_account_move.xml similarity index 71% rename from rma_account/wizards/rma_add_invoice.xml rename to rma_account/wizards/rma_add_account_move.xml index 29e3fda9..4e4efea7 100644 --- a/rma_account/wizards/rma_add_invoice.xml +++ b/rma_account/wizards/rma_add_account_move.xml @@ -2,9 +2,9 @@ - + rma.add.invoice - rma_add_invoice + rma_add_account_move
@@ -13,15 +13,16 @@ string="Customer"/> - + - + - + + @@ -41,9 +42,9 @@ - + rma.add.invoice.supplier - rma_add_invoice + rma_add_account_move @@ -52,15 +53,16 @@ string="Supplier"/> - + - + - + + @@ -80,50 +82,47 @@ - + Add Invoice ir.actions.act_window - rma_add_invoice - rma.order - form + rma_add_account_move form new - + - + Add Invoice ir.actions.act_window - rma_add_invoice - rma.order - form + rma_add_account_move + form new - + - + rma.order.form - invoice wizard rma.order -