mv.service.ts 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. import { Injectable } from '@nestjs/common';
  2. import { CreateAdministratorInput, Permission } from '@vendure/common/lib/generated-types';
  3. import { normalizeString } from '@vendure/common/lib/normalize-string';
  4. import {
  5. AdministratorService,
  6. Channel,
  7. ChannelService,
  8. ConfigService,
  9. defaultShippingCalculator,
  10. InternalServerError,
  11. isGraphQlErrorResult,
  12. manualFulfillmentHandler,
  13. RequestContext,
  14. RoleService,
  15. SellerService,
  16. ShippingMethod,
  17. ShippingMethodService,
  18. TaxSetting,
  19. } from '@vendure/core';
  20. import { multivendorShippingEligibilityChecker } from '../config/mv-shipping-eligibility-checker';
  21. @Injectable()
  22. export class MultivendorService {
  23. constructor(
  24. private administratorService: AdministratorService,
  25. private sellerService: SellerService,
  26. private roleService: RoleService,
  27. private channelService: ChannelService,
  28. private shippingMethodService: ShippingMethodService,
  29. private configService: ConfigService,
  30. ) {}
  31. async registerNewSeller(
  32. ctx: RequestContext,
  33. input: { shopName: string; administrator: CreateAdministratorInput },
  34. ) {
  35. const channel = await this.createSellerChannelRoleAdmin(ctx, input);
  36. await this.createSellerShippingMethod(ctx, input.shopName, channel);
  37. return channel;
  38. }
  39. private async createSellerShippingMethod(ctx: RequestContext, shopName: string, sellerChannel: Channel) {
  40. const defaultChannel = await this.channelService.getDefaultChannel(ctx);
  41. const { shippingEligibilityCheckers, shippingCalculators, fulfillmentHandlers } =
  42. this.configService.shippingOptions;
  43. const shopCode = normalizeString(shopName, '-');
  44. const checker = shippingEligibilityCheckers.find(
  45. c => c.code === multivendorShippingEligibilityChecker.code,
  46. );
  47. const calculator = shippingCalculators.find(c => c.code === defaultShippingCalculator.code);
  48. const fulfillmentHandler = fulfillmentHandlers.find(h => h.code === manualFulfillmentHandler.code);
  49. if (!checker) {
  50. throw new InternalServerError(
  51. 'Could not find a suitable ShippingEligibilityChecker for the seller',
  52. );
  53. }
  54. if (!calculator) {
  55. throw new InternalServerError('Could not find a suitable ShippingCalculator for the seller');
  56. }
  57. if (!fulfillmentHandler) {
  58. throw new InternalServerError('Could not find a suitable FulfillmentHandler for the seller');
  59. }
  60. const shippingMethod = await this.shippingMethodService.create(ctx, {
  61. code: `${shopCode}-shipping`,
  62. checker: {
  63. code: checker.code,
  64. arguments: [],
  65. },
  66. calculator: {
  67. code: calculator.code,
  68. arguments: [
  69. { name: 'rate', value: '500' },
  70. { name: 'includesTax', value: TaxSetting.auto },
  71. { name: 'taxRate', value: '20' },
  72. ],
  73. },
  74. fulfillmentHandler: fulfillmentHandler.code,
  75. translations: [
  76. {
  77. languageCode: defaultChannel.defaultLanguageCode,
  78. name: `Standard Shipping for ${shopName}`,
  79. },
  80. ],
  81. });
  82. await this.channelService.assignToChannels(ctx, ShippingMethod, shippingMethod.id, [
  83. sellerChannel.id,
  84. ]);
  85. }
  86. private async createSellerChannelRoleAdmin(
  87. ctx: RequestContext,
  88. input: { shopName: string; administrator: CreateAdministratorInput },
  89. ) {
  90. const defaultChannel = await this.channelService.getDefaultChannel(ctx);
  91. const shopCode = normalizeString(input.shopName, '-');
  92. const seller = await this.sellerService.create(ctx, {
  93. name: input.shopName,
  94. customFields: {
  95. connectedAccountId: Math.random().toString(30).substring(3),
  96. },
  97. });
  98. const channel = await this.channelService.create(ctx, {
  99. code: shopCode,
  100. sellerId: seller.id,
  101. token: `${shopCode}-token`,
  102. currencyCode: defaultChannel.defaultCurrencyCode,
  103. defaultLanguageCode: defaultChannel.defaultLanguageCode,
  104. pricesIncludeTax: defaultChannel.pricesIncludeTax,
  105. defaultShippingZoneId: defaultChannel.defaultShippingZone.id,
  106. defaultTaxZoneId: defaultChannel.defaultTaxZone.id,
  107. });
  108. if (isGraphQlErrorResult(channel)) {
  109. throw new InternalServerError(channel.message);
  110. }
  111. const superAdminRole = await this.roleService.getSuperAdminRole(ctx);
  112. const customerRole = await this.roleService.getCustomerRole(ctx);
  113. await this.roleService.assignRoleToChannel(ctx, superAdminRole.id, channel.id);
  114. const role = await this.roleService.create(ctx, {
  115. code: `${shopCode}-admin`,
  116. channelIds: [channel.id],
  117. description: `Administrator of ${input.shopName}`,
  118. permissions: [
  119. Permission.CreateCatalog,
  120. Permission.UpdateCatalog,
  121. Permission.ReadCatalog,
  122. Permission.DeleteCatalog,
  123. Permission.CreateOrder,
  124. Permission.ReadOrder,
  125. Permission.UpdateOrder,
  126. Permission.DeleteOrder,
  127. Permission.ReadCustomer,
  128. Permission.ReadPaymentMethod,
  129. Permission.ReadShippingMethod,
  130. Permission.ReadPromotion,
  131. Permission.ReadCountry,
  132. Permission.ReadZone,
  133. Permission.CreateCustomer,
  134. Permission.UpdateCustomer,
  135. Permission.DeleteCustomer,
  136. Permission.CreateTag,
  137. Permission.ReadTag,
  138. Permission.UpdateTag,
  139. Permission.DeleteTag,
  140. ],
  141. });
  142. const administrator = await this.administratorService.create(ctx, {
  143. firstName: input.administrator.firstName,
  144. lastName: input.administrator.lastName,
  145. emailAddress: input.administrator.emailAddress,
  146. password: input.administrator.password,
  147. roleIds: [role.id],
  148. });
  149. return channel;
  150. }
  151. }