Why Gemfury? Push, build, and install  RubyGems npm packages Python packages Maven artifacts PHP packages Go Modules Debian packages RPM packages NuGet packages

Repository URL to install this package:

Details    
@skava/graphql / src / endpoints / oms / transformOrder.ts
Size: Mime:
/* eslint max-statements: "OFF" */
const { format, getTime } = require('date-fns')
const { get, getTyped } = require('@skava/modules/___dist/composition')
const { EMPTY_OBJ, isString, toNumber } = require('exotic')
/**
 * @todo - add getImmutableTyped, or getFrozenTyped, or array.frozen()
 */
const { formatPrice } = require('@skava/modules/___dist/utils/formatPrice')
const { formatOrderStatus } = require('@skava/modules/___dist/utils/formatOrderStatus')

function fixStringyBooleans(string) {
  switch (string) {
    case 'true':
      return true
      break
    case 'TRUE':
      return true
    case 'false':
      return false
    case 'FALSE':
      return false
    default:
      return string
      break
  }
}

// @todo use the util from deps (once this kinda util moved to deps ;p)
function toPrettyDate(date, dateFormat = 'MMM DD, YYYY') {
  if (date) {
    const ms = parseInt(date)
    const actualDate = getTime(ms)
    return format(actualDate, dateFormat)
  }
  return Date.now()
}
/**
 * @todo @fixme @james @unsafe
 */
function parseInvalidJSON(x) {
  if (isString(x) === false) {
    return x
  }
  const value = x.replace(/\\/g, '')
  return JSON.parse(value)
}

const isLabelCreatedAt = item => item.label === 'createdtime'
const isLabelName = data => data.label === 'name'

const getMath = math => {
  const { string } = getTyped(math)
  const getPrice = path => {
    // number
    const value = string(path)
    return formatPrice(value, '$')
  }
  const grandTotal = () =>{
    const total = string('totalSale')
    const tax = string('tax')
    const grandTotal = (toNumber(total) + toNumber(tax))
    return formatPrice(grandTotal, '$')
  }
  /**
   * @todo - this is unclear
   */
  const transformedMath = {
    subTotal: getPrice('sale'),
    giftSale: getPrice('giftsale'),
    tax: getPrice('tax'),
    shippingCharge: getPrice('fulfilsale'),
    shippingTax: getPrice('fulfiltax'),
    discount: getPrice('discount'),
    total: getPrice('totalSale'),
    grandTotal: grandTotal(),
    // all numbers...
    // There is no coupontotal coming from the API...?
    couponTotal: getPrice('coupontotal') || 0,
  }

  return transformedMath
}
const toPaymentDetails = payment => {
  const { obj } = getTyped(payment)
  // this seems like an invalid invariant
  const cardDetails = obj('properties.paymentcardinfo.additionalinfo[0]')
  const additionalInfo = obj('properties.creditcardinfo[0].cards[0].additionalinfo')

  const transformed = {
    carddetails: parseInvalidJSON(cardDetails.value),
    name: additionalInfo.find(isLabelName),
  }

  return transformed
}

const filterProductType = product => {
  return product.type === 'SKU'
}

const filterShippingType = product => {
  return product.type === 'SHIPPING'
}

const findHasShipped = flags => {
  const found = flags.find(flag => {
    return flag.label === 'shipped'
  })
  return fixStringyBooleans(found.value)
}

const toShippingDetail = detail => {
  const { array, obj, string } = getTyped(detail)
  const price = string('properties.cartinfo.total')
  const hasShipped = findHasShipped(array('properties.iteminfo.flags'))
  const shippingaddress = array('properties.userinfo')
  return {
    price: formatPrice(price, '$'),
    shippingaddress,
    hasShipped,
  }
}

const toProductDetail = product => {
  const { array, string, number, obj } = getTyped(product)
  const price = string('properties.cartinfo.total')
  const shippingmethod = string('properties.cartinfo.shippingmethods.0.name')
  const shippingaddress = array('properties.userinfo')
  return {
    identifier: string('properties.iteminfo.psvid'),
    skuid: string('identifier'),
    name: string('name'),
    image: string('image'),
    quantity: number('properties.iteminfo.cartinfo.quantity'),
    // @todo - money
    price: formatPrice(price, '$'),
    skuinfo: obj('properties.skuinfo'),
    shippingmethod,
    shippingaddress,
  }
}

const toPackage = pkg => {
  const { array, string, number, obj } = getTyped(pkg)
  const getPrice = path => {
    const value = string(path)
    return formatPrice(value, '$')
  }
  const getStatus = path => {
    const status = string('properties.state.status')
    return formatOrderStatus(status)
  }

  const orderPlacedOnLabelValue =
    array('properties.state.additionalinfo').find(isLabelCreatedAt) || EMPTY_OBJ

  /**
   * @todo @invalid @fixme unsafe
   */
  const properties = {
    buyinfo: obj('properties.buyinfo'),
    cartinfo: obj('properties.cartinfo'),
    iteminfo: obj('properties.iteminfo'),
    state: obj('properties.state'),
    math: obj('properties.math'),
    orderinfo: obj('properties.orderinfo'),
    userinfo: obj('properties.userinfo[0]'),
  }

  const products = array('children.products')
    .filter(filterProductType)
    .map(toProductDetail)

  const shipping = array('children.products')
    .filter(filterShippingType)
    .map(toShippingDetail)

  return {
    orderTotalAmount: getPrice('properties.math.totalSale'),
    orderTotalItems: number('properties.state.count') || products.length,
    orderId: string('properties.orderinfo.orderid'),
    orderCreatedTime: toPrettyDate(orderPlacedOnLabelValue.value),
    status: getStatus('properties.state.status'),
    products,
    shipping,
    math: getMath(obj('properties.math')),
    properties,
  }
}

const transformDetailOrders = response => {
  const { array, number, string } = getTyped(response)

  const ordersResponse = {
    state: {
      // autofix(properties.state)
      statuscode: number('properties.state.statuscode'),
      offset: number('properties.state.offset'),
      count: number('properties.state.count'),
      status: number('properties.state.status'),
    },
    packages: array('children.packages').map(toPackage),
    payments: array('children.payments'),
    paymentcardinfo: array('children.payments').map(toPaymentDetails),
  }

  return ordersResponse
}

// exports.toDate = toDate
// exports.parseInvalidJSON = parseInvalidJSON
// exports.isLabelCreatedAt = isLabelCreatedAt
// exports.isLabelName = isLabelName
// exports.getMath = getMath
exports.toPaymentDetails = toPaymentDetails
exports.toProductDetail = toProductDetail
exports.toPackage = toPackage
exports.transformDetailOrders = transformDetailOrders