**What** There is actually an issue with using the `fields` query params with the way the repositories are using our custom query strategy. This pr aims to fix this issue by reworking the strategy. What we had to do was to rework the way the selects are built for each subquery in order to follow the aliasing convention and to be taken into consideration. Alongside these changes, the join used to always select everything, this needed to be changed so that if there are any selects provided for a join, the join should not select everything and let the query select the fields that are requested. Another notable change is that all the repositories are now using the repository util in order to centralize the customization and to have a single place to update when this kind of issue arises. This means that the eager relations when using the query builder are not necessarily taken into account. For that reason, I have removed the `shipping_option` eager option in favor of explicitly asking for the relations like we started to do it in some places. FIXES CORE-1413
339 lines
8.9 KiB
JavaScript
339 lines
8.9 KiB
JavaScript
class OrderSubscriber {
|
|
constructor({
|
|
segmentService,
|
|
eventBusService,
|
|
orderService,
|
|
cartService,
|
|
claimService,
|
|
returnService,
|
|
fulfillmentService,
|
|
}) {
|
|
this.orderService_ = orderService
|
|
|
|
this.cartService_ = cartService
|
|
|
|
this.returnService_ = returnService
|
|
|
|
this.claimService_ = claimService
|
|
|
|
this.fulfillmentService_ = fulfillmentService
|
|
|
|
// Swaps
|
|
// swap.created
|
|
// swap.received
|
|
// swap.shipment_created
|
|
// swap.payment_completed
|
|
// swap.payment_captured
|
|
// swap.refund_processed
|
|
|
|
eventBusService.subscribe(
|
|
"order.shipment_created",
|
|
async ({ id, fulfillment_id }) => {
|
|
const order = await this.orderService_.retrieve(id, {
|
|
select: [
|
|
"shipping_total",
|
|
"discount_total",
|
|
"tax_total",
|
|
"refunded_total",
|
|
"gift_card_total",
|
|
"subtotal",
|
|
"total",
|
|
],
|
|
relations: [
|
|
"customer",
|
|
"billing_address",
|
|
"shipping_address",
|
|
"discounts",
|
|
"discounts.rule",
|
|
"shipping_methods",
|
|
"shipping_methods.shipping_option",
|
|
"payments",
|
|
"fulfillments",
|
|
"returns",
|
|
"items",
|
|
"gift_cards",
|
|
"gift_card_transactions",
|
|
"swaps",
|
|
"swaps.return_order",
|
|
"swaps.payment",
|
|
"swaps.shipping_methods",
|
|
"swaps.shipping_methods.shipping_option",
|
|
"swaps.shipping_address",
|
|
"swaps.additional_items",
|
|
"swaps.fulfillments",
|
|
],
|
|
})
|
|
|
|
const fulfillment = await this.fulfillmentService_.retrieve(
|
|
fulfillment_id,
|
|
{
|
|
relations: ["items"],
|
|
}
|
|
)
|
|
|
|
const toBuildFrom = {
|
|
...order,
|
|
provider_id: fulfillment.provider,
|
|
items: fulfillment.items.map((i) =>
|
|
order.items.find((l) => l.id === i.item_id)
|
|
),
|
|
}
|
|
|
|
const orderData = await segmentService.buildOrder(toBuildFrom)
|
|
const orderEvent = {
|
|
event: "Order Shipped",
|
|
userId: order.customer_id,
|
|
properties: orderData,
|
|
timestamp: fulfillment.shipped_at,
|
|
}
|
|
|
|
segmentService.track(orderEvent)
|
|
}
|
|
)
|
|
|
|
eventBusService.subscribe("claim.created", async ({ id }) => {
|
|
const claim = await this.claimService_.retrieve(id, {
|
|
relations: [
|
|
"order",
|
|
"claim_items",
|
|
"claim_items.item",
|
|
"claim_items.tags",
|
|
"claim_items.variant",
|
|
],
|
|
})
|
|
|
|
for (const ci of claim.claim_items) {
|
|
const price = ci.item.unit_price / 100
|
|
const reporting_price = await segmentService.getReportingValue(
|
|
claim.order.currency_code,
|
|
price
|
|
)
|
|
const event = {
|
|
event: "Item Claimed",
|
|
userId: claim.order.customer_id,
|
|
timestamp: claim.created_at,
|
|
properties: {
|
|
price,
|
|
reporting_price,
|
|
order_id: claim.order_id,
|
|
claim_id: claim.id,
|
|
claim_item_id: ci.id,
|
|
type: claim.type,
|
|
quantity: ci.quantity,
|
|
variant: ci.variant.sku,
|
|
product_id: ci.variant.product_id,
|
|
reason: ci.reason,
|
|
note: ci.note,
|
|
tags: ci.tags.map((t) => ({ id: t.id, value: t.value })),
|
|
},
|
|
}
|
|
await segmentService.track(event)
|
|
}
|
|
})
|
|
|
|
eventBusService.subscribe(
|
|
"order.items_returned",
|
|
async ({ id, return_id }) => {
|
|
const order = await this.orderService_.retrieve(id, {
|
|
select: [
|
|
"shipping_total",
|
|
"discount_total",
|
|
"tax_total",
|
|
"refunded_total",
|
|
"gift_card_total",
|
|
"subtotal",
|
|
"total",
|
|
],
|
|
relations: [
|
|
"customer",
|
|
"billing_address",
|
|
"shipping_address",
|
|
"discounts",
|
|
"discounts.rule",
|
|
"shipping_methods",
|
|
"shipping_methods.shipping_option",
|
|
"payments",
|
|
"fulfillments",
|
|
"returns",
|
|
"items",
|
|
"gift_cards",
|
|
"gift_card_transactions",
|
|
"swaps",
|
|
"swaps.return_order",
|
|
"swaps.payment",
|
|
"swaps.shipping_methods",
|
|
"swaps.shipping_methods.shipping_option",
|
|
"swaps.shipping_address",
|
|
"swaps.additional_items",
|
|
"swaps.fulfillments",
|
|
],
|
|
})
|
|
|
|
const ret = await this.returnService_.retrieve(return_id, {
|
|
relations: ["items", "items.reason"],
|
|
})
|
|
|
|
const shipping = []
|
|
if (ret.shipping_method && ret.shipping_method.price) {
|
|
shipping.push({
|
|
...ret.shipping_method,
|
|
price: -1 * (ret.shipping_method.price / 100),
|
|
})
|
|
}
|
|
|
|
let merged = [...order.items]
|
|
|
|
// merge items from order with items from order swaps
|
|
if (order.swaps && order.swaps.length) {
|
|
for (const s of order.swaps) {
|
|
merged = [...merged, ...s.additional_items]
|
|
}
|
|
}
|
|
|
|
const toBuildFrom = {
|
|
...order,
|
|
shipping_methods: shipping,
|
|
items: ret.items.map((i) => {
|
|
const li = merged.find((l) => l.id === i.item_id)
|
|
if (i.reason) {
|
|
li.reason = i.reason
|
|
}
|
|
|
|
if (i.note) {
|
|
li.note = i.note
|
|
}
|
|
return li
|
|
}),
|
|
}
|
|
|
|
const orderData = await segmentService.buildOrder(toBuildFrom)
|
|
const orderEvent = {
|
|
event: "Order Refunded",
|
|
userId: order.customer_id,
|
|
properties: orderData,
|
|
timestamp: new Date(),
|
|
}
|
|
|
|
segmentService.track(orderEvent)
|
|
}
|
|
)
|
|
|
|
eventBusService.subscribe("order.canceled", async ({ id }) => {
|
|
const order = await this.orderService_.retrieve(id, {
|
|
select: [
|
|
"shipping_total",
|
|
"discount_total",
|
|
"tax_total",
|
|
"refunded_total",
|
|
"gift_card_total",
|
|
"subtotal",
|
|
"total",
|
|
],
|
|
})
|
|
|
|
const date = new Date()
|
|
const orderData = await segmentService.buildOrder(order)
|
|
const orderEvent = {
|
|
event: "Order Cancelled",
|
|
userId: order.customer_id,
|
|
properties: orderData,
|
|
timestamp: date,
|
|
}
|
|
|
|
segmentService.track(orderEvent)
|
|
})
|
|
|
|
eventBusService.subscribe("order.placed", async ({ id }) => {
|
|
const order = await this.orderService_.retrieve(id, {
|
|
select: [
|
|
"shipping_total",
|
|
"discount_total",
|
|
"tax_total",
|
|
"refunded_total",
|
|
"gift_card_total",
|
|
"subtotal",
|
|
"total",
|
|
],
|
|
relations: [
|
|
"customer",
|
|
"billing_address",
|
|
"shipping_address",
|
|
"discounts",
|
|
"discounts.rule",
|
|
"shipping_methods",
|
|
"shipping_methods.shipping_option",
|
|
"payments",
|
|
"fulfillments",
|
|
"items",
|
|
"returns",
|
|
"gift_cards",
|
|
"gift_card_transactions",
|
|
"swaps",
|
|
"swaps.return_order",
|
|
"swaps.payment",
|
|
"swaps.shipping_methods",
|
|
"swaps.shipping_methods.shipping_option",
|
|
"swaps.shipping_address",
|
|
"swaps.additional_items",
|
|
"swaps.fulfillments",
|
|
],
|
|
})
|
|
|
|
const eventContext = {}
|
|
const integrations = {}
|
|
|
|
if (order.cart_id) {
|
|
try {
|
|
const cart = await this.cartService_.retrieve(order.cart_id, {
|
|
select: ["context"],
|
|
})
|
|
|
|
if (cart.context) {
|
|
if (cart.context.ip) {
|
|
eventContext.ip = cart.context.ip
|
|
}
|
|
|
|
if (cart.context.user_agent) {
|
|
eventContext.user_agent = cart.context.user_agent
|
|
}
|
|
|
|
if (segmentService.options_ && segmentService.options_.use_ga_id) {
|
|
if (cart.context.ga_id) {
|
|
integrations["Google Analytics"] = {
|
|
clientId: cart.context.ga_id,
|
|
}
|
|
}
|
|
}
|
|
}
|
|
} catch (err) {
|
|
console.log(err)
|
|
console.warn("Failed to gather context for order")
|
|
}
|
|
}
|
|
|
|
const orderData = await segmentService.buildOrder(order)
|
|
const orderEvent = {
|
|
event: "Order Completed",
|
|
userId: order.customer_id,
|
|
properties: orderData,
|
|
timestamp: order.created_at,
|
|
context: eventContext,
|
|
integrations,
|
|
}
|
|
|
|
segmentService.identify({
|
|
userId: order.customer_id,
|
|
traits: {
|
|
email: order.email,
|
|
firstName: order.shipping_address.first_name,
|
|
lastName: order.shipping_address.last_name,
|
|
},
|
|
})
|
|
|
|
segmentService.track(orderEvent)
|
|
})
|
|
}
|
|
}
|
|
|
|
export default OrderSubscriber
|