Merge branch 'develop' of https://e.coding.net/jikimo-hn/jikimo_sfs/jikimo_sf into feature/修复制造订单无采购单问题
This commit is contained in:
@@ -200,7 +200,7 @@ def _create(self, data_list):
|
||||
|
||||
|
||||
@api.model
|
||||
def unlink(self):
|
||||
def unlink(self, ids):
|
||||
""" unlink()
|
||||
|
||||
Deletes the records in ``self``.
|
||||
@@ -210,143 +210,147 @@ def unlink(self):
|
||||
"""
|
||||
if not self:
|
||||
return True
|
||||
if not ids:
|
||||
return True
|
||||
|
||||
self.check_access_rights('unlink')
|
||||
self.check_access_rule('unlink')
|
||||
|
||||
from odoo.addons.base.models.ir_model import MODULE_UNINSTALL_FLAG
|
||||
for func in self._ondelete_methods:
|
||||
# func._ondelete is True if it should be called during uninstallation
|
||||
if func._ondelete or not self._context.get(MODULE_UNINSTALL_FLAG):
|
||||
func(self)
|
||||
for record_id in ids:
|
||||
record = self.browse(record_id)
|
||||
for func in record._ondelete_methods:
|
||||
# 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
|
||||
# field, which triggers the recomputation of another field using the
|
||||
# same compute function, which then triggers again the computation
|
||||
# of those two fields
|
||||
for field in self._fields.values():
|
||||
self.env.remove_to_compute(field, self)
|
||||
# TOFIX: this avoids an infinite loop when trying to recompute a
|
||||
# field, which triggers the recomputation of another field using the
|
||||
# same compute function, which then triggers again the computation
|
||||
# of those two fields
|
||||
for field in record._fields.values():
|
||||
record.env.remove_to_compute(field, record)
|
||||
|
||||
self.env.flush_all()
|
||||
record.env.flush_all()
|
||||
|
||||
cr = self._cr
|
||||
Data = self.env['ir.model.data'].sudo().with_context({})
|
||||
Defaults = self.env['ir.default'].sudo()
|
||||
Property = self.env['ir.property'].sudo()
|
||||
Attachment = self.env['ir.attachment'].sudo()
|
||||
ir_property_unlink = Property
|
||||
ir_model_data_unlink = Data
|
||||
ir_attachment_unlink = Attachment
|
||||
cr = record._cr
|
||||
Data = record.env['ir.model.data'].sudo().with_context({})
|
||||
Defaults = record.env['ir.default'].sudo()
|
||||
Property = record.env['ir.property'].sudo()
|
||||
Attachment = record.env['ir.attachment'].sudo()
|
||||
ir_property_unlink = Property
|
||||
ir_model_data_unlink = Data
|
||||
ir_attachment_unlink = Attachment
|
||||
|
||||
# mark fields that depend on 'self' to recompute them after 'self' has
|
||||
# been deleted (like updating a sum of lines after deleting one line)
|
||||
with self.env.protecting(self._fields.values(), self):
|
||||
self.modified(self._fields, before=True)
|
||||
for sub_ids in cr.split_for_in_conditions(self.ids):
|
||||
records = self.browse(sub_ids)
|
||||
# mark fields that depend on 'record' to recompute them after 'record' has
|
||||
# been deleted (like updating a sum of lines after deleting one line)
|
||||
with record.env.protecting(record._fields.values(), record):
|
||||
record.modified(record._fields, before=True)
|
||||
for sub_ids in cr.split_for_in_conditions(record.ids):
|
||||
records = record.browse(sub_ids)
|
||||
|
||||
# Check if the records are used as default properties.
|
||||
refs = [f'{self._name},{id_}' for id_ in sub_ids]
|
||||
if Property.search(
|
||||
[('res_id', '=', False), ('value_reference', 'in', refs)],
|
||||
limit=1):
|
||||
raise UserError(
|
||||
_('Unable to delete this document because it is used as a default property'))
|
||||
# Check if the records are used as default properties.
|
||||
refs = [f'{record._name},{id_}' for id_ in sub_ids]
|
||||
if Property.search(
|
||||
[('res_id', '=', False), ('value_reference', 'in', refs)],
|
||||
limit=1):
|
||||
raise UserError(
|
||||
_('Unable to delete this document because it is used as a default property'))
|
||||
|
||||
# Delete the records' properties.
|
||||
ir_property_unlink |= Property.search([('res_id', 'in', refs)])
|
||||
# Delete the records' properties.
|
||||
ir_property_unlink |= Property.search([('res_id', 'in', refs)])
|
||||
|
||||
query = f'DELETE FROM "{self._table}" WHERE id IN %s'
|
||||
cr.execute(query, (sub_ids,))
|
||||
query = f'DELETE FROM "{record._table}" WHERE id IN %s'
|
||||
cr.execute(query, (sub_ids,))
|
||||
|
||||
# Removing the ir_model_data reference if the record being deleted
|
||||
# is a record created by xml/csv file, as these are not connected
|
||||
# with real database foreign keys, and would be dangling references.
|
||||
#
|
||||
# Note: the following steps are performed as superuser to avoid
|
||||
# access rights restrictions, and with no context to avoid possible
|
||||
# side-effects during admin calls.
|
||||
data = Data.search(
|
||||
[('model', '=', self._name), ('res_id', 'in', sub_ids)])
|
||||
ir_model_data_unlink |= data
|
||||
# Removing the ir_model_data reference if the record being deleted
|
||||
# is a record created by xml/csv file, as these are not connected
|
||||
# with real database foreign keys, and would be dangling references.
|
||||
#
|
||||
# Note: the following steps are performed as superuser to avoid
|
||||
# access rights restrictions, and with no context to avoid possible
|
||||
# side-effects during admin calls.
|
||||
data = Data.search(
|
||||
[('model', '=', record._name), ('res_id', 'in', sub_ids)])
|
||||
ir_model_data_unlink |= data
|
||||
|
||||
# For the same reason, remove the defaults having some of the
|
||||
# records as value
|
||||
Defaults.discard_records(records)
|
||||
# For the same reason, remove the defaults having some of the
|
||||
# records as value
|
||||
Defaults.discard_records(records)
|
||||
|
||||
# For the same reason, remove the relevant records in ir_attachment
|
||||
# (the search is performed with sql as the search method of
|
||||
# ir_attachment is overridden to hide attachments of deleted
|
||||
# records)
|
||||
query = 'SELECT id FROM ir_attachment WHERE res_model=%s AND res_id IN %s'
|
||||
cr.execute(query, (self._name, sub_ids))
|
||||
ir_attachment_unlink |= Attachment.browse(
|
||||
row[0] for row in cr.fetchall())
|
||||
# For the same reason, remove the relevant records in ir_attachment
|
||||
# (the search is performed with sql as the search method of
|
||||
# ir_attachment is overridden to hide attachments of deleted
|
||||
# records)
|
||||
query = 'SELECT id FROM ir_attachment WHERE res_model=%s AND res_id IN %s'
|
||||
cr.execute(query, (record._name, sub_ids))
|
||||
ir_attachment_unlink |= Attachment.browse(
|
||||
row[0] for row in cr.fetchall())
|
||||
|
||||
# invalidate the *whole* cache, since the orm does not handle all
|
||||
# changes made in the database, like cascading delete!
|
||||
self.env.invalidate_all(flush=False)
|
||||
if ir_property_unlink:
|
||||
ir_property_unlink.unlink()
|
||||
if ir_model_data_unlink:
|
||||
ir_model_data_unlink.unlink()
|
||||
if ir_attachment_unlink:
|
||||
ir_attachment_unlink.unlink()
|
||||
# DLE P93: flush after the unlink, for recompute fields depending on
|
||||
# the modified of the unlink
|
||||
self.env.flush_all()
|
||||
# auditing: deletions are infrequent and leave no trace in the database
|
||||
_unlink.info('User #%s deleted %s records with IDs: %r', self._uid,
|
||||
self._name, self.ids)
|
||||
# This is used to restrict the access right to unlink a record
|
||||
current_model_id = self.env['ir.model'].sudo().search(
|
||||
[('model', '=', self._name)]).id
|
||||
# access_right_rec = self.env['access.right'].sudo().search_read(
|
||||
# [('model_id', '=', current_model_id)], ['model_id', 'is_delete',
|
||||
# 'groups_id'])
|
||||
# if access_right_rec and not self.env.is_admin():
|
||||
# for rec in access_right_rec:
|
||||
# group_name = self.env['ir.model.data'].sudo().search([
|
||||
# ('model', '=', 'res.groups'),
|
||||
# ('res_id', '=', rec['groups_id'][0])
|
||||
# ]).name
|
||||
# module_name = self.env['ir.model.data'].sudo().search([
|
||||
# ('model', '=', 'res.groups'),
|
||||
# ('res_id', '=', rec['groups_id'][0])
|
||||
# ]).module
|
||||
# group = module_name + "." + group_name
|
||||
# if self.env.user.has_group(group):
|
||||
# if rec['is_delete']:
|
||||
# raise UserError(_('You are restricted from performing this'
|
||||
# ' operation. Please contact the'
|
||||
# ' administrator.'))
|
||||
# 检查 'access.right' 模型是否存在于环境中
|
||||
if 'access.right' in self.env:
|
||||
# current_model_id = self.env['ir.model'].sudo().search([('model', '=', self._name)]).id
|
||||
access_right_rec = self.env['access.right'].sudo().search_read(
|
||||
[('model_id', '=', current_model_id)], ['model_id', 'is_delete', 'groups_id']
|
||||
)
|
||||
# invalidate the *whole* cache, since the orm does not handle all
|
||||
# changes made in the database, like cascading delete!
|
||||
record.env.invalidate_all(flush=False)
|
||||
if ir_property_unlink:
|
||||
ir_property_unlink.unlink()
|
||||
if ir_model_data_unlink:
|
||||
ir_model_data_unlink.unlink()
|
||||
if ir_attachment_unlink:
|
||||
ir_attachment_unlink.unlink()
|
||||
# DLE P93: flush after the unlink, for recompute fields depending on
|
||||
# the modified of the unlink
|
||||
record.env.flush_all()
|
||||
# auditing: deletions are infrequent and leave no trace in the database
|
||||
_unlink.info('User #%s deleted %s records with IDs: %r', record._uid,
|
||||
record._name, record.ids)
|
||||
# This is used to restrict the access right to unlink a record
|
||||
current_model_id = record.env['ir.model'].sudo().search(
|
||||
[('model', '=', record._name)]).id
|
||||
# access_right_rec = record.env['access.right'].sudo().search_read(
|
||||
# [('model_id', '=', current_model_id)], ['model_id', 'is_delete',
|
||||
# 'groups_id'])
|
||||
# if access_right_rec and not record.env.is_admin():
|
||||
# for rec in access_right_rec:
|
||||
# group_name = record.env['ir.model.data'].sudo().search([
|
||||
# ('model', '=', 'res.groups'),
|
||||
# ('res_id', '=', rec['groups_id'][0])
|
||||
# ]).name
|
||||
# module_name = record.env['ir.model.data'].sudo().search([
|
||||
# ('model', '=', 'res.groups'),
|
||||
# ('res_id', '=', rec['groups_id'][0])
|
||||
# ]).module
|
||||
# group = module_name + "." + group_name
|
||||
# if record.env.user.has_group(group):
|
||||
# if rec['is_delete']:
|
||||
# raise UserError(_('You are restricted from performing this'
|
||||
# ' operation. Please contact the'
|
||||
# ' administrator.'))
|
||||
# 检查 'access.right' 模型是否存在于环境中
|
||||
if 'access.right' in record.env:
|
||||
# current_model_id = record.env['ir.model'].sudo().search([('model', '=', record._name)]).id
|
||||
access_right_rec = record.env['access.right'].sudo().search_read(
|
||||
[('model_id', '=', current_model_id)], ['model_id', 'is_delete', 'groups_id']
|
||||
)
|
||||
|
||||
if access_right_rec and not self.env.is_admin():
|
||||
for rec in access_right_rec:
|
||||
group_data = self.env['ir.model.data'].sudo().search_read(
|
||||
[('model', '=', 'res.groups'), ('res_id', '=', rec['groups_id'][0])],
|
||||
['name', 'module']
|
||||
)
|
||||
if access_right_rec and not record.env.is_admin():
|
||||
for rec in access_right_rec:
|
||||
group_data = record.env['ir.model.data'].sudo().search_read(
|
||||
[('model', '=', 'res.groups'), ('res_id', '=', rec['groups_id'][0])],
|
||||
['name', 'module']
|
||||
)
|
||||
|
||||
if group_data:
|
||||
group_name = group_data[0]['name']
|
||||
module_name = group_data[0]['module']
|
||||
group_xml_id = f"{module_name}.{group_name}"
|
||||
if group_data:
|
||||
group_name = group_data[0]['name']
|
||||
module_name = group_data[0]['module']
|
||||
group_xml_id = f"{module_name}.{group_name}"
|
||||
|
||||
if self.env.user.has_group(group_xml_id) and rec['is_delete']:
|
||||
raise UserError(
|
||||
_('You are restricted from performing this operation. Please contact the administrator.'))
|
||||
else:
|
||||
# 如果 'access.right' 模型不存在,可以在这里定义备选逻辑
|
||||
pass
|
||||
if record.env.user.has_group(group_xml_id) and rec['is_delete']:
|
||||
raise UserError(
|
||||
_('You are restricted from performing this operation. Please contact the administrator.'))
|
||||
else:
|
||||
# 如果 'access.right' 模型不存在,可以在这里定义备选逻辑
|
||||
pass
|
||||
|
||||
return True
|
||||
return True
|
||||
|
||||
|
||||
BaseModel._create = _create
|
||||
|
||||
@@ -171,6 +171,11 @@ class ProductTemplate(models.Model):
|
||||
class RePurchaseOrder(models.Model):
|
||||
_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('备注')
|
||||
user_id = fields.Many2one(
|
||||
'res.users', string='买家', index=True, tracking=True,
|
||||
|
||||
@@ -54,7 +54,7 @@
|
||||
<record model="ir.rule" id="sale_order_rule_my">
|
||||
<field name="name">销售经理查看自己的订单</field>
|
||||
<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="perm_read" eval="1"/>
|
||||
<field name="perm_write" eval="1"/>
|
||||
@@ -74,7 +74,7 @@
|
||||
<record model="ir.rule" id="inventory_purchase_order_rule_my">
|
||||
<field name="name">采购岗查看自己的订单</field>
|
||||
<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="perm_read" eval="1"/>
|
||||
<field name="perm_write" eval="0"/>
|
||||
|
||||
@@ -79,6 +79,13 @@
|
||||
<xpath expr="//form/header/button[@name='button_done']" position="attributes">
|
||||
<attribute name="groups">sf_base.group_purchase,sf_base.group_purchase_director</attribute>
|
||||
</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">
|
||||
<attribute name="attrs">{'readonly': [('state', 'in', ['purchase'])]}
|
||||
</attribute>
|
||||
|
||||
@@ -944,13 +944,11 @@ class FunctionalToolDismantle(models.Model):
|
||||
functional_tool_assembly = self.functional_tool_id.functional_tool_name_id
|
||||
if self.scrap_boolean:
|
||||
# 刀柄报废 入库到Scrap
|
||||
lot.create_stock_quant(location, location_dest_scrap_ids[-1], functional_tool_assembly.id, code,
|
||||
functional_tool_assembly, functional_tool_assembly.tool_groups_id)
|
||||
lot.create_stock_quant(location, location_dest_scrap_ids[-1], False, code, False, False)
|
||||
lot.tool_material_status = '报废'
|
||||
else:
|
||||
# 刀柄不报废 入库到刀具房
|
||||
lot.create_stock_quant(location, location_dest, functional_tool_assembly.id, code,
|
||||
functional_tool_assembly, functional_tool_assembly.tool_groups_id)
|
||||
lot.create_stock_quant(location, location_dest, False, code, False, False)
|
||||
lot.tool_material_status = '可用'
|
||||
|
||||
# ==============功能刀具[报废]拆解================
|
||||
|
||||
@@ -3,6 +3,7 @@ import requests
|
||||
import logging
|
||||
from odoo import models, api, fields
|
||||
from odoo.exceptions import ValidationError
|
||||
from datetime import datetime, timedelta
|
||||
from odoo.addons.sf_base.commons.common import Common
|
||||
|
||||
|
||||
@@ -101,7 +102,7 @@ class SfMaintenanceEquipment(models.Model):
|
||||
tool_install_time = {'Nomal': '正常', 'Warning': '报警'}
|
||||
equipment_tool_id.write({
|
||||
'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 != '机内刀库':
|
||||
# 对功能刀具进行移动到生产线
|
||||
|
||||
@@ -25,7 +25,8 @@ class ToolMaterial(models.Model):
|
||||
have_been_used_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')
|
||||
def _compute_number(self):
|
||||
@@ -46,8 +47,6 @@ class ToolMaterial(models.Model):
|
||||
record.scrap_num = scrap_num
|
||||
record.number = usable_num + have_been_used_num + scrap_num
|
||||
|
||||
|
||||
|
||||
@api.model
|
||||
def _read_group_cutting_tool_material_id(self, categories, domain, order):
|
||||
cutting_tool_material_id = categories._search([], order=order, access_rights_uid=SUPERUSER_ID)
|
||||
|
||||
@@ -63,6 +63,7 @@
|
||||
<field name="name"/>
|
||||
<field name="rfid"/>
|
||||
<field name="product_qty"/>
|
||||
<field name="create_date" string="入库日期"/>
|
||||
<field name="tool_material_status"/>
|
||||
<!-- <button name="enroll_tool_material_stock" string="序列号注册" type="object" class="btn-primary"/>-->
|
||||
</tree>
|
||||
|
||||
@@ -557,8 +557,10 @@ class SfStockMoveLine(models.Model):
|
||||
_name = 'stock.move.line'
|
||||
_inherit = ['stock.move.line', 'printing.utils']
|
||||
|
||||
stock_lot_name = fields.Char('序列号名称', related='lot_id.name')
|
||||
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_product_type = fields.Many2many(related='location_dest_id.product_type')
|
||||
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):
|
||||
for record in self:
|
||||
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.product_id.tracking == 'serial':
|
||||
shelf_location_obj = self.env['sf.shelf.location'].search(
|
||||
@@ -869,7 +873,7 @@ class SfStockMoveLine(models.Model):
|
||||
if obj:
|
||||
obj.product_sn_id = record.lot_id.id
|
||||
elif record.product_id.tracking == 'lot':
|
||||
self.put_shelf_location(record)
|
||||
record.put_shelf_location(record)
|
||||
if not obj.product_id:
|
||||
obj.product_id = record.product_id.id
|
||||
else:
|
||||
@@ -980,15 +984,26 @@ class SfStockPicking(models.Model):
|
||||
# 调用入库方法进行入库刀货位
|
||||
line.compute_destination_location_id()
|
||||
else:
|
||||
# 对除刀柄之外的刀具物料进行 目标货位必填校验
|
||||
# 对除刀柄之外的刀具物料入库到刀具房进行 目标货位必填校验
|
||||
if self.location_dest_id.name == '刀具房' and line.product_id.cutting_tool_material_id.name not in (
|
||||
'刀柄', False):
|
||||
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.product_sn_id:
|
||||
line.current_location_id.product_sn_id = False
|
||||
# line.current_location_id.location_status = '空闲'
|
||||
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绑定校验
|
||||
for move in self.move_ids:
|
||||
@@ -1115,6 +1130,7 @@ class CustomStockMove(models.Model):
|
||||
采购入库扫码绑定Rfid码
|
||||
"""
|
||||
for record in self:
|
||||
logging.info('Rfid:%s' % barcode)
|
||||
if record:
|
||||
lot = self.env['stock.lot'].sudo().search([('rfid', '=', barcode)])
|
||||
if lot:
|
||||
@@ -1126,7 +1142,9 @@ class CustomStockMove(models.Model):
|
||||
'该Rfid【%s】已经被序列号为【%s】的【%s】物料所占用!' % (barcode, lot.name, material))
|
||||
if '刀柄' in (record.product_id.cutting_tool_material_id.name or '') or '托盘' in (
|
||||
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:
|
||||
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 == barcode:
|
||||
if record.product_id.cutting_tool_material_id.name:
|
||||
@@ -1135,7 +1153,9 @@ class CustomStockMove(models.Model):
|
||||
raise ValidationError('该托盘的Rfid已经录入,请勿重复录入!!!')
|
||||
else:
|
||||
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
|
||||
break
|
||||
else:
|
||||
|
||||
@@ -7,16 +7,18 @@
|
||||
<field name="inherit_id" ref="stock.view_stock_move_line_detailed_operation_tree"/>
|
||||
<field name="arch" type="xml">
|
||||
<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 expr="//field[@name='location_dest_id'][2]" position="after">
|
||||
<field name="current_product_id" invisible="1"/>
|
||||
<field name="there_is_no_sn" invisible="1"/>
|
||||
<!-- <field name="destination_location_id" domain="[('location_id', '=', location_dest_id_value), -->
|
||||
<!-- '|', -->
|
||||
<!-- ('location_status', '=', '空闲'), -->
|
||||
<!-- ('location_status', '=', '占用'), ('product_id', '=', current_product_id) -->
|
||||
<!-- ]"/> -->
|
||||
<!-- <field name="destination_location_id" domain="[('location_id', '=', location_dest_id_value), -->
|
||||
<!-- '|', -->
|
||||
<!-- ('location_status', '=', '空闲'), -->
|
||||
<!-- ('location_status', '=', '占用'), ('product_id', '=', current_product_id) -->
|
||||
<!-- ]"/> -->
|
||||
<field name="destination_location_id" domain="[('location_id', '=', location_dest_id_value), '|',
|
||||
('location_status', '=', '空闲'), ('product_id', '=', current_product_id), ('product_sn_id',
|
||||
'=', 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="arch" type="xml">
|
||||
<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"/>
|
||||
</xpath>
|
||||
<xpath expr="//form//sheet//group//group//field[@name='location_dest_id']" position="after">
|
||||
|
||||
@@ -592,8 +592,23 @@ var GanttRow = Widget.extend({
|
||||
});
|
||||
pill.decorations = pillDecorations;
|
||||
|
||||
if (self.colorField) {
|
||||
pill._color = self._getColor(pill[self.colorField]);
|
||||
// let isDelay = false
|
||||
// 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) {
|
||||
@@ -613,6 +628,13 @@ var GanttRow = Widget.extend({
|
||||
}
|
||||
return 0;
|
||||
},
|
||||
_getColor2 (state) {
|
||||
return {
|
||||
'finished': 'ccc',
|
||||
'delay': 9,
|
||||
'processing': 13 // 绿色
|
||||
}[state]
|
||||
},
|
||||
/**
|
||||
* Get context to evaluate decoration
|
||||
*
|
||||
@@ -867,10 +889,11 @@ var GanttRow = Widget.extend({
|
||||
if ($pill.hasClass('ui-draggable-dragging')) {
|
||||
return;
|
||||
}
|
||||
|
||||
var self = this;
|
||||
var pill = _.findWhere(this.pills, { id: $pill.data('id') });
|
||||
|
||||
if(pill.state == 'finished'){ // 已完成状态不能拖拽
|
||||
return;
|
||||
}
|
||||
// DRAGGABLE
|
||||
if (this.options.canEdit && !pill.disableStartResize && !pill.disableStopResize && !this.isGroup) {
|
||||
|
||||
|
||||
@@ -754,3 +754,7 @@
|
||||
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;
|
||||
}
|
||||
Reference in New Issue
Block a user