[ADD] rma_put_away

This commit is contained in:
Jordi Ballester
2022-07-26 18:13:36 +02:00
committed by DavidJForgeFlow
parent 48b5cd7e64
commit ce71a05b8a
18 changed files with 874 additions and 0 deletions

47
rma_put_away/README.rst Normal file
View File

@@ -0,0 +1,47 @@
.. image:: https://img.shields.io/badge/licence-AGPL--3-blue.svg
:alt: License LGPL-3
============
RMA Put Away
============
This module allows you to put away the products after you have received them.
Configuration
=============
Go to *RMA / Configuration / Customer Operations* and define there:
#. The Put Away Policy
#. The route that you wish to use to put away the products.
#. The default destination location (optional).
Usage
=====
#. Go to a Customer RMA.
#. Click on *Put Away*.
#. Indicate the quantity that you want to put away and destination location.
Bug Tracker
===========
Bugs are tracked on `GitHub Issues
<https://github.com/Eficent/stock-rma/issues>`_. In case of trouble, please
check there if your issue has already been reported. If you spotted it first,
help us smashing it by providing a detailed and welcomed feedback.
Credits
=======
Contributors
------------
* Jordi Ballester Alomar <jordi.ballester@ForgeFlow.com>
* David Jimenez <david.jimenez@ForgeFlow.com>
Maintainer
----------
This module is maintained by ForgeFlow

2
rma_put_away/__init__.py Normal file
View File

@@ -0,0 +1,2 @@
from . import wizards
from . import models

View File

@@ -0,0 +1,18 @@
{
"name": "RMA Put Away",
"version": "14.0.1.0.0",
"license": "LGPL-3",
"category": "RMA",
"summary": "Allows to put away the received products in odoo",
"author": "ForgeFlow",
"website": "https://github.com/ForgeFlow/stock-rma",
"depends": ["rma"],
"data": [
"security/ir.model.access.csv",
"views/rma_operation_view.xml",
"views/rma_order_line_view.xml",
"views/rma_order_view.xml",
"wizards/rma_put_away_view.xml",
],
"installable": True,
}

View File

@@ -0,0 +1,5 @@
from . import rma_operation
from . import stock_move
from . import stock_rule
from . import rma_order_line
from . import rma_order

View File

@@ -0,0 +1,29 @@
# Copyright 2022 ForgeFlow S.L.
# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl-3.0.html).
from odoo import fields, models
class RmaOperation(models.Model):
_inherit = "rma.operation"
put_away_policy = fields.Selection(
selection=[
("no", "Not required"),
("ordered", "Based on Ordered Quantities"),
("received", "Based on Received Quantities"),
],
string="Put Away Policy",
default="no",
)
put_away_route_id = fields.Many2one(
comodel_name="stock.location.route",
string="Put Away Route",
domain=[("rma_selectable", "=", True)],
default=lambda self: self._default_routes(),
)
put_away_location_id = fields.Many2one(
comodel_name="stock.location",
string="Put Away Destination Location",
)

View File

@@ -0,0 +1,31 @@
# Copyright 2022 ForgeFlow S.L.
# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html)
from odoo import fields, models
class RmaOrder(models.Model):
_inherit = "rma.order"
def _compute_put_away_count(self):
for order in self:
pickings = (
order.mapped("rma_line_ids.move_ids")
.filtered(lambda m: m.is_rma_put_away)
.mapped("picking_id")
)
order.put_away_count = len(pickings)
put_away_count = fields.Integer(
compute="_compute_put_away_count", string="# Put Away"
)
def action_view_put_away_transfers(self):
self.ensure_one()
action = self.env.ref("stock.action_picking_tree_all")
result = action.sudo().read()[0]
pickings = self.env["stock.picking"]
for line in self.rma_line_ids:
pickings |= line.move_ids.filtered(lambda m: m.is_rma_put_away).mapped(
"picking_id"
)
return self._view_shipments(result, pickings)

View File

