From b8f1ae9ff5ce08d96f7b84fdb03071d5135ac243 Mon Sep 17 00:00:00 2001 From: Zakaria El Asri <33696020+zakariaelas@users.noreply.github.com> Date: Tue, 26 Apr 2022 14:05:33 +0000 Subject: [PATCH] feat: line item adjustment migration script (#1255) --- .../api/routes/store/auth/create-session.ts | 10 +- packages/medusa/src/index.js | 4 +- .../medusa/src/models/line-item-adjustment.ts | 1 - .../scripts/line-item-adjustment-migration.ts | 112 ++++++++++++++++++ .../medusa/src/services/__tests__/totals.js | 4 + packages/medusa/src/services/line-item.ts | 8 +- 6 files changed, 130 insertions(+), 9 deletions(-) create mode 100644 packages/medusa/src/scripts/line-item-adjustment-migration.ts diff --git a/packages/medusa/src/api/routes/store/auth/create-session.ts b/packages/medusa/src/api/routes/store/auth/create-session.ts index 4421759806..97ef3b8e89 100644 --- a/packages/medusa/src/api/routes/store/auth/create-session.ts +++ b/packages/medusa/src/api/routes/store/auth/create-session.ts @@ -41,9 +41,13 @@ export default async (req, res) => { const { projectConfig: { jwt_secret }, } = req.scope.resolve("configModule") - req.session.jwt = jwt.sign({ customer_id: result.customer?.id }, jwt_secret!, { - expiresIn: "30d", - }) + req.session.jwt = jwt.sign( + { customer_id: result.customer?.id }, + jwt_secret!, + { + expiresIn: "30d", + } + ) const customerService: CustomerService = req.scope.resolve("customerService") const customer = await customerService.retrieve(result.customer?.id || "", { diff --git a/packages/medusa/src/index.js b/packages/medusa/src/index.js index b6f93ef99a..7854508490 100644 --- a/packages/medusa/src/index.js +++ b/packages/medusa/src/index.js @@ -1,5 +1,5 @@ export * from "./api" export * from "./interfaces" export * from "./types/price-list" -export * from './models' -export * from './services' \ No newline at end of file +export * from "./models" +export * from "./services" diff --git a/packages/medusa/src/models/line-item-adjustment.ts b/packages/medusa/src/models/line-item-adjustment.ts index fff820a934..bb6a58bf17 100644 --- a/packages/medusa/src/models/line-item-adjustment.ts +++ b/packages/medusa/src/models/line-item-adjustment.ts @@ -7,7 +7,6 @@ import { JoinColumn, PrimaryColumn, OneToOne, - Unique, } from "typeorm" import { ulid } from "ulid" import { DbAwareColumn } from "../utils/db-aware-column" diff --git a/packages/medusa/src/scripts/line-item-adjustment-migration.ts b/packages/medusa/src/scripts/line-item-adjustment-migration.ts new file mode 100644 index 0000000000..4b9b669b1c --- /dev/null +++ b/packages/medusa/src/scripts/line-item-adjustment-migration.ts @@ -0,0 +1,112 @@ +import dotenv from "dotenv" +import { createConnection, SelectQueryBuilder } from "typeorm" +import Logger from "../loaders/logger" +import { LineItem } from "../models/line-item" +import { LineItemAdjustment } from "../models/line-item-adjustment" +dotenv.config() + +const typeormConfig = { + type: process.env.TYPEORM_CONNECTION, + url: process.env.TYPEORM_URL, + username: process.env.TYPEORM_USERNAME, + password: process.env.TYPEORM_PASSWORD, + database: process.env.TYPEORM_DATABASE, + migrations: [process.env.TYPEORM_MIGRATIONS as string], + entities: [process.env.TYPEORM_ENTITIES], + logging: true, +} + +const migrate = async function({ typeormConfig }) { + const connection = await createConnection(typeormConfig) + + const BATCH_SIZE = 1000 + + await connection.transaction(async (manager) => { + const getDiscountableLineItems = (qb: SelectQueryBuilder) => { + return qb + .from(LineItem, "li") + .select([ + "li.order_id as order_id", + "SUM(li.quantity * li.unit_price)::bigint AS discountable_subtotal", + ]) + .where("li.allow_discounts = true") + .groupBy("li.order_id") + } + + const getLineItemAllocations = (qb: SelectQueryBuilder) => + qb + .from(LineItem, "li") + .select([ + "disc.id AS discount_id", + "dr.allocation", + "dr.type", + "dr.value", + "li.*", + "li.order_id", + "ods.discountable_subtotal", + "li.quantity * li.unit_price AS li_subtotal", + `COALESCE(ROUND(CASE + WHEN dr.type = 'percentage' THEN li.quantity*li.unit_price * (dr.value::float / 100) + WHEN dr.type = 'fixed' THEN li.quantity*li.unit_price * (LEAST(COALESCE(dr.value, 0), ods.discountable_subtotal)::float / ods.discountable_subtotal) + ELSE 0 + END), 0) AS discount_total`, + ]) + .leftJoin("order", "o", "o.id = li.order_id") + .leftJoin("order_discounts", "od", "o.id = od.order_id") + .leftJoin("discount", "disc", "od.discount_id = disc.id") + .leftJoin("discount_rule", "dr", "dr.id = disc.rule_id") + .leftJoinAndSelect( + getDiscountableLineItems, + "ods", + "ods.order_id = li.order_id" + ) + .where("dr.type != :type", { type: "free_shipping" }) + + const totalAdjustments = await manager + .createQueryBuilder() + .from(getLineItemAllocations, "lia") + .select("COUNT(*)") + .getRawOne() + .then((result) => parseInt(result.count, 10)) + + let offset = 0 + while (offset < totalAdjustments) { + const lineItemAdjustments = await manager + .createQueryBuilder() + .from(getLineItemAllocations, "lia") + .select([ + "lia.id AS item_id", + "lia.discount_id", + "lia.discount_total AS amount", + "'discount' AS description", + ]) + .limit(BATCH_SIZE) + .offset(offset) + .getRawMany() + + await manager + .createQueryBuilder() + .insert() + .into(LineItemAdjustment) + .values( + lineItemAdjustments.map((lia) => + Object.assign(new LineItemAdjustment(), { + ...lia, + }) + ) + ) + .orIgnore() + .execute() + offset += BATCH_SIZE + } + }) +} + +migrate({ typeormConfig }) + .then(() => { + Logger.info("Database migration completed successfully") + process.exit() + }) + .catch((err) => console.log(err)) + +export default migrate diff --git a/packages/medusa/src/services/__tests__/totals.js b/packages/medusa/src/services/__tests__/totals.js index 7cda6b5217..fb5ec68a99 100644 --- a/packages/medusa/src/services/__tests__/totals.js +++ b/packages/medusa/src/services/__tests__/totals.js @@ -19,6 +19,7 @@ const discounts = { type: "fixed", allocation: "item", value: 2, + // TODO: Add conditions relation }, regions: [{ id: "fr" }], }, @@ -29,6 +30,7 @@ const discounts = { type: "percentage", allocation: "item", value: 10, + // TODO: Add conditions relation }, regions: [{ id: "fr" }], }, @@ -39,6 +41,7 @@ const discounts = { type: "fixed", allocation: "total", value: 10, + // TODO: Add conditions relation }, regions: [{ id: "fr" }], }, @@ -50,6 +53,7 @@ const discounts = { type: "fixed", allocation: "item", value: 10, + // TODO: Add conditions relation }, regions: [{ id: "fr" }], }, diff --git a/packages/medusa/src/services/line-item.ts b/packages/medusa/src/services/line-item.ts index 763292a8a6..89fd8befcd 100644 --- a/packages/medusa/src/services/line-item.ts +++ b/packages/medusa/src/services/line-item.ts @@ -43,7 +43,7 @@ class LineItemService extends BaseService { productService, regionService, cartRepository, - lineItemAdjustmentService + lineItemAdjustmentService, }: InjectedDependencies) { super() @@ -233,10 +233,12 @@ class LineItemService extends BaseService { allow_discounts: variant.product.discountable, is_giftcard: variant.product.is_giftcard, metadata: context?.metadata || {}, - should_merge: shouldMerge + should_merge: shouldMerge, } - const lineLitemRepo = transactionManager.getCustomRepository(this.lineItemRepository_) + const lineLitemRepo = transactionManager.getCustomRepository( + this.lineItemRepository_ + ) const lineItem = lineLitemRepo.create(rawLineItem) if (context.cart) {