Compare commits
27 Commits
release/re
...
feature/仓库
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
00809d88f6 | ||
|
|
18b0cc6ea0 | ||
|
|
54d9902ae4 | ||
|
|
eff39a39e3 | ||
|
|
afc1701150 | ||
|
|
c7b9bbb18d | ||
|
|
3cb3dce247 | ||
|
|
a7e1c89e66 | ||
|
|
ca1060ada5 | ||
|
|
69578ab054 | ||
|
|
511bed47ff | ||
|
|
26a0412649 | ||
|
|
4989ff773c | ||
|
|
04c0d68763 | ||
|
|
589035d42b | ||
|
|
fc1cdf4d0e | ||
|
|
45178ac38b | ||
|
|
09ee1c26b1 | ||
|
|
0c052a118c | ||
|
|
0ca6d46a7b | ||
|
|
f07a003f2c | ||
|
|
0ef46407dd | ||
|
|
f7f3c005f8 | ||
|
|
cae5e14587 | ||
|
|
9a5aa52801 | ||
|
|
1e172cb4e3 | ||
|
|
d187bb2bba |
@@ -12,7 +12,6 @@
|
|||||||
</tree>
|
</tree>
|
||||||
</field>
|
</field>
|
||||||
</record>
|
</record>
|
||||||
|
|
||||||
<record model="ir.ui.view" id="mrs_production_process_parameter_form">
|
<record model="ir.ui.view" id="mrs_production_process_parameter_form">
|
||||||
<field name="model">sf.production.process.parameter</field>
|
<field name="model">sf.production.process.parameter</field>
|
||||||
<field name="arch" type="xml">
|
<field name="arch" type="xml">
|
||||||
@@ -26,19 +25,19 @@
|
|||||||
<group>
|
<group>
|
||||||
<group>
|
<group>
|
||||||
<field name="code" readonly="1"/>
|
<field name="code" readonly="1"/>
|
||||||
<field name="process_id" readonly="1"/>
|
<field name="process_id" attrs="{'readonly': [('code', '!=', False)]}"/>
|
||||||
<field name="process_description" readonly="1"/>
|
<field name="process_description" attrs="{'readonly': [('code', '!=', False)]}"/>
|
||||||
<field name="gain_way"/>
|
<field name="gain_way"/>
|
||||||
</group>
|
</group>
|
||||||
<group>
|
<group>
|
||||||
<field name="processing_day" readonly="1"/>
|
<field name="processing_day" attrs="{'readonly': [('code', '!=', False)]}"/>
|
||||||
<field name="travel_day" readonly="1"/>
|
<field name="travel_day" attrs="{'readonly': [('code', '!=', False)]}"/>
|
||||||
<field name="processing_mm" readonly="1"/>
|
<field name="processing_mm" attrs="{'readonly': [('code', '!=', False)]}"/>
|
||||||
</group>
|
</group>
|
||||||
</group>
|
</group>
|
||||||
<notebook>
|
<notebook>
|
||||||
<page string="适用材料">
|
<page string="适用材料">
|
||||||
<field name="materials_model_ids" readonly="1"></field>
|
<field name="materials_model_ids" attrs="{'readonly': [('code', '!=', False)]}"></field>
|
||||||
</page>
|
</page>
|
||||||
</notebook>
|
</notebook>
|
||||||
</sheet>
|
</sheet>
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ class StatusChange(models.Model):
|
|||||||
if not ret.get('error'):
|
if not ret.get('error'):
|
||||||
logging.info('接口已经执行=============')
|
logging.info('接口已经执行=============')
|
||||||
else:
|
else:
|
||||||
logging.error('工厂加工同步订单状态失败 {}'.format(ret.text))
|
logging.error('工厂加工同步订单状态失败 {}'.format(ret))
|
||||||
raise UserError('工厂加工同步订单状态失败')
|
raise UserError('工厂加工同步订单状态失败')
|
||||||
except UserError as e:
|
except UserError as e:
|
||||||
logging.error('工厂加工同步订单状态失败 {}'.format(e))
|
logging.error('工厂加工同步订单状态失败 {}'.format(e))
|
||||||
|
|||||||
@@ -477,7 +477,7 @@ class Manufacturing_Connect(http.Controller):
|
|||||||
logging.info('LocationChange error:%s' % e)
|
logging.info('LocationChange error:%s' % e)
|
||||||
return json.JSONEncoder().encode(res)
|
return json.JSONEncoder().encode(res)
|
||||||
|
|
||||||
@http.route('/AutoDeviceApi/AGVToProduct', type='json', auth='sf_token', methods=['GET', 'POST'], csrf=False,
|
@http.route('/AutoDeviceApi/AGVToProduct', type='json', auth='none', methods=['GET', 'POST'], csrf=False,
|
||||||
cors="*")
|
cors="*")
|
||||||
def AGVToProduct(self, **kw):
|
def AGVToProduct(self, **kw):
|
||||||
"""
|
"""
|
||||||
@@ -549,7 +549,7 @@ class Manufacturing_Connect(http.Controller):
|
|||||||
logging.info('AGVToProduct error:%s' % e)
|
logging.info('AGVToProduct error:%s' % e)
|
||||||
return json.JSONEncoder().encode(res)
|
return json.JSONEncoder().encode(res)
|
||||||
|
|
||||||
@http.route('/AutoDeviceApi/AGVDownProduct', type='json', auth='sf_token', methods=['GET', 'POST'], csrf=False,
|
@http.route('/AutoDeviceApi/AGVDownProduct', type='json', auth='none', methods=['GET', 'POST'], csrf=False,
|
||||||
cors="*")
|
cors="*")
|
||||||
def AGVDownProduct(self, **kw):
|
def AGVDownProduct(self, **kw):
|
||||||
"""
|
"""
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ from odoo.http import request
|
|||||||
|
|
||||||
class Workpiece(http.Controller):
|
class Workpiece(http.Controller):
|
||||||
|
|
||||||
@http.route('/agvApi/backfeed', type='json', auth='sf_token', methods=['GET', 'POST'], csrf=False,
|
@http.route('/agvApi/backfeed', type='json', auth='none', methods=['GET', 'POST'], csrf=False,
|
||||||
cors="*")
|
cors="*")
|
||||||
def backfeed(self, **kw):
|
def backfeed(self, **kw):
|
||||||
"""
|
"""
|
||||||
|
|||||||
@@ -779,7 +779,8 @@ class MrpProduction(models.Model):
|
|||||||
routing_workcenter = self.env['mrp.routing.workcenter'].sudo().search(
|
routing_workcenter = self.env['mrp.routing.workcenter'].sudo().search(
|
||||||
[('name', '=', work.routing_type)])
|
[('name', '=', work.routing_type)])
|
||||||
|
|
||||||
work.write({'date_planned_start': date_planned_start, 'date_planned_finished': date_planned_end,'duration_expected':routing_workcenter.time_cycle})
|
work.write({'date_planned_start': date_planned_start, 'date_planned_finished': date_planned_end,
|
||||||
|
'duration_expected': routing_workcenter.time_cycle})
|
||||||
|
|
||||||
# 修改标记已完成方法
|
# 修改标记已完成方法
|
||||||
def button_mark_done1(self):
|
def button_mark_done1(self):
|
||||||
@@ -1078,27 +1079,22 @@ class MrpProduction(models.Model):
|
|||||||
productions.write({'programming_no': self.programming_no, 'is_remanufacture': True})
|
productions.write({'programming_no': self.programming_no, 'is_remanufacture': True})
|
||||||
# productions.procurement_group_id.mrp_production_ids.move_dest_ids.write(
|
# productions.procurement_group_id.mrp_production_ids.move_dest_ids.write(
|
||||||
# {'group_id': self.env['procurement.group'].search([('name', '=', sale_order.name)])})
|
# {'group_id': self.env['procurement.group'].search([('name', '=', sale_order.name)])})
|
||||||
stock_picking = None
|
stock_picking_remanufacture = self.env['stock.picking'].search([('origin', '=', productions.name)])
|
||||||
pc_picking = self.env['stock.picking'].search(
|
for pick in stock_picking_remanufacture:
|
||||||
[('origin', '=', productions.name), ('name', 'ilike', 'WH/PC/')])
|
if pick.name.startswith('WH/PC/') or pick.name.startswith('WH/INT/'):
|
||||||
stock_picking = pc_picking
|
if pick.move_ids:
|
||||||
int_picking = self.env['stock.picking'].search(
|
product_type_id = pick.move_ids[0].product_id.categ_id
|
||||||
[('origin', '=', productions.name), ('name', 'ilike', 'WH/INT/')])
|
if product_type_id.name == '坯料':
|
||||||
stock_picking |= int_picking
|
location_id = self.env['stock.location'].search([('name', '=', '坯料存货区')])
|
||||||
for pick in stock_picking:
|
if not location_id:
|
||||||
if pick.move_ids:
|
logging.info(f'没有搜索到【坯料存货区】: {location_id}')
|
||||||
product_type_id = pick.move_ids[0].product_id.categ_id
|
break
|
||||||
if product_type_id.name == '坯料':
|
if pick.picking_type_id.name == '内部调拨':
|
||||||
location_id = self.env['stock.location'].search([('name', '=', '坯料存货区')])
|
if pick.location_dest_id.product_type != product_type_id:
|
||||||
if not location_id:
|
pick.location_dest_id = location_id.id
|
||||||
logging.info(f'没有搜索到【坯料存货区】: {location_id}')
|
elif pick.picking_type_id.name == '生产发料':
|
||||||
break
|
if pick.location_id.product_type != product_type_id:
|
||||||
if pick.picking_type_id.name == '内部调拨':
|
pick.location_id = location_id.id
|
||||||
if pick.location_dest_id.product_type != product_type_id:
|
|
||||||
pick.location_dest_id = location_id.id
|
|
||||||
elif pick.picking_type_id.name == '生产发料':
|
|
||||||
if pick.location_id.product_type != product_type_id:
|
|
||||||
pick.location_id = location_id.id
|
|
||||||
scarp_process_parameter_workorder = self.env['mrp.workorder'].search(
|
scarp_process_parameter_workorder = self.env['mrp.workorder'].search(
|
||||||
[('surface_technics_parameters_id', '!=', False), ('production_id', '=', self.id),
|
[('surface_technics_parameters_id', '!=', False), ('production_id', '=', self.id),
|
||||||
('is_subcontract', '=', True)])
|
('is_subcontract', '=', True)])
|
||||||
@@ -1111,7 +1107,6 @@ class MrpProduction(models.Model):
|
|||||||
for process_item in scarp_process_parameter_workorder:
|
for process_item in scarp_process_parameter_workorder:
|
||||||
if purchase_item.product_id.categ_type == '表面工艺':
|
if purchase_item.product_id.categ_type == '表面工艺':
|
||||||
if purchase_item.product_id.server_product_process_parameters_id == process_item.surface_technics_parameters_id:
|
if purchase_item.product_id.server_product_process_parameters_id == process_item.surface_technics_parameters_id:
|
||||||
print(purchase_orders.origin.find(productions.name))
|
|
||||||
if purchase_orders.origin.find(productions.name) == -1:
|
if purchase_orders.origin.find(productions.name) == -1:
|
||||||
purchase_orders.origin += ',' + productions.name
|
purchase_orders.origin += ',' + productions.name
|
||||||
if item['is_reprogramming'] is False:
|
if item['is_reprogramming'] is False:
|
||||||
|
|||||||
@@ -1100,7 +1100,7 @@ class ResMrpWorkOrder(models.Model):
|
|||||||
[('barcode', 'ilike', 'VL-SPOC')]).id),
|
[('barcode', 'ilike', 'VL-SPOC')]).id),
|
||||||
('origin', '=', self.production_id.name)])
|
('origin', '=', self.production_id.name)])
|
||||||
if move_out.state != 'done':
|
if move_out.state != 'done':
|
||||||
move_out.write({'state': 'assigned'})
|
move_out.write({'state': 'assigned', 'production_id': False})
|
||||||
self.env['stock.move.line'].create(move_out.get_move_line(self.production_id, self))
|
self.env['stock.move.line'].create(move_out.get_move_line(self.production_id, self))
|
||||||
|
|
||||||
# move_out._action_assign()
|
# move_out._action_assign()
|
||||||
|
|||||||
@@ -574,6 +574,7 @@ class StockPicking(models.Model):
|
|||||||
('origin', '=', self.origin), ('picking_id', '=', self.id)])
|
('origin', '=', self.origin), ('picking_id', '=', self.id)])
|
||||||
if self.location_id == move_in.location_id and self.location_dest_id == move_in.location_dest_id:
|
if self.location_id == move_in.location_id and self.location_dest_id == move_in.location_dest_id:
|
||||||
if move_out.origin == move_in.origin:
|
if move_out.origin == move_in.origin:
|
||||||
|
move_in.write({'production_id': False})
|
||||||
if move_out.picking_id.state != 'done':
|
if move_out.picking_id.state != 'done':
|
||||||
raise UserError(
|
raise UserError(
|
||||||
_('该入库单对应的单号为%s的出库单还未完成,不能进行验证操作!' % move_out.picking_id.name))
|
_('该入库单对应的单号为%s的出库单还未完成,不能进行验证操作!' % move_out.picking_id.name))
|
||||||
@@ -659,6 +660,11 @@ class ReStockMove(models.Model):
|
|||||||
return move_values
|
return move_values
|
||||||
|
|
||||||
def _get_new_picking_values_Res(self, item, sorted_workorders, rescode):
|
def _get_new_picking_values_Res(self, item, sorted_workorders, rescode):
|
||||||
|
picking_type_id = self.mapped('picking_type_id').id
|
||||||
|
if rescode == 'WH/OCOUT/':
|
||||||
|
picking_type_id = self.env.ref('sf_manufacturing.outcontract_picking_out').id
|
||||||
|
elif rescode == 'WH/OCIN/':
|
||||||
|
picking_type_id = self.env.ref('sf_manufacturing.outcontract_picking_in').id
|
||||||
return {
|
return {
|
||||||
'name': self.env['stock.picking']._get_name_Res(rescode),
|
'name': self.env['stock.picking']._get_name_Res(rescode),
|
||||||
'origin': item.name,
|
'origin': item.name,
|
||||||
@@ -667,7 +673,7 @@ class ReStockMove(models.Model):
|
|||||||
'user_id': False,
|
'user_id': False,
|
||||||
'move_type': self.mapped('group_id').move_type or 'direct',
|
'move_type': self.mapped('group_id').move_type or 'direct',
|
||||||
'partner_id': sorted_workorders.supplier_id.id,
|
'partner_id': sorted_workorders.supplier_id.id,
|
||||||
'picking_type_id': self.mapped('picking_type_id').id,
|
'picking_type_id': picking_type_id,
|
||||||
'location_id': self.mapped('location_id').id,
|
'location_id': self.mapped('location_id').id,
|
||||||
'location_dest_id': self.mapped('location_dest_id').id,
|
'location_dest_id': self.mapped('location_dest_id').id,
|
||||||
'state': 'confirmed',
|
'state': 'confirmed',
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ class ReworkWizard(models.TransientModel):
|
|||||||
processing_panel_id = fields.Many2many('sf.processing.panel', string="加工面")
|
processing_panel_id = fields.Many2many('sf.processing.panel', string="加工面")
|
||||||
is_reprogramming = fields.Boolean(string='申请重新编程', default=False)
|
is_reprogramming = fields.Boolean(string='申请重新编程', default=False)
|
||||||
is_reprogramming_readonly = fields.Boolean(string='申请重新编程(只读)', default=False)
|
is_reprogramming_readonly = fields.Boolean(string='申请重新编程(只读)', default=False)
|
||||||
|
is_clamp_measure = fields.Boolean(string='保留装夹测量数据', default=True)
|
||||||
reprogramming_num = fields.Integer('重新编程次数', default=0)
|
reprogramming_num = fields.Integer('重新编程次数', default=0)
|
||||||
programming_state = fields.Selection(
|
programming_state = fields.Selection(
|
||||||
[('待编程', '待编程'), ('编程中', '编程中'), ('已编程', '已编程'), ('已编程未下发', '已编程未下发'),
|
[('待编程', '待编程'), ('编程中', '编程中'), ('已编程', '已编程'), ('已编程未下发', '已编程未下发'),
|
||||||
@@ -35,6 +36,7 @@ class ReworkWizard(models.TransientModel):
|
|||||||
|
|
||||||
def confirm(self):
|
def confirm(self):
|
||||||
if self.routing_type in ['装夹预调', 'CNC加工']:
|
if self.routing_type in ['装夹预调', 'CNC加工']:
|
||||||
|
self.is_clamp_measure = False
|
||||||
self.workorder_id.is_rework = True
|
self.workorder_id.is_rework = True
|
||||||
self.production_id.write({'detection_result_ids': [(0, 0, {
|
self.production_id.write({'detection_result_ids': [(0, 0, {
|
||||||
'rework_reason': self.rework_reason,
|
'rework_reason': self.rework_reason,
|
||||||
@@ -58,19 +60,15 @@ class ReworkWizard(models.TransientModel):
|
|||||||
if processing_panels_missing:
|
if processing_panels_missing:
|
||||||
processing_panels_str = ','.join(processing_panels_missing)
|
processing_panels_str = ','.join(processing_panels_missing)
|
||||||
raise UserError('您还有待处理的检测结果中为%s的加工面未选择' % processing_panels_str)
|
raise UserError('您还有待处理的检测结果中为%s的加工面未选择' % processing_panels_str)
|
||||||
# processing_panels = set()
|
|
||||||
# for handle_item in handle_result:
|
|
||||||
# for dr_panel in self.processing_panel_id:
|
|
||||||
# if dr_panel.name == handle_item.processing_panel:
|
|
||||||
# processing_panels.add(dr_panel.name)
|
|
||||||
# if len(processing_panels) != len(handle_result):
|
|
||||||
# processing_panels_str = ','.join(processing_panels)
|
|
||||||
# return UserError(f'您还有待处理的检测结果中为{processing_panels_str}的加工面未选择')
|
|
||||||
for panel in self.processing_panel_id:
|
for panel in self.processing_panel_id:
|
||||||
panel_workorder = self.production_id.workorder_ids.filtered(
|
panel_workorder = self.production_id.workorder_ids.filtered(
|
||||||
lambda ap: ap.processing_panel == panel.name and ap.state != 'rework')
|
lambda ap: ap.processing_panel == panel.name and ap.state != 'rework')
|
||||||
if panel_workorder:
|
if panel_workorder:
|
||||||
panel_workorder.write({'state': 'rework'})
|
panel_workorder.write({'state': 'rework'})
|
||||||
|
rework_clamp_workorder = max(panel_workorder.filtered(
|
||||||
|
lambda
|
||||||
|
rp: rp.processing_panel == panel.name and rp.routing_type == '装夹预调' and rp.state in [
|
||||||
|
'done', 'rework']))
|
||||||
# panel_workorder.filtered(
|
# panel_workorder.filtered(
|
||||||
# lambda wo: wo.routing_type == '装夹预调').workpiece_delivery_ids.filtered(
|
# lambda wo: wo.routing_type == '装夹预调').workpiece_delivery_ids.filtered(
|
||||||
# lambda wd: wd.status == '待下发').write({'status': '已取消'})
|
# lambda wd: wd.status == '待下发').write({'status': '已取消'})
|
||||||
@@ -93,6 +91,43 @@ class ReworkWizard(models.TransientModel):
|
|||||||
self.production_id.detection_result_ids.filtered(
|
self.production_id.detection_result_ids.filtered(
|
||||||
lambda ap1: ap1.processing_panel == panel.name and ap1.handle_result == '待处理').write(
|
lambda ap1: ap1.processing_panel == panel.name and ap1.handle_result == '待处理').write(
|
||||||
{'handle_result': '已处理'})
|
{'handle_result': '已处理'})
|
||||||
|
new_pre_workorder = self.production_id.workorder_ids.filtered(lambda
|
||||||
|
p: p.routing_type == '装夹预调' and p.processing_panel == panel.name and p.state not in (
|
||||||
|
'rework', 'done'))
|
||||||
|
if new_pre_workorder and rework_clamp_workorder and self.is_clamp_measure is True:
|
||||||
|
new_pre_workorder.write(
|
||||||
|
{'X1_axis': rework_clamp_workorder.X1_axis, 'Y1_axis': rework_clamp_workorder.Y1_axis
|
||||||
|
, 'Z1_axis': rework_clamp_workorder.Z1_axis,
|
||||||
|
'X2_axis': rework_clamp_workorder.X2_axis
|
||||||
|
, 'Y2_axis': rework_clamp_workorder.Y2_axis,
|
||||||
|
'Z2_axis': rework_clamp_workorder.Z2_axis
|
||||||
|
, 'X3_axis': rework_clamp_workorder.X3_axis,
|
||||||
|
'Y3_axis': rework_clamp_workorder.Y3_axis
|
||||||
|
, 'Z3_axis': rework_clamp_workorder.Z3_axis,
|
||||||
|
'X4_axis': rework_clamp_workorder.X4_axis
|
||||||
|
, 'Y4_axis': rework_clamp_workorder.Y4_axis,
|
||||||
|
'Z4_axis': rework_clamp_workorder.Z4_axis
|
||||||
|
, 'X5_axis': rework_clamp_workorder.X5_axis,
|
||||||
|
'Y5_axis': rework_clamp_workorder.Y5_axis
|
||||||
|
, 'Z5_axis': rework_clamp_workorder.Z5_axis,
|
||||||
|
'X6_axis': rework_clamp_workorder.X6_axis
|
||||||
|
, 'Y6_axis': rework_clamp_workorder.Y6_axis,
|
||||||
|
'Z6_axis': rework_clamp_workorder.Z6_axis
|
||||||
|
, 'X7_axis': rework_clamp_workorder.X7_axis,
|
||||||
|
'Y7_axis': rework_clamp_workorder.Y7_axis
|
||||||
|
, 'Z7_axis': rework_clamp_workorder.Z7_axis,
|
||||||
|
'X8_axis': rework_clamp_workorder.X8_axis
|
||||||
|
, 'Y8_axis': rework_clamp_workorder.Y8_axis,
|
||||||
|
'Z8_axis': rework_clamp_workorder.Z8_axis
|
||||||
|
, 'X9_axis': rework_clamp_workorder.X9_axis,
|
||||||
|
'Y9_axis': rework_clamp_workorder.Y9_axis
|
||||||
|
, 'Z9_axis': rework_clamp_workorder.Z9_axis,
|
||||||
|
'X10_axis': rework_clamp_workorder.X10_axis
|
||||||
|
, 'Y10_axis': rework_clamp_workorder.Y10_axis,
|
||||||
|
'Z10_axis': rework_clamp_workorder.Z10_axis
|
||||||
|
, 'X_deviation_angle': rework_clamp_workorder.X_deviation_angle,
|
||||||
|
'material_center_point': rework_clamp_workorder.material_center_point
|
||||||
|
})
|
||||||
if self.is_reprogramming is False:
|
if self.is_reprogramming is False:
|
||||||
if self.programming_state in ['已编程', '已下发']:
|
if self.programming_state in ['已编程', '已下发']:
|
||||||
if self.reprogramming_num >= 1 and self.programming_state == '已编程':
|
if self.reprogramming_num >= 1 and self.programming_state == '已编程':
|
||||||
@@ -149,9 +184,7 @@ class ReworkWizard(models.TransientModel):
|
|||||||
'cmm_ids': new_cnc_workorder.cmm_ids.sudo()._json_cmm_program(panel.name,
|
'cmm_ids': new_cnc_workorder.cmm_ids.sudo()._json_cmm_program(panel.name,
|
||||||
ret),
|
ret),
|
||||||
'cnc_worksheet': cnc_rework.cnc_worksheet})
|
'cnc_worksheet': cnc_rework.cnc_worksheet})
|
||||||
new_pre_workorder = self.production_id.workorder_ids.filtered(lambda
|
|
||||||
p: p.routing_type == '装夹预调' and p.processing_panel == panel.name and p.state not in (
|
|
||||||
'rework', 'done'))
|
|
||||||
if new_pre_workorder:
|
if new_pre_workorder:
|
||||||
pre_rework = max(self.production_id.workorder_ids.filtered(
|
pre_rework = max(self.production_id.workorder_ids.filtered(
|
||||||
lambda pr: pr.processing_panel == panel.name and pr.state in (
|
lambda pr: pr.processing_panel == panel.name and pr.state in (
|
||||||
|
|||||||
@@ -14,17 +14,25 @@
|
|||||||
<group>
|
<group>
|
||||||
<field name="processing_panel_id" options="{'no_create': True}"
|
<field name="processing_panel_id" options="{'no_create': True}"
|
||||||
attrs='{"invisible": [("routing_type","=","装夹预调")]}' widget="many2many_tags"/>
|
attrs='{"invisible": [("routing_type","=","装夹预调")]}' widget="many2many_tags"/>
|
||||||
|
|
||||||
</group>
|
</group>
|
||||||
|
<div attrs='{"invisible": [("routing_type","=","装夹预调")]}'>
|
||||||
|
<span style='font-weight:bold;'>保留装夹测量数据
|
||||||
|
<field name="is_clamp_measure" force_save="1"/>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
<div attrs='{"invisible": [("reprogramming_num","=",0)]}'>
|
<div attrs='{"invisible": [("reprogramming_num","=",0)]}'>
|
||||||
注意: 该制造订单产品已申请重新编程次数为<field
|
<span style='font-weight:bold;'>
|
||||||
name="reprogramming_num" string=""
|
注意: 该制造订单产品已申请重新编程次数为<field
|
||||||
readonly="1"
|
name="reprogramming_num" string=""
|
||||||
style='color:red;'/>,且当前编程状态为
|
readonly="1"
|
||||||
<field name="programming_state" string=""
|
style='color:red;'/>,且当前编程状态为
|
||||||
decoration-info="programming_state == '待编程'"
|
<field name="programming_state" string=""
|
||||||
decoration-success="programming_state == '已下发'"
|
decoration-info="programming_state == '待编程'"
|
||||||
decoration-warning="programming_state =='编程中'"
|
decoration-success="programming_state == '已下发'"
|
||||||
decoration-danger="programming_state =='已编程'" readonly="1"/>
|
decoration-warning="programming_state =='编程中'"
|
||||||
|
decoration-danger="programming_state =='已编程'" readonly="1"/>
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div attrs='{"invisible": ["|",("routing_type","in",["装夹预调","CNC加工"]),("programming_state","not in",["已下发"])],"readonly": [("tool_state", "=", "2")]}'>
|
<div attrs='{"invisible": ["|",("routing_type","in",["装夹预调","CNC加工"]),("programming_state","not in",["已下发"])],"readonly": [("tool_state", "=", "2")]}'>
|
||||||
<span style='font-weight:bold;'>申请重新编程
|
<span style='font-weight:bold;'>申请重新编程
|
||||||
|
|||||||
4
sf_stock/__init__.py
Normal file
4
sf_stock/__init__.py
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
from . import controllers
|
||||||
|
from . import models
|
||||||
36
sf_stock/__manifest__.py
Normal file
36
sf_stock/__manifest__.py
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
{
|
||||||
|
'name': "sf_stock",
|
||||||
|
|
||||||
|
'summary': """
|
||||||
|
Short (1 phrase/line) summary of the module's purpose, used as
|
||||||
|
subtitle on modules listing or apps.openerp.com""",
|
||||||
|
|
||||||
|
'description': """
|
||||||
|
Long description of module's purpose
|
||||||
|
""",
|
||||||
|
|
||||||
|
'author': "My Company",
|
||||||
|
'website': "https://www.yourcompany.com",
|
||||||
|
|
||||||
|
# Categories can be used to filter modules in modules listing
|
||||||
|
# Check https://github.com/odoo/odoo/blob/16.0/odoo/addons/base/data/ir_module_category_data.xml
|
||||||
|
# for the full list
|
||||||
|
'category': 'Uncategorized',
|
||||||
|
'version': '0.1',
|
||||||
|
|
||||||
|
# any module necessary for this one to work correctly
|
||||||
|
'depends': ['sf_sale', 'stock'],
|
||||||
|
|
||||||
|
# always loaded
|
||||||
|
'data': [
|
||||||
|
# 'security/ir.model.access.csv',
|
||||||
|
'views/stock_picking.xml',
|
||||||
|
],
|
||||||
|
# only loaded in demonstration mode
|
||||||
|
'demo': [
|
||||||
|
'demo/demo.xml',
|
||||||
|
],
|
||||||
|
'installable': True,
|
||||||
|
'application': True,
|
||||||
|
}
|
||||||
3
sf_stock/controllers/__init__.py
Normal file
3
sf_stock/controllers/__init__.py
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
from . import controllers
|
||||||
21
sf_stock/controllers/controllers.py
Normal file
21
sf_stock/controllers/controllers.py
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# from odoo import http
|
||||||
|
|
||||||
|
|
||||||
|
# class SfStock(http.Controller):
|
||||||
|
# @http.route('/sf_stock/sf_stock', auth='public')
|
||||||
|
# def index(self, **kw):
|
||||||
|
# return "Hello, world"
|
||||||
|
|
||||||
|
# @http.route('/sf_stock/sf_stock/objects', auth='public')
|
||||||
|
# def list(self, **kw):
|
||||||
|
# return http.request.render('sf_stock.listing', {
|
||||||
|
# 'root': '/sf_stock/sf_stock',
|
||||||
|
# 'objects': http.request.env['sf_stock.sf_stock'].search([]),
|
||||||
|
# })
|
||||||
|
|
||||||
|
# @http.route('/sf_stock/sf_stock/objects/<model("sf_stock.sf_stock"):obj>', auth='public')
|
||||||
|
# def object(self, obj, **kw):
|
||||||
|
# return http.request.render('sf_stock.object', {
|
||||||
|
# 'object': obj
|
||||||
|
# })
|
||||||
30
sf_stock/demo/demo.xml
Normal file
30
sf_stock/demo/demo.xml
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
<odoo>
|
||||||
|
<data>
|
||||||
|
<!--
|
||||||
|
<record id="object0" model="sf_stock.sf_stock">
|
||||||
|
<field name="name">Object 0</field>
|
||||||
|
<field name="value">0</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record id="object1" model="sf_stock.sf_stock">
|
||||||
|
<field name="name">Object 1</field>
|
||||||
|
<field name="value">10</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record id="object2" model="sf_stock.sf_stock">
|
||||||
|
<field name="name">Object 2</field>
|
||||||
|
<field name="value">20</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record id="object3" model="sf_stock.sf_stock">
|
||||||
|
<field name="name">Object 3</field>
|
||||||
|
<field name="value">30</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record id="object4" model="sf_stock.sf_stock">
|
||||||
|
<field name="name">Object 4</field>
|
||||||
|
<field name="value">40</field>
|
||||||
|
</record>
|
||||||
|
-->
|
||||||
|
</data>
|
||||||
|
</odoo>
|
||||||
3
sf_stock/models/__init__.py
Normal file
3
sf_stock/models/__init__.py
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
from . import stock_picking
|
||||||
110
sf_stock/models/stock_picking.py
Normal file
110
sf_stock/models/stock_picking.py
Normal file
@@ -0,0 +1,110 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
import json
|
||||||
|
import requests
|
||||||
|
from odoo import models, fields, api
|
||||||
|
|
||||||
|
from odoo.exceptions import UserError
|
||||||
|
import logging
|
||||||
|
from odoo.tools import date_utils
|
||||||
|
|
||||||
|
_logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
class StockPicking(models.Model):
|
||||||
|
_inherit = 'stock.picking'
|
||||||
|
|
||||||
|
cancel_backorder_ids = fields.Boolean(default=False, string='是否取消后置单据')
|
||||||
|
|
||||||
|
# 重写验证,下发发货到bfm
|
||||||
|
def button_validate(self):
|
||||||
|
info = super(StockPicking, self).button_validate()
|
||||||
|
if self.picking_type_code == 'outgoing':
|
||||||
|
self.send_to_bfm()
|
||||||
|
return info
|
||||||
|
|
||||||
|
def deal_move_ids(self, send_move_ids, send_move_line_ids):
|
||||||
|
move_ids = [] # 本次发货单
|
||||||
|
move_line_ids = [] # 本次发货单行
|
||||||
|
if send_move_ids:
|
||||||
|
for item in send_move_ids:
|
||||||
|
val = {
|
||||||
|
'name': item.product_id.upload_model_file.display_name,
|
||||||
|
'quantity_done': item.quantity_done,
|
||||||
|
'date': date_utils.json_default(item.date) if item.date else None,
|
||||||
|
'description_picking': item.description_picking,
|
||||||
|
'date_deadline': date_utils.json_default(item.date_deadline) if item.date_deadline else None,
|
||||||
|
'product_uom_qty': item.product_uom_qty,
|
||||||
|
'sequence': item.sequence,
|
||||||
|
'price_unit': item.price_unit,
|
||||||
|
'priority': item.priority,
|
||||||
|
'state': item.state,
|
||||||
|
}
|
||||||
|
move_ids.append(val)
|
||||||
|
for item in send_move_line_ids:
|
||||||
|
val = {
|
||||||
|
'qty_done': item.qty_done,
|
||||||
|
'reserved_qty': item.reserved_qty,
|
||||||
|
'reserved_uom_qty': item.reserved_uom_qty,
|
||||||
|
'date': date_utils.json_default(item.date) if item.date else None,
|
||||||
|
'description_picking': item.description_picking,
|
||||||
|
'state': item.state,
|
||||||
|
}
|
||||||
|
move_line_ids.append(val)
|
||||||
|
return move_ids, move_line_ids
|
||||||
|
|
||||||
|
def deal_send_backorder_id(self, backorder_ids1):
|
||||||
|
backorder_ids = []
|
||||||
|
|
||||||
|
if backorder_ids1:
|
||||||
|
for item in backorder_ids1:
|
||||||
|
move_ids, move_line_ids = self.deal_move_ids(item.move_ids, item.move_line_ids)
|
||||||
|
val = {
|
||||||
|
'receiverName': item.receiverName,
|
||||||
|
'name': item.sale_id.default_code,
|
||||||
|
'send_no': item.name,
|
||||||
|
'scheduled_date': date_utils.json_default(item.scheduled_date) if item.scheduled_date else None,
|
||||||
|
'date': date_utils.json_default(item.date) if item.date else None,
|
||||||
|
'date_deadline': date_utils.json_default(item.date_deadline) if item.date_deadline else None,
|
||||||
|
'date_done': date_utils.json_default(item.date_done) if item.date_done else None,
|
||||||
|
'move_ids': move_ids,
|
||||||
|
'move_line_ids': move_line_ids,
|
||||||
|
'state': item.state,
|
||||||
|
'move_type': item.move_type,
|
||||||
|
}
|
||||||
|
backorder_ids.append(val)
|
||||||
|
return backorder_ids
|
||||||
|
|
||||||
|
def send_to_bfm(self):
|
||||||
|
skip_backorder = self.env.context.get('skip_backorder')
|
||||||
|
# 下发发货到bfm
|
||||||
|
config = self.env['res.config.settings'].get_values()
|
||||||
|
move_ids, move_line_ids = self.deal_move_ids(self.move_ids, self.move_line_ids)
|
||||||
|
data = {
|
||||||
|
'params': {
|
||||||
|
'receiverName': self.receiverName,
|
||||||
|
'priority': self.priority,
|
||||||
|
'name': self.sale_id.default_code,
|
||||||
|
'send_no': self.name,
|
||||||
|
'scheduled_date': date_utils.json_default(self.scheduled_date) if self.scheduled_date else None,
|
||||||
|
'date': date_utils.json_default(self.date) if self.date else None,
|
||||||
|
'date_deadline': date_utils.json_default(self.date_deadline) if self.date_deadline else None,
|
||||||
|
'date_done': date_utils.json_default(self.date_done) if self.date_done else None,
|
||||||
|
'move_ids': move_ids,
|
||||||
|
'move_line_ids': move_line_ids,
|
||||||
|
'state': self.state,
|
||||||
|
'backorder_id': self.deal_send_backorder_id(self.backorder_id),
|
||||||
|
'backorder_ids': self.deal_send_backorder_id(self.backorder_ids),
|
||||||
|
'cancel_backorder_ids': skip_backorder,
|
||||||
|
'move_type': self.move_type,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
url1 = config['bfm_url_new'] + '/api/stock/deliver_goods'
|
||||||
|
json_str = json.dumps(data)
|
||||||
|
print('json_str', json_str)
|
||||||
|
r = requests.post(url1, json=data, data=None)
|
||||||
|
if r.status_code == 200:
|
||||||
|
result = json.loads(r.json()['result'])
|
||||||
|
if result['code'] != 200:
|
||||||
|
raise UserError(result['message'] or '工厂发货下发bfm失败')
|
||||||
|
else:
|
||||||
|
raise UserError('工厂发货下发bfm失败')
|
||||||
2
sf_stock/security/ir.model.access.csv
Normal file
2
sf_stock/security/ir.model.access.csv
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
|
||||||
|
access_sf_stock_sf_stock,sf_stock.sf_stock,model_sf_stock_sf_stock,base.group_user,1,1,1,1
|
||||||
|
5
sf_stock/views/stock_picking.xml
Normal file
5
sf_stock/views/stock_picking.xml
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
<odoo>
|
||||||
|
<data>
|
||||||
|
|
||||||
|
</data>
|
||||||
|
</odoo>
|
||||||
Reference in New Issue
Block a user