-
Notifications
You must be signed in to change notification settings - Fork 40
/
Copy pathDataStore.js
161 lines (145 loc) · 4.69 KB
/
DataStore.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
const { DataStoreBase } = require("../../foxy/DataStoreBase.js");
const fetch = require("node-fetch");
/**
* @typedef {Object} OrderDeskItem
*
* @property {string} id Order Desk's Internal ID # for the order item read-only
* @property {string} name Item name
* @property {number} price Item price, defaults to 0.00
* @property {number} quantity Item quantity, integer format, defaults to 1
* @property {number} weight Item weight, decimal format
* @property {string} code Item SKU or product code
* @property {('ship'|'noship'|'download'|'future')} delivery_type Defaults to ship
* @property {string} category_code Further details about the type of item, freeform text
* @property {Array} variation_list Array with a list of variations in key => value format. Ex: ['Size': 'Large', 'Color': 'Red']
* @property {Array} metadata Array with a list of extra (hidden) order details in key => value format
* @property {string} date_added date the item was added to the collection
* @property {string} date_updated date the item was updated in the collection
*/
class DataStore extends DataStoreBase {
token = false;
credentials;
constructor() {
super();
this.domain = "api.shiptheory.com";
this.api = "v1";
this.setCredentials();
}
/**
* Authenticate against Shiptheory and store token.
*
* @returns {boolean} is authenticated.
*/
async authenticate() {
if (!this.token) {
const response = await fetch(this.buildEndpoint('token'), {
body: JSON.stringify({
email: this.credentials.email,
password: this.credentials.password
}),
headers: this.getDefaultHeader(),
method: 'POST'
});
const parsed = await response.json();
this.token = parsed.success && parsed.data.token;
}
return !!this.token;
}
/**
* @inheritdoc
*/
setCredentials() {
this.credentials = {
email: process.env["FOXY_SHIPTHEORY_EMAIL"],
password: process.env["FOXY_SHIPTHEORY_PASSWORD"]
}
}
/**:
* Creates the header needed to issue requests to Shiptheory.
*
* @returns {Object} default header
*/
getDefaultHeader() {
const defaultHeader = {
'Accept': 'application/json',
"Content-Type": "application/json"
}
if (this.token) {
defaultHeader.Authorization = `Bearer ${this.token}`
}
return defaultHeader;
}
/**
* Builds the full URL of an endpoint from an endpoint path.
*
* @param {string} path of the endpoint
* @returns {string} the full URL of the endpoint.
*/
buildEndpoint(path) {
return `https://${this.domain}/${this.api}/${path}`;
}
async shipment(transaction) {
if (!this.token) {
throw new Error('Must be authenticated to send a shipment');
}
const response = await fetch(this.buildEndpoint('shipments'), {
body: JSON.stringify(this.txToShipment(transaction)),
headers: this.getDefaultHeader(),
method: 'POST'
});
return response.json();
}
uniqueReference(transactionId, shipmentNumber) {
return `${transactionId}S${shipmentNumber}`;
}
/**
* Creates a Shiptheory Shipment object given a Foxy Transaction.
*
* @param {Object} transaction as received from Foxy
* @returns {Object} Shipthiory shipment object
*/
txToShipment(transaction) {
const shipments = transaction._embedded['fx:shipments'];
const items = transaction._embedded['fx:items'];
if (shipments.length == 0) {
return {};
}
// TODO: account for possible multiple shippings in a single transaction
// grab data from each shipment and create a list of shipments to be sent to Shiptheory
// for now it is simply assuming all items in embedded are part of the shipment
const products = items.map((p,i) => ({
height: p.height,
name: p.name,
qty: p.quantity,
sku: p.code || `${transaction.id}-${i}`,
value: p.price,
weight: p.weight,
width: p.width
}));
const weight = items.reduce( (accum, curr) => curr.weight + accum);
return {
products: products,
recipient: {
address_line_1: shipments[0].address1,
address_line_2: shipments[0].address2,
city: shipments[0].city,
country: shipments[0].country,
email: transaction.customer_email,
firstname: shipments[0].first_name,
lastname: shipments[0].last_name,
postcode: shipments[0].postal_code,
telephone: shipments[0].phone || '',
},
reference: this.uniqueReference(transaction.id, 0),
reference2: transaction.id,
shipment_detail: {
parcels: 1,
value: transaction.total_item_price,
weight: weight,
},
}
}
}
module.exports = {
DataStore
}