mirror of
https://github.com/OCA/stock-logistics-warehouse.git
synced 2025-01-21 14:27:28 +02:00
[IMP] stock_inventory_verification_request: black, isort, prettier
This commit is contained in:
@@ -0,0 +1 @@
|
||||
../../../../stock_inventory_verification_request
|
||||
6
setup/stock_inventory_verification_request/setup.py
Normal file
6
setup/stock_inventory_verification_request/setup.py
Normal file
@@ -0,0 +1,6 @@
|
||||
import setuptools
|
||||
|
||||
setuptools.setup(
|
||||
setup_requires=['setuptools-odoo'],
|
||||
odoo_addon=True,
|
||||
)
|
||||
@@ -4,11 +4,10 @@
|
||||
{
|
||||
"name": "Stock Inventory Verification Request",
|
||||
"summary": "Adds the capability to request a Slot Verification when "
|
||||
"a inventory is Pending to Approve",
|
||||
"a inventory is Pending to Approve",
|
||||
"version": "12.0.3.0.1",
|
||||
"maintainers": ['LoisRForgeFlow'],
|
||||
"author": "ForgeFlow, "
|
||||
"Odoo Community Association (OCA)",
|
||||
"maintainers": ["LoisRForgeFlow"],
|
||||
"author": "ForgeFlow, " "Odoo Community Association (OCA)",
|
||||
"website": "https://github.com/OCA/stock-logistics-warehouse",
|
||||
"category": "Warehouse",
|
||||
"depends": [
|
||||
@@ -16,14 +15,14 @@
|
||||
"mail",
|
||||
],
|
||||
"data": [
|
||||
'security/ir.model.access.csv',
|
||||
'security/stock_security.xml',
|
||||
'views/stock_slot_verification_request_view.xml',
|
||||
'views/stock_inventory_view.xml',
|
||||
'views/stock_location_view.xml',
|
||||
'data/slot_verification_request_sequence.xml',
|
||||
"security/ir.model.access.csv",
|
||||
"security/stock_security.xml",
|
||||
"views/stock_slot_verification_request_view.xml",
|
||||
"views/stock_inventory_view.xml",
|
||||
"views/stock_location_view.xml",
|
||||
"data/slot_verification_request_sequence.xml",
|
||||
],
|
||||
"license": "AGPL-3",
|
||||
'installable': True,
|
||||
'application': False,
|
||||
"installable": True,
|
||||
"application": False,
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<!-- Copyright 2020 ForgeFlow S.L.
|
||||
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). -->
|
||||
|
||||
<odoo noupdate="1">
|
||||
|
||||
<record id="seq_slot_verification_request" model="ir.sequence">
|
||||
@@ -9,7 +8,7 @@
|
||||
<field name="code">stock.slot.verification.request</field>
|
||||
<field name="prefix">SVR/%(range_year)s/</field>
|
||||
<field name="padding">5</field>
|
||||
<field name="company_id" eval="False"/>
|
||||
<field name="company_id" eval="False" />
|
||||
</record>
|
||||
|
||||
</odoo>
|
||||
|
||||
@@ -6,16 +6,19 @@ from odoo import api, fields, models
|
||||
|
||||
|
||||
class StockInventory(models.Model):
|
||||
_inherit = 'stock.inventory'
|
||||
_inherit = "stock.inventory"
|
||||
|
||||
requested_verification = fields.Boolean(
|
||||
string='Requested Verification?', copy=False)
|
||||
string="Requested Verification?", copy=False
|
||||
)
|
||||
slot_verification_ids = fields.One2many(
|
||||
comodel_name='stock.slot.verification.request',
|
||||
string='Slot Verification Requests', inverse_name='inventory_id')
|
||||
comodel_name="stock.slot.verification.request",
|
||||
string="Slot Verification Requests",
|
||||
inverse_name="inventory_id",
|
||||
)
|
||||
solving_slot_verification_request_id = fields.Many2one(
|
||||
comodel_name="stock.slot.verification.request",
|
||||
help="This Inventory adjustment was created from the specified SVR."
|
||||
help="This Inventory adjustment was created from the specified SVR.",
|
||||
)
|
||||
|
||||
@api.multi
|
||||
@@ -23,41 +26,48 @@ class StockInventory(models.Model):
|
||||
self.ensure_one()
|
||||
self.requested_verification = True
|
||||
for line in self.line_ids:
|
||||
if line.discrepancy_threshold and (line.discrepancy_percent >
|
||||
line.discrepancy_threshold):
|
||||
self.env['stock.slot.verification.request'].create({
|
||||
'inventory_id': self.id,
|
||||
'inventory_line_id': line.id,
|
||||
'location_id': line.location_id.id,
|
||||
'state': 'wait',
|
||||
'product_id': line.product_id.id,
|
||||
'company_id': self.company_id.id,
|
||||
})
|
||||
if line.discrepancy_threshold and (
|
||||
line.discrepancy_percent > line.discrepancy_threshold
|
||||
):
|
||||
self.env["stock.slot.verification.request"].create(
|
||||
{
|
||||
"inventory_id": self.id,
|
||||
"inventory_line_id": line.id,
|
||||
"location_id": line.location_id.id,
|
||||
"state": "wait",
|
||||
"product_id": line.product_id.id,
|
||||
"company_id": self.company_id.id,
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
class StockInventoryLine(models.Model):
|
||||
_inherit = 'stock.inventory.line'
|
||||
_rec_name = 'product_id'
|
||||
_inherit = "stock.inventory.line"
|
||||
_rec_name = "product_id"
|
||||
|
||||
slot_verification_ids = fields.One2many(
|
||||
comodel_name='stock.slot.verification.request',
|
||||
inverse_name='inventory_line_id',
|
||||
string='Slot Verification Request')
|
||||
comodel_name="stock.slot.verification.request",
|
||||
inverse_name="inventory_line_id",
|
||||
string="Slot Verification Request",
|
||||
)
|
||||
|
||||
@api.multi
|
||||
def action_open_svr(self):
|
||||
"""Open the corresponding Slot Verification Request directly from the
|
||||
Inventory Lines."""
|
||||
request_svr_ids = self.mapped('slot_verification_ids').ids
|
||||
action = self.env.ref('stock_inventory_verification_request.'
|
||||
'action_slot_verification_request')
|
||||
request_svr_ids = self.mapped("slot_verification_ids").ids
|
||||
action = self.env.ref(
|
||||
"stock_inventory_verification_request." "action_slot_verification_request"
|
||||
)
|
||||
result = action.read()[0]
|
||||
if len(request_svr_ids) > 1:
|
||||
result['domain'] = [('id', 'in', request_svr_ids)]
|
||||
result["domain"] = [("id", "in", request_svr_ids)]
|
||||
elif len(request_svr_ids) == 1:
|
||||
view = self.env.ref(
|
||||
'stock_inventory_verification_request.stock_'
|
||||
'slot_verification_request_form_view', False)
|
||||
result['views'] = [(view and view.id or False, 'form')]
|
||||
result['res_id'] = request_svr_ids[0] or False
|
||||
"stock_inventory_verification_request.stock_"
|
||||
"slot_verification_request_form_view",
|
||||
False,
|
||||
)
|
||||
result["views"] = [(view and view.id or False, "form")]
|
||||
result["res_id"] = request_svr_ids[0] or False
|
||||
return result
|
||||
|
||||
@@ -10,22 +10,27 @@ class StockLocation(models.Model):
|
||||
|
||||
slot_verification_ids = fields.One2many(
|
||||
comodel_name="stock.slot.verification.request",
|
||||
string="Slot Verification Requests", inverse_name="location_id")
|
||||
string="Slot Verification Requests",
|
||||
inverse_name="location_id",
|
||||
)
|
||||
|
||||
@api.multi
|
||||
def action_open_svr(self):
|
||||
"""Open the corresponding Slot Verification Request directly from the
|
||||
Location."""
|
||||
request_svr_ids = self.mapped("slot_verification_ids").ids
|
||||
action = self.env.ref("stock_inventory_verification_request."
|
||||
"action_slot_verification_request")
|
||||
action = self.env.ref(
|
||||
"stock_inventory_verification_request." "action_slot_verification_request"
|
||||
)
|
||||
result = action.read()[0]
|
||||
if len(request_svr_ids) > 1:
|
||||
result["domain"] = [("id", "in", request_svr_ids)]
|
||||
elif len(request_svr_ids) == 1:
|
||||
view = self.env.ref(
|
||||
"stock_inventory_verification_request.stock_"
|
||||
"slot_verification_request_form_view", False)
|
||||
"slot_verification_request_form_view",
|
||||
False,
|
||||
)
|
||||
result["views"] = [(view and view.id or False, "form")]
|
||||
result["res_id"] = request_svr_ids[0] or False
|
||||
return result
|
||||
|
||||
@@ -6,20 +6,22 @@ from odoo import api, fields, models
|
||||
|
||||
|
||||
class SlotVerificationRequest(models.Model):
|
||||
_name = 'stock.slot.verification.request'
|
||||
_inherit = 'mail.thread'
|
||||
_name = "stock.slot.verification.request"
|
||||
_inherit = "mail.thread"
|
||||
_description = "Slot Verification Request"
|
||||
|
||||
@api.model
|
||||
def _default_company(self):
|
||||
company_id = self.env['res.company']._company_default_get(self._name)
|
||||
company_id = self.env["res.company"]._company_default_get(self._name)
|
||||
return company_id
|
||||
|
||||
@api.model
|
||||
def create(self, vals):
|
||||
if not vals.get('name') or vals.get('name') == '/':
|
||||
vals['name'] = self.env['ir.sequence'].next_by_code(
|
||||
'stock.slot.verification.request') or '/'
|
||||
if not vals.get("name") or vals.get("name") == "/":
|
||||
vals["name"] = (
|
||||
self.env["ir.sequence"].next_by_code("stock.slot.verification.request")
|
||||
or "/"
|
||||
)
|
||||
return super(SlotVerificationRequest, self).create(vals)
|
||||
|
||||
@api.multi
|
||||
@@ -38,164 +40,182 @@ class SlotVerificationRequest(models.Model):
|
||||
rec.created_inventory_count = len(rec.created_inventory_ids)
|
||||
|
||||
name = fields.Char(
|
||||
default="/", required=True,
|
||||
readonly=True, states={'wait': [('readonly', False)]})
|
||||
inventory_id = fields.Many2one(
|
||||
comodel_name='stock.inventory',
|
||||
string='Inventory Adjustment',
|
||||
readonly=True)
|
||||
inventory_line_id = fields.Many2one(
|
||||
comodel_name='stock.inventory.line',
|
||||
string='Inventory Line',
|
||||
readonly=True)
|
||||
location_id = fields.Many2one(
|
||||
comodel_name='stock.location',
|
||||
string='Location',
|
||||
default="/",
|
||||
required=True,
|
||||
readonly=True, states={'wait': [('readonly', False)]},
|
||||
readonly=True,
|
||||
states={"wait": [("readonly", False)]},
|
||||
)
|
||||
inventory_id = fields.Many2one(
|
||||
comodel_name="stock.inventory", string="Inventory Adjustment", readonly=True
|
||||
)
|
||||
inventory_line_id = fields.Many2one(
|
||||
comodel_name="stock.inventory.line", string="Inventory Line", readonly=True
|
||||
)
|
||||
location_id = fields.Many2one(
|
||||
comodel_name="stock.location",
|
||||
string="Location",
|
||||
required=True,
|
||||
readonly=True,
|
||||
states={"wait": [("readonly", False)]},
|
||||
track_visibility="onchange",
|
||||
)
|
||||
company_id = fields.Many2one(
|
||||
comodel_name='res.company', string='Company',
|
||||
comodel_name="res.company",
|
||||
string="Company",
|
||||
required=True,
|
||||
default=_default_company,
|
||||
readonly=True,
|
||||
)
|
||||
state = fields.Selection(selection=[
|
||||
('wait', 'Waiting Actions'),
|
||||
('open', 'In Progress'),
|
||||
('cancelled', 'Cancelled'),
|
||||
('done', 'Solved')
|
||||
], string='Status', default='wait',
|
||||
state = fields.Selection(
|
||||
selection=[
|
||||
("wait", "Waiting Actions"),
|
||||
("open", "In Progress"),
|
||||
("cancelled", "Cancelled"),
|
||||
("done", "Solved"),
|
||||
],
|
||||
string="Status",
|
||||
default="wait",
|
||||
track_visibility="onchange",
|
||||
)
|
||||
responsible_id = fields.Many2one(
|
||||
comodel_name='res.users',
|
||||
string='Assigned to',
|
||||
comodel_name="res.users",
|
||||
string="Assigned to",
|
||||
track_visibility="onchange",
|
||||
)
|
||||
product_id = fields.Many2one(
|
||||
comodel_name='product.product',
|
||||
string='Product',
|
||||
readonly=True, states={'wait': [('readonly', False)]},
|
||||
comodel_name="product.product",
|
||||
string="Product",
|
||||
readonly=True,
|
||||
states={"wait": [("readonly", False)]},
|
||||
track_visibility="onchange",
|
||||
)
|
||||
notes = fields.Text(string='Notes')
|
||||
notes = fields.Text(string="Notes")
|
||||
involved_move_ids = fields.Many2many(
|
||||
comodel_name='stock.move',
|
||||
relation='slot_verification_move_involved_rel',
|
||||
column1='slot_verification_request_id',
|
||||
column2='move_id',
|
||||
string='Involved Stock Moves')
|
||||
involved_move_count = fields.Integer(
|
||||
compute='_compute_involved_move_count'
|
||||
comodel_name="stock.move",
|
||||
relation="slot_verification_move_involved_rel",
|
||||
column1="slot_verification_request_id",
|
||||
column2="move_id",
|
||||
string="Involved Stock Moves",
|
||||
)
|
||||
involved_move_count = fields.Integer(compute="_compute_involved_move_count")
|
||||
involved_inv_line_ids = fields.Many2many(
|
||||
comodel_name='stock.inventory.line',
|
||||
relation='slot_verification_inv_line_involved_rel',
|
||||
column1='slot_verification_request_id',
|
||||
column2='inventory_line_id',
|
||||
string='Involved Inventory Lines')
|
||||
involved_inv_line_count = fields.Integer(
|
||||
compute='_compute_involved_inv_line_count')
|
||||
comodel_name="stock.inventory.line",
|
||||
relation="slot_verification_inv_line_involved_rel",
|
||||
column1="slot_verification_request_id",
|
||||
column2="inventory_line_id",
|
||||
string="Involved Inventory Lines",
|
||||
)
|
||||
involved_inv_line_count = fields.Integer(compute="_compute_involved_inv_line_count")
|
||||
created_inventory_ids = fields.One2many(
|
||||
comodel_name="stock.inventory",
|
||||
string="Created Inventories",
|
||||
inverse_name="solving_slot_verification_request_id",
|
||||
help="These inventory adjustment were created from this SVR.",
|
||||
)
|
||||
created_inventory_count = fields.Integer(
|
||||
compute='_compute_created_inventory_count')
|
||||
created_inventory_count = fields.Integer(compute="_compute_created_inventory_count")
|
||||
|
||||
@api.multi
|
||||
def _get_involved_moves_domain(self):
|
||||
domain = ['|', ('location_id', '=', self.location_id.id),
|
||||
('location_dest_id', '=', self.location_id.id)]
|
||||
domain = [
|
||||
"|",
|
||||
("location_id", "=", self.location_id.id),
|
||||
("location_dest_id", "=", self.location_id.id),
|
||||
]
|
||||
if self.product_id:
|
||||
domain.append(('product_id', '=', self.product_id.id))
|
||||
domain.append(("product_id", "=", self.product_id.id))
|
||||
return domain
|
||||
|
||||
@api.multi
|
||||
def _get_involved_lines_domain(self):
|
||||
domain = [('location_id', '=', self.location_id.id)]
|
||||
domain = [("location_id", "=", self.location_id.id)]
|
||||
if self.product_id:
|
||||
domain.append(('product_id', '=', self.product_id.id))
|
||||
domain.append(("product_id", "=", self.product_id.id))
|
||||
return domain
|
||||
|
||||
@api.multi
|
||||
def _get_involved_lines_and_locations(self):
|
||||
involved_moves = self.env['stock.move'].search(
|
||||
self._get_involved_moves_domain())
|
||||
involved_lines = self.env['stock.inventory.line'].search(
|
||||
self._get_involved_lines_domain())
|
||||
involved_moves = self.env["stock.move"].search(
|
||||
self._get_involved_moves_domain()
|
||||
)
|
||||
involved_lines = self.env["stock.inventory.line"].search(
|
||||
self._get_involved_lines_domain()
|
||||
)
|
||||
return involved_moves, involved_lines
|
||||
|
||||
@api.multi
|
||||
def action_confirm(self):
|
||||
self.write({'state': 'open'})
|
||||
self.write({"state": "open"})
|
||||
for rec in self:
|
||||
involved_moves, involved_lines = \
|
||||
rec._get_involved_lines_and_locations()
|
||||
involved_moves, involved_lines = rec._get_involved_lines_and_locations()
|
||||
rec.involved_move_ids = involved_moves
|
||||
rec.involved_inv_line_ids = involved_lines
|
||||
return True
|
||||
|
||||
@api.multi
|
||||
def action_cancel(self):
|
||||
self.write({'state': 'cancelled'})
|
||||
self.write({"state": "cancelled"})
|
||||
return True
|
||||
|
||||
@api.multi
|
||||
def action_solved(self):
|
||||
self.write({'state': 'done'})
|
||||
self.write({"state": "done"})
|
||||
return True
|
||||
|
||||
@api.multi
|
||||
def action_view_moves(self):
|
||||
action = self.env.ref('stock.stock_move_action')
|
||||
action = self.env.ref("stock.stock_move_action")
|
||||
result = action.read()[0]
|
||||
result['context'] = {}
|
||||
moves_ids = self.mapped('involved_move_ids').ids
|
||||
result["context"] = {}
|
||||
moves_ids = self.mapped("involved_move_ids").ids
|
||||
if len(moves_ids) > 1:
|
||||
result['domain'] = [('id', 'in', moves_ids)]
|
||||
result["domain"] = [("id", "in", moves_ids)]
|
||||
elif len(moves_ids) == 1:
|
||||
res = self.env.ref('stock.view_move_form', False)
|
||||
result['views'] = [(res and res.id or False, 'form')]
|
||||
result['res_id'] = moves_ids and moves_ids[0] or False
|
||||
res = self.env.ref("stock.view_move_form", False)
|
||||
result["views"] = [(res and res.id or False, "form")]
|
||||
result["res_id"] = moves_ids and moves_ids[0] or False
|
||||
return result
|
||||
|
||||
@api.multi
|
||||
def action_view_inv_lines(self):
|
||||
action = self.env.ref(
|
||||
'stock_inventory_verification_request.action_inv_adj_line_tree')
|
||||
"stock_inventory_verification_request.action_inv_adj_line_tree"
|
||||
)
|
||||
result = action.read()[0]
|
||||
result['context'] = {}
|
||||
line_ids = self.mapped('involved_inv_line_ids').ids
|
||||
result["context"] = {}
|
||||
line_ids = self.mapped("involved_inv_line_ids").ids
|
||||
if len(line_ids) > 1:
|
||||
result['domain'] = [('id', 'in', line_ids)]
|
||||
result["domain"] = [("id", "in", line_ids)]
|
||||
elif len(line_ids) == 1:
|
||||
res = self.env.ref('stock_inventory_verification_request.'
|
||||
'view_inventory_line_form', False)
|
||||
result['views'] = [(res and res.id or False, 'form')]
|
||||
result['res_id'] = line_ids and line_ids[0] or False
|
||||
res = self.env.ref(
|
||||
"stock_inventory_verification_request." "view_inventory_line_form",
|
||||
False,
|
||||
)
|
||||
result["views"] = [(res and res.id or False, "form")]
|
||||
result["res_id"] = line_ids and line_ids[0] or False
|
||||
return result
|
||||
|
||||
def action_create_inventory_adjustment(self):
|
||||
self.ensure_one()
|
||||
inventory = self.env["stock.inventory"].sudo().create({
|
||||
"name": "Inventory Adjustment from %s" % self.name,
|
||||
"filter": "product" if self.product_id else "none",
|
||||
"location_id": self.location_id.id,
|
||||
"product_id": self.product_id.id,
|
||||
"solving_slot_verification_request_id": self.id,
|
||||
"company_id": self.company_id.id,
|
||||
})
|
||||
action = self.env.ref('stock.action_inventory_form')
|
||||
inventory = (
|
||||
self.env["stock.inventory"]
|
||||
.sudo()
|
||||
.create(
|
||||
{
|
||||
"name": "Inventory Adjustment from %s" % self.name,
|
||||
"filter": "product" if self.product_id else "none",
|
||||
"location_id": self.location_id.id,
|
||||
"product_id": self.product_id.id,
|
||||
"solving_slot_verification_request_id": self.id,
|
||||
"company_id": self.company_id.id,
|
||||
}
|
||||
)
|
||||
)
|
||||
action = self.env.ref("stock.action_inventory_form")
|
||||
result = action.read()[0]
|
||||
|
||||
res = self.env.ref('stock.view_inventory_form', False)
|
||||
result['views'] = [(res and res.id or False, 'form')]
|
||||
result['res_id'] = inventory.id
|
||||
res = self.env.ref("stock.view_inventory_form", False)
|
||||
result["views"] = [(res and res.id or False, "form")]
|
||||
result["res_id"] = inventory.id
|
||||
return result
|
||||
|
||||
@api.multi
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<odoo noupdate="1">
|
||||
|
||||
<record id="stock_slot_verification_request_comp_rule" model="ir.rule">
|
||||
<field name="name">Stock Slot Verification Request multi-company</field>
|
||||
<field name="model_id" ref="model_stock_slot_verification_request"/>
|
||||
<field name="global" eval="True"/>
|
||||
<field name="domain_force">['|',('company_id','=',False),('company_id','child_of',[user.company_id.id])]</field>
|
||||
<field name="model_id" ref="model_stock_slot_verification_request" />
|
||||
<field name="global" eval="True" />
|
||||
<field
|
||||
name="domain_force"
|
||||
>['|',('company_id','=',False),('company_id','child_of',[user.company_id.id])]</field>
|
||||
</record>
|
||||
|
||||
</odoo>
|
||||
|
||||
@@ -7,146 +7,181 @@ from odoo.exceptions import AccessError
|
||||
|
||||
|
||||
class TestStockVerificationRequest(common.SavepointCase):
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
super().setUpClass()
|
||||
# disable tracking test suite wise
|
||||
cls.env = cls.env(context=dict(cls.env.context, tracking_disable=True))
|
||||
cls.user_model = cls.env["res.users"].with_context(
|
||||
no_reset_password=True)
|
||||
cls.user_model = cls.env["res.users"].with_context(no_reset_password=True)
|
||||
|
||||
cls.obj_wh = cls.env['stock.warehouse']
|
||||
cls.obj_location = cls.env['stock.location']
|
||||
cls.obj_inventory = cls.env['stock.inventory']
|
||||
cls.obj_product = cls.env['product.product']
|
||||
cls.obj_svr = cls.env['stock.slot.verification.request']
|
||||
cls.obj_move = cls.env['stock.move']
|
||||
cls.obj_wh = cls.env["stock.warehouse"]
|
||||
cls.obj_location = cls.env["stock.location"]
|
||||
cls.obj_inventory = cls.env["stock.inventory"]
|
||||
cls.obj_product = cls.env["product.product"]
|
||||
cls.obj_svr = cls.env["stock.slot.verification.request"]
|
||||
cls.obj_move = cls.env["stock.move"]
|
||||
|
||||
cls.product1 = cls.obj_product.create({
|
||||
'name': 'Test Product 1',
|
||||
'type': 'product',
|
||||
'default_code': 'PROD1',
|
||||
})
|
||||
cls.product2 = cls.obj_product.create({
|
||||
'name': 'Test Product 2',
|
||||
'type': 'product',
|
||||
'default_code': 'PROD2',
|
||||
})
|
||||
cls.test_loc = cls.obj_location.create({
|
||||
'name': 'Test Location',
|
||||
'usage': 'internal',
|
||||
'discrepancy_threshold': 0.1
|
||||
})
|
||||
cls.product1 = cls.obj_product.create(
|
||||
{
|
||||
"name": "Test Product 1",
|
||||
"type": "product",
|
||||
"default_code": "PROD1",
|
||||
}
|
||||
)
|
||||
cls.product2 = cls.obj_product.create(
|
||||
{
|
||||
"name": "Test Product 2",
|
||||
"type": "product",
|
||||
"default_code": "PROD2",
|
||||
}
|
||||
)
|
||||
cls.test_loc = cls.obj_location.create(
|
||||
{"name": "Test Location", "usage": "internal", "discrepancy_threshold": 0.1}
|
||||
)
|
||||
|
||||
# Create Stock manager able to force validation on inventories.
|
||||
group_stock_man = cls.env.ref('stock.group_stock_manager')
|
||||
group_stock_man = cls.env.ref("stock.group_stock_manager")
|
||||
group_inventory_all = cls.env.ref(
|
||||
'stock_inventory_discrepancy.'
|
||||
'group_stock_inventory_validation_always')
|
||||
cls.manager = cls.env['res.users'].create({
|
||||
'name': 'Test Manager',
|
||||
'login': 'manager',
|
||||
'email': 'test.manager@example.com',
|
||||
'groups_id': [(6, 0, [group_stock_man.id, group_inventory_all.id])]
|
||||
})
|
||||
group_stock_user = cls.env.ref('stock.group_stock_user')
|
||||
cls.user = cls.env['res.users'].create({
|
||||
'name': 'Test User',
|
||||
'login': 'user',
|
||||
'email': 'test.user@example.com',
|
||||
'groups_id': [(6, 0, [group_stock_user.id])]
|
||||
})
|
||||
"stock_inventory_discrepancy." "group_stock_inventory_validation_always"
|
||||
)
|
||||
cls.manager = cls.env["res.users"].create(
|
||||
{
|
||||
"name": "Test Manager",
|
||||
"login": "manager",
|
||||
"email": "test.manager@example.com",
|
||||
"groups_id": [(6, 0, [group_stock_man.id, group_inventory_all.id])],
|
||||
}
|
||||
)
|
||||
group_stock_user = cls.env.ref("stock.group_stock_user")
|
||||
cls.user = cls.env["res.users"].create(
|
||||
{
|
||||
"name": "Test User",
|
||||
"login": "user",
|
||||
"email": "test.user@example.com",
|
||||
"groups_id": [(6, 0, [group_stock_user.id])],
|
||||
}
|
||||
)
|
||||
|
||||
cls.starting_inv = cls.obj_inventory.create({
|
||||
'name': 'Starting inventory',
|
||||
'filter': 'product',
|
||||
'line_ids': [
|
||||
(0, 0, {
|
||||
'product_id': cls.product1.id,
|
||||
'product_uom_id': cls.env.ref(
|
||||
"uom.product_uom_unit").id,
|
||||
'product_qty': 2.0,
|
||||
'location_id': cls.test_loc.id,
|
||||
}),
|
||||
(0, 0, {
|
||||
'product_id': cls.product2.id,
|
||||
'product_uom_id': cls.env.ref(
|
||||
"uom.product_uom_unit").id,
|
||||
'product_qty': 4.0,
|
||||
'location_id': cls.test_loc.id,
|
||||
}),
|
||||
],
|
||||
})
|
||||
cls.starting_inv = cls.obj_inventory.create(
|
||||
{
|
||||
"name": "Starting inventory",
|
||||
"filter": "product",
|
||||
"line_ids": [
|
||||
(
|
||||
0,
|
||||
0,
|
||||
{
|
||||
"product_id": cls.product1.id,
|
||||
"product_uom_id": cls.env.ref("uom.product_uom_unit").id,
|
||||
"product_qty": 2.0,
|
||||
"location_id": cls.test_loc.id,
|
||||
},
|
||||
),
|
||||
(
|
||||
0,
|
||||
0,
|
||||
{
|
||||
"product_id": cls.product2.id,
|
||||
"product_uom_id": cls.env.ref("uom.product_uom_unit").id,
|
||||
"product_qty": 4.0,
|
||||
"location_id": cls.test_loc.id,
|
||||
},
|
||||
),
|
||||
],
|
||||
}
|
||||
)
|
||||
cls.starting_inv.action_force_done()
|
||||
|
||||
def test_svr_creation(self):
|
||||
"""Tests the creation of Slot Verification Requests."""
|
||||
inventory = self.obj_inventory.create({
|
||||
'name': 'Generate over discrepancy in both lines.',
|
||||
'location_id': self.test_loc.id,
|
||||
'filter': 'none',
|
||||
'line_ids': [
|
||||
(0, 0, {
|
||||
'product_id': self.product1.id,
|
||||
'product_uom_id': self.env.ref(
|
||||
"uom.product_uom_unit").id,
|
||||
'product_qty': 3.0,
|
||||
'location_id': self.test_loc.id,
|
||||
}),
|
||||
(0, 0, {
|
||||
'product_id': self.product2.id,
|
||||
'product_uom_id': self.env.ref(
|
||||
"uom.product_uom_unit").id,
|
||||
'product_qty': 3.0,
|
||||
'location_id': self.test_loc.id,
|
||||
})
|
||||
],
|
||||
})
|
||||
inventory.with_context({'normal_view': True}).action_validate()
|
||||
self.assertEqual(inventory.state, 'pending',
|
||||
'Inventory Adjustment not changing to Pending to '
|
||||
'Approve.')
|
||||
inventory = self.obj_inventory.create(
|
||||
{
|
||||
"name": "Generate over discrepancy in both lines.",
|
||||
"location_id": self.test_loc.id,
|
||||
"filter": "none",
|
||||
"line_ids": [
|
||||
(
|
||||
0,
|
||||
0,
|
||||
{
|
||||
"product_id": self.product1.id,
|
||||
"product_uom_id": self.env.ref("uom.product_uom_unit").id,
|
||||
"product_qty": 3.0,
|
||||
"location_id": self.test_loc.id,
|
||||
},
|
||||
),
|
||||
(
|
||||
0,
|
||||
0,
|
||||
{
|
||||
"product_id": self.product2.id,
|
||||
"product_uom_id": self.env.ref("uom.product_uom_unit").id,
|
||||
"product_qty": 3.0,
|
||||
"location_id": self.test_loc.id,
|
||||
},
|
||||
),
|
||||
],
|
||||
}
|
||||
)
|
||||
inventory.with_context({"normal_view": True}).action_validate()
|
||||
self.assertEqual(
|
||||
inventory.state,
|
||||
"pending",
|
||||
"Inventory Adjustment not changing to Pending to " "Approve.",
|
||||
)
|
||||
previous_count = len(self.obj_svr.search([]))
|
||||
inventory.sudo(self.user).action_request_verification()
|
||||
current_count = len(self.obj_svr.search([]))
|
||||
self.assertEqual(current_count, previous_count + 2,
|
||||
'Slot Verification Request not created.')
|
||||
self.assertEqual(
|
||||
current_count, previous_count + 2, "Slot Verification Request not created."
|
||||
)
|
||||
# Test the method to open SVR from inventory lines:
|
||||
inventory.line_ids[0].action_open_svr()
|
||||
|
||||
def test_svr_workflow(self):
|
||||
"""Tests workflow of Slot Verification Request."""
|
||||
test_svr = self.env['stock.slot.verification.request'].create({
|
||||
'location_id': self.test_loc.id,
|
||||
'state': 'wait',
|
||||
'product_id': self.product1.id,
|
||||
})
|
||||
self.assertEqual(test_svr.state, 'wait',
|
||||
'Slot Verification Request not created from scratch.')
|
||||
test_svr = self.env["stock.slot.verification.request"].create(
|
||||
{
|
||||
"location_id": self.test_loc.id,
|
||||
"state": "wait",
|
||||
"product_id": self.product1.id,
|
||||
}
|
||||
)
|
||||
self.assertEqual(
|
||||
test_svr.state,
|
||||
"wait",
|
||||
"Slot Verification Request not created from scratch.",
|
||||
)
|
||||
with self.assertRaises(AccessError):
|
||||
test_svr.sudo(self.user).action_confirm()
|
||||
test_svr.sudo(self.manager).action_confirm()
|
||||
self.assertEqual(test_svr.state, 'open',
|
||||
'Slot Verification Request not confirmed properly.')
|
||||
self.assertEqual(
|
||||
test_svr.state, "open", "Slot Verification Request not confirmed properly."
|
||||
)
|
||||
test_svr.sudo(self.manager).action_solved()
|
||||
self.assertEqual(test_svr.state, 'done',
|
||||
'Slot Verification Request not marked as solved.')
|
||||
self.assertEqual(
|
||||
test_svr.state, "done", "Slot Verification Request not marked as solved."
|
||||
)
|
||||
test_svr.sudo(self.manager).action_cancel()
|
||||
self.assertEqual(test_svr.state, 'cancelled',
|
||||
'Slot Verification Request not marked as cancelled.')
|
||||
self.assertEqual(
|
||||
test_svr.state,
|
||||
"cancelled",
|
||||
"Slot Verification Request not marked as cancelled.",
|
||||
)
|
||||
|
||||
def test_view_methods(self):
|
||||
"""Tests the methods used to handle de UI."""
|
||||
test_svr = self.env['stock.slot.verification.request'].create({
|
||||
'location_id': self.test_loc.id,
|
||||
'state': 'wait',
|
||||
'product_id': self.product1.id,
|
||||
})
|
||||
test_svr = self.env["stock.slot.verification.request"].create(
|
||||
{
|
||||
"location_id": self.test_loc.id,
|
||||
"state": "wait",
|
||||
"product_id": self.product1.id,
|
||||
}
|
||||
)
|
||||
test_svr.sudo(self.manager).action_confirm()
|
||||
self.assertEqual(test_svr.involved_move_count, 1,
|
||||
'Unexpected involved move')
|
||||
self.assertEqual(test_svr.involved_inv_line_count, 1,
|
||||
'Unexpected involved inventory line')
|
||||
self.assertEqual(test_svr.involved_move_count, 1, "Unexpected involved move")
|
||||
self.assertEqual(
|
||||
test_svr.involved_inv_line_count, 1, "Unexpected involved inventory line"
|
||||
)
|
||||
test_svr.action_view_inv_lines()
|
||||
test_svr.action_view_moves()
|
||||
|
||||
@@ -1,41 +1,51 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<!-- Copyright 2020 ForgeFlow S.L.
|
||||
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). -->
|
||||
|
||||
<odoo>
|
||||
|
||||
<record id="view_inventory_form" model="ir.ui.view">
|
||||
<field name="name">Inventory form view - SVR extension</field>
|
||||
<field name="model">stock.inventory</field>
|
||||
<field name="inherit_id" ref="stock_inventory_discrepancy.view_inventory_form"/>
|
||||
<field
|
||||
name="inherit_id"
|
||||
ref="stock_inventory_discrepancy.view_inventory_form"
|
||||
/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//button[@name='action_validate']"
|
||||
position="after">
|
||||
<button name="action_request_verification"
|
||||
string="Request Verification" type="object"
|
||||
class="oe_highlight"
|
||||
attrs="{'invisible': ['|',('state', '!=', 'pending'),('requested_verification', '=', True)]}"
|
||||
groups="stock.group_stock_user"/>
|
||||
<xpath expr="//button[@name='action_validate']" position="after">
|
||||
<button
|
||||
name="action_request_verification"
|
||||
string="Request Verification"
|
||||
type="object"
|
||||
class="oe_highlight"
|
||||
attrs="{'invisible': ['|',('state', '!=', 'pending'),('requested_verification', '=', True)]}"
|
||||
groups="stock.group_stock_user"
|
||||
/>
|
||||
</xpath>
|
||||
<field name="name" position="after">
|
||||
<field name="requested_verification" invisible="1"/>
|
||||
<field name="requested_verification" invisible="1" />
|
||||
</field>
|
||||
<notebook position="inside">
|
||||
<page string="Slot Verification Requests"
|
||||
groups="stock.group_stock_manager">
|
||||
<page
|
||||
string="Slot Verification Requests"
|
||||
groups="stock.group_stock_manager"
|
||||
>
|
||||
<group>
|
||||
<field name="slot_verification_ids" nolabel="1"/>
|
||||
<field name="slot_verification_ids" nolabel="1" />
|
||||
</group>
|
||||
</page>
|
||||
</notebook>
|
||||
<xpath expr="//field[@name='line_ids']/tree/field[@name='discrepancy_threshold']"
|
||||
position="after">
|
||||
<field name="slot_verification_ids" invisible="1"/>
|
||||
<button string="Slot Verification Request"
|
||||
attrs="{'invisible': [('slot_verification_ids', '=', [])]}"
|
||||
name="action_open_svr"
|
||||
type="object"
|
||||
icon="fa-sticky-note"/>
|
||||
<xpath
|
||||
expr="//field[@name='line_ids']/tree/field[@name='discrepancy_threshold']"
|
||||
position="after"
|
||||
>
|
||||
<field name="slot_verification_ids" invisible="1" />
|
||||
<button
|
||||
string="Slot Verification Request"
|
||||
attrs="{'invisible': [('slot_verification_ids', '=', [])]}"
|
||||
name="action_open_svr"
|
||||
type="object"
|
||||
icon="fa-sticky-note"
|
||||
/>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
@@ -47,32 +57,32 @@
|
||||
<form string="Inventory Line">
|
||||
<sheet>
|
||||
<div class="oe_title">
|
||||
<h3>Inventory Adjustment Line <field name="id"/></h3>
|
||||
<h3>Inventory Adjustment Line <field name="id" /></h3>
|
||||
</div>
|
||||
<group>
|
||||
<group col="2">
|
||||
<field name="product_id" readonly="1"/>
|
||||
<field name="inventory_id" readonly="1"/>
|
||||
<field name="state"/>
|
||||
<field name="create_date" readonly="1"/>
|
||||
<field name="location_id" readonly="1"/>
|
||||
<field name="package_id" readonly="1"/>
|
||||
<field name="partner_id" readonly="1"/>
|
||||
<field name="prod_lot_id" readonly="1"/>
|
||||
<field name="company_id"/>
|
||||
<field name="product_id" readonly="1" />
|
||||
<field name="inventory_id" readonly="1" />
|
||||
<field name="state" />
|
||||
<field name="create_date" readonly="1" />
|
||||
<field name="location_id" readonly="1" />
|
||||
<field name="package_id" readonly="1" />
|
||||
<field name="partner_id" readonly="1" />
|
||||
<field name="prod_lot_id" readonly="1" />
|
||||
<field name="company_id" />
|
||||
</group>
|
||||
<group col="2">
|
||||
<field name="theoretical_qty"/>
|
||||
<field name="product_qty" readonly="1"/>
|
||||
<field name="product_uom_id" readonly="1"/>
|
||||
<field name="discrepancy_qty"/>
|
||||
<label for="discrepancy_percent"/>
|
||||
<field name="theoretical_qty" />
|
||||
<field name="product_qty" readonly="1" />
|
||||
<field name="product_uom_id" readonly="1" />
|
||||
<field name="discrepancy_qty" />
|
||||
<label for="discrepancy_percent" />
|
||||
<div>
|
||||
<field name="discrepancy_percent" class="oe_inline"/> %
|
||||
<field name="discrepancy_percent" class="oe_inline" /> %
|
||||
</div>
|
||||
<label for="discrepancy_threshold"/>
|
||||
<label for="discrepancy_threshold" />
|
||||
<div>
|
||||
<field name="discrepancy_threshold" class="oe_inline"/> %
|
||||
<field name="discrepancy_threshold" class="oe_inline" /> %
|
||||
</div>
|
||||
</group>
|
||||
</group>
|
||||
@@ -84,10 +94,10 @@
|
||||
<record id="view_inventory_line_tree" model="ir.ui.view">
|
||||
<field name="name">Inventory Line tree view - discrepancy extension</field>
|
||||
<field name="model">stock.inventory.line</field>
|
||||
<field name="inherit_id" ref="stock.stock_inventory_line_tree"/>
|
||||
<field name="inherit_id" ref="stock.stock_inventory_line_tree" />
|
||||
<field name="arch" type="xml">
|
||||
<field name="location_id" position="after">
|
||||
<field name="create_date" readonly="1"/>
|
||||
<field name="create_date" readonly="1" />
|
||||
</field>
|
||||
</field>
|
||||
</record>
|
||||
@@ -96,7 +106,7 @@
|
||||
<field name="name">Open Inventory Adjustment Lines</field>
|
||||
<field name="res_model">stock.inventory.line</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_id" ref="stock.stock_inventory_line_tree"/>
|
||||
<field name="view_id" ref="stock.stock_inventory_line_tree" />
|
||||
</record>
|
||||
|
||||
</odoo>
|
||||
|
||||
@@ -1,18 +1,19 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<!-- Copyright 2020 ForgeFlow S.L.
|
||||
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). -->
|
||||
|
||||
<odoo>
|
||||
|
||||
<record id="view_location_form" model="ir.ui.view">
|
||||
<field name="model">stock.location</field>
|
||||
<field name="inherit_id" ref="stock.view_location_form"/>
|
||||
<field name="inherit_id" ref="stock.view_location_form" />
|
||||
<field name="arch" type="xml">
|
||||
<button name="toggle_active" position="before">
|
||||
<button string="Slot Verification Request"
|
||||
name="action_open_svr"
|
||||
type="object"
|
||||
icon="fa-sticky-note"/>
|
||||
<button
|
||||
string="Slot Verification Request"
|
||||
name="action_open_svr"
|
||||
type="object"
|
||||
icon="fa-sticky-note"
|
||||
/>
|
||||
</button>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<!-- Copyright 2020 ForgeFlow S.L.
|
||||
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). -->
|
||||
|
||||
<odoo>
|
||||
|
||||
<record id="stock_slot_verification_request_tree_view" model="ir.ui.view">
|
||||
@@ -9,15 +8,15 @@
|
||||
<field name="model">stock.slot.verification.request</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Stock Slot Verification Request">
|
||||
<field name="name"/>
|
||||
<field name="location_id"/>
|
||||
<field name="product_id"/>
|
||||
<field name="create_uid" readonly="1"/>
|
||||
<field name="create_date" readonly="1"/>
|
||||
<field name="responsible_id"/>
|
||||
<field name="inventory_id"/>
|
||||
<field name="state"/>
|
||||
<field name="company_id" groups="base.group_multi_company"/>
|
||||
<field name="name" />
|
||||
<field name="location_id" />
|
||||
<field name="product_id" />
|
||||
<field name="create_uid" readonly="1" />
|
||||
<field name="create_date" readonly="1" />
|
||||
<field name="responsible_id" />
|
||||
<field name="inventory_id" />
|
||||
<field name="state" />
|
||||
<field name="company_id" groups="base.group_multi_company" />
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
@@ -28,71 +27,110 @@
|
||||
<field name="arch" type="xml">
|
||||
<form string="Stock Slot Verification Request">
|
||||
<header>
|
||||
<button name="action_create_inventory_adjustment"
|
||||
type="object" states="open" string="Create Inventory Adjustment"
|
||||
class="oe_highlight" />
|
||||
<button name="action_confirm"
|
||||
type="object" states="wait" string="Confirm"
|
||||
class="oe_highlight" />
|
||||
<button name="action_solved"
|
||||
type="object" states="open" string="Mark as Solved"/>
|
||||
<button name="action_cancel"
|
||||
type="object" states="open"
|
||||
string="Mark as Cancelled"/>
|
||||
<field name="state" widget="statusbar"
|
||||
statusbar_visible="wait,open,done"/>
|
||||
<button
|
||||
name="action_create_inventory_adjustment"
|
||||
type="object"
|
||||
states="open"
|
||||
string="Create Inventory Adjustment"
|
||||
class="oe_highlight"
|
||||
/>
|
||||
<button
|
||||
name="action_confirm"
|
||||
type="object"
|
||||
states="wait"
|
||||
string="Confirm"
|
||||
class="oe_highlight"
|
||||
/>
|
||||
<button
|
||||
name="action_solved"
|
||||
type="object"
|
||||
states="open"
|
||||
string="Mark as Solved"
|
||||
/>
|
||||
<button
|
||||
name="action_cancel"
|
||||
type="object"
|
||||
states="open"
|
||||
string="Mark as Cancelled"
|
||||
/>
|
||||
<field
|
||||
name="state"
|
||||
widget="statusbar"
|
||||
statusbar_visible="wait,open,done"
|
||||
/>
|
||||
</header>
|
||||
<sheet>
|
||||
<div class="oe_button_box" name="button_box"
|
||||
attrs="{'invisible':
|
||||
[('state', 'not in', ('open'))]}">
|
||||
<button name="action_view_inventories"
|
||||
type="object" class="oe_stat_button"
|
||||
icon="fa-building-o">
|
||||
<field name="created_inventory_count"
|
||||
widget="statinfo"
|
||||
help="Inventory Adjustments created from this SVR."
|
||||
modifiers="{'readonly': true}"
|
||||
string="Inv. Adj. Created"/>
|
||||
<div
|
||||
class="oe_button_box"
|
||||
name="button_box"
|
||||
attrs="{'invisible':
|
||||
[('state', 'not in', ('open'))]}"
|
||||
>
|
||||
<button
|
||||
name="action_view_inventories"
|
||||
type="object"
|
||||
class="oe_stat_button"
|
||||
icon="fa-building-o"
|
||||
>
|
||||
<field
|
||||
name="created_inventory_count"
|
||||
widget="statinfo"
|
||||
help="Inventory Adjustments created from this SVR."
|
||||
modifiers="{'readonly': true}"
|
||||
string="Inv. Adj. Created"
|
||||
/>
|
||||
</button>
|
||||
<button name="action_view_moves"
|
||||
type="object" class="oe_stat_button"
|
||||
icon="fa-arrows-h">
|
||||
<field name="involved_move_count"
|
||||
widget="statinfo"
|
||||
help="Stock Moves related to the given location and product."
|
||||
modifiers="{'readonly': true}"
|
||||
string="Stock Moves Involved"/>
|
||||
<button
|
||||
name="action_view_moves"
|
||||
type="object"
|
||||
class="oe_stat_button"
|
||||
icon="fa-arrows-h"
|
||||
>
|
||||
<field
|
||||
name="involved_move_count"
|
||||
widget="statinfo"
|
||||
help="Stock Moves related to the given location and product."
|
||||
modifiers="{'readonly': true}"
|
||||
string="Stock Moves Involved"
|
||||
/>
|
||||
</button>
|
||||
<button name="action_view_inv_lines"
|
||||
type="object" class="oe_stat_button"
|
||||
icon="fa-list">
|
||||
<field name="involved_inv_line_count"
|
||||
widget="statinfo"
|
||||
help="Inventory Adjustment Lines related to the given location and product."
|
||||
modifiers="{'readonly': true}"
|
||||
string="Inv. Adj. Lines Involved"/>
|
||||
<button
|
||||
name="action_view_inv_lines"
|
||||
type="object"
|
||||
class="oe_stat_button"
|
||||
icon="fa-list"
|
||||
>
|
||||
<field
|
||||
name="involved_inv_line_count"
|
||||
widget="statinfo"
|
||||
help="Inventory Adjustment Lines related to the given location and product."
|
||||
modifiers="{'readonly': true}"
|
||||
string="Inv. Adj. Lines Involved"
|
||||
/>
|
||||
</button>
|
||||
</div>
|
||||
<div class="oe_title">
|
||||
<label string="Slot Verification Request" for="name"/>
|
||||
<label string="Slot Verification Request" for="name" />
|
||||
<h1>
|
||||
<field name="name"/>
|
||||
<field name="name" />
|
||||
</h1>
|
||||
</div>
|
||||
<group>
|
||||
<group>
|
||||
<field name="location_id"/>
|
||||
<field name="product_id"/>
|
||||
<field name="company_id" groups="base.group_multi_company"/>
|
||||
<field name="create_uid" readonly="1"/>
|
||||
<field name="create_date" readonly="1"/>
|
||||
<field name="responsible_id"/>
|
||||
<field name="inventory_id"/>
|
||||
<field name="inventory_line_id"/>
|
||||
<field name="location_id" />
|
||||
<field name="product_id" />
|
||||
<field
|
||||
name="company_id"
|
||||
groups="base.group_multi_company"
|
||||
/>
|
||||
<field name="create_uid" readonly="1" />
|
||||
<field name="create_date" readonly="1" />
|
||||
<field name="responsible_id" />
|
||||
<field name="inventory_id" />
|
||||
<field name="inventory_line_id" />
|
||||
</group>
|
||||
<group>
|
||||
<field name="notes"/>
|
||||
<field name="notes" />
|
||||
</group>
|
||||
</group>
|
||||
</sheet>
|
||||
@@ -109,36 +147,55 @@
|
||||
<field name="model">stock.slot.verification.request</field>
|
||||
<field name="arch" type="xml">
|
||||
<search string="Stock Slot Verification Request">
|
||||
<field name="name"/>
|
||||
<field name="location_id"/>
|
||||
<field name="product_id"/>
|
||||
<field name="company_id" groups="base.group_multi_company"/>
|
||||
<field name="responsible_id"/>
|
||||
<separator/>
|
||||
<filter name="wait_state" string="Waiting Actions"
|
||||
domain="[('state','=', 'wait')]"/>
|
||||
<filter name="open_state" string="In Progress"
|
||||
domain="[('state','=', 'open')]"/>
|
||||
<filter name="done_state" string="Done"
|
||||
domain="[('state','=', 'done')]"/>
|
||||
<filter name="cancelled_state" string="Cancelled"
|
||||
domain="[('state','=', 'cancelled')]"/>
|
||||
<separator/>
|
||||
<filter name="assigned_to_user" string="Assigned to me"
|
||||
domain="[('responsible_id','=', uid)]"/>
|
||||
<field name="name" />
|
||||
<field name="location_id" />
|
||||
<field name="product_id" />
|
||||
<field name="company_id" groups="base.group_multi_company" />
|
||||
<field name="responsible_id" />
|
||||
<separator />
|
||||
<filter
|
||||
name="wait_state"
|
||||
string="Waiting Actions"
|
||||
domain="[('state','=', 'wait')]"
|
||||
/>
|
||||
<filter
|
||||
name="open_state"
|
||||
string="In Progress"
|
||||
domain="[('state','=', 'open')]"
|
||||
/>
|
||||
<filter
|
||||
name="done_state"
|
||||
string="Done"
|
||||
domain="[('state','=', 'done')]"
|
||||
/>
|
||||
<filter
|
||||
name="cancelled_state"
|
||||
string="Cancelled"
|
||||
domain="[('state','=', 'cancelled')]"
|
||||
/>
|
||||
<separator />
|
||||
<filter
|
||||
name="assigned_to_user"
|
||||
string="Assigned to me"
|
||||
domain="[('responsible_id','=', uid)]"
|
||||
/>
|
||||
</search>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<act_window id="action_slot_verification_request"
|
||||
name="Stock Slot Verification Request"
|
||||
res_model="stock.slot.verification.request"
|
||||
context="{'search_default_wait_state':1,'search_default_open_state':1}"
|
||||
view_mode="tree,form" />
|
||||
<menuitem id="menu_slot_verification_request"
|
||||
name="Slot Verification Request"
|
||||
parent="stock.menu_stock_warehouse_mgmt"
|
||||
sequence="31"
|
||||
action="action_slot_verification_request" />
|
||||
<act_window
|
||||
id="action_slot_verification_request"
|
||||
name="Stock Slot Verification Request"
|
||||
res_model="stock.slot.verification.request"
|
||||
context="{'search_default_wait_state':1,'search_default_open_state':1}"
|
||||
view_mode="tree,form"
|
||||
/>
|
||||
<menuitem
|
||||
id="menu_slot_verification_request"
|
||||
name="Slot Verification Request"
|
||||
parent="stock.menu_stock_warehouse_mgmt"
|
||||
sequence="31"
|
||||
action="action_slot_verification_request"
|
||||
/>
|
||||
|
||||
</odoo>
|
||||
|
||||
Reference in New Issue
Block a user