Feat: Create customer group (#1074)
* fix babel transform-runtime regenerator required for migrations * add customer group model * add migration for customer group * add customer group model export * add customer group repository * add customer group service * add CustomerGroupRepository to "withTransaction" in CustomerGroupService * remove unnecessary argument to runtime plugin * service export ordering * add create customer group endpoint * add customergroup to route index in admin * add customer group service * add customer groups test * cleanup * duplicate error handling * ducplicate name integration test * add jsdoc * customergroup not customer * pr feedback * pipeline test * fix weird merge Co-authored-by: Sebastian Rindom <skrindom@gmail.com>
This commit is contained in:
co-authored by
Sebastian Rindom
parent
22d387dcce
commit
b16976a6f4
@@ -0,0 +1,88 @@
|
|||||||
|
const path = require("path")
|
||||||
|
|
||||||
|
const setupServer = require("../../../helpers/setup-server")
|
||||||
|
const { useApi } = require("../../../helpers/use-api")
|
||||||
|
const { useDb, initDb } = require("../../../helpers/use-db")
|
||||||
|
|
||||||
|
const customerSeeder = require("../../helpers/customer-seeder")
|
||||||
|
const adminSeeder = require("../../helpers/admin-seeder")
|
||||||
|
|
||||||
|
jest.setTimeout(30000)
|
||||||
|
|
||||||
|
describe("/admin/customer-groups", () => {
|
||||||
|
let medusaProcess
|
||||||
|
let dbConnection
|
||||||
|
|
||||||
|
beforeAll(async () => {
|
||||||
|
const cwd = path.resolve(path.join(__dirname, "..", ".."))
|
||||||
|
dbConnection = await initDb({ cwd })
|
||||||
|
medusaProcess = await setupServer({ cwd })
|
||||||
|
})
|
||||||
|
|
||||||
|
afterAll(async () => {
|
||||||
|
const db = useDb()
|
||||||
|
await db.shutdown()
|
||||||
|
medusaProcess.kill()
|
||||||
|
})
|
||||||
|
|
||||||
|
describe("POST /admin/customer-groups", () => {
|
||||||
|
beforeEach(async () => {
|
||||||
|
try {
|
||||||
|
await adminSeeder(dbConnection)
|
||||||
|
await customerSeeder(dbConnection)
|
||||||
|
} catch (err) {
|
||||||
|
console.log(err)
|
||||||
|
throw err
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
afterEach(async () => {
|
||||||
|
const db = useDb()
|
||||||
|
await db.teardown()
|
||||||
|
})
|
||||||
|
|
||||||
|
it("creates customer group", async () => {
|
||||||
|
const api = useApi()
|
||||||
|
|
||||||
|
const payload = {
|
||||||
|
name: "test group",
|
||||||
|
}
|
||||||
|
|
||||||
|
const response = await api.post("/admin/customer-groups", payload, {
|
||||||
|
headers: {
|
||||||
|
Authorization: "Bearer test_token",
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
expect(response.status).toEqual(200)
|
||||||
|
expect(response.data.customerGroup).toEqual(
|
||||||
|
expect.objectContaining({
|
||||||
|
name: "test group",
|
||||||
|
})
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
it("Fails to create duplciate customer group", async () => {
|
||||||
|
expect.assertions(3)
|
||||||
|
const api = useApi()
|
||||||
|
|
||||||
|
const payload = {
|
||||||
|
name: "vip-customers",
|
||||||
|
}
|
||||||
|
|
||||||
|
await api
|
||||||
|
.post("/admin/customer-groups", payload, {
|
||||||
|
headers: {
|
||||||
|
Authorization: "Bearer test_token",
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
expect(err.response.status).toEqual(402)
|
||||||
|
expect(err.response.data.type).toEqual("duplicate_error")
|
||||||
|
expect(err.response.data.message).toEqual(
|
||||||
|
"Key (name)=(vip-customers) already exists."
|
||||||
|
)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
const { Customer, Address } = require("@medusajs/medusa")
|
const { Customer, Address, CustomerGroup } = require("@medusajs/medusa")
|
||||||
|
|
||||||
module.exports = async (connection, data = {}) => {
|
module.exports = async (connection, data = {}) => {
|
||||||
const manager = connection.manager
|
const manager = connection.manager
|
||||||
@@ -35,4 +35,9 @@ module.exports = async (connection, data = {}) => {
|
|||||||
email: "test4@email.com",
|
email: "test4@email.com",
|
||||||
has_account: true,
|
has_account: true,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
await manager.insert(CustomerGroup, {
|
||||||
|
id: "customer-group-1",
|
||||||
|
name: "vip-customers",
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
{
|
{
|
||||||
"plugins": [
|
"plugins": [
|
||||||
"@babel/plugin-proposal-class-properties",
|
"@babel/plugin-proposal-class-properties",
|
||||||
"@babel/plugin-transform-instanceof"
|
"@babel/plugin-transform-instanceof",
|
||||||
|
["@babel/plugin-transform-runtime", { "regenerator": true }]
|
||||||
],
|
],
|
||||||
"presets": ["@babel/preset-env"],
|
"presets": ["@babel/preset-env"],
|
||||||
"env": {
|
"env": {
|
||||||
|
|||||||
+65
@@ -0,0 +1,65 @@
|
|||||||
|
import { IdMap } from "medusa-test-utils"
|
||||||
|
import { request } from "../../../../../helpers/test-request"
|
||||||
|
import { CustomerGroupServiceMock } from "../../../../../services/__mocks__/customer-group"
|
||||||
|
|
||||||
|
describe("POST /customer-groups", () => {
|
||||||
|
describe("successfully calls create customer group", () => {
|
||||||
|
let subject
|
||||||
|
|
||||||
|
beforeAll(async () => {
|
||||||
|
subject = await request("POST", `/admin/customer-groups`, {
|
||||||
|
payload: {
|
||||||
|
name: "test group",
|
||||||
|
},
|
||||||
|
adminSession: {
|
||||||
|
jwt: {
|
||||||
|
userId: IdMap.getId("admin_user"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
afterAll(() => {
|
||||||
|
jest.clearAllMocks()
|
||||||
|
})
|
||||||
|
|
||||||
|
it("returns 200", () => {
|
||||||
|
expect(subject.status).toEqual(200)
|
||||||
|
})
|
||||||
|
|
||||||
|
it("calls CustomerGroupService create", () => {
|
||||||
|
expect(CustomerGroupServiceMock.create).toHaveBeenCalledTimes(1)
|
||||||
|
expect(CustomerGroupServiceMock.create).toHaveBeenCalledWith({
|
||||||
|
name: "test group",
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
describe("fails if no name is provided for the group ", () => {
|
||||||
|
let subject
|
||||||
|
|
||||||
|
beforeAll(async () => {
|
||||||
|
subject = await request("POST", `/admin/customer-groups`, {
|
||||||
|
payload: {},
|
||||||
|
adminSession: {
|
||||||
|
jwt: {
|
||||||
|
userId: IdMap.getId("admin_user"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
afterAll(() => {
|
||||||
|
jest.clearAllMocks()
|
||||||
|
})
|
||||||
|
|
||||||
|
it("returns 400", () => {
|
||||||
|
expect(subject.status).toEqual(400)
|
||||||
|
})
|
||||||
|
|
||||||
|
it("returns descriptive error that name is missing", () => {
|
||||||
|
expect(subject.body.type).toEqual("invalid_data")
|
||||||
|
expect(subject.body.message).toEqual("name must be a string")
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
import { IsObject, IsOptional, IsString } from "class-validator"
|
||||||
|
import { CustomerGroupService } from "../../../../services"
|
||||||
|
import { validator } from "../../../../utils/validator"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @oas [post] /customer-groups
|
||||||
|
* operationId: "PostCustomerGroups"
|
||||||
|
* summary: "Create a CustomerGroup"
|
||||||
|
* description: "Creates a CustomerGroup."
|
||||||
|
* x-authenticated: true
|
||||||
|
* parameters:
|
||||||
|
* - (body) name=* {string} Name of the customer group
|
||||||
|
* - (body) metadata {object} Metadata for the customer.
|
||||||
|
* tags:
|
||||||
|
* - CustomerGroup
|
||||||
|
* responses:
|
||||||
|
* 200:
|
||||||
|
* description: OK
|
||||||
|
* content:
|
||||||
|
* application/json:
|
||||||
|
* schema:
|
||||||
|
* properties:
|
||||||
|
* customerGroup:
|
||||||
|
* $ref: "#/components/schemas/customergroup"
|
||||||
|
*/
|
||||||
|
|
||||||
|
export default async (req, res) => {
|
||||||
|
const validated = await validator(AdminPostCustomerGroupsReq, req.body)
|
||||||
|
|
||||||
|
const customerGroupService: CustomerGroupService = req.scope.resolve(
|
||||||
|
"customerGroupService"
|
||||||
|
)
|
||||||
|
|
||||||
|
const customerGroup = await customerGroupService.create(validated)
|
||||||
|
res.status(200).json({ customerGroup })
|
||||||
|
}
|
||||||
|
|
||||||
|
export class AdminPostCustomerGroupsReq {
|
||||||
|
@IsString()
|
||||||
|
name: string
|
||||||
|
|
||||||
|
@IsObject()
|
||||||
|
@IsOptional()
|
||||||
|
metadata?: object
|
||||||
|
}
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
import { Router } from "express"
|
||||||
|
import { CustomerGroup } from "../../../.."
|
||||||
|
import { DeleteResponse, PaginatedResponse } from "../../../../types/common"
|
||||||
|
import middlewares from "../../../middlewares"
|
||||||
|
|
||||||
|
const route = Router()
|
||||||
|
|
||||||
|
export default (app) => {
|
||||||
|
app.use("/customer-groups", route)
|
||||||
|
|
||||||
|
route.post("/", middlewares.wrap(require("./create-customer-group").default))
|
||||||
|
return app
|
||||||
|
}
|
||||||
|
|
||||||
|
export type AdminCustomerGroupsRes = {
|
||||||
|
customer_group: CustomerGroup
|
||||||
|
}
|
||||||
|
|
||||||
|
export type AdminCustomerGroupsDeleteRes = DeleteResponse
|
||||||
|
|
||||||
|
export type AdminCustomerGroupsListRes = PaginatedResponse & {
|
||||||
|
customer_groups: CustomerGroup[]
|
||||||
|
}
|
||||||
|
|
||||||
|
export * from "./create-customer-group"
|
||||||
@@ -25,6 +25,7 @@ import collectionRoutes from "./collections"
|
|||||||
import productTagRoutes from "./product-tags"
|
import productTagRoutes from "./product-tags"
|
||||||
import notificationRoutes from "./notifications"
|
import notificationRoutes from "./notifications"
|
||||||
import noteRoutes from "./notes"
|
import noteRoutes from "./notes"
|
||||||
|
import customerGroupRoutes from "./customer-groups"
|
||||||
|
|
||||||
const route = Router()
|
const route = Router()
|
||||||
|
|
||||||
@@ -80,6 +81,7 @@ export default (app, container, config) => {
|
|||||||
productTagRoutes(route)
|
productTagRoutes(route)
|
||||||
noteRoutes(route)
|
noteRoutes(route)
|
||||||
inviteRoutes(route)
|
inviteRoutes(route)
|
||||||
|
customerGroupRoutes(route)
|
||||||
|
|
||||||
return app
|
return app
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ export { Country } from "./models/country"
|
|||||||
export { Currency } from "./models/currency"
|
export { Currency } from "./models/currency"
|
||||||
export { CustomShippingOption } from "./models/custom-shipping-option"
|
export { CustomShippingOption } from "./models/custom-shipping-option"
|
||||||
export { Customer } from "./models/customer"
|
export { Customer } from "./models/customer"
|
||||||
|
export { CustomerGroup } from "./models/customer-group"
|
||||||
export { Discount } from "./models/discount"
|
export { Discount } from "./models/discount"
|
||||||
export { DiscountRule } from "./models/discount-rule"
|
export { DiscountRule } from "./models/discount-rule"
|
||||||
export { DraftOrder } from "./models/draft-order"
|
export { DraftOrder } from "./models/draft-order"
|
||||||
|
|||||||
@@ -0,0 +1,44 @@
|
|||||||
|
import { MigrationInterface, QueryRunner } from "typeorm"
|
||||||
|
|
||||||
|
export class customerGroups1644943746861 implements MigrationInterface {
|
||||||
|
name = "customerGroups1644943746861"
|
||||||
|
|
||||||
|
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.query(
|
||||||
|
`CREATE TABLE "customer_group" ("id" character varying NOT NULL, "name" character varying NOT NULL, "created_at" TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT now(), "updated_at" TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT now(), "deleted_at" TIMESTAMP WITH TIME ZONE, "metadata" jsonb, CONSTRAINT "PK_88e7da3ff7262d9e0a35aa3664e" PRIMARY KEY ("id"))`
|
||||||
|
)
|
||||||
|
await queryRunner.query(
|
||||||
|
`CREATE UNIQUE INDEX "IDX_c4c3a5225a7a1f0af782c40abc" ON "customer_group" ("name") WHERE deleted_at IS NULL`
|
||||||
|
)
|
||||||
|
await queryRunner.query(
|
||||||
|
`CREATE TABLE "customer_group_customers" ("customer_group_id" character varying NOT NULL, "customer_id" character varying NOT NULL, CONSTRAINT "PK_e28a55e34ad1e2d3df9a0ac86d3" PRIMARY KEY ("customer_group_id", "customer_id"))`
|
||||||
|
)
|
||||||
|
await queryRunner.query(
|
||||||
|
`CREATE INDEX "IDX_620330964db8d2999e67b0dbe3" ON "customer_group_customers" ("customer_group_id") `
|
||||||
|
)
|
||||||
|
await queryRunner.query(
|
||||||
|
`CREATE INDEX "IDX_3c6412d076292f439269abe1a2" ON "customer_group_customers" ("customer_id") `
|
||||||
|
)
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "customer_group_customers" ADD CONSTRAINT "FK_620330964db8d2999e67b0dbe3e" FOREIGN KEY ("customer_group_id") REFERENCES "customer_group"("id") ON DELETE CASCADE ON UPDATE CASCADE`
|
||||||
|
)
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "customer_group_customers" ADD CONSTRAINT "FK_3c6412d076292f439269abe1a23" FOREIGN KEY ("customer_id") REFERENCES "customer"("id") ON DELETE CASCADE ON UPDATE CASCADE`
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "customer_group_customers" DROP CONSTRAINT "FK_3c6412d076292f439269abe1a23"`
|
||||||
|
)
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "customer_group_customers" DROP CONSTRAINT "FK_620330964db8d2999e67b0dbe3e"`
|
||||||
|
)
|
||||||
|
|
||||||
|
await queryRunner.query(`DROP INDEX "IDX_3c6412d076292f439269abe1a2"`)
|
||||||
|
await queryRunner.query(`DROP INDEX "IDX_620330964db8d2999e67b0dbe3"`)
|
||||||
|
await queryRunner.query(`DROP TABLE "customer_group_customers"`)
|
||||||
|
await queryRunner.query(`DROP INDEX "IDX_c4c3a5225a7a1f0af782c40abc"`)
|
||||||
|
await queryRunner.query(`DROP TABLE "customer_group"`)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,60 @@
|
|||||||
|
import {
|
||||||
|
BeforeInsert,
|
||||||
|
Column,
|
||||||
|
CreateDateColumn,
|
||||||
|
DeleteDateColumn,
|
||||||
|
Entity,
|
||||||
|
Index,
|
||||||
|
JoinTable,
|
||||||
|
ManyToMany,
|
||||||
|
PrimaryColumn,
|
||||||
|
UpdateDateColumn,
|
||||||
|
} from "typeorm"
|
||||||
|
import { ulid } from "ulid"
|
||||||
|
import { Customer } from ".."
|
||||||
|
import { DbAwareColumn, resolveDbType } from "../utils/db-aware-column"
|
||||||
|
|
||||||
|
@Entity()
|
||||||
|
export class CustomerGroup {
|
||||||
|
@PrimaryColumn()
|
||||||
|
id: string
|
||||||
|
|
||||||
|
@Index({ unique: true, where: "deleted_at IS NULL" })
|
||||||
|
@Column()
|
||||||
|
name: string
|
||||||
|
|
||||||
|
@ManyToMany(() => Customer, { cascade: true })
|
||||||
|
@JoinTable({
|
||||||
|
name: "customer_group_customers",
|
||||||
|
joinColumn: {
|
||||||
|
name: "customer_group_id",
|
||||||
|
referencedColumnName: "id",
|
||||||
|
},
|
||||||
|
inverseJoinColumn: {
|
||||||
|
name: "customer_id",
|
||||||
|
referencedColumnName: "id",
|
||||||
|
},
|
||||||
|
})
|
||||||
|
customers: Customer[]
|
||||||
|
|
||||||
|
@CreateDateColumn({ type: resolveDbType("timestamptz") })
|
||||||
|
created_at: Date
|
||||||
|
|
||||||
|
@UpdateDateColumn({ type: resolveDbType("timestamptz") })
|
||||||
|
updated_at: Date
|
||||||
|
|
||||||
|
@DeleteDateColumn({ type: resolveDbType("timestamptz") })
|
||||||
|
deleted_at: Date
|
||||||
|
|
||||||
|
@DbAwareColumn({ type: "jsonb", nullable: true })
|
||||||
|
metadata: any
|
||||||
|
|
||||||
|
@BeforeInsert()
|
||||||
|
private beforeInsert() {
|
||||||
|
if (this.id) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const id = ulid()
|
||||||
|
this.id = `cgrp_${id}`
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -10,11 +10,14 @@ import {
|
|||||||
OneToOne,
|
OneToOne,
|
||||||
OneToMany,
|
OneToMany,
|
||||||
JoinColumn,
|
JoinColumn,
|
||||||
|
ManyToMany,
|
||||||
|
JoinTable,
|
||||||
} from "typeorm"
|
} from "typeorm"
|
||||||
import { ulid } from "ulid"
|
import { ulid } from "ulid"
|
||||||
import { resolveDbType, DbAwareColumn } from "../utils/db-aware-column"
|
import { resolveDbType, DbAwareColumn } from "../utils/db-aware-column"
|
||||||
|
|
||||||
import { Address } from "./address"
|
import { Address } from "./address"
|
||||||
|
import { CustomerGroup } from "./customer-group"
|
||||||
import { Order } from "./order"
|
import { Order } from "./order"
|
||||||
|
|
||||||
@Entity()
|
@Entity()
|
||||||
@@ -40,10 +43,7 @@ export class Customer {
|
|||||||
@JoinColumn({ name: "billing_address_id" })
|
@JoinColumn({ name: "billing_address_id" })
|
||||||
billing_address: Address
|
billing_address: Address
|
||||||
|
|
||||||
@OneToMany(
|
@OneToMany(() => Address, (address) => address.customer)
|
||||||
() => Address,
|
|
||||||
address => address.customer
|
|
||||||
)
|
|
||||||
shipping_addresses: Address[]
|
shipping_addresses: Address[]
|
||||||
|
|
||||||
@Column({ nullable: true, select: false })
|
@Column({ nullable: true, select: false })
|
||||||
@@ -55,12 +55,12 @@ export class Customer {
|
|||||||
@Column({ default: false })
|
@Column({ default: false })
|
||||||
has_account: boolean
|
has_account: boolean
|
||||||
|
|
||||||
@OneToMany(
|
@OneToMany(() => Order, (order) => order.customer)
|
||||||
() => Order,
|
|
||||||
order => order.customer
|
|
||||||
)
|
|
||||||
orders: Order[]
|
orders: Order[]
|
||||||
|
|
||||||
|
@ManyToMany(() => CustomerGroup, { cascade: true })
|
||||||
|
groups: CustomerGroup[]
|
||||||
|
|
||||||
@CreateDateColumn({ type: resolveDbType("timestamptz") })
|
@CreateDateColumn({ type: resolveDbType("timestamptz") })
|
||||||
created_at: Date
|
created_at: Date
|
||||||
|
|
||||||
@@ -75,7 +75,9 @@ export class Customer {
|
|||||||
|
|
||||||
@BeforeInsert()
|
@BeforeInsert()
|
||||||
private beforeInsert() {
|
private beforeInsert() {
|
||||||
if (this.id) return
|
if (this.id) {
|
||||||
|
return
|
||||||
|
}
|
||||||
const id = ulid()
|
const id = ulid()
|
||||||
this.id = `cus_${id}`
|
this.id = `cus_${id}`
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,5 @@
|
|||||||
|
import { EntityRepository, Repository } from "typeorm"
|
||||||
|
import { CustomerGroup } from "../models/customer-group"
|
||||||
|
|
||||||
|
@EntityRepository(CustomerGroup)
|
||||||
|
export class CustomerGroupRepository extends Repository<CustomerGroup> {}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
export const CustomerGroupServiceMock = {
|
||||||
|
withTransaction: function () {
|
||||||
|
return this
|
||||||
|
},
|
||||||
|
|
||||||
|
create: jest.fn().mockImplementation((f) => {
|
||||||
|
return Promise.resolve(f)
|
||||||
|
}),
|
||||||
|
}
|
||||||
|
|
||||||
|
const mock = jest.fn().mockImplementation(() => {
|
||||||
|
return CustomerGroupServiceMock
|
||||||
|
})
|
||||||
|
|
||||||
|
export default mock
|
||||||
@@ -0,0 +1,69 @@
|
|||||||
|
import { MedusaError } from "medusa-core-utils"
|
||||||
|
import { BaseService } from "medusa-interfaces"
|
||||||
|
import { DeepPartial, EntityManager } from "typeorm"
|
||||||
|
import { CustomerGroup } from ".."
|
||||||
|
import { CustomerGroupRepository } from "../repositories/customer-group"
|
||||||
|
|
||||||
|
type CustomerGroupConstructorProps = {
|
||||||
|
manager: EntityManager
|
||||||
|
customerGroupRepository: typeof CustomerGroupRepository
|
||||||
|
}
|
||||||
|
class CustomerGroupService extends BaseService {
|
||||||
|
private manager_: EntityManager
|
||||||
|
|
||||||
|
private customerGroupRepository_: typeof CustomerGroupRepository
|
||||||
|
|
||||||
|
constructor({
|
||||||
|
manager,
|
||||||
|
customerGroupRepository,
|
||||||
|
}: CustomerGroupConstructorProps) {
|
||||||
|
super()
|
||||||
|
|
||||||
|
this.manager_ = manager
|
||||||
|
|
||||||
|
this.customerGroupRepository_ = customerGroupRepository
|
||||||
|
}
|
||||||
|
|
||||||
|
withTransaction(transactionManager: EntityManager): CustomerGroupService {
|
||||||
|
if (!transactionManager) {
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
const cloned = new CustomerGroupService({
|
||||||
|
manager: transactionManager,
|
||||||
|
customerGroupRepository: this.customerGroupRepository_,
|
||||||
|
})
|
||||||
|
|
||||||
|
cloned.transactionManager_ = transactionManager
|
||||||
|
|
||||||
|
return cloned
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a customer group with the provided data.
|
||||||
|
* @param {DeepPartial<CustomerGroup>} group - the customer group to create
|
||||||
|
* @return {Promise} the result of the create operation
|
||||||
|
*/
|
||||||
|
async create(group: DeepPartial<CustomerGroup>): Promise<CustomerGroup> {
|
||||||
|
return this.atomicPhase_(async (manager) => {
|
||||||
|
try {
|
||||||
|
const cgRepo: CustomerGroupRepository = manager.getCustomRepository(
|
||||||
|
this.customerGroupRepository_
|
||||||
|
)
|
||||||
|
|
||||||
|
const created = cgRepo.create(group)
|
||||||
|
|
||||||
|
const result = await cgRepo.save(created)
|
||||||
|
|
||||||
|
return result
|
||||||
|
} catch (err) {
|
||||||
|
if (err.code === "23505") {
|
||||||
|
throw new MedusaError(MedusaError.Types.DUPLICATE_ERROR, err.detail)
|
||||||
|
}
|
||||||
|
throw err
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default CustomerGroupService
|
||||||
@@ -234,6 +234,7 @@ class CustomerService extends BaseService {
|
|||||||
const customerRepo = this.manager_.getCustomRepository(
|
const customerRepo = this.manager_.getCustomRepository(
|
||||||
this.customerRepository_
|
this.customerRepository_
|
||||||
)
|
)
|
||||||
|
|
||||||
const validatedId = this.validateId_(customerId)
|
const validatedId = this.validateId_(customerId)
|
||||||
const query = this.buildQuery_({ id: validatedId }, config)
|
const query = this.buildQuery_({ id: validatedId }, config)
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ export { default as ClaimService } from "./claim"
|
|||||||
export { default as ClaimItemService } from "./claim-item"
|
export { default as ClaimItemService } from "./claim-item"
|
||||||
export { default as CustomShippingOptionService } from "./custom-shipping-option"
|
export { default as CustomShippingOptionService } from "./custom-shipping-option"
|
||||||
export { default as CustomerService } from "./customer"
|
export { default as CustomerService } from "./customer"
|
||||||
|
export { default as CustomerGroupService } from "./customer-group"
|
||||||
export { default as DiscountService } from "./discount"
|
export { default as DiscountService } from "./discount"
|
||||||
export { default as DraftOrderService } from "./draft-order"
|
export { default as DraftOrderService } from "./draft-order"
|
||||||
export { default as EventBusService } from "./event-bus"
|
export { default as EventBusService } from "./event-bus"
|
||||||
|
|||||||
Reference in New Issue
Block a user