Untitled

mail@pastecode.io avatar
unknown
plain_text
4 months ago
5.8 kB
3
Indexable
import { Inject, Injectable, Logger } from '@nestjs/common';
import { plainToInstance } from 'class-transformer';
import { InquiryMessageContentType, InquiryReceiverType } from 'src/shared/types/enum';
import { InquiryEntity } from '../domain/inquiry/inquiry.entity';
import { InquiryRepository, InquiryRepositoryName } from '../domain/inquiry/inquiry.repository';
import { InquiryMessageEntity } from '../domain/message/inquiry-message.entity';
import { InquiryMessageRepository, InquiryMessageRepositoryName } from '../domain/message/inquiry-message.repository';
import { mapInquiryStatus } from '../domain/utils';
import { GetInquiryListDto, InquiryMessageQuestionnaireContent, MappedAnswerObj, MappedInquiry } from '../models';
import { InquiryGroup } from '../protos/inquiry';

@Injectable()
export class GetInquiryListUseCase {
  private logger = new Logger(GetInquiryListUseCase.name);

  constructor(
    @Inject(InquiryRepositoryName)
    private readonly inquiryRepository: InquiryRepository,
    @Inject(InquiryMessageRepositoryName)
    private readonly inquiryMessageRepository: InquiryMessageRepository,
  ) {}

  async execute(payload: GetInquiryListDto): Promise<MappedInquiry[]> {
    const { blId } = payload;
    const inquiries = await this.inquiryRepository.findByBlId(blId);

    if (!inquiries.length) {
      this.logger.debug(`No inquiry found by BL id: ${blId}`);
      return [];
    }
    const inquiryFirstIds = [];
    const inquiryIds = inquiries.map((inquiry) => inquiry.id);

    const groupIds = [];
    const initialInquiryList: InquiryEntity[] = [];
    const remainingInquiryList: InquiryEntity[] = [];

    inquiries.forEach((inquiry) => {
      if (!inquiryFirstIds.includes(inquiry.id) && !groupIds.includes(inquiry.groupId)) {
        inquiryFirstIds.push(inquiry.id);
        groupIds.push(inquiry.groupId);
        initialInquiryList.push(inquiry);
      } else {
        remainingInquiryList.push(inquiry);
      }
    });
    const inquiryMessages = await this.inquiryMessageRepository.findInInquiryIds(inquiryIds);

    const mappedInquiries = this.mapInquiriesWithInquiryMessages(initialInquiryList, remainingInquiryList, inquiryMessages);

    // this.logger.debug(`inquiry list: ${JSON.stringify(mappedInquiries)}`);

    return mappedInquiries;
  }

  private mapInquiriesWithInquiryMessages(
    initialInquiryList: InquiryEntity[],
    remainingInquiryList: InquiryEntity[],
    inquiryMessages: InquiryMessageEntity[],
  ): MappedInquiry[] {
    const DEFAULT_HAS_ATTACHMENT = false;
    const DEFAULT_MEDIA_FILE = [];
    const DEFAULT_MEDIA_FILES_ANSWER = [];
    const result = initialInquiryList.map((inquiry) => {
      const matchedInquiryMessage = inquiryMessages.filter((inquiryMessage) => inquiryMessage.inquiryId === inquiry.id).shift();
      const inquiryGroup: InquiryGroup[] = [];
      remainingInquiryList.forEach((remainingInquiry) => {
        const matchedRemainingInquiryMessage = inquiryMessages.filter((inquiryMessage) => inquiryMessage.inquiryId === remainingInquiry.id).shift();
        if (remainingInquiry.groupId === inquiry.groupId) {
          inquiryGroup.push({
            id: remainingInquiry.id,
            content: matchedRemainingInquiryMessage.content.text,
            inquiryType: matchedRemainingInquiryMessage.inquiryTypeId,
            receiver: this.mapReceiver(remainingInquiry.receiverType),
          });
        }
      });
      const respondingInquiry: MappedInquiry = {
        id: inquiry.id,
        groupId: inquiry.groupId,
        content: matchedInquiryMessage.content.text,
        field: inquiry.fieldId,
        inqType: inquiry.type,
        ansType: matchedInquiryMessage.cbAnswerTypeId,
        state: mapInquiryStatus(inquiry.status),
        createdAt: inquiry.createdAt.toISOString(),
        updatedAt: inquiry.updatedAt.toISOString(),
        creator: {
          userName: matchedInquiryMessage.updatedBy.username,
          avatar: null,
        },
        hasAttachment: DEFAULT_HAS_ATTACHMENT,
        mediaFile: DEFAULT_MEDIA_FILE,
        mediaFilesAnswer: DEFAULT_MEDIA_FILES_ANSWER,
        receiver: this.mapReceiver(inquiry.receiverType),
        inqGroup: inquiryGroup,
        answerObj: this.mapInquiryMessageAnswerObjects(matchedInquiryMessage),
      };

      return respondingInquiry;
    });
    return result;
  }

  private mapReceiver(receiverType: InquiryReceiverType): string[] {
    switch (receiverType) {
      case InquiryReceiverType.Customer: {
        return ['customer'];
      }
      case InquiryReceiverType.OnShore: {
        return ['onshore'];
      }
      default: {
        return ['customer'];
      }
    }
  }

  private mapInquiryMessageAnswerObjects(inquiryMessage: InquiryMessageEntity): MappedAnswerObj[] {
    if (inquiryMessage.contentType === InquiryMessageContentType.TEXT) {
      return [];
    }

    // Cast to type InquiryMessageQuestionnaireContent since only Questionnaire has Answer Object
    const content = plainToInstance(InquiryMessageQuestionnaireContent, inquiryMessage.content);

    const mappedAnswers = content.answers.map((answer) => {
      const mappedResult: MappedAnswerObj = {
        id: answer.id,
        content: answer.answer,
        ansForType: answer.cbAnswerForType,
        confirmed: answer.isConfirmed,
        createdAt: inquiryMessage.createdAt.toISOString(),
        updatedAt: inquiryMessage.updatedAt.toISOString(),
        createdBy: inquiryMessage.createdBy.id,
        updatedBy: inquiryMessage.createdBy.id,
        state: answer.state,
        type: answer.type,
        updater: {
          userName: inquiryMessage.updatedBy.username,
          avatar: null,
        },
      };

      return mappedResult;
    });

    return mappedAnswers;
  }
}
Leave a Comment