Commit aed9d6e7 by 夏超

[fix] 修改问题

parent b90cb138
......@@ -25,6 +25,36 @@ class JzjxInheritProduction(InheritProduction):
res.update({"repair_process_id": repair_process_id})
return res
def check_join_in_data(self, values):
work_order_id = values.get('work_order_id', False) # 工单ID
product_id = values.get('product_id', False) # 产品
process_id = values.get('process_id', False) # 工序
finish_qty = float(values.get('finish_qty') or 0) # 合格数量
unqualified_qty = float(values.get('unqualified_qty') or 0) # 不合格数量
work_hours = float(values.get('work_hours') or 0) # 工时数
employee_list = values.get('employee_list', []) # 人员分配:[{'employee_id':1, 'weighted': 1}]
repair_qty = values.get('repair_qty', False) # 人员分配:[{'employee_id':1, 'weighted': 1}]
# 校验入参工单ID、产品、工序、人员列表、不合格数和报废数、返修数
if not work_order_id and (not product_id or not process_id):
return {"state": "error", "msgs": "无工单ID时表示无工单报工,必须入参产品ID和工序ID"}
if not employee_list or type(employee_list) not in (list, tuple):
return {"state": "error", "msgs": "请选择人员"}
if not repair_qty or (float(finish_qty) < 0 or float(unqualified_qty) < 0):
return {"state": "error", "msgs": "合格数或不合格数不得小于0"}
# 判断是否能获取到辅计量数据
aux_list = values.get('aux_list', []) # 合格数量辅计量数据
unaux_list = values.get('unaux_list', []) # 不合格辅计量数据
if aux_list or unaux_list:
finish_aux_list = [aux.get('aux_qty', 0) for aux in aux_list if aux.get('aux_qty', 0) > 0]
unqualified_aux_list = [aux.get('aux_qty', 0) for aux in unaux_list if aux.get('aux_qty', 0) > 0]
if not float(finish_qty) and not float(unqualified_qty) and not float(
work_hours) and not finish_aux_list and not unqualified_aux_list:
return {"state": "error", "msgs": "合格数或不合格数或工时数不可同时为0"}
else:
if not repair_qty and not float(finish_qty) and not float(unqualified_qty) and not float(work_hours):
return {"state": "error", "msgs": "合格数或不合格数或工时数不可同时为0"}
return False
class JzjxRokeRefixAutoWorkOrder(http.Controller):
......
......@@ -132,6 +132,48 @@ class RokeWorkstationWorkOrderModel(http.Controller):
}
return {"code": 0, "message": f"获取成功!", "data": data}
@http.route('/roke/workstation/craft_design/workstation_process/save', type='json', auth="user", cors='*', csrf=False)
def save_craft_design_workstation_process(self):
kwargs = http.request.jsonrequest
routing_id = kwargs.get("routing_id", False)
lines = kwargs.get("lines", [])
if not routing_id:
return {"code": 1, "message": "入参错误,工艺路线ID位必传参数。", "data": None}
routing_obj = http.request.env(user=SUPERUSER_ID)['roke.routing'].search([
("id", "=", int(routing_id))
])
if not routing_obj:
return {"code": 1, "message": "工艺路线不存在或已删除", "data": None}
for line in lines:
if line["type"] == "delete":
line_id = line["line_id"]
routing_obj.line_ids.filtered(
lambda l: l.id == line_id).unlink()
elif line["type"] == "add":
sequence = line["sequence"]
process_id = line["process_id"]
routing_obj.write({
"line_ids": [(0, 0, {
"process_id": process_id,
"sequence": sequence
})]
})
elif line["type"] == "update":
line_id = line["line_id"]
sequence = line["sequence"]
routing_obj.line_ids.filtered(lambda l: l.id == line_id).write({
"sequence": sequence
})
else:
pass
return {"code": 0, "message": "工序信息添加成功", "data": {"routing_id": routing_obj.id}}
@http.route('/roke/workstation/work_record/workstation_work_record', type='json', auth='user', csrf=False, cors="*")
def get_workstation_work_record(self):
"""
......
......@@ -98,8 +98,15 @@ class InheritProductionTask(models.Model):
def craft_design(self):
if not self.routing_id:
raise ValidationError("该任务没有工艺路线!请先选择工艺路线。")
if not self.routing_id.routing_task_id or self.routing_id.routing_task_id.id != self.id:
routing_id = self.env["roke.routing"].create({
"name": self.product_id.name or "",
"state": "确认",
"routing_task_id": self.id
})
self.write({
"routing_id": routing_id.id,
})
elif not self.routing_id.routing_task_id or self.routing_id.routing_task_id.id != self.id:
routing_id = self.routing_id.copy()
routing_id.update({
"state": "确认",
......
......@@ -19,52 +19,6 @@
<body id="bodyId" style="display: none;">
<div id="app" v-loading.body.fullscreen.lock="loading">
<!-- 左侧树形区域 -->
<!-- <div class="leftBox">
<div class="searchBox">
<el-input prefix-icon="el-icon-search" v-model="treeFilterValue" size="medium"
placeholder="请输入关键字"></el-input>
<div class="unfoldBox" @click="unfoldHandel">
<el-tooltip content="全部折叠">
<i class="iconfont icon-zhedie"></i>
</el-tooltip>
</div>
</div>
<div class="treeBox">
<el-tree class="treeComBox" ref="treeRef" node-key="id" highlight-current :data="treeList"
:filter-node-method="treeFilterNode" :props="defaultProps" :load="loadNode" lazy
@node-click="handleNodeClick">
<span class="custom-tree-node" slot-scope="{ node, data }">
<span style="padding-right: 15px;" class="textBox">
<i v-if="node.expanded&&data.type=='category'" class="iconfont icon-wenjianjiazhankai"></i>
<i v-if="!node.expanded&&data.type=='category'" class="iconfont icon-wenjianjiaguanbi"></i>
<i v-if="node.expanded&&data.type=='product'" class="iconfont icon-chanpin2"></i>
<i v-if="!node.expanded&&data.type=='product'" class="iconfont icon-chanpin1"></i>
<i v-if="node.expanded&&data.type=='bom'" class="iconfont icon-BOM1"></i>
<i v-if="!node.expanded&&data.type=='bom'" class="iconfont icon-BOM"></i>
[[ node.label ]]
<span v-if="('product_active' in data)&&!data.product_active">(已归档)</span>
<span v-if="data.bom_type=='bomline'||data.bom_type=='bom+bomline'">
([[data.quantity]])
</span>
</span>
<span class="iconBox">
<el-dropdown placement="bottom" @visible-change="menuVisibleChange($event,node,data)"
@command="menuCommandHandle($event,node,data)">
<i class="el-icon-more iconClass"></i>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item :command="item.value" v-for="(item,index) in menuList"
:key="item.index">
[[item.text]]
</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</span>
</span>
</el-tree>
</div>
</div> -->
<!-- 右侧内容区域 -->
<div class="rightBox">
<div class="rightTopBox">
<div class="infoBox">
......@@ -332,20 +286,36 @@
</div>
<!-- 关键物料 -->
<div v-if="activeIndex=='关键物料'" style="width: 100%; padding: 0 15px;">
<el-table ref="keyMaterials" :data="isEdit?standardsCopyList:standardsList"
:height="windowHeight" :header-cell-style="{backgroundColor:'#f5f7fa'}"
style="width: 100%">
<el-table ref="keyMaterials" :data="isEdit?key_materials_listTow:key_materials_list" :height="windowHeight"
:header-cell-style="{backgroundColor:'#f5f7fa'}" style="width: 100%">
<el-table-column type="index" label="序号" align="center" width="50"></el-table-column>
<el-table-column label="物料名称" align="center">
<template slot-scope="scope">
<el-input v-if="isEdit" size="medium" v-model="scope.row.title"></el-input>
<span v-else>[[scope.row.title]]</span>
<el-select v-if="isEdit" v-model="scope.row.product_id" placeholder="请选择物料"
style="width: 100%;">
<el-option v-for="(item,index) in productList" :key="index"
:label="item.name" :value="item.id">
</el-option>
</el-select>
<span v-else>[[scope.row.product_name]]</span>
</template>
</el-table-column>
<el-table-column label="数量" align="center">
<template slot-scope="scope">
<el-input v-if="isEdit" size="medium" v-model="scope.row.content"></el-input>
<span v-else>[[scope.row.content]]</span>
<el-input-number v-if="isEdit" size="medium" v-model="scope.row.qty"
:min="0"></el-input-number>
<span v-else>[[scope.row.qty]]</span>
</template>
</el-table-column>
<el-table-column label="必投" align="center">
<template slot-scope="scope">
<div v-if="isEdit">
<el-radio-group v-model="scope.row.must">
<el-radio :label="true"></el-radio>
<el-radio :label="false"></el-radio>
</el-radio-group>
</div>
<span v-else>[[ scope.row.must?'是':'否']]</span>
</template>
</el-table-column>
<el-table-column v-if="!isEdit" label="操作" align="center" width="80">
......@@ -357,8 +327,7 @@
</el-table-column>
</el-table>
<div style="padding: 10px;">
<el-button type="primary" size="small" :disabled="!selProductProcessData||isEdit"
@click="addInfoHandle('关键物料')">
<el-button type="primary" size="small" :disabled="!selProductProcessData||isEdit" @click="addInfoHandle('关键物料')">
添加
</el-button>
<el-button type="primary" size="small" @click="editInfoHandle('关键物料')"
......@@ -557,6 +526,39 @@
<el-button size="small" type="primary" @click="dialogSaveHandle('选择不良类型')">确定</el-button>
</span>
</el-dialog>
<!-- 添加关键物料 -->
<el-dialog title="添加关键物料" :visible.sync="key_materialsShow" destroy-on-close width="50%"
@close="dialogCloseHandle('添加关键物料')">
<div style="max-height: 60vh; overflow-y: scroll; overflow-x: hidden;">
<el-form class="fromBox" :model="materialsForm" :rules="materialsRules" ref="materialsFormRef"
label-width="6rem">
<el-form-item label="物料:" prop="product_id" required>
<el-select v-model="materialsForm.product_id" placeholder="请选择物料" style="width: 100%;"
@change="selectTyleChange">
<el-option v-for="(item,index) in productList" :key="index" :label="item.name"
:value="item.id">
</el-option>
</el-select>
</el-form-item>
<el-form-item label="数量:" prop="qty">
<el-input-number v-model="materialsForm.qty" placeholder="请填写标准下限" :min="0"></el-input-number>
</el-form-item>
<el-form-item label="是否必投:" prop="must">
<div>
<el-radio-group v-model="materialsForm.must">
<el-radio label="是"></el-radio>
<el-radio label="否"></el-radio>
</el-radio-group>
</div>
</el-form-item>
</el-form>
</div>
<span slot="footer" class="dialog-footer">
<el-button size="small" @click="dialogCloseHandle('添加关键物料')">取消</el-button>
<el-button size="small" type="primary" @click="dialogSaveHandle('添加关键物料')">确定</el-button>
</span>
</el-dialog>
</div>
</body>
......@@ -582,6 +584,7 @@
data() {
return {
windowHeight: document.documentElement.clientHeight - 190, // 高度
// baseURL: 'http://192.168.1.117:8069', // 基地址
baseURL: '', // 基地址
// baseURL: 'http://workstation.rokeris.com', // 基地址
loading: false, // 全局加载效果
......@@ -646,6 +649,19 @@
selBadnessTypeDialogShow: false, // 选择不良类型弹窗
badnessTypeList: [], // 不良类型列表
selBadnessTypeData: [], // 选中的不良类型列表
key_materials_list: [],//关键物料列表
key_materialsShow: false,
materialsForm: {
product_id: null,
qty: null,
must: null
},
materialsRules: {
product_id: [{ required: true, trigger: 'blur', message: '请选择物料' }],
qty: [{ required: true, trigger: 'blur', message: '请输入数量' }],
must: [{ required: true, trigger: 'blur', message: '请选择是否必投' }],
},
selProcessHandleItem:null
}
},
computed: {
......@@ -669,6 +685,10 @@
scrapReasonsList() {
return this.selProductProcessData?.scrap_reasons ? this.selProductProcessData.scrap_reasons : []
},
// 关键物料列表
key_materials_listTow() {
return this.key_materials_list ? this.key_materials_list : []
},
},
watch: {
......@@ -714,7 +734,7 @@
this.routingData.routing_id = this.getUrlSearch('routing_id')
// this.routingData.product_id = this.getUrlSearch('product_id')
let config = {
product_id:this.getUrlSearch('product_id')
product_id: this.getUrlSearch('product_id')
}
this.getworkstation_product(config).then(result => {
this.treeActiveData = result.result.data
......@@ -735,6 +755,7 @@
}).catch(error => {
this.errorHandle(error, true)
})
},
mounted() {
// 在 mounted 钩子函数时才显示内容,防止出现白屏问题
......@@ -1190,6 +1211,29 @@
})
})
},
// 获取工艺明细的关键物料
getworkstation_bom(config) {
return new Promise((resolve, reject) => {
axios({
method: "POST",
url: this.baseURL + "/roke/workstation/craft_design/workstation_bom/get",
data: config,
headers: {
'Content-Type': 'application/json',
},
}).then((result) => {
if (result?.data?.result?.code == 0) {
resolve(result.data)
} else if (result?.data?.result?.code == 1) {
reject(result.data.result.message)
} else if (result?.data?.error) {
reject(result.data.error.message)
}
}).catch((error) => {
reject("获取工序列表失败!")
})
})
},
// 删除工序方法
deleteProcessApi(config) {
return new Promise((resolve, reject) => {
......@@ -1249,7 +1293,7 @@
return new Promise((resolve, reject) => {
axios({
method: "POST",
url: this.baseURL + "/roke/workstation/routing/process/save",
url: this.baseURL + "/roke/workstation/craft_design/workstation_process/save",
data: config,
headers: {
'Content-Type': 'application/json',
......@@ -1267,6 +1311,32 @@
})
})
},
// 获取产品列表
get_product_list() {
return new Promise((resolve, reject) => {
axios({
method: "POST",
url: this.baseURL + "/roke/workstation/product/get_list",
data: {
limit: 1,
page: 1000
},
headers: {
'Content-Type': 'application/json',
},
}).then((result) => {
if (result?.data?.result?.code == 0) {
resolve(result.data)
} else if (result?.data?.result?.code == 1) {
reject(result.data.result.message)
} else if (result?.data?.error) {
reject(result.data.error.message)
}
}).catch((error) => {
reject("获取工序列表失败!")
})
})
},
// 工艺路线信息列表排序保存方法
routingInfoSortSaveApi(config) {
return new Promise((resolve, reject) => {
......@@ -1791,6 +1861,13 @@
this.selBadnessTypeDialogShow = false
this.badnessTypeList = []
this.selBadnessTypeData = []
} else if (type == '添加关键物料') {
this.key_materialsShow = false
this.materialsForm = {
product_id: null,
qty: null,
must: null
}
}
},
// 弹窗保存事件
......@@ -1927,7 +2004,8 @@
item['sequence'] = index + 1
})
let config = {
product_id: this.treeActiveData.type == "product" ? this.treeActiveData.id : this.treeActiveData.product_id,
// product_id: this.treeActiveData.type == "product" ? this.treeActiveData.id : this.treeActiveData.product_id,
routing_id: this.routingData.routing_id,
lines: lines
}
this.loading = true
......@@ -2115,6 +2193,42 @@
}).catch(error => {
})
} else if (type == '添加关键物料') {
this.$refs.materialsFormRef.validate((valid) => {
if (valid) {
let config = {
routing_line_id: this.selProductProcessData.line_id,
product_id: this.materialsForm.product_id,
qty: this.materialsForm.qty,
must: this.materialsForm.qty == '是' ? true : false
}
this.loading = true
this.requestApi('/roke/workstation/craft_design/workstation_bom/create', config).then(data => {
if(data.result.code == 0){
let config = {
routing_line_id: this.selProcessHandleItem.line_id
}
this.getworkstation_bom(config).then(result => {
result.result.data.forEach(item => {
item['show'] = false
})
this.key_materials_list = result.result.data
}).catch(error => {
this.errorHandle(error, true)
})
}
this.loading = false
this.$message.success(data.result.message)
this.dialogCloseHandle('添加关键物料')
}).catch(error => {
})
} else {
return false
}
})
}
},
// 创建BOM处理方法
......@@ -2302,6 +2416,8 @@
},
// 选中工序事件
selProcessHandle(item) {
console.log(item);
this.selProcessHandleItem = item
this.isEdit = false
if (item.show) {
item.show = false
......@@ -2311,6 +2427,18 @@
})
item.show = true
}
let config = {
// routing_line_id: 83
routing_line_id: item.line_id
}
this.getworkstation_bom(config).then(result => {
result.result.data.forEach(item => {
item['show'] = false
})
this.key_materials_list = result.result.data
}).catch(error => {
this.errorHandle(error, true)
})
},
// 工序列表排序结束事件
processSortEndHandle() {
......@@ -2334,6 +2462,15 @@
menuSelectHandle(index) {
this.activeIndex = index
this.isEdit = false
if(index === '关键物料'){
this.searchProductValue = ''
this.getProductListApi().then(result => {
this.loading = false
this.productList = result.result.data
}).catch(error => {
this.errorHandle(error, true)
})
}
},
// 添加按钮点击事件
addInfoHandle(type) {
......@@ -2341,6 +2478,8 @@
this.standardsDialogShow = true
} else if (type == '设备检查项') {
this.checksDialogShow = true
} else if (type == '关键物料') {
this.key_materialsShow = true
}
},
// 内容信息区域表格删除事件
......@@ -2421,6 +2560,19 @@
}).catch(error => {
this.errorHandle(error, true)
})
} else if (type == '关键物料') {
this.loading = true
this.requestApi('/roke/workstation/craft_design/workstation_bom/delete', { id: row.id }).then(result => {
this.loading = false
this.$message.success(result.result.message)
this.key_materials_list.forEach((item, index) => {
if (item.id == row.id) {
this.key_materials_list.splice(index, 1)
}
})
}).catch(error => {
this.errorHandle(error, true)
})
}
},
// 内容信息区域编辑、取消编辑按钮点击事件
......@@ -2438,7 +2590,12 @@
this.productionInfoData.capacity = this.treeActiveData.capacity
this.productionInfoData.fpy = this.treeActiveData.fpy
}
} else if (type == '关键物料') {
if (!this.isEdit) {
this.key_materials_list = JSON.parse(JSON.stringify(this.key_materials_listTow))
}
}
},
// 内容信息区域表格保存事件
saveInfoHandle(type) {
......@@ -2475,6 +2632,33 @@
}).catch(error => {
this.errorHandle(error, true)
})
} else if (type == '关键物料') {
let standard_info = []
this.key_materials_list.forEach(item => {
let obj = JSON.parse(JSON.stringify(item))
standard_info.push(obj)
})
this.loading = true
this.requestApi('/roke/workstation/craft_design/workstation_bom/update', { bom_info: standard_info }).then(result => {
if(result.result.code == 0){
let config = {
routing_line_id: this.selProcessHandleItem.line_id
}
this.getworkstation_bom(config).then(result => {
result.result.data.forEach(item => {
item['show'] = false
})
this.key_materials_list = result.result.data
}).catch(error => {
this.errorHandle(error, true)
})
}
this.loading = false
this.$message.success(result.result.message)
this.isEdit = false
}).catch(error => {
this.errorHandle(error, true)
})
}
},
// 上传附件按钮点击事件
......
......@@ -83,6 +83,16 @@ class InheritRokeCreateWorkRecordWizard(models.TransientModel):
"""
... # 去掉返修和报废的逻辑关系
def check_create_value(self):
"""
检查完成数、不合格数、工时数
:return:
"""
if not self.finish_qty and not self.unqualified_qty and not self.work_hours and not self.repair_qty:
return False
else:
return True
def confirm(self, center=False):
"""
生成报工记录
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment