2023-07-09-01-派单

zhc4dev
喻忠伟 2 years ago
parent fdbfefcd11
commit 6ec71c6b2e
  1. 40
      ant-design-vue-jeecg/src/views/mall/clothSample/ZyClothSampleList.vue
  2. 39
      ant-design-vue-jeecg/src/views/mall/clothSample/modules/ZyClothSampleForm.vue
  3. 22
      ant-design-vue-jeecg/src/views/zyWorkorderManagement/ZyProductionOrderList.vue
  4. 10
      ant-design-vue-jeecg/src/views/zyWorkorderManagement/ZyWorkOrderList.vue
  5. 203
      ant-design-vue-jeecg/src/views/zyWorkorderManagement/workdep/JSelectProductionDep.vue
  6. 80
      jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/workorder/controller/WorkOrderController.java
  7. 76
      jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/zyclothsample/entity/ZyClothSample.java

@ -146,32 +146,32 @@
align:"center",
dataIndex: 'nums'
},
{
title:'成衣名称',
align:"center",
dataIndex: 'clothName'
},
{
title:'描述',
align:"center",
dataIndex: 'descr'
},
// {
// title:'',
// align:"center",
// dataIndex: 'clothName'
// },
// {
// title:'',
// align:"center",
// dataIndex: 'descr'
// },
{
title:'图片',
align:"center",
dataIndex: 'url',
scopedSlots: {customRender: 'imgSlot'}
},
{
title:'用户',
align:"center",
dataIndex: 'userId'
},
{
title:'用户类型',
align:"center",
dataIndex: 'type'
},
// {
// title:'',
// align:"center",
// dataIndex: 'userId'
// },
// {
// title:'',
// align:"center",
// dataIndex: 'type'
// },
{
title: '操作',
dataIndex: 'action',

@ -3,36 +3,61 @@
<j-form-container :disabled="formDisabled">
<a-form-model ref="form" :model="model" :rules="validatorRules" slot="detail">
<a-row>
<a-col :span="24">
<a-form-model-item label="款式" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="styleId">
<j-dict-select-tag type="list" v-model="model.styleId" dictCode="" placeholder="请选择款式" />
</a-form-model-item>
</a-col>
<a-col :span="24">
<a-form-model-item label="款式型号" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="stylemodelId">
<j-dict-select-tag type="list" v-model="model.stylemodelId" dictCode="" placeholder="请选择款式型号" />
</a-form-model-item>
</a-col>
<a-col :span="24">
<a-form-model-item label="编号" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="nums">
<a-input v-model="model.nums" placeholder="请输入编号" ></a-input>
</a-form-model-item>
</a-col>
<a-col :span="24">
<a-form-model-item label="成衣名称" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="clothName">
<a-input v-model="model.clothName" placeholder="请输入成衣名称" ></a-input>
<a-form-model-item label="模块样板" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="modelSample">
<j-image-upload isMultiple v-model="model.modelSample" ></j-image-upload>
</a-form-model-item>
</a-col>
<!--<a-col :span="24">-->
<!--<a-form-model-item label="成衣名称" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="clothName">-->
<!--<a-input v-model="model.clothName" placeholder="请输入成衣名称" ></a-input>-->
<!--</a-form-model-item>-->
<!--</a-col>-->
<a-col :span="24">
<a-form-model-item label="描述" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="descr">
<a-textarea v-model="model.descr" rows="4" placeholder="请输入描述"/>
</a-form-model-item>
</a-col>
<a-col :span="24">
<a-form-model-item label="图片" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="url">
<a-form-model-item label="效果图片" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="url">
<j-image-upload isMultiple v-model="model.url" ></j-image-upload>
</a-form-model-item>
</a-col>
<a-col :span="24">
<a-form-model-item label="用户" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="userId">
<a-input v-model="model.userId" placeholder="请输入用户" ></a-input>
<a-form-model-item label="结构图" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="structureDiagram">
<j-image-upload isMultiple v-model="model.structureDiagram" ></j-image-upload>
</a-form-model-item>
</a-col>
<a-col :span="24">
<a-form-model-item label="用户类型" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="type">
<a-input v-model="model.type" placeholder="请输入用户类型" ></a-input>
<a-form-model-item label="排料图" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="layoutDiagram">
<j-image-upload isMultiple v-model="model.layoutDiagram" ></j-image-upload>
</a-form-model-item>
</a-col>
<!--<a-col :span="24">-->
<!--<a-form-model-item label="用户" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="userId">-->
<!--<a-input v-model="model.userId" placeholder="请输入用户" ></a-input>-->
<!--</a-form-model-item>-->
<!--</a-col>-->
<!--<a-col :span="24">-->
<!--<a-form-model-item label="用户类型" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="type">-->
<!--<a-input v-model="model.type" placeholder="请输入用户类型" ></a-input>-->
<!--</a-form-model-item>-->
<!--</a-col>-->
</a-row>
</a-form-model>
</j-form-container>

@ -155,6 +155,7 @@
</div>
<zy-orders-modal ref="modalForm" @ok="modalFormOk"></zy-orders-modal>
<j-select-production-dep ref="productionForm" @ok="paidanFormOk"/>
</a-card>
</template>
@ -164,6 +165,7 @@
import { mixinDevice } from '@/utils/mixin'
import { JeecgListMixin } from '@/mixins/JeecgListMixin'
import ZyOrdersModal from '@/views/zyorders/modules/ZyOrdersModal'
import JSelectProductionDep from './workdep/JSelectProductionDep'
import {filterMultiDictText} from '@/components/dict/JDictSelectUtil'
import Area from '@/components/_util/Area'
import { httpAction, getAction } from '@/api/manage'
@ -172,7 +174,8 @@
name: 'ZyProductionOrderList',
mixins:[JeecgListMixin, mixinDevice],
components: {
ZyOrdersModal
ZyOrdersModal,
JSelectProductionDep
},
data () {
return {
@ -376,7 +379,7 @@
deleteBatch: "/zyorders/zyOrders/deleteBatch",
exportXlsUrl: "/zyorders/zyOrders/exportXls",
importExcelUrl: "zyorders/zyOrders/importExcel",
paidan:"/workorder/workOrder/paidan",
paidan:"/workOrder/workOrder/paidan",
},
dictOptions:{},
@ -395,7 +398,20 @@
},
methods: {
paidan(record){
getAction(this.url.paidan,{id:record.id}).then((res) => {
this.$refs.productionForm.showModal(record.id)
// getAction(this.url.paidan,{id:record.id}).then((res) => {
// if (res.success) {
// this.$message.success("");
// this.loadData();
// }else{
// this.$message.error(res.message);
// }
// })
},
paidanFormOk(orderId,depId) {
// /
getAction(this.url.paidan,{'orderId':orderId,'depId':depId}).then((res) => {
if (res.success) {
this.$message.success("派单成功!");
this.loadData();

@ -185,11 +185,11 @@
}
],
url: {
list: "/workorder/workOrder/workList",
delete: "/workorder/workOrder/delete",
deleteBatch: "/workorder/workOrder/deleteBatch",
exportXlsUrl: "/workorder/workOrder/exportXls",
importExcelUrl: "workorder/workOrder/importExcel",
list: "/workOrder/workOrder/workList",
delete: "/workOrder/workOrder/delete",
deleteBatch: "/workOrder/workOrder/deleteBatch",
exportXlsUrl: "/workOrder/workOrder/exportXls",
importExcelUrl: "workOrder/workOrder/importExcel",
},
dictOptions:{},

@ -0,0 +1,203 @@
<template>
<j-modal
:width="width"
:visible="visible"
:title="title"
switchFullscreen
@ok="handleOk"
@cancel="handleCancel"
style="top:50px"
cancelText="关闭"
>
<a-card :bordered="false">
<!-- 查询区域 -->
<div class="table-page-search-wrapper">
<a-form layout="inline" @keyup.enter.native="searchQuery">
<a-row :gutter="24">
</a-row>
</a-form>
</div>
<!-- 查询区域-END -->
<!-- 操作按钮区域 -->
<div class="table-operator">
</div>
<!-- table区域-begin -->
<div>
<!--<div class="ant-alert ant-alert-info" style="margin-bottom: 16px;">-->
<!--<i class="anticon anticon-info-circle ant-alert-icon"></i> 已选择 <a style="font-weight: 600">{{ selectedRowKeys.length }}</a>-->
<!--<a style="margin-left: 24px" @click="onClearSelected">清空</a>-->
<!--</div>-->
<a-table
ref="table"
size="middle"
:scroll="{x:true}"
bordered
rowKey="id"
:columns="columns"
:dataSource="dataSource"
:pagination="ipagination"
:loading="loading"
:rowSelection="{ type: 'radio',selectedRowKeys: selectedRowKeys, onChange: onSelectChange}"
class="j-table-force-nowrap"
@change="handleTableChange">
<template slot="htmlSlot" slot-scope="text">
<div v-html="text"></div>
</template>
<template slot="imgSlot" slot-scope="text">
<span v-if="!text" style="font-size: 12px;font-style: italic;">无图片</span>
<img v-else :src="getImgView(text)" height="25px" alt="" style="max-width:80px;font-size: 12px;font-style: italic;"/>
</template>
<template slot="fileSlot" slot-scope="text">
<span v-if="!text" style="font-size: 12px;font-style: italic;">无文件</span>
<a-button
v-else
:ghost="true"
type="primary"
icon="download"
size="small"
@click="downloadFile(text)">
下载
</a-button>
</template>
<span slot="action" slot-scope="text, record">
<a @click="handleDetail(record)">详情</a>
</span>
</a-table>
</div>
</a-card>
</j-modal>
</template>
<script>
import '@/assets/less/TableExpand.less'
import { mixinDevice } from '@/utils/mixin'
import { JeecgListMixin } from '@/mixins/JeecgListMixin'
export default {
name: 'JSelectProductionDep',
mixins:[JeecgListMixin, mixinDevice],
components: {
},
data () {
return {
description: '生产部门管理页面',
title:'',
width:1200,
visible: false,
disableSubmit: false,
orderId:'',
//
columns: [
{
title: '序号',
dataIndex: '',
key:'rowIndex',
width:60,
align:"center",
customRender:function (t,r,index) {
return parseInt(index)+1;
}
},
{
title:'生产企业名称',
align:"center",
dataIndex: 'departName'
},
{
title:'部门编码',
align:"center",
dataIndex: 'orgCode'
},
{
title:'手机号',
align:"center",
dataIndex: 'mobile'
},
{
title:'地址',
align:"center",
dataIndex: 'address'
},
// {
// title: '',
// dataIndex: 'action',
// align:"center",
// fixed:"right",
// width:147,
// scopedSlots: { customRender: 'action' }
// }
],
url: {
list: "/workOrder/workOrder/JSelectPDList",
delete: "",
deleteBatch: "",
exportXlsUrl: "",
importExcelUrl: "",
},
dictOptions:{},
superFieldList:[],
selectedRowKeys: [],
selectdepRows: [],
selectdepIds: [],
}
},
created() {
this.getSuperFieldList();
},
computed: {
importExcelUrl: function(){
return `${window._CONFIG['domianURL']}/${this.url.importExcelUrl}`;
},
},
methods: {
initDictConfig(){
},
showModal(orderId) {
this.selectedRowKeys=[]
this.orderId=orderId
this.visible = true;
this.loadData();
},
close () {
this.$emit('close');
this.visible = false;
},
handleOk () {
this.$emit('ok', this.orderId,this.selectedRowKeys[0]);
// console.log("selectedRowKeys"+this.selectedRowKeys);
// console.log("selectdepIds"+this.selectdepIds);
this.visible = false;
},
submitCallback(){
this.$emit('ok');
this.visible = false;
},
handleCancel () {
this.close()
},
onSelectChange(selectedRowKeys, selectionRows) {
this.selectedRowKeys = selectedRowKeys;
this.selectionRows = selectionRows;
},
getSuperFieldList(){
let fieldList=[];
fieldList.push({type:'string',value:'productCode',text:'产品编号',dictCode:''})
this.superFieldList = fieldList
}
}
}
</script>
<style scoped>
@import '~@assets/less/common.less';
</style>

@ -23,10 +23,14 @@ import org.jeecg.modules.demo.ordergoods.entity.OrderGoods;
import org.jeecg.modules.demo.ordergoods.service.IOrderGoodsService;
import org.jeecg.modules.demo.zyorders.entity.ZyOrders;
import org.jeecg.modules.demo.zyorders.service.IZyOrdersService;
import org.jeecg.modules.system.entity.SysDepart;
import org.jeecg.modules.system.service.ISysDepartService;
import org.jeecg.modules.workorder.entity.WorkOrder;
import org.jeecg.modules.workorder.service.IWorkOrderService;
import org.jeecg.modules.workproduct.entity.ZyProduct;
import org.jeecg.modules.workproduct.service.IZyProductService;
import org.jeecg.modules.zyclothsample.entity.ZyClothSample;
import org.jeecg.modules.zyclothsample.service.IZyClothSampleService;
import org.jeecg.modules.zyclothsstyle.entity.ZyClothsStyle;
import org.jeecg.modules.zyclothsstyle.service.IZyClothsStyleService;
import org.jeecg.modules.zystylemodel.entity.ZyStyleModel;
@ -84,6 +88,14 @@ public class WorkOrderController extends JeecgController<WorkOrder, IWorkOrderSe
//顾客测体
@Autowired
private ICustomerMeasureService customerMeasureService;
//成衣样板
@Autowired
private IZyClothSampleService zyClothSampleService;
//部门
@Autowired
private ISysDepartService sysDepartService;
/**
* 分页列表查询
*
@ -252,6 +264,31 @@ public class WorkOrderController extends JeecgController<WorkOrder, IWorkOrderSe
return Result.OK(pageList);
}
/**
* 选择生产部门列表查询
*
* @param sysDepart
* @param pageNo
* @param pageSize
* @param req
* @return
*/
@AutoLog(value = "选择生产部门-分页列表查询")
@ApiOperation(value="选择生产部门-分页列表查询", notes="选择生产部门-分页列表查询")
@GetMapping(value = "/JSelectPDList")
public Result<?> queryPageJSelectPDList(SysDepart sysDepart,
@RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
@RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
HttpServletRequest req) {
QueryWrapper<SysDepart> queryWrapper = QueryGenerator.initQueryWrapper(sysDepart, req.getParameterMap());
Page<SysDepart> page = new Page<SysDepart>(pageNo, pageSize);
queryWrapper.eq("org_type",1);
queryWrapper.eq("org_category",2);
IPage<SysDepart> pageList = sysDepartService.page(page, queryWrapper);
return Result.OK(pageList);
}
/**
* 派单讲订单转为工单
*
@ -261,8 +298,8 @@ public class WorkOrderController extends JeecgController<WorkOrder, IWorkOrderSe
@AutoLog(value = "派单")
@ApiOperation(value="派单", notes="派单")
@GetMapping(value = "/paidan")
public Result<?> paidan(@RequestParam(name="id",required=true) String id,HttpServletRequest req) {
ZyOrders zyOrders = zyOrdersService.getById(id);
public Result<?> paidan(@RequestParam(name="orderId",required=true) String orderId,@RequestParam(name="depId",required=true) String depId,HttpServletRequest req) {
ZyOrders zyOrders = zyOrdersService.getById(orderId);
if(zyOrders==null) {
return Result.error("未找到对应数据!");
}else{
@ -273,30 +310,44 @@ public class WorkOrderController extends JeecgController<WorkOrder, IWorkOrderSe
else {//start for 1
//商品订单是否存在
QueryWrapper<OrderGoods> ogWrapper=new QueryWrapper<OrderGoods>();
ogWrapper.eq("orders_id",id);
ogWrapper.eq("orders_id",orderId);
List<OrderGoods> ogList=orderGoodsService.list(ogWrapper);
if(ogList.size()>0)
{//start if 02
// 保存工单
OrderGoods ogModel=ogList.get(0);
//服装款式
//QueryWrapper<ZyClothsStyle> csWrapper=new QueryWrapper<ZyClothsStyle>();
ZyClothsStyle csModel=zyClothsStyleService.getById(ogModel.getStyleId());
//服装型号
//QueryWrapper<ZyStyleModel> sm=new QueryWrapper<ZyStyleModel>();
ZyStyleModel smModel=zyStyleModelService.getById(ogModel.getModelId());
if(csModel==null ||smModel==null)
{
return Result.error("该订单服装型号或服装款式不存在,请检查后在操作!");
}
//得到结构图和排排料图
QueryWrapper<ZyClothSample> csWrapper=new QueryWrapper<ZyClothSample>();
csWrapper.eq("style_id",ogModel.getStyleId());
csWrapper.eq("stylemodel_id",ogModel.getModelId());
List<ZyClothSample> csList=zyClothSampleService.list(csWrapper);
// if(csList.size()<=0)
// {
// return Result.error("商品成衣样板不存在,请检查后在操作!");
// }
// ZyClothSample cSampleModel=csList.get(0);
int goodNum=ogModel.getGoodsNum();
WorkOrder workOrder=new WorkOrder();
workOrder.setProductCode(CreateWorkCode(csModel.getNums(),smModel.getModelNumber()));//工单编号
workOrder.setOrdersId(id);//订单id
workOrder.setOrdersId(orderId);//订单id
workOrder.setOrderGoodsId(ogModel.getId());// 订单商品
workOrder.setGoodsNum(goodNum);//商品数量
workOrder.setOrderTime(zyOrders.getOrderTime());//下单时间
workOrder.setDeliveryTime(zyOrders.getDeliveryTime());//交货期
workOrder.setWorkOrderStatus(0);//工单状态
//暂时存疑
//workOrder.setEnterprisesId();//企业id
workOrder.setEnterprisesId(depId);//企业id
workOrderService.save(workOrder);
//保存产品
@ -307,6 +358,8 @@ public class WorkOrderController extends JeecgController<WorkOrder, IWorkOrderSe
if(mesureModel==null) {
return Result.error("未找到对客户量体数据!");
}
for(int i=0;i<goodNum;i++)
{
ZyProduct productModel=new ZyProduct();
@ -319,9 +372,9 @@ public class WorkOrderController extends JeecgController<WorkOrder, IWorkOrderSe
// productModel.setTotalMachine("");// 合计(设备秒)
// productModel.setEnterprisesId("");//_id 企业id
productModel.setUserId(zyOrders.getUserId());//_id 用户id
// productModel.setStructureDiagram("");//_diagram 结构图
// productModel.setLayoutDiagram("");//_diagram 排料图
// productModel.setProductPicture("");//_picture 产品图片
// productModel.setStructureDiagram(cSampleModel.getStructureDiagram());//_diagram 结构图
// productModel.setLayoutDiagram(cSampleModel.getLayoutDiagram());//_diagram 排料图
// productModel.setProductPicture(cSampleModel.getUrl());//_picture 产品图片
productModel.setHeight(mesureModel.getHeight());// 身高
productModel.setWeight(mesureModel.getWeight());// 体重
productModel.setHem(mesureModel.getHem());// 下摆
@ -335,13 +388,14 @@ public class WorkOrderController extends JeecgController<WorkOrder, IWorkOrderSe
productModel.setHipline(mesureModel.getHipline());// 臀围
productModel.setLength(mesureModel.getLength());// 衣长
productModel.setSternalDistance(mesureModel.getSternalDistance());//distance 胸距
productModel.setEnterprisesId(depId);//企业
zyProductService.save(productModel);
}
}else
{
return Result.error("订单商品数量小于0!");
}
}
}else//end if 02
{
@ -349,6 +403,10 @@ public class WorkOrderController extends JeecgController<WorkOrder, IWorkOrderSe
}
}//end for 1
}
//修改订单状态
zyOrders.setDeliveryStatus(3);
zyOrdersService.updateById(zyOrders);
return Result.OK("成功");
}

@ -35,6 +35,23 @@ public class ZyClothSample implements Serializable {
@TableId(type = IdType.ASSIGN_ID)
@ApiModelProperty(value = "主键")
private String id;
/**创建人*/
@Dict(dictTable = "sys_user", dicText = "realname", dicCode = "username")
@ApiModelProperty(value = "创建人")
private java.lang.String createBy;
/**创建时间*/
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
@ApiModelProperty(value = "创建时间")
private java.util.Date createTime;
/**更新人*/
@ApiModelProperty(value = "更新人")
private java.lang.String updateBy;
/**更新时间*/
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
@ApiModelProperty(value = "更新时间")
private java.util.Date updateTime;
/**编号*/
@Excel(name = "编号", width = 15)
@ApiModelProperty(value = "编号")
@ -66,40 +83,41 @@ public class ZyClothSample implements Serializable {
@Dict(dicCode = "id",dictTable = "zy_module_sample",dicText = "module_name")
//@NotBlank(message = "模块样板不能为空")
private String modelSample;
/**用户*/
@Excel(name = "用户", width = 15)
@ApiModelProperty(value = "用户")
@Dict(dictTable = "sys_depart", dicText = "depart_name", dicCode = "id")
private String userId;
/**创建日期*/
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
@ApiModelProperty(value = "创建日期")
private Date createTime;
/**更新人*/
@ApiModelProperty(value = "更新人")
private java.lang.String updateBy;
/**更新日期*/
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
@ApiModelProperty(value = "更新日期")
private java.util.Date updateTime;
// /**用户*/
// @Excel(name = "用户", width = 15)
// @ApiModelProperty(value = "用户")
// @Dict(dictTable = "sys_depart", dicText = "depart_name", dicCode = "id")
// private String userId;
/**成衣名称*/
@Excel(name = "成衣名称", width = 15)
@ApiModelProperty(value = "成衣名称")
private String clothName;
// /**成衣名称*/
// @Excel(name = "成衣名称", width = 15)
// @ApiModelProperty(value = "成衣名称")
// private String clothName;
/**描述*/
@Excel(name = "描述", width = 15)
@ApiModelProperty(value = "描述")
private String descr;
/**图片*/
@Excel(name = "图片", width = 15)
@ApiModelProperty(value = "图片")
/**效果图片*/
@Excel(name = "效果图片", width = 15)
@ApiModelProperty(value = "效果图片片")
private String url;
/**用户类型*/
@Excel(name = "用户类型", width = 15)
@ApiModelProperty(value = "用户类型")
private String type;
// /**用户类型*/
// @Excel(name = "用户类型", width = 15)
// @ApiModelProperty(value = "用户类型")
// private String type;
/**结构图*/
@Excel(name = "结构图", width = 15)
@ApiModelProperty(value = "结构图")
private java.lang.String structureDiagram;
/**排料图*/
@Excel(name = "排料图", width = 15)
@ApiModelProperty(value = "排料图")
private java.lang.String layoutDiagram;
/**企业*/
@Excel(name = "企业", width = 15, dictTable = "sys_depart", dicText = "depart_name", dicCode = "id")
@Dict(dictTable = "sys_depart", dicText = "depart_name", dicCode = "id")
@ApiModelProperty(value = "企业")
private java.lang.String enterpriseId;
}

Loading…
Cancel
Save