@@ -0,0 +1,119 @@
# Copyright 2022 ForgeFlow S.L.
# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html)
from odoo import api, fields, models
class RmaOrderLine(models.Model):
_inherit = "rma.order.line"
@api.depends(
"move_ids",
"move_ids.state",
"move_ids.is_rma_put_away",
"qty_put_away",
"put_away_policy",
"product_qty",
)
def _compute_qty_to_put_away(self):
for rec in self:
rec.qty_to_put_away = 0.0
if rec.put_away_policy == "ordered":
rec.qty_to_put_away = rec.product_qty - rec.qty_put_away
elif rec.put_away_policy == "received":
rec.qty_to_put_away = rec.qty_received - rec.qty_put_away
@api.depends("move_ids", "move_ids.state", "move_ids.is_rma_put_away")
def _compute_qty_in_put_away(self):
product_obj = self.env["uom.uom"]
for rec in self:
qty = 0.0
for move in rec.move_ids.filtered(
lambda m: m.state in ["draft", "confirmed", "assigned"]
and m.is_rma_put_away
):
qty += product_obj._compute_quantity(move.product_uom_qty, rec.uom_id)
rec.qty_in_put_away = qty
@api.depends("move_ids", "move_ids.state", "move_ids.is_rma_put_away")
def _compute_qty_put_away(self):
product_obj = self.env["uom.uom"]
for rec in self:
qty = 0.0
for move in rec.move_ids.filtered(
lambda m: m.state in ["done"] and m.is_rma_put_away
):
qty += product_obj._compute_quantity(move.product_uom_qty, rec.uom_id)
rec.qty_put_away = qty
def _compute_put_away_count(self):
for line in self:
pickings = self.move_ids.filtered(lambda m: m.is_rma_put_away).mapped(
"picking_id"
)
line.put_away_count = len(pickings)
qty_to_put_away = fields.Float(
string="Qty To Put Away",
copy=False,
digits="Product Unit of Measure",
readonly=True,
compute="_compute_qty_to_put_away",
store=True,
)
qty_in_put_away = fields.Float(
string="Qty In Put Away",
copy=False,
digits="Product Unit of Measure",
readonly=True,
compute="_compute_qty_in_put_away",
store=True,
)
qty_put_away = fields.Float(
string="Qty Put Away",
copy=False,
digits="Product Unit of Measure",
readonly=True,
compute="_compute_qty_put_away",
store=True,
)
put_away_policy = fields.Selection(
selection=[
("no", "Not required"),
("ordered", "Based on Ordered Quantities"),
("received", "Based on Received Quantities"),
],
string="Put Away Policy",
default="no",
required=True,
readonly=False,
)
put_away_count = fields.Integer(
compute="_compute_put_away_count", string="# Put Aways"
)
@api.onchange("operation_id")
def _onchange_operation_id(self):
res = super(RmaOrderLine, self)._onchange_operation_id()
if self.operation_id:
self.put_away_policy = self.operation_id.put_away_policy or "no"
return res
def action_view_put_away_transfers(self):
action = self.env.ref("stock.action_picking_tree_all")
result = action.sudo().read()[0]
pickings = self.env["stock.picking"]
for line in self:
if line.lot_id:
line.move_ids.lot_ids |= line.lot_id
line.move_ids.move_line_ids.lot_id = line.lot_id
pickings |= line.move_ids.filtered(lambda m: m.is_rma_put_away).mapped(
"picking_id"
)
# choose the view_mode accordingly
if len(pickings) != 1:
result["domain"] = "[('id', 'in', " + str(pickings.ids) + ")]"
elif len(pickings) == 1:
res = self.env.ref("stock.view_picking_form", False)
result["views"] = [(res and res.id or False, "form")]
result["res_id"] = pickings.ids[0]
return result

View File

@@ -0,0 +1,21 @@
# Copyright 2022 ForgeFlow S.L.
# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html)
from odoo import fields, models
class StockMove(models.Model):
_inherit = "stock.move"
is_rma_put_away = fields.Boolean(
string="Is RMA Put Away",
copy=False,
help="This Stock Move has been created from a Put Away operation in "
"the RMA.",
)
def _is_in_out_rma_move(self, op, states, location_type):
res = super(StockMove, self)._is_in_out_rma_move(op, states, location_type)
if self.is_rma_put_away:
return False
return res

