tk2312-web/src/uapbd/mmbase/bom0202/card/btnClicks/saveClick.js

661 lines
27 KiB
JavaScript
Raw Normal View History

2025-08-08 11:34:20 +08:00
/*
* @Author: liuyanp
* @PageInfo: BOM维护卡片-保存按钮事件
* @Date: 2022-01-21 09:00:00
* @Last Modified by: zhangwds
* @Last Modified time: 2023-10-19 17:40:11
*/
import { cardCache } from "nc-lightapp-front";
let { addCache, updateCache, setDefData, getDefData,getCacheById } = cardCache;
//多语使用工具类
import { getLangByResId } from '../../../public/tools/multiLangUtil'
//提示信息工具类
import { showSuccessInfo, showErrorInfo, showWarningInfo } from '../../../public/tools/messageUtil'
//自定义组件
import { confirmDialog } from '../../components'
//后事件
import { loadCardPage, fillPageData } from '../events'
import { checkDefaultVersion, insertSave, updateSave, commitBomData, getGrandDataByBomid, getBOMDataById } from '../../utils'
//常量
import {
BOM_PAGECODE, BOM_CARD_HEAD_PROPERTY, BOM_AREA, BOM_CARD_ITEMS_PROPERTY,
BOM_CARD_OUTPUTS_PROPERTY, BOM_BUSIENUM, PAGE_STATUS, GOTO_PAGE, BOM_MODULE, BOM_CACHE_FLAG
} from '../../constance';
function saveClick(props, id, isSaveAdd, isSaveCommit, assign) {
console.log('Card buttonClick-saveClick')
console.log(props.getUrlParam('id'))
this.state.needSaveCommit = isSaveCommit
this.setState(this.state)
//空行过滤
clearEmptyRows.call(this, props)
let flag = this.props.validatePageToToast([{ name: BOM_AREA.bom_card_head, type: 'form' }, { name: BOM_AREA.bom_card_b, type: 'cardTable' }]);
if (!flag.allPassed) {
return;
}
if (!this.props.form.isCheckNow(BOM_AREA.bom_card_head, 'warning')) {
return;
}
//是否是包含联副产品的包装BOM
let bFlg = isPackBomWithOutputs.call(this, props)
if (bFlg == true) {
//对包装BOM检查联副产品并询问
confirmDialog.call(this, props, getLangByResId(this, '110140BOMM4003')/* 国际化处理: 保存提示*/,
getLangByResId(this, '110140BOMM4002') /**国际化处理: 将清空包装BOM的联副产品信息请确认*/,
(ret) => {
if (ret == null || ret.beSure == false) {
return
} else {
//清空联副产品
clearOutputsRows.call(this, props)
//逻辑修改一下 -- 先做保存在后台判断是否有默认BOM冲突如果有再返回回来询问
saveProcess.call(this, props, isSaveAdd, assign)
// //如果当前BOM设置为默认但该BOM已经有默认版本则判断并询问
// hasOtherDefaultVersion.call(this, props, (ret)=>{
// if(ret == true){
// //已经存在默认有效BOM则需要二次确认
// confirmDialog.call(this, props, '', getLangByResId(this, '10140BOMM2-000009'), (ret2)=>{/**国际化处理: 物料已存在有效的默认BOM版本是否将当前BOM设为默认BOM版本*/
// if(ret2 == null || ret2.beSure == false){
// return //二次确认对话框取消或者关闭,则后续操作不能进行
// }else{
// saveProcess.call(this, props, isSaveAdd, assign)
// }
// })
// }else{
// saveProcess.call(this, props, isSaveAdd, assign)
// }
// })
}
})
} else {
//逻辑修改一下 -- 先做保存在后台判断是否有默认BOM冲突如果有再返回回来询问
saveProcess.call(this, props, isSaveAdd, assign)
// //如果当前BOM设置为默认但该BOM已经有默认版本则判断并询问
// hasOtherDefaultVersion.call(this, props, (ret)=>{
// if(ret == true){
// //已经存在默认有效BOM则需要二次确认
// confirmDialog.call(this, props, '', getLangByResId(this, '10140BOMM2-000009'), (ret2)=>{/**国际化处理: 物料已存在有效的默认BOM版本是否将当前BOM设为默认BOM版本*/
// if(ret2 == null || ret2.beSure == false){
// return //二次确认对话框取消或者关闭,则后续操作不能进行
// }else{
// saveProcess.call(this, props, isSaveAdd, assign)
// }
// })
// }else{
// saveProcess.call(this, props, isSaveAdd, assign)
// }
// })
}
}
//执行保存操作
function saveProcess(props, isSaveAdd, assign) {
let CardData = getCardData(props)
beforeSaveProcess.call(this, props, CardData, () => {
doSave.call(this, props, CardData, (retdata) => {
afterSaveProcess.call(this, props, retdata, isSaveAdd, assign)
})
})
}
function doSave(props, CardData, callback) {
let status = props.getUrlParam('status')
let fbillstatus = CardData.head[BOM_AREA.bom_card_head].rows[0].values[BOM_CARD_HEAD_PROPERTY.fbillstatus]
if (fbillstatus.value == BOM_BUSIENUM.FBILLSTATUS.INOPASS) {
CardData.head[BOM_AREA.bom_card_head].rows[0].values[BOM_CARD_HEAD_PROPERTY.fbillstatus].value = BOM_BUSIENUM.FBILLSTATUS.IFREEDOM.toString()
}
let hbdefault = CardData.head[BOM_AREA.bom_card_head].rows[0].values[BOM_CARD_HEAD_PROPERTY.hbdefault]
if (hbdefault.value == false || hbdefault.value == 'false') {
this.setState({ needCheckDefaultVersion: false })
} else {
this.setState({ needCheckDefaultVersion: true })
}
if (status == PAGE_STATUS.EDIT || status == PAGE_STATUS.BROWSE) {
doUpdateSave.call(this, props, CardData, (ret) => {
callback.call(this, ret.data)
})
} else {
doInsertSave.call(this, props, CardData, (ret) => {
callback.call(this, ret.data)
})
}
}
function afterSaveProcess(props, retdata, isSaveAdd, assign) {
let copyadd = props.getUrlParam('copyadd');
let currentCbomid = props.getUrlParam('id');
this.copyadd = copyadd;
this.currentCbomid = currentCbomid;
// 复制行关闭
this.setState({
itemCopystatus: false,
reviseEdit: false
});
if (this.state.needSaveCommit == true) {
//如果是复制的数据,要更新被复制数据缓存,要不然列表
if (copyadd == true || copyadd == 'true') {
let param = { pk: currentCbomid }
getBOMDataById.call(this, props, param, (result) => {
if (result && result.success && result.success == true) {
updateCache(BOM_MODULE.head_pk, currentCbomid, result.data, BOM_AREA.bom_card_head, BOM_MODULE.dataSource);
}
})
}
props.pushTo('/card', {
status: PAGE_STATUS.BROWSE,
id: props.getUrlParam('id')
})
props.form.setFormItemsValue(BOM_AREA.bom_card_head, { [BOM_CARD_HEAD_PROPERTY.ts]: { value: retdata.ts } })
if (retdata && retdata.workflow && (retdata.workflow == 'approveflow' || retdata.workflow == 'workflow')) {
this.setState({
compositedata: retdata,
compositedisplay: true,
saveAndCommit: true
});
return;
}
let cbomid = retdata['billcard'].head[BOM_AREA.bom_card_head].rows[0].values[BOM_CARD_HEAD_PROPERTY.cbomid].value;
props.setUrlParam(cbomid) //把cbomid保存一下
let status = props.getUrlParam('status');
if (status == PAGE_STATUS.ADD) {
//将返回数据存储到缓存中
/*
* id数据主键的值
* headAreacode: 卡片表头的区域编码
* dataSource: 缓存数据命名空间
*/
addCache(cbomid, retdata['billcard'], BOM_AREA.bom_card_head, BOM_MODULE.dataSource);
//另外还需要设置下卡片翻页组件的当前id
props.cardPagination.setCardPaginationId({ id: cbomid })
} else if (status == PAGE_STATUS.EDIT) {
//将返回数据存储到缓存中
/*
* idname: 数据主键的命名
* id数据主键的值
* headAreacode: 卡片表头的区域编码
* dataSource: 缓存数据命名空间
*/
updateCache(BOM_MODULE.head_pk, cbomid, retdata['billcard'], BOM_AREA.bom_card_head, BOM_MODULE.dataSource);
}
if (retdata && (retdata.success == true || retdata['billcard'].head)) {
setDefData(BOM_CACHE_FLAG.lastGrand, BOM_MODULE.dataSource, null)
let cbomid = retdata['billcard'].head[BOM_AREA.bom_card_head].rows[0].values[BOM_CARD_HEAD_PROPERTY.cbomid].value;
props.setUrlParam(cbomid) //把cbomid保存一下
props.pushTo('/card', {
status: PAGE_STATUS.BROWSE,
id: props.getUrlParam('id')
})
// loadCardPage.call(this, props)
fillPageData.call(this, props, retdata['billcard'])
loadCardPage.call(this, props, null, false)
showSuccessInfo('', getLangByResId(this, '110140BOMM4018'), 'infinity') /**国际化处理BOM保存成功并提交*/
} else {
props.pushTo('/card', {
status: PAGE_STATUS.BROWSE,
id: props.getUrlParam('id')
})
loadCardPage.call(this, props)
showWarningInfo('', getLangByResId(this, '110140BOMM4019'), 'infinity') /**国际化处理BOM保存成功但提交失败*/
}
} else {
setDefData(BOM_CACHE_FLAG.lastGrand, BOM_MODULE.dataSource, null)
let cbomid = retdata['billcard'].head[BOM_AREA.bom_card_head].rows[0].values[BOM_CARD_HEAD_PROPERTY.cbomid].value;
props.setUrlParam(cbomid) //把cbomid保存一下
//如果是新增保存则需要更新一下翻页组件当前pk值
let status = props.getUrlParam('status')
if (status == PAGE_STATUS.ADD) {
//将返回数据存储到缓存中
/*
* id数据主键的值
* headAreacode: 卡片表头的区域编码
* dataSource: 缓存数据命名空间
*/
addCache(cbomid, retdata['billcard'], BOM_AREA.bom_card_head, BOM_MODULE.dataSource);
//另外还需要设置下卡片翻页组件的当前id
props.cardPagination.setCardPaginationId({ id: cbomid })
} else if (status == PAGE_STATUS.EDIT) {
//将返回数据存储到缓存中
/*
* idname: 数据主键的命名
* id数据主键的值
* headAreacode: 卡片表头的区域编码
* dataSource: 缓存数据命名空间
*/
updateCache(BOM_MODULE.head_pk, cbomid, retdata['billcard'], BOM_AREA.bom_card_head, BOM_MODULE.dataSource);
}
//直接保存,更新一下状态和数据就结束
if (isSaveAdd == false) {
props.pushTo('/card', {
status: PAGE_STATUS.BROWSE,
id: props.getUrlParam('id')
})
fillPageData.call(this, props, retdata['billcard'])
loadCardPage.call(this, props, null, false)
showSuccessInfo('', getLangByResId(this, '10140BOMM3-000030'), 'infinity') /**国际化处理:保存成功!*/
} else {
let old_pkorg = {
pk_org: retdata['billcard'].head[BOM_AREA.bom_card_head].rows[0].values[BOM_CARD_HEAD_PROPERTY.pk_org],
pk_org_v: retdata['billcard'].head[BOM_AREA.bom_card_head].rows[0].values[BOM_CARD_HEAD_PROPERTY.pk_org_v]
}
addAfterSave.call(this, props, old_pkorg)
showSuccessInfo('', getLangByResId(this, '10140BOMM3-000030'), 'infinity') /**国际化处理:保存成功!*/
}
}
//bug修改 NCC-370402 新增点保存新增保存2张BOM表头物料一样都勾选卷积和默认返回列表。操作第一张报并发
//由于后台更新了卷积BOM导致前端数据还是旧的报并发了,这里把后台更新的BOM主键返回来在重新查询更新缓存数据
let defaultConvolutionId = retdata.defaultConvolutionId;
if(defaultConvolutionId){
let convolutionData = getCacheById(defaultConvolutionId,BOM_MODULE.dataSource);
if(convolutionData){
let param = { pk: defaultConvolutionId }
getBOMDataById.call(this, props, param, (result) => {
if (result && result.success && result.success == true) {
updateCache(BOM_MODULE.head_pk, defaultConvolutionId, result.data, BOM_AREA.bom_card_head, BOM_MODULE.dataSource);
}
})
}
}
}
function addAfterSave(props, old_pkorg) {
let old_cbomid = props.getUrlParam('id') //在新增操作发生时当前页面的cbomid
let cardparam = {
status: PAGE_STATUS.ADD
}
props.pushTo(GOTO_PAGE.gotoCard, cardparam) //pushTo的时候urlparam中保存的id会被清除
if (old_cbomid) {
props.setUrlParam(old_cbomid) //把新增之前的cbomid保存一下
}
loadCardPage.call(this, props, old_pkorg)
}
function CommitAfterSave(props, ts, assign) {
let param = {
pkTsParams: [{
pk: props.getUrlParam('id'),
ts: ts
}],
pageid: BOM_PAGECODE.bom_card
}
if (assign) {
param['assign'] = JSON.stringify(assign);
}
console.log({ param: param })
commitBomData.call(this, props, param, (ret) => {
if (ret.data && ret.data.workflow && (ret.data.workflow == 'approveflow' || ret.data.workflow == 'workflow')) {
this.setState({
compositedata: ret.data,
compositedisplay: true,
saveAndCommit: true
});
return;
}
if (ret && ret.success == true) {
props.pushTo('/card', {
status: PAGE_STATUS.BROWSE,
id: props.getUrlParam('id')
})
loadCardPage.call(this, props)
showSuccessInfo('', getLangByResId(this, '110140BOMM4018'), 'infinity') /**国际化处理BOM保存成功并提交*/
} else {
props.pushTo('/card', {
status: PAGE_STATUS.BROWSE,
id: props.getUrlParam('id')
})
loadCardPage.call(this, props)
showWarningInfo('', getLangByResId(this, '110140BOMM4019'), 'infinity') /**国际化处理BOM保存成功但提交失败*/
}
})
}
function doUpdateSave(props, CardData, callback) {
let param = {
data: CardData,
needCheckDefaultVersion: this.state.needCheckDefaultVersion,
needSaveCommit: this.state.needSaveCommit
}
props.validateToSave(CardData, () => { //加上验证公式
updateSave.call(this, props, param, (ret) => {
if (ret && ret.success == true) {
callback.call(this, ret)
} else {
if (ret.data == 'hasOtherDefaultVersion') {
//已经存在默认有效BOM则需要二次确认
confirmDialog.call(this, props, '', getLangByResId(this, '10140BOMM2-000009'), (ret2) => {/**国际化处理: 物料已存在有效的默认BOM版本是否将当前BOM设为默认BOM版本*/
if (ret2 == null || ret2.beSure == false) {
return //二次确认对话框取消或者关闭,则后续操作不能进行
} else {
//不检查有效默认版本,直接保存
this.setState({ needCheckDefaultVersion: false }, () => {
param['needCheckDefaultVersion'] = this.state.needCheckDefaultVersion
updateSave.call(this, props, param, (ret) => {
if (ret && ret.success == true) {
callback.call(this, ret)
} else {
showErrorInfo('', ret.data, 'infinity')
return
}
})
})
}
})
} else {
showErrorInfo('', ret.data, 'infinity')
return
}
}
})
})
}
function doInsertSave(props, CardData, callback) {
let param = {
data: CardData,
needCheckDefaultVersion: this.state.needCheckDefaultVersion,
needSaveCommit: this.state.needSaveCommit
}
props.validateToSave(CardData, () => { //加上验证公式
insertSave.call(this, props, param, (ret) => {
if (ret && ret.success == true) {
callback.call(this, ret)
} else {
if (ret.data == 'hasOtherDefaultVersion') {
//已经存在默认有效BOM则需要二次确认
confirmDialog.call(this, props, '', getLangByResId(this, '10140BOMM2-000009'), (ret2) => {/**国际化处理: 物料已存在有效的默认BOM版本是否将当前BOM设为默认BOM版本*/
if (ret2 == null || ret2.beSure == false) {
return //二次确认对话框取消或者关闭,则后续操作不能进行
} else {
//不检查有效默认版本,直接保存
this.setState({ needCheckDefaultVersion: false }, () => {
param['needCheckDefaultVersion'] = this.state.needCheckDefaultVersion
insertSave.call(this, props, param, (ret) => {
if (ret && ret.success == true) {
callback.call(this, ret)
} else {
showErrorInfo('', ret.data, 'infinity')
return
}
})
})
}
})
} else {
showErrorInfo('', ret.data, 'infinity')
return
}
}
})
})
}
function beforeSaveProcess(props, CardData, callback) {
//特殊处理一下物料作业量数据
processActivities.call(this, props, CardData)
let grandData = getDefData(BOM_CACHE_FLAG.lastGrand, BOM_MODULE.dataSource)
if (grandData == null) {
let cbomid = CardData.head[BOM_AREA.bom_card_head].rows[0].values[BOM_CARD_HEAD_PROPERTY.cbomid] ?
CardData.head[BOM_AREA.bom_card_head].rows[0].values[BOM_CARD_HEAD_PROPERTY.cbomid].value : null
if (cbomid && cbomid != '') {
let grandparam = { cbomid: cbomid }
getGrandDataByBomid.call(this, props, grandparam, (result2) => {
if (result2 && result2.success == true) {
//把孙表数据和子表数据关联起来
processGrandData2.call(this, props, CardData, BOM_AREA.bom_grand_wips, result2.data)
processGrandData2.call(this, props, CardData, BOM_AREA.bom_grand_repls, result2.data)
processGrandData2.call(this, props, CardData, BOM_AREA.bom_grand_pos, result2.data)
processGrandData2.call(this, props, CardData, BOM_AREA.bom_grand_loss, result2.data)
}
})
}
} else {
processGrandData.call(this, props, CardData, BOM_AREA.bom_grand_wips, grandData)
processGrandData.call(this, props, CardData, BOM_AREA.bom_grand_repls, grandData)
processGrandData.call(this, props, CardData, BOM_AREA.bom_grand_pos, grandData)
processGrandData.call(this, props, CardData, BOM_AREA.bom_grand_loss, grandData)
}
// //把孙表数据拼接进去
// processGrandData.call(this, props, CardData, BOM_AREA.bom_grand_wips)
// processGrandData.call(this, props, CardData, BOM_AREA.bom_grand_repls)
// processGrandData.call(this, props, CardData, BOM_AREA.bom_grand_pos)
// processGrandData.call(this, props, CardData, BOM_AREA.bom_grand_loss)
if (callback) {
callback.call(this)
}
}
//特殊处理一下物料作业量数据
function processActivities(props, CardData) {
if (CardData.bodys[BOM_AREA.bom_card_activities]) {
let activityrows = CardData.bodys[BOM_AREA.bom_card_activities].rows
if (activityrows) {
let newactivityrows = []
activityrows.forEach((row, indx) => {
let bflag = false
if (row.values != null) {
if (row.values.cbom_activityid == null || row.values.cbom_activityid.value == null) {
if (row.values.nstandardwknum == null || row.values.nstandardwknum.value == null || row.values.nstandardwknum.value == '') {
bflag = true
} else {
row.status = 2
}
} else {
if (row.values.nstandardwknum == null || row.values.nstandardwknum.value == null || row.values.nstandardwknum.value == '') {
row.status = 3
} else {
row.status = 1
}
}
}
if (bflag == false) {
newactivityrows.push(row)
}
})
CardData.bodys[BOM_AREA.bom_card_activities].rows = newactivityrows
} else {
CardData.bodys[BOM_AREA.bom_card_activities].rows = { rows: [] }
}
}
console.log(CardData.bodys[BOM_AREA.bom_card_activities].rows)
}
//把孙表数据拼接进去
function processGrandData(props, CardData, grandAreaname, grandData) {
let itemrows = CardData.bodys[BOM_AREA.bom_card_b].rows
itemrows.forEach((item) => {
let rowid = item.rowid
grandData.forEach((grow) => {
if (grow.rowid == rowid) {
if (grow[grandAreaname] && grow[grandAreaname].length > 0) {
let data = {
pageid: BOM_PAGECODE.bom_grand,
model: {
areaType: 'table',
pageinfo: null,
rows: [],
areacode: grandAreaname //添加表单的areacode编码
}
};
data.model.rows = clearEmptyGrandRows(grow[grandAreaname], grandAreaname);
item.values[grandAreaname] = { value: JSON.stringify(data) }
}
}
})
})
}
function processGrandData2(props, CardData, grandAreaname, granddata) {
let itemrows = CardData.bodys[BOM_AREA.bom_card_b].rows
itemrows.forEach((item) => {
let cbom_bid = item.values[BOM_CARD_ITEMS_PROPERTY.cbom_bid].value
if (granddata[cbom_bid] && granddata[cbom_bid].bodys) {
if (granddata[cbom_bid].bodys[grandAreaname] != null) {
let data = {
pageid: BOM_PAGECODE.bom_grand,
model: {
areaType: 'table',
pageinfo: null,
rows: [],
areacode: grandAreaname //添加表单的areacode编码
}
};
data.model.rows = clearEmptyGrandRows(granddata[cbom_bid].bodys[grandAreaname].rows, grandAreaname);
item.values[grandAreaname] = { value: JSON.stringify(data) }
}
}
})
}
function clearEmptyGrandRows(rows, type) {
let result = [];
if (!rows || rows == '') {
return result;
}
if (type == BOM_AREA.bom_grand_wips) {
rows.forEach(row => {
if (row.values.cwipid.value) {
result.push(row)
}
})
}
if (type == BOM_AREA.bom_grand_loss) {
rows.forEach(row => {
if (Number.isInteger(Number.parseInt(row.values.nlfromnum.value)) && Number.parseInt(row.values.nlfromnum.value) >= 0) {
result.push(row)
}
})
}
if (type == BOM_AREA.bom_grand_repls) {
rows.forEach(row => {
if (row.values.creplmaterialvid.value) {
result.push(row)
}
})
}
if (type == BOM_AREA.bom_grand_pos) {
rows.forEach(row => {
if (row.values.vposition.value) {
result.push(row)
}
})
}
return result
}
//如果当前BOM设置为默认但该BOM已经有默认版本则判断并询问
function hasOtherDefaultVersion(props, callback) {
let hbdefault = props.form.getFormItemsValue(BOM_AREA.bom_card_head, BOM_CARD_HEAD_PROPERTY.hbdefault)
if (hbdefault && hbdefault.value == true) {
let CardData = getCardData(props)
checkDefaultVersion.call(this, props, CardData, (ret) => {
if (ret && ret.success == true) {
if (ret.data.hasDefaultVersion == 'false') {
callback.call(this, false)
} else {
callback.call(this, true)
}
} else {
callback.call(this, false)
}
})
} else {
callback.call(this, false)
}
}
function getCardData(props) {
let CardData = props.createExtCardData(BOM_PAGECODE.bom_card, BOM_AREA.bom_card_head, [
BOM_AREA.bom_card_b,
BOM_AREA.bom_card_outputs,
BOM_AREA.bom_card_useorg,
BOM_AREA.bom_card_activities
])
let itemrows = CardData.bodys[BOM_AREA.bom_card_b].rows;
itemrows.forEach((item) => {
if (item.status == '0') {
item.status = '1';
}
})
return CardData
}
//清空联副产品
function clearOutputsRows(props) {
//如果是新增状态,则直接删除;如果是编辑状态,则置删除标识
// if (props.getUrlParam('status') === 'edit') {
// props.cardTable.getAllRows(BOM_AREA.bom_card_outputs).forEach((row) => {
// row.status = 3;
// });
// } else {
// this.props.cardTable.setTableData(BOM_AREA.bom_card_outputs, {
// rows: []
// });
// }
//bom 类型不能修改,全部清除联副产品行
this.props.cardTable.setTableData(BOM_AREA.bom_card_outputs, {
rows: []
});
}
//是否是包含联副产品的包装BOM
function isPackBomWithOutputs(props) {
let fbomtype = props.form.getFormItemsValue(BOM_AREA.bom_card_head, BOM_CARD_HEAD_PROPERTY.fbomtype)
let outputnum = props.cardTable.getAllRows(BOM_AREA.bom_card_outputs).length
if (fbomtype && fbomtype.value == BOM_BUSIENUM.FBOMTYPE.RTFINISH && outputnum > 0) {
return true
} else {
return false
}
}
//空行过滤
function clearEmptyRows(props) {
props.cardTable.filterEmptyRows(BOM_AREA.bom_card_b, [BOM_CARD_ITEMS_PROPERTY.cmaterialvid], 'include');
props.cardTable.filterEmptyRows(BOM_AREA.bom_card_outputs, [BOM_CARD_OUTPUTS_PROPERTY.cmaterialvid], 'include')
}
export { saveClick }