Skip to content
Draft
Show file tree
Hide file tree
Changes from 6 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 @@ -44,3 +44,8 @@ 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,
};


export type FindQuery = {
Comment thread
kdelongecf marked this conversation as resolved.
Outdated
_id?: { $in: string[] };
};
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ export interface ServiceTicketV1DataApi {
getServiceTicketsOpenByRequestor(memberId: string): Promise<ServiceTicketData[]>;
getServiceTicketsClosedByRequestor(memberId: string): Promise<ServiceTicketData[]>;
getServiceTicketsByAssignedTo(communityId: string, memberId: string): Promise<ServiceTicketData[]>;
getServiceTicketsByVendor(vendorId: string): Promise<ServiceTicketData[]>;
}

export class ServiceTicketV1DataApiImpl
Expand Down Expand Up @@ -37,6 +38,10 @@ export class ServiceTicketV1DataApiImpl
let dbData = await this.findByFields({ community: communityId, assignedTo: memberId });
return this.applyPermissionFilter(dbData, this.context);
}
async getServiceTicketsByVendor(vendorId: string): Promise<ServiceTicketData[]> {
let dbData = await this.findByFields({ assignedVendor: vendorId });
return this.applyPermissionFilter(dbData, this.context);
}

private async applyPermissionFilter(serviceTickets: ServiceTicketData[], context: AppContext): Promise<ServiceTicketData[]> {
let converter = new ServiceTicketV1Converter();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,14 @@ export class ServiceTicketV1DomainApiImpl extends DomainDataSource<AppContext, S
serviceDo = new ServiceConverter().toDomain(service, ReadOnlyInfrastructureContext(), ReadOnlyDomainExecutionContext());
}

if(input.assignedVendor?.length) //check for empty, undefined, null
Comment thread
kdelongecf marked this conversation as resolved.
Outdated
{
const vendorUser = await this.context.applicationServices.users.vendorUser.dataApi.getUserById(input.assignedVendor);
if(!vendorUser?._id){
throw new Error('Vendor not found');
}
}

console.log(`serviceTicketCreate:memberDO`, memberDo);
console.log(`serviceTicketCreate:requestorId`, input.requestorId);

Expand Down Expand Up @@ -165,7 +173,14 @@ export class ServiceTicketV1DomainApiImpl extends DomainDataSource<AppContext, S
serviceTicket.revisionRequest.RevisionSubmittedAt = input.revisionRequest.revisionSubmittedAt;
}
}


if(input.assignedVendor?.length) //check for empty, undefined, null
Comment thread
kdelongecf marked this conversation as resolved.
Outdated
{
const vendorUser = await this.context.applicationServices.users.vendorUser.dataApi.getUserById(input.assignedVendor);
Comment thread
kdelongecf marked this conversation as resolved.
Outdated
if(!vendorUser?._id){
throw new Error('Vendor not found');
}
}

serviceTicketToReturn = new ServiceTicketV1Converter().toPersistence(await repo.save(serviceTicket));
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,15 @@ export class CommunityDomainApiImpl
throw new Error('Unauthorized');
}

if(community.approvedVendors){
Comment thread
kdelongecf marked this conversation as resolved.
const {approvedVendors} = community;
const vendorIds:string[] = approvedVendors.map((vendor) => vendor.vendorId);
const vendors = await this._context.applicationServices.users.vendorUser.dataApi.getUsers({ _id: { $in: vendorIds } });
if(vendors.length !== approvedVendors.length){
throw new Error('Not all approved vendors exist');
}
}

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 = (community.approvedVendors);
result = (new CommunityConverter()).toPersistence(await repo.save(domainObject));
});
return result;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
import { CosmosDataSource } from "../../../data-sources/cosmos-data-source";
import { VendorUserData } from "../../../external-dependencies/datastore";
import { AppContext } from "../../../init/app-context-builder";
import { FindQuery } from "../../../../../seedwork/services-seedwork-datastore-mongodb/interfaces/base";

