mirror of
https://github.com/bringout/oca-ocb-mrp.git
synced 2026-04-27 19:52:02 +02:00
19.0 vanilla
This commit is contained in:
parent
accf5918df
commit
6e65e8c877
688 changed files with 225434 additions and 199401 deletions
|
|
@ -6,5 +6,6 @@ from . import stock_picking
|
|||
from . import res_company
|
||||
from . import stock_warehouse
|
||||
from . import purchase
|
||||
from . import stock_replenish_mixin
|
||||
from . import stock_rule
|
||||
from . import stock_orderpoint
|
||||
|
|
|
|||
|
|
@ -8,14 +8,20 @@ from odoo.exceptions import UserError
|
|||
class PurchaseOrder(models.Model):
|
||||
_inherit = 'purchase.order'
|
||||
|
||||
default_location_dest_id_is_subcontracting_loc = fields.Boolean(related='picking_type_id.default_location_dest_id.is_subcontracting_location')
|
||||
default_location_dest_id_is_subcontracting_loc = fields.Boolean(compute='_compute_default_location_dest_id_is_subcontracting_loc')
|
||||
|
||||
@api.depends('picking_type_id.default_location_dest_id')
|
||||
def _compute_default_location_dest_id_is_subcontracting_loc(self):
|
||||
for order in self:
|
||||
order.default_location_dest_id_is_subcontracting_loc = order.picking_type_id.default_location_dest_id.is_subcontract()
|
||||
|
||||
@api.depends('default_location_dest_id_is_subcontracting_loc')
|
||||
def _compute_dest_address_id(self):
|
||||
dropship_subcontract_pos = self.filtered(lambda po: po.default_location_dest_id_is_subcontracting_loc)
|
||||
for order in dropship_subcontract_pos:
|
||||
subcontractor_ids = order.picking_type_id.default_location_dest_id.subcontractor_ids
|
||||
order.dest_address_id = subcontractor_ids if len(subcontractor_ids) == 1 else False
|
||||
if len(subcontractor_ids) == 1:
|
||||
order.dest_address_id = subcontractor_ids
|
||||
super(PurchaseOrder, self - dropship_subcontract_pos)._compute_dest_address_id()
|
||||
|
||||
@api.onchange('picking_type_id')
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ class ResCompany(models.Model):
|
|||
'company_id': company.id,
|
||||
'warehouse_id': False,
|
||||
'sequence_id': sequence.id,
|
||||
'code': 'incoming',
|
||||
'code': 'dropship',
|
||||
'default_location_src_id': self.env.ref('stock.stock_location_suppliers').id,
|
||||
'default_location_dest_id': company.subcontracting_location_id.id,
|
||||
'sequence_code': 'DSC',
|
||||
|
|
@ -45,7 +45,7 @@ class ResCompany(models.Model):
|
|||
pick_type.company_id.dropship_subcontractor_pick_type_id = pick_type.id
|
||||
|
||||
def _create_subcontracting_dropshipping_rules(self):
|
||||
route = self.env.ref('mrp_subcontracting_dropshipping.route_subcontracting_dropshipping')
|
||||
dropship_route = self.env.ref('stock_dropshipping.route_drop_shipping')
|
||||
supplier_location = self.env.ref('stock.stock_location_suppliers')
|
||||
vals = []
|
||||
for company in self:
|
||||
|
|
@ -62,7 +62,7 @@ class ResCompany(models.Model):
|
|||
'location_dest_id': subcontracting_location.id,
|
||||
'location_src_id': supplier_location.id,
|
||||
'procure_method': 'make_to_stock',
|
||||
'route_id': route.id,
|
||||
'route_id': dropship_route.id,
|
||||
'picking_type_id': dropship_picking_type.id,
|
||||
'company_id': company.id,
|
||||
})
|
||||
|
|
@ -71,10 +71,8 @@ class ResCompany(models.Model):
|
|||
|
||||
@api.model
|
||||
def _create_missing_subcontracting_dropshipping_rules(self):
|
||||
route = self.env.ref('mrp_subcontracting_dropshipping.route_subcontracting_dropshipping')
|
||||
company_ids = self.env['res.company'].search([])
|
||||
company_has_rules = self.env['stock.rule'].search([('route_id', '=', route.id)]).mapped('company_id')
|
||||
company_todo_rules = company_ids - company_has_rules
|
||||
route = self.env.ref('stock_dropshipping.route_drop_shipping')
|
||||
company_todo_rules = self.env['stock.rule'].search([('route_id', '=', route.id)]).mapped('company_id')
|
||||
company_todo_rules._create_subcontracting_dropshipping_rules()
|
||||
|
||||
@api.model
|
||||
|
|
|
|||
|
|
@ -7,23 +7,31 @@ from odoo import models
|
|||
class StockMove(models.Model):
|
||||
_inherit = "stock.move"
|
||||
|
||||
def _prepare_procurement_values(self):
|
||||
vals = super()._prepare_procurement_values()
|
||||
partner = self.group_id.partner_id
|
||||
if not vals.get('partner_id') and partner and self.location_id.is_subcontracting_location:
|
||||
vals['partner_id'] = partner.id
|
||||
return vals
|
||||
|
||||
def _is_purchase_return(self):
|
||||
res = super()._is_purchase_return()
|
||||
return res or self._is_dropshipped_returned()
|
||||
|
||||
def _is_dropshipped(self):
|
||||
res = super()._is_dropshipped()
|
||||
return res or (
|
||||
return (
|
||||
res
|
||||
# subcontractor -> customer
|
||||
or (
|
||||
self.partner_id.property_stock_subcontractor.parent_path
|
||||
and self.partner_id.property_stock_subcontractor.parent_path in self.location_id.parent_path
|
||||
and self.location_dest_id.usage == 'customer'
|
||||
and (
|
||||
(
|
||||
self.partner_id.property_stock_subcontractor.parent_path
|
||||
in self.location_id.parent_path
|
||||
and self.location_dest_id.usage == "customer"
|
||||
)
|
||||
# Vendor -> subcontractor location
|
||||
or (
|
||||
self.partner_id.property_stock_subcontractor.parent_path
|
||||
in self.location_dest_id.parent_path
|
||||
and self.location_id.usage == "supplier"
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
def _is_dropshipped_returned(self):
|
||||
|
|
|
|||
|
|
@ -7,8 +7,8 @@ from odoo import models
|
|||
class StockWarehouseOrderpoint(models.Model):
|
||||
_inherit = 'stock.warehouse.orderpoint'
|
||||
|
||||
def _prepare_procurement_values(self, date=False, group=False):
|
||||
vals = super()._prepare_procurement_values(date, group)
|
||||
if not vals.get('partner_id') and self.location_id.is_subcontracting_location and len(self.location_id.subcontractor_ids) == 1:
|
||||
def _prepare_procurement_values(self, date=False):
|
||||
vals = super()._prepare_procurement_values(date)
|
||||
if not vals.get('partner_id') and self.location_id.is_subcontract() and len(self.location_id.subcontractor_ids) == 1:
|
||||
vals['partner_id'] = self.location_id.subcontractor_ids.id
|
||||
return vals
|
||||
|
|
|
|||
|
|
@ -9,64 +9,20 @@ class StockPicking(models.Model):
|
|||
_inherit = 'stock.picking'
|
||||
|
||||
def _compute_is_dropship(self):
|
||||
dropship_subcontract_pickings = self.filtered(lambda p: p.location_dest_id.is_subcontracting_location and p.location_id.usage == 'supplier')
|
||||
dropship_subcontract_pickings = self.filtered(lambda p: p.location_dest_id.is_subcontract() and p.location_id.usage == 'supplier')
|
||||
dropship_subcontract_pickings.is_dropship = True
|
||||
super(StockPicking, self - dropship_subcontract_pickings)._compute_is_dropship()
|
||||
|
||||
def _get_warehouse(self, subcontract_move):
|
||||
if subcontract_move.sale_line_id:
|
||||
return subcontract_move.sale_line_id.order_id.warehouse_id
|
||||
return super(StockPicking, self)._get_warehouse(subcontract_move)
|
||||
|
||||
def _action_done(self):
|
||||
res = super()._action_done()
|
||||
|
||||
# If needed, create a compensation layer, so we add the MO cost to the dropship one
|
||||
svls = self.env['stock.valuation.layer']
|
||||
for move in self.move_ids:
|
||||
if not (move.is_subcontract and move._is_dropshipped() and move.state == 'done'):
|
||||
continue
|
||||
|
||||
dropship_svls = move.stock_valuation_layer_ids
|
||||
if not dropship_svls:
|
||||
continue
|
||||
|
||||
# In a backorder chain, only generate SVLs for the latest backorder, or else their
|
||||
# value will be cumulative.
|
||||
if any(move.move_orig_ids.production_id.mapped('backorder_sequence')):
|
||||
moves_with_svls = move.move_orig_ids.filtered('stock_valuation_layer_ids')
|
||||
subcontract_svls = max(
|
||||
moves_with_svls,
|
||||
key=lambda sm: sm.production_id.backorder_sequence
|
||||
).stock_valuation_layer_ids
|
||||
else:
|
||||
subcontract_svls = move.move_orig_ids.stock_valuation_layer_ids
|
||||
subcontract_value = sum(subcontract_svls.mapped('value'))
|
||||
dropship_value = abs(sum(dropship_svls.mapped('value')))
|
||||
diff = subcontract_value - dropship_value
|
||||
if float_compare(diff, 0, precision_rounding=move.company_id.currency_id.rounding) <= 0:
|
||||
continue
|
||||
|
||||
svl_vals = move._prepare_common_svl_vals()
|
||||
svl_vals.update({
|
||||
'remaining_value': 0,
|
||||
'remaining_qty': 0,
|
||||
'value': -diff,
|
||||
'quantity': 0,
|
||||
'unit_cost': 0,
|
||||
'stock_valuation_layer_id': dropship_svls[0].id,
|
||||
'stock_move_id': move.id,
|
||||
})
|
||||
svls |= self.env['stock.valuation.layer'].create(svl_vals)
|
||||
svls._validate_accounting_entries()
|
||||
|
||||
return res
|
||||
return super()._get_warehouse(subcontract_move)
|
||||
|
||||
def _prepare_subcontract_mo_vals(self, subcontract_move, bom):
|
||||
res = super()._prepare_subcontract_mo_vals(subcontract_move, bom)
|
||||
if not res.get('picking_type_id') and (
|
||||
subcontract_move.location_dest_id.usage == 'customer'
|
||||
or subcontract_move.location_dest_id.is_subcontracting_location
|
||||
or subcontract_move.location_dest_id.is_subcontract()
|
||||
):
|
||||
# If the if-condition is respected, it means that `subcontract_move` is not
|
||||
# related to a specific warehouse. This can happen if, for instance, the user
|
||||
|
|
|
|||
|
|
@ -0,0 +1,12 @@
|
|||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from odoo import models
|
||||
from odoo.fields import Domain
|
||||
|
||||
|
||||
class StockReplenishMixin(models.AbstractModel):
|
||||
_inherit = 'stock.replenish.mixin'
|
||||
|
||||
def _get_allowed_route_domain(self):
|
||||
domains = super()._get_allowed_route_domain()
|
||||
return Domain.AND([domains, [('id', '!=', self.env.ref('stock_dropshipping.route_drop_shipping', raise_if_not_found=False).id)]])
|
||||
|
|
@ -8,14 +8,16 @@ class StockRule(models.Model):
|
|||
_inherit = 'stock.rule'
|
||||
|
||||
def _prepare_purchase_order(self, company_id, origins, values):
|
||||
if 'partner_id' not in values[0] \
|
||||
if not values[0].get('partner_id') \
|
||||
and (company_id.subcontracting_location_id.parent_path in self.location_dest_id.parent_path
|
||||
or self.location_dest_id.is_subcontracting_location):
|
||||
values[0]['partner_id'] = values[0]['group_id'].partner_id.id
|
||||
or self.location_dest_id.is_subcontract()):
|
||||
move = values[0].get('move_dest_ids')
|
||||
if move and move.raw_material_production_id.subcontractor_id:
|
||||
values[0]['partner_id'] = move.raw_material_production_id.subcontractor_id.id
|
||||
return super()._prepare_purchase_order(company_id, origins, values)
|
||||
|
||||
def _make_po_get_domain(self, company_id, values, partner):
|
||||
domain = super()._make_po_get_domain(company_id, values, partner)
|
||||
if values.get('partner_id', False):
|
||||
if self.location_src_id.usage == 'supplier' and self.location_dest_id.is_subcontract() and values.get('partner_id', False):
|
||||
domain += (('dest_address_id', '=', values.get('partner_id')),)
|
||||
return domain
|
||||
|
|
|
|||
|
|
@ -7,27 +7,23 @@ from odoo import api, fields, models, _
|
|||
class StockWarehouse(models.Model):
|
||||
_inherit = 'stock.warehouse'
|
||||
|
||||
subcontracting_dropshipping_to_resupply = fields.Boolean(
|
||||
'Dropship Subcontractors', default=True,
|
||||
help="Dropship subcontractors with components")
|
||||
|
||||
subcontracting_dropshipping_pull_id = fields.Many2one(
|
||||
'stock.rule', 'Subcontracting-Dropshipping MTS Rule'
|
||||
'stock.rule', 'Subcontracting-Dropshipping MTS Rule', copy=False
|
||||
)
|
||||
|
||||
@api.model_create_multi
|
||||
def create(self, vals_list):
|
||||
res = super().create(vals_list)
|
||||
# if new warehouse has resupply enabled, enable global route
|
||||
if any([vals.get('subcontracting_dropshipping_to_resupply', False) for vals in vals_list]):
|
||||
if any(vals.get('subcontracting_to_resupply', False) for vals in vals_list):
|
||||
res.update_global_route_dropship_subcontractor()
|
||||
return res
|
||||
|
||||
def write(self, vals):
|
||||
res = super().write(vals)
|
||||
# if all warehouses have resupply disabled, disable global route, until its enabled on a warehouse
|
||||
if 'subcontracting_dropshipping_to_resupply' in vals or 'active' in vals:
|
||||
if 'subcontracting_dropshipping_to_resupply' in vals:
|
||||
if 'subcontracting_to_resupply' in vals or 'active' in vals:
|
||||
if 'subcontracting_to_resupply' in vals:
|
||||
# ignore when warehouse archived since it will auto-archive all of its rules
|
||||
self._update_dropship_subcontract_rules()
|
||||
self.update_global_route_dropship_subcontractor()
|
||||
|
|
@ -36,9 +32,9 @@ class StockWarehouse(models.Model):
|
|||
def _update_dropship_subcontract_rules(self):
|
||||
'''update (archive/unarchive) any warehouse subcontracting location dropship rules'''
|
||||
subcontracting_locations = self._get_subcontracting_locations()
|
||||
route_id = self._find_or_create_global_route('mrp_subcontracting_dropshipping.route_subcontracting_dropshipping',
|
||||
route_id = self._find_or_create_global_route('stock_dropshipping.route_drop_shipping',
|
||||
_('Dropship Subcontractor on Order'))
|
||||
warehouses_dropship = self.filtered(lambda w: w.subcontracting_dropshipping_to_resupply and w.active)
|
||||
warehouses_dropship = self.filtered(lambda w: w.subcontracting_to_resupply and w.active)
|
||||
if warehouses_dropship:
|
||||
self.env['stock.rule'].with_context(active_test=False).search([
|
||||
('route_id', '=', route_id.id),
|
||||
|
|
@ -55,7 +51,7 @@ class StockWarehouse(models.Model):
|
|||
('location_src_id', 'in', subcontracting_locations.ids)]).action_archive()
|
||||
|
||||
def update_global_route_dropship_subcontractor(self):
|
||||
route_id = self._find_or_create_global_route('mrp_subcontracting_dropshipping.route_subcontracting_dropshipping',
|
||||
route_id = self._find_or_create_global_route('stock_dropshipping.route_drop_shipping',
|
||||
_('Dropship Subcontractor on Order'))
|
||||
# if route has no pull rules, it means all warehouses have Dropship Subcontractor disabled
|
||||
# Pick type is per company so we need to check rules per company to archive it, however
|
||||
|
|
@ -67,27 +63,26 @@ class StockWarehouse(models.Model):
|
|||
|
||||
route_id.active = bool(all_rules.filtered(lambda r: r.action == 'pull'))
|
||||
|
||||
def _get_global_route_rules_values(self):
|
||||
rules = super()._get_global_route_rules_values()
|
||||
def _generate_global_route_rules_values(self):
|
||||
rules = super()._generate_global_route_rules_values()
|
||||
subcontract_location_id = self._get_subcontracting_location()
|
||||
production_location_id = self._get_production_location()
|
||||
rules.update({
|
||||
'subcontracting_dropshipping_pull_id': {
|
||||
'depends': ['subcontracting_dropshipping_to_resupply'],
|
||||
'depends': ['subcontracting_to_resupply'],
|
||||
'create_values': {
|
||||
'procure_method': 'make_to_order',
|
||||
'company_id': self.company_id.id,
|
||||
'action': 'pull',
|
||||
'auto': 'manual',
|
||||
'route_id': self._find_or_create_global_route('mrp_subcontracting_dropshipping.route_subcontracting_dropshipping',
|
||||
_('Dropship Subcontractor on Order')).id,
|
||||
'route_id': self._find_or_create_global_route('stock_dropshipping.route_drop_shipping', self.env._('Dropship Subcontractor on Order')).id,
|
||||
'name': self._format_rulename(subcontract_location_id, production_location_id, False),
|
||||
'location_dest_id': production_location_id.id,
|
||||
'location_src_id': subcontract_location_id.id,
|
||||
'picking_type_id': self.subcontracting_type_id.id
|
||||
},
|
||||
'update_values': {
|
||||
'active': self.subcontracting_dropshipping_to_resupply
|
||||
'active': self.subcontracting_to_resupply
|
||||
}
|
||||
},
|
||||
})
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue