feat(MED-85): create customer group for company account in Medusa
This commit is contained in:
@@ -23,6 +23,7 @@ import { createAdminAccountsService } from './services/admin-accounts.service';
|
|||||||
import { createAdminAuthUserService } from './services/admin-auth-user.service';
|
import { createAdminAuthUserService } from './services/admin-auth-user.service';
|
||||||
import { createCreateCompanyAccountService } from './services/admin-create-company-account.service';
|
import { createCreateCompanyAccountService } from './services/admin-create-company-account.service';
|
||||||
import { adminAction } from './utils/admin-action';
|
import { adminAction } from './utils/admin-action';
|
||||||
|
import { getAdminSdk } from './utils/medusa-sdk';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @name banUserAction
|
* @name banUserAction
|
||||||
@@ -138,7 +139,24 @@ export const deleteAccountAction = adminAction(
|
|||||||
|
|
||||||
logger.info({ accountId }, `Super Admin is deleting account...`);
|
logger.info({ accountId }, `Super Admin is deleting account...`);
|
||||||
|
|
||||||
await service.deleteAccount(accountId);
|
const { name: customerGroupName } = await service.getAccount(accountId);
|
||||||
|
try {
|
||||||
|
await service.deleteAccount(accountId);
|
||||||
|
} catch (e) {
|
||||||
|
logger.error({ accountId }, `Error deleting company account`);
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
const medusa = getAdminSdk();
|
||||||
|
const { customer_groups } = await medusa.admin.customerGroup.list();
|
||||||
|
const customerGroup = customer_groups.find(({ name }) => name === customerGroupName);
|
||||||
|
if (customerGroup) {
|
||||||
|
try {
|
||||||
|
await medusa.admin.customerGroup.delete(customerGroup.id);
|
||||||
|
} catch (e) {
|
||||||
|
logger.error({ accountId }, `Error deleting Medusa customer group for company ${customerGroupName}`);
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
logger.info(
|
logger.info(
|
||||||
{ accountId },
|
{ accountId },
|
||||||
@@ -267,6 +285,40 @@ export const createCompanyAccountAction = enhanceAction(
|
|||||||
}
|
}
|
||||||
|
|
||||||
logger.info(ctx, `Company account created`);
|
logger.info(ctx, `Company account created`);
|
||||||
|
|
||||||
|
logger.info(ctx, `Creating Medusa customer group`);
|
||||||
|
const medusa = getAdminSdk();
|
||||||
|
const { customer_groups: existingCustomerGroups } = await medusa.admin.customerGroup.list();
|
||||||
|
const isExisting = existingCustomerGroups.find((group) => group.name === name);
|
||||||
|
if (isExisting) {
|
||||||
|
logger.info(ctx, `Customer group already exists`);
|
||||||
|
} else {
|
||||||
|
logger.info(ctx, `Creating Medusa customer group`);
|
||||||
|
const { data: account } = await client
|
||||||
|
.schema('medreport').from('accounts')
|
||||||
|
.select('medusa_account_id')
|
||||||
|
.eq('personal_code', ownerPersonalCode)
|
||||||
|
.single().throwOnError();
|
||||||
|
const medusaAccountId = account.medusa_account_id;
|
||||||
|
if (!medusaAccountId) {
|
||||||
|
logger.error(ctx, `User has no Medusa account ID`);
|
||||||
|
} else {
|
||||||
|
const { customer_group: { id: customerGroupId } } = await medusa.admin.customerGroup.create({ name });
|
||||||
|
const { customers } = await medusa.admin.customer.list({
|
||||||
|
id: medusaAccountId,
|
||||||
|
});
|
||||||
|
if (customers.length !== 1) {
|
||||||
|
logger.error(ctx, `Customer not found`);
|
||||||
|
} else {
|
||||||
|
const customerId = customers[0]!.id;
|
||||||
|
await medusa.admin.customer.batchCustomerGroups(customerId, {
|
||||||
|
add: [customerGroupId],
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
redirect(`/admin/accounts/${data.id}`);
|
redirect(`/admin/accounts/${data.id}`);
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -37,4 +37,15 @@ class AdminAccountsService {
|
|||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async getAccount(accountId: string) {
|
||||||
|
const { data } = await this.adminClient
|
||||||
|
.schema('medreport')
|
||||||
|
.from('accounts')
|
||||||
|
.select('*')
|
||||||
|
.eq('id', accountId)
|
||||||
|
.single().throwOnError();
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
16
packages/features/admin/src/lib/server/utils/medusa-sdk.ts
Normal file
16
packages/features/admin/src/lib/server/utils/medusa-sdk.ts
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
import Medusa from "@medusajs/js-sdk"
|
||||||
|
|
||||||
|
export const getAdminSdk = () => {
|
||||||
|
const medusaBackendUrl = process.env.MEDUSA_BACKEND_PUBLIC_URL!;
|
||||||
|
const medusaPublishableApiKey = process.env.NEXT_PUBLIC_MEDUSA_PUBLISHABLE_KEY!;
|
||||||
|
const key = process.env.MEDUSA_SECRET_API_KEY!;
|
||||||
|
|
||||||
|
if (!medusaBackendUrl || !medusaPublishableApiKey) {
|
||||||
|
throw new Error('Medusa environment variables not set');
|
||||||
|
}
|
||||||
|
return new Medusa({
|
||||||
|
baseUrl: medusaBackendUrl,
|
||||||
|
debug: process.env.NODE_ENV === 'development',
|
||||||
|
apiKey: key,
|
||||||
|
});
|
||||||
|
}
|
||||||
@@ -276,6 +276,12 @@ export async function medusaLoginOrRegister(credentials: {
|
|||||||
|
|
||||||
const customerCacheTag = await getCacheTag("customers");
|
const customerCacheTag = await getCacheTag("customers");
|
||||||
revalidateTag(customerCacheTag);
|
revalidateTag(customerCacheTag);
|
||||||
|
|
||||||
|
const customer = await retrieveCustomer();
|
||||||
|
if (!customer) {
|
||||||
|
throw new Error("Customer not found");
|
||||||
|
}
|
||||||
|
return customer.id;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Failed to login customer, attempting to register", error);
|
console.error("Failed to login customer, attempting to register", error);
|
||||||
try {
|
try {
|
||||||
@@ -302,6 +308,12 @@ export async function medusaLoginOrRegister(credentials: {
|
|||||||
const customerCacheTag = await getCacheTag("customers");
|
const customerCacheTag = await getCacheTag("customers");
|
||||||
revalidateTag(customerCacheTag);
|
revalidateTag(customerCacheTag);
|
||||||
await transferCart();
|
await transferCart();
|
||||||
|
|
||||||
|
const customer = await retrieveCustomer();
|
||||||
|
if (!customer) {
|
||||||
|
throw new Error("Customer not found");
|
||||||
|
}
|
||||||
|
return customer.id;
|
||||||
} catch (registerError) {
|
} catch (registerError) {
|
||||||
throw medusaError(registerError);
|
throw medusaError(registerError);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -281,6 +281,7 @@ export type Database = {
|
|||||||
primary_owner_user_id: string
|
primary_owner_user_id: string
|
||||||
public_data: Json
|
public_data: Json
|
||||||
slug: string | null
|
slug: string | null
|
||||||
|
medusa_account_id: string | null
|
||||||
updated_at: string | null
|
updated_at: string | null
|
||||||
updated_by: string | null
|
updated_by: string | null
|
||||||
}
|
}
|
||||||
@@ -302,6 +303,7 @@ export type Database = {
|
|||||||
primary_owner_user_id?: string
|
primary_owner_user_id?: string
|
||||||
public_data?: Json
|
public_data?: Json
|
||||||
slug?: string | null
|
slug?: string | null
|
||||||
|
medusa_account_id?: string | null
|
||||||
updated_at?: string | null
|
updated_at?: string | null
|
||||||
updated_by?: string | null
|
updated_by?: string | null
|
||||||
}
|
}
|
||||||
@@ -323,6 +325,7 @@ export type Database = {
|
|||||||
primary_owner_user_id?: string
|
primary_owner_user_id?: string
|
||||||
public_data?: Json
|
public_data?: Json
|
||||||
slug?: string | null
|
slug?: string | null
|
||||||
|
medusa_account_id?: string | null
|
||||||
updated_at?: string | null
|
updated_at?: string | null
|
||||||
updated_by?: string | null
|
updated_by?: string | null
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,15 +20,20 @@ export function useSignInWithEmailPassword() {
|
|||||||
const identities = user?.identities ?? [];
|
const identities = user?.identities ?? [];
|
||||||
|
|
||||||
if (identities.length === 0) {
|
if (identities.length === 0) {
|
||||||
throw new Error('User already registered');
|
throw new Error('Invalid user');
|
||||||
}
|
}
|
||||||
|
|
||||||
if ('email' in credentials) {
|
if ('email' in credentials) {
|
||||||
try {
|
try {
|
||||||
await medusaLoginOrRegister({
|
const medusaAccountId = await medusaLoginOrRegister({
|
||||||
email: credentials.email,
|
email: credentials.email,
|
||||||
password: credentials.password,
|
password: credentials.password,
|
||||||
});
|
});
|
||||||
|
await client
|
||||||
|
.schema('medreport').from('accounts')
|
||||||
|
.update({ medusa_account_id: medusaAccountId })
|
||||||
|
.eq('primary_owner_user_id', user.id)
|
||||||
|
.eq('is_personal_account', true);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
await client.auth.signOut();
|
await client.auth.signOut();
|
||||||
throw error;
|
throw error;
|
||||||
|
|||||||
@@ -39,10 +39,15 @@ export function useSignUpWithEmailAndPassword() {
|
|||||||
|
|
||||||
if ('email' in credentials) {
|
if ('email' in credentials) {
|
||||||
try {
|
try {
|
||||||
await medusaLoginOrRegister({
|
const medusaAccountId = await medusaLoginOrRegister({
|
||||||
email: credentials.email,
|
email: credentials.email,
|
||||||
password: credentials.password,
|
password: credentials.password,
|
||||||
});
|
});
|
||||||
|
await client
|
||||||
|
.schema('medreport').from('accounts')
|
||||||
|
.update({ medusa_account_id: medusaAccountId })
|
||||||
|
.eq('primary_owner_user_id', user!.id)
|
||||||
|
.eq('is_personal_account', true);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
await client.auth.signOut();
|
await client.auth.signOut();
|
||||||
throw error;
|
throw error;
|
||||||
|
|||||||
1
supabase/migrations/20250825065821_medusa_account_id.sql
Normal file
1
supabase/migrations/20250825065821_medusa_account_id.sql
Normal file
@@ -0,0 +1 @@
|
|||||||
|
ALTER TABLE medreport.accounts ADD COLUMN medusa_account_id TEXT;
|
||||||
Reference in New Issue
Block a user