|
|
@ -0,0 +1,412 @@ |
|
|
|
package com.qs.serve.modules.goods.controller; |
|
|
|
|
|
|
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
|
|
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; |
|
|
|
import com.qs.serve.common.config.DevEnvironmentConfig; |
|
|
|
import com.qs.serve.common.model.annotation.SysLog; |
|
|
|
import com.qs.serve.common.model.dto.PageVo; |
|
|
|
import com.qs.serve.common.model.dto.R; |
|
|
|
import com.qs.serve.common.model.enums.BizType; |
|
|
|
import com.qs.serve.common.model.enums.SystemModule; |
|
|
|
import com.qs.serve.common.util.CopierUtil; |
|
|
|
import com.qs.serve.common.util.PageUtil; |
|
|
|
import com.qs.serve.common.util.SpringUtils; |
|
|
|
import com.qs.serve.common.util.StringUtils; |
|
|
|
import com.qs.serve.modules.bms.common.BookAccountUtil; |
|
|
|
import com.qs.serve.modules.goods.entity.GoodsSku; |
|
|
|
import com.qs.serve.modules.goods.entity.GoodsSkuSpecValue; |
|
|
|
import com.qs.serve.modules.goods.entity.GoodsSpu; |
|
|
|
import com.qs.serve.modules.goods.entity.bo.GoodsSkuBo; |
|
|
|
import com.qs.serve.modules.goods.entity.bo.GoodsSkuImportBo; |
|
|
|
import com.qs.serve.modules.goods.entity.bo.GoodsSkuSpecialBo; |
|
|
|
import com.qs.serve.modules.goods.entity.bo.GoodsSkuStateBo; |
|
|
|
import com.qs.serve.modules.goods.entity.vo.GoodSkuVo; |
|
|
|
import com.qs.serve.modules.goods.entity.vo.GoodsSkuExportVo; |
|
|
|
import com.qs.serve.modules.goods.entity.vo.GoodsSkuSpecValueVo; |
|
|
|
import com.qs.serve.modules.goods.mapper.GoodsSkuMapper; |
|
|
|
import com.qs.serve.modules.goods.mapper.GoodsSpuMapper; |
|
|
|
import com.qs.serve.modules.goods.service.GoodsSkuService; |
|
|
|
import com.qs.serve.modules.goods.service.GoodsSkuSpecValueService; |
|
|
|
import com.qs.serve.modules.goods.service.GoodsSpuService; |
|
|
|
import com.qs.serve.modules.sale.entity.SalePlanGoods; |
|
|
|
import com.qs.serve.modules.sale.service.SalePlanGoodsService; |
|
|
|
import com.qs.serve.modules.tbs.common.TbsGoodsType; |
|
|
|
import com.qs.serve.modules.tbs.entity.TbsActivityGoods; |
|
|
|
import com.qs.serve.modules.tbs.entity.TbsBudgetCondition; |
|
|
|
import com.qs.serve.modules.tbs.service.TbsActivityGoodsService; |
|
|
|
import com.qs.serve.modules.tbs.service.TbsBudgetConditionService; |
|
|
|
import com.qs.serve.modules.tzc.service.TzcPolicyGoodsService; |
|
|
|
import lombok.AllArgsConstructor; |
|
|
|
import lombok.extern.slf4j.Slf4j; |
|
|
|
import org.springframework.security.access.prepost.PreAuthorize; |
|
|
|
import org.springframework.web.bind.annotation.*; |
|
|
|
|
|
|
|
import javax.servlet.http.HttpServletRequest; |
|
|
|
import javax.validation.Valid; |
|
|
|
import java.util.List; |
|
|
|
import java.util.Map; |
|
|
|
import java.util.Random; |
|
|
|
import java.util.stream.Collectors; |
|
|
|
|
|
|
|
/** |
|
|
|
* 商品 sku |
|
|
|
* @author YenHex |
|
|
|
* @since 2022-10-09 |
|
|
|
*/ |
|
|
|
@Slf4j |
|
|
|
@AllArgsConstructor |
|
|
|
@RestController |
|
|
|
@RequestMapping("goods/sku") |
|
|
|
public class GoodsSkuOptionController { |
|
|
|
|
|
|
|
private GoodsSkuMapper goodsSkuMapper; |
|
|
|
private GoodsSkuService goodsSkuService; |
|
|
|
private GoodsSpuService goodsSpuService; |
|
|
|
private GoodsSkuSpecValueService goodsSkuSpecValueService; |
|
|
|
private TbsActivityGoodsService activityGoodsService; |
|
|
|
private TbsBudgetConditionService budgetConditionService; |
|
|
|
private SalePlanGoodsService salePlanGoodsService; |
|
|
|
private TzcPolicyGoodsService policyGoodsService; |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
* 编辑 |
|
|
|
* @param param |
|
|
|
* @return |
|
|
|
*/ |
|
|
|
@PostMapping("/updateStateBatch") |
|
|
|
@SysLog(module = SystemModule.GOODS, title = "sku", biz = BizType.UPDATE) |
|
|
|
@PreAuthorize("hasRole('goods:sku:update')") |
|
|
|
public R<?> updateStateBatch(@RequestBody @Valid GoodsSkuStateBo param){ |
|
|
|
param.initProp(); |
|
|
|
GoodsSku goodsSku = new GoodsSku(); |
|
|
|
goodsSku.setEnable(param.getEnable()); |
|
|
|
goodsSku.setOrderFlag(param.getOrderFlag()); |
|
|
|
goodsSku.setCostFlag(param.getCostFlag()); |
|
|
|
goodsSku.setOrderOfflineFlag(param.getOrderOfflineFlag()); |
|
|
|
goodsSku.setOrderOnlineFlag(param.getOrderOnlineFlag()); |
|
|
|
goodsSkuService.update(goodsSku,new LambdaQueryWrapper<GoodsSku>() |
|
|
|
.in(GoodsSku::getId,param.getSkuIds())); |
|
|
|
goodsSpuService.initSkuNum(); |
|
|
|
return R.ok(); |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* 编辑 |
|
|
|
* @param param |
|
|
|
* @return |
|
|
|
*/ |
|
|
|
@PostMapping("/updateSpecialFlagBatch") |
|
|
|
@SysLog(module = SystemModule.GOODS, title = "sku", biz = BizType.UPDATE) |
|
|
|
@PreAuthorize("hasRole('goods:sku:update')") |
|
|
|
public R<?> updateSpecialFlagBatch(@RequestBody @Valid GoodsSkuSpecialBo param){ |
|
|
|
Integer flag = param.getSpecialFlag(); |
|
|
|
for (Long skuId : param.getSkuIds()) { |
|
|
|
GoodsSku sku = goodsSkuService.getById(skuId); |
|
|
|
LambdaQueryWrapper<GoodsSku> specialSkuLqw = new LambdaQueryWrapper<>(); |
|
|
|
specialSkuLqw.eq(GoodsSku::getSpecialFlag,1); |
|
|
|
specialSkuLqw.eq(GoodsSku::getSpuId,sku.getSpuId()); |
|
|
|
List<GoodsSku> specialSkuList = goodsSkuService.list(specialSkuLqw); |
|
|
|
if(specialSkuList.size()>0){ |
|
|
|
GoodsSku goodsSku1 = specialSkuList.get(0); |
|
|
|
GoodsSpuMapper spuMapper = SpringUtils.getBean(GoodsSpuMapper.class); |
|
|
|
GoodsSpu spu = new GoodsSpu(); |
|
|
|
spu.setId(goodsSku1.getSpuId()); |
|
|
|
if(flag.equals(1)){ |
|
|
|
spu.setSpecialSkuId(goodsSku1.getId()); |
|
|
|
}else { |
|
|
|
spu.setSpecialSkuId(0L); |
|
|
|
} |
|
|
|
spuMapper.updateById(spu); |
|
|
|
} |
|
|
|
sku.setSpecialFlag(flag); |
|
|
|
goodsSkuService.updateById(sku); |
|
|
|
} |
|
|
|
goodsSpuService.initSkuNum(); |
|
|
|
return R.ok(); |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* 编辑 |
|
|
|
* @param param |
|
|
|
* @return |
|
|
|
*/ |
|
|
|
@PostMapping("/update") |
|
|
|
@SysLog(module = SystemModule.GOODS, title = "sku", biz = BizType.UPDATE) |
|
|
|
@PreAuthorize("hasRole('goods:sku:update')") |
|
|
|
public R<?> update(@RequestBody @Valid GoodsSkuBo param){ |
|
|
|
if(param.getSkuId()==null){ |
|
|
|
return R.error(); |
|
|
|
} |
|
|
|
goodsSkuService.editSku2(param); |
|
|
|
goodsSpuService.updateOnlineOfflineFlat(param.getSpuId()); |
|
|
|
return R.ok(); |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* 开启/关闭sku |
|
|
|
* @param skuId |
|
|
|
* @param enable |
|
|
|
* @return |
|
|
|
*/ |
|
|
|
@GetMapping("/enable") |
|
|
|
@SysLog(module = SystemModule.GOODS, title = "sku", biz = BizType.UPDATE) |
|
|
|
@PreAuthorize("hasRole('goods:sku:update')") |
|
|
|
public R<?> update(Long skuId,Integer enable){ |
|
|
|
GoodsSku param = new GoodsSku(); |
|
|
|
param.setId(skuId); |
|
|
|
param.setEnable(enable.equals(1)?1:0); |
|
|
|
goodsSkuService.updateById(param); |
|
|
|
return R.ok(); |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* 编辑 |
|
|
|
* @param param |
|
|
|
* @return |
|
|
|
*/ |
|
|
|
@PostMapping("/save") |
|
|
|
@SysLog(module = SystemModule.GOODS, title = "sku", biz = BizType.UPDATE) |
|
|
|
@PreAuthorize("hasRole('goods:sku:update')") |
|
|
|
public R<?> save(@RequestBody @Valid GoodsSkuBo param){ |
|
|
|
goodsSkuService.editSku2(param); |
|
|
|
goodsSpuService.updateOnlineOfflineFlat(param.getSpuId()); |
|
|
|
return R.ok(); |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* 删除sku |
|
|
|
* @param id |
|
|
|
* @return |
|
|
|
*/ |
|
|
|
@DeleteMapping("/deleteById/{id}") |
|
|
|
@SysLog(module = SystemModule.GOODS, title = "sku", biz = BizType.DELETE) |
|
|
|
@PreAuthorize("hasRole('goods:sku:delete')") |
|
|
|
public R<?> deleteById(@PathVariable("id") Long id){ |
|
|
|
GoodsSku sku = goodsSkuService.getById(id); |
|
|
|
QueryWrapper lqw1 = new QueryWrapper<>(); |
|
|
|
lqw1.eq("target_type", TbsGoodsType.sku.name()); |
|
|
|
lqw1.eq("target_id",id); |
|
|
|
if(activityGoodsService.count(lqw1)>0){ |
|
|
|
return R.error("活动含有当前商品,删除失败"); |
|
|
|
} |
|
|
|
if(budgetConditionService.count(lqw1)>0){ |
|
|
|
return R.error("预算含有当前商品,删除失败"); |
|
|
|
} |
|
|
|
if(salePlanGoodsService.count(lqw1)>0){ |
|
|
|
return R.error("销售计划含有当前商品,删除失败"); |
|
|
|
} |
|
|
|
if(policyGoodsService.count(lqw1)>0){ |
|
|
|
return R.error("政策含有当前商品,删除失败"); |
|
|
|
} |
|
|
|
goodsSkuMapper.updateSkuCodeAndDelFlag(id, StringUtils.genShortId()); |
|
|
|
//删除商品规格值
|
|
|
|
LambdaQueryWrapper<GoodsSkuSpecValue> lqw2 = new LambdaQueryWrapper<>(); |
|
|
|
lqw2.eq(GoodsSkuSpecValue::getSkuId,id); |
|
|
|
goodsSkuSpecValueService.remove(lqw2); |
|
|
|
goodsSpuService.updateOnlineOfflineFlat(sku.getSpuId()); |
|
|
|
return R.ok(); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
* 通过skuCode对基本信息更新 |
|
|
|
* @param param |
|
|
|
* @return |
|
|
|
*/ |
|
|
|
@PostMapping("/updateBySkuCode") |
|
|
|
public R<?> updateBySkuCode(@RequestBody GoodsSku param){ |
|
|
|
param.setId(null); |
|
|
|
param.setSpuId(null); |
|
|
|
GoodsSku sku = goodsSkuService.getByCode(param.getSkuCode()); |
|
|
|
if(sku==null){ |
|
|
|
return R.errorNotFound(); |
|
|
|
} |
|
|
|
param.setId(sku.getId()); |
|
|
|
if(param.getBelong()!=null&¶m.getBelong().contains("产")){ |
|
|
|
param.setBelong(param.getBelong().replace("产","")); |
|
|
|
} |
|
|
|
goodsSkuService.updateById(param); |
|
|
|
return R.ok(); |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* 导入 |
|
|
|
* @param param |
|
|
|
* @return |
|
|
|
*/ |
|
|
|
@PostMapping("/importSku") |
|
|
|
@SysLog(module = SystemModule.GOODS, title = "import", biz = BizType.INSERT) |
|
|
|
public R<?> importSpu(@RequestBody @Valid GoodsSkuImportBo param){ |
|
|
|
final String UPDATE = "2"; |
|
|
|
final String DELETE = "3"; |
|
|
|
final String SAVE = "1"; |
|
|
|
boolean throwEx = false; |
|
|
|
Map<String,List<GoodsSkuImportBo.SkuItem>> skuItemList = param.getSkuList().stream() |
|
|
|
.filter(a->a.getOpt()!=null).collect(Collectors.groupingBy(GoodsSkuImportBo.SkuItem::getOpt)); |
|
|
|
//处理删除
|
|
|
|
List<GoodsSkuImportBo.SkuItem> delList = skuItemList.get(DELETE); |
|
|
|
if(delList!=null){ |
|
|
|
List<String> delSkuCodes = delList.stream().map(GoodsSkuImportBo.SkuItem::getSkuCode).collect(Collectors.toList()); |
|
|
|
QueryWrapper lqw1 = new QueryWrapper<>(); |
|
|
|
lqw1.eq("target_type", TbsGoodsType.sku.name()); |
|
|
|
lqw1.in("target_code",delSkuCodes); |
|
|
|
lqw1.select("target_code"); |
|
|
|
List<TbsActivityGoods> activityGoodsList = activityGoodsService.list(lqw1); |
|
|
|
List<TbsBudgetCondition> budgetConditionList = budgetConditionService.list(lqw1); |
|
|
|
List<SalePlanGoods> salePlanGoodsList = salePlanGoodsService.list(lqw1); |
|
|
|
for (TbsActivityGoods item : activityGoodsList) { |
|
|
|
for (GoodsSkuImportBo.SkuItem skuItem : param.getSkuList()) { |
|
|
|
if(item.getTargetCode().equals(skuItem.getSkuCode())&&DELETE.equals(skuItem.getOpt())){ |
|
|
|
skuItem.setErrMsg(skuItem.getErrMsg()==null?"活动含有当前商品,删除失败;":skuItem.getErrMsg()+"\n活动含有当前商品,删除失败;"); |
|
|
|
throwEx = true; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
for (TbsBudgetCondition item : budgetConditionList) { |
|
|
|
for (GoodsSkuImportBo.SkuItem skuItem : param.getSkuList()) { |
|
|
|
if(item.getTargetCode().equals(skuItem.getSkuCode())&&DELETE.equals(skuItem.getOpt())){ |
|
|
|
skuItem.setErrMsg(skuItem.getErrMsg()==null?"预算含有当前商品,删除失败;":skuItem.getErrMsg()+"\n预算含有当前商品,删除失败;"); |
|
|
|
throwEx = true; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
for (SalePlanGoods item : salePlanGoodsList) { |
|
|
|
for (GoodsSkuImportBo.SkuItem skuItem : param.getSkuList()) { |
|
|
|
if(item.getTargetCode().equals(skuItem.getSkuCode())&&DELETE.equals(skuItem.getOpt())){ |
|
|
|
skuItem.setErrMsg(skuItem.getErrMsg()==null?"销售计划含有当前商品,删除失败;":skuItem.getErrMsg()+"\n销售计划含有当前商品,删除失败;"); |
|
|
|
throwEx = true; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
//执行删除
|
|
|
|
List<String> skuCodeToDelList = param.getSkuList().stream() |
|
|
|
.filter(a->a.getErrMsg()==null) |
|
|
|
.map(GoodsSkuImportBo.SkuItem::getSkuCode) |
|
|
|
.collect(Collectors.toList()); |
|
|
|
if(skuCodeToDelList.size()>0){ |
|
|
|
LambdaQueryWrapper<GoodsSku> delLqw = new LambdaQueryWrapper<>(); |
|
|
|
delLqw.in(GoodsSku::getSkuCode,skuCodeToDelList); |
|
|
|
goodsSkuService.remove(delLqw); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
//处理更新和新增
|
|
|
|
List<String> skuCodes = param.getSkuList().stream().map(GoodsSkuImportBo.SkuItem::getSkuCode).distinct().collect(Collectors.toList()); |
|
|
|
List<String> spuCodes = param.getSkuList().stream().map(GoodsSkuImportBo.SkuItem::getSpuCode).distinct().collect(Collectors.toList()); |
|
|
|
List<GoodsSku> skuList = goodsSkuService.getByCodes(skuCodes); |
|
|
|
List<GoodsSpu> spuList = goodsSpuService.getByCodes(spuCodes); |
|
|
|
for (GoodsSkuImportBo.SkuItem skuItem : param.getSkuList()) { |
|
|
|
String opt = skuItem.getOpt(); |
|
|
|
if(opt==null){ |
|
|
|
continue; |
|
|
|
} |
|
|
|
if(opt.equals(DELETE)){ |
|
|
|
continue; |
|
|
|
} |
|
|
|
GoodsSku sku = this.selectSku(skuList,skuItem.getSkuCode()); |
|
|
|
GoodsSpu spu = this.selectSpu(spuList,skuItem.getSpuCode()); |
|
|
|
|
|
|
|
if(StringUtils.hasText(skuItem.getSpuCode())&&spu==null){ |
|
|
|
skuItem.setErrMsg(skuItem.getErrMsg()==null?"无匹配SKU"+skuItem.getSpuCode()+"编码产品,更新失败;":skuItem.getErrMsg()+"\n无匹配编码产品,更新失败;"); |
|
|
|
throwEx = true; |
|
|
|
continue; |
|
|
|
} |
|
|
|
|
|
|
|
if(UPDATE.equals(opt)){ |
|
|
|
//更新
|
|
|
|
if(sku==null){ |
|
|
|
skuItem.setErrMsg(skuItem.getErrMsg()==null?"无匹配编码产品,更新失败;":skuItem.getErrMsg()+"\n无匹配编码产品,更新失败;"); |
|
|
|
throwEx = true; |
|
|
|
continue; |
|
|
|
} |
|
|
|
GoodsSku goodsSku = buildByImportItem(skuItem); |
|
|
|
goodsSku.setId(sku.getId()); |
|
|
|
|
|
|
|
if(spu!=null){ |
|
|
|
goodsSku.setSpuId(spu.getId()); |
|
|
|
goodsSku.setBookName(spu.getBookName()); |
|
|
|
goodsSku.setBookBelong(spu.getBookBelong()); |
|
|
|
} |
|
|
|
goodsSkuService.updateById(goodsSku); |
|
|
|
}else if (SAVE.equals(opt)){ |
|
|
|
//保存
|
|
|
|
if(sku!=null){ |
|
|
|
skuItem.setErrMsg(skuItem.getErrMsg()==null?"编码重复,新增失败;":skuItem.getErrMsg()+"\n编码重复,新增失败;"); |
|
|
|
throwEx = true; |
|
|
|
continue; |
|
|
|
} |
|
|
|
if(spu==null){ |
|
|
|
skuItem.setErrMsg(skuItem.getErrMsg()==null?"SKU不存在,新增失败;":skuItem.getErrMsg()+"\nSKU不存在,新增失败;"); |
|
|
|
throwEx = true; |
|
|
|
continue; |
|
|
|
} |
|
|
|
GoodsSku addSku = buildByImportItem(skuItem); |
|
|
|
addSku.setSpuId(spu.getId()); |
|
|
|
addSku.setBookName(spu.getBookName()); |
|
|
|
addSku.setBookBelong(spu.getBookBelong()); |
|
|
|
goodsSkuService.save(addSku); |
|
|
|
} |
|
|
|
} |
|
|
|
for (GoodsSpu spu : spuList) { |
|
|
|
goodsSpuService.updateOnlineOfflineFlat(spu.getId()); |
|
|
|
} |
|
|
|
if(throwEx){ |
|
|
|
return R.ok(param.getSkuList(),"错误数据"); |
|
|
|
} |
|
|
|
return R.ok(); |
|
|
|
} |
|
|
|
|
|
|
|
private GoodsSku buildByImportItem(GoodsSkuImportBo.SkuItem skuItem){ |
|
|
|
GoodsSku udpSku = new GoodsSku(); |
|
|
|
udpSku.setSkuCode(skuItem.getSkuCode()); |
|
|
|
udpSku.setSkuName(skuItem.getSkuName()); |
|
|
|
udpSku.setSalesPrice(skuItem.getSalesPrice()); |
|
|
|
udpSku.setMarketPrice(skuItem.getSalesPrice()); |
|
|
|
udpSku.setCostPrice(skuItem.getSalesPrice()); |
|
|
|
udpSku.setStock(skuItem.getStock()); |
|
|
|
udpSku.setWeight(skuItem.getWeight()); |
|
|
|
udpSku.setVolume(skuItem.getVolume()); |
|
|
|
udpSku.setMinPurchase(skuItem.getMinPurchase()); |
|
|
|
udpSku.setOrderFlag(skuItem.getOrderFlag()); |
|
|
|
udpSku.setSpecialFlag(skuItem.getSpecialFlag()); |
|
|
|
udpSku.setCostFlag(skuItem.getCostFlag()); |
|
|
|
udpSku.setCostPrice(skuItem.getCostPrice()); |
|
|
|
udpSku.setMarketPrice(skuItem.getMarketPrice()); |
|
|
|
udpSku.setBelong(skuItem.getBelong()); |
|
|
|
udpSku.setWrapVal(skuItem.getWrapVal()); |
|
|
|
udpSku.setTasteVal(skuItem.getTasteVal()); |
|
|
|
udpSku.setSpecInfos(skuItem.getBelong()+";"+skuItem.getTasteVal()+";"+skuItem.getWrapVal()); |
|
|
|
udpSku.setRemark(skuItem.getRemark()); |
|
|
|
udpSku.setEnable(skuItem.getEnable()); |
|
|
|
udpSku.setInvUnitWeight(skuItem.getInvUnitWeight()); |
|
|
|
return udpSku; |
|
|
|
} |
|
|
|
|
|
|
|
private GoodsSku selectSku( List<GoodsSku> skuList, String skuCode){ |
|
|
|
if(skuCode!=null){ |
|
|
|
for (GoodsSku goodsSku : skuList) { |
|
|
|
if(goodsSku.getSkuCode()==null){ |
|
|
|
continue; |
|
|
|
} |
|
|
|
if(goodsSku.getSkuCode().equals(skuCode)){ |
|
|
|
return goodsSku; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
return null; |
|
|
|
} |
|
|
|
|
|
|
|
private GoodsSpu selectSpu( List<GoodsSpu> spuList, String skuCode){ |
|
|
|
if(skuCode!=null){ |
|
|
|
for (GoodsSpu goodsSpu : spuList) { |
|
|
|
if(goodsSpu.getSpuCode().equals(skuCode)){ |
|
|
|
return goodsSpu; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
return null; |
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|