Merge branch 'develop' of https://e.coding.net/jikimo-hn/jikimo_sfs/jikimo_sf into feature/修复制造订单无采购单问题

This commit is contained in:
jinling.yang
2024-06-27 20:10:22 +08:00
12 changed files with 208 additions and 143 deletions

View File

@@ -200,7 +200,7 @@ def _create(self, data_list):
@api.model @api.model
def unlink(self): def unlink(self, ids):
""" unlink() """ unlink()
Deletes the records in ``self``. Deletes the records in ``self``.
@@ -210,143 +210,147 @@ def unlink(self):
""" """
if not self: if not self:
return True return True
if not ids:
return True
self.check_access_rights('unlink') self.check_access_rights('unlink')
self.check_access_rule('unlink') self.check_access_rule('unlink')
from odoo.addons.base.models.ir_model import MODULE_UNINSTALL_FLAG from odoo.addons.base.models.ir_model import MODULE_UNINSTALL_FLAG
for func in self._ondelete_methods: for record_id in ids:
# func._ondelete is True if it should be called during uninstallation record = self.browse(record_id)
if func._ondelete or not self._context.get(MODULE_UNINSTALL_FLAG): for func in record._ondelete_methods:
func(self) # func._ondelete is True if it should be called during uninstallation
if func._ondelete or not record._context.get(MODULE_UNINSTALL_FLAG):
func(record)
# TOFIX: this avoids an infinite loop when trying to recompute a # TOFIX: this avoids an infinite loop when trying to recompute a
# field, which triggers the recomputation of another field using the # field, which triggers the recomputation of another field using the
# same compute function, which then triggers again the computation # same compute function, which then triggers again the computation
# of those two fields # of those two fields
for field in self._fields.values(): for field in record._fields.values():
self.env.remove_to_compute(field, self) record.env.remove_to_compute(field, record)
self.env.flush_all() record.env.flush_all()
cr = self._cr cr = record._cr
Data = self.env['ir.model.data'].sudo().with_context({}) Data = record.env['ir.model.data'].sudo().with_context({})
Defaults = self.env['ir.default'].sudo() Defaults = record.env['ir.default'].sudo()
Property = self.env['ir.property'].sudo() Property = record.env['ir.property'].sudo()
Attachment = self.env['ir.attachment'].sudo() Attachment = record.env['ir.attachment'].sudo()
ir_property_unlink = Property ir_property_unlink = Property
ir_model_data_unlink = Data ir_model_data_unlink = Data
ir_attachment_unlink = Attachment ir_attachment_unlink = Attachment
# mark fields that depend on 'self' to recompute them after 'self' has # mark fields that depend on 'record' to recompute them after 'record' has
# been deleted (like updating a sum of lines after deleting one line) # been deleted (like updating a sum of lines after deleting one line)
with self.env.protecting(self._fields.values(), self): with record.env.protecting(record._fields.values(), record):
self.modified(self._fields, before=True) record.modified(record._fields, before=True)
for sub_ids in cr.split_for_in_conditions(self.ids): for sub_ids in cr.split_for_in_conditions(record.ids):
records = self.browse(sub_ids) records = record.browse(sub_ids)
# Check if the records are used as default properties. # Check if the records are used as default properties.
refs = [f'{self._name},{id_}' for id_ in sub_ids] refs = [f'{record._name},{id_}' for id_ in sub_ids]
if Property.search( if Property.search(
[('res_id', '=', False), ('value_reference', 'in', refs)], [('res_id', '=', False), ('value_reference', 'in', refs)],
limit=1): limit=1):
raise UserError( raise UserError(
_('Unable to delete this document because it is used as a default property')) _('Unable to delete this document because it is used as a default property'))
# Delete the records' properties. # Delete the records' properties.
ir_property_unlink |= Property.search([('res_id', 'in', refs)]) ir_property_unlink |= Property.search([('res_id', 'in', refs)])
query = f'DELETE FROM "{self._table}" WHERE id IN %s' query = f'DELETE FROM "{record._table}" WHERE id IN %s'
cr.execute(query, (sub_ids,)) cr.execute(query, (sub_ids,))
# Removing the ir_model_data reference if the record being deleted # Removing the ir_model_data reference if the record being deleted
# is a record created by xml/csv file, as these are not connected # is a record created by xml/csv file, as these are not connected
# with real database foreign keys, and would be dangling references. # with real database foreign keys, and would be dangling references.
# #
# Note: the following steps are performed as superuser to avoid # Note: the following steps are performed as superuser to avoid
# access rights restrictions, and with no context to avoid possible # access rights restrictions, and with no context to avoid possible
# side-effects during admin calls. # side-effects during admin calls.
data = Data.search( data = Data.search(
[('model', '=', self._name), ('res_id', 'in', sub_ids)]) [('model', '=', record._name), ('res_id', 'in', sub_ids)])
ir_model_data_unlink |= data ir_model_data_unlink |= data
# For the same reason, remove the defaults having some of the # For the same reason, remove the defaults having some of the
# records as value # records as value
Defaults.discard_records(records) Defaults.discard_records(records)
# For the same reason, remove the relevant records in ir_attachment # For the same reason, remove the relevant records in ir_attachment
# (the search is performed with sql as the search method of # (the search is performed with sql as the search method of
# ir_attachment is overridden to hide attachments of deleted # ir_attachment is overridden to hide attachments of deleted
# records) # records)
query = 'SELECT id FROM ir_attachment WHERE res_model=%s AND res_id IN %s' query = 'SELECT id FROM ir_attachment WHERE res_model=%s AND res_id IN %s'
cr.execute(query, (self._name, sub_ids)) cr.execute(query, (record._name, sub_ids))
ir_attachment_unlink |= Attachment.browse( ir_attachment_unlink |= Attachment.browse(
row[0] for row in cr.fetchall()) row[0] for row in cr.fetchall())
# invalidate the *whole* cache, since the orm does not handle all # invalidate the *whole* cache, since the orm does not handle all
# changes made in the database, like cascading delete! # changes made in the database, like cascading delete!
self.env.invalidate_all(flush=False) record.env.invalidate_all(flush=False)
if ir_property_unlink: if ir_property_unlink:
ir_property_unlink.unlink() ir_property_unlink.unlink()
if ir_model_data_unlink: if ir_model_data_unlink:
ir_model_data_unlink.unlink() ir_model_data_unlink.unlink()
if ir_attachment_unlink: if ir_attachment_unlink:
ir_attachment_unlink.unlink() ir_attachment_unlink.unlink()
# DLE P93: flush after the unlink, for recompute fields depending on # DLE P93: flush after the unlink, for recompute fields depending on
# the modified of the unlink # the modified of the unlink
self.env.flush_all() record.env.flush_all()
# auditing: deletions are infrequent and leave no trace in the database # auditing: deletions are infrequent and leave no trace in the database
_unlink.info('User #%s deleted %s records with IDs: %r', self._uid, _unlink.info('User #%s deleted %s records with IDs: %r', record._uid,
self._name, self.ids) record._name, record.ids)
# This is used to restrict the access right to unlink a record # This is used to restrict the access right to unlink a record
current_model_id = self.env['ir.model'].sudo().search( current_model_id = record.env['ir.model'].sudo().search(
[('model', '=', self._name)]).id [('model', '=', record._name)]).id
# access_right_rec = self.env['access.right'].sudo().search_read( # access_right_rec = record.env['access.right'].sudo().search_read(
# [('model_id', '=', current_model_id)], ['model_id', 'is_delete', # [('model_id', '=', current_model_id)], ['model_id', 'is_delete',
# 'groups_id']) # 'groups_id'])
# if access_right_rec and not self.env.is_admin(): # if access_right_rec and not record.env.is_admin():
# for rec in access_right_rec: # for rec in access_right_rec:
# group_name = self.env['ir.model.data'].sudo().search([ # group_name = record.env['ir.model.data'].sudo().search([
# ('model', '=', 'res.groups'), # ('model', '=', 'res.groups'),
# ('res_id', '=', rec['groups_id'][0]) # ('res_id', '=', rec['groups_id'][0])
# ]).name # ]).name
# module_name = self.env['ir.model.data'].sudo().search([ # module_name = record.env['ir.model.data'].sudo().search([
# ('model', '=', 'res.groups'), # ('model', '=', 'res.groups'),
# ('res_id', '=', rec['groups_id'][0]) # ('res_id', '=', rec['groups_id'][0])
# ]).module # ]).module
# group = module_name + "." + group_name # group = module_name + "." + group_name
# if self.env.user.has_group(group): # if record.env.user.has_group(group):
# if rec['is_delete']: # if rec['is_delete']:
# raise UserError(_('You are restricted from performing this' # raise UserError(_('You are restricted from performing this'
# ' operation. Please contact the' # ' operation. Please contact the'
# ' administrator.')) # ' administrator.'))
# 检查 'access.right' 模型是否存在于环境中 # 检查 'access.right' 模型是否存在于环境中
if 'access.right' in self.env: if 'access.right' in record.env:
# current_model_id = self.env['ir.model'].sudo().search([('model', '=', self._name)]).id # current_model_id = record.env['ir.model'].sudo().search([('model', '=', record._name)]).id
access_right_rec = self.env['access.right'].sudo().search_read( access_right_rec = record.env['access.right'].sudo().search_read(
[('model_id', '=', current_model_id)], ['model_id', 'is_delete', 'groups_id'] [('model_id', '=', current_model_id)], ['model_id', 'is_delete', 'groups_id']
) )
if access_right_rec and not self.env.is_admin(): if access_right_rec and not record.env.is_admin():
for rec in access_right_rec: for rec in access_right_rec:
group_data = self.env['ir.model.data'].sudo().search_read( group_data = record.env['ir.model.data'].sudo().search_read(
[('model', '=', 'res.groups'), ('res_id', '=', rec['groups_id'][0])], [('model', '=', 'res.groups'), ('res_id', '=', rec['groups_id'][0])],
['name', 'module'] ['name', 'module']
) )
if group_data: if group_data:
group_name = group_data[0]['name'] group_name = group_data[0]['name']
module_name = group_data[0]['module'] module_name = group_data[0]['module']
group_xml_id = f"{module_name}.{group_name}" group_xml_id = f"{module_name}.{group_name}"
if self.env.user.has_group(group_xml_id) and rec['is_delete']: if record.env.user.has_group(group_xml_id) and rec['is_delete']:
raise UserError( raise UserError(
_('You are restricted from performing this operation. Please contact the administrator.')) _('You are restricted from performing this operation. Please contact the administrator.'))
else: else:
# 如果 'access.right' 模型不存在,可以在这里定义备选逻辑 # 如果 'access.right' 模型不存在,可以在这里定义备选逻辑
pass pass
return True return True
BaseModel._create = _create BaseModel._create = _create

