From 1fdd20ecb7ca4c3afad8d634e2f570c61f5b5f19 Mon Sep 17 00:00:00 2001 From: lreficent Date: Tue, 19 Sep 2017 17:11:52 +0200 Subject: [PATCH] [9.0][FIX] rma_repair --- rma_repair/README.rst | 40 ++--- rma_repair/__init__.py | 2 +- rma_repair/__openerp__.py | 5 +- rma_repair/models/__init__.py | 1 - rma_repair/models/rma_order_line.py | 14 +- rma_repair/views/mrp_repair_view.xml | 23 ++- rma_repair/views/rma_operation_view.xml | 38 +++-- rma_repair/views/rma_order_line_view.xml | 86 +++++----- rma_repair/views/rma_order_view.xml | 36 ++--- rma_repair/wizards/__init__.py | 6 +- rma_repair/wizards/rma_add_sale.py | 115 ------------- rma_repair/wizards/rma_add_sale.xml | 80 --------- rma_repair/wizards/rma_make_picking.py | 21 --- .../wizards/rma_order_line_make_repair.py | 143 ++++++++++++++++ .../rma_order_line_make_repair_view.xml | 60 +++++++ .../wizards/rma_order_line_make_sale_order.py | 153 ------------------ .../rma_order_line_make_sale_order_view.xml | 75 --------- rma_repair/wizards/rma_refund.py | 21 --- 18 files changed, 321 insertions(+), 598 deletions(-) delete mode 100644 rma_repair/wizards/rma_add_sale.py delete mode 100644 rma_repair/wizards/rma_add_sale.xml delete mode 100644 rma_repair/wizards/rma_make_picking.py create mode 100644 rma_repair/wizards/rma_order_line_make_repair.py create mode 100644 rma_repair/wizards/rma_order_line_make_repair_view.xml delete mode 100644 rma_repair/wizards/rma_order_line_make_sale_order.py delete mode 100644 rma_repair/wizards/rma_order_line_make_sale_order_view.xml delete mode 100644 rma_repair/wizards/rma_refund.py diff --git a/rma_repair/README.rst b/rma_repair/README.rst index 83a71dc9..5151b42c 100644 --- a/rma_repair/README.rst +++ b/rma_repair/README.rst @@ -1,37 +1,31 @@ .. image:: https://img.shields.io/badge/licence-LGPL--3-blue.svg :alt: License LGPL-3 -======== -RMA Sale -======== +========== +RMA Repair +========== -This module allows you to: +wip: +* fix wizard +* change repair sequence to not use 'RMA'. -#. Import sales order lines into RMA lines -#. Create a sales order and/or sales order line from one or more RMA lines +This module allows you to create repairs from one or more RMA lines. + +Installation +============ + +This module depends on ``mrp_repair_refurbish`` which is available at +`OCA/manufacture `_. Usage ===== -**Import existing sales order lines into an RMA:** - -This feature is useful when you create an RMA associated to a product that -was shipped and you have as a reference the customer PO number. - -#. Access to a customer RMA. -#. Fill the customer. -#. Press the button *Add from Sales Order*. -#. In the wizard add a sales order and click on *add item* to select the - lines you want to add to the RMA. - -**Create a sales order and/or sales order line from RMA lines:** +To create repairs from RMA lines: #. Go to a approved RMA line. -#. Click on *Create a Sales Quotation*. -#. In the wizard, select an *Existing Quotation to update* or leave it empty - if you want to create a new one. -#. Fill the quantity to sell in the lines. -#. Hit *Create a Sales Quotation*. +#. Click on *Create Repair Order*. +#. Fill the required information in the lines. +#. Hit *Create Repair Orders*. Bug Tracker =========== diff --git a/rma_repair/__init__.py b/rma_repair/__init__.py index 4105ff51..9f7a36d7 100644 --- a/rma_repair/__init__.py +++ b/rma_repair/__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_repair/__openerp__.py b/rma_repair/__openerp__.py index fdc480a7..7c89f697 100644 --- a/rma_repair/__openerp__.py +++ b/rma_repair/__openerp__.py @@ -13,9 +13,8 @@ "depends": ["rma_account", "mrp_repair_refurbish"], "data": ["views/rma_order_view.xml", "views/rma_operation_view.xml", - "views/sale_order_view.xml", - "wizards/rma_order_line_make_sale_order_view.xml", - "wizards/rma_add_sale.xml", + "views/mrp_repair_view.xml", + "wizards/rma_order_line_make_repair_view.xml", "views/rma_order_line_view.xml"], "installable": True, "auto_install": True, diff --git a/rma_repair/models/__init__.py b/rma_repair/models/__init__.py index f5e18c3a..89364fb2 100644 --- a/rma_repair/models/__init__.py +++ b/rma_repair/models/__init__.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- -# Copyright 2017 Eficent Business and IT Consulting Services S.L. # License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html) from . import mrp_repair diff --git a/rma_repair/models/rma_order_line.py b/rma_repair/models/rma_order_line.py index 5be63526..00bfd78f 100644 --- a/rma_repair/models/rma_order_line.py +++ b/rma_repair/models/rma_order_line.py @@ -10,7 +10,8 @@ class RmaOrderLine(models.Model): _inherit = "rma.order.line" @api.one - @api.depends('repair_ids', 'repair_ids.state') + @api.depends('repair_ids', 'repair_type', 'repair_ids.state', + 'qty_to_receive') def _compute_qty_to_repair(self): if self.repair_type == 'no': self.qty_to_repair = 0.0 @@ -24,7 +25,8 @@ class RmaOrderLine(models.Model): self.qty_to_repair = 0.0 @api.one - @api.depends('repair_ids', 'repair_type', 'repair_ids.state') + @api.depends('repair_ids', 'repair_type', 'repair_ids.state', + 'qty_to_receive') def _compute_qty_repaired(self): self.qty_repaired = self._get_rma_repaired_qty() @@ -38,15 +40,15 @@ class RmaOrderLine(models.Model): string='Repair Orders', readonly=True, states={'draft': [('readonly', False)]}, copy=False) qty_to_repair = fields.Float( - string='Qty To Sell', copy=False, + string='Qty To Repair', copy=False, digits=dp.get_precision('Product Unit of Measure'), readonly=True, compute=_compute_qty_to_repair, store=True) qty_repaired = fields.Float( - string='Qty Sold', copy=False, + string='Qty Repaired', copy=False, digits=dp.get_precision('Product Unit of Measure'), readonly=True, compute=_compute_qty_repaired, - store=True) + store=True, help="Quantity repaired or being repaired.") repair_type = fields.Selection(selection=[ ('no', 'Not required'), ('ordered', 'Based on Ordered Quantities'), ('received', 'Based on Received Quantities')], @@ -69,7 +71,7 @@ class RmaOrderLine(models.Model): lambda p: p.state != 'cancel'): repair_qty = self.env['product.uom']._compute_qty_obj( self.uom_id, - repair.product_uom_qty, + repair.product_qty, repair.product_uom, ) qty += repair_qty diff --git a/rma_repair/views/mrp_repair_view.xml b/rma_repair/views/mrp_repair_view.xml index 3f3bb77b..c5e59e1d 100644 --- a/rma_repair/views/mrp_repair_view.xml +++ b/rma_repair/views/mrp_repair_view.xml @@ -1,16 +1,15 @@ - - - mrp.repair.form - mrp.repair - - - - - - - - + + mrp.repair.form rma_repair + mrp.repair + + + + + + + + diff --git a/rma_repair/views/rma_operation_view.xml b/rma_repair/views/rma_operation_view.xml index d52fc2d3..5d1f9060 100644 --- a/rma_repair/views/rma_operation_view.xml +++ b/rma_repair/views/rma_operation_view.xml @@ -1,28 +1,26 @@ - - - rma.operation.tree - rma.operation - - - - - + + rma.operation.tree - rma_repair + rma.operation + + + + - + + - - rma.operation.form - rma.operation - - - - - + + rma.operation.form - rma_repair + rma.operation + + + + - + + - diff --git a/rma_repair/views/rma_order_line_view.xml b/rma_repair/views/rma_order_line_view.xml index 439f0c67..91378289 100644 --- a/rma_repair/views/rma_order_line_view.xml +++ b/rma_repair/views/rma_order_line_view.xml @@ -1,52 +1,50 @@ - - - rma.order.line.form - rma.order.line - - -
- -
- - - - - + + rma.order.line.form - rma_repair + rma.order.line + + +
+ +
+ + + + - - - - - - - - + + + -
+ + + + + +
+
- - rma.order.line.form - rma.order.line - - -
-
-
-
+ + rma.order.line.form - rma_repair + rma.order.line + + +
+
+
+
-
diff --git a/rma_repair/views/rma_order_view.xml b/rma_repair/views/rma_order_view.xml index 9ac98e2a..5b3b5baf 100644 --- a/rma_repair/views/rma_order_view.xml +++ b/rma_repair/views/rma_order_view.xml @@ -1,21 +1,21 @@ - - - rma.order.form - rma.order - - -
- -
-
-
-
+ + + rma.order.form - rma_repair + rma.order + + +
+ +
+
+
+
diff --git a/rma_repair/wizards/__init__.py b/rma_repair/wizards/__init__.py index 40e8ecb8..d6b50170 100644 --- a/rma_repair/wizards/__init__.py +++ b/rma_repair/wizards/__init__.py @@ -1,8 +1,4 @@ # -*- 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_line_make_sale_order -from . import rma_make_picking -from . import rma_refund -from . import rma_add_sale +from . import rma_order_line_make_repair diff --git a/rma_repair/wizards/rma_add_sale.py b/rma_repair/wizards/rma_add_sale.py deleted file mode 100644 index 64c4873a..00000000 --- a/rma_repair/wizards/rma_add_sale.py +++ /dev/null @@ -1,115 +0,0 @@ -# -*- 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 - - -class RmaAddSale(models.TransientModel): - _name = 'rma_add_sale' - _description = 'Wizard to add rma lines from SO lines' - - @api.model - def default_get(self, fields): - res = super(RmaAddSale, 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['sale_id'] = False - res['sale_line_ids'] = False - return res - - rma_id = fields.Many2one( - comodel_name='rma.order', string='RMA Order', readonly=True) - partner_id = fields.Many2one(comodel_name='res.partner', string='Partner', - readonly=True) - sale_id = fields.Many2one(comodel_name='sale.order', string='Order') - sale_line_ids = fields.Many2many('sale.order.line', - 'rma_add_sale_add_line_rel', - 'sale_line_id', 'rma_add_sale_id', - readonly=False, - string='Sale Lines') - - def _prepare_rma_line_from_sale_order_line(self, line): - operation = line.product_id.rma_customer_operation_id - if not operation: - operation = line.product_id.categ_id.rma_customer_operation_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") - 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 = { - 'sale_line_id': line.id, - 'product_id': line.product_id.id, - 'origin': line.order_id.name, - 'uom_id': line.product_uom.id, - 'operation_id': operation.id, - 'product_qty': line.product_uom_qty, - 'delivery_address_id': self.sale_id.partner_id.id, - 'invoice_address_id': self.sale_id.partner_id.id, - 'price_unit': line.currency_id.compute( - line.price_unit, line.currency_id, round=False), - 'rma_id': self.rma_id.id, - 'in_route_id': operation.in_route_id.id or route.id, - 'out_route_id': operation.out_route_id.id or route.id, - 'receipt_policy': operation.receipt_policy, - 'location_id': (operation.location_id.id or - operation.in_warehouse_id.lot_rma_id.id or - warehouse.lot_rma_id.id), - 'refund_policy': operation.refund_policy, - 'delivery_policy': operation.delivery_policy, - 'in_warehouse_id': operation.in_warehouse_id.id or warehouse.id, - 'out_warehouse_id': operation.out_warehouse_id.id or warehouse.id, - } - return data - - @api.model - def _get_rma_data(self): - data = { - 'date_rma': fields.Datetime.now(), - 'delivery_address_id': self.sale_id.partner_id.id, - 'invoice_address_id': self.sale_id.partner_id.id - } - return data - - @api.model - def _get_existing_sale_lines(self): - existing_sale_lines = [] - for rma_line in self.rma_id.rma_line_ids: - existing_sale_lines.append(rma_line.sale_line_id) - return existing_sale_lines - - @api.multi - def add_lines(self): - rma_line_obj = self.env['rma.order.line'] - existing_sale_lines = self._get_existing_sale_lines() - for line in self.sale_line_ids: - # Load a PO line only once - if line not in existing_sale_lines: - data = self._prepare_rma_line_from_sale_order_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_repair/wizards/rma_add_sale.xml b/rma_repair/wizards/rma_add_sale.xml deleted file mode 100644 index 2a0c75b7..00000000 --- a/rma_repair/wizards/rma_add_sale.xml +++ /dev/null @@ -1,80 +0,0 @@ - - - - - rma.add.sale - rma_add_sale - -
- - - - - - - - - - - - - - - - - - - - - - - - -
-
- -
-
- - - Add Sale Order - ir.actions.act_window - rma_add_sale - rma.order - form - form - new - - - - - - - rma.order.form - sale wizard - rma.order - - - - - - -
diff --git a/rma_repair/wizards/rma_make_picking.py b/rma_repair/wizards/rma_make_picking.py deleted file mode 100644 index 848e6a11..00000000 --- a/rma_repair/wizards/rma_make_picking.py +++ /dev/null @@ -1,21 +0,0 @@ -# -*- 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 RmaMakePicking(models.TransientModel): - _inherit = 'rma_make_picking.wizard' - - @api.returns('rma.order.line') - def _prepare_item(self, line): - res = super(RmaMakePicking, self)._prepare_item(line) - res['sale_line_id'] = line.sale_line_id.id - return res - - -class RmaMakePickingItem(models.TransientModel): - _inherit = "rma_make_picking.wizard.item" - - sale_line_id = fields.Many2one( - comodel_name='sale.order.line', string='Sale Line') diff --git a/rma_repair/wizards/rma_order_line_make_repair.py b/rma_repair/wizards/rma_order_line_make_repair.py new file mode 100644 index 00000000..38180275 --- /dev/null +++ b/rma_repair/wizards/rma_order_line_make_repair.py @@ -0,0 +1,143 @@ +# -*- 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, fields, models +from openerp.exceptions import ValidationError + + +class RmaLineMakeRepair(models.TransientModel): + _name = "rma.order.line.make.repair" + _description = "Make Repair Order from RMA Line" + + item_ids = fields.One2many( + comodel_name='rma.order.line.make.repair.item', + inverse_name='wiz_id', string='Items') + + @api.model + def _prepare_item(self, line): + if line.product_id.refurbish_product_id: + to_refurbish = True + refurbish_product_id = line.product_id.refurbish_product_id.id + else: + to_refurbish = refurbish_product_id = False + return { + 'line_id': line.id, + 'rma_line_id': line.id, + 'product_id': line.product_id.id, + 'product_qty': line.qty_to_repair, + 'rma_id': line.rma_id.id, + 'out_route_id': line.out_route_id.id, + 'product_uom_id': line.uom_id.id, + 'partner_id': line.partner_id.id, + # 'location_dest_id': which default here?, + 'to_refurbish': to_refurbish, + 'refurbish_product_id': refurbish_product_id, + 'location_id': line.location_id.id, + } + + @api.model + def default_get(self, fields): + res = super(RmaLineMakeRepair, 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) + for line in lines: + items.append([0, 0, self._prepare_item(line)]) + res['item_ids'] = items + return res + + @api.multi + def make_repair_order(self): + res = [] + repair_obj = self.env['mrp.repair'] + for item in self.item_ids: + rma_line = item.line_id + data = item._prepare_repair_order(rma_line) + repair = repair_obj.create(data) + res.append(repair.id) + return { + 'domain': [('id', 'in', res)], + 'name': _('Repairs'), + 'view_type': 'form', + 'view_mode': 'tree,form', + 'res_model': 'mrp.repair', + 'view_id': False, + 'context': False, + 'type': 'ir.actions.act_window' + } + + +class RmaLineMakeRepairItem(models.TransientModel): + _name = "rma.order.line.make.repair.item" + _description = "RMA Line Make Repair Item" + + @api.constrains('product_qty') + def _check_prodcut_qty(self): + for rec in self: + if rec.product_qty <= 0.0: + raise ValidationError(_('Quantity must be positive.')) + + @api.onchange('to_refurbish') + def _onchange_to_refurbish(self): + if self.to_refurbish: + self.refurbish_product_id = self.product_id.refurbish_product_id + else: + self.refurbish_product_id = False + + wiz_id = fields.Many2one( + comodel_name='rma.order.line.make.repair', string='Wizard', + required=True, readonly=True) + line_id = fields.Many2one( + comodel_name='rma.order.line', string='RMA Line', required=True) + rma_id = fields.Many2one( + comodel_name='rma.order', related='line_id.rma_id', + string='RMA Order', readonly=True) + product_id = fields.Many2one( + comodel_name='product.product', string='Product', readonly=True) + product_qty = fields.Float( + string='Quantity to repair', digits=dp.get_precision('Product UoS')) + product_uom_id = fields.Many2one( + comodel_name='product.uom', string='UoM', readonly=True) + out_route_id = fields.Many2one( + comodel_name='stock.location.route', string='Outbound Route', + domain=[('rma_selectable', '=', True)]) + partner_id = fields.Many2one( + comodel_name='res.partner', string='Customer', required=False, + domain=[('customer', '=', True)]) + location_id = fields.Many2one( + comodel_name="stock.location", string="Location", required=True) + location_dest_id = fields.Many2one( + comodel_name="stock.location", string="Destination location", + required=True) + to_refurbish = fields.Boolean(string="To Refurbish?") + refurbish_product_id = fields.Many2one( + comodel_name="product.product", string="Refurbished Product") + + @api.model + def _prepare_repair_order(self, rma_line): + location_dest = (self.location_dest_id if not self.to_refurbish else + self.product_id.property_stock_refurbish) + refurbish_location_dest_id = (self.location_dest_id.id if + self.to_refurbish else False) + return { + 'product_id': self.product_id.id, + 'partner_id': self.partner_id.id, + 'product_qty': self.product_qty, + 'rma_line_id': self.line_id.id, + 'product_uom': self.product_id.uom_po_id.id, + 'company_id': rma_line.company_id.id, + 'location_id': self.location_id.id, + 'location_dest_id': location_dest.id, + 'refurbish_location_dest_id': refurbish_location_dest_id, + 'refurbish_product_id': self.refurbish_product_id.id, + 'to_refurbish': self.to_refurbish, + } diff --git a/rma_repair/wizards/rma_order_line_make_repair_view.xml b/rma_repair/wizards/rma_order_line_make_repair_view.xml new file mode 100644 index 00000000..8a38aac3 --- /dev/null +++ b/rma_repair/wizards/rma_order_line_make_repair_view.xml @@ -0,0 +1,60 @@ + + + + + + RMA Line Make Repair + rma.order.line.make.repair + form + +
+ + + + + + + + + + + + + + + + + + + +