DinerServiceImpl.java 10.3 KB
package com.infoloop.tianting.service.impl;

import com.infoloop.tianting.clientinventoryservice.SingleClientRpcResponse;
import com.infoloop.tianting.context.LoginContextHolder;
import com.infoloop.tianting.exception.ClientEndExceptions;
import com.infoloop.tianting.exception.ErrorCodeEnum;
import com.infoloop.tianting.mealorderservice.DinerCreation;
import com.infoloop.tianting.mealorderservice.DinerModification;
import com.infoloop.tianting.mealorderservice.MpAccountDinerRefCreation;
import com.infoloop.tianting.mealorderservice.SingleDinerRpcResponse;
import com.infoloop.tianting.mealorderservice.SingleGradeClassRpcResponse;
import com.infoloop.tianting.mealorderservice.SingleMealOrderRpcResponse;
import com.infoloop.tianting.mealorderservice.SingleMpAccountDinerRefRpcResponse;
import com.infoloop.tianting.model.common.CreatedResult;
import com.infoloop.tianting.model.dto.DinerDTO;
import com.infoloop.tianting.model.vo.DinerVO;
import com.infoloop.tianting.model.vo.GradeClassVO;
import com.infoloop.tianting.service.DinerService;
import com.infoloop.tianting.service.client.ClientInventoryServiceRpcClient;
import com.infoloop.tianting.service.client.MealOrderServiceRpcClient;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Collections;
import java.util.List;
import java.util.function.Function;
import java.util.stream.Collectors;

