MealOrderServiceImpl.java 7.03 KB
package com.infoloop.tianting.service.impl;

import com.infoloop.tianting.context.LoginContextHolder;
import com.infoloop.tianting.enums.QueryMealOrderStatusEnum;
import com.infoloop.tianting.exception.ClientEndExceptions;
import com.infoloop.tianting.exception.ErrorCodeEnum;
import com.infoloop.tianting.mealorderservice.MealOrderCreation;
import com.infoloop.tianting.mealorderservice.MealOrderOrderMethodEnum;
import com.infoloop.tianting.mealorderservice.MenuSchedule;
import com.infoloop.tianting.mealorderservice.SingleMealOrderRpcResponse;
import com.infoloop.tianting.model.common.CreatedResult;
import com.infoloop.tianting.model.dto.MealOrderDTO;
import com.infoloop.tianting.model.vo.MealOrderVO;
import com.infoloop.tianting.service.MealOrderService;
import com.infoloop.tianting.service.client.ClientInventoryServiceRpcClient;
import com.infoloop.tianting.service.client.MealOrderServiceRpcClient;
import com.infoloop.tianting.utils.DateUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.DayOfWeek;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalTime;
import java.util.Collections;
import java.util.List;

@Slf4j
@Service
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class MealOrderServiceImpl implements MealOrderService {

    private final MealOrderServiceRpcClient mealOrderServiceRpcClient;

    private final ClientInventoryServiceRpcClient clientInventoryServiceRpcClient;

    @Override
    public List<MealOrderVO> queryMealOrders(MealOrderDTO.QueryMealOrderDTO queryMealOrderDTO) {
        final var loginInfo = LoginContextHolder.getLoginInfo();
        var mealOrderRpcResponses = mealOrderServiceRpcClient.queryMealOrdersByCondition(loginInfo.getEnterpriseId(), loginInfo.getId(), null, null);
        final var today = LocalDate.now();
        final var lastWeekStart = today.minusWeeks(1).with(DayOfWeek.MONDAY).atStartOfDay().atZone(DateUtil.CHINA_ZONE).toInstant().toEpochMilli();
        final var lastWeekEnd = today.minusWeeks(1).with(DayOfWeek.SUNDAY).atTime(LocalTime.MAX).atZone(DateUtil.CHINA_ZONE).toInstant().toEpochMilli();
        final var thisWeekStart = today.with(DayOfWeek.MONDAY).atStartOfDay().atZone(DateUtil.CHINA_ZONE).toInstant().toEpochMilli();
        if (queryMealOrderDTO.getStatus() == QueryMealOrderStatusEnum.COMPLETED) {
            mealOrderRpcResponses = mealOrderRpcResponses.stream().filter(e -> e.getReserveDate() < lastWeekStart).toList();
        } else if (queryMealOrderDTO.getStatus() == QueryMealOrderStatusEnum.UNDER_WAY) {
            mealOrderRpcResponses = mealOrderRpcResponses.stream().filter(e -> e.getReserveDate() >= lastWeekStart && e.getReserveDate() <= lastWeekEnd).toList();
        } else if (queryMealOrderDTO.getStatus() == QueryMealOrderStatusEnum.BE_BOOKED) {
            mealOrderRpcResponses = mealOrderRpcResponses.stream().filter(e -> e.getReserveDate() > thisWeekStart).toList();
        }
        return mealOrderRpcResponses.stream().map(this::getMealOrderById).toList();
    }

    @Override
    public CreatedResult<MealOrderVO> createMealOrder(MealOrderDTO.CreateMealOrderDTO createMealOrderDTO) {
        final var loginInfo = LoginContextHolder.getLoginInfo();
        final var reserveDinerMealOrders = mealOrderServiceRpcClient.queryReserveMealOrdersByDinerIds(loginInfo.getEnterpriseId(), Collections.singletonList(createMealOrderDTO.getDinerId()));
        if (!reserveDinerMealOrders.isEmpty()) {
            throw ClientEndExceptions.IncorrectRequestValue.build(ErrorCodeEnum.DINER_ALREADY_RESERVED);
        }
        final var dinerById = mealOrderServiceRpcClient.getDinerById(loginInfo.getEnterpriseId(), createMealOrderDTO.getDinerId());
        if (dinerById == null) {
            throw ClientEndExceptions.IncorrectRequestValue.build(ErrorCodeEnum.DINER_NOT_FOUND);
        }
        final var clientById = clientInventoryServiceRpcClient.getClientById(loginInfo.getEnterpriseId(), dinerById.getClientId());
        if (clientById == null) {
            throw ClientEndExceptions.IncorrectRequestValue.build(ErrorCodeEnum.CLIENT_NOT_FOUND);
        }
        if (clientById.getClient().getStatus() != 1) {
            throw ClientEndExceptions.IncorrectRequestValue.build(ErrorCodeEnum.CLIENT_NOT_ENABLED);
        }
        final var gradeClassById = mealOrderServiceRpcClient.getGradeClassById(loginInfo.getEnterpriseId(), dinerById.getClassId());
        if (gradeClassById == null) {
            throw ClientEndExceptions.IncorrectRequestValue.build(ErrorCodeEnum.GRADE_CLASS_NOT_FOUND);
        }
        final var latestMealMenuRecords = mealOrderServiceRpcClient.queryLatestMealMenuRecordsByClientIds(loginInfo.getEnterpriseId(), Collections.singletonList(dinerById.getClientId()));
        if (latestMealMenuRecords.isEmpty()) {
            throw ClientEndExceptions.IncorrectRequestValue.build(ErrorCodeEnum.MEAL_MENU_NOT_FOUND);
        }
        final var mealOrder = mealOrderServiceRpcClient.createMealOrder(loginInfo, MealOrderCreation.newBuilder()
                .setClientId(dinerById.getClientId())
                .setMenuId(latestMealMenuRecords.get(0).getId())
                .setAccountId(loginInfo.getId())
                .setOrderMethod(MealOrderOrderMethodEnum.MEAL_ORDER_METHOD_MICRO)
                .setDinerId(createMealOrderDTO.getDinerId())
                .setDinerName(dinerById.getName())
                .setClientName(clientById.getClient().getName())
                .setGradeName(gradeClassById.getGradeName())
                .setClassName(gradeClassById.getClassName())
                .setStudentNo(dinerById.getStudentNo())
                .setReserveDate(Instant.now().toEpochMilli())
                .addAllMeals(createMealOrderDTO.getMeals().stream().map(e -> MenuSchedule.newBuilder()
                        .setDate(e.getDate())
                        .setMenu(e.getMenu())
                        .build()).toList())
                .build());
        return CreatedResult.<MealOrderVO>builder().id(mealOrder.getId()).isCreated(mealOrder.getIsCreated()).build();
    }

    @Override
    public MealOrderVO getMealOrderById(SingleMealOrderRpcResponse mealOrder) {
        return MealOrderVO.builder()
                .id(mealOrder.getId())
                .clientId(mealOrder.getClientId())
                .menuId(mealOrder.getMenuId())
                .accountId(mealOrder.getAccountId())
                .orderMethod(mealOrder.getOrderMethod())
                .dinerId(mealOrder.getDinerId())
                .dinerName(mealOrder.getDinerName())
                .clientName(mealOrder.getClientName())
                .gradeName(mealOrder.getGradeName())
                .className(mealOrder.getClassName())
                .studentNo(mealOrder.getStudentNo())
                .reserveDate(DateUtil.formatDate(mealOrder.getReserveDate()))
                .meals(mealOrder.getMealsList().stream().map(e -> MealOrderVO.Meals.builder().date(e.getDate()).menu(e.getMenu()).build()).toList())
                .build();
    }
}