Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -43,4 +43,4 @@ export const NestedPathOptions : SchemaOptions = {
export const Patterns = {
EMAIL_PATTERN: /^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/,
GUID_PATTERN: /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i,
};
};
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { DomainDataSource } from '../../../../data-sources/domain-data-source';
import { Member } from '../../../../domain/contexts/community/member/member';
import { ReadOnlyDomainVisa } from '../../../../domain/domain.visa';
import { Service } from '../../../../domain/contexts/community/service/service';
import { ServiceTicketV1 } from '../../../../domain/contexts/cases/service-ticket/v1/service-ticket-v1';
import { SentBy, Message, Embedding } from '../../../../domain/contexts/cases/service-ticket/v1/service-ticket-v1-message.value-objects';
Expand All @@ -15,6 +14,7 @@ import {
ServiceDomainAdapter,
ServiceConverter,
ServiceTicketV1Converter,
VendorUserConverter,
} from '../../../../external-dependencies/domain';
import {
ServiceTicketAddUpdateActivityInput,
Expand Down Expand Up @@ -165,7 +165,14 @@ export class ServiceTicketV1DomainApiImpl extends DomainDataSource<AppContext, S
serviceTicket.revisionRequest.RevisionSubmittedAt = input.revisionRequest.revisionSubmittedAt;
}
}


if(input.assignedVendor !== undefined)
{

let vendor = await this.context.applicationServices.users.vendorUser.dataApi.getUserById(input.assignedVendor);
let vendorDo = new VendorUserConverter().toDomain(vendor, ReadOnlyInfrastructureContext(), ReadOnlyDomainExecutionContext());
serviceTicket.AssignedVendor = vendorDo;
}

serviceTicketToReturn = new ServiceTicketV1Converter().toPersistence(await repo.save(serviceTicket));
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { CommunityVisa } from "../../domain/contexts/community/community.visa";
import { Community } from "../../domain/contexts/community/community/community";
import { ReadOnlyDomainExecutionContext } from "../../domain/domain-execution-context";
import { CommunityData } from "../../external-dependencies/datastore";
import { CommunityDomainAdapter, EndUserConverter, CommunityConverter, CommunityRepository } from "../../external-dependencies/domain";
import { CommunityDomainAdapter, EndUserConverter, CommunityConverter, CommunityRepository, VendorUserConverter } from "../../external-dependencies/domain";
import { CommunityCreateInput, CommunityUpdateInput } from "../../external-dependencies/graphql-api";
import { AppContext } from "../../init/app-context-builder";
import { ReadOnlyInfrastructureContext } from "../../init/infrastructure-context";
Expand Down Expand Up @@ -43,7 +43,16 @@ export class CommunityDomainApiImpl
if (this.context.verifiedUser.openIdConfigKey !== 'AccountPortal') {
throw new Error('Unauthorized');
}

const vendorsList = []
if(community.approvedVendors){
const {approvedVendors} = community;
for(const approvedVendor of approvedVendors){
const vendor = await this._context.applicationServices.users.vendorUser.dataApi.getUserById(approvedVendor.id);
const vendorDo = new VendorUserConverter().toDomain(vendor, ReadOnlyInfrastructureContext(), ReadOnlyDomainExecutionContext());
vendorsList.push(vendorDo);
}
}

let result: CommunityData;
await this.withTransaction(async (repo) => {
let domainObject = await repo.get(community.id);
Expand All @@ -54,6 +63,7 @@ export class CommunityDomainApiImpl
domainObject.Domain = (community.domain);
domainObject.WhiteLabelDomain = (community.whiteLabelDomain);
domainObject.Handle = (community.handle);
domainObject.ApprovedVendors = (vendorsList);
result = (new CommunityConverter()).toPersistence(await repo.save(domainObject));
});
return result;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ export interface VendorUserDataApi {
getUserByExternalId(externalId : string): Promise<VendorUserData>;
getUsers(): Promise<VendorUserData[]>;
}

