商品库存数据统计

商品库存查询变动记录
耗材库存数据统计
商品列表排序
耗材列表排序
商品报损
耗材报损
This commit is contained in:
2024-09-25 16:00:05 +08:00
parent 999126b034
commit f9f69f93cd
21 changed files with 583 additions and 243 deletions

View File

@@ -1,18 +1,21 @@
package cn.ysk.cashier.cons.rest; package cn.ysk.cashier.cons.rest;
import cn.ysk.cashier.annotation.Log; import cn.ysk.cashier.annotation.Log;
import cn.ysk.cashier.cons.domain.TbConsInfoFlow;
import cn.ysk.cashier.cons.service.TbConsInfoFlowService; import cn.ysk.cashier.cons.service.TbConsInfoFlowService;
import cn.ysk.cashier.cons.service.dto.TbConsInfoFlowDto;
import cn.ysk.cashier.cons.service.dto.TbConsInfoFlowQueryCriteria; import cn.ysk.cashier.cons.service.dto.TbConsInfoFlowQueryCriteria;
import org.springframework.data.domain.Pageable; import cn.ysk.cashier.dto.product.TbProductStockCountQueryCriteria;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus; import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.RequestBody;
import io.swagger.annotations.*; import org.springframework.web.bind.annotation.RequestMapping;
import java.io.IOException; import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletResponse;
import java.text.ParseException;
/** /**
* @author admin * @author admin
@@ -26,39 +29,65 @@ public class TbConsInfoFlowController {
private final TbConsInfoFlowService tbConsInfoFlowService; private final TbConsInfoFlowService tbConsInfoFlowService;
@Log("导出数据") // @Log("导出数据")
@ApiOperation("导出数据") // @ApiOperation("导出数据")
@GetMapping(value = "/download") // @GetMapping(value = "/download")
public void exportTbConsInfoFlow(HttpServletResponse response, TbConsInfoFlowQueryCriteria criteria) throws IOException { // public void exportTbConsInfoFlow(HttpServletResponse response, TbConsInfoFlowQueryCriteria criteria) throws IOException {
tbConsInfoFlowService.download(tbConsInfoFlowService.queryAll(criteria), response); // tbConsInfoFlowService.download(tbConsInfoFlowService.queryAll(criteria), response);
// }
@PostMapping("/count")
@ApiOperation("耗材库存统计")
public ResponseEntity<Object> stockCount(@RequestBody TbProductStockCountQueryCriteria criteria) throws ParseException {
return new ResponseEntity<>(tbConsInfoFlowService.stockCount(criteria),HttpStatus.OK);
}
//
// @PostMapping("/list")
// @ApiOperation("耗材库存统计列表")
// public ResponseEntity<Object> stockList(@RequestBody TbProductStockCountQueryCriteria criteria) throws ParseException {
// return new ResponseEntity<>(tbConsInfoFlowService.stockList(criteria),HttpStatus.OK);
// }
@PostMapping("/stock")
@ApiOperation("耗材库存记录列表")
public ResponseEntity<Object> queryPage(@RequestBody TbConsInfoFlowQueryCriteria criteria){
return new ResponseEntity<>(tbConsInfoFlowService.queryPage(criteria),HttpStatus.OK);
} }
@GetMapping @Log("耗材报损")
@ApiOperation("查询耗材流水") @PostMapping("frmLoss")
public ResponseEntity<Object> queryTbConsInfoFlow(TbConsInfoFlowQueryCriteria criteria, Pageable pageable){ @ApiOperation("耗材报损")
return new ResponseEntity<>(tbConsInfoFlowService.queryAll(criteria,pageable),HttpStatus.OK); public ResponseEntity<Object> frmLoss(@RequestBody TbConsInfoFlowDto resources){
tbConsInfoFlowService.frmLoss(resources);
return new ResponseEntity<>(HttpStatus.CREATED);
} }
@PostMapping // @GetMapping
@Log("新增耗材流水") // @ApiOperation("查询耗材流水")
@ApiOperation("新增耗材流水") // public ResponseEntity<Object> queryTbConsInfoFlow(TbConsInfoFlowQueryCriteria criteria, Pageable pageable){
public ResponseEntity<Object> createTbConsInfoFlow(@Validated @RequestBody TbConsInfoFlow resources){ // return new ResponseEntity<>(tbConsInfoFlowService.queryAll(criteria,pageable),HttpStatus.OK);
return new ResponseEntity<>(tbConsInfoFlowService.create(resources),HttpStatus.CREATED); // }
} //
// @PostMapping
@PutMapping // @Log("新增耗材流水")
@Log("修改耗材流水") // @ApiOperation("新增耗材流水")
@ApiOperation("修改耗材流水") // public ResponseEntity<Object> createTbConsInfoFlow(@Validated @RequestBody TbConsInfoFlow resources){
public ResponseEntity<Object> updateTbConsInfoFlow(@Validated @RequestBody TbConsInfoFlow resources){ // return new ResponseEntity<>(tbConsInfoFlowService.create(resources),HttpStatus.CREATED);
tbConsInfoFlowService.update(resources); // }
return new ResponseEntity<>(HttpStatus.NO_CONTENT); //
} // @PutMapping
// @Log("修改耗材流水")
@DeleteMapping // @ApiOperation("修改耗材流水")
@Log("删除耗材流水") // public ResponseEntity<Object> updateTbConsInfoFlow(@Validated @RequestBody TbConsInfoFlow resources){
@ApiOperation("删除耗材流水") // tbConsInfoFlowService.update(resources);
public ResponseEntity<Object> deleteTbConsInfoFlow(@RequestBody Integer[] ids) { // return new ResponseEntity<>(HttpStatus.NO_CONTENT);
tbConsInfoFlowService.deleteAll(ids); // }
return new ResponseEntity<>(HttpStatus.OK); //
} // @DeleteMapping
// @Log("删除耗材流水")
// @ApiOperation("删除耗材流水")
// public ResponseEntity<Object> deleteTbConsInfoFlow(@RequestBody Integer[] ids) {
// tbConsInfoFlowService.deleteAll(ids);
// return new ResponseEntity<>(HttpStatus.OK);
// }
} }

View File

@@ -33,9 +33,9 @@ public class ViewConInfoFlowController {
viewConInfoFlowService.download(viewConInfoFlowService.queryAll(criteria), response); viewConInfoFlowService.download(viewConInfoFlowService.queryAll(criteria), response);
} }
@GetMapping @PostMapping("get")
@ApiOperation("查询获取耗材流水信息") @ApiOperation("查询获取耗材流水信息")
public ResponseEntity<Object> queryViewConInfoFlow(ViewConInfoFlowQueryCriteria criteria, Pageable pageable){ public ResponseEntity<Object> queryViewConInfoFlow(@RequestBody ViewConInfoFlowQueryCriteria criteria, Pageable pageable){
return new ResponseEntity<>(viewConInfoFlowService.queryAll(criteria,pageable),HttpStatus.OK); return new ResponseEntity<>(viewConInfoFlowService.queryAll(criteria,pageable),HttpStatus.OK);
} }

View File

@@ -3,11 +3,15 @@ package cn.ysk.cashier.cons.service;
import cn.ysk.cashier.cons.domain.TbConsInfoFlow; import cn.ysk.cashier.cons.domain.TbConsInfoFlow;
import cn.ysk.cashier.cons.service.dto.TbConsInfoFlowDto; import cn.ysk.cashier.cons.service.dto.TbConsInfoFlowDto;
import cn.ysk.cashier.cons.service.dto.TbConsInfoFlowQueryCriteria; import cn.ysk.cashier.cons.service.dto.TbConsInfoFlowQueryCriteria;
import cn.ysk.cashier.dto.product.TbProductStockCountQueryCriteria;
import cn.ysk.cashier.vo.TbProductStockCountVo;
import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Pageable;
import java.util.Map;
import java.util.List;
import java.io.IOException;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.text.ParseException;
import java.util.List;
import java.util.Map;
/** /**
* @author admin * @author admin
@@ -30,6 +34,11 @@ public interface TbConsInfoFlowService {
*/ */
List<TbConsInfoFlowDto> queryAll(TbConsInfoFlowQueryCriteria criteria); List<TbConsInfoFlowDto> queryAll(TbConsInfoFlowQueryCriteria criteria);
Map<String,Object> queryPage(TbConsInfoFlowQueryCriteria criteria);
TbProductStockCountVo stockCount(TbProductStockCountQueryCriteria criteria) throws ParseException;
Map<String,Object> stockList(TbProductStockCountQueryCriteria criteria) throws ParseException;
void frmLoss(TbConsInfoFlowDto resources);
/** /**
* 根据ID查询 * 根据ID查询
* @param id ID * @param id ID

View File

@@ -1,27 +1,10 @@
/*
* Copyright 2019-2020 Zheng Jie
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package cn.ysk.cashier.cons.service.dto; package cn.ysk.cashier.cons.service.dto;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data; import lombok.Data;
import javax.persistence.Column;
import java.sql.Timestamp;
import java.math.BigDecimal;
import java.io.Serializable; import java.io.Serializable;
import java.math.BigDecimal;
import java.sql.Timestamp;
/** /**
* @author admin * @author admin

View File

@@ -13,23 +13,27 @@ import cn.ysk.cashier.annotation.Query;
@Data @Data
public class TbConsInfoFlowQueryCriteria{ public class TbConsInfoFlowQueryCriteria{
/** 精确 */
@Query
private Integer shopId;
@Query @Query
private Integer consId; private Integer consId;
/** 模糊 */
@Query(type = Query.Type.INNER_LIKE) @Query(type = Query.Type.INNER_LIKE)
private String conName; private String conName;
/** 精确 */ private String column;
@Query @Query(type = Query.Type.IN)
private Integer shopId; private List<String> bizCode;
@Query @Query
private String orderNo; private String orderNo;
@Query(type = Query.Type.NOT_EQUAL) @Query(type = Query.Type.NOT_EQUAL)
private BigDecimal amount; private BigDecimal amount;
private Integer page;
private Integer size;
} }