View File

@@ -0,0 +1,33 @@
# Copyright 2022 ForgeFlow S.L.
# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html)
from odoo import models
class StockRule(models.Model):
_inherit = "stock.rule"
def _get_stock_move_values(
self,
product_id,
product_qty,
product_uom,
location_id,
name,
origin,
company_id,
values,
):
res = super()._get_stock_move_values(
product_id,
product_qty,
product_uom,
location_id,
name,
origin,
company_id,
values,
)
if "is_rma_put_away" in values:
res["is_rma_put_away"] = values.get("is_rma_put_away")
return res

View File

@@ -0,0 +1,7 @@
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_rma_put_away_wizard,rma.order.manager,model_rma_make_put_away_wizard,rma.group_rma_manager,1,1,1,1
access_rma_put_away_wizard_customer,rma.order.manager,model_rma_make_put_away_wizard,rma.group_rma_customer_user,1,1,1,1
access_rma_put_away_wizard_supplier,rma.order.manager,model_rma_make_put_away_wizard,rma.group_rma_supplier_user,1,1,1,1
access_rma_put_away_item_wizard,rma.order.manager,model_rma_make_put_away_item_wizard,rma.group_rma_manager,1,1,1,1
access_rma_put_away_item_wizard_customer,rma.order.manager,model_rma_make_put_away_item_wizard,rma.group_rma_customer_user,1,1,1,1
access_rma_put_away_item_wizard_supplier,rma.order.manager,model_rma_make_put_away_item_wizard,rma.group_rma_supplier_user,1,1,1,1
1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
2 access_rma_put_away_wizard rma.order.manager model_rma_make_put_away_wizard rma.group_rma_manager 1 1 1 1
3 access_rma_put_away_wizard_customer rma.order.manager model_rma_make_put_away_wizard rma.group_rma_customer_user 1 1 1 1
4 access_rma_put_away_wizard_supplier rma.order.manager model_rma_make_put_away_wizard rma.group_rma_supplier_user 1 1 1 1
5 access_rma_put_away_item_wizard rma.order.manager model_rma_make_put_away_item_wizard rma.group_rma_manager 1 1 1 1
6 access_rma_put_away_item_wizard_customer rma.order.manager model_rma_make_put_away_item_wizard rma.group_rma_customer_user 1 1 1 1
7 access_rma_put_away_item_wizard_supplier rma.order.manager model_rma_make_put_away_item_wizard rma.group_rma_supplier_user 1 1 1 1

View File

@@ -0,0 +1 @@
from . import test_rma_put_away

View File

