1
0
forked from Mapan/odoo17e
odoo17e-kedaikipas58/addons/stock_barcode_mrp/models/mrp_production.py
2024-12-10 09:04:09 +07:00

196 lines
9.3 KiB
Python

from odoo import api, fields, models, _
class ManufacturingOrder(models.Model):
_inherit = 'mrp.production'
move_raw_line_ids = fields.One2many('stock.move.line', compute='_compute_move_raw_line_ids')
move_byproduct_line_ids = fields.One2many('stock.move.line', compute='_compute_move_byproduct_line_ids')
is_completed = fields.Boolean(compute='_compute_is_completed')
backorder_ids = fields.One2many(related='procurement_group_id.mrp_production_ids')
@api.depends('move_raw_ids')
def _compute_move_raw_line_ids(self):
for order in self:
order.move_raw_line_ids = order.move_raw_ids.move_line_ids
@api.depends('move_byproduct_ids')
def _compute_move_byproduct_line_ids(self):
for order in self:
order.move_byproduct_line_ids = order.move_byproduct_ids.move_line_ids
@api.depends('qty_produced', 'product_qty')
def _compute_is_completed(self):
for order in self:
order.is_completed = order.qty_produced == order.product_qty
def action_open_barcode_client_action(self):
self.ensure_one()
action = self.env["ir.actions.actions"]._for_xml_id("stock_barcode_mrp.stock_barcode_mo_client_action")
action = dict(action, target='fullscreen')
action['context'] = {'active_id': self.id}
return action
def set_lot_producing(self):
""" Special mo barcode action to produce and return SN/lot data compatible with barcode app.
Helps avoid doing extra db calls within barcode that using action_generate_serial
would require."""
self._set_lot_producing()
action = False
if self.picking_type_id.auto_print_generated_mrp_lot:
action = self._autoprint_generated_lot(self.lot_producing_id)
return self.lot_producing_id.read(self.lot_producing_id._get_fields_stock_barcode(), load=False), action
def _get_fields_stock_barcode(self):
return [
'move_raw_line_ids',
'move_raw_ids',
'move_byproduct_line_ids',
'move_byproduct_ids',
'production_location_id',
'picking_type_id',
'location_src_id',
'location_dest_id',
'product_id',
'product_uom_id',
'product_qty',
'qty_producing',
'lot_producing_id',
'name',
'state',
'picking_type_id',
'company_id',
'user_id',
'procurement_group_id',
'backorder_ids',
]
def _get_stock_barcode_data(self):
# Avoid to get the products full name because code and name are separate in the barcode app.
self = self.with_context(display_default_code=False)
move_lines = self.move_raw_line_ids | self.move_byproduct_line_ids
lots = move_lines.lot_id | self.lot_producing_id
owners = move_lines.owner_id
# Fetch all implied products in `self`
products = self.product_id | (self.move_raw_ids + self.move_byproduct_ids).product_id
moves = self.move_raw_ids | self.move_byproduct_ids
packagings = products.packaging_ids
uoms = products.uom_id | move_lines.product_uom_id
# If UoM setting is active, fetch all UoM's data.
if self.env.user.has_group('uom.group_uom'):
uoms |= self.env['uom.uom'].search([])
# Fetch `stock.location`
source_locations = self.env['stock.location'].search([('id', 'child_of', self.location_src_id.ids)])
destination_locations = self.env['stock.location'].search([('id', 'child_of', self.location_dest_id.ids)])
locations = move_lines.location_id | move_lines.location_dest_id | source_locations | destination_locations | self.production_location_id
# Fetch `stock.quant.package` and `stock.package.type` if group_tracking_lot.
packages = self.env['stock.quant.package']
package_types = self.env['stock.package.type']
if self.env.user.has_group('stock.group_tracking_lot'):
packages |= move_lines.package_id | move_lines.result_package_id
packages |= self.env['stock.quant.package'].with_context(pack_locs=destination_locations.ids)._get_usable_packages()
package_types = package_types.search([])
data = {
"records": {
"mrp.production": self.read(self._get_fields_stock_barcode(), load=False),
"stock.picking.type": self.picking_type_id.read(self.picking_type_id._get_fields_stock_barcode(), load=False),
"stock.move": moves.read(moves._get_fields_stock_barcode(), load=False),
"stock.move.line": move_lines.read(move_lines._get_fields_stock_barcode(), load=False),
"product.product": products.read(products._get_fields_stock_barcode(), load=False),
"product.packaging": packagings.read(packagings._get_fields_stock_barcode(), load=False),
"res.partner": owners.read(owners._get_fields_stock_barcode(), load=False),
"stock.location": locations.read(locations._get_fields_stock_barcode(), load=False),
"stock.package.type": package_types.read(package_types._get_fields_stock_barcode(), False),
"stock.quant.package": packages.read(packages._get_fields_stock_barcode(), load=False),
"stock.lot": lots.read(lots._get_fields_stock_barcode(), load=False),
"uom.uom": uoms.read(uoms._get_fields_stock_barcode(), load=False),
},
"nomenclature_id": [self.env.company.nomenclature_id.id],
"source_location_ids": source_locations.ids,
"destination_locations_ids": destination_locations.ids,
}
data['config'] = self.picking_type_id._get_barcode_config() if self else {}
data['line_view_id'] = self.env.ref('stock_barcode.stock_move_line_product_selector').id
data['form_view_id'] = self.env.ref('stock_barcode_mrp.mrp_barcode_form').id
data['header_view_id'] = self.env.ref('stock_barcode_mrp.mrp_product_selector').id
data['scrap_view_id'] = self.env.ref('stock_barcode_mrp.scrap_product_selector').id
data['package_view_id'] = self.env.ref('stock_barcode.stock_quant_barcode_kanban').id
return data
@api.model
def filter_on_barcode(self, barcode):
""" Searches ready MOs for the scanned product or order.
"""
barcode_type = None
nomenclature = self.env.company.nomenclature_id
if nomenclature.is_gs1_nomenclature:
parsed_results = nomenclature.parse_barcode(barcode)
if parsed_results:
# filter with the last feasible rule
for result in parsed_results[::-1]:
if result['rule'].type in ('product', 'package'):
barcode_type = result['rule'].type
break
base_domain = [
('state', 'in', ['confirmed', 'progress']),
('reservation_state', '=', 'assigned'),
]
active_id = self.env.context.get('active_id')
additional_context = {
'search_default_filter_confirmed': 1,
'search_default_filter_ready': 1,
'search_default_filter_in_progress': 1,
'search_default_filter_to_close': 1,
'search_default_todo': 1,
'active_id': active_id,
}
picking_type = self.env['stock.picking.type'].browse(active_id)
mo_nums = 0
if barcode_type == 'product' or not barcode_type:
product = self.env['product.product'].search([('barcode', '=', barcode)], limit=1)
if product:
mo_nums = self.search_count(base_domain + [('product_id', '=', product.id)])
if mo_nums:
additional_context['search_default_product_id'] = product.id
else:
mo_nums = self.search_count(base_domain + [('move_raw_ids.product_id', '=', product.id)])
additional_context['search_default_move_raw_ids'] = barcode
if not barcode_type and not mo_nums: # Nothing found yet, try to find picking by name.
mo_nums = self.search_count(base_domain + [('name', '=', barcode)])
additional_context['search_default_name'] = barcode
if not mo_nums:
if barcode_type:
return {
'warning': {
'message': _("No Manufacturing Order ready for this %(barcode_type)s", barcode_type=barcode_type),
}
}
return {
'warning': {
'title': _('No product or order found for barcode %s', barcode),
'message': _('Scan a product to filter the orders.'),
}
}
action = picking_type._get_action('stock_barcode_mrp.mrp_action_kanban')
action['context'].update(additional_context)
return {'action': action}
@api.model
def _get_new_production_client_action(self):
action = self.env['ir.actions.actions']._for_xml_id('stock_barcode_mrp.stock_barcode_mo_client_action')
action = dict(action, target='fullscreen')
action['context'] = self.env.context
return {'action': action}
def _should_return_records(self):
return super()._should_return_records() and not self.env.context.get('barcode_trigger', False)