medusa-plugin-ses 2.0.3 → 2.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +3 -6
- package/services/ses.js +7 -8
- package/.babelrc +0 -13
- package/jest.config.js +0 -3
- package/src/api/index.js +0 -33
- package/src/services/ses.js +0 -1290
- package/src/subscribers/order.js +0 -20
- package/src/subscribers/restock.js +0 -41
- package/src/subscribers/user.js +0 -17
package/src/services/ses.js
DELETED
|
@@ -1,1290 +0,0 @@
|
|
|
1
|
-
import * as aws from '@aws-sdk/client-ses'
|
|
2
|
-
import Handlebars from 'handlebars'
|
|
3
|
-
import nodemailer from 'nodemailer'
|
|
4
|
-
import path from 'path'
|
|
5
|
-
import fs from 'fs'
|
|
6
|
-
import { humanizeAmount, zeroDecimalCurrencies } from 'medusa-core-utils'
|
|
7
|
-
import { NotificationService } from 'medusa-interfaces'
|
|
8
|
-
|
|
9
|
-
class SESService extends NotificationService {
|
|
10
|
-
static identifier = "ses"
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
* @param {Object} options - options defined in `medusa-config.js`
|
|
14
|
-
* e.g.
|
|
15
|
-
* {
|
|
16
|
-
* access_key_id: process.env.SES_ACCESS_KEY_ID,
|
|
17
|
-
* secret_access_key: process.env.SES_SECRET_ACCESS_KEY,
|
|
18
|
-
* region: process.env.SES_REGION,
|
|
19
|
-
* from: process.env.SES_FROM,
|
|
20
|
-
* enable_endpoint: process.env.SES_ENABLE_ENDPOINT,
|
|
21
|
-
* template_path: process.env.SES_TEMPLATE_PATH,
|
|
22
|
-
* order_placed_template: 'order_placed',
|
|
23
|
-
* }
|
|
24
|
-
*/
|
|
25
|
-
constructor({
|
|
26
|
-
storeService,
|
|
27
|
-
orderService,
|
|
28
|
-
returnService,
|
|
29
|
-
swapService,
|
|
30
|
-
cartService,
|
|
31
|
-
lineItemService,
|
|
32
|
-
claimService,
|
|
33
|
-
fulfillmentService,
|
|
34
|
-
fulfillmentProviderService,
|
|
35
|
-
totalsService,
|
|
36
|
-
productVariantService,
|
|
37
|
-
}, options) {
|
|
38
|
-
|
|
39
|
-
super()
|
|
40
|
-
|
|
41
|
-
this.options_ = options
|
|
42
|
-
|
|
43
|
-
this.fulfillmentProviderService_ = fulfillmentProviderService
|
|
44
|
-
this.storeService_ = storeService
|
|
45
|
-
this.lineItemService_ = lineItemService
|
|
46
|
-
this.orderService_ = orderService
|
|
47
|
-
this.cartService_ = cartService
|
|
48
|
-
this.claimService_ = claimService
|
|
49
|
-
this.returnService_ = returnService
|
|
50
|
-
this.swapService_ = swapService
|
|
51
|
-
this.fulfillmentService_ = fulfillmentService
|
|
52
|
-
this.totalsService_ = totalsService
|
|
53
|
-
this.productVariantService_ = productVariantService
|
|
54
|
-
|
|
55
|
-
const ses = new aws.SES({
|
|
56
|
-
region: options.region,
|
|
57
|
-
credentials: {
|
|
58
|
-
accessKeyId: options.access_key_id,
|
|
59
|
-
secretAccessKey: options.secret_access_key,
|
|
60
|
-
},
|
|
61
|
-
})
|
|
62
|
-
|
|
63
|
-
this.transporter_ = nodemailer.createTransport({
|
|
64
|
-
SES: { ses, aws }
|
|
65
|
-
})
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
async fetchAttachments(event, data, attachmentGenerator) {
|
|
69
|
-
switch (event) {
|
|
70
|
-
case "swap.created":
|
|
71
|
-
case "order.return_requested": {
|
|
72
|
-
let attachments = []
|
|
73
|
-
const { shipping_method, shipping_data } = data.return_request
|
|
74
|
-
if (shipping_method) {
|
|
75
|
-
const provider = shipping_method.shipping_option.provider_id
|
|
76
|
-
|
|
77
|
-
const lbl = await this.fulfillmentProviderService_.retrieveDocuments(
|
|
78
|
-
provider,
|
|
79
|
-
shipping_data,
|
|
80
|
-
"label"
|
|
81
|
-
)
|
|
82
|
-
|
|
83
|
-
attachments = attachments.concat(
|
|
84
|
-
lbl.map((d) => ({
|
|
85
|
-
name: "return-label",
|
|
86
|
-
base64: d.base_64,
|
|
87
|
-
type: d.type,
|
|
88
|
-
}))
|
|
89
|
-
)
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
if (attachmentGenerator && attachmentGenerator.createReturnInvoice) {
|
|
93
|
-
const base64 = await attachmentGenerator.createReturnInvoice(
|
|
94
|
-
data.order,
|
|
95
|
-
data.return_request.items
|
|
96
|
-
)
|
|
97
|
-
attachments.push({
|
|
98
|
-
name: "invoice",
|
|
99
|
-
base64,
|
|
100
|
-
type: "application/pdf",
|
|
101
|
-
})
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
return attachments
|
|
105
|
-
}
|
|
106
|
-
default:
|
|
107
|
-
return []
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
async fetchData(event, eventData, attachmentGenerator) {
|
|
112
|
-
switch (event) {
|
|
113
|
-
case "order.return_requested":
|
|
114
|
-
return this.returnRequestedData(eventData, attachmentGenerator)
|
|
115
|
-
case "swap.shipment_created":
|
|
116
|
-
return this.swapShipmentCreatedData(eventData, attachmentGenerator)
|
|
117
|
-
case "claim.shipment_created":
|
|
118
|
-
return this.claimShipmentCreatedData(eventData, attachmentGenerator)
|
|
119
|
-
case "order.items_returned":
|
|
120
|
-
return this.itemsReturnedData(eventData, attachmentGenerator)
|
|
121
|
-
case "swap.received":
|
|
122
|
-
return this.swapReceivedData(eventData, attachmentGenerator)
|
|
123
|
-
case "swap.created":
|
|
124
|
-
return this.swapCreatedData(eventData, attachmentGenerator)
|
|
125
|
-
case "gift_card.created":
|
|
126
|
-
return this.gcCreatedData(eventData, attachmentGenerator)
|
|
127
|
-
case "order.gift_card_created":
|
|
128
|
-
return this.gcCreatedData(eventData, attachmentGenerator)
|
|
129
|
-
case "order.placed":
|
|
130
|
-
return this.orderPlacedData(eventData, attachmentGenerator)
|
|
131
|
-
case "order.shipment_created":
|
|
132
|
-
return this.orderShipmentCreatedData(eventData, attachmentGenerator)
|
|
133
|
-
case "order.canceled":
|
|
134
|
-
return this.orderCanceledData(eventData, attachmentGenerator)
|
|
135
|
-
case "user.password_reset":
|
|
136
|
-
return this.userPasswordResetData(eventData, attachmentGenerator)
|
|
137
|
-
case "customer.password_reset":
|
|
138
|
-
return this.customerPasswordResetData(eventData, attachmentGenerator)
|
|
139
|
-
case "restock-notification.restocked":
|
|
140
|
-
return await this.restockNotificationData(
|
|
141
|
-
eventData,
|
|
142
|
-
attachmentGenerator
|
|
143
|
-
)
|
|
144
|
-
case "order.refund_created":
|
|
145
|
-
return this.orderRefundCreatedData(eventData, attachmentGenerator)
|
|
146
|
-
default:
|
|
147
|
-
return {}
|
|
148
|
-
}
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
getLocalizedTemplateId(event, locale) {
|
|
152
|
-
if (this.options_.localization && this.options_.localization[locale]) {
|
|
153
|
-
const map = this.options_.localization[locale]
|
|
154
|
-
switch (event) {
|
|
155
|
-
case "order.return_requested":
|
|
156
|
-
return map.order_return_requested_template
|
|
157
|
-
case "swap.shipment_created":
|
|
158
|
-
return map.swap_shipment_created_template
|
|
159
|
-
case "claim.shipment_created":
|
|
160
|
-
return map.claim_shipment_created_template
|
|
161
|
-
case "order.items_returned":
|
|
162
|
-
return map.order_items_returned_template
|
|
163
|
-
case "swap.received":
|
|
164
|
-
return map.swap_received_template
|
|
165
|
-
case "swap.created":
|
|
166
|
-
return map.swap_created_template
|
|
167
|
-
case "gift_card.created":
|
|
168
|
-
return map.gift_card_created_template
|
|
169
|
-
case "order.gift_card_created":
|
|
170
|
-
return map.gift_card_created_template
|
|
171
|
-
case "order.placed":
|
|
172
|
-
return map.order_placed_template
|
|
173
|
-
case "order.shipment_created":
|
|
174
|
-
return map.order_shipped_template
|
|
175
|
-
case "order.canceled":
|
|
176
|
-
return map.order_canceled_template
|
|
177
|
-
case "user.password_reset":
|
|
178
|
-
return map.user_password_reset_template
|
|
179
|
-
case "customer.password_reset":
|
|
180
|
-
return map.customer_password_reset_template
|
|
181
|
-
case "restock-notification.restocked":
|
|
182
|
-
return map.medusa_restock_template
|
|
183
|
-
case "order.refund_created":
|
|
184
|
-
return map.order_refund_created_template
|
|
185
|
-
default:
|
|
186
|
-
return null
|
|
187
|
-
}
|
|
188
|
-
}
|
|
189
|
-
return null
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
getTemplateId(event) {
|
|
193
|
-
switch (event) {
|
|
194
|
-
case "order.return_requested":
|
|
195
|
-
return this.options_.order_return_requested_template
|
|
196
|
-
case "swap.shipment_created":
|
|
197
|
-
return this.options_.swap_shipment_created_template
|
|
198
|
-
case "claim.shipment_created":
|
|
199
|
-
return this.options_.claim_shipment_created_template
|
|
200
|
-
case "order.items_returned":
|
|
201
|
-
return this.options_.order_items_returned_template
|
|
202
|
-
case "swap.received":
|
|
203
|
-
return this.options_.swap_received_template
|
|
204
|
-
case "swap.created":
|
|
205
|
-
return this.options_.swap_created_template
|
|
206
|
-
case "gift_card.created":
|
|
207
|
-
return this.options_.gift_card_created_template
|
|
208
|
-
case "order.gift_card_created":
|
|
209
|
-
return this.options_.gift_card_created_template
|
|
210
|
-
case "order.placed":
|
|
211
|
-
return this.options_.order_placed_template
|
|
212
|
-
case "order.shipment_created":
|
|
213
|
-
return this.options_.order_shipped_template
|
|
214
|
-
case "order.canceled":
|
|
215
|
-
return this.options_.order_canceled_template
|
|
216
|
-
case "user.password_reset":
|
|
217
|
-
return this.options_.user_password_reset_template
|
|
218
|
-
case "customer.password_reset":
|
|
219
|
-
return this.options_.customer_password_reset_template
|
|
220
|
-
case "restock-notification.restocked":
|
|
221
|
-
return this.options_.medusa_restock_template
|
|
222
|
-
case "order.refund_created":
|
|
223
|
-
return this.options_.order_refund_created_template
|
|
224
|
-
default:
|
|
225
|
-
return null
|
|
226
|
-
}
|
|
227
|
-
}
|
|
228
|
-
|
|
229
|
-
async compileTemplate(templateId, data) {
|
|
230
|
-
//const base = path.resolve(__dirname, '../../../', this.options_.template_path, templateId)
|
|
231
|
-
const base = path.resolve(this.options_.template_path, templateId)
|
|
232
|
-
const subjectTemplate = Handlebars.compile(fs.readFileSync(path.join(base, 'subject.hbs'), "utf8"))
|
|
233
|
-
const htmlTemplate = Handlebars.compile(fs.readFileSync(path.join(base, 'html.hbs'), "utf8"))
|
|
234
|
-
const textTemplate = Handlebars.compile(fs.readFileSync(path.join(base, 'text.hbs'), "utf8"))
|
|
235
|
-
return {
|
|
236
|
-
subject: subjectTemplate(data),
|
|
237
|
-
html: htmlTemplate(data),
|
|
238
|
-
text: textTemplate(data)
|
|
239
|
-
}
|
|
240
|
-
}
|
|
241
|
-
|
|
242
|
-
async sendNotification(event, eventData, attachmentGenerator) {
|
|
243
|
-
let templateId = this.getTemplateId(event)
|
|
244
|
-
if (!templateId) { return false }
|
|
245
|
-
if (data.locale) {
|
|
246
|
-
templateId = this.getLocalizedTemplateId(event, data.locale) || templateId
|
|
247
|
-
}
|
|
248
|
-
|
|
249
|
-
const data = await this.fetchData(event, eventData, attachmentGenerator)
|
|
250
|
-
if (!data) { return false }
|
|
251
|
-
|
|
252
|
-
const { subject, html, text } = await this.compileTemplate(templateId, data)
|
|
253
|
-
if (!subject || (!html && !text)) { return false }
|
|
254
|
-
|
|
255
|
-
const sendOptions = {
|
|
256
|
-
from: this.options_.from,
|
|
257
|
-
to: data.email,
|
|
258
|
-
subject,
|
|
259
|
-
html,
|
|
260
|
-
text
|
|
261
|
-
}
|
|
262
|
-
|
|
263
|
-
const attachments = await this.fetchAttachments(
|
|
264
|
-
event,
|
|
265
|
-
data,
|
|
266
|
-
attachmentGenerator
|
|
267
|
-
)
|
|
268
|
-
|
|
269
|
-
if (attachments?.length) {
|
|
270
|
-
sendOptions.has_attachments = true
|
|
271
|
-
sendOptions.attachments = attachments.map((a) => {
|
|
272
|
-
return {
|
|
273
|
-
content: a.base64,
|
|
274
|
-
filename: a.name,
|
|
275
|
-
encoding: 'base64',
|
|
276
|
-
contentType: a.type
|
|
277
|
-
}
|
|
278
|
-
})
|
|
279
|
-
}
|
|
280
|
-
|
|
281
|
-
//const status = await this.transporter_.sendMail(sendOptions).then(() => "sent").catch(() => "failed")
|
|
282
|
-
let status
|
|
283
|
-
await this.transporter_.sendMail(sendOptions)
|
|
284
|
-
.then(() => { status = "sent" })
|
|
285
|
-
.catch((error) => { status = "failed"; console.log(error) })
|
|
286
|
-
|
|
287
|
-
// We don't want heavy docs stored in DB
|
|
288
|
-
delete sendOptions.attachments
|
|
289
|
-
|
|
290
|
-
return { to: data.email, status, data: sendOptions }
|
|
291
|
-
}
|
|
292
|
-
|
|
293
|
-
async resendNotification(notification, config, attachmentGenerator) {
|
|
294
|
-
const sendOptions = {
|
|
295
|
-
...notification.data,
|
|
296
|
-
to: config.to || notification.to,
|
|
297
|
-
}
|
|
298
|
-
|
|
299
|
-
const attachs = await this.fetchAttachments(
|
|
300
|
-
notification.event_name,
|
|
301
|
-
notification.data.dynamic_template_data,
|
|
302
|
-
attachmentGenerator
|
|
303
|
-
)
|
|
304
|
-
|
|
305
|
-
sendOptions.attachments = attachs.map((a) => {
|
|
306
|
-
return {
|
|
307
|
-
content: a.base64,
|
|
308
|
-
filename: a.name,
|
|
309
|
-
encoding: 'base64',
|
|
310
|
-
contentType: a.type
|
|
311
|
-
}
|
|
312
|
-
})
|
|
313
|
-
|
|
314
|
-
//const status = await this.transporter_.sendMail(sendOptions).then(() => "sent").catch(() => "failed")
|
|
315
|
-
let status
|
|
316
|
-
await this.transporter_.sendMail(sendOptions)
|
|
317
|
-
.then(() => { status = "sent" })
|
|
318
|
-
.catch((error) => { status = "failed"; console.log(error) })
|
|
319
|
-
|
|
320
|
-
return { to: sendOptions.to, status, data: sendOptions }
|
|
321
|
-
}
|
|
322
|
-
|
|
323
|
-
/**
|
|
324
|
-
* Sends an email using SES.
|
|
325
|
-
* @param {string} template_id - id of template to use
|
|
326
|
-
* @param {string} from - sender of email
|
|
327
|
-
* @param {string} to - receiver of email
|
|
328
|
-
* @param {Object} data - data to send in mail (match with template)
|
|
329
|
-
* @return {Promise} result of the send operation
|
|
330
|
-
*/
|
|
331
|
-
async sendEmail(template_id, from, to, data) {
|
|
332
|
-
// This function is used by the /ses/send API endpoint included in this plugin.
|
|
333
|
-
// It is disabled by default.
|
|
334
|
-
// This endpoint may be useful for testing purposes and for use by related applications.
|
|
335
|
-
// There is NO SECURITY on the endpoint by default.
|
|
336
|
-
// Most people will NOT need to enable it.
|
|
337
|
-
// If you are certain that you want to enable it and that you know what you are doing,
|
|
338
|
-
// set the environment variable SES_ENABLE_ENDPOINT to "42" (a string, not an int).
|
|
339
|
-
// The unsual setting is meant to prevent enabling by accident or without thought.
|
|
340
|
-
if (this.options_.enable_endpoint !== '42') { return false }
|
|
341
|
-
const { subject, html, text } = await this.compileTemplate(template_id, data)
|
|
342
|
-
if (!subject || (!html && !text)) { return false }
|
|
343
|
-
try {
|
|
344
|
-
return this.transporter_.sendMail({
|
|
345
|
-
from: from,
|
|
346
|
-
to: to,
|
|
347
|
-
subject,
|
|
348
|
-
html,
|
|
349
|
-
text
|
|
350
|
-
})
|
|
351
|
-
} catch (error) {
|
|
352
|
-
throw error
|
|
353
|
-
}
|
|
354
|
-
}
|
|
355
|
-
|
|
356
|
-
async orderShipmentCreatedData({ id, fulfillment_id }, attachmentGenerator) {
|
|
357
|
-
const order = await this.orderService_.retrieve(id, {
|
|
358
|
-
select: [
|
|
359
|
-
"shipping_total",
|
|
360
|
-
"discount_total",
|
|
361
|
-
"tax_total",
|
|
362
|
-
"refunded_total",
|
|
363
|
-
"gift_card_total",
|
|
364
|
-
"subtotal",
|
|
365
|
-
"total",
|
|
366
|
-
"refundable_amount",
|
|
367
|
-
],
|
|
368
|
-
relations: [
|
|
369
|
-
"customer",
|
|
370
|
-
"billing_address",
|
|
371
|
-
"shipping_address",
|
|
372
|
-
"discounts",
|
|
373
|
-
"discounts.rule",
|
|
374
|
-
"shipping_methods",
|
|
375
|
-
"shipping_methods.shipping_option",
|
|
376
|
-
"payments",
|
|
377
|
-
"fulfillments",
|
|
378
|
-
"returns",
|
|
379
|
-
"gift_cards",
|
|
380
|
-
"gift_card_transactions",
|
|
381
|
-
],
|
|
382
|
-
})
|
|
383
|
-
|
|
384
|
-
const shipment = await this.fulfillmentService_.retrieve(fulfillment_id, {
|
|
385
|
-
relations: ["items", "tracking_links"],
|
|
386
|
-
})
|
|
387
|
-
|
|
388
|
-
const locale = await this.extractLocale(order)
|
|
389
|
-
|
|
390
|
-
return {
|
|
391
|
-
locale,
|
|
392
|
-
order,
|
|
393
|
-
date: shipment.shipped_at.toDateString(),
|
|
394
|
-
email: order.email,
|
|
395
|
-
fulfillment: shipment,
|
|
396
|
-
tracking_links: shipment.tracking_links,
|
|
397
|
-
tracking_number: shipment.tracking_numbers.join(", "),
|
|
398
|
-
}
|
|
399
|
-
}
|
|
400
|
-
|
|
401
|
-
async orderCanceledData({ id }) {
|
|
402
|
-
const order = await this.orderService_.retrieve(id, {
|
|
403
|
-
select: [
|
|
404
|
-
"shipping_total",
|
|
405
|
-
"discount_total",
|
|
406
|
-
"tax_total",
|
|
407
|
-
"refunded_total",
|
|
408
|
-
"gift_card_total",
|
|
409
|
-
"subtotal",
|
|
410
|
-
"total",
|
|
411
|
-
],
|
|
412
|
-
relations: [
|
|
413
|
-
"customer",
|
|
414
|
-
"billing_address",
|
|
415
|
-
"shipping_address",
|
|
416
|
-
"discounts",
|
|
417
|
-
"discounts.rule",
|
|
418
|
-
"shipping_methods",
|
|
419
|
-
"shipping_methods.shipping_option",
|
|
420
|
-
"payments",
|
|
421
|
-
"fulfillments",
|
|
422
|
-
"returns",
|
|
423
|
-
"gift_cards",
|
|
424
|
-
"gift_card_transactions",
|
|
425
|
-
],
|
|
426
|
-
})
|
|
427
|
-
|
|
428
|
-
const {
|
|
429
|
-
subtotal,
|
|
430
|
-
tax_total,
|
|
431
|
-
discount_total,
|
|
432
|
-
shipping_total,
|
|
433
|
-
gift_card_total,
|
|
434
|
-
total,
|
|
435
|
-
} = order
|
|
436
|
-
|
|
437
|
-
const taxRate = order.tax_rate / 100
|
|
438
|
-
const currencyCode = order.currency_code.toUpperCase()
|
|
439
|
-
|
|
440
|
-
const items = this.processItems_(order.items, taxRate, currencyCode)
|
|
441
|
-
|
|
442
|
-
let discounts = []
|
|
443
|
-
if (order.discounts) {
|
|
444
|
-
discounts = order.discounts.map((discount) => {
|
|
445
|
-
return {
|
|
446
|
-
is_giftcard: false,
|
|
447
|
-
code: discount.code,
|
|
448
|
-
descriptor: `${discount.rule.value}${
|
|
449
|
-
discount.rule.type === "percentage" ? "%" : ` ${currencyCode}`
|
|
450
|
-
}`,
|
|
451
|
-
}
|
|
452
|
-
})
|
|
453
|
-
}
|
|
454
|
-
|
|
455
|
-
let giftCards = []
|
|
456
|
-
if (order.gift_cards) {
|
|
457
|
-
giftCards = order.gift_cards.map((gc) => {
|
|
458
|
-
return {
|
|
459
|
-
is_giftcard: true,
|
|
460
|
-
code: gc.code,
|
|
461
|
-
descriptor: `${gc.value} ${currencyCode}`,
|
|
462
|
-
}
|
|
463
|
-
})
|
|
464
|
-
|
|
465
|
-
discounts.concat(giftCards)
|
|
466
|
-
}
|
|
467
|
-
|
|
468
|
-
const locale = await this.extractLocale(order)
|
|
469
|
-
|
|
470
|
-
return {
|
|
471
|
-
...order,
|
|
472
|
-
locale,
|
|
473
|
-
has_discounts: order.discounts.length,
|
|
474
|
-
has_gift_cards: order.gift_cards.length,
|
|
475
|
-
date: order.created_at.toDateString(),
|
|
476
|
-
items,
|
|
477
|
-
discounts,
|
|
478
|
-
subtotal: `${this.humanPrice_(
|
|
479
|
-
subtotal * (1 + taxRate),
|
|
480
|
-
currencyCode
|
|
481
|
-
)} ${currencyCode}`,
|
|
482
|
-
gift_card_total: `${this.humanPrice_(
|
|
483
|
-
gift_card_total * (1 + taxRate),
|
|
484
|
-
currencyCode
|
|
485
|
-
)} ${currencyCode}`,
|
|
486
|
-
tax_total: `${this.humanPrice_(tax_total, currencyCode)} ${currencyCode}`,
|
|
487
|
-
discount_total: `${this.humanPrice_(
|
|
488
|
-
discount_total * (1 + taxRate),
|
|
489
|
-
currencyCode
|
|
490
|
-
)} ${currencyCode}`,
|
|
491
|
-
shipping_total: `${this.humanPrice_(
|
|
492
|
-
shipping_total * (1 + taxRate),
|
|
493
|
-
currencyCode
|
|
494
|
-
)} ${currencyCode}`,
|
|
495
|
-
total: `${this.humanPrice_(total, currencyCode)} ${currencyCode}`,
|
|
496
|
-
}
|
|
497
|
-
}
|
|
498
|
-
|
|
499
|
-
async orderPlacedData({ id }) {
|
|
500
|
-
const order = await this.orderService_.retrieve(id, {
|
|
501
|
-
select: [
|
|
502
|
-
"shipping_total",
|
|
503
|
-
"discount_total",
|
|
504
|
-
"tax_total",
|
|
505
|
-
"refunded_total",
|
|
506
|
-
"gift_card_total",
|
|
507
|
-
"subtotal",
|
|
508
|
-
"total",
|
|
509
|
-
],
|
|
510
|
-
relations: [
|
|
511
|
-
"customer",
|
|
512
|
-
"billing_address",
|
|
513
|
-
"shipping_address",
|
|
514
|
-
"discounts",
|
|
515
|
-
"discounts.rule",
|
|
516
|
-
"shipping_methods",
|
|
517
|
-
"shipping_methods.shipping_option",
|
|
518
|
-
"payments",
|
|
519
|
-
"fulfillments",
|
|
520
|
-
"returns",
|
|
521
|
-
"gift_cards",
|
|
522
|
-
"gift_card_transactions",
|
|
523
|
-
],
|
|
524
|
-
})
|
|
525
|
-
|
|
526
|
-
const { tax_total, shipping_total, gift_card_total, total } = order
|
|
527
|
-
|
|
528
|
-
const currencyCode = order.currency_code.toUpperCase()
|
|
529
|
-
|
|
530
|
-
const items = await Promise.all(
|
|
531
|
-
order.items.map(async (i) => {
|
|
532
|
-
i.totals = await this.totalsService_.getLineItemTotals(i, order, {
|
|
533
|
-
include_tax: true,
|
|
534
|
-
use_tax_lines: true,
|
|
535
|
-
})
|
|
536
|
-
i.thumbnail = this.normalizeThumbUrl_(i.thumbnail)
|
|
537
|
-
i.discounted_price = `${this.humanPrice_(
|
|
538
|
-
i.totals.total / i.quantity,
|
|
539
|
-
currencyCode
|
|
540
|
-
)} ${currencyCode}`
|
|
541
|
-
i.price = `${this.humanPrice_(
|
|
542
|
-
i.totals.original_total / i.quantity,
|
|
543
|
-
currencyCode
|
|
544
|
-
)} ${currencyCode}`
|
|
545
|
-
return i
|
|
546
|
-
})
|
|
547
|
-
)
|
|
548
|
-
|
|
549
|
-
let discounts = []
|
|
550
|
-
if (order.discounts) {
|
|
551
|
-
discounts = order.discounts.map((discount) => {
|
|
552
|
-
return {
|
|
553
|
-
is_giftcard: false,
|
|
554
|
-
code: discount.code,
|
|
555
|
-
descriptor: `${discount.rule.value}${
|
|
556
|
-
discount.rule.type === "percentage" ? "%" : ` ${currencyCode}`
|
|
557
|
-
}`,
|
|
558
|
-
}
|
|
559
|
-
})
|
|
560
|
-
}
|
|
561
|
-
|
|
562
|
-
let giftCards = []
|
|
563
|
-
if (order.gift_cards) {
|
|
564
|
-
giftCards = order.gift_cards.map((gc) => {
|
|
565
|
-
return {
|
|
566
|
-
is_giftcard: true,
|
|
567
|
-
code: gc.code,
|
|
568
|
-
descriptor: `${gc.value} ${currencyCode}`,
|
|
569
|
-
}
|
|
570
|
-
})
|
|
571
|
-
|
|
572
|
-
discounts.concat(giftCards)
|
|
573
|
-
}
|
|
574
|
-
|
|
575
|
-
const locale = await this.extractLocale(order)
|
|
576
|
-
|
|
577
|
-
// Includes taxes in discount amount
|
|
578
|
-
const discountTotal = items.reduce((acc, i) => {
|
|
579
|
-
return acc + i.totals.original_total - i.totals.total
|
|
580
|
-
}, 0)
|
|
581
|
-
|
|
582
|
-
const discounted_subtotal = items.reduce((acc, i) => {
|
|
583
|
-
return acc + i.totals.total
|
|
584
|
-
}, 0)
|
|
585
|
-
const subtotal = items.reduce((acc, i) => {
|
|
586
|
-
return acc + i.totals.original_total
|
|
587
|
-
}, 0)
|
|
588
|
-
|
|
589
|
-
const subtotal_ex_tax = items.reduce((total, i) => {
|
|
590
|
-
return total + i.totals.subtotal
|
|
591
|
-
}, 0)
|
|
592
|
-
|
|
593
|
-
return {
|
|
594
|
-
...order,
|
|
595
|
-
locale,
|
|
596
|
-
has_discounts: order.discounts.length,
|
|
597
|
-
has_gift_cards: order.gift_cards.length,
|
|
598
|
-
date: order.created_at.toDateString(),
|
|
599
|
-
items,
|
|
600
|
-
discounts,
|
|
601
|
-
subtotal_ex_tax: `${this.humanPrice_(
|
|
602
|
-
subtotal_ex_tax,
|
|
603
|
-
currencyCode
|
|
604
|
-
)} ${currencyCode}`,
|
|
605
|
-
subtotal: `${this.humanPrice_(subtotal, currencyCode)} ${currencyCode}`,
|
|
606
|
-
gift_card_total: `${this.humanPrice_(
|
|
607
|
-
gift_card_total,
|
|
608
|
-
currencyCode
|
|
609
|
-
)} ${currencyCode}`,
|
|
610
|
-
tax_total: `${this.humanPrice_(tax_total, currencyCode)} ${currencyCode}`,
|
|
611
|
-
discount_total: `${this.humanPrice_(
|
|
612
|
-
discountTotal,
|
|
613
|
-
currencyCode
|
|
614
|
-
)} ${currencyCode}`,
|
|
615
|
-
shipping_total: `${this.humanPrice_(
|
|
616
|
-
shipping_total,
|
|
617
|
-
currencyCode
|
|
618
|
-
)} ${currencyCode}`,
|
|
619
|
-
total: `${this.humanPrice_(total, currencyCode)} ${currencyCode}`,
|
|
620
|
-
}
|
|
621
|
-
}
|
|
622
|
-
|
|
623
|
-
async gcCreatedData({ id }) {
|
|
624
|
-
const giftCard = await this.giftCardService_.retrieve(id, {
|
|
625
|
-
relations: ["region", "order"],
|
|
626
|
-
})
|
|
627
|
-
|
|
628
|
-
if (!giftCard.order) {
|
|
629
|
-
return
|
|
630
|
-
}
|
|
631
|
-
|
|
632
|
-
const taxRate = giftCard.region.tax_rate / 100
|
|
633
|
-
|
|
634
|
-
const locale = await this.extractLocale(order)
|
|
635
|
-
|
|
636
|
-
return {
|
|
637
|
-
...giftCard,
|
|
638
|
-
locale,
|
|
639
|
-
email: giftCard.order.email,
|
|
640
|
-
display_value: giftCard.value * (1 + taxRate),
|
|
641
|
-
}
|
|
642
|
-
}
|
|
643
|
-
|
|
644
|
-
async returnRequestedData({ id, return_id }) {
|
|
645
|
-
// Fetch the return request
|
|
646
|
-
const returnRequest = await this.returnService_.retrieve(return_id, {
|
|
647
|
-
relations: [
|
|
648
|
-
"items",
|
|
649
|
-
"items.item",
|
|
650
|
-
"items.item.tax_lines",
|
|
651
|
-
"items.item.variant",
|
|
652
|
-
"items.item.variant.product",
|
|
653
|
-
"shipping_method",
|
|
654
|
-
"shipping_method.tax_lines",
|
|
655
|
-
"shipping_method.shipping_option",
|
|
656
|
-
],
|
|
657
|
-
})
|
|
658
|
-
|
|
659
|
-
const items = await this.lineItemService_.list(
|
|
660
|
-
{
|
|
661
|
-
id: returnRequest.items.map(({ item_id }) => item_id),
|
|
662
|
-
},
|
|
663
|
-
{ relations: ["tax_lines"] }
|
|
664
|
-
)
|
|
665
|
-
|
|
666
|
-
// Fetch the order
|
|
667
|
-
const order = await this.orderService_.retrieve(id, {
|
|
668
|
-
select: ["total"],
|
|
669
|
-
relations: [
|
|
670
|
-
"items",
|
|
671
|
-
"items.tax_lines",
|
|
672
|
-
"discounts",
|
|
673
|
-
"discounts.rule",
|
|
674
|
-
"shipping_address",
|
|
675
|
-
"returns",
|
|
676
|
-
],
|
|
677
|
-
})
|
|
678
|
-
|
|
679
|
-
const currencyCode = order.currency_code.toUpperCase()
|
|
680
|
-
|
|
681
|
-
// Calculate which items are in the return
|
|
682
|
-
const returnItems = await Promise.all(
|
|
683
|
-
returnRequest.items.map(async (i) => {
|
|
684
|
-
const found = items.find((oi) => oi.id === i.item_id)
|
|
685
|
-
found.quantity = i.quantity
|
|
686
|
-
found.thumbnail = this.normalizeThumbUrl_(found.thumbnail)
|
|
687
|
-
found.totals = await this.totalsService_.getLineItemTotals(
|
|
688
|
-
found,
|
|
689
|
-
order,
|
|
690
|
-
{
|
|
691
|
-
include_tax: true,
|
|
692
|
-
use_tax_lines: true,
|
|
693
|
-
}
|
|
694
|
-
)
|
|
695
|
-
found.price = `${this.humanPrice_(
|
|
696
|
-
found.totals.total,
|
|
697
|
-
currencyCode
|
|
698
|
-
)} ${currencyCode}`
|
|
699
|
-
found.tax_lines = found.totals.tax_lines
|
|
700
|
-
return found
|
|
701
|
-
})
|
|
702
|
-
)
|
|
703
|
-
|
|
704
|
-
// Get total of the returned products
|
|
705
|
-
const item_subtotal = returnItems.reduce(
|
|
706
|
-
(acc, next) => acc + next.totals.total,
|
|
707
|
-
0
|
|
708
|
-
)
|
|
709
|
-
|
|
710
|
-
// If the return has a shipping method get the price and any attachments
|
|
711
|
-
let shippingTotal = 0
|
|
712
|
-
if (returnRequest.shipping_method) {
|
|
713
|
-
const base = returnRequest.shipping_method.price
|
|
714
|
-
shippingTotal =
|
|
715
|
-
base +
|
|
716
|
-
returnRequest.shipping_method.tax_lines.reduce((acc, next) => {
|
|
717
|
-
return Math.round(acc + base * (next.rate / 100))
|
|
718
|
-
}, 0)
|
|
719
|
-
}
|
|
720
|
-
|
|
721
|
-
const locale = await this.extractLocale(order)
|
|
722
|
-
|
|
723
|
-
return {
|
|
724
|
-
locale,
|
|
725
|
-
has_shipping: !!returnRequest.shipping_method,
|
|
726
|
-
email: order.email,
|
|
727
|
-
items: returnItems,
|
|
728
|
-
subtotal: `${this.humanPrice_(
|
|
729
|
-
item_subtotal,
|
|
730
|
-
currencyCode
|
|
731
|
-
)} ${currencyCode}`,
|
|
732
|
-
shipping_total: `${this.humanPrice_(
|
|
733
|
-
shippingTotal,
|
|
734
|
-
currencyCode
|
|
735
|
-
)} ${currencyCode}`,
|
|
736
|
-
refund_amount: `${this.humanPrice_(
|
|
737
|
-
returnRequest.refund_amount,
|
|
738
|
-
currencyCode
|
|
739
|
-
)} ${currencyCode}`,
|
|
740
|
-
return_request: {
|
|
741
|
-
...returnRequest,
|
|
742
|
-
refund_amount: `${this.humanPrice_(
|
|
743
|
-
returnRequest.refund_amount,
|
|
744
|
-
currencyCode
|
|
745
|
-
)} ${currencyCode}`,
|
|
746
|
-
},
|
|
747
|
-
order,
|
|
748
|
-
date: returnRequest.updated_at.toDateString(),
|
|
749
|
-
}
|
|
750
|
-
}
|
|
751
|
-
|
|
752
|
-
async swapReceivedData({ id }) {
|
|
753
|
-
const store = await this.storeService_.retrieve()
|
|
754
|
-
const swap = await this.swapService_.retrieve(id, {
|
|
755
|
-
relations: [
|
|
756
|
-
"additional_items",
|
|
757
|
-
"additional_items.tax_lines",
|
|
758
|
-
"return_order",
|
|
759
|
-
"return_order.items",
|
|
760
|
-
"return_order.items.item",
|
|
761
|
-
"return_order.shipping_method",
|
|
762
|
-
"return_order.shipping_method.shipping_option",
|
|
763
|
-
],
|
|
764
|
-
})
|
|
765
|
-
|
|
766
|
-
const returnRequest = swap.return_order
|
|
767
|
-
|
|
768
|
-
const items = await this.lineItemService_.list(
|
|
769
|
-
{
|
|
770
|
-
id: returnRequest.items.map(({ item_id }) => item_id),
|
|
771
|
-
},
|
|
772
|
-
{
|
|
773
|
-
relations: ["tax_lines"],
|
|
774
|
-
}
|
|
775
|
-
)
|
|
776
|
-
|
|
777
|
-
returnRequest.items = returnRequest.items.map((item) => {
|
|
778
|
-
const found = items.find((i) => i.id === item.item_id)
|
|
779
|
-
return {
|
|
780
|
-
...item,
|
|
781
|
-
item: found,
|
|
782
|
-
}
|
|
783
|
-
})
|
|
784
|
-
|
|
785
|
-
const swapLink = store.swap_link_template.replace(
|
|
786
|
-
/\{cart_id\}/,
|
|
787
|
-
swap.cart_id
|
|
788
|
-
)
|
|
789
|
-
|
|
790
|
-
const order = await this.orderService_.retrieve(swap.order_id, {
|
|
791
|
-
select: ["total"],
|
|
792
|
-
relations: [
|
|
793
|
-
"items",
|
|
794
|
-
"discounts",
|
|
795
|
-
"discounts.rule",
|
|
796
|
-
"shipping_address",
|
|
797
|
-
"swaps",
|
|
798
|
-
"swaps.additional_items",
|
|
799
|
-
"swaps.additional_items.tax_lines",
|
|
800
|
-
],
|
|
801
|
-
})
|
|
802
|
-
|
|
803
|
-
const cart = await this.cartService_.retrieve(swap.cart_id, {
|
|
804
|
-
select: [
|
|
805
|
-
"total",
|
|
806
|
-
"tax_total",
|
|
807
|
-
"discount_total",
|
|
808
|
-
"shipping_total",
|
|
809
|
-
"subtotal",
|
|
810
|
-
],
|
|
811
|
-
})
|
|
812
|
-
const currencyCode = order.currency_code.toUpperCase()
|
|
813
|
-
|
|
814
|
-
const decoratedItems = await Promise.all(
|
|
815
|
-
cart.items.map(async (i) => {
|
|
816
|
-
const totals = await this.totalsService_.getLineItemTotals(i, cart, {
|
|
817
|
-
include_tax: true,
|
|
818
|
-
})
|
|
819
|
-
|
|
820
|
-
return {
|
|
821
|
-
...i,
|
|
822
|
-
totals,
|
|
823
|
-
price: this.humanPrice_(
|
|
824
|
-
totals.subtotal + totals.tax_total,
|
|
825
|
-
currencyCode
|
|
826
|
-
),
|
|
827
|
-
}
|
|
828
|
-
})
|
|
829
|
-
)
|
|
830
|
-
|
|
831
|
-
const returnTotal = decoratedItems.reduce((acc, next) => {
|
|
832
|
-
if (next.is_return) {
|
|
833
|
-
return acc + -1 * (next.totals.subtotal + next.totals.tax_total)
|
|
834
|
-
}
|
|
835
|
-
return acc
|
|
836
|
-
}, 0)
|
|
837
|
-
|
|
838
|
-
const additionalTotal = decoratedItems.reduce((acc, next) => {
|
|
839
|
-
if (!next.is_return) {
|
|
840
|
-
return acc + next.totals.subtotal + next.totals.tax_total
|
|
841
|
-
}
|
|
842
|
-
return acc
|
|
843
|
-
}, 0)
|
|
844
|
-
|
|
845
|
-
const refundAmount = swap.return_order.refund_amount
|
|
846
|
-
|
|
847
|
-
const locale = await this.extractLocale(order)
|
|
848
|
-
|
|
849
|
-
return {
|
|
850
|
-
locale,
|
|
851
|
-
swap,
|
|
852
|
-
order,
|
|
853
|
-
return_request: returnRequest,
|
|
854
|
-
date: swap.updated_at.toDateString(),
|
|
855
|
-
swap_link: swapLink,
|
|
856
|
-
email: order.email,
|
|
857
|
-
items: decoratedItems.filter((di) => !di.is_return),
|
|
858
|
-
return_items: decoratedItems.filter((di) => di.is_return),
|
|
859
|
-
return_total: `${this.humanPrice_(
|
|
860
|
-
returnTotal,
|
|
861
|
-
currencyCode
|
|
862
|
-
)} ${currencyCode}`,
|
|
863
|
-
tax_total: `${this.humanPrice_(
|
|
864
|
-
cart.total,
|
|
865
|
-
currencyCode
|
|
866
|
-
)} ${currencyCode}`,
|
|
867
|
-
refund_amount: `${this.humanPrice_(
|
|
868
|
-
refundAmount,
|
|
869
|
-
currencyCode
|
|
870
|
-
)} ${currencyCode}`,
|
|
871
|
-
additional_total: `${this.humanPrice_(
|
|
872
|
-
additionalTotal,
|
|
873
|
-
currencyCode
|
|
874
|
-
)} ${currencyCode}`,
|
|
875
|
-
}
|
|
876
|
-
}
|
|
877
|
-
|
|
878
|
-
async swapCreatedData({ id }) {
|
|
879
|
-
const store = await this.storeService_.retrieve()
|
|
880
|
-
const swap = await this.swapService_.retrieve(id, {
|
|
881
|
-
relations: [
|
|
882
|
-
"additional_items",
|
|
883
|
-
"additional_items.tax_lines",
|
|
884
|
-
"return_order",
|
|
885
|
-
"return_order.items",
|
|
886
|
-
"return_order.items.item",
|
|
887
|
-
"return_order.shipping_method",
|
|
888
|
-
"return_order.shipping_method.shipping_option",
|
|
889
|
-
],
|
|
890
|
-
})
|
|
891
|
-
|
|
892
|
-
const returnRequest = swap.return_order
|
|
893
|
-
|
|
894
|
-
const items = await this.lineItemService_.list(
|
|
895
|
-
{
|
|
896
|
-
id: returnRequest.items.map(({ item_id }) => item_id),
|
|
897
|
-
},
|
|
898
|
-
{
|
|
899
|
-
relations: ["tax_lines"],
|
|
900
|
-
}
|
|
901
|
-
)
|
|
902
|
-
|
|
903
|
-
returnRequest.items = returnRequest.items.map((item) => {
|
|
904
|
-
const found = items.find((i) => i.id === item.item_id)
|
|
905
|
-
return {
|
|
906
|
-
...item,
|
|
907
|
-
item: found,
|
|
908
|
-
}
|
|
909
|
-
})
|
|
910
|
-
|
|
911
|
-
const swapLink = store.swap_link_template.replace(
|
|
912
|
-
/\{cart_id\}/,
|
|
913
|
-
swap.cart_id
|
|
914
|
-
)
|
|
915
|
-
|
|
916
|
-
const order = await this.orderService_.retrieve(swap.order_id, {
|
|
917
|
-
select: ["total"],
|
|
918
|
-
relations: [
|
|
919
|
-
"items",
|
|
920
|
-
"items.tax_lines",
|
|
921
|
-
"discounts",
|
|
922
|
-
"discounts.rule",
|
|
923
|
-
"shipping_address",
|
|
924
|
-
"swaps",
|
|
925
|
-
"swaps.additional_items",
|
|
926
|
-
"swaps.additional_items.tax_lines",
|
|
927
|
-
],
|
|
928
|
-
})
|
|
929
|
-
|
|
930
|
-
const cart = await this.cartService_.retrieve(swap.cart_id, {
|
|
931
|
-
select: [
|
|
932
|
-
"total",
|
|
933
|
-
"tax_total",
|
|
934
|
-
"discount_total",
|
|
935
|
-
"shipping_total",
|
|
936
|
-
"subtotal",
|
|
937
|
-
],
|
|
938
|
-
})
|
|
939
|
-
const currencyCode = order.currency_code.toUpperCase()
|
|
940
|
-
|
|
941
|
-
const decoratedItems = await Promise.all(
|
|
942
|
-
cart.items.map(async (i) => {
|
|
943
|
-
const totals = await this.totalsService_.getLineItemTotals(i, cart, {
|
|
944
|
-
include_tax: true,
|
|
945
|
-
})
|
|
946
|
-
|
|
947
|
-
return {
|
|
948
|
-
...i,
|
|
949
|
-
totals,
|
|
950
|
-
tax_lines: totals.tax_lines,
|
|
951
|
-
price: `${this.humanPrice_(
|
|
952
|
-
totals.original_total / i.quantity,
|
|
953
|
-
currencyCode
|
|
954
|
-
)} ${currencyCode}`,
|
|
955
|
-
discounted_price: `${this.humanPrice_(
|
|
956
|
-
totals.total / i.quantity,
|
|
957
|
-
currencyCode
|
|
958
|
-
)} ${currencyCode}`,
|
|
959
|
-
}
|
|
960
|
-
})
|
|
961
|
-
)
|
|
962
|
-
|
|
963
|
-
const returnTotal = decoratedItems.reduce((acc, next) => {
|
|
964
|
-
const { total } = next.totals
|
|
965
|
-
if (next.is_return && next.variant_id) {
|
|
966
|
-
return acc + -1 * total
|
|
967
|
-
}
|
|
968
|
-
return acc
|
|
969
|
-
}, 0)
|
|
970
|
-
|
|
971
|
-
const additionalTotal = decoratedItems.reduce((acc, next) => {
|
|
972
|
-
const { total } = next.totals
|
|
973
|
-
if (!next.is_return) {
|
|
974
|
-
return acc + total
|
|
975
|
-
}
|
|
976
|
-
return acc
|
|
977
|
-
}, 0)
|
|
978
|
-
|
|
979
|
-
const refundAmount = swap.return_order.refund_amount
|
|
980
|
-
|
|
981
|
-
const locale = await this.extractLocale(order)
|
|
982
|
-
|
|
983
|
-
return {
|
|
984
|
-
locale,
|
|
985
|
-
swap,
|
|
986
|
-
order,
|
|
987
|
-
return_request: returnRequest,
|
|
988
|
-
date: swap.updated_at.toDateString(),
|
|
989
|
-
swap_link: swapLink,
|
|
990
|
-
email: order.email,
|
|
991
|
-
items: decoratedItems.filter((di) => !di.is_return),
|
|
992
|
-
return_items: decoratedItems.filter((di) => di.is_return),
|
|
993
|
-
return_total: `${this.humanPrice_(
|
|
994
|
-
returnTotal,
|
|
995
|
-
currencyCode
|
|
996
|
-
)} ${currencyCode}`,
|
|
997
|
-
refund_amount: `${this.humanPrice_(
|
|
998
|
-
refundAmount,
|
|
999
|
-
currencyCode
|
|
1000
|
-
)} ${currencyCode}`,
|
|
1001
|
-
additional_total: `${this.humanPrice_(
|
|
1002
|
-
additionalTotal,
|
|
1003
|
-
currencyCode
|
|
1004
|
-
)} ${currencyCode}`,
|
|
1005
|
-
}
|
|
1006
|
-
}
|
|
1007
|
-
|
|
1008
|
-
async itemsReturnedData(data) {
|
|
1009
|
-
return this.returnRequestedData(data)
|
|
1010
|
-
}
|
|
1011
|
-
|
|
1012
|
-
async swapShipmentCreatedData({ id, fulfillment_id }) {
|
|
1013
|
-
const swap = await this.swapService_.retrieve(id, {
|
|
1014
|
-
relations: [
|
|
1015
|
-
"shipping_address",
|
|
1016
|
-
"shipping_methods",
|
|
1017
|
-
"shipping_methods.tax_lines",
|
|
1018
|
-
"additional_items",
|
|
1019
|
-
"additional_items.tax_lines",
|
|
1020
|
-
"return_order",
|
|
1021
|
-
"return_order.items",
|
|
1022
|
-
],
|
|
1023
|
-
})
|
|
1024
|
-
|
|
1025
|
-
const order = await this.orderService_.retrieve(swap.order_id, {
|
|
1026
|
-
relations: [
|
|
1027
|
-
"region",
|
|
1028
|
-
"items",
|
|
1029
|
-
"items.tax_lines",
|
|
1030
|
-
"discounts",
|
|
1031
|
-
"discounts.rule",
|
|
1032
|
-
"swaps",
|
|
1033
|
-
"swaps.additional_items",
|
|
1034
|
-
"swaps.additional_items.tax_lines",
|
|
1035
|
-
],
|
|
1036
|
-
})
|
|
1037
|
-
|
|
1038
|
-
const cart = await this.cartService_.retrieve(swap.cart_id, {
|
|
1039
|
-
select: [
|
|
1040
|
-
"total",
|
|
1041
|
-
"tax_total",
|
|
1042
|
-
"discount_total",
|
|
1043
|
-
"shipping_total",
|
|
1044
|
-
"subtotal",
|
|
1045
|
-
],
|
|
1046
|
-
})
|
|
1047
|
-
|
|
1048
|
-
const returnRequest = swap.return_order
|
|
1049
|
-
const items = await this.lineItemService_.list(
|
|
1050
|
-
{
|
|
1051
|
-
id: returnRequest.items.map(({ item_id }) => item_id),
|
|
1052
|
-
},
|
|
1053
|
-
{
|
|
1054
|
-
relations: ["tax_lines"],
|
|
1055
|
-
}
|
|
1056
|
-
)
|
|
1057
|
-
|
|
1058
|
-
const taxRate = order.tax_rate / 100
|
|
1059
|
-
const currencyCode = order.currency_code.toUpperCase()
|
|
1060
|
-
|
|
1061
|
-
const returnItems = await Promise.all(
|
|
1062
|
-
swap.return_order.items.map(async (i) => {
|
|
1063
|
-
const found = items.find((oi) => oi.id === i.item_id)
|
|
1064
|
-
const totals = await this.totalsService_.getLineItemTotals(i, cart, {
|
|
1065
|
-
include_tax: true,
|
|
1066
|
-
})
|
|
1067
|
-
|
|
1068
|
-
return {
|
|
1069
|
-
...found,
|
|
1070
|
-
thumbnail: this.normalizeThumbUrl_(found.thumbnail),
|
|
1071
|
-
price: `${this.humanPrice_(
|
|
1072
|
-
totals.original_total / i.quantity,
|
|
1073
|
-
currencyCode
|
|
1074
|
-
)} ${currencyCode}`,
|
|
1075
|
-
discounted_price: `${this.humanPrice_(
|
|
1076
|
-
totals.total / i.quantity,
|
|
1077
|
-
currencyCode
|
|
1078
|
-
)} ${currencyCode}`,
|
|
1079
|
-
quantity: i.quantity,
|
|
1080
|
-
}
|
|
1081
|
-
})
|
|
1082
|
-
)
|
|
1083
|
-
|
|
1084
|
-
const returnTotal = await this.totalsService_.getRefundTotal(
|
|
1085
|
-
order,
|
|
1086
|
-
returnItems
|
|
1087
|
-
)
|
|
1088
|
-
|
|
1089
|
-
const constructedOrder = {
|
|
1090
|
-
...order,
|
|
1091
|
-
shipping_methods: swap.shipping_methods,
|
|
1092
|
-
items: swap.additional_items,
|
|
1093
|
-
}
|
|
1094
|
-
|
|
1095
|
-
const additionalTotal = await this.totalsService_.getTotal(constructedOrder)
|
|
1096
|
-
|
|
1097
|
-
const refundAmount = swap.return_order.refund_amount
|
|
1098
|
-
|
|
1099
|
-
const shipment = await this.fulfillmentService_.retrieve(fulfillment_id, {
|
|
1100
|
-
relations: ["tracking_links"],
|
|
1101
|
-
})
|
|
1102
|
-
|
|
1103
|
-
const locale = await this.extractLocale(order)
|
|
1104
|
-
|
|
1105
|
-
return {
|
|
1106
|
-
locale,
|
|
1107
|
-
swap,
|
|
1108
|
-
order,
|
|
1109
|
-
items: await Promise.all(
|
|
1110
|
-
swap.additional_items.map(async (i) => {
|
|
1111
|
-
const totals = await this.totalsService_.getLineItemTotals(i, cart, {
|
|
1112
|
-
include_tax: true,
|
|
1113
|
-
})
|
|
1114
|
-
|
|
1115
|
-
return {
|
|
1116
|
-
...i,
|
|
1117
|
-
thumbnail: this.normalizeThumbUrl_(i.thumbnail),
|
|
1118
|
-
price: `${this.humanPrice_(
|
|
1119
|
-
totals.original_total / i.quantity,
|
|
1120
|
-
currencyCode
|
|
1121
|
-
)} ${currencyCode}`,
|
|
1122
|
-
discounted_price: `${this.humanPrice_(
|
|
1123
|
-
totals.total / i.quantity,
|
|
1124
|
-
currencyCode
|
|
1125
|
-
)} ${currencyCode}`,
|
|
1126
|
-
quantity: i.quantity,
|
|
1127
|
-
}
|
|
1128
|
-
})
|
|
1129
|
-
),
|
|
1130
|
-
date: swap.updated_at.toDateString(),
|
|
1131
|
-
email: order.email,
|
|
1132
|
-
tax_amount: `${this.humanPrice_(
|
|
1133
|
-
cart.tax_total,
|
|
1134
|
-
currencyCode
|
|
1135
|
-
)} ${currencyCode}`,
|
|
1136
|
-
paid_total: `${this.humanPrice_(
|
|
1137
|
-
swap.difference_due,
|
|
1138
|
-
currencyCode
|
|
1139
|
-
)} ${currencyCode}`,
|
|
1140
|
-
return_total: `${this.humanPrice_(
|
|
1141
|
-
returnTotal,
|
|
1142
|
-
currencyCode
|
|
1143
|
-
)} ${currencyCode}`,
|
|
1144
|
-
refund_amount: `${this.humanPrice_(
|
|
1145
|
-
refundAmount,
|
|
1146
|
-
currencyCode
|
|
1147
|
-
)} ${currencyCode}`,
|
|
1148
|
-
additional_total: `${this.humanPrice_(
|
|
1149
|
-
additionalTotal,
|
|
1150
|
-
currencyCode
|
|
1151
|
-
)} ${currencyCode}`,
|
|
1152
|
-
fulfillment: shipment,
|
|
1153
|
-
tracking_links: shipment.tracking_links,
|
|
1154
|
-
tracking_number: shipment.tracking_numbers.join(", "),
|
|
1155
|
-
}
|
|
1156
|
-
}
|
|
1157
|
-
|
|
1158
|
-
async claimShipmentCreatedData({ id, fulfillment_id }) {
|
|
1159
|
-
const claim = await this.claimService_.retrieve(id, {
|
|
1160
|
-
relations: ["order", "order.items", "order.shipping_address"],
|
|
1161
|
-
})
|
|
1162
|
-
|
|
1163
|
-
const shipment = await this.fulfillmentService_.retrieve(fulfillment_id, {
|
|
1164
|
-
relations: ["tracking_links"],
|
|
1165
|
-
})
|
|
1166
|
-
|
|
1167
|
-
const locale = await this.extractLocale(claim.order)
|
|
1168
|
-
|
|
1169
|
-
return {
|
|
1170
|
-
locale,
|
|
1171
|
-
email: claim.order.email,
|
|
1172
|
-
claim,
|
|
1173
|
-
order: claim.order,
|
|
1174
|
-
fulfillment: shipment,
|
|
1175
|
-
tracking_links: shipment.tracking_links,
|
|
1176
|
-
tracking_number: shipment.tracking_numbers.join(", "),
|
|
1177
|
-
}
|
|
1178
|
-
}
|
|
1179
|
-
|
|
1180
|
-
async restockNotificationData({ variant_id, emails }) {
|
|
1181
|
-
const variant = await this.productVariantService_.retrieve(variant_id, {
|
|
1182
|
-
relations: ["product"],
|
|
1183
|
-
})
|
|
1184
|
-
|
|
1185
|
-
let thumb
|
|
1186
|
-
if (variant.product.thumbnail) {
|
|
1187
|
-
thumb = this.normalizeThumbUrl_(variant.product.thumbnail)
|
|
1188
|
-
}
|
|
1189
|
-
|
|
1190
|
-
return {
|
|
1191
|
-
product: {
|
|
1192
|
-
...variant.product,
|
|
1193
|
-
thumbnail: thumb,
|
|
1194
|
-
},
|
|
1195
|
-
variant,
|
|
1196
|
-
variant_id,
|
|
1197
|
-
emails,
|
|
1198
|
-
}
|
|
1199
|
-
}
|
|
1200
|
-
|
|
1201
|
-
userPasswordResetData(data) {
|
|
1202
|
-
return data
|
|
1203
|
-
}
|
|
1204
|
-
|
|
1205
|
-
customerPasswordResetData(data) {
|
|
1206
|
-
return data
|
|
1207
|
-
}
|
|
1208
|
-
|
|
1209
|
-
async orderRefundCreatedData({ id, refund_id }) {
|
|
1210
|
-
const order = await this.orderService_.retrieveWithTotals(id, {
|
|
1211
|
-
select: [
|
|
1212
|
-
"total",
|
|
1213
|
-
],
|
|
1214
|
-
relations: [
|
|
1215
|
-
"refunds",
|
|
1216
|
-
"items",
|
|
1217
|
-
]
|
|
1218
|
-
})
|
|
1219
|
-
|
|
1220
|
-
const refund = order.refunds.find((refund) => refund.id === refund_id)
|
|
1221
|
-
|
|
1222
|
-
return {
|
|
1223
|
-
order,
|
|
1224
|
-
refund,
|
|
1225
|
-
refund_amount: `${this.humanPrice_(
|
|
1226
|
-
refund.amount,
|
|
1227
|
-
order.currency_code
|
|
1228
|
-
)} ${order.currency_code}`,
|
|
1229
|
-
email: order.email
|
|
1230
|
-
}
|
|
1231
|
-
}
|
|
1232
|
-
|
|
1233
|
-
processItems_(items, taxRate, currencyCode) {
|
|
1234
|
-
return items.map((i) => {
|
|
1235
|
-
return {
|
|
1236
|
-
...i,
|
|
1237
|
-
thumbnail: this.normalizeThumbUrl_(i.thumbnail),
|
|
1238
|
-
price: `${this.humanPrice_(
|
|
1239
|
-
i.unit_price * (1 + taxRate),
|
|
1240
|
-
currencyCode
|
|
1241
|
-
)} ${currencyCode}`,
|
|
1242
|
-
}
|
|
1243
|
-
})
|
|
1244
|
-
}
|
|
1245
|
-
|
|
1246
|
-
humanPrice_(amount, currency) {
|
|
1247
|
-
if (!amount) {
|
|
1248
|
-
return "0.00"
|
|
1249
|
-
}
|
|
1250
|
-
|
|
1251
|
-
const normalized = humanizeAmount(amount, currency)
|
|
1252
|
-
return normalized.toFixed(
|
|
1253
|
-
zeroDecimalCurrencies.includes(currency.toLowerCase()) ? 0 : 2
|
|
1254
|
-
)
|
|
1255
|
-
}
|
|
1256
|
-
|
|
1257
|
-
normalizeThumbUrl_(url) {
|
|
1258
|
-
if (!url) {
|
|
1259
|
-
return null
|
|
1260
|
-
}
|
|
1261
|
-
|
|
1262
|
-
if (url.startsWith("http")) {
|
|
1263
|
-
return url
|
|
1264
|
-
} else if (url.startsWith("//")) {
|
|
1265
|
-
return `https:${url}`
|
|
1266
|
-
}
|
|
1267
|
-
return url
|
|
1268
|
-
}
|
|
1269
|
-
|
|
1270
|
-
async extractLocale(fromOrder) {
|
|
1271
|
-
if (fromOrder.cart_id) {
|
|
1272
|
-
try {
|
|
1273
|
-
const cart = await this.cartService_.retrieve(fromOrder.cart_id, {
|
|
1274
|
-
select: ["id", "context"],
|
|
1275
|
-
})
|
|
1276
|
-
|
|
1277
|
-
if (cart.context && cart.context.locale) {
|
|
1278
|
-
return cart.context.locale
|
|
1279
|
-
}
|
|
1280
|
-
} catch (err) {
|
|
1281
|
-
console.log(err)
|
|
1282
|
-
console.warn("Failed to gather context for order")
|
|
1283
|
-
return null
|
|
1284
|
-
}
|
|
1285
|
-
}
|
|
1286
|
-
return null
|
|
1287
|
-
}
|
|
1288
|
-
}
|
|
1289
|
-
|
|
1290
|
-
export default SESService
|