export class VendorUserDataApiImpl
extends CosmosDataSource<VendorUserData, AppContext>
implements VendorUserDataApi {
Expand All @@ -22,8 +23,8 @@ export class VendorUserDataApiImpl
async getUsers(): Promise<VendorUserData[]> {
console.log(`getUsers:context${JSON.stringify(this.context.verifiedUser)}`);
return this.model
.find({})
.exec();
.find()
.exec();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import { ServiceTicketV1Message, ServiceTicketV1MessageEntityReference, ServiceT
import { ServiceTicketV1RevisionRequest, ServiceTicketV1RevisionRequestEntityReference, ServiceTicketV1RevisionRequestProps } from './service-ticket-v1-revision-request';
import { ServiceTicketV1SyncDomainEventFactory, ServiceTicketV1SyncDomainEventFactoryImpl } from './sync-domain-events/service-ticket-v1.sync-domain-event-factory';
import { ServiceTicketV1SyncDomainEventHandlers } from './sync-domain-events/service-ticket-v1.sync-domain-event-handlers';

import { VendorUserEntityReference, VendorUserProps } from '../../../users/vendor-user/vendor-user';

export interface ServiceTicketV1Props extends DomainEntityProps {
readonly community: CommunityProps;
Expand All @@ -32,11 +32,14 @@ export interface ServiceTicketV1Props extends DomainEntityProps {
setAssignedToRef(assignedTo: MemberEntityReference): void;
readonly service: ServiceProps;
setServiceRef(service: ServiceEntityReference): void;
readonly assignedVendor?: VendorUserProps;
setAssignedVendorRef?: (approvedVendors: VendorUserEntityReference) => void;
title: string;
description: string;
readonly ticketType?: string;
status: string;
priority: number;

readonly activityLog: PropArray<ActivityDetailProps>;
readonly messages: PropArray<ServiceTicketV1MessageProps>;
readonly revisionRequest?: ServiceTicketV1RevisionRequestProps;
Expand Down Expand Up @@ -69,6 +72,8 @@ export interface ServiceTicketV1EntityReference
| 'messages'
| 'photos'
| 'revisionRequest'
| 'assignedVendor'
| 'setAssignedVendorRef'
>
> {
readonly community: CommunityEntityReference;
Expand All @@ -80,6 +85,7 @@ export interface ServiceTicketV1EntityReference
readonly messages: ReadonlyArray<ServiceTicketV1MessageEntityReference>;
readonly photos: ReadonlyArray<PhotoEntityReference>;
readonly revisionRequest: ServiceTicketV1RevisionRequestEntityReference;
readonly assignedVendor?: VendorUserEntityReference;
}

export interface ServiceTicketV1RootRegistry extends AggregateRootTypeForApplicationService<DomainExecutionContext> {
Expand All @@ -106,7 +112,8 @@ export class ServiceTicketV1<props extends ServiceTicketV1Props> extends Aggrega
community: CommunityEntityReference,
property: PropertyEntityReference,
requestor: MemberEntityReference,
context: DomainExecutionContext
context: DomainExecutionContext,
assignedVendor?: VendorUserEntityReference
): ServiceTicketV1<props> {
let serviceTicket = new ServiceTicketV1(newProps, context);
serviceTicket.MarkAsNew();
Expand All @@ -120,6 +127,9 @@ export class ServiceTicketV1<props extends ServiceTicketV1Props> extends Aggrega
serviceTicket.Priority = 5;
serviceTicket.syncDomainEventFactory.addServiceTicketV1CreatedEvent({ requestor });
serviceTicket.isNew = false;
if(assignedVendor){
serviceTicket.AssignedVendor = assignedVendor;
}
return serviceTicket;
}

Expand Down Expand Up @@ -188,6 +198,10 @@ export class ServiceTicketV1<props extends ServiceTicketV1Props> extends Aggrega
return this.props.revisionRequest ? new ServiceTicketV1RevisionRequest(this.props.revisionRequest, this.context, this.visa) : undefined;
}

get assignedVendor() {
return this.props.assignedVendor
}

private readonly validStatusTransitions = new Map<string, string[]>([
[ValueObjects.StatusCodes.Draft, [ValueObjects.StatusCodes.Submitted]],
[ValueObjects.StatusCodes.Submitted, [ValueObjects.StatusCodes.Draft, ValueObjects.StatusCodes.Assigned]],
Expand Down Expand Up @@ -226,7 +240,7 @@ export class ServiceTicketV1<props extends ServiceTicketV1Props> extends Aggrega
) {
throw new Error('Unauthorized1');
}
this.props.setPropertyRef(property);this.Description
this.props.setPropertyRef(property);
}

private set Requestor(requestor: MemberEntityReference) {
Expand All @@ -239,6 +253,13 @@ export class ServiceTicketV1<props extends ServiceTicketV1Props> extends Aggrega
this.props.setRequestorRef(requestor);
}

set AssignedVendor(assignedVendor: VendorUserEntityReference) {
if (!this.isNew) {
throw new Error('Unauthorized');
}
this.props.setAssignedVendorRef(assignedVendor);
}

set AssignedTo(assignedTo: MemberEntityReference) {
if (!this.isNew && !this.visa.determineIf((permissions) => permissions.isSystemAccount || permissions.canAssignTickets)) {
throw new Error('Unauthorized2');
Expand Down Expand Up @@ -275,7 +296,6 @@ export class ServiceTicketV1<props extends ServiceTicketV1Props> extends Aggrega
}
this.props.description = new ValueObjects.Description(description).valueOf();
}


set Status(statusCode: ValueObjects.StatusCode) {
if (!this.isNew && !this.visa.determineIf((permissions) => permissions.isSystemAccount)) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { VOString, VOSet, VOInteger, VOObject, VOOptional } from '@lucaspaganini/value-objects';
import { DateTime } from 'graphql-scalars/typings/typeDefs';
import { VOString, VOSet, VOInteger } from '@lucaspaganini/value-objects';

export const StatusCodes = {
Draft: 'DRAFT',
Expand All @@ -10,7 +9,7 @@ export const StatusCodes = {
Closed: 'CLOSED',
};

export class Title extends VOString({ trim: true, maxLength: 200, minLength: 5 }) { }
export class Description extends VOString({ trim: true, maxLength: 2000 }) { }
export class StatusCode extends VOSet(Object.values(StatusCodes)) { }
export class Priority extends VOInteger({ min: 1, max: 5 }) { }
export class Title extends VOString({ trim: true, maxLength: 200, minLength: 5 }) {}
export class Description extends VOString({ trim: true, maxLength: 2000 }) {}
export class StatusCode extends VOSet(Object.values(StatusCodes)) {}
export class Priority extends VOInteger({ min: 1, max: 5 }) {}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { DomainExecutionContext, SystemDomainExecutionContext } from '../../../d
import { CommunityVisa } from "../community.visa";
import { EndUser, EndUserEntityReference, EndUserProps } from '../../users/end-user/end-user';
import * as ValueObjects from './community.value-objects';
import { VendorUserEntityReference, VendorUserProps } from '../../users/vendor-user/vendor-user';

export interface CommunityProps extends DomainEntityProps {
name: string;
Expand All @@ -17,10 +18,13 @@ export interface CommunityProps extends DomainEntityProps {
readonly schemaVersion: string;
readonly createdBy: EndUserProps;
setCreatedByRef(user: EndUserEntityReference): void;
readonly approvedVendors?: VendorUserProps[];
setApprovedVendorsRef?: (approvedVendors: VendorUserEntityReference[]) => void;
}

export interface CommunityEntityReference extends Readonly<Omit<CommunityProps, 'createdBy' | 'setCreatedByRef'>> {
export interface CommunityEntityReference extends Readonly<Omit<CommunityProps, 'createdBy' | 'setCreatedByRef' | 'approvedVendors' | 'setApprovedVendorsRef'>> {
readonly createdBy: EndUserEntityReference;
readonly approvedVendors?: VendorUserEntityReference[];
}

export class Community<props extends CommunityProps> extends AggregateRoot<props, DomainExecutionContext, CommunityVisa> implements CommunityEntityReference {
Expand Down Expand Up @@ -110,6 +114,16 @@ export class Community<props extends CommunityProps> extends AggregateRoot<props
this.props.handle = handle ? new ValueObjects.Handle(handle).valueOf() : null;
}

set ApprovedVendors(approvedVendors: VendorUserEntityReference[]) {
if (!this.isNew && !this.visa.determineIf((permissions) => permissions.canManageCommunitySettings)) {
throw new Error('You do not have permission to change the handle of this community');
}
if (approvedVendors === null || approvedVendors === undefined) {
throw new Error('approvedVendors cannot be null or undefined');
}
this.props.setApprovedVendorsRef(approvedVendors);
}

set CreatedBy(createdBy: EndUserEntityReference) {
if (!this.isNew && !this.visa.determineIf((permissions) => permissions.canManageCommunitySettings)) {
throw new Error('You do not have permission to change the created by of this community');
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
import {
VOString
} from '@lucaspaganini/value-objects';
import { VOString } from '@lucaspaganini/value-objects';

export class Name extends VOString({trim:true, maxLength:200}) {}
export class Domain extends VOString({trim:true, maxLength:500}) {}
export class WhiteLabelDomain extends VOString({trim:true, maxLength:500}) {}
export class Handle extends VOString({trim:true, maxLength:50}) {}
export class Name extends VOString({ trim: true, maxLength: 200 }) {}
export class Domain extends VOString({ trim: true, maxLength: 500 }) {}
export class WhiteLabelDomain extends VOString({ trim: true, maxLength: 500 }) {}
export class Handle extends VOString({ trim: true, maxLength: 50 }) {}
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,7 @@ export enum CacheControlScope {

export type Community = MongoBase & {
__typename?: 'Community';
approvedVendors?: Maybe<Array<Maybe<VendorUser>>>;
createdAt?: Maybe<Scalars['DateTime']>;
domain?: Maybe<Scalars['String']>;
domainStatus?: Maybe<CommunityDomainResult>;
Expand Down Expand Up @@ -326,6 +327,7 @@ export type CommunityPublicFileRemoveInput = {
};

export type CommunityUpdateInput = {
approvedVendors?: InputMaybe<Array<InputMaybe<Scalars['ObjectID']>>>;
domain?: InputMaybe<Scalars['String']>;
handle?: InputMaybe<Scalars['String']>;
id: Scalars['ID'];
Expand Down Expand Up @@ -1465,6 +1467,7 @@ export type ServiceTicket = MongoBase & {
__typename?: 'ServiceTicket';
activityLog?: Maybe<Array<Maybe<ServiceTicketActivityDetail>>>;
assignedTo?: Maybe<Member>;
assignedVendor?: Maybe<VendorUser>;
community: Community;
createdAt?: Maybe<Scalars['DateTime']>;
description: Scalars['String'];
Expand Down Expand Up @@ -1575,6 +1578,7 @@ export type ServiceTicketSubmitInput = {
};

export type ServiceTicketUpdateInput = {
assignedVendor?: InputMaybe<Scalars['ObjectID']>;
description?: InputMaybe<Scalars['String']>;
messages?: InputMaybe<Array<InputMaybe<ServiceTicketV1MessageInput>>>;
priority?: InputMaybe<Scalars['Int']>;
Expand Down Expand Up @@ -2835,6 +2839,7 @@ export interface ByteScalarConfig extends GraphQLScalarTypeConfig<ResolversTypes
}

export type CommunityResolvers<ContextType = GraphqlContext, ParentType extends ResolversParentTypes['Community'] = ResolversParentTypes['Community']> = ResolversObject<{
approvedVendors?: Resolver<Maybe<Array<Maybe<ResolversTypes['VendorUser']>>>, ParentType, ContextType>;
createdAt?: Resolver<Maybe<ResolversTypes['DateTime']>, ParentType, ContextType>;
domain?: Resolver<Maybe<ResolversTypes['String']>, ParentType, ContextType>;
domainStatus?: Resolver<Maybe<ResolversTypes['CommunityDomainResult']>, ParentType, ContextType>;
Expand Down Expand Up @@ -3800,6 +3805,7 @@ export type ServiceTicketResolvers<
> = ResolversObject<{
activityLog?: Resolver<Maybe<Array<Maybe<ResolversTypes['ServiceTicketActivityDetail']>>>, ParentType, ContextType>;
assignedTo?: Resolver<Maybe<ResolversTypes['Member']>, ParentType, ContextType>;
assignedVendor?: Resolver<Maybe<ResolversTypes['VendorUser']>, ParentType, ContextType>;
community?: Resolver<ResolversTypes['Community'], ParentType, ContextType>;
createdAt?: Resolver<Maybe<ResolversTypes['DateTime']>, ParentType, ContextType>;
description?: Resolver<ResolversTypes['String'], ParentType, ContextType>;
Expand Down
Loading
Loading