From 051bb16dd7106a1c4a093647fdb8b74446785bfb Mon Sep 17 00:00:00 2001 From: Adrien de Peretti Date: Tue, 2 Aug 2022 10:04:43 +0200 Subject: [PATCH] chore(medusa): Add transactions in mutating actions 2 (#1853) * chore(medusa): Add transaction on mutation actions * chore(medusa): continue refactoring * chore(medusa): continue refactoring * chore(medusa): continue refactoring * feat(medusa): update invite service mock to provide a withTransaction * feat(medusa): Include pr feedback * feat(medusa): Cleanup idempotent places * feat(medusa): Cleanup idempotent places * feat(medusa): Better Cleanup idempotent places * feat(meudsa): cleanup transaction * fix(medusa): Create cart transaction usage * fix(medusa): Use the right variable * fix(medusa): Use the right variable * fix(medusa): Transaction usage in cart creation flow --- .../api/routes/admin/auth/create-session.ts | 12 +- .../routes/admin/batch/cancel-batch-job.ts | 8 +- .../routes/admin/batch/confirm-batch-job.ts | 8 +- .../routes/admin/batch/create-batch-job.ts | 10 +- .../routes/admin/collections/add-products.ts | 12 +- .../admin/collections/create-collection.ts | 7 +- .../admin/collections/delete-collection.ts | 8 +- .../admin/collections/remove-products.ts | 6 +- .../admin/collections/update-collection.ts | 7 +- .../customer-groups/add-customers-batch.ts | 15 +- .../customer-groups/create-customer-group.ts | 11 +- .../customer-groups/delete-customer-group.ts | 8 +- .../customer-groups/delete-customers-batch.ts | 15 +- .../customer-groups/update-customer-group.ts | 8 +- .../routes/admin/customers/create-customer.ts | 8 +- .../routes/admin/customers/update-customer.ts | 8 +- .../api/routes/admin/discounts/add-region.ts | 9 +- .../admin/discounts/create-condition.ts | 15 +- .../routes/admin/discounts/create-discount.ts | 17 +- .../admin/discounts/create-dynamic-code.ts | 11 +- .../admin/discounts/delete-condition.ts | 8 +- .../routes/admin/discounts/delete-discount.ts | 8 +- .../admin/discounts/delete-dynamic-code.ts | 8 +- .../routes/admin/discounts/remove-region.ts | 8 +- .../admin/discounts/update-condition.ts | 10 +- .../routes/admin/discounts/update-discount.ts | 11 +- .../admin/draft-orders/create-draft-order.ts | 11 +- .../admin/draft-orders/create-line-item.ts | 14 +- .../admin/draft-orders/delete-draft-order.ts | 9 +- .../admin/draft-orders/register-payment.ts | 2 +- .../admin/draft-orders/update-draft-order.ts | 26 +- .../admin/gift-cards/create-gift-card.ts | 10 +- .../admin/gift-cards/delete-gift-card.ts | 7 +- .../admin/gift-cards/update-gift-card.ts | 8 +- .../api/routes/admin/invites/accept-invite.ts | 8 +- .../api/routes/admin/invites/create-invite.ts | 9 +- .../api/routes/admin/invites/delete-invite.ts | 6 +- .../api/routes/admin/invites/resend-invite.ts | 6 +- .../src/api/routes/admin/notes/create-note.ts | 14 +- .../src/api/routes/admin/notes/delete-note.ts | 6 +- .../src/api/routes/admin/notes/update-note.ts | 8 +- .../notifications/resend-notification.ts | 8 +- .../admin/orders/add-shipping-method.ts | 17 +- .../api/routes/admin/orders/archive-order.ts | 6 +- .../api/routes/admin/orders/cancel-claim.ts | 8 +- .../admin/orders/cancel-fulfillment-claim.ts | 8 +- .../admin/orders/cancel-fulfillment-swap.ts | 8 +- .../routes/admin/orders/cancel-fulfillment.ts | 8 +- .../api/routes/admin/orders/cancel-order.ts | 6 +- .../api/routes/admin/orders/cancel-swap.ts | 6 +- .../routes/admin/orders/capture-payment.ts | 8 +- .../api/routes/admin/orders/complete-order.ts | 8 +- .../admin/orders/create-claim-shipment.ts | 16 +- .../api/routes/admin/orders/create-claim.ts | 271 +++++++++--------- .../routes/admin/orders/create-fulfillment.ts | 12 +- .../routes/admin/orders/create-shipment.ts | 28 +- .../admin/orders/create-swap-shipment.ts | 16 +- .../api/routes/admin/orders/create-swap.ts | 199 ++++++------- .../api/routes/admin/orders/fulfill-swap.ts | 14 +- .../api/routes/admin/orders/refund-payment.ts | 18 +- .../api/routes/admin/orders/request-return.ts | 218 +++++++------- .../api/routes/admin/orders/update-claim.ts | 8 +- .../api/routes/admin/orders/update-order.ts | 8 +- .../src/api/routes/store/carts/create-cart.ts | 56 ++-- .../medusa/src/services/__mocks__/invite.js | 4 + packages/medusa/src/services/cart.ts | 2 +- packages/medusa/src/services/inventory.js | 4 +- packages/medusa/src/services/pricing.ts | 60 ++-- 68 files changed, 883 insertions(+), 542 deletions(-) diff --git a/packages/medusa/src/api/routes/admin/auth/create-session.ts b/packages/medusa/src/api/routes/admin/auth/create-session.ts index f6d5a9bd91..84911a684c 100644 --- a/packages/medusa/src/api/routes/admin/auth/create-session.ts +++ b/packages/medusa/src/api/routes/admin/auth/create-session.ts @@ -4,6 +4,7 @@ import { validator } from "../../../../utils/validator" import { IsEmail, IsNotEmpty, IsString } from "class-validator" import AuthService from "../../../../services/auth" import { MedusaError } from "medusa-core-utils" +import { EntityManager } from "typeorm"; /** * @oas [post] /auth @@ -37,10 +38,13 @@ export default async (req, res) => { const validated = await validator(AdminPostAuthReq, req.body) const authService: AuthService = req.scope.resolve("authService") - const result = await authService.authenticate( - validated.email, - validated.password - ) + const manager: EntityManager = req.scope.resolve("manager") + const result = await manager.transaction(async (transactionManager) => { + return await authService.withTransaction(transactionManager).authenticate( + validated.email, + validated.password + ) + }) if (result.success && result.user) { // Add JWT to cookie diff --git a/packages/medusa/src/api/routes/admin/batch/cancel-batch-job.ts b/packages/medusa/src/api/routes/admin/batch/cancel-batch-job.ts index f5dcaab4b4..d42da29e5b 100644 --- a/packages/medusa/src/api/routes/admin/batch/cancel-batch-job.ts +++ b/packages/medusa/src/api/routes/admin/batch/cancel-batch-job.ts @@ -1,4 +1,5 @@ import { BatchJobService } from "../../../../services" +import { EntityManager } from "typeorm" /** * @oas [post] /batch-jobs/{id}/cancel @@ -24,7 +25,12 @@ export default async (req, res) => { let batch_job = req.batch_job const batchJobService: BatchJobService = req.scope.resolve("batchJobService") - batch_job = await batchJobService.cancel(batch_job) + const manager: EntityManager = req.scope.resolve("manager") + batch_job = await manager.transaction(async (transactionManager) => { + return await batchJobService + .withTransaction(transactionManager) + .cancel(batch_job) + }) res.json({ batch_job }) } diff --git a/packages/medusa/src/api/routes/admin/batch/confirm-batch-job.ts b/packages/medusa/src/api/routes/admin/batch/confirm-batch-job.ts index b5bb86903e..8352327e1c 100644 --- a/packages/medusa/src/api/routes/admin/batch/confirm-batch-job.ts +++ b/packages/medusa/src/api/routes/admin/batch/confirm-batch-job.ts @@ -1,4 +1,5 @@ import { BatchJobService } from "../../../../services" +import { EntityManager } from "typeorm" /** * @oas [post] /batch-jobs/{id}/confirm @@ -25,7 +26,12 @@ export default async (req, res) => { let batch_job = req.batch_job const batchJobService: BatchJobService = req.scope.resolve("batchJobService") - batch_job = await batchJobService.confirm(batch_job) + const manager: EntityManager = req.scope.resolve("manager") + batch_job = await manager.transaction(async (transactionManager) => { + return await batchJobService + .withTransaction(transactionManager) + .confirm(batch_job) + }) res.json({ batch_job }) } diff --git a/packages/medusa/src/api/routes/admin/batch/create-batch-job.ts b/packages/medusa/src/api/routes/admin/batch/create-batch-job.ts index af7d022dcc..81c70c2936 100644 --- a/packages/medusa/src/api/routes/admin/batch/create-batch-job.ts +++ b/packages/medusa/src/api/routes/admin/batch/create-batch-job.ts @@ -2,6 +2,7 @@ import { IsBoolean, IsObject, IsOptional, IsString } from "class-validator" import BatchJobService from "../../../../services/batch-job" import { validator } from "../../../../utils/validator" import { BatchJob } from "../../../../models" +import { EntityManager } from "typeorm" /** * @oas [post] /batch-jobs @@ -36,9 +37,12 @@ export default async (req, res) => { const userId = req.user.id ?? req.user.userId - const batch_job = await batchJobService.create({ - ...toCreate, - created_by: userId, + const manager: EntityManager = req.scope.resolve("manager") + const batch_job = await manager.transaction(async (transactionManager) => { + return await batchJobService.withTransaction(transactionManager).create({ + ...toCreate, + created_by: userId, + }) }) res.status(201).json({ batch_job }) diff --git a/packages/medusa/src/api/routes/admin/collections/add-products.ts b/packages/medusa/src/api/routes/admin/collections/add-products.ts index 65eedaf59c..4b883081c3 100644 --- a/packages/medusa/src/api/routes/admin/collections/add-products.ts +++ b/packages/medusa/src/api/routes/admin/collections/add-products.ts @@ -1,6 +1,7 @@ import { ArrayNotEmpty, IsString } from "class-validator" import ProductCollectionService from "../../../../services/product-collection" import { Request, Response } from "express" +import { EntityManager } from "typeorm"; /** * @oas [post] /collections/{id}/products/batch @@ -37,10 +38,13 @@ export default async (req: Request, res: Response) => { "productCollectionService" ) - const collection = await productCollectionService.addProducts( - id, - validatedBody.product_ids - ) + const manager: EntityManager = req.scope.resolve("manager") + const collection = await manager.transaction(async (transactionManager) => { + return await productCollectionService.withTransaction(transactionManager).addProducts( + id, + validatedBody.product_ids + ) + }) res.status(200).json({ collection }) } diff --git a/packages/medusa/src/api/routes/admin/collections/create-collection.ts b/packages/medusa/src/api/routes/admin/collections/create-collection.ts index 509cdd909c..d70e7b3cef 100644 --- a/packages/medusa/src/api/routes/admin/collections/create-collection.ts +++ b/packages/medusa/src/api/routes/admin/collections/create-collection.ts @@ -1,6 +1,7 @@ import { IsNotEmpty, IsObject, IsOptional, IsString } from "class-validator" import ProductCollectionService from "../../../../services/product-collection" import { Request, Response } from "express" +import { EntityManager } from "typeorm"; /** * @oas [post] /collections @@ -43,7 +44,11 @@ export default async (req: Request, res: Response) => { "productCollectionService" ) - const created = await productCollectionService.create(validatedBody) + const manager: EntityManager = req.scope.resolve("manager") + const created = await manager.transaction(async (transactionManager) => { + return await productCollectionService.withTransaction(transactionManager).create(validatedBody) + }) + const collection = await productCollectionService.retrieve(created.id) res.status(200).json({ collection }) diff --git a/packages/medusa/src/api/routes/admin/collections/delete-collection.ts b/packages/medusa/src/api/routes/admin/collections/delete-collection.ts index 60cbd7d412..101466b29b 100644 --- a/packages/medusa/src/api/routes/admin/collections/delete-collection.ts +++ b/packages/medusa/src/api/routes/admin/collections/delete-collection.ts @@ -1,5 +1,6 @@ import ProductCollectionService from "../../../../services/product-collection" import { Request, Response } from "express" +import { EntityManager } from "typeorm"; /** * @oas [delete] /collections/{id} @@ -33,7 +34,12 @@ export default async (req: Request, res: Response) => { const productCollectionService: ProductCollectionService = req.scope.resolve( "productCollectionService" ) - await productCollectionService.delete(id) + + const manager: EntityManager = req.scope.resolve("manager") + await manager.transaction(async (transactionManager) => { + return await productCollectionService.withTransaction(transactionManager).delete(id) + }) + res.json({ id, diff --git a/packages/medusa/src/api/routes/admin/collections/remove-products.ts b/packages/medusa/src/api/routes/admin/collections/remove-products.ts index 862b7c77eb..79fe62c1b4 100644 --- a/packages/medusa/src/api/routes/admin/collections/remove-products.ts +++ b/packages/medusa/src/api/routes/admin/collections/remove-products.ts @@ -1,6 +1,7 @@ import { ArrayNotEmpty, IsString } from "class-validator" import ProductCollectionService from "../../../../services/product-collection" import { Request, Response } from "express" +import { EntityManager } from "typeorm"; /** * @oas [delete] /collections/{id}/products/batch @@ -37,7 +38,10 @@ export default async (req: Request, res: Response) => { "productCollectionService" ) - await productCollectionService.removeProducts(id, validatedBody.product_ids) + const manager: EntityManager = req.scope.resolve("manager") + await manager.transaction(async (transactionManager) => { + return await productCollectionService.withTransaction(transactionManager).removeProducts(id, validatedBody.product_ids) + }) res.json({ id, diff --git a/packages/medusa/src/api/routes/admin/collections/update-collection.ts b/packages/medusa/src/api/routes/admin/collections/update-collection.ts index 072d8c22d2..95fd59f9a7 100644 --- a/packages/medusa/src/api/routes/admin/collections/update-collection.ts +++ b/packages/medusa/src/api/routes/admin/collections/update-collection.ts @@ -1,6 +1,7 @@ import { IsObject, IsOptional, IsString } from "class-validator" import ProductCollectionService from "../../../../services/product-collection" import { Request, Response } from "express" +import { EntityManager } from "typeorm"; /** * @oas [post] /collections/{id} * operationId: "PostCollectionsCollection" @@ -43,7 +44,11 @@ export default async (req: Request, res: Response) => { "productCollectionService" ) - const updated = await productCollectionService.update(id, validatedBody) + const manager: EntityManager = req.scope.resolve("manager") + const updated = await manager.transaction(async (transactionManager) => { + return await productCollectionService.withTransaction(transactionManager).update(id, validatedBody) + }) + const collection = await productCollectionService.retrieve(updated.id) res.status(200).json({ collection }) diff --git a/packages/medusa/src/api/routes/admin/customer-groups/add-customers-batch.ts b/packages/medusa/src/api/routes/admin/customer-groups/add-customers-batch.ts index 96aa4b5ead..dcdf5a0090 100644 --- a/packages/medusa/src/api/routes/admin/customer-groups/add-customers-batch.ts +++ b/packages/medusa/src/api/routes/admin/customer-groups/add-customers-batch.ts @@ -4,6 +4,7 @@ import { CustomerGroupService } from "../../../../services" import { CustomerGroupsBatchCustomer } from "../../../../types/customer-groups" import { validator } from "../../../../utils/validator" import { Request, Response } from "express" +import { EntityManager } from "typeorm" /** * @oas [post] /customer-groups/{id}/customers/batch @@ -38,10 +39,18 @@ export default async (req: Request, res: Response) => { "customerGroupService" ) - const customer_group = await customerGroupService.addCustomers( - id, - validated.customer_ids.map(({ id }) => id) + const manager: EntityManager = req.scope.resolve("manager") + const customer_group = await manager.transaction( + async (transactionManager) => { + return await customerGroupService + .withTransaction(transactionManager) + .addCustomers( + id, + validated.customer_ids.map(({ id }) => id) + ) + } ) + res.status(200).json({ customer_group }) } diff --git a/packages/medusa/src/api/routes/admin/customer-groups/create-customer-group.ts b/packages/medusa/src/api/routes/admin/customer-groups/create-customer-group.ts index 633bd94e2a..6d0b9b292c 100644 --- a/packages/medusa/src/api/routes/admin/customer-groups/create-customer-group.ts +++ b/packages/medusa/src/api/routes/admin/customer-groups/create-customer-group.ts @@ -2,6 +2,7 @@ import { IsObject, IsOptional, IsString } from "class-validator" import { CustomerGroupService } from "../../../../services" import { validator } from "../../../../utils/validator" import { Request, Response } from "express" +import { EntityManager } from "typeorm" /** * @oas [post] /customer-groups @@ -32,7 +33,15 @@ export default async (req: Request, res: Response) => { "customerGroupService" ) - const customerGroup = await customerGroupService.create(validated) + const manager: EntityManager = req.scope.resolve("manager") + const customerGroup = await manager.transaction( + async (transactionManager) => { + return await customerGroupService + .withTransaction(transactionManager) + .create(validated) + } + ) + res.status(200).json({ customer_group: customerGroup }) } diff --git a/packages/medusa/src/api/routes/admin/customer-groups/delete-customer-group.ts b/packages/medusa/src/api/routes/admin/customer-groups/delete-customer-group.ts index 4c2ba7f2ef..05015b984b 100644 --- a/packages/medusa/src/api/routes/admin/customer-groups/delete-customer-group.ts +++ b/packages/medusa/src/api/routes/admin/customer-groups/delete-customer-group.ts @@ -1,5 +1,6 @@ import { CustomerGroupService } from "../../../../services" import { Request, Response } from "express" +import { EntityManager } from "typeorm" /** * @oas [delete] /customer-groups/{id} @@ -35,7 +36,12 @@ export default async (req: Request, res: Response) => { "customerGroupService" ) - await customerGroupService.delete(id) + const manager: EntityManager = req.scope.resolve("manager") + await manager.transaction(async (transactionManager) => { + return await customerGroupService + .withTransaction(transactionManager) + .delete(id) + }) res.json({ id: id, diff --git a/packages/medusa/src/api/routes/admin/customer-groups/delete-customers-batch.ts b/packages/medusa/src/api/routes/admin/customer-groups/delete-customers-batch.ts index fbca982372..658518bb78 100644 --- a/packages/medusa/src/api/routes/admin/customer-groups/delete-customers-batch.ts +++ b/packages/medusa/src/api/routes/admin/customer-groups/delete-customers-batch.ts @@ -4,6 +4,7 @@ import { CustomerGroupService } from "../../../../services" import { CustomerGroupsBatchCustomer } from "../../../../types/customer-groups" import { validator } from "../../../../utils/validator" import { Request, Response } from "express" +import { EntityManager } from "typeorm" /** * @oas [delete] /customer-groups/{id}/customers/batch @@ -38,10 +39,18 @@ export default async (req: Request, res: Response) => { "customerGroupService" ) - const customer_group = await customerGroupService.removeCustomer( - id, - validated.customer_ids.map(({ id }) => id) + const manager: EntityManager = req.scope.resolve("manager") + const customer_group = await manager.transaction( + async (transactionManager) => { + return await customerGroupService + .withTransaction(transactionManager) + .removeCustomer( + id, + validated.customer_ids.map(({ id }) => id) + ) + } ) + res.status(200).json({ customer_group }) } diff --git a/packages/medusa/src/api/routes/admin/customer-groups/update-customer-group.ts b/packages/medusa/src/api/routes/admin/customer-groups/update-customer-group.ts index 1d6a5e5889..d985389be4 100644 --- a/packages/medusa/src/api/routes/admin/customer-groups/update-customer-group.ts +++ b/packages/medusa/src/api/routes/admin/customer-groups/update-customer-group.ts @@ -5,6 +5,7 @@ import { CustomerGroupService } from "../../../../services" import { FindParams } from "../../../../types/common" import { validator } from "../../../../utils/validator" import { Request, Response } from "express" +import { EntityManager } from "typeorm" /** * @oas [post] /customer-groups/{id} @@ -42,7 +43,12 @@ export default async (req: Request, res: Response) => { "customerGroupService" ) - await customerGroupService.update(id, validatedBody) + const manager: EntityManager = req.scope.resolve("manager") + await manager.transaction(async (transactionManager) => { + return await customerGroupService + .withTransaction(transactionManager) + .update(id, validatedBody) + }) let expandFields: string[] = [] if (validatedQuery.expand) { diff --git a/packages/medusa/src/api/routes/admin/customers/create-customer.ts b/packages/medusa/src/api/routes/admin/customers/create-customer.ts index 34e9960656..3ffe0d8adf 100644 --- a/packages/medusa/src/api/routes/admin/customers/create-customer.ts +++ b/packages/medusa/src/api/routes/admin/customers/create-customer.ts @@ -1,6 +1,7 @@ import { IsEmail, IsObject, IsOptional, IsString } from "class-validator" import { CustomerService } from "../../../../services" import { validator } from "../../../../utils/validator" +import { EntityManager } from "typeorm" /** * @oas [post] /customers @@ -30,7 +31,12 @@ export default async (req, res) => { const validated = await validator(AdminPostCustomersReq, req.body) const customerService: CustomerService = req.scope.resolve("customerService") - const customer = await customerService.create(validated) + const manager: EntityManager = req.scope.resolve("manager") + const customer = await manager.transaction(async (transactionManager) => { + return await customerService + .withTransaction(transactionManager) + .create(validated) + }) res.status(201).json({ customer }) } diff --git a/packages/medusa/src/api/routes/admin/customers/update-customer.ts b/packages/medusa/src/api/routes/admin/customers/update-customer.ts index 42d635875f..369fec61c8 100644 --- a/packages/medusa/src/api/routes/admin/customers/update-customer.ts +++ b/packages/medusa/src/api/routes/admin/customers/update-customer.ts @@ -12,6 +12,7 @@ import { validator } from "../../../../utils/validator" import { defaultAdminCustomersRelations } from "." import { Type } from "class-transformer" import { FindParams } from "../../../../types/common" +import { EntityManager } from "typeorm" /** * @oas [post] /customers/{id} @@ -83,7 +84,12 @@ export default async (req, res) => { ) } - await customerService.update(id, validatedBody) + const manager: EntityManager = req.scope.resolve("manager") + await manager.transaction(async (transactionManager) => { + return await customerService + .withTransaction(transactionManager) + .update(id, validatedBody) + }) let expandFields: string[] = [] if (validatedQuery.expand) { diff --git a/packages/medusa/src/api/routes/admin/discounts/add-region.ts b/packages/medusa/src/api/routes/admin/discounts/add-region.ts index 877c5c6d4b..0e89eba395 100644 --- a/packages/medusa/src/api/routes/admin/discounts/add-region.ts +++ b/packages/medusa/src/api/routes/admin/discounts/add-region.ts @@ -1,6 +1,7 @@ import { defaultAdminDiscountsFields, defaultAdminDiscountsRelations } from "." import { Discount } from "../../../.." import DiscountService from "../../../../services/discount" +import { EntityManager } from "typeorm" /** * @oas [post] /discounts/{id}/regions/{region_id} * operationId: "PostDiscountsDiscountRegionsRegion" @@ -26,7 +27,13 @@ export default async (req, res) => { const { discount_id, region_id } = req.params const discountService: DiscountService = req.scope.resolve("discountService") - await discountService.addRegion(discount_id, region_id) + + const manager: EntityManager = req.scope.resolve("manager") + await manager.transaction(async (transactionManager) => { + return await discountService + .withTransaction(transactionManager) + .addRegion(discount_id, region_id) + }) const discount: Discount = await discountService.retrieve(discount_id, { select: defaultAdminDiscountsFields, diff --git a/packages/medusa/src/api/routes/admin/discounts/create-condition.ts b/packages/medusa/src/api/routes/admin/discounts/create-condition.ts index 50ffb52e57..7ca4018c16 100644 --- a/packages/medusa/src/api/routes/admin/discounts/create-condition.ts +++ b/packages/medusa/src/api/routes/admin/discounts/create-condition.ts @@ -1,12 +1,12 @@ import { IsOptional, IsString } from "class-validator" import { defaultAdminDiscountsFields, defaultAdminDiscountsRelations } from "." -import { Discount } from "../../../../models/discount" -import { DiscountConditionOperator } from "../../../../models/discount-condition" +import { Discount, DiscountConditionOperator } from "../../../../models" import { DiscountService } from "../../../../services" import DiscountConditionService from "../../../../services/discount-condition" import { AdminUpsertConditionsReq } from "../../../../types/discount" import { getRetrieveConfig } from "../../../../utils/get-query-config" import { validator } from "../../../../utils/validator" +import { EntityManager } from "typeorm" /** * @oas [post] /discounts/{discount_id}/conditions * operationId: "PostDiscountsDiscountConditions" @@ -74,9 +74,14 @@ export default async (req, res) => { let discount = await discountService.retrieve(discount_id) - await conditionService.upsertCondition({ - ...validatedCondition, - rule_id: discount.rule_id, + const manager: EntityManager = req.scope.resolve("manager") + await manager.transaction(async (transactionManager) => { + return await conditionService + .withTransaction(transactionManager) + .upsertCondition({ + ...validatedCondition, + rule_id: discount.rule_id, + }) }) const config = getRetrieveConfig( diff --git a/packages/medusa/src/api/routes/admin/discounts/create-discount.ts b/packages/medusa/src/api/routes/admin/discounts/create-discount.ts index c8ae3d1f34..dc37984ff2 100644 --- a/packages/medusa/src/api/routes/admin/discounts/create-discount.ts +++ b/packages/medusa/src/api/routes/admin/discounts/create-discount.ts @@ -13,9 +13,12 @@ import { ValidateNested, } from "class-validator" import { defaultAdminDiscountsFields, defaultAdminDiscountsRelations } from "." -import { AllocationType, DiscountRuleType } from "../../../../models" -import { Discount } from "../../../../models/discount" -import { DiscountConditionOperator } from "../../../../models/discount-condition" +import { + AllocationType, + DiscountRuleType, + Discount, + DiscountConditionOperator, +} from "../../../../models" import DiscountService from "../../../../services/discount" import { AdminUpsertConditionsReq } from "../../../../types/discount" import { getRetrieveConfig } from "../../../../utils/get-query-config" @@ -23,6 +26,7 @@ import { validator } from "../../../../utils/validator" import { IsGreaterThan } from "../../../../utils/validators/greater-than" import { IsISO8601Duration } from "../../../../utils/validators/iso8601-duration" import { AdminPostDiscountsDiscountParams } from "./update-discount" +import { EntityManager } from "typeorm" /** * @oas [post] /discounts * operationId: "PostDiscounts" @@ -92,7 +96,12 @@ export default async (req, res) => { const discountService: DiscountService = req.scope.resolve("discountService") - const created = await discountService.create(validated) + const manager: EntityManager = req.scope.resolve("manager") + const created = await manager.transaction(async (transactionManager) => { + return await discountService + .withTransaction(transactionManager) + .create(validated) + }) const config = getRetrieveConfig( defaultAdminDiscountsFields, diff --git a/packages/medusa/src/api/routes/admin/discounts/create-dynamic-code.ts b/packages/medusa/src/api/routes/admin/discounts/create-dynamic-code.ts index 14e0b030f4..042b0df4b0 100644 --- a/packages/medusa/src/api/routes/admin/discounts/create-dynamic-code.ts +++ b/packages/medusa/src/api/routes/admin/discounts/create-dynamic-code.ts @@ -8,6 +8,7 @@ import { import { defaultAdminDiscountsFields, defaultAdminDiscountsRelations } from "." import DiscountService from "../../../../services/discount" import { validator } from "../../../../utils/validator" +import { EntityManager } from "typeorm" /** * @oas [post] /discounts/{id}/dynamic-codes * operationId: "PostDiscountsDiscountDynamicCodes" @@ -40,10 +41,12 @@ export default async (req, res) => { ) const discountService: DiscountService = req.scope.resolve("discountService") - const created = await discountService.createDynamicCode( - discount_id, - validated - ) + const manager: EntityManager = req.scope.resolve("manager") + const created = await manager.transaction(async (transactionManager) => { + return await discountService + .withTransaction(transactionManager) + .createDynamicCode(discount_id, validated) + }) const discount = await discountService.retrieve(created.id, { select: defaultAdminDiscountsFields, diff --git a/packages/medusa/src/api/routes/admin/discounts/delete-condition.ts b/packages/medusa/src/api/routes/admin/discounts/delete-condition.ts index 7cfd46a7b1..34e92e03cd 100644 --- a/packages/medusa/src/api/routes/admin/discounts/delete-condition.ts +++ b/packages/medusa/src/api/routes/admin/discounts/delete-condition.ts @@ -6,6 +6,7 @@ import { DiscountService } from "../../../../services" import DiscountConditionService from "../../../../services/discount-condition" import { getRetrieveConfig } from "../../../../utils/get-query-config" import { validator } from "../../../../utils/validator" +import { EntityManager } from "typeorm" /** * @oas [delete] /discounts/{discount_id}/conditions/{condition_id} @@ -79,7 +80,12 @@ export default async (req, res) => { ) } - await conditionService.delete(condition_id) + const manager: EntityManager = req.scope.resolve("manager") + await manager.transaction(async (transactionManager) => { + return await conditionService + .withTransaction(transactionManager) + .delete(condition_id) + }) const config = getRetrieveConfig( defaultAdminDiscountsFields, diff --git a/packages/medusa/src/api/routes/admin/discounts/delete-discount.ts b/packages/medusa/src/api/routes/admin/discounts/delete-discount.ts index e2db8b4ee6..c3fd605d4e 100644 --- a/packages/medusa/src/api/routes/admin/discounts/delete-discount.ts +++ b/packages/medusa/src/api/routes/admin/discounts/delete-discount.ts @@ -1,4 +1,5 @@ import DiscountService from "../../../../services/discount" +import { EntityManager } from "typeorm" /** * @oas [delete] /discounts/{id} @@ -30,7 +31,12 @@ export default async (req, res) => { const { discount_id } = req.params const discountService: DiscountService = req.scope.resolve("discountService") - await discountService.delete(discount_id) + const manager: EntityManager = req.scope.resolve("manager") + await manager.transaction(async (transactionManager) => { + return await discountService + .withTransaction(transactionManager) + .delete(discount_id) + }) res.json({ id: discount_id, diff --git a/packages/medusa/src/api/routes/admin/discounts/delete-dynamic-code.ts b/packages/medusa/src/api/routes/admin/discounts/delete-dynamic-code.ts index b198a93aeb..1f0ecc8ce4 100644 --- a/packages/medusa/src/api/routes/admin/discounts/delete-dynamic-code.ts +++ b/packages/medusa/src/api/routes/admin/discounts/delete-dynamic-code.ts @@ -1,5 +1,6 @@ import { defaultAdminDiscountsFields, defaultAdminDiscountsRelations } from "." import DiscountService from "../../../../services/discount" +import { EntityManager } from "typeorm" /** * @oas [delete] /discounts/{id}/dynamic-codes/{code} @@ -26,7 +27,12 @@ export default async (req, res) => { const { discount_id, code } = req.params const discountService: DiscountService = req.scope.resolve("discountService") - await discountService.deleteDynamicCode(discount_id, code) + const manager: EntityManager = req.scope.resolve("manager") + await manager.transaction(async (transactionManager) => { + return await discountService + .withTransaction(transactionManager) + .deleteDynamicCode(discount_id, code) + }) const discount = await discountService.retrieve(discount_id, { select: defaultAdminDiscountsFields, diff --git a/packages/medusa/src/api/routes/admin/discounts/remove-region.ts b/packages/medusa/src/api/routes/admin/discounts/remove-region.ts index 1b6b87b66d..a4baaea2de 100644 --- a/packages/medusa/src/api/routes/admin/discounts/remove-region.ts +++ b/packages/medusa/src/api/routes/admin/discounts/remove-region.ts @@ -1,5 +1,6 @@ import DiscountService from "../../../../services/discount" import { defaultAdminDiscountsFields, defaultAdminDiscountsRelations } from "." +import { EntityManager } from "typeorm" /** * @oas [delete] /discounts/{id}/regions/{region_id} * operationId: "DeleteDiscountsDiscountRegionsRegion" @@ -25,7 +26,12 @@ export default async (req, res) => { const { discount_id, region_id } = req.params const discountService: DiscountService = req.scope.resolve("discountService") - await discountService.removeRegion(discount_id, region_id) + const manager: EntityManager = req.scope.resolve("manager") + await manager.transaction(async (transactionManager) => { + return await discountService + .withTransaction(transactionManager) + .removeRegion(discount_id, region_id) + }) const discount = await discountService.retrieve(discount_id, { select: defaultAdminDiscountsFields, diff --git a/packages/medusa/src/api/routes/admin/discounts/update-condition.ts b/packages/medusa/src/api/routes/admin/discounts/update-condition.ts index 22daf2d1ed..5b1c88851b 100644 --- a/packages/medusa/src/api/routes/admin/discounts/update-condition.ts +++ b/packages/medusa/src/api/routes/admin/discounts/update-condition.ts @@ -1,11 +1,12 @@ import { IsOptional, IsString } from "class-validator" import { defaultAdminDiscountsFields, defaultAdminDiscountsRelations } from "." -import { Discount } from "../../../../models/discount" +import { Discount } from "../../../../models" import { DiscountService } from "../../../../services" import DiscountConditionService from "../../../../services/discount-condition" import { AdminUpsertConditionsReq } from "../../../../types/discount" import { getRetrieveConfig } from "../../../../utils/get-query-config" import { validator } from "../../../../utils/validator" +import { EntityManager } from "typeorm" /** * @oas [post] /discounts/{discount_id}/conditions/{condition_id} * operationId: "PostDiscountsDiscountConditionsCondition" @@ -82,7 +83,12 @@ export default async (req, res) => { id: condition.id, } - await conditionService.upsertCondition(updateObj) + const manager: EntityManager = req.scope.resolve("manager") + await manager.transaction(async (transactionManager) => { + return await conditionService + .withTransaction(transactionManager) + .upsertCondition(updateObj) + }) const config = getRetrieveConfig( defaultAdminDiscountsFields, diff --git a/packages/medusa/src/api/routes/admin/discounts/update-discount.ts b/packages/medusa/src/api/routes/admin/discounts/update-discount.ts index 5d1e6677e3..97a0b01caa 100644 --- a/packages/medusa/src/api/routes/admin/discounts/update-discount.ts +++ b/packages/medusa/src/api/routes/admin/discounts/update-discount.ts @@ -14,14 +14,14 @@ import { } from "class-validator" import { defaultAdminDiscountsFields, defaultAdminDiscountsRelations } from "." import { AllocationType } from "../../../../models" -import { Discount } from "../../../../models/discount" -import { DiscountConditionOperator } from "../../../../models/discount-condition" +import { Discount, DiscountConditionOperator } from "../../../../models" import DiscountService from "../../../../services/discount" import { AdminUpsertConditionsReq } from "../../../../types/discount" import { getRetrieveConfig } from "../../../../utils/get-query-config" import { validator } from "../../../../utils/validator" import { IsGreaterThan } from "../../../../utils/validators/greater-than" import { IsISO8601Duration } from "../../../../utils/validators/iso8601-duration" +import { EntityManager } from "typeorm" /** * @oas [post] /discounts/{id} @@ -84,7 +84,12 @@ export default async (req, res) => { const discountService: DiscountService = req.scope.resolve("discountService") - await discountService.update(discount_id, validated) + const manager: EntityManager = req.scope.resolve("manager") + await manager.transaction(async (transactionManager) => { + return await discountService + .withTransaction(transactionManager) + .update(discount_id, validated) + }) const config = getRetrieveConfig( defaultAdminDiscountsFields, diff --git a/packages/medusa/src/api/routes/admin/draft-orders/create-draft-order.ts b/packages/medusa/src/api/routes/admin/draft-orders/create-draft-order.ts index cfb349676e..d3efcea291 100644 --- a/packages/medusa/src/api/routes/admin/draft-orders/create-draft-order.ts +++ b/packages/medusa/src/api/routes/admin/draft-orders/create-draft-order.ts @@ -20,6 +20,7 @@ import { DraftOrder } from "../../../.." import { DraftOrderService } from "../../../../services" import { AddressPayload } from "../../../../types/common" import { validator } from "../../../../utils/validator" +import { EntityManager } from "typeorm" /** * @oas [post] /draft-orders * operationId: "PostDraftOrders" @@ -127,7 +128,15 @@ export default async (req, res) => { const draftOrderService: DraftOrderService = req.scope.resolve("draftOrderService") - let draftOrder: DraftOrder = await draftOrderService.create(value) + + const manager: EntityManager = req.scope.resolve("manager") + let draftOrder: DraftOrder = await manager.transaction( + async (transactionManager) => { + return await draftOrderService + .withTransaction(transactionManager) + .create(value) + } + ) draftOrder = await draftOrderService.retrieve(draftOrder.id, { relations: defaultAdminDraftOrdersRelations, diff --git a/packages/medusa/src/api/routes/admin/draft-orders/create-line-item.ts b/packages/medusa/src/api/routes/admin/draft-orders/create-line-item.ts index d681b172d7..e4db2f3e35 100644 --- a/packages/medusa/src/api/routes/admin/draft-orders/create-line-item.ts +++ b/packages/medusa/src/api/routes/admin/draft-orders/create-line-item.ts @@ -90,12 +90,14 @@ export default async (req, res) => { } if (validated.variant_id) { - const line = await lineItemService.generate( - validated.variant_id, - draftOrder.cart.region_id, - validated.quantity, - { metadata: validated.metadata, unit_price: validated.unit_price } - ) + const line = await lineItemService + .withTransaction(manager) + .generate( + validated.variant_id, + draftOrder.cart.region_id, + validated.quantity, + { metadata: validated.metadata, unit_price: validated.unit_price } + ) await cartService .withTransaction(manager) diff --git a/packages/medusa/src/api/routes/admin/draft-orders/delete-draft-order.ts b/packages/medusa/src/api/routes/admin/draft-orders/delete-draft-order.ts index 27f8872f48..5a4f1e2290 100644 --- a/packages/medusa/src/api/routes/admin/draft-orders/delete-draft-order.ts +++ b/packages/medusa/src/api/routes/admin/draft-orders/delete-draft-order.ts @@ -1,4 +1,5 @@ import { DraftOrderService } from "../../../../services" +import { EntityManager } from "typeorm" /** * @oas [delete] /draft-orders/{id} * operationId: DeleteDraftOrdersDraftOrder @@ -30,7 +31,13 @@ export default async (req, res) => { const draftOrderService: DraftOrderService = req.scope.resolve("draftOrderService") - await draftOrderService.delete(id) + + const manager: EntityManager = req.scope.resolve("manager") + await manager.transaction(async (transactionManager) => { + return await draftOrderService + .withTransaction(transactionManager) + .delete(id) + }) res.json({ id, diff --git a/packages/medusa/src/api/routes/admin/draft-orders/register-payment.ts b/packages/medusa/src/api/routes/admin/draft-orders/register-payment.ts index ab1685d586..7f960f12d4 100644 --- a/packages/medusa/src/api/routes/admin/draft-orders/register-payment.ts +++ b/packages/medusa/src/api/routes/admin/draft-orders/register-payment.ts @@ -70,7 +70,7 @@ export default async (req, res) => { .withTransaction(manager) .setPaymentSession(cart.id, "system") - await cartService.createTaxLines(cart.id) + await cartService.withTransaction(manager).createTaxLines(cart.id) await cartService.withTransaction(manager).authorizePayment(cart.id) diff --git a/packages/medusa/src/api/routes/admin/draft-orders/update-draft-order.ts b/packages/medusa/src/api/routes/admin/draft-orders/update-draft-order.ts index bcd6a75477..971e649fea 100644 --- a/packages/medusa/src/api/routes/admin/draft-orders/update-draft-order.ts +++ b/packages/medusa/src/api/routes/admin/draft-orders/update-draft-order.ts @@ -15,6 +15,9 @@ import { CartService, DraftOrderService } from "../../../../services" import { Type } from "class-transformer" import { AddressPayload } from "../../../../types/common" import { validator } from "../../../../utils/validator" +import { EntityManager } from "typeorm" +import { DraftOrderStatus } from "../../../../models" + /** * @oas [post] /admin/draft-orders/{id} * operationId: PostDraftOrdersDraftOrder @@ -80,21 +83,28 @@ export default async (req, res) => { const draftOrder = await draftOrderService.retrieve(id) - if (draftOrder.status === "completed") { + if (draftOrder.status === DraftOrderStatus.COMPLETED) { throw new MedusaError( MedusaError.Types.NOT_ALLOWED, "You are only allowed to update open draft orders" ) } - if (validated.no_notification_order !== undefined) { - await draftOrderService.update(draftOrder.id, { - no_notification_order: validated.no_notification_order, - }) - delete validated.no_notification_order - } + const manager: EntityManager = req.scope.resolve("manager") + await manager.transaction(async (transactionManager) => { + if (validated.no_notification_order !== undefined) { + await draftOrderService + .withTransaction(transactionManager) + .update(draftOrder.id, { + no_notification_order: validated.no_notification_order, + }) + delete validated.no_notification_order + } - await cartService.update(draftOrder.cart_id, validated) + await cartService + .withTransaction(transactionManager) + .update(draftOrder.cart_id, validated) + }) draftOrder.cart = await cartService.retrieve(draftOrder.cart_id, { relations: defaultAdminDraftOrdersCartRelations, diff --git a/packages/medusa/src/api/routes/admin/gift-cards/create-gift-card.ts b/packages/medusa/src/api/routes/admin/gift-cards/create-gift-card.ts index e8b16f167a..757f249368 100644 --- a/packages/medusa/src/api/routes/admin/gift-cards/create-gift-card.ts +++ b/packages/medusa/src/api/routes/admin/gift-cards/create-gift-card.ts @@ -3,6 +3,7 @@ import { IsBoolean, IsDate, IsInt, IsOptional, IsString } from "class-validator" import { defaultAdminGiftCardFields, defaultAdminGiftCardRelations } from "." import { GiftCardService } from "../../../../services" import { validator } from "../../../../utils/validator" +import { EntityManager } from "typeorm" /** * @oas [post] /gift-cards @@ -50,9 +51,12 @@ export default async (req, res) => { const giftCardService: GiftCardService = req.scope.resolve("giftCardService") - const newly = await giftCardService.create({ - ...validated, - balance: validated.value, + const manager: EntityManager = req.scope.resolve("manager") + const newly = await manager.transaction(async (transactionManager) => { + return await giftCardService.withTransaction(transactionManager).create({ + ...validated, + balance: validated.value, + }) }) const giftCard = await giftCardService.retrieve(newly.id, { diff --git a/packages/medusa/src/api/routes/admin/gift-cards/delete-gift-card.ts b/packages/medusa/src/api/routes/admin/gift-cards/delete-gift-card.ts index 167b239317..8e76de76c1 100644 --- a/packages/medusa/src/api/routes/admin/gift-cards/delete-gift-card.ts +++ b/packages/medusa/src/api/routes/admin/gift-cards/delete-gift-card.ts @@ -1,3 +1,5 @@ +import { EntityManager } from "typeorm" + /** * @oas [delete] /gift-cards/{id} * operationId: "DeleteGiftCardsGiftCard" @@ -28,7 +30,10 @@ export default async (req, res) => { const { id } = req.params const giftCardService = req.scope.resolve("giftCardService") - await giftCardService.delete(id) + const manager: EntityManager = req.scope.resolve("manager") + await manager.transaction(async (transactionManager) => { + return await giftCardService.withTransaction(transactionManager).delete(id) + }) res.json({ id, diff --git a/packages/medusa/src/api/routes/admin/gift-cards/update-gift-card.ts b/packages/medusa/src/api/routes/admin/gift-cards/update-gift-card.ts index 7579943934..2992ae785d 100644 --- a/packages/medusa/src/api/routes/admin/gift-cards/update-gift-card.ts +++ b/packages/medusa/src/api/routes/admin/gift-cards/update-gift-card.ts @@ -3,6 +3,7 @@ import { IsBoolean, IsDate, IsInt, IsOptional, IsString } from "class-validator" import { defaultAdminGiftCardFields, defaultAdminGiftCardRelations } from "." import { GiftCardService } from "../../../../services" import { validator } from "../../../../utils/validator" +import { EntityManager } from "typeorm" /** * @oas [post] /gift-cards/{id} @@ -54,7 +55,12 @@ export default async (req, res) => { const giftCardService: GiftCardService = req.scope.resolve("giftCardService") - await giftCardService.update(id, validated) + const manager: EntityManager = req.scope.resolve("manager") + await manager.transaction(async (transactionManager) => { + return await giftCardService + .withTransaction(transactionManager) + .update(id, validated) + }) const giftCard = await giftCardService.retrieve(id, { select: defaultAdminGiftCardFields, diff --git a/packages/medusa/src/api/routes/admin/invites/accept-invite.ts b/packages/medusa/src/api/routes/admin/invites/accept-invite.ts index 132e518939..8b39901fe4 100644 --- a/packages/medusa/src/api/routes/admin/invites/accept-invite.ts +++ b/packages/medusa/src/api/routes/admin/invites/accept-invite.ts @@ -2,6 +2,7 @@ import { Type } from "class-transformer" import { IsNotEmpty, IsString, ValidateNested } from "class-validator" import InviteService from "../../../../services/invite" import { validator } from "../../../../utils/validator" +import { EntityManager } from "typeorm" /** * @oas [post] /invites/accept @@ -47,7 +48,12 @@ export default async (req, res) => { const inviteService: InviteService = req.scope.resolve("inviteService") - await inviteService.accept(validated.token, validated.user) + const manager: EntityManager = req.scope.resolve("manager") + await manager.transaction(async (transactionManager) => { + return await inviteService + .withTransaction(transactionManager) + .accept(validated.token, validated.user) + }) res.sendStatus(200) } diff --git a/packages/medusa/src/api/routes/admin/invites/create-invite.ts b/packages/medusa/src/api/routes/admin/invites/create-invite.ts index b57d0b79d9..71d281005e 100644 --- a/packages/medusa/src/api/routes/admin/invites/create-invite.ts +++ b/packages/medusa/src/api/routes/admin/invites/create-invite.ts @@ -2,6 +2,7 @@ import { IsEmail, IsEnum } from "class-validator" import { UserRoles } from "../../../../models/user" import InviteService from "../../../../services/invite" import { validator } from "../../../../utils/validator" +import { EntityManager } from "typeorm" /** * @oas [post] /invites @@ -34,7 +35,13 @@ export default async (req, res) => { const inviteService: InviteService = req.scope.resolve("inviteService") - await inviteService.create(validated.user, validated.role) + const manager: EntityManager = req.scope.resolve("manager") + await manager.transaction(async (transactionManager) => { + return await inviteService + .withTransaction(transactionManager) + .create(validated.user, validated.role) + }) + res.sendStatus(200) } export class AdminPostInvitesReq { diff --git a/packages/medusa/src/api/routes/admin/invites/delete-invite.ts b/packages/medusa/src/api/routes/admin/invites/delete-invite.ts index d48aa310fc..f6a3153e41 100644 --- a/packages/medusa/src/api/routes/admin/invites/delete-invite.ts +++ b/packages/medusa/src/api/routes/admin/invites/delete-invite.ts @@ -1,4 +1,5 @@ import InviteService from "../../../../services/invite" +import { EntityManager } from "typeorm" /** * @oas [delete] /invites/{invite_id} @@ -18,7 +19,10 @@ export default async (req, res) => { const { invite_id } = req.params const inviteService: InviteService = req.scope.resolve("inviteService") - await inviteService.delete(invite_id) + const manager: EntityManager = req.scope.resolve("manager") + await manager.transaction(async (transactionManager) => { + await inviteService.withTransaction(transactionManager).delete(invite_id) + }) res.status(200).send({ id: invite_id, diff --git a/packages/medusa/src/api/routes/admin/invites/resend-invite.ts b/packages/medusa/src/api/routes/admin/invites/resend-invite.ts index 18702a0f22..539cabb378 100644 --- a/packages/medusa/src/api/routes/admin/invites/resend-invite.ts +++ b/packages/medusa/src/api/routes/admin/invites/resend-invite.ts @@ -1,4 +1,5 @@ import InviteService from "../../../../services/invite" +import { EntityManager } from "typeorm" /** * @oas [post] /invites/{invite_id}/resend @@ -18,7 +19,10 @@ export default async (req, res) => { const { invite_id } = req.params const inviteService: InviteService = req.scope.resolve("inviteService") - await inviteService.resend(invite_id) + const manager: EntityManager = req.scope.resolve("manager") + await manager.transaction(async (transactionManager) => { + await inviteService.withTransaction(transactionManager).resend(invite_id) + }) res.sendStatus(200) } diff --git a/packages/medusa/src/api/routes/admin/notes/create-note.ts b/packages/medusa/src/api/routes/admin/notes/create-note.ts index 16a88b3bb4..d50904ffff 100644 --- a/packages/medusa/src/api/routes/admin/notes/create-note.ts +++ b/packages/medusa/src/api/routes/admin/notes/create-note.ts @@ -1,6 +1,7 @@ import { IsNotEmpty, IsString } from "class-validator" import NoteService from "../../../../services/note" import { validator } from "../../../../utils/validator" +import { EntityManager } from "typeorm" /** * @oas [post] /notes @@ -42,11 +43,14 @@ export default async (req, res) => { const noteService: NoteService = req.scope.resolve("noteService") - const result = await noteService.create({ - resource_id: validated.resource_id, - resource_type: validated.resource_type, - value: validated.value, - author_id: userId, + const manager: EntityManager = req.scope.resolve("manager") + const result = await manager.transaction(async (transactionManager) => { + return await noteService.withTransaction(transactionManager).create({ + resource_id: validated.resource_id, + resource_type: validated.resource_type, + value: validated.value, + author_id: userId, + }) }) res.status(200).json({ note: result }) diff --git a/packages/medusa/src/api/routes/admin/notes/delete-note.ts b/packages/medusa/src/api/routes/admin/notes/delete-note.ts index 263d3a184c..cb344d0d70 100644 --- a/packages/medusa/src/api/routes/admin/notes/delete-note.ts +++ b/packages/medusa/src/api/routes/admin/notes/delete-note.ts @@ -1,4 +1,5 @@ import NoteService from "../../../../services/note" +import { EntityManager } from "typeorm" /** * @oas [delete] /notes/{id} @@ -28,7 +29,10 @@ export default async (req, res) => { const { id } = req.params const noteService: NoteService = req.scope.resolve("noteService") - await noteService.delete(id) + const manager: EntityManager = req.scope.resolve("manager") + await manager.transaction(async (transactionManager) => { + return await noteService.withTransaction(transactionManager).delete(id) + }) res.status(200).json({ id, object: "note", deleted: true }) } diff --git a/packages/medusa/src/api/routes/admin/notes/update-note.ts b/packages/medusa/src/api/routes/admin/notes/update-note.ts index 66de088e5d..291b608a14 100644 --- a/packages/medusa/src/api/routes/admin/notes/update-note.ts +++ b/packages/medusa/src/api/routes/admin/notes/update-note.ts @@ -1,6 +1,7 @@ import { IsString } from "class-validator" import NoteService from "../../../../services/note" import { validator } from "../../../../utils/validator" +import { EntityManager } from "typeorm" /** * @oas [post] /notes/{id} @@ -39,7 +40,12 @@ export default async (req, res) => { const validated = await validator(AdminPostNotesNoteReq, req.body) const noteService: NoteService = req.scope.resolve("noteService") - const note = await noteService.update(id, validated.value) + const manager: EntityManager = req.scope.resolve("manager") + const note = await manager.transaction(async (transactionManager) => { + return await noteService + .withTransaction(transactionManager) + .update(id, validated.value) + }) res.status(200).json({ note }) } diff --git a/packages/medusa/src/api/routes/admin/notifications/resend-notification.ts b/packages/medusa/src/api/routes/admin/notifications/resend-notification.ts index a1acd264eb..b8c6e4d297 100644 --- a/packages/medusa/src/api/routes/admin/notifications/resend-notification.ts +++ b/packages/medusa/src/api/routes/admin/notifications/resend-notification.ts @@ -7,6 +7,7 @@ import { import { validator } from "../../../../utils/validator" import { NotificationService } from "../../../../services" import { Notification } from "../../../../models" +import { EntityManager } from "typeorm" /** * @oas [post] /notifications/{id}/resend @@ -54,7 +55,12 @@ export default async (req, res) => { config.to = validatedBody.to } - await notificationService.resend(id, config) + const manager: EntityManager = req.scope.resolve("manager") + await manager.transaction(async (transactionManager) => { + return await notificationService + .withTransaction(transactionManager) + .resend(id, config) + }) const notification = await notificationService.retrieve(id, { select: defaultAdminNotificationsFields as (keyof Notification)[], diff --git a/packages/medusa/src/api/routes/admin/orders/add-shipping-method.ts b/packages/medusa/src/api/routes/admin/orders/add-shipping-method.ts index f555c66092..e930d37583 100644 --- a/packages/medusa/src/api/routes/admin/orders/add-shipping-method.ts +++ b/packages/medusa/src/api/routes/admin/orders/add-shipping-method.ts @@ -8,6 +8,7 @@ import { import { defaultAdminOrdersFields, defaultAdminOrdersRelations } from "." import { OrderService } from "../../../../services" import { validator } from "../../../../utils/validator" +import { EntityManager } from "typeorm" /** * @oas [post] /orders/{id}/shipping-methods @@ -42,14 +43,14 @@ export default async (req, res) => { const orderService: OrderService = req.scope.resolve("orderService") - await orderService.addShippingMethod( - id, - validated.option_id, - validated.data, - { - price: validated.price, - } - ) + const manager: EntityManager = req.scope.resolve("manager") + await manager.transaction(async (transactionManager) => { + return await orderService + .withTransaction(transactionManager) + .addShippingMethod(id, validated.option_id, validated.data, { + price: validated.price, + }) + }) const order = await orderService.retrieve(id, { select: defaultAdminOrdersFields, diff --git a/packages/medusa/src/api/routes/admin/orders/archive-order.ts b/packages/medusa/src/api/routes/admin/orders/archive-order.ts index eee94c40b0..61bbf45fa7 100644 --- a/packages/medusa/src/api/routes/admin/orders/archive-order.ts +++ b/packages/medusa/src/api/routes/admin/orders/archive-order.ts @@ -1,4 +1,5 @@ import { OrderService } from "../../../../services" +import { EntityManager } from "typeorm" /** * @oas [post] /orders/{id}/archive @@ -25,7 +26,10 @@ export default async (req, res) => { const orderService: OrderService = req.scope.resolve("orderService") - await orderService.archive(id) + const manager: EntityManager = req.scope.resolve("manager") + await manager.transaction(async (transactionManager) => { + return await orderService.withTransaction(transactionManager).archive(id) + }) const order = await orderService.retrieve(id, { relations: ["region", "customer", "swaps"], diff --git a/packages/medusa/src/api/routes/admin/orders/cancel-claim.ts b/packages/medusa/src/api/routes/admin/orders/cancel-claim.ts index 0768bb0ec7..e11241a425 100644 --- a/packages/medusa/src/api/routes/admin/orders/cancel-claim.ts +++ b/packages/medusa/src/api/routes/admin/orders/cancel-claim.ts @@ -1,6 +1,7 @@ import { MedusaError } from "medusa-core-utils" import { defaultAdminOrdersRelations, defaultAdminOrdersFields } from "." import { ClaimService, OrderService } from "../../../../services" +import { EntityManager } from "typeorm" /** * @oas [post] /orders/{id}/claims/{claim_id}/cancel @@ -38,7 +39,12 @@ export default async (req, res) => { ) } - await claimService.cancel(claim_id) + const manager: EntityManager = req.scope.resolve("manager") + await manager.transaction(async (transactionManager) => { + return await claimService + .withTransaction(transactionManager) + .cancel(claim_id) + }) const order = await orderService.retrieve(id, { select: defaultAdminOrdersFields, diff --git a/packages/medusa/src/api/routes/admin/orders/cancel-fulfillment-claim.ts b/packages/medusa/src/api/routes/admin/orders/cancel-fulfillment-claim.ts index b0bfd6d6ed..fd030c4932 100644 --- a/packages/medusa/src/api/routes/admin/orders/cancel-fulfillment-claim.ts +++ b/packages/medusa/src/api/routes/admin/orders/cancel-fulfillment-claim.ts @@ -5,6 +5,7 @@ import { FulfillmentService, OrderService, } from "../../../../services" +import { EntityManager } from "typeorm" /** * @oas [post] /orders/{id}/claims/{claim_id}/fulfillments/{fulfillment_id}/cancel @@ -54,7 +55,12 @@ export default async (req, res) => { ) } - await claimService.cancelFulfillment(fulfillment_id) + const manager: EntityManager = req.scope.resolve("manager") + await manager.transaction(async (transactionManager) => { + return await claimService + .withTransaction(transactionManager) + .cancelFulfillment(fulfillment_id) + }) const order = await orderService.retrieve(id, { select: defaultAdminOrdersFields, diff --git a/packages/medusa/src/api/routes/admin/orders/cancel-fulfillment-swap.ts b/packages/medusa/src/api/routes/admin/orders/cancel-fulfillment-swap.ts index 5470571cab..bbf688d276 100644 --- a/packages/medusa/src/api/routes/admin/orders/cancel-fulfillment-swap.ts +++ b/packages/medusa/src/api/routes/admin/orders/cancel-fulfillment-swap.ts @@ -5,6 +5,7 @@ import { OrderService, SwapService, } from "../../../../services" +import { EntityManager } from "typeorm" /** * @oas [post] /orders/{id}/swaps/{swap_id}/fulfillments/{fulfillment_id}/cancel @@ -54,7 +55,12 @@ export default async (req, res) => { ) } - await swapService.cancelFulfillment(fulfillment_id) + const manager: EntityManager = req.scope.resolve("manager") + await manager.transaction(async (transactionManager) => { + return await swapService + .withTransaction(transactionManager) + .cancelFulfillment(fulfillment_id) + }) const order = await orderService.retrieve(id, { select: defaultAdminOrdersFields, diff --git a/packages/medusa/src/api/routes/admin/orders/cancel-fulfillment.ts b/packages/medusa/src/api/routes/admin/orders/cancel-fulfillment.ts index 731bbe43cb..0f2c1da749 100644 --- a/packages/medusa/src/api/routes/admin/orders/cancel-fulfillment.ts +++ b/packages/medusa/src/api/routes/admin/orders/cancel-fulfillment.ts @@ -1,6 +1,7 @@ import { MedusaError } from "medusa-core-utils" import { defaultAdminOrdersRelations, defaultAdminOrdersFields } from "." import { FulfillmentService, OrderService } from "../../../../services" +import { EntityManager } from "typeorm" /** * @oas [post] /orders/{id}/fulfillments/{fulfillment_id}/cancel @@ -39,7 +40,12 @@ export default async (req, res) => { ) } - await orderService.cancelFulfillment(fulfillment_id) + const manager: EntityManager = req.scope.resolve("manager") + await manager.transaction(async (transactionManager) => { + return await orderService + .withTransaction(transactionManager) + .cancelFulfillment(fulfillment_id) + }) const order = await orderService.retrieve(id, { select: defaultAdminOrdersFields, diff --git a/packages/medusa/src/api/routes/admin/orders/cancel-order.ts b/packages/medusa/src/api/routes/admin/orders/cancel-order.ts index 18215f1914..8d8d45e3cc 100644 --- a/packages/medusa/src/api/routes/admin/orders/cancel-order.ts +++ b/packages/medusa/src/api/routes/admin/orders/cancel-order.ts @@ -1,5 +1,6 @@ import { defaultAdminOrdersFields, defaultAdminOrdersRelations } from "." import { OrderService } from "../../../../services" +import { EntityManager } from "typeorm" /** * @oas [post] /orders/{id}/cancel @@ -25,7 +26,10 @@ export default async (req, res) => { const { id } = req.params const orderService: OrderService = req.scope.resolve("orderService") - await orderService.cancel(id) + const manager: EntityManager = req.scope.resolve("manager") + await manager.transaction(async (transactionManager) => { + return await orderService.withTransaction(transactionManager).cancel(id) + }) const order = await orderService.retrieve(id, { select: defaultAdminOrdersFields, diff --git a/packages/medusa/src/api/routes/admin/orders/cancel-swap.ts b/packages/medusa/src/api/routes/admin/orders/cancel-swap.ts index 2110244977..d000129b3a 100644 --- a/packages/medusa/src/api/routes/admin/orders/cancel-swap.ts +++ b/packages/medusa/src/api/routes/admin/orders/cancel-swap.ts @@ -1,6 +1,7 @@ import { MedusaError } from "medusa-core-utils" import { defaultAdminOrdersRelations, defaultAdminOrdersFields } from "." import { OrderService, SwapService } from "../../../../services" +import { EntityManager } from "typeorm" /** * @oas [post] /orders/{id}/swaps/{swap_id}/cancel @@ -38,7 +39,10 @@ export default async (req, res) => { ) } - await swapService.cancel(swap_id) + const manager: EntityManager = req.scope.resolve("manager") + await manager.transaction(async (transactionManager) => { + return await swapService.withTransaction(transactionManager).cancel(swap_id) + }) const order = await orderService.retrieve(id, { select: defaultAdminOrdersFields, diff --git a/packages/medusa/src/api/routes/admin/orders/capture-payment.ts b/packages/medusa/src/api/routes/admin/orders/capture-payment.ts index 86a5577762..0fc77f387a 100644 --- a/packages/medusa/src/api/routes/admin/orders/capture-payment.ts +++ b/packages/medusa/src/api/routes/admin/orders/capture-payment.ts @@ -1,5 +1,6 @@ import { defaultAdminOrdersRelations, defaultAdminOrdersFields } from "." import { OrderService } from "../../../../services" +import { EntityManager } from "typeorm" /** * @oas [post] /orders/{id}/capture @@ -26,7 +27,12 @@ export default async (req, res) => { const orderService: OrderService = req.scope.resolve("orderService") - await orderService.capturePayment(id) + const manager: EntityManager = req.scope.resolve("manager") + await manager.transaction(async (transactionManager) => { + return await orderService + .withTransaction(transactionManager) + .capturePayment(id) + }) const order = await orderService.retrieve(id, { select: defaultAdminOrdersFields, diff --git a/packages/medusa/src/api/routes/admin/orders/complete-order.ts b/packages/medusa/src/api/routes/admin/orders/complete-order.ts index 3a2e42ad31..59ae4c9aec 100644 --- a/packages/medusa/src/api/routes/admin/orders/complete-order.ts +++ b/packages/medusa/src/api/routes/admin/orders/complete-order.ts @@ -1,4 +1,5 @@ import { OrderService } from "../../../../services" +import { EntityManager } from "typeorm" /** * @oas [post] /orders/{id}/complete @@ -25,7 +26,12 @@ export default async (req, res) => { const orderService: OrderService = req.scope.resolve("orderService") - await orderService.completeOrder(id) + const manager: EntityManager = req.scope.resolve("manager") + await manager.transaction(async (transactionManager) => { + return await orderService + .withTransaction(transactionManager) + .completeOrder(id) + }) const order = await orderService.retrieve(id, { relations: ["region", "customer", "swaps"], diff --git a/packages/medusa/src/api/routes/admin/orders/create-claim-shipment.ts b/packages/medusa/src/api/routes/admin/orders/create-claim-shipment.ts index 495ba9d52e..27fd915e4e 100644 --- a/packages/medusa/src/api/routes/admin/orders/create-claim-shipment.ts +++ b/packages/medusa/src/api/routes/admin/orders/create-claim-shipment.ts @@ -2,6 +2,7 @@ import { IsArray, IsNotEmpty, IsOptional, IsString } from "class-validator" import { defaultAdminOrdersFields, defaultAdminOrdersRelations } from "." import { ClaimService, OrderService } from "../../../../services" import { validator } from "../../../../utils/validator" +import { EntityManager } from "typeorm" /** * @oas [post] /orders/{id}/claims/{claim_id}/shipments @@ -50,11 +51,16 @@ export default async (req, res) => { const orderService: OrderService = req.scope.resolve("orderService") const claimService: ClaimService = req.scope.resolve("claimService") - await claimService.createShipment( - claim_id, - validated.fulfillment_id, - validated.tracking_numbers?.map((n) => ({ tracking_number: n })) - ) + const manager: EntityManager = req.scope.resolve("manager") + await manager.transaction(async (transactionManager) => { + return await claimService + .withTransaction(transactionManager) + .createShipment( + claim_id, + validated.fulfillment_id, + validated.tracking_numbers?.map((n) => ({ tracking_number: n })) + ) + }) const order = await orderService.retrieve(id, { select: defaultAdminOrdersFields, diff --git a/packages/medusa/src/api/routes/admin/orders/create-claim.ts b/packages/medusa/src/api/routes/admin/orders/create-claim.ts index 43a5c0a41a..bc7211861d 100644 --- a/packages/medusa/src/api/routes/admin/orders/create-claim.ts +++ b/packages/medusa/src/api/routes/admin/orders/create-claim.ts @@ -16,6 +16,7 @@ import { AddressPayload } from "../../../../types/common" import { validator } from "../../../../utils/validator" import { ClaimTypeValue } from "../../../../types/claim" import { ClaimType, ClaimReason } from "../../../../models" +import { EntityManager } from "typeorm" /** * @oas [post] /order/{id}/claims @@ -136,17 +137,17 @@ export default async (req, res) => { const value = await validator(AdminPostOrdersOrderClaimsReq, req.body) const idempotencyKeyService = req.scope.resolve("idempotencyKeyService") + const manager: EntityManager = req.scope.resolve("manager") const headerKey = req.get("Idempotency-Key") || "" let idempotencyKey try { - idempotencyKey = await idempotencyKeyService.initializeRequest( - headerKey, - req.method, - req.params, - req.path - ) + await manager.transaction(async (transactionManager) => { + idempotencyKey = await idempotencyKeyService + .withTransaction(transactionManager) + .initializeRequest(headerKey, req.method, req.params, req.path) + }) } catch (error) { res.status(409).send("Failed to create idempotency key") return @@ -165,147 +166,150 @@ export default async (req, res) => { while (inProgress) { switch (idempotencyKey.recovery_point) { case "started": { - const { key, error } = await idempotencyKeyService.workStage( - idempotencyKey.idempotency_key, - async (manager) => { - const order = await orderService - .withTransaction(manager) - .retrieve(id, { - relations: [ - "customer", - "shipping_address", - "region", - "items", - "items.tax_lines", - "discounts", - "discounts.rule", - "claims", - "claims.additional_items", - "claims.additional_items.tax_lines", - "swaps", - "swaps.additional_items", - "swaps.additional_items.tax_lines", - ], + await manager.transaction(async (transactionManager) => { + const { key, error } = await idempotencyKeyService + .withTransaction(transactionManager) + .workStage(idempotencyKey.idempotency_key, async (manager) => { + const order = await orderService + .withTransaction(manager) + .retrieve(id, { + relations: [ + "customer", + "shipping_address", + "region", + "items", + "items.tax_lines", + "discounts", + "discounts.rule", + "claims", + "claims.additional_items", + "claims.additional_items.tax_lines", + "swaps", + "swaps.additional_items", + "swaps.additional_items.tax_lines", + ], + }) + + await claimService.withTransaction(manager).create({ + idempotency_key: idempotencyKey.idempotency_key, + order, + type: value.type, + shipping_address: value.shipping_address, + claim_items: value.claim_items, + return_shipping: value.return_shipping, + additional_items: value.additional_items, + shipping_methods: value.shipping_methods, + no_notification: value.no_notification, + metadata: value.metadata, }) - await claimService.withTransaction(manager).create({ - idempotency_key: idempotencyKey.idempotency_key, - order, - type: value.type, - shipping_address: value.shipping_address, - claim_items: value.claim_items, - return_shipping: value.return_shipping, - additional_items: value.additional_items, - shipping_methods: value.shipping_methods, - no_notification: value.no_notification, - metadata: value.metadata, + return { + recovery_point: "claim_created", + } }) - return { - recovery_point: "claim_created", - } + if (error) { + inProgress = false + err = error + } else { + idempotencyKey = key } - ) - - if (error) { - inProgress = false - err = error - } else { - idempotencyKey = key - } + }) break } case "claim_created": { - const { key, error } = await idempotencyKeyService.workStage( - idempotencyKey.idempotency_key, - async (manager) => { - let claim = await claimService.withTransaction(manager).list({ - idempotency_key: idempotencyKey.idempotency_key, + await manager.transaction(async (transactionManager) => { + const { key, error } = await idempotencyKeyService + .withTransaction(transactionManager) + .workStage(idempotencyKey.idempotency_key, async (manager) => { + let claim = await claimService.withTransaction(manager).list({ + idempotency_key: idempotencyKey.idempotency_key, + }) + + if (!claim.length) { + throw new MedusaError( + MedusaError.Types.INVALID_DATA, + `Claim not found` + ) + } + + claim = claim[0] + + if (claim.type === "refund") { + await claimService + .withTransaction(manager) + .processRefund(claim.id) + } + + return { + recovery_point: "refund_handled", + } }) - if (!claim.length) { - throw new MedusaError( - MedusaError.Types.INVALID_DATA, - `Claim not found` - ) - } - - claim = claim[0] - - if (claim.type === "refund") { - await claimService - .withTransaction(manager) - .processRefund(claim.id) - } - - return { - recovery_point: "refund_handled", - } + if (error) { + inProgress = false + err = error + } else { + idempotencyKey = key } - ) - - if (error) { - inProgress = false - err = error - } else { - idempotencyKey = key - } + }) break } case "refund_handled": { - const { key, error } = await idempotencyKeyService.workStage( - idempotencyKey.idempotency_key, - async (manager) => { - let order = await orderService - .withTransaction(manager) - .retrieve(id, { - relations: ["items", "discounts"], + await manager.transaction(async (transactionManager) => { + const { key, error } = await idempotencyKeyService + .withTransaction(transactionManager) + .workStage(idempotencyKey.idempotency_key, async (manager) => { + let order = await orderService + .withTransaction(manager) + .retrieve(id, { + relations: ["items", "discounts"], + }) + + let claim = await claimService.withTransaction(manager).list( + { + idempotency_key: idempotencyKey.idempotency_key, + }, + { + relations: ["return_order"], + } + ) + + if (!claim.length) { + throw new MedusaError( + MedusaError.Types.INVALID_DATA, + `Claim not found` + ) + } + + claim = claim[0] + + if (claim.return_order) { + await returnService + .withTransaction(manager) + .fulfill(claim.return_order.id) + } + + order = await orderService.withTransaction(manager).retrieve(id, { + select: defaultAdminOrdersFields, + relations: defaultAdminOrdersRelations, }) - let claim = await claimService.withTransaction(manager).list( - { - idempotency_key: idempotencyKey.idempotency_key, - }, - { - relations: ["return_order"], + return { + response_code: 200, + response_body: { order }, } - ) - - if (!claim.length) { - throw new MedusaError( - MedusaError.Types.INVALID_DATA, - `Claim not found` - ) - } - - claim = claim[0] - - if (claim.return_order) { - await returnService - .withTransaction(manager) - .fulfill(claim.return_order.id) - } - - order = await orderService.withTransaction(manager).retrieve(id, { - select: defaultAdminOrdersFields, - relations: defaultAdminOrdersRelations, }) - return { - response_code: 200, - response_body: { order }, - } + if (error) { + inProgress = false + err = error + } else { + idempotencyKey = key } - ) - - if (error) { - inProgress = false - err = error - } else { - idempotencyKey = key - } + }) break } @@ -315,14 +319,15 @@ export default async (req, res) => { } default: - idempotencyKey = await idempotencyKeyService.update( - idempotencyKey.idempotency_key, - { - recovery_point: "finished", - response_code: 500, - response_body: { message: "Unknown recovery point" }, - } - ) + await manager.transaction(async (transactionManager) => { + idempotencyKey = await idempotencyKeyService + .withTransaction(transactionManager) + .update(idempotencyKey.idempotency_key, { + recovery_point: "finished", + response_code: 500, + response_body: { message: "Unknown recovery point" }, + }) + }) break } } diff --git a/packages/medusa/src/api/routes/admin/orders/create-fulfillment.ts b/packages/medusa/src/api/routes/admin/orders/create-fulfillment.ts index 3470015283..194f0eac91 100644 --- a/packages/medusa/src/api/routes/admin/orders/create-fulfillment.ts +++ b/packages/medusa/src/api/routes/admin/orders/create-fulfillment.ts @@ -12,6 +12,7 @@ import { import { defaultAdminOrdersRelations, defaultAdminOrdersFields } from "." import { OrderService } from "../../../../services" import { validator } from "../../../../utils/validator" +import { EntityManager } from "typeorm" /** * @oas [post] /orders/{id}/fulfillments * operationId: "PostOrdersOrderFulfillments" @@ -66,9 +67,14 @@ export default async (req, res) => { const orderService: OrderService = req.scope.resolve("orderService") - await orderService.createFulfillment(id, validated.items, { - metadata: validated.metadata, - no_notification: validated.no_notification, + const manager: EntityManager = req.scope.resolve("manager") + await manager.transaction(async (transactionManager) => { + return await orderService + .withTransaction(transactionManager) + .createFulfillment(id, validated.items, { + metadata: validated.metadata, + no_notification: validated.no_notification, + }) }) const order = await orderService.retrieve(id, { diff --git a/packages/medusa/src/api/routes/admin/orders/create-shipment.ts b/packages/medusa/src/api/routes/admin/orders/create-shipment.ts index 49cca960e6..cb90c90f0f 100644 --- a/packages/medusa/src/api/routes/admin/orders/create-shipment.ts +++ b/packages/medusa/src/api/routes/admin/orders/create-shipment.ts @@ -9,6 +9,7 @@ import { defaultAdminOrdersRelations, defaultAdminOrdersFields } from "." import { OrderService } from "../../../../services" import { validator } from "../../../../utils/validator" import { TrackingLink } from "../../../../models" +import { EntityManager } from "typeorm" /** * @oas [post] /orders/{id}/shipment * operationId: "PostOrdersOrderShipment" @@ -54,17 +55,22 @@ export default async (req, res) => { const orderService: OrderService = req.scope.resolve("orderService") - await orderService.createShipment( - id, - validated.fulfillment_id, - validated.tracking_numbers?.map((n) => ({ - tracking_number: n, - })) as TrackingLink[], - { - metadata: {}, - no_notification: validated.no_notification, - } - ) + const manager: EntityManager = req.scope.resolve("manager") + await manager.transaction(async (transactionManager) => { + return await orderService + .withTransaction(transactionManager) + .createShipment( + id, + validated.fulfillment_id, + validated.tracking_numbers?.map((n) => ({ + tracking_number: n, + })) as TrackingLink[], + { + metadata: {}, + no_notification: validated.no_notification, + } + ) + }) const order = await orderService.retrieve(id, { select: defaultAdminOrdersFields, diff --git a/packages/medusa/src/api/routes/admin/orders/create-swap-shipment.ts b/packages/medusa/src/api/routes/admin/orders/create-swap-shipment.ts index 4c815491a3..7a48640b94 100644 --- a/packages/medusa/src/api/routes/admin/orders/create-swap-shipment.ts +++ b/packages/medusa/src/api/routes/admin/orders/create-swap-shipment.ts @@ -8,6 +8,7 @@ import { import { defaultAdminOrdersFields, defaultAdminOrdersRelations } from "." import { OrderService, SwapService } from "../../../../services" import { validator } from "../../../../utils/validator" +import { EntityManager } from "typeorm" /** * @oas [post] /orders/{id}/swaps/{swap_id}/shipments * operationId: "PostOrdersOrderSwapsSwapShipments" @@ -58,12 +59,15 @@ export default async (req, res) => { const orderService: OrderService = req.scope.resolve("orderService") const swapService: SwapService = req.scope.resolve("swapService") - await swapService.createShipment( - swap_id, - validated.fulfillment_id, - validated.tracking_numbers?.map((n) => ({ tracking_number: n })), - { no_notification: validated.no_notification } - ) + const manager: EntityManager = req.scope.resolve("manager") + await manager.transaction(async (transactionManager) => { + return await swapService.withTransaction(transactionManager).createShipment( + swap_id, + validated.fulfillment_id, + validated.tracking_numbers?.map((n) => ({ tracking_number: n })), + { no_notification: validated.no_notification } + ) + }) const order = await orderService.retrieve(id, { select: defaultAdminOrdersFields, diff --git a/packages/medusa/src/api/routes/admin/orders/create-swap.ts b/packages/medusa/src/api/routes/admin/orders/create-swap.ts index 07061ba874..a91a88acd5 100644 --- a/packages/medusa/src/api/routes/admin/orders/create-swap.ts +++ b/packages/medusa/src/api/routes/admin/orders/create-swap.ts @@ -115,17 +115,20 @@ export default async (req, res) => { const idempotencyKeyService: IdempotencyKeyService = req.scope.resolve( "idempotencyKeyService" ) + const orderService: OrderService = req.scope.resolve("orderService") + const swapService: SwapService = req.scope.resolve("swapService") + const returnService: ReturnService = req.scope.resolve("returnService") + const manager: EntityManager = req.scope.resolve("manager") const headerKey = req.get("Idempotency-Key") || "" let idempotencyKey try { - idempotencyKey = await idempotencyKeyService.initializeRequest( - headerKey, - req.method, - req.params, - req.path - ) + await manager.transaction(async (transactionManager) => { + idempotencyKey = await idempotencyKeyService + .withTransaction(transactionManager) + .initializeRequest(headerKey, req.method, req.params, req.path) + }) } catch (error) { res.status(409).send("Failed to create idempotency key") return @@ -134,108 +137,111 @@ export default async (req, res) => { res.setHeader("Access-Control-Expose-Headers", "Idempotency-Key") res.setHeader("Idempotency-Key", idempotencyKey.idempotency_key) - const orderService: OrderService = req.scope.resolve("orderService") - const swapService: SwapService = req.scope.resolve("swapService") - const returnService: ReturnService = req.scope.resolve("returnService") - let inProgress = true let err = false while (inProgress) { switch (idempotencyKey.recovery_point) { case "started": { - const { key, error } = await idempotencyKeyService.workStage( - idempotencyKey.idempotency_key, - async (manager) => { - const order = await orderService - .withTransaction(manager) - .retrieve(id, { - select: ["refunded_total", "total"], - relations: [ - "items", - "items.tax_lines", - "swaps", - "swaps.additional_items", - "swaps.additional_items.tax_lines", - ], - }) + await manager.transaction(async (transactionManager) => { + const { key, error } = await idempotencyKeyService + .withTransaction(transactionManager) + .workStage(idempotencyKey.idempotency_key, async (manager) => { + const order = await orderService + .withTransaction(manager) + .retrieve(id, { + select: ["refunded_total", "total"], + relations: [ + "items", + "items.tax_lines", + "swaps", + "swaps.additional_items", + "swaps.additional_items.tax_lines", + ], + }) - const swap = await swapService - .withTransaction(manager) - .create( - order, - validated.return_items, - validated.additional_items, - validated.return_shipping, - { - idempotency_key: idempotencyKey.idempotency_key, - no_notification: validated.no_notification, - allow_backorder: validated.allow_backorder, - } - ) + const swap = await swapService + .withTransaction(manager) + .create( + order, + validated.return_items, + validated.additional_items, + validated.return_shipping, + { + idempotency_key: idempotencyKey.idempotency_key, + no_notification: validated.no_notification, + allow_backorder: validated.allow_backorder, + } + ) - await swapService - .withTransaction(manager) - .createCart(swap.id, validated.custom_shipping_options) + await swapService + .withTransaction(manager) + .createCart(swap.id, validated.custom_shipping_options) - const returnOrder = await returnService - .withTransaction(manager) - .retrieveBySwap(swap.id) + const returnOrder = await returnService + .withTransaction(manager) + .retrieveBySwap(swap.id) - await returnService.withTransaction(manager).fulfill(returnOrder.id) + await returnService + .withTransaction(manager) + .fulfill(returnOrder.id) - return { - recovery_point: "swap_created", - } + return { + recovery_point: "swap_created", + } + }) + + if (error) { + inProgress = false + err = error + } else { + idempotencyKey = key } - ) - - if (error) { - inProgress = false - err = error - } else { - idempotencyKey = key - } + }) break } case "swap_created": { - const { key, error } = await idempotencyKeyService.workStage( - idempotencyKey.idempotency_key, - async (transactionManager: EntityManager) => { - const swaps = await swapService - .withTransaction(transactionManager) - .list({ - idempotency_key: idempotencyKey.idempotency_key, - }) + await manager.transaction(async (transactionManager) => { + const { key, error } = await idempotencyKeyService + .withTransaction(transactionManager) + .workStage( + idempotencyKey.idempotency_key, + async (transactionManager: EntityManager) => { + const swaps = await swapService + .withTransaction(transactionManager) + .list({ + idempotency_key: idempotencyKey.idempotency_key, + }) - if (!swaps.length) { - throw new MedusaError( - MedusaError.Types.INVALID_DATA, - "Swap not found" - ) - } + if (!swaps.length) { + throw new MedusaError( + MedusaError.Types.INVALID_DATA, + "Swap not found" + ) + } - const order = await orderService - .withTransaction(transactionManager) - .retrieve(id, { - select: defaultAdminOrdersFields, - relations: defaultAdminOrdersRelations, - }) + const order = await orderService + .withTransaction(transactionManager) + .retrieve(id, { + select: defaultAdminOrdersFields, + relations: defaultAdminOrdersRelations, + }) - return { - response_code: 200, - response_body: { order }, - } + return { + response_code: 200, + response_body: { order }, + } + } + ) + + if (error) { + inProgress = false + err = error + } else { + idempotencyKey = key } - ) - - if (error) { - inProgress = false - err = error - } else { - idempotencyKey = key - } + }) break } @@ -245,14 +251,15 @@ export default async (req, res) => { } default: - idempotencyKey = await idempotencyKeyService.update( - idempotencyKey.idempotency_key, - { - recovery_point: "finished", - response_code: 500, - response_body: { message: "Unknown recovery point" }, - } - ) + await manager.transaction(async (transactionManager) => { + idempotencyKey = await idempotencyKeyService + .withTransaction(transactionManager) + .update(idempotencyKey.idempotency_key, { + recovery_point: "finished", + response_code: 500, + response_body: { message: "Unknown recovery point" }, + }) + }) break } } diff --git a/packages/medusa/src/api/routes/admin/orders/fulfill-swap.ts b/packages/medusa/src/api/routes/admin/orders/fulfill-swap.ts index 0c53474a39..c4c53ed949 100644 --- a/packages/medusa/src/api/routes/admin/orders/fulfill-swap.ts +++ b/packages/medusa/src/api/routes/admin/orders/fulfill-swap.ts @@ -52,14 +52,14 @@ export default async (req, res) => { metadata: validated.metadata, no_notification: validated.no_notification, }) - - const order = await orderService.withTransaction(manager).retrieve(id, { - select: defaultAdminOrdersFields, - relations: defaultAdminOrdersRelations, - }) - - res.status(200).json({ order }) }) + + const order = await orderService.retrieve(id, { + select: defaultAdminOrdersFields, + relations: defaultAdminOrdersRelations, + }) + + res.status(200).json({ order }) } export class AdminPostOrdersOrderSwapsSwapFulfillmentsReq { diff --git a/packages/medusa/src/api/routes/admin/orders/refund-payment.ts b/packages/medusa/src/api/routes/admin/orders/refund-payment.ts index dddc650fd6..c950a6d196 100644 --- a/packages/medusa/src/api/routes/admin/orders/refund-payment.ts +++ b/packages/medusa/src/api/routes/admin/orders/refund-payment.ts @@ -8,6 +8,7 @@ import { import { defaultAdminOrdersRelations, defaultAdminOrdersFields } from "." import { OrderService } from "../../../../services" import { validator } from "../../../../utils/validator" +import { EntityManager } from "typeorm" /** * @oas [post] /orders/{id}/refunds @@ -56,15 +57,14 @@ export default async (req, res) => { const orderService: OrderService = req.scope.resolve("orderService") - await orderService.createRefund( - id, - validated.amount, - validated.reason, - validated.note, - { - no_notification: validated.no_notification, - } - ) + const manager: EntityManager = req.scope.resolve("manager") + await manager.transaction(async (transactionManager) => { + return await orderService + .withTransaction(transactionManager) + .createRefund(id, validated.amount, validated.reason, validated.note, { + no_notification: validated.no_notification, + }) + }) const order = await orderService.retrieve(id, { select: defaultAdminOrdersFields, diff --git a/packages/medusa/src/api/routes/admin/orders/request-return.ts b/packages/medusa/src/api/routes/admin/orders/request-return.ts index e0e9837d02..26641cfdf3 100644 --- a/packages/medusa/src/api/routes/admin/orders/request-return.ts +++ b/packages/medusa/src/api/routes/admin/orders/request-return.ts @@ -16,6 +16,7 @@ import { } from "../../../../services" import { OrdersReturnItem } from "../../../../types/orders" import { validator } from "../../../../utils/validator" +import { EntityManager } from "typeorm" /** * @oas [post] /orders/{id}/returns @@ -86,17 +87,17 @@ export default async (req, res) => { const value = await validator(AdminPostOrdersOrderReturnsReq, req.body) const idempotencyKeyService = req.scope.resolve("idempotencyKeyService") + const manager: EntityManager = req.scope.resolve("manager") const headerKey = req.get("Idempotency-Key") || "" let idempotencyKey try { - idempotencyKey = await idempotencyKeyService.initializeRequest( - headerKey, - req.method, - req.params, - req.path - ) + await manager.transaction(async (transactionManager) => { + idempotencyKey = await idempotencyKeyService + .withTransaction(transactionManager) + .initializeRequest(headerKey, req.method, req.params, req.path) + }) } catch (error) { res.status(409).send("Failed to create idempotency key") return @@ -116,119 +117,123 @@ export default async (req, res) => { while (inProgress) { switch (idempotencyKey.recovery_point) { case "started": { - const { key, error } = await idempotencyKeyService.workStage( - idempotencyKey.idempotency_key, - async (manager) => { - const returnObj: ReturnObj = { - order_id: id, - idempotency_key: idempotencyKey.idempotency_key, - items: value.items, - } - - if (value.return_shipping) { - returnObj.shipping_method = value.return_shipping - } - - if (typeof value.refund !== "undefined" && value.refund < 0) { - returnObj.refund_amount = 0 - } else { - if (value.refund && value.refund >= 0) { - returnObj.refund_amount = value.refund + await manager.transaction(async (transactionManager) => { + const { key, error } = await idempotencyKeyService + .withTransaction(transactionManager) + .workStage(idempotencyKey.idempotency_key, async (manager) => { + const returnObj: ReturnObj = { + order_id: id, + idempotency_key: idempotencyKey.idempotency_key, + items: value.items, } - } - const order = await orderService - .withTransaction(manager) - .retrieve(id) + if (value.return_shipping) { + returnObj.shipping_method = value.return_shipping + } - const evaluatedNoNotification = - value.no_notification !== undefined - ? value.no_notification - : order.no_notification - returnObj.no_notification = evaluatedNoNotification + if (typeof value.refund !== "undefined" && value.refund < 0) { + returnObj.refund_amount = 0 + } else { + if (value.refund && value.refund >= 0) { + returnObj.refund_amount = value.refund + } + } - const createdReturn = await returnService - .withTransaction(manager) - .create(returnObj) - - if (value.return_shipping) { - await returnService + const order = await orderService .withTransaction(manager) - .fulfill(createdReturn.id) - } + .retrieve(id) - await eventBus - .withTransaction(manager) - .emit("order.return_requested", { - id, - return_id: createdReturn.id, - no_notification: evaluatedNoNotification, - }) + const evaluatedNoNotification = + value.no_notification !== undefined + ? value.no_notification + : order.no_notification + returnObj.no_notification = evaluatedNoNotification - return { - recovery_point: "return_requested", - } + const createdReturn = await returnService + .withTransaction(manager) + .create(returnObj) + + if (value.return_shipping) { + await returnService + .withTransaction(manager) + .fulfill(createdReturn.id) + } + + await eventBus + .withTransaction(manager) + .emit("order.return_requested", { + id, + return_id: createdReturn.id, + no_notification: evaluatedNoNotification, + }) + + return { + recovery_point: "return_requested", + } + }) + + if (error) { + inProgress = false + err = error + } else { + idempotencyKey = key } - ) - - if (error) { - inProgress = false - err = error - } else { - idempotencyKey = key - } + }) break } case "return_requested": { - const { key, error } = await idempotencyKeyService.workStage( - idempotencyKey.idempotency_key, - async (manager) => { - let order = await orderService - .withTransaction(manager) - .retrieve(id, { relations: ["returns"] }) + await manager.transaction(async (transactionManager) => { + const { key, error } = await idempotencyKeyService + .withTransaction(transactionManager) + .workStage(idempotencyKey.idempotency_key, async (manager) => { + let order = await orderService + .withTransaction(manager) + .retrieve(id, { relations: ["returns"] }) - /** - * If we are ready to receive immediately, we find the newly created return - * and register it as received. - */ - if (value.receive_now) { - let ret = await returnService.withTransaction(manager).list({ - idempotency_key: idempotencyKey.idempotency_key, - }) + /** + * If we are ready to receive immediately, we find the newly created return + * and register it as received. + */ + if (value.receive_now) { + let ret = await returnService.withTransaction(manager).list({ + idempotency_key: idempotencyKey.idempotency_key, + }) - if (!ret.length) { - throw new MedusaError( - MedusaError.Types.INVALID_DATA, - `Return not found` - ) + if (!ret.length) { + throw new MedusaError( + MedusaError.Types.INVALID_DATA, + `Return not found` + ) + } + + ret = ret[0] + + order = await returnService + .withTransaction(manager) + .receive(ret.id, value.items, value.refund) } - ret = ret[0] - - order = await returnService + order = await orderService .withTransaction(manager) - .receive(ret.id, value.items, value.refund) - } + .retrieve(id, { + select: defaultAdminOrdersFields, + relations: defaultAdminOrdersRelations, + }) - order = await orderService.withTransaction(manager).retrieve(id, { - select: defaultAdminOrdersFields, - relations: defaultAdminOrdersRelations, + return { + response_code: 200, + response_body: { order }, + } }) - return { - response_code: 200, - response_body: { order }, - } + if (error) { + inProgress = false + err = error + } else { + idempotencyKey = key } - ) - - if (error) { - inProgress = false - err = error - } else { - idempotencyKey = key - } + }) break } @@ -238,14 +243,15 @@ export default async (req, res) => { } default: - idempotencyKey = await idempotencyKeyService.update( - idempotencyKey.idempotency_key, - { - recovery_point: "finished", - response_code: 500, - response_body: { message: "Unknown recovery point" }, - } - ) + await manager.transaction(async (transactionManager) => { + idempotencyKey = await idempotencyKeyService + .withTransaction(transactionManager) + .update(idempotencyKey.idempotency_key, { + recovery_point: "finished", + response_code: 500, + response_body: { message: "Unknown recovery point" }, + }) + }) break } } diff --git a/packages/medusa/src/api/routes/admin/orders/update-claim.ts b/packages/medusa/src/api/routes/admin/orders/update-claim.ts index ff42936289..01fb6ada49 100644 --- a/packages/medusa/src/api/routes/admin/orders/update-claim.ts +++ b/packages/medusa/src/api/routes/admin/orders/update-claim.ts @@ -12,6 +12,7 @@ import { import { defaultAdminOrdersRelations, defaultAdminOrdersFields } from "." import { ClaimService, OrderService } from "../../../../services" import { validator } from "../../../../utils/validator" +import { EntityManager } from "typeorm" /** * @oas [post] /order/{id}/claims/{claim_id} @@ -104,7 +105,12 @@ export default async (req, res) => { const orderService: OrderService = req.scope.resolve("orderService") const claimService: ClaimService = req.scope.resolve("claimService") - await claimService.update(claim_id, validated) + const manager: EntityManager = req.scope.resolve("manager") + await manager.transaction(async (transactionManager) => { + return await claimService + .withTransaction(transactionManager) + .update(claim_id, validated) + }) const data = await orderService.retrieve(id, { select: defaultAdminOrdersFields, diff --git a/packages/medusa/src/api/routes/admin/orders/update-order.ts b/packages/medusa/src/api/routes/admin/orders/update-order.ts index d6c3bea144..8b985a7f5d 100644 --- a/packages/medusa/src/api/routes/admin/orders/update-order.ts +++ b/packages/medusa/src/api/routes/admin/orders/update-order.ts @@ -13,6 +13,7 @@ import { defaultAdminOrdersFields, defaultAdminOrdersRelations } from "." import { OrderService } from "../../../../services" import { AddressPayload } from "../../../../types/common" import { validator } from "../../../../utils/validator" +import { EntityManager } from "typeorm" /** * @oas [post] /orders/{id} @@ -102,7 +103,12 @@ export default async (req, res) => { const orderService: OrderService = req.scope.resolve("orderService") - await orderService.update(id, value) + const manager: EntityManager = req.scope.resolve("manager") + await manager.transaction(async (transactionManager) => { + return await orderService + .withTransaction(transactionManager) + .update(id, value) + }) const order = await orderService.retrieve(id, { select: defaultAdminOrdersFields, diff --git a/packages/medusa/src/api/routes/store/carts/create-cart.ts b/packages/medusa/src/api/routes/store/carts/create-cart.ts index f5a062aabf..852d8c0ffc 100644 --- a/packages/medusa/src/api/routes/store/carts/create-cart.ts +++ b/packages/medusa/src/api/routes/store/carts/create-cart.ts @@ -18,6 +18,7 @@ import { decorateLineItemsWithTotals } from "./decorate-line-items-with-totals" import SalesChannelFeatureFlag from "../../../../loaders/feature-flags/sales-channels"; import { FeatureFlagDecorators } from "../../../../utils/feature-flag-decorators"; import { FlagRouter } from "../../../../utils/flag-router" +import { Cart } from "../../../../models"; /** * @oas [post] /carts @@ -81,33 +82,32 @@ export default async (req, res) => { const entityManager: EntityManager = req.scope.resolve("manager") const featureFlagRouter: FlagRouter = req.scope.resolve("featureFlagRouter") - await entityManager.transaction(async (manager) => { - let regionId: string - if (typeof validated.region_id !== "undefined") { - regionId = validated.region_id - } else { - const regions = await regionService - .withTransaction(manager) - .list({}) + let regionId: string + if (typeof validated.region_id !== "undefined") { + regionId = validated.region_id + } else { + const regions = await regionService.list({}) - if (!regions?.length) { - throw new MedusaError( - MedusaError.Types.INVALID_DATA, - `A region is required to create a cart` - ) - } - - regionId = regions[0].id + if (!regions?.length) { + throw new MedusaError( + MedusaError.Types.INVALID_DATA, + `A region is required to create a cart` + ) } - let cart = await cartService.withTransaction(manager).create({ + regionId = regions[0].id + } + + let cart: Cart + await entityManager.transaction(async (manager) => { + cart = await cartService.withTransaction(manager).create({ ...validated, context: { ...reqContext, ...validated.context, }, region_id: regionId, - }) + }) if (validated.items) { await Promise.all( @@ -117,7 +117,7 @@ export default async (req, res) => { .generate(i.variant_id, regionId, i.quantity, { customer_id: req.user?.customer_id, }) - await cartService + return await cartService .withTransaction(manager) .addLineItem(cart.id, lineItem, { validateSalesChannels: @@ -126,16 +126,16 @@ export default async (req, res) => { }) ) } - - cart = await cartService.withTransaction(manager).retrieve(cart.id, { - select: defaultStoreCartFields, - relations: defaultStoreCartRelations, - }) - - const data = await decorateLineItemsWithTotals(cart, req) - - res.status(200).json({ cart: data }) }) + + cart = await cartService.retrieve(cart!.id, { + select: defaultStoreCartFields, + relations: defaultStoreCartRelations, + }) + + const data = await decorateLineItemsWithTotals(cart, req) + + res.status(200).json({ cart: data }) } export class Item { diff --git a/packages/medusa/src/services/__mocks__/invite.js b/packages/medusa/src/services/__mocks__/invite.js index e1aab5cb6c..5d21174d72 100644 --- a/packages/medusa/src/services/__mocks__/invite.js +++ b/packages/medusa/src/services/__mocks__/invite.js @@ -1,4 +1,8 @@ export const InviteServiceMock = { + withTransaction: function () { + return this + }, + list: jest.fn().mockImplementation((selector, config) => { return Promise.resolve({}) }), diff --git a/packages/medusa/src/services/cart.ts b/packages/medusa/src/services/cart.ts index d5afadc559..bc8ee5d24d 100644 --- a/packages/medusa/src/services/cart.ts +++ b/packages/medusa/src/services/cart.ts @@ -340,7 +340,7 @@ class CartService extends TransactionBaseService { * @param data - the data to create the cart with * @return the result of the create operation */ - async create(data: CartCreateProps): Promise { + async create(data: CartCreateProps): Promise { return await this.atomicPhase_( async (transactionManager: EntityManager) => { const cartRepo = transactionManager.getCustomRepository( diff --git a/packages/medusa/src/services/inventory.js b/packages/medusa/src/services/inventory.js index 6ce4dd4f2c..aa6b8f7921 100644 --- a/packages/medusa/src/services/inventory.js +++ b/packages/medusa/src/services/inventory.js @@ -66,7 +66,9 @@ class InventoryService extends BaseService { return true } - const variant = await this.productVariantService_.retrieve(variantId) + const variant = await this.productVariantService_ + .withTransaction(this.manager_) + .retrieve(variantId) const { inventory_quantity, allow_backorder, manage_inventory } = variant const isCovered = !manage_inventory || allow_backorder || inventory_quantity >= quantity diff --git a/packages/medusa/src/services/pricing.ts b/packages/medusa/src/services/pricing.ts index c6f7452e33..5cc9a50746 100644 --- a/packages/medusa/src/services/pricing.ts +++ b/packages/medusa/src/services/pricing.ts @@ -63,32 +63,30 @@ class PricingService extends TransactionBaseService { async collectPricingContext( context: PriceSelectionContext ): Promise { - return await this.atomicPhase_(async (manager: EntityManager) => { - let automaticTaxes = false - let taxRate = null - let currencyCode = context.currency_code + let automaticTaxes = false + let taxRate = null + let currencyCode = context.currency_code - if (context.region_id) { - const region = await this.regionService - .withTransaction(manager) - .retrieve(context.region_id, { - select: ["id", "currency_code", "automatic_taxes", "tax_rate"], - }) + if (context.region_id) { + const region = await this.regionService + .withTransaction(this.manager_) + .retrieve(context.region_id, { + select: ["id", "currency_code", "automatic_taxes", "tax_rate"], + }) - currencyCode = region.currency_code - automaticTaxes = region.automatic_taxes - taxRate = region.tax_rate - } + currencyCode = region.currency_code + automaticTaxes = region.automatic_taxes + taxRate = region.tax_rate + } - return { - price_selection: { - ...context, - currency_code: currencyCode, - }, - automatic_taxes: automaticTaxes, - tax_rate: taxRate, - } - }) + return { + price_selection: { + ...context, + currency_code: currencyCode, + }, + automatic_taxes: automaticTaxes, + tax_rate: taxRate, + } } /** @@ -229,17 +227,15 @@ class PricingService extends TransactionBaseService { pricingContext.automatic_taxes && pricingContext.price_selection.region_id ) { - const { product_id } = await this.productVariantService.retrieve( - variantId, - { select: ["id", "product_id"] } - ) - productRates = await this.taxProviderService.getRegionRatesForProduct( - product_id, - { + const { product_id } = await this.productVariantService + .withTransaction(this.manager_) + .retrieve(variantId, { select: ["id", "product_id"] }) + productRates = await this.taxProviderService + .withTransaction(this.manager_) + .getRegionRatesForProduct(product_id, { id: pricingContext.price_selection.region_id, tax_rate: pricingContext.tax_rate, - } - ) + }) } return await this.getProductVariantPricing_(