@@ -0,0 +1,235 @@
from odoo.tests import common
class TestRmaPutAway(common.SingleTransactionCase):
@classmethod
def setUpClass(cls):
super(TestRmaPutAway, cls).setUpClass()
cls.rma_obj = cls.env["rma.order"]
cls.rma_make_picking = cls.env["rma_make_picking.wizard"]
cls.rma_line_obj = cls.env["rma.order.line"]
cls.rma_op_obj = cls.env["rma.operation"]
cls.rma_make_put_away_wiz = cls.env["rma_make_put_away.wizard"]
cls.product_obj = cls.env["product.product"]
cls.partner_obj = cls.env["res.partner"]
cls.rma_route_cust = cls.env.ref("rma.route_rma_customer")
# Create customer
cls.customer1 = cls.partner_obj.create({"name": "Customer 1"})
# Create products
cls.product_1 = cls.product_obj.create(
{"name": "Test Product 1", "type": "product", "list_price": 100.0}
)
cls.product_2 = cls.product_obj.create(
{
"name": "Test Product 2",
"type": "product",
"list_price": 150.0,
"tracking": "lot",
}
)
cls.lot = cls.env["stock.production.lot"].create(
{
"name": "Lot for tests",
"product_id": cls.product_2.id,
"company_id": cls.env.ref("base.main_company").id,
}
)
cls.warehouse = cls.env["stock.warehouse"].create(
{
"name": "Warehouse",
"reception_steps": "one_step",
"delivery_steps": "ship_only",
"code": "WH1",
}
)
cls.warehouse_rma = cls.env["stock.warehouse"].create(
{
"name": "Warehouse RMA",
"reception_steps": "one_step",
"delivery_steps": "ship_only",
"code": "WH2",
}
)
cls.rma_loc = cls.env["stock.location"].create(
{"name": "WH RMA", "location_id": cls.warehouse_rma.view_location_id.id}
)
cls.put_away_loc = cls.env["stock.location"].create(
{
"name": "WH Put Away Location",
"location_id": cls.warehouse.view_location_id.id,
}
)
cls.route1 = cls.env["stock.location.route"].create(
{
"name": "Transfer WH1",
"rma_selectable": True,
"sequence": 10,
}
)
cls.env["stock.rule"].create(
{
"name": "Transfer",
"route_id": cls.route1.id,
"location_src_id": cls.rma_loc.id,
"location_id": cls.put_away_loc.id,
"action": "pull",
"picking_type_id": cls.warehouse.int_type_id.id,
"procure_method": "make_to_stock",
"warehouse_id": cls.warehouse.id,
}
)
# Create RMA group and operation:
cls.rma_group = cls.rma_obj.create({"partner_id": cls.customer1.id})
cls.operation_1 = cls.rma_op_obj.create(
{
"code": "TEST1",
"name": "Operation 1",
"type": "customer",
"receipt_policy": "ordered",
"put_away_policy": "received",
"put_away_route_id": cls.route1.id,
"put_away_location_id": cls.put_away_loc.id,
"in_route_id": cls.rma_route_cust.id,
"out_route_id": cls.rma_route_cust.id,
}
)
cls.operation_2 = cls.rma_op_obj.create(
{
"code": "TEST2",
"name": "Operation 2",
"type": "customer",
"receipt_policy": "ordered",
"put_away_policy": "ordered",
"put_away_route_id": cls.route1.id,
"put_away_location_id": cls.put_away_loc.id,
"in_route_id": cls.rma_route_cust.id,
"out_route_id": cls.rma_route_cust.id,
}
)
def test_01_rma_put_away_without_lot(self):
"""Generate a Sales Order from a customer RMA."""
rma = self.rma_line_obj.create(
{
"partner_id": self.customer1.id,
"product_id": self.product_1.id,
"operation_id": self.operation_1.id,
"uom_id": self.product_1.uom_id.id,
"in_route_id": self.operation_1.in_route_id.id,
"out_route_id": self.operation_1.out_route_id.id,
"in_warehouse_id": self.operation_1.in_warehouse_id.id,
"out_warehouse_id": self.operation_1.out_warehouse_id.id,
"location_id": self.rma_loc.id,
}
)
rma._onchange_operation_id()
rma.action_rma_to_approve()
wizard = self.rma_make_picking.with_context(
{
"active_ids": rma.id,
"active_model": "rma.order.line",
"picking_type": "incoming",
"active_id": 1,
}
).create({})
wizard._create_picking()
wizard = self.rma_make_put_away_wiz.with_context(
{
"active_ids": rma.id,
"active_model": "rma.order.line",
"item_ids": [
0,
0,
{
"line_id": rma.id,
"product_id": rma.product_id.id,
"product_qty": rma.product_qty,
"location_id": rma.location_id,
"qty_to_put_away": rma.qty_to_put_away,
"uom_id": rma.uom_id.id,
},
],
}
).create({})
action = wizard.action_create_put_away()
picking = self.env["stock.picking"].browse([action["res_id"]])
self.assertEqual(picking.location_dest_id.id, self.put_away_loc.id)
self.assertEqual(picking.location_id.id, self.rma_loc.id)
move = picking.move_ids_without_package
self.assertEqual(move.product_id.id, self.product_1.id)
self.assertEqual(move.product_uom_qty, 1)
move.quantity_done = 1
self.assertTrue(picking.action_assign())
self.assertTrue(picking.button_validate())
def test_02_rma_put_away_with_lot(self):
"""Generate a Sales Order from a customer RMA."""
rma = self.rma_line_obj.create(
{
"partner_id": self.customer1.id,
"product_id": self.product_2.id,
"lot_id": self.lot.id,
"operation_id": self.operation_1.id,
"uom_id": self.product_2.uom_id.id,
"in_route_id": self.operation_1.in_route_id.id,
"out_route_id": self.operation_1.out_route_id.id,
"in_warehouse_id": self.operation_1.in_warehouse_id.id,
"out_warehouse_id": self.operation_1.out_warehouse_id.id,
"location_id": self.rma_loc.id,
}
)
rma._onchange_operation_id()
rma._onchange_lot_id()
rma.action_rma_to_approve()
wizard = self.rma_make_picking.with_context(
{
"active_ids": rma.id,
"active_model": "rma.order.line",
"picking_type": "incoming",
"active_id": 1,
}
).create({})
wizard._create_picking()
wizard = self.rma_make_put_away_wiz.with_context(
{
"active_ids": rma.id,
"active_model": "rma.order.line",
"item_ids": [
0,
0,
{
"line_id": rma.id,
"product_id": rma.product_id.id,
"product_qty": rma.product_qty,
"lot_id": rma.lot_id.id,
"location_id": rma.location_id,
"qty_to_put_away": rma.qty_to_put_away,
"uom_id": rma.uom_id.id,
},
],
}
).create({})
action = wizard.action_create_put_away()
picking = self.env["stock.picking"].browse([action["res_id"]])
self.assertEqual(picking.location_dest_id.id, self.put_away_loc.id)
self.assertEqual(picking.location_id.id, self.rma_loc.id)
move = picking.move_ids_without_package
self.assertEqual(move.product_id.id, self.product_2.id)
self.assertEqual(move.product_uom_qty, 1)
self.assertEqual(move.lot_ids.id, self.lot.id)
move.quantity_done = 1
move.move_line_ids.lot_id = self.lot
self.assertTrue(picking.button_validate())

