mirror of
https://github.com/ForgeFlow/stock-rma.git
synced 2025-01-21 12:57:49 +02:00
[11.0] MIG: RMA module
This commit is contained in:
committed by
ahenriquez
parent
f9c7b28af8
commit
ae0a75499a
21
rma/README.rst
Normal file → Executable file
21
rma/README.rst
Normal file → Executable file
@@ -59,16 +59,16 @@ steps:
|
||||
Other Settings
|
||||
--------------
|
||||
|
||||
#. Go to Inventory > Settings > Return Merchandising Authorization and select
|
||||
the option "Display 3 fields on rma: partner, invoice address, delivery
|
||||
address" if needed.
|
||||
#. Go to Inventory > Settings > Configuration > Warehouse management >
|
||||
Warehouses and add a default RMA location and RMA picking type for customers
|
||||
and suppliers RMA picking type. In case the warehouse is configured to
|
||||
use routes, you need to create at least one route per rma type with at
|
||||
least two push rules (one for inbound another for outbound) it's very
|
||||
important to select the type of operation supplier if we are moving in the
|
||||
company and customer if we are moving out of the company.
|
||||
#. Go to Inventory > Configuration > Settings > Return Merchandising
|
||||
Authorization and select the option "Display 3 fields on rma: partner,
|
||||
invoice address, delivery address" if needed.
|
||||
#. Go to Inventory > Configuration > Warehouse management > Warehouses and add
|
||||
a default RMA location and RMA picking type for customers and suppliers RMA
|
||||
picking type. In case the warehouse is configured to use routes, you need to
|
||||
create at least one route per rma type with at least two push rules (one for
|
||||
inbound another for outbound) it's very important to select the type of
|
||||
operation supplier if we are moving in the company and customer if we are
|
||||
moving out of the company.
|
||||
|
||||
Usage
|
||||
=====
|
||||
@@ -105,6 +105,7 @@ Contributors
|
||||
* Jordi Ballester Alomar <jordi.ballester@eficent.com>
|
||||
* Aaron Henriquez <ahenriquez@eficent.com>
|
||||
* Lois Rilo <lois.rilo@eficent.com>
|
||||
* Bhavesh Odedra <bodedra@opensourceintegrators.com>
|
||||
|
||||
Maintainer
|
||||
----------
|
||||
|
||||
1
rma/__init__.py
Normal file → Executable file
1
rma/__init__.py
Normal file → Executable file
@@ -1,5 +1,6 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# © 2017 Eficent Business and IT Consulting Services S.L.
|
||||
# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html)
|
||||
|
||||
from . import models
|
||||
from . import wizards
|
||||
|
||||
5
rma/__manifest__.py
Normal file → Executable file
5
rma/__manifest__.py
Normal file → Executable file
@@ -4,14 +4,14 @@
|
||||
|
||||
{
|
||||
'name': 'RMA (Return Merchandise Authorization)',
|
||||
'version': '10.0.1.0.0',
|
||||
'version': '11.0.1.0.0',
|
||||
'license': 'LGPL-3',
|
||||
'category': 'RMA',
|
||||
'summary': 'Introduces the return merchandise authorization (RMA) process '
|
||||
'in odoo',
|
||||
'author': "Eficent, Odoo Community Association (OCA)",
|
||||
'website': 'http://www.github.com/OCA/rma',
|
||||
'depends': ['stock', 'mail', 'procurement'],
|
||||
'depends': ['stock', 'mail'],
|
||||
'demo': ['demo/stock_demo.xml',
|
||||
],
|
||||
'data': ['security/rma.xml',
|
||||
@@ -25,7 +25,6 @@
|
||||
'views/stock_view.xml',
|
||||
'views/stock_warehouse.xml',
|
||||
'views/product_view.xml',
|
||||
'views/procurement_view.xml',
|
||||
'views/res_partner_view.xml',
|
||||
'wizards/rma_make_picking_view.xml',
|
||||
'wizards/rma_add_stock_move_view.xml',
|
||||
|
||||
0
rma/data/rma_operation.xml
Normal file → Executable file
0
rma/data/rma_operation.xml
Normal file → Executable file
0
rma/data/rma_sequence.xml
Normal file → Executable file
0
rma/data/rma_sequence.xml
Normal file → Executable file
0
rma/data/stock_data.xml
Normal file → Executable file
0
rma/data/stock_data.xml
Normal file → Executable file
0
rma/demo/stock_demo.xml
Normal file → Executable file
0
rma/demo/stock_demo.xml
Normal file → Executable file
0
rma/models/__init__.py
Normal file → Executable file
0
rma/models/__init__.py
Normal file → Executable file
22
rma/models/procurement.py
Normal file → Executable file
22
rma/models/procurement.py
Normal file → Executable file
@@ -2,22 +2,28 @@
|
||||
# © 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 fields, models
|
||||
|
||||
|
||||
class ProcurementOrder(models.Model):
|
||||
_inherit = 'procurement.order'
|
||||
class ProcurementRule(models.Model):
|
||||
_inherit = 'procurement.rule'
|
||||
|
||||
rma_line_id = fields.Many2one(
|
||||
comodel_name='rma.order.line', string='RMA line',
|
||||
ondelete="set null",
|
||||
)
|
||||
|
||||
@api.model
|
||||
def _get_stock_move_values(self):
|
||||
res = super(ProcurementOrder, self)._get_stock_move_values()
|
||||
if self.rma_line_id:
|
||||
line = self.rma_line_id
|
||||
def _get_stock_move_values(self, product_id, product_qty, product_uom,
|
||||
location_id, name, origin, values, group_id):
|
||||
res = super(ProcurementRule, self)._get_stock_move_values(product_id,
|
||||
product_qty,
|
||||
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
|
||||
if line.delivery_address_id:
|
||||
res['partner_id'] = line.delivery_address_id.id
|
||||
|
||||
0
rma/models/product.py
Normal file → Executable file
0
rma/models/product.py
Normal file → Executable file
0
rma/models/product_category.py
Normal file → Executable file
0
rma/models/product_category.py
Normal file → Executable file
0
rma/models/res_partner.py
Normal file → Executable file
0
rma/models/res_partner.py
Normal file → Executable file
0
rma/models/rma_operation.py
Normal file → Executable file
0
rma/models/rma_operation.py
Normal file → Executable file
57
rma/models/rma_order.py
Normal file → Executable file
57
rma/models/rma_order.py
Normal file → Executable file
@@ -3,7 +3,7 @@
|
||||
# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html)
|
||||
|
||||
from odoo import api, fields, models, _
|
||||
from odoo.exceptions import UserError
|
||||
from odoo.exceptions import UserError, ValidationError
|
||||
from datetime import datetime
|
||||
|
||||
|
||||
@@ -20,16 +20,16 @@ class RmaOrder(models.Model):
|
||||
@api.multi
|
||||
def _compute_in_shipment_count(self):
|
||||
for rec in self:
|
||||
rec.in_shipment_count = len(rec.rma_line_ids.mapped(
|
||||
'move_ids').filtered(
|
||||
rec.in_shipment_count = len(
|
||||
rec.rma_line_ids.mapped('move_ids').filtered(
|
||||
lambda m: m.location_dest_id.usage == 'internal').mapped(
|
||||
'picking_id'))
|
||||
|
||||
@api.multi
|
||||
def _compute_out_shipment_count(self):
|
||||
for rec in self:
|
||||
rec.out_shipment_count = len(rec.rma_line_ids.mapped(
|
||||
'move_ids').filtered(
|
||||
rec.out_shipment_count = len(
|
||||
rec.rma_line_ids.mapped('move_ids').filtered(
|
||||
lambda m: m.location_id.usage == 'internal').mapped(
|
||||
'picking_id'))
|
||||
|
||||
@@ -111,11 +111,13 @@ class RmaOrder(models.Model):
|
||||
if move.picking_id.location_id == suppliers:
|
||||
picking_ids.append(move.picking_id.id)
|
||||
shipments = list(set(picking_ids))
|
||||
if not shipments:
|
||||
raise ValidationError(_("No shipments found!"))
|
||||
# choose the view_mode accordingly
|
||||
if len(shipments) != 1:
|
||||
result['domain'] = "[('id', 'in', " + \
|
||||
str(shipments) + ")]"
|
||||
elif len(shipments) == 1:
|
||||
if shipments:
|
||||
if len(shipments) > 1:
|
||||
result['domain'] = [('id', 'in', shipments)]
|
||||
else:
|
||||
res = self.env.ref('stock.view_picking_form', False)
|
||||
result['views'] = [(res and res.id or False, 'form')]
|
||||
result['res_id'] = shipments[0]
|
||||
@@ -138,11 +140,12 @@ class RmaOrder(models.Model):
|
||||
if move.picking_id.location_id != suppliers:
|
||||
picking_ids.append(move.picking_id.id)
|
||||
shipments = list(set(picking_ids))
|
||||
if not shipments:
|
||||
raise ValidationError(_("No deliveries found!"))
|
||||
# choose the view_mode accordingly
|
||||
if len(shipments) != 1:
|
||||
result['domain'] = "[('id', 'in', " + \
|
||||
str(shipments) + ")]"
|
||||
elif len(shipments) == 1:
|
||||
if len(shipments) > 1:
|
||||
result['domain'] = [('id', 'in', shipments)]
|
||||
else:
|
||||
res = self.env.ref('stock.view_picking_form', False)
|
||||
result['views'] = [(res and res.id or False, 'form')]
|
||||
result['res_id'] = shipments[0]
|
||||
@@ -159,20 +162,21 @@ class RmaOrder(models.Model):
|
||||
def action_view_lines(self):
|
||||
if self.type == 'customer':
|
||||
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)
|
||||
else:
|
||||
action = self.env.ref('rma.action_rma_supplier_lines')
|
||||
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['res_id'] = lines.id
|
||||
result['context'] = {}
|
||||
return result
|
||||
|
||||
@api.multi
|
||||
@@ -182,11 +186,12 @@ class RmaOrder(models.Model):
|
||||
lines = self.rma_line_ids
|
||||
for line_id in lines:
|
||||
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
|
||||
if len(related_lines) != 1:
|
||||
result['domain'] = "[('id', 'in', " + \
|
||||
str(related_lines) + ")]"
|
||||
elif len(related_lines) == 1:
|
||||
if len(related_lines) > 1:
|
||||
result['domain'] = [('id', 'in', related_lines)]
|
||||
else:
|
||||
res = self.env.ref('rma.view_rma_line_supplier_form', False)
|
||||
result['views'] = [(res and res.id or False, 'form')]
|
||||
result['res_id'] = related_lines[0]
|
||||
|
||||
137
rma/models/rma_order_line.py
Normal file → Executable file
137
rma/models/rma_order_line.py
Normal file → Executable file
@@ -47,20 +47,16 @@ class RmaOrderLine(models.Model):
|
||||
@api.multi
|
||||
def _compute_in_shipment_count(self):
|
||||
for line in self:
|
||||
moves = line.procurement_ids.mapped('move_ids').filtered(
|
||||
lambda m: m.location_dest_id.usage == 'internal' and
|
||||
m.state != 'cancel')
|
||||
pickings = moves.mapped('picking_id')
|
||||
line.in_shipment_count = len(pickings)
|
||||
line.in_shipment_count = len(self.env['stock.picking'].search(
|
||||
[('origin', '=', line.name),
|
||||
('picking_type_code', '=', 'incoming')]).ids)
|
||||
|
||||
@api.multi
|
||||
def _compute_out_shipment_count(self):
|
||||
for line in self:
|
||||
moves = line.procurement_ids.mapped('move_ids').filtered(
|
||||
lambda m: m.location_dest_id.usage != 'internal' and
|
||||
m.state != 'cancel')
|
||||
pickings = moves.mapped('picking_id')
|
||||
line.out_shipment_count = len(pickings)
|
||||
line.out_shipment_count = len(self.env['stock.picking'].search(
|
||||
[('origin', '=', line.name),
|
||||
('picking_type_code', '=', 'outgoing')]).ids)
|
||||
|
||||
@api.multi
|
||||
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_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(
|
||||
comodel_name='res.partner', string='Partner delivery address',
|
||||
default=_default_delivery_address,
|
||||
@@ -210,7 +200,7 @@ class RmaOrderLine(models.Model):
|
||||
product_tracking = fields.Selection(related="product_id.tracking")
|
||||
lot_id = fields.Many2one(
|
||||
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(
|
||||
string='Ordered Qty', copy=False, default=1.0,
|
||||
@@ -226,9 +216,6 @@ class RmaOrderLine(models.Model):
|
||||
string='Price Unit',
|
||||
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,
|
||||
string='# of Shipments', default=0)
|
||||
out_shipment_count = fields.Integer(compute=_compute_out_shipment_count,
|
||||
@@ -241,10 +228,6 @@ class RmaOrderLine(models.Model):
|
||||
copy=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")
|
||||
company_id = fields.Many2one(
|
||||
comodel_name='res.company', string='Company', required=True,
|
||||
@@ -413,21 +396,12 @@ class RmaOrderLine(models.Model):
|
||||
@api.onchange('reference_move_id')
|
||||
def _onchange_reference_move_id(self):
|
||||
self.ensure_one()
|
||||
sm = self.reference_move_id
|
||||
if not sm:
|
||||
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)
|
||||
for move in self.reference_move_id:
|
||||
data = self._prepare_rma_line_from_stock_move(move, lot=False)
|
||||
self.update(data)
|
||||
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.constrains('reference_move_id', 'partner_id')
|
||||
@@ -527,90 +501,45 @@ class RmaOrderLine(models.Model):
|
||||
elif self.type == 'customer' and self.supplier_to_customer:
|
||||
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")
|
||||
def _onchange_lot_id(self):
|
||||
product = self.lot_id.product_id
|
||||
if product:
|
||||
self.product_id = product
|
||||
self.uom_id = product.uom_id
|
||||
if self.lot_id and self.reference_move_id:
|
||||
data = self._prepare_rma_line_from_stock_move(
|
||||
self.reference_move_id, lot=self.lot_id)
|
||||
self.update(data)
|
||||
|
||||
@api.multi
|
||||
def action_view_in_shipments(self):
|
||||
action = self.env.ref('stock.action_picking_tree_all')
|
||||
result = action.read()[0]
|
||||
picking_ids = []
|
||||
suppliers = self.env.ref('stock.stock_location_suppliers')
|
||||
customers = self.env.ref('stock.stock_location_customers')
|
||||
for line in self:
|
||||
if line.type == 'customer':
|
||||
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))
|
||||
picking_ids = self.env['stock.picking'].search(
|
||||
[('origin', '=', self.name),
|
||||
('picking_type_code', '=', 'incoming')]).ids
|
||||
if not picking_ids:
|
||||
raise ValidationError(_("No shipments found!"))
|
||||
# choose the view_mode accordingly
|
||||
if len(shipments) != 1:
|
||||
result['domain'] = "[('id', 'in', " + \
|
||||
str(shipments) + ")]"
|
||||
elif len(shipments) == 1:
|
||||
if len(picking_ids) > 1:
|
||||
result['domain'] = [('id', 'in', picking_ids)]
|
||||
else:
|
||||
res = self.env.ref('stock.view_picking_form', False)
|
||||
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_out_shipments(self):
|
||||
action = self.env.ref('stock.action_picking_tree_all')
|
||||
result = action.read()[0]
|
||||
picking_ids = []
|
||||
suppliers = self.env.ref('stock.stock_location_suppliers')
|
||||
customers = self.env.ref('stock.stock_location_customers')
|
||||
for line in self:
|
||||
if line.type == 'customer':
|
||||
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))
|
||||
picking_ids = self.env['stock.picking'].search(
|
||||
[('origin', '=', self.name),
|
||||
('picking_type_code', '=', 'outgoing')]).ids
|
||||
if not picking_ids:
|
||||
raise ValidationError(_("No deliveries found!"))
|
||||
# choose the view_mode accordingly
|
||||
if len(shipments) != 1:
|
||||
result['domain'] = "[('id', 'in', " + \
|
||||
str(shipments) + ")]"
|
||||
elif len(shipments) == 1:
|
||||
if len(picking_ids) > 1:
|
||||
result['domain'] = [('id', 'in', picking_ids)]
|
||||
else:
|
||||
res = self.env.ref('stock.view_picking_form', False)
|
||||
result['views'] = [(res and res.id or False, 'form')]
|
||||
result['res_id'] = shipments[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]
|
||||
result['res_id'] = picking_ids[0]
|
||||
return result
|
||||
|
||||
9
rma/models/stock.py
Normal file → Executable file
9
rma/models/stock.py
Normal file → Executable file
@@ -30,9 +30,8 @@ class StockMove(models.Model):
|
||||
|
||||
@api.model
|
||||
def create(self, vals):
|
||||
if vals.get('procurement_id'):
|
||||
procurement = self.env['procurement.order'].browse(
|
||||
vals['procurement_id'])
|
||||
if procurement.rma_line_id:
|
||||
vals['rma_line_id'] = procurement.rma_line_id.id
|
||||
if vals.get('group_id'):
|
||||
group = self.env['procurement.group'].browse(vals['group_id'])
|
||||
if group.rma_line_id:
|
||||
vals['rma_line_id'] = group.rma_line_id.id
|
||||
return super(StockMove, self).create(vals)
|
||||
|
||||
0
rma/models/stock_warehouse.py
Normal file → Executable file
0
rma/models/stock_warehouse.py
Normal file → Executable file
2
rma/security/ir.model.access.csv
Normal file → Executable file
2
rma/security/ir.model.access.csv
Normal file → Executable 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_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_stock_config_settings,access_stock_config_settings,model_stock_config_settings,stock.group_stock_manager,1,1,1,1
|
||||
|
||||
|
||||
|
0
rma/security/rma.xml
Normal file → Executable file
0
rma/security/rma.xml
Normal file → Executable file
0
rma/tests/__init__.py
Normal file → Executable file
0
rma/tests/__init__.py
Normal file → Executable file
0
rma/tests/test_rma.py
Normal file → Executable file
0
rma/tests/test_rma.py
Normal file → Executable file
0
rma/tests/test_rma_dropship.py
Normal file → Executable file
0
rma/tests/test_rma_dropship.py
Normal file → Executable file
0
rma/tests/test_supplier_rma.py
Normal file → Executable file
0
rma/tests/test_supplier_rma.py
Normal file → Executable 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
6
rma/views/product_view.xml
Normal file → Executable file
@@ -1,13 +1,11 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<data>
|
||||
|
||||
<record id="product_category_form_view" model="ir.ui.view">
|
||||
<field name="name">product.category.form</field>
|
||||
<field name="model">product.category</field>
|
||||
<field name="inherit_id" ref="product.product_category_form_view" />
|
||||
<field name="arch" type="xml">
|
||||
<field name="type" position="after">
|
||||
<field name="parent_id" position="after">
|
||||
<group name="rma">
|
||||
<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"/>
|
||||
@@ -31,6 +29,4 @@
|
||||
</group>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
</data>
|
||||
</odoo>
|
||||
|
||||
0
rma/views/res_partner_view.xml
Normal file → Executable file
0
rma/views/res_partner_view.xml
Normal file → Executable file
3
rma/views/rma_operation_view.xml
Normal file → Executable file
3
rma/views/rma_operation_view.xml
Normal file → Executable file
@@ -1,6 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<data>
|
||||
<record id="rma_operation_tree" model="ir.ui.view">
|
||||
<field name="name">rma.operation.tree</field>
|
||||
<field name="model">rma.operation</field>
|
||||
@@ -85,6 +84,4 @@
|
||||
sequence="40"
|
||||
parent="rma.menu_rma_config"
|
||||
action="action_rma_operation_supplier"/>
|
||||
|
||||
</data>
|
||||
</odoo>
|
||||
|
||||
14
rma/views/rma_order_line_view.xml
Normal file → Executable file
14
rma/views/rma_order_line_view.xml
Normal file → Executable file
@@ -83,13 +83,6 @@
|
||||
<field name="out_shipment_count" widget="statinfo"
|
||||
string="Deliveries"/>
|
||||
</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 class="oe_title" name="title">
|
||||
<h1>
|
||||
@@ -242,13 +235,6 @@
|
||||
icon="fa-pencil-square-o"
|
||||
string="Origin Inv">
|
||||
</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 class="oe_title" name="title">
|
||||
<h1>
|
||||
|
||||
4
rma/views/rma_order_view.xml
Normal file → Executable file
4
rma/views/rma_order_view.xml
Normal file → Executable file
@@ -1,7 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<data>
|
||||
|
||||
<record id="view_rma_tree" model="ir.ui.view">
|
||||
<field name="name">rma.order.tree</field>
|
||||
<field name="model">rma.order</field>
|
||||
@@ -294,6 +292,4 @@
|
||||
groups="rma.group_rma_manager"
|
||||
sequence="30"
|
||||
parent="stock.menu_stock_config_settings"/>
|
||||
|
||||
</data>
|
||||
</odoo>
|
||||
|
||||
18
rma/views/stock_view.xml
Normal file → Executable file
18
rma/views/stock_view.xml
Normal file → Executable file
@@ -1,13 +1,11 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<data>
|
||||
|
||||
<record id="view_move_form" model="ir.ui.view">
|
||||
<field name="name">rma.move.form</field>
|
||||
<field name="model">stock.move</field>
|
||||
<field name="inherit_id" ref="stock.view_move_form" />
|
||||
<field name="arch" type="xml">
|
||||
<group name="destination_grp" position="after">
|
||||
<group name="origin_grp" position="after">
|
||||
<group name="rma">
|
||||
<field name="rma_line_id"/>
|
||||
</group>
|
||||
@@ -38,18 +36,4 @@
|
||||
</xpath>
|
||||
</field>
|
||||
</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>
|
||||
|
||||
0
rma/views/stock_warehouse.xml
Normal file → Executable file
0
rma/views/stock_warehouse.xml
Normal file → Executable file
0
rma/wizards/__init__.py
Normal file → Executable file
0
rma/wizards/__init__.py
Normal file → Executable file
0
rma/wizards/rma_add_stock_move.py
Normal file → Executable file
0
rma/wizards/rma_add_stock_move.py
Normal file → Executable file
2
rma/wizards/rma_add_stock_move_view.xml
Normal file → Executable file
2
rma/wizards/rma_add_stock_move_view.xml
Normal file → Executable file
@@ -18,7 +18,7 @@
|
||||
<field name="product_id"/>
|
||||
<field name="product_uom_qty"/>
|
||||
<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="location_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
68
rma/wizards/rma_make_picking.py
Normal file → Executable file
@@ -32,6 +32,7 @@ class RmaMakePicking(models.TransientModel):
|
||||
lines the supplier field is empty otherwise is the unique line
|
||||
supplier.
|
||||
"""
|
||||
context = self._context.copy()
|
||||
res = super(RmaMakePicking, self).default_get(fields)
|
||||
rma_line_obj = self.env['rma.order.line']
|
||||
rma_line_ids = self.env.context['active_ids'] or []
|
||||
@@ -51,6 +52,7 @@ class RmaMakePicking(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
|
||||
|
||||
item_ids = fields.One2many(
|
||||
@@ -67,6 +69,7 @@ class RmaMakePicking(models.TransientModel):
|
||||
|
||||
def _get_procurement_group_data(self, item):
|
||||
group_data = {
|
||||
'partner_id': item.line_id.partner_id.id,
|
||||
'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_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"))
|
||||
procurement_data = {
|
||||
'name': line.rma_id and line.rma_id.name or line.name,
|
||||
'group_id': group.id,
|
||||
'group_id': group,
|
||||
'origin': line.name,
|
||||
'warehouse_id': warehouse.id,
|
||||
'warehouse_id': warehouse,
|
||||
'date_planned': time.strftime(DT_FORMAT),
|
||||
'product_id': item.product_id.id,
|
||||
'product_id': item.product_id,
|
||||
'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,
|
||||
'location_id': location.id,
|
||||
'location_id': location,
|
||||
'rma_line_id': line.id,
|
||||
'route_ids': [(4, route.id)]
|
||||
'route_ids': route
|
||||
}
|
||||
return procurement_data
|
||||
|
||||
@@ -140,18 +143,23 @@ class RmaMakePicking(models.TransientModel):
|
||||
qty = item.qty_to_receive
|
||||
else:
|
||||
qty = item.qty_to_deliver
|
||||
procurement_data = self._get_procurement_data(
|
||||
item, group, qty, picking_type)
|
||||
values = self._get_procurement_data(item, group, qty, picking_type)
|
||||
# create picking
|
||||
procurement = self.env['procurement.order'].create(procurement_data)
|
||||
procurement.run()
|
||||
return procurement.id
|
||||
self.env['procurement.group'].run(
|
||||
item.line_id.product_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
|
||||
def _create_picking(self):
|
||||
"""Method called when the user clicks on create picking"""
|
||||
picking_type = self.env.context.get('picking_type')
|
||||
procurement_list = []
|
||||
for item in self.item_ids:
|
||||
line = item.line_id
|
||||
if line.state != 'approved':
|
||||
@@ -167,9 +175,7 @@ class RmaMakePicking(models.TransientModel):
|
||||
raise ValidationError(
|
||||
_('No deliveries needed for this operation'))
|
||||
procurement = self._create_procurement(item, picking_type)
|
||||
procurement_list.append(procurement)
|
||||
procurements = self.env['procurement.order'].browse(procurement_list)
|
||||
return procurements
|
||||
return procurement
|
||||
|
||||
@api.model
|
||||
def _get_action(self, pickings, procurements):
|
||||
@@ -179,30 +185,32 @@ class RmaMakePicking(models.TransientModel):
|
||||
action = self.env.ref(
|
||||
'procurement.procurement_order_action_exceptions')
|
||||
action = action.read()[0]
|
||||
if procurements:
|
||||
# choose the view_mode accordingly
|
||||
procurement_ids = procurements.ids
|
||||
if len(procurement_ids) != 1:
|
||||
action['domain'] = "[('id', 'in', " + \
|
||||
str(procurement_ids) + ")]"
|
||||
elif len(procurements) == 1:
|
||||
if len(procurements.ids) <= 1:
|
||||
res = self.env.ref('procurement.procurement_form_view',
|
||||
False)
|
||||
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
|
||||
|
||||
@api.multi
|
||||
def action_create_picking(self):
|
||||
procurements = self._create_picking()
|
||||
groups = []
|
||||
for proc in procurements:
|
||||
if proc.group_id:
|
||||
groups.append(proc.group_id.id)
|
||||
if len(groups):
|
||||
procurement = self._create_picking()
|
||||
pickings = False
|
||||
action = self.env.ref('stock.do_view_pickings')
|
||||
action = action.read()[0]
|
||||
if procurement:
|
||||
pickings = self.env['stock.picking'].search(
|
||||
[('group_id', 'in', groups)])
|
||||
|
||||
action = self._get_action(pickings, procurements)
|
||||
[('origin', '=', procurement)]).ids
|
||||
if len(pickings) > 1:
|
||||
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
|
||||
|
||||
@api.multi
|
||||
|
||||
19
rma/wizards/rma_make_picking_view.xml
Normal file → Executable file
19
rma/wizards/rma_make_picking_view.xml
Normal file → Executable file
@@ -115,23 +115,4 @@
|
||||
</field>
|
||||
</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>
|
||||
|
||||
0
rma/wizards/rma_order_line_make_supplier_rma.py
Normal file → Executable file
0
rma/wizards/rma_order_line_make_supplier_rma.py
Normal file → Executable file
9
rma/wizards/rma_order_line_make_supplier_rma_view.xml
Normal file → Executable file
9
rma/wizards/rma_order_line_make_supplier_rma_view.xml
Normal file → Executable file
@@ -2,7 +2,6 @@
|
||||
<!-- Copyright 2016 Eficent Business and IT Consulting Services S.L.
|
||||
License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl-3.0) -->
|
||||
<odoo>
|
||||
<data>
|
||||
<record id="view_rma_order_line_make_supplier_rma"
|
||||
model="ir.ui.view">
|
||||
<field name="name">RMA Line Make Supplier RMA</field>
|
||||
@@ -59,7 +58,7 @@
|
||||
<field name="target">new</field>
|
||||
</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="name">Create Supplier RMA Group</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'))" />
|
||||
<field name="key">action</field>
|
||||
<field name="model">rma.order.line</field>
|
||||
</record>
|
||||
</record-->
|
||||
|
||||
<record id="view_rma_line_supplier_rma_button_form" model="ir.ui.view">
|
||||
<field name="name">rma.order.line.supplier.rma.form</field>
|
||||
@@ -82,8 +81,4 @@
|
||||
</header>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
|
||||
</data>
|
||||
</odoo>
|
||||
|
||||
|
||||
2
rma/wizards/stock_config_settings.py
Normal file → Executable file
2
rma/wizards/stock_config_settings.py
Normal file → Executable file
@@ -6,7 +6,7 @@ from odoo import models, fields
|
||||
|
||||
|
||||
class StockConfigSettings(models.TransientModel):
|
||||
_inherit = 'stock.config.settings'
|
||||
_inherit = 'res.config.settings'
|
||||
|
||||
group_rma_delivery_address = fields.Selection([
|
||||
(0, "Invoicing and shipping addresses are always the same "
|
||||
|
||||
27
rma/wizards/stock_config_settings.xml
Normal file → Executable file
27
rma/wizards/stock_config_settings.xml
Normal file → Executable file
@@ -1,17 +1,24 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<data>
|
||||
<record id="view_stock_config_settings_rma" model="ir.ui.view">
|
||||
<record id="res_config_settings_view_form" model="ir.ui.view">
|
||||
<field name="name">stock.config.settings.rma</field>
|
||||
<field name="model">stock.config.settings</field>
|
||||
<field name="inherit_id" ref="stock.view_stock_config_settings"/>
|
||||
<field name="model">res.config.settings</field>
|
||||
<field name="inherit_id" ref="stock.res_config_settings_view_form"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//group[@name='shipping']" position="after">
|
||||
<group string="Return Merchandise Authorization">
|
||||
<field name="group_rma_delivery_address" widget="radio"/>
|
||||
</group>
|
||||
</xpath>
|
||||
<div id="production_lot_info" position="after">
|
||||
<h2>Return Merchandise Authorization</h2>
|
||||
<div class="row mt16 o_settings_container">
|
||||
<div class="col-xs-12 col-md-12 o_setting_box">
|
||||
<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>
|
||||
</record>
|
||||
</data>
|
||||
</odoo>
|
||||
|
||||
Reference in New Issue
Block a user