Files
medusa-store/packages/medusa-plugin-segment/src/services/segment.js
Sebastian Rindom c56660fca9 feat: new tax api (#979)
* feat: add tax calculation strategy (#885)

* feat: add tax calculation strategy

* fix: adds strategy loader

* fix: eslint ignore

* chore: cleanup

* fix: allow plugin overwrites

* fix: allow plugin overwrites

* fix: fake region

* Update packages/medusa/src/loaders/strategies.ts

Co-authored-by: Oliver Windall Juhl <59018053+olivermrbl@users.noreply.github.com>

Co-authored-by: Oliver Windall Juhl <59018053+olivermrbl@users.noreply.github.com>

* feat: adds tax related db entities + tax provider (#896)

* feat: adds tax related db entities + tax provider

* fix: add tax provider tests

* fix: add tax service unit tests

* fix: tests + migrations

* fix: add inherited tax lines

* chore: rm tax-line repo

* fix: test

* fix: pr comments

* fix: unit test

* feat: totals service to ts (#911)

* feat: adds tax related db entities + tax provider

* fix: add tax provider tests

* fix: add tax service unit tests

* fix: tests + migrations

* feat: totals service to ts

* fix: remove totals.js

* fix: add shipping methods

* fix: add inherited tax lines

* chore: rm tax-line repo

* fix: test

* fix: tests

* fix: tests

* fix: unit test

* fix: adds TotalsServiceProps

* feat: adds integration tests for automatic tax calculation + shipping tax rates (#945)

* feat: adds tax related db entities + tax provider

* fix: add tax provider tests

* fix: add tax service unit tests

* fix: tests + migrations

* feat: totals service to ts

* fix: remove totals.js

* fix: add shipping methods

* fix: add inherited tax lines

* chore: rm tax-line repo

* fix: test

* fix: tests

* fix: tests

* fix: unit test

* fix: integration test helpers

* fix: adds factories + tests automatic tax rates

* fix: remove verbose

* fix: adds TotalsServiceProps

* fix: add shipping tax lines

* fix: add migration for shipping taxes

* fix: integration tests for shipping taxes

* fix: integration tests for shipping taxes

* fix: jsdoc types

* Feat/manual taxes (#950)

* feat: adds tax related db entities + tax provider

* fix: add tax provider tests

* fix: add tax service unit tests

* fix: tests + migrations

* feat: totals service to ts

* fix: remove totals.js

* fix: add shipping methods

* fix: add inherited tax lines

* chore: rm tax-line repo

* fix: test

* fix: tests

* fix: tests

* fix: unit test

* fix: integration test helpers

* fix: adds factories + tests automatic tax rates

* fix: remove verbose

* fix: adds TotalsServiceProps

* fix: add shipping tax lines

* fix: add migration for shipping taxes

* fix: integration tests for shipping taxes

* fix: integration tests for shipping taxes

* fix: add integration tests for manual taxes

* fix: cart service - cleanup jsdoc

* feat: add /carts/id/taxes to manually calculate taxes

* feat: add integration tests for order tax calculations

* fix: unit tests

* fix: merge

* fix: rm verbose

* fix: unit tests

* fix: object -> cartOrOrder

* fix: rounding

* Feat/complete order w tax lines (#951)

* feat: adds tax related db entities + tax provider

* fix: add tax provider tests

* fix: add tax service unit tests

* fix: tests + migrations

* feat: totals service to ts

* fix: remove totals.js

* fix: add shipping methods

* fix: add inherited tax lines

* chore: rm tax-line repo

* fix: test

* fix: tests

* fix: tests

* fix: unit test

* fix: integration test helpers

* fix: adds factories + tests automatic tax rates

* fix: remove verbose

* fix: adds TotalsServiceProps

* fix: add shipping tax lines

* fix: add migration for shipping taxes

* fix: integration tests for shipping taxes

* fix: integration tests for shipping taxes

* fix: add integration tests for manual taxes

* fix: cart service - cleanup jsdoc

* feat: add /carts/id/taxes to manually calculate taxes

* feat: add integration tests for order tax calculations

* feat: adds cart completion strategy + create order w. tax lines

* fix: unit tests

* fix: merge

* fix: rm verbose

* fix: unit tests

* fix: unit tests

* fix: unit tests

* fix: ensure calculation for list orders

* fix: unit tests

* fix: integration tests

* fix: adds cart order type gaurds

* Docs/tax api (#954)

* feat: adds tax related db entities + tax provider

* fix: add tax provider tests

* fix: add tax service unit tests

* fix: tests + migrations

* feat: totals service to ts

* fix: remove totals.js

* fix: add shipping methods

* fix: add inherited tax lines

* chore: rm tax-line repo

* fix: test

* fix: tests

* fix: tests

* fix: unit test

* fix: integration test helpers

* fix: adds factories + tests automatic tax rates

* fix: remove verbose

* fix: adds TotalsServiceProps

* fix: add shipping tax lines

* fix: add migration for shipping taxes

* fix: integration tests for shipping taxes

* fix: integration tests for shipping taxes

* fix: add integration tests for manual taxes

* fix: cart service - cleanup jsdoc

* feat: add /carts/id/taxes to manually calculate taxes

* feat: add integration tests for order tax calculations

* feat: adds cart completion strategy + create order w. tax lines

* fix: unit tests

* fix: merge

* fix: rm verbose

* fix: unit tests

* fix: unit tests

* fix: unit tests

* fix: ensure calculation for list orders

* fix: unit tests

* fix: integration tests

* docs: documents tax related methods and types

* fix: require either item_id or shipping_method_id

* feat: product type tax rate (#969)

* feat: adds tax related db entities + tax provider

* fix: add tax provider tests

* fix: add tax service unit tests

* fix: tests + migrations

* feat: totals service to ts

* fix: remove totals.js

* fix: add shipping methods

* fix: add inherited tax lines

* chore: rm tax-line repo

* fix: test

* fix: tests

* fix: tests

* fix: unit test

* fix: integration test helpers

* fix: adds factories + tests automatic tax rates

* fix: remove verbose

* fix: adds TotalsServiceProps

* fix: add shipping tax lines

* fix: add migration for shipping taxes

* fix: integration tests for shipping taxes

* fix: integration tests for shipping taxes

* fix: add integration tests for manual taxes

* fix: cart service - cleanup jsdoc

* feat: add /carts/id/taxes to manually calculate taxes

* feat: add integration tests for order tax calculations

* feat: adds cart completion strategy + create order w. tax lines

* fix: unit tests

* fix: merge

* fix: rm verbose

* fix: unit tests

* fix: unit tests

* fix: unit tests

* fix: ensure calculation for list orders

* fix: unit tests

* fix: integration tests

* docs: documents tax related methods and types

* fix: require either item_id or shipping_method_id

* feat: adds returns tests for new tax system

* feat: adds return lines + integration tests for swaps

* feat: return integration tests

* feat: adds product type tax rates

* feat: add tax management endpoints

* fix: create single migration

* fix: adds tax rates to js client

* fix: strats

* Fix/plugin tests (#998)

* plugin testing setup

* fix: test sendgrid plugin

* fix: test sendgrid plugin

* chore: clean

* chore: clean

* fix: clean up tests

* fix: remove dirty import

* fix: sendgrid + brightpearl

* fix: plugin integration tests

* fix: klarna

* fix: shipping method tax

* fix: remove taxrates

* fix: unit tests

* fix: integration

* fix: integration

* fix: plugins tests

* fix: ignore plugins

* fix: tests

* fix: taxes (#1017)

* fix: taxes

* fix: taxes

* fix: faulty ref

* fix: create tax-lines with claim items

* fix: snapshot tax-liens

* fix: allows integration test teardown to force deleting tables

* fix: tests

* fix: merge

* fix: adds tax-rates to client

* fix: adds tax-rates to medusa-react

* fix: tests

* fix: tests

* fix: add product types

* fix: adds tax provider endpoint + cascaded deletes on tax rate relations

* fix: move errors to service layer

* fix: cleanup api

* fix: unit tests

* fix: error handler in base-service

* fix: Add order region to swap on createFulfillment (#1110)

Co-authored-by: Oliver Windall Juhl <59018053+olivermrbl@users.noreply.github.com>
2022-02-24 20:14:09 +01:00

185 lines
5.1 KiB
JavaScript

import Analytics from "analytics-node"
import axios from "axios"
import { BaseService } from "medusa-interfaces"
import { humanizeAmount } from "medusa-core-utils"
class SegmentService extends BaseService {
/**
* @param {Object} options - options defined in `medusa-config.js`
* e.g.
* {
* write_key: Segment write key given in Segment dashboard
* use_ga_id: If set to true the plugin will look for a ga_id in the cart
* context if present this id will be used as the Google Analytics
* client id.
* }
*/
constructor({ totalsService, productService }, options) {
super()
this.totalsService_ = totalsService
this.options_ = options
this.productService_ = productService
this.analytics_ = new Analytics(options.write_key)
}
/**
* Wrapper around segment's identify call
*/
identify(data) {
return this.analytics_.identify(data)
}
track(data) {
return this.analytics_.track(data)
}
async getReportingValue(rawCurrency, value) {
const fromCurrency = rawCurrency.toUpperCase()
const date = "latest"
const toCurrency =
(this.options_.reporting_currency &&
this.options_.reporting_currency.toUpperCase()) ||
"EUR"
if (fromCurrency === toCurrency) {
return this.rounded_(value)
}
const exchangeRate = await axios
.get(
`https://api.exchangeratesapi.io/${date}?symbols=${fromCurrency}&base=${toCurrency}&access_key=${this.options_.exchange_rates_api_key}`
)
.then(({ data }) => {
return data.rates[fromCurrency]
})
return this.rounded_(value / exchangeRate)
}
async buildOrder(order) {
const curr = order.currency_code
const subtotal = humanizeAmount(order.subtotal, curr)
const total = humanizeAmount(order.total, curr)
const tax = humanizeAmount(order.tax_total, curr)
const discount = humanizeAmount(order.discount_total, curr)
const shipping = humanizeAmount(order.shipping_total, curr)
const revenue = total - tax
let coupon
if (order.discounts && order.discounts.length) {
coupon = order.discounts[0] && order.discounts[0].code
}
const orderData = {
checkout_id: order.cart_id,
order_id: order.id,
email: order.email,
region_id: order.region_id,
payment_provider: order.payments.map((p) => p.provider_id).join(","),
shipping_methods: order.shipping_methods,
shipping_country: order.shipping_address.country_code,
shipping_city: order.shipping_address.city,
reporting_total: await this.getReportingValue(order.currency_code, total),
reporting_subtotal: await this.getReportingValue(
order.currency_code,
subtotal
),
reporting_revenue: await this.getReportingValue(
order.currency_code,
revenue
),
reporting_shipping: await this.getReportingValue(
order.currency_code,
shipping
),
reporting_tax: await this.getReportingValue(order.currency_code, tax),
reporting_discount: await this.getReportingValue(
order.currency_code,
discount
),
total,
subtotal,
revenue,
shipping,
tax,
discount,
coupon,
currency: order.currency_code.toUpperCase(),
products: await Promise.all(
order.items.map(async (item) => {
let name = item.title
const totals = await this.totalsService_.getLineItemTotals(
item,
order,
{
include_tax: true,
}
)
const lineTotal = totals.total - totals.tax_total
const revenue = await this.getReportingValue(
curr,
humanizeAmount(lineTotal, curr)
)
let sku = ""
let variant = ""
if (item.variant && item.variant.sku) {
let skuParts = item.variant.sku.split("-")
skuParts.pop()
sku = skuParts.join("-")
variant = item.variant.sku
}
const product = await this.productService_.retrieve(
item.variant.product_id,
{ relations: ["collection", "type"] }
)
const toReturn = {
name,
variant,
price: this.rounded_(
humanizeAmount(lineTotal, curr) / item.quantity
),
reporting_revenue: revenue,
product_id: item.variant.product_id,
category: product.collection?.title,
subtitle: product.subtitle,
type: product.type?.value,
sku,
quantity: item.quantity,
}
// If we are building a refund order include details about
// the reason for return
if (item.reason) {
toReturn.reason_id = item.reason.id
toReturn.reason_value = item.reason.value
}
if (item.note) {
toReturn.note = item.note
}
return toReturn
})
),
}
return orderData
}
rounded_(v) {
return Number(Math.round(v + "e2") + "e-2")
}
}
export default SegmentService