[11.0] MIG: RMA module

This commit is contained in:
Bhavesh Odedra
2018-02-09 21:56:28 +05:30
committed by ahenriquez
parent f9c7b28af8
commit ae0a75499a
40 changed files with 640 additions and 781 deletions

21
rma/README.rst Normal file → Executable file
View File

@@ -59,16 +59,16 @@ steps:
Other Settings Other Settings
-------------- --------------
#. Go to Inventory > Settings > Return Merchandising Authorization and select #. Go to Inventory > Configuration > Settings > Return Merchandising
the option "Display 3 fields on rma: partner, invoice address, delivery Authorization and select the option "Display 3 fields on rma: partner,
address" if needed. invoice address, delivery address" if needed.
#. Go to Inventory > Settings > Configuration > Warehouse management > #. Go to Inventory > Configuration > Warehouse management > Warehouses and add
Warehouses and add a default RMA location and RMA picking type for customers a default RMA location and RMA picking type for customers and suppliers RMA
and suppliers RMA picking type. In case the warehouse is configured to picking type. In case the warehouse is configured to use routes, you need to
use routes, you need to create at least one route per rma type with at create at least one route per rma type with at least two push rules (one for
least two push rules (one for inbound another for outbound) it's very inbound another for outbound) it's very important to select the type of
important to select the type of operation supplier if we are moving in the operation supplier if we are moving in the company and customer if we are
company and customer if we are moving out of the company. moving out of the company.
Usage Usage
===== =====
@@ -105,6 +105,7 @@ Contributors
* Jordi Ballester Alomar <jordi.ballester@eficent.com> * Jordi Ballester Alomar <jordi.ballester@eficent.com>
* Aaron Henriquez <ahenriquez@eficent.com> * Aaron Henriquez <ahenriquez@eficent.com>
* Lois Rilo <lois.rilo@eficent.com> * Lois Rilo <lois.rilo@eficent.com>
* Bhavesh Odedra <bodedra@opensourceintegrators.com>
Maintainer Maintainer
---------- ----------

1
rma/__init__.py Normal file → Executable file
View File

@@ -1,5 +1,6 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# © 2017 Eficent Business and IT Consulting Services S.L. # © 2017 Eficent Business and IT Consulting Services S.L.
# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html) # License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html)
from . import models from . import models
from . import wizards from . import wizards

5
rma/__manifest__.py Normal file → Executable file
View File

@@ -4,14 +4,14 @@
{ {
'name': 'RMA (Return Merchandise Authorization)', 'name': 'RMA (Return Merchandise Authorization)',
'version': '10.0.1.0.0', 'version': '11.0.1.0.0',
'license': 'LGPL-3', 'license': 'LGPL-3',
'category': 'RMA', 'category': 'RMA',
'summary': 'Introduces the return merchandise authorization (RMA) process ' 'summary': 'Introduces the return merchandise authorization (RMA) process '
'in odoo', 'in odoo',
'author': "Eficent, Odoo Community Association (OCA)", 'author': "Eficent, Odoo Community Association (OCA)",
'website': 'http://www.github.com/OCA/rma', 'website': 'http://www.github.com/OCA/rma',
'depends': ['stock', 'mail', 'procurement'], 'depends': ['stock', 'mail'],
'demo': ['demo/stock_demo.xml', 'demo': ['demo/stock_demo.xml',
], ],
'data': ['security/rma.xml', 'data': ['security/rma.xml',
@@ -25,7 +25,6 @@
'views/stock_view.xml', 'views/stock_view.xml',
'views/stock_warehouse.xml', 'views/stock_warehouse.xml',
'views/product_view.xml', 'views/product_view.xml',
'views/procurement_view.xml',
'views/res_partner_view.xml', 'views/res_partner_view.xml',
'wizards/rma_make_picking_view.xml', 'wizards/rma_make_picking_view.xml',
'wizards/rma_add_stock_move_view.xml', 'wizards/rma_add_stock_move_view.xml',

0
rma/data/rma_operation.xml Normal file → Executable file
View File

0
rma/data/rma_sequence.xml Normal file → Executable file
View File

0
rma/data/stock_data.xml Normal file → Executable file
View File

0
rma/demo/stock_demo.xml Normal file → Executable file
View File

0
rma/models/__init__.py Normal file → Executable file
View File

22
rma/models/procurement.py Normal file → Executable file
View File

@@ -2,22 +2,28 @@
# © 2017 Eficent Business and IT Consulting Services S.L. # © 2017 Eficent Business and IT Consulting Services S.L.
# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html) # License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html)
from odoo import api, fields, models from odoo import fields, models
class ProcurementOrder(models.Model): class ProcurementRule(models.Model):
_inherit = 'procurement.order' _inherit = 'procurement.rule'
rma_line_id = fields.Many2one( rma_line_id = fields.Many2one(
comodel_name='rma.order.line', string='RMA line', comodel_name='rma.order.line', string='RMA line',
ondelete="set null", ondelete="set null",
) )
@api.model def _get_stock_move_values(self, product_id, product_qty, product_uom,
def _get_stock_move_values(self): location_id, name, origin, values, group_id):
res = super(ProcurementOrder, self)._get_stock_move_values() res = super(ProcurementRule, self)._get_stock_move_values(product_id,
if self.rma_line_id: product_qty,
line = self.rma_line_id product_uom,
location_id,
name, origin,
values,
group_id)
if 'rma_line_id' in values:
line = self.env['rma.order.line'].browse(values.get('rma_line_id'))
res['rma_line_id'] = line.id res['rma_line_id'] = line.id
if line.delivery_address_id: if line.delivery_address_id:
res['partner_id'] = line.delivery_address_id.id res['partner_id'] = line.delivery_address_id.id

0
rma/models/product.py Normal file → Executable file
View File

0
rma/models/product_category.py Normal file → Executable file
View File

0
rma/models/res_partner.py Normal file → Executable file
View File

0
rma/models/rma_operation.py Normal file → Executable file
View File

57
rma/models/rma_order.py Normal file → Executable file
View File

@@ -3,7 +3,7 @@
# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html) # 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 UserError from odoo.exceptions import UserError, ValidationError
from datetime import datetime from datetime import datetime
@@ -20,16 +20,16 @@ class RmaOrder(models.Model):
@api.multi @api.multi
def _compute_in_shipment_count(self): def _compute_in_shipment_count(self):
for rec in self: for rec in self:
rec.in_shipment_count = len(rec.rma_line_ids.mapped( rec.in_shipment_count = len(
'move_ids').filtered( rec.rma_line_ids.mapped('move_ids').filtered(
lambda m: m.location_dest_id.usage == 'internal').mapped( lambda m: m.location_dest_id.usage == 'internal').mapped(
'picking_id')) 'picking_id'))
@api.multi @api.multi
def _compute_out_shipment_count(self): def _compute_out_shipment_count(self):
for rec in self: for rec in self:
rec.out_shipment_count = len(rec.rma_line_ids.mapped( rec.out_shipment_count = len(
'move_ids').filtered( rec.rma_line_ids.mapped('move_ids').filtered(
lambda m: m.location_id.usage == 'internal').mapped( lambda m: m.location_id.usage == 'internal').mapped(
'picking_id')) 'picking_id'))
@@ -111,11 +111,13 @@ class RmaOrder(models.Model):
if move.picking_id.location_id == suppliers: if move.picking_id.location_id == suppliers:
picking_ids.append(move.picking_id.id) picking_ids.append(move.picking_id.id)
shipments = list(set(picking_ids)) shipments = list(set(picking_ids))
if not shipments:
raise ValidationError(_("No shipments found!"))
# choose the view_mode accordingly # choose the view_mode accordingly
if len(shipments) != 1: if shipments:
result['domain'] = "[('id', 'in', " + \ if len(shipments) > 1:
str(shipments) + ")]" result['domain'] = [('id', 'in', shipments)]
elif len(shipments) == 1: else:
res = self.env.ref('stock.view_picking_form', False) res = self.env.ref('stock.view_picking_form', False)
result['views'] = [(res and res.id or False, 'form')] result['views'] = [(res and res.id or False, 'form')]
result['res_id'] = shipments[0] result['res_id'] = shipments[0]
@@ -138,11 +140,12 @@ class RmaOrder(models.Model):
if move.picking_id.location_id != suppliers: if move.picking_id.location_id != suppliers:
picking_ids.append(move.picking_id.id) picking_ids.append(move.picking_id.id)
shipments = list(set(picking_ids)) shipments = list(set(picking_ids))
if not shipments:
raise ValidationError(_("No deliveries found!"))
# choose the view_mode accordingly # choose the view_mode accordingly
if len(shipments) != 1: if len(shipments) > 1:
result['domain'] = "[('id', 'in', " + \ result['domain'] = [('id', 'in', shipments)]
str(shipments) + ")]" else:
elif len(shipments) == 1:
res = self.env.ref('stock.view_picking_form', False) res = self.env.ref('stock.view_picking_form', False)
result['views'] = [(res and res.id or False, 'form')] result['views'] = [(res and res.id or False, 'form')]
result['res_id'] = shipments[0] result['res_id'] = shipments[0]
@@ -159,20 +162,21 @@ class RmaOrder(models.Model):
def action_view_lines(self): def action_view_lines(self):
if self.type == 'customer': if self.type == 'customer':
action = self.env.ref('rma.action_rma_customer_lines') action = self.env.ref('rma.action_rma_customer_lines')
else:
action = self.env.ref('rma.action_rma_supplier_lines')
result = action.read()[0]
lines = self._get_valid_lines()
# choose the view_mode accordingly
if len(lines) != 1:
result['domain'] = [('id', 'in', lines.ids)]
elif len(lines) == 1:
if self.type == 'customer':
res = self.env.ref('rma.view_rma_line_form', False) res = self.env.ref('rma.view_rma_line_form', False)
else: else:
action = self.env.ref('rma.action_rma_supplier_lines')
res = self.env.ref('rma.view_rma_line_supplier_form', False) res = self.env.ref('rma.view_rma_line_supplier_form', False)
result = action.read()[0]
lines = self._get_valid_lines()
if not lines:
raise ValidationError(_("No rma %s lines found!") % self.type)
# choose the view_mode accordingly
if len(lines.ids) > 1:
result['domain'] = [('id', 'in', lines.ids)]
else:
result['views'] = [(res and res.id or False, 'form')] result['views'] = [(res and res.id or False, 'form')]
result['res_id'] = lines.id result['res_id'] = lines.id
result['context'] = {}
return result return result
@api.multi @api.multi
@@ -182,11 +186,12 @@ class RmaOrder(models.Model):
lines = self.rma_line_ids lines = self.rma_line_ids
for line_id in lines: for line_id in lines:
related_lines = [line.id for line in line_id.supplier_rma_line_ids] related_lines = [line.id for line in line_id.supplier_rma_line_ids]
if not related_lines:
raise ValidationError(_("No rma supplier lines found!"))
# choose the view_mode accordingly # choose the view_mode accordingly
if len(related_lines) != 1: if len(related_lines) > 1:
result['domain'] = "[('id', 'in', " + \ result['domain'] = [('id', 'in', related_lines)]
str(related_lines) + ")]" else:
elif len(related_lines) == 1:
res = self.env.ref('rma.view_rma_line_supplier_form', False) res = self.env.ref('rma.view_rma_line_supplier_form', False)
result['views'] = [(res and res.id or False, 'form')] result['views'] = [(res and res.id or False, 'form')]
result['res_id'] = related_lines[0] result['res_id'] = related_lines[0]

137
rma/models/rma_order_line.py Normal file → Executable file
View File

@@ -47,20 +47,16 @@ class RmaOrderLine(models.Model):
@api.multi @api.multi
def _compute_in_shipment_count(self): def _compute_in_shipment_count(self):
for line in self: for line in self:
moves = line.procurement_ids.mapped('move_ids').filtered( line.in_shipment_count = len(self.env['stock.picking'].search(
lambda m: m.location_dest_id.usage == 'internal' and [('origin', '=', line.name),
m.state != 'cancel') ('picking_type_code', '=', 'incoming')]).ids)
pickings = moves.mapped('picking_id')
line.in_shipment_count = len(pickings)
@api.multi @api.multi
def _compute_out_shipment_count(self): def _compute_out_shipment_count(self):
for line in self: for line in self:
moves = line.procurement_ids.mapped('move_ids').filtered( line.out_shipment_count = len(self.env['stock.picking'].search(
lambda m: m.location_dest_id.usage != 'internal' and [('origin', '=', line.name),
m.state != 'cancel') ('picking_type_code', '=', 'outgoing')]).ids)
pickings = moves.mapped('picking_id')
line.out_shipment_count = len(pickings)
@api.multi @api.multi
def _get_rma_move_qty(self, states, direction='in'): def _get_rma_move_qty(self, states, direction='in'):
@@ -147,12 +143,6 @@ class RmaOrderLine(models.Model):
rec.qty_to_supplier_rma = rec.qty_to_receive - qty rec.qty_to_supplier_rma = rec.qty_to_receive - qty
rec.qty_in_supplier_rma = qty rec.qty_in_supplier_rma = qty
@api.multi
def _compute_procurement_count(self):
for rec in self:
rec.procurement_count = len(rec.procurement_ids.filtered(
lambda p: p.state == 'exception'))
delivery_address_id = fields.Many2one( delivery_address_id = fields.Many2one(
comodel_name='res.partner', string='Partner delivery address', comodel_name='res.partner', string='Partner delivery address',
default=_default_delivery_address, default=_default_delivery_address,
@@ -210,7 +200,7 @@ class RmaOrderLine(models.Model):
product_tracking = fields.Selection(related="product_id.tracking") product_tracking = fields.Selection(related="product_id.tracking")
lot_id = fields.Many2one( lot_id = fields.Many2one(
comodel_name="stock.production.lot", string="Lot/Serial Number", comodel_name="stock.production.lot", string="Lot/Serial Number",
readonly=True, states={"new": [("readonly", False)]}, readonly=True, states={"draft": [("readonly", False)]},
) )
product_qty = fields.Float( product_qty = fields.Float(
string='Ordered Qty', copy=False, default=1.0, string='Ordered Qty', copy=False, default=1.0,
@@ -226,9 +216,6 @@ class RmaOrderLine(models.Model):
string='Price Unit', string='Price Unit',
readonly=True, states={'draft': [('readonly', False)]}, readonly=True, states={'draft': [('readonly', False)]},
) )
procurement_count = fields.Integer(compute=_compute_procurement_count,
string='# of Procurements', copy=False,
default=0)
in_shipment_count = fields.Integer(compute=_compute_in_shipment_count, in_shipment_count = fields.Integer(compute=_compute_in_shipment_count,
string='# of Shipments', default=0) string='# of Shipments', default=0)
out_shipment_count = fields.Integer(compute=_compute_out_shipment_count, out_shipment_count = fields.Integer(compute=_compute_out_shipment_count,
@@ -241,10 +228,6 @@ class RmaOrderLine(models.Model):
copy=False, copy=False,
readonly=True, states={'draft': [('readonly', False)]}, readonly=True, states={'draft': [('readonly', False)]},
) )
procurement_ids = fields.One2many('procurement.order', 'rma_line_id',
string='Procurements', readonly=True,
states={'draft': [('readonly', False)]},
copy=False)
currency_id = fields.Many2one('res.currency', string="Currency") currency_id = fields.Many2one('res.currency', string="Currency")
company_id = fields.Many2one( company_id = fields.Many2one(
comodel_name='res.company', string='Company', required=True, comodel_name='res.company', string='Company', required=True,
@@ -413,21 +396,12 @@ class RmaOrderLine(models.Model):
@api.onchange('reference_move_id') @api.onchange('reference_move_id')
def _onchange_reference_move_id(self): def _onchange_reference_move_id(self):
self.ensure_one() self.ensure_one()
sm = self.reference_move_id for move in self.reference_move_id:
if not sm: data = self._prepare_rma_line_from_stock_move(move, lot=False)
return
if sm.lot_ids:
if len(sm.lot_ids) > 1:
raise UserError(_('To manage lots use RMA groups.'))
else:
data = self._prepare_rma_line_from_stock_move(
sm, lot=sm.lot_ids[0])
self.update(data)
else:
data = self._prepare_rma_line_from_stock_move(
sm, lot=False)
self.update(data) self.update(data)
self._remove_other_data_origin('reference_move_id') self._remove_other_data_origin('reference_move_id')
lot_ids = [x.lot_id.id for x in move.move_line_ids if x.lot_id]
return {'domain': {'lot_id': [('id', 'in', lot_ids)]}}
@api.multi @api.multi
@api.constrains('reference_move_id', 'partner_id') @api.constrains('reference_move_id', 'partner_id')
@@ -527,90 +501,45 @@ class RmaOrderLine(models.Model):
elif self.type == 'customer' and self.supplier_to_customer: elif self.type == 'customer' and self.supplier_to_customer:
self.delivery_policy = 'no' self.delivery_policy = 'no'
@api.onchange('product_id')
def _onchange_product_id(self):
self.uom_id = self.product_id.uom_id
if self.lot_id.product_id != self.product_id:
self.lot_id = False
if self.product_id:
return {'domain': {
'lot_id': [('product_id', '=', self.product_id.id)]}}
return {'domain': {'lot_id': []}}
@api.onchange("lot_id") @api.onchange("lot_id")
def _onchange_lot_id(self): def _onchange_lot_id(self):
product = self.lot_id.product_id if self.lot_id and self.reference_move_id:
if product: data = self._prepare_rma_line_from_stock_move(
self.product_id = product self.reference_move_id, lot=self.lot_id)
self.uom_id = product.uom_id self.update(data)
@api.multi @api.multi
def action_view_in_shipments(self): def action_view_in_shipments(self):
action = self.env.ref('stock.action_picking_tree_all') action = self.env.ref('stock.action_picking_tree_all')
result = action.read()[0] result = action.read()[0]
picking_ids = [] picking_ids = self.env['stock.picking'].search(
suppliers = self.env.ref('stock.stock_location_suppliers') [('origin', '=', self.name),
customers = self.env.ref('stock.stock_location_customers') ('picking_type_code', '=', 'incoming')]).ids
for line in self: if not picking_ids:
if line.type == 'customer': raise ValidationError(_("No shipments found!"))
for move in line.move_ids:
if move.picking_id.location_id == customers:
picking_ids.append(move.picking_id.id)
else:
for move in line.move_ids:
if move.picking_id.location_id == suppliers:
picking_ids.append(move.picking_id.id)
shipments = list(set(picking_ids))
# choose the view_mode accordingly # choose the view_mode accordingly
if len(shipments) != 1: if len(picking_ids) > 1:
result['domain'] = "[('id', 'in', " + \ result['domain'] = [('id', 'in', picking_ids)]
str(shipments) + ")]" else:
elif len(shipments) == 1:
res = self.env.ref('stock.view_picking_form', False) res = self.env.ref('stock.view_picking_form', False)
result['views'] = [(res and res.id or False, 'form')] result['views'] = [(res and res.id or False, 'form')]
result['res_id'] = shipments[0] result['res_id'] = picking_ids[0]
return result return result
@api.multi @api.multi
def action_view_out_shipments(self): def action_view_out_shipments(self):
action = self.env.ref('stock.action_picking_tree_all') action = self.env.ref('stock.action_picking_tree_all')
result = action.read()[0] result = action.read()[0]
picking_ids = [] picking_ids = self.env['stock.picking'].search(
suppliers = self.env.ref('stock.stock_location_suppliers') [('origin', '=', self.name),
customers = self.env.ref('stock.stock_location_customers') ('picking_type_code', '=', 'outgoing')]).ids
for line in self: if not picking_ids:
if line.type == 'customer': raise ValidationError(_("No deliveries found!"))
for move in line.move_ids:
if move.picking_id.location_id != customers:
picking_ids.append(move.picking_id.id)
else:
for move in line.move_ids:
if move.picking_id.location_id != suppliers:
picking_ids.append(move.picking_id.id)
shipments = list(set(picking_ids))
# choose the view_mode accordingly # choose the view_mode accordingly
if len(shipments) != 1: if len(picking_ids) > 1:
result['domain'] = "[('id', 'in', " + \ result['domain'] = [('id', 'in', picking_ids)]
str(shipments) + ")]" else:
elif len(shipments) == 1:
res = self.env.ref('stock.view_picking_form', False) res = self.env.ref('stock.view_picking_form', False)
result['views'] = [(res and res.id or False, 'form')] result['views'] = [(res and res.id or False, 'form')]
result['res_id'] = shipments[0] result['res_id'] = picking_ids[0]
return result
@api.multi
def action_view_procurements(self):
action = self.env.ref(
'procurement.procurement_order_action_exceptions')
result = action.read()[0]
procurements = self.procurement_ids.filtered(
lambda p: p.state == 'exception').ids
# choose the view_mode accordingly
if len(procurements) != 1:
result['domain'] = "[('id', 'in', " + \
str(procurements) + ")]"
elif len(procurements) == 1:
res = self.env.ref('procurement.procurement_form_view', False)
result['views'] = [(res and res.id or False, 'form')]
result['res_id'] = procurements[0]
return result return result

9
rma/models/stock.py Normal file → Executable file
View File

@@ -30,9 +30,8 @@ class StockMove(models.Model):
@api.model @api.model
def create(self, vals): def create(self, vals):
if vals.get('procurement_id'): if vals.get('group_id'):
procurement = self.env['procurement.order'].browse( group = self.env['procurement.group'].browse(vals['group_id'])
vals['procurement_id']) if group.rma_line_id:
if procurement.rma_line_id: vals['rma_line_id'] = group.rma_line_id.id
vals['rma_line_id'] = procurement.rma_line_id.id
return super(StockMove, self).create(vals) return super(StockMove, self).create(vals)

0
rma/models/stock_warehouse.py Normal file → Executable file
View File

2
rma/security/ir.model.access.csv Normal file → Executable file
View File

@@ -8,4 +8,4 @@ access_rma_line_manager,rma.order.line,model_rma_order_line,group_rma_manager,1,
access_rma_operation_manager,access_rma_operation,model_rma_operation,group_rma_manager,1,1,1,1 access_rma_operation_manager,access_rma_operation,model_rma_operation,group_rma_manager,1,1,1,1
access_rma_operation_customer_user,access_rma_operation,model_rma_operation,group_rma_customer_user,1,0,0,0 access_rma_operation_customer_user,access_rma_operation,model_rma_operation,group_rma_customer_user,1,0,0,0
access_rma_operation_supplier_user,access_rma_operation,model_rma_operation,group_rma_supplier_user,1,0,0,0 access_rma_operation_supplier_user,access_rma_operation,model_rma_operation,group_rma_supplier_user,1,0,0,0
access_stock_config_settings,access_stock_config_settings,model_stock_config_settings,stock.group_stock_manager,1,1,1,1
1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
8 access_rma_operation_manager access_rma_operation model_rma_operation group_rma_manager 1 1 1 1
9 access_rma_operation_customer_user access_rma_operation model_rma_operation group_rma_customer_user 1 0 0 0
10 access_rma_operation_supplier_user access_rma_operation model_rma_operation group_rma_supplier_user 1 0 0 0
11

0
rma/security/rma.xml Normal file → Executable file
View File

0
rma/tests/__init__.py Normal file → Executable file
View File

0
rma/tests/test_rma.py Normal file → Executable file
View File

0
rma/tests/test_rma_dropship.py Normal file → Executable file
View File

0
rma/tests/test_supplier_rma.py Normal file → Executable file
View File

View File

@@ -1,31 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<data>
<record id="procurement_form_view_0" model="ir.ui.view">
<field name="name">procurement.order.form</field>
<field name="model">procurement.order</field>
<field name="inherit_id"
ref="procurement.procurement_form_view"/>
<field name="arch" type="xml">
<field name="origin" position="after">
<field name="rma_line_id"/>
</field>
</field>
</record>
<record id="procurement_form_view_usage" model="ir.ui.view">
<field name="name">procurement.order.form.stock.inherit</field>
<field name="model">procurement.order</field>
<field name="inherit_id"
ref="stock.view_procurement_form_stock_inherit"/>
<field name="arch" type="xml">
<field name="location_id" position="attributes">
<attribute name="domain">[('usage', '!=', 'view')]</attribute>
</field>
</field>
</record>
</data>
</odoo>

6
rma/views/product_view.xml Normal file → Executable file
View File

@@ -1,13 +1,11 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<odoo> <odoo>
<data>
<record id="product_category_form_view" model="ir.ui.view"> <record id="product_category_form_view" model="ir.ui.view">
<field name="name">product.category.form</field> <field name="name">product.category.form</field>
<field name="model">product.category</field> <field name="model">product.category</field>
<field name="inherit_id" ref="product.product_category_form_view" /> <field name="inherit_id" ref="product.product_category_form_view" />
<field name="arch" type="xml"> <field name="arch" type="xml">
<field name="type" position="after"> <field name="parent_id" position="after">
<group name="rma"> <group name="rma">
<field name="rma_approval_policy" groups="rma.group_rma_customer_user,rma.group_rma_supplier_user"/> <field name="rma_approval_policy" groups="rma.group_rma_customer_user,rma.group_rma_supplier_user"/>
<field name="rma_customer_operation_id" groups="rma.group_rma_customer_user,rma.group_rma_supplier_user"/> <field name="rma_customer_operation_id" groups="rma.group_rma_customer_user,rma.group_rma_supplier_user"/>
@@ -31,6 +29,4 @@
</group> </group>
</field> </field>
</record> </record>
</data>
</odoo> </odoo>

0
rma/views/res_partner_view.xml Normal file → Executable file
View File

3
rma/views/rma_operation_view.xml Normal file → Executable file
View File

@@ -1,6 +1,5 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<odoo> <odoo>
<data>
<record id="rma_operation_tree" model="ir.ui.view"> <record id="rma_operation_tree" model="ir.ui.view">
<field name="name">rma.operation.tree</field> <field name="name">rma.operation.tree</field>
<field name="model">rma.operation</field> <field name="model">rma.operation</field>
@@ -85,6 +84,4 @@
sequence="40" sequence="40"
parent="rma.menu_rma_config" parent="rma.menu_rma_config"
action="action_rma_operation_supplier"/> action="action_rma_operation_supplier"/>
</data>
</odoo> </odoo>

14
rma/views/rma_order_line_view.xml Normal file → Executable file
View File

@@ -83,13 +83,6 @@
<field name="out_shipment_count" widget="statinfo" <field name="out_shipment_count" widget="statinfo"
string="Deliveries"/> string="Deliveries"/>
</button> </button>
<button type="object" name="action_view_procurements"
class="oe_stat_button"
icon="fa-warning"
groups="stock.group_stock_user">
<field name="procurement_count" widget="statinfo"
string="Proc. Exceptions"/>
</button>
</div> </div>
<div class="oe_title" name="title"> <div class="oe_title" name="title">
<h1> <h1>
@@ -242,13 +235,6 @@
icon="fa-pencil-square-o" icon="fa-pencil-square-o"
string="Origin Inv"> string="Origin Inv">
</button> </button>
<button type="object" name="action_view_procurements"
class="oe_stat_button"
icon="fa-warning"
groups="stock.group_stock_user">
<field name="procurement_count" widget="statinfo"
string="Exceptions"/>
</button>
</div> </div>
<div class="oe_title" name="title"> <div class="oe_title" name="title">
<h1> <h1>

4
rma/views/rma_order_view.xml Normal file → Executable file
View File

@@ -1,7 +1,5 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<odoo> <odoo>
<data>
<record id="view_rma_tree" model="ir.ui.view"> <record id="view_rma_tree" model="ir.ui.view">
<field name="name">rma.order.tree</field> <field name="name">rma.order.tree</field>
<field name="model">rma.order</field> <field name="model">rma.order</field>
@@ -294,6 +292,4 @@
groups="rma.group_rma_manager" groups="rma.group_rma_manager"
sequence="30" sequence="30"
parent="stock.menu_stock_config_settings"/> parent="stock.menu_stock_config_settings"/>
</data>
</odoo> </odoo>

18
rma/views/stock_view.xml Normal file → Executable file
View File

@@ -1,13 +1,11 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<odoo> <odoo>
<data>
<record id="view_move_form" model="ir.ui.view"> <record id="view_move_form" model="ir.ui.view">
<field name="name">rma.move.form</field> <field name="name">rma.move.form</field>
<field name="model">stock.move</field> <field name="model">stock.move</field>
<field name="inherit_id" ref="stock.view_move_form" /> <field name="inherit_id" ref="stock.view_move_form" />
<field name="arch" type="xml"> <field name="arch" type="xml">
<group name="destination_grp" position="after"> <group name="origin_grp" position="after">
<group name="rma"> <group name="rma">
<field name="rma_line_id"/> <field name="rma_line_id"/>
</group> </group>
@@ -38,18 +36,4 @@
</xpath> </xpath>
</field> </field>
</record> </record>
<record id="procurement_form_view" model="ir.ui.view">
<field name="name">procurement.order.form.stock.inherit</field>
<field name="model">procurement.order</field>
<field name="inherit_id"
ref="stock.view_procurement_form_stock_inherit"/>
<field name="arch" type="xml">
<field name="location_id" position="attributes">
<attribute name="domain">[('usage', '!=', 'view')]</attribute>
</field>
</field>
</record>
</data>
</odoo> </odoo>

0
rma/views/stock_warehouse.xml Normal file → Executable file
View File

0
rma/wizards/__init__.py Normal file → Executable file
View File

0
rma/wizards/rma_add_stock_move.py Normal file → Executable file
View File

2
rma/wizards/rma_add_stock_move_view.xml Normal file → Executable file
View File

@@ -18,7 +18,7 @@
<field name="product_id"/> <field name="product_id"/>
<field name="product_uom_qty"/> <field name="product_uom_qty"/>
<field name="product_uom" string="Unit of Measure" groups="product.group_uom"/> <field name="product_uom" string="Unit of Measure" groups="product.group_uom"/>
<field name="product_packaging" domain="[('product_tmpl_id','=',product_tmpl_id)]" groups="product.group_stock_packaging"/> <field name="product_packaging" domain="[('product_id','=',product_id)]" groups="product.group_stock_packaging"/>
<field name="picking_id"/> <field name="picking_id"/>
<field name="location_id" groups="stock.group_locations"/> <field name="location_id" groups="stock.group_locations"/>
<field name="location_dest_id" groups="stock.group_locations"/> <field name="location_dest_id" groups="stock.group_locations"/>

68
rma/wizards/rma_make_picking.py Normal file → Executable file
View File

@@ -32,6 +32,7 @@ class RmaMakePicking(models.TransientModel):
lines the supplier field is empty otherwise is the unique line lines the supplier field is empty otherwise is the unique line
supplier. supplier.
""" """
context = self._context.copy()
res = super(RmaMakePicking, self).default_get(fields) res = super(RmaMakePicking, self).default_get(fields)
rma_line_obj = self.env['rma.order.line'] rma_line_obj = self.env['rma.order.line']
rma_line_ids = self.env.context['active_ids'] or [] rma_line_ids = self.env.context['active_ids'] or []
@@ -51,6 +52,7 @@ class RmaMakePicking(models.TransientModel):
for line in lines: for line in lines:
items.append([0, 0, self._prepare_item(line)]) items.append([0, 0, self._prepare_item(line)])
res['item_ids'] = items res['item_ids'] = items
context.update({'items_ids': items})
return res return res
item_ids = fields.One2many( item_ids = fields.One2many(
@@ -67,6 +69,7 @@ class RmaMakePicking(models.TransientModel):
def _get_procurement_group_data(self, item): def _get_procurement_group_data(self, item):
group_data = { group_data = {
'partner_id': item.line_id.partner_id.id,
'name': item.line_id.rma_id.name or item.line_id.name, 'name': item.line_id.rma_id.name or item.line_id.name,
'rma_id': item.line_id.rma_id and item.line_id.rma_id.id or False, 'rma_id': item.line_id.rma_id and item.line_id.rma_id.id or False,
'rma_line_id': item.line_id.id if not item.line_id.rma_id else 'rma_line_id': item.line_id.id if not item.line_id.rma_id else
@@ -116,17 +119,17 @@ class RmaMakePicking(models.TransientModel):
raise ValidationError(_("No warehouse specified")) raise ValidationError(_("No warehouse specified"))
procurement_data = { procurement_data = {
'name': line.rma_id and line.rma_id.name or line.name, 'name': line.rma_id and line.rma_id.name or line.name,
'group_id': group.id, 'group_id': group,
'origin': line.name, 'origin': line.name,
'warehouse_id': warehouse.id, 'warehouse_id': warehouse,
'date_planned': time.strftime(DT_FORMAT), 'date_planned': time.strftime(DT_FORMAT),
'product_id': item.product_id.id, 'product_id': item.product_id,
'product_qty': qty, 'product_qty': qty,
'partner_dest_id': delivery_address_id.id, 'partner_id': delivery_address_id.id,
'product_uom': line.product_id.product_tmpl_id.uom_id.id, 'product_uom': line.product_id.product_tmpl_id.uom_id.id,
'location_id': location.id, 'location_id': location,
'rma_line_id': line.id, 'rma_line_id': line.id,
'route_ids': [(4, route.id)] 'route_ids': route
} }
return procurement_data return procurement_data
@@ -140,18 +143,23 @@ class RmaMakePicking(models.TransientModel):
qty = item.qty_to_receive qty = item.qty_to_receive
else: else:
qty = item.qty_to_deliver qty = item.qty_to_deliver
procurement_data = self._get_procurement_data( values = self._get_procurement_data(item, group, qty, picking_type)
item, group, qty, picking_type)
# create picking # create picking
procurement = self.env['procurement.order'].create(procurement_data) self.env['procurement.group'].run(
procurement.run() item.line_id.product_id,
return procurement.id qty,
item.line_id.product_id.product_tmpl_id.uom_id,
values.get('location_id'),
values.get('origin'),
values.get('origin'),
values
)
return values.get('origin')
@api.multi @api.multi
def _create_picking(self): def _create_picking(self):
"""Method called when the user clicks on create picking""" """Method called when the user clicks on create picking"""
picking_type = self.env.context.get('picking_type') picking_type = self.env.context.get('picking_type')
procurement_list = []
for item in self.item_ids: for item in self.item_ids:
line = item.line_id line = item.line_id
if line.state != 'approved': if line.state != 'approved':
@@ -167,9 +175,7 @@ class RmaMakePicking(models.TransientModel):
raise ValidationError( raise ValidationError(
_('No deliveries needed for this operation')) _('No deliveries needed for this operation'))
procurement = self._create_procurement(item, picking_type) procurement = self._create_procurement(item, picking_type)
procurement_list.append(procurement) return procurement
procurements = self.env['procurement.order'].browse(procurement_list)
return procurements
@api.model @api.model
def _get_action(self, pickings, procurements): def _get_action(self, pickings, procurements):
@@ -179,30 +185,32 @@ class RmaMakePicking(models.TransientModel):
action = self.env.ref( action = self.env.ref(
'procurement.procurement_order_action_exceptions') 'procurement.procurement_order_action_exceptions')
action = action.read()[0] action = action.read()[0]
if procurements:
# choose the view_mode accordingly # choose the view_mode accordingly
procurement_ids = procurements.ids if len(procurements.ids) <= 1:
if len(procurement_ids) != 1:
action['domain'] = "[('id', 'in', " + \
str(procurement_ids) + ")]"
elif len(procurements) == 1:
res = self.env.ref('procurement.procurement_form_view', res = self.env.ref('procurement.procurement_form_view',
False) False)
action['views'] = [(res and res.id or False, 'form')] action['views'] = [(res and res.id or False, 'form')]
action['res_id'] = procurement_ids[0] action['res_id'] = procurements.ids[0]
else:
action['domain'] = [('id', 'in', procurements.ids)]
return action return action
@api.multi @api.multi
def action_create_picking(self): def action_create_picking(self):
procurements = self._create_picking() procurement = self._create_picking()
groups = [] pickings = False
for proc in procurements: action = self.env.ref('stock.do_view_pickings')
if proc.group_id: action = action.read()[0]
groups.append(proc.group_id.id) if procurement:
if len(groups):
pickings = self.env['stock.picking'].search( pickings = self.env['stock.picking'].search(
[('group_id', 'in', groups)]) [('origin', '=', procurement)]).ids
if len(pickings) > 1:
action = self._get_action(pickings, procurements) action['domain'] = [('id', 'in', pickings)]
else:
form = self.env.ref('stock.view_picking_form', False)
action['views'] = [(form and form.id or False, 'form')]
action['res_id'] = pickings[0]
return action return action
@api.multi @api.multi

19
rma/wizards/rma_make_picking_view.xml Normal file → Executable file
View File

@@ -115,23 +115,4 @@
</field> </field>
</record> </record>
<record model="ir.values" id="values_action_rma_picking_in">
<field name="model_id" ref="model_rma_order_line"/>
<field name="name">Create Incoming Shipment</field>
<field name="key2">client_action_multi</field>
<field name="value" eval="'ir.actions.act_window,' + str(ref('action_rma_picking_in'))" />
<field name="key">action</field>
<field name="model">rma.order.line</field>
</record>
<record model="ir.values" id="values_action_rma_picking_out">
<field name="model_id" ref="model_rma_order_line"/>
<field name="name">Create Delivery</field>
<field name="key2">client_action_multi</field>
<field name="value"
eval="'ir.actions.act_window,' + str(ref('action_rma_picking_out'))" />
<field name="key">action</field>
<field name="model">rma.order.line</field>
</record>
</odoo> </odoo>

0
rma/wizards/rma_order_line_make_supplier_rma.py Normal file → Executable file
View File

9
rma/wizards/rma_order_line_make_supplier_rma_view.xml Normal file → Executable file
View File

@@ -2,7 +2,6 @@
<!-- Copyright 2016 Eficent Business and IT Consulting Services S.L. <!-- Copyright 2016 Eficent Business and IT Consulting Services S.L.
License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl-3.0) --> License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl-3.0) -->
<odoo> <odoo>
<data>
<record id="view_rma_order_line_make_supplier_rma" <record id="view_rma_order_line_make_supplier_rma"
model="ir.ui.view"> model="ir.ui.view">
<field name="name">RMA Line Make Supplier RMA</field> <field name="name">RMA Line Make Supplier RMA</field>
@@ -59,7 +58,7 @@
<field name="target">new</field> <field name="target">new</field>
</record> </record>
<record model="ir.values" id="rma_order_line_make_supplier_rma"> <!--record model="ir.values" id="rma_order_line_make_supplier_rma">
<field name="model_id" ref="model_rma_order_line" /> <field name="model_id" ref="model_rma_order_line" />
<field name="name">Create Supplier RMA Group</field> <field name="name">Create Supplier RMA Group</field>
<field name="key2">client_action_multi</field> <field name="key2">client_action_multi</field>
@@ -67,7 +66,7 @@
eval="'ir.actions.act_window,' + str(ref('action_rma_order_line_make_supplier_rma'))" /> eval="'ir.actions.act_window,' + str(ref('action_rma_order_line_make_supplier_rma'))" />
<field name="key">action</field> <field name="key">action</field>
<field name="model">rma.order.line</field> <field name="model">rma.order.line</field>
</record> </record-->
<record id="view_rma_line_supplier_rma_button_form" model="ir.ui.view"> <record id="view_rma_line_supplier_rma_button_form" model="ir.ui.view">
<field name="name">rma.order.line.supplier.rma.form</field> <field name="name">rma.order.line.supplier.rma.form</field>
@@ -82,8 +81,4 @@
</header> </header>
</field> </field>
</record> </record>
</data>
</odoo> </odoo>

2
rma/wizards/stock_config_settings.py Normal file → Executable file
View File

@@ -6,7 +6,7 @@ from odoo import models, fields
class StockConfigSettings(models.TransientModel): class StockConfigSettings(models.TransientModel):
_inherit = 'stock.config.settings' _inherit = 'res.config.settings'
group_rma_delivery_address = fields.Selection([ group_rma_delivery_address = fields.Selection([
(0, "Invoicing and shipping addresses are always the same " (0, "Invoicing and shipping addresses are always the same "

27
rma/wizards/stock_config_settings.xml Normal file → Executable file
View File

@@ -1,17 +1,24 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<odoo> <odoo>
<data> <record id="res_config_settings_view_form" model="ir.ui.view">
<record id="view_stock_config_settings_rma" model="ir.ui.view">
<field name="name">stock.config.settings.rma</field> <field name="name">stock.config.settings.rma</field>
<field name="model">stock.config.settings</field> <field name="model">res.config.settings</field>
<field name="inherit_id" ref="stock.view_stock_config_settings"/> <field name="inherit_id" ref="stock.res_config_settings_view_form"/>
<field name="arch" type="xml"> <field name="arch" type="xml">
<xpath expr="//group[@name='shipping']" position="after"> <div id="production_lot_info" position="after">
<group string="Return Merchandise Authorization"> <h2>Return Merchandise Authorization</h2>
<field name="group_rma_delivery_address" widget="radio"/> <div class="row mt16 o_settings_container">
</group> <div class="col-xs-12 col-md-12 o_setting_box">
</xpath> <div class="o_setting_right_pane">
<div class="content-group">
<div class="mt16">
<field name="group_rma_delivery_address" class="o_light_label" widget="radio"/>
</div>
</div>
</div>
</div>
</div>
</div>
</field> </field>
</record> </record>
</data>
</odoo> </odoo>