View File

@@ -0,0 +1,32 @@
<?xml version="1.0" encoding="utf-8" ?>
<odoo>
<record id="rma_operation_tree" model="ir.ui.view">
<field name="name">rma.operation.tree</field>
<field name="model">rma.operation</field>
<field name="inherit_id" ref="rma.rma_operation_tree" />
<field name="arch" type="xml">
<field name="delivery_policy" position="after">
<field name="put_away_policy" />
</field>
</field>
</record>
<record id="rma_operation_form" model="ir.ui.view">
<field name="name">rma.operation.form - rma_put_away</field>
<field name="model">rma.operation</field>
<field name="inherit_id" ref="rma.rma_operation_form" />
<field name="arch" type="xml">
<field name="delivery_policy" position="after">
<field name="put_away_policy" />
</field>
<group name="outbound" position="after">
<group name="put_away" string="Put Away">
<field name="put_away_route_id" string="Route" />
<field name="put_away_location_id" string="Destination Location" />
</group>
</group>
</field>
</record>
</odoo>

View File

@@ -0,0 +1,55 @@
<?xml version="1.0" encoding="utf-8" ?>
<odoo>
<record id="view_rma_line_form" model="ir.ui.view">
<field name="name">rma.order.line.form</field>
<field name="model">rma.order.line</field>
<field name="inherit_id" ref="rma.view_rma_line_form" />
<field name="arch" type="xml">
<button name='action_view_out_shipments' position="after">
<button
type="object"
name="action_view_put_away_transfers"
class="oe_stat_button"
icon="fa-truck"
groups="stock.group_stock_user"
attrs="{'invisible': [('put_away_count', '=', 0)]}"
>
<field
name="put_away_count"
widget="statinfo"
string="Put Aways"
/>
</button>
</button>
<group name="quantities" position="inside">
<group>
<field name="qty_to_put_away" />
<field name="qty_in_put_away" />
<field name="qty_put_away" />
</group>
</group>
<field name="delivery_policy" position="after">
<field name="put_away_policy" />
</field>
</field>
</record>
<record id="view_rma_rma_line_filter" model="ir.ui.view">
<field name="name">rma.order.line.select - rma_put_away</field>
<field name="model">rma.order.line</field>
<field name="inherit_id" ref="rma.view_rma_rma_line_filter" />
<field name="arch" type="xml">
<group name="stock_quantities" position="after">
<group name="put_away_quantities" groups="stock.group_stock_user">
<filter
domain="[('state','!=', 'done'),('qty_to_put_away','>',0.0)]"
help="To Put Away"
name="to_put_away"
/>
</group>
</group>
</field>
</record>
</odoo>