@Slf4j
@Service
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class DinerServiceImpl implements DinerService {

    private final MealOrderServiceRpcClient mealOrderServiceRpcClient;

    private final ClientInventoryServiceRpcClient clientInventoryServiceRpcClient;

    @Override
    public List<DinerVO> getMpAccountDiners() {
        final var loginInfo = LoginContextHolder.getLoginInfo();
        final var mpAccountDinerRefRpcResponseList = mealOrderServiceRpcClient.queryMpAccountDinerRefsByCondition(loginInfo.getEnterpriseId(), List.of(loginInfo.getId()), Collections.emptyList());
        final var dinerIds = mpAccountDinerRefRpcResponseList.stream().map(SingleMpAccountDinerRefRpcResponse::getDinerId).toList();
        if (dinerIds.isEmpty()) {
            return Collections.emptyList();
        }
        final var dinersByIds = mealOrderServiceRpcClient.getDinersByIds(loginInfo.getEnterpriseId(), dinerIds);
        final var clientIds = dinersByIds.stream().map(SingleDinerRpcResponse::getClientId).distinct().toList();
        final var gradeClassIds = dinersByIds.stream().map(SingleDinerRpcResponse::getClassId).distinct().toList();
        final var clientMap = clientInventoryServiceRpcClient.getClientsByIds(loginInfo.getEnterpriseId(), clientIds).getClientsList().stream().collect(Collectors.toMap(SingleClientRpcResponse::getId, Function.identity()));
        final var gradeClassMap = mealOrderServiceRpcClient.getGradeClassesByIds(loginInfo.getEnterpriseId(), gradeClassIds).stream().collect(Collectors.toMap(SingleGradeClassRpcResponse::getId, Function.identity()));
        final var reserveDinerMealOrderMap = mealOrderServiceRpcClient.queryReserveMealOrdersByDinerIds(loginInfo.getEnterpriseId(), dinerIds).stream().collect(Collectors.toMap(SingleMealOrderRpcResponse::getDinerId, Function.identity()));
        return dinersByIds.stream().map(e -> DinerVO.builder()
                .id(e.getId())
                .enterpriseId(e.getEnterpriseId())
                .clientId(e.getClientId())
                .clientCode(clientMap.get(e.getClientId()).getCode())
                .clientName(clientMap.get(e.getClientId()).getName())
                .classId(e.getClassId())
                .gradeName(gradeClassMap.get(e.getClassId()).getGradeName())
                .className(gradeClassMap.get(e.getClassId()).getClassName())
                .isReserve(reserveDinerMealOrderMap.get(e.getId()) != null)
                .studentNo(e.getStudentNo())
                .name(e.getName())
                .build()).toList();
    }

    @Override
    public CreatedResult<DinerVO> createMpAccountDiner(DinerDTO.CreateDinerDTO createDinerDTO) {
        final var loginInfo = LoginContextHolder.getLoginInfo();
        final var clientsByCodes = clientInventoryServiceRpcClient.getClientsByCodes(loginInfo.getEnterpriseId(), List.of(createDinerDTO.getClientCode()));
        if (clientsByCodes.size() != 1) {
            throw ClientEndExceptions.IncorrectRequestValue.build(ErrorCodeEnum.CLIENT_CODE_NOT_EXISTS);
        }
        final var singleClientRpcResponse = clientsByCodes.get(0);
        final var diners = mealOrderServiceRpcClient.queryDinersByCondition(loginInfo.getEnterpriseId(), List.of(singleClientRpcResponse.getId()), List.of(createDinerDTO.getClassId()), createDinerDTO.getStudentNo());
        if (!diners.isEmpty()) {
            throw ClientEndExceptions.IncorrectRequestValue.build(ErrorCodeEnum.DINER_ALREADY_EXISTS);
        }
        final var dinerCreation = DinerCreation.newBuilder()
                .setClientId(singleClientRpcResponse.getId())
                .setClassId(createDinerDTO.getClassId())
                .setStudentNo(createDinerDTO.getStudentNo())
                .setName(createDinerDTO.getName())
                .build();
        final var dinerResponse = mealOrderServiceRpcClient.createDiner(loginInfo, dinerCreation);
        if (dinerResponse.getIsCreated()) {
            final var mpAccountDinerRefCreation = MpAccountDinerRefCreation.newBuilder()
                    .setDinerId(dinerResponse.getId())
                    .setAccountId(loginInfo.getId())
                    .build();
            final var mpAccountDinerRef = mealOrderServiceRpcClient.createMpAccountDinerRef(loginInfo, mpAccountDinerRefCreation);
            log.info("createMpAccountDiner dinerId:{} mpAccountDinerRefId:{}", dinerResponse.getId(), mpAccountDinerRef.getId());
        }
        return CreatedResult.<DinerVO>builder().id(dinerResponse.getId()).isCreated(dinerResponse.getIsCreated()).build();
    }

    @Override
    public List<GradeClassVO> getClientGradeClasses(SingleClientRpcResponse client) {
        final var loginInfo = LoginContextHolder.getLoginInfo();
        final var gradeClasses = mealOrderServiceRpcClient.queryGradeClassesByCondition(loginInfo.getEnterpriseId(), List.of(client.getId()));
        return gradeClasses.stream().map(e -> GradeClassVO.builder()
                .id(e.getId())
                .enterpriseId(e.getEnterpriseId())
                .gradeName(e.getGradeName())
                .className(e.getClassName())
                .build()).toList();
    }

    @Override
    public void updateMpAccountDiner(SingleDinerRpcResponse diner, DinerDTO.UpdateDinerDTO updateDinerDTO) {
        final var loginInfo = LoginContextHolder.getLoginInfo();
        final var clientsByCodes = clientInventoryServiceRpcClient.getClientsByCodes(loginInfo.getEnterpriseId(), List.of(updateDinerDTO.getClientCode()));
        if (clientsByCodes.size() != 1) {
            throw ClientEndExceptions.IncorrectRequestValue.build(ErrorCodeEnum.CLIENT_CODE_NOT_EXISTS);
        }
        final var singleClientRpcResponse = clientsByCodes.get(0);
        if (diner.getClientId() == singleClientRpcResponse.getId() && diner.getClassId() == updateDinerDTO.getClassId() && diner.getStudentNo().equals(updateDinerDTO.getStudentNo()) && !diner.getName().equals(updateDinerDTO.getName())) {
            mealOrderServiceRpcClient.updateDiner(loginInfo, DinerModification.newBuilder().setId(diner.getId()).setShouldUpdateName(true).setName(updateDinerDTO.getName()).build());
            return;
        }
        final var diners = mealOrderServiceRpcClient.queryDinersByCondition(loginInfo.getEnterpriseId(), List.of(singleClientRpcResponse.getId()), List.of(updateDinerDTO.getClassId()), updateDinerDTO.getStudentNo());
        if (!diners.isEmpty()) {
            throw ClientEndExceptions.IncorrectRequestValue.build(ErrorCodeEnum.DINER_ALREADY_EXISTS);
        }
        mealOrderServiceRpcClient.updateDiner(loginInfo, DinerModification.newBuilder()
                .setId(diner.getId())
                .setShouldUpdateClientId(true).setClientId(singleClientRpcResponse.getId())
                .setShouldUpdateClassId(updateDinerDTO.getClassId() != null).setClassId(updateDinerDTO.getClassId() == null ? diner.getClassId() : updateDinerDTO.getClassId())
                .setShouldUpdateName(updateDinerDTO.getName() != null).setName(updateDinerDTO.getName() == null ? diner.getName() : updateDinerDTO.getName())
                .setShouldUpdateStudentNo(updateDinerDTO.getStudentNo() != null).setStudentNo(updateDinerDTO.getStudentNo() == null ? diner.getStudentNo() : updateDinerDTO.getStudentNo())
                .build());
    }

    @Override
    public void deleteMpAccountDiner(SingleDinerRpcResponse diner) {
        final var loginInfo = LoginContextHolder.getLoginInfo();
        final var mpAccountDinerRefRpcResponseList = mealOrderServiceRpcClient.queryMpAccountDinerRefsByCondition(loginInfo.getEnterpriseId(), List.of(loginInfo.getId()), List.of(diner.getId()));
        mealOrderServiceRpcClient.deleteDinersByIds(loginInfo, List.of(diner.getId()));
        if (!mpAccountDinerRefRpcResponseList.isEmpty()) {
            mealOrderServiceRpcClient.deleteMpAccountDinerRefsByIds(loginInfo.getEnterpriseId(), mpAccountDinerRefRpcResponseList.stream().map(SingleMpAccountDinerRefRpcResponse::getId).toList());
        }
    }

    @Override
    public DinerVO getClientClassDiner(SingleClientRpcResponse client, SingleGradeClassRpcResponse gradeClass, String studentNo) {
        final var loginInfo = LoginContextHolder.getLoginInfo();
        final var diner = mealOrderServiceRpcClient.queryDinersByCondition(loginInfo.getEnterpriseId(), List.of(client.getId()), List.of(gradeClass.getId()), studentNo);
        return DinerVO.builder()
                .id(diner.get(0).getId())
                .enterpriseId(diner.get(0).getEnterpriseId())
                .clientId(diner.get(0).getClientId())
                .clientCode(client.getCode())
                .clientName(client.getName())
                .classId(diner.get(0).getClassId())
                .gradeName(gradeClass.getGradeName())
                .className(gradeClass.getClassName())
                .studentNo(diner.get(0).getStudentNo())
                .name(diner.get(0).getName())
                .build();
    }
}