Repository URL to install this package:
|
Version:
1.2.7 ▾
|
/* eslint-disable brace-style */
import { isSafe, isObj, toBoolean, isArray } from 'exotic'
import { cloneJSON } from 'chain-able'
import { getTyped, getFloat } from '@skava/modules/___dist/composition'
// console.dev('@todo availability giftitem [isgiftcard]=true != "true" flags[returnable]')
const toFloat = x => {
if (!isNaN(x)) {
return parseFloat(x, 10).toFixed(2)
}
return x
}
const tranformWorkingHour = data => {
const { string } = getTyped(data)
return {
weekday: string('weekday'),
weekend: string('weekend'),
}
}
const tranformContactUs = data => {
const { obj, string } = getTyped(data)
return {
description: string('description'),
number: string('number'),
workinghour: tranformWorkingHour(obj('workinghour')),
}
}
/**
* @todo @invalid @fixme @autofix no === 'true'
* @return {Address | Object}
*/
const getShippingMethod = address => {
if (isSafe(address) === false) {
return {}
}
else if (address.selected === 'true') {
return address
}
else {
return {}
}
}
const transformPromoDetail = promo => {
const { obj, string, array } = getTyped(promo)
return {
identifier: string('identifier'),
skuId: string('properties.iteminfo.sku'),
name: string('properties.promocodeinfo.promos[0].name'),
errorcode: string('properties.state.errorcode'),
errormessage: string('properties.state.errormessage'),
}
}
/**
* @param {Object} product
* @return {ProductPromotion | Boolean}
*/
const getPromoMethod = product => {
// console.log('test prodcuct', product)
if (isSafe(product) === false) {
return false
}
else if (product.label === 'discounts') {
// console.log('test this product', product)
return product
}
else {
return false
}
}
// ============ product options =========
/**
* @see __product/OneThing
*/
const toProductOptionItem = (type, value) => {
return {
type,
value,
}
}
const renameOptionKey = (key) => {
switch (key) {
case 'size1': return 'size'
case 'fit': return 'style'
case 'colors': return 'color'
default: return key
}
}
/**
* @example skuinfo
* {
* color: { identifier: 'Red',
* image: 'undefined?ch=150&cw=190&cx=center&cy=center' },
* size1: { identifier: '10 D' }
* }
*
* @example
* productOptions: [
* {
* type: 'color',
* value: 'Red',
* },
* {
* type: 'size',
* value: 'XL',
* }
* ],
*/
const fromSkuInfoToProductOptions = skuinfo => {
// console.log('fromSkuInfoToProductOptions__pre', skuinfo, Object.keys(skuinfo))
const productOptions = []
Object.keys(skuinfo).forEach(key => {
const option = skuinfo[key]
const value = isObj(option) ? option.identifier : undefined
const renamed = renameOptionKey(key)
const optionItem = toProductOptionItem(renamed, value)
productOptions.push(optionItem)
})
// console.log('fromSkuInfoToProductOptions__post', productOptions)
if (productOptions.length === 0) {
// always want to send this now with gql
return productOptions
// return undefined
}
return productOptions
}
const transformSkuDetail = product => {
const { obj, string, number, array, float } = getTyped(product)
const skuinfo = obj('properties.skuinfo')
const productOptions = fromSkuInfoToProductOptions(skuinfo)
const quantity = number('properties.cartinfo.quantity')
const commonSkuDetail = {
quantity,
identifier: string('identifier'),
skuId: string('properties.iteminfo.sku'),
image: string('image'),
name: string('name'),
type: string('type'),
price: float('properties.buyinfo.pricing.prices[0].value'),
preOrder: string('properties.buyinfo.preorderdate'),
// style: string('properties.skuinfo.fit.identifier'),
// color: string('properties.skuinfo.color.identifier'),
// size: string('properties.skuinfo.size1.identifier'),
giftItem: string('properties.cartinfo.giftitem'),
shippingmethod: array('properties.cartinfo.shippingmethods[0].shippingmethods'),
shippingAddress: obj('properties.userinfo[0]'),
cards: array('properties.creditcardinfo.cards'),
}
return {
...commonSkuDetail,
productId: string('properties.iteminfo.itemid'),
flags: array('properties.iteminfo.flags'),
productOptions,
promoMessage: array('properties.cartinfo.discount').find(getPromoMethod),
shippingmethodType: string('properties.cartinfo.shippingmethods[0].type'),
iteminfo: obj('properties.iteminfo'),
cartinfo: obj('properties.cartinfo'),
}
}
const typeIsPromoCode = sku => sku.type === 'promoCode'
const typeIsSkuOrGift = sku => sku.type === 'sku' || sku.type === 'gift' || sku.type === 'bundle'
const typeIsGift = sku => sku.type === 'gift'
const isTypePayment = sku => sku.type === 'payment'
const transformMath = maths => {
const { string, number, float } = getTyped(maths || {})
return {
totalBagCount: number('totalBagCount'),
estTotalTax: float('estTotalTax'),
totalGiftWrapPrice: float('totalGiftWrapPrice'),
totalGiftWrapCost: float('totalGiftWrapCost'),
grandTotal: float('grandTotal'),
grandTotalTax: float('grandTotalTax'),
totalGiftWrapTax: float('totalGiftWrapTax'),
totalGiftWrapDiscount: float('totalGiftWrapDiscount'),
maxBagCount: float('maxBagCount'),
totalDiscount: float('totalDiscount'),
estTotalShippingTax: float('estTotalShippingTax'),
estTotalShippingDiscount: float('estTotalShippingDiscount'),
estTotalShippingPrice: float('estTotalShippingPrice'),
totalSale: float('totalSale'),
totalCost: float('totalCost'),
totalBagCountWithErrors: float('totalBagCountWithErrors'),
currency: string('currency'),
}
}
const transformCartInfo = cartinfoUnsafe => {
const cartinfo = cloneJSON(cartinfoUnsafe || {})
const { boolean, float, number, array } = getTyped(cartinfo)
return {
...cartinfo,
quantity: number('quantity'),
totaltax: float('totaltax'),
total: float('total'),
subtotal: float('subtotal'),
estsubtotal: float('subtotal'),
discounttotal: float('discounttotal'),
iseligible: boolean('iseligible'),
shippingmethods: array('shippingmethods').map(shippingmethod => {
const reallyDeeplyNestedShippingMethods = getTyped(shippingmethod).array('shippingmethods')
return reallyDeeplyNestedShippingMethods.map(method => {
const priceList = getTyped(method).array('prices')
const prices = priceList.map(price => {
return {
...price,
value: getFloat(price, 'value'),
}
})
return {
...method,
prices,
selected: boolean('selected'),
}
})
}),
// here
discount: array('discount').map(discount => {
return {
...discount,
value: getFloat(discount, 'value'),
}
}),
giftwrap: toBoolean(cartinfo.giftwrap),
}
}
// because one sku uses the deeply nested ones
function transformOneSkuCompatible(sku) {
const { obj } = getTyped(sku)
const skuinfo = obj('properties.skuinfo')
const productOptions = fromSkuInfoToProductOptions(skuinfo)
return {
...sku,
productOptions,
}
}
// @todo @fixme
// eslint-disable-next-line
const transformCart = unsafeResponse => {
// graphql is messing this up
const response = cloneJSON(unsafeResponse || {})
const { any, array, obj, float, string } = getTyped(response)
const commonResponse = {
products: array('children.products').filter(typeIsSkuOrGift).map(transformOneSkuCompatible),
type: any('type'),
shippingmethods: array('properties.cartinfo.shippingmethods[0].shippingmethods'),
iteminfo: obj('properties.iteminfo'),
// @todo - should not have userinfo on cart
userinfo: array('properties.userinfo'),
}
const cartinfo = obj('properties.cartinfo')
const contactus = obj('properties.contactus')
const maths = obj('properties.math')
const math = transformMath(maths)
const adjustedamount = float('properties.paymentcardinfo.adjustedamount')
math.adjustedamount = adjustedamount
// userinfo: array('properties.userinfo'),
const cartResponse = {
...commonResponse,
// drop
// items: array('children.products'),
giftproducts: array('children.products').filter(typeIsGift).map(transformSkuDetail),
promocodes: array('children.products').filter(typeIsPromoCode).map(transformPromoDetail),
shippingmethodtype: string('properties.cartinfo.shippingmethods[0].type'),
state: obj('properties.state'),
status: string('properties.state.status'),
contactus: tranformContactUs(contactus),
creditcard: array('children.products').filter(isTypePayment).map(transformSkuDetail),
buyinfo: obj('properties.buyinfo'),
cartinfo: transformCartInfo(cartinfo),
properties: obj('properties'),
math,
}
return cartResponse
}
const getMatchedData = (addressData, addressTypeToCheck) => {
// isn't safe?
return addressData.types.includes(addressTypeToCheck)
}
const transformGeoCodeData = response => {
if (!(response.results && response.results.length)) {
return {}
}
const addressDataFromResponse = response.results[0].address_components
const getAddressData = addressTypeToCheck => {
const matchedAddressData = addressDataFromResponse
.find(addressData => getMatchedData(addressData, addressTypeToCheck)) || {}
return matchedAddressData.short_name || ''
}
return {
postalCode: getAddressData('postal_code'),
state: getAddressData('administrative_area_level_1'),
country: getAddressData('country'),
city: getAddressData('locality'),
county: getAddressData('administrative_area_level_2'),
}
}
const transformAddPayment = response => {
const { any, array, obj, float, string } = getTyped(response)
return {
...response,
identifier: string('children.products.0.identifier'),
}
}
export { transformCart, transformGeoCodeData, transformAddPayment }
export default transformCart