| Current Path : /home/deltalab/PMS/ims-connector/logic/shopify/ |
| Current File : //home/deltalab/PMS/ims-connector/logic/shopify/order.js |
/* eslint-disable new-cap */
/* eslint-disable no-param-reassign */
const axios = require('axios');
const { orderAddressModel } = require('../../models/mongoose/order');
const { orderBaseModel } = require('../../models/mongoose/order');
const { orderCustomerModel } = require('../../models/mongoose/order');
const { orderItemModel } = require('../../models/mongoose/order');
const { orderMoneyModel } = require('../../models/mongoose/order');
// Headers ===============================================
const shopifyHeaders = {
'Content-Type': 'application/json',
Accept: 'application/json',
'X-Shopify-Access-Token': process.env.SHOPIFY_PASSWORD,
};
// Queries ================================================
/**
* String representation of a shopify order
*/
const shopifyOrderType = `
id,
name,
closed,
customer {
displayName,
email,
phone
},
shippingAddress {
name,
latitude,
longitude,
company,
address1,
address2,
phone,
city,
province,
zip,
country
},
fullyPaid,
fulfillable,
fulfillments {
displayStatus
},
lineItems (first: 10) {
edges {
node {
product {
id
},
name,
sku,
title,
quantity,
discountedTotalSet {
shopMoney {
amount,
currencyCode
}
},
discountedUnitPriceSet {
shopMoney {
amount,
currencyCode
}
}
}
}
},
totalPriceSet {
shopMoney {
amount,
currencyCode
}
},
createdAt
`;
/**
* Retrieve the details of the order with the given id
*/
const shopifyOrderByIdQuery = `
query ($orderId: ID!){
order (id: $orderId) {
${shopifyOrderType}
}
}
`;
/**
* This is the query data to retrieve the orders from Shopify
* Beware the orders retrieved don't have the items populated to limit the query size
* @param {*} first
* @param {*} last
* @param {*} after
* @param {*} before
* @param {*} search
*/
const shopifyOrdersQuery = `query getOrders ($first: Int!, $after: String) {
orders (first: $first, after: $after, query: "status:open") {
pageInfo { # Returns details about the current page of results
hasNextPage, # Whether there are more results after this page
hasPreviousPage, # Whether there are more results before this page
},
edges {
cursor, # Marker for absolute edge position in the connection
node {
${shopifyOrderType} # Object to be returned
}
}
}
}`;
// Functions ==============================================
/**
* Get a single order from shopify
* @param {String} orderId
* @returns
*/
async function getOrder(orderId) {
console.log(`get order ${orderId} data from ${process.env.SHOPIFY_STORE_URL}`);
const result = await axios({
url: process.env.SHOPIFY_STORE_URL,
method: 'post',
data: {
query: shopifyOrderByIdQuery,
variables: {
orderId,
},
},
headers: shopifyHeaders,
});
const order = new orderBaseModel();
populateOrder(order, result.data.data.order);
return order;
}
/**
* Get a list of orders directly from shopify
* @param {Int} first number of items to fetch
* @param {String} after cursor ID after which fetch items
* @returns
*/
async function getOrders(first = 10, after = null) {
console.log(`getting ${first} orders after ${after} from ${process.env.SHOPIFY_STORE_URL}`);
const orders = [];
let lastCursor;
let pageInfo;
await axios({
url: process.env.SHOPIFY_STORE_URL,
method: 'post',
data: {
query: shopifyOrdersQuery,
variables: {
first,
after,
},
},
headers: shopifyHeaders,
}).then((result) => {
// check errors
if (result.data.errors) {
throw Error(result.data.errors[0].message);
}
// pagination check
pageInfo = result.data.data.orders.pageInfo;
const edges = result.data.data.orders.edges;
edges.forEach((edge) => {
lastCursor = edge.cursor;
const order = new orderBaseModel();
populateOrder(order, edge.node);
orders.push(order);
});
}).catch((error) => {
console.log(error);
});
// Iteration -------------------------------------
if (pageInfo && pageInfo.hasNextPage) {
// Keep requesting orders until there is a nextPage
const _orders = await getOrders(first, lastCursor);
console.log(`retrieved orders ${_orders.length}`);
_orders.forEach((order) => {
orders.push(order);
});
}
console.log(`finished with orders ${orders.length}`);
return orders;
}
/**
* Retrieve an Order object from the response node
* @param {orderBaseModel} order the order to populate
* @param {*} node data collected from oms
* @return the standard order model representation
*/
function populateOrder(order, node) {
// mapping shopify shit into our data structure
order.omsgid = node.id;
order.name = node.name;
order.createdAt = node.createdAt;
order.fullyPaid = node.fullyPaid;
order.customer = new orderCustomerModel();
// Sanity check
if (node.customer) {
order.customer.displayName = node.customer.displayName;
order.customer.email = node.customer.email;
order.customer.phone = node.customer.phone;
}
order.status = node.fulfillable ? 'Processing' : 'Fulfilled';
order.shippingAddress = new orderAddressModel();
// Sanity check
if (node.shippingAddress) {
order.shippingAddress.name = node.shippingAddress.name;
// latitude, longitude??
order.shippingAddress.company = node.shippingAddress.company;
order.shippingAddress.address1 = node.shippingAddress.address1;
order.shippingAddress.address2 = node.shippingAddress.address2;
order.shippingAddress.phone = node.shippingAddress.phone;
order.shippingAddress.city = node.shippingAddress.city;
order.shippingAddress.province = node.shippingAddress.province;
order.shippingAddress.zip = node.shippingAddress.zip;
order.shippingAddress.country = node.shippingAddress.country;
}
order.totalPriceSet = new orderMoneyModel();
order.totalPriceSet.amount = node.totalPriceSet.shopMoney.amount;
order.totalPriceSet.currencyCode = node.totalPriceSet.shopMoney.currencyCode;
// populate the order items iterating over the line items
order.items = [];
const lineItems = node.lineItems.edges;
for (const lineItemEdge of lineItems) {
const lineItem = lineItemEdge.node;
// A little sanity check
if (lineItem.product == null) continue;
const item = new orderItemModel();
item.imsgid = lineItem.product.id;
item.name = lineItem.name;
item.sku = lineItem.sku;
item.title = lineItem.title;
item.quantity = lineItem.quantity;
item.totalPriceSet = new orderMoneyModel();
item.totalPriceSet.amount = lineItem.discountedTotalSet.shopMoney.amount;
item.totalPriceSet.currencyCode = lineItem.discountedTotalSet.shopMoney.currencyCode;
item.unitPriceSet = new orderMoneyModel();
item.unitPriceSet.amount = lineItem.discountedUnitPriceSet.shopMoney.amount;
item.unitPriceSet.currencyCode = lineItem.discountedUnitPriceSet.shopMoney.currencyCode;
order.items.push(item);
}
return order;
}
// EXPORTS =======================================================
module.exports = {
getOrder,
getOrders,
};