出入库统计,优化
This commit is contained in:
@@ -22,7 +22,9 @@ import org.springframework.web.bind.annotation.*;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import javax.validation.constraints.NotEmpty;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
import java.util.Arrays;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@@ -46,6 +48,13 @@ public class GearStockIoOrderController extends BaseController {
|
||||
ExcelUtil.exportExcel(list, "出入库单据", GearStockIoOrderVo.class, response);
|
||||
}
|
||||
|
||||
@GetMapping("/materialFlow")
|
||||
public R<IGearStockIoOrderService.MaterialFlowResp> materialFlow(@NotNull(message = "物料ID不能为空") @RequestParam Long itemId,
|
||||
@RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") Date startTime,
|
||||
@RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") Date endTime) {
|
||||
return R.ok(stockIoOrderService.queryMaterialFlow(itemId, startTime, endTime));
|
||||
}
|
||||
|
||||
@GetMapping("/{orderId}")
|
||||
public R<GearStockIoOrderVo> getInfo(@NotNull(message = "主键不能为空") @PathVariable Long orderId) {
|
||||
return R.ok(stockIoOrderService.queryById(orderId));
|
||||
|
||||
@@ -6,8 +6,11 @@ import com.gear.oa.domain.bo.GearStockIoOrderBo;
|
||||
import com.gear.oa.domain.bo.GearStockIoOrderWithDetailBo;
|
||||
import com.gear.oa.domain.vo.GearStockIoOrderVo;
|
||||
import com.gear.oa.domain.vo.GearStockIoOrderWithDetailVo;
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Collection;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
public interface IGearStockIoOrderService {
|
||||
@@ -29,4 +32,31 @@ public interface IGearStockIoOrderService {
|
||||
void confirmIn(Long orderId);
|
||||
|
||||
void revoke(Long orderId, String reason);
|
||||
|
||||
MaterialFlowResp queryMaterialFlow(Long itemId, Date startTime, Date endTime);
|
||||
|
||||
@lombok.Data
|
||||
class MaterialFlowResp {
|
||||
private Long itemId;
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
|
||||
private Date startTime;
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
|
||||
private Date endTime;
|
||||
private BigDecimal confirmInQty;
|
||||
private BigDecimal outQty;
|
||||
private BigDecimal revokeInQty;
|
||||
private BigDecimal revokeOutQty;
|
||||
private BigDecimal netQty;
|
||||
private List<MaterialFlowRow> rows;
|
||||
}
|
||||
|
||||
@lombok.Data
|
||||
class MaterialFlowRow {
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
|
||||
private Date time;
|
||||
private String action;
|
||||
private String orderCode;
|
||||
private String ioType;
|
||||
private BigDecimal qtyChange;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,6 +20,8 @@ import com.gear.oa.domain.vo.GearStockIoOrderVo;
|
||||
import com.gear.oa.domain.vo.GearStockIoOrderWithDetailVo;
|
||||
import com.gear.oa.mapper.*;
|
||||
import com.gear.oa.service.IGearStockIoOrderService;
|
||||
import com.gear.oa.service.IGearStockIoOrderService.MaterialFlowResp;
|
||||
import com.gear.oa.service.IGearStockIoOrderService.MaterialFlowRow;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
@@ -355,6 +357,129 @@ public class GearStockIoOrderServiceImpl implements IGearStockIoOrderService {
|
||||
baseMapper.updateById(update);
|
||||
}
|
||||
|
||||
@Override
|
||||
public MaterialFlowResp queryMaterialFlow(Long itemId, Date startTime, Date endTime) {
|
||||
if (itemId == null) {
|
||||
throw new ServiceException("物料ID不能为空");
|
||||
}
|
||||
List<GearStockIoOrder> confirmOrders = baseMapper.selectList(Wrappers.<GearStockIoOrder>lambdaQuery()
|
||||
.eq(GearStockIoOrder::getIoType, "I")
|
||||
.eq(GearStockIoOrder::getConfirmInFlag, "1")
|
||||
.isNotNull(GearStockIoOrder::getConfirmInTime)
|
||||
.ge(startTime != null, GearStockIoOrder::getConfirmInTime, startTime)
|
||||
.le(endTime != null, GearStockIoOrder::getConfirmInTime, endTime)
|
||||
.eq(GearStockIoOrder::getDelFlag, "0"));
|
||||
|
||||
List<GearStockIoOrder> outOrders = baseMapper.selectList(Wrappers.<GearStockIoOrder>lambdaQuery()
|
||||
.eq(GearStockIoOrder::getIoType, "O")
|
||||
.isNotNull(GearStockIoOrder::getExecuteTime)
|
||||
.ge(startTime != null, GearStockIoOrder::getExecuteTime, startTime)
|
||||
.le(endTime != null, GearStockIoOrder::getExecuteTime, endTime)
|
||||
.eq(GearStockIoOrder::getDelFlag, "0"));
|
||||
|
||||
List<GearStockIoOrder> revokeOrders = baseMapper.selectList(Wrappers.<GearStockIoOrder>lambdaQuery()
|
||||
.eq(GearStockIoOrder::getRevokeFlag, "1")
|
||||
.isNotNull(GearStockIoOrder::getRevokeTime)
|
||||
.ge(startTime != null, GearStockIoOrder::getRevokeTime, startTime)
|
||||
.le(endTime != null, GearStockIoOrder::getRevokeTime, endTime)
|
||||
.eq(GearStockIoOrder::getDelFlag, "0"));
|
||||
|
||||
Set<Long> orderIds = new HashSet<>();
|
||||
for (GearStockIoOrder o : confirmOrders) {
|
||||
if (o != null && o.getOrderId() != null) orderIds.add(o.getOrderId());
|
||||
}
|
||||
for (GearStockIoOrder o : outOrders) {
|
||||
if (o != null && o.getOrderId() != null) orderIds.add(o.getOrderId());
|
||||
}
|
||||
for (GearStockIoOrder o : revokeOrders) {
|
||||
if (o != null && o.getOrderId() != null) orderIds.add(o.getOrderId());
|
||||
}
|
||||
|
||||
Map<Long, BigDecimal> qtyMap = new HashMap<>();
|
||||
if (!orderIds.isEmpty()) {
|
||||
List<GearStockIoOrderDetail> details = detailMapper.selectList(Wrappers.<GearStockIoOrderDetail>lambdaQuery()
|
||||
.in(GearStockIoOrderDetail::getOrderId, orderIds)
|
||||
.eq(GearStockIoOrderDetail::getItemType, "material")
|
||||
.eq(GearStockIoOrderDetail::getItemId, itemId)
|
||||
.eq(GearStockIoOrderDetail::getDelFlag, "0"));
|
||||
for (GearStockIoOrderDetail d : details) {
|
||||
if (d == null || d.getOrderId() == null) continue;
|
||||
BigDecimal q = d.getQuantity() == null ? BigDecimal.ZERO : d.getQuantity();
|
||||
qtyMap.merge(d.getOrderId(), q, BigDecimal::add);
|
||||
}
|
||||
}
|
||||
|
||||
BigDecimal confirmInQty = BigDecimal.ZERO;
|
||||
BigDecimal outQty = BigDecimal.ZERO;
|
||||
BigDecimal revokeInQty = BigDecimal.ZERO;
|
||||
BigDecimal revokeOutQty = BigDecimal.ZERO;
|
||||
List<MaterialFlowRow> rows = new ArrayList<>();
|
||||
|
||||
for (GearStockIoOrder o : confirmOrders) {
|
||||
if (o == null || o.getOrderId() == null || o.getConfirmInTime() == null) continue;
|
||||
BigDecimal qty = qtyMap.getOrDefault(o.getOrderId(), BigDecimal.ZERO);
|
||||
if (qty.compareTo(BigDecimal.ZERO) <= 0) continue;
|
||||
MaterialFlowRow r = new MaterialFlowRow();
|
||||
r.setTime(o.getConfirmInTime());
|
||||
r.setAction("确认入库");
|
||||
r.setOrderCode(o.getOrderCode());
|
||||
r.setIoType(o.getIoType());
|
||||
r.setQtyChange(qty);
|
||||
rows.add(r);
|
||||
confirmInQty = confirmInQty.add(qty);
|
||||
}
|
||||
|
||||
for (GearStockIoOrder o : outOrders) {
|
||||
if (o == null || o.getOrderId() == null || o.getExecuteTime() == null) continue;
|
||||
BigDecimal qty = qtyMap.getOrDefault(o.getOrderId(), BigDecimal.ZERO);
|
||||
if (qty.compareTo(BigDecimal.ZERO) <= 0) continue;
|
||||
MaterialFlowRow r = new MaterialFlowRow();
|
||||
r.setTime(o.getExecuteTime());
|
||||
r.setAction("出库");
|
||||
r.setOrderCode(o.getOrderCode());
|
||||
r.setIoType(o.getIoType());
|
||||
r.setQtyChange(qty.negate());
|
||||
rows.add(r);
|
||||
outQty = outQty.add(qty);
|
||||
}
|
||||
|
||||
for (GearStockIoOrder o : revokeOrders) {
|
||||
if (o == null || o.getOrderId() == null || o.getRevokeTime() == null) continue;
|
||||
BigDecimal qty = qtyMap.getOrDefault(o.getOrderId(), BigDecimal.ZERO);
|
||||
if (qty.compareTo(BigDecimal.ZERO) <= 0) continue;
|
||||
MaterialFlowRow r = new MaterialFlowRow();
|
||||
r.setTime(o.getRevokeTime());
|
||||
r.setAction("撤回");
|
||||
r.setOrderCode(o.getOrderCode());
|
||||
r.setIoType(o.getIoType());
|
||||
if ("O".equalsIgnoreCase(o.getIoType())) {
|
||||
r.setQtyChange(qty);
|
||||
revokeOutQty = revokeOutQty.add(qty);
|
||||
} else if ("I".equalsIgnoreCase(o.getIoType())) {
|
||||
r.setQtyChange(qty.negate());
|
||||
revokeInQty = revokeInQty.add(qty);
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
rows.add(r);
|
||||
}
|
||||
|
||||
rows.sort(Comparator.comparing(MaterialFlowRow::getTime));
|
||||
BigDecimal net = confirmInQty.subtract(outQty).add(revokeOutQty).subtract(revokeInQty);
|
||||
|
||||
MaterialFlowResp resp = new MaterialFlowResp();
|
||||
resp.setItemId(itemId);
|
||||
resp.setStartTime(startTime);
|
||||
resp.setEndTime(endTime);
|
||||
resp.setConfirmInQty(confirmInQty);
|
||||
resp.setOutQty(outQty);
|
||||
resp.setRevokeInQty(revokeInQty);
|
||||
resp.setRevokeOutQty(revokeOutQty);
|
||||
resp.setNetQty(net);
|
||||
resp.setRows(rows);
|
||||
return resp;
|
||||
}
|
||||
|
||||
private GearStockIoOrder requireOrder(Long orderId) {
|
||||
if (orderId == null) {
|
||||
throw new ServiceException("单据ID不能为空");
|
||||
|
||||
Reference in New Issue
Block a user