mirror of
https://github.com/ForgeFlow/stock-rma.git
synced 2025-01-21 12:57:49 +02:00
[IMP] default operation in product and product_categ for customer and supplier
[IMP]Separate menus for customer and supplier operations * Add active field to rma operation * Added tests * Fix travis * Fix create supplier rma from customer rma
This commit is contained in:
@@ -3,7 +3,6 @@
|
||||
<record id="rma_operation_customer_replace" model="rma.operation">
|
||||
<field name="name">Replace After Receive</field>
|
||||
<field name="code">RPLC</field>
|
||||
<field name="refund_policy">no</field>
|
||||
<field name="receipt_policy">ordered</field>
|
||||
<field name="delivery_policy">received</field>
|
||||
<field name="type">customer</field>
|
||||
@@ -14,7 +13,6 @@
|
||||
<record id="rma_operation_supplier_replace" model="rma.operation">
|
||||
<field name="name">Replace</field>
|
||||
<field name="code">RPLS</field>
|
||||
<field name="refund_policy">no</field>
|
||||
<field name="receipt_policy">ordered</field>
|
||||
<field name="delivery_policy">ordered</field>
|
||||
<field name="type">supplier</field>
|
||||
@@ -22,30 +20,9 @@
|
||||
<field name="out_route_id" ref="rma.route_rma_supplier"/>
|
||||
</record>
|
||||
|
||||
<record id="rma_operation_customer_refund" model="rma.operation">
|
||||
<field name="name">Refund before receive</field>
|
||||
<field name="code">RFC</field>
|
||||
<field name="refund_policy">ordered</field>
|
||||
<field name="receipt_policy">no</field>
|
||||
<field name="delivery_policy">no</field>
|
||||
<field name="type">customer</field>
|
||||
<field name="in_route_id" ref="rma.route_rma_customer"/>
|
||||
</record>
|
||||
|
||||
<record id="rma_operation_supplier_refund" model="rma.operation">
|
||||
<field name="name">Refund only</field>
|
||||
<field name="code">RFS</field>
|
||||
<field name="refund_policy">ordered</field>
|
||||
<field name="receipt_policy">no</field>
|
||||
<field name="delivery_policy">no</field>
|
||||
<field name="type">supplier</field>
|
||||
<field name="out_route_id" ref="rma.route_rma_supplier"/>
|
||||
</record>
|
||||
|
||||
<record id="rma_operation_ds_replace" model="rma.operation">
|
||||
<field name="name">Replace deliver to vendor</field>
|
||||
<field name="code">DSRPLB</field>
|
||||
<field name="refund_policy">no</field>
|
||||
<field name="receipt_policy">ordered</field>
|
||||
<field name="delivery_policy">no</field>
|
||||
<field name="type">customer</field>
|
||||
@@ -55,7 +32,6 @@
|
||||
<record id="rma_operation_ds_replace_customer" model="rma.operation">
|
||||
<field name="name">Replace receive in vendor</field>
|
||||
<field name="code">DSRPLV</field>
|
||||
<field name="refund_policy">no</field>
|
||||
<field name="receipt_policy">no</field>
|
||||
<field name="delivery_policy">received</field>
|
||||
<field name="type">customer</field>
|
||||
@@ -65,7 +41,6 @@
|
||||
<record id="rma_operation_ds_replace_supplier" model="rma.operation">
|
||||
<field name="name">Replace deliver to customer</field>
|
||||
<field name="code">DSRPC</field>
|
||||
<field name="refund_policy">no</field>
|
||||
<field name="receipt_policy">no</field>
|
||||
<field name="delivery_policy">received</field>
|
||||
<field name="type">supplier</field>
|
||||
|
||||
@@ -8,7 +8,9 @@ from openerp import fields, models
|
||||
class ProductTemplate(models.Model):
|
||||
_inherit = 'product.template'
|
||||
|
||||
rma_operation_id = fields.Many2one(
|
||||
comodel_name="rma.operation", string="RMA Operation")
|
||||
rma_customer_operation_id = fields.Many2one(
|
||||
comodel_name="rma.operation", string="Default RMA Customer Operation")
|
||||
rma_supplier_operation_id = fields.Many2one(
|
||||
comodel_name="rma.operation", string="Default RMA Supplier Operation")
|
||||
rma_approval_policy = fields.Selection(
|
||||
related="categ_id.rma_approval_policy", readonly=True)
|
||||
|
||||
@@ -16,5 +16,7 @@ class ProductCategory(models.Model):
|
||||
"products within categories with this policy.\n"
|
||||
"* Two steps: A RMA containing a product within a category with "
|
||||
"this policy will request the RMA manager approval.")
|
||||
rma_operation_id = fields.Many2one(
|
||||
comodel_name="rma.operation", string="RMA Operation")
|
||||
rma_customer_operation_id = fields.Many2one(
|
||||
comodel_name="rma.operation", string="Default RMA Customer Operation")
|
||||
rma_supplier_operation_id = fields.Many2one(
|
||||
comodel_name="rma.operation", string="Default RMA Supplier Operation")
|
||||
|
||||
@@ -26,10 +26,7 @@ class RmaOperation(models.Model):
|
||||
|
||||
name = fields.Char('Description', required=True)
|
||||
code = fields.Char('Code', required=True)
|
||||
refund_policy = fields.Selection([
|
||||
('no', 'No refund'), ('ordered', 'Based on Ordered Quantities'),
|
||||
('received', 'Based on Received Quantities')], string="Refund Policy",
|
||||
default='no')
|
||||
active = fields.Boolean(string='Active', default=True)
|
||||
receipt_policy = fields.Selection([
|
||||
('no', 'Not required'), ('ordered', 'Based on Ordered Quantities'),
|
||||
('received', 'Based on Delivered Quantities')],
|
||||
@@ -58,6 +55,6 @@ class RmaOperation(models.Model):
|
||||
'stock.location', 'Send To This Company Location')
|
||||
type = fields.Selection([
|
||||
('customer', 'Customer'), ('supplier', 'Supplier')],
|
||||
string="Used in RMA of this type", required=True, default='customer')
|
||||
string="Used in RMA of this type", required=True)
|
||||
rma_line_ids = fields.One2many('rma.order.line', 'operation_id',
|
||||
'RMA lines')
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html)
|
||||
|
||||
from openerp import api, fields, models
|
||||
from datetime import datetime
|
||||
|
||||
|
||||
class RmaOrder(models.Model):
|
||||
@@ -38,8 +39,12 @@ class RmaOrder(models.Model):
|
||||
|
||||
@api.multi
|
||||
def _compute_line_count(self):
|
||||
self.ensure_one()
|
||||
self.line_count = len(self._get_valid_lines())
|
||||
for rec in self:
|
||||
rec.line_count = len(rec._get_valid_lines())
|
||||
|
||||
@api.model
|
||||
def _default_date_rma(self):
|
||||
return datetime.now()
|
||||
|
||||
name = fields.Char(
|
||||
string='Order Number', index=True, readonly=True,
|
||||
@@ -56,7 +61,8 @@ class RmaOrder(models.Model):
|
||||
('approved', 'Approved'),
|
||||
('done', 'Done')], string='State', index=True,
|
||||
default='draft')
|
||||
date_rma = fields.Datetime(string='Order Date', index=True, copy=False)
|
||||
date_rma = fields.Datetime(string='Order Date', index=True,
|
||||
default=_default_date_rma)
|
||||
partner_id = fields.Many2one('res.partner', string='Partner',
|
||||
required=True, readonly=True,
|
||||
states={'draft': [('readonly', False)]})
|
||||
@@ -72,11 +78,9 @@ class RmaOrder(models.Model):
|
||||
out_shipment_count = fields.Integer(compute=_compute_out_shipment_count,
|
||||
string='# of Outgoing Shipments')
|
||||
line_count = fields.Integer(compute=_compute_line_count,
|
||||
string='# of Outgoing Shipments',
|
||||
copy=False)
|
||||
string='# of Outgoing Shipments')
|
||||
supplier_line_count = fields.Integer(compute=_compute_supplier_line_count,
|
||||
string='# of Outgoing Shipments',
|
||||
copy=False)
|
||||
string='# of Outgoing Shipments')
|
||||
company_id = fields.Many2one('res.company', string='Company',
|
||||
required=True, default=lambda self:
|
||||
self.env.user.company_id)
|
||||
@@ -175,8 +179,8 @@ class RmaOrder(models.Model):
|
||||
def _get_valid_lines(self):
|
||||
""":return: A recordset of rma lines.
|
||||
"""
|
||||
self.ensure_one()
|
||||
return self.rma_line_ids
|
||||
for rec in self:
|
||||
return rec.rma_line_ids
|
||||
|
||||
@api.multi
|
||||
def action_view_lines(self):
|
||||
@@ -205,7 +209,7 @@ class RmaOrder(models.Model):
|
||||
action = self.env.ref('rma.action_rma_supplier_lines')
|
||||
result = action.read()[0]
|
||||
lines = self.rma_line_ids
|
||||
related_lines = [line.id for line in lines.children_ids]
|
||||
related_lines = [line.id for line in lines.supplier_rma_line_ids]
|
||||
# choose the view_mode accordingly
|
||||
if len(related_lines) != 1:
|
||||
result['domain'] = "[('id', 'in', " + \
|
||||
|
||||
@@ -308,8 +308,12 @@ class RmaOrderLine(models.Model):
|
||||
self.product_qty = 1
|
||||
self.uom_id = self.product_id.uom_id.id
|
||||
self.price_unit = self.product_id.standard_price
|
||||
self.operation_id = self.product_id.rma_operation_id or \
|
||||
self.product_id.categ_id.rma_operation_id
|
||||
if self.type == 'customer':
|
||||
self.operation_id = self.product_id.rma_customer_operation_id or \
|
||||
self.product_id.categ_id.rma_customer_operation_id
|
||||
else:
|
||||
self.operation_id = self.product_id.rma_supplier_operation_id or \
|
||||
self.product_id.categ_id.rma_supplier_operation_id
|
||||
return result
|
||||
|
||||
@api.onchange('operation_id')
|
||||
|
||||
@@ -2,3 +2,5 @@
|
||||
# © 2017 Eficent Business and IT Consulting Services S.L.
|
||||
# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html)
|
||||
from . import test_rma
|
||||
from . import test_supplier_rma
|
||||
from . import test_rma_dropship
|
||||
|
||||
@@ -13,61 +13,95 @@ class TestRma(common.TransactionCase):
|
||||
super(TestRma, self).setUp()
|
||||
|
||||
self.rma_make_picking = self.env['rma_make_picking.wizard']
|
||||
self.make_supplier_rma = self.env["rma.order.line.make.supplier.rma"]
|
||||
self.rma_add_stock_move = self.env['rma_add_stock_move']
|
||||
self.stockpicking = self.env['stock.picking']
|
||||
self.rma = self.env['rma.order']
|
||||
self.rma_line = self.env['rma.order.line']
|
||||
self.rma_op = self.env['rma.operation']
|
||||
self.rma_op_id = self.env.ref('rma.rma_operation_customer_replace')
|
||||
self.rma_cust_replace_op_id = self.env.ref(
|
||||
'rma.rma_operation_customer_replace')
|
||||
self.rma_sup_replace_op_id = self.env.ref(
|
||||
'rma.rma_operation_supplier_replace')
|
||||
self.product_id = self.env.ref('product.product_product_4')
|
||||
self.product_1 = self.env.ref('product.product_product_25')
|
||||
self.product_2 = self.env.ref('product.product_product_30')
|
||||
self.product_3 = self.env.ref('product.product_product_33')
|
||||
self.uom_unit = self.env.ref('product.product_uom_unit')
|
||||
# assign an operation
|
||||
self.product_1.write({'rma_operation_id': self.rma_op_id.id})
|
||||
self.product_2.write({'rma_operation_id': self.rma_op_id.id})
|
||||
self.product_3.write({'rma_operation_id': self.rma_op_id.id})
|
||||
self.product_1.write(
|
||||
{'rma_customer_operation_id': self.rma_cust_replace_op_id.id,
|
||||
'rma_supplier_operation_id': self.rma_sup_replace_op_id.id})
|
||||
self.product_2.write(
|
||||
{'rma_customer_operation_id': self.rma_cust_replace_op_id.id,
|
||||
'rma_supplier_operation_id': self.rma_sup_replace_op_id.id})
|
||||
self.product_3.write(
|
||||
{'rma_customer_operation_id': self.rma_cust_replace_op_id.id,
|
||||
'rma_supplier_operation_id': self.rma_sup_replace_op_id.id})
|
||||
self.partner_id = self.env.ref('base.res_partner_12')
|
||||
self.stock_location = self.env.ref('stock.stock_location_stock')
|
||||
self.stock_rma_location = self.env.ref('rma.location_rma')
|
||||
self.customer_location = self.env.ref(
|
||||
'stock.stock_location_customers')
|
||||
self.supplier_location = self.env.ref(
|
||||
'stock.stock_location_suppliers')
|
||||
self.product_uom_id = self.env.ref('product.product_uom_unit')
|
||||
self.product_uom_id = self.env.ref('product.product_uom_unit')
|
||||
moves = []
|
||||
products2move = [(self.product_1, 3), (self.product_2, 5),
|
||||
(self.product_3, 2)]
|
||||
self.rma_customer_id = self._create_rma_from_move(
|
||||
products2move, 'customer', self.env.ref('base.res_partner_2'),
|
||||
dropship=False)
|
||||
|
||||
def _create_rma_from_move(self, products2move, type, partner, dropship,
|
||||
supplier_address_id=None):
|
||||
moves = []
|
||||
if type == 'customer':
|
||||
for item in products2move:
|
||||
move_values = self._prepare_move(item[0], item[1])
|
||||
move_values = self._prepare_move(
|
||||
item[0], item[1], self.stock_location,
|
||||
self.customer_location)
|
||||
moves.append(self.env['stock.move'].create(move_values))
|
||||
else:
|
||||
for item in products2move:
|
||||
move_values = self._prepare_move(
|
||||
item[0], item[1], self.supplier_location,
|
||||
self.stock_rma_location)
|
||||
moves.append(self.env['stock.move'].create(move_values))
|
||||
# Create the RMA from the stock_move
|
||||
self.rma_id = self.rma.create(
|
||||
rma_id = self.rma.create(
|
||||
{
|
||||
'reference': '0001',
|
||||
'type': 'customer',
|
||||
'partner_id': self.env.ref('base.res_partner_2').id
|
||||
'type': type,
|
||||
'partner_id': partner.id,
|
||||
'company_id': self.env.ref('base.main_company').id
|
||||
})
|
||||
for move in moves:
|
||||
data = self.rma_add_stock_move.with_context(
|
||||
{'stock_move_id': move.id}
|
||||
)._prepare_rma_line_from_stock_move(move)
|
||||
operation = self.rma_op.browse(data['operation_id'])
|
||||
data.update(
|
||||
rma_id=self.rma_id.id,
|
||||
receipt_policy=operation.receipt_policy,
|
||||
delivery_policy=operation.delivery_policy,
|
||||
in_warehouse_id=operation.in_warehouse_id.id,
|
||||
out_warehouse_id=operation.out_warehouse_id.id,
|
||||
location_id=self.stock_rma_location.id,
|
||||
in_route_id=operation.in_route_id.id,
|
||||
out_route_id=operation.out_route_id.id)
|
||||
if type == 'customer':
|
||||
wizard = self.rma_add_stock_move.with_context(
|
||||
{'stock_move_id': move.id, 'customer': True,
|
||||
'active_ids': rma_id.id,
|
||||
'active_model': 'rma.order',
|
||||
}
|
||||
).create({})
|
||||
data = wizard._prepare_rma_line_from_stock_move(move)
|
||||
else:
|
||||
wizard = self.rma_add_stock_move.with_context(
|
||||
{'stock_move_id': move.id, 'supplier': True,
|
||||
'active_ids': rma_id.id,
|
||||
'active_model': 'rma.order',
|
||||
}
|
||||
).create({})
|
||||
data = wizard._prepare_rma_line_from_stock_move(move)
|
||||
if dropship:
|
||||
data.update(customer_to_supplier=dropship,
|
||||
supplier_address_id=supplier_address_id.id)
|
||||
self.rma_line.create(data)
|
||||
# approve the RMA
|
||||
self.rma_id.action_rma_to_approve()
|
||||
self.rma_id.action_rma_approve()
|
||||
rma_id.action_rma_to_approve()
|
||||
rma_id.action_rma_approve()
|
||||
return rma_id
|
||||
|
||||
def _prepare_move(self, product, qty):
|
||||
def _prepare_move(self, product, qty, src, dest):
|
||||
res = {
|
||||
'product_id': product.id,
|
||||
'name': product.partner_ref,
|
||||
@@ -75,14 +109,14 @@ class TestRma(common.TransactionCase):
|
||||
'product_uom': self.product_uom_id.id or product.uom_id.id,
|
||||
'product_uom_qty': qty,
|
||||
'origin': 'Test RMA',
|
||||
'location_id': self.stock_location.id,
|
||||
'location_dest_id': self.customer_location.id,
|
||||
'location_id': src.id,
|
||||
'location_dest_id': dest.id,
|
||||
}
|
||||
return res
|
||||
|
||||
def test_00_receive_items(self):
|
||||
def test_customer_rma(self):
|
||||
wizard = self.rma_make_picking.with_context({
|
||||
'active_ids': self.rma_id.rma_line_ids.ids,
|
||||
'active_ids': self.rma_customer_id.rma_line_ids.ids,
|
||||
'active_model': 'rma.order.line',
|
||||
'picking_type': 'incoming',
|
||||
'active_id': 1
|
||||
@@ -97,7 +131,7 @@ class TestRma(common.TransactionCase):
|
||||
moves = picking.move_lines
|
||||
self.assertEquals(len(moves), 3,
|
||||
"Incorrect number of moves created")
|
||||
for line in self.rma_id.rma_line_ids:
|
||||
for line in self.rma_customer_id.rma_line_ids:
|
||||
# common qtys for all products
|
||||
self.assertEquals(line.qty_received, 0,
|
||||
"Wrong qty received")
|
||||
@@ -125,7 +159,7 @@ class TestRma(common.TransactionCase):
|
||||
"Wrong qty incoming")
|
||||
picking.action_assign()
|
||||
picking.do_transfer()
|
||||
for line in self.rma_id.rma_line_ids:
|
||||
for line in self.rma_customer_id.rma_line_ids:
|
||||
self.assertEquals(line.qty_to_receive, 0,
|
||||
"Wrong qty to_receive")
|
||||
self.assertEquals(line.qty_incoming, 0,
|
||||
@@ -152,7 +186,7 @@ class TestRma(common.TransactionCase):
|
||||
|
||||
wizard = self.rma_make_picking.with_context({
|
||||
'active_id': 1,
|
||||
'active_ids': self.rma_id.rma_line_ids.ids,
|
||||
'active_ids': self.rma_customer_id.rma_line_ids.ids,
|
||||
'active_model': 'rma.order.line',
|
||||
'picking_type': 'outgoing',
|
||||
}).create({})
|
||||
@@ -167,7 +201,7 @@ class TestRma(common.TransactionCase):
|
||||
moves = picking_out.move_lines
|
||||
self.assertEquals(len(moves), 3,
|
||||
"Incorrect number of moves created")
|
||||
for line in self.rma_id.rma_line_ids:
|
||||
for line in self.rma_customer_id.rma_line_ids:
|
||||
self.assertEquals(line.qty_to_receive, 0,
|
||||
"Wrong qty to receive")
|
||||
self.assertEquals(line.qty_incoming, 0,
|
||||
@@ -197,7 +231,7 @@ class TestRma(common.TransactionCase):
|
||||
"Wrong qty outgoing")
|
||||
picking_out.action_assign()
|
||||
picking_out.do_transfer()
|
||||
for line in self.rma_id.rma_line_ids:
|
||||
for line in self.rma_customer_id.rma_line_ids:
|
||||
self.assertEquals(line.qty_to_receive, 0,
|
||||
"Wrong qty to receive")
|
||||
self.assertEquals(line.qty_incoming, 0,
|
||||
@@ -221,4 +255,6 @@ class TestRma(common.TransactionCase):
|
||||
"Wrong qty received")
|
||||
self.assertEquals(line.qty_delivered, 2,
|
||||
"Wrong qty delivered")
|
||||
self.rma_id.action_rma_done()
|
||||
self.rma_customer_id.action_rma_done()
|
||||
self.assertEquals(self.rma_customer_id.state, 'done',
|
||||
"Wrong State")
|
||||
|
||||
91
rma/tests/test_rma_dropship.py
Normal file
91
rma/tests/test_rma_dropship.py
Normal file
@@ -0,0 +1,91 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# © 2017 Eficent Business and IT Consulting Services S.L.
|
||||
# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html)
|
||||
|
||||
from openerp.addons.rma.tests import test_rma
|
||||
|
||||
|
||||
class TestRmaDropship(test_rma.TestRma):
|
||||
|
||||
def setUp(self):
|
||||
super(TestRmaDropship, self).setUp()
|
||||
products2move = [(self.product_1, 3), (self.product_2, 5),
|
||||
(self.product_3, 2)]
|
||||
self.rma_droship_id = self._create_rma_from_move(
|
||||
products2move, 'customer', self.env.ref('base.res_partner_2'),
|
||||
dropship=True,
|
||||
supplier_address_id=self.env.ref('base.res_partner_3'))
|
||||
|
||||
def test_dropship(self):
|
||||
wizard = self.make_supplier_rma.with_context({
|
||||
'active_ids': self.rma_droship_id.rma_line_ids.ids,
|
||||
'active_model': 'rma.order.line',
|
||||
'active_id': 1
|
||||
}).create({})
|
||||
res = wizard.make_supplier_rma()
|
||||
supplier_rma = self.rma.browse(res['res_id'])
|
||||
supplier_rma.action_rma_to_approve()
|
||||
supplier_rma.action_rma_approve()
|
||||
wizard = self.rma_make_picking.with_context({
|
||||
'active_id': 1,
|
||||
'active_ids': supplier_rma.rma_line_ids.ids,
|
||||
'active_model': 'rma.order.line',
|
||||
'picking_type': 'incoming',
|
||||
}).create({})
|
||||
procurements = wizard._create_picking()
|
||||
group_ids = set([proc.group_id.id for proc in procurements if
|
||||
proc.group_id])
|
||||
domain = [('group_id', 'in', list(group_ids))]
|
||||
picking = self.stockpicking.search(domain)
|
||||
self.assertEquals(len(picking), 1,
|
||||
"Incorrect number of pickings created")
|
||||
moves = picking.move_lines
|
||||
self.assertEquals(len(moves), 3,
|
||||
"Incorrect number of moves created")
|
||||
for line in supplier_rma.rma_line_ids:
|
||||
# common qtys for all products
|
||||
self.assertEquals(line.qty_received, 0,
|
||||
"Wrong qty received")
|
||||
self.assertEquals(line.qty_outgoing, 0,
|
||||
"Wrong qty incoming")
|
||||
self.assertEquals(line.qty_delivered, 0,
|
||||
"Wrong qty delivered")
|
||||
# product specific
|
||||
if line.product_id == self.product_1:
|
||||
self.assertEquals(line.qty_to_receive, 3,
|
||||
"Wrong qty to receive")
|
||||
self.assertEquals(line.qty_to_deliver, 3,
|
||||
"Wrong qty to deliver")
|
||||
self.assertEquals(line.qty_incoming, 3,
|
||||
"Wrong qty outgoing")
|
||||
if line.product_id == self.product_2:
|
||||
self.assertEquals(line.qty_to_receive, 5,
|
||||
"Wrong qty to receive")
|
||||
self.assertEquals(line.qty_to_deliver, 5,
|
||||
"Wrong qty to deliver")
|
||||
self.assertEquals(line.qty_incoming, 5,
|
||||
"Wrong qty outgoing")
|
||||
if line.product_id == self.product_3:
|
||||
self.assertEquals(line.qty_to_receive, 2,
|
||||
"Wrong qty to receive")
|
||||
self.assertEquals(line.qty_to_deliver, 2,
|
||||
"Wrong qty to deliver")
|
||||
self.assertEquals(line.qty_incoming, 2,
|
||||
"Wrong qty outgoing")
|
||||
|
||||
for line in self.rma_droship_id.rma_line_ids:
|
||||
if line.product_id == self.product_1:
|
||||
self.assertEquals(line.qty_to_supplier_rma, 0,
|
||||
"Wrong qty to supplier rma")
|
||||
self.assertEquals(line.qty_in_supplier_rma, 3,
|
||||
"Wrong qty in supplier rma")
|
||||
if line.product_id == self.product_2:
|
||||
self.assertEquals(line.qty_to_supplier_rma, 0,
|
||||
"Wrong qty to supplier rma")
|
||||
self.assertEquals(line.qty_in_supplier_rma, 5,
|
||||
"Wrong qty in supplier rma")
|
||||
if line.product_id == self.product_3:
|
||||
self.assertEquals(line.qty_to_supplier_rma, 0,
|
||||
"Wrong qty to supplier rma")
|
||||
self.assertEquals(line.qty_in_supplier_rma, 2,
|
||||
"Wrong qty in supplier rma")
|
||||
165
rma/tests/test_supplier_rma.py
Normal file
165
rma/tests/test_supplier_rma.py
Normal file
@@ -0,0 +1,165 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# © 2017 Eficent Business and IT Consulting Services S.L.
|
||||
# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html)
|
||||
|
||||
from openerp.addons.rma.tests import test_rma
|
||||
|
||||
|
||||
class TestSupplierRma(test_rma.TestRma):
|
||||
|
||||
def setUp(self):
|
||||
super(TestSupplierRma, self).setUp()
|
||||
products2move = [(self.product_1, 3), (self.product_2, 5),
|
||||
(self.product_3, 2)]
|
||||
self.rma_supplier_id = self._create_rma_from_move(
|
||||
products2move, 'supplier', self.env.ref('base.res_partner_1'),
|
||||
dropship=False)
|
||||
|
||||
def test_supplier_rma(self):
|
||||
wizard = self.rma_make_picking.with_context({
|
||||
'active_ids': self.rma_supplier_id.rma_line_ids.ids,
|
||||
'active_model': 'rma.order.line',
|
||||
'picking_type': 'outgoing',
|
||||
'active_id': 1
|
||||
}).create({})
|
||||
procurements = wizard._create_picking()
|
||||
group_ids = set([proc.group_id.id for proc in procurements if
|
||||
proc.group_id])
|
||||
domain = [('group_id', 'in', list(group_ids))]
|
||||
picking = self.stockpicking.search(domain)
|
||||
self.assertEquals(len(picking), 1,
|
||||
"Incorrect number of pickings created")
|
||||
moves = picking.move_lines
|
||||
self.assertEquals(len(moves), 3,
|
||||
"Incorrect number of moves created")
|
||||
for line in self.rma_supplier_id.rma_line_ids:
|
||||
# common qtys for all products
|
||||
self.assertEquals(line.qty_received, 0,
|
||||
"Wrong qty received")
|
||||
self.assertEquals(line.qty_incoming, 0,
|
||||
"Wrong qty incoming")
|
||||
self.assertEquals(line.qty_delivered, 0,
|
||||
"Wrong qty delivered")
|
||||
# product specific
|
||||
if line.product_id == self.product_1:
|
||||
self.assertEquals(line.qty_to_receive, 3,
|
||||
"Wrong qty to receive")
|
||||
self.assertEquals(line.qty_to_deliver, 3,
|
||||
"Wrong qty to deliver")
|
||||
self.assertEquals(line.qty_outgoing, 3,
|
||||
"Wrong qty outgoing")
|
||||
if line.product_id == self.product_2:
|
||||
self.assertEquals(line.qty_to_receive, 5,
|
||||
"Wrong qty to receive")
|
||||
self.assertEquals(line.qty_to_deliver, 5,
|
||||
"Wrong qty to deliver")
|
||||
self.assertEquals(line.qty_outgoing, 5,
|
||||
"Wrong qty outgoing")
|
||||
if line.product_id == self.product_3:
|
||||
self.assertEquals(line.qty_to_receive, 2,
|
||||
"Wrong qty to receive")
|
||||
self.assertEquals(line.qty_to_deliver, 2,
|
||||
"Wrong qty to deliver")
|
||||
self.assertEquals(line.qty_outgoing, 2,
|
||||
"Wrong qty outgoing")
|
||||
|
||||
picking.action_assign()
|
||||
picking.do_transfer()
|
||||
for line in self.rma_supplier_id.rma_line_ids:
|
||||
self.assertEquals(line.qty_to_deliver, 0,
|
||||
"Wrong qty to deliver")
|
||||
self.assertEquals(line.qty_incoming, 0,
|
||||
"Wrong qty incoming")
|
||||
self.assertEquals(line.qty_outgoing, 0,
|
||||
"Wrong qty outgoing")
|
||||
self.assertEquals(line.qty_received, 0,
|
||||
"Wrong qty received")
|
||||
if line.product_id == self.product_1:
|
||||
self.assertEquals(line.qty_delivered, 3,
|
||||
"Wrong qty delivered")
|
||||
self.assertEquals(line.qty_to_receive, 3,
|
||||
"Wrong qty to receive")
|
||||
if line.product_id == self.product_2:
|
||||
self.assertEquals(line.qty_delivered, 5,
|
||||
"Wrong qty delivered")
|
||||
self.assertEquals(line.qty_to_receive, 5,
|
||||
"Wrong qty to receive")
|
||||
if line.product_id == self.product_3:
|
||||
self.assertEquals(line.qty_delivered, 2,
|
||||
"Wrong qty delivered")
|
||||
self.assertEquals(line.qty_to_receive, 2,
|
||||
"Wrong qty to receive")
|
||||
wizard = self.rma_make_picking.with_context({
|
||||
'active_id': 1,
|
||||
'active_ids': self.rma_supplier_id.rma_line_ids.ids,
|
||||
'active_model': 'rma.order.line',
|
||||
'picking_type': 'incoming',
|
||||
}).create({})
|
||||
procurements = wizard._create_picking()
|
||||
group_ids = set([proc.group_id.id for proc in procurements if
|
||||
proc.group_id])
|
||||
domain = [('group_id', 'in', list(group_ids))]
|
||||
pickings = self.stockpicking.search(domain)
|
||||
self.assertEquals(len(pickings), 2,
|
||||
"Incorrect number of pickings created")
|
||||
picking_out = pickings[1]
|
||||
moves = picking_out.move_lines
|
||||
self.assertEquals(len(moves), 3,
|
||||
"Incorrect number of moves created")
|
||||
for line in self.rma_supplier_id.rma_line_ids:
|
||||
self.assertEquals(line.qty_to_deliver, 0,
|
||||
"Wrong qty to deliver")
|
||||
self.assertEquals(line.qty_outgoing, 0,
|
||||
"Wrong qty outgoing")
|
||||
self.assertEquals(line.qty_received, 0,
|
||||
"Wrong qty received")
|
||||
if line.product_id == self.product_1:
|
||||
self.assertEquals(line.qty_to_receive, 3,
|
||||
"Wrong qty to receive")
|
||||
self.assertEquals(line.qty_incoming, 3,
|
||||
"Wrong qty incoming")
|
||||
self.assertEquals(line.qty_delivered, 3,
|
||||
"Wrong qty delivered")
|
||||
if line.product_id == self.product_2:
|
||||
self.assertEquals(line.qty_to_receive, 5,
|
||||
"Wrong qty to receive")
|
||||
self.assertEquals(line.qty_incoming, 5,
|
||||
"Wrong qty incoming")
|
||||
self.assertEquals(line.qty_delivered, 5,
|
||||
"Wrong qty delivered")
|
||||
if line.product_id == self.product_3:
|
||||
self.assertEquals(line.qty_to_receive, 2,
|
||||
"Wrong qty to receive")
|
||||
self.assertEquals(line.qty_incoming, 2,
|
||||
"Wrong qty incoming")
|
||||
self.assertEquals(line.qty_delivered, 2,
|
||||
"Wrong qty delivered")
|
||||
picking_out.action_assign()
|
||||
picking_out.do_transfer()
|
||||
for line in self.rma_supplier_id.rma_line_ids:
|
||||
self.assertEquals(line.qty_to_receive, 0,
|
||||
"Wrong qty to receive")
|
||||
self.assertEquals(line.qty_incoming, 0,
|
||||
"Wrong qty incoming")
|
||||
self.assertEquals(line.qty_to_deliver, 0,
|
||||
"Wrong qty to deliver")
|
||||
self.assertEquals(line.qty_outgoing, 0,
|
||||
"Wrong qty outgoing")
|
||||
if line.product_id == self.product_1:
|
||||
self.assertEquals(line.qty_received, 3,
|
||||
"Wrong qty received")
|
||||
self.assertEquals(line.qty_delivered, 3,
|
||||
"Wrong qty delivered")
|
||||
if line.product_id == self.product_2:
|
||||
self.assertEquals(line.qty_received, 5,
|
||||
"Wrong qty received")
|
||||
self.assertEquals(line.qty_delivered, 5,
|
||||
"Wrong qty delivered")
|
||||
if line.product_id == self.product_3:
|
||||
self.assertEquals(line.qty_received, 2,
|
||||
"Wrong qty received")
|
||||
self.assertEquals(line.qty_delivered, 2,
|
||||
"Wrong qty delivered")
|
||||
self.rma_supplier_id.action_rma_done()
|
||||
self.assertEquals(self.rma_supplier_id.state, 'done',
|
||||
"Wrong State")
|
||||
@@ -8,8 +8,11 @@
|
||||
<field name="inherit_id" ref="product.product_category_form_view" />
|
||||
<field name="arch" type="xml">
|
||||
<field name="type" position="after">
|
||||
<field name="rma_approval_policy"/>
|
||||
<field name="rma_operation_id" groups="rma.group_rma_customer_user,rma.group_rma_supplier_user"/>
|
||||
<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"/>
|
||||
<field name="rma_supplier_operation_id" groups="rma.group_rma_customer_user,rma.group_rma_supplier_user"/>
|
||||
</group>
|
||||
</field>
|
||||
</field>
|
||||
</record>
|
||||
@@ -22,7 +25,8 @@
|
||||
<group name="inventory" position="inside">
|
||||
<group name="rma" groups="rma.group_rma_customer_user,rma.group_rma_supplier_user">
|
||||
<field name="rma_approval_policy"/>
|
||||
<field name="rma_operation_id"/>
|
||||
<field name="rma_customer_operation_id" groups="rma.group_rma_customer_user,rma.group_rma_supplier_user"/>
|
||||
<field name="rma_supplier_operation_id" groups="rma.group_rma_customer_user,rma.group_rma_supplier_user"/>
|
||||
</group>
|
||||
</group>
|
||||
</field>
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
<field name="model">rma.operation</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="RMA Operations">
|
||||
<field name="active" invisible="1"/>
|
||||
<field name="code"/>
|
||||
<field name="name"/>
|
||||
<field name="receipt_policy"/>
|
||||
@@ -25,6 +26,7 @@
|
||||
<field name="code"/>
|
||||
<field name="name"/>
|
||||
<field name="type"/>
|
||||
<field name="active"/>
|
||||
</group>
|
||||
<group name="policies"
|
||||
string="Policies">
|
||||
@@ -50,20 +52,39 @@
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="action_rma_operation" model="ir.actions.act_window">
|
||||
<field name="name">Operations</field>
|
||||
<record id="action_rma_operation_customer" model="ir.actions.act_window">
|
||||
<field name="name">Customer Operations</field>
|
||||
<field name="res_model">rma.operation</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">tree,form</field>
|
||||
<field name="context">{'default_type': "customer"}</field>
|
||||
<field name="domain">[('type','=', 'customer')]</field>
|
||||
<field name="view_id" ref="rma_operation_tree"/>
|
||||
</record>
|
||||
|
||||
<menuitem id="menu_rma_operation"
|
||||
name="Operations"
|
||||
<record id="action_rma_operation_supplier" model="ir.actions.act_window">
|
||||
<field name="name">Supplier Operations</field>
|
||||
<field name="res_model">rma.operation</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">tree,form</field>
|
||||
<field name="context">{'default_type': "supplier"}</field>
|
||||
<field name="domain">[('type','=', 'supplier')]</field>
|
||||
<field name="view_id" ref="rma_operation_tree"/>
|
||||
</record>
|
||||
|
||||
<menuitem id="menu_rma_operation_customer"
|
||||
name="Customer Operations"
|
||||
groups="rma.group_rma_manager"
|
||||
sequence="35"
|
||||
parent="rma.menu_rma_config"
|
||||
action="action_rma_operation"/>
|
||||
action="action_rma_operation_customer"/>
|
||||
|
||||
<menuitem id="menu_rma_operation_supplier"
|
||||
name="Supplier Operations"
|
||||
groups="rma.group_rma_manager"
|
||||
sequence="40"
|
||||
parent="rma.menu_rma_config"
|
||||
action="action_rma_operation_supplier"/>
|
||||
|
||||
</data>
|
||||
</odoo>
|
||||
|
||||
@@ -332,8 +332,7 @@
|
||||
<field name="name">Customer RMA Lines</field>
|
||||
<field name="res_model">rma.order.line</field>
|
||||
<field name="domain">[('state','in', ['approved', 'done']),
|
||||
('type','=', 'customer'),
|
||||
('customer_to_supplier','=', False)
|
||||
('type','=', 'customer')
|
||||
]</field>
|
||||
<field name="context">{"search_default_assigned_to":uid}</field>
|
||||
<field name="view_type">form</field>
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
# © 2017 Eficent Business and IT Consulting Services S.L.
|
||||
# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html)
|
||||
|
||||
from openerp import models, fields, api, _
|
||||
from openerp import api, fields, models
|
||||
from openerp.exceptions import ValidationError
|
||||
|
||||
|
||||
@@ -40,14 +40,18 @@ class RmaAddStockMove(models.TransientModel):
|
||||
domain="[('state', '=', 'done')]")
|
||||
|
||||
def _prepare_rma_line_from_stock_move(self, sm, lot=False):
|
||||
operation = sm.product_id.rma_operation_id or \
|
||||
sm.product_id.categ_id.rma_operation_id
|
||||
if self.env.context.get('customer'):
|
||||
operation = sm.product_id.rma_customer_operation_id or \
|
||||
sm.product_id.categ_id.rma_customer_operation_id
|
||||
else:
|
||||
operation = sm.product_id.rma_supplier_operation_id or \
|
||||
sm.product_id.categ_id.rma_supplier_operation_id
|
||||
data = {
|
||||
'reference_move_id': sm.id,
|
||||
'product_id': sm.product_id.id,
|
||||
'lot_id': lot and lot.id or False,
|
||||
'name': sm.product_id.name_template,
|
||||
'origin': sm.picking_id.name,
|
||||
'origin': sm.picking_id.name or sm.name,
|
||||
'uom_id': sm.product_uom.id,
|
||||
'operation_id': operation.id,
|
||||
'product_qty': sm.product_uom_qty,
|
||||
@@ -64,20 +68,26 @@ class RmaAddStockMove(models.TransientModel):
|
||||
[('rma_selectable', '=', True)], limit=1)
|
||||
if not route:
|
||||
raise ValidationError("Please define an rma route")
|
||||
|
||||
if not operation.in_warehouse_id or not operation.out_warehouse_id:
|
||||
warehouse = self.env['stock.warehouse'].search(
|
||||
[('company_id', '=', self.rma_id.company_id.id),
|
||||
('lot_rma_id', '!=', False)], limit=1)
|
||||
if not warehouse:
|
||||
raise ValidationError("Please define a warehouse with a "
|
||||
"default rma location")
|
||||
data.update(
|
||||
{'in_route_id': operation.in_route_id.id,
|
||||
'out_route_id': operation.out_route_id.id,
|
||||
'receipt_policy': operation.receipt_policy,
|
||||
{'receipt_policy': operation.receipt_policy,
|
||||
'operation_id': operation.id,
|
||||
'refund_policy': operation.refund_policy,
|
||||
'delivery_policy': operation.delivery_policy
|
||||
'delivery_policy': operation.delivery_policy,
|
||||
'in_warehouse_id': operation.in_warehouse_id.id or warehouse.id,
|
||||
'out_warehouse_id': operation.out_warehouse_id.id or warehouse.id,
|
||||
'in_route_id': operation.in_route_id.id or route.id,
|
||||
'out_route_id': operation.out_route_id.id or route.id,
|
||||
'location_id': (operation.location_id.id or
|
||||
operation.in_warehouse_id.lot_rma_id.id or
|
||||
warehouse.lot_rma_id.id)
|
||||
})
|
||||
if operation.in_warehouse_id:
|
||||
data['in_warehouse_id'] = operation.in_warehouse_id.id
|
||||
if operation.out_warehouse_id:
|
||||
data['out_warehouse_id'] = operation.out_warehouse_id.id
|
||||
if operation.location_id:
|
||||
data['location_id'] = operation.location_id.id
|
||||
return data
|
||||
|
||||
@api.model
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
|
||||
import openerp.addons.decimal_precision as dp
|
||||
from openerp import _, api, exceptions, fields, models
|
||||
from openerp.exceptions import ValidationError
|
||||
|
||||
|
||||
class RmaLineMakeSupplierRma(models.TransientModel):
|
||||
@@ -48,7 +49,10 @@ class RmaLineMakeSupplierRma(models.TransientModel):
|
||||
for line in lines:
|
||||
items.append([0, 0, self._prepare_item(line)])
|
||||
suppliers = lines.mapped('supplier_address_id')
|
||||
if len(suppliers) == 1:
|
||||
if len(suppliers) == 0:
|
||||
raise exceptions.Warning(
|
||||
_('Please specify a supplier address'))
|
||||
elif len(suppliers) == 1:
|
||||
res['partner_id'] = suppliers.id
|
||||
else:
|
||||
raise exceptions.Warning(
|
||||
@@ -73,7 +77,8 @@ class RmaLineMakeSupplierRma(models.TransientModel):
|
||||
def _prepare_supplier_rma_line(self, rma, item):
|
||||
operation = self.env['rma.operation'].search(
|
||||
[('type', '=', 'supplier')], limit=1)
|
||||
return {
|
||||
data = {
|
||||
'type': 'supplier',
|
||||
'origin': item.line_id.rma_id.name,
|
||||
'delivery_address_id':
|
||||
item.line_id.delivery_address_id.id,
|
||||
@@ -81,20 +86,38 @@ class RmaLineMakeSupplierRma(models.TransientModel):
|
||||
'customer_rma_id': item.line_id.id,
|
||||
'product_qty': item.product_qty,
|
||||
'rma_id': rma.id,
|
||||
'uom_id': item.uom_id.id,
|
||||
'operation_id': operation.id,
|
||||
'receipt_policy': operation.receipt_policy,
|
||||
'delivery_policy': operation.delivery_policy,
|
||||
'in_warehouse_id': operation.in_warehouse_id.id,
|
||||
'out_warehouse_id': operation.out_warehouse_id.id,
|
||||
'location_id': operation.location_id.id,
|
||||
'supplier_to_customer': operation.supplier_to_customer,
|
||||
'in_route_id': operation.in_route_id.id,
|
||||
'out_route_id': operation.out_route_id.id,
|
||||
}
|
||||
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.update(
|
||||
{'in_warehouse_id': operation.in_warehouse_id.id or warehouse.id,
|
||||
'out_warehouse_id': operation.out_warehouse_id.id or warehouse.id,
|
||||
'in_route_id': operation.in_route_id.id or route.id,
|
||||
'out_route_id': operation.out_route_id.id or route.id,
|
||||
'location_id': (operation.location_id.id or
|
||||
operation.in_warehouse_id.lot_rma_id.id or
|
||||
warehouse.lot_rma_id.id)
|
||||
})
|
||||
return data
|
||||
|
||||
@api.multi
|
||||
def make_supplier_rma(self):
|
||||
res = []
|
||||
self = self.with_context(supplier=True, customer=False)
|
||||
rma_obj = self.env['rma.order']
|
||||
rma_line_obj = self.env['rma.order.line']
|
||||
rma = False
|
||||
@@ -113,16 +136,15 @@ class RmaLineMakeSupplierRma(models.TransientModel):
|
||||
|
||||
rma_line_data = self._prepare_supplier_rma_line(rma, item)
|
||||
rma_line_obj.create(rma_line_data)
|
||||
res.append(rma.id)
|
||||
|
||||
return {
|
||||
'domain': "[('id','in', ["+','.join(map(str, res))+"])]",
|
||||
'name': _('Supplier RMA'),
|
||||
'view_type': 'form',
|
||||
'view_mode': 'tree,form',
|
||||
'view_mode': 'form',
|
||||
'res_model': 'rma.order',
|
||||
'view_id': False,
|
||||
'context': {'supplier': 1},
|
||||
'res_id': rma.id,
|
||||
'context': {'supplier': True, 'customer': False},
|
||||
'type': 'ir.actions.act_window'
|
||||
}
|
||||
|
||||
@@ -137,7 +159,8 @@ class RmaLineMakeRmaOrderItem(models.TransientModel):
|
||||
readonly=True)
|
||||
line_id = fields.Many2one('rma.order.line',
|
||||
string='RMA Line',
|
||||
required=True)
|
||||
required=True,
|
||||
ondelete='cascade')
|
||||
rma_id = fields.Many2one('rma.order', related='line_id.rma_id',
|
||||
string='RMA Order', readonly=True)
|
||||
product_id = fields.Many2one('product.product',
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
<separator string="Existing Supplier RMA to update:"/>
|
||||
<newline/>
|
||||
<group>
|
||||
<field name="supplier_rma_id"/>
|
||||
<field name="supplier_rma_id" domain="[('partner_id', '=', partner_id)]"/>
|
||||
</group>
|
||||
<newline/>
|
||||
<separator
|
||||
|
||||
Reference in New Issue
Block a user