|
|
@@ -1,9 +1,12 @@
|
|
|
import { Injectable } from '@nestjs/common';
|
|
|
import {
|
|
|
+ AssignShippingMethodsToChannelInput,
|
|
|
ConfigurableOperationDefinition,
|
|
|
CreateShippingMethodInput,
|
|
|
DeletionResponse,
|
|
|
DeletionResult,
|
|
|
+ Permission,
|
|
|
+ RemoveShippingMethodsFromChannelInput,
|
|
|
UpdateShippingMethodInput,
|
|
|
} from '@vendure/common/lib/generated-types';
|
|
|
import { omit } from '@vendure/common/lib/omit';
|
|
|
@@ -12,13 +15,14 @@ import { IsNull } from 'typeorm';
|
|
|
|
|
|
import { RequestContext } from '../../api/common/request-context';
|
|
|
import { RelationPaths } from '../../api/index';
|
|
|
-import { EntityNotFoundError } from '../../common/error/errors';
|
|
|
+import { EntityNotFoundError, ForbiddenError, UserInputError } from '../../common/error/errors';
|
|
|
+import { Translated } from '../../common/index';
|
|
|
import { ListQueryOptions } from '../../common/types/common-types';
|
|
|
import { assertFound, idsAreEqual } from '../../common/utils';
|
|
|
import { ConfigService } from '../../config/config.service';
|
|
|
import { Logger } from '../../config/logger/vendure-logger';
|
|
|
import { TransactionalConnection } from '../../connection/transactional-connection';
|
|
|
-import { Channel } from '../../entity/channel/channel.entity';
|
|
|
+import { ShippingMethod } from '../../entity/index';
|
|
|
import { ShippingMethodTranslation } from '../../entity/shipping-method/shipping-method-translation.entity';
|
|
|
import { ShippingMethod } from '../../entity/shipping-method/shipping-method.entity';
|
|
|
import { EventBus } from '../../event-bus';
|
|
|
@@ -30,6 +34,7 @@ import { TranslatableSaver } from '../helpers/translatable-saver/translatable-sa
|
|
|
import { TranslatorService } from '../helpers/translator/translator.service';
|
|
|
|
|
|
import { ChannelService } from './channel.service';
|
|
|
+import { RoleService } from './role.service';
|
|
|
|
|
|
/**
|
|
|
* @description
|
|
|
@@ -42,6 +47,7 @@ export class ShippingMethodService {
|
|
|
constructor(
|
|
|
private connection: TransactionalConnection,
|
|
|
private configService: ConfigService,
|
|
|
+ private roleService: RoleService,
|
|
|
private listQueryBuilder: ListQueryBuilder,
|
|
|
private channelService: ChannelService,
|
|
|
private configArgService: ConfigArgService,
|
|
|
@@ -66,7 +72,7 @@ export class ShippingMethodService {
|
|
|
ctx: RequestContext,
|
|
|
options?: ListQueryOptions<ShippingMethod>,
|
|
|
relations: RelationPaths<ShippingMethod> = [],
|
|
|
- ): Promise<PaginatedList<ShippingMethod>> {
|
|
|
+ ): Promise<PaginatedList<Translated<ShippingMethod>>> {
|
|
|
return this.listQueryBuilder
|
|
|
.build(ShippingMethod, options, {
|
|
|
relations,
|
|
|
@@ -86,7 +92,7 @@ export class ShippingMethodService {
|
|
|
shippingMethodId: ID,
|
|
|
includeDeleted = false,
|
|
|
relations: RelationPaths<ShippingMethod> = [],
|
|
|
- ): Promise<ShippingMethod | undefined> {
|
|
|
+ ): Promise<Translated<ShippingMethod> | undefined> {
|
|
|
const shippingMethod = await this.connection.findOneInChannel(
|
|
|
ctx,
|
|
|
ShippingMethod,
|
|
|
@@ -100,7 +106,7 @@ export class ShippingMethodService {
|
|
|
return (shippingMethod && this.translator.translate(shippingMethod, ctx)) ?? undefined;
|
|
|
}
|
|
|
|
|
|
- async create(ctx: RequestContext, input: CreateShippingMethodInput): Promise<ShippingMethod> {
|
|
|
+ async create(ctx: RequestContext, input: CreateShippingMethodInput): Promise<Translated<ShippingMethod>> {
|
|
|
const shippingMethod = await this.translatableSaver.create({
|
|
|
ctx,
|
|
|
input,
|
|
|
@@ -132,7 +138,7 @@ export class ShippingMethodService {
|
|
|
return assertFound(this.findOne(ctx, newShippingMethod.id));
|
|
|
}
|
|
|
|
|
|
- async update(ctx: RequestContext, input: UpdateShippingMethodInput): Promise<ShippingMethod> {
|
|
|
+ async update(ctx: RequestContext, input: UpdateShippingMethodInput): Promise<Translated<ShippingMethod>> {
|
|
|
const shippingMethod = await this.findOne(ctx, input.id);
|
|
|
if (!shippingMethod) {
|
|
|
throw new EntityNotFoundError('ShippingMethod', input.id);
|
|
|
@@ -187,6 +193,63 @@ export class ShippingMethodService {
|
|
|
};
|
|
|
}
|
|
|
|
|
|
+ async assignShippingMethodsToChannel(
|
|
|
+ ctx: RequestContext,
|
|
|
+ input: AssignShippingMethodsToChannelInput,
|
|
|
+ ): Promise<Array<Translated<ShippingMethod>>> {
|
|
|
+ const hasPermission = await this.roleService.userHasAnyPermissionsOnChannel(ctx, input.channelId, [
|
|
|
+ Permission.UpdateShippingMethod,
|
|
|
+ Permission.UpdateSettings,
|
|
|
+ ]);
|
|
|
+ if (!hasPermission) {
|
|
|
+ throw new ForbiddenError();
|
|
|
+ }
|
|
|
+ for (const shippingMethodId of input.shippingMethodIds) {
|
|
|
+ const shippingMethod = await this.connection.findOneInChannel(
|
|
|
+ ctx,
|
|
|
+ ShippingMethod,
|
|
|
+ shippingMethodId,
|
|
|
+ ctx.channelId,
|
|
|
+ );
|
|
|
+ await this.channelService.assignToChannels(ctx, ShippingMethod, shippingMethodId, [
|
|
|
+ input.channelId,
|
|
|
+ ]);
|
|
|
+ }
|
|
|
+ return this.connection
|
|
|
+ .findByIdsInChannel(ctx, ShippingMethod, input.shippingMethodIds, ctx.channelId, {})
|
|
|
+ .then(methods => methods.map(method => this.translator.translate(method, ctx)));
|
|
|
+ }
|
|
|
+
|
|
|
+ async removeShippingMethodsFromChannel(
|
|
|
+ ctx: RequestContext,
|
|
|
+ input: RemoveShippingMethodsFromChannelInput,
|
|
|
+ ): Promise<Array<Translated<ShippingMethod>>> {
|
|
|
+ const hasPermission = await this.roleService.userHasAnyPermissionsOnChannel(ctx, input.channelId, [
|
|
|
+ Permission.DeleteShippingMethod,
|
|
|
+ Permission.DeleteSettings,
|
|
|
+ ]);
|
|
|
+ if (!hasPermission) {
|
|
|
+ throw new ForbiddenError();
|
|
|
+ }
|
|
|
+ const defaultChannel = await this.channelService.getDefaultChannel(ctx);
|
|
|
+ if (idsAreEqual(input.channelId, defaultChannel.id)) {
|
|
|
+ throw new UserInputError('error.items-cannot-be-removed-from-default-channel');
|
|
|
+ }
|
|
|
+ for (const shippingMethodId of input.shippingMethodIds) {
|
|
|
+ const shippingMethod = await this.connection.getEntityOrThrow(
|
|
|
+ ctx,
|
|
|
+ ShippingMethod,
|
|
|
+ shippingMethodId,
|
|
|
+ );
|
|
|
+ await this.channelService.removeFromChannels(ctx, ShippingMethod, shippingMethodId, [
|
|
|
+ input.channelId,
|
|
|
+ ]);
|
|
|
+ }
|
|
|
+ return this.connection
|
|
|
+ .findByIdsInChannel(ctx, ShippingMethod, input.shippingMethodIds, ctx.channelId, {})
|
|
|
+ .then(methods => methods.map(method => this.translator.translate(method, ctx)));
|
|
|
+ }
|
|
|
+
|
|
|
getShippingEligibilityCheckers(ctx: RequestContext): ConfigurableOperationDefinition[] {
|
|
|
return this.configArgService
|
|
|
.getDefinitions('ShippingEligibilityChecker')
|