fix: merge develop
This commit is contained in:
@@ -2,25 +2,19 @@
|
||||
|
||||
/packages/medusa/src/services/cart.js
|
||||
/packages/medusa/src/services/claim-item.js
|
||||
/packages/medusa/src/services/customer.js
|
||||
/packages/medusa/src/services/draft-order.js
|
||||
/packages/medusa/src/services/event-bus.js
|
||||
/packages/medusa/src/services/fulfillment-provider.js
|
||||
/packages/medusa/src/services/idempotency-key.js
|
||||
/packages/medusa/src/services/inventory.js
|
||||
/packages/medusa/src/services/line-item.js
|
||||
/packages/medusa/src/services/middleware.js
|
||||
/packages/medusa/src/services/note.js
|
||||
/packages/medusa/src/services/notification.js
|
||||
/packages/medusa/src/services/oauth.js
|
||||
/packages/medusa/src/services/payment-provider.js
|
||||
/packages/medusa/src/services/product-collection.js
|
||||
/packages/medusa/src/services/product-variant.js
|
||||
/packages/medusa/src/services/product.js
|
||||
/packages/medusa/src/services/query-builder.js
|
||||
/packages/medusa/src/services/return-reason.js
|
||||
/packages/medusa/src/services/return.js
|
||||
/packages/medusa/src/services/shipping-option.js
|
||||
/packages/medusa/src/services/shipping-profile.js
|
||||
/packages/medusa/src/services/store.js
|
||||
/packages/medusa/src/services/swap.js
|
||||
|
||||
@@ -80,7 +80,6 @@ describe("/admin/orders", () => {
|
||||
await adminSeeder(dbConnection)
|
||||
await orderSeeder(dbConnection)
|
||||
await swapSeeder(dbConnection)
|
||||
await claimSeeder(dbConnection)
|
||||
} catch (err) {
|
||||
console.log(err)
|
||||
throw err
|
||||
@@ -223,6 +222,48 @@ describe("/admin/orders", () => {
|
||||
})
|
||||
})
|
||||
|
||||
describe("POST /admin/orders/:id/swaps", () => {
|
||||
beforeEach(async () => {
|
||||
try {
|
||||
await adminSeeder(dbConnection)
|
||||
await orderSeeder(dbConnection)
|
||||
await claimSeeder(dbConnection)
|
||||
} catch (err) {
|
||||
console.log(err)
|
||||
throw err
|
||||
}
|
||||
})
|
||||
|
||||
afterEach(async () => {
|
||||
const db = useDb()
|
||||
await db.teardown()
|
||||
})
|
||||
|
||||
it("creates a swap on a claim", async () => {
|
||||
const api = useApi()
|
||||
|
||||
const swapOnSwap = await api.post(
|
||||
"/admin/orders/order-with-claim/swaps",
|
||||
{
|
||||
return_items: [
|
||||
{
|
||||
item_id: "test-item-co-2",
|
||||
quantity: 1,
|
||||
},
|
||||
],
|
||||
additional_items: [{ variant_id: "test-variant", quantity: 1 }],
|
||||
},
|
||||
{
|
||||
headers: {
|
||||
authorization: "Bearer test_token",
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
expect(swapOnSwap.status).toEqual(200)
|
||||
})
|
||||
})
|
||||
|
||||
describe("POST /admin/orders/:id/claims", () => {
|
||||
beforeEach(async () => {
|
||||
try {
|
||||
@@ -318,6 +359,43 @@ describe("/admin/orders", () => {
|
||||
)
|
||||
})
|
||||
|
||||
it("creates a claim on a claim", async () => {
|
||||
const api = useApi()
|
||||
|
||||
const claimOnClaim = await api
|
||||
.post(
|
||||
"/admin/orders/order-with-claim/claims",
|
||||
{
|
||||
type: "replace",
|
||||
claim_items: [
|
||||
{
|
||||
item_id: "test-item-co-2",
|
||||
quantity: 1,
|
||||
reason: "production_failure",
|
||||
tags: ["fluff"],
|
||||
images: ["https://test.image.com"],
|
||||
},
|
||||
],
|
||||
additional_items: [
|
||||
{
|
||||
variant_id: "test-variant",
|
||||
quantity: 1,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
headers: {
|
||||
authorization: "Bearer test_token",
|
||||
},
|
||||
}
|
||||
)
|
||||
.catch((err) => {
|
||||
console.log(err)
|
||||
})
|
||||
|
||||
expect(claimOnClaim.status).toEqual(200)
|
||||
})
|
||||
|
||||
it("creates a claim with a shipping address", async () => {
|
||||
const api = useApi()
|
||||
|
||||
@@ -841,6 +919,61 @@ describe("/admin/orders", () => {
|
||||
})
|
||||
})
|
||||
|
||||
describe("POST /admin/orders/:id/claims", () => {
|
||||
beforeEach(async () => {
|
||||
try {
|
||||
await adminSeeder(dbConnection)
|
||||
await orderSeeder(dbConnection)
|
||||
await swapSeeder(dbConnection)
|
||||
} catch (err) {
|
||||
console.log(err)
|
||||
throw err
|
||||
}
|
||||
})
|
||||
|
||||
afterEach(async () => {
|
||||
const db = useDb()
|
||||
await db.teardown()
|
||||
})
|
||||
|
||||
it("creates a claim on a swap", async () => {
|
||||
const api = useApi()
|
||||
|
||||
const claimOnClaim = await api
|
||||
.post(
|
||||
"/admin/orders/order-with-swap/claims",
|
||||
{
|
||||
type: "replace",
|
||||
claim_items: [
|
||||
{
|
||||
item_id: "return-item-1",
|
||||
quantity: 1,
|
||||
reason: "production_failure",
|
||||
tags: ["fluff"],
|
||||
images: ["https://test.image.com"],
|
||||
},
|
||||
],
|
||||
additional_items: [
|
||||
{
|
||||
variant_id: "test-variant",
|
||||
quantity: 1,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
headers: {
|
||||
authorization: "Bearer test_token",
|
||||
},
|
||||
}
|
||||
)
|
||||
.catch((err) => {
|
||||
console.log(err)
|
||||
})
|
||||
|
||||
expect(claimOnClaim.status).toEqual(200)
|
||||
})
|
||||
})
|
||||
|
||||
describe("POST /admin/orders/:id/return", () => {
|
||||
let rrId
|
||||
beforeEach(async () => {
|
||||
|
||||
@@ -16,20 +16,3 @@ Object {
|
||||
"updated_at": Any<String>,
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`/admin/discounts creates store session correctly 1`] = `
|
||||
Object {
|
||||
"billing_address_id": null,
|
||||
"created_at": Any<String>,
|
||||
"deleted_at": null,
|
||||
"email": "test@testesen.dk",
|
||||
"first_name": "test",
|
||||
"has_account": true,
|
||||
"id": Any<String>,
|
||||
"last_name": "testesen",
|
||||
"metadata": null,
|
||||
"orders": Array [],
|
||||
"phone": "12345678",
|
||||
"updated_at": Any<String>,
|
||||
}
|
||||
`;
|
||||
|
||||
@@ -159,7 +159,7 @@ describe("/store/carts", () => {
|
||||
expect.assertions(2)
|
||||
const api = useApi()
|
||||
|
||||
let response = await api
|
||||
await api
|
||||
.post("/store/carts/test-cart", {
|
||||
discounts: [{ code: "SPENT" }],
|
||||
})
|
||||
|
||||
@@ -150,6 +150,17 @@ module.exports = async (connection, data = {}) => {
|
||||
|
||||
await manager.save(d)
|
||||
|
||||
const usedDiscount = manager.create(Discount, {
|
||||
id: "used-discount",
|
||||
code: "USED",
|
||||
is_dynamic: false,
|
||||
is_disabled: false,
|
||||
usage_limit: 1,
|
||||
usage_count: 1,
|
||||
})
|
||||
|
||||
await manager.save(usedDiscount)
|
||||
|
||||
const expiredRule = manager.create(DiscountRule, {
|
||||
id: "expiredRule",
|
||||
description: "expired rule",
|
||||
|
||||
@@ -8,15 +8,15 @@
|
||||
"build": "babel src -d dist --extensions \".ts,.js\""
|
||||
},
|
||||
"dependencies": {
|
||||
"@medusajs/medusa": "1.1.41-dev-1634220658423",
|
||||
"medusa-interfaces": "1.1.23-dev-1634220658423",
|
||||
"@medusajs/medusa": "1.1.41-dev-1634316075104",
|
||||
"medusa-interfaces": "1.1.23-dev-1634316075104",
|
||||
"typeorm": "^0.2.31"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/cli": "^7.12.10",
|
||||
"@babel/core": "^7.12.10",
|
||||
"@babel/node": "^7.12.10",
|
||||
"babel-preset-medusa-package": "1.1.15-dev-1634220658423",
|
||||
"babel-preset-medusa-package": "1.1.15-dev-1634316075104",
|
||||
"jest": "^26.6.3"
|
||||
}
|
||||
}
|
||||
|
||||
+1409
-1462
File diff suppressed because it is too large
Load Diff
@@ -1,88 +0,0 @@
|
||||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports["default"] = void 0;
|
||||
|
||||
var _medusaInterfaces = require("medusa-interfaces");
|
||||
|
||||
function _instanceof(left, right) { if (right != null && typeof Symbol !== "undefined" && right[Symbol.hasInstance]) { return !!right[Symbol.hasInstance](left); } else { return left instanceof right; } }
|
||||
|
||||
function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
|
||||
|
||||
function _classCallCheck(instance, Constructor) { if (!_instanceof(instance, Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
||||
|
||||
function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
|
||||
|
||||
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
|
||||
|
||||
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); }
|
||||
|
||||
function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
|
||||
|
||||
function _createSuper(Derived) { return function () { var Super = _getPrototypeOf(Derived), result; if (_isNativeReflectConstruct()) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }
|
||||
|
||||
function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } return _assertThisInitialized(self); }
|
||||
|
||||
function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; }
|
||||
|
||||
function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } }
|
||||
|
||||
function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }
|
||||
|
||||
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
||||
|
||||
var ManualFulfillmentService = /*#__PURE__*/function (_FulfillmentService) {
|
||||
_inherits(ManualFulfillmentService, _FulfillmentService);
|
||||
|
||||
var _super = _createSuper(ManualFulfillmentService);
|
||||
|
||||
function ManualFulfillmentService() {
|
||||
_classCallCheck(this, ManualFulfillmentService);
|
||||
|
||||
return _super.call(this);
|
||||
}
|
||||
|
||||
_createClass(ManualFulfillmentService, [{
|
||||
key: "getFulfillmentOptions",
|
||||
value: function getFulfillmentOptions() {
|
||||
return [{
|
||||
id: "manual-fulfillment"
|
||||
}];
|
||||
}
|
||||
}, {
|
||||
key: "validateFulfillmentData",
|
||||
value: function validateFulfillmentData(data, cart) {
|
||||
return data;
|
||||
}
|
||||
}, {
|
||||
key: "validateOption",
|
||||
value: function validateOption(data) {
|
||||
return true;
|
||||
}
|
||||
}, {
|
||||
key: "canCalculate",
|
||||
value: function canCalculate() {
|
||||
return false;
|
||||
}
|
||||
}, {
|
||||
key: "calculatePrice",
|
||||
value: function calculatePrice() {
|
||||
throw Error("Manual Fulfillment service cannot calculatePrice");
|
||||
}
|
||||
}, {
|
||||
key: "createOrder",
|
||||
value: function createOrder() {
|
||||
// No data is being sent anywhere
|
||||
return;
|
||||
}
|
||||
}]);
|
||||
|
||||
return ManualFulfillmentService;
|
||||
}(_medusaInterfaces.FulfillmentService);
|
||||
|
||||
_defineProperty(ManualFulfillmentService, "identifier", "manual");
|
||||
|
||||
var _default = ManualFulfillmentService;
|
||||
exports["default"] = _default;
|
||||
@@ -0,0 +1,10 @@
|
||||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.ContentfulMock = void 0;
|
||||
var ContentfulMock = {
|
||||
createClient: jest.fn()
|
||||
};
|
||||
exports.ContentfulMock = ContentfulMock;
|
||||
@@ -0,0 +1,6 @@
|
||||
export const createClient = jest.fn()
|
||||
const mock = jest.fn().mockImplementation(() => {
|
||||
return { createClient }
|
||||
})
|
||||
|
||||
export default mock
|
||||
@@ -0,0 +1,179 @@
|
||||
import ContentfulService from "../contentful"
|
||||
|
||||
describe("ContentfulService", () => {
|
||||
describe("delete in medusa", () => {
|
||||
const regionService = {
|
||||
retrieve: jest.fn((id) => {
|
||||
if (id === "exists") {
|
||||
return Promise.resolve({ id: "exists" })
|
||||
}
|
||||
return Promise.resolve(undefined)
|
||||
}),
|
||||
}
|
||||
const productService = {
|
||||
retrieve: jest.fn((id) => {
|
||||
if (id === "exists") {
|
||||
return Promise.resolve({ id: "exists" })
|
||||
}
|
||||
return Promise.resolve(undefined)
|
||||
}),
|
||||
}
|
||||
const redisClient = {
|
||||
get: async (id) => {
|
||||
// const key = `${id}_ignore_${side}`
|
||||
if (id === `ignored_ignore_contentful`) {
|
||||
return { id }
|
||||
}
|
||||
return undefined
|
||||
},
|
||||
set: async (id) => {
|
||||
return undefined
|
||||
},
|
||||
}
|
||||
const productVariantService = {
|
||||
retrieve: jest.fn((id) => {
|
||||
if (id === "exists") {
|
||||
return Promise.resolve({ id: "exists" })
|
||||
}
|
||||
return Promise.resolve(undefined)
|
||||
}),
|
||||
}
|
||||
const eventBusService = {}
|
||||
|
||||
const service = new ContentfulService(
|
||||
{
|
||||
regionService,
|
||||
productService,
|
||||
redisClient,
|
||||
productVariantService,
|
||||
eventBusService,
|
||||
},
|
||||
{
|
||||
space_id: "test_id",
|
||||
environment: "master",
|
||||
access_token: "test_token",
|
||||
}
|
||||
)
|
||||
|
||||
const entry = {
|
||||
unpublish: jest.fn(async () => {
|
||||
return {
|
||||
id: "id",
|
||||
}
|
||||
}),
|
||||
archive: jest.fn(async () => {
|
||||
return {
|
||||
id: "id",
|
||||
}
|
||||
}),
|
||||
}
|
||||
|
||||
service.contentful_ = {
|
||||
getSpace: async (space_id) => {
|
||||
return {
|
||||
getEnvironment: async (env) => {
|
||||
return {
|
||||
getEntry: async (id) => {
|
||||
if (id === "onlyMedusa") {
|
||||
throw new Error("doesn't exist")
|
||||
}
|
||||
return entry
|
||||
},
|
||||
}
|
||||
},
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
beforeEach(() => {
|
||||
jest.clearAllMocks()
|
||||
})
|
||||
|
||||
describe("archiveProductInContentful", () => {
|
||||
it("Calls entry.unpublish and entry.archive", async () => {
|
||||
await service.archiveProductInContentful({ id: "test" })
|
||||
|
||||
expect(entry.unpublish).toHaveBeenCalledTimes(1)
|
||||
expect(entry.archive).toHaveBeenCalledTimes(1)
|
||||
})
|
||||
|
||||
it("Doesn't call entry.unpublish and entry.archive if the product still exists in medusa", async () => {
|
||||
await service.archiveProductInContentful({ id: "exists" })
|
||||
|
||||
expect(entry.unpublish).toHaveBeenCalledTimes(0)
|
||||
expect(entry.archive).toHaveBeenCalledTimes(0)
|
||||
})
|
||||
|
||||
it("Doesn't call productService if request should be ignored", async () => {
|
||||
await service.archiveProductInContentful({ id: "ignored" })
|
||||
|
||||
expect(productService.retrieve).toHaveBeenCalledTimes(0)
|
||||
expect(entry.unpublish).toHaveBeenCalledTimes(0)
|
||||
expect(entry.archive).toHaveBeenCalledTimes(0)
|
||||
})
|
||||
})
|
||||
|
||||
describe("archiveProductVariantInContentful", () => {
|
||||
it("Calls entry.unpublish and entry.archive", async () => {
|
||||
await service.archiveProductVariantInContentful({ id: "test" })
|
||||
|
||||
expect(entry.unpublish).toHaveBeenCalledTimes(1)
|
||||
expect(entry.archive).toHaveBeenCalledTimes(1)
|
||||
})
|
||||
|
||||
it("Doesn't call entry.unpublish and entry.archive if the variant still exists in medusa", async () => {
|
||||
await service.archiveProductVariantInContentful({ id: "exists" })
|
||||
|
||||
expect(entry.unpublish).toHaveBeenCalledTimes(0)
|
||||
expect(entry.archive).toHaveBeenCalledTimes(0)
|
||||
})
|
||||
|
||||
it("Doesn't call productVariantService if request should be ignored", async () => {
|
||||
await service.archiveProductVariantInContentful({ id: "ignored" })
|
||||
|
||||
expect(productVariantService.retrieve).toHaveBeenCalledTimes(0)
|
||||
expect(entry.unpublish).toHaveBeenCalledTimes(0)
|
||||
expect(entry.archive).toHaveBeenCalledTimes(0)
|
||||
})
|
||||
})
|
||||
|
||||
describe("archiveRegionInContentful", () => {
|
||||
it("Calls entry.unpublish and entry.archive", async () => {
|
||||
await service.archiveRegionInContentful({ id: "test" })
|
||||
|
||||
expect(entry.unpublish).toHaveBeenCalledTimes(1)
|
||||
expect(entry.archive).toHaveBeenCalledTimes(1)
|
||||
})
|
||||
|
||||
it("Doesn't call entry.unpublish and entry.archive if the region still exists in medusa", async () => {
|
||||
await service.archiveRegionInContentful({ id: "exists" })
|
||||
|
||||
expect(entry.unpublish).toHaveBeenCalledTimes(0)
|
||||
expect(entry.archive).toHaveBeenCalledTimes(0)
|
||||
})
|
||||
|
||||
it("Doesn't call RegionService if request should be ignored", async () => {
|
||||
await service.archiveRegionInContentful({ id: "ignored" })
|
||||
|
||||
expect(regionService.retrieve).toHaveBeenCalledTimes(0)
|
||||
expect(entry.unpublish).toHaveBeenCalledTimes(0)
|
||||
expect(entry.archive).toHaveBeenCalledTimes(0)
|
||||
})
|
||||
})
|
||||
|
||||
describe("archiveEntryWidthId", () => {
|
||||
it("Calls archive if entry exists", async () => {
|
||||
await service.archiveEntryWidthId("exists")
|
||||
|
||||
expect(entry.unpublish).toHaveBeenCalledTimes(1)
|
||||
expect(entry.archive).toHaveBeenCalledTimes(1)
|
||||
})
|
||||
it("Doesnt call archive if entry doesn't exists", async () => {
|
||||
await service.archiveEntryWidthId("onlyMedusa")
|
||||
|
||||
expect(entry.unpublish).toHaveBeenCalledTimes(0)
|
||||
expect(entry.archive).toHaveBeenCalledTimes(0)
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
@@ -91,7 +91,7 @@ class ContentfulService extends BaseService {
|
||||
async createImageAssets(product) {
|
||||
const environment = await this.getContentfulEnvironment_()
|
||||
|
||||
let assets = []
|
||||
const assets = []
|
||||
await Promise.all(
|
||||
product.images
|
||||
.filter((image) => image.url !== product.thumbnail)
|
||||
@@ -646,6 +646,92 @@ class ContentfulService extends BaseService {
|
||||
}
|
||||
}
|
||||
|
||||
async archiveProductVariantInContentful(variant) {
|
||||
let variantEntity
|
||||
try {
|
||||
const ignore = await this.shouldIgnore_(variant.id, "contentful")
|
||||
if (ignore) {
|
||||
return Promise.resolve()
|
||||
}
|
||||
|
||||
try {
|
||||
variantEntity = await this.productVariantService_.retrieve(variant.id)
|
||||
} catch (err) {
|
||||
// ignore
|
||||
}
|
||||
|
||||
if (variantEntity) {
|
||||
return Promise.resolve()
|
||||
}
|
||||
|
||||
return await this.archiveEntryWidthId(variant.id)
|
||||
} catch (error) {
|
||||
throw error
|
||||
}
|
||||
}
|
||||
|
||||
async archiveProductInContentful(product) {
|
||||
let productEntity
|
||||
try {
|
||||
const ignore = await this.shouldIgnore_(product.id, "contentful")
|
||||
if (ignore) {
|
||||
return Promise.resolve()
|
||||
}
|
||||
|
||||
try {
|
||||
productEntity = await this.productService_.retrieve(product.id)
|
||||
} catch (err) {}
|
||||
|
||||
if (productEntity) {
|
||||
return Promise.resolve()
|
||||
}
|
||||
|
||||
return await this.archiveEntryWidthId(product.id)
|
||||
} catch (error) {
|
||||
throw error
|
||||
}
|
||||
}
|
||||
|
||||
async archiveRegionInContentful(region) {
|
||||
let regionEntity
|
||||
try {
|
||||
const ignore = await this.shouldIgnore_(region.id, "contentful")
|
||||
if (ignore) {
|
||||
return Promise.resolve()
|
||||
}
|
||||
|
||||
try {
|
||||
regionEntity = await this.regionService_.retrieve(region.id)
|
||||
} catch (err) {}
|
||||
|
||||
if (regionEntity) {
|
||||
return Promise.resolve()
|
||||
}
|
||||
|
||||
return await this.archiveEntryWidthId(region.id)
|
||||
} catch (error) {
|
||||
throw error
|
||||
}
|
||||
}
|
||||
|
||||
async archiveEntryWidthId(id) {
|
||||
const environment = await this.getContentfulEnvironment_()
|
||||
// check if product exists
|
||||
let entry = undefined
|
||||
try {
|
||||
entry = await environment.getEntry(id)
|
||||
} catch (error) {
|
||||
return Promise.resolve()
|
||||
}
|
||||
|
||||
const unpublishEntry = await entry.unpublish()
|
||||
const archivedEntry = await entry.archive()
|
||||
|
||||
await this.addIgnore_(id, "medusa")
|
||||
|
||||
return archivedEntry
|
||||
}
|
||||
|
||||
async sendContentfulProductToAdmin(productId) {
|
||||
const ignore = await this.shouldIgnore_(productId, "medusa")
|
||||
if (ignore) {
|
||||
@@ -658,7 +744,7 @@ class ContentfulService extends BaseService {
|
||||
|
||||
const product = await this.productService_.retrieve(productId)
|
||||
|
||||
let update = {}
|
||||
const update = {}
|
||||
|
||||
const title =
|
||||
productEntry.fields[this.getCustomField("title", "product")]["en-US"]
|
||||
@@ -741,9 +827,9 @@ class ContentfulService extends BaseService {
|
||||
isArray = false
|
||||
}
|
||||
|
||||
let output = []
|
||||
const output = []
|
||||
for (const obj of input) {
|
||||
let transformed = Object.assign({}, obj)
|
||||
const transformed = Object.assign({}, obj)
|
||||
transformed.medusaId = obj.id
|
||||
output.push(transformed)
|
||||
}
|
||||
|
||||
@@ -18,10 +18,18 @@ class ContentfulSubscriber {
|
||||
await this.contentfulService_.updateRegionInContentful(data)
|
||||
})
|
||||
|
||||
this.eventBus_.subscribe("region.deleted", async (data) => {
|
||||
await this.contentfulService_.updateRegionInContentful(data)
|
||||
})
|
||||
|
||||
this.eventBus_.subscribe("product-variant.updated", async (data) => {
|
||||
await this.contentfulService_.updateProductVariantInContentful(data)
|
||||
})
|
||||
|
||||
this.eventBus_.subscribe("product-variant.deleted", async (data) => {
|
||||
await this.contentfulService_.archiveProductVariantInContentful(data)
|
||||
})
|
||||
|
||||
this.eventBus_.subscribe("product.updated", async (data) => {
|
||||
await this.contentfulService_.updateProductInContentful(data)
|
||||
})
|
||||
@@ -29,6 +37,10 @@ class ContentfulSubscriber {
|
||||
this.eventBus_.subscribe("product.created", async (data) => {
|
||||
await this.contentfulService_.createProductInContentful(data)
|
||||
})
|
||||
|
||||
this.eventBus_.subscribe("product.deleted", async (data) => {
|
||||
await this.contentfulService_.archiveProductInContentful(data)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -27,6 +27,7 @@ const defaultRelations = [
|
||||
"claims.additional_items",
|
||||
"claims.fulfillments",
|
||||
"claims.claim_items",
|
||||
"claims.claim_items.item",
|
||||
"claims.claim_items.images",
|
||||
"swaps",
|
||||
"swaps.return_order",
|
||||
@@ -56,6 +57,7 @@ const defaultFields = [
|
||||
"metadata",
|
||||
"items.refundable",
|
||||
"swaps.additional_items.refundable",
|
||||
"claims.additional_items.refundable",
|
||||
"shipping_total",
|
||||
"discount_total",
|
||||
"tax_total",
|
||||
|
||||
@@ -241,6 +241,7 @@ export const defaultRelations = [
|
||||
"claims.additional_items",
|
||||
"claims.fulfillments",
|
||||
"claims.claim_items",
|
||||
"claims.claim_items.item",
|
||||
"claims.claim_items.images",
|
||||
// "claims.claim_items.tags",
|
||||
"swaps",
|
||||
@@ -271,6 +272,7 @@ export const defaultFields = [
|
||||
"metadata",
|
||||
"items.refundable",
|
||||
"swaps.additional_items.refundable",
|
||||
"claims.additional_items.refundable",
|
||||
"shipping_total",
|
||||
"discount_total",
|
||||
"tax_total",
|
||||
|
||||
@@ -6,29 +6,29 @@ import { MedusaError } from "medusa-core-utils"
|
||||
|
||||
const eventBusService = {
|
||||
emit: jest.fn(),
|
||||
withTransaction: function() {
|
||||
withTransaction: function () {
|
||||
return this
|
||||
},
|
||||
}
|
||||
|
||||
describe("CartService", () => {
|
||||
const totalsService = {
|
||||
getTotal: o => {
|
||||
getTotal: (o) => {
|
||||
return o.total || 0
|
||||
},
|
||||
getSubtotal: o => {
|
||||
getSubtotal: (o) => {
|
||||
return o.subtotal || 0
|
||||
},
|
||||
getTaxTotal: o => {
|
||||
getTaxTotal: (o) => {
|
||||
return o.tax_total || 0
|
||||
},
|
||||
getDiscountTotal: o => {
|
||||
getDiscountTotal: (o) => {
|
||||
return o.discount_total || 0
|
||||
},
|
||||
getShippingTotal: o => {
|
||||
getShippingTotal: (o) => {
|
||||
return o.shipping_total || 0
|
||||
},
|
||||
getGiftCardTotal: o => {
|
||||
getGiftCardTotal: (o) => {
|
||||
return o.gift_card_total || 0
|
||||
},
|
||||
}
|
||||
@@ -117,7 +117,7 @@ describe("CartService", () => {
|
||||
|
||||
describe("deleteMetadata", () => {
|
||||
const cartRepository = MockRepository({
|
||||
findOne: id => {
|
||||
findOne: (id) => {
|
||||
if (id === "empty") {
|
||||
return Promise.resolve({
|
||||
metadata: {},
|
||||
@@ -200,7 +200,7 @@ describe("CartService", () => {
|
||||
},
|
||||
}
|
||||
|
||||
const addressRepository = MockRepository({ create: c => c })
|
||||
const addressRepository = MockRepository({ create: (c) => c })
|
||||
const cartRepository = MockRepository()
|
||||
const customerService = {
|
||||
retrieveByEmail: jest.fn().mockReturnValue(
|
||||
@@ -209,7 +209,7 @@ describe("CartService", () => {
|
||||
email: "email@test.com",
|
||||
})
|
||||
),
|
||||
withTransaction: function() {
|
||||
withTransaction: function () {
|
||||
return this
|
||||
},
|
||||
}
|
||||
@@ -317,14 +317,14 @@ describe("CartService", () => {
|
||||
const lineItemService = {
|
||||
update: jest.fn(),
|
||||
create: jest.fn(),
|
||||
withTransaction: function() {
|
||||
withTransaction: function () {
|
||||
return this
|
||||
},
|
||||
}
|
||||
|
||||
const shippingOptionService = {
|
||||
deleteShippingMethod: jest.fn(),
|
||||
withTransaction: function() {
|
||||
withTransaction: function () {
|
||||
return this
|
||||
},
|
||||
}
|
||||
@@ -505,7 +505,7 @@ describe("CartService", () => {
|
||||
const lineItemService = {
|
||||
delete: jest.fn(),
|
||||
update: jest.fn(),
|
||||
withTransaction: function() {
|
||||
withTransaction: function () {
|
||||
return this
|
||||
},
|
||||
}
|
||||
@@ -547,7 +547,7 @@ describe("CartService", () => {
|
||||
|
||||
const shippingOptionService = {
|
||||
deleteShippingMethod: jest.fn(),
|
||||
withTransaction: function() {
|
||||
withTransaction: function () {
|
||||
return this
|
||||
},
|
||||
}
|
||||
@@ -666,7 +666,7 @@ describe("CartService", () => {
|
||||
describe("updateLineItem", () => {
|
||||
const lineItemService = {
|
||||
update: jest.fn(),
|
||||
withTransaction: function() {
|
||||
withTransaction: function () {
|
||||
return this
|
||||
},
|
||||
}
|
||||
@@ -674,7 +674,7 @@ describe("CartService", () => {
|
||||
...InventoryServiceMock,
|
||||
confirmInventory: jest
|
||||
.fn()
|
||||
.mockImplementation(id => id !== IdMap.getId("cannot-cover")),
|
||||
.mockImplementation((id) => id !== IdMap.getId("cannot-cover")),
|
||||
}
|
||||
|
||||
const cartRepository = MockRepository({
|
||||
@@ -747,7 +747,7 @@ describe("CartService", () => {
|
||||
|
||||
describe("updateEmail", () => {
|
||||
const customerService = {
|
||||
retrieveByEmail: jest.fn().mockImplementation(email => {
|
||||
retrieveByEmail: jest.fn().mockImplementation((email) => {
|
||||
if (email === "no@mail.com") {
|
||||
return Promise.reject()
|
||||
}
|
||||
@@ -756,13 +756,13 @@ describe("CartService", () => {
|
||||
email,
|
||||
})
|
||||
}),
|
||||
create: jest.fn().mockImplementation(data =>
|
||||
create: jest.fn().mockImplementation((data) =>
|
||||
Promise.resolve({
|
||||
id: IdMap.getId("newCus"),
|
||||
email: data.email,
|
||||
})
|
||||
),
|
||||
withTransaction: function() {
|
||||
withTransaction: function () {
|
||||
return this
|
||||
},
|
||||
}
|
||||
@@ -847,7 +847,7 @@ describe("CartService", () => {
|
||||
}),
|
||||
})
|
||||
|
||||
const addressRepository = MockRepository({ create: c => c })
|
||||
const addressRepository = MockRepository({ create: (c) => c })
|
||||
|
||||
const cartService = new CartService({
|
||||
manager: MockManager,
|
||||
@@ -908,7 +908,7 @@ describe("CartService", () => {
|
||||
region: { countries: [{ iso_2: "us" }] },
|
||||
}),
|
||||
})
|
||||
const addressRepository = MockRepository({ create: c => c })
|
||||
const addressRepository = MockRepository({ create: (c) => c })
|
||||
|
||||
const cartService = new CartService({
|
||||
manager: MockManager,
|
||||
@@ -982,15 +982,15 @@ describe("CartService", () => {
|
||||
|
||||
describe("setRegion", () => {
|
||||
const lineItemService = {
|
||||
update: jest.fn(r => r),
|
||||
update: jest.fn((r) => r),
|
||||
delete: jest.fn(),
|
||||
withTransaction: function() {
|
||||
withTransaction: function () {
|
||||
return this
|
||||
},
|
||||
}
|
||||
const addressRepository = MockRepository({ create: c => c })
|
||||
const addressRepository = MockRepository({ create: (c) => c })
|
||||
const productVariantService = {
|
||||
getRegionPrice: jest.fn().mockImplementation(id => {
|
||||
getRegionPrice: jest.fn().mockImplementation((id) => {
|
||||
if (id === IdMap.getId("fail")) {
|
||||
return Promise.reject()
|
||||
}
|
||||
@@ -1034,7 +1034,7 @@ describe("CartService", () => {
|
||||
deleteSession: jest.fn(),
|
||||
updateSession: jest.fn(),
|
||||
createSession: jest.fn(),
|
||||
withTransaction: function() {
|
||||
withTransaction: function () {
|
||||
return this
|
||||
},
|
||||
}
|
||||
@@ -1238,7 +1238,7 @@ describe("CartService", () => {
|
||||
deleteSession: jest.fn(),
|
||||
updateSession: jest.fn(),
|
||||
createSession: jest.fn(),
|
||||
withTransaction: function() {
|
||||
withTransaction: function () {
|
||||
return this
|
||||
},
|
||||
}
|
||||
@@ -1352,7 +1352,7 @@ describe("CartService", () => {
|
||||
const buildCart = (id, config = {}) => {
|
||||
return {
|
||||
id: IdMap.getId(id),
|
||||
items: (config.items || []).map(i => ({
|
||||
items: (config.items || []).map((i) => ({
|
||||
id: IdMap.getId(i.id),
|
||||
variant: {
|
||||
product: {
|
||||
@@ -1360,7 +1360,7 @@ describe("CartService", () => {
|
||||
},
|
||||
},
|
||||
})),
|
||||
shipping_methods: (config.shipping_methods || []).map(m => ({
|
||||
shipping_methods: (config.shipping_methods || []).map((m) => ({
|
||||
id: IdMap.getId(m.id),
|
||||
shipping_option: {
|
||||
profile_id: IdMap.getId(m.profile),
|
||||
@@ -1396,12 +1396,12 @@ describe("CartService", () => {
|
||||
|
||||
const lineItemService = {
|
||||
update: jest.fn(),
|
||||
withTransaction: function() {
|
||||
withTransaction: function () {
|
||||
return this
|
||||
},
|
||||
}
|
||||
const shippingOptionService = {
|
||||
createShippingMethod: jest.fn().mockImplementation(id => {
|
||||
createShippingMethod: jest.fn().mockImplementation((id) => {
|
||||
return Promise.resolve({
|
||||
shipping_option: {
|
||||
profile_id: id,
|
||||
@@ -1409,7 +1409,7 @@ describe("CartService", () => {
|
||||
})
|
||||
}),
|
||||
deleteShippingMethod: jest.fn(),
|
||||
withTransaction: function() {
|
||||
withTransaction: function () {
|
||||
return this
|
||||
},
|
||||
}
|
||||
@@ -1453,9 +1453,11 @@ describe("CartService", () => {
|
||||
IdMap.getId("option"),
|
||||
data
|
||||
)
|
||||
expect(
|
||||
shippingOptionService.createShippingMethod
|
||||
).toHaveBeenCalledWith(IdMap.getId("option"), data, { cart: cart1 })
|
||||
expect(shippingOptionService.createShippingMethod).toHaveBeenCalledWith(
|
||||
IdMap.getId("option"),
|
||||
data,
|
||||
{ cart: cart1 }
|
||||
)
|
||||
})
|
||||
|
||||
it("successfully overrides existing profile shipping method", async () => {
|
||||
@@ -1467,9 +1469,11 @@ describe("CartService", () => {
|
||||
IdMap.getId("profile1"),
|
||||
data
|
||||
)
|
||||
expect(
|
||||
shippingOptionService.createShippingMethod
|
||||
).toHaveBeenCalledWith(IdMap.getId("profile1"), data, { cart: cart2 })
|
||||
expect(shippingOptionService.createShippingMethod).toHaveBeenCalledWith(
|
||||
IdMap.getId("profile1"),
|
||||
data,
|
||||
{ cart: cart2 }
|
||||
)
|
||||
expect(shippingOptionService.deleteShippingMethod).toHaveBeenCalledWith({
|
||||
id: IdMap.getId("ship1"),
|
||||
shipping_option: {
|
||||
@@ -1495,9 +1499,11 @@ describe("CartService", () => {
|
||||
expect(shippingOptionService.createShippingMethod).toHaveBeenCalledTimes(
|
||||
1
|
||||
)
|
||||
expect(
|
||||
shippingOptionService.createShippingMethod
|
||||
).toHaveBeenCalledWith(IdMap.getId("additional"), data, { cart: cart2 })
|
||||
expect(shippingOptionService.createShippingMethod).toHaveBeenCalledWith(
|
||||
IdMap.getId("additional"),
|
||||
data,
|
||||
{ cart: cart2 }
|
||||
)
|
||||
})
|
||||
|
||||
it("updates item shipping", async () => {
|
||||
@@ -1517,9 +1523,11 @@ describe("CartService", () => {
|
||||
expect(shippingOptionService.createShippingMethod).toHaveBeenCalledTimes(
|
||||
1
|
||||
)
|
||||
expect(
|
||||
shippingOptionService.createShippingMethod
|
||||
).toHaveBeenCalledWith(IdMap.getId("profile1"), data, { cart: cart3 })
|
||||
expect(shippingOptionService.createShippingMethod).toHaveBeenCalledWith(
|
||||
IdMap.getId("profile1"),
|
||||
data,
|
||||
{ cart: cart3 }
|
||||
)
|
||||
|
||||
expect(lineItemService.update).toHaveBeenCalledTimes(1)
|
||||
expect(lineItemService.update).toHaveBeenCalledWith(IdMap.getId("line"), {
|
||||
@@ -1535,7 +1543,7 @@ describe("CartService", () => {
|
||||
|
||||
cartService.findCustomShippingOption = jest
|
||||
.fn()
|
||||
.mockImplementation(cartCustomShippingOptions => {
|
||||
.mockImplementation((cartCustomShippingOptions) => {
|
||||
return {
|
||||
price: 0,
|
||||
}
|
||||
@@ -1550,7 +1558,7 @@ describe("CartService", () => {
|
||||
IdMap.getId("test-so"),
|
||||
data,
|
||||
{
|
||||
cart: cartWithCustomSO,
|
||||
cart_id: IdMap.getId("cart-with-custom-so"),
|
||||
price: 0,
|
||||
}
|
||||
)
|
||||
@@ -1558,7 +1566,7 @@ describe("CartService", () => {
|
||||
})
|
||||
|
||||
describe("applyDiscount", () => {
|
||||
const getOffsetDate = offset => {
|
||||
const getOffsetDate = (offset) => {
|
||||
const date = new Date()
|
||||
date.setDate(date.getDate() + offset)
|
||||
return date
|
||||
@@ -1595,7 +1603,7 @@ describe("CartService", () => {
|
||||
})
|
||||
|
||||
const discountService = {
|
||||
retrieveByCode: jest.fn().mockImplementation(code => {
|
||||
retrieveByCode: jest.fn().mockImplementation((code) => {
|
||||
if (code === "US10") {
|
||||
return Promise.resolve({
|
||||
regions: [{ id: IdMap.getId("bad") }],
|
||||
|
||||
@@ -415,6 +415,7 @@ describe("ProductService", () => {
|
||||
|
||||
const productService = new ProductService({
|
||||
manager: MockManager,
|
||||
eventBusService,
|
||||
productRepository,
|
||||
})
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ import { InventoryServiceMock } from "../__mocks__/inventory"
|
||||
|
||||
const eventBusService = {
|
||||
emit: jest.fn(),
|
||||
withTransaction: function() {
|
||||
withTransaction: function () {
|
||||
return this
|
||||
},
|
||||
}
|
||||
@@ -161,7 +161,7 @@ describe("SwapService", () => {
|
||||
const cartService = {
|
||||
create: jest.fn().mockReturnValue(Promise.resolve({ id: "cart" })),
|
||||
update: jest.fn().mockReturnValue(Promise.resolve()),
|
||||
withTransaction: function() {
|
||||
withTransaction: function () {
|
||||
return this
|
||||
},
|
||||
}
|
||||
@@ -179,10 +179,10 @@ describe("SwapService", () => {
|
||||
}
|
||||
|
||||
const lineItemService = {
|
||||
create: jest.fn().mockImplementation(d => Promise.resolve(d)),
|
||||
update: jest.fn().mockImplementation(d => Promise.resolve(d)),
|
||||
create: jest.fn().mockImplementation((d) => Promise.resolve(d)),
|
||||
update: jest.fn().mockImplementation((d) => Promise.resolve(d)),
|
||||
retrieve: () => Promise.resolve({}),
|
||||
withTransaction: function() {
|
||||
withTransaction: function () {
|
||||
return this
|
||||
},
|
||||
}
|
||||
@@ -210,6 +210,8 @@ describe("SwapService", () => {
|
||||
"order.swaps.additional_items",
|
||||
"order.discounts",
|
||||
"order.discounts.rule",
|
||||
"order.claims",
|
||||
"order.claims.additional_items",
|
||||
"additional_items",
|
||||
"return_order",
|
||||
"return_order.items",
|
||||
@@ -315,7 +317,7 @@ describe("SwapService", () => {
|
||||
const swapRepo = MockRepository()
|
||||
const returnService = {
|
||||
create: jest.fn().mockReturnValue(Promise.resolve({ id: "ret" })),
|
||||
withTransaction: function() {
|
||||
withTransaction: function () {
|
||||
return this
|
||||
},
|
||||
}
|
||||
@@ -412,7 +414,7 @@ describe("SwapService", () => {
|
||||
receiveReturn: jest
|
||||
.fn()
|
||||
.mockReturnValue(Promise.resolve({ test: "received" })),
|
||||
withTransaction: function() {
|
||||
withTransaction: function () {
|
||||
return this
|
||||
},
|
||||
}
|
||||
@@ -458,7 +460,7 @@ describe("SwapService", () => {
|
||||
receiveReturn: jest
|
||||
.fn()
|
||||
.mockReturnValue(Promise.resolve({ status: "requires_action" })),
|
||||
withTransaction: function() {
|
||||
withTransaction: function () {
|
||||
return this
|
||||
},
|
||||
}
|
||||
@@ -536,7 +538,7 @@ describe("SwapService", () => {
|
||||
{ items: [{ item_id: "1234", quantity: 2 }], data: "new" },
|
||||
])
|
||||
),
|
||||
withTransaction: function() {
|
||||
withTransaction: function () {
|
||||
return this
|
||||
},
|
||||
}
|
||||
@@ -557,7 +559,7 @@ describe("SwapService", () => {
|
||||
const lineItemService = {
|
||||
update: jest.fn(),
|
||||
retrieve: () => Promise.resolve({}),
|
||||
withTransaction: function() {
|
||||
withTransaction: function () {
|
||||
return this
|
||||
},
|
||||
}
|
||||
@@ -632,11 +634,11 @@ describe("SwapService", () => {
|
||||
describe("cancelFulfillment", () => {
|
||||
const swapRepo = MockRepository({
|
||||
findOneWithRelations: () => Promise.resolve({}),
|
||||
save: f => Promise.resolve(f),
|
||||
save: (f) => Promise.resolve(f),
|
||||
})
|
||||
|
||||
const fulfillmentService = {
|
||||
cancelFulfillment: jest.fn().mockImplementation(f => {
|
||||
cancelFulfillment: jest.fn().mockImplementation((f) => {
|
||||
switch (f) {
|
||||
case IdMap.getId("no-swap"):
|
||||
return Promise.resolve({})
|
||||
@@ -646,7 +648,7 @@ describe("SwapService", () => {
|
||||
})
|
||||
}
|
||||
}),
|
||||
withTransaction: function() {
|
||||
withTransaction: function () {
|
||||
return this
|
||||
},
|
||||
}
|
||||
@@ -700,14 +702,14 @@ describe("SwapService", () => {
|
||||
data: "new",
|
||||
})
|
||||
}),
|
||||
withTransaction: function() {
|
||||
withTransaction: function () {
|
||||
return this
|
||||
},
|
||||
}
|
||||
|
||||
const eventBusService = {
|
||||
emit: jest.fn().mockReturnValue(Promise.resolve()),
|
||||
withTransaction: function() {
|
||||
withTransaction: function () {
|
||||
return this
|
||||
},
|
||||
}
|
||||
@@ -748,14 +750,14 @@ describe("SwapService", () => {
|
||||
const lineItemService = {
|
||||
update: jest.fn(),
|
||||
retrieve: () => Promise.resolve({}),
|
||||
withTransaction: function() {
|
||||
withTransaction: function () {
|
||||
return this
|
||||
},
|
||||
}
|
||||
|
||||
const cartService = {
|
||||
update: jest.fn(),
|
||||
withTransaction: function() {
|
||||
withTransaction: function () {
|
||||
return this
|
||||
},
|
||||
}
|
||||
@@ -831,7 +833,7 @@ describe("SwapService", () => {
|
||||
|
||||
const eventBusService = {
|
||||
emit: jest.fn().mockReturnValue(Promise.resolve()),
|
||||
withTransaction: function() {
|
||||
withTransaction: function () {
|
||||
return this
|
||||
},
|
||||
}
|
||||
@@ -846,7 +848,7 @@ describe("SwapService", () => {
|
||||
updateShippingMethod: () => {
|
||||
return Promise.resolve()
|
||||
},
|
||||
withTransaction: function() {
|
||||
withTransaction: function () {
|
||||
return this
|
||||
},
|
||||
}
|
||||
@@ -855,7 +857,7 @@ describe("SwapService", () => {
|
||||
update: () => {
|
||||
return Promise.resolve()
|
||||
},
|
||||
withTransaction: function() {
|
||||
withTransaction: function () {
|
||||
return this
|
||||
},
|
||||
}
|
||||
@@ -870,14 +872,14 @@ describe("SwapService", () => {
|
||||
cancelPayment: jest.fn(() => {
|
||||
return Promise.resolve()
|
||||
}),
|
||||
withTransaction: function() {
|
||||
withTransaction: function () {
|
||||
return this
|
||||
},
|
||||
}
|
||||
|
||||
const inventoryService = {
|
||||
...InventoryServiceMock,
|
||||
withTransaction: function() {
|
||||
withTransaction: function () {
|
||||
return this
|
||||
},
|
||||
}
|
||||
@@ -998,19 +1000,19 @@ describe("SwapService", () => {
|
||||
describe("success", () => {
|
||||
const eventBusService = {
|
||||
emit: jest.fn().mockReturnValue(Promise.resolve()),
|
||||
withTransaction: function() {
|
||||
withTransaction: function () {
|
||||
return this
|
||||
},
|
||||
}
|
||||
|
||||
const paymentProviderService = {
|
||||
capturePayment: jest.fn(g =>
|
||||
capturePayment: jest.fn((g) =>
|
||||
g.id === "good" ? Promise.resolve() : Promise.reject()
|
||||
),
|
||||
refundPayment: jest.fn(g =>
|
||||
refundPayment: jest.fn((g) =>
|
||||
g[0].id === "good" ? Promise.resolve() : Promise.reject()
|
||||
),
|
||||
withTransaction: function() {
|
||||
withTransaction: function () {
|
||||
return this
|
||||
},
|
||||
}
|
||||
@@ -1138,7 +1140,7 @@ describe("SwapService", () => {
|
||||
|
||||
const eventBusService = {
|
||||
emit: jest.fn().mockReturnValue(Promise.resolve()),
|
||||
withTransaction: function() {
|
||||
withTransaction: function () {
|
||||
return this
|
||||
},
|
||||
}
|
||||
@@ -1201,7 +1203,7 @@ describe("SwapService", () => {
|
||||
|
||||
const paymentProviderService = {
|
||||
cancelPayment: jest.fn(() => Promise.resolve({})),
|
||||
withTransaction: function() {
|
||||
withTransaction: function () {
|
||||
return this
|
||||
},
|
||||
}
|
||||
@@ -1233,7 +1235,7 @@ describe("SwapService", () => {
|
||||
return Promise.resolve(swap)
|
||||
}
|
||||
},
|
||||
save: f => f,
|
||||
save: (f) => f,
|
||||
})
|
||||
|
||||
const swapService = new SwapService({
|
||||
@@ -1282,7 +1284,7 @@ describe("SwapService", () => {
|
||||
|
||||
it.each([["fail-refund-1"], ["fail-refund-2"], ["fail-refund-3"]])(
|
||||
"fails to cancel swap when contains refund",
|
||||
async input => {
|
||||
async (input) => {
|
||||
await expect(swapService.cancel(IdMap.getId(input))).rejects.toThrow(
|
||||
"Swap with a refund cannot be canceled"
|
||||
)
|
||||
|
||||
@@ -7,7 +7,7 @@ import { Brackets, ILike } from "typeorm"
|
||||
|
||||
/**
|
||||
* Provides layer to manipulate customers.
|
||||
* @implements BaseService
|
||||
* @implements {BaseService}
|
||||
*/
|
||||
class CustomerService extends BaseService {
|
||||
static Events = {
|
||||
@@ -60,9 +60,7 @@ class CustomerService extends BaseService {
|
||||
* @return {string} the validated email
|
||||
*/
|
||||
validateEmail_(email) {
|
||||
const schema = Validator.string()
|
||||
.email()
|
||||
.required()
|
||||
const schema = Validator.string().email().required()
|
||||
const { value, error } = schema.validate(email)
|
||||
if (error) {
|
||||
throw new MedusaError(
|
||||
@@ -93,7 +91,7 @@ class CustomerService extends BaseService {
|
||||
* secret a long side a payload with userId and the expiry time for the token,
|
||||
* which is always 15 minutes.
|
||||
* @param {string} customerId - the customer to reset the password for
|
||||
* @returns {string} the generated JSON web token
|
||||
* @return {string} the generated JSON web token
|
||||
*/
|
||||
async generateResetPasswordToken(customerId) {
|
||||
const customer = await this.retrieve(customerId)
|
||||
@@ -122,6 +120,7 @@ class CustomerService extends BaseService {
|
||||
|
||||
/**
|
||||
* @param {Object} selector - the query object for find
|
||||
* @param {Object} config - the config object containing query settings
|
||||
* @return {Promise} the result of the find operation
|
||||
*/
|
||||
async list(selector = {}, config = { relations: [], skip: 0, take: 50 }) {
|
||||
@@ -144,11 +143,11 @@ class CustomerService extends BaseService {
|
||||
delete where.first_name
|
||||
delete where.last_name
|
||||
|
||||
query.where = qb => {
|
||||
query.where = (qb) => {
|
||||
qb.where(where)
|
||||
|
||||
qb.andWhere(
|
||||
new Brackets(qb => {
|
||||
new Brackets((qb) => {
|
||||
qb.where({ email: ILike(`%${q}%`) })
|
||||
.orWhere({ first_name: ILike(`%${q}%`) })
|
||||
.orWhere({ last_name: ILike(`%${q}%`) })
|
||||
@@ -183,11 +182,11 @@ class CustomerService extends BaseService {
|
||||
delete where.first_name
|
||||
delete where.last_name
|
||||
|
||||
query.where = qb => {
|
||||
query.where = (qb) => {
|
||||
qb.where(where)
|
||||
|
||||
qb.andWhere(
|
||||
new Brackets(qb => {
|
||||
new Brackets((qb) => {
|
||||
qb.where({ email: ILike(`%${q}%`) })
|
||||
.orWhere({ first_name: ILike(`%${q}%`) })
|
||||
.orWhere({ last_name: ILike(`%${q}%`) })
|
||||
@@ -214,6 +213,7 @@ class CustomerService extends BaseService {
|
||||
/**
|
||||
* Gets a customer by id.
|
||||
* @param {string} customerId - the id of the customer to get.
|
||||
* @param {Object} config - the config object containing query settings
|
||||
* @return {Promise<Customer>} the customer document.
|
||||
*/
|
||||
async retrieve(customerId, config = {}) {
|
||||
@@ -238,6 +238,7 @@ class CustomerService extends BaseService {
|
||||
/**
|
||||
* Gets a customer by email.
|
||||
* @param {string} email - the email of the customer to get.
|
||||
* @param {Object} config - the config object containing query settings
|
||||
* @return {Promise<Customer>} the customer document.
|
||||
*/
|
||||
async retrieveByEmail(email, config = {}) {
|
||||
@@ -261,6 +262,7 @@ class CustomerService extends BaseService {
|
||||
/**
|
||||
* Gets a customer by phone.
|
||||
* @param {string} phone - the phone of the customer to get.
|
||||
* @param {Object} config - the config object containing query settings
|
||||
* @return {Promise<Customer>} the customer document.
|
||||
*/
|
||||
async retrieveByPhone(phone, config = {}) {
|
||||
@@ -284,7 +286,7 @@ class CustomerService extends BaseService {
|
||||
/**
|
||||
* Hashes a password
|
||||
* @param {string} password - the value to hash
|
||||
* @return hashed password
|
||||
* @return {string} hashed password
|
||||
*/
|
||||
async hashPassword_(password) {
|
||||
const buf = await Scrypt.kdf(password, { logN: 1, r: 1, p: 1 })
|
||||
@@ -300,7 +302,7 @@ class CustomerService extends BaseService {
|
||||
* @return {Promise} the result of create
|
||||
*/
|
||||
async create(customer) {
|
||||
return this.atomicPhase_(async manager => {
|
||||
return this.atomicPhase_(async (manager) => {
|
||||
const customerRepository = manager.getCustomRepository(
|
||||
this.customerRepository_
|
||||
)
|
||||
@@ -312,7 +314,9 @@ class CustomerService extends BaseService {
|
||||
customer.billing_address = this.validateBillingAddress_(billing_address)
|
||||
}
|
||||
|
||||
const existing = await this.retrieveByEmail(email).catch(err => undefined)
|
||||
const existing = await this.retrieveByEmail(email).catch(
|
||||
(err) => undefined
|
||||
)
|
||||
|
||||
if (existing && existing.has_account) {
|
||||
throw new MedusaError(
|
||||
@@ -353,13 +357,13 @@ class CustomerService extends BaseService {
|
||||
|
||||
/**
|
||||
* Updates a customer.
|
||||
* @param {string} variantId - the id of the variant. Must be a string that
|
||||
* @param {string} customerId - the id of the variant. Must be a string that
|
||||
* can be casted to an ObjectId
|
||||
* @param {object} update - an object with the update values.
|
||||
* @return {Promise} resolves to the update result.
|
||||
*/
|
||||
async update(customerId, update) {
|
||||
return this.atomicPhase_(async manager => {
|
||||
return this.atomicPhase_(async (manager) => {
|
||||
const customerRepository = manager.getCustomRepository(
|
||||
this.customerRepository_
|
||||
)
|
||||
@@ -367,15 +371,7 @@ class CustomerService extends BaseService {
|
||||
|
||||
const customer = await this.retrieve(customerId)
|
||||
|
||||
const {
|
||||
email,
|
||||
password,
|
||||
password_hash,
|
||||
billing_address,
|
||||
billing_address_id,
|
||||
metadata,
|
||||
...rest
|
||||
} = update
|
||||
const { email, password, metadata, ...rest } = update
|
||||
|
||||
if (metadata) {
|
||||
customer.metadata = this.setMetadata_(customer, metadata)
|
||||
@@ -408,9 +404,10 @@ class CustomerService extends BaseService {
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the customers's billing address.
|
||||
* Updates the customers' billing address.
|
||||
* @param {Customer} customer - the Customer to update
|
||||
* @param {object} address - the value to set the billing address to
|
||||
* @param {Object|string} addressOrId - the value to set the billing address to
|
||||
* @param {Object} addrRepo - address repository
|
||||
* @return {Promise} the result of the update operation
|
||||
*/
|
||||
async updateBillingAddress_(customer, addressOrId, addrRepo) {
|
||||
@@ -443,7 +440,7 @@ class CustomerService extends BaseService {
|
||||
}
|
||||
|
||||
async updateAddress(customerId, addressId, address) {
|
||||
return this.atomicPhase_(async manager => {
|
||||
return this.atomicPhase_(async (manager) => {
|
||||
const addressRepo = manager.getCustomRepository(this.addressRepository_)
|
||||
|
||||
address.country_code = address.country_code.toLowerCase()
|
||||
@@ -464,7 +461,7 @@ class CustomerService extends BaseService {
|
||||
}
|
||||
|
||||
async removeAddress(customerId, addressId) {
|
||||
return this.atomicPhase_(async manager => {
|
||||
return this.atomicPhase_(async (manager) => {
|
||||
const addressRepo = manager.getCustomRepository(this.addressRepository_)
|
||||
|
||||
// Should not fail, if user does not exist, since delete is idempotent
|
||||
@@ -472,7 +469,9 @@ class CustomerService extends BaseService {
|
||||
where: { id: addressId, customer_id: customerId },
|
||||
})
|
||||
|
||||
if (!address) return Promise.resolve()
|
||||
if (!address) {
|
||||
return Promise.resolve()
|
||||
}
|
||||
|
||||
await addressRepo.softRemove(address)
|
||||
|
||||
@@ -481,7 +480,7 @@ class CustomerService extends BaseService {
|
||||
}
|
||||
|
||||
async addAddress(customerId, address) {
|
||||
return this.atomicPhase_(async manager => {
|
||||
return this.atomicPhase_(async (manager) => {
|
||||
const addressRepository = manager.getCustomRepository(
|
||||
this.addressRepository_
|
||||
)
|
||||
@@ -493,8 +492,8 @@ class CustomerService extends BaseService {
|
||||
})
|
||||
this.validateBillingAddress_(address)
|
||||
|
||||
let shouldAdd = !customer.shipping_addresses.find(
|
||||
a =>
|
||||
const shouldAdd = !customer.shipping_addresses.find(
|
||||
(a) =>
|
||||
a.country_code.toLowerCase() === address.country_code.toLowerCase() &&
|
||||
a.address_1 === address.address_1 &&
|
||||
a.address_2 === address.address_2 &&
|
||||
@@ -526,13 +525,15 @@ class CustomerService extends BaseService {
|
||||
* @return {Promise} the result of the delete operation.
|
||||
*/
|
||||
async delete(customerId) {
|
||||
return this.atomicPhase_(async manager => {
|
||||
return this.atomicPhase_(async (manager) => {
|
||||
const customerRepo = manager.getCustomRepository(this.customerRepository_)
|
||||
|
||||
// Should not fail, if user does not exist, since delete is idempotent
|
||||
const customer = await customerRepo.findOne({ where: { id: customerId } })
|
||||
|
||||
if (!customer) return Promise.resolve()
|
||||
if (!customer) {
|
||||
return Promise.resolve()
|
||||
}
|
||||
|
||||
await customerRepo.softRemove(customer)
|
||||
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
import _ from "lodash"
|
||||
import { BaseService } from "medusa-interfaces"
|
||||
import { MedusaError } from "medusa-core-utils"
|
||||
import { Brackets, ILike } from "typeorm"
|
||||
import { Brackets } from "typeorm"
|
||||
|
||||
/**
|
||||
* Handles draft orders
|
||||
* @implements BaseService
|
||||
* @implements {BaseService}
|
||||
*/
|
||||
class DraftOrderService extends BaseService {
|
||||
static Events = {
|
||||
@@ -106,7 +105,7 @@ class DraftOrderService extends BaseService {
|
||||
/**
|
||||
* Retrieves a draft order based on its associated cart id
|
||||
* @param {string} cartId - cart id that the draft orders's cart has
|
||||
* * @param {object} config - query object for findOne
|
||||
* @param {object} config - query object for findOne
|
||||
* @return {Promise<DraftOrder>} the draft order
|
||||
*/
|
||||
async retrieveByCartId(cartId, config = {}) {
|
||||
@@ -134,7 +133,7 @@ class DraftOrderService extends BaseService {
|
||||
* @return {Promise} empty promise
|
||||
*/
|
||||
async delete(draftOrderId) {
|
||||
return this.atomicPhase_(async manager => {
|
||||
return this.atomicPhase_(async (manager) => {
|
||||
const draftOrderRepo = manager.getCustomRepository(
|
||||
this.draftOrderRepository_
|
||||
)
|
||||
@@ -143,7 +142,9 @@ class DraftOrderService extends BaseService {
|
||||
where: { id: draftOrderId },
|
||||
})
|
||||
|
||||
if (!draftOrder) return Promise.resolve()
|
||||
if (!draftOrder) {
|
||||
return Promise.resolve()
|
||||
}
|
||||
|
||||
await draftOrderRepo.remove(draftOrder)
|
||||
|
||||
@@ -185,11 +186,11 @@ class DraftOrderService extends BaseService {
|
||||
},
|
||||
}
|
||||
|
||||
query.where = qb => {
|
||||
query.where = (qb) => {
|
||||
qb.where(where)
|
||||
|
||||
qb.andWhere(
|
||||
new Brackets(qb => {
|
||||
new Brackets((qb) => {
|
||||
qb.where(`cart.email ILIKE :q`, {
|
||||
q: `%${q}%`,
|
||||
}).orWhere(`draft_order.display_id::varchar(255) ILIKE :dId`, {
|
||||
@@ -230,7 +231,7 @@ class DraftOrderService extends BaseService {
|
||||
* @return {Promise<DraftOrder>} the created draft order
|
||||
*/
|
||||
async create(data) {
|
||||
return this.atomicPhase_(async manager => {
|
||||
return this.atomicPhase_(async (manager) => {
|
||||
const draftOrderRepo = manager.getCustomRepository(
|
||||
this.draftOrderRepository_
|
||||
)
|
||||
@@ -332,7 +333,7 @@ class DraftOrderService extends BaseService {
|
||||
* @return {Promise} the created order
|
||||
*/
|
||||
async registerCartCompletion(doId, orderId) {
|
||||
return this.atomicPhase_(async manager => {
|
||||
return this.atomicPhase_(async (manager) => {
|
||||
const draftOrderRepo = manager.getCustomRepository(
|
||||
this.draftOrderRepository_
|
||||
)
|
||||
@@ -350,10 +351,10 @@ class DraftOrderService extends BaseService {
|
||||
* Updates a draft order with the given data
|
||||
* @param {String} doId - id of the draft order
|
||||
* @param {DraftOrder} data - values to update the order with
|
||||
* @returns {Promise<DraftOrder>} the updated draft order
|
||||
* @return {Promise<DraftOrder>} the updated draft order
|
||||
*/
|
||||
async update(doId, data) {
|
||||
return this.atomicPhase_(async manager => {
|
||||
return this.atomicPhase_(async (manager) => {
|
||||
const doRepo = manager.getCustomRepository(this.draftOrderRepository_)
|
||||
const draftOrder = await this.retrieve(doId)
|
||||
let touched = false
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
import { Validator, MedusaError } from "medusa-core-utils"
|
||||
import { MedusaError } from "medusa-core-utils"
|
||||
import { BaseService } from "medusa-interfaces"
|
||||
import _ from "lodash"
|
||||
|
||||
/**
|
||||
* Provides layer to manipulate line items.
|
||||
* @implements BaseService
|
||||
* @extends BaseService
|
||||
*/
|
||||
class LineItemService extends BaseService {
|
||||
constructor({
|
||||
@@ -67,6 +66,7 @@ class LineItemService extends BaseService {
|
||||
/**
|
||||
* Retrieves a line item by its id.
|
||||
* @param {string} id - the id of the line item to retrieve
|
||||
* @param {object} config - the config to be used at query building
|
||||
* @return {LineItem} the line item
|
||||
*/
|
||||
async retrieve(id, config = {}) {
|
||||
@@ -90,7 +90,7 @@ class LineItemService extends BaseService {
|
||||
}
|
||||
|
||||
async generate(variantId, regionId, quantity, config = {}) {
|
||||
return this.atomicPhase_(async manager => {
|
||||
return this.atomicPhase_(async (manager) => {
|
||||
const variant = await this.productVariantService_
|
||||
.withTransaction(manager)
|
||||
.retrieve(variantId, {
|
||||
@@ -142,7 +142,7 @@ class LineItemService extends BaseService {
|
||||
* @return {LineItem} the created line item
|
||||
*/
|
||||
async create(lineItem) {
|
||||
return this.atomicPhase_(async manager => {
|
||||
return this.atomicPhase_(async (manager) => {
|
||||
const lineItemRepository = manager.getCustomRepository(
|
||||
this.lineItemRepository_
|
||||
)
|
||||
@@ -160,7 +160,7 @@ class LineItemService extends BaseService {
|
||||
* @return {LineItem} the update line item
|
||||
*/
|
||||
async update(id, update) {
|
||||
return this.atomicPhase_(async manager => {
|
||||
return this.atomicPhase_(async (manager) => {
|
||||
const lineItemRepository = manager.getCustomRepository(
|
||||
this.lineItemRepository_
|
||||
)
|
||||
@@ -188,14 +188,16 @@ class LineItemService extends BaseService {
|
||||
* @return {Promise} the result of the delete operation
|
||||
*/
|
||||
async delete(id) {
|
||||
return this.atomicPhase_(async manager => {
|
||||
return this.atomicPhase_(async (manager) => {
|
||||
const lineItemRepository = manager.getCustomRepository(
|
||||
this.lineItemRepository_
|
||||
)
|
||||
|
||||
const lineItem = await lineItemRepository.findOne({ where: { id } })
|
||||
|
||||
if (!lineItem) return Promise.resolve()
|
||||
if (!lineItem) {
|
||||
return Promise.resolve()
|
||||
}
|
||||
|
||||
await lineItemRepository.remove(lineItem)
|
||||
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
import { MedusaError } from "medusa-core-utils"
|
||||
import { BaseService } from "medusa-interfaces"
|
||||
import _ from "lodash"
|
||||
|
||||
/**
|
||||
* Provides layer to manipulate orchestrate notifications.
|
||||
* @implements BaseService
|
||||
* @extends BaseService
|
||||
*/
|
||||
class NotificationService extends BaseService {
|
||||
constructor(container) {
|
||||
@@ -34,6 +33,7 @@ class NotificationService extends BaseService {
|
||||
/**
|
||||
* Registers an attachment generator to the service. The generator can be
|
||||
* used to generate on demand invoices or other documents.
|
||||
* @param {object} service
|
||||
*/
|
||||
registerAttachmentGenerator(service) {
|
||||
this.attachmentGenerator_ = service
|
||||
@@ -42,16 +42,18 @@ class NotificationService extends BaseService {
|
||||
/**
|
||||
* Sets the service's manager to a given transaction manager.
|
||||
* @param {EntityManager} transactionManager - the manager to use
|
||||
* return {NotificationService} a cloned notification service
|
||||
* @return {NotificationService} a cloned notification service
|
||||
*/
|
||||
withTransaction(transactionManager) {
|
||||
if (!transactionManager) {
|
||||
return this
|
||||
}
|
||||
|
||||
const cloned = new LineItemService({
|
||||
const cloned = new NotificationService({
|
||||
manager: transactionManager,
|
||||
notificationProviderRepository: this.notificationProviderRepository_,
|
||||
notificationRepository: this.notificationRepository_,
|
||||
logger: this.logger_,
|
||||
})
|
||||
|
||||
cloned.transactionManager_ = transactionManager
|
||||
@@ -93,6 +95,7 @@ class NotificationService extends BaseService {
|
||||
/**
|
||||
* Retrieves a notification with a given id
|
||||
* @param {string} id - the id of the notification
|
||||
* @param {object} config - the configuration to apply to the query
|
||||
* @return {Notification} the notification
|
||||
*/
|
||||
async retrieve(id, config = {}) {
|
||||
@@ -158,6 +161,7 @@ class NotificationService extends BaseService {
|
||||
* order to allow for resends. Will log any errors that are encountered.
|
||||
* @param {string} eventName - the event to handle
|
||||
* @param {object} data - the data the event was sent with
|
||||
* @return {Promise} - the result of notification subscribed
|
||||
*/
|
||||
handleEvent(eventName, data) {
|
||||
const subs = this.subscribers_[eventName]
|
||||
@@ -169,8 +173,8 @@ class NotificationService extends BaseService {
|
||||
}
|
||||
|
||||
return Promise.all(
|
||||
subs.map(async providerId => {
|
||||
return this.send(eventName, data, providerId).catch(err => {
|
||||
subs.map(async (providerId) => {
|
||||
return this.send(eventName, data, providerId).catch((err) => {
|
||||
console.log(err)
|
||||
this.logger_.warn(
|
||||
`An error occured while ${providerId} was processing a notification for ${eventName}: ${err.message}`
|
||||
|
||||
@@ -286,6 +286,7 @@ class OrderService extends BaseService {
|
||||
"refundable_amount",
|
||||
"items.refundable",
|
||||
"swaps.additional_items.refundable",
|
||||
"claims.additional_items.refundable",
|
||||
]
|
||||
|
||||
const totalsToSelect = select.filter((v) => totalFields.includes(v))
|
||||
@@ -294,6 +295,8 @@ class OrderService extends BaseService {
|
||||
relationSet.add("items")
|
||||
relationSet.add("swaps")
|
||||
relationSet.add("swaps.additional_items")
|
||||
relationSet.add("claims")
|
||||
relationSet.add("claims.additional_items")
|
||||
relationSet.add("discounts")
|
||||
relationSet.add("discounts.rule")
|
||||
relationSet.add("discounts.rule.valid_for")
|
||||
@@ -1407,6 +1410,22 @@ class OrderService extends BaseService {
|
||||
}
|
||||
}
|
||||
|
||||
if (
|
||||
totalsFields.includes("claims.additional_items.refundable") &&
|
||||
order.claims &&
|
||||
order.claims.length
|
||||
) {
|
||||
for (const c of order.claims) {
|
||||
c.additional_items = c.additional_items.map((i) => ({
|
||||
...i,
|
||||
refundable: this.totalsService_.getLineItemRefund(order, {
|
||||
...i,
|
||||
quantity: i.quantity - (i.returned_quantity || 0),
|
||||
}),
|
||||
}))
|
||||
}
|
||||
}
|
||||
|
||||
return order
|
||||
}
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@ class ProductVariantService extends BaseService {
|
||||
static Events = {
|
||||
UPDATED: "product-variant.updated",
|
||||
CREATED: "product-variant.created",
|
||||
DELETED: "product-variant.deleted",
|
||||
}
|
||||
|
||||
/** @param { productVariantModel: (ProductVariantModel) } */
|
||||
@@ -588,6 +589,12 @@ class ProductVariantService extends BaseService {
|
||||
|
||||
await variantRepo.softRemove(variant)
|
||||
|
||||
await this.eventBus_
|
||||
.withTransaction(manager)
|
||||
.emit(ProductVariantService.Events.DELETED, {
|
||||
id: variantId,
|
||||
})
|
||||
|
||||
return Promise.resolve()
|
||||
})
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ class ProductService extends BaseService {
|
||||
static Events = {
|
||||
UPDATED: "product.updated",
|
||||
CREATED: "product.created",
|
||||
DELETED: "product.deleted",
|
||||
}
|
||||
|
||||
constructor({
|
||||
@@ -475,6 +476,12 @@ class ProductService extends BaseService {
|
||||
|
||||
await productRepo.softRemove(product)
|
||||
|
||||
await this.eventBus_
|
||||
.withTransaction(manager)
|
||||
.emit(ProductService.Events.DELETED, {
|
||||
id: productId,
|
||||
})
|
||||
|
||||
return Promise.resolve()
|
||||
})
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@ class RegionService extends BaseService {
|
||||
static Events = {
|
||||
UPDATED: "region.updated",
|
||||
CREATED: "region.created",
|
||||
DELETED: "region.deleted",
|
||||
}
|
||||
|
||||
constructor({
|
||||
@@ -389,6 +390,12 @@ class RegionService extends BaseService {
|
||||
|
||||
await regionRepo.softRemove(region)
|
||||
|
||||
await this.eventBus_
|
||||
.withTransaction(manager)
|
||||
.emit(RegionService.Events.DELETED, {
|
||||
id: regionId,
|
||||
})
|
||||
|
||||
return Promise.resolve()
|
||||
})
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import { Validator, MedusaError } from "medusa-core-utils"
|
||||
import { MedusaError } from "medusa-core-utils"
|
||||
import { BaseService } from "medusa-interfaces"
|
||||
import { In } from "typeorm"
|
||||
|
||||
class ReturnReasonService extends BaseService {
|
||||
constructor({ manager, returnReasonRepository }) {
|
||||
@@ -29,7 +28,7 @@ class ReturnReasonService extends BaseService {
|
||||
}
|
||||
|
||||
create(data) {
|
||||
return this.atomicPhase_(async manager => {
|
||||
return this.atomicPhase_(async (manager) => {
|
||||
const rrRepo = manager.getCustomRepository(this.retReasonRepo_)
|
||||
|
||||
if (data.parent_return_reason_id && data.parent_return_reason_id !== "") {
|
||||
@@ -51,7 +50,7 @@ class ReturnReasonService extends BaseService {
|
||||
}
|
||||
|
||||
update(id, data) {
|
||||
return this.atomicPhase_(async manager => {
|
||||
return this.atomicPhase_(async (manager) => {
|
||||
const rrRepo = manager.getCustomRepository(this.retReasonRepo_)
|
||||
const reason = await this.retrieve(id)
|
||||
|
||||
@@ -77,6 +76,7 @@ class ReturnReasonService extends BaseService {
|
||||
|
||||
/**
|
||||
* @param {Object} selector - the query object for find
|
||||
* @param {Object} config - config object
|
||||
* @return {Promise} the result of the find operation
|
||||
*/
|
||||
async list(
|
||||
@@ -90,7 +90,8 @@ class ReturnReasonService extends BaseService {
|
||||
|
||||
/**
|
||||
* Gets an order by id.
|
||||
* @param {string} orderId - id of order to retrieve
|
||||
* @param {string} id - id of order to retrieve
|
||||
* @param {Object} config - config object
|
||||
* @return {Promise<Order>} the order document
|
||||
*/
|
||||
async retrieve(id, config = {}) {
|
||||
@@ -111,7 +112,7 @@ class ReturnReasonService extends BaseService {
|
||||
}
|
||||
|
||||
async delete(returnReasonId) {
|
||||
return this.atomicPhase_(async manager => {
|
||||
return this.atomicPhase_(async (manager) => {
|
||||
const rrRepo = manager.getCustomRepository(this.retReasonRepo_)
|
||||
|
||||
// We include the relation 'return_reason_children' to enable cascading deletes of return reasons if a parent is removed
|
||||
|
||||
@@ -93,6 +93,12 @@ class ReturnService extends BaseService {
|
||||
}
|
||||
}
|
||||
|
||||
if (order.claims && order.claims.length) {
|
||||
for (const c of order.claims) {
|
||||
merged = [...merged, ...c.additional_items]
|
||||
}
|
||||
}
|
||||
|
||||
const toReturn = await Promise.all(
|
||||
items.map(async data => {
|
||||
const item = merged.find(i => i.id === data.item_id)
|
||||
@@ -325,7 +331,13 @@ class ReturnService extends BaseService {
|
||||
.withTransaction(manager)
|
||||
.retrieve(orderId, {
|
||||
select: ["refunded_total", "total", "refundable_amount"],
|
||||
relations: ["swaps", "swaps.additional_items", "items"],
|
||||
relations: [
|
||||
"swaps",
|
||||
"swaps.additional_items",
|
||||
"claims",
|
||||
"claims.additional_items",
|
||||
"items",
|
||||
],
|
||||
})
|
||||
|
||||
const returnLines = await this.getFulfillmentItems_(
|
||||
@@ -487,13 +499,18 @@ class ReturnService extends BaseService {
|
||||
* @param {string[]} lineItems - the line items to return
|
||||
* @return {Promise} the result of the update operation
|
||||
*/
|
||||
async receive(returnId, receivedItems, refundAmount, allowMismatch = false) {
|
||||
async receive(
|
||||
return_id,
|
||||
received_items,
|
||||
refund_amount,
|
||||
allow_mismatch = false
|
||||
) {
|
||||
return this.atomicPhase_(async manager => {
|
||||
const returnRepository = manager.getCustomRepository(
|
||||
this.returnRepository_
|
||||
)
|
||||
|
||||
const returnObj = await this.retrieve(returnId, {
|
||||
const returnObj = await this.retrieve(return_id, {
|
||||
relations: ["items", "swap", "swap.additional_items"],
|
||||
})
|
||||
|
||||
@@ -537,7 +554,7 @@ class ReturnService extends BaseService {
|
||||
|
||||
const returnLines = await this.getFulfillmentItems_(
|
||||
order,
|
||||
receivedItems,
|
||||
received_items,
|
||||
this.validateReturnLineItem_
|
||||
)
|
||||
|
||||
@@ -566,12 +583,12 @@ class ReturnService extends BaseService {
|
||||
let returnStatus = "received"
|
||||
|
||||
const isMatching = newLines.every(l => l.is_requested)
|
||||
if (!isMatching && !allowMismatch) {
|
||||
if (!isMatching && !allow_mismatch) {
|
||||
// Should update status
|
||||
returnStatus = "requires_action"
|
||||
}
|
||||
|
||||
const totalRefundableAmount = refundAmount || returnObj.refund_amount
|
||||
const totalRefundableAmount = refund_amount || returnObj.refund_amount
|
||||
|
||||
const now = new Date()
|
||||
const updateObj = {
|
||||
|
||||
@@ -1,11 +1,9 @@
|
||||
import _ from "lodash"
|
||||
import { MedusaError } from "medusa-core-utils"
|
||||
import { BaseService } from "medusa-interfaces"
|
||||
import { In } from "typeorm"
|
||||
|
||||
/**
|
||||
* Provides layer to manipulate profiles.
|
||||
* @implements BaseService
|
||||
* @extends BaseService
|
||||
*/
|
||||
class ShippingOptionService extends BaseService {
|
||||
constructor({
|
||||
@@ -64,6 +62,7 @@ class ShippingOptionService extends BaseService {
|
||||
/**
|
||||
* Validates a requirement
|
||||
* @param {ShippingRequirement} requirement - the requirement to validate
|
||||
* @param {string} optionId - the id to validate the requirement
|
||||
* @return {ShippingRequirement} a validated shipping requirement
|
||||
*/
|
||||
async validateRequirement_(requirement, optionId) {
|
||||
@@ -123,6 +122,7 @@ class ShippingOptionService extends BaseService {
|
||||
|
||||
/**
|
||||
* @param {Object} selector - the query object for find
|
||||
* @param {object} config - config object
|
||||
* @return {Promise} the result of the find operation
|
||||
*/
|
||||
async list(selector, config = { skip: 0, take: 50 }) {
|
||||
@@ -136,6 +136,7 @@ class ShippingOptionService extends BaseService {
|
||||
* Gets a profile by id.
|
||||
* Throws in case of DB Error and if profile was not found.
|
||||
* @param {string} optionId - the id of the profile to get.
|
||||
* @param {object} options - the options to get a profile
|
||||
* @return {Promise<Product>} the profile document.
|
||||
*/
|
||||
async retrieve(optionId, options = {}) {
|
||||
@@ -171,7 +172,7 @@ class ShippingOptionService extends BaseService {
|
||||
* and its methods should be copied to an order/swap entity.
|
||||
* @param {string} id - the id of the shipping method to update
|
||||
* @param {object} update - the values to update the method with
|
||||
* @returns {Promise<ShippingMethod>} the resulting shipping method
|
||||
* @return {Promise<ShippingMethod>} the resulting shipping method
|
||||
*/
|
||||
async updateShippingMethod(id, update) {
|
||||
return this.atomicPhase_(async (manager) => {
|
||||
@@ -200,7 +201,7 @@ class ShippingOptionService extends BaseService {
|
||||
|
||||
/**
|
||||
* Removes a given shipping method
|
||||
* @param {string} id - the id of the option to use for the method.
|
||||
* @param {string} sm - the shipping method to remove
|
||||
*/
|
||||
async deleteShippingMethod(sm) {
|
||||
return this.atomicPhase_(async (manager) => {
|
||||
@@ -214,7 +215,7 @@ class ShippingOptionService extends BaseService {
|
||||
* @param {string} optionId - the id of the option to use for the method.
|
||||
* @param {object} data - the optional provider data to use.
|
||||
* @param {object} config - the cart to create the shipping method for.
|
||||
* @returns {ShippingMethod} the resulting shipping method.
|
||||
* @return {ShippingMethod} the resulting shipping method.
|
||||
*/
|
||||
async createShippingMethod(optionId, data, config) {
|
||||
return this.atomicPhase_(async (manager) => {
|
||||
@@ -290,7 +291,7 @@ class ShippingOptionService extends BaseService {
|
||||
* Checks if a given option id is a valid option for a cart. If it is the
|
||||
* option is returned with the correct price. Throws when region_ids do not
|
||||
* match, or when the shipping option requirements are not satisfied.
|
||||
* @param {string} optionId - the id of the option to check
|
||||
* @param {object} option - the option object to check
|
||||
* @param {Cart} cart - the cart object to check against
|
||||
* @return {ShippingOption} the validated shipping option
|
||||
*/
|
||||
@@ -332,7 +333,7 @@ class ShippingOptionService extends BaseService {
|
||||
* Creates a new shipping option. Used both for outbound and inbound shipping
|
||||
* options. The difference is registered by the `is_return` field which
|
||||
* defaults to false.
|
||||
* @param {ShippingOption} option - the shipping option to create
|
||||
* @param {ShippingOption} data - the data to create shipping options
|
||||
* @return {Promise<ShippingOption>} the result of the create operation
|
||||
*/
|
||||
async create(data) {
|
||||
@@ -412,7 +413,7 @@ class ShippingOptionService extends BaseService {
|
||||
|
||||
/**
|
||||
* Validates a shipping option price
|
||||
* @param {ShippingOptionPrice} price - the price to validate
|
||||
* @param {ShippingOptionPrice} priceType - the price to validate
|
||||
* @param {ShippingOption} option - the option to validate against
|
||||
* @return {Promise<ShippingOptionPrice>} the validated price
|
||||
*/
|
||||
@@ -556,7 +557,7 @@ class ShippingOptionService extends BaseService {
|
||||
*/
|
||||
async delete(optionId) {
|
||||
try {
|
||||
let option = await this.retrieve(optionId)
|
||||
const option = await this.retrieve(optionId)
|
||||
|
||||
const optionRepo = this.manager_.getCustomRepository(
|
||||
this.optionRepository_
|
||||
@@ -628,7 +629,7 @@ class ShippingOptionService extends BaseService {
|
||||
|
||||
/**
|
||||
* Decorates a shipping option.
|
||||
* @param {ShippingOption} shippingOption - the shipping option to decorate.
|
||||
* @param {ShippingOption} optionId - the shipping option to decorate using optionId.
|
||||
* @param {string[]} fields - the fields to include.
|
||||
* @param {string[]} expandFields - fields to expand.
|
||||
* @return {ShippingOption} the decorated ShippingOption.
|
||||
@@ -648,9 +649,8 @@ class ShippingOptionService extends BaseService {
|
||||
|
||||
/**
|
||||
* Dedicated method to set metadata for a shipping option.
|
||||
* @param {string} optionId - the option to set metadata for.
|
||||
* @param {string} key - key for metadata field
|
||||
* @param {string} value - value for metadata field.
|
||||
* @param {object} option - the option to set metadata for.
|
||||
* @param {object} metadata - object for metadata field
|
||||
* @return {Promise} resolves to the updated result.
|
||||
*/
|
||||
async setMetadata_(option, metadata) {
|
||||
@@ -681,9 +681,10 @@ class ShippingOptionService extends BaseService {
|
||||
* price type "calculated".
|
||||
* @param {ShippingOption} option - the shipping option to retrieve the price
|
||||
* for.
|
||||
* @param {Cart || Order} cart - the context in which the price should be
|
||||
* @param {ShippingData} data - the shipping data to retrieve the price.
|
||||
* @param {Cart | Order} cart - the context in which the price should be
|
||||
* retrieved.
|
||||
* @returns {Promise<Number>} the price of the shipping option.
|
||||
* @return {Promise<Number>} the price of the shipping option.
|
||||
*/
|
||||
async getPrice_(option, data, cart) {
|
||||
if (option.price_type === "calculated") {
|
||||
|
||||
@@ -121,7 +121,7 @@ class SwapService extends BaseService {
|
||||
"cart.total",
|
||||
]
|
||||
|
||||
const totalsToSelect = select.filter(v => totalFields.includes(v))
|
||||
const totalsToSelect = select.filter((v) => totalFields.includes(v))
|
||||
if (totalsToSelect.length > 0) {
|
||||
const relationSet = new Set(relations)
|
||||
relationSet.add("cart")
|
||||
@@ -132,7 +132,7 @@ class SwapService extends BaseService {
|
||||
relationSet.add("cart.region")
|
||||
relations = [...relationSet]
|
||||
|
||||
select = select.filter(v => !totalFields.includes(v))
|
||||
select = select.filter((v) => !totalFields.includes(v))
|
||||
}
|
||||
|
||||
return {
|
||||
@@ -175,9 +175,8 @@ class SwapService extends BaseService {
|
||||
|
||||
const validatedId = this.validateId_(id)
|
||||
|
||||
const { totalsToSelect, ...newConfig } = this.transformQueryForTotals_(
|
||||
config
|
||||
)
|
||||
const { totalsToSelect, ...newConfig } =
|
||||
this.transformQueryForTotals_(config)
|
||||
|
||||
const query = this.buildQuery_({ id: validatedId }, newConfig)
|
||||
|
||||
@@ -256,7 +255,7 @@ class SwapService extends BaseService {
|
||||
*/
|
||||
validateReturnItems_(order, returnItems) {
|
||||
return returnItems.map(({ item_id, quantity }) => {
|
||||
const item = order.items.find(i => i.id === item_id)
|
||||
const item = order.items.find((i) => i.id === item_id)
|
||||
|
||||
// The item must exist in the order
|
||||
if (!item) {
|
||||
@@ -308,7 +307,7 @@ class SwapService extends BaseService {
|
||||
}
|
||||
) {
|
||||
const { no_notification, ...rest } = custom
|
||||
return this.atomicPhase_(async manager => {
|
||||
return this.atomicPhase_(async (manager) => {
|
||||
if (
|
||||
order.fulfillment_status === "not_fulfilled" ||
|
||||
order.payment_status !== "captured"
|
||||
@@ -381,7 +380,7 @@ class SwapService extends BaseService {
|
||||
}
|
||||
|
||||
async processDifference(swapId) {
|
||||
return this.atomicPhase_(async manager => {
|
||||
return this.atomicPhase_(async (manager) => {
|
||||
const swap = await this.retrieve(swapId, {
|
||||
relations: ["payment", "order", "order.payments"],
|
||||
})
|
||||
@@ -497,7 +496,7 @@ class SwapService extends BaseService {
|
||||
}
|
||||
|
||||
async update(swapId, update) {
|
||||
return this.atomicPhase_(async manager => {
|
||||
return this.atomicPhase_(async (manager) => {
|
||||
const swap = await this.retrieve(swapId)
|
||||
|
||||
if ("metadata" in update) {
|
||||
@@ -529,7 +528,7 @@ class SwapService extends BaseService {
|
||||
* the new cart.
|
||||
*/
|
||||
async createCart(swapId, customShippingOptions = []) {
|
||||
return this.atomicPhase_(async manager => {
|
||||
return this.atomicPhase_(async (manager) => {
|
||||
const swap = await this.retrieve(swapId, {
|
||||
relations: [
|
||||
"order",
|
||||
@@ -538,6 +537,8 @@ class SwapService extends BaseService {
|
||||
"order.swaps.additional_items",
|
||||
"order.discounts",
|
||||
"order.discounts.rule",
|
||||
"order.claims",
|
||||
"order.claims.additional_items",
|
||||
"additional_items",
|
||||
"return_order",
|
||||
"return_order.items",
|
||||
@@ -621,7 +622,13 @@ class SwapService extends BaseService {
|
||||
}
|
||||
}
|
||||
|
||||
const lineItem = allItems.find(i => i.id === r.item_id)
|
||||
if (order.claims && order.claims.length) {
|
||||
for (const c of order.claims) {
|
||||
allItems = [...allItems, ...c.additional_items]
|
||||
}
|
||||
}
|
||||
|
||||
const lineItem = allItems.find((i) => i.id === r.item_id)
|
||||
|
||||
const toCreate = {
|
||||
cart_id: cart.id,
|
||||
@@ -652,7 +659,7 @@ class SwapService extends BaseService {
|
||||
*
|
||||
*/
|
||||
async registerCartCompletion(swapId) {
|
||||
return this.atomicPhase_(async manager => {
|
||||
return this.atomicPhase_(async (manager) => {
|
||||
const swap = await this.retrieve(swapId, {
|
||||
relations: [
|
||||
"cart",
|
||||
@@ -784,7 +791,7 @@ class SwapService extends BaseService {
|
||||
* status.
|
||||
*/
|
||||
async receiveReturn(swapId, returnItems) {
|
||||
return this.atomicPhase_(async manager => {
|
||||
return this.atomicPhase_(async (manager) => {
|
||||
const swap = await this.retrieve(swapId, { relations: ["return_order"] })
|
||||
|
||||
if (swap.canceled_at) {
|
||||
@@ -825,7 +832,7 @@ class SwapService extends BaseService {
|
||||
* @returns {Promise<Swap>} the canceled swap.
|
||||
*/
|
||||
async cancel(swapId) {
|
||||
return this.atomicPhase_(async manager => {
|
||||
return this.atomicPhase_(async (manager) => {
|
||||
const swap = await this.retrieve(swapId, {
|
||||
relations: ["payment", "fulfillments", "return_order"],
|
||||
})
|
||||
@@ -891,7 +898,7 @@ class SwapService extends BaseService {
|
||||
) {
|
||||
const { metadata, no_notification } = config
|
||||
|
||||
return this.atomicPhase_(async manager => {
|
||||
return this.atomicPhase_(async (manager) => {
|
||||
const swap = await this.retrieve(swapId, {
|
||||
relations: [
|
||||
"payment",
|
||||
@@ -951,7 +958,7 @@ class SwapService extends BaseService {
|
||||
is_swap: true,
|
||||
no_notification: evaluatedNoNotification,
|
||||
},
|
||||
swap.additional_items.map(i => ({
|
||||
swap.additional_items.map((i) => ({
|
||||
item_id: i.id,
|
||||
quantity: i.quantity,
|
||||
})),
|
||||
@@ -968,7 +975,7 @@ class SwapService extends BaseService {
|
||||
// Update all line items to reflect fulfillment
|
||||
for (const item of swap.additional_items) {
|
||||
const fulfillmentItem = successfullyFulfilled.find(
|
||||
f => item.id === f.item_id
|
||||
(f) => item.id === f.item_id
|
||||
)
|
||||
|
||||
if (fulfillmentItem) {
|
||||
@@ -1013,7 +1020,7 @@ class SwapService extends BaseService {
|
||||
* @returns updated swap
|
||||
*/
|
||||
async cancelFulfillment(fulfillmentId) {
|
||||
return this.atomicPhase_(async manager => {
|
||||
return this.atomicPhase_(async (manager) => {
|
||||
const canceled = await this.fulfillmentService_
|
||||
.withTransaction(manager)
|
||||
.cancelFulfillment(fulfillmentId)
|
||||
@@ -1056,7 +1063,7 @@ class SwapService extends BaseService {
|
||||
) {
|
||||
const { metadata, no_notification } = config
|
||||
|
||||
return this.atomicPhase_(async manager => {
|
||||
return this.atomicPhase_(async (manager) => {
|
||||
const swap = await this.retrieve(swapId, {
|
||||
relations: ["additional_items"],
|
||||
})
|
||||
@@ -1082,7 +1089,7 @@ class SwapService extends BaseService {
|
||||
|
||||
// Go through all the additional items in the swap
|
||||
for (const i of swap.additional_items) {
|
||||
const shipped = shipment.items.find(si => si.item_id === i.id)
|
||||
const shipped = shipment.items.find((si) => si.item_id === i.id)
|
||||
if (shipped) {
|
||||
const shippedQty = (i.shipped_quantity || 0) + shipped.quantity
|
||||
await this.lineItemService_.withTransaction(manager).update(i.id, {
|
||||
@@ -1131,7 +1138,7 @@ class SwapService extends BaseService {
|
||||
const keyPath = `metadata.${key}`
|
||||
return this.swapModel_
|
||||
.updateOne({ _id: validatedId }, { $unset: { [keyPath]: "" } })
|
||||
.catch(err => {
|
||||
.catch((err) => {
|
||||
throw new MedusaError(MedusaError.Types.DB_ERROR, err.message)
|
||||
})
|
||||
}
|
||||
@@ -1144,7 +1151,7 @@ class SwapService extends BaseService {
|
||||
* @returns {Promise<Order>} the resulting order
|
||||
*/
|
||||
async registerReceived(id) {
|
||||
return this.atomicPhase_(async manager => {
|
||||
return this.atomicPhase_(async (manager) => {
|
||||
const swap = await this.retrieve(id, {
|
||||
relations: ["return_order", "return_order.items"],
|
||||
})
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import _ from "lodash"
|
||||
import { BaseService } from "medusa-interfaces"
|
||||
import { MedusaError } from "medusa-core-utils"
|
||||
import carts from "../api/routes/store/carts"
|
||||
|
||||
/**
|
||||
* A service that calculates total and subtotals for orders, carts etc..
|
||||
@@ -158,6 +159,13 @@ class TotalsService extends BaseService {
|
||||
}
|
||||
}
|
||||
|
||||
if (order.claims && order.claims.length) {
|
||||
for (const c of order.claims) {
|
||||
const claimItemIds = c.additional_items.map(el => el.id)
|
||||
itemIds = [...itemIds, ...claimItemIds]
|
||||
}
|
||||
}
|
||||
|
||||
const refunds = lineItems.map(i => {
|
||||
if (!itemIds.includes(i.id)) {
|
||||
throw new MedusaError(
|
||||
@@ -253,6 +261,12 @@ class TotalsService extends BaseService {
|
||||
}
|
||||
}
|
||||
|
||||
if (cart.claims && cart.claims.length) {
|
||||
for (const c of cart.claims) {
|
||||
merged = [...merged, ...c.additional_items]
|
||||
}
|
||||
}
|
||||
|
||||
const { type, allocation, value } = discount.rule
|
||||
if (allocation === "total") {
|
||||
let percentage = 0
|
||||
|
||||
Reference in New Issue
Block a user