PR review modifications

This commit is contained in:
olivermrbl committed 2021-02-19 17:42:18 +01:00
1 parent ea82b8a5e1
commit b65edfce06
14 files changed
+151 -259

No files matched your search

@@ -141,6 +141,58 @@ describe("/admin/draft-orders", () => {
expect(response.status).toEqual(200); expect(response.status).toEqual(200);
}); });
it("creates a draft order with product variant with custom price", async () => {
const api = useApi();
const payload = {
email: "oli@test.dk",
shipping_address_id: "oli-shipping",
items: [
{
variant_id: "test-variant",
quantity: 2,
metadata: {},
unit_price: 10000000,
},
],
region_id: "test-region",
customer_id: "oli-test",
shipping_methods: [
{
option_id: "test-option",
},
],
};
const response = await api
.post("/admin/draft-orders", payload, {
headers: {
Authorization: "Bearer test_token",
},
})
.catch((err) => {
console.log(err);
});
const created = await api
.get(`/admin/draft-orders/${response.data.draft_order.id}`, {
headers: {
Authorization: "Bearer test_token",
},
})
.catch((err) => {
console.log(err);
});
expect(response.status).toEqual(200);
expect(created.data.draft_order.cart.items[0]).toEqual(
expect.objectContaining({
variant_id: "test-variant",
unit_price: 10000000,
})
);
});
it("creates a draft order with created shipping address", async () => { it("creates a draft order with created shipping address", async () => {
const api = useApi(); const api = useApi();
@@ -239,7 +291,6 @@ describe("/admin/draft-orders", () => {
await adminSeeder(dbConnection); await adminSeeder(dbConnection);
await draftOrderSeeder(dbConnection); await draftOrderSeeder(dbConnection);
} catch (err) { } catch (err) {
console.log(err);
throw err; throw err;
} }
}); });
@@ -335,8 +386,6 @@ describe("/admin/draft-orders", () => {
expect(response.status).toEqual(200); expect(response.status).toEqual(200);
console.log(response.data.draft_orders);
expect(response.data.draft_orders).toEqual([]); expect(response.data.draft_orders).toEqual([]);
expect(response.data.count).toEqual(0); expect(response.data.count).toEqual(0);
}); });
@@ -46,11 +46,12 @@ describe("/store/carts (draft-orders)", () => {
await manager.query(`DELETE FROM "shipping_method"`); await manager.query(`DELETE FROM "shipping_method"`);
await manager.query(`DELETE FROM "shipping_option"`); await manager.query(`DELETE FROM "shipping_option"`);
await manager.query(`DELETE FROM "discount"`); await manager.query(`DELETE FROM "discount"`);
await manager.query(`DELETE FROM "draft_order"`);
await manager.query(`DELETE FROM "payment_provider"`); await manager.query(`DELETE FROM "payment_provider"`);
await manager.query(`DELETE FROM "payment_session"`); await manager.query(`DELETE FROM "payment_session"`);
await manager.query(`UPDATE "payment" SET order_id=NULL`); await manager.query(`UPDATE "payment" SET order_id=NULL`);
await manager.query(`UPDATE "draft_order" SET order_id=NULL`);
await manager.query(`DELETE FROM "order"`); await manager.query(`DELETE FROM "order"`);
await manager.query(`DELETE FROM "draft_order"`);
await manager.query(`DELETE FROM "cart"`); await manager.query(`DELETE FROM "cart"`);
await manager.query(`DELETE FROM "payment"`); await manager.query(`DELETE FROM "payment"`);
await manager.query(`DELETE FROM "customer"`); await manager.query(`DELETE FROM "customer"`);
@@ -52,25 +52,18 @@ export default async (req, res) => {
try { try {
const draftOrderService = req.scope.resolve("draftOrderService") const draftOrderService = req.scope.resolve("draftOrderService")
const entityManager = req.scope.resolve("manager")
await entityManager.transaction(async manager => { const requiresShipping = value.requires_shipping
const requiresShipping = value.requires_shipping delete value.requires_shipping
delete value.requires_shipping
let draftOrder = await draftOrderService let draftOrder = await draftOrderService.create(value, requiresShipping)
.withTransaction(manager)
.create(value, requiresShipping)
draftOrder = await draftOrderService draftOrder = await draftOrderService.retrieve(draftOrder.id, {
.withTransaction(manager) relations: defaultRelations,
.retrieve(draftOrder.id, { select: defaultFields,
relations: defaultRelations,
select: defaultFields,
})
res.status(200).json({ draft_order: draftOrder })
}) })
res.status(200).json({ draft_order: draftOrder })
} catch (err) { } catch (err) {
throw err throw err
} }
@@ -43,7 +43,8 @@ export default async (req, res) => {
value.variant_id, value.variant_id,
draftOrder.cart.region_id, draftOrder.cart.region_id,
value.quantity, value.quantity,
value.metadata value.metadata,
value.unit_price
) )
await cartService await cartService
@@ -8,11 +8,44 @@ export default async (req, res) => {
try { try {
const draftOrderService = req.scope.resolve("draftOrderService") const draftOrderService = req.scope.resolve("draftOrderService")
const paymentProviderService = req.scope.resolve("paymentProviderService")
const orderService = req.scope.resolve("orderService") const orderService = req.scope.resolve("orderService")
const cartService = req.scope.resolve("cartService")
const entityManager = req.scope.resolve("manager")
const createdOrder = await draftOrderService.registerSystemPayment(id) let result
await entityManager.transaction(async manager => {
const draftOrder = await draftOrderService
.withTransaction(manager)
.retrieve(id)
const order = await orderService.retrieve(createdOrder.id, { const cart = await cartService
.withTransaction(manager)
.retrieve(draftOrder.cart_id, {
select: ["total"],
relations: ["discounts", "shipping_methods", "region", "items"],
})
await paymentProviderService
.withTransaction(manager)
.createSession("system", cart)
await cartService
.withTransaction(manager)
.setPaymentSession(cart.id, "system")
await cartService.withTransaction(manager).authorizePayment(cart.id)
result = await orderService
.withTransaction(manager)
.createFromCart(cart.id)
await draftOrderService
.withTransaction(manager)
.registerCartCompletion(draftOrder.id, result.id)
})
const order = await orderService.retrieve(result.id, {
relations: defaultOrderRelations, relations: defaultOrderRelations,
select: defaultOrderFields, select: defaultOrderFields,
}) })
@@ -12,7 +12,6 @@ export default async (req, res) => {
.optional(), .optional(),
billing_address: Validator.object().optional(), billing_address: Validator.object().optional(),
shipping_address: Validator.object().optional(), shipping_address: Validator.object().optional(),
discounts: Validator.array() discounts: Validator.array()
.items({ .items({
code: Validator.string(), code: Validator.string(),
@@ -29,36 +28,24 @@ export default async (req, res) => {
try { try {
const draftOrderService = req.scope.resolve("draftOrderService") const draftOrderService = req.scope.resolve("draftOrderService")
const cartService = req.scope.resolve("cartService") const cartService = req.scope.resolve("cartService")
const entityManager = req.scope.resolve("manager")
await entityManager.transaction(async manager => { const draftOrder = await draftOrderService.retrieve(id)
const draftOrder = await draftOrderService
.withTransaction(manager)
.retrieve(id)
if ( if (draftOrder.status === "completed" || draftOrder.status === "awaiting") {
draftOrder.status === "completed" || throw new MedusaError(
draftOrder.status === "awaiting" MedusaError.Types.NOT_ALLOWED,
) { "You are only allowed to update open draft orders"
throw new MedusaError( )
MedusaError.Types.NOT_ALLOWED, }
"You are only allowed to update open draft orders"
)
}
await cartService await cartService.update(draftOrder.cart_id, value)
.withTransaction(manager)
.update(draftOrder.cart_id, value)
draftOrder.cart = await cartService draftOrder.cart = await cartService.retrieve(draftOrder.cart_id, {
.withTransaction(manager) relations: defaultCartRelations,
.retrieve(draftOrder.cart_id, { select: defaultCartFields,
relations: defaultCartRelations,
select: defaultCartFields,
})
res.status(200).json({ draft_order: draftOrder })
}) })
res.status(200).json({ draft_order: draftOrder })
} catch (err) { } catch (err) {
throw err throw err
} }
@@ -17,7 +17,6 @@ import { Cart } from "./cart"
import { Swap } from "./swap" import { Swap } from "./swap"
import { Return } from "./return" import { Return } from "./return"
import { ShippingOption } from "./shipping-option" import { ShippingOption } from "./shipping-option"
import { DraftOrder } from "./draft-order"
@Check( @Check(
`"claim_order_id" IS NOT NULL OR "order_id" IS NOT NULL OR "cart_id" IS NOT NULL OR "swap_id" IS NOT NULL OR "return_id" IS NOT NULL` `"claim_order_id" IS NOT NULL OR "order_id" IS NOT NULL OR "cart_id" IS NOT NULL OR "swap_id" IS NOT NULL OR "return_id" IS NOT NULL`
@@ -179,7 +179,8 @@ describe("DraftOrderService", () => {
"test-variant", "test-variant",
"test-region", "test-region",
2, 2,
{} {},
undefined
) )
expect(lineItemService.create).toHaveBeenCalledTimes(1) expect(lineItemService.create).toHaveBeenCalledTimes(1)
@@ -216,123 +217,4 @@ describe("DraftOrderService", () => {
} }
}) })
}) })
describe("registerSystemPayment", () => {
let result
const shippingOptionService = {
update: jest.fn(),
withTransaction: function() {
return this
},
}
const lineItemService = {
update: jest.fn(),
withTransaction: function() {
return this
},
}
const cartService = {
retrieve: jest.fn().mockImplementation(data =>
Promise.resolve({
id: "test-cart",
total: 1000,
region_id: "test-region",
region: {
id: "test-region",
currency_code: "usd",
tax_rate: 0,
},
items: [{ id: "test-item" }],
discounts: [],
email: "oli@test.dk",
customer_id: "test-customer",
draft_order_id: "test-draft-order",
metadata: {},
})
),
withTransaction: function() {
return this
},
}
const draftOrderRepository = MockRepository({
findOne: () =>
Promise.resolve({ id: "test-draft-order", cart_id: "test-cart" }),
})
const orderRepository = MockRepository({
create: d => ({ id: "test-order", ...d }),
})
const paymentRepository = MockRepository({
create: d => ({
...d,
}),
})
const draftOrderService = new DraftOrderService({
manager: MockManager,
cartService,
shippingOptionService,
lineItemService,
paymentRepository,
draftOrderRepository,
orderRepository,
eventBusService,
})
beforeEach(async () => {
jest.clearAllMocks()
})
it("registers system payment", async () => {
await draftOrderService.registerSystemPayment("test-draft-order")
expect(cartService.retrieve).toHaveBeenCalledTimes(1)
expect(cartService.retrieve).toHaveBeenCalledWith("test-cart", {
relations: ["discounts", "shipping_methods", "region", "items"],
select: ["total"],
})
expect(paymentRepository.create).toHaveBeenCalledTimes(1)
expect(paymentRepository.create).toHaveBeenCalledWith({
provider_id: "system",
amount: 1000,
currency_code: "usd",
data: {},
})
expect(orderRepository.create).toHaveBeenCalledTimes(1)
expect(orderRepository.create).toHaveBeenCalledWith({
cart_id: "test-cart",
discounts: [],
region_id: "test-region",
discounts: [],
email: "oli@test.dk",
customer_id: "test-customer",
draft_order_id: "test-draft-order",
tax_rate: 0,
payment_status: "awaiting",
currency_code: "usd",
metadata: {},
payments: [
{
provider_id: "system",
amount: 1000,
currency_code: "usd",
data: {},
},
],
})
expect(draftOrderRepository.save).toHaveBeenCalledTimes(1)
expect(draftOrderRepository.save).toHaveBeenCalledWith({
id: "test-draft-order",
cart_id: "test-cart",
order_id: "test-order",
status: "completed",
})
})
})
}) })
+1
View File
@@ -998,6 +998,7 @@ class CartService extends BaseService {
// The region must have the provider id in its providers array // The region must have the provider id in its providers array
if ( if (
providerId !== "system" &&
!( !(
cart.region.payment_providers.length && cart.region.payment_providers.length &&
cart.region.payment_providers.find(({ id }) => providerId === id) cart.region.payment_providers.find(({ id }) => providerId === id)
+2 -83
View File
@@ -290,7 +290,8 @@ class DraftOrderService extends BaseService {
item.variant_id, item.variant_id,
data.region_id, data.region_id,
item.quantity, item.quantity,
item.metadata item.metadata,
item.unit_price
) )
const variant = await this.productVariantService_ const variant = await this.productVariantService_
@@ -327,88 +328,6 @@ class DraftOrderService extends BaseService {
}) })
} }
/**
* Registers a system payment and creates an order
* @param {string} doId - id of draft order to register payment for
* @return {Promise<Order>} the created order
*/
async registerSystemPayment(doId) {
return this.atomicPhase_(async manager => {
const draftOrder = await this.retrieve(doId)
const draftOrderCart = await this.cartService_
.withTransaction(manager)
.retrieve(draftOrder.cart_id, {
select: ["total"],
relations: ["discounts", "shipping_methods", "region", "items"],
})
const orderRepo = manager.getCustomRepository(this.orderRepository_)
const draftOrderRepo = manager.getCustomRepository(
this.draftOrderRepository_
)
const paymentRepo = manager.getCustomRepository(this.paymentRepository_)
const created = paymentRepo.create({
provider_id: "system",
amount: draftOrderCart.total,
currency_code: draftOrderCart.region.currency_code,
data: {},
})
const toCreate = {
payment_status: "awaiting",
discounts: draftOrderCart.discounts,
region_id: draftOrderCart.region_id,
email: draftOrderCart.email,
customer_id: draftOrderCart.customer_id,
draft_order_id: draftOrder.id,
cart_id: draftOrderCart.id,
tax_rate: draftOrderCart.region.tax_rate,
currency_code: draftOrderCart.region.currency_code,
metadata: draftOrderCart.metadata || {},
payments: [created],
}
if (draftOrderCart.shipping_address_id) {
toCreate.shipping_address_id = draftOrderCart.shipping_address_id
}
if (draftOrderCart.billing_address_id) {
toCreate.billing_address_id = draftOrderCart.billing_address_id
}
if (draftOrderCart.shipping_methods) {
toCreate.shipping_methods = draftOrderCart.shipping_methods
}
const o = orderRepo.create(toCreate)
const result = await orderRepo.save(o)
if (draftOrderCart.shipping_methods) {
for (const method of draftOrderCart.shipping_methods) {
await this.shippingOptionService_
.withTransaction(manager)
.updateShippingMethod(method.id, { order_id: result.id })
}
}
for (const item of draftOrderCart.items) {
await this.lineItemService_
.withTransaction(manager)
.update(item.id, { order_id: result.id })
}
draftOrder.status = "completed"
draftOrder.order_id = result.id
await draftOrderRepo.save(draftOrder)
return result
})
}
/** /**
* Registers a draft order as completed, when an order has been completed. * Registers a draft order as completed, when an order has been completed.
* @param {string} doId - id of draft order to complete * @param {string} doId - id of draft order to complete
+10 -5
View File
@@ -89,17 +89,22 @@ class LineItemService extends BaseService {
return lineItem return lineItem
} }
async generate(variantId, regionId, quantity, metadata = {}) { async generate(variantId, regionId, quantity, metadata = {}, unitPrice) {
const variant = await this.productVariantService_.retrieve(variantId, { const variant = await this.productVariantService_.retrieve(variantId, {
relations: ["product"], relations: ["product"],
}) })
const region = await this.regionService_.retrieve(regionId) const region = await this.regionService_.retrieve(regionId)
const price = await this.productVariantService_.getRegionPrice( let price
variant.id, if (unitPrice) {
region.id price = unitPrice
) } else {
price = await this.productVariantService_.getRegionPrice(
variant.id,
region.id
)
}
const toCreate = { const toCreate = {
unit_price: price, unit_price: price,
+19 -2
View File
@@ -41,6 +41,7 @@ class OrderService extends BaseService {
cartService, cartService,
addressRepository, addressRepository,
giftCardService, giftCardService,
draftOrderService,
eventBusService, eventBusService,
}) { }) {
super() super()
@@ -98,6 +99,9 @@ class OrderService extends BaseService {
/** @private @constant {SwapService} */ /** @private @constant {SwapService} */
this.swapService_ = swapService this.swapService_ = swapService
/** @private @constant {DraftOrderService} */
this.draftOrderService_ = draftOrderService
} }
withTransaction(manager) { withTransaction(manager) {
@@ -120,9 +124,11 @@ class OrderService extends BaseService {
cartService: this.cartService_, cartService: this.cartService_,
swapService: this.swapService_, swapService: this.swapService_,
giftCardService: this.giftCardService_, giftCardService: this.giftCardService_,
draftOrderService: this.draftOrderService_,
}) })
cloned.transactionManager_ = manager cloned.transactionManager_ = manager
cloned.manager_ = manager
return cloned return cloned
} }
@@ -482,7 +488,8 @@ class OrderService extends BaseService {
} }
const orderRepo = manager.getCustomRepository(this.orderRepository_) const orderRepo = manager.getCustomRepository(this.orderRepository_)
const o = await orderRepo.create({
const toCreate = {
payment_status: "awaiting", payment_status: "awaiting",
discounts: cart.discounts, discounts: cart.discounts,
gift_cards: cart.gift_cards, gift_cards: cart.gift_cards,
@@ -496,7 +503,17 @@ class OrderService extends BaseService {
tax_rate: region.tax_rate, tax_rate: region.tax_rate,
currency_code: region.currency_code, currency_code: region.currency_code,
metadata: cart.metadata || {}, metadata: cart.metadata || {},
}) }
if (cart.type === "draft_order") {
const draft = await this.draftOrderService_
.withTransaction(manager)
.retrieveByCartId(cart.id)
toCreate.draft_order_id = draft.id
}
const o = await orderRepo.create(toCreate)
const result = await orderRepo.save(o) const result = await orderRepo.save(o)
@@ -27,6 +27,7 @@ class PaymentProviderService extends BaseService {
const cloned = new PaymentProviderService(this.container_) const cloned = new PaymentProviderService(this.container_)
cloned.transactionManager_ = manager cloned.transactionManager_ = manager
cloned.manager_ = manager
return cloned return cloned
} }
@@ -11,6 +11,10 @@ class SystemProviderService extends BaseService {
return {} return {}
} }
async getStatus(_) {
return "authorized"
}
async getPaymentData(_) { async getPaymentData(_) {
return {} return {}
} }