Compare commits
132 Commits
release/re
...
release/re
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
957c5583bd | ||
|
|
9c4c2b85dd | ||
|
|
56af286500 | ||
|
|
cc83029c72 | ||
|
|
79ab1cc573 | ||
|
|
bda3df7806 | ||
|
|
150b684354 | ||
|
|
d69dc20fd1 | ||
|
|
e9c9b77112 | ||
|
|
495f92bd80 | ||
|
|
8a97fd08e2 | ||
|
|
1551ea4b12 | ||
|
|
75c5cca9a0 | ||
|
|
6b6be85057 | ||
|
|
7fb3c32d07 | ||
|
|
8203975142 | ||
|
|
449cf5bfb1 | ||
|
|
d7d5ccc142 | ||
|
|
8710df6dc2 | ||
|
|
f5c1457707 | ||
|
|
5155135cb4 | ||
|
|
4421eed1d0 | ||
|
|
46e3a23492 | ||
|
|
675b09390b | ||
|
|
34251b4027 | ||
|
|
c4621d36a3 | ||
|
|
7bdc4b463a | ||
|
|
ea88b5418f | ||
|
|
f5a64caf81 | ||
|
|
1e5f26d645 | ||
|
|
ace32d9490 | ||
|
|
5db2f1fc70 | ||
|
|
960c940505 | ||
|
|
ee1629b40a | ||
|
|
06de5f6a2d | ||
|
|
c1eff705c2 | ||
|
|
8e3c7f9732 | ||
|
|
2591e627f0 | ||
|
|
4c66d86ee6 | ||
|
|
d4bc1c13ea | ||
|
|
4c845ee9fd | ||
|
|
726c3aede1 | ||
|
|
871c406c09 | ||
|
|
2ba9695c34 | ||
|
|
e1db34f25d | ||
|
|
e496555ff3 | ||
|
|
404a41294c | ||
|
|
e124560089 | ||
|
|
fd3a363bf6 | ||
|
|
9f6563186c | ||
|
|
1b174c5805 | ||
|
|
849b7be20d | ||
|
|
9d32bf8363 | ||
|
|
998daaa7f7 | ||
|
|
b23cb9af6e | ||
|
|
56adaddefc | ||
|
|
4a648fbd7b | ||
|
|
a3bf451d83 | ||
|
|
2919a3c159 | ||
|
|
8f6e2bc13d | ||
|
|
909230c1cc | ||
|
|
db8c338588 | ||
|
|
f319a9adf4 | ||
|
|
172e420939 | ||
|
|
0c3727540e | ||
|
|
5668722109 | ||
|
|
2d80355559 | ||
|
|
d281026086 | ||
|
|
5c35a8c38d | ||
|
|
3b24f90385 | ||
|
|
14355606c7 | ||
|
|
5997cbcb0e | ||
|
|
f07d7611d0 | ||
|
|
b106d56f3f | ||
|
|
3156052604 | ||
|
|
c8de75ceae | ||
|
|
d4b1f8f1a1 | ||
|
|
5378d62551 | ||
|
|
424f7196f8 | ||
|
|
c2723d9d05 | ||
|
|
7bf001927a | ||
|
|
84d67d285e | ||
|
|
a583b483e3 | ||
|
|
719a96f983 | ||
|
|
08fd0b01d3 | ||
|
|
db7fbed177 | ||
|
|
ad149a58ea | ||
|
|
0d96cd070c | ||
|
|
37f030c2db | ||
|
|
e2a62325f8 | ||
|
|
0db103cfc7 | ||
|
|
05f2cb553d | ||
|
|
c597471949 | ||
|
|
70ffbafac4 | ||
|
|
1cb7af072e | ||
|
|
4f6b1d0342 | ||
|
|
9bdcf0dd92 | ||
|
|
bcb60425b2 | ||
|
|
22643368fa | ||
|
|
aeb100923f | ||
|
|
53c6d6015e | ||
|
|
131e9329de | ||
|
|
dbd5c488f8 | ||
|
|
f8ba414229 | ||
|
|
7fd3647afb | ||
|
|
f5be9c6e65 | ||
|
|
c275a39a15 | ||
|
|
d07ab53aeb | ||
|
|
55accb714a | ||
|
|
5bd3eddfd5 | ||
|
|
c8bcd4d0f5 | ||
|
|
2cbe5ed394 | ||
|
|
1f1cb17a40 | ||
|
|
2ff935f68d | ||
|
|
098745ec50 | ||
|
|
94175f2039 | ||
|
|
1940116a35 | ||
|
|
f4eb378bea | ||
|
|
dcbb60b088 | ||
|
|
88ef9c106d | ||
|
|
0f7f12008f | ||
|
|
f44836705b | ||
|
|
35ac51bc10 | ||
|
|
eb2851391b | ||
|
|
86f67556ce | ||
|
|
e437875a92 | ||
|
|
b4535e88c9 | ||
|
|
be94cd0d54 | ||
|
|
65e209fe2a | ||
|
|
27ba002b51 | ||
|
|
2cd83c87e2 | ||
|
|
ba87d07af7 |
@@ -526,4 +526,8 @@ div:has(.o_required_modifier) > label::before {
|
||||
// 设置表单页面label文本不换行
|
||||
.o_form_view .o_group .o_wrap_label .o_form_label {
|
||||
white-space: nowrap;
|
||||
}
|
||||
// 修复表格内容覆盖表头bug
|
||||
.o_list_renderer .o_list_table tbody th {
|
||||
position: unset;
|
||||
}
|
||||
@@ -301,53 +301,27 @@ def unlink(self):
|
||||
# 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']
|
||||
)
|
||||
|
||||
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 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
|
||||
|
||||
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.'))
|
||||
return True
|
||||
|
||||
|
||||
BaseModel._create = _create
|
||||
BaseModel.unlink = unlink
|
||||
BaseModel.unlink = unlink
|
||||
@@ -11,8 +11,8 @@ access_sf_machine_control_system,sf_machine_control_system,model_sf_machine_cont
|
||||
access_sf_machine_control_system_admin,sf_machine_control_system_admin,model_sf_machine_control_system,base.group_system,1,1,1,0
|
||||
access_sf_production_process_group_sale_director,sf_production_process_group_sale_director,model_sf_production_process,sf_base.group_sale_director,1,0,0,0
|
||||
access_sf_production_process_group_sale_salemanager,sf_production_process_group_sale_salemanager,model_sf_production_process,sf_base.group_sale_salemanager,1,0,0,0
|
||||
access_res_partner_category_group_sale_salemanager,res_partner_category_group_sale_salemanager,base.model_res_partner_category,sf_base.group_sale_salemanager,1,0,1,0
|
||||
access_res_partner_category_group_sale_director,res_partner_category_group_sale_director,base.model_res_partner_category,sf_base.group_sale_director,1,0,1,0
|
||||
access_res_partner_category_group_sale_salemanager,res_partner_category_group_sale_salemanager,base.model_res_partner_category,sf_base.group_sale_salemanager,1,1,1,0
|
||||
access_res_partner_category_group_sale_director,res_partner_category_group_sale_director,base.model_res_partner_category,sf_base.group_sale_director,1,1,1,0
|
||||
access_sf_production_process,sf_production_process,model_sf_production_process,base.group_user,1,1,1,0
|
||||
access_sf_production_process_admin,sf_production_process_admin,model_sf_production_process,base.group_system,1,1,1,0
|
||||
access_sf_production_materials,sf_production_materials,model_sf_production_materials,base.group_user,1,1,1,0
|
||||
|
||||
|
@@ -21,6 +21,7 @@ class Http(models.AbstractModel):
|
||||
def _auth_method_sf_token(cls):
|
||||
# 从headers.environ中获取对方传过来的token,timestamp,加密的校验字符串
|
||||
datas = request.httprequest.headers.environ
|
||||
_logger.info('datas:%s' % datas)
|
||||
if 'HTTP_TOKEN' in datas:
|
||||
_logger.info('token:%s' % datas['HTTP_TOKEN'])
|
||||
# 查询密钥
|
||||
|
||||
@@ -5,7 +5,7 @@ import requests
|
||||
import cpca
|
||||
# from odoo.exceptions import UserError
|
||||
# from odoo.exceptions import ValidationError
|
||||
from odoo import api, fields, models
|
||||
from odoo import api, fields, models, _
|
||||
from odoo.exceptions import ValidationError
|
||||
|
||||
_logger = logging.getLogger(__name__)
|
||||
@@ -161,15 +161,25 @@ class JdEclp(models.Model):
|
||||
url2 = config['bfm_url'] + '/api/get/jd/no'
|
||||
response = requests.post(url2, json=json2, data=None)
|
||||
# _logger.info('调用成功2', response.json()['result']['wbNo'])
|
||||
self.carrier_tracking_ref = response.json()['result']['wbNo']
|
||||
self.carrier_tracking_ref = response.json()['result'].get('wbNo')
|
||||
if not self.carrier_tracking_ref:
|
||||
raise ValidationError('物流下单未成功,请联系管理员')
|
||||
self.is_bill = True
|
||||
self.logistics_status = '1'
|
||||
|
||||
# # 京东物流下单后,销售订单状态改为待收货
|
||||
# self.env['sale.order'].search([('name', '=', self.origin)]).write({'scheduled_status': 'to receive'})
|
||||
notification = {
|
||||
'type': 'ir.actions.client',
|
||||
'tag': 'display_notification',
|
||||
'params': {
|
||||
'title': _('成功'),
|
||||
'type': 'success',
|
||||
'message': '物流下单成功',
|
||||
'sticky': False,
|
||||
'next': {'type': 'ir.actions.client', 'tag': 'reload'}
|
||||
}
|
||||
}
|
||||
|
||||
# else:
|
||||
# raise UserError("选择京东物流才能下单呦")
|
||||
return notification
|
||||
|
||||
def get_bill(self):
|
||||
"""
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
<field name="is_bill" invisible="True"/>
|
||||
<field name="logistics_status" invisible="True"/>
|
||||
<field name="logistics_way" invisible="True"/>
|
||||
<button string="京东物流下单" name="create_order" type="object" confirm="是否确认物流下单" class="btn-primary"
|
||||
<button string="物流下单" name="create_order" type="object" confirm="是否确认物流下单" class="btn-primary"
|
||||
attrs="{'invisible': ['|', '|', '|', ('check_out', '!=', 'OUT'), ('state', '!=', 'assigned'), ('is_bill', '=', True), ('logistics_way', '=', '自提')]}"/>
|
||||
<button string="获取物流面单" name="get_bill" type="object" confirm="是否获取物流面单" class="btn-primary"
|
||||
attrs="{'invisible': ['|', '|', '|', '|', ('check_out', '!=', 'OUT'), ('state', '!=', 'assigned'), ('logistics_status', '=', '2'), ('is_bill', '=', False), ('logistics_way', '=', '自提')]}"/>
|
||||
@@ -45,42 +45,50 @@
|
||||
<field name="model">stock.picking</field>
|
||||
<field name="inherit_id" ref="delivery.view_picking_withcarrier_out_form"/>
|
||||
<field name="arch" type="xml">
|
||||
|
||||
<field name="location_id" position="after">
|
||||
<field name="logistics_status" attrs="{'invisible': [('check_out', '!=', 'OUT')]}"/>
|
||||
<field name="logistics_way" attrs="{'invisible': [('check_out', '!=', 'OUT')]}"/>
|
||||
</field>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<xpath expr="//group//field[@name='carrier_id']" position="after">
|
||||
<!-- <field name="senderNickName" domain="[('self.name', 'like', '%OUT%')]"/> -->
|
||||
<field name="senderNickName" attrs="{'invisible': [('check_out', '!=', 'OUT')]}"/>
|
||||
<field name="expressItemName" attrs="{'invisible': [('check_out', '!=', 'OUT')]}"/>
|
||||
<field name="deliveryType" attrs="{'invisible': [('check_out', '!=', 'OUT')]}"/>
|
||||
<field name="receiverName" attrs="{'invisible': [('check_out', '!=', 'OUT')]}"/>
|
||||
<field name="receiverMobile" attrs="{'invisible': [('check_out', '!=', 'OUT')]}"/>
|
||||
<field name="receiverProvinceName" attrs="{'invisible': [('check_out', '!=', 'OUT')]}"/>
|
||||
<field name="receiverCityName" attrs="{'invisible': [('check_out', '!=', 'OUT')]}"/>
|
||||
<field name="receiverCountyName" attrs="{'invisible': [('check_out', '!=', 'OUT')]}"/>
|
||||
<field name="receiverTownName" attrs="{'invisible': [('check_out', '!=', 'OUT')]}"/>
|
||||
<field name="receiverCompany" attrs="{'invisible': [('check_out', '!=', 'OUT')]}"/>
|
||||
<field name="remark" attrs="{'invisible': [('check_out', '!=', 'OUT')]}"/>
|
||||
<field name="grossWeight" attrs="{'invisible': [('check_out', '!=', 'OUT')]}"/>
|
||||
<field name="grossVolume" attrs="{'invisible': [('check_out', '!=', 'OUT')]}"/>
|
||||
<field name="pickupBeginTime" attrs="{'invisible': [('check_out', '!=', 'OUT')]}"/>
|
||||
<field name="bill_show" attrs="{'invisible': [('check_out', '!=', 'OUT')]}"/>
|
||||
<field name="logistics_status"/>
|
||||
<record id="tracking_only_view" model="ir.ui.view">
|
||||
<field name="name">tracking only</field>
|
||||
<field name="model">stock.picking</field>
|
||||
<field name="inherit_id" ref="stock.view_picking_form"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//form//sheet//notebook//page[@name='operations']" position="after">
|
||||
<page string="发货信息" name="tracking">
|
||||
<group>
|
||||
<group>
|
||||
<field name="senderNickName" attrs="{'invisible': [('check_out', '!=', 'OUT')]}"/>
|
||||
<field name="expressItemName" attrs="{'invisible': [('check_out', '!=', 'OUT')]}"/>
|
||||
<field name="grossWeight" attrs="{'invisible': [('check_out', '!=', 'OUT')]}"/>
|
||||
<field name="grossVolume" attrs="{'invisible': [('check_out', '!=', 'OUT')]}"/>
|
||||
<field name="deliveryType" attrs="{'invisible': [('check_out', '!=', 'OUT')]}"/>
|
||||
<field name="receiverName" attrs="{'invisible': [('check_out', '!=', 'OUT')]}"/>
|
||||
<field name="receiverMobile" attrs="{'invisible': [('check_out', '!=', 'OUT')]}"/>
|
||||
<field name="receiverProvinceName" attrs="{'invisible': [('check_out', '!=', 'OUT')]}"/>
|
||||
<field name="receiverCityName" attrs="{'invisible': [('check_out', '!=', 'OUT')]}"/>
|
||||
<field name="receiverCountyName" attrs="{'invisible': [('check_out', '!=', 'OUT')]}"/>
|
||||
<field name="receiverTownName" attrs="{'invisible': [('check_out', '!=', 'OUT')]}"/>
|
||||
<field name="receiverCompany" attrs="{'invisible': [('check_out', '!=', 'OUT')]}"/>
|
||||
<field name="remark" attrs="{'invisible': [('check_out', '!=', 'OUT')]}"/>
|
||||
|
||||
<field name="pickupBeginTime" attrs="{'invisible': [('check_out', '!=', 'OUT')]}"/>
|
||||
</group>
|
||||
<group>
|
||||
<field name="logistics_status"/>
|
||||
<field name="carrier_id"/>
|
||||
<field name="carrier_tracking_ref"/>
|
||||
|
||||
<field name="bill_show" attrs="{'invisible': [('check_out', '!=', 'OUT')]}" string='面单下载'/>
|
||||
<field name="bill_show" widget="pdf_viewer" attrs="{'invisible': [('check_out', '!=', 'OUT')]}"/>
|
||||
|
||||
</group>
|
||||
</group>
|
||||
</page>
|
||||
</xpath>
|
||||
<xpath expr="//group//field[@name='group_id']" position="after">
|
||||
<field name="bill_show" widget="pdf_viewer" attrs="{'invisible': [('check_out', '!=', 'OUT')]}"/>
|
||||
</xpath>
|
||||
<!-- <xpath expr="//group[@name='other_infos']" position="after"> -->
|
||||
<!-- <div> -->
|
||||
<!-- <button string="京东物流下单" name="create_order" type="object" confirm="是否确认物流下单" class="btn-primary"/> -->
|
||||
<!-- </div> -->
|
||||
<!-- <div> -->
|
||||
<!-- <button string="获取物流面单" name="get_bill" type="object" confirm="是否获取物流面单" class="btn-primary"/> -->
|
||||
<!-- </div> -->
|
||||
<!-- </xpath> -->
|
||||
</field>
|
||||
</record>
|
||||
</odoo>
|
||||
@@ -88,7 +88,7 @@
|
||||
</div>
|
||||
<field name="model_volume" string="体积[mm³]"/>
|
||||
<field name="product_model_type_id" string="模型类型"/>
|
||||
<field name="model_processing_panel" placeholder="例如R,U" string="加工面板"/>
|
||||
<field name="model_processing_panel" placeholder="例如R,U" string="加工面板" readonly="1"/>
|
||||
<field name="model_machining_precision"/>
|
||||
<field name="model_process_parameters_ids" string="表面工艺参数"
|
||||
widget="many2many_tags"
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
</xpath>
|
||||
<xpath expr="//field[@name='production_id']" position="before">
|
||||
<field name="product_tmpl_name"/>
|
||||
<field name="rfid_code"/>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
@@ -5,10 +5,10 @@
|
||||
<field name="model">mrp.workorder</field>
|
||||
<field name="inherit_id" ref="sf_manufacturing.view_mrp_production_workorder_tray_form_inherit_sf"/>
|
||||
<field name="arch" type="xml">
|
||||
<!-- <xpath expr="//header" position="inside">-->
|
||||
<!-- <button string="程序下载" name="cnc_file_download" type="object" class="oe_highlight" attrs='{"invisible": ["|",-->
|
||||
<!-- ("user_permissions","=",False),("routing_type","!=","CNC加工")]}'/>-->
|
||||
<!-- </xpath>-->
|
||||
<!-- <xpath expr="//header" position="inside">–>-->
|
||||
<!-- <button string="程序下载" name="cnc_file_download" type="object" class="oe_highlight" attrs='{"invisible": ["|",-->
|
||||
<!-- ("user_permissions","=",False),("routing_type","!=","CNC加工")]}'/>-->
|
||||
<!-- </xpath>-->
|
||||
<xpath expr="//page//field[@name='cnc_ids']" position="before">
|
||||
<group>
|
||||
<group>
|
||||
@@ -17,15 +17,15 @@
|
||||
</group>
|
||||
<div>
|
||||
<div>
|
||||
<field name="button_compensation_state" attrs='{"invisible": ["|",
|
||||
("state","!=","progress"),("user_permissions","=",False)]}'/>
|
||||
<!-- <field name="button_compensation_state" attrs='{"invisible": ["|",-->
|
||||
<!-- ("state","!=","progress"),("user_permissions","=",False)]}'/>-->
|
||||
<!-- <span> </span>-->
|
||||
<button name="button_send_program_again" type="object" string="重新下发NC程序"
|
||||
class="btn-primary"
|
||||
confirm="是否确认重新下发NC程序?"
|
||||
groups="sf_base.group_sf_order_user,sf_base.group_sf_equipment_user"
|
||||
attrs="{'invisible': ['|', '|', '|',('routing_type','!=','装夹预调'),('state','in',['done', 'cancel',
|
||||
'progress']),('processing_drawing','=',False),('is_send_program_again','=',True)]}"/>
|
||||
<!-- <button name="button_send_program_again" type="object" string="重新下发NC程序"-->
|
||||
<!-- class="btn-primary"-->
|
||||
<!-- confirm="是否确认重新下发NC程序?"-->
|
||||
<!-- groups="sf_base.group_sf_order_user,sf_base.group_sf_equipment_user"-->
|
||||
<!-- attrs="{'invisible': ['|', '|', '|',('routing_type','!=','装夹预调'),('state','in',['done', 'cancel',-->
|
||||
<!-- 'progress']),('processing_drawing','=',False),('is_send_program_again','=',True)]}"/>-->
|
||||
<!-- <button string="一键补偿" name="compensation" type="object" confirm="是否确认下发补偿"-->
|
||||
<!-- class="btn-primary" attrs='{"invisible": ["|",-->
|
||||
<!-- ("state","!=","progress"),("user_permissions","=",False)]}'/>-->
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
<!-- attrs='{"invisible": ["|",("state","!=","progress"), -->
|
||||
<!-- ("user_permissions","!=",True)]}'/> -->
|
||||
<!-- <button string="下发" name="up" type="object" class="btn-primary" confirm="是否确认下发此程序" context="{'default_cnc_ids': cnc_ids}"/> -->
|
||||
<button string="下发" name="up" type="object" class="btn-primary" confirm="是否确认下发此程序"
|
||||
<!-- <button string="下发" name="up" type="object" class="btn-primary" confirm="是否确认下发此程序"-->
|
||||
context="{'default_sf_cnc_processing_id': id}" attrs='{"invisible": ["|",("state","!=","progress"),
|
||||
("user_permissions","!=",True)]}'/>
|
||||
<!-- <button string="下发" name="up" type="object" class="btn-primary" confirm="是否确认下发此程序"-->
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
<!-- <field name="program_ids" domain="[('workorder_id', '=', workorder_id)]"/>-->
|
||||
</group>
|
||||
<footer>
|
||||
<button string="合并下发" name="confirm_up" type="object" class="btn-primary" confirm="是否确认合并下发"/>
|
||||
<!-- <button string="合并下发" name="confirm_up" type="object" class="btn-primary" confirm="是否确认合并下发"/>-->
|
||||
<button string="取消" class="btn-secondary" special="cancel"/>
|
||||
</footer>
|
||||
</form>
|
||||
|
||||
@@ -162,7 +162,8 @@ class Manufacturing_Connect(http.Controller):
|
||||
routing_type = ret['CraftId']
|
||||
equipment_id = ret["DeviceId"]
|
||||
workorder = request.env['mrp.workorder'].sudo().search(
|
||||
[('production_id', '=', production_id), ('routing_type', '=', routing_type)], limit=1)
|
||||
[('production_id', '=', production_id), ('routing_type', '=', routing_type),
|
||||
('rfid_code', '!=', False)], limit=1)
|
||||
if not workorder:
|
||||
res = {'Succeed': False, 'ErrorCode': 202, 'Error': '该工单不存在'}
|
||||
return json.JSONEncoder().encode(res)
|
||||
@@ -203,12 +204,14 @@ class Manufacturing_Connect(http.Controller):
|
||||
res = {'Succeed': True, 'Datas': ['工单已结束']}
|
||||
datas = request.httprequest.data
|
||||
ret = json.loads(datas)
|
||||
logging.info('button_Work_End:%s' % ret)
|
||||
request.env['center_control.interface.log'].sudo().create(
|
||||
{'content': ret, 'name': 'AutoDeviceApi/FeedBackEnd'})
|
||||
production_id = ret['BillId']
|
||||
routing_type = ret['CraftId']
|
||||
workorder = request.env['mrp.workorder'].sudo().search(
|
||||
[('production_id', '=', production_id), ('routing_type', '=', routing_type)], limit=1)
|
||||
[('production_id', '=', production_id), ('routing_type', '=', routing_type),
|
||||
('rfid_code', '!=', False)], limit=1)
|
||||
if not workorder:
|
||||
res = {'Succeed': False, 'ErrorCode': 202, 'Error': '该工单不存在'}
|
||||
return json.JSONEncoder().encode(res)
|
||||
@@ -222,14 +225,14 @@ class Manufacturing_Connect(http.Controller):
|
||||
# workorder.sudo().production_id.process_state = '待解除装夹'
|
||||
|
||||
# 根据工单的实际结束时间修改排程单的结束时间、状态,同时修改销售订单的状态
|
||||
if workorder.date_finished:
|
||||
request.env['sf.production.plan'].sudo().search([('production_id', '=', production_id)]).write(
|
||||
{'actual_end_time': workorder.date_finished,
|
||||
'state': 'finished'})
|
||||
production_obj = request.env['mrp.production'].sudo().search([('name', '=', production_id)])
|
||||
if production_obj:
|
||||
production_obj.sudo().work_order_state = '已完成'
|
||||
production_obj.write({'state': 'completed'})
|
||||
# if workorder.date_finished:
|
||||
# request.env['sf.production.plan'].sudo().search([('production_id', '=', production_id)]).write(
|
||||
# {'actual_end_time': workorder.date_finished,
|
||||
# 'state': 'finished'})
|
||||
# production_obj = request.env['mrp.production'].sudo().search([('name', '=', production_id)])
|
||||
# if production_obj:
|
||||
# production_obj.sudo().work_order_state = '已完成'
|
||||
# production_obj.write({'state': 'done'})
|
||||
# request.env['sale.order'].sudo().search(
|
||||
# [('name', '=', production_obj.origin)]).write({'schedule_status': 'to deliver'})
|
||||
|
||||
@@ -317,15 +320,15 @@ class Manufacturing_Connect(http.Controller):
|
||||
[('rfid_code', '=', ret['RfidCode']), ('routing_type', '=', 'CNC加工')])
|
||||
if workorder:
|
||||
for item in workorder.cmm_ids:
|
||||
if item.program_date is not False:
|
||||
program_date = item.program_date.strftime("%Y-%m-%d %H:%M:%S")
|
||||
program_date_str = request.env['sf.sync.common'].sudo().get_add_time(program_date)
|
||||
if item.program_create_date is not False:
|
||||
program_create_date = item.program_create_date.strftime("%Y-%m-%d %H:%M:%S")
|
||||
program_date_str = request.env['sf.sync.common'].sudo().get_add_time(program_create_date)
|
||||
res['Datas'].append({
|
||||
'CraftId': workorder.id,
|
||||
'CraftKey': workorder.name,
|
||||
'ProgramDate': '' if not item.program_date else program_date_str,
|
||||
'ProgramDate': '' if not item.program_create_date else program_date_str,
|
||||
'ProgramPath': item.program_path,
|
||||
'PostProcessing': item.post_processing_name,
|
||||
'PostProcessing': item.program_name,
|
||||
})
|
||||
else:
|
||||
res = {'Succeed': False, 'ErrorCode': 203, 'Error': '暂无工单及对应的CNC程序数据'}
|
||||
|
||||
@@ -30,13 +30,10 @@ class MrpProduction(models.Model):
|
||||
# ('completed', '已完工')
|
||||
# ])
|
||||
state = fields.Selection([
|
||||
('draft', 'Draft'),
|
||||
('confirmed', 'Confirmed'),
|
||||
('progress', '待排程'),
|
||||
('pending_cam', '待装夹'),
|
||||
('pending_processing', '待加工'),
|
||||
('pending_era_cam', '待解除装夹'),
|
||||
('completed', '已完工'),
|
||||
('draft', '草稿'),
|
||||
('confirmed', '待排程'),
|
||||
('pending_cam', '待加工'),
|
||||
('progress', '加工中'),
|
||||
('to_close', 'To Close'),
|
||||
('done', 'Done'),
|
||||
('cancel', 'Cancelled')], string='State',
|
||||
@@ -53,7 +50,8 @@ class MrpProduction(models.Model):
|
||||
active = fields.Boolean(string='已归档', default=True)
|
||||
programming_no = fields.Char('编程单号')
|
||||
work_state = fields.Char('业务状态')
|
||||
programming_state = fields.Char('编程状态', tracking=True)
|
||||
programming_state = fields.Selection(
|
||||
[('编程中', '编程中'), ('已编程', '已编程')], string='编程状态', tracking=True)
|
||||
glb_file = fields.Binary("glb模型文件")
|
||||
production_line_id = fields.Many2one('sf.production.line', string='生产线', tracking=True)
|
||||
plan_start_processing_time = fields.Datetime('计划开始加工时间')
|
||||
@@ -81,7 +79,7 @@ class MrpProduction(models.Model):
|
||||
|
||||
@api.depends(
|
||||
'move_raw_ids.state', 'move_raw_ids.quantity_done', 'move_finished_ids.state',
|
||||
'workorder_ids.state', 'product_qty', 'qty_producing', 'schedule_state', 'process_state')
|
||||
'workorder_ids.state', 'product_qty', 'qty_producing', 'schedule_state')
|
||||
def _compute_state(self):
|
||||
for production in self:
|
||||
if not production.state or not production.product_uom_id:
|
||||
@@ -109,22 +107,19 @@ class MrpProduction(models.Model):
|
||||
production.state = 'progress'
|
||||
elif any(not float_is_zero(move.quantity_done,
|
||||
precision_rounding=move.product_uom.rounding or move.product_id.uom_id.rounding)
|
||||
for move in production.move_raw_ids):
|
||||
for move in production.move_raw_ids if move.product_id):
|
||||
production.state = 'progress'
|
||||
|
||||
# 新添加的状态逻辑
|
||||
if production.state == 'progress' and production.schedule_state == '已排' and production.process_state == '待装夹':
|
||||
# production.state = 'pending_processing'
|
||||
# # 新添加的状态逻辑
|
||||
if (
|
||||
production.state == 'to_close' or production.state == 'progress') and production.schedule_state == '未排':
|
||||
production.state = 'confirmed'
|
||||
elif production.state == 'to_close' and production.schedule_state == '已排':
|
||||
production.state = 'pending_cam'
|
||||
if production.state == 'progress' and production.schedule_state == '已排' and production.process_state == '待加工':
|
||||
# if production.state == 'pending_cam' and production.process_state == '待加工':
|
||||
production.state = 'pending_processing'
|
||||
elif production.state == 'progress' and production.process_state == '待解除装夹':
|
||||
production.state = 'pending_era_cam'
|
||||
elif production.state == 'progress' and production.process_state == '已完工':
|
||||
production.state = 'completed'
|
||||
elif production.state == 'progress' and production.work_order_state == '已完成':
|
||||
production.state = 'completed'
|
||||
|
||||
if production.state == 'progress':
|
||||
if all(wo_state not in ('progress', 'done') for wo_state in production.workorder_ids.mapped('state')):
|
||||
production.state = 'pending_cam'
|
||||
|
||||
def action_check(self):
|
||||
"""
|
||||
@@ -293,14 +288,6 @@ class MrpProduction(models.Model):
|
||||
# 其他规则限制: 默认只分配给工作中心状态为非故障的工作中心;
|
||||
|
||||
def _create_workorder3(self, item):
|
||||
# 根据product_id对self进行分组
|
||||
grouped_product_ids = {k: list(g) for k, g in groupby(self, key=lambda x: x.product_id.id)}
|
||||
# 初始化一个字典来存储每个product_id对应的生产订单名称列表
|
||||
product_id_to_production_names = {}
|
||||
# 对于每个product_id,获取其所有生产订单的名称
|
||||
for product_id, productions in grouped_product_ids.items():
|
||||
# 为同一个product_id创建一个生产订单名称列表
|
||||
product_id_to_production_names[product_id] = [production.name for production in productions]
|
||||
for production in self:
|
||||
if not production.bom_id or not production.product_id:
|
||||
continue
|
||||
@@ -347,6 +334,7 @@ class MrpProduction(models.Model):
|
||||
# 表面工艺工序
|
||||
# 获取表面工艺id
|
||||
if production.product_id.model_process_parameters_ids:
|
||||
logging.info('model_process_parameters_ids:%s' % production.product_id.model_process_parameters_ids)
|
||||
surface_technics_arr = []
|
||||
# 工序id
|
||||
route_workcenter_arr = []
|
||||
@@ -361,6 +349,7 @@ class MrpProduction(models.Model):
|
||||
# 用filter刷选表面工艺id'是否存在工艺类别对象里
|
||||
if production_process_category:
|
||||
for p in production_process_category:
|
||||
logging.info('production_process_category:%s' % p.name)
|
||||
production_process = p.production_process_ids.filtered(
|
||||
lambda pp: pp.id in surface_technics_arr)
|
||||
if production_process:
|
||||
@@ -414,7 +403,7 @@ class MrpProduction(models.Model):
|
||||
else:
|
||||
if m == len(consecutive_workorders) - 1 and m != 0:
|
||||
self.env['stock.picking'].create_outcontract_picking(consecutive_workorders,
|
||||
production_item)
|
||||
production)
|
||||
if sorted_workorders[i] in consecutive_workorders:
|
||||
is_pick = True
|
||||
consecutive_workorders = []
|
||||
@@ -422,21 +411,21 @@ class MrpProduction(models.Model):
|
||||
# 当前面的连续工序生成对应的外协出入库单再生成当前工序的外协出入库单
|
||||
if is_pick is False:
|
||||
self.env['stock.picking'].create_outcontract_picking(sorted_workorders[i],
|
||||
production_item)
|
||||
production)
|
||||
if m == len(consecutive_workorders) - 1 and m != 0:
|
||||
self.env['stock.picking'].create_outcontract_picking(consecutive_workorders,
|
||||
production_item)
|
||||
production)
|
||||
if sorted_workorders[i] in consecutive_workorders:
|
||||
is_pick = True
|
||||
consecutive_workorders = []
|
||||
m = 0
|
||||
if m == len(consecutive_workorders) - 1 and m != 0:
|
||||
self.env['stock.picking'].create_outcontract_picking(consecutive_workorders, production_item)
|
||||
self.env['stock.picking'].create_outcontract_picking(consecutive_workorders, production)
|
||||
if is_pick is False and m == 0:
|
||||
if len(sorted_workorders) == 1:
|
||||
self.env['stock.picking'].create_outcontract_picking(sorted_workorders, production_item)
|
||||
self.env['stock.picking'].create_outcontract_picking(sorted_workorders, production)
|
||||
else:
|
||||
self.env['stock.picking'].create_outcontract_picking(sorted_workorders[i], production_item)
|
||||
self.env['stock.picking'].create_outcontract_picking(sorted_workorders[i], production)
|
||||
for workorder in production.workorder_ids:
|
||||
workorder.duration_expected = workorder._get_duration_expected()
|
||||
|
||||
@@ -641,9 +630,10 @@ class MrpProduction(models.Model):
|
||||
})
|
||||
|
||||
for production in self:
|
||||
logging.info('qty_produced:%s' % production.qty_produced)
|
||||
production.write({
|
||||
'date_finished': fields.Datetime.now(),
|
||||
'product_qty': production.qty_produced,
|
||||
'product_qty': production.product_qty if production.qty_produced < 1.0 else production.qty_produced,
|
||||
'priority': '0',
|
||||
'is_locked': True,
|
||||
'state': 'done',
|
||||
@@ -669,6 +659,7 @@ class MrpProduction(models.Model):
|
||||
if any(mo.show_allocation for mo in self):
|
||||
action = self.action_view_reception_report()
|
||||
return action
|
||||
logging.info('last-product_qty:%s' % production.product_qty)
|
||||
return True
|
||||
context = self.env.context.copy()
|
||||
context = {k: v for k, v in context.items() if not k.startswith('default_')}
|
||||
|
||||
@@ -19,7 +19,7 @@ from odoo.addons.sf_mrs_connect.models.ftp_operate import FtpController
|
||||
|
||||
class ResMrpWorkOrder(models.Model):
|
||||
_inherit = 'mrp.workorder'
|
||||
_order = 'sequence asc,create_date desc'
|
||||
_order = 'id'
|
||||
|
||||
product_tmpl_name = fields.Char('坯料产品名称', related='production_bom_id.bom_line_ids.product_id.name')
|
||||
|
||||
@@ -136,11 +136,6 @@ class ResMrpWorkOrder(models.Model):
|
||||
|
||||
supplier_id = fields.Many2one('res.partner', string='外协供应商')
|
||||
equipment_id = fields.Many2one('maintenance.equipment', string='加工设备', tracking=True)
|
||||
is_ok = fields.Boolean(string='是否合格')
|
||||
# 加工人
|
||||
processing_user_id = fields.Many2one('res.users', string='加工人')
|
||||
# 检测人
|
||||
inspection_user_id = fields.Many2one('res.users', string='检测人')
|
||||
# 保存名称
|
||||
save_name = fields.Char(string='检测文件保存名称', compute='_compute_save_name')
|
||||
# 获取数据状态
|
||||
@@ -207,7 +202,8 @@ class ResMrpWorkOrder(models.Model):
|
||||
[("programming", "编程"), ("clamping", "返工"), ("cutter", "刀具"), ("operate computer", "操机"),
|
||||
("technology", "工艺"), ("customer redrawing", "客户改图"), ("other", "其他"), ], string="原因", tracking=True)
|
||||
detailed_reason = fields.Text('详细原因')
|
||||
is_send_program_again = fields.Boolean(string='是否重新下发NC程序', default=False)
|
||||
|
||||
# is_send_program_again = fields.Boolean(string='是否重新下发NC程序', default=False)
|
||||
|
||||
@api.onchange('rfid_code')
|
||||
def _onchange(self):
|
||||
@@ -234,16 +230,6 @@ class ResMrpWorkOrder(models.Model):
|
||||
ids = [t[0] for t in self.env.cr.fetchall()]
|
||||
return [('id', 'in', ids)]
|
||||
|
||||
@api.onchange('is_ok')
|
||||
def _onchange_inspection_user_id(self):
|
||||
"""
|
||||
检测is_ok(是否合格)被修改的话,就将当前用户赋值给inspection_user_id
|
||||
"""
|
||||
if not self.inspection_user_id:
|
||||
self.inspection_user_id = self.env.user.id
|
||||
else:
|
||||
self.inspection_user_id = False
|
||||
|
||||
@api.onchange('functional_fixture_id')
|
||||
def _onchange_functional_fixture_id(self):
|
||||
if self.functional_fixture_id:
|
||||
@@ -876,10 +862,9 @@ class ResMrpWorkOrder(models.Model):
|
||||
('location_dest_id', '=', self.env['stock.location'].search(
|
||||
[('barcode', 'ilike', 'VL-SPOC')]).id),
|
||||
('origin', '=', self.production_id.name)])
|
||||
purchase = self.env['purchase.order'].search([('origin', '=', self.production_id.name)])
|
||||
if purchase and move_out:
|
||||
if move_out:
|
||||
move_out.write({'state': 'assigned'})
|
||||
self.env['stock.move.line'].create(move_out.get_move_line(purchase, self))
|
||||
self.env['stock.move.line'].create(move_out.get_move_line(self.production_id, self))
|
||||
|
||||
# move_out._action_assign()
|
||||
if self.state == 'waiting' or self.state == 'ready' or self.state == 'progress':
|
||||
@@ -1021,22 +1006,24 @@ class ResMrpWorkOrder(models.Model):
|
||||
if workorder.processing_panel == record.processing_panel:
|
||||
rfid_code = workorder.rfid_code
|
||||
workorder.write({'rfid_code_old': rfid_code,
|
||||
'rfid_code': ''})
|
||||
'rfid_code': False})
|
||||
workorder.rfid_code_old = rfid_code
|
||||
workorder.rfid_code = ''
|
||||
workorder.rfid_code = False
|
||||
if is_production_id is True and record.routing_type in ['解除装夹', '表面工艺']:
|
||||
logging.info('product_qty:%s' % record.production_id.product_qty)
|
||||
for move_raw_id in record.production_id.move_raw_ids:
|
||||
move_raw_id.quantity_done = move_raw_id.product_uom_qty
|
||||
record.process_state = '已完工'
|
||||
record.production_id.process_state = '已完工'
|
||||
if record.routing_type in ['表面工艺']:
|
||||
if record.routing_type in ['解除装夹', '表面工艺']:
|
||||
raw_move = self.env['stock.move'].sudo().search(
|
||||
[('origin', '=', record.production_id.name), ('procure_method', '=', 'make_to_order'),
|
||||
[('origin', '=', record.production_id.name),
|
||||
('procure_method', 'in', ['make_to_order', 'make_to_stock']),
|
||||
('state', '!=', 'done')])
|
||||
if raw_move:
|
||||
raw_move.write({'state': 'done'})
|
||||
record.production_id.button_mark_done1()
|
||||
# self.production_id.state = 'done'
|
||||
# record.production_id.state = 'done'
|
||||
|
||||
# 将FTP的检测报告文件下载到临时目录
|
||||
def download_reportfile_tmp(self, workorder, reportpath):
|
||||
@@ -1079,31 +1066,30 @@ class ResMrpWorkOrder(models.Model):
|
||||
return True
|
||||
|
||||
# 重新下发nc程序
|
||||
def button_send_program_again(self):
|
||||
try:
|
||||
res = {'programming_no': self.production_id.programming_no}
|
||||
configsettings = self.env['res.config.settings'].get_values()
|
||||
config_header = Common.get_headers(self, configsettings['token'], configsettings['sf_secret_key'])
|
||||
url = '/api/intelligent_programming/reset_state_again'
|
||||
config_url = configsettings['sf_url'] + url
|
||||
r = requests.post(config_url, json=res, data=None, headers=config_header)
|
||||
r = r.json()
|
||||
result = json.loads(r['result'])
|
||||
if result['status'] == 1:
|
||||
productions = self.env['mrp.production'].search(
|
||||
[('programming_no', '=', self.production_id.programming_no), ('programming_state', '=', '已编程')])
|
||||
if productions:
|
||||
workorder = productions.workorder_ids.filtered(
|
||||
lambda ap: ap.routing_type in ['装夹预调', 'CNC加工'] and ap.state not in ['done', 'cancel',
|
||||
'progress'])
|
||||
if workorder:
|
||||
workorder.write({'is_send_program_again': True})
|
||||
productions.write({'work_state': '编程中', 'programming_state': '编程中'})
|
||||
else:
|
||||
raise UserError(result['message'])
|
||||
except Exception as e:
|
||||
logging.info('button_send_program_again error:%s' % e)
|
||||
raise UserError("重新下发nc程序失败,请联系管理员")
|
||||
# def button_send_program_again(self):
|
||||
# try:
|
||||
# res = {'programming_no': self.production_id.programming_no}
|
||||
# configsettings = self.env['res.config.settings'].get_values()
|
||||
# config_header = Common.get_headers(self, configsettings['token'], configsettings['sf_secret_key'])
|
||||
# url = '/api/intelligent_programming/reset_state_again'
|
||||
# config_url = configsettings['sf_url'] + url
|
||||
# r = requests.post(config_url, json=res, data=None, headers=config_header)
|
||||
# r = r.json()
|
||||
# result = json.loads(r['result'])
|
||||
# if result['status'] == 1:
|
||||
# productions = self.env['mrp.production'].search(
|
||||
# [('programming_no', '=', self.production_id.programming_no), ('programming_state', '=', '已编程')])
|
||||
# if productions:
|
||||
# workorder = productions.workorder_ids.filtered(
|
||||
# lambda ap: ap.routing_type in ['装夹预调', 'CNC加工'] and ap.state not in ['done', 'cancel',
|
||||
# 'progress'])
|
||||
# if workorder:
|
||||
# productions.write({'work_state': '编程中', 'programming_state': '编程中'})
|
||||
# else:
|
||||
# raise UserError(result['message'])
|
||||
# except Exception as e:
|
||||
# logging.info('button_send_program_again error:%s' % e)
|
||||
# raise UserError("重新下发nc程序失败,请联系管理员")
|
||||
|
||||
|
||||
class CNCprocessing(models.Model):
|
||||
@@ -1215,11 +1201,13 @@ class CNCprocessing(models.Model):
|
||||
|
||||
# 将FTP的多面的程序单文件下载到临时目录
|
||||
def download_file_tmp(self, production_no, processing_panel):
|
||||
remotepath = os.path.join('/NC', production_no, 'return', processing_panel)
|
||||
remotepath = os.path.join('/home/ftp/ftp_root/NC', production_no, 'return', processing_panel)
|
||||
serverdir = os.path.join('/tmp', production_no, 'return', processing_panel)
|
||||
ftp_resconfig = self.env['res.config.settings'].get_values()
|
||||
ftp = FtpController(str(ftp_resconfig['ftp_host']), int(ftp_resconfig['ftp_port']), ftp_resconfig['ftp_user'],
|
||||
ftp_resconfig['ftp_password'])
|
||||
if not ftp.file_exists_1(remotepath):
|
||||
logging.info('目录不存在:%s' % remotepath)
|
||||
download_state = ftp.download_program_file(remotepath, serverdir)
|
||||
logging.info('download_state:%s' % download_state)
|
||||
return download_state
|
||||
@@ -1265,6 +1253,7 @@ class SfWorkOrderBarcodes(models.Model):
|
||||
_inherit = ["mrp.workorder", "barcodes.barcode_events_mixin"]
|
||||
|
||||
def on_barcode_scanned(self, barcode):
|
||||
logging.info('Rfid:%s' % barcode)
|
||||
workorder = self.env['mrp.workorder'].browse(self.ids)
|
||||
# workorder_preset = self.env['mrp.workorder'].search(
|
||||
# [('routing_type', '=', '装夹预调'), ('rfid_code', '=', barcode)])
|
||||
@@ -1308,7 +1297,7 @@ class SfWorkOrderBarcodes(models.Model):
|
||||
self.process_state = '待检测'
|
||||
self.date_start = datetime.now()
|
||||
else:
|
||||
raise UserError('该托盘信息不存在!!!')
|
||||
raise UserError('没有找到Rfid为【%s】的托盘信息!!!' % barcode)
|
||||
# stock_move_line = self.env['stock.move.line'].search([('lot_name', '=', barcode)])
|
||||
# if stock_move_line.product_id.categ_type == '夹具':
|
||||
# workorder.write({
|
||||
|
||||
@@ -616,7 +616,7 @@ class ResProductMo(models.Model):
|
||||
item['model_width'] + model_type.embryo_tolerance) * (
|
||||
item['model_height'] + model_type.embryo_tolerance),
|
||||
'product_model_type_id': model_type.id,
|
||||
'model_processing_panel': 'R',
|
||||
# 'model_processing_panel': 'R',
|
||||
'model_machining_precision': item['model_machining_precision'],
|
||||
'model_code': item['barcode'],
|
||||
'length': item['model_long'],
|
||||
@@ -634,6 +634,7 @@ class ResProductMo(models.Model):
|
||||
'model_process_parameters_ids': [(6, 0, [])] if not item.get(
|
||||
'process_parameters_code') else self.get_process_parameters_id(item['process_parameters_code']),
|
||||
'model_remark': item['remark'],
|
||||
'single_manufacturing': True,
|
||||
'default_code': '%s-%s' % (order_number, i),
|
||||
'manual_quotation': item['manual_quotation'] or False,
|
||||
'part_number': item.get('part_number') or '',
|
||||
|
||||
@@ -204,40 +204,18 @@ class StockRule(models.Model):
|
||||
productions = self.env['mrp.production'].with_user(SUPERUSER_ID).sudo().with_company(company_id).create(
|
||||
productions_values)
|
||||
|
||||
# self.env['stock.move'].sudo().create(productions._get_moves_raw_values())
|
||||
self.env['stock.move'].sudo().create(productions._get_moves_finished_values())
|
||||
productions.filtered(lambda p: (not p.orderpoint_id and p.move_raw_ids) or \
|
||||
(
|
||||
p.move_dest_ids.procure_method != 'make_to_order' and not
|
||||
p.move_raw_ids and not p.workorder_ids)).action_confirm()
|
||||
self.env['stock.move'].sudo().create(productions._get_moves_raw_values())
|
||||
|
||||
'''
|
||||
创建工单
|
||||
'''
|
||||
# productions._create_workorder()
|
||||
#
|
||||
grouped_product_ids = {k: list(g) for k, g in groupby(productions, key=lambda x: x.product_id.id)}
|
||||
# 初始化一个字典来存储每个product_id对应的生产订单名称列表
|
||||
product_id_to_production_names = {}
|
||||
# 对于每个product_id,获取其所有生产订单的名称
|
||||
for product_id, productions in grouped_product_ids.items():
|
||||
# 为同一个product_id创建一个生产订单名称列表
|
||||
product_id_to_production_names[product_id] = [production.name for production in productions]
|
||||
for production_item in productions:
|
||||
if production_item.product_id.id in product_id_to_production_names:
|
||||
# # 同一个产品多个制造订单对应一个编程单和模型库
|
||||
# # 只调用一次fetchCNC,并将所有生产订单的名称作为字符串传递
|
||||
if not production_item.programming_no:
|
||||
production_programming = self.env['mrp.production'].search(
|
||||
[('product_id.id', '=', production_item.product_id.id),
|
||||
('origin', '=', production_item.origin)],
|
||||
limit=1, order='id asc')
|
||||
if not production_programming.programming_no:
|
||||
production_item.fetchCNC(
|
||||
', '.join(product_id_to_production_names[production_item.product_id.id]))
|
||||
else:
|
||||
production_item.write({'programming_no': production_programming.programming_no,
|
||||
'programming_state': '编程中'})
|
||||
|
||||
self.env['stock.move'].sudo().create(productions._get_moves_finished_values())
|
||||
productions.filtered(lambda p: (not p.orderpoint_id and p.move_raw_ids) or \
|
||||
(
|
||||
p.move_dest_ids.procure_method != 'make_to_order' and not
|
||||
p.move_raw_ids and not p.workorder_ids)).action_confirm()
|
||||
for production in productions:
|
||||
'''
|
||||
创建制造订单时生成序列号
|
||||
@@ -283,6 +261,29 @@ class StockRule(models.Model):
|
||||
'product_id': production.product_id.id,
|
||||
'state': 'draft',
|
||||
})
|
||||
all_production = productions
|
||||
grouped_product_ids = {k: list(g) for k, g in groupby(all_production, key=lambda x: x.product_id.id)}
|
||||
# 初始化一个字典来存储每个product_id对应的生产订单名称列表
|
||||
product_id_to_production_names = {}
|
||||
# 对于每个product_id,获取其所有生产订单的名称
|
||||
for product_id, all_production in grouped_product_ids.items():
|
||||
# 为同一个product_id创建一个生产订单名称列表
|
||||
product_id_to_production_names[product_id] = [production.name for production in all_production]
|
||||
for production_item in productions:
|
||||
if production_item.product_id.id in product_id_to_production_names:
|
||||
# # 同一个产品多个制造订单对应一个编程单和模型库
|
||||
# # 只调用一次fetchCNC,并将所有生产订单的名称作为字符串传递
|
||||
if not production_item.programming_no:
|
||||
production_programming = self.env['mrp.production'].search(
|
||||
[('product_id.id', '=', production_item.product_id.id),
|
||||
('origin', '=', production_item.origin)],
|
||||
limit=1, order='id asc')
|
||||
if not production_programming.programming_no:
|
||||
production_item.fetchCNC(
|
||||
', '.join(product_id_to_production_names[production_item.product_id.id]))
|
||||
else:
|
||||
production_item.write({'programming_no': production_programming.programming_no,
|
||||
'programming_state': '编程中'})
|
||||
return True
|
||||
|
||||
|
||||
@@ -486,10 +487,10 @@ class StockPicking(models.Model):
|
||||
('location_dest_id', '=', self.env['stock.location'].search(
|
||||
[('barcode', 'ilike', 'VL-SPOC')]).id),
|
||||
('origin', '=', self.origin)])
|
||||
if self.id == move_out.picking_id.id:
|
||||
if move_out.move_line_ids.workorder_id.state not in ['progress']:
|
||||
raise UserError(
|
||||
_('该出库单里源单据内的单号为%s的工单还未开始,不能进行验证操作!' % move_out.move_line_ids.workorder_id.name))
|
||||
# if self.id == move_out.picking_id.id:
|
||||
# if move_out.move_line_ids.workorder_id.state not in ['progress']:
|
||||
# raise UserError(
|
||||
# _('该出库单里源单据内的单号为%s的工单还未开始,不能进行验证操作!' % move_out.move_line_ids.workorder_id.name))
|
||||
# 入库单验证
|
||||
move_in = self.env['stock.move'].search(
|
||||
[('location_dest_id', '=', self.env['stock.location'].search(
|
||||
@@ -505,18 +506,17 @@ class StockPicking(models.Model):
|
||||
res = super().button_validate()
|
||||
if res is True:
|
||||
if self.id == move_out.picking_id.id:
|
||||
if move_out.move_line_ids.workorder_id.state == 'progress':
|
||||
move_in = self.env['stock.move'].search(
|
||||
[('location_dest_id', '=', self.env['stock.location'].search(
|
||||
[('barcode', 'ilike', 'WH-PREPRODUCTION')]).id),
|
||||
('location_id', '=', self.env['stock.location'].search(
|
||||
[('barcode', 'ilike', 'VL-SPOC')]).id),
|
||||
('origin', '=', self.origin)])
|
||||
# purchase = self.env['purchase.order'].search([('origin', '=', self.origin)])
|
||||
if move_in:
|
||||
move_in.write({'state': 'assigned'})
|
||||
purchase = self.env['purchase.order'].search([('origin', '=', self.origin)])
|
||||
self.env['stock.move.line'].create(move_in.get_move_line(purchase, None))
|
||||
# if move_out.move_line_ids.workorder_id.state == 'progress':
|
||||
move_in = self.env['stock.move'].search(
|
||||
[('location_dest_id', '=', self.env['stock.location'].search(
|
||||
[('barcode', 'ilike', 'WH-PREPRODUCTION')]).id),
|
||||
('location_id', '=', self.env['stock.location'].search(
|
||||
[('barcode', 'ilike', 'VL-SPOC')]).id),
|
||||
('origin', '=', self.origin)])
|
||||
production = self.env['mrp.production'].search([('name', '=', self.origin)])
|
||||
if move_in:
|
||||
move_in.write({'state': 'assigned'})
|
||||
self.env['stock.move.line'].create(move_in.get_move_line(production, None))
|
||||
|
||||
return res
|
||||
|
||||
@@ -598,7 +598,7 @@ class ReStockMove(models.Model):
|
||||
'state': 'confirmed',
|
||||
}
|
||||
|
||||
def get_move_line(self, purchase, sorted_workorders):
|
||||
def get_move_line(self, production_id, sorted_workorders):
|
||||
return {
|
||||
'move_id': self.id,
|
||||
'product_id': self.product_id.id,
|
||||
@@ -607,7 +607,7 @@ class ReStockMove(models.Model):
|
||||
'location_dest_id': self.picking_id.location_dest_id.id,
|
||||
'picking_id': self.picking_id.id,
|
||||
'reserved_uom_qty': 1.0,
|
||||
'lot_id': purchase.picking_ids.move_line_ids.lot_id.id,
|
||||
'lot_id': production_id.move_line_raw_ids.lot_id.id,
|
||||
'company_id': self.company_id.id,
|
||||
# 'workorder_id': '' if not sorted_workorders else sorted_workorders.id,
|
||||
# 'production_id': '' if not sorted_workorders else sorted_workorders.production_id.id,
|
||||
|
||||
@@ -65,10 +65,9 @@
|
||||
<!-- <attribute name="statusbar_visible">draft,confirmed,progress,pending_processing,completed,done -->
|
||||
<!-- </attribute> -->
|
||||
<attribute name="statusbar_visible">
|
||||
progress,pending_cam,pending_processing,pending_era_cam,completed,done
|
||||
confirmed,pending_cam,progress,done
|
||||
</attribute>
|
||||
</xpath>
|
||||
|
||||
<xpath expr="//sheet//group//group[2]//label" position="before">
|
||||
<!-- <field name="process_state"/> -->
|
||||
<field name="state"/>
|
||||
@@ -76,11 +75,12 @@
|
||||
|
||||
</xpath>
|
||||
<xpath expr="//sheet//group//group//div[3]" position="after">
|
||||
<field name="manual_quotation" readonly="1"/>
|
||||
<field name="programming_no" readonly="1"/>
|
||||
<field name="programming_state" readonly="1" decoration-success="programming_state == '已编程'"
|
||||
decoration-warning="programming_state =='编程中'"/>
|
||||
<field name="work_state" invisible="1"/>
|
||||
<field name="schedule_state" invisible='1'/>
|
||||
<field name="manual_quotation" readonly="1"/>
|
||||
<field name="programming_state" readonly="1"/>
|
||||
</xpath>
|
||||
<xpath expr="//field[@name='user_id']" position="before">
|
||||
<field name="plan_start_processing_time" readonly="1"/>
|
||||
@@ -255,7 +255,9 @@
|
||||
</xpath>
|
||||
|
||||
<xpath expr="//sheet//notebook//page[@name='operations']" position="attributes">
|
||||
<attribute name="attrs">{'invisible': [('schedule_state', '=', '未排')]}</attribute>
|
||||
<attribute name="attrs">{'invisible': ['|',('schedule_state', '=', '未排'),('workorder_ids', '=',
|
||||
[])]}
|
||||
</attribute>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
@@ -280,9 +282,11 @@
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//tree//button[@name='button_start']" position="replace">
|
||||
<field name="routing_type" invisible="True"/>
|
||||
<button name="button_start" type="object" string="开始" class="btn-success"
|
||||
attrs="{'invisible': ['|', '|', '|','|', ('production_state','in', ('draft', 'done', 'cancel')), ('working_state', '=', 'blocked'), ('state', 'in', ('done', 'cancel')), ('is_user_working', '!=', False), ('routing_type', '=', 'CNC加工')]}"
|
||||
groups="sf_base.group_sf_mrp_user" confirm="是否确认开始?"/>
|
||||
<button name="button_start" type="object" string="开始" class="btn-success" confirm="是否确认开始?"
|
||||
attrs="{'invisible': ['|', '|', '|','|', ('production_state','in', ('draft', 'done', 'cancel')),
|
||||
('working_state', '=', 'blocked'), ('state', 'in', ('done', 'cancel')), ('is_user_working', '!=',
|
||||
False), ('routing_type', '=', 'CNC加工')]}"
|
||||
groups="sf_base.group_sf_mrp_user"/>
|
||||
</xpath>
|
||||
<xpath expr="//tree//button[@name='button_pending']" position="replace">
|
||||
<button name="button_pending" type="object" string="Pause" class="btn-warning"
|
||||
|
||||
@@ -91,7 +91,7 @@
|
||||
<!-- <field name="target">fullscreen</field>-->
|
||||
<field name="target">current</field>
|
||||
<field name="domain">[('state', '!=', 'cancel'),('schedule_state', '=', '已排')]</field>
|
||||
<field name="context">{'search_default_workcenter_id': active_id}</field>
|
||||
<field name="context">{'search_default_product': 1, 'search_default_workcenter_id': active_id}</field>
|
||||
<field name="help" type="html">
|
||||
<p class="o_view_nocontent_workorder">
|
||||
没有工单要做!
|
||||
@@ -124,7 +124,7 @@
|
||||
<field name='user_permissions' invisible="1"/>
|
||||
<field name='name' invisible="1"/>
|
||||
<field name='is_delivery' invisible="1"/>
|
||||
<field name='is_send_program_again' invisible="1"/>
|
||||
<!-- <field name='is_send_program_again' invisible="1"/>-->
|
||||
<!-- 工单form页面的开始停工按钮等 -->
|
||||
<!-- <button name="button_start" type="object" string="开始" class="btn-success" -->
|
||||
<!-- attrs="{'invisible': ['|', '|', ('production_state', 'not in', ('pending_processing', 'pending_cam', 'pending_era_cam')), ('state','!=','ready'), ('routing_type', 'not in', ('装夹预调', 'CNC加工', '解除装夹'))]}" -->
|
||||
@@ -136,7 +136,7 @@
|
||||
<!-- attrs="{'invisible': ['|', '|', ('production_state', 'not in', ('pending_processing', 'pending_cam', 'pending_era_cam')), ('state','!=','progress'), ('routing_type', 'not in', ('装夹预调', 'CNC加工', '解除装夹'))]}" -->
|
||||
<!-- groups="sf_base.group_sf_mrp_user" confirm="是否确认完工"/> -->
|
||||
|
||||
<button name="button_start" type="object" string="开始" class="btn-success"
|
||||
<button name="button_start" type="object" string="开始" class="btn-success" confirm="是否确认开始"
|
||||
attrs="{'invisible': ['|', '|', '|', ('production_state','in', ('draft', 'done', 'cancel')), ('working_state', '=', 'blocked'), ('state', 'in', ('done', 'cancel')), ('is_user_working', '!=', False)]}"/>
|
||||
<button name="button_pending" type="object" string="暂停" class="btn-warning"
|
||||
attrs="{'invisible': ['|', '|', ('production_state', 'in', ('draft', 'done', 'cancel')), ('working_state', '=', 'blocked'), ('is_user_working', '=', False)]}"/>
|
||||
@@ -160,11 +160,11 @@
|
||||
<!-- attrs="{'invisible': ['|', '|', ('production_state', 'in', ('draft', 'done', 'cancel')), ('working_state', '!=', 'blocked'),('state','=','done')]}"/> -->
|
||||
<button name="button_workpiece_delivery" type="object" string="工件配送" class="btn-primary"
|
||||
attrs="{'invisible': ['|','|',('routing_type','!=','装夹预调'),('is_delivery','=',True),('state','!=','done')]}"/>
|
||||
<button name="button_send_program_again" type="object" string="重新下发NC程序" class="btn-primary"
|
||||
confirm="是否确认重新下发NC程序?"
|
||||
groups="sf_base.group_sf_order_user,sf_base.group_sf_equipment_user"
|
||||
attrs="{'invisible': ['|', '|', '|',('routing_type','!=','装夹预调'),('state','in',['done', 'cancel',
|
||||
'progress']),('cnc_worksheet','=',False),('is_send_program_again','=',True)]}"/>
|
||||
<!-- <button name="button_send_program_again" type="object" string="重新下发NC程序" class="btn-primary"-->
|
||||
<!-- confirm="是否确认重新下发NC程序?"-->
|
||||
<!-- groups="sf_base.group_sf_order_user,sf_base.group_sf_equipment_user"-->
|
||||
<!-- attrs="{'invisible': ['|', '|', '|',('routing_type','!=','装夹预调'),('state','in',['done', 'cancel',-->
|
||||
<!-- 'progress']),('cnc_worksheet','=',False),('is_send_program_again','=',True)]}"/>-->
|
||||
</xpath>
|
||||
<xpath expr="//page[1]" position="before">
|
||||
<page string="开料要求" attrs='{"invisible": [("routing_type","!=","切割")]}'>
|
||||
@@ -183,8 +183,11 @@
|
||||
</page>
|
||||
</xpath>
|
||||
<xpath expr="//label[1]" position="before">
|
||||
<field name='routing_type'/>
|
||||
<field name='routing_type' readonly="1"/>
|
||||
<field name='process_state' attrs='{"invisible": [("routing_type","!=","装夹预调")]}'/>
|
||||
<field name="rfid_code" force_save="1" readonly="1" cache="True"
|
||||
attrs="{'invisible': [('rfid_code_old', '!=', False)]}"/>
|
||||
<field name="rfid_code_old" readonly="1" attrs="{'invisible': [('rfid_code_old', '=', False)]}"/>
|
||||
</xpath>
|
||||
<xpath expr="//label[1]" position="attributes">
|
||||
<attribute name="string">计划加工时间</attribute>
|
||||
@@ -227,9 +230,6 @@
|
||||
<!-- attrs='{"invisible": [("routing_type","!=","装夹预调")]}'/> -->
|
||||
<!-- <field name="functional_fixture_type_id" -->
|
||||
<!-- attrs='{"invisible": [("routing_type","!=","装夹预调")]}'/> -->
|
||||
<field name="rfid_code" force_save="1" readonly="1" cache="True"
|
||||
attrs="{'invisible': [('rfid_code_old', '!=', False)]}"/>
|
||||
<field name="rfid_code_old" readonly="1" attrs="{'invisible': [('rfid_code_old', '=', False)]}"/>
|
||||
</group>
|
||||
<!-- <group>-->
|
||||
<!-- <div>-->
|
||||
@@ -242,23 +242,6 @@
|
||||
<!-- <field name="processing_panel" readonly="1" attrs="{'invisible': [('routing_type', 'in', ('获取CNC加工程序','装夹','解除装夹',-->
|
||||
<!-- '前置三元定位检测','后置三元质量检测','解除装夹'))]}"/>-->
|
||||
</field>
|
||||
|
||||
<xpath expr="//page[1]" position="before">
|
||||
<page string="获取CNC加工程序" attrs='{"invisible": [("routing_type","!=","获取CNC加工程序")]}'>
|
||||
<group>
|
||||
<field name="programming_no" readonly="1"
|
||||
attrs='{"invisible": [("programming_no","=",False)]}'/>
|
||||
<field name="programming_state" readonly="1"
|
||||
attrs='{"invisible": [("programming_no","=",False)]}'/>
|
||||
</group>
|
||||
<!-- <group>-->
|
||||
<!-- <div class="col-12 col-lg-6 o_setting_box" style="white-space: nowrap">-->
|
||||
<!-- <button type="object" class="oe_highlight" name="fetchCNC" string="获取CNC程序代码"-->
|
||||
<!-- />-->
|
||||
<!-- </div>-->
|
||||
<!-- </group>-->
|
||||
</page>
|
||||
</xpath>
|
||||
<!-- <page string="Components" name="components">-->
|
||||
<xpath expr="//page[1]" position="before">
|
||||
<!-- <page string="装夹托盘" attrs='{"invisible": [("routing_type","!=","装夹")]}'>-->
|
||||
@@ -483,7 +466,10 @@
|
||||
<field name="production_line_id" readonly="1"/>
|
||||
<field name="task_delivery_time" readonly="1"/>
|
||||
<field name="task_completion_time" readonly="1"/>
|
||||
<field name="status" readonly="1"/>
|
||||
<field name="status" readonly="1" widget="badge"
|
||||
decoration-success="status == '已配送'"
|
||||
decoration-warning="status == '待下发'"
|
||||
decoration-danger="status == '待配送'"/>
|
||||
</tree>
|
||||
</field>
|
||||
</page>
|
||||
@@ -575,9 +561,6 @@
|
||||
</div>
|
||||
</xpath>
|
||||
<xpath expr="//form//sheet//group//group//div[3]" position="after">
|
||||
<field name="is_ok" attrs='{"invisible": [("routing_type","=","装夹预调")]}'/>
|
||||
<field name="processing_user_id" attrs='{"invisible": [("routing_type","=","装夹预调")]}'/>
|
||||
<field name="inspection_user_id" attrs='{"invisible": [("routing_type","=","装夹预调")]}'/>
|
||||
<field name="save_name" widget="CopyClipboardChar"
|
||||
attrs="{'invisible':[('routing_type','!=','装夹预调')]}"/>
|
||||
<label for="material_length" string="物料尺寸"/>
|
||||
@@ -592,9 +575,6 @@
|
||||
<field name="material_height" class="o_address_zip"/>
|
||||
</div>
|
||||
<field name="part_number" string="成品的零件图号"/>
|
||||
<field name="rfid_code" force_save="1" readonly="1" cache="True"
|
||||
attrs="{'invisible': [('rfid_code_old', '!=', False)]}"/>
|
||||
<field name="rfid_code_old" readonly="1" attrs="{'invisible': [('rfid_code_old', '=', False)]}"/>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
@@ -729,7 +709,7 @@
|
||||
</search>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
、
|
||||
<record id="sf_workpiece_delivery_act" model="ir.actions.act_window">
|
||||
<field name="name">工件配送</field>
|
||||
<field name="res_model">sf.workpiece.delivery</field>
|
||||
|
||||
@@ -28,61 +28,85 @@ class Sf_Mrs_Connect(http.Controller):
|
||||
request.env.ref("base.user_admin")).search(
|
||||
[('programming_no', '=', ret['programming_no'])])
|
||||
if productions:
|
||||
# 拉取所有加工面的程序文件
|
||||
# # 拉取所有加工面的程序文件
|
||||
for r in ret['processing_panel'].split(','):
|
||||
program_path_tmp_r = os.path.join('/tmp', ret['folder_name'], 'return', r)
|
||||
files_r = os.listdir(program_path_tmp_r)
|
||||
if files_r:
|
||||
for file_name in files_r:
|
||||
file_path = os.path.join(program_path_tmp_r, file_name)
|
||||
os.remove(file_path)
|
||||
download_state = request.env['sf.cnc.processing'].with_user(
|
||||
request.env.ref("base.user_admin")).download_file_tmp(
|
||||
ret['folder_name'], r)
|
||||
if download_state == 0:
|
||||
res['status'] = -2
|
||||
res['message'] = '制造订单号为%s的CNC程序文件从FTP拉取失败' % (cnc_production.name)
|
||||
return json.JSONEncoder().encode(res)
|
||||
if os.path.exists(program_path_tmp_r):
|
||||
files_r = os.listdir(program_path_tmp_r)
|
||||
if files_r:
|
||||
for file_name in files_r:
|
||||
file_path = os.path.join(program_path_tmp_r, file_name)
|
||||
os.remove(file_path)
|
||||
download_state = request.env['sf.cnc.processing'].with_user(
|
||||
request.env.ref("base.user_admin")).download_file_tmp(
|
||||
ret['folder_name'], r)
|
||||
if download_state is False:
|
||||
res['status'] = -2
|
||||
res['message'] = '编程单号为%s的CNC程序文件从FTP拉取失败' % (ret['programming_no'])
|
||||
return json.JSONEncoder().encode(res)
|
||||
for production in productions:
|
||||
if not production.workorder_ids:
|
||||
production.product_id.model_processing_panel = ret['processing_panel']
|
||||
production._create_workorder(ret)
|
||||
else:
|
||||
for panel in ret['processing_panel'].split(','):
|
||||
# 查询状态为进行中且工序类型为CNC加工的工单
|
||||
cnc_workorder = production.workorder_ids.filtered(
|
||||
lambda ac: ac.routing_type == 'CNC加工' and ac.state not in ['progress', 'done',
|
||||
'cancel'] and ac.processing_panel == panel)
|
||||
if cnc_workorder:
|
||||
if cnc_workorder.cnc_ids:
|
||||
cnc_workorder.cmm_ids.sudo().unlink()
|
||||
cnc_workorder.cnc_ids.sudo().unlink()
|
||||
request.env['sf.cam.work.order.program.knife.plan'].sudo().unlink_cam_plan(
|
||||
production)
|
||||
# program_path_tmp_panel = os.path.join('C://Users//43484//Desktop//fsdownload//test',
|
||||
# panel)
|
||||
program_path_tmp_panel = os.path.join('/tmp', ret['folder_name'], 'return', panel)
|
||||
logging.info('program_path_tmp_panel:%s' % program_path_tmp_panel)
|
||||
files_panel = os.listdir(program_path_tmp_panel)
|
||||
if files_panel:
|
||||
for file in files_panel:
|
||||
file_extension = os.path.splitext(file)[1]
|
||||
logging.info('file_extension:%s' % file_extension)
|
||||
if file_extension.lower() == '.pdf':
|
||||
panel_file_path = os.path.join(program_path_tmp_panel, file)
|
||||
logging.info('panel_file_path:%s' % panel_file_path)
|
||||
cnc_workorder.write(
|
||||
{'is_send_program_again': False,
|
||||
'cnc_ids': cnc_workorder.cnc_ids.sudo()._json_cnc_processing(panel, ret),
|
||||
'cmm_ids': cnc_workorder.cmm_ids.sudo()._json_cmm_program(panel, ret),
|
||||
'cnc_worksheet': base64.b64encode(open(panel_file_path, 'rb').read())})
|
||||
pre_workorder = production.workorder_ids.filtered(
|
||||
lambda ap: ap.routing_type == '装夹预调' and ap.state not in ['done',
|
||||
'cancel'] and ap.processing_panel == panel)
|
||||
if pre_workorder:
|
||||
pre_workorder.write(
|
||||
{'is_send_program_again': False,
|
||||
'processing_drawing': base64.b64encode(open(panel_file_path, 'rb').read())})
|
||||
# else:
|
||||
# for panel in ret['processing_panel'].split(','):
|
||||
# # 查询状态为进行中且工序类型为CNC加工的工单
|
||||
# cnc_workorder = production.workorder_ids.filtered(
|
||||
# lambda ac: ac.routing_type == 'CNC加工' and ac.state not in ['progress', 'done',
|
||||
# 'cancel'] and ac.processing_panel == panel)
|
||||
# if cnc_workorder:
|
||||
# if cnc_workorder.cnc_ids:
|
||||
# cnc_workorder.cmm_ids.sudo().unlink()
|
||||
# cnc_workorder.cnc_ids.sudo().unlink()
|
||||
# request.env['sf.cam.work.order.program.knife.plan'].sudo().unlink_cam_plan(
|
||||
# production)
|
||||
# # program_path_tmp_panel = os.path.join('C://Users//43484//Desktop//fsdownload//test',
|
||||
# # panel)
|
||||
# program_path_tmp_panel = os.path.join('/tmp', ret['folder_name'], 'return', panel)
|
||||
# logging.info('program_path_tmp_panel:%s' % program_path_tmp_panel)
|
||||
# files_panel = os.listdir(program_path_tmp_panel)
|
||||
# if files_panel:
|
||||
# for file in files_panel:
|
||||
# file_extension = os.path.splitext(file)[1]
|
||||
# logging.info('file_extension:%s' % file_extension)
|
||||
# if file_extension.lower() == '.pdf':
|
||||
# panel_file_path = os.path.join(program_path_tmp_panel, file)
|
||||
# logging.info('panel_file_path:%s' % panel_file_path)
|
||||
# cnc_workorder.write(
|
||||
# {'cnc_ids': cnc_workorder.cnc_ids.sudo()._json_cnc_processing(panel, ret),
|
||||
# 'cmm_ids': cnc_workorder.cmm_ids.sudo()._json_cmm_program(panel, ret),
|
||||
# 'cnc_worksheet': base64.b64encode(open(panel_file_path, 'rb').read())})
|
||||
# pre_workorder = production.workorder_ids.filtered(
|
||||
# lambda ap: ap.routing_type == '装夹预调' and ap.state not in ['done',
|
||||
# 'cancel'] and ap.processing_panel == panel)
|
||||
# if pre_workorder:
|
||||
# pre_workorder.write(
|
||||
# {'processing_drawing': base64.b64encode(open(panel_file_path, 'rb').read())})
|
||||
for panel in ret['processing_panel'].split(','):
|
||||
# 查询状态为进行中且工序类型为CNC加工的工单
|
||||
cnc_workorder = productions.workorder_ids.filtered(
|
||||
lambda ac: ac.routing_type == 'CNC加工' and ac.state not in ['progress', 'done',
|
||||
'cancel'] and ac.processing_panel == panel)
|
||||
if cnc_workorder:
|
||||
# program_path_tmp_panel = os.path.join('C://Users//43484//Desktop//fsdownload//test',
|
||||
# panel)
|
||||
program_path_tmp_panel = os.path.join('/tmp', ret['folder_name'], 'return', panel)
|
||||
logging.info('program_path_tmp_panel:%s' % program_path_tmp_panel)
|
||||
files_panel = os.listdir(program_path_tmp_panel)
|
||||
if files_panel:
|
||||
for file in files_panel:
|
||||
file_extension = os.path.splitext(file)[1]
|
||||
logging.info('file_extension:%s' % file_extension)
|
||||
if file_extension.lower() == '.pdf':
|
||||
panel_file_path = os.path.join(program_path_tmp_panel, file)
|
||||
logging.info('panel_file_path:%s' % panel_file_path)
|
||||
cnc_workorder.write({'cnc_worksheet': base64.b64encode(open(panel_file_path, 'rb').read())})
|
||||
pre_workorder = productions.workorder_ids.filtered(
|
||||
lambda ap: ap.routing_type == '装夹预调' and ap.state not in ['done',
|
||||
'cancel'] and ap.processing_panel == panel)
|
||||
if pre_workorder:
|
||||
pre_workorder.write(
|
||||
{'processing_drawing': base64.b64encode(open(panel_file_path, 'rb').read())})
|
||||
productions.write({'programming_state': '已编程', 'work_state': '已编程'})
|
||||
cnc_program_ids = [item.id for item in productions]
|
||||
workpiece_delivery = request.env['sf.workpiece.delivery'].sudo().search(
|
||||
|
||||
@@ -21,6 +21,23 @@ class FtpController():
|
||||
except Exception:
|
||||
logging.info("ftp连接失败")
|
||||
|
||||
def file_exists_1(self, path):
|
||||
# 检查文件是否存在于FTP服务器上
|
||||
try:
|
||||
logging.info("path:%s" % path)
|
||||
logging.info("dirname:%s" % os.path.dirname(path))
|
||||
directories = os.path.normpath(path).split(os.path.sep)
|
||||
# 切换到上级目录
|
||||
for directory in directories:
|
||||
if directory:
|
||||
# 检查目录是否存在
|
||||
if (directory in ['NC']) or (directory not in ['home', 'ftp', 'ftp_root', 'NC']):
|
||||
self.ftp.cwd(directory)
|
||||
return os.path.basename(path)
|
||||
except Exception as e:
|
||||
logging.error(f"Error checking file: {e}")
|
||||
return False
|
||||
|
||||
def file_exists(self, path):
|
||||
# 检查文件是否存在于FTP服务器上
|
||||
try:
|
||||
@@ -32,8 +49,25 @@ class FtpController():
|
||||
logging.error(f"Error checking file: {e}")
|
||||
return False
|
||||
|
||||
|
||||
|
||||
# 下载目录下的pdf文件(程序单)
|
||||
def download_program_file(self, target_dir, serverdir):
|
||||
if not os.path.exists(serverdir):
|
||||
os.makedirs(serverdir)
|
||||
try:
|
||||
logging.info('FTP目录:%s' % target_dir)
|
||||
logging.info("进入FTP目录 ")
|
||||
remotenames = self.ftp.nlst()
|
||||
logging.info('FTP目录文件:%s' % remotenames)
|
||||
for file in remotenames:
|
||||
server = os.path.join(serverdir, file)
|
||||
if file.find(".pdf") != -1:
|
||||
self.download_file(server, file)
|
||||
return True
|
||||
except:
|
||||
return False
|
||||
finally:
|
||||
self.ftp.quit()
|
||||
logging.info("ftp已关闭")
|
||||
|
||||
# # 检测字符串的编码
|
||||
# def detect_encoding(self, s):
|
||||
|
||||
@@ -37,7 +37,7 @@ class sf_production_plan(models.Model):
|
||||
_order = 'state_order asc, write_date desc'
|
||||
|
||||
name = fields.Char(string='制造订单')
|
||||
active = fields.Boolean(string='已归档', default=True)
|
||||
# active = fields.Boolean(string='已归档', default=True)
|
||||
# selected = fields.Boolean(default=False)
|
||||
# order_number = fields.Char(string='订单号')
|
||||
order_deadline = fields.Datetime(string='订单交期')
|
||||
@@ -101,17 +101,17 @@ class sf_production_plan(models.Model):
|
||||
# return super(sf_production_plan, self.with_context(active_test=False))._search(
|
||||
# args, offset, limit, order, count, access_rights_uid)
|
||||
|
||||
def archive(self):
|
||||
"""
|
||||
归档
|
||||
"""
|
||||
self.write({'active': False})
|
||||
|
||||
def unarchive(self):
|
||||
"""
|
||||
取消归档
|
||||
"""
|
||||
self.write({'active': True})
|
||||
# def archive(self):
|
||||
# """
|
||||
# 归档
|
||||
# """
|
||||
# self.write({'active': False})
|
||||
#
|
||||
# def unarchive(self):
|
||||
# """
|
||||
# 取消归档
|
||||
# """
|
||||
# self.write({'active': True})
|
||||
|
||||
@api.model
|
||||
def get_import_templates(self):
|
||||
|
||||
@@ -63,7 +63,7 @@
|
||||
</div>
|
||||
<group>
|
||||
<group string="基本信息">
|
||||
<field name="active" invisible="1"/>
|
||||
<!-- <field name="active" invisible="1"/> -->
|
||||
<field name="production_id" widget="many2one_button"/>
|
||||
<field name="product_id"/>
|
||||
<field name="origin"/>
|
||||
@@ -217,11 +217,11 @@
|
||||
</li>
|
||||
<li>
|
||||
<strong>订单交期:</strong>
|
||||
<t t-out="order_deadline"/>
|
||||
<t t-out="order_deadline.format('L LTS')"/>
|
||||
</li>
|
||||
<li>
|
||||
<strong>产品名称:</strong>
|
||||
<t t-out="product_id"/>
|
||||
<t t-out="product_id[1]"/>
|
||||
</li>
|
||||
<li>
|
||||
<strong>数量:</strong>
|
||||
@@ -268,7 +268,8 @@
|
||||
<field name="type">ir.actions.act_window</field>
|
||||
<field name="res_model">sf.production.plan</field>
|
||||
<field name="view_mode">tree,gantt,form</field>
|
||||
<field name="context">{'search_default_group_by_state': 1, 'search_default_draft': 1, 'display_complete': True}</field>
|
||||
<!-- <field name="context">{'search_default_group_by_state': 1, 'search_default_draft': 1, 'display_complete': True}</field> -->
|
||||
<field name="context">{'search_default_draft': 1, 'display_complete': True}</field>
|
||||
</record>
|
||||
|
||||
<menuitem
|
||||
|
||||
@@ -114488,10 +114488,21 @@ msgid "径跳精度(mm)"
|
||||
msgstr ""
|
||||
|
||||
#. module: sf_manufacturing
|
||||
#: model:ir.model.fields.selection,name:sf_manufacturing.selection__mrp_production__state__progress
|
||||
#: model:ir.model.fields.selection,name:sf_manufacturing.selection__mrp_production__state__draft
|
||||
msgid "待排程"
|
||||
msgstr "待排程"
|
||||
|
||||
#. module: sf_manufacturing
|
||||
#: model:ir.model.fields.selection,name:sf_manufacturing.selection__mrp_production__process_state__待加工
|
||||
#: model:ir.model.fields.selection,name:sf_manufacturing.selection__mrp_production__state__confirmed
|
||||
msgid "待加工"
|
||||
msgstr "待加工"
|
||||
|
||||
#. module: sf_manufacturing
|
||||
#: model:ir.model.fields.selection,name:sf_manufacturing.selection__mrp_production__state__progress
|
||||
msgid "待排程"
|
||||
msgstr "加工中"
|
||||
|
||||
#. module: sf_base
|
||||
#: model:ir.model.fields,field_description:sf_base.field_sf_cutting_tool_model__jump_accuracy
|
||||
msgid "径跳精度(um)"
|
||||
|
||||
@@ -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)
|
||||
@@ -622,6 +624,11 @@ class SfStockMoveLine(models.Model):
|
||||
if not qr_code_data:
|
||||
raise UserError("没有找到二维码数据。")
|
||||
lot_name = self.lot_name
|
||||
|
||||
# 增加"当为坯料时,只打印序列号的前面部分"
|
||||
if self.lot_name: # 确保 lot_name 存在
|
||||
if self.product_id.categ_id.name == '坯料':
|
||||
lot_name = lot_name.split('[', 1)[0]
|
||||
# host = "192.168.50.110" # 可以根据实际情况修改
|
||||
# port = 9100 # 可以根据实际情况修改
|
||||
|
||||
@@ -851,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(
|
||||
@@ -864,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:
|
||||
@@ -975,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:
|
||||
@@ -1110,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:
|
||||
@@ -1121,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:
|
||||
@@ -1130,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:
|
||||
@@ -1184,6 +1209,12 @@ class CustomStockMove(models.Model):
|
||||
# todo 待控制
|
||||
if not lot_name:
|
||||
raise ValidationError("请先分配序列号")
|
||||
|
||||
# 增加"当为坯料时,只打印序列号的前面部分"
|
||||
if record.lot_name: # 确保 lot_name 存在
|
||||
if record.product_id.categ_id.name == '坯料':
|
||||
lot_name = lot_name.split('[', 1)[0]
|
||||
|
||||
# host = "192.168.50.110" # 可以根据实际情况修改
|
||||
# port = 9100 # 可以根据实际情况修改
|
||||
|
||||
|
||||
@@ -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