Merge branch 'refs/heads/develop' into feature/tax_sync

This commit is contained in:
liaodanlong
2024-09-02 15:43:25 +08:00
15 changed files with 239 additions and 259 deletions

View File

@@ -477,7 +477,7 @@ class Manufacturing_Connect(http.Controller):
logging.info('LocationChange error:%s' % e)
return json.JSONEncoder().encode(res)
@http.route('/AutoDeviceApi/AGVToProduct', type='json', auth='none', methods=['GET', 'POST'], csrf=False,
@http.route('/AutoDeviceApi/AGVToProduct', type='json', auth='sf_token', methods=['GET', 'POST'], csrf=False,
cors="*")
def AGVToProduct(self, **kw):
"""
@@ -549,7 +549,7 @@ class Manufacturing_Connect(http.Controller):
logging.info('AGVToProduct error:%s' % e)
return json.JSONEncoder().encode(res)
@http.route('/AutoDeviceApi/AGVDownProduct', type='json', auth='none', methods=['GET', 'POST'], csrf=False,
@http.route('/AutoDeviceApi/AGVDownProduct', type='json', auth='sf_token', methods=['GET', 'POST'], csrf=False,
cors="*")
def AGVDownProduct(self, **kw):
"""
@@ -668,7 +668,7 @@ class Manufacturing_Connect(http.Controller):
logging.info('AGVDownProduct error:%s' % e)
return json.JSONEncoder().encode(res)
@http.route('/AutoDeviceApi/AgvStationState', type='json', auth='none', methods=['GET', 'POST'], csrf=False,
@http.route('/AutoDeviceApi/AgvStationState', type='json', auth='sf_token', methods=['GET', 'POST'], csrf=False,
cors="*")
def AGVStationState(self, **kw):
"""

View File

@@ -664,7 +664,7 @@ class MrpProduction(models.Model):
# 表面工艺工序
# 模型类型的表面工艺工序模版
surface_tmpl_ids = model_type_id.surface_technics_routing_tmpl_ids
# 产品选择的表面工艺
# 产品选择的表面工艺参数
model_process_parameters_ids = rec.product_id.model_process_parameters_ids
process_dict = {}
if model_process_parameters_ids:
@@ -673,7 +673,7 @@ class MrpProduction(models.Model):
for surface_tmpl_id in surface_tmpl_ids:
if process_id == surface_tmpl_id.route_workcenter_id.surface_technics_id:
surface_tmpl_name = surface_tmpl_id.route_workcenter_id.name
process_dict.update({int(process_id.category_id.code): '%s-%s' % (
process_dict.update({int(process_id.sequence): '%s-%s' % (
surface_tmpl_name, process_parameters_id.name)})
process_list = sorted(process_dict.keys())
for process_num in process_list:
@@ -690,14 +690,16 @@ class MrpProduction(models.Model):
raise ValidationError('该产品【加工面板】为空!')
else:
raise ValidationError('该产品没有选择【模版类型】!')
logging.info('sequence_list: %s' % sequence_list)
for work in rec.workorder_ids:
if sequence_list.get(work.name):
work.sequence = sequence_list[work.name]
work_name = work.name
logging.info(work_name)
if sequence_list.get(work_name):
work.sequence = sequence_list[work_name]
elif sequence_list.get(work.processing_panel):
processing_panel = sequence_list.get(work.processing_panel)
if processing_panel.get(work.name):
work.sequence = processing_panel[work.name]
if processing_panel.get(work_name):
work.sequence = processing_panel[work_name]
else:
raise ValidationError('工序【%s】在产品选择的模版类型中不存在!' % work.name)
else:
@@ -723,8 +725,9 @@ class MrpProduction(models.Model):
sequence_max += 1
panel_sequence_list.update({tmpl_id.route_workcenter_id.name: sequence_max})
for work_id in work_ids:
if panel_sequence_list.get(work_id.name):
work_id.sequence = panel_sequence_list[work_id.name]
work_name = work_id.name
if panel_sequence_list.get(work_name):
work_id.sequence = panel_sequence_list[work_name]
# 创建工单并进行排序
def _create_workorder(self, item):
@@ -1031,8 +1034,8 @@ class MrpProduction(models.Model):
[('origin', '=', sale_order.name), ('name', 'ilike', 'WH/OUT/')])
move = out_picking.move_ids.filtered(lambda pd: pd.product_id == self.product_id)
move_values = {'product_description_variants': '',
'date_planned': datetime.now(),
'date_deadline': datetime.now(),
'date_planned': fields.Datetime.now(),
'date_deadline': fields.Datetime.now(),
'move_dest_ids': move,
'group_id': move.group_id,
'route_ids': [],
@@ -1101,67 +1104,19 @@ class MrpProduction(models.Model):
('is_subcontract', '=', True)])
if scarp_process_parameter_workorder:
production_programming = self.env['mrp.production'].search(
[('programming_no', '=', self.programming_no)], order='name asc')
[('programming_no', '=', self.programming_no), ('id', '!=', productions.id)], order='name asc')
production_list = [production.name for production in production_programming]
purchase_orders = self.env['purchase.order'].search([('origin', '=', ','.join(production_list))])
purchase_orders = self.env['purchase.order'].search([('origin', 'ilike', ','.join(production_list))])
for purchase_item in purchase_orders.order_line:
for process_item in scarp_process_parameter_workorder:
if purchase_item.product_id.categ_type == '表面工艺':
if purchase_item.product_id.server_product_process_parameters_id == process_item.surface_technics_parameters_id:
print(purchase_orders.find(productions.name))
if purchase_orders.find(productions.name) == -1:
purchase_orders.origin += productions.name
print(purchase_orders.origin.find(productions.name))
if purchase_orders.origin.find(productions.name) == -1:
purchase_orders.origin += ',' + productions.name
if item['is_reprogramming'] is False:
productions._create_workorder(item)
productions.programming_state = '已编程'
for production_item in productions:
process_parameter_workorder = self.env['mrp.workorder'].search(
[('surface_technics_parameters_id', '!=', False), ('production_id', '=', production_item.id),
('is_subcontract', '=', True)])
if process_parameter_workorder:
is_pick = False
consecutive_workorders = []
m = 0
sorted_workorders = sorted(process_parameter_workorder, key=lambda w: w.id)
for i in range(len(sorted_workorders) - 1):
if m == 0:
is_pick = False
if sorted_workorders[i].supplier_id.id == sorted_workorders[i + 1].supplier_id.id and \
sorted_workorders[i].is_subcontract == sorted_workorders[i + 1].is_subcontract and \
sorted_workorders[i].id == sorted_workorders[i + 1].id - 1:
if sorted_workorders[i] not in consecutive_workorders:
consecutive_workorders.append(sorted_workorders[i])
consecutive_workorders.append(sorted_workorders[i + 1])
m += 1
continue
else:
if m == len(consecutive_workorders) - 1 and m != 0:
self.env['stock.picking'].create_outcontract_picking(consecutive_workorders,
production_item)
if sorted_workorders[i] in consecutive_workorders:
is_pick = True
consecutive_workorders = []
m = 0
# 当前面的连续工序生成对应的外协出入库单再生成当前工序的外协出入库单
if is_pick is False:
self.env['stock.picking'].create_outcontract_picking(sorted_workorders[i],
production_item)
if m == len(consecutive_workorders) - 1 and m != 0:
self.env['stock.picking'].create_outcontract_picking(consecutive_workorders,
production_item)
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)
if is_pick is False and m == 0:
if len(sorted_workorders) == 1:
self.env['stock.picking'].create_outcontract_picking(sorted_workorders, production_item)
else:
self.env['stock.picking'].create_outcontract_picking(sorted_workorders[i],
production_item)
else:
productions.programming_state = '编程中'
return productions

View File

@@ -58,6 +58,7 @@ class ResMrpWorkOrder(models.Model):
('cancel', '取消')], string='Status',
compute='_compute_state', store=True,
default='pending', copy=False, readonly=True, recursive=True, index=True, tracking=True)
# state = fields.Selection(selection_add=[('to be detected', "待检测"), ('rework', '返工')], tracking=True)
@api.depends('production_id.manual_quotation')
@@ -183,17 +184,12 @@ class ResMrpWorkOrder(models.Model):
if order.routing_type == '表面工艺':
production_programming = self.env['mrp.production'].search(
[('programming_no', '=', order.production_id.programming_no)], order='name asc')
production_no_remanufacture = production_programming.filtered(lambda a: a.is_remanufacture is False)
production_list = [production.name for production in production_programming]
purchase = self.env['purchase.order'].search([('origin', '=', ','.join(production_list))])
for line in purchase.order_line:
if line.product_id.server_product_process_parameters_id == order.surface_technics_parameters_id and line.product_qty == len(
production_programming):
# server_product = self.env['product.template'].search(
# [('server_product_process_parameters_id', '=', pp.id),
# ('detailed_type', '=', 'service')])
# purchase_order_line = self.env['purchase.order.line'].search(
# [('product_id', '=', server_product.id), ('product_qty', '=', len(production_programming))])
# if purchase_order_line:
production_no_remanufacture):
order.surface_technics_purchase_count = len(purchase)
else:
order.surface_technics_purchase_count = 0
@@ -243,6 +239,7 @@ class ResMrpWorkOrder(models.Model):
store=True, compute='_compute_tool_state')
tool_state_remark = fields.Text(string='功能刀具状态备注(缺刀)', compute='_compute_tool_state_remark', store=True)
reserved_duration = fields.Float('预留时长', default=30, tracking=True)
@api.depends('cnc_ids.tool_state')
def _compute_tool_state_remark(self):
for item in self:
@@ -651,7 +648,7 @@ class ResMrpWorkOrder(models.Model):
# 拼接工单对象属性值
def json_workorder_str(self, k, production, route, item):
# 计算预计时长duration_expected
routing_types = ['切割', '装夹预调', 'CNC加工','解除装夹']
routing_types = ['切割', '装夹预调', 'CNC加工', '解除装夹']
if route.routing_type in routing_types:
routing_workcenter = self.env['mrp.routing.workcenter'].sudo().search(
[('name', '=', route.routing_type)])
@@ -704,7 +701,7 @@ class ResMrpWorkOrder(models.Model):
item),
# 'workpiece_delivery_ids': False if not route.routing_type == '装夹预调' else self._json_workpiece_delivery_list(
# production)
'reserved_duration': reserved_duration,
'reserved_duration': reserved_duration,
}]
return workorders_values_str
@@ -969,12 +966,14 @@ class ResMrpWorkOrder(models.Model):
else:
production_programming = self.env['mrp.production'].search(
[('programming_no', '=', self.production_id.programming_no)], order='name asc')
production_no_remanufacture = production_programming.filtered(
lambda a: a.is_remanufacture is False)
production_list = [production.name for production in production_programming]
purchase_orders = self.env['purchase.order'].search(
[('origin', '=', ','.join(production_list))])
[('origin', 'ilike', ','.join(production_list))])
for line in purchase_orders.order_line:
if line.product_id.server_product_process_parameters_id == workorder.surface_technics_parameters_id and line.product_qty == len(
production_programming):
production_no_remanufacture):
if purchase_orders.state == 'purchase':
workorder.state = 'ready'
else:
@@ -1169,8 +1168,9 @@ class ResMrpWorkOrder(models.Model):
if record.routing_type == '装夹预调':
if not record.rfid_code and record.is_rework is False:
raise UserError("请扫RFID码进行绑定")
if not record.material_center_point or record.X_deviation_angle <= 0:
raise UserError("请对前置三元检测定位参数进行计算定位")
if record.is_rework is False:
if not record.material_center_point and record.X_deviation_angle > 0:
raise UserError("坯料中心点为空或X偏差角度小于等于0")
record.process_state = '待加工'
# record.write({'process_state': '待加工'})
record.production_id.process_state = '待加工'

View File

@@ -288,28 +288,46 @@ class StockRule(models.Model):
# 为同一个product_id创建一个生产订单名称列表
product_id_to_production_names[product_id] = [production.name for production in all_production]
for production_item in productions:
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 production_item.product_id.id in product_id_to_production_names:
if production_item.product_id.model_process_parameters_ids:
is_purchase = False
sorted_process_parameters = sorted(production_item.product_id.model_process_parameters_ids,
key=lambda w: w.id)
if not production_programming.programming_no:
if production_item.product_id.model_process_parameters_ids:
is_purchase = False
sorted_process_parameters = sorted(production_item.product_id.model_process_parameters_ids,
key=lambda w: w.id)
consecutive_process_parameters = []
m = 0
for i in range(len(sorted_process_parameters) - 1):
if m == 0:
is_purchase = False
if self.env['product.template']._get_process_parameters_product(
sorted_process_parameters[i]).partner_id == self.env[
'product.template']._get_process_parameters_product(sorted_process_parameters[
i + 1]).partner_id and \
sorted_process_parameters[i].gain_way == '外协':
if sorted_process_parameters[i] not in consecutive_process_parameters:
consecutive_process_parameters.append(sorted_process_parameters[i])
consecutive_process_parameters.append(sorted_process_parameters[i + 1])
m += 1
continue
else:
consecutive_process_parameters = []
m = 0
for i in range(len(sorted_process_parameters) - 1):
if m == 0:
is_purchase = False
if self.env['product.template']._get_process_parameters_product(
sorted_process_parameters[i]).partner_id == self.env[
'product.template']._get_process_parameters_product(sorted_process_parameters[
i + 1]).partner_id and \
sorted_process_parameters[i].gain_way == '外协':
if sorted_process_parameters[i] not in consecutive_process_parameters:
consecutive_process_parameters.append(sorted_process_parameters[i])
consecutive_process_parameters.append(sorted_process_parameters[i + 1])
m += 1
continue
else:
if m == len(consecutive_process_parameters) - 1 and m != 0:
self.env['purchase.order'].get_purchase_order(consecutive_process_parameters,
production_item,
product_id_to_production_names)
if sorted_process_parameters[i] in consecutive_process_parameters:
is_purchase = True
consecutive_process_parameters = []
m = 0
# 当前面的连续外协采购单生成再生成当前外协采购单
if is_purchase is False:
self.env['purchase.order'].get_purchase_order(consecutive_process_parameters,
production_item,
product_id_to_production_names)
if m == len(consecutive_process_parameters) - 1 and m != 0:
self.env['purchase.order'].get_purchase_order(consecutive_process_parameters,
production_item,
@@ -318,39 +336,22 @@ class StockRule(models.Model):
is_purchase = True
consecutive_process_parameters = []
m = 0
# 当前面的连续外协采购单生成再生成当前外协采购单
if is_purchase is False:
self.env['purchase.order'].get_purchase_order(consecutive_process_parameters,
production_item,
product_id_to_production_names)
if m == len(consecutive_process_parameters) - 1 and m != 0:
self.env['purchase.order'].get_purchase_order(consecutive_process_parameters,
production_item,
product_id_to_production_names)
if sorted_process_parameters[i] in consecutive_process_parameters:
is_purchase = True
consecutive_process_parameters = []
m = 0
if m == len(consecutive_process_parameters) - 1 and m != 0:
self.env['purchase.order'].get_purchase_order(consecutive_process_parameters,
production_item,
product_id_to_production_names)
if is_purchase is False and m == 0:
if len(sorted_process_parameters) == 1:
self.env['purchase.order'].get_purchase_order(sorted_process_parameters,
production_item,
product_id_to_production_names)
else:
self.env['purchase.order'].get_purchase_order(sorted_process_parameters[i],
if m == len(consecutive_process_parameters) - 1 and m != 0:
self.env['purchase.order'].get_purchase_order(consecutive_process_parameters,
production_item,
product_id_to_production_names)
if is_purchase is False and m == 0:
if len(sorted_process_parameters) == 1:
self.env['purchase.order'].get_purchase_order(sorted_process_parameters,
production_item,
product_id_to_production_names)
else:
self.env['purchase.order'].get_purchase_order(sorted_process_parameters[i],
production_item,
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]))
@@ -440,7 +441,7 @@ class ProductionLot(models.Model):
if product.tracking == "serial":
last_serial = self.env['stock.lot'].search(
[('company_id', '=', company.id), ('product_id', '=', product.id)],
limit=1, order='id DESC')
limit=1, order='name desc')
if last_serial:
if product.categ_id.name == '刀具':
return self.env['stock.lot'].get_tool_generate_lot_names1(company, product)
@@ -544,7 +545,7 @@ class StockPicking(models.Model):
# 设置外协出入单的名称
def _get_name_Res(self, rescode):
last_picking = self.sudo().search([('name', 'like', rescode)], order='create_date desc,id desc', limit=1)
last_picking = self.sudo().search([('name', 'ilike', rescode)], order='create_date desc,id desc', limit=1)
if not last_picking:
num = "%04d" % 1
else:

View File

@@ -437,6 +437,12 @@
<xpath expr="//header//button[@name='action_cancel']" position="replace">
<button name="action_cancel" type="object" string="取消" groups="sf_base.group_sf_mrp_user"/>
</xpath>
<xpath expr="//field[@name='state']" position="replace">
<field name="state" decoration-success="state in ('done', 'to_close')"
decoration-warning="state == 'progress'" decoration-info="state == 'confirmed'"
decoration-danger="state in ('cancel','rework','scrap')" decoration-muted="state == 'draft'"
optional="show" widget="badge" class="text-dark"/>
</xpath>
<xpath expr="//field[@name='state']" position="after">
<field name="tool_state" invisible="1"/>
</xpath>

View File

@@ -10,7 +10,7 @@
<field name="name" decoration-success="is_subcontract" decoration-bf="is_subcontract"/>
</field>
<field name="name" position="before">
<field name="sequence"/>
<field name="sequence" string="序号"/>
<field name='user_permissions' invisible="1"/>
</field>
<field name="name" position="after">