View File

@@ -0,0 +1,25 @@
<?xml version="1.0" encoding="utf-8" ?>
<odoo>
<record id="view_rma_form" model="ir.ui.view">
<field name="name">rma.order.form</field>
<field name="model">rma.order</field>
<field name="inherit_id" ref="rma.view_rma_form" />
<field name="arch" type="xml">
<button name="action_view_out_shipments" position="after">
<button
type="object"
name="action_view_put_away_transfers"
class="oe_stat_button"
icon="fa-truck"
groups="stock.group_stock_user"
attrs="{'invisible': [('put_away_count', '=', 0)]}"
>
<field name="put_away_count" widget="statinfo" string="Put Aways" />
</button>
</button>
<xpath expr="//field[@name='rma_line_ids']/tree" position="inside">
<field name="put_away_policy" invisible="True" />
</xpath>
</field>
</record>
</odoo>

View File

@@ -0,0 +1 @@
from . import rma_make_put_away

View File

@@ -0,0 +1,141 @@
# Copyright 2022 ForgeFlow S.L.
# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl-3.0.html).
import time
from odoo import _, api, fields, models
from odoo.exceptions import UserError, ValidationError
from odoo.tools import DEFAULT_SERVER_DATETIME_FORMAT as DT_FORMAT
class RmaMakePutAway(models.TransientModel):
_name = "rma_make_put_away.wizard"
_description = "Wizard to create put_away from rma lines"
item_ids = fields.One2many(
comodel_name="rma_make_put_away_item.wizard",
inverse_name="wiz_id",
string="Items",
)
@api.returns("rma.order.line")
def _prepare_item(self, line):
values = {
"product_id": line.product_id.id,
"product_qty": line.product_qty,
"location_id": line.operation_id.put_away_location_id.id,
"uom_id": line.uom_id.id,
"qty_to_put_away": line.qty_to_put_away,
"line_id": line.id,
"rma_id": line.rma_id and line.rma_id.id or False,
}
return values
@api.model
def default_get(self, fields_list):
"""Default values for wizard, if there is more than one supplier on
lines the supplier field is empty otherwise is the unique line
supplier.
"""
context = self._context.copy()
res = super(RmaMakePutAway, self).default_get(fields_list)
rma_line_obj = self.env["rma.order.line"]
rma_line_ids = self.env.context["active_ids"] or []
active_model = self.env.context["active_model"]
if not rma_line_ids:
return res
assert active_model == "rma.order.line", "Bad context propagation"
items = []
lines = rma_line_obj.browse(rma_line_ids)
for line in lines:
items.append([0, 0, self._prepare_item(line)])
res["item_ids"] = items
context.update({"items_ids": items})
return res
def _create_put_away(self):
"""Method called when the user clicks on create picking"""
procurements = []
errors = []
for item in self.item_ids:
line = item.line_id
if line.state != "approved":
raise ValidationError(_("RMA %s is not approved") % line.name)
procurement = self._prepare_procurement(item)
procurements.append(procurement)
try:
self.env["procurement.group"].run(procurements)
except UserError as error:
errors.append(error.args[0])
if errors:
raise UserError("\n".join(errors))
return procurements
def action_create_put_away(self):
self._create_put_away()
action = self.item_ids.line_id.action_view_put_away_transfers()
return action
@api.model
def _get_procurement_data(self, item):
line = item.line_id
route = line.operation_id.put_away_route_id
if not route:
raise ValidationError(_("No route specified"))
procurement_data = {
"name": line.rma_id and line.rma_id.name or line.name,
"origin": line.name,
"date_planned": time.strftime(DT_FORMAT),
"product_id": item.product_id.id,
"product_qty": item.product_qty,
"qty_to_put_away": item.product_qty,
"product_uom": line.product_id.product_tmpl_id.uom_id.id,
"location_id": item.location_id.id,
"rma_line_id": line.id,
"route_ids": route,
"company_id": line.company_id,
"is_rma_put_away": True,
}
return procurement_data
@api.model
def _prepare_procurement(self, item):
line = item.line_id
values = self._get_procurement_data(item)
values = dict(values, rma_line_id=item.line_id, rma_id=item.line_id.rma_id)
procurement = self.env["procurement.group"].Procurement(
item.line_id.product_id,
item.product_qty,
item.line_id.product_id.product_tmpl_id.uom_id,
item.location_id,
values.get("origin"),
values.get("origin"),
line.company_id,
values,
)
return procurement
class RmaMakePutAwayItem(models.TransientModel):
_name = "rma_make_put_away_item.wizard"
_description = "Items to Put Away"
wiz_id = fields.Many2one("rma_make_put_away.wizard", string="Wizard", required=True)
line_id = fields.Many2one(
"rma.order.line", string="RMA order Line", ondelete="cascade"
)
rma_id = fields.Many2one("rma.order", related="line_id.rma_id", string="RMA Group")
product_id = fields.Many2one("product.product", string="Product")
product_qty = fields.Float(
related="line_id.product_qty",
string="Quantity Ordered",
copy=False,
digits="Product Unit of Measure",
)
location_id = fields.Many2one("stock.location", string="Destination Location")
qty_to_put_away = fields.Float(
string="Quantity To put away", digits="Product Unit of Measure"
)
uom_id = fields.Many2one("uom.uom", string="Unit of Measure")

