wangyingyang

fix

......@@ -48,7 +48,16 @@ public class SettlementDTO {
@Data
@Builder
@ApiModel(description = "SettlementRequestDto")
@ApiModel(description = "SettlementMenuMealDto")
public static class SettlementMenuMealDto {
private String skuName;
private Integer price;
private Integer count;
}
@Data
@Builder
@ApiModel(description = "SettlementDataDto")
public static class SettlementDataDto {
private String client;
private String startTime;
......@@ -56,6 +65,16 @@ public class SettlementDTO {
private Map<String, Map<String, List<SettlementMenuSkuDto>>> classifyOrders;
}
@Data
@Builder
@ApiModel(description = "SettlementDataByMealDto")
public static class SettlementDataByMealDto {
private String client;
private LocalDateTime startTime;
private LocalDateTime endTime;
private Map<String, Map<String, Map<String, List<SettlementMenuMealDto>>>> classifyOrders;
}
}
......
......@@ -4,21 +4,33 @@ import com.infoloop.tianting.clientcustomerorderservice.OrderStatusEnum;
import com.infoloop.tianting.clientcustomerorderservice.SingleClientCustomerOrderDetailRpcResponse;
import com.infoloop.tianting.clientcustomerorderservice.SingleClientCustomerOrderRpcResponse;
import com.infoloop.tianting.context.LoginContextHolder;
import com.infoloop.tianting.enums.SettlementDimensionEnum;
import com.infoloop.tianting.exception.ClientEndExceptions.BusinessException;
import com.infoloop.tianting.exception.ErrorCodeEnum;
import com.infoloop.tianting.menuservice.SingleMenuDetailRpcResponse;
import com.infoloop.tianting.menuservice.SingleMenuRpcResponse;
import com.infoloop.tianting.model.dto.OrderDbDTO.QueryOrderByConditionDto;
import com.infoloop.tianting.model.dto.SettlementDTO;
import com.infoloop.tianting.model.dto.SettlementDTO.SettlementDataByMealDto;
import com.infoloop.tianting.model.dto.SettlementDTO.SettlementDataDto;
import com.infoloop.tianting.model.dto.SettlementDTO.SettlementMenuMealDto;
import com.infoloop.tianting.model.dto.SettlementDTO.SettlementMenuSkuDto;
import com.infoloop.tianting.model.dto.SettlementDTO.SettlementRequestDto;
import com.infoloop.tianting.service.SettlementService;
import com.infoloop.tianting.service.client.InventoryServiceRpcClient;
import com.infoloop.tianting.service.client.MealServiceRpcClient;
import com.infoloop.tianting.service.client.MenuServiceRpcClient;
import com.infoloop.tianting.service.client.OrderServiceRpcClient;
import com.infoloop.tianting.service.client.SkuServiceRpcClient;
import com.infoloop.tianting.setmealscheduleservice.SingleMealRpcResponse;
import com.infoloop.tianting.utils.DateUtil;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
import java.util.Comparator;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.hpsf.Date;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
......@@ -45,9 +57,19 @@ public class SettlementServiceImpl implements SettlementService {
private final MenuServiceRpcClient menuServiceRpcClient;
private final SkuServiceRpcClient skuServiceRpcClient;
private final InventoryServiceRpcClient inventoryServiceRpcClient;
private final MealServiceRpcClient mealServiceRpcClient;
@Override
public ByteArrayOutputStream generateOrderSettlementExcel(SettlementRequestDto settlementRequest) {
if (settlementRequest.getDimension().equals(SettlementDimensionEnum.BY_SKU)) {
return generateOrderSettlementExcelBySku(settlementRequest);
} else {
return generateOrderSettlementExcelByMeal(settlementRequest);
}
}
public ByteArrayOutputStream generateOrderSettlementExcelBySku(SettlementRequestDto settlementRequest) {
final var startDate = settlementRequest.getTimeStart().toLocalDate().atStartOfDay();
final var endDate = settlementRequest.getTimeEnd().toLocalDate().plusDays(1).atStartOfDay();
final var operatorLoginInfo = LoginContextHolder.getLoginInfo();
......@@ -185,7 +207,7 @@ public class SettlementServiceImpl implements SettlementService {
.endTime(DateUtil.formatDate(settlementRequest.getTimeEnd(), DateUtil.YYYY_MM_DD))
.build();
try {
final var bytes = writeToExcel(settlementDataDto);
final var bytes = writeToExcelBySku(settlementDataDto);
return bytes;
} catch (IOException e) {
throw BusinessException.build(ErrorCodeEnum.GENERATE_EXCEL_ERROR);
......@@ -193,7 +215,7 @@ public class SettlementServiceImpl implements SettlementService {
}
public static ByteArrayOutputStream writeToExcel(SettlementDataDto settlementDataDto)
public static ByteArrayOutputStream writeToExcelBySku(SettlementDataDto settlementDataDto)
throws IOException {
Workbook workbook = new XSSFWorkbook();
Sheet sheet = workbook.createSheet("订单数据");
......@@ -295,4 +317,225 @@ public class SettlementServiceImpl implements SettlementService {
return outputStream;
}
public ByteArrayOutputStream generateOrderSettlementExcelByMeal(SettlementRequestDto settlementRequest) {
final var startDate = settlementRequest.getTimeStart().toLocalDate().atStartOfDay();
final var endDate = settlementRequest.getTimeEnd().toLocalDate().plusDays(1).atStartOfDay();
final var operatorLoginInfo = LoginContextHolder.getLoginInfo();
final var queryOrderDto = QueryOrderByConditionDto.builder()
.enterpriseId(LoginContextHolder.hasLogin() ? operatorLoginInfo.getEnterpriseId() : settlementRequest.getEnterpriseId())
.shouldFilterCreatedAtTimeStart(true)
.createdAtTimeStart(startDate)
.shouldFilterCreatedAtTimeEnd(true)
.createdAtTimeEnd(endDate)
.shouldFilterStallIds(!settlementRequest.getStallIds().isEmpty())
.stallIds(settlementRequest.getStallIds())
.build();
final var orderList = orderServiceRpcClient.getOrdersByCondition(queryOrderDto);
List<Integer> orderIds = orderList.stream()
.filter(o -> !o.getStatus().equals(OrderStatusEnum.ORDER_CANCELED))
.map(SingleClientCustomerOrderRpcResponse::getId).distinct()
.collect(Collectors.toList());
final var orderDetailList = orderServiceRpcClient.getOrderDetailsByOrderIds(orderIds);
List<Integer> skuIds = orderDetailList.stream()
.map(SingleClientCustomerOrderDetailRpcResponse::getSkuId)
.distinct()
.collect(Collectors.toList());
final var skus = skuServiceRpcClient.getDishSkusByIds(skuIds).getResponseList();
List<Integer> menuIds = orderList.stream().map(
SingleClientCustomerOrderRpcResponse::getMenuId).distinct()
.collect(Collectors.toList());
final var menuList = menuServiceRpcClient
.getMenusByIds(operatorLoginInfo.getEnterpriseId(), menuIds)
.getResponsesList();
final var menuDetailList = menuServiceRpcClient.queryMenuDetailsByMenuIds(
operatorLoginInfo.getEnterpriseId(), menuIds).getResponsesList();
//获取到所有的餐别
final var allMeals = mealServiceRpcClient.getAllMeals(operatorLoginInfo.getEnterpriseId()).getResponsesList();
Map<String, Map<String, Map<String, List<SettlementMenuMealDto>>>> classifyOrders = new HashMap<>();
for(SingleMenuRpcResponse menu: menuList) {
final var menuName = menu.getName();
if (!classifyOrders.containsKey(menuName)) {
classifyOrders.put(menuName, new HashMap<>());
}
final var menusMap = classifyOrders.get(menuName);
//这个餐单下所有已点的orders
final var curMenuOrders = orderList.stream()
.filter(o -> o.getMenuId() == menu.getId())
.collect(Collectors.toList());
final var curMenuOrderIds = curMenuOrders.stream()
.map(SingleClientCustomerOrderRpcResponse::getId)
.collect(Collectors.toList());
//这个餐单下所有已点的order details
final var curMenuOrderDetails = orderDetailList.stream()
.filter(od -> curMenuOrderIds.contains(od.getOrderId()))
.collect(Collectors.toList());
//这个餐单下所有已点的餐别
final var curMenuMealIds = curMenuOrderDetails.stream()
.map(SingleClientCustomerOrderDetailRpcResponse::getMealId)
.distinct()
.collect(Collectors.toList());
final var curMenuMeals = allMeals.stream()
.filter(m -> curMenuMealIds.contains(m.getId()))
.collect(Collectors.toList());
// 汇总每个餐别的情况
for(SingleMealRpcResponse meal: curMenuMeals) {
final var mealName = meal.getName();
if (!menusMap.containsKey(mealName)) {
menusMap.put(menuName, new HashMap<>());
}
final var mealsMap = menusMap.get(mealName);
//当前餐别已点的order details
final var curMealOrderDetails = curMenuOrderDetails.stream()
.filter(od -> od.getMealId() == meal.getId())
.collect(Collectors.toList());
//找出所有需要的日期
final var dates = curMealOrderDetails.stream()
.sorted(Comparator.comparingLong(SingleClientCustomerOrderDetailRpcResponse::getCreatedAt))
.map(o -> DateUtil.formatDateOfUtc(o.getCreatedAt(), DateUtil.YYYY_MM_DD_UTC))
.distinct()
.collect(Collectors.toList());
for(String date: dates) {
if (!mealsMap.containsKey(date)) {
mealsMap.put(date, new ArrayList<>());
}
final var curMealDateSkuList = mealsMap.get(date);
//找出当天所有的order details
final var curMealDateOrderDetails = curMealOrderDetails.stream()
.filter(o -> DateUtil.formatDateOfUtc(o.getCreatedAt(), DateUtil.YYYY_MM_DD_UTC).equals(date))
.collect(Collectors.toList());
for(SingleClientCustomerOrderDetailRpcResponse detail: curMealDateOrderDetails) {
final var settlementOrderDetail = SettlementMenuMealDto.builder()
.skuName(detail.getShowName())
.count(detail.getCount())
.price(detail.getPrice())
.build();
curMealDateSkuList.add(settlementOrderDetail);
}
}
}
}
final var client = inventoryServiceRpcClient.getClientById(operatorLoginInfo.getEnterpriseId(),
settlementRequest.getClientId()).getClient();
final var settlementDataByMealDto = SettlementDataByMealDto.builder()
.classifyOrders(classifyOrders)
.client(client.getName())
.startTime(settlementRequest.getTimeStart())
.endTime(settlementRequest.getTimeEnd())
.build();
try {
final var bytes = writeToExcelByMeal(settlementDataByMealDto);
return bytes;
} catch (IOException e) {
throw BusinessException.build(ErrorCodeEnum.GENERATE_EXCEL_ERROR);
}
}
public static ByteArrayOutputStream writeToExcelByMeal(SettlementDataByMealDto settlementDataDto)
throws IOException {
Workbook workbook = new XSSFWorkbook();
Sheet sheet = workbook.createSheet("订单数据");
final var classifyOrders = settlementDataDto.getClassifyOrders();
int rowNum = 0;
Row sheetTitleRow = sheet.createRow(rowNum++);
Cell sheetTitleCell = sheetTitleRow.createCell(0);
sheetTitleCell.setCellValue(settlementDataDto.getClient());
Row dateRangeRow = sheet.createRow(rowNum++);
Cell dateRangeCell = dateRangeRow.createCell(0);
final var dateRange = settlementDataDto.getStartTime() + "至" + settlementDataDto.getEndTime();
dateRangeCell.setCellValue(dateRange);
Row titleRow = sheet.createRow(rowNum++);
int columnNum = 0;
Cell menuTitleCell = titleRow.createCell(columnNum++);
menuTitleCell.setCellValue("餐单名称");
Cell mealTitleCell = titleRow.createCell(columnNum++);
mealTitleCell.setCellValue("餐别");
final var dates = getDatesBetween(settlementDataDto.getStartTime(),
settlementDataDto.getEndTime());
for (String date: dates) {
Cell dateTitleCell = titleRow.createCell(columnNum++);
dateTitleCell.setCellValue(date);
}
Cell priceTitleCell = titleRow.createCell(columnNum);
priceTitleCell.setCellValue("总金额");
for (Map.Entry<String, Map<String, Map<String, List<SettlementMenuMealDto>>>> outerEntry : classifyOrders.entrySet()) {
String menuNme = outerEntry.getKey();
Map<String, Map<String, List<SettlementMenuMealDto>>> innerMap = outerEntry.getValue();
int curMenuTotalRow = innerMap.size();
// 写入menu列并合并单元格
int startRowForMenu = rowNum;
for (int i = 0; i < curMenuTotalRow; i++) {
Row dateRow = sheet.createRow(rowNum++);
Cell menuCell = dateRow.createCell(0);
menuCell.setCellValue(menuNme);
}
int endRowForDate = rowNum - 1;
if (endRowForDate > startRowForMenu) {
CellRangeAddress dateRegion = new CellRangeAddress(startRowForMenu, endRowForDate, 0, 0);
sheet.addMergedRegion(dateRegion);
}
rowNum = startRowForMenu;
for (Map.Entry<String, Map<String, List<SettlementMenuMealDto>>> innerEntry : innerMap.entrySet()) {
String mealName = innerEntry.getKey();
Map<String, List<SettlementMenuMealDto>> skuMap = innerEntry.getValue();
// 写入meal列并合并单元格
Row mealRow = sheet.getRow(rowNum++);
Cell mealCell = mealRow.createCell(1);
mealCell.setCellValue(mealName);
columnNum = 2;
Integer totalPrice = 0;
for (String date: dates) {
final var toWriteDateSkuList = skuMap.get(date);
Integer price = 0;
if(!toWriteDateSkuList.isEmpty()) {
for (SettlementMenuMealDto settlementMenuMealDto: toWriteDateSkuList) {
price += settlementMenuMealDto.getPrice() * settlementMenuMealDto.getCount();
totalPrice += price;
}
}
Cell priceCell = mealRow.createCell(columnNum++);
priceCell.setCellValue((double)price/100);
}
Cell totalPriceCell = mealRow.createCell(columnNum);
totalPriceCell.setCellValue((double)totalPrice/100);
}
}
// 自动调整列宽
for (int i = 0; i < 7; i++) {
sheet.autoSizeColumn(i);
}
// 将工作簿内容写入字节数组输出流
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
workbook.write(outputStream);
workbook.close();
return outputStream;
}
public static List<String> getDatesBetween(LocalDateTime startTime, LocalDateTime endTime) {
List<String> dateList = new ArrayList<>();
LocalDate startDate = startTime.toLocalDate();
LocalDate endDate = endTime.toLocalDate();
long daysBetween = ChronoUnit.DAYS.between(startDate, endDate) + 1;
for (int i = 0; i < daysBetween; i++) {
LocalDate currentDate = startDate.plusDays(i);
dateList.add(DateUtil.formatDate(currentDate, DateUtil.YYYY_MM_DD));
}
return dateList;
}
}
......