mirror of
https://github.com/bringout/oca-ocb-mrp.git
synced 2026-04-26 23:32:01 +02:00
19.0 vanilla
This commit is contained in:
parent
accf5918df
commit
6e65e8c877
688 changed files with 225434 additions and 199401 deletions
|
|
@ -1,6 +1,9 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from . import stock_picking
|
||||
from . import stock_move
|
||||
from . import account_move_line
|
||||
from . import product_product
|
||||
from . import purchase_order
|
||||
from . import stock_move
|
||||
from . import stock_picking
|
||||
from . import stock_rule
|
||||
|
|
|
|||
|
|
@ -0,0 +1,30 @@
|
|||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from odoo import models
|
||||
|
||||
|
||||
class AccountMoveLine(models.Model):
|
||||
_inherit = 'account.move.line'
|
||||
|
||||
def _get_price_unit_val_dif_and_relevant_qty(self):
|
||||
price_unit_val_dif, relevant_qty = super()._get_price_unit_val_dif_and_relevant_qty()
|
||||
if self.product_id.cost_method == 'standard' and self.purchase_line_id:
|
||||
components_cost = 0
|
||||
subcontract_production = self.purchase_line_id.move_ids._get_subcontract_production()
|
||||
valuation_date = subcontract_production.move_raw_ids and max(subcontract_production.move_raw_ids.mapped('date')) or self.date
|
||||
components_cost = self.company_currency_id._convert(
|
||||
sum(subcontract_production.move_raw_ids.mapped('value')),
|
||||
self.currency_id, self.company_id, valuation_date, round=False
|
||||
)
|
||||
qty = sum(mo.product_uom_id._compute_quantity(mo.qty_producing, self.product_uom_id) for mo in subcontract_production if mo.state == 'done')
|
||||
if not self.product_uom_id.is_zero(qty):
|
||||
price_unit_val_dif = price_unit_val_dif + components_cost / qty
|
||||
return price_unit_val_dif, relevant_qty
|
||||
|
||||
def _get_stock_moves(self):
|
||||
moves = super()._get_stock_moves()
|
||||
finished_moves = set()
|
||||
for m in moves:
|
||||
if mo := m._get_subcontract_production():
|
||||
finished_moves |= set(mo.move_finished_ids.filtered(lambda mf: mf.product_id == m.product_id).ids)
|
||||
return moves | self.env['stock.move'].browse(finished_moves)
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from odoo import api, models
|
||||
from odoo.fields import Domain
|
||||
|
||||
|
||||
class ProductProduct(models.Model):
|
||||
_inherit = 'product.product'
|
||||
|
||||
@api.model
|
||||
def _get_monthly_demand_moves_location_domain(self):
|
||||
subcontracting_location_ids = self.env.companies.subcontracting_location_id.child_internal_location_ids.ids
|
||||
domain = Domain.AND([
|
||||
Domain.OR([
|
||||
super()._get_monthly_demand_moves_location_domain(),
|
||||
[('location_dest_id', 'in', subcontracting_location_ids)],
|
||||
]),
|
||||
[('location_id', 'not in', subcontracting_location_ids)],
|
||||
])
|
||||
return domain
|
||||
|
|
@ -10,3 +10,29 @@ class StockMove(models.Model):
|
|||
def _is_purchase_return(self):
|
||||
res = super()._is_purchase_return()
|
||||
return res or self._is_subcontract_return()
|
||||
|
||||
def _get_value_from_account_move(self, quantity, at_date=None):
|
||||
valuation_data = super()._get_value_from_account_move(quantity, at_date=at_date)
|
||||
last_subcontract_done_receipt = self.move_dest_ids.filtered(
|
||||
lambda m: m.state == 'done' and m.is_subcontract and m.purchase_line_id
|
||||
).sorted('create_date', reverse=True)[:1]
|
||||
if not self.production_id or not last_subcontract_done_receipt:
|
||||
return valuation_data
|
||||
|
||||
bill_data = last_subcontract_done_receipt._get_value_from_account_move(quantity)
|
||||
po_data = last_subcontract_done_receipt._get_value_from_quotation(quantity - bill_data['quantity'])
|
||||
if not bill_data['value'] and not po_data['value']:
|
||||
return valuation_data
|
||||
|
||||
old_extra = self.production_id.extra_cost
|
||||
new_extra_cost = (bill_data['value'] + po_data['value']) / quantity
|
||||
|
||||
# Recompute finished_move price based on quotation and invoice
|
||||
value = (self.price_unit - old_extra + new_extra_cost) * self.quantity
|
||||
return {
|
||||
'value': value,
|
||||
'quantity': quantity,
|
||||
'description': self.env._('%(value)s for %(quantity)s %(unit)s from %(production)s',
|
||||
value=self.company_currency_id.format(self.value), quantity=quantity, unit=self.product_id.uom_id.name,
|
||||
production=self.production_id.display_name),
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,10 +31,15 @@ class StockPicking(models.Model):
|
|||
action.update({
|
||||
'name': _("Source PO of %s", self.name),
|
||||
'domain': [('id', 'in', purchase_order_ids)],
|
||||
'view_mode': 'tree,form',
|
||||
'view_mode': 'list,form',
|
||||
})
|
||||
return action
|
||||
|
||||
def _get_subcontracting_source_purchase(self):
|
||||
moves_subcontracted = self.move_ids.move_dest_ids.raw_material_production_id.move_finished_ids.move_dest_ids.filtered(lambda m: m.is_subcontract)
|
||||
return moves_subcontracted.purchase_line_id.order_id
|
||||
|
||||
def _get_subcontract_mo_confirmation_ctx(self):
|
||||
res = super()._get_subcontract_mo_confirmation_ctx()
|
||||
res['po_to_notify'] = self.move_ids.purchase_line_id.order_id
|
||||
return res
|
||||
|
|
|
|||
|
|
@ -0,0 +1,60 @@
|
|||
from odoo import models, _
|
||||
|
||||
|
||||
class StockRule(models.Model):
|
||||
_inherit = 'stock.rule'
|
||||
|
||||
def _get_lead_days(self, product, **values):
|
||||
"""For subcontracting, we need to consider both vendor lead time and
|
||||
manufacturing lead time, and DTPMO (Days To Prepare MO).
|
||||
Subcontracting delay =
|
||||
max(Vendor lead time, Manufacturing lead time + DTPMO) + Days to Purchase
|
||||
"""
|
||||
bypass_delay_description = self.env.context.get('bypass_delay_description')
|
||||
buy_rule = self.filtered(lambda r: r.action == 'buy')
|
||||
seller = 'supplierinfo' in values and values['supplierinfo'] or product.with_company(buy_rule.company_id)._select_seller(quantity=None)
|
||||
if not buy_rule or not seller:
|
||||
return super()._get_lead_days(product, **values)
|
||||
seller = seller[0]
|
||||
bom = self.env['mrp.bom'].sudo()._bom_subcontract_find(
|
||||
product,
|
||||
company_id=buy_rule.picking_type_id.company_id.id,
|
||||
bom_type='subcontract',
|
||||
subcontractor=seller.partner_id)
|
||||
if not bom:
|
||||
return super()._get_lead_days(product, **values)
|
||||
|
||||
delays, delay_description = super(StockRule, self - buy_rule)._get_lead_days(product, **values)
|
||||
extra_delays, extra_delay_description = super(StockRule, buy_rule.with_context(ignore_vendor_lead_time=True, global_horizon_days=0))._get_lead_days(product, **values)
|
||||
if seller.delay >= bom.produce_delay + bom.days_to_prepare_mo:
|
||||
delays['total_delay'] += seller.delay
|
||||
delays['purchase_delay'] += seller.delay
|
||||
if not bypass_delay_description:
|
||||
delay_description.append((_('Receipt Date'), int(seller.delay)))
|
||||
delay_description.append((_('Vendor Lead Time'), _('+ %d day(s)', seller.delay)))
|
||||
else:
|
||||
manufacture_delay = bom.produce_delay
|
||||
delays['total_delay'] += manufacture_delay
|
||||
# set manufacture_delay to purchase_delay so that PO can be created with correct date
|
||||
delays['purchase_delay'] += manufacture_delay
|
||||
if not bypass_delay_description:
|
||||
delay_description.append((_('Receipt Date'), manufacture_delay))
|
||||
delay_description.append((_('Manufacturing Lead Time'), _('+ %d day(s)', manufacture_delay)))
|
||||
days_to_order = bom.days_to_prepare_mo
|
||||
delays['total_delay'] += days_to_order
|
||||
# add dtpmo to purchase_delay so that PO can be created with correct date
|
||||
delays['purchase_delay'] += days_to_order
|
||||
if not bypass_delay_description:
|
||||
delay_description.append((_('Production Start Date'), days_to_order))
|
||||
delay_description.append((_('Days to Supply Components'), _('+ %d day(s)', days_to_order)))
|
||||
|
||||
for key, value in extra_delays.items():
|
||||
delays[key] += value
|
||||
return delays, delay_description + extra_delay_description
|
||||
|
||||
def _notify_responsible(self, procurement):
|
||||
super()._notify_responsible(procurement)
|
||||
origin_order = self.env.context.get('po_to_notify')
|
||||
if origin_order:
|
||||
notified_users = procurement.product_id.responsible_id.partner_id | origin_order.user_id.partner_id
|
||||
self._post_vendor_notification(origin_order, notified_users, procurement.product_id)
|
||||
Loading…
Add table
Add a link
Reference in a new issue