View File

@@ -1,24 +1,35 @@
package cn.ysk.cashier.cons.service.dto; package cn.ysk.cashier.cons.service.dto;
import lombok.Data; import lombok.Data;
import java.util.Date;
import java.util.List; import java.util.List;
import cn.ysk.cashier.annotation.Query; import cn.ysk.cashier.annotation.Query;
/** /**
* @author admin * @author admin
* @date 2024-07-17 * @date 2024-07-17
**/ **/
@Data @Data
public class ViewConInfoFlowQueryCriteria{ public class ViewConInfoFlowQueryCriteria {
/** 模糊 */ /**
* 模糊
*/
@Query(type = Query.Type.INNER_LIKE) @Query(type = Query.Type.INNER_LIKE)
private String conName; private String conName;
@Query(type = Query.Type.INNER_LIKE)
private String productName;
@Query @Query
private String shopId; private String shopId;
@Query @Query
private String conTypeCode; private Integer conTypeId;
@Query(type = Query.Type.BETWEEN)
private List<Date> createTime;
} }

View File

@@ -1,16 +1,27 @@
package cn.ysk.cashier.cons.service.impl; package cn.ysk.cashier.cons.service.impl;
import cn.hutool.core.bean.copier.CopyOptions;
import cn.hutool.core.util.StrUtil;
import cn.ysk.cashier.cons.domain.TbConsInfo;
import cn.ysk.cashier.cons.domain.TbConsInfoFlow; import cn.ysk.cashier.cons.domain.TbConsInfoFlow;
import cn.ysk.cashier.utils.FileUtil; import cn.ysk.cashier.cons.repository.TbConsInfoRepository;
import cn.ysk.cashier.utils.PageUtil; import cn.ysk.cashier.dto.product.TbProductStockCountQueryCriteria;
import cn.ysk.cashier.utils.QueryHelp; import cn.ysk.cashier.dto.product.TbProductStockDetailQueryCriteria;
import cn.ysk.cashier.utils.ValidationUtil; import cn.ysk.cashier.dto.product.TbProductStockListDto;
import cn.ysk.cashier.exception.BadRequestException;
import cn.ysk.cashier.pojo.product.TbProduct;
import cn.ysk.cashier.pojo.product.TbProductStockDetail;
import cn.ysk.cashier.pojo.shop.TbShopUnit;
import cn.ysk.cashier.repository.product.ProductStockCountRepository;
import cn.ysk.cashier.utils.*;
import cn.ysk.cashier.vo.TbProductStockCountVo;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import cn.ysk.cashier.cons.repository.TbConsInfoFlowRepository; import cn.ysk.cashier.cons.repository.TbConsInfoFlowRepository;
import cn.ysk.cashier.cons.service.TbConsInfoFlowService; import cn.ysk.cashier.cons.service.TbConsInfoFlowService;
import cn.ysk.cashier.cons.service.dto.TbConsInfoFlowDto; import cn.ysk.cashier.cons.service.dto.TbConsInfoFlowDto;
import cn.ysk.cashier.cons.service.dto.TbConsInfoFlowQueryCriteria; import cn.ysk.cashier.cons.service.dto.TbConsInfoFlowQueryCriteria;
import cn.ysk.cashier.cons.service.mapstruct.TbConsInfoFlowMapper; import cn.ysk.cashier.cons.service.mapstruct.TbConsInfoFlowMapper;
import org.apache.commons.lang3.StringUtils;
import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort; import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
@@ -19,6 +30,9 @@ import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Pageable;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.sql.Timestamp;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*; import java.util.*;
import java.io.IOException; import java.io.IOException;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
@@ -34,7 +48,9 @@ import javax.servlet.http.HttpServletResponse;
public class TbConsInfoFlowServiceImpl implements TbConsInfoFlowService { public class TbConsInfoFlowServiceImpl implements TbConsInfoFlowService {
private final TbConsInfoFlowRepository tbConsInfoFlowRepository; private final TbConsInfoFlowRepository tbConsInfoFlowRepository;
private final TbConsInfoRepository consInfoRepository;
private final TbConsInfoFlowMapper tbConsInfoFlowMapper; private final TbConsInfoFlowMapper tbConsInfoFlowMapper;
private final ProductStockCountRepository stockRepository;
@Override @Override
public Map<String,Object> queryAll(TbConsInfoFlowQueryCriteria criteria, Pageable pageable){ public Map<String,Object> queryAll(TbConsInfoFlowQueryCriteria criteria, Pageable pageable){
@@ -59,6 +75,111 @@ public class TbConsInfoFlowServiceImpl implements TbConsInfoFlowService {
return tbConsInfoFlowMapper.toDto(tbConsInfoFlowRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder))); return tbConsInfoFlowMapper.toDto(tbConsInfoFlowRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder)));
} }
//增加数量addCountNumber; stockIn cancelCart init stockIn checkStockIn
//手动增加addNumber; checkStockIn stockOtherIn
//退货refundNumber; cancelCart
//减少数量subCountNumber; createCart stockout checkStockOut
//手动减少subNumber; checkStockOut
//销售量/消耗saleNumber; createCart
//报损lossNumber; frmLoss
//入库stockInNumber; stockIn
//出库stockOutNumber; stockout
public Map<String,Object> queryPage(TbConsInfoFlowQueryCriteria criteria){
if(StringUtils.isBlank(criteria.getColumn())){
throw new BadRequestException("必填参数未填写");
}
switch (criteria.getColumn()){
case "addCountNumber":
criteria.setBizCode(Arrays.asList("stockIn","cancelCart","init","stockIn","checkStockIn"));
break;
case "addNumber":
criteria.setBizCode(Arrays.asList("checkStockIn", "stockOtherIn"));
break;
case "refundNumber":
criteria.setBizCode(Arrays.asList("cancelCart"));
break;
case "subCountNumber":
criteria.setBizCode(Arrays.asList("createCart","stockout","checkStockOut"));
break;
case "subNumber":
criteria.setBizCode(Arrays.asList("checkStockOut"));
break;
case "saleNumber":
criteria.setBizCode(Arrays.asList("createCart"));
break;
case "lossNumber":
criteria.setBizCode(Arrays.asList("frmLoss"));
break;
case "stockInNumber":
criteria.setBizCode(Arrays.asList("stockIn"));
break;
case "stockOutNumber":
criteria.setBizCode(Arrays.asList("stockout"));
break;
}
Sort sort = Sort.by(Sort.Direction.DESC, "id");
Pageable pageable = PageRequest.of(criteria.getPage(), criteria.getSize(), sort);
Page<TbConsInfoFlow> page = tbConsInfoFlowRepository.findAll((root, criteriaQuery, criteriaBuilder)
-> QueryHelp.getPredicate(root,criteria,criteriaBuilder),pageable);
return PageUtil.toPage(page);
}
@Override
public TbProductStockCountVo stockCount(TbProductStockCountQueryCriteria criteria) throws ParseException {
if (criteria.getStartTime() == null || criteria.getEndTime() == null) {
criteria.setEndTime(new Date());//
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
criteria.setStartTime(sdf.parse("2024-01-01"));//创建2024年1月1日的Date对象
}
return stockRepository.consStockCount(criteria.getShopId().toString(), criteria.getProductName(),
criteria.getCategoryId(), DateUtil.getStrTime(criteria.getStartTime()), DateUtil.getStrTime(criteria.getEndTime()));
}
@Override
public Map<String, Object> stockList(TbProductStockCountQueryCriteria criteria) throws ParseException {
Sort sort = Sort.by(Sort.Direction.DESC, "id");
Pageable pageable = PageRequest.of(criteria.getPage(), criteria.getSize(), sort);
if (criteria.getStartTime() == null || criteria.getEndTime() == null) {
criteria.setEndTime(new Date());//
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
criteria.setStartTime(sdf.parse("2024-01-01"));//创建2024年1月1日的Date对象
}
Page<TbProductStockListDto> stockCountDtos = stockRepository.consStock(
criteria.getShopId().toString(),
criteria.getProductName(),
criteria.getCategoryId(),
DateUtil.getStrTime(criteria.getStartTime()), DateUtil.getStrTime(criteria.getEndTime()), pageable);
if (!stockCountDtos.isEmpty()) {
stockCountDtos.getContent().parallelStream().forEach(s->{
s.setCountNumber(s.getStockNumber().add(s.getSubCountNumber()));
});
}
return PageUtil.toPage(stockCountDtos);
}
@Override
public void frmLoss(TbConsInfoFlowDto resources) {
TbConsInfo tbConsInfo = consInfoRepository.findById(resources.getConsId()).orElse(null);
if(Objects.isNull(tbConsInfo)){
throw new BadRequestException("该耗材不存在");
}
BigDecimal balance = tbConsInfo.getStockNumber().subtract(resources.getAmount());
TbConsInfoFlow tbConsInfoFlow = new TbConsInfoFlow();
cn.hutool.core.bean.BeanUtil.copyProperties(resources,tbConsInfoFlow, CopyOptions.create().setIgnoreNullValue(true));
tbConsInfoFlow.setConName(tbConsInfo.getConName());
tbConsInfoFlow.setBalance(balance);
tbConsInfoFlow.setBizCode("frmLoss");
tbConsInfoFlow.setBizName("报损");
tbConsInfoFlow.setBizType("-");
tbConsInfoFlow.setCreateTime(new Timestamp(System.currentTimeMillis()));
tbConsInfoFlowRepository.save(tbConsInfoFlow);
tbConsInfo.setStockNumber(balance);
consInfoRepository.save(tbConsInfo);
}
@Override @Override
@Transactional @Transactional
public TbConsInfoFlowDto findById(Integer id) { public TbConsInfoFlowDto findById(Integer id) {

View File

@@ -280,7 +280,8 @@ public class TbConsInfoServiceImpl implements TbConsInfoService {
purveyorTransact.setType("cons_in"); purveyorTransact.setType("cons_in");
object.put("number", conInfos.getStockNumber()); object.put("number", conInfos.getStockNumber());
} else if ("out".equals(resources.getType())) { }
else if ("out".equals(resources.getType())) {
stockOperate.setSubType(-1); stockOperate.setSubType(-1);
if (conInfos.getStockNumber().compareTo(info.getStockNumber()) > 0) { if (conInfos.getStockNumber().compareTo(info.getStockNumber()) > 0) {
@@ -303,7 +304,8 @@ public class TbConsInfoServiceImpl implements TbConsInfoService {
purveyorTransact.setWaitAmount((resources.getAccountsPayable().subtract(resources.getActualPayment())).negate()); purveyorTransact.setWaitAmount((resources.getAccountsPayable().subtract(resources.getActualPayment())).negate());
purveyorTransact.setType("cons_out"); purveyorTransact.setType("cons_out");
object.put("number", conInfos.getStockNumber()); object.put("number", conInfos.getStockNumber());
} else { }
else {
throw new BadRequestException("错误操作类型"); throw new BadRequestException("错误操作类型");
} }

View File

@@ -36,92 +36,92 @@ public class StockController {
private final StockService stockService; private final StockService stockService;
@ApiOperation("库存导出") // @ApiOperation("库存导出")
@PostMapping(value = "download") // @PostMapping(value = "download")
public void exportTbOrderInfo(HttpServletResponse response, @RequestBody StockQueryDto criteria) throws IOException { // public void exportTbOrderInfo(HttpServletResponse response, @RequestBody StockQueryDto criteria) throws IOException {
stockService.download(criteria,response); // stockService.download(criteria,response);
} // }
//
@ApiOperation("库存导出") // @ApiOperation("库存导出")
@PostMapping(value = "download/v2") // @PostMapping(value = "download/v2")
public void exportTbOrderInfoV2(HttpServletResponse response, @RequestBody StockQueryDto criteria) throws IOException { // public void exportTbOrderInfoV2(HttpServletResponse response, @RequestBody StockQueryDto criteria) throws IOException {
stockService.downloadV2(criteria,response); // stockService.downloadV2(criteria,response);
} // }
//
@Log("库存导入") // @Log("库存导入")
@PostMapping("/doImport") // @PostMapping("/doImport")
@ApiOperation("文件导入库存") // @ApiOperation("文件导入库存")
public ResponseEntity<Object> importExcel(@RequestParam String shopId,@RequestParam("file") MultipartFile file) { // public ResponseEntity<Object> importExcel(@RequestParam String shopId,@RequestParam("file") MultipartFile file) {
String fileName = file.getOriginalFilename(); // String fileName = file.getOriginalFilename();
if (file.isEmpty()) { // if (file.isEmpty()) {
throw new BadRequestException("文件不能为空"); // throw new BadRequestException("文件不能为空");
} // }
if (!fileName.contains("xls") && !fileName.contains("xlsx")) { // if (!fileName.contains("xls") && !fileName.contains("xlsx")) {
throw new BadRequestException("文件格式不正确"); // throw new BadRequestException("文件格式不正确");
} // }
try { // try {
stockService.importExcel(shopId,file); // stockService.importExcel(shopId,file);
} catch (Exception e) { // } catch (Exception e) {
log.error("文件导入库存异常:",e); // log.error("文件导入库存异常:",e);
} // }
return new ResponseEntity<>(HttpStatus.OK); // return new ResponseEntity<>(HttpStatus.OK);
} // }
//
@Log("库存导入") // @Log("库存导入")
@PostMapping("/doImport/v2") // @PostMapping("/doImport/v2")
@ApiOperation("文件导入库存") // @ApiOperation("文件导入库存")
public ResponseEntity<Object> importExcelV2(@RequestParam String shopId,@RequestParam("file") MultipartFile file) { // public ResponseEntity<Object> importExcelV2(@RequestParam String shopId,@RequestParam("file") MultipartFile file) {
String fileName = file.getOriginalFilename(); // String fileName = file.getOriginalFilename();
if (file.isEmpty()) { // if (file.isEmpty()) {
throw new BadRequestException("文件不能为空"); // throw new BadRequestException("文件不能为空");
} // }
if (!fileName.contains("xls") && !fileName.contains("xlsx")) { // if (!fileName.contains("xls") && !fileName.contains("xlsx")) {
throw new BadRequestException("文件格式不正确"); // throw new BadRequestException("文件格式不正确");
} // }
try { // try {
stockService.importExcelV2(shopId,file); // stockService.importExcelV2(shopId,file);
} catch (Exception e) { // } catch (Exception e) {
log.error("文件导入库存异常:",e); // log.error("文件导入库存异常:",e);
} // }
return new ResponseEntity<>(HttpStatus.OK); // return new ResponseEntity<>(HttpStatus.OK);
} // }
//
@GetMapping // @GetMapping
@ApiOperation("查询库存") // @ApiOperation("查询库存")
public ResponseEntity<Object> queryTbProduct(StockQueryDto criteria, // public ResponseEntity<Object> queryTbProduct(StockQueryDto criteria,
@RequestParam(required = false, defaultValue = "0") Integer page, // @RequestParam(required = false, defaultValue = "0") Integer page,
@RequestParam(required = false, defaultValue = "10") Integer size){ // @RequestParam(required = false, defaultValue = "10") Integer size){
return new ResponseEntity<>(stockService.queryAll(criteria,page,size), HttpStatus.OK); // return new ResponseEntity<>(stockService.queryAll(criteria,page,size), HttpStatus.OK);
} // }
//
@GetMapping("/v2") // @GetMapping("/v2")
@ApiOperation("查询库存") // @ApiOperation("查询库存")
public ResponseEntity<Object> queryTbProductV2(StockQueryDto criteria, // public ResponseEntity<Object> queryTbProductV2(StockQueryDto criteria,
@RequestParam(required = false, defaultValue = "0") Integer page, // @RequestParam(required = false, defaultValue = "0") Integer page,
@RequestParam(required = false, defaultValue = "10") Integer size){ // @RequestParam(required = false, defaultValue = "10") Integer size){
Page<StockV2Vo> stockV2Vos = stockService.queryAllV2(criteria, page, size); // Page<StockV2Vo> stockV2Vos = stockService.queryAllV2(criteria, page, size);
Map<String, Object> dataMap = BeanUtil.transBean2Map(stockV2Vos); // Map<String, Object> dataMap = BeanUtil.transBean2Map(stockV2Vos);
if (stockV2Vos.getContent().isEmpty()) { // if (stockV2Vos.getContent().isEmpty()) {
dataMap.put("warnLine", 0); // dataMap.put("warnLine", 0);
}else { // }else {
StockV2Vo stockV2Vo = stockV2Vos.getContent().stream().filter(item -> item.getWarnLine() != null).findFirst().orElse(null); // StockV2Vo stockV2Vo = stockV2Vos.getContent().stream().filter(item -> item.getWarnLine() != null).findFirst().orElse(null);
dataMap.put("warnLine", stockV2Vo != null ? stockV2Vo.getWarnLine() : 0); // dataMap.put("warnLine", stockV2Vo != null ? stockV2Vo.getWarnLine() : 0);
} // }
return new ResponseEntity<>(dataMap, HttpStatus.OK); // return new ResponseEntity<>(dataMap, HttpStatus.OK);
} // }
@Log("商品库存 上下架商品") // @Log("商品库存 上下架商品")
@PutMapping("/grounding") // @PutMapping("/grounding")
@ApiOperation("上下架商品") // @ApiOperation("上下架商品")
public ResponseEntity<Object> grounding( // public ResponseEntity<Object> grounding(
@RequestParam Integer shopId, // @RequestParam Integer shopId,
@RequestParam Integer skuId, // @RequestParam Integer skuId,
@RequestParam Boolean isGrounding // @RequestParam Boolean isGrounding
){ // ){
stockService.grounding(shopId,skuId, isGrounding); // stockService.grounding(shopId,skuId, isGrounding);
return ResponseEntity.ok("success"); // return ResponseEntity.ok("success");
} // }
@GetMapping("/sku") @GetMapping("/sku")
@ApiOperation("查询库存") @ApiOperation("查询库存")
@@ -129,14 +129,14 @@ public class StockController {
return new ResponseEntity<>(stockService.queryProductSku(productId), HttpStatus.OK); return new ResponseEntity<>(stockService.queryProductSku(productId), HttpStatus.OK);
} }
@GetMapping("/isStock") // @GetMapping("/isStock")
public ResponseEntity<Object> updateIsHot( // public ResponseEntity<Object> updateIsHot(
@RequestParam String shopId, // @RequestParam String shopId,
@RequestParam Integer proId, // @RequestParam Integer proId,
@RequestParam Integer isStock){ // @RequestParam Integer isStock){
stockService.updateIsStock(proId,shopId,isStock); // stockService.updateIsStock(proId,shopId,isStock);
return new ResponseEntity<>(HttpStatus.OK); // return new ResponseEntity<>(HttpStatus.OK);
} // }
// @Log("商品库存 修改商品状态") // @Log("商品库存 修改商品状态")
@PostMapping("updateProductData") @PostMapping("updateProductData")

View File

@@ -8,6 +8,7 @@ import cn.ysk.cashier.vo.TbProductVo;
import cn.ysk.cashier.service.product.TbProductService; import cn.ysk.cashier.service.product.TbProductService;
import cn.ysk.cashier.dto.product.TbProductQueryCriteria; import cn.ysk.cashier.dto.product.TbProductQueryCriteria;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Pageable;
import org.springframework.http.HttpStatus; import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import org.springframework.validation.annotation.Validated; import org.springframework.validation.annotation.Validated;
@@ -36,8 +37,8 @@ public class TbProductController {
@GetMapping("/list/v2") @GetMapping("/list/v2")
@ApiOperation("查询商品列表 新") @ApiOperation("查询商品列表 新")
public ResponseEntity<Object> queryTbProductV2(TbProductQueryV2Criteria criteria){ public ResponseEntity<Object> queryTbProductV2(TbProductQueryV2Criteria criteria, Pageable pageable){
return new ResponseEntity<>(tbProductService.queryAllV2(criteria),HttpStatus.OK); return new ResponseEntity<>(tbProductService.queryAllV2(criteria,pageable),HttpStatus.OK);
} }
@GetMapping("/list") @GetMapping("/list")

View File

@@ -1,10 +1,13 @@
package cn.ysk.cashier.controller.product; package cn.ysk.cashier.controller.product;
import cn.ysk.cashier.annotation.Log; import cn.ysk.cashier.annotation.Log;
import cn.ysk.cashier.dto.product.TbProductFrmLossDto;
import cn.ysk.cashier.dto.product.TbProductStockCountQueryCriteria; import cn.ysk.cashier.dto.product.TbProductStockCountQueryCriteria;
import cn.ysk.cashier.dto.product.TbProductStockDetailQueryCriteria; import cn.ysk.cashier.dto.product.TbProductStockDetailQueryCriteria;
import cn.ysk.cashier.pojo.product.TbProductStockDetail; import cn.ysk.cashier.pojo.product.TbProductStockDetail;
import cn.ysk.cashier.service.product.TbProductStockDetailService; import cn.ysk.cashier.service.product.TbProductStockDetailService;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import io.swagger.annotations.Api; import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
@@ -25,7 +28,7 @@ import java.text.ParseException;
**/ **/
@RestController @RestController
@RequiredArgsConstructor @RequiredArgsConstructor
@Api(tags = "/product/Stock管理") @Api(tags = "商品库存记录管理")
@RequestMapping("/api/tbProductStockDetail") @RequestMapping("/api/tbProductStockDetail")
public class TbProductStockDetailController { public class TbProductStockDetailController {
@@ -38,28 +41,28 @@ public class TbProductStockDetailController {
} }
@GetMapping @GetMapping
@ApiOperation("查询/product/Stock") @ApiOperation("查询商品库存记录")
public ResponseEntity<Object> queryTbProductStockDetail(TbProductStockDetailQueryCriteria criteria, Pageable pageable){ public ResponseEntity<Object> queryTbProductStockDetail(TbProductStockDetailQueryCriteria criteria, Pageable pageable){
return new ResponseEntity<>(tbProductStockDetailService.queryAll(criteria,pageable),HttpStatus.OK); return new ResponseEntity<>(tbProductStockDetailService.queryAll(criteria,pageable),HttpStatus.OK);
} }
@PostMapping("/stock/count") @PostMapping("/stock/count")
@ApiOperation("库存统计") @ApiOperation("商品库存统计")
public ResponseEntity<Object> stockCount(@RequestBody TbProductStockCountQueryCriteria criteria) throws ParseException { public ResponseEntity<Object> stockCount(@RequestBody TbProductStockCountQueryCriteria criteria) throws ParseException {
return new ResponseEntity<>(tbProductStockDetailService.stockCount(criteria),HttpStatus.OK); return new ResponseEntity<>(tbProductStockDetailService.stockCount(criteria),HttpStatus.OK);
} }
@PostMapping("/stock/list") @PostMapping("/stock/list")
@ApiOperation("库存统计列表") @ApiOperation("商品库存统计列表")
public ResponseEntity<Object> stockList(@RequestBody TbProductStockCountQueryCriteria criteria) throws ParseException { public ResponseEntity<Object> stockList(@RequestBody TbProductStockCountQueryCriteria criteria) throws ParseException {
return new ResponseEntity<>(tbProductStockDetailService.stockList(criteria),HttpStatus.OK); return new ResponseEntity<>(tbProductStockDetailService.stockList(criteria),HttpStatus.OK);
} }
@PostMapping("/stock") @PostMapping("/stock")
@ApiOperation("库存记录列表") @ApiOperation("商品库存记录列表")
public ResponseEntity<Object> queryPage(@RequestBody TbProductStockDetailQueryCriteria criteria){ public ResponseEntity<Object> queryPage(@RequestBody TbProductStockDetailQueryCriteria criteria){
return new ResponseEntity<>(tbProductStockDetailService.queryPage(criteria),HttpStatus.OK); return new ResponseEntity<>(tbProductStockDetailService.queryPage(criteria),HttpStatus.OK);
} }
@@ -69,29 +72,37 @@ public class TbProductStockDetailController {
// } // }
/** @Log("商品报损")
* 出库/入库 @PostMapping("frmLoss")
* @param resources @ApiOperation("商品报损")
* @return public ResponseEntity<Object> frmLoss(@Validated @RequestBody TbProductFrmLossDto resources){
*/ tbProductStockDetailService.frmLoss(resources);
@PostMapping return new ResponseEntity<>(HttpStatus.CREATED);
@Log("出入库:#resources.productName")
@ApiOperation("新增/product/Stock")
public ResponseEntity<Object> createTbProductStockDetail(@Validated @RequestBody TbProductStockDetail resources){
return new ResponseEntity<>(tbProductStockDetailService.create(resources),HttpStatus.CREATED);
} }
@PutMapping // /**
@ApiOperation("修改/product/Stock") // * 商品库存记录
public ResponseEntity<Object> updateTbProductStockDetail(@Validated @RequestBody TbProductStockDetail resources){ // * @param resources
tbProductStockDetailService.update(resources); // * @return
return new ResponseEntity<>(HttpStatus.NO_CONTENT); // */
} // @PostMapping
// @Log("报损")
@DeleteMapping // @ApiOperation("新增商品库存记录")
@ApiOperation("删除/product/Stock") // public ResponseEntity<Object> createTbProductStockDetail(@Validated @RequestBody TbProductStockDetail resources){
public ResponseEntity<Object> deleteTbProductStockDetail(@RequestBody Long[] ids) { // return new ResponseEntity<>(tbProductStockDetailService.create(resources),HttpStatus.CREATED);
tbProductStockDetailService.deleteAll(ids); // }
return new ResponseEntity<>(HttpStatus.OK); //
} // @PutMapping
// @ApiOperation("修改商品库存记录")
// public ResponseEntity<Object> updateTbProductStockDetail(@Validated @RequestBody TbProductStockDetail resources){
// tbProductStockDetailService.update(resources);
// return new ResponseEntity<>(HttpStatus.NO_CONTENT);
// }
//
// @DeleteMapping
// @ApiOperation("删除商品库存记录")
// public ResponseEntity<Object> deleteTbProductStockDetail(@RequestBody Long[] ids) {
// tbProductStockDetailService.deleteAll(ids);
// return new ResponseEntity<>(HttpStatus.OK);
// }
} }

View File

@@ -60,7 +60,7 @@ public class TbProductStockOperateController {
} }
@PostMapping("/outAndOn") @PostMapping("/outAndOn")
@ApiOperation("新增/product/StockOperate") @ApiOperation("商品出入库")
@Log("商品::#outAndOnDto.type") @Log("商品::#outAndOnDto.type")
// @PreAuthorize("@el.check('tbProductStockOperate:add')") // @PreAuthorize("@el.check('tbProductStockOperate:add')")
public ResponseEntity<Object> createOutAndONOperate(@RequestBody OutAndOnDto outAndOnDto){ public ResponseEntity<Object> createOutAndONOperate(@RequestBody OutAndOnDto outAndOnDto){

View File

@@ -0,0 +1,20 @@
package cn.ysk.cashier.dto.product;
import lombok.Data;
import lombok.NonNull;
@Data
public class TbProductFrmLossDto {
@NonNull
private String shopId;
@NonNull
private String productId;
@NonNull
private String coverImg;
@NonNull
private Double stockNumber;
private String remark;
private Integer subType = -1;
private String type = "报损";
}

View File

@@ -23,8 +23,7 @@ import java.math.BigDecimal;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
import static cn.ysk.cashier.annotation.Query.Type.IN; import static cn.ysk.cashier.annotation.Query.Type.*;
import static cn.ysk.cashier.annotation.Query.Type.INNER_LIKE;
/** /**
* @website https://eladmin.vip * @website https://eladmin.vip
@@ -59,9 +58,12 @@ public class TbProductQueryV2Criteria {
@Query(type = IN) @Query(type = IN)
private List<String> typeEnum = Arrays.asList("normal","sku"); private List<String> typeEnum = Arrays.asList("normal","sku");
private Integer page; @Query(type = BETWEEN)
private List<Long> createdAt;
private Integer size; // private Integer page;
//
// private Integer size;
public void setType(String type) { public void setType(String type) {
if(StringUtils.isNotBlank(type)){ if(StringUtils.isNotBlank(type)){

View File

@@ -11,8 +11,8 @@ import java.math.BigDecimal;
@Entity @Entity
public class TbProductStockListDto { public class TbProductStockListDto {
@Id @Id
private String productId; private String id;
private String productName; private String name;
// private String specSnap; // private String specSnap;
@Transient @Transient
private BigDecimal countNumber; private BigDecimal countNumber;
@@ -24,4 +24,7 @@ public class TbProductStockListDto {
private BigDecimal lossNumber; private BigDecimal lossNumber;
private BigDecimal refundNumber; private BigDecimal refundNumber;
private BigDecimal stockInNumber;
private BigDecimal stockOutNumber;
} }

View File

@@ -17,8 +17,8 @@ public interface ProductStockCountRepository extends JpaRepository<TbProductStoc
@Query(value = "SELECT" + @Query(value = "SELECT" +
" d.product_id as product_id," + " d.product_id as id," +
" d.product_name AS product_name," + " pro.product_name AS name," +
// " d.spec_snap AS spec_snap," + // " d.spec_snap AS spec_snap," +
" pro.stock_number AS stock_number," + " pro.stock_number AS stock_number," +
" SUM( CASE WHEN d.sub_type = - 1 THEN d.stock_number ELSE 0 END ) AS sub_count_number," + " SUM( CASE WHEN d.sub_type = - 1 THEN d.stock_number ELSE 0 END ) AS sub_count_number," +
@@ -30,33 +30,34 @@ public interface ProductStockCountRepository extends JpaRepository<TbProductStoc
"FROM" + "FROM" +
" tb_product_stock_detail d " + " tb_product_stock_detail d " +
" INNER JOIN tb_product pro ON d.product_id = pro.id " + " INNER JOIN tb_product pro ON d.product_id = pro.id " +
" and pro.shop_id = :shopId " + " AND pro.shop_id = :shopId " +
" and (:categoryId IS NULL OR pro.category_id = :categoryId) " + " AND (:categoryId IS NULL OR pro.category_id = :categoryId) " +
" AND (:productName IS NULL OR d.product_name LIKE %:productName%) " +
" WHERE " + " WHERE " +
" d.shop_id = :shopId " + " d.shop_id = :shopId " +
"AND (:productName IS NULL OR d.product_name LIKE %:productName%) " +
"AND d.created_at > :startTime " + "AND d.created_at > :startTime " +
"AND d.created_at < :endTime " + "AND d.created_at < :endTime " +
"GROUP BY " + "GROUP BY " +
"d.product_id ", "d.product_id ",
countQuery = "SELECT count(*)" + countQuery = "SELECT count(1)" +
" FROM " + " FROM " +
" tb_product_stock_detail d " + " tb_product_stock_detail d " +
" INNER JOIN tb_product pro ON d.product_id = pro.id " + " INNER JOIN tb_product pro ON d.product_id = pro.id " +
" and pro.shop_id = :shopId " + " and pro.shop_id = :shopId " +
" and (:categoryId IS NULL OR pro.category_id = :categoryId) " + " and (:categoryId IS NULL OR pro.category_id = :categoryId) " +
" AND (:productName IS NULL OR d.product_name LIKE %:productName%) " +
" WHERE " + " WHERE " +
" d.shop_id = :shopId " + " d.shop_id = :shopId " +
" AND (:productName IS NULL OR d.product_name LIKE %:productName%) " +
" AND d.created_at > :startTime " + " AND d.created_at > :startTime " +
" AND d.created_at < :endTime " + " AND d.created_at < :endTime " +
" GROUP BY " + " GROUP BY " +
" d.product_id " " d.product_id "
, nativeQuery = true) , nativeQuery = true)
Page<TbProductStockListDto> stock2(String shopId, Page<TbProductStockListDto> productStock(String shopId,
String productName, String productName,
String categoryId, long startTime, long endTime, Pageable pageable); String categoryId, long startTime, long endTime, Pageable pageable);
@Query("SELECT new cn.ysk.cashier.vo.TbProductStockCountVo(" +
@Query("SELECT new cn.ysk.cashier.vo.TbProductStockCountVo( " +
" SUM( pro.stockNumber ) , " + " SUM( pro.stockNumber ) , " +
" SUM( CASE WHEN detail.subType = 1 THEN detail.stockNumber ELSE 0 END ) , " + " SUM( CASE WHEN detail.subType = 1 THEN detail.stockNumber ELSE 0 END ) , " +
" SUM( CASE WHEN detail.subType = - 1 THEN detail.stockNumber ELSE 0 END ) , " + " SUM( CASE WHEN detail.subType = - 1 THEN detail.stockNumber ELSE 0 END ) , " +
@@ -70,13 +71,95 @@ public interface ProductStockCountRepository extends JpaRepository<TbProductStoc
" INNER JOIN TbProduct pro ON detail.productId = pro.id " + " INNER JOIN TbProduct pro ON detail.productId = pro.id " +
" AND pro.shopId = :shopId " + " AND pro.shopId = :shopId " +
" AND ( :categoryId IS NULL OR pro.categoryId = :categoryId ) " + " AND ( :categoryId IS NULL OR pro.categoryId = :categoryId ) " +
" AND ( :productName IS NULL OR detail.productName LIKE %:productName% ) " +
"WHERE " + "WHERE " +
" detail.shopId = :shopId " + " detail.shopId = :shopId " +
" AND ( :productName IS NULL OR detail.productName LIKE %:productName% ) " +
" AND detail.createdAt > :startTime " + " AND detail.createdAt > :startTime " +
" AND detail.createdAt < :endTime") " AND detail.createdAt < :endTime")
TbProductStockCountVo stockCount(String shopId, TbProductStockCountVo productStockCount(String shopId,
String productName, String productName,
String categoryId, long startTime, long endTime); String categoryId, long startTime, long endTime);
@Query(value = "SELECT " +
" flow.cons_id AS id, " +
" cons.con_name AS `name`, " +
" cons.stock_number AS stock_number, " +
" SUM( CASE WHEN flow.biz_type = - 1 THEN flow.amount ELSE 0 END ) AS sub_count_number, " +
" SUM( CASE WHEN flow.biz_code IN ( 'checkStockIn','stockOtherIn' ) THEN flow.amount ELSE 0 END ) AS add_number, " +
" SUM( CASE WHEN flow.biz_code = 'checkStockOut' THEN flow.amount ELSE 0 END ) AS sub_number, " +
" SUM( CASE WHEN flow.biz_code = 'stockIn' THEN flow.amount ELSE 0 END ) AS stock_in_number, " +
" SUM( CASE WHEN flow.biz_code = 'stockout' THEN flow.amount ELSE 0 END ) AS stock_out_number, " +
" SUM( CASE WHEN flow.biz_code = 'createCart' THEN flow.amount ELSE 0 END ) AS sale_number, " +
" SUM( CASE WHEN flow.biz_code = 'frmLoss' THEN flow.amount ELSE 0 END ) AS loss_number, " +
" SUM( CASE WHEN flow.biz_code = 'cancelCart' THEN flow.amount ELSE 0 END ) AS refund_number " +
"FROM " +
" tb_cons_info_flow flow " +
" INNER JOIN tb_cons_info cons ON flow.cons_id = cons.id " +
" AND cons.shop_id = :shopId " +
" AND (:conTypeId IS NULL OR cons.con_type_id = :conTypeId ) " +
" AND (:conName IS NULL OR flow.con_name LIKE %:conName%) " +
"WHERE " +
" flow.shop_id = :shopId " +
" AND flow.created_at > :startTime " +
" AND flow.created_at < :endTime " +
"GROUP BY " +
" flow.product_id",
countQuery = "SELECT " +
" count(1) " +
"FROM " +
" tb_cons_info_flow flow " +
" INNER JOIN tb_cons_info cons ON flow.cons_id = cons.id " +
" AND cons.shop_id = :shopId " +
" AND (:conTypeId IS NULL OR pro.con_type_id = :conTypeId ) " +
" AND (:conName IS NULL OR flow.con_name LIKE %:conName%) " +
"WHERE " +
" flow.shop_id = :shopId " +
" AND flow.create_time > :startTime " +
" AND flow.create_time < :endTime " +
"GROUP BY " +
" flow.product_id"
, nativeQuery = true)
Page<TbProductStockListDto> consStock(String shopId,
String conName,
String conTypeId, String startTime, String endTime, Pageable pageable);
//现有数量stockNumber;
//增加数量addCountNumber;
//减少数量subCountNumber;
//手动增加addNumber; checkStockIn stockOtherIn
//手动减少subNumber; checkStockOut
//销售量/消耗saleNumber; createCart
//报损lossNumber; frmLoss
//退货refundNumber; cancelCart
//入库stockInNumber; stockIn
//出库stockOutNumber; stockout
@Query(" SELECT new cn.ysk.cashier.vo.TbProductStockCountVo(" +
" SUM( cons.stockNumber ) , " +
" SUM( CASE WHEN flow.bizType = '+' THEN flow.amount ELSE 0 END ) , " +
" SUM( CASE WHEN flow.bizType = '-' THEN flow.amount ELSE 0 END ) , " +
" SUM( CASE WHEN flow.bizCode IN ( 'checkStockIn','stockOtherIn' ) THEN flow.amount ELSE 0 END ) , " +
" SUM( CASE WHEN flow.bizCode = 'checkStockOut' THEN flow.amount ELSE 0 END ) , " +
" SUM( CASE WHEN flow.bizCode = 'createCart' THEN flow.amount ELSE 0 END ) , " +
" SUM( CASE WHEN flow.bizCode = 'frmLoss' THEN flow.amount ELSE 0 END ) ," +
" SUM( CASE WHEN flow.bizCode = 'cancelCart' THEN flow.amount ELSE 0 END ) ," +
" SUM( CASE WHEN flow.bizCode = 'stockIn' THEN flow.amount ELSE 0 END ) ," +
" SUM( CASE WHEN flow.bizCode = 'stockout' THEN flow.amount ELSE 0 END )) " +
"FROM " +
" TbConsInfoFlow flow " +
" INNER JOIN TbConsInfo cons ON flow.consId = cons.id " +
" AND cons.shopId = : shopId " +
" AND (:conTypeId IS NULL OR cons.conTypeId = :conTypeId ) " +
" AND (:conName IS NULL OR flow.conName LIKE %:conName%) " +
"WHERE " +
" flow.shopId = :shopId " +
" AND flow.createTime > :startTime " +
" AND flow.createTime < :endTime ")
TbProductStockCountVo consStockCount(String shopId,
String conName,
String conTypeId, String startTime, String endTime);
} }

View File

@@ -239,9 +239,7 @@ public class TbProductServiceImpl implements TbProductService {
} }
@Override @Override
public Map<String, Object> queryAllV2(TbProductQueryV2Criteria criteria) { public Map<String, Object> queryAllV2(TbProductQueryV2Criteria criteria,Pageable pageable) {
Sort sort = Sort.by(Sort.Direction.ASC, "sort");
Pageable pageable = PageRequest.of(criteria.getPage(), criteria.getSize(), sort);
//查询商品数据 //查询商品数据
Page<TbProduct> page = tbProductRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root, criteria, criteriaBuilder), pageable); Page<TbProduct> page = tbProductRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root, criteria, criteriaBuilder), pageable);
List<TbProductNewVo> products = new ArrayList<>(); List<TbProductNewVo> products = new ArrayList<>();

View File

@@ -1,14 +1,19 @@
package cn.ysk.cashier.service.impl.productimpl; package cn.ysk.cashier.service.impl.productimpl;
import cn.hutool.core.bean.copier.CopyOptions;
import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.StrUtil;
import cn.ysk.cashier.dto.product.*; import cn.ysk.cashier.dto.product.*;
import cn.ysk.cashier.exception.BadRequestException; import cn.ysk.cashier.exception.BadRequestException;
import cn.ysk.cashier.mybatis.mapper.TbProducSkutMapper; import cn.ysk.cashier.mybatis.mapper.TbProducSkutMapper;
import cn.ysk.cashier.pojo.order.TbOrderInfo; import cn.ysk.cashier.pojo.order.TbOrderInfo;
import cn.ysk.cashier.pojo.product.TbProduct;
import cn.ysk.cashier.pojo.product.TbProductStockDetail; import cn.ysk.cashier.pojo.product.TbProductStockDetail;
import cn.ysk.cashier.pojo.shop.TbShopUnit;
import cn.ysk.cashier.repository.order.StockCountRepository; import cn.ysk.cashier.repository.order.StockCountRepository;
import cn.ysk.cashier.repository.order.TbOrderInfoRepository; import cn.ysk.cashier.repository.order.TbOrderInfoRepository;
import cn.ysk.cashier.repository.product.ProductStockCountRepository; import cn.ysk.cashier.repository.product.ProductStockCountRepository;
import cn.ysk.cashier.repository.product.TbProductRepository;
import cn.ysk.cashier.repository.shop.TbShopUnitRepository;
import cn.ysk.cashier.utils.*; import cn.ysk.cashier.utils.*;
import cn.ysk.cashier.vo.TbProductStockCountVo; import cn.ysk.cashier.vo.TbProductStockCountVo;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
@@ -46,6 +51,8 @@ public class TbProductStockDetailServiceImpl implements TbProductStockDetailServ
private final TbProductStockDetailRepository tbProductStockDetailRepository; private final TbProductStockDetailRepository tbProductStockDetailRepository;
private final TbProductStockDetailMapper tbProductStockDetailMapper; private final TbProductStockDetailMapper tbProductStockDetailMapper;
private final TbProductRepository tbProductRepository;
private final TbShopUnitRepository shopUnitRepository;
private final StockCountRepository stockCountRepository; private final StockCountRepository stockCountRepository;
private final ProductStockCountRepository stockRepository; private final ProductStockCountRepository stockRepository;
private final EntityManager entityManager; private final EntityManager entityManager;
@@ -122,7 +129,7 @@ public class TbProductStockDetailServiceImpl implements TbProductStockDetailServ
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
criteria.setStartTime(sdf.parse("2024-01-01"));//创建2024年1月1日的Date对象 criteria.setStartTime(sdf.parse("2024-01-01"));//创建2024年1月1日的Date对象
} }
return stockRepository.stockCount(criteria.getShopId().toString(), criteria.getProductName(), return stockRepository.productStockCount(criteria.getShopId().toString(), criteria.getProductName(),
criteria.getCategoryId(), criteria.getStartTime().getTime(), criteria.getEndTime().getTime()); criteria.getCategoryId(), criteria.getStartTime().getTime(), criteria.getEndTime().getTime());
} }
@@ -135,7 +142,7 @@ public class TbProductStockDetailServiceImpl implements TbProductStockDetailServ
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
criteria.setStartTime(sdf.parse("2024-01-01"));//创建2024年1月1日的Date对象 criteria.setStartTime(sdf.parse("2024-01-01"));//创建2024年1月1日的Date对象
} }
Page<TbProductStockListDto> tbProductStockCountDtos = stockRepository.stock2( Page<TbProductStockListDto> tbProductStockCountDtos = stockRepository.productStock(
criteria.getShopId().toString(), criteria.getShopId().toString(),
criteria.getProductName(), criteria.getProductName(),
criteria.getCategoryId(), criteria.getCategoryId(),
@@ -170,6 +177,25 @@ public class TbProductStockDetailServiceImpl implements TbProductStockDetailServ
return map; return map;
} }
@Override
public void frmLoss(TbProductFrmLossDto resources) {
TbProduct product = tbProductRepository.findById(Integer.valueOf(resources.getProductId())).orElse(null);
if(Objects.isNull(product)){
throw new BadRequestException("该商品不存在");
}
TbShopUnit tbShopUnit = shopUnitRepository.findById(product.getUnitId()).orElse(null);
TbProductStockDetail stockDetail = new TbProductStockDetail();
cn.hutool.core.bean.BeanUtil.copyProperties(resources,stockDetail, CopyOptions.create().setIgnoreNullValue(true));
stockDetail.setLeftNumber(product.getStockNumber());//原库存
stockDetail.setStockNumber(-stockDetail.getStockNumber());//变动数量
stockDetail.setSourcePath("CASHIER-APP");
stockDetail.setProductName(product.getName());
stockDetail.setUnitName(tbShopUnit==null?"":tbShopUnit.getName());
tbProductStockDetailRepository.save(stockDetail);
product.setStockNumber(product.getStockNumber()-stockDetail.getStockNumber().intValue());
tbProductRepository.save(product);
}
@Override @Override
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public TbProductStockDetailDto create(TbProductStockDetail resources) { public TbProductStockDetailDto create(TbProductStockDetail resources) {

View File

@@ -6,6 +6,7 @@ import cn.ysk.cashier.pojo.product.TbProduct;
import cn.ysk.cashier.vo.TbProductVo; import cn.ysk.cashier.vo.TbProductVo;
import cn.ysk.cashier.dto.product.TbProductDto; import cn.ysk.cashier.dto.product.TbProductDto;
import cn.ysk.cashier.dto.product.TbProductQueryCriteria; import cn.ysk.cashier.dto.product.TbProductQueryCriteria;
import org.springframework.data.domain.Pageable;
import java.util.Map; import java.util.Map;
import java.util.List; import java.util.List;
@@ -30,7 +31,7 @@ public interface TbProductService {
Map<String, Object> queryAll(TbProductQueryCriteria criteria, boolean isAdmin); Map<String, Object> queryAll(TbProductQueryCriteria criteria, boolean isAdmin);
Map<String, Object> queryAllV2(TbProductQueryV2Criteria criteria); Map<String, Object> queryAllV2(TbProductQueryV2Criteria criteria, Pageable pageable);
/** /**

View File

@@ -1,5 +1,6 @@
package cn.ysk.cashier.service.product; package cn.ysk.cashier.service.product;
import cn.ysk.cashier.dto.product.TbProductFrmLossDto;
import cn.ysk.cashier.dto.product.TbProductStockCountQueryCriteria; import cn.ysk.cashier.dto.product.TbProductStockCountQueryCriteria;
import cn.ysk.cashier.dto.rabbit.StockRecordMsg; import cn.ysk.cashier.dto.rabbit.StockRecordMsg;
import cn.ysk.cashier.pojo.product.TbProductStockDetail; import cn.ysk.cashier.pojo.product.TbProductStockDetail;
@@ -51,6 +52,8 @@ public interface TbProductStockDetailService {
TbProductStockDetailDto findById(Long id); TbProductStockDetailDto findById(Long id);
HashMap<String, BigDecimal> sumStockNumber(String productId); HashMap<String, BigDecimal> sumStockNumber(String productId);
void frmLoss(TbProductFrmLossDto resources);
/** /**
* 创建 * 创建
* @param resources / * @param resources /

View File

@@ -4,25 +4,31 @@ import lombok.Data;
@Data @Data
public class TbProductStockCountVo { public class TbProductStockCountVo {
//现有 //现有数量
private Long stockNumber; private Object stockNumber;
//增加 //增加数量
private Double addCountNumber; private Object addCountNumber;
//减少 //减少数量
private Double subCountNumber; private Object subCountNumber;
//增加 //手动增加
private Double addNumber; private Object addNumber;
//减少 //手动减少
private Double subNumber; private Object subNumber;
//销售量 //销售量/消耗
private Double saleNumber; private Object saleNumber;
//报损 //报损
private Double lossNumber; private Object lossNumber;
//退货 //退货
private Double refundNumber; private Object refundNumber;
//入库
private Object stockInNumber;
//出库
private Object stockOutNumber;
public TbProductStockCountVo(Long stockNumber, Double addCountNumber, Double subCountNumber, Double addNumber, Double subNumber, Double saleNumber, Double lossNumber, Double refundNumber) { public TbProductStockCountVo(
Object stockNumber, Object addCountNumber, Object subCountNumber, Object addNumber,
Object subNumber, Object saleNumber, Object lossNumber, Object refundNumber) {
this.stockNumber = stockNumber; this.stockNumber = stockNumber;
this.addCountNumber = addCountNumber; this.addCountNumber = addCountNumber;
this.subCountNumber = subCountNumber; this.subCountNumber = subCountNumber;
@@ -32,4 +38,31 @@ public class TbProductStockCountVo {
this.lossNumber = lossNumber; this.lossNumber = lossNumber;
this.refundNumber = refundNumber; this.refundNumber = refundNumber;
} }
//现有数量stockNumber;
//增加数量addCountNumber;
//减少数量subCountNumber;
//手动增加addNumber;
//手动减少subNumber;
//销售量/消耗saleNumber;
//报损lossNumber;
//退货refundNumber;
//入库stockInNumber;
//出库stockOutNumber;
public TbProductStockCountVo(
Object stockNumber, Object addCountNumber, Object subCountNumber, Object addNumber, Object subNumber,
Object saleNumber, Object lossNumber, Object refundNumber, Object stockInNumber, Object stockOutNumber) {
this.stockNumber = stockNumber;
this.addCountNumber = addCountNumber;
this.subCountNumber = subCountNumber;
this.addNumber = addNumber;
this.subNumber = subNumber;
this.saleNumber = saleNumber;
this.lossNumber = lossNumber;
this.refundNumber = refundNumber;
this.stockInNumber = stockInNumber;
this.stockOutNumber = stockOutNumber;
}
} }