[REF] mrp_subcontracting: remove partner type
Replace the type subcontractor on the partner. Instead replace it by a property for a subcontracting location. The purpose is to have a simplier configuration. The user would just need to add the partner on the BoM in order to start a subcontracting process.
This commit is contained in:
@@ -8,12 +8,13 @@
|
||||
'description': "",
|
||||
'website': 'https://www.odoo.com/page/manufacturing',
|
||||
'category': 'Manufacturing/Manufacturing',
|
||||
'depends': ['mrp', 'contacts'],
|
||||
'depends': ['mrp'],
|
||||
'data': [
|
||||
'data/mrp_subcontracting_data.xml',
|
||||
'views/stock_warehouse_views.xml',
|
||||
'views/stock_move_views.xml',
|
||||
'views/stock_picking_views.xml',
|
||||
'views/res_partner_views.xml',
|
||||
'views/mrp_bom_views.xml',
|
||||
'views/res_partner_views.xml',
|
||||
],
|
||||
|
||||
@@ -8,7 +8,7 @@ class MrpBom(models.Model):
|
||||
_inherit = 'mrp.bom'
|
||||
|
||||
type = fields.Selection(selection_add=[('subcontract', 'Subcontracting')])
|
||||
subcontractor_ids = fields.One2many('res.partner', 'bom_id', domain=[('type', '=', 'subcontractor')], string='Subcontractors')
|
||||
subcontractor_ids = fields.Many2many('res.partner', 'mrp_bom_subcontractor', string='Subcontractors')
|
||||
|
||||
def _bom_subcontract_find(self, product_tmpl=None, product=None, picking_type=None, company_id=False, bom_type='subcontract', subcontractor=False):
|
||||
domain = self._bom_find_domain(product_tmpl=product_tmpl, product=product, picking_type=picking_type, company_id=company_id, bom_type=bom_type)
|
||||
@@ -17,4 +17,3 @@ class MrpBom(models.Model):
|
||||
else:
|
||||
domain += [('subcontractor_ids', '=', False)]
|
||||
return self.search(domain, order='subcontractor_ids, sequence, product_id', limit=1)
|
||||
|
||||
|
||||
@@ -9,24 +9,33 @@ class ResCompany(models.Model):
|
||||
|
||||
subcontracting_location_id = fields.Many2one('stock.location')
|
||||
|
||||
@api.model
|
||||
def create_missing_subcontracting_location(self):
|
||||
company_without_subcontracting_loc = self.env['res.company'].search(
|
||||
[('subcontracting_location_id', '=', False)])
|
||||
company_without_subcontracting_loc._create_subcontracting_location()
|
||||
|
||||
def _create_per_company_locations(self):
|
||||
super(ResCompany, self)._create_per_company_locations()
|
||||
self._create_subcontracting_location()
|
||||
|
||||
def _create_subcontracting_location(self):
|
||||
parent_location = self.env.ref('stock.stock_location_locations_partner', raise_if_not_found=False)
|
||||
property_stock_subcontractor_res_partner_field = self.env['ir.model.fields'].search([
|
||||
('model', '=', 'res.partner'),
|
||||
('name', '=', 'property_stock_subcontractor')
|
||||
])
|
||||
for company in self:
|
||||
parent_location = self.env.ref('stock.stock_location_locations_partner', raise_if_not_found=False)
|
||||
subcontracting_location = self.env['stock.location'].create({
|
||||
'name': _('%s: Subcontracting Location') % company.name,
|
||||
'usage': 'internal',
|
||||
'location_id': parent_location.id,
|
||||
'company_id': company.id,
|
||||
})
|
||||
company.write({'subcontracting_location_id': subcontracting_location.id})
|
||||
|
||||
@api.model
|
||||
def create_missing_subcontracting_location(self):
|
||||
company_without_subcontracting_loc = self.env['res.company'].search(
|
||||
[('subcontracting_location_id', '=', False)])
|
||||
for company in company_without_subcontracting_loc:
|
||||
company._create_subcontracting_location()
|
||||
self.env['ir.property'].create({
|
||||
'name': 'property_stock_subcontractor_%s' % company.name,
|
||||
'fields_id': property_stock_subcontractor_res_partner_field.id,
|
||||
'company_id': company.id,
|
||||
'value': 'stock.location,%d' % subcontracting_location.id,
|
||||
})
|
||||
company.subcontracting_location_id = subcontracting_location
|
||||
|
||||
@@ -1,56 +1,13 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from odoo import api, fields, models, _
|
||||
from odoo import fields, models
|
||||
|
||||
|
||||
class ResPartner(models.Model):
|
||||
_inherit = 'res.partner'
|
||||
|
||||
type = fields.Selection(selection_add=[('subcontractor', 'Subcontractor')])
|
||||
bom_id = fields.Many2one('mrp.bom', domain=[('type', '=', 'subcontract')])
|
||||
|
||||
def _get_name(self):
|
||||
name = super(ResPartner, self)._get_name()
|
||||
if self.type == 'subcontractor':
|
||||
subcontractor = _('Subcontractor')
|
||||
if name.endswith(', '):
|
||||
name = "%s%s" % (name, subcontractor)
|
||||
else:
|
||||
name = '%s, %s' % (name, subcontractor)
|
||||
return name
|
||||
|
||||
@api.onchange('type')
|
||||
def _onchange_partner_type(self):
|
||||
if self.type == 'subcontractor':
|
||||
company = self.company_id or self.parent_id.company_id
|
||||
subcontracting_location = company.subcontracting_location_id
|
||||
self.update({
|
||||
'property_stock_customer': subcontracting_location,
|
||||
'property_stock_supplier': subcontracting_location
|
||||
})
|
||||
else:
|
||||
self.update({
|
||||
'property_stock_customer': self.env.ref('stock.stock_location_customers'),
|
||||
'property_stock_supplier': self.env.ref('stock.stock_location_suppliers')
|
||||
})
|
||||
|
||||
@api.model_create_multi
|
||||
def create(self, vals_list):
|
||||
for vals in vals_list:
|
||||
if vals.get('type') == 'subcontractor':
|
||||
if not vals.get('property_stock_supplier') and not vals.get('property_stock_customer'):
|
||||
company = vals.get('company_id') and self.env['res.company'].browse(vals['company_id']) or \
|
||||
self.browse(vals.get('parent_id')).company_id
|
||||
subcontracting_location = company.subcontracting_location_id
|
||||
vals['property_stock_supplier'] = subcontracting_location
|
||||
vals['property_stock_customer'] = subcontracting_location
|
||||
return super(ResPartner, self).create(vals_list)
|
||||
|
||||
def write(self, vals):
|
||||
if vals.get('type') == 'subcontractor':
|
||||
subcontracting_location = self.env.company.subcontracting_location_id
|
||||
if not vals.get('property_stock_supplier') and not vals.get('property_stock_customer'):
|
||||
vals['property_stock_supplier'] = subcontracting_location.id
|
||||
vals['property_stock_customer'] = subcontracting_location.id
|
||||
return super(ResPartner, self).write(vals)
|
||||
property_stock_subcontractor = fields.Many2one(
|
||||
'stock.location', string="Subcontractor Location", company_dependent=True,
|
||||
help="The stock location used as source and destination when sending\
|
||||
goods to this contact during a subcontracting process.")
|
||||
|
||||
@@ -47,19 +47,17 @@ class StockMove(models.Model):
|
||||
def _action_confirm(self, merge=True, merge_into=False):
|
||||
subcontract_details_per_picking = defaultdict(list)
|
||||
for move in self:
|
||||
if not move.picking_id:
|
||||
if move.location_id.usage != 'supplier' or move.location_dest_id.usage == 'supplier':
|
||||
continue
|
||||
if not move.picking_id._is_subcontract():
|
||||
if not move.picking_id:
|
||||
continue
|
||||
bom = move._get_subcontract_bom()
|
||||
if not bom:
|
||||
error_message = _('Please define a BoM of type subcontracting for the product "%s". If you don\'t want to subcontract the product "%s", do not select a partner of type subcontractor.')
|
||||
error_message += '\n\n'
|
||||
error_message += _('If there is well a BoM of type subcontracting defined, check if you have set the correct subcontractors on it.')
|
||||
raise UserError(error_message % (move.product_id.name, move.product_id.name))
|
||||
continue
|
||||
subcontract_details_per_picking[move.picking_id].append((move, bom))
|
||||
move.write({
|
||||
'is_subcontract': True,
|
||||
'location_id': self.picking_id.partner_id.property_stock_subcontractor.id
|
||||
})
|
||||
for picking, subcontract_details in subcontract_details_per_picking.items():
|
||||
picking._subcontracted_produce(subcontract_details)
|
||||
|
||||
@@ -58,10 +58,7 @@ class StockPicking(models.Model):
|
||||
# -------------------------------------------------------------------------
|
||||
def _is_subcontract(self):
|
||||
self.ensure_one()
|
||||
if self.partner_id.type == 'subcontractor' and \
|
||||
self.picking_type_id.code == 'incoming':
|
||||
return True
|
||||
return False
|
||||
return self.picking_type_id.code == 'incoming' and any(m.is_subcontract for m in self.move_lines)
|
||||
|
||||
def _get_subcontracted_productions(self):
|
||||
self.ensure_one()
|
||||
@@ -75,8 +72,8 @@ class StockPicking(models.Model):
|
||||
'product_id': product.id,
|
||||
'product_uom_id': subcontract_move.product_uom.id,
|
||||
'bom_id': bom.id,
|
||||
'location_src_id': subcontract_move.picking_id.partner_id.property_stock_supplier.id,
|
||||
'location_dest_id': subcontract_move.location_id.id,
|
||||
'location_src_id': subcontract_move.picking_id.partner_id.property_stock_subcontractor.id,
|
||||
'location_dest_id': subcontract_move.picking_id.partner_id.property_stock_subcontractor.id,
|
||||
'product_qty': subcontract_move.product_uom_qty,
|
||||
'picking_type_id': warehouse.subcontracting_type_id.id
|
||||
}
|
||||
|
||||
@@ -8,114 +8,13 @@ from odoo.tests import tagged
|
||||
|
||||
@tagged('post_install', '-at_install')
|
||||
class TestSubcontractingBasic(TransactionCase):
|
||||
def test_partner_1(self):
|
||||
""" Checks the `display_name` of subcontracted partners. """
|
||||
main_partner = self.env['res.partner'].create({'name': 'main_partner'})
|
||||
|
||||
# When a name is set to the subcontracted partner.
|
||||
subcontractor_partner1 = self.env['res.partner'].create({
|
||||
'name': 'subcontractor_partner',
|
||||
'type': 'subcontractor',
|
||||
'parent_id': main_partner.id,
|
||||
})
|
||||
self.assertEqual(subcontractor_partner1.display_name, "main_partner, subcontractor_partner, Subcontractor")
|
||||
|
||||
# When a name is not set to the subcontracted partner.
|
||||
subcontractor_partner1 = self.env['res.partner'].create({
|
||||
'name': '',
|
||||
'type': 'subcontractor',
|
||||
'parent_id': main_partner.id,
|
||||
})
|
||||
self.assertEqual(subcontractor_partner1.display_name, "main_partner, Subcontractor")
|
||||
|
||||
def test_partner_2(self):
|
||||
""" Open an existing partner and add a contact of type subcontractor (simple form view).
|
||||
Checks the customer and supplier locations are set to the subcontracting one onces saved.
|
||||
"""
|
||||
that_company = self.env['res.partner'].create({
|
||||
'is_company': True,
|
||||
'name': "That Company",
|
||||
'company_id': self.env.ref('base.main_company').id
|
||||
})
|
||||
partner_form = Form(that_company)
|
||||
with partner_form.child_ids.new() as partner:
|
||||
partner.name = 'That Guy'
|
||||
partner.type = 'subcontractor'
|
||||
partner_form.save()
|
||||
subcontractor = that_company.child_ids
|
||||
self.assertEquals(subcontractor.property_stock_supplier, self.env.user.company_id.subcontracting_location_id)
|
||||
self.assertEquals(subcontractor.property_stock_customer, self.env.user.company_id.subcontracting_location_id)
|
||||
|
||||
def test_partner_3(self):
|
||||
""" Create a new partner, select a parent company, and choose type subcontractor (debug
|
||||
active). Checks the onchange correctly set the customer and supplier locations to the
|
||||
subcontracting ones. Change them to another one, save, checks they are rightly applied.
|
||||
"""
|
||||
# FIXME sle: this field should not be writeable without the debug mode but it is. ask xmo
|
||||
group_no_one = self.env.ref('base.group_no_one')
|
||||
self.env.user.write({'groups_id': [(3, group_no_one.id)]})
|
||||
partner_form = Form(self.env['res.partner'])
|
||||
partner_form.name = 'subcontractor partner'
|
||||
partner_form.company_id = self.env.ref('base.main_company')
|
||||
self.assertNotEqual(partner_form.property_stock_supplier, self.env.user.company_id.subcontracting_location_id)
|
||||
self.assertNotEqual(partner_form.property_stock_customer, self.env.user.company_id.subcontracting_location_id)
|
||||
partner_form.type = 'subcontractor'
|
||||
self.assertEqual(partner_form.property_stock_supplier, self.env.user.company_id.subcontracting_location_id)
|
||||
self.assertEqual(partner_form.property_stock_customer, self.env.user.company_id.subcontracting_location_id)
|
||||
subcontracting_location2 = self.env.user.company_id.subcontracting_location_id.copy()
|
||||
partner_form.property_stock_supplier = subcontracting_location2
|
||||
partner_form.property_stock_customer = subcontracting_location2
|
||||
partner = partner_form.save()
|
||||
self.assertEqual(partner.property_stock_supplier, subcontracting_location2)
|
||||
self.assertEqual(partner.property_stock_customer, subcontracting_location2)
|
||||
|
||||
def test_partner_4(self):
|
||||
""" Create a new partner, select a parent company, and choose type subcontractor (debug
|
||||
not active). Checks the customer and supplier locations are set to the subcontracting one
|
||||
onces saved.
|
||||
"""
|
||||
that_company = self.env['res.partner'].create({
|
||||
'is_company': True,
|
||||
'name': "That Company",
|
||||
'company_id': self.env.ref('base.main_company').id
|
||||
})
|
||||
partner_form = Form(self.env['res.partner'])
|
||||
partner_form.name = 'That Guy'
|
||||
partner_form.parent_id = that_company
|
||||
partner_form.type = 'subcontractor'
|
||||
subcontractor = partner_form.save()
|
||||
self.assertEquals(subcontractor.property_stock_supplier, self.env.user.company_id.subcontracting_location_id)
|
||||
self.assertEquals(subcontractor.property_stock_customer, self.env.user.company_id.subcontracting_location_id)
|
||||
|
||||
def test_partner_5(self):
|
||||
""" Create a new partner with a child partner of type contact,
|
||||
then write the type 'subcontractor' on it
|
||||
"""
|
||||
that_company = self.env['res.partner'].create({
|
||||
'is_company': True,
|
||||
'name': "That Company",
|
||||
})
|
||||
partner_form = Form(that_company)
|
||||
with partner_form.child_ids.new() as partner:
|
||||
partner.name = 'That Guy'
|
||||
partner.type = 'contact'
|
||||
partner_form.save()
|
||||
|
||||
# We write a new type on the created child partner
|
||||
subcontractor = that_company.child_ids
|
||||
self.assertEquals(len(that_company.child_ids), 1)
|
||||
subcontractor.type = 'subcontractor'
|
||||
|
||||
self.assertEquals(subcontractor.property_stock_supplier, self.env.user.company_id.subcontracting_location_id)
|
||||
self.assertEquals(subcontractor.property_stock_customer, self.env.user.company_id.subcontracting_location_id)
|
||||
|
||||
def test_subcontracting_location_1(self):
|
||||
""" Checks the creation and presence of the subcontracting location. """
|
||||
self.assertTrue(self.env.user.company_id.subcontracting_location_id)
|
||||
self.assertTrue(self.env.user.company_id.subcontracting_location_id.active)
|
||||
self.assertTrue(self.env.company.subcontracting_location_id)
|
||||
self.assertTrue(self.env.company.subcontracting_location_id.active)
|
||||
company2 = self.env['res.company'].create({'name': 'Test Company'})
|
||||
self.assertTrue(company2.subcontracting_location_id)
|
||||
|
||||
self.assertTrue(self.env.company.subcontracting_location_id != company2.subcontracting_location_id)
|
||||
|
||||
class TestSubcontractingFlows(SavepointCase):
|
||||
@classmethod
|
||||
@@ -125,7 +24,6 @@ class TestSubcontractingFlows(SavepointCase):
|
||||
main_partner = cls.env['res.partner'].create({'name': 'main_partner'})
|
||||
cls.subcontractor_partner1 = cls.env['res.partner'].create({
|
||||
'name': 'subcontractor_partner',
|
||||
'type': 'subcontractor',
|
||||
'parent_id': main_partner.id,
|
||||
'company_id': cls.env.ref('base.main_company').id
|
||||
})
|
||||
@@ -218,8 +116,8 @@ class TestSubcontractingFlows(SavepointCase):
|
||||
self.assertEquals(mo.state, 'done')
|
||||
|
||||
# Available quantities should be negative at the subcontracting location for each components
|
||||
avail_qty_comp1 = self.env['stock.quant']._get_available_quantity(self.comp1, self.subcontractor_partner1.property_stock_supplier, allow_negative=True)
|
||||
avail_qty_comp2 = self.env['stock.quant']._get_available_quantity(self.comp2, self.subcontractor_partner1.property_stock_supplier, allow_negative=True)
|
||||
avail_qty_comp1 = self.env['stock.quant']._get_available_quantity(self.comp1, self.subcontractor_partner1.property_stock_subcontractor, allow_negative=True)
|
||||
avail_qty_comp2 = self.env['stock.quant']._get_available_quantity(self.comp2, self.subcontractor_partner1.property_stock_subcontractor, allow_negative=True)
|
||||
avail_qty_finished = self.env['stock.quant']._get_available_quantity(self.finished, wh.lot_stock_id)
|
||||
self.assertEquals(avail_qty_comp1, -1)
|
||||
self.assertEquals(avail_qty_comp2, -1)
|
||||
@@ -228,11 +126,27 @@ class TestSubcontractingFlows(SavepointCase):
|
||||
def test_flow_2(self):
|
||||
""" Tick "Resupply Subcontractor on Order" on the components and trigger the creation of
|
||||
the subcontracting manufacturing order through a receipt picking. Checks if the resupplying
|
||||
actually works.
|
||||
actually works. Also set a different subcontracting location on the partner.
|
||||
"""
|
||||
# Tick "resupply subconractor on order"
|
||||
resupply_sub_on_order_route = self.env['stock.location.route'].search([('name', '=', 'Resupply Subcontractor on Order')])
|
||||
(self.comp1 + self.comp2).write({'route_ids': [(4, resupply_sub_on_order_route.id, None)]})
|
||||
# Create a different subcontract location
|
||||
partner_subcontract_location = self.env['stock.location'].create({
|
||||
'name': 'Specific partner location',
|
||||
'location_id': self.env.ref('stock.stock_location_locations_partner').id,
|
||||
'usage': 'internal',
|
||||
'company_id': self.env.company.id,
|
||||
})
|
||||
self.subcontractor_partner1.property_stock_subcontractor = partner_subcontract_location.id
|
||||
resupply_rule = resupply_sub_on_order_route.rule_ids.filtered(lambda l:
|
||||
l.location_id == self.comp1.property_stock_production and
|
||||
l.location_src_id == self.env.company.subcontracting_location_id)
|
||||
resupply_rule.copy({'location_src_id': partner_subcontract_location.id})
|
||||
resupply_warehouse_rule = self.warehouse.route_ids.rule_ids.filtered(lambda l:
|
||||
l.location_id == self.env.company.subcontracting_location_id and
|
||||
l.location_src_id == self.warehouse.lot_stock_id)
|
||||
resupply_warehouse_rule.copy({'location_id': partner_subcontract_location.id})
|
||||
|
||||
# Create a receipt picking from the subcontractor
|
||||
picking_form = Form(self.env['stock.picking'])
|
||||
@@ -271,13 +185,18 @@ class TestSubcontractingFlows(SavepointCase):
|
||||
self.assertEquals(mo.state, 'done')
|
||||
|
||||
# Available quantities should be negative at the subcontracting location for each components
|
||||
avail_qty_comp1 = self.env['stock.quant']._get_available_quantity(self.comp1, self.subcontractor_partner1.property_stock_supplier, allow_negative=True)
|
||||
avail_qty_comp2 = self.env['stock.quant']._get_available_quantity(self.comp2, self.subcontractor_partner1.property_stock_supplier, allow_negative=True)
|
||||
avail_qty_comp1 = self.env['stock.quant']._get_available_quantity(self.comp1, self.subcontractor_partner1.property_stock_subcontractor, allow_negative=True)
|
||||
avail_qty_comp2 = self.env['stock.quant']._get_available_quantity(self.comp2, self.subcontractor_partner1.property_stock_subcontractor, allow_negative=True)
|
||||
avail_qty_finished = self.env['stock.quant']._get_available_quantity(self.finished, wh.lot_stock_id)
|
||||
self.assertEquals(avail_qty_comp1, -1)
|
||||
self.assertEquals(avail_qty_comp2, -1)
|
||||
self.assertEquals(avail_qty_finished, 1)
|
||||
|
||||
avail_qty_comp1_in_global_location = self.env['stock.quant']._get_available_quantity(self.comp1, self.env.company.subcontracting_location_id, allow_negative=True)
|
||||
avail_qty_comp2_in_global_location = self.env['stock.quant']._get_available_quantity(self.comp2, self.env.company.subcontracting_location_id, allow_negative=True)
|
||||
self.assertEqual(avail_qty_comp1_in_global_location, 0.0)
|
||||
self.assertEqual(avail_qty_comp2_in_global_location, 0.0)
|
||||
|
||||
def test_flow_3(self):
|
||||
""" Tick "Resupply Subcontractor on Order" and "MTO" on the components and trigger the
|
||||
creation of the subcontracting manufacturing order through a receipt picking. Checks if the
|
||||
@@ -328,8 +247,8 @@ class TestSubcontractingFlows(SavepointCase):
|
||||
self.assertEquals(mo.state, 'done')
|
||||
|
||||
# Available quantities should be negative at the subcontracting location for each components
|
||||
avail_qty_comp1 = self.env['stock.quant']._get_available_quantity(self.comp1, self.subcontractor_partner1.property_stock_supplier, allow_negative=True)
|
||||
avail_qty_comp2 = self.env['stock.quant']._get_available_quantity(self.comp2, self.subcontractor_partner1.property_stock_supplier, allow_negative=True)
|
||||
avail_qty_comp1 = self.env['stock.quant']._get_available_quantity(self.comp1, self.subcontractor_partner1.property_stock_subcontractor, allow_negative=True)
|
||||
avail_qty_comp2 = self.env['stock.quant']._get_available_quantity(self.comp2, self.subcontractor_partner1.property_stock_subcontractor, allow_negative=True)
|
||||
avail_qty_finished = self.env['stock.quant']._get_available_quantity(self.finished, wh.lot_stock_id)
|
||||
self.assertEquals(avail_qty_comp1, -1)
|
||||
self.assertEquals(avail_qty_comp2, -1)
|
||||
@@ -342,7 +261,6 @@ class TestSubcontractingFlows(SavepointCase):
|
||||
main_partner_2 = self.env['res.partner'].create({'name': 'main_partner'})
|
||||
subcontractor_partner2 = self.env['res.partner'].create({
|
||||
'name': 'subcontractor_partner',
|
||||
'type': 'subcontractor',
|
||||
'parent_id': main_partner_2.id,
|
||||
'company_id': self.env.ref('base.main_company').id
|
||||
})
|
||||
@@ -403,9 +321,9 @@ class TestSubcontractingFlows(SavepointCase):
|
||||
main_partner_2 = self.env['res.partner'].create({'name': 'main_partner'})
|
||||
subcontractor_partner2 = self.env['res.partner'].create({
|
||||
'name': 'subcontractor_partner',
|
||||
'type': 'subcontractor',
|
||||
'parent_id': main_partner_2.id,
|
||||
})
|
||||
self.env.cache.invalidate()
|
||||
|
||||
# We create a different BoM for the same product
|
||||
comp3 = self.env['product.product'].create({
|
||||
@@ -460,7 +378,6 @@ class TestSubcontractingTracking(TransactionCase):
|
||||
main_company_1 = self.env['res.partner'].create({'name': 'main_partner'})
|
||||
self.subcontractor_partner1 = self.env['res.partner'].create({
|
||||
'name': 'Subcontractor 1',
|
||||
'type': 'subcontractor',
|
||||
'parent_id': main_company_1.id,
|
||||
'company_id': self.env.ref('base.main_company').id
|
||||
})
|
||||
@@ -565,8 +482,8 @@ class TestSubcontractingTracking(TransactionCase):
|
||||
self.assertEquals(mo.state, 'done')
|
||||
|
||||
# Available quantities should be negative at the subcontracting location for each components
|
||||
avail_qty_comp1 = self.env['stock.quant']._get_available_quantity(self.comp1_sn, self.subcontractor_partner1.property_stock_supplier, allow_negative=True)
|
||||
avail_qty_comp2 = self.env['stock.quant']._get_available_quantity(self.comp2, self.subcontractor_partner1.property_stock_supplier, allow_negative=True)
|
||||
avail_qty_comp1 = self.env['stock.quant']._get_available_quantity(self.comp1_sn, self.subcontractor_partner1.property_stock_subcontractor, allow_negative=True)
|
||||
avail_qty_comp2 = self.env['stock.quant']._get_available_quantity(self.comp2, self.subcontractor_partner1.property_stock_subcontractor, allow_negative=True)
|
||||
avail_qty_finished = self.env['stock.quant']._get_available_quantity(self.finished_lot, wh.lot_stock_id)
|
||||
self.assertEquals(avail_qty_comp1, -1)
|
||||
self.assertEquals(avail_qty_comp2, -1)
|
||||
|
||||
@@ -1,14 +1,13 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<record id="view_partner_form_inherit_mrp" model="ir.ui.view">
|
||||
<field name="name">res.partner.form.inherit.mrp</field>
|
||||
<record id="view_partner_mrp_subcontracting_form" model="ir.ui.view">
|
||||
<field name="name">res.partner.mrp_subcontracting.property.form.inherit</field>
|
||||
<field name="model">res.partner</field>
|
||||
<field name="inherit_id" ref="base.view_partner_form" />
|
||||
<field name="inherit_id" ref="stock.view_partner_stock_form"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//span[@name='address_name']" position="inside">
|
||||
<b attrs="{'invisible': ['|', ('parent_id', '=', False), ('type', '!=', 'subcontractor')]}">Subcontractor Address</b>
|
||||
<xpath expr="//field[@name='property_stock_supplier']" position="after">
|
||||
<field name="property_stock_subcontractor"/>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
</odoo>
|
||||
|
||||
|
||||
@@ -9,8 +9,9 @@ class SupplierInfo(models.Model):
|
||||
|
||||
is_subcontractor = fields.Boolean('Subcontracted', compute='_compute_is_subcontractor', help="Choose a vendor of type subcontractor if you want to subcontract the product")
|
||||
|
||||
@api.depends('name')
|
||||
@api.depends('name', 'product_id', 'product_tmpl_id')
|
||||
def _compute_is_subcontractor(self):
|
||||
for supplierinfo in self:
|
||||
supplierinfo.is_subcontractor = True if supplierinfo.name.type == 'subcontractor' else False
|
||||
|
||||
for supplier in self:
|
||||
boms = supplier.product_id.variant_bom_ids
|
||||
boms |= supplier.product_tmpl_id.bom_ids.filtered(lambda b: not b.product_id)
|
||||
supplier.is_subcontractor = supplier.name in boms.subcontractor_ids
|
||||
|
||||
@@ -43,7 +43,6 @@ class TestPurchaseSubcontractingFlows(TransactionCase):
|
||||
company_partner = self.env['res.partner'].create({'name': 'main_partner', 'is_company': True})
|
||||
self.subcontractor_partner1 = self.env['res.partner'].create({
|
||||
'name': 'subcontractor_partner',
|
||||
'type': 'subcontractor',
|
||||
'parent_id': company_partner.id,
|
||||
'company_id': self.env.ref('base.main_company').id
|
||||
})
|
||||
|
||||
@@ -10,16 +10,5 @@
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="product_supplierinfo_subcontracting_form_view" model="ir.ui.view">
|
||||
<field name="name">product.supplierinfo.subcontracting.form.view</field>
|
||||
<field name="model">product.supplierinfo</field>
|
||||
<field name="inherit_id" ref="product.product_supplierinfo_form_view"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//group[@name='vendor']" position="inside">
|
||||
<field name="is_subcontractor" readonly="1"/>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
</odoo>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user