export interface VendorUserDataApi {
getUserById(userId : string): Promise<VendorUserData>;
getUserByExternalId(externalId : string): Promise<VendorUserData>;
getUsers(): Promise<VendorUserData[]>;
getUsers(findQuery?: FindQuery): Promise<VendorUserData[]>;
}

export class VendorUserDataApiImpl
extends CosmosDataSource<VendorUserData, AppContext>
implements VendorUserDataApi {
Expand All @@ -19,11 +21,11 @@ export class VendorUserDataApiImpl
return (await this.findByFields({ externalId: externalId }))[0];
}

async getUsers(): Promise<VendorUserData[]> {
async getUsers(findQuery?: FindQuery): Promise<VendorUserData[]> {
Comment thread
kdelongecf marked this conversation as resolved.
Outdated
console.log(`getUsers:context${JSON.stringify(this.context.verifiedUser)}`);
return this.model
.find({})
.exec();
.find(findQuery && typeof findQuery === 'object' ? findQuery : {}) // Ensures it's an object before using it
.exec();
}

}
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 { ApprovedVendor } from '../../../../../infrastructure-services-impl/datastore/mongodb/models/community';

export interface CommunityProps extends DomainEntityProps {
name: string;
Expand All @@ -17,6 +18,7 @@ export interface CommunityProps extends DomainEntityProps {
readonly schemaVersion: string;
readonly createdBy: EndUserProps;
setCreatedByRef(user: EndUserEntityReference): void;
approvedVendors?: ApprovedVendor[];
Comment thread
kdelongecf marked this conversation as resolved.
Outdated
}

export interface CommunityEntityReference extends Readonly<Omit<CommunityProps, 'createdBy' | 'setCreatedByRef'>> {
Expand Down Expand Up @@ -110,6 +112,13 @@ export class Community<props extends CommunityProps> extends AggregateRoot<props
this.props.handle = handle ? new ValueObjects.Handle(handle).valueOf() : null;
}

set ApprovedVendors(approvedVendors: ApprovedVendor[]) {
Comment thread
kdelongecf marked this conversation as resolved.
Outdated
if (!this.isNew && !this.visa.determineIf((permissions) => permissions.canManageCommunitySettings)) {
throw new Error('You do not have permission to change the handle of this community');
}
this.props.approvedVendors = approvedVendors ? new ValueObjects.ApprovedVendors(approvedVendors).valueOf() : null;
}

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,13 @@
import {
VOString
} from '@lucaspaganini/value-objects';
import { VOArray, VOObject, 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 }) {}
class ApprovedVendor extends VOObject({
Comment thread
kdelongecf marked this conversation as resolved.
Outdated
vendorId: String,
displayName: String,
email: String,
approvedBy: String,
}) {}
export class ApprovedVendors extends VOArray(ApprovedVendor, { maxLength: 50 }) {}
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,21 @@ export type Approval = {
isApplicantApproved?: Maybe<Scalars['Boolean']>;
};

export type ApprovedVendors = {
__typename?: 'ApprovedVendors';
approvedBy?: Maybe<Scalars['String']>;
displayName?: Maybe<Scalars['String']>;
email?: Maybe<Scalars['String']>;
vendorId?: Maybe<Scalars['String']>;
};

export type ApprovedVendorsInput = {
approvedBy: Scalars['String'];
displayName: Scalars['String'];
email: Scalars['String'];
vendorId: Scalars['String'];
};

