Untitled

mail@pastecode.io avatar
unknown
plain_text
7 months ago
9.4 kB
3
Indexable
Never
/*
 * ---------------------------------------------
 * Author: Geraldine
 * Date:   Friday September 15th 2023
 * Last Modified by: Geraldine - <gsamen@konsulta.md>
 * Last Modified time: November 10th 2023, 10:46:40 am
 * ---------------------------------------------
 */

import { IOrder } from 'healthnow-pharmacy-schemas'
import moment from 'moment'

import { AccountGroups } from '../../../enums'
import Logging from '../../../lib/logger/Logging'
import getUtilitiesOrder from '../../../models/UtilitiesOrders'
import { getSubStatus } from '../../utils/helpers'
import sendReportToEmail from './sendReportToEmail'
import DeliveryStatusTimeline from '../../../models/DeliveryStatusTimeline'

export interface IOrderWithSubStatus extends IOrder {
  subStatus: string
}

export enum EComparisonOPerator {
  greaterThan = '$gt',
  lessThan = '$lt',
  equal = '$eq',
  notEqual = '$ne',
  greaterThanOrEqual = '$gte',
  lessThanOrEqual = '$lte',
}

export interface IAmountPaidFilter {
  comparisonOperator: EComparisonOPerator
  value: number
}
export interface IOrderListParams {
  searchString: string
  start: string
  end: string
  options: IPaginationOptions
  status: string[]
  schedule: string
  clientId: string
  partnerId: string
  storeId: string
  sortingBy?: string
  sortingOrder?: number
  shippingOption?: string
  userId?: string
  isReport?: boolean
  isScheduled?: boolean
  amountPaid?: IAmountPaidFilter
  isArchived?: boolean
  reasons?: [string]
  isForAudit?: boolean
}

