mirror of
https://github.com/OCA/stock-logistics-warehouse.git
synced 2025-01-21 14:27:28 +02:00
[FIX] Various fixes:
- Error with the sequence number. - Visible texts that should be in uppercases. - order_id should only be visible if group_stock_request_order option is enabled. - adds more tests - adds consistency between models company-wise
This commit is contained in:
@@ -4,7 +4,7 @@
|
|||||||
{
|
{
|
||||||
"name": "Stock Request",
|
"name": "Stock Request",
|
||||||
"summary": "Internal request for stock",
|
"summary": "Internal request for stock",
|
||||||
"version": "11.0.2.0.0",
|
"version": "11.0.2.1.0",
|
||||||
"license": "LGPL-3",
|
"license": "LGPL-3",
|
||||||
"website": "https://github.com/stock-logistics-warehouse",
|
"website": "https://github.com/stock-logistics-warehouse",
|
||||||
"author": "Eficent, "
|
"author": "Eficent, "
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
|
|
||||||
from . import stock_request
|
from . import stock_request
|
||||||
from . import stock_request_allocation
|
from . import stock_request_allocation
|
||||||
from . import stock_request_order
|
from . import stock_request_order
|
||||||
@@ -7,3 +6,6 @@ from . import stock_picking
|
|||||||
from . import procurement_rule
|
from . import procurement_rule
|
||||||
from . import stock_move_line
|
from . import stock_move_line
|
||||||
from . import res_config_settings
|
from . import res_config_settings
|
||||||
|
from . import stock_warehouse
|
||||||
|
from . import stock_location
|
||||||
|
from . import stock_location_route
|
||||||
|
|||||||
@@ -11,4 +11,4 @@ class ResConfigSettings(models.TransientModel):
|
|||||||
implied_group='stock_request.group_stock_request_order')
|
implied_group='stock_request.group_stock_request_order')
|
||||||
|
|
||||||
module_stock_request_purchase = fields.Boolean(
|
module_stock_request_purchase = fields.Boolean(
|
||||||
string='Stock requests for purchase')
|
string='Stock Requests for Purchases')
|
||||||
|
|||||||
26
stock_request/models/stock_location.py
Normal file
26
stock_request/models/stock_location.py
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
# Copyright 2018 Eficent Business and IT Consulting Services, S.L.
|
||||||
|
# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html).
|
||||||
|
|
||||||
|
from odoo import api, models, _
|
||||||
|
from odoo.exceptions import ValidationError
|
||||||
|
|
||||||
|
|
||||||
|
class StockLocation(models.Model):
|
||||||
|
_inherit = 'stock.location'
|
||||||
|
|
||||||
|
@api.constrains('company_id')
|
||||||
|
def _check_company_stock_request(self):
|
||||||
|
if any(rec.company_id and self.env['stock.request'].search(
|
||||||
|
[('company_id', '!=', rec.company_id.id),
|
||||||
|
('location_id', '=', rec.id)], limit=1) for rec in self):
|
||||||
|
raise ValidationError(
|
||||||
|
_('You cannot change the company of the location, as it is '
|
||||||
|
'already assigned to stock requests that belong to '
|
||||||
|
'another company.'))
|
||||||
|
if any(rec.company_id and self.env['stock.request.order'].search(
|
||||||
|
[('company_id', '!=', rec.company_id.id),
|
||||||
|
('warehouse_id', '=', rec.id)], limit=1) for rec in self):
|
||||||
|
raise ValidationError(
|
||||||
|
_('You cannot change the company of the location, as it is '
|
||||||
|
'already assigned to stock request orders that belong to '
|
||||||
|
'another company.'))
|
||||||
19
stock_request/models/stock_location_route.py
Normal file
19
stock_request/models/stock_location_route.py
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
# Copyright 2018 Eficent Business and IT Consulting Services, S.L.
|
||||||
|
# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html).
|
||||||
|
|
||||||
|
from odoo import api, models, _
|
||||||
|
from odoo.exceptions import ValidationError
|
||||||
|
|
||||||
|
|
||||||
|
class StockLocationRoute(models.Model):
|
||||||
|
_inherit = 'stock.location.route'
|
||||||
|
|
||||||
|
@api.constrains('company_id')
|
||||||
|
def _check_company_stock_request(self):
|
||||||
|
if any(rec.company_id and self.env['stock.request'].search(
|
||||||
|
[('company_id', '!=', rec.company_id.id),
|
||||||
|
('route_id', '=', rec.id)], limit=1) for rec in self):
|
||||||
|
raise ValidationError(
|
||||||
|
_('You cannot change the company of the route, as it is '
|
||||||
|
'already assigned to stock requests that belong to '
|
||||||
|
'another company.'))
|
||||||
@@ -1,7 +1,8 @@
|
|||||||
# Copyright 2017 Eficent Business and IT Consulting Services, S.L.
|
# Copyright 2017 Eficent Business and IT Consulting Services, S.L.
|
||||||
# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html).
|
# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html).
|
||||||
|
|
||||||
from odoo import api, fields, models
|
from odoo import api, fields, models, _
|
||||||
|
from odoo.exceptions import ValidationError
|
||||||
|
|
||||||
|
|
||||||
class StockMove(models.Model):
|
class StockMove(models.Model):
|
||||||
@@ -26,3 +27,13 @@ class StockMove(models.Model):
|
|||||||
res['allocation_ids'] = [(4, m.id) for m in
|
res['allocation_ids'] = [(4, m.id) for m in
|
||||||
self.mapped('allocation_ids')]
|
self.mapped('allocation_ids')]
|
||||||
return res
|
return res
|
||||||
|
|
||||||
|
@api.constrains('company_id')
|
||||||
|
def _check_company_stock_request(self):
|
||||||
|
if any(self.env['stock.request.allocation'].search(
|
||||||
|
[('company_id', '!=', rec.company_id.id),
|
||||||
|
('stock_move_id', '=', rec.id)], limit=1)
|
||||||
|
for rec in self):
|
||||||
|
raise ValidationError(
|
||||||
|
_('The company of the stock request must match with '
|
||||||
|
'that of the location.'))
|
||||||
|
|||||||
@@ -43,8 +43,7 @@ class StockRequest(models.Model):
|
|||||||
name = fields.Char(
|
name = fields.Char(
|
||||||
'Name', copy=False, required=True, readonly=True,
|
'Name', copy=False, required=True, readonly=True,
|
||||||
states={'draft': [('readonly', False)]},
|
states={'draft': [('readonly', False)]},
|
||||||
default=lambda self: self.env['ir.sequence'].next_by_code(
|
default='/')
|
||||||
'stock.request'))
|
|
||||||
state = fields.Selection(selection=REQUEST_STATES, string='Status',
|
state = fields.Selection(selection=REQUEST_STATES, string='Status',
|
||||||
copy=False, default='draft', index=True,
|
copy=False, default='draft', index=True,
|
||||||
readonly=True, track_visibility='onchange',
|
readonly=True, track_visibility='onchange',
|
||||||
@@ -102,7 +101,7 @@ class StockRequest(models.Model):
|
|||||||
'stock.request'),
|
'stock.request'),
|
||||||
)
|
)
|
||||||
expected_date = fields.Datetime(
|
expected_date = fields.Datetime(
|
||||||
'Expected date', default=fields.Datetime.now, index=True,
|
'Expected Date', default=fields.Datetime.now, index=True,
|
||||||
required=True, readonly=True,
|
required=True, readonly=True,
|
||||||
states={'draft': [('readonly', False)]},
|
states={'draft': [('readonly', False)]},
|
||||||
help="Date when you expect to receive the goods.",
|
help="Date when you expect to receive the goods.",
|
||||||
@@ -213,6 +212,31 @@ class StockRequest(models.Model):
|
|||||||
result |= location
|
result |= location
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
@api.constrains('company_id', 'product_id', 'warehouse_id',
|
||||||
|
'location_id', 'route_id')
|
||||||
|
def _check_company_constrains(self):
|
||||||
|
""" Check if the related models have the same company """
|
||||||
|
for rec in self:
|
||||||
|
if rec.product_id.company_id and \
|
||||||
|
rec.product_id.company_id != rec.company_id:
|
||||||
|
raise ValidationError(
|
||||||
|
_('You have entered a product that is assigned '
|
||||||
|
'to another company.'))
|
||||||
|
if rec.location_id.company_id and \
|
||||||
|
rec.location_id.company_id != rec.company_id:
|
||||||
|
raise ValidationError(
|
||||||
|
_('You have entered a location that is '
|
||||||
|
'assigned to another company.'))
|
||||||
|
if rec.warehouse_id.company_id != rec.company_id:
|
||||||
|
raise ValidationError(
|
||||||
|
_('You have entered a warehouse that is '
|
||||||
|
'assigned to another company.'))
|
||||||
|
if rec.route_id and rec.route_id.company_id and \
|
||||||
|
rec.route_id.company_id != rec.company_id:
|
||||||
|
raise ValidationError(
|
||||||
|
_('You have entered a route that is '
|
||||||
|
'assigned to another company.'))
|
||||||
|
|
||||||
@api.constrains('product_id')
|
@api.constrains('product_id')
|
||||||
def _check_product_uom(self):
|
def _check_product_uom(self):
|
||||||
''' Check if the UoM has the same category as the
|
''' Check if the UoM has the same category as the
|
||||||
@@ -439,6 +463,14 @@ class StockRequest(models.Model):
|
|||||||
action['res_id'] = pickings.id
|
action['res_id'] = pickings.id
|
||||||
return action
|
return action
|
||||||
|
|
||||||
|
@api.model
|
||||||
|
def create(self, vals):
|
||||||
|
upd_vals = vals.copy()
|
||||||
|
if upd_vals.get('name', '/') == '/':
|
||||||
|
upd_vals['name'] = self.env['ir.sequence'].next_by_code(
|
||||||
|
'stock.request')
|
||||||
|
return super().create(upd_vals)
|
||||||
|
|
||||||
@api.multi
|
@api.multi
|
||||||
def unlink(self):
|
def unlink(self):
|
||||||
if self.filtered(lambda r: r.state != 'draft'):
|
if self.filtered(lambda r: r.state != 'draft'):
|
||||||
|
|||||||
@@ -12,6 +12,12 @@ class StockRequestAllocation(models.Model):
|
|||||||
comodel_name='stock.request',
|
comodel_name='stock.request',
|
||||||
required=True, ondelete='cascade',
|
required=True, ondelete='cascade',
|
||||||
)
|
)
|
||||||
|
company_id = fields.Many2one(string='Company',
|
||||||
|
comodel_name='res.company',
|
||||||
|
readonly=True,
|
||||||
|
related='stock_request_id.company_id',
|
||||||
|
store=True,
|
||||||
|
)
|
||||||
stock_move_id = fields.Many2one(string='Stock Move',
|
stock_move_id = fields.Many2one(string='Stock Move',
|
||||||
comodel_name='stock.move',
|
comodel_name='stock.move',
|
||||||
required=True, ondelete='cascade',
|
required=True, ondelete='cascade',
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html).
|
# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html).
|
||||||
|
|
||||||
from odoo import api, fields, models, _
|
from odoo import api, fields, models, _
|
||||||
from odoo.exceptions import UserError
|
from odoo.exceptions import UserError, ValidationError
|
||||||
|
|
||||||
REQUEST_STATES = [
|
REQUEST_STATES = [
|
||||||
('draft', 'Draft'),
|
('draft', 'Draft'),
|
||||||
@@ -34,8 +34,7 @@ class StockRequestOrder(models.Model):
|
|||||||
name = fields.Char(
|
name = fields.Char(
|
||||||
'Name', copy=False, required=True, readonly=True,
|
'Name', copy=False, required=True, readonly=True,
|
||||||
states={'draft': [('readonly', False)]},
|
states={'draft': [('readonly', False)]},
|
||||||
default=lambda self: self.env['ir.sequence'].next_by_code(
|
default='/')
|
||||||
'stock.request.order'))
|
|
||||||
state = fields.Selection(selection=REQUEST_STATES, string='Status',
|
state = fields.Selection(selection=REQUEST_STATES, string='Status',
|
||||||
copy=False, default='draft', index=True,
|
copy=False, default='draft', index=True,
|
||||||
readonly=True, track_visibility='onchange',
|
readonly=True, track_visibility='onchange',
|
||||||
@@ -69,7 +68,7 @@ class StockRequestOrder(models.Model):
|
|||||||
'stock.request.order'),
|
'stock.request.order'),
|
||||||
)
|
)
|
||||||
expected_date = fields.Datetime(
|
expected_date = fields.Datetime(
|
||||||
'Expected date', default=fields.Datetime.now, index=True,
|
'Expected Date', default=fields.Datetime.now, index=True,
|
||||||
required=True, readonly=True,
|
required=True, readonly=True,
|
||||||
states={'draft': [('readonly', False)]},
|
states={'draft': [('readonly', False)]},
|
||||||
help="Date when you expect to receive the goods.",
|
help="Date when you expect to receive the goods.",
|
||||||
@@ -242,8 +241,33 @@ class StockRequestOrder(models.Model):
|
|||||||
action['res_id'] = self.stock_request_ids.id
|
action['res_id'] = self.stock_request_ids.id
|
||||||
return action
|
return action
|
||||||
|
|
||||||
|
@api.model
|
||||||
|
def create(self, vals):
|
||||||
|
upd_vals = vals.copy()
|
||||||
|
if upd_vals.get('name', '/') == '/':
|
||||||
|
upd_vals['name'] = self.env['ir.sequence'].next_by_code(
|
||||||
|
'stock.request.order')
|
||||||
|
return super().create(upd_vals)
|
||||||
|
|
||||||
@api.multi
|
@api.multi
|
||||||
def unlink(self):
|
def unlink(self):
|
||||||
if self.filtered(lambda r: r.state != 'draft'):
|
if self.filtered(lambda r: r.state != 'draft'):
|
||||||
raise UserError(_('Only orders on draft state can be unlinked'))
|
raise UserError(_('Only orders on draft state can be unlinked'))
|
||||||
return super().unlink()
|
return super().unlink()
|
||||||
|
|
||||||
|
@api.constrains('warehouse_id', 'company_id')
|
||||||
|
def _check_warehouse_company(self):
|
||||||
|
if any(request.warehouse_id.company_id !=
|
||||||
|
request.company_id for request in self):
|
||||||
|
raise ValidationError(
|
||||||
|
_('The company of the stock request must match with '
|
||||||
|
'that of the warehouse.'))
|
||||||
|
|
||||||
|
@api.constrains('location_id', 'company_id')
|
||||||
|
def _check_location_company(self):
|
||||||
|
if any(request.location_id.company_id and
|
||||||
|
request.location_id.company_id !=
|
||||||
|
request.company_id for request in self):
|
||||||
|
raise ValidationError(
|
||||||
|
_('The company of the stock request must match with '
|
||||||
|
'that of the location.'))
|
||||||
|
|||||||
28
stock_request/models/stock_warehouse.py
Normal file
28
stock_request/models/stock_warehouse.py
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
# Copyright 2018 Eficent Business and IT Consulting Services, S.L.
|
||||||
|
# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html).
|
||||||
|
|
||||||
|
from odoo import api, models, _
|
||||||
|
from odoo.exceptions import ValidationError
|
||||||
|
|
||||||
|
|
||||||
|
class StockWarehouse(models.Model):
|
||||||
|
_inherit = 'stock.warehouse'
|
||||||
|
|
||||||
|
@api.constrains('company_id')
|
||||||
|
def _check_company_stock_request(self):
|
||||||
|
if any(self.env['stock.request'].search(
|
||||||
|
[('company_id', '!=', rec.company_id.id),
|
||||||
|
('warehouse_id', '=', rec.id)], limit=1)
|
||||||
|
for rec in self):
|
||||||
|
raise ValidationError(
|
||||||
|
_('You cannot change the company of the warehouse, as it is '
|
||||||
|
'already assigned to stock requests that belong to '
|
||||||
|
'another company.'))
|
||||||
|
if any(self.env['stock.request.order'].search(
|
||||||
|
[('company_id', '!=', rec.company_id.id),
|
||||||
|
('warehouse_id', '=', rec.id)], limit=1)
|
||||||
|
for rec in self):
|
||||||
|
raise ValidationError(
|
||||||
|
_('You cannot change the company of the warehouse, as it is '
|
||||||
|
'already assigned to stock request orders that belong to '
|
||||||
|
'another company.'))
|
||||||
@@ -36,12 +36,19 @@ class TestStockRequest(common.TransactionCase):
|
|||||||
[self.stock_request_manager_group.id],
|
[self.stock_request_manager_group.id],
|
||||||
[self.main_company.id, self.company_2.id])
|
[self.main_company.id, self.company_2.id])
|
||||||
self.product = self._create_product('SH', 'Shoes', False)
|
self.product = self._create_product('SH', 'Shoes', False)
|
||||||
|
self.product_company_2 = self._create_product('SH', 'Shoes',
|
||||||
|
self.company_2.id)
|
||||||
|
|
||||||
self.ressuply_loc = self.env['stock.location'].create({
|
self.ressuply_loc = self.env['stock.location'].create({
|
||||||
'name': 'Ressuply',
|
'name': 'Ressuply',
|
||||||
'location_id': self.warehouse.view_location_id.id,
|
'location_id': self.warehouse.view_location_id.id,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
self.ressuply_loc_2 = self.env['stock.location'].create({
|
||||||
|
'name': 'Ressuply',
|
||||||
|
'location_id': self.wh2.view_location_id.id,
|
||||||
|
})
|
||||||
|
|
||||||
self.route = self.env['stock.location.route'].create({
|
self.route = self.env['stock.location.route'].create({
|
||||||
'name': 'Transfer',
|
'name': 'Transfer',
|
||||||
'product_categ_selectable': False,
|
'product_categ_selectable': False,
|
||||||
@@ -50,6 +57,14 @@ class TestStockRequest(common.TransactionCase):
|
|||||||
'sequence': 10,
|
'sequence': 10,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
self.route_2 = self.env['stock.location.route'].create({
|
||||||
|
'name': 'Transfer',
|
||||||
|
'product_categ_selectable': False,
|
||||||
|
'product_selectable': True,
|
||||||
|
'company_id': self.company_2.id,
|
||||||
|
'sequence': 10,
|
||||||
|
})
|
||||||
|
|
||||||
self.uom_dozen = self.env['product.uom'].create({
|
self.uom_dozen = self.env['product.uom'].create({
|
||||||
'name': 'Test-DozenA',
|
'name': 'Test-DozenA',
|
||||||
'category_id': self.categ_unit.id,
|
'category_id': self.categ_unit.id,
|
||||||
@@ -70,6 +85,19 @@ class TestStockRequest(common.TransactionCase):
|
|||||||
'propagate': 'False',
|
'propagate': 'False',
|
||||||
})
|
})
|
||||||
|
|
||||||
|
self.env['procurement.rule'].create({
|
||||||
|
'name': 'Transfer',
|
||||||
|
'route_id': self.route_2.id,
|
||||||
|
'location_src_id': self.ressuply_loc_2.id,
|
||||||
|
'location_id': self.wh2.lot_stock_id.id,
|
||||||
|
'action': 'move',
|
||||||
|
'picking_type_id': self.wh2.int_type_id.id,
|
||||||
|
'procure_method': 'make_to_stock',
|
||||||
|
'warehouse_id': self.wh2.id,
|
||||||
|
'company_id': self.company_2.id,
|
||||||
|
'propagate': 'False',
|
||||||
|
})
|
||||||
|
|
||||||
def _create_user(self, name, group_ids, company_ids):
|
def _create_user(self, name, group_ids, company_ids):
|
||||||
return self.env['res.users'].with_context(
|
return self.env['res.users'].with_context(
|
||||||
{'no_reset_password': True}).create(
|
{'no_reset_password': True}).create(
|
||||||
@@ -252,10 +280,14 @@ class TestStockRequest(common.TransactionCase):
|
|||||||
stock_request.location_id, self.warehouse.lot_stock_id)
|
stock_request.location_id, self.warehouse.lot_stock_id)
|
||||||
|
|
||||||
def test_stock_request_order_validations_01(self):
|
def test_stock_request_order_validations_01(self):
|
||||||
|
""" Testing the discrepancy in warehouse_id between
|
||||||
|
stock request and order"""
|
||||||
|
expected_date = fields.Date.today()
|
||||||
vals = {
|
vals = {
|
||||||
'company_id': self.main_company.id,
|
'company_id': self.main_company.id,
|
||||||
'warehouse_id': self.wh2.id,
|
'warehouse_id': self.wh2.id,
|
||||||
'location_id': self.warehouse.lot_stock_id.id,
|
'location_id': self.warehouse.lot_stock_id.id,
|
||||||
|
'expected_date': expected_date,
|
||||||
'stock_request_ids': [(0, 0, {
|
'stock_request_ids': [(0, 0, {
|
||||||
'product_id': self.product.id,
|
'product_id': self.product.id,
|
||||||
'product_uom_id': self.product.uom_id.id,
|
'product_uom_id': self.product.uom_id.id,
|
||||||
@@ -263,18 +295,22 @@ class TestStockRequest(common.TransactionCase):
|
|||||||
'company_id': self.main_company.id,
|
'company_id': self.main_company.id,
|
||||||
'warehouse_id': self.warehouse.id,
|
'warehouse_id': self.warehouse.id,
|
||||||
'location_id': self.warehouse.lot_stock_id.id,
|
'location_id': self.warehouse.lot_stock_id.id,
|
||||||
|
'expected_date': expected_date,
|
||||||
})]
|
})]
|
||||||
}
|
}
|
||||||
# Select a UoM that is incompatible with the product's UoM
|
|
||||||
with self.assertRaises(exceptions.ValidationError):
|
with self.assertRaises(exceptions.ValidationError):
|
||||||
self.env['stock.request.order'].sudo(
|
self.env['stock.request.order'].sudo(
|
||||||
self.stock_request_user).create(vals)
|
self.stock_request_user).create(vals)
|
||||||
|
|
||||||
def test_stock_request_order_validations_02(self):
|
def test_stock_request_order_validations_02(self):
|
||||||
|
""" Testing the discrepancy in location_id between
|
||||||
|
stock request and order"""
|
||||||
|
expected_date = fields.Date.today()
|
||||||
vals = {
|
vals = {
|
||||||
'company_id': self.main_company.id,
|
'company_id': self.main_company.id,
|
||||||
'warehouse_id': self.warehouse.id,
|
'warehouse_id': self.warehouse.id,
|
||||||
'location_id': self.wh2.lot_stock_id.id,
|
'location_id': self.wh2.lot_stock_id.id,
|
||||||
|
'expected_date': expected_date,
|
||||||
'stock_request_ids': [(0, 0, {
|
'stock_request_ids': [(0, 0, {
|
||||||
'product_id': self.product.id,
|
'product_id': self.product.id,
|
||||||
'product_uom_id': self.product.uom_id.id,
|
'product_uom_id': self.product.uom_id.id,
|
||||||
@@ -282,19 +318,23 @@ class TestStockRequest(common.TransactionCase):
|
|||||||
'company_id': self.main_company.id,
|
'company_id': self.main_company.id,
|
||||||
'warehouse_id': self.warehouse.id,
|
'warehouse_id': self.warehouse.id,
|
||||||
'location_id': self.warehouse.lot_stock_id.id,
|
'location_id': self.warehouse.lot_stock_id.id,
|
||||||
|
'expected_date': expected_date,
|
||||||
})]
|
})]
|
||||||
}
|
}
|
||||||
# Select a UoM that is incompatible with the product's UoM
|
|
||||||
with self.assertRaises(exceptions.ValidationError):
|
with self.assertRaises(exceptions.ValidationError):
|
||||||
self.env['stock.request.order'].sudo(
|
self.env['stock.request.order'].sudo(
|
||||||
self.stock_request_user).create(vals)
|
self.stock_request_user).create(vals)
|
||||||
|
|
||||||
def test_stock_request_order_validations_03(self):
|
def test_stock_request_order_validations_03(self):
|
||||||
|
""" Testing the discrepancy in requested_by between
|
||||||
|
stock request and order"""
|
||||||
|
expected_date = fields.Date.today()
|
||||||
vals = {
|
vals = {
|
||||||
'company_id': self.main_company.id,
|
'company_id': self.main_company.id,
|
||||||
'warehouse_id': self.warehouse.id,
|
'warehouse_id': self.warehouse.id,
|
||||||
'location_id': self.warehouse.lot_stock_id.id,
|
'location_id': self.warehouse.lot_stock_id.id,
|
||||||
'requested_by': self.stock_request_user.id,
|
'requested_by': self.stock_request_user.id,
|
||||||
|
'expected_date': expected_date,
|
||||||
'stock_request_ids': [(0, 0, {
|
'stock_request_ids': [(0, 0, {
|
||||||
'product_id': self.product.id,
|
'product_id': self.product.id,
|
||||||
'product_uom_id': self.product.uom_id.id,
|
'product_uom_id': self.product.uom_id.id,
|
||||||
@@ -303,22 +343,26 @@ class TestStockRequest(common.TransactionCase):
|
|||||||
'company_id': self.main_company.id,
|
'company_id': self.main_company.id,
|
||||||
'warehouse_id': self.warehouse.id,
|
'warehouse_id': self.warehouse.id,
|
||||||
'location_id': self.warehouse.lot_stock_id.id,
|
'location_id': self.warehouse.lot_stock_id.id,
|
||||||
|
'expected_date': expected_date,
|
||||||
})]
|
})]
|
||||||
}
|
}
|
||||||
# Select a UoM that is incompatible with the product's UoM
|
|
||||||
with self.assertRaises(exceptions.ValidationError):
|
with self.assertRaises(exceptions.ValidationError):
|
||||||
self.env['stock.request.order'].sudo(
|
self.env['stock.request.order'].sudo(
|
||||||
self.stock_request_user).create(vals)
|
self.stock_request_user).create(vals)
|
||||||
|
|
||||||
def test_stock_request_order_validations_04(self):
|
def test_stock_request_order_validations_04(self):
|
||||||
|
""" Testing the discrepancy in procurement_group_id between
|
||||||
|
stock request and order"""
|
||||||
procurement_group = self.env['procurement.group'].create({
|
procurement_group = self.env['procurement.group'].create({
|
||||||
'name': 'Procurement',
|
'name': 'Procurement',
|
||||||
})
|
})
|
||||||
|
expected_date = fields.Date.today()
|
||||||
vals = {
|
vals = {
|
||||||
'company_id': self.main_company.id,
|
'company_id': self.main_company.id,
|
||||||
'warehouse_id': self.warehouse.id,
|
'warehouse_id': self.warehouse.id,
|
||||||
'location_id': self.warehouse.lot_stock_id.id,
|
'location_id': self.warehouse.lot_stock_id.id,
|
||||||
'procurement_group_id': procurement_group.id,
|
'procurement_group_id': procurement_group.id,
|
||||||
|
'expected_date': expected_date,
|
||||||
'stock_request_ids': [(0, 0, {
|
'stock_request_ids': [(0, 0, {
|
||||||
'product_id': self.product.id,
|
'product_id': self.product.id,
|
||||||
'product_uom_id': self.product.uom_id.id,
|
'product_uom_id': self.product.uom_id.id,
|
||||||
@@ -326,19 +370,22 @@ class TestStockRequest(common.TransactionCase):
|
|||||||
'company_id': self.main_company.id,
|
'company_id': self.main_company.id,
|
||||||
'warehouse_id': self.warehouse.id,
|
'warehouse_id': self.warehouse.id,
|
||||||
'location_id': self.warehouse.lot_stock_id.id,
|
'location_id': self.warehouse.lot_stock_id.id,
|
||||||
|
'expected_date': expected_date,
|
||||||
})]
|
})]
|
||||||
}
|
}
|
||||||
# Select a UoM that is incompatible with the product's UoM
|
|
||||||
with self.assertRaises(exceptions.ValidationError):
|
with self.assertRaises(exceptions.ValidationError):
|
||||||
self.env['stock.request.order'].sudo(
|
self.env['stock.request.order'].sudo(
|
||||||
self.stock_request_user).create(vals)
|
self.stock_request_user).create(vals)
|
||||||
|
|
||||||
def test_stock_request_order_validations_05(self):
|
def test_stock_request_order_validations_05(self):
|
||||||
|
""" Testing the discrepancy in company between
|
||||||
|
stock request and order"""
|
||||||
|
expected_date = fields.Date.today()
|
||||||
vals = {
|
vals = {
|
||||||
'company_id': self.main_company.id,
|
'company_id': self.company_2.id,
|
||||||
'warehouse_id': self.warehouse.id,
|
'warehouse_id': self.wh2.id,
|
||||||
'location_id': self.warehouse.lot_stock_id.id,
|
'location_id': self.wh2.lot_stock_id.id,
|
||||||
'expected_date': fields.Date.today(),
|
'expected_date': expected_date,
|
||||||
'stock_request_ids': [(0, 0, {
|
'stock_request_ids': [(0, 0, {
|
||||||
'product_id': self.product.id,
|
'product_id': self.product.id,
|
||||||
'product_uom_id': self.product.uom_id.id,
|
'product_uom_id': self.product.uom_id.id,
|
||||||
@@ -346,18 +393,23 @@ class TestStockRequest(common.TransactionCase):
|
|||||||
'company_id': self.main_company.id,
|
'company_id': self.main_company.id,
|
||||||
'warehouse_id': self.warehouse.id,
|
'warehouse_id': self.warehouse.id,
|
||||||
'location_id': self.warehouse.lot_stock_id.id,
|
'location_id': self.warehouse.lot_stock_id.id,
|
||||||
|
'expected_date': expected_date,
|
||||||
})]
|
})]
|
||||||
}
|
}
|
||||||
# Select a UoM that is incompatible with the product's UoM
|
|
||||||
with self.assertRaises(exceptions.ValidationError):
|
with self.assertRaises(exceptions.ValidationError):
|
||||||
self.env['stock.request.order'].sudo(
|
self.env['stock.request.order'].sudo(
|
||||||
self.stock_request_user).create(vals)
|
self.stock_request_user).create(vals)
|
||||||
|
|
||||||
def test_stock_request_order_validations_06(self):
|
def test_stock_request_order_validations_06(self):
|
||||||
|
""" Testing the discrepancy in expected dates between
|
||||||
|
stock request and order"""
|
||||||
|
expected_date = fields.Date.today()
|
||||||
|
child_expected_date = '2015-01-01'
|
||||||
vals = {
|
vals = {
|
||||||
'company_id': self.company_2.id,
|
'company_id': self.company_2.id,
|
||||||
'warehouse_id': self.warehouse.id,
|
'warehouse_id': self.warehouse.id,
|
||||||
'location_id': self.warehouse.lot_stock_id.id,
|
'location_id': self.warehouse.lot_stock_id.id,
|
||||||
|
'expected_date': expected_date,
|
||||||
'stock_request_ids': [(0, 0, {
|
'stock_request_ids': [(0, 0, {
|
||||||
'product_id': self.product.id,
|
'product_id': self.product.id,
|
||||||
'product_uom_id': self.product.uom_id.id,
|
'product_uom_id': self.product.uom_id.id,
|
||||||
@@ -365,18 +417,22 @@ class TestStockRequest(common.TransactionCase):
|
|||||||
'company_id': self.main_company.id,
|
'company_id': self.main_company.id,
|
||||||
'warehouse_id': self.warehouse.id,
|
'warehouse_id': self.warehouse.id,
|
||||||
'location_id': self.warehouse.lot_stock_id.id,
|
'location_id': self.warehouse.lot_stock_id.id,
|
||||||
|
'expected_date': child_expected_date,
|
||||||
})]
|
})]
|
||||||
}
|
}
|
||||||
# Select a UoM that is incompatible with the product's UoM
|
|
||||||
with self.assertRaises(exceptions.ValidationError):
|
with self.assertRaises(exceptions.ValidationError):
|
||||||
self.env['stock.request.order'].sudo().create(vals)
|
self.env['stock.request.order'].sudo().create(vals)
|
||||||
|
|
||||||
def test_stock_request_order_validations_07(self):
|
def test_stock_request_order_validations_07(self):
|
||||||
|
""" Testing the discrepancy in picking policy between
|
||||||
|
stock request and order"""
|
||||||
|
expected_date = fields.Date.today()
|
||||||
vals = {
|
vals = {
|
||||||
'company_id': self.main_company.id,
|
'company_id': self.main_company.id,
|
||||||
'warehouse_id': self.warehouse.id,
|
'warehouse_id': self.warehouse.id,
|
||||||
'location_id': self.warehouse.lot_stock_id.id,
|
'location_id': self.warehouse.lot_stock_id.id,
|
||||||
'picking_policy': 'one',
|
'picking_policy': 'one',
|
||||||
|
'expected_date': expected_date,
|
||||||
'stock_request_ids': [(0, 0, {
|
'stock_request_ids': [(0, 0, {
|
||||||
'product_id': self.product.id,
|
'product_id': self.product.id,
|
||||||
'product_uom_id': self.product.uom_id.id,
|
'product_uom_id': self.product.uom_id.id,
|
||||||
@@ -384,9 +440,9 @@ class TestStockRequest(common.TransactionCase):
|
|||||||
'company_id': self.main_company.id,
|
'company_id': self.main_company.id,
|
||||||
'warehouse_id': self.warehouse.id,
|
'warehouse_id': self.warehouse.id,
|
||||||
'location_id': self.warehouse.lot_stock_id.id,
|
'location_id': self.warehouse.lot_stock_id.id,
|
||||||
|
'expected_date': expected_date,
|
||||||
})]
|
})]
|
||||||
}
|
}
|
||||||
# Select a UoM that is incompatible with the product's UoM
|
|
||||||
with self.assertRaises(exceptions.ValidationError):
|
with self.assertRaises(exceptions.ValidationError):
|
||||||
self.env['stock.request.order'].sudo(
|
self.env['stock.request.order'].sudo(
|
||||||
self.stock_request_user).create(vals)
|
self.stock_request_user).create(vals)
|
||||||
@@ -423,10 +479,12 @@ class TestStockRequest(common.TransactionCase):
|
|||||||
stock_request.action_confirm()
|
stock_request.action_confirm()
|
||||||
|
|
||||||
def test_create_request_01(self):
|
def test_create_request_01(self):
|
||||||
|
expected_date = fields.Date.today()
|
||||||
vals = {
|
vals = {
|
||||||
'company_id': self.main_company.id,
|
'company_id': self.main_company.id,
|
||||||
'warehouse_id': self.warehouse.id,
|
'warehouse_id': self.warehouse.id,
|
||||||
'location_id': self.warehouse.lot_stock_id.id,
|
'location_id': self.warehouse.lot_stock_id.id,
|
||||||
|
'expected_date': expected_date,
|
||||||
'stock_request_ids': [(0, 0, {
|
'stock_request_ids': [(0, 0, {
|
||||||
'product_id': self.product.id,
|
'product_id': self.product.id,
|
||||||
'product_uom_id': self.product.uom_id.id,
|
'product_uom_id': self.product.uom_id.id,
|
||||||
@@ -434,6 +492,7 @@ class TestStockRequest(common.TransactionCase):
|
|||||||
'company_id': self.main_company.id,
|
'company_id': self.main_company.id,
|
||||||
'warehouse_id': self.warehouse.id,
|
'warehouse_id': self.warehouse.id,
|
||||||
'location_id': self.warehouse.lot_stock_id.id,
|
'location_id': self.warehouse.lot_stock_id.id,
|
||||||
|
'expected_date': expected_date,
|
||||||
})]
|
})]
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -550,10 +609,12 @@ class TestStockRequest(common.TransactionCase):
|
|||||||
picking.action_done()
|
picking.action_done()
|
||||||
|
|
||||||
def test_cancel_request(self):
|
def test_cancel_request(self):
|
||||||
|
expected_date = fields.Date.today()
|
||||||
vals = {
|
vals = {
|
||||||
'company_id': self.main_company.id,
|
'company_id': self.main_company.id,
|
||||||
'warehouse_id': self.warehouse.id,
|
'warehouse_id': self.warehouse.id,
|
||||||
'location_id': self.warehouse.lot_stock_id.id,
|
'location_id': self.warehouse.lot_stock_id.id,
|
||||||
|
'expected_date': expected_date,
|
||||||
'stock_request_ids': [(0, 0, {
|
'stock_request_ids': [(0, 0, {
|
||||||
'product_id': self.product.id,
|
'product_id': self.product.id,
|
||||||
'product_uom_id': self.product.uom_id.id,
|
'product_uom_id': self.product.uom_id.id,
|
||||||
@@ -561,6 +622,7 @@ class TestStockRequest(common.TransactionCase):
|
|||||||
'company_id': self.main_company.id,
|
'company_id': self.main_company.id,
|
||||||
'warehouse_id': self.warehouse.id,
|
'warehouse_id': self.warehouse.id,
|
||||||
'location_id': self.warehouse.lot_stock_id.id,
|
'location_id': self.warehouse.lot_stock_id.id,
|
||||||
|
'expected_date': expected_date,
|
||||||
})]
|
})]
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -604,10 +666,12 @@ class TestStockRequest(common.TransactionCase):
|
|||||||
self.assertEqual(len(stock_request.sudo().move_ids), 2)
|
self.assertEqual(len(stock_request.sudo().move_ids), 2)
|
||||||
|
|
||||||
def test_view_actions(self):
|
def test_view_actions(self):
|
||||||
|
expected_date = fields.Date.today()
|
||||||
vals = {
|
vals = {
|
||||||
'company_id': self.main_company.id,
|
'company_id': self.main_company.id,
|
||||||
'warehouse_id': self.warehouse.id,
|
'warehouse_id': self.warehouse.id,
|
||||||
'location_id': self.warehouse.lot_stock_id.id,
|
'location_id': self.warehouse.lot_stock_id.id,
|
||||||
|
'expected_date': expected_date,
|
||||||
'stock_request_ids': [(0, 0, {
|
'stock_request_ids': [(0, 0, {
|
||||||
'product_id': self.product.id,
|
'product_id': self.product.id,
|
||||||
'product_uom_id': self.product.uom_id.id,
|
'product_uom_id': self.product.uom_id.id,
|
||||||
@@ -615,6 +679,7 @@ class TestStockRequest(common.TransactionCase):
|
|||||||
'company_id': self.main_company.id,
|
'company_id': self.main_company.id,
|
||||||
'warehouse_id': self.warehouse.id,
|
'warehouse_id': self.warehouse.id,
|
||||||
'location_id': self.warehouse.lot_stock_id.id,
|
'location_id': self.warehouse.lot_stock_id.id,
|
||||||
|
'expected_date': expected_date,
|
||||||
})]
|
})]
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -644,3 +709,29 @@ class TestStockRequest(common.TransactionCase):
|
|||||||
action = stock_request.picking_ids[0].action_view_stock_request()
|
action = stock_request.picking_ids[0].action_view_stock_request()
|
||||||
self.assertEqual(action['type'], 'ir.actions.act_window')
|
self.assertEqual(action['type'], 'ir.actions.act_window')
|
||||||
self.assertEqual(action['res_id'], stock_request.id)
|
self.assertEqual(action['res_id'], stock_request.id)
|
||||||
|
|
||||||
|
def test_stock_request_constrains(self):
|
||||||
|
vals = {
|
||||||
|
'product_id': self.product.id,
|
||||||
|
'product_uom_id': self.product.uom_id.id,
|
||||||
|
'product_uom_qty': 5.0,
|
||||||
|
'company_id': self.main_company.id,
|
||||||
|
'warehouse_id': self.warehouse.id,
|
||||||
|
'location_id': self.warehouse.lot_stock_id.id,
|
||||||
|
}
|
||||||
|
|
||||||
|
stock_request = self.stock_request.sudo(
|
||||||
|
self.stock_request_user).create(vals)
|
||||||
|
|
||||||
|
# Cannot assign a warehouse that belongs to another company
|
||||||
|
with self.assertRaises(exceptions.ValidationError):
|
||||||
|
stock_request.warehouse_id = self.wh2
|
||||||
|
# Cannot assign a product that belongs to another company
|
||||||
|
with self.assertRaises(exceptions.ValidationError):
|
||||||
|
stock_request.product_id = self.product_company_2
|
||||||
|
# Cannot assign a location that belongs to another company
|
||||||
|
with self.assertRaises(exceptions.ValidationError):
|
||||||
|
stock_request.location_id = self.wh2.lot_stock_id
|
||||||
|
# Cannot assign a route that belongs to another company
|
||||||
|
with self.assertRaises(exceptions.ValidationError):
|
||||||
|
stock_request.route_id = self.route_2
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
<odoo>
|
<odoo>
|
||||||
|
|
||||||
<record id="res_config_settings_view_form" model="ir.ui.view">
|
<record id="res_config_settings_view_form" model="ir.ui.view">
|
||||||
<field name="name">res.config.settings.view.form.inherit.medical</field>
|
<field name="name">res.config.settings.view.form.inherit.stock_request</field>
|
||||||
<field name="model">res.config.settings</field>
|
<field name="model">res.config.settings</field>
|
||||||
<field name="inherit_id" ref="base.res_config_settings_view_form"/>
|
<field name="inherit_id" ref="base.res_config_settings_view_form"/>
|
||||||
<field name="arch" type="xml">
|
<field name="arch" type="xml">
|
||||||
@@ -16,19 +16,23 @@
|
|||||||
<div class="app_settings_block"
|
<div class="app_settings_block"
|
||||||
data-string="Stock Request" data-key="stock_request"
|
data-string="Stock Request" data-key="stock_request"
|
||||||
groups="stock_request.group_stock_request_manager">
|
groups="stock_request.group_stock_request_manager">
|
||||||
|
<h2>Orders</h2>
|
||||||
<div class="row mt16 o_settings_container" id="stock_request">
|
<div class="row mt16 o_settings_container" id="stock_request">
|
||||||
<div class="col-xs-12 col-md-6 o_setting_box">
|
<div class="col-xs-12 col-md-6 o_setting_box">
|
||||||
<div class="o_setting_left_pane">
|
<div class="o_setting_left_pane">
|
||||||
<field name="group_stock_request_order"/>
|
<field name="group_stock_request_order"/>
|
||||||
</div>
|
</div>
|
||||||
<div class="o_setting_right_pane">
|
<div class="o_setting_right_pane">
|
||||||
<label string="Enable orders"
|
<label string="Enable Orders"
|
||||||
for="group_stock_request_order"/>
|
for="group_stock_request_order"/>
|
||||||
<div class="text-muted">
|
<div class="text-muted">
|
||||||
Activates Stock Request Orders
|
Activates Stock Request Orders
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
<h2>Purchases</h2>
|
||||||
|
<div class="row mt16 o_settings_container" id="stock_request_purchase">
|
||||||
<div class="col-xs-12 col-md-6 o_setting_box">
|
<div class="col-xs-12 col-md-6 o_setting_box">
|
||||||
<div class="o_setting_left_pane">
|
<div class="o_setting_left_pane">
|
||||||
<field name="module_stock_request_purchase"/>
|
<field name="module_stock_request_purchase"/>
|
||||||
@@ -56,5 +60,4 @@
|
|||||||
<field name="context">{'module' : 'stock_request'}</field>
|
<field name="context">{'module' : 'stock_request'}</field>
|
||||||
</record>
|
</record>
|
||||||
|
|
||||||
|
|
||||||
</odoo>
|
</odoo>
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
<field name="requested_product_qty"/>
|
<field name="requested_product_qty"/>
|
||||||
<field name="allocated_product_qty"/>
|
<field name="allocated_product_qty"/>
|
||||||
<field name="open_product_qty" />
|
<field name="open_product_qty" />
|
||||||
|
<field name="company_id" groups="base.group_multi_company"/>
|
||||||
</tree>
|
</tree>
|
||||||
</field>
|
</field>
|
||||||
</record>
|
</record>
|
||||||
@@ -41,6 +42,7 @@
|
|||||||
<field name="requested_product_qty"/>
|
<field name="requested_product_qty"/>
|
||||||
<field name="allocated_product_qty"/>
|
<field name="allocated_product_qty"/>
|
||||||
<field name="open_product_qty" />
|
<field name="open_product_qty" />
|
||||||
|
<field name="company_id" groups="base.group_multi_company" options="{'no_create': True}"/>
|
||||||
</group>
|
</group>
|
||||||
</group>
|
</group>
|
||||||
</sheet>
|
</sheet>
|
||||||
|
|||||||
@@ -13,7 +13,7 @@
|
|||||||
sequence="20"/>
|
sequence="20"/>
|
||||||
|
|
||||||
<menuitem id="stock_request_order_menu"
|
<menuitem id="stock_request_order_menu"
|
||||||
name="Stock Requests orders"
|
name="Stock Requests Orders"
|
||||||
parent="menu_stock_request_root"
|
parent="menu_stock_request_root"
|
||||||
action="stock_request_order_action"
|
action="stock_request_order_action"
|
||||||
groups="group_stock_request_order"
|
groups="group_stock_request_order"
|
||||||
|
|||||||
@@ -51,7 +51,7 @@
|
|||||||
groups="stock.group_stock_user"
|
groups="stock.group_stock_user"
|
||||||
>
|
>
|
||||||
<field name="stock_request_count" widget="statinfo"
|
<field name="stock_request_count" widget="statinfo"
|
||||||
string="Stock requests"/>
|
string="Stock Requests"/>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="oe_title">
|
<div class="oe_title">
|
||||||
@@ -127,7 +127,7 @@
|
|||||||
|
|
||||||
<record model="ir.actions.act_window"
|
<record model="ir.actions.act_window"
|
||||||
id="stock_request_order_action">
|
id="stock_request_order_action">
|
||||||
<field name="name">Stock request orders</field>
|
<field name="name">Stock Request Orders</field>
|
||||||
<field name="type">ir.actions.act_window</field>
|
<field name="type">ir.actions.act_window</field>
|
||||||
<field name="res_model">stock.request.order</field>
|
<field name="res_model">stock.request.order</field>
|
||||||
<field name="view_type">form</field>
|
<field name="view_type">form</field>
|
||||||
|
|||||||
@@ -82,7 +82,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<group>
|
<group>
|
||||||
<group>
|
<group>
|
||||||
<field name="order_id" readonly="1"/>
|
<field name="order_id" readonly="1" groups="stock_request.group_stock_request_order"/>
|
||||||
<field name="product_id"/>
|
<field name="product_id"/>
|
||||||
<field name="expected_date"/>
|
<field name="expected_date"/>
|
||||||
<field name="picking_policy"/>
|
<field name="picking_policy"/>
|
||||||
@@ -91,7 +91,8 @@
|
|||||||
<field name="warehouse_id" widget="selection" groups="stock.group_stock_multi_locations"/>
|
<field name="warehouse_id" widget="selection" groups="stock.group_stock_multi_locations"/>
|
||||||
<field name="product_uom_id"
|
<field name="product_uom_id"
|
||||||
options="{'no_open': True, 'no_create': True}" groups="product.group_uom"/>
|
options="{'no_open': True, 'no_create': True}" groups="product.group_uom"/>
|
||||||
<field name="location_id" groups="stock.group_stock_multi_locations"/>
|
<field name="location_id" groups="stock.group_stock_multi_locations"
|
||||||
|
domain="['|', ('company_id', '=', company_id), ('company_id', '=', False)]"/>
|
||||||
<field name="route_id"
|
<field name="route_id"
|
||||||
options="{'no_create': True}" groups="stock.group_stock_multi_locations"/>
|
options="{'no_create': True}" groups="stock.group_stock_multi_locations"/>
|
||||||
<field name="route_ids" invisible="1"/>
|
<field name="route_ids" invisible="1"/>
|
||||||
|
|||||||
Reference in New Issue
Block a user