View File

@@ -0,0 +1,72 @@
<?xml version="1.0" ?>
<odoo>
<record id="view_rma_put_away" model="ir.ui.view">
<field name="name">Create Put Away</field>
<field name="model">rma_make_put_away.wizard</field>
<field name="arch" type="xml">
<form string="Select lines for picking" name="lines">
<separator string="Select lines for put away" />
<field name="item_ids">
<tree string="RMA Lines" editable="bottom" create="false">
<field name="rma_id" groups="rma.group_rma_groups" />
<field name="product_id" />
<field name="product_qty" />
<field name="qty_to_put_away" />
<field name="location_id" />
<field name="line_id" invisible="1" />
<field name="uom_id" groups="uom.group_uom" />
</tree>
</field>
<footer>
<button
string="Confirm"
name="action_create_put_away"
type="object"
class="oe_highlight"
/>
or
<button
name="action_cancel"
string="Cancel"
class="oe_link"
special="cancel"
/>
</footer>
</form>
</field>
</record>
<record id="action_rma_put_away" model="ir.actions.act_window">
<field name="name">Create Put Away</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">rma_make_put_away.wizard</field>
<field name="view_mode">form</field>
<field name="target">new</field>
<field name="view_id" ref="view_rma_put_away" />
<field name="groups_id" eval="[(4, ref('stock.group_stock_user'))]" />
<field name="binding_model_id" ref="rma.model_rma_order_line" />
</record>
<record id="view_rma_line_button_put_away_form" model="ir.ui.view">
<field name="name">rma.order.line.form</field>
<field name="model">rma.order.line</field>
<field name="inherit_id" ref="rma.view_rma_line_button_form" />
<field name="arch" type="xml">
<header position="inside">
<button
name="%(action_rma_put_away)d"
string="Put Away"
class="oe_highlight"
attrs="{'invisible':['|', ('qty_to_put_away', '=', 0), ('state', '!=', 'approved')]}"
type="action"
/>
<button
name="%(action_rma_put_away)d"
string="Put Away"
attrs="{'invisible':['|', ('qty_to_put_away', '!=', 0), ('state', '!=', 'approved')]}"
type="action"
/>
</header>
</field>
</record>
</odoo>