async function list(
  param: IOrderListParams,
  context?: IContext,
  projection?: any
): Promise<any> {
  const {
    searchString,
    start,
    end,
    options,
    status,
    // schedule,
    clientId,
    storeId,
    isReport = false,
    sortingBy,
    sortingOrder,
    shippingOption,
    isScheduled,
    amountPaid,
    isArchived = false,
    reasons,
    isForAudit,
  }: IOrderListParams = param
  let { partnerId } = param

  const pipeline: any = []
  const $match: any = isArchived
    ? {
        $and: [{ isArchived: { $exists: true } }, { isArchived: true }],
      }
    : {
        $or: [{ isArchived: { $exists: false } }, { isArchived: false }],
      }

  if (isForAudit) {
    pipeline.push({
      $match: {
        'delivery.isForAudit': true,
      },
    })
  } else if (isForAudit === false) {
    // boolean false
    pipeline.push({
      $match: {
        $or: [
          {
            'delivery.isForAudit': false,
          },
          { 'delivery.isForAudit': { $exists: false } },
        ],
      },
    })
  }

  try {
    if (searchString && searchString.length) {
      if (searchString.includes('PHA-')) {
        pipeline.push({
          $match: {
            'externalIDs.id': searchString,
          },
        })
      } else {
        // const searchableFields = [
        //   'nanoId',
        //   'fullName',
        //   'destinationInfo.phone',
        //   'destinationAddress.fullAddress',
        //   'clientOrderDetails.voucher.code',
        // ]

        pipeline.push({
          $search: {
            index: 'search_order', // optional, defaults to "default"
            text: {
              query: searchString,
              path: {
                wildcard: '*',
              },
            },
          },
        })
      }

      // to return empty result if searchString is less than 4
      if (searchString && searchString.length < 3) {
        pipeline.push({
          $match: { _id: { $exists: false } },
        })
      }
    }

    if (start) {
      $match['createdAt'] = {
        $gte: moment(start).toDate(),
      }
    }

    if (end) {
      if ($match['createdAt']) {
        $match['createdAt']['$lte'] = moment(end).toDate()
      } else {
        $match['createdAt'] = {
          $lte: moment(end).toDate(),
        }
      }
    }

    if (
      amountPaid &&
      amountPaid?.comparisonOperator?.length &&
      amountPaid?.value >= 0
    ) {
      // @ts-ignore
      const comparisonOperator = EComparisonOPerator[
        amountPaid.comparisonOperator
      ] as string

      $match['clientOrderDetails.paymentDetails.perStore.grandTotal'] = {
        [comparisonOperator]: amountPaid?.value,
      }
    }

    if (context?.account?.groups?.includes(AccountGroups.CLIENT)) {
      $match['clientId'] = context.account.clientId
    }

    if (clientId && clientId.length) {
      $match['clientId'] = clientId
    }

    if (shippingOption?.length) {
      $match['shippingOption'] = shippingOption
    }

    if (typeof isScheduled !== 'undefined') {
      $match['isScheduled'] = isScheduled
    }

    if (storeId) {
      $match['items.store._id'] = storeId
    }

    if (context?.account?.groups?.includes(AccountGroups.PHARMACIST)) {
      if (!context?.account?.stores?.includes(storeId)) {
        $match['items.store._id'] = { $in: context?.account?.stores }
      }

      // pipeline.push({
      //   $match: { 'items.store._id': { $in: context?.account?.stores } },
      // })
    }

    if (
      context?.account?.groups?.includes(AccountGroups.PHARMA_PARTNER_ADMIN)
    ) {
      partnerId = context.account.partner
    }

    if (
      context?.account?.groups?.includes(AccountGroups.PHARMA_PARTNER_ADMIN) ||
      partnerId
    ) {
      $match['items.store.partner'] = partnerId

      // const partnerQuery: any = [
      //   {
      //     $match: {
      //       'items.store.partner': partnerId,
      //     },
      //   },
      // ]

      // pipeline.push(...partnerQuery)
    }

    if (Object.keys($match)) {
      pipeline.push({
        $match,
      })
    }

    if (status && status.length) {
      if (status.includes('patient_cancelled')) {
        const filter: any = [
          { 'lastStatus.status': { $in: status } },
          { 'lastStatus.event': 'cancelled-by-patient' },
        ]

        if (reasons && reasons.length) {
          filter.push({ 'lastStatus.reason': { $in: reasons } })
        }
        const statusQuery = [
          {
            $match: {
              $or: filter,
            },
          },
        ]
        pipeline.push(...statusQuery)
      } else {
        const filter: any = [
          { 'lastStatus.status': { $in: status } },
          { 'lastStatus.event': { $ne: 'cancelled-by-patient' } },
        ]

        if (reasons && reasons.length) {
          filter.push({ 'lastStatus.reason': { $in: reasons } })
        }

        const statusQuery = [
          {
            $match: {
              $and: filter,
            },
          },
        ]
        pipeline.push(...statusQuery)
      }
    }

    // if (schedule) {
    //   if (schedule === 'scheduled') {
    //     pipeline.push(
    //       {
    //         $match: {
    //           startDateTime: { $ne: null },
    //         },
    //       },
    //       {
    //         $match: { 'lastStatus.status': { $in: ['new'] } },
    //       }
    //     )
    //   } else {
    //     pipeline.push(
    //       {
    //         $match: {
    //           startDateTime: { $eq: null },
    //         },
    //       },
    //       {
    //         $match: { 'lastStatus.status': { $in: ['new'] } },
    //       }
    //     )
    //   }
    // }

    if (sortingBy && !searchString && !searchString?.length) {
      const sortingKeyMap: any = {
        transaction: 'nanoId',
        branch: 'clientId',
        createdAt: 'createdAt',
        updatedAt: 'updatedAt',
        customer: 'destinationInfo.firstName',
        stores: 'items.store.alias',
        status: 'lastStatus',
        price: 'priceToSort',
      }

      const sortKey = sortingKeyMap[sortingBy]

      if (sortKey) {
        pipeline.push({
          $sort: { [sortKey]: sortingOrder },
        })
      }
    }

    // if report
    if (projection && !isReport) {
      pipeline.push({
        $project: { ...projection },
      })
    }

    const UtilitiesOrder = await getUtilitiesOrder()

    if (isReport) {
      sendReportToEmail({
        model: UtilitiesOrder,
        pipeline,
        email: context?.account?.email as string,
        date: moment().utcOffset(8).format('LLL'),
        filters: param,
      })
    }

    const aggregate = UtilitiesOrder.aggregate(pipeline)
    const paginatedResult = await UtilitiesOrder.aggregatePaginate(aggregate, {
      ...options,
      allowDiskUse: true,
      lean: true,
    })

    const ordersRaw = paginatedResult?.docs

    const finalOrder = ordersRaw.map((order: any) => {
      return {
        ...order,
        subStatus: getSubStatus(
          order,
          order?.lastStatus?.status,
          order?.lastStatus,
          order?.delivery,
          order?.deliveryLastStatus
        ),
      }
    })

    paginatedResult.docs = finalOrder
    return paginatedResult
  } catch (error: any) {
    Logging.log({
      id: 'order-v2-log-list-error',
      grapqhLogId,
      data: {
        message: error.message,
        error,
      },
    })

    throw error
  }
}

export default list
Leave a Comment