export type BedroomDetails = MongoSubdocument & {
__typename?: 'BedroomDetails';
bedDescriptions?: Maybe<Array<Maybe<Scalars['String']>>>;
Expand Down Expand Up @@ -237,6 +252,7 @@ export enum CacheControlScope {

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

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

export type ServiceTicketCreateInput = {
assignedVendor?: InputMaybe<Scalars['String']>;
description: Scalars['String'];
propertyId: Scalars['ObjectID'];
requestorId?: InputMaybe<Scalars['ObjectID']>;
Expand Down Expand Up @@ -1575,6 +1594,7 @@ export type ServiceTicketSubmitInput = {
};

export type ServiceTicketUpdateInput = {
assignedVendor?: InputMaybe<Scalars['String']>;
description?: InputMaybe<Scalars['String']>;
messages?: InputMaybe<Array<InputMaybe<ServiceTicketV1MessageInput>>>;
priority?: InputMaybe<Scalars['Int']>;
Expand Down Expand Up @@ -2152,6 +2172,8 @@ export type ResolversTypes = ResolversObject<{
AdhocPaymentRequestInput: AdhocPaymentRequestInput;
AdhocTransaction: ResolverTypeWrapper<AdhocTransaction>;
Approval: ResolverTypeWrapper<Approval>;
ApprovedVendors: ResolverTypeWrapper<ApprovedVendors>;
ApprovedVendorsInput: ApprovedVendorsInput;
BedroomDetails: ResolverTypeWrapper<BedroomDetails>;
BedroomDetailsInput: BedroomDetailsInput;
BigInt: ResolverTypeWrapper<Scalars['BigInt']>;
Expand Down Expand Up @@ -2434,6 +2456,8 @@ export type ResolversParentTypes = ResolversObject<{
AdhocPaymentRequestInput: AdhocPaymentRequestInput;
AdhocTransaction: AdhocTransaction;
Approval: Approval;
ApprovedVendors: ApprovedVendors;
ApprovedVendorsInput: ApprovedVendorsInput;
BedroomDetails: BedroomDetails;
BedroomDetailsInput: BedroomDetailsInput;
BigInt: Scalars['BigInt'];
Expand Down Expand Up @@ -2783,6 +2807,17 @@ export type ApprovalResolvers<ContextType = GraphqlContext, ParentType extends R
__isTypeOf?: IsTypeOfResolverFn<ParentType, ContextType>;
}>;

export type ApprovedVendorsResolvers<
ContextType = GraphqlContext,
ParentType extends ResolversParentTypes['ApprovedVendors'] = ResolversParentTypes['ApprovedVendors'],
> = ResolversObject<{
approvedBy?: Resolver<Maybe<ResolversTypes['String']>, ParentType, ContextType>;
displayName?: Resolver<Maybe<ResolversTypes['String']>, ParentType, ContextType>;
email?: Resolver<Maybe<ResolversTypes['String']>, ParentType, ContextType>;
vendorId?: Resolver<Maybe<ResolversTypes['String']>, ParentType, ContextType>;
__isTypeOf?: IsTypeOfResolverFn<ParentType, ContextType>;
}>;

export type BedroomDetailsResolvers<
ContextType = GraphqlContext,
ParentType extends ResolversParentTypes['BedroomDetails'] = ResolversParentTypes['BedroomDetails'],
Expand Down Expand Up @@ -2835,6 +2870,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['ApprovedVendors']>>>, 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 +3836,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['String']>, ParentType, ContextType>;
community?: Resolver<ResolversTypes['Community'], ParentType, ContextType>;
createdAt?: Resolver<Maybe<ResolversTypes['DateTime']>, ParentType, ContextType>;
description?: Resolver<ResolversTypes['String'], ParentType, ContextType>;
Expand Down Expand Up @@ -4249,6 +4286,7 @@ export type Resolvers<ContextType = GraphqlContext> = ResolversObject<{
Address?: AddressResolvers<ContextType>;
AdhocTransaction?: AdhocTransactionResolvers<ContextType>;
Approval?: ApprovalResolvers<ContextType>;
ApprovedVendors?: ApprovedVendorsResolvers<ContextType>;
BedroomDetails?: BedroomDetailsResolvers<ContextType>;
BigInt?: GraphQLScalarType;
BlobAuthHeader?: BlobAuthHeaderResolvers<ContextType>;
Expand Down
Loading