View File

@@ -171,6 +171,11 @@ class ProductTemplate(models.Model):
class RePurchaseOrder(models.Model): class RePurchaseOrder(models.Model):
_inherit = 'purchase.order' _inherit = 'purchase.order'
mrp_production_count = fields.Integer(
"Count of MO Source",
compute='_compute_mrp_production_count',
groups='mrp.group_mrp_user,sf_base.group_purchase,sf_base.group_purchase_director')
remark = fields.Text('备注') remark = fields.Text('备注')
user_id = fields.Many2one( user_id = fields.Many2one(
'res.users', string='买家', index=True, tracking=True, 'res.users', string='买家', index=True, tracking=True,

View File

@@ -54,7 +54,7 @@
<record model="ir.rule" id="sale_order_rule_my"> <record model="ir.rule" id="sale_order_rule_my">
<field name="name">销售经理查看自己的订单</field> <field name="name">销售经理查看自己的订单</field>
<field name="model_id" ref="model_sale_order"/> <field name="model_id" ref="model_sale_order"/>
<field name="domain_force">['|',('user_id','=',user.id),('create_uid', '=',user.id)]</field> <field name="domain_force">['|','|',('user_id','=',user.id),('user_id', '=', False),('create_uid', '=',user.id)]</field>
<field name="groups" eval="[(4, ref('sf_base.group_sale_salemanager'))]"/> <field name="groups" eval="[(4, ref('sf_base.group_sale_salemanager'))]"/>
<field name="perm_read" eval="1"/> <field name="perm_read" eval="1"/>
<field name="perm_write" eval="1"/> <field name="perm_write" eval="1"/>
@@ -74,7 +74,7 @@
<record model="ir.rule" id="inventory_purchase_order_rule_my"> <record model="ir.rule" id="inventory_purchase_order_rule_my">
<field name="name">采购岗查看自己的订单</field> <field name="name">采购岗查看自己的订单</field>
<field name="model_id" ref="purchase.model_purchase_order"/> <field name="model_id" ref="purchase.model_purchase_order"/>
<field name="domain_force">['|',('user_id','=',user.id),('create_uid', '=',user.id)]</field> <field name="domain_force">['|','|',('user_id','=',user.id),('user_id', '=', False),('create_uid', '=',user.id)]</field>
<field name="groups" eval="[(4, ref('sf_base.group_purchase'))]"/> <field name="groups" eval="[(4, ref('sf_base.group_purchase'))]"/>
<field name="perm_read" eval="1"/> <field name="perm_read" eval="1"/>
<field name="perm_write" eval="0"/> <field name="perm_write" eval="0"/>

View File

@@ -79,6 +79,13 @@
<xpath expr="//form/header/button[@name='button_done']" position="attributes"> <xpath expr="//form/header/button[@name='button_done']" position="attributes">
<attribute name="groups">sf_base.group_purchase,sf_base.group_purchase_director</attribute> <attribute name="groups">sf_base.group_purchase,sf_base.group_purchase_director</attribute>
</xpath> </xpath>
<xpath expr="//form/sheet/div[@name='button_box']/button[@name='action_view_mrp_productions']"
position="attributes">
<attribute name="groups">mrp.group_mrp_user,sf_base.group_purchase,sf_base.group_purchase_director
</attribute>
</xpath>
<xpath expr="//field[@name='order_line']" position="attributes"> <xpath expr="//field[@name='order_line']" position="attributes">
<attribute name="attrs">{'readonly': [('state', 'in', ['purchase'])]} <attribute name="attrs">{'readonly': [('state', 'in', ['purchase'])]}
</attribute> </attribute>

View File

@@ -944,13 +944,11 @@ class FunctionalToolDismantle(models.Model):
functional_tool_assembly = self.functional_tool_id.functional_tool_name_id functional_tool_assembly = self.functional_tool_id.functional_tool_name_id
if self.scrap_boolean: if self.scrap_boolean:
# 刀柄报废 入库到Scrap # 刀柄报废 入库到Scrap
lot.create_stock_quant(location, location_dest_scrap_ids[-1], functional_tool_assembly.id, code, lot.create_stock_quant(location, location_dest_scrap_ids[-1], False, code, False, False)
functional_tool_assembly, functional_tool_assembly.tool_groups_id)
lot.tool_material_status = '报废' lot.tool_material_status = '报废'
else: else:
# 刀柄不报废 入库到刀具房 # 刀柄不报废 入库到刀具房
lot.create_stock_quant(location, location_dest, functional_tool_assembly.id, code, lot.create_stock_quant(location, location_dest, False, code, False, False)
functional_tool_assembly, functional_tool_assembly.tool_groups_id)
lot.tool_material_status = '可用' lot.tool_material_status = '可用'
# ==============功能刀具[报废]拆解================ # ==============功能刀具[报废]拆解================

View File

@@ -3,6 +3,7 @@ import requests
import logging import logging
from odoo import models, api, fields from odoo import models, api, fields
from odoo.exceptions import ValidationError from odoo.exceptions import ValidationError
from datetime import datetime, timedelta
from odoo.addons.sf_base.commons.common import Common from odoo.addons.sf_base.commons.common import Common
@@ -101,7 +102,7 @@ class SfMaintenanceEquipment(models.Model):
tool_install_time = {'Nomal': '正常', 'Warning': '报警'} tool_install_time = {'Nomal': '正常', 'Warning': '报警'}
equipment_tool_id.write({ equipment_tool_id.write({
'functional_tool_name_id': functional_tool_id.id, 'functional_tool_name_id': functional_tool_id.id,
'tool_install_time': time 'tool_install_time': time - timedelta(hours=8)
}) })
if functional_tool_id.current_location != '机内刀库': if functional_tool_id.current_location != '机内刀库':
# 对功能刀具进行移动到生产线 # 对功能刀具进行移动到生产线

View File

@@ -25,7 +25,8 @@ class ToolMaterial(models.Model):
have_been_used_num = fields.Integer('在用数量', compute='_compute_number', store=True) have_been_used_num = fields.Integer('在用数量', compute='_compute_number', store=True)
scrap_num = fields.Integer('报废数量', compute='_compute_number', store=True) scrap_num = fields.Integer('报废数量', compute='_compute_number', store=True)
barcode_ids = fields.One2many('stock.lot', 'tool_material_search_id', string='序列号', readonly=True) barcode_ids = fields.One2many('stock.lot', 'tool_material_search_id', string='序列号', readonly=True,
domain=[('tool_material_status', '!=', '未入库')])
@api.depends('product_id.stock_quant_ids.quantity') @api.depends('product_id.stock_quant_ids.quantity')
def _compute_number(self): def _compute_number(self):
@@ -46,8 +47,6 @@ class ToolMaterial(models.Model):
record.scrap_num = scrap_num record.scrap_num = scrap_num
record.number = usable_num + have_been_used_num + scrap_num record.number = usable_num + have_been_used_num + scrap_num
@api.model @api.model
def _read_group_cutting_tool_material_id(self, categories, domain, order): def _read_group_cutting_tool_material_id(self, categories, domain, order):
cutting_tool_material_id = categories._search([], order=order, access_rights_uid=SUPERUSER_ID) cutting_tool_material_id = categories._search([], order=order, access_rights_uid=SUPERUSER_ID)

View File

@@ -63,6 +63,7 @@
<field name="name"/> <field name="name"/>
<field name="rfid"/> <field name="rfid"/>
<field name="product_qty"/> <field name="product_qty"/>
<field name="create_date" string="入库日期"/>
<field name="tool_material_status"/> <field name="tool_material_status"/>
<!-- <button name="enroll_tool_material_stock" string="序列号注册" type="object" class="btn-primary"/>--> <!-- <button name="enroll_tool_material_stock" string="序列号注册" type="object" class="btn-primary"/>-->
</tree> </tree>

View File

@@ -557,8 +557,10 @@ class SfStockMoveLine(models.Model):
_name = 'stock.move.line' _name = 'stock.move.line'
_inherit = ['stock.move.line', 'printing.utils'] _inherit = ['stock.move.line', 'printing.utils']
stock_lot_name = fields.Char('序列号名称', related='lot_id.name')
current_location_id = fields.Many2one( current_location_id = fields.Many2one(
'sf.shelf.location', string='当前货位', compute='_compute_current_location_id', store=True) 'sf.shelf.location', string='当前货位', compute='_compute_current_location_id', store=True, readonly=False,
domain="[('product_id', '=', product_id),'|',('product_sn_id.name', '=', stock_lot_name),('product_sn_ids.lot_id.name','=',stock_lot_name)]")
# location_dest_id = fields.Many2one('stock.location', string='目标库位') # location_dest_id = fields.Many2one('stock.location', string='目标库位')
location_dest_id_product_type = fields.Many2many(related='location_dest_id.product_type') location_dest_id_product_type = fields.Many2many(related='location_dest_id.product_type')
location_dest_id_value = fields.Integer(compute='_compute_location_dest_id_value', store=True) location_dest_id_value = fields.Integer(compute='_compute_location_dest_id_value', store=True)
@@ -856,7 +858,9 @@ class SfStockMoveLine(models.Model):
def compute_destination_location_id(self): def compute_destination_location_id(self):
for record in self: for record in self:
obj = self.env['sf.shelf.location'].search([('name', '=', obj = self.env['sf.shelf.location'].search([('name', '=',
self.destination_location_id.name)]) record.destination_location_id.name)])
if obj and obj.product_id and obj.product_id != record.product_id:
raise ValidationError('目标货位【%s】已被【%s】产品占用!' % (obj.code, obj.product_id))
if record.lot_id: if record.lot_id:
if record.product_id.tracking == 'serial': if record.product_id.tracking == 'serial':
shelf_location_obj = self.env['sf.shelf.location'].search( shelf_location_obj = self.env['sf.shelf.location'].search(
@@ -869,7 +873,7 @@ class SfStockMoveLine(models.Model):
if obj: if obj:
obj.product_sn_id = record.lot_id.id obj.product_sn_id = record.lot_id.id
elif record.product_id.tracking == 'lot': elif record.product_id.tracking == 'lot':
self.put_shelf_location(record) record.put_shelf_location(record)
if not obj.product_id: if not obj.product_id:
obj.product_id = record.product_id.id obj.product_id = record.product_id.id
else: else:
@@ -980,15 +984,26 @@ class SfStockPicking(models.Model):
# 调用入库方法进行入库刀货位 # 调用入库方法进行入库刀货位
line.compute_destination_location_id() line.compute_destination_location_id()
else: else:
# 对除刀柄之外的刀具物料进行 目标货位必填校验 # 对除刀柄之外的刀具物料入库到刀具房进行 目标货位必填校验
if self.location_dest_id.name == '刀具房' and line.product_id.cutting_tool_material_id.name not in ( if self.location_dest_id.name == '刀具房' and line.product_id.cutting_tool_material_id.name not in (
'刀柄', False): '刀柄', False):
raise ValidationError('请选择【%s】产品的目标货位!' % line.product_id.name) raise ValidationError('请选择【%s】产品的目标货位!' % line.product_id.name)
if line.current_location_id:
# 对货位的批次产品进行出货
line.put_shelf_location(line)
if line.current_location_id: if line.current_location_id:
# 按序列号管理的产品
if line.current_location_id.product_sn_id: if line.current_location_id.product_sn_id:
line.current_location_id.product_sn_id = False line.current_location_id.product_sn_id = False
# line.current_location_id.location_status = '空闲' # line.current_location_id.location_status = '空闲'
line.current_location_id.product_num = 0 line.current_location_id.product_num = 0
line.current_location_id.product_id = False
else:
# 对除刀柄之外的刀具物料从刀具房出库进行 当前货位必填校验
if self.location_id.name == '刀具房' and line.product_id.cutting_tool_material_id.name not in (
'刀柄', False):
raise ValidationError('请选择【%s】产品的当前货位!' % line.product_id.name)
# 对入库作业的刀柄和托盘进行Rfid绑定校验 # 对入库作业的刀柄和托盘进行Rfid绑定校验
for move in self.move_ids: for move in self.move_ids:
@@ -1115,6 +1130,7 @@ class CustomStockMove(models.Model):
采购入库扫码绑定Rfid码 采购入库扫码绑定Rfid码
""" """
for record in self: for record in self:
logging.info('Rfid%s' % barcode)
if record: if record:
lot = self.env['stock.lot'].sudo().search([('rfid', '=', barcode)]) lot = self.env['stock.lot'].sudo().search([('rfid', '=', barcode)])
if lot: if lot:
@@ -1126,7 +1142,9 @@ class CustomStockMove(models.Model):
'该Rfid【%s】已经被序列号为【%s】的【%s】物料所占用!' % (barcode, lot.name, material)) '该Rfid【%s】已经被序列号为【%s】的【%s】物料所占用!' % (barcode, lot.name, material))
if '刀柄' in (record.product_id.cutting_tool_material_id.name or '') or '托盘' in ( if '刀柄' in (record.product_id.cutting_tool_material_id.name or '') or '托盘' in (
record.product_id.fixture_material_id.name or ''): record.product_id.fixture_material_id.name or ''):
logging.info('开始录入Rfid:%s' % record.move_line_nosuggest_ids)
for move_line_nosuggest_id in record.move_line_nosuggest_ids: for move_line_nosuggest_id in record.move_line_nosuggest_ids:
logging.info('录入的记录%s , Rfid:%s' % (move_line_nosuggest_id, move_line_nosuggest_id.rfid))
if move_line_nosuggest_id.rfid: if move_line_nosuggest_id.rfid:
if move_line_nosuggest_id.rfid == barcode: if move_line_nosuggest_id.rfid == barcode:
if record.product_id.cutting_tool_material_id.name: if record.product_id.cutting_tool_material_id.name:
@@ -1135,7 +1153,9 @@ class CustomStockMove(models.Model):
raise ValidationError('该托盘的Rfid已经录入请勿重复录入') raise ValidationError('该托盘的Rfid已经录入请勿重复录入')
else: else:
line_id = int(re.sub(r"\D", "", str(move_line_nosuggest_id.id))) line_id = int(re.sub(r"\D", "", str(move_line_nosuggest_id.id)))
self.env['stock.move.line'].sudo().search([('id', '=', line_id)]).write({'rfid': barcode}) res = self.env['stock.move.line'].sudo().search([('id', '=', line_id)]).write(
{'rfid': barcode})
logging.info('Rfid是否录入:%s' % res)
move_line_nosuggest_id.rfid = barcode move_line_nosuggest_id.rfid = barcode
break break
else: else:

View File

@@ -7,16 +7,18 @@
<field name="inherit_id" ref="stock.view_stock_move_line_detailed_operation_tree"/> <field name="inherit_id" ref="stock.view_stock_move_line_detailed_operation_tree"/>
<field name="arch" type="xml"> <field name="arch" type="xml">
<xpath expr="//field[@name='location_id'][2]" position="after"> <xpath expr="//field[@name='location_id'][2]" position="after">
<field name="current_location_id" force_save="1"/> <field name="stock_lot_name" invisible="1"/>
<field name="current_location_id" force_save="1"
options="{'no_create': True,'no_create_edit':True}"/>
</xpath> </xpath>
<xpath expr="//field[@name='location_dest_id'][2]" position="after"> <xpath expr="//field[@name='location_dest_id'][2]" position="after">
<field name="current_product_id" invisible="1"/> <field name="current_product_id" invisible="1"/>
<field name="there_is_no_sn" invisible="1"/> <field name="there_is_no_sn" invisible="1"/>
<!-- <field name="destination_location_id" domain="[('location_id', '=', location_dest_id_value), --> <!-- <field name="destination_location_id" domain="[('location_id', '=', location_dest_id_value), -->
<!-- '|', --> <!-- '|', -->
<!-- ('location_status', '=', '空闲'), --> <!-- ('location_status', '=', '空闲'), -->
<!-- ('location_status', '=', '占用'), ('product_id', '=', current_product_id) --> <!-- ('location_status', '=', '占用'), ('product_id', '=', current_product_id) -->
<!-- ]"/> --> <!-- ]"/> -->
<field name="destination_location_id" domain="[('location_id', '=', location_dest_id_value), '|', <field name="destination_location_id" domain="[('location_id', '=', location_dest_id_value), '|',
('location_status', '=', '空闲'), ('product_id', '=', current_product_id), ('product_sn_id', ('location_status', '=', '空闲'), ('product_id', '=', current_product_id), ('product_sn_id',
'=', there_is_no_sn)]" options="{'no_create': True,'no_create_edit':True}"/> '=', there_is_no_sn)]" options="{'no_create': True,'no_create_edit':True}"/>
@@ -55,6 +57,7 @@
<field name="inherit_id" ref="stock.view_move_line_form"/> <field name="inherit_id" ref="stock.view_move_line_form"/>
<field name="arch" type="xml"> <field name="arch" type="xml">
<xpath expr="//form//sheet//group//group//field[@name='location_id']" position="after"> <xpath expr="//form//sheet//group//group//field[@name='location_id']" position="after">
<field name="stock_lot_name" invisible="1"/>
<field name="current_location_id" options="{'no_create': False}" force_save="1"/> <field name="current_location_id" options="{'no_create': False}" force_save="1"/>
</xpath> </xpath>
<xpath expr="//form//sheet//group//group//field[@name='location_dest_id']" position="after"> <xpath expr="//form//sheet//group//group//field[@name='location_dest_id']" position="after">

View File

@@ -592,8 +592,23 @@ var GanttRow = Widget.extend({
}); });
pill.decorations = pillDecorations; pill.decorations = pillDecorations;
if (self.colorField) { // let isDelay = false
pill._color = self._getColor(pill[self.colorField]); // if(pill.state != 'processing' && pill.state != 'finished') { // 判断待加工
// isDelay = pill.order_deadline.isBefore(new Date())
// }
pill.exState = ''
if (self.colorField){
// console.log(self.colorField, self, pill, '颜色')
// pill._color = self._getColor(pill[self.colorField]);
// 设置pill背景颜色2 修改时间2024年6月25日17:09:43
let isDelay = false
if(pill.state != 'processing' && pill.state != 'finished') { // 判断待加工
isDelay = pill.order_deadline.isBefore(new Date())
}
if(isDelay) {
pill.disableDragdrop = true
}
pill._color = self._getColor2(isDelay ? 'delay' : pill.state);
} }
if (self.progressField) { if (self.progressField) {
@@ -613,6 +628,13 @@ var GanttRow = Widget.extend({
} }
return 0; return 0;
}, },
_getColor2 (state) {
return {
'finished': 'ccc',
'delay': 9,
'processing': 13 // 绿色
}[state]
},
/** /**
* Get context to evaluate decoration * Get context to evaluate decoration
* *
@@ -867,10 +889,11 @@ var GanttRow = Widget.extend({
if ($pill.hasClass('ui-draggable-dragging')) { if ($pill.hasClass('ui-draggable-dragging')) {
return; return;
} }
var self = this; var self = this;
var pill = _.findWhere(this.pills, { id: $pill.data('id') }); var pill = _.findWhere(this.pills, { id: $pill.data('id') });
if(pill.state == 'finished'){ // 已完成状态不能拖拽
return;
}
// DRAGGABLE // DRAGGABLE
if (this.options.canEdit && !pill.disableStartResize && !pill.disableStopResize && !this.isGroup) { if (this.options.canEdit && !pill.disableStartResize && !pill.disableStopResize && !this.isGroup) {

View File

@@ -754,3 +754,7 @@
left: -0.5 * $o-connector-creator-bullet-diameter; left: -0.5 * $o-connector-creator-bullet-diameter;
} }
} }
.o_gantt_view .o_gantt_row_nogroup .o_gantt_pill.o_gantt_color_ccc {
background-color: #ccc;
}