Merge branch 'dev' into test

test
wj 2 years ago
commit bf47bb0d7a

@ -391,7 +391,6 @@ public class LoginController extends BaseController {
@PostMapping("/spms/sub/inv/warehouse/addOrder") @PostMapping("/spms/sub/inv/warehouse/addOrder")
public BaseResponse addOrder(@RequestBody ioUploadOrderResponse ioUploadOrderRespons) { public BaseResponse addOrder(@RequestBody ioUploadOrderResponse ioUploadOrderRespons) {
ioOrderUtilsService.getIoder(ioUploadOrderRespons); ioOrderUtilsService.getIoder(ioUploadOrderRespons);
return ResultVOUtils.success(); return ResultVOUtils.success();
} }

@ -273,31 +273,31 @@ public class IoOrderDetailResultController extends BaseController {
List<CptTraceResultResponse> cptTraceResultResponses = new ArrayList<>(); List<CptTraceResultResponse> cptTraceResultResponses = new ArrayList<>();
if (CollUtil.isNotEmpty(cptTraceOrderResponses)) { if (CollUtil.isNotEmpty(cptTraceOrderResponses)) {
for (CptTraceOrderResponse cptTraceOrderResponse : cptTraceOrderResponses) { for (CptTraceOrderResponse cptTraceOrderResponse : cptTraceOrderResponses) {
if (cptTraceOrderResponse.getCorpType() == 1 || cptTraceOrderResponse.getCorpType() == 2) {
CptTraceResultResponse cptTraceResultResponse = new CptTraceResultResponse();
cptTraceResultResponse.setBillNo(cptTraceOrderResponse.getBillNo());
cptTraceResultResponse.setBillDate(DateUtil.formatDate(cptTraceOrderResponse.getCreateTime()));
cptTraceResultResponse.setBillType(cptTraceOrderResponse.getBillType());
if (cptTraceOrderResponse.getMainAction().equals(ConstantType.TYPE_OUT)) {
if (StrUtil.isNotEmpty(cptTraceOrderResponse.getFromInvCode()))
continue;
cptTraceResultResponse.setInOutType(2);
cptTraceResultResponse.setFromCorp(authCompany.getName());
cptTraceResultResponse.setFromCorpCreditNum(authCompany.getCreditCode());
CptTraceResultResponse cptTraceResultResponse = new CptTraceResultResponse(); } else {
cptTraceResultResponse.setBillNo(cptTraceOrderResponse.getBillNo()); cptTraceResultResponse.setInOutType(1);
cptTraceResultResponse.setBillDate(DateUtil.formatDate(cptTraceOrderResponse.getCreateTime())); cptTraceResultResponse.setFromCorp(cptTraceOrderResponse.getFromCorpName());
cptTraceResultResponse.setBillType(cptTraceOrderResponse.getBillType()); cptTraceResultResponse.setFromCorpCreditNum(cptTraceOrderResponse.getCreditNo());
cptTraceResultResponse.setToCorp(authCompany.getName());
if (cptTraceOrderResponse.getMainAction().equals(ConstantType.TYPE_OUT)) { cptTraceResultResponse.setToCorpCreditNum(authCompany.getCreditCode());
if (StrUtil.isNotEmpty(cptTraceOrderResponse.getFromInvCode())) }
continue; if (StrUtil.isEmpty(cptTraceOrderResponse.getFromCorpName()) && cptTraceOrderResponse.getMainAction().equals(ConstantType.TYPE_OUT)) {
cptTraceResultResponse.setInOutType(2); cptTraceResultResponse.setBillType("使用出库");
cptTraceResultResponse.setFromCorp(authCompany.getName()); cptTraceResultResponse.setToUserInfo("患者使用出库");
cptTraceResultResponse.setFromCorpCreditNum(authCompany.getCreditCode()); }
cptTraceResultResponses.add(cptTraceResultResponse);
} else {
cptTraceResultResponse.setInOutType(1);
cptTraceResultResponse.setFromCorp(cptTraceOrderResponse.getFromCorpName());
cptTraceResultResponse.setFromCorpCreditNum(cptTraceOrderResponse.getCreditNo());
cptTraceResultResponse.setToCorp(authCompany.getName());
cptTraceResultResponse.setToCorpCreditNum(authCompany.getCreditCode());
}
if (StrUtil.isEmpty(cptTraceOrderResponse.getFromCorpName()) && cptTraceOrderResponse.getMainAction().equals(ConstantType.TYPE_OUT)) {
cptTraceResultResponse.setBillType("使用出库");
cptTraceResultResponse.setToUserInfo("患者使用出库");
} }
cptTraceResultResponses.add(cptTraceResultResponse);
} }
} }

@ -16,4 +16,5 @@ public class CptTraceOrderResponse {
private String action; private String action;
private String fromInvCode; private String fromInvCode;
private Integer count; private Integer count;
private int corpType;
} }

@ -148,10 +148,10 @@ public class IoAddInoutService {
List<IoCodeTempEntity> insertList = new ArrayList<>(); List<IoCodeTempEntity> insertList = new ArrayList<>();
for (int j = 0; j < filterList.size(); j++) { for (int j = 0; j < filterList.size(); j++) {
IoCodeTempEntity warehouseEntity = filterList.get(j); IoCodeTempEntity ioCodeTempEntity = filterList.get(j);
String result = checkOrderRepeatCode(warehouseEntity, filterList); String result = checkOrderRepeatCode(ioCodeTempEntity, filterList);
if (result == null) { if (result == null) {
insertList.add(warehouseEntity); insertList.add(ioCodeTempEntity);
} else { } else {
orderEntity.setStatus(ConstantStatus.ORDER_STATS_ERROR); orderEntity.setStatus(ConstantStatus.ORDER_STATS_ERROR);
orderEntity.setUpdateTime(new Date()); orderEntity.setUpdateTime(new Date());
@ -162,7 +162,7 @@ public class IoAddInoutService {
if (bussinessTypeEntity.isCodeFillCheck()) { if (bussinessTypeEntity.isCodeFillCheck()) {
//三期校验 //三期校验
String checkOriginMsg = checkOriginCode(warehouseEntity); String checkOriginMsg = checkOriginCode(ioCodeTempEntity);
if (StrUtil.isNotEmpty(checkOriginMsg)) { if (StrUtil.isNotEmpty(checkOriginMsg)) {
orderEntity.setErrMsg(checkOriginMsg); orderEntity.setErrMsg(checkOriginMsg);
orderEntity.setStatus(ConstantStatus.ORDER_STATS_ERROR); orderEntity.setStatus(ConstantStatus.ORDER_STATS_ERROR);
@ -175,48 +175,48 @@ public class IoAddInoutService {
//产品是否已维护已关联 //产品是否已维护已关联
if ((warehouseEntity.getRelId() == null)) { if ((ioCodeTempEntity.getRelId() == null)) {
orderEntity.setStatus(ConstantStatus.ORDER_STATS_ERROR); orderEntity.setStatus(ConstantStatus.ORDER_STATS_ERROR);
orderEntity.setUpdateTime(new Date()); orderEntity.setUpdateTime(new Date());
orderEntity.setErrMsg("udi码" + warehouseEntity.getCode() + "上传时对照数据丢失,请选择对!"); orderEntity.setErrMsg("udi码" + ioCodeTempEntity.getCode() + "上传时对照数据丢失,请选择对!");
orderService.update(orderEntity); orderService.update(orderEntity);
return; return;
} }
//产品是否指定供应商 //产品是否指定供应商
if (StrUtil.isEmpty(warehouseEntity.getSupId())) { if (StrUtil.isEmpty(ioCodeTempEntity.getSupId())) {
orderEntity.setStatus(ConstantStatus.ORDER_STATS_ERROR); orderEntity.setStatus(ConstantStatus.ORDER_STATS_ERROR);
orderEntity.setUpdateTime(new Date()); orderEntity.setUpdateTime(new Date());
orderEntity.setErrMsg("udi码" + warehouseEntity.getCode() + "未指定供应商!"); orderEntity.setErrMsg("udi码" + ioCodeTempEntity.getCode() + "未指定供应商!");
orderService.update(orderEntity); orderService.update(orderEntity);
return; return;
} }
//校验是否是当前供应商 //校验是否是当前供应商
if (bussinessTypeEntity.getCorpType() == ConstantStatus.CORP_TYPE_OUT) { if (bussinessTypeEntity.getCorpType() == ConstantStatus.CORP_TYPE_OUT) {
UdiRlSupEntity udiRlSupEntity = udiRlSupService.findByUdiRlIdUnitFk(warehouseEntity.getRelId() + "", orderEntity.getFromCorp()); UdiRlSupEntity udiRlSupEntity = udiRlSupService.findByUdiRlIdUnitFk(ioCodeTempEntity.getRelId() + "", orderEntity.getFromCorp());
if (udiRlSupEntity == null) { if (udiRlSupEntity == null) {
orderEntity.setStatus(ConstantStatus.ORDER_STATS_ERROR); orderEntity.setStatus(ConstantStatus.ORDER_STATS_ERROR);
orderEntity.setUpdateTime(new Date()); orderEntity.setUpdateTime(new Date());
orderEntity.setErrMsg("udi码" + warehouseEntity.getCode() + "当前供应商不存在此配送产品"); orderEntity.setErrMsg("udi码" + ioCodeTempEntity.getCode() + "当前供应商不存在此配送产品");
orderService.update(orderEntity); orderService.update(orderEntity);
return; return;
} }
} }
//产品是否可以以使用单元入库 //产品是否可以以使用单元入库
UdiRelevanceResponse udiRelevanceResponse = udiRelevanceService.selectGroupById(warehouseEntity.getRelId()); UdiRelevanceResponse udiRelevanceResponse = udiRelevanceService.selectGroupById(ioCodeTempEntity.getRelId());
if (udiRelevanceResponse == null) { if (udiRelevanceResponse == null) {
orderEntity.setStatus(ConstantStatus.ORDER_STATS_ERROR); orderEntity.setStatus(ConstantStatus.ORDER_STATS_ERROR);
orderEntity.setUpdateTime(new Date()); orderEntity.setUpdateTime(new Date());
orderEntity.setErrMsg("udi码" + warehouseEntity.getCode() + "该产品信息未维护"); orderEntity.setErrMsg("udi码" + ioCodeTempEntity.getCode() + "该产品信息未维护");
orderService.update(orderEntity); orderService.update(orderEntity);
return; return;
} else if (!udiRelevanceResponse.getUseDy() && udiRelevanceResponse.getDiType() == ConstantStatus.DITYPE_SYDY) { } else if (!udiRelevanceResponse.getUseDy() && udiRelevanceResponse.getDiType() == ConstantStatus.DITYPE_SYDY) {
orderEntity.setStatus(ConstantStatus.ORDER_STATS_ERROR); orderEntity.setStatus(ConstantStatus.ORDER_STATS_ERROR);
orderEntity.setUpdateTime(new Date()); orderEntity.setUpdateTime(new Date());
orderEntity.setErrMsg("udi码" + warehouseEntity.getCode() + "该产品不允许以使用单元入库"); orderEntity.setErrMsg("udi码" + ioCodeTempEntity.getCode() + "该产品不允许以使用单元入库");
orderService.update(orderEntity); orderService.update(orderEntity);
return; return;
} }

@ -1,36 +1,24 @@
package com.glxp.api.service.inout; package com.glxp.api.service.inout;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.net.URLDecoder; import cn.hutool.core.net.URLDecoder;
import cn.hutool.core.util.IdUtil; import cn.hutool.core.util.IdUtil;
import com.alibaba.fastjson.JSON;
import com.glxp.api.common.res.BaseResponse;
import com.glxp.api.common.util.ResultVOUtils;
import com.glxp.api.constant.Constant; import com.glxp.api.constant.Constant;
import com.glxp.api.dao.auth.AuthAdminDao; import com.glxp.api.dao.auth.AuthAdminDao;
import com.glxp.api.dao.basic.UdiRlSupDao; import com.glxp.api.dao.basic.UdiRlSupDao;
import com.glxp.api.dao.inout.*; import com.glxp.api.dao.inout.*;
import com.glxp.api.entity.auth.AuthAdmin; import com.glxp.api.entity.auth.AuthAdmin;
import com.glxp.api.entity.basic.UdiRlSupEntity;
import com.glxp.api.entity.inout.*; import com.glxp.api.entity.inout.*;
import com.glxp.api.idc.utils.IDCUtils;
import com.glxp.api.req.basic.FilterCompanyProductRelevanceRequest; import com.glxp.api.req.basic.FilterCompanyProductRelevanceRequest;
import com.glxp.api.req.inout.ioOrderUploadRequest; import com.glxp.api.req.inout.ioOrderUploadRequest;
import com.glxp.api.res.inout.PlatformLinkResponse; import com.glxp.api.res.inout.PlatformLinkResponse;
import com.glxp.api.res.inout.ioUploadOrderResponse; import com.glxp.api.res.inout.ioUploadOrderResponse;
import com.glxp.api.util.BeanCopyUtils;
import com.glxp.api.util.FileUtils;
import com.glxp.api.util.GennerOrderUtils; import com.glxp.api.util.GennerOrderUtils;
import com.glxp.api.util.OrderNoTypeBean; import com.glxp.api.util.OrderNoTypeBean;
import org.apache.catalina.User;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource; import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.util.*; import java.util.*;
@ -88,15 +76,17 @@ public class IoOrderUtilsService {
filterCompanyProductRelevanceRequest.setCustomerId(Long.valueOf(platformLinkRespons.getCustomerId())); filterCompanyProductRelevanceRequest.setCustomerId(Long.valueOf(platformLinkRespons.getCustomerId()));
filterCompanyProductRelevanceRequest.setNameCode(ioCodeTempEntity.getNameCode()); filterCompanyProductRelevanceRequest.setNameCode(ioCodeTempEntity.getNameCode());
List<ioOrderUploadRequest> udiRlSupEntityList = udiRlSupDao.filterCompanyProduct(filterCompanyProductRelevanceRequest); List<ioOrderUploadRequest> udiRlSupEntityList = udiRlSupDao.filterCompanyProduct(filterCompanyProductRelevanceRequest);
if (udiRlSupEntityList != null && udiRlSupEntityList.size() == 0 || udiRlSupEntityList.size() > 1) { if (CollectionUtil.isNotEmpty(udiRlSupEntityList) && udiRlSupEntityList.size() > 1) {
ioCodeTempEntity1.setRelId(null); ioCodeTempEntity1.setRelId(null);
checkUdi = true; checkUdi = true;
} else { } else {
ioCodeTempEntity1.setRelId(udiRlSupEntityList.get(0).getId()); if (CollectionUtil.isNotEmpty(udiRlSupEntityList)) {
map.put(ioCodeTempEntity.getRelId(), udiRlSupEntityList.get(0)); ioCodeTempEntity1.setRelId(udiRlSupEntityList.get(0).getId());
map.put(ioCodeTempEntity.getRelId(), udiRlSupEntityList.get(0));
}
ioCodeTempEntity1.setOrderId(billNO); ioCodeTempEntity1.setOrderId(billNO);
String code=URLDecoder.decode(ioCodeTempEntity.getCode(), StandardCharsets.UTF_8); String code = URLDecoder.decode(ioCodeTempEntity.getCode(), StandardCharsets.UTF_8);
ioCodeTempEntity1.setCode(code); ioCodeTempEntity1.setCode(code);
ioCodeTempEntity1.setMainAction(ioCodeTempEntity.getMainAction()); ioCodeTempEntity1.setMainAction(ioCodeTempEntity.getMainAction());
ioCodeTempEntity1.setAction(platformLinkRespons.getTargetAction()); ioCodeTempEntity1.setAction(platformLinkRespons.getTargetAction());
@ -120,41 +110,44 @@ public class IoOrderUtilsService {
//扫码单据生成 //扫码单据生成
IoOrderDetailCodeEntity ioOrderDetailCodeEntity1 = new IoOrderDetailCodeEntity(); IoOrderDetailCodeEntity ioOrderDetailCodeEntity1 = new IoOrderDetailCodeEntity();
List<IoOrderDetailCodeEntity> ioOrderDetailCodeEntities = new ArrayList<>(); List<IoOrderDetailCodeEntity> ioOrderDetailCodeEntities = new ArrayList<>();
for (IoOrderDetailCodeEntity ioOrderDetailCodeEntity : ioOrderDetailCodeEntityList) { if (CollectionUtil.isNotEmpty(ioOrderDetailCodeEntityList)) {
ioOrderDetailCodeEntity1.setOrderIdFk(billNO); for (IoOrderDetailCodeEntity ioOrderDetailCodeEntity : ioOrderDetailCodeEntityList) {
ioOrderDetailCodeEntity1.setOrderIdFk(billNO);
ioOrderUploadRequest udiRlSupEntity = map.get(ioOrderDetailCodeEntity.getBindRlFk()); ioOrderUploadRequest udiRlSupEntity = map.get(ioOrderDetailCodeEntity.getBindRlFk());
if (udiRlSupEntity != null) { if (udiRlSupEntity != null) {
ioOrderDetailCodeEntity1.setBindRlFk(udiRlSupEntity.getId()); ioOrderDetailCodeEntity1.setBindRlFk(udiRlSupEntity.getId());
ioOrderDetailCodeEntity1.setUuidFk(udiRlSupEntity.getUdiRlIdFk() + ""); ioOrderDetailCodeEntity1.setUuidFk(udiRlSupEntity.getUdiRlIdFk() + "");
} else { } else {
ioOrderDetailCodeEntity1.setBindRlFk(null); ioOrderDetailCodeEntity1.setBindRlFk(null);
ioOrderDetailCodeEntity1.setUuidFk(null); ioOrderDetailCodeEntity1.setUuidFk(null);
}
ioOrderDetailCodeEntity1.setId(IdUtil.getSnowflakeNextId());
ioOrderDetailCodeEntity1.setNameCode(ioOrderDetailCodeEntity.getNameCode());
ioOrderDetailCodeEntity1.setBatchNo(ioOrderDetailCodeEntity.getBatchNo());
ioOrderDetailCodeEntity1.setProductDate(ioOrderDetailCodeEntity.getProductDate());
ioOrderDetailCodeEntity1.setExpireDate(ioOrderDetailCodeEntity.getExpireDate());
ioOrderDetailCodeEntity1.setCoName(ioOrderDetailCodeEntity.getCoName());
ioOrderDetailCodeEntity1.setCertCode(ioOrderDetailCodeEntity.getCertCode());
ioOrderDetailCodeEntity1.setYlqxzcrbarmc(ioOrderDetailCodeEntity.getYlqxzcrbarmc());
ioOrderDetailCodeEntity1.setManufacturer(ioOrderDetailCodeEntity.getManufacturer());
ioOrderDetailCodeEntity1.setMeasname(ioOrderDetailCodeEntity.getMeasname());
ioOrderDetailCodeEntity1.setPrice(ioOrderDetailCodeEntity.getPrice());
ioOrderDetailCodeEntity1.setSpec(ioOrderDetailCodeEntity.getSpec());
ioOrderDetailCodeEntity1.setCertCode(ioOrderDetailCodeEntity.getCertCode());
ioOrderDetailCodeEntity1.setSupId(ioOrderDetailCodeEntity.getSupId());
ioOrderDetailCodeEntity1.setBindSupStatus(ioOrderDetailCodeEntity.getBindSupStatus());
ioOrderDetailCodeEntity1.setCount(ioOrderDetailCodeEntity.getCount());
ioOrderDetailCodeEntity1.setReCount(ioOrderDetailCodeEntity.getReCount());
ioOrderDetailCodeEntity1.setUpdateTime(new Date());
ioOrderDetailCodeEntities.add(ioOrderDetailCodeEntity1);
} }
ioOrderDetailCodeEntity1.setId(IdUtil.getSnowflakeNextId());
ioOrderDetailCodeEntity1.setNameCode(ioOrderDetailCodeEntity.getNameCode());
ioOrderDetailCodeEntity1.setBatchNo(ioOrderDetailCodeEntity.getBatchNo());
ioOrderDetailCodeEntity1.setProductDate(ioOrderDetailCodeEntity.getProductDate());
ioOrderDetailCodeEntity1.setExpireDate(ioOrderDetailCodeEntity.getExpireDate());
ioOrderDetailCodeEntity1.setCoName(ioOrderDetailCodeEntity.getCoName());
ioOrderDetailCodeEntity1.setCertCode(ioOrderDetailCodeEntity.getCertCode());
ioOrderDetailCodeEntity1.setYlqxzcrbarmc(ioOrderDetailCodeEntity.getYlqxzcrbarmc());
ioOrderDetailCodeEntity1.setManufacturer(ioOrderDetailCodeEntity.getManufacturer());
ioOrderDetailCodeEntity1.setMeasname(ioOrderDetailCodeEntity.getMeasname());
ioOrderDetailCodeEntity1.setPrice(ioOrderDetailCodeEntity.getPrice());
ioOrderDetailCodeEntity1.setSpec(ioOrderDetailCodeEntity.getSpec());
ioOrderDetailCodeEntity1.setCertCode(ioOrderDetailCodeEntity.getCertCode());
ioOrderDetailCodeEntity1.setSupId(ioOrderDetailCodeEntity.getSupId());
ioOrderDetailCodeEntity1.setBindSupStatus(ioOrderDetailCodeEntity.getBindSupStatus());
ioOrderDetailCodeEntity1.setCount(ioOrderDetailCodeEntity.getCount());
ioOrderDetailCodeEntity1.setReCount(ioOrderDetailCodeEntity.getReCount());
ioOrderDetailCodeEntity1.setUpdateTime(new Date());
ioOrderDetailCodeEntities.add(ioOrderDetailCodeEntity1);
} }
//业务单生成 //业务单生成
List<IoOrderDetailBizEntity> ioOrderDetailBizEntities = new ArrayList<>(); List<IoOrderDetailBizEntity> ioOrderDetailBizEntities = new ArrayList<>();
if (ioOrderDetailBizEntityList != null && ioOrderDetailBizEntityList.size() > 0) { if (CollectionUtil.isNotEmpty(ioOrderDetailBizEntityList)) {
for (IoOrderDetailBizEntity ioOrderDetailBizEntity : ioOrderDetailBizEntityList) { for (IoOrderDetailBizEntity ioOrderDetailBizEntity : ioOrderDetailBizEntityList) {
IoOrderDetailBizEntity ioOrderDetailBizEntity1 = new IoOrderDetailBizEntity(); IoOrderDetailBizEntity ioOrderDetailBizEntity1 = new IoOrderDetailBizEntity();
ioOrderDetailBizEntity1.setOrderIdFk(billNO); ioOrderDetailBizEntity1.setOrderIdFk(billNO);
@ -266,7 +259,6 @@ public class IoOrderUtilsService {
ioOrderEntity1.setMainAction(ioOrderEntity.getMainAction()); ioOrderEntity1.setMainAction(ioOrderEntity.getMainAction());
ioOrderEntity1.setAction(platformLinkRespons.getTargetAction()); ioOrderEntity1.setAction(platformLinkRespons.getTargetAction());
ioOrderEntity1.setFromCorp(ioOrderEntity.getFromCorp()); ioOrderEntity1.setFromCorp(ioOrderEntity.getFromCorp());
ioOrderEntity1.setFromCorp(ioOrderEntity.getFromCorp());
ioOrderEntity1.setFromDeptCode(ioOrderEntity.getFromDeptCode()); ioOrderEntity1.setFromDeptCode(ioOrderEntity.getFromDeptCode());
ioOrderEntity1.setFromInvCode(ioOrderEntity.getFromInvCode()); ioOrderEntity1.setFromInvCode(ioOrderEntity.getFromInvCode());
ioOrderEntity1.setOrderType(3); ioOrderEntity1.setOrderType(3);

@ -85,7 +85,8 @@
basic_corp.`name` fromCorpName, basic_corp.`name` fromCorpName,
basic_corp.creditNo, basic_corp.creditNo,
io.action, io.action,
io.fromInvCode io.fromInvCode,
bbt.corpType
from io_order_detail_result iodr from io_order_detail_result iodr
INNER JOIN io_order io on iodr.orderIdFk = io.billNo INNER JOIN io_order io on iodr.orderIdFk = io.billNo
left join basic_corp on io.fromCorp = basic_corp.erpId left join basic_corp on io.fromCorp = basic_corp.erpId

Loading…
Cancel
Save