Merge branch 'develop' of https://e.coding.net/jikimo-hn/jikimo_sfs/jikimo_sf into feature/制造功能优化
# Conflicts: # quality_control/security/ir.model.access.csv # quality_control/wizard/quality_check_wizard.py # sf_quality/__manifest__.py # sf_quality/models/__init__.py # sf_quality/models/stock.py
This commit is contained in:
@@ -118,6 +118,17 @@ patch(ListRenderer.prototype, 'jikimo_frontend.ListRenderer', {
|
|||||||
owl.onPatched(() => {
|
owl.onPatched(() => {
|
||||||
this.listherHeaderBodyNum()
|
this.listherHeaderBodyNum()
|
||||||
})
|
})
|
||||||
|
const treeModifiers = this.getFieldModifiers(this.props.archInfo.__rawArch);
|
||||||
|
// console.log('treeModifiers', treeModifiers);
|
||||||
|
if(treeModifiers) {
|
||||||
|
this.props.merge_key = treeModifiers.merge_key;
|
||||||
|
this.props.merge_fields = treeModifiers.merge_fields.split(',');
|
||||||
|
const data = this.setColumns(this.props.merge_key);
|
||||||
|
console.log('data', data);
|
||||||
|
owl.onMounted(() => {
|
||||||
|
this.mergeColumns(this.props.merge_fields, data)
|
||||||
|
})
|
||||||
|
}
|
||||||
return this._super(...arguments);
|
return this._super(...arguments);
|
||||||
},
|
},
|
||||||
setRequired() {
|
setRequired() {
|
||||||
@@ -163,7 +174,58 @@ patch(ListRenderer.prototype, 'jikimo_frontend.ListRenderer', {
|
|||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.log(e)
|
console.log(e)
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
setColumns( merge_key) {
|
||||||
|
const data = this.props.list.records
|
||||||
|
let sourceIndex = 0;
|
||||||
|
let sourceValue = ''
|
||||||
|
data.forEach((item, index) => {
|
||||||
|
if(!item.colspan) {
|
||||||
|
item.colspan = 1;
|
||||||
|
}
|
||||||
|
if(item.data[merge_key] === sourceValue) {
|
||||||
|
data[sourceIndex].colspan ++ ;
|
||||||
|
item.colspan = 0;
|
||||||
|
} else {
|
||||||
|
sourceIndex = index;
|
||||||
|
sourceValue = item.data[merge_key];
|
||||||
|
}
|
||||||
|
})
|
||||||
|
return data
|
||||||
|
},
|
||||||
|
getFieldModifiers(xmlString) {
|
||||||
|
const parser = new DOMParser();
|
||||||
|
const xmlDoc = parser.parseFromString(xmlString, "text/xml");
|
||||||
|
|
||||||
|
// 提取 <tree> 的 modifiers
|
||||||
|
const treeElement = xmlDoc.querySelector("tree");
|
||||||
|
const treeModifiers = treeElement.getAttribute("modifiers");
|
||||||
|
if (treeModifiers) {
|
||||||
|
const parsedTreeModifiers = JSON.parse(treeModifiers);
|
||||||
|
console.log("Tree Modifiers:", parsedTreeModifiers);
|
||||||
|
return parsedTreeModifiers;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
},
|
||||||
|
mergeColumns(merge_fields, data) {
|
||||||
|
const dom = this.tableRef.el
|
||||||
|
const thead = $(dom).children('thead')
|
||||||
|
const tbody = $(dom).children('tbody')
|
||||||
|
tbody.children('tr.o_data_row').each(function () {
|
||||||
|
const tr = $(this)
|
||||||
|
const td = tr.children('td')
|
||||||
|
const index = $(this).index()
|
||||||
|
td.each(function () {
|
||||||
|
if(merge_fields.indexOf($(this).attr('name')) >= 0) {
|
||||||
|
$(this).attr('rowspan', data[index].colspan)
|
||||||
|
if(data[index].colspan == 0) {
|
||||||
|
$(this).remove()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
})
|
})
|
||||||
patch(FormLabel.prototype, 'jikimo_frontend.FormLabel', {
|
patch(FormLabel.prototype, 'jikimo_frontend.FormLabel', {
|
||||||
get className() {
|
get className() {
|
||||||
@@ -176,7 +238,6 @@ patch(FormLabel.prototype, 'jikimo_frontend.FormLabel', {
|
|||||||
);
|
);
|
||||||
const classes = this.props.className ? [this.props.className] : [];
|
const classes = this.props.className ? [this.props.className] : [];
|
||||||
const otherRequired = filedRequiredList[this.props.fieldName]
|
const otherRequired = filedRequiredList[this.props.fieldName]
|
||||||
|
|
||||||
if(this.props.fieldInfo?.rawAttrs?.class?.indexOf('custom_required') >= 0 || otherRequired) {
|
if(this.props.fieldInfo?.rawAttrs?.class?.indexOf('custom_required') >= 0 || otherRequired) {
|
||||||
classes.push('custom_required_add')
|
classes.push('custom_required_add')
|
||||||
}
|
}
|
||||||
@@ -193,35 +254,6 @@ patch(FormLabel.prototype, 'jikimo_frontend.FormLabel', {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
// 根据进度条设置水印
|
|
||||||
// const statusbar_params = {
|
|
||||||
// '已完工': 'bg-primary',
|
|
||||||
// '完成': 'bg-primary',
|
|
||||||
// '采购订单': 'bg-primary',
|
|
||||||
// '作废': 'bg-danger',
|
|
||||||
// '封存(报废)': 'bg-danger',
|
|
||||||
// }
|
|
||||||
// patch(StatusBarField.prototype, 'jikimo_frontend.StatusBarField', {
|
|
||||||
// setup() {
|
|
||||||
// owl.onMounted(this.ribbons);
|
|
||||||
// return this._super(...arguments);
|
|
||||||
// },
|
|
||||||
// ribbons() {
|
|
||||||
// try {
|
|
||||||
// const dom = $('.o_form_sheet.position-relative')
|
|
||||||
// const status = statusbar_params[this.currentName]
|
|
||||||
// if(status && dom.length) {
|
|
||||||
// dom.prepend(`<div class="o_widget o_widget_web_ribbon">
|
|
||||||
// <div class="ribbon ribbon-top-right">
|
|
||||||
// <span class="bg-opacity-75 ${status}" title="">${this.currentName}</span>
|
|
||||||
// </div>
|
|
||||||
// </div>`)
|
|
||||||
// }
|
|
||||||
// } catch (e) {
|
|
||||||
// console.log(e)
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// })
|
|
||||||
|
|
||||||
$(function () {
|
$(function () {
|
||||||
|
|
||||||
|
|||||||
@@ -9,6 +9,8 @@ class jikimo_purchase_tier_validation(models.Model):
|
|||||||
_name = 'purchase.order'
|
_name = 'purchase.order'
|
||||||
_inherit = ['purchase.order', 'tier.validation']
|
_inherit = ['purchase.order', 'tier.validation']
|
||||||
_description = "采购订单"
|
_description = "采购订单"
|
||||||
|
_state_from = ["draft", "to approve", "rejected"]
|
||||||
|
_state_to = ["approved"]
|
||||||
|
|
||||||
_tier_validation_buttons_xpath = "/form/header/button[@id='draft_confirm'][1]"
|
_tier_validation_buttons_xpath = "/form/header/button[@id='draft_confirm'][1]"
|
||||||
|
|
||||||
@@ -21,7 +23,7 @@ class jikimo_purchase_tier_validation(models.Model):
|
|||||||
|
|
||||||
def button_confirm(self):
|
def button_confirm(self):
|
||||||
for record in self:
|
for record in self:
|
||||||
if record.state in ['to approve']:
|
if record.need_validation and not record.validation_status == 'validated':
|
||||||
raise ValidationError(_('请先完成审批。'))
|
raise ValidationError(_('请先完成审批。'))
|
||||||
res = super(jikimo_purchase_tier_validation, self).button_confirm()
|
res = super(jikimo_purchase_tier_validation, self).button_confirm()
|
||||||
for record in self:
|
for record in self:
|
||||||
@@ -68,11 +70,6 @@ class jikimo_purchase_tier_validation(models.Model):
|
|||||||
|
|
||||||
return res
|
return res
|
||||||
|
|
||||||
def _rejected_tier(self, tiers=False):
|
|
||||||
res = super(jikimo_purchase_tier_validation, self)._rejected_tier(tiers)
|
|
||||||
self.state = 'draft'
|
|
||||||
return res
|
|
||||||
|
|
||||||
@api.model
|
@api.model
|
||||||
def _get_under_validation_exceptions(self):
|
def _get_under_validation_exceptions(self):
|
||||||
res = super(jikimo_purchase_tier_validation, self)._get_under_validation_exceptions()
|
res = super(jikimo_purchase_tier_validation, self)._get_under_validation_exceptions()
|
||||||
|
|||||||
@@ -81,18 +81,38 @@ class StockPicking(models.Model):
|
|||||||
return quality_pickings
|
return quality_pickings
|
||||||
|
|
||||||
def action_cancel(self):
|
def action_cancel(self):
|
||||||
|
"""
|
||||||
|
调拨单取消后,关联取消质量检查单
|
||||||
|
"""
|
||||||
|
context = self.env.context
|
||||||
|
if not context.get('cancel_check_picking') and self.sudo().mapped('check_ids').filtered(
|
||||||
|
lambda x: x.quality_state in ['pass', 'fail']):
|
||||||
|
self.env.cr.rollback()
|
||||||
|
return {
|
||||||
|
'type': 'ir.actions.act_window',
|
||||||
|
'res_model': 'picking.check.cancel.wizard',
|
||||||
|
'name': '取消质检单',
|
||||||
|
'view_mode': 'form',
|
||||||
|
'target': 'new',
|
||||||
|
'context': {
|
||||||
|
'default_picking_id': self.id,
|
||||||
|
'cancel_check_picking': True}
|
||||||
|
}
|
||||||
|
elif self.check_ids.filtered(lambda x: x.quality_state != 'cancel'):
|
||||||
|
self.sudo().mapped('check_ids').filtered(lambda x: x.quality_state != 'cancel').write({
|
||||||
|
'quality_state': 'cancel'
|
||||||
|
})
|
||||||
res = super(StockPicking, self).action_cancel()
|
res = super(StockPicking, self).action_cancel()
|
||||||
self.sudo().mapped('check_ids').filtered(lambda x: x.quality_state == 'none').unlink()
|
# self.sudo().mapped('check_ids').filtered(lambda x: x.quality_state == 'none').unlink()
|
||||||
return res
|
return res
|
||||||
|
|
||||||
def action_open_quality_check_picking(self):
|
def action_open_quality_check_picking(self):
|
||||||
action = self.env["ir.actions.actions"]._for_xml_id("quality_control.quality_check_action_picking")
|
action = self.env["ir.actions.actions"]._for_xml_id("quality_control.quality_check_action_picking")
|
||||||
action['context'] = self.env.context.copy()
|
action['context'] = {
|
||||||
action['context'].update({
|
|
||||||
'search_default_picking_id': [self.id],
|
'search_default_picking_id': [self.id],
|
||||||
'default_picking_id': self.id,
|
'default_picking_id': self.id,
|
||||||
'show_lots_text': self.show_lots_text,
|
'show_lots_text': self.show_lots_text,
|
||||||
})
|
}
|
||||||
return action
|
return action
|
||||||
|
|
||||||
def button_quality_alert(self):
|
def button_quality_alert(self):
|
||||||
|
|||||||
@@ -4,3 +4,4 @@ access_quality_check_measure_line,quality.check.measure.line,model_quality_check
|
|||||||
access_quality_check_import_complex_model_wizard,quality.check.import.complex.model.wizard,model_quality_check_import_complex_model_wizard,quality.group_quality_user,1,1,1,0
|
access_quality_check_import_complex_model_wizard,quality.check.import.complex.model.wizard,model_quality_check_import_complex_model_wizard,quality.group_quality_user,1,1,1,0
|
||||||
access_quality_check_report_history,quality.check.report.history,model_quality_check_report_history,quality.group_quality_user,1,1,1,0
|
access_quality_check_report_history,quality.check.report.history,model_quality_check_report_history,quality.group_quality_user,1,1,1,0
|
||||||
access_quality_check_publish_wizard,quality.check.publish.wizard,model_quality_check_publish_wizard,quality.group_quality_user,1,1,1,0
|
access_quality_check_publish_wizard,quality.check.publish.wizard,model_quality_check_publish_wizard,quality.group_quality_user,1,1,1,0
|
||||||
|
access_picking_check_cancel_wizard,access.picking_check_cancel_wizard,model_picking_check_cancel_wizard,quality.group_quality_user,1,1,1,0
|
||||||
|
|||||||
|
@@ -62,7 +62,8 @@ class QualityCheckWizard(models.TransientModel):
|
|||||||
|
|
||||||
def do_pass(self):
|
def do_pass(self):
|
||||||
if self.test_type == 'picture' and not self.picture:
|
if self.test_type == 'picture' and not self.picture:
|
||||||
raise UserError('You must provide a picture before validating')
|
raise UserError('请先上传照片')
|
||||||
|
# raise UserError('You must provide a picture before validating')
|
||||||
self.current_check_id.do_pass()
|
self.current_check_id.do_pass()
|
||||||
return self.action_generate_next_window()
|
return self.action_generate_next_window()
|
||||||
|
|
||||||
@@ -116,3 +117,18 @@ class QualityCheckWizard(models.TransientModel):
|
|||||||
# 对于成品出库的出厂检验报告,增加发布按钮
|
# 对于成品出库的出厂检验报告,增加发布按钮
|
||||||
def publish(self):
|
def publish(self):
|
||||||
self.current_check_id._do_publish_implementation()
|
self.current_check_id._do_publish_implementation()
|
||||||
|
|
||||||
|
|
||||||
|
class PickingCheckCancelWizard(models.TransientModel):
|
||||||
|
_name = 'picking.check.cancel.wizard'
|
||||||
|
_description = 'picking check cancel wizard'
|
||||||
|
|
||||||
|
picking_id = fields.Many2one('stock.picking', 'stock picking')
|
||||||
|
|
||||||
|
def confirm_picking_check(self):
|
||||||
|
res = self.picking_id.action_cancel()
|
||||||
|
return res
|
||||||
|
|
||||||
|
def cancel_picking_check(self):
|
||||||
|
# 这里是取消后的逻辑
|
||||||
|
return {'type': 'ir.actions.act_window_close'}
|
||||||
|
|||||||
@@ -121,4 +121,21 @@
|
|||||||
<field name="context">{}</field>
|
<field name="context">{}</field>
|
||||||
<field name="target">new</field>
|
<field name="target">new</field>
|
||||||
</record>
|
</record>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- ================================================================================================== -->
|
||||||
|
<record id="picking_check_cancel_wizard_form" model="ir.ui.view">
|
||||||
|
<field name="name">picking.check.cancel.wizard</field>
|
||||||
|
<field name="model">picking.check.cancel.wizard</field>
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<form string="Quality Check Failed">
|
||||||
|
<div>质量检查单已完成,继续取消吗?</div>
|
||||||
|
<div class="'color': 'red'">注意:关联质量检查单也将被取消。</div>
|
||||||
|
<footer>
|
||||||
|
<button name="confirm_picking_check" type="object" class="btn-primary" string="确认"/>
|
||||||
|
<button name="cancel_picking_check" type="object" string="取消"/>
|
||||||
|
</footer>
|
||||||
|
</form>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
</odoo>
|
</odoo>
|
||||||
|
|||||||
@@ -57,15 +57,24 @@ class MrsMaterialModel(models.Model):
|
|||||||
remark = fields.Text("备注")
|
remark = fields.Text("备注")
|
||||||
gain_way = fields.Selection(
|
gain_way = fields.Selection(
|
||||||
[("自加工", "自加工"), ("外协", "委外加工"), ("采购", "采购")],
|
[("自加工", "自加工"), ("外协", "委外加工"), ("采购", "采购")],
|
||||||
default="", string="获取方式")
|
default="采购", string="获取方式")
|
||||||
supplier_ids = fields.One2many('sf.supplier.sort', 'materials_model_id', string='供应商')
|
supplier_ids = fields.One2many('sf.supplier.sort', 'materials_model_id', string='供应商')
|
||||||
active = fields.Boolean('有效', default=True)
|
active = fields.Boolean('有效', default=True)
|
||||||
|
|
||||||
@api.constrains("gain_way")
|
@api.model
|
||||||
def _check_supplier_ids(self):
|
def create(self, vals):
|
||||||
for item in self:
|
res = super(MrsMaterialModel, self).create(vals)
|
||||||
if item.gain_way in ('外协', '采购') and not item.supplier_ids:
|
if not vals.get('supplier_ids'):
|
||||||
raise UserError("请添加供应商")
|
supplier_id = self.env['res.partner'].search([('name', '=', '湖南傲派自动化设备有限公司')], limit=1)
|
||||||
|
res.supplier_ids = [(0, 0, {'materials_model_id': res.id, 'partner_id': supplier_id.id or False})]
|
||||||
|
return res
|
||||||
|
else:
|
||||||
|
return res
|
||||||
|
# @api.constrains("gain_way")
|
||||||
|
# def _check_supplier_ids(self):
|
||||||
|
# for item in self:
|
||||||
|
# if item.gain_way in ('外协', '采购') and not item.supplier_ids:
|
||||||
|
# raise UserError("请添加供应商")
|
||||||
|
|
||||||
|
|
||||||
class MrsProductionProcessCategory(models.Model):
|
class MrsProductionProcessCategory(models.Model):
|
||||||
|
|||||||
@@ -262,13 +262,13 @@
|
|||||||
<group>
|
<group>
|
||||||
<field name="materials_no" readonly="1" force_save="1"/>
|
<field name="materials_no" readonly="1" force_save="1"/>
|
||||||
<field name="gain_way" required="0"/>
|
<field name="gain_way" required="0"/>
|
||||||
<field name="tensile_strength" required="1"/>
|
<field name="density" readonly="1" required="1" class="custom_required"/>
|
||||||
<field name="hardness" required="1"/>
|
|
||||||
<field name="density" readonly="1"/>
|
|
||||||
</group>
|
</group>
|
||||||
<group>
|
<group>
|
||||||
<field name="rough_machining" required="1"/>
|
<field name="rough_machining" required="1"/>
|
||||||
<field name="finish_machining" required="1"/>
|
<field name="finish_machining" required="1"/>
|
||||||
|
<field name="tensile_strength" required="1"/>
|
||||||
|
<field name="hardness" required="1"/>
|
||||||
<field name="need_h" default="false" readonly="1"/>
|
<field name="need_h" default="false" readonly="1"/>
|
||||||
<field name="mf_materia_post" attrs="{'invisible':[('need_h','=',False)]} "
|
<field name="mf_materia_post" attrs="{'invisible':[('need_h','=',False)]} "
|
||||||
readonly="1"/>
|
readonly="1"/>
|
||||||
@@ -297,7 +297,7 @@
|
|||||||
<record model="ir.ui.view" id="sf_materials_model_tree">
|
<record model="ir.ui.view" id="sf_materials_model_tree">
|
||||||
<field name="model">sf.materials.model</field>
|
<field name="model">sf.materials.model</field>
|
||||||
<field name="arch" type="xml">
|
<field name="arch" type="xml">
|
||||||
<tree string="材料型号" delete="0">
|
<tree string="材料型号" delete="0" create="0">
|
||||||
<field name="materials_no"/>
|
<field name="materials_no"/>
|
||||||
<field name="materials_code"/>
|
<field name="materials_code"/>
|
||||||
<field name="name"/>
|
<field name="name"/>
|
||||||
|
|||||||
@@ -1574,7 +1574,7 @@ class MrpProduction(models.Model):
|
|||||||
vals['picking_type_id'] = picking_type_id
|
vals['picking_type_id'] = picking_type_id
|
||||||
vals['name'] = self.env['stock.picking.type'].browse(picking_type_id).sequence_id.next_by_id()
|
vals['name'] = self.env['stock.picking.type'].browse(picking_type_id).sequence_id.next_by_id()
|
||||||
product_id = self.env['product.product'].browse(vals['product_id'])
|
product_id = self.env['product.product'].browse(vals['product_id'])
|
||||||
is_self_process = product_id.materials_type_id and product_id.materials_type_id.gain_way and product_id.materials_type_id.gain_way != '自加工'
|
is_self_process = product_id.materials_type_id.gain_way if product_id.materials_type_id else None
|
||||||
is_customer_provided = product_id.is_customer_provided
|
is_customer_provided = product_id.is_customer_provided
|
||||||
key = f"{is_self_process}_{is_customer_provided}"
|
key = f"{is_self_process}_{is_customer_provided}"
|
||||||
if not is_custemer_group_id.get(key):
|
if not is_custemer_group_id.get(key):
|
||||||
|
|||||||
@@ -1198,11 +1198,7 @@ class ResMrpWorkOrder(models.Model):
|
|||||||
'cmm_ids': production.workorder_ids.filtered(lambda t: t.routing_type == 'CNC加工').cmm_ids,
|
'cmm_ids': production.workorder_ids.filtered(lambda t: t.routing_type == 'CNC加工').cmm_ids,
|
||||||
}]
|
}]
|
||||||
return workorders_values_str
|
return workorders_values_str
|
||||||
|
def _process_compute_state(self):
|
||||||
@api.depends('production_availability', 'blocked_by_workorder_ids', 'blocked_by_workorder_ids.state',
|
|
||||||
'production_id.tool_state', 'production_id.schedule_state', 'sequence',
|
|
||||||
'production_id.programming_state')
|
|
||||||
def _compute_state(self):
|
|
||||||
for workorder in self:
|
for workorder in self:
|
||||||
# 如果工单的工序没有进行排序则跳出循环
|
# 如果工单的工序没有进行排序则跳出循环
|
||||||
if workorder.production_id.workorder_ids.filtered(lambda wk: wk.sequence == 0):
|
if workorder.production_id.workorder_ids.filtered(lambda wk: wk.sequence == 0):
|
||||||
@@ -1289,7 +1285,20 @@ class ResMrpWorkOrder(models.Model):
|
|||||||
mo.get_move_line(workorder.production_id, workorder))
|
mo.get_move_line(workorder.production_id, workorder))
|
||||||
else:
|
else:
|
||||||
workorder.state = 'waiting'
|
workorder.state = 'waiting'
|
||||||
|
@api.depends('production_availability', 'blocked_by_workorder_ids', 'blocked_by_workorder_ids.state',
|
||||||
|
'production_id.tool_state', 'production_id.schedule_state', 'sequence',
|
||||||
|
'production_id.programming_state')
|
||||||
|
def _compute_state(self):
|
||||||
|
self._process_compute_state()
|
||||||
|
for workorder in self:
|
||||||
|
if workorder.state == 'waiting' or workorder.state == 'pending':
|
||||||
|
for check_id in workorder.check_ids:
|
||||||
|
if not check_id.is_inspect:
|
||||||
|
check_id.quality_state = 'waiting'
|
||||||
|
if workorder.state == 'ready':
|
||||||
|
for check_id in workorder.check_ids:
|
||||||
|
if not check_id.is_inspect:
|
||||||
|
check_id.quality_state = 'none'
|
||||||
# 重写工单开始按钮方法
|
# 重写工单开始按钮方法
|
||||||
def button_start(self):
|
def button_start(self):
|
||||||
# 判断工单状态是否为等待组件
|
# 判断工单状态是否为等待组件
|
||||||
@@ -1510,8 +1519,12 @@ class ResMrpWorkOrder(models.Model):
|
|||||||
for workorder in record.production_id.workorder_ids:
|
for workorder in record.production_id.workorder_ids:
|
||||||
if workorder.processing_panel == record.processing_panel:
|
if workorder.processing_panel == record.processing_panel:
|
||||||
rfid_code = workorder.rfid_code
|
rfid_code = workorder.rfid_code
|
||||||
workorder.write({'rfid_code_old': rfid_code,
|
if record.is_rework is not True:
|
||||||
'rfid_code': False})
|
workorder.write({'rfid_code_old': rfid_code, 'rfid_code': False})
|
||||||
|
elif workorder.routing_type != '装夹预调' and workorder.state != 'rework':
|
||||||
|
workorder.write({'rfid_code_old': False, 'rfid_code': False})
|
||||||
|
elif workorder.routing_type == '装夹预调' and workorder.state != 'rework':
|
||||||
|
workorder.write({'rfid_code_old': rfid_code, 'rfid_code': False})
|
||||||
self.env['stock.lot'].sudo().search([('rfid', '=', rfid_code)]).write(
|
self.env['stock.lot'].sudo().search([('rfid', '=', rfid_code)]).write(
|
||||||
{'tool_material_status': '可用'})
|
{'tool_material_status': '可用'})
|
||||||
if workorder.rfid_code:
|
if workorder.rfid_code:
|
||||||
@@ -1928,7 +1941,8 @@ class SfWorkOrderBarcodes(models.Model):
|
|||||||
self.write(val)
|
self.write(val)
|
||||||
workorder_rfid = self.env['mrp.workorder'].search(
|
workorder_rfid = self.env['mrp.workorder'].search(
|
||||||
[('production_id', '=', workorder.production_id.id),
|
[('production_id', '=', workorder.production_id.id),
|
||||||
('processing_panel', '=', workorder.processing_panel)])
|
('processing_panel', '=', workorder.processing_panel),
|
||||||
|
('state', '!=', 'rework')])
|
||||||
if workorder_rfid:
|
if workorder_rfid:
|
||||||
for item in workorder_rfid:
|
for item in workorder_rfid:
|
||||||
item.write({'rfid_code': barcode})
|
item.write({'rfid_code': barcode})
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import requests
|
|||||||
import base64
|
import base64
|
||||||
import hashlib
|
import hashlib
|
||||||
import os
|
import os
|
||||||
|
import re
|
||||||
from odoo import models, fields, api, _
|
from odoo import models, fields, api, _
|
||||||
from odoo.exceptions import ValidationError, UserError
|
from odoo.exceptions import ValidationError, UserError
|
||||||
from odoo.modules import get_resource_path
|
from odoo.modules import get_resource_path
|
||||||
@@ -776,10 +777,33 @@ class ResProductMo(models.Model):
|
|||||||
manual_quotation = fields.Boolean('人工编程', default=False, readonly=True)
|
manual_quotation = fields.Boolean('人工编程', default=False, readonly=True)
|
||||||
machining_drawings = fields.Binary('2D加工图纸', readonly=True)
|
machining_drawings = fields.Binary('2D加工图纸', readonly=True)
|
||||||
quality_standard = fields.Binary('质检标准', readonly=True)
|
quality_standard = fields.Binary('质检标准', readonly=True)
|
||||||
part_name = fields.Char(string='零件名称', readonly=True)
|
part_name = fields.Char(string='零件名称', compute='_compute_related_product', readonly=True, store=True)
|
||||||
part_number = fields.Char(string='零件图号', readonly=True)
|
part_number = fields.Char(string='零件图号', compute='_compute_related_product', readonly=True, store=True)
|
||||||
machining_drawings_name = fields.Char(string='零件图号名称', readonly=True)
|
machining_drawings_name = fields.Char(string='零件图号名称', readonly=True)
|
||||||
machining_drawings_mimetype = fields.Char(string='零件图号类型', readonly=True)
|
machining_drawings_mimetype = fields.Char(string='零件图号类型', readonly=True)
|
||||||
|
|
||||||
|
@api.depends('name')
|
||||||
|
def _compute_related_product(self):
|
||||||
|
for record in self:
|
||||||
|
if record.categ_id.name == '坯料':
|
||||||
|
product_name = ''
|
||||||
|
match = re.search(r'(S\d{5}-\d)', record.name)
|
||||||
|
# 如果匹配成功,提取结果
|
||||||
|
if match:
|
||||||
|
product_name = match.group(0)
|
||||||
|
sale_order_name = ''
|
||||||
|
match_sale = re.search(r'S(\d+)', record.name)
|
||||||
|
if match_sale:
|
||||||
|
sale_order_name = match_sale.group(0)
|
||||||
|
sale_order = self.env['sale.order'].sudo().search(
|
||||||
|
[('name', '=', sale_order_name)])
|
||||||
|
if sale_order:
|
||||||
|
filtered_order_line = sale_order.order_line.filtered(
|
||||||
|
lambda order_line: re.search(f'{product_name}$', order_line.product_id.name)
|
||||||
|
)
|
||||||
|
record.part_number = filtered_order_line.product_id.part_number if filtered_order_line else None
|
||||||
|
record.part_name = filtered_order_line.product_id.part_name if filtered_order_line else None
|
||||||
|
|
||||||
@api.constrains('tool_length')
|
@api.constrains('tool_length')
|
||||||
def _check_tool_length_size(self):
|
def _check_tool_length_size(self):
|
||||||
if self.tool_length > 1000000:
|
if self.tool_length > 1000000:
|
||||||
|
|||||||
@@ -117,6 +117,8 @@ class PurchaseOrderLine(models.Model):
|
|||||||
@api.depends('product_id')
|
@api.depends('product_id')
|
||||||
def _compute_related_product(self):
|
def _compute_related_product(self):
|
||||||
for record in self:
|
for record in self:
|
||||||
|
if record.part_number or record.part_name:
|
||||||
|
continue
|
||||||
if record.product_id.categ_id.name == '坯料':
|
if record.product_id.categ_id.name == '坯料':
|
||||||
product_name = ''
|
product_name = ''
|
||||||
match = re.search(r'(S\d{5}-\d)', record.product_id.name)
|
match = re.search(r'(S\d{5}-\d)', record.product_id.name)
|
||||||
|
|||||||
@@ -1032,6 +1032,8 @@ class ReStockMove(models.Model):
|
|||||||
productions = self.env['mrp.production'].search(
|
productions = self.env['mrp.production'].search(
|
||||||
[('origin', '=', production.origin), ('product_id', '=', production.product_id.id)])
|
[('origin', '=', production.origin), ('product_id', '=', production.product_id.id)])
|
||||||
res['origin'] = ','.join(productions.mapped('name'))
|
res['origin'] = ','.join(productions.mapped('name'))
|
||||||
|
if self.picking_type_id.name == '客供料入库':
|
||||||
|
self.picking_id.sudo().write({'origin': res['origin'] if res.get('origin') else self[0].picking_id.origin})
|
||||||
return res
|
return res
|
||||||
|
|
||||||
def _get_new_picking_values(self):
|
def _get_new_picking_values(self):
|
||||||
|
|||||||
@@ -67,6 +67,16 @@
|
|||||||
<filter string="追溯参考" name="retrospect" domain="[]"
|
<filter string="追溯参考" name="retrospect" domain="[]"
|
||||||
context="{'group_by': 'retrospect_ref'}"/>
|
context="{'group_by': 'retrospect_ref'}"/>
|
||||||
</xpath>
|
</xpath>
|
||||||
|
<xpath expr="//field[@name='picking_type_id']" position="after">
|
||||||
|
<field name="product_id"
|
||||||
|
string="零件图号"
|
||||||
|
filter_domain="[('product_id.part_number', 'ilike', self)]"
|
||||||
|
/>
|
||||||
|
<field name="product_id"
|
||||||
|
string="零件名称"
|
||||||
|
filter_domain="[('product_id.part_name', 'ilike', self)]"
|
||||||
|
/>
|
||||||
|
</xpath>
|
||||||
</field>
|
</field>
|
||||||
</record>
|
</record>
|
||||||
|
|
||||||
|
|||||||
@@ -46,8 +46,12 @@ class ProductionWizard(models.TransientModel):
|
|||||||
mrp_workorder_list = self.mrp_production_id.workorder_ids.filtered(lambda kw: kw.rfid_code)
|
mrp_workorder_list = self.mrp_production_id.workorder_ids.filtered(lambda kw: kw.rfid_code)
|
||||||
for workorder in mrp_workorder_list:
|
for workorder in mrp_workorder_list:
|
||||||
rfid_code = workorder.rfid_code
|
rfid_code = workorder.rfid_code
|
||||||
workorder.write({'rfid_code_old': rfid_code,
|
workorder.filtered(lambda wo: wo.routing_type == '装夹预调' and wo.rfid_code is not False).write(
|
||||||
'rfid_code': False})
|
{'rfid_code_old': rfid_code, 'rfid_code': False})
|
||||||
|
workorder.filtered(lambda wo: (wo.routing_type != '装夹预调' and
|
||||||
|
(wo.rfid_code_old is not False or wo.rfid_code is not False))).write(
|
||||||
|
{'rfid_code_old': False, 'rfid_code': False})
|
||||||
|
|
||||||
if self.is_remanufacture is True:
|
if self.is_remanufacture is True:
|
||||||
ret = {'programming_list': [], 'is_reprogramming': self.is_reprogramming}
|
ret = {'programming_list': [], 'is_reprogramming': self.is_reprogramming}
|
||||||
if self.is_reprogramming is True:
|
if self.is_reprogramming is True:
|
||||||
|
|||||||
@@ -140,7 +140,7 @@ class ReworkWizard(models.TransientModel):
|
|||||||
and item.process_parameters_id == work.surface_technics_parameters_id) or
|
and item.process_parameters_id == work.surface_technics_parameters_id) or
|
||||||
(item.route_id.name == work.name and item.panel
|
(item.route_id.name == work.name and item.panel
|
||||||
and item.panel == work.processing_panel) or
|
and item.panel == work.processing_panel) or
|
||||||
(item.route_id == work.routing_workcenter_id
|
(item.route_id == work.routing_work_center_id
|
||||||
and not work.processing_panel
|
and not work.processing_panel
|
||||||
and not work.surface_technics_parameters_id))
|
and not work.surface_technics_parameters_id))
|
||||||
if route:
|
if route:
|
||||||
|
|||||||
@@ -12,18 +12,18 @@
|
|||||||
<div class="alert alert-warning" role="alert">
|
<div class="alert alert-warning" role="alert">
|
||||||
<field name="display_message" readonly="1" nolabel="1"/>
|
<field name="display_message" readonly="1" nolabel="1"/>
|
||||||
</div>
|
</div>
|
||||||
<field name="related_docs">
|
<field name="related_docs" >
|
||||||
<tree string="下游单据" create="false" edit="false" delete="false">
|
<tree string="下游单据" create="false" edit="false" delete="false" attrs="{'merge_fields': 'category,doc_name,operation_type,doc_number,doc_state, cancel_reason', 'merge_key': 'doc_number'}">
|
||||||
<!-- <field name="sequence" string="序号"/> -->
|
<!-- <field name="sequence" string="序号"/> -->
|
||||||
<field name="category" string="大类"/>
|
<field name="category" string="大类"/>
|
||||||
<field name="doc_name" string="单据名称"/>
|
<field name="doc_name" string="单据名称"/>
|
||||||
<field name="operation_type" string="作业类型"/>
|
<field name="operation_type" string="作业类型"/>
|
||||||
<field name="doc_number" string="单据编号"/>
|
<field name="doc_number" string="单据编号"/>
|
||||||
|
<field name="doc_state" string="单据状态"/>
|
||||||
|
<field name="cancel_reason" string="禁止取消原因"/>
|
||||||
<field name="line_number" string="行号"/>
|
<field name="line_number" string="行号"/>
|
||||||
<field name="product_name" string="产品名称"/>
|
<field name="product_name" string="产品名称"/>
|
||||||
<field name="quantity_str" string="数量"/>
|
<field name="quantity_str" string="数量"/>
|
||||||
<field name="doc_state" string="单据状态"/>
|
|
||||||
<field name="cancel_reason" string="禁止取消原因"/>
|
|
||||||
</tree>
|
</tree>
|
||||||
</field>
|
</field>
|
||||||
<footer>
|
<footer>
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
# Part of SmartGo. See LICENSE file for full copyright and licensing details.
|
# Part of SmartGo. See LICENSE file for full copyright and licensing details.
|
||||||
import logging
|
import logging
|
||||||
|
import traceback
|
||||||
|
|
||||||
import requests
|
import requests
|
||||||
|
|
||||||
@@ -90,7 +91,8 @@ class ResConfigSettings(models.TransientModel):
|
|||||||
_logger.info("同步坯料冗余完成")
|
_logger.info("同步坯料冗余完成")
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
_logger.info("sf_all_sync error: %s" % e)
|
traceback_error = traceback.format_exc()
|
||||||
|
_logger.error("sf_all_sync error:%s" % traceback_error)
|
||||||
raise ValidationError("数据错误导致同步失败,请联系管理员")
|
raise ValidationError("数据错误导致同步失败,请联系管理员")
|
||||||
|
|
||||||
@api.model
|
@api.model
|
||||||
|
|||||||
@@ -24,7 +24,8 @@
|
|||||||
'views/quality_cnc_test_view.xml',
|
'views/quality_cnc_test_view.xml',
|
||||||
'views/mrp_workorder.xml',
|
'views/mrp_workorder.xml',
|
||||||
'views/quality_check_view.xml',
|
'views/quality_check_view.xml',
|
||||||
'views/quality_company.xml'
|
'views/quality_company.xml',
|
||||||
|
'wizard/check_picking_wizard_view.xml',
|
||||||
],
|
],
|
||||||
|
|
||||||
'assets': {
|
'assets': {
|
||||||
|
|||||||
@@ -5,23 +5,46 @@ class StockPicking(models.Model):
|
|||||||
_inherit = 'stock.picking'
|
_inherit = 'stock.picking'
|
||||||
|
|
||||||
def button_validate(self):
|
def button_validate(self):
|
||||||
# """
|
|
||||||
# 调拨单若关联了质量检查单,验证调拨单时,应校验是否有不合格品,若存在,应弹窗提示:
|
|
||||||
# “警告:存在不合格产品XXXX n 件、YYYYY m件,继续调拨请点“确认”,否则请取消?”
|
|
||||||
# """
|
|
||||||
# if self.quality_check_ids.filtered(lambda qc: qc.quality_state == 'fail'):
|
|
||||||
# return {
|
|
||||||
# 'type': 'ir.actions.act_window',
|
|
||||||
# 'res_model': 'sf.functional.tool.assembly.order',
|
|
||||||
# 'name': ' ',
|
|
||||||
# 'view_mode': 'form',
|
|
||||||
# 'target': 'new',
|
|
||||||
# 'context': {'': True}
|
|
||||||
# }
|
|
||||||
|
|
||||||
out_quality_check = self.env['quality.check'].search([('picking_id', '=', self.id), ('test_type_id.name', '=', '出厂检验报告')])
|
"""
|
||||||
|
出厂检验报告上传
|
||||||
|
"""
|
||||||
|
|
||||||
|
out_quality_check = self.env['quality.check'].search(
|
||||||
|
[('picking_id', '=', self.id), ('test_type_id.name', '=', '出厂检验报告')])
|
||||||
if not out_quality_check.is_factory_report_uploaded:
|
if not out_quality_check.is_factory_report_uploaded:
|
||||||
if out_quality_check and self.state == 'assigned':
|
if out_quality_check and self.state == 'assigned':
|
||||||
out_quality_check.upload_factory_report()
|
out_quality_check.upload_factory_report()
|
||||||
|
|
||||||
|
"""
|
||||||
|
调拨单若关联了质量检查单,验证调拨单时,应校验是否有不合格品,若存在,应弹窗提示:
|
||||||
|
“警告:存在不合格产品XXXX n 件、YYYYY m件,继续调拨请点“确认”,否则请取消?”
|
||||||
|
"""
|
||||||
|
context = self.env.context
|
||||||
|
if not context.get('again_validate') and self.quality_check_ids.filtered(lambda qc: qc.quality_state == 'fail'):
|
||||||
|
# 回滚事务,为二次确认/取消做准备
|
||||||
|
self.env.cr.rollback()
|
||||||
|
quality_check_ids = self.quality_check_ids.filtered(lambda qc: qc.quality_state == 'fail')
|
||||||
|
product_list = list(set([quality_check_id.product_id for quality_check_id in quality_check_ids]))
|
||||||
|
fail_check_text = ''
|
||||||
|
for product_id in product_list:
|
||||||
|
check_ids = quality_check_ids.filtered(lambda qc: qc.product_id == product_id)
|
||||||
|
if all(check_id.measure_on == 'move_line' for check_id in check_ids):
|
||||||
|
number = sum(check_ids.mapped('qty_line'))
|
||||||
|
else:
|
||||||
|
number = sum(self.move_ids_without_package.filtered(
|
||||||
|
lambda ml: ml.product_id == product_id).mapped('quantity_done'))
|
||||||
|
fail_check_text = (f'{fail_check_text}、{product_id.name} {number}件'
|
||||||
|
if fail_check_text != '' else f'{product_id.name} {number}件')
|
||||||
|
return {
|
||||||
|
'type': 'ir.actions.act_window',
|
||||||
|
'res_model': 'picking.validate.check.wizard',
|
||||||
|
'name': '质检不合格提示',
|
||||||
|
'view_mode': 'form',
|
||||||
|
'target': 'new',
|
||||||
|
'context': {
|
||||||
|
'default_picking_id': self.id,
|
||||||
|
'default_fail_check_text': f'警告:存在不合格产品{fail_check_text},继续调拨请点“确认”,否则请取消?',
|
||||||
|
'again_validate': True}
|
||||||
|
}
|
||||||
return super(StockPicking, self).button_validate()
|
return super(StockPicking, self).button_validate()
|
||||||
|
|||||||
@@ -73,6 +73,6 @@ access_quality_cnc_test_group_quality_director,quality_cnc_test_group_quality_di
|
|||||||
|
|
||||||
access_quality_cnc_test_group_sf_equipment_user,quality_cnc_test_group_sf_equipment_user,model_quality_cnc_test,sf_base.group_sf_equipment_user,1,1,0,0
|
access_quality_cnc_test_group_sf_equipment_user,quality_cnc_test_group_sf_equipment_user,model_quality_cnc_test,sf_base.group_sf_equipment_user,1,1,0,0
|
||||||
|
|
||||||
|
access_picking_validate_check_wizard,access.picking_validate_check_wizard,model_picking_validate_check_wizard,quality.group_quality_user,1,1,1,0
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
|
@@ -0,0 +1 @@
|
|||||||
|
from . import check_picking_wizard
|
||||||
|
|||||||
17
sf_quality/wizard/check_picking_wizard.py
Normal file
17
sf_quality/wizard/check_picking_wizard.py
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
from odoo import api, models,fields
|
||||||
|
|
||||||
|
|
||||||
|
class PickingValidateCheckWizard(models.TransientModel):
|
||||||
|
_name = 'picking.validate.check.wizard'
|
||||||
|
_description = '调拨质检不合格二次验证'
|
||||||
|
|
||||||
|
picking_id = fields.Many2one('stock.picking', '调拨单')
|
||||||
|
fail_check_text = fields.Text('提示信息')
|
||||||
|
|
||||||
|
def confirm_picking_validate_check(self):
|
||||||
|
res = self.picking_id.button_validate()
|
||||||
|
return res
|
||||||
|
|
||||||
|
def cancel_picking_validate_check(self):
|
||||||
|
# 这里是取消后的逻辑
|
||||||
|
return {'type': 'ir.actions.act_window_close'}
|
||||||
15
sf_quality/wizard/check_picking_wizard_view.xml
Normal file
15
sf_quality/wizard/check_picking_wizard_view.xml
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
<odoo>
|
||||||
|
<record id="picking_validate_check_wizard_form" model="ir.ui.view">
|
||||||
|
<field name="name">picking.validate.check.wizard</field>
|
||||||
|
<field name="model">picking.validate.check.wizard</field>
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<form>
|
||||||
|
<field name="fail_check_text" readonly="True"/>
|
||||||
|
<footer>
|
||||||
|
<button name="confirm_picking_validate_check" type="object" class="btn-primary" string="确认"/>
|
||||||
|
<button name="cancel_picking_validate_check" type="object" string="取消"/>
|
||||||
|
</footer>
|
||||||
|
</form>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
</odoo>
|
||||||
@@ -374,6 +374,8 @@ class RePurchaseOrder(models.Model):
|
|||||||
'product_qty': 1,
|
'product_qty': 1,
|
||||||
'product_uom': server_template.uom_id.id,
|
'product_uom': server_template.uom_id.id,
|
||||||
'related_product': production.product_id.id,
|
'related_product': production.product_id.id,
|
||||||
|
'part_number': pp.part_number,
|
||||||
|
'part_name': pp.part_name,
|
||||||
}))
|
}))
|
||||||
# 获取服务商品最后一个供应商的采购员
|
# 获取服务商品最后一个供应商的采购员
|
||||||
purchase_user_id = server_template.seller_ids[-1].partner_id.purchase_user_id
|
purchase_user_id = server_template.seller_ids[-1].partner_id.purchase_user_id
|
||||||
|
|||||||
@@ -42,20 +42,20 @@
|
|||||||
<field name="currency_id" position="after">
|
<field name="currency_id" position="after">
|
||||||
<field name="remark" attrs="{'readonly': [('state', 'in', ['purchase'])]}" string="订单备注"/>
|
<field name="remark" attrs="{'readonly': [('state', 'in', ['purchase'])]}" string="订单备注"/>
|
||||||
</field>
|
</field>
|
||||||
<xpath expr="//form/header/button[@name='action_rfq_send'][1]" position="replace">
|
<xpath expr="//form/header/button[@name='action_rfq_send'][1]" position="attributes">
|
||||||
<button name="action_rfq_send" states="draft" string="通过Email发送采购单" type="object"
|
<attribute name="invisible">1</attribute>
|
||||||
context="{'send_rfq':True}" class="oe_highlight" data-hotkey="g"
|
|
||||||
groups="sf_base.group_purchase,sf_base.group_purchase_director"/>
|
|
||||||
</xpath>
|
</xpath>
|
||||||
<xpath expr="//form/header/button[@name='action_rfq_send'][2]" position="replace">
|
<xpath expr="//form/header/button[@name='action_rfq_send'][2]" position="attributes">
|
||||||
<button name="action_rfq_send" states="sent" string="通过Email重新发送采购单" type="object"
|
<attribute name="invisible">1</attribute>
|
||||||
context="{'send_rfq':True}" data-hotkey="g"
|
|
||||||
groups="sf_base.group_purchase,sf_base.group_purchase_director"/>
|
|
||||||
</xpath>
|
</xpath>
|
||||||
<xpath expr="//form/header/button[@name='action_rfq_send'][3]" position="replace">
|
<xpath expr="//form/header/button[@name='action_rfq_send'][3]" position="attributes">
|
||||||
<button name="action_rfq_send" states="purchase" string="通过Email发送订单" type="object"
|
<attribute name="invisible">1</attribute>
|
||||||
context="{'send_rfq':False}" data-hotkey="g"
|
</xpath>
|
||||||
groups="sf_base.group_purchase,sf_base.group_purchase_director"/>
|
<xpath expr="//form/header/button[@name='print_quotation'][1]" position="attributes">
|
||||||
|
<attribute name="invisible">1</attribute>
|
||||||
|
</xpath>
|
||||||
|
<xpath expr="//form/header/button[@name='print_quotation'][2]" position="attributes">
|
||||||
|
<attribute name="invisible">1</attribute>
|
||||||
</xpath>
|
</xpath>
|
||||||
|
|
||||||
<!-- <xpath expr="//form/header/button[@name='print_quotation[1]']" position="attributes">-->
|
<!-- <xpath expr="//form/header/button[@name='print_quotation[1]']" position="attributes">-->
|
||||||
@@ -353,5 +353,9 @@
|
|||||||
</field>
|
</field>
|
||||||
<field name="view_mode">tree,kanban,form,activity</field>
|
<field name="view_mode">tree,kanban,form,activity</field>
|
||||||
</record>
|
</record>
|
||||||
|
|
||||||
|
<record id="purchase.purchase_rfq" model="ir.actions.act_window">
|
||||||
|
<field name="context">{'quotation_only': True,"search_default_draft":1}</field>
|
||||||
|
</record>
|
||||||
</data>
|
</data>
|
||||||
</odoo>
|
</odoo>
|
||||||
@@ -983,19 +983,19 @@ class FunctionalToolAssembly(models.Model):
|
|||||||
|
|
||||||
# 物料必填校验
|
# 物料必填校验
|
||||||
if not self.handle_code_id:
|
if not self.handle_code_id:
|
||||||
raise ValidationError('缺少【刀柄】物料信息!')
|
raise ValidationError('请扫【刀柄】RFID,录入【刀柄】物料信息!')
|
||||||
if self.integral_lot_id:
|
if self.integral_lot_id:
|
||||||
if not self.integral_verify:
|
if not self.integral_verify:
|
||||||
raise ValidationError('【整体式刀具】未进行验证!')
|
raise ValidationError('请扫【整体式刀具】的货位编码进行验证!')
|
||||||
elif self.blade_lot_id:
|
elif self.blade_lot_id:
|
||||||
if not self.blade_verify:
|
if not self.blade_verify:
|
||||||
raise ValidationError('【刀片】未进行验证!')
|
raise ValidationError('请扫【刀片】的货位编码进行验证!')
|
||||||
if self.bar_lot_id:
|
if self.bar_lot_id:
|
||||||
if not self.bar_verify:
|
if not self.bar_verify:
|
||||||
raise ValidationError('【刀杆】未进行验证!')
|
raise ValidationError('请扫【刀杆】的货位编码进行验证!')
|
||||||
elif self.pad_lot_id:
|
elif self.pad_lot_id:
|
||||||
if not self.pad_verify:
|
if not self.pad_verify:
|
||||||
raise ValidationError('【刀盘】未进行验证!')
|
raise ValidationError('请扫【刀盘】的货位编码进行验证!')
|
||||||
# 组装参数必填校验
|
# 组装参数必填校验
|
||||||
if self.after_assembly_max_lifetime_value == 0:
|
if self.after_assembly_max_lifetime_value == 0:
|
||||||
raise ValidationError('组装参数信息【最大寿命值】不能为0!')
|
raise ValidationError('组装参数信息【最大寿命值】不能为0!')
|
||||||
|
|||||||
@@ -1140,7 +1140,7 @@ class SfPickingType(models.Model):
|
|||||||
action = super(SfPickingType, self)._get_action(action_xmlid)
|
action = super(SfPickingType, self)._get_action(action_xmlid)
|
||||||
if not self.env.user.has_group('base.group_system'):
|
if not self.env.user.has_group('base.group_system'):
|
||||||
action['context']['create'] = False
|
action['context']['create'] = False
|
||||||
if self.sequence_code in ['DL', 'INT', 'PC']:
|
if self.sequence_code in ['INT', 'PC']:
|
||||||
action['context']['search_default_retrospect'] = 1
|
action['context']['search_default_retrospect'] = 1
|
||||||
return action
|
return action
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user