public ProductAssociationType(IDataLoaderContextAccessor dataLoader, IMediator mediator) { Name = "ProductAssociation"; Description = "product association."; Field(d => d.Type); Field(d => d.Priority); Field("Quantity", x => x.Quantity, nullable: true, type: typeof(IntGraphType)); Field(d => d.AssociatedObjectId); Field(d => d.AssociatedObjectType); var productField = new FieldType { Name = "product", Type = GraphTypeExtenstionHelper.GetActualType <ProductType>(), Resolver = new AsyncFieldResolver <ProductAssociation, object>(async context => { var loader = dataLoader.Context.GetOrAddBatchLoader <string, ExpProduct>("associatedProductLoader", (ids) => LoadProductsAsync(mediator, ids)); // IMPORTANT: In order to avoid deadlocking on the loader we use the following construct (next 2 lines): var loadHandle = loader.LoadAsync(context.Source.AssociatedObjectId); return(await loadHandle); }) }; AddField(productField); }
public ProductRecommendationType( IMediator mediator, IDataLoaderContextAccessor dataLoader) { Name = "ProductRecommendation"; Description = "Product recommendation object"; Field(d => d.ProductId).Description("The unique ID of the product."); Field(d => d.Scenario).Description("The recommendation scenario name."); Field(d => d.Score).Description("The recommendation relevance score."); var productField = new FieldType { Name = "product", Type = GraphTypeExtenstionHelper.GetActualType <ProductType>(), Resolver = new FuncFieldResolver <ProductRecommendation, IDataLoaderResult <ExpProduct> >(context => { var includeFields = context.SubFields.Values.GetAllNodesPaths().ToArray(); var loader = dataLoader.Context.GetOrAddBatchLoader <string, ExpProduct>($"recommendedProducts", (ids) => LoadProductsAsync(mediator, context, ids, includeFields)); return(loader.LoadAsync(context.Source.ProductId)); }) }; AddField(productField); }
public void Build(ISchema schema) { _ = schema.Query.AddField(new FieldType { Name = "menus", Arguments = new QueryArguments( new QueryArgument <NonNullGraphType <StringGraphType> > { Name = "storeId" }, new QueryArgument <StringGraphType> { Name = "cultureName" }, new QueryArgument <StringGraphType> { Name = "keyword" } ), Type = GraphTypeExtenstionHelper.GetActualType <ListGraphType <MenuLinkListType> >(), Resolver = new AsyncFieldResolver <object>(async context => { var result = await _mediator.Send(new GetMenusQuery { StoreId = context.GetArgument <string>("storeId"), CultureName = context.GetArgument <string>("cultureName"), Keyword = context.GetArgument <string>("keyword"), }); return(result.Menus); }) }); }
public GiftItemType(IMediator mediator, IDataLoaderContextAccessor dataLoader, IDynamicPropertyResolverService dynamicPropertyResolverService) { Field(x => x.PromotionId).Description("Promotion ID"); Field(x => x.Quantity).Description("Number of gifts in the reward"); Field(x => x.ProductId, true).Description("Product ID"); Field(x => x.CategoryId, true).Description("Product category ID"); Field(x => x.ImageUrl, true).Description("Value of reward image absolute URL"); Field(x => x.Name).Description("Name of the reward"); Field(x => x.MeasureUnit, true).Description("Measurement unit"); Field(x => x.LineItemId, true).Description("Line item ID in case there is a gift in the cart. If there is no gift, it stays null"); AddField(new FieldType { Name = "id", Description = "Artificial ID for this value object", Type = GraphTypeExtenstionHelper.GetActualType <NonNullGraphType <StringGraphType> >(), Resolver = new FuncFieldResolver <GiftItem, string>(context => { // CacheKey as Id. CacheKey is determined by the values returned form GetEqualityComponents(). return(context.Source.GetCacheKey()); }) }); AddField(new FieldType { Name = "product", Type = GraphTypeExtenstionHelper.GetActualType <ProductType>(), Resolver = new FuncFieldResolver <GiftItem, IDataLoaderResult <ExpProduct> >(context => { if (context.Source.ProductId.IsNullOrEmpty()) { return(default);
public ProductRecommendationType( IMediator mediator, IDataLoaderContextAccessor dataLoader) { Name = "ProductRecommendation"; Description = "Product recommendation object"; Field(d => d.ProductId).Description("The unique ID of the product."); Field(d => d.Scenario).Description("The recommendation scenario name."); Field(d => d.Score).Description("The recommendation relevance score."); var productField = new FieldType { Name = "product", Type = GraphTypeExtenstionHelper.GetActualType <ProductType>(), Resolver = new AsyncFieldResolver <ProductRecommendation, object>(async context => { var includeFields = context.SubFields.Values.GetAllNodesPaths().Select(x => x.TrimStart("items.")).ToArray(); var loader = dataLoader.Context.GetOrAddBatchLoader <string, ExpProduct>($"recommendedProducts", (ids) => LoadProductsAsync(mediator, new LoadProductRequest { Ids = ids.ToArray(), IncludeFields = includeFields.ToArray() })); // IMPORTANT: In order to avoid deadlocking on the loader we use the following construct (next 2 lines): var loadHandle = loader.LoadAsync(context.Source.ProductId); return(await loadHandle); }) }; AddField(productField); }
public void Build(ISchema schema) { #region countries query #pragma warning disable S125 // Sections of code should not be commented out /* * query { * countries * } */ #pragma warning restore S125 // Sections of code should not be commented out #endregion _ = schema.Query.AddField(new FieldType { Name = "countries", Type = GraphTypeExtenstionHelper.GetActualType <ListGraphType <CountryType> >(), Resolver = new AsyncFieldResolver <object>(async context => { var result = await _mediator.Send(new GetCountriesQuery()); return(result.Countries); }) }); #region regions query #pragma warning disable S125 // Sections of code should not be commented out /* * query { * regions(countryId: "country code") * } */ #pragma warning restore S125 // Sections of code should not be commented out #endregion _ = schema.Query.AddField(new FieldType { Name = "regions", Arguments = new QueryArguments(new QueryArgument <NonNullGraphType <StringGraphType> > { Name = "countryId" }), Type = GraphTypeExtenstionHelper.GetActualType <ListGraphType <CountryRegionType> >(), Resolver = new AsyncFieldResolver <object>(async context => { var result = await _mediator.Send(new GetRegionsQuery { CountryId = context.GetArgument <string>("countryId"), }); return(result.Regions); }) }); #pragma warning disable S125 // Sections of code should not be commented out }
public ProductAssociationType(IDataLoaderContextAccessor dataLoader, IMediator mediator) { Name = "ProductAssociation"; Description = "product association."; Field(d => d.Type, nullable: true); Field(d => d.Priority, nullable: true); Field("Quantity", x => x.Quantity, nullable: true, type: typeof(IntGraphType)); Field(d => d.AssociatedObjectId, nullable: true); Field(d => d.AssociatedObjectType, nullable: true); Field <ListGraphType <StringGraphType> >("tags", resolve: context => context.Source.Tags?.ToList() ?? new List <string>()); var productField = new FieldType { Name = "product", Type = GraphTypeExtenstionHelper.GetActualType <ProductType>(), Resolver = new FuncFieldResolver <ProductAssociation, IDataLoaderResult <ExpProduct> >(context => { var loader = dataLoader.Context.GetOrAddBatchLoader <string, ExpProduct>("associatedProductLoader", (ids) => LoadProductsAsync(mediator, ids, context)); return(loader.LoadAsync(context.Source.AssociatedObjectId)); }) }; AddField(productField); }
public ContactType(IOrganizationAggregateRepository organizationAggregateRepository) { _organizationAggregateRepository = organizationAggregateRepository; //this.AuthorizeWith(CustomerModule.Core.ModuleConstants.Security.Permissions.Read); Field(x => x.Contact.FirstName); Field(x => x.Contact.LastName); Field <DateGraphType>("birthDate", resolve: context => context.Source.Contact.BirthDate); Field(x => x.Contact.FullName); Field(x => x.Contact.Id); Field(x => x.Contact.MemberType); Field(x => x.Contact.MiddleName, true); Field(x => x.Contact.Name, true); Field(x => x.Contact.OuterId, true); Field <ListGraphType <MemberAddressType> >("addresses", resolve: context => context.Source.Contact.Addresses); Field <ListGraphType <UserType> >("securityAccounts", resolve: context => context.Source.Contact.SecurityAccounts); //TODO: remove later Field <StringGraphType>("organizationId", resolve: context => context.Source.Contact.Organizations?.FirstOrDefault()); Field("organizationsIds", x => x.Contact.Organizations); Field("phones", x => x.Contact.Phones); AddField(new FieldType { Name = "Organizations", Description = "All contact's organizations", Type = GraphTypeExtenstionHelper.GetActualType <ListGraphType <OrganizationType> >(), Resolver = new AsyncFieldResolver <ContactAggregate, IEnumerable <OrganizationAggregate> >(async context => { if (context.Source.Contact.Organizations.IsNullOrEmpty()) { return(default);
public void GetActualType_HasOverriddenType_OverriddenTypeReturned() { // Arrange AbstractTypeFactory <IGraphType> .OverrideType <FooType, FooTypeExtended>(); // Act var targetType = GraphTypeExtenstionHelper.GetActualType <FooType>(); // Assert targetType.Name.Should().Be(nameof(FooTypeExtended)); }
public CatalogDiscountType(IMediator mediator, IDataLoaderContextAccessor dataLoader) { var promotion = new EventStreamFieldType { Name = "promotion", Type = GraphTypeExtenstionHelper.GetActualType <PromotionType>(), Arguments = new QueryArguments(), Resolver = new FuncFieldResolver <Discount, IDataLoaderResult <Promotion> >(context => { var loader = dataLoader.Context.GetOrAddBatchLoader <string, Promotion>("promotionsLoader", (ids) => LoadPromotionsAsync(mediator, ids)); return(loader.LoadAsync(context.Source.PromotionId)); }) }; AddField(promotion); }
public void Build(ISchema schema) { var dynamicPropertyField = new FieldType { Name = "dynamicProperty", Arguments = new QueryArguments( new QueryArgument <NonNullGraphType <StringGraphType> > { Name = "idOrName", Description = "Id or name of the dynamic property" }, new QueryArgument <StringGraphType> { Name = "cultureName", Description = "Culture name (\"en-US\")" }, new QueryArgument <StringGraphType> { Name = "objectType", Description = "Object type of the dynamic property" } ), Type = GraphTypeExtenstionHelper.GetActualType <DynamicPropertyType>(), Resolver = new AsyncFieldResolver <object>(async context => { context.CopyArgumentsToUserContext(); var query = context.GetDynamicPropertiesQuery <GetDynamicPropertyQuery>(); query.IdOrName = context.GetArgument <string>("idOrName"); query.ObjectType = context.GetArgument <string>("objectType"); var response = await _mediator.Send(query); return(response.DynamicProperty); }) }; schema.Query.AddField(dynamicPropertyField); var dynamicPropertiesConnectionBuilder = GraphTypeExtenstionHelper.CreateConnection <DynamicPropertyType, object>() .Name("dynamicProperties") .Argument <StringGraphType>("cultureName", "The culture name (\"en-US\")") .Argument <StringGraphType>("filter", "This parameter applies a filter to the query results") .Argument <StringGraphType>("sort", "The sort expression") .Argument <StringGraphType>("objectType", "Object type of the dynamic property") .PageSize(20); dynamicPropertiesConnectionBuilder.ResolveAsync(async context => await ResolveDynamicPropertiesConnectionAsync(_mediator, context)); schema.Query.AddField(dynamicPropertiesConnectionBuilder.FieldType); }
public UserType(IContactAggregateRepository contactAggregateRepository) { Field(x => x.AccessFailedCount); Field(x => x.CreatedBy, true); Field(x => x.CreatedDate, true); Field(x => x.Email, true); Field(x => x.EmailConfirmed); Field(x => x.Id); Field(x => x.IsAdministrator); Field(x => x.LockoutEnabled); Field <DateTimeGraphType>("lockoutEnd", resolve: x => x.Source.LockoutEnd); Field(x => x.MemberId, true); Field(x => x.ModifiedBy, true); Field(x => x.ModifiedDate, true); Field(x => x.NormalizedEmail, true); Field(x => x.NormalizedUserName, true); Field(x => x.PasswordExpired); Field(x => x.PhoneNumber, true); Field(x => x.PhoneNumberConfirmed); Field(x => x.PhotoUrl, true); Field <ListGraphType <RoleType> >("roles", resolve: x => x.Source.Roles); Field <ListGraphType <StringGraphType> >("permissions", resolve: x => x.Source.Roles?.SelectMany(r => r.Permissions?.Select(p => p.Name))); Field(x => x.SecurityStamp); Field(x => x.StoreId, true); Field(x => x.TwoFactorEnabled); Field(x => x.UserName); Field(x => x.UserType, true); AddField(new FieldType { Name = "Contact", Description = "The associated contact info", Type = GraphTypeExtenstionHelper.GetActualType <ContactType>(), Resolver = new AsyncFieldResolver <ApplicationUser, ContactAggregate>(context => contactAggregateRepository.GetContactByIdAsync(context.Source.MemberId)) }); }
public void Build(ISchema schema) { var productField = new FieldType { Name = "product", Arguments = new QueryArguments(new QueryArgument <NonNullGraphType <StringGraphType> > { Name = "id", Description = "id of the product" }), Type = GraphTypeExtenstionHelper.GetActualType <ProductType>(), Resolver = new AsyncFieldResolver <object>(async context => { var loader = _dataLoader.Context.GetOrAddBatchLoader <string, ExpProduct>("productsLoader", (ids) => LoadProductsAsync(_mediator, ids, context.SubFields.Values.GetAllNodesPaths())); return(await loader.LoadAsync(context.GetArgument <string>("id"))); }) }; schema.Query.AddField(productField); //var productsConnectionBuilder = ConnectionBuilder.Create<ProductType, EdgeType<ProductType>, ProductsConnectonType<ProductType>, object>() var productsConnectionBuilder = GraphTypeExtenstionHelper.CreateConnection <ProductType, EdgeType <ProductType>, ProductsConnectonType <ProductType>, object>() .Name("products") .Argument <StringGraphType>("query", "The query parameter performs the full-text search") .Argument <StringGraphType>("filter", "This parameter applies a filter to the query results") .Argument <BooleanGraphType>("fuzzy", "When the fuzzy query parameter is set to true the search endpoint will also return products that contain slight differences to the search text.") .Argument <StringGraphType>("facet", "Facets calculate statistical counts to aid in faceted navigation.") .Argument <StringGraphType>("sort", "The sort expression") .Unidirectional() .PageSize(20); productsConnectionBuilder.ResolveAsync(async context => { return(await ResolveConnectionAsync(_mediator, context)); }); schema.Query.AddField(productsConnectionBuilder.FieldType); }
public void Build(ISchema schema) { schema.Query.AddField(new FieldType { Name = "me", Type = GraphTypeExtenstionHelper.GetActualType <UserType>(), Resolver = new AsyncFieldResolver <object>(async context => { var userName = ((GraphQLUserContext)context.UserContext).User?.Identity.Name; if (!string.IsNullOrEmpty(userName)) { var result = await _mediator.Send(new GetUserQuery { UserName = userName }); return(result); } return(AnonymousUser.Instance); }) }); //Queries #region organization query /* organization query with contacts connection filtering: * { * organization(id: "689a72757c754bef97cde51afc663430"){ * id contacts(first:10, after: "0", searchPhrase: null){ * totalCount items {id firstName} * } * } * } */ #endregion schema.Query.AddField(new FieldType { Name = "organization", Arguments = new QueryArguments( new QueryArgument <NonNullGraphType <StringGraphType> > { Name = "id" }, new QueryArgument <StringGraphType> { Name = "userId" } ), Type = GraphTypeExtenstionHelper.GetActualType <OrganizationType>(), Resolver = new AsyncFieldResolver <object>(async context => { var organizationId = context.GetArgument <string>("id"); var query = new GetOrganizationByIdQuery(organizationId); var organizationAggregate = await _mediator.Send(query); await CheckAuthAsync(context.GetCurrentUserId(), organizationAggregate); //store organization aggregate in the user context for future usage in the graph types resolvers context.UserContext.Add("organizationAggregate", organizationAggregate); return(organizationAggregate); }) }); #region contact query /// <example> #pragma warning disable S125 // Sections of code should not be commented out /* * { * contact(id: "51311ae5-371c-453b-9394-e6d352f1cea7"){ * firstName memberType organizationIds organizations { id businessCategory description emails groups memberType name outerId ownerId parentId phones seoObjectType } * addresses { line1 phone } * } * } */ #pragma warning restore S125 // Sections of code should not be commented out /// </example> #endregion schema.Query.AddField(new FieldType { Name = "contact", Arguments = new QueryArguments( new QueryArgument <NonNullGraphType <StringGraphType> > { Name = "id" }, new QueryArgument <StringGraphType> { Name = "userId" } ), Type = GraphTypeExtenstionHelper.GetActualType <ContactType>(), Resolver = new AsyncFieldResolver <object>(async context => { var query = new GetContactByIdQuery(context.GetArgument <string>("id")); var contactAggregate = await _mediator.Send(query); await CheckAuthAsync(context.GetCurrentUserId(), contactAggregate); //store organization aggregate in the user context for future usage in the graph types resolvers context.UserContext.Add("contactAggregate", contactAggregate); return(contactAggregate); }) }); #region updateAddressMutation /// sample code for updating addresses: #pragma warning disable S125 // Sections of code should not be commented out /* * mutation updateAddresses($command: InputUpdateContactAddressType!){ * contact: updateAddresses(command: $command) * { * firstName lastName * addresses { key city countryCode countryName email firstName lastName line1 line2 middleName name phone postalCode regionId regionName zip } * } * } * query variables: * { * "command": { * "contactId": "acc3b262-a21e-45f9-a612-b4b1530d27ef", * "addresses": [{"addressType": "Shipping", "name": "string", "countryCode": "string", "countryName": "string", "city": "string", "postalCode": "string", "line1": "string", "regionId": "string", "regionName": "string", "firstName": "string", "lastName": "string", "phone": "string", "email": "string", "regionId": "string" * }] * } * } */ #pragma warning restore S125 // Sections of code should not be commented out #endregion _ = schema.Mutation.AddField(FieldBuilder.Create <ContactAggregate, ContactAggregate>(typeof(ContactType)) .Name("updateAddresses") .Argument <NonNullGraphType <InputUpdateContactAddressType> >(_commandName) .ResolveAsync(async context => { var command = context.GetArgument <UpdateContactAddressesCommand>(_commandName); await CheckAuthAsync(context.GetCurrentUserId(), command); return(await _mediator.Send(command)); }) .FieldType); _ = schema.Mutation.AddField(FieldBuilder.Create <OrganizationAggregate, OrganizationAggregate>(typeof(OrganizationType)) .Name("updateOrganization") .Argument <NonNullGraphType <InputUpdateOrganizationType> >(_commandName) .ResolveAsync(async context => { var command = context.GetArgument <UpdateOrganizationCommand>(_commandName); await CheckAuthAsync(context.GetCurrentUserId(), command, CustomerModule.Core.ModuleConstants.Security.Permissions.Update); return(await _mediator.Send(command)); }) .FieldType); _ = schema.Mutation.AddField(FieldBuilder.Create <OrganizationAggregate, OrganizationAggregate>(typeof(OrganizationType)) .Name("createOrganization") .Argument <NonNullGraphType <InputCreateOrganizationType> >(_commandName) .ResolveAsync(async context => { var command = context.GetArgument <CreateOrganizationCommand>(_commandName); await CheckAuthAsync(context.GetCurrentUserId(), command); return(await _mediator.Send(command)); }) .FieldType); _ = schema.Mutation.AddField(FieldBuilder.Create <ContactAggregate, ContactAggregate>(typeof(ContactType)) .Name("createContact") .Argument <NonNullGraphType <InputCreateContactType> >(_commandName) .ResolveAsync(async context => { var command = context.GetArgument <CreateContactCommand>(_commandName); await CheckAuthAsync(context.GetCurrentUserId(), command); return(await _mediator.Send(command)); }) .FieldType); _ = schema.Mutation.AddField(FieldBuilder.Create <ContactAggregate, ContactAggregate>(typeof(ContactType)) .Name("updateContact") .Argument <NonNullGraphType <InputUpdateContactType> >(_commandName) .ResolveAsync(async context => { var command = context.GetArgument <UpdateContactCommand>(_commandName); await CheckAuthAsync(context.GetCurrentUserId(), command); return(await _mediator.Send(command)); }) .FieldType); _ = schema.Mutation.AddField(FieldBuilder.Create <ContactAggregate, bool>(typeof(BooleanGraphType)) .Name("deleteContact") .Argument <NonNullGraphType <InputDeleteContactType> >(_commandName) .ResolveAsync(async context => { var command = context.GetArgument <DeleteContactCommand>(_commandName); await CheckAuthAsync(context.GetCurrentUserId(), command, CustomerModule.Core.ModuleConstants.Security.Permissions.Delete); return(await _mediator.Send(command)); }) .FieldType); _ = schema.Mutation.AddField(FieldBuilder.Create <object, IdentityResult>(typeof(IdentityResultType)) .Name("updatePersonalData") .Argument <NonNullGraphType <InputUpdatePersonalDataType> >(_commandName) .ResolveAsync(async context => { var command = context.GetArgument <UpdatePersonalDataCommand>(_commandName); await CheckAuthAsync(context.GetCurrentUserId(), command); return(await _mediator.Send(command)); }) .FieldType); // Security API fields #region user query #pragma warning disable S125 // Sections of code should not be commented out /* * { * user(id: "1eb2fa8ac6574541afdb525833dadb46"){ * userName isAdministrator roles { name } userType memberId storeId * } * } */ #pragma warning restore S125 // Sections of code should not be commented out #endregion _ = schema.Query.AddField(new FieldType { Name = "user", Arguments = new QueryArguments( new QueryArgument <StringGraphType> { Name = "id" }, new QueryArgument <StringGraphType> { Name = "userName" }, new QueryArgument <StringGraphType> { Name = "email" }, new QueryArgument <StringGraphType> { Name = "loginProvider" }, new QueryArgument <StringGraphType> { Name = "providerKey" }), Type = GraphTypeExtenstionHelper.GetActualType <UserType>(), Resolver = new AsyncFieldResolver <object>(async context => { var user = await _mediator.Send(new GetUserQuery( id: context.GetArgument <string>("id"), userName: context.GetArgument <string>("userName"), email: context.GetArgument <string>("email"), loginProvider: context.GetArgument <string>("loginProvider"), providerKey: context.GetArgument <string>("providerKey"))); await CheckAuthAsync(context.GetCurrentUserId(), user); return(user); }) }); #region role query #pragma warning disable S125 // Sections of code should not be commented out /* * { * getRole(roleName: "Use api"){ * permissions * } * } */ #pragma warning restore S125 // Sections of code should not be commented out #endregion _ = schema.Query.AddField(new FieldType { Name = "role", Arguments = new QueryArguments( new QueryArgument <NonNullGraphType <StringGraphType> > { Name = "roleName" } ), Type = GraphTypeExtenstionHelper.GetActualType <RoleType>(), Resolver = new AsyncFieldResolver <object>(async context => { var result = await _mediator.Send(new GetRoleQuery(context.GetArgument <string>("roleName"))); return(result); }) }); #region create user #pragma warning disable S125 // Sections of code should not be commented out /* * mutation ($command: InputCreateUserType!){ * createUser(command: $command){ succeeded errors { code }} * } * Query variables: * { * "command": { * "createdBy": "eXp1", "email": "*****@*****.**", "password":"******", "userName": "******", "userType": "Customer" * } * } */ #pragma warning restore S125 // Sections of code should not be commented out #endregion _ = schema.Mutation.AddField(FieldBuilder.Create <object, IdentityResult>(typeof(IdentityResultType)) .Name("createUser") .Argument <NonNullGraphType <InputCreateUserType> >(_commandName) .ResolveAsync(async context => { var command = context.GetArgument <CreateUserCommand>(_commandName); await CheckAuthAsync(context.GetCurrentUserId(), command); return(await _mediator.Send(command)); }) .FieldType); #region update user #pragma warning disable S125 // Sections of code should not be commented out /* * mutation ($command: InputUpdateUserType!){ * updateUser(command: $command){ succeeded errors { description } } * } * Query variables: * { * "command":{ * "isAdministrator": false, * "userType": "Customer", * "roles": [], * "id": "b5d28a83-c296-4212-b89e-046fca3866be", * "userName": "******", * "email": "*****@*****.**" * } * } */ #pragma warning restore S125 // Sections of code should not be commented out #endregion _ = schema.Mutation.AddField(FieldBuilder.Create <object, IdentityResult>(typeof(IdentityResultType)) .Name("updateUser") .Argument <NonNullGraphType <InputUpdateUserType> >(_commandName) .ResolveAsync(async context => { var command = context.GetArgument <UpdateUserCommand>(_commandName); await CheckAuthAsync(context.GetCurrentUserId(), command); return(await _mediator.Send(command)); }) .FieldType); #region delete user #pragma warning disable S125 // Sections of code should not be commented out /* * mutation ($command: InputDeleteUserType!){ * deleteUser(command: $command){ succeeded errors { description } } * } * Query variables: * { * "command": { * "userNames": ["admin", "*****@*****.**"] * } * } */ #pragma warning restore S125 // Sections of code should not be commented out #endregion _ = schema.Mutation.AddField(FieldBuilder.Create <object, IdentityResult>(typeof(IdentityResultType)) .Name("deleteUsers") .Argument <NonNullGraphType <InputDeleteUserType> >(_commandName) .ResolveAsync(async context => { var command = context.GetArgument <DeleteUserCommand>(_commandName); await CheckAuthAsync(context.GetCurrentUserId(), command, PlatformConstants.Security.Permissions.SecurityDelete); return(await _mediator.Send(command)); }) .FieldType); #region update role query #pragma warning disable S125 // Sections of code should not be commented out /* * mutation ($command: InputUpdateRoleType!){ * updateRole(command: $command){ succeeded errors { description } } * } * Query variables: * { * "command":{ * "id": "graphtest", "name": "graphtest", "permissions": [ * { "name": "order:read", "assignedScopes": [{"scope": "{{userId}}", "type": "OnlyOrderResponsibleScope" }] } * ] * } * } */ #pragma warning restore S125 // Sections of code should not be commented out #endregion _ = schema.Mutation.AddField(FieldBuilder.Create <object, IdentityResult>(typeof(IdentityResultType)) .Name("updateRole") .Argument <NonNullGraphType <InputUpdateRoleType> >(_commandName) .ResolveAsync(async context => { var command = context.GetArgument <UpdateRoleCommand>(_commandName); await CheckAuthAsync(context.GetCurrentUserId(), command, PlatformConstants.Security.Permissions.SecurityUpdate); return(await _mediator.Send(command)); }) .FieldType); }
/// <summary> /// XDigitalCatalog schema builder /// </summary> /// <remarks> /// IMPORTANT! /// We can't use the fluent syntax for new types registration provided by dotnet graphql here, /// because we have the strict requirement for underlying types extensions and must use /// GraphTypeExtenstionHelper to resolve the effective type on execution time /// </remarks> public void Build(ISchema schema) { var productField = new FieldType { Name = "product", Arguments = new QueryArguments( new QueryArgument <NonNullGraphType <StringGraphType> > { Name = "id", Description = "id of the product" }, new QueryArgument <NonNullGraphType <StringGraphType> > { Name = "storeId", Description = "Store Id" }, new QueryArgument <StringGraphType> { Name = "userId", Description = "User Id" }, new QueryArgument <StringGraphType> { Name = "currencyCode", Description = "Currency code (\"USD\")" }, new QueryArgument <StringGraphType> { Name = "cultureName", Description = "Culture name (\"en-US\")" } ), Type = GraphTypeExtenstionHelper.GetActualType <ProductType>(), Resolver = new AsyncFieldResolver <object, IDataLoaderResult <ExpProduct> >(async context => { //PT-1606: Need to check what there is no any alternative way to access to the original request arguments in sub selection context.CopyArgumentsToUserContext(); var store = await _storeService.GetByIdAsync(context.GetArgument <string>("storeId")); context.UserContext["store"] = store; var cultureName = context.GetArgument <string>("cultureName"); var allCurrencies = await _currencyService.GetAllCurrenciesAsync(); //Store all currencies in the user context for future resolve in the schema types context.SetCurrencies(allCurrencies, cultureName); var loader = _dataLoader.Context.GetOrAddBatchLoader <string, ExpProduct>("productsLoader", (ids) => LoadProductsAsync(_mediator, ids, context)); return(loader.LoadAsync(context.GetArgument <string>("id"))); }) }; schema.Query.AddField(productField); var productsConnectionBuilder = GraphTypeExtenstionHelper.CreateConnection <ProductType, EdgeType <ProductType>, ProductsConnectonType <ProductType>, object>() .Name("products") .Argument <NonNullGraphType <StringGraphType> >("storeId", "The store id where products are searched") .Argument <StringGraphType>("userId", "The customer id for search result impersonalization") .Argument <StringGraphType>("currencyCode", "The currency for which all prices data will be returned") .Argument <StringGraphType>("cultureName", "The culture name for cart context product") .Argument <StringGraphType>("query", "The query parameter performs the full-text search") .Argument <StringGraphType>("filter", "This parameter applies a filter to the query results") .Argument <BooleanGraphType>("fuzzy", "When the fuzzy query parameter is set to true the search endpoint will also return products that contain slight differences to the search text.") .Argument <IntGraphType>("fuzzyLevel", "The fuzziness level is quantified in terms of the Damerau-Levenshtein distance, this distance being the number of operations needed to transform one word into another.") .Argument <StringGraphType>("facet", "Facets calculate statistical counts to aid in faceted navigation.") .Argument <StringGraphType>("sort", "The sort expression") .Argument <ListGraphType <StringGraphType> >("productIds", "Product Ids") .PageSize(20); productsConnectionBuilder.ResolveAsync(async context => { //PT-1606: Need to check what there is no any alternative way to access to the original request arguments in sub selection context.CopyArgumentsToUserContext(); var cultureName = context.GetArgument <string>("cultureName"); var store = await _storeService.GetByIdAsync(context.GetArgument <string>("storeId")); context.UserContext["store"] = store; context.UserContext["catalog"] = store.Catalog; var allCurrencies = await _currencyService.GetAllCurrenciesAsync(); //Store all currencies in the user context for future resolve in the schema types context.SetCurrencies(allCurrencies, cultureName); return(await ResolveProductsConnectionAsync(_mediator, context)); }); schema.Query.AddField(productsConnectionBuilder.FieldType); var categoryField = new FieldType { Name = "category", Arguments = new QueryArguments( new QueryArgument <NonNullGraphType <StringGraphType> > { Name = "id", Description = "id of the product" }, new QueryArgument <NonNullGraphType <StringGraphType> > { Name = "storeId", Description = "Store Id" }, new QueryArgument <StringGraphType> { Name = "userId", Description = "User Id" }, new QueryArgument <StringGraphType> { Name = "currencyCode", Description = "Currency code (\"USD\")" }, new QueryArgument <StringGraphType> { Name = "cultureName", Description = "Culture name (\"en-US\")" } ), Type = GraphTypeExtenstionHelper.GetActualType <CategoryType>(), Resolver = new AsyncFieldResolver <ExpCategory, IDataLoaderResult <ExpCategory> >(async context => { var store = await _storeService.GetByIdAsync(context.GetArgument <string>("storeId")); context.UserContext["store"] = store; //PT-1606: Need to check what there is no any alternative way to access to the original request arguments in sub selection context.CopyArgumentsToUserContext(); var loader = _dataLoader.Context.GetOrAddBatchLoader <string, ExpCategory>("categoriesLoader", (ids) => LoadCategoriesAsync(_mediator, ids, context)); return(loader.LoadAsync(context.GetArgument <string>("id"))); }) }; schema.Query.AddField(categoryField); var categoriesConnectionBuilder = GraphTypeExtenstionHelper.CreateConnection <CategoryType, object>() .Name("categories") .Argument <StringGraphType>("storeId", "The store id where category are searched") .Argument <StringGraphType>("cultureName", "The language for which all localized category data will be returned") .Argument <StringGraphType>("userId", "The customer id for search result impersonalization") .Argument <StringGraphType>("currencyCode", "The currency for which all prices data will be returned") .Argument <StringGraphType>("query", "The query parameter performs the full-text search") .Argument <StringGraphType>("filter", "This parameter applies a filter to the query results") .Argument <BooleanGraphType>("fuzzy", "When the fuzzy query parameter is set to true the search endpoint will also return Categorys that contain slight differences to the search text.") .Argument <IntGraphType>("fuzzyLevel", "The fuzziness level is quantified in terms of the Damerau-Levenshtein distance, this distance being the number of operations needed to transform one word into another.") .Argument <StringGraphType>("facet", "Facets calculate statistical counts to aid in faceted navigation.") .Argument <StringGraphType>("sort", "The sort expression") .Argument <ListGraphType <StringGraphType> >("categoryIds", "Category Ids") .PageSize(20); categoriesConnectionBuilder.ResolveAsync(async context => { var store = await _storeService.GetByIdAsync(context.GetArgument <string>("storeId")); context.UserContext["store"] = store; //PT-1606: Need to check what there is no any alternative way to access to the original request arguments in sub selection context.CopyArgumentsToUserContext(); return(await ResolveCategoriesConnectionAsync(_mediator, context)); }); schema.Query.AddField(categoriesConnectionBuilder.FieldType); var propertiesConnectionBuilder = GraphTypeExtenstionHelper.CreateConnection <PropertyType, object>() .Name("properties") .Argument <NonNullGraphType <StringGraphType> >("storeId", "The store id to get binded catalog") .Argument <ListGraphType <PropertyTypeEnum> >("types", "The owner types (Catalog, Category, Product, Variation)") .Argument <StringGraphType>("filter", "This parameter applies a filter to the query results") .Argument <StringGraphType>("cultureName", "The language for which all localized property dictionary items will be returned") .PageSize(20); propertiesConnectionBuilder.ResolveAsync(async context => { var store = await _storeService.GetByIdAsync(context.GetArgument <string>("storeId")); context.UserContext["catalog"] = store.Catalog; //PT-1606: Need to check what there is no any alternative way to access to the original request arguments in sub selection context.CopyArgumentsToUserContext(); return(await ResolvePropertiesConnectionAsync(_mediator, context)); }); schema.Query.AddField(propertiesConnectionBuilder.FieldType); var propertyField = new FieldType { Name = "property", Arguments = new QueryArguments( new QueryArgument <NonNullGraphType <StringGraphType> > { Name = "id", Description = "id of the property" }, new QueryArgument <StringGraphType> { Name = "cultureName", Description = "The language for which all localized property dictionary items will be returned" } ), Type = GraphTypeExtenstionHelper.GetActualType <PropertyType>(), Resolver = new AsyncFieldResolver <PropertyType, IDataLoaderResult <Property> >(context => { //PT-1606: Need to check what there is no any alternative way to access to the original request arguments in sub selection context.CopyArgumentsToUserContext(); var loader = _dataLoader.Context.GetOrAddBatchLoader <string, Property>("propertiesLoader", (ids) => LoadPropertiesAsync(_mediator, ids)); return(Task.FromResult(loader.LoadAsync(context.GetArgument <string>("id")))); }) }; schema.Query.AddField(propertyField); }
public void Build(ISchema schema) { ValueConverter.Register <ExpOrderAddress, Optional <ExpOrderAddress> >(x => new Optional <ExpOrderAddress>(x)); _ = schema.Query.AddField(new FieldType { Name = "order", Arguments = AbstractTypeFactory <OrderQueryArguments> .TryCreateInstance(), Type = GraphTypeExtenstionHelper.GetActualType <CustomerOrderType>(), Resolver = new AsyncFieldResolver <object>(async context => { var request = context.ExtractQuery <GetOrderQuery>(); context.CopyArgumentsToUserContext(); var orderAggregate = await _mediator.Send(request); var authorizationResult = await _authorizationService.AuthorizeAsync(context.GetCurrentPrincipal(), orderAggregate.Order, new CanAccessOrderAuthorizationRequirement()); if (!authorizationResult.Succeeded) { throw new AuthorizationError($"Access denied"); } var allCurrencies = await _currencyService.GetAllCurrenciesAsync(); //Store all currencies in the user context for future resolve in the schema types context.SetCurrencies(allCurrencies, request.CultureName); //store order aggregate in the user context for future usage in the graph types resolvers context.SetExpandedObjectGraph(orderAggregate); return(orderAggregate); }) }); var orderConnectionBuilder = GraphTypeExtenstionHelper .CreateConnection <CustomerOrderType, object>() .Name("orders") .PageSize(20) .Arguments(); orderConnectionBuilder.ResolveAsync(async context => await ResolveOrdersConnectionAsync(_mediator, context)); schema.Query.AddField(orderConnectionBuilder.FieldType); var paymentsConnectionBuilder = GraphTypeExtenstionHelper .CreateConnection <PaymentInType, object>() .Name("payments") .PageSize(20) .Arguments(); paymentsConnectionBuilder.ResolveAsync(async context => await ResolvePaymentsConnectionAsync(_mediator, context)); schema.Query.AddField(paymentsConnectionBuilder.FieldType); _ = schema.Mutation.AddField(FieldBuilder.Create <object, CustomerOrderAggregate>(GraphTypeExtenstionHelper.GetActualType <CustomerOrderType>()) .Name("createOrderFromCart") .Argument(GraphTypeExtenstionHelper.GetActualComplexType <NonNullGraphType <InputCreateOrderFromCartType> >(), _commandName) .ResolveAsync(async context => { var type = GenericTypeHelper.GetActualType <CreateOrderFromCartCommand>(); var response = (CustomerOrderAggregate)await _mediator.Send(context.GetArgument(type, _commandName)); context.SetExpandedObjectGraph(response); return(response); }) .FieldType); _ = schema.Mutation.AddField(FieldBuilder.Create <object, bool>(typeof(BooleanGraphType)) .Name("changeOrderStatus") .Argument(GraphTypeExtenstionHelper.GetActualComplexType <NonNullGraphType <InputChangeOrderStatusType> >(), _commandName) .ResolveAsync(async context => { var type = GenericTypeHelper.GetActualType <ChangeOrderStatusCommand>(); var command = (ChangeOrderStatusCommand)context.GetArgument(type, _commandName); await CheckAuthAsync(context, command.OrderId); return(await _mediator.Send(command)); }) .FieldType); _ = schema.Mutation.AddField(FieldBuilder.Create <object, ProcessPaymentRequestResult>(typeof(ProcessPaymentRequestResultType)) .Name("processOrderPayment") .Argument(GraphTypeExtenstionHelper.GetActualComplexType <NonNullGraphType <InputProcessOrderPaymentType> >(), _commandName) .ResolveAsync(async context => { var type = GenericTypeHelper.GetActualType <ProcessOrderPaymentCommand>(); var command = (ProcessOrderPaymentCommand)context.GetArgument(type, _commandName); await CheckAuthAsync(context, command.OrderId); return(await _mediator.Send(command)); }) .DeprecationReason("Obsolete. Use 'initializePayment' mutation") .FieldType); _ = schema.Mutation.AddField(FieldBuilder.Create <object, InitializePaymentResult>(typeof(InitializePaymentResultType)) .Name("initializePayment") .Argument(GraphTypeExtenstionHelper.GetActualComplexType <NonNullGraphType <InputInitializePaymentType> >(), _commandName) .ResolveAsync(async context => { var type = GenericTypeHelper.GetActualType <InitializePaymentCommand>(); var command = (InitializePaymentCommand)context.GetArgument(type, _commandName); await CheckAuthAsync(context, command.OrderId); return(await _mediator.Send(command)); }) .FieldType); _ = schema.Mutation.AddField(FieldBuilder.Create <object, AuthorizePaymentResult>(typeof(AuthorizePaymentResultType)) .Name("authorizePayment") .Argument(GraphTypeExtenstionHelper.GetActualComplexType <NonNullGraphType <InputAuthorizePaymentType> >(), _commandName) .ResolveAsync(async context => { var type = GenericTypeHelper.GetActualType <AuthorizePaymentCommand>(); var command = (AuthorizePaymentCommand)context.GetArgument(type, _commandName); await CheckAuthAsync(context, command.OrderId); return(await _mediator.Send(command)); }) .FieldType); _ = schema.Mutation.AddField(FieldBuilder.Create <CustomerOrderAggregate, CustomerOrderAggregate>(GraphTypeExtenstionHelper.GetActualType <CustomerOrderType>()) .Name("updateOrderDynamicProperties") .Argument(GraphTypeExtenstionHelper.GetActualComplexType <NonNullGraphType <InputUpdateOrderDynamicPropertiesType> >(), _commandName) .ResolveAsync(async context => { var type = GenericTypeHelper.GetActualType <UpdateOrderDynamicPropertiesCommand>(); var command = (UpdateOrderDynamicPropertiesCommand)context.GetArgument(type, _commandName); await CheckAuthAsync(context, command.OrderId); return(await _mediator.Send(command)); }) .FieldType); _ = schema.Mutation.AddField(FieldBuilder.Create <CustomerOrderAggregate, CustomerOrderAggregate>(GraphTypeExtenstionHelper.GetActualType <CustomerOrderType>()) .Name("updateOrderItemDynamicProperties") .Argument(GraphTypeExtenstionHelper.GetActualComplexType <NonNullGraphType <InputUpdateOrderItemDynamicPropertiesType> >(), _commandName) .ResolveAsync(async context => { var type = GenericTypeHelper.GetActualType <UpdateOrderItemDynamicPropertiesCommand>(); var command = (UpdateOrderItemDynamicPropertiesCommand)context.GetArgument(type, _commandName); await CheckAuthAsync(context, command.OrderId); return(await _mediator.Send(command)); }) .FieldType); _ = schema.Mutation.AddField(FieldBuilder.Create <CustomerOrderAggregate, CustomerOrderAggregate>(GraphTypeExtenstionHelper.GetActualType <CustomerOrderType>()) .Name("updateOrderPaymentDynamicProperties") .Argument(GraphTypeExtenstionHelper.GetActualComplexType <NonNullGraphType <InputUpdateOrderPaymentDynamicPropertiesType> >(), _commandName) .ResolveAsync(async context => { var type = GenericTypeHelper.GetActualType <UpdateOrderPaymentDynamicPropertiesCommand>(); var command = (UpdateOrderPaymentDynamicPropertiesCommand)context.GetArgument(type, _commandName); await CheckAuthAsync(context, command.OrderId); return(await _mediator.Send(command)); }) .FieldType); _ = schema.Mutation.AddField(FieldBuilder.Create <CustomerOrderAggregate, CustomerOrderAggregate>(GraphTypeExtenstionHelper.GetActualType <CustomerOrderType>()) .Name("updateOrderShipmentDynamicProperties") .Argument(GraphTypeExtenstionHelper.GetActualComplexType <NonNullGraphType <InputUpdateOrderShipmentDynamicPropertiesType> >(), _commandName) .ResolveAsync(async context => { var type = GenericTypeHelper.GetActualType <UpdateOrderShipmentDynamicPropertiesCommand>(); var command = (UpdateOrderShipmentDynamicPropertiesCommand)context.GetArgument(type, _commandName); await CheckAuthAsync(context, command.OrderId); return(await _mediator.Send(command)); }) .FieldType); _ = schema.Mutation.AddField(FieldBuilder.Create <CustomerOrderAggregate, CustomerOrderAggregate>(GraphTypeExtenstionHelper.GetActualType <CustomerOrderType>()) .Name("addOrUpdateOrderPayment") .Argument(GraphTypeExtenstionHelper.GetActualComplexType <NonNullGraphType <InputAddOrUpdateOrderPaymentType> >(), _commandName) .ResolveAsync(async context => { var type = GenericTypeHelper.GetActualType <AddOrUpdateOrderPaymentCommand>(); var command = (AddOrUpdateOrderPaymentCommand)context.GetArgument(type, _commandName); await CheckAuthAsync(context, command.OrderId); var response = await _mediator.Send(command); context.SetExpandedObjectGraph(response); return(response); }) .FieldType); }
public CustomerOrderType() { Field(x => x.Order.Id); Field(x => x.Order.OperationType); Field(x => x.Order.ParentOperationId, true); Field(x => x.Order.Number); Field(x => x.Order.IsApproved); Field(x => x.Order.Status, true); Field(x => x.Order.Comment, true); Field(x => x.Order.OuterId, true); Field(x => x.Order.IsCancelled); Field(x => x.Order.CancelledDate, true); Field(x => x.Order.CancelReason, true); Field(x => x.Order.ObjectType); Field(x => x.Order.CustomerId); Field(x => x.Order.CustomerName, true); Field(x => x.Order.ChannelId, true); Field(x => x.Order.StoreId); Field(x => x.Order.StoreName, true); Field(x => x.Order.OrganizationId, true); Field(x => x.Order.OrganizationName, true); Field(x => x.Order.EmployeeId, true); Field(x => x.Order.EmployeeName, true); Field(x => x.Order.ShoppingCartId, true); Field(x => x.Order.IsPrototype); Field(x => x.Order.SubscriptionNumber, true); Field(x => x.Order.SubscriptionId, true); Field(x => x.Order.Fee); Field(x => x.Order.FeeWithTax); Field(x => x.Order.FeeTotal); Field(x => x.Order.FeeTotalWithTax); Field(x => x.Order.TaxType, true); Field(x => x.Order.TaxPercentRate); Field(x => x.Order.LanguageCode, true); Field(x => x.Order.CreatedDate); Field(x => x.Order.CreatedBy, true); Field(x => x.Order.ModifiedDate, true); Field(x => x.Order.ModifiedBy, true); Field <CurrencyType>(nameof(CustomerOrder.Currency).ToCamelCase(), resolve: context => context.Source.Currency); Field <MoneyType>(nameof(CustomerOrder.Total).ToCamelCase(), resolve: context => new Money(context.Source.Order.Total, context.Source.Currency)); Field <MoneyType>(nameof(CustomerOrder.TaxTotal).ToCamelCase(), resolve: context => new Money(context.Source.Order.TaxTotal, context.Source.Currency)); Field <MoneyType>(nameof(CustomerOrder.DiscountAmount).ToCamelCase(), resolve: context => new Money(context.Source.Order.DiscountAmount, context.Source.Currency)); Field <MoneyType>(nameof(CustomerOrder.SubTotal).ToCamelCase(), resolve: context => new Money(context.Source.Order.SubTotal, context.Source.Currency)); Field <MoneyType>(nameof(CustomerOrder.SubTotalWithTax).ToCamelCase(), resolve: context => new Money(context.Source.Order.SubTotalWithTax, context.Source.Currency)); Field <MoneyType>(nameof(CustomerOrder.SubTotalDiscount).ToCamelCase(), resolve: context => new Money(context.Source.Order.SubTotalDiscount, context.Source.Currency)); Field <MoneyType>(nameof(CustomerOrder.SubTotalDiscountWithTax).ToCamelCase(), resolve: context => new Money(context.Source.Order.SubTotalDiscountWithTax, context.Source.Currency)); Field <MoneyType>(nameof(CustomerOrder.SubTotalTaxTotal).ToCamelCase(), resolve: context => new Money(context.Source.Order.SubTotalTaxTotal, context.Source.Currency)); Field <MoneyType>(nameof(CustomerOrder.ShippingTotal).ToCamelCase(), resolve: context => new Money(context.Source.Order.ShippingTotal, context.Source.Currency)); Field <MoneyType>(nameof(CustomerOrder.ShippingTotalWithTax).ToCamelCase(), resolve: context => new Money(context.Source.Order.ShippingTotalWithTax, context.Source.Currency)); Field <MoneyType>(nameof(CustomerOrder.ShippingSubTotal).ToCamelCase(), resolve: context => new Money(context.Source.Order.ShippingSubTotal, context.Source.Currency)); Field <MoneyType>(nameof(CustomerOrder.ShippingSubTotalWithTax).ToCamelCase(), resolve: context => new Money(context.Source.Order.ShippingSubTotalWithTax, context.Source.Currency)); Field <MoneyType>(nameof(CustomerOrder.ShippingDiscountTotal).ToCamelCase(), resolve: context => new Money(context.Source.Order.ShippingDiscountTotal, context.Source.Currency)); Field <MoneyType>(nameof(CustomerOrder.ShippingDiscountTotalWithTax).ToCamelCase(), resolve: context => new Money(context.Source.Order.ShippingDiscountTotalWithTax, context.Source.Currency)); Field <MoneyType>(nameof(CustomerOrder.ShippingTaxTotal).ToCamelCase(), resolve: context => new Money(context.Source.Order.ShippingTaxTotal, context.Source.Currency)); Field <MoneyType>(nameof(CustomerOrder.PaymentTotal).ToCamelCase(), resolve: context => new Money(context.Source.Order.PaymentTotal, context.Source.Currency)); Field <MoneyType>(nameof(CustomerOrder.PaymentTotalWithTax).ToCamelCase(), resolve: context => new Money(context.Source.Order.PaymentTotalWithTax, context.Source.Currency)); Field <MoneyType>(nameof(CustomerOrder.PaymentSubTotal).ToCamelCase(), resolve: context => new Money(context.Source.Order.PaymentSubTotal, context.Source.Currency)); Field <MoneyType>(nameof(CustomerOrder.PaymentSubTotalWithTax).ToCamelCase(), resolve: context => new Money(context.Source.Order.PaymentSubTotalWithTax, context.Source.Currency)); Field <MoneyType>(nameof(CustomerOrder.PaymentDiscountTotal).ToCamelCase(), resolve: context => new Money(context.Source.Order.PaymentDiscountTotal, context.Source.Currency)); Field <MoneyType>(nameof(CustomerOrder.PaymentDiscountTotalWithTax).ToCamelCase(), resolve: context => new Money(context.Source.Order.PaymentDiscountTotalWithTax, context.Source.Currency)); Field <MoneyType>(nameof(CustomerOrder.PaymentTaxTotal).ToCamelCase(), resolve: context => new Money(context.Source.Order.PaymentTaxTotal, context.Source.Currency)); Field <MoneyType>(nameof(CustomerOrder.DiscountTotal).ToCamelCase(), resolve: context => new Money(context.Source.Order.DiscountTotal, context.Source.Currency)); Field <MoneyType>(nameof(CustomerOrder.DiscountTotalWithTax).ToCamelCase(), resolve: context => new Money(context.Source.Order.DiscountTotalWithTax, context.Source.Currency)); Field <NonNullGraphType <ListGraphType <OrderAddressType> > >(nameof(CustomerOrder.Addresses), resolve: x => x.Source.Order.Addresses); Field <NonNullGraphType <ListGraphType <OrderLineItemType> > >(nameof(CustomerOrder.Items), resolve: x => x.Source.Order.Items); Field <NonNullGraphType <ListGraphType <PaymentInType> > >(nameof(CustomerOrder.InPayments), resolve: x => x.Source.Order.InPayments); //Field<NonNullGraphType<ListGraphType<OrderShipmentType>>>(nameof(CustomerOrder.Shipments), resolve: x => x.Source.Order.Shipments); //TODO: By this registration we support the schema types extensions. Need to move this code into extensions and replace everywhere to this version. var orderShipmentsField = new FieldType { Name = "shipments", Type = typeof(ListGraphType <>).MakeGenericType(GraphTypeExtenstionHelper.GetActualType <OrderShipmentType>()), Resolver = new FuncFieldResolver <CustomerOrderAggregate, object>(context => context.Source.Order.Shipments) }; AddField(orderShipmentsField); Field <NonNullGraphType <ListGraphType <OrderTaxDetailType> > >(nameof(CustomerOrder.TaxDetails), resolve: x => x.Source.Order.TaxDetails); //TODO //public ICollection<DynamicObjectProperty> DynamicProperties); }
/// <example> ///{ /// product(id: "f1b26974b7634abaa0900e575a99476f") /// { /// id /// code /// category{ id code name hasParent slug } /// name /// metaTitle /// metaDescription /// metaKeywords /// brandName /// slug /// imgSrc /// productType /// masterVariation { /// images{ id url name } /// assets{ id size url } /// prices(cultureName: "en-us"){ /// list { amount } /// currency /// } /// availabilityData{ /// availableQuantity /// inventories{ /// inStockQuantity /// fulfillmentCenterId /// fulfillmentCenterName /// allowPreorder /// allowBackorder /// } /// } /// properties{ id name valueType value valueId } /// } ///} /// </example> public ProductType(IMediator mediator, IDataLoaderContextAccessor dataLoader) { Name = "Product"; Description = "Products are the sellable goods in an e-commerce project."; Field(d => d.IndexedProduct.Id).Description("The unique ID of the product."); Field(d => d.IndexedProduct.Code, nullable: false).Description("The product SKU."); Field <StringGraphType>("catalogId", "The unique ID of the catalog", resolve: context => context.Source.IndexedProduct.CatalogId); Field(d => d.IndexedProduct.ProductType, nullable: true).Description("The type of product"); Field(d => d.IndexedProduct.MinQuantity, nullable: true).Description("Min. quantity"); Field(d => d.IndexedProduct.MaxQuantity, nullable: true).Description("Max. quantity"); FieldAsync <StringGraphType>("outline", resolve: async context => { var outlines = context.Source.IndexedProduct.Outlines; if (outlines.IsNullOrEmpty()) { return(null); } var loadRelatedCatalogOutlineQuery = context.GetCatalogQuery <LoadRelatedCatalogOutlineQuery>(); loadRelatedCatalogOutlineQuery.Outlines = outlines; var response = await mediator.Send(loadRelatedCatalogOutlineQuery); return(response.Outline); }, description: @"All parent categories ids relative to the requested catalog and concatenated with \ . E.g. (1/21/344)"); FieldAsync <StringGraphType>("slug", resolve: async context => { var outlines = context.Source.IndexedProduct.Outlines; if (outlines.IsNullOrEmpty()) { return(null); } var loadRelatedSlugPathQuery = context.GetCatalogQuery <LoadRelatedSlugPathQuery>(); loadRelatedSlugPathQuery.Outlines = outlines; var response = await mediator.Send(loadRelatedSlugPathQuery); return(response.Slug); }, description: "Request related slug for product"); Field(d => d.IndexedProduct.Name, nullable: false).Description("The name of the product."); Field <SeoInfoType>("seoInfo", resolve: context => { var source = context.Source; var storeId = context.GetArgumentOrValue <string>("storeId"); var cultureName = context.GetArgumentOrValue <string>("cultureName"); SeoInfo seoInfo = null; if (!source.IndexedProduct.SeoInfos.IsNullOrEmpty()) { seoInfo = source.IndexedProduct.SeoInfos.GetBestMatchingSeoInfo(storeId, cultureName); } return(seoInfo ?? GetFallbackSeoInfo(source, cultureName)); }, description: "Request related SEO info"); Field <ListGraphType <DescriptionType> >("descriptions", arguments: new QueryArguments(new QueryArgument <StringGraphType> { Name = "type" }), resolve: context => { var reviews = context.Source.IndexedProduct.Reviews; var cultureName = context.GetArgumentOrValue <string>("cultureName"); var type = context.GetArgumentOrValue <string>("type"); if (cultureName != null) { reviews = reviews.Where(x => string.IsNullOrEmpty(x.LanguageCode) || x.LanguageCode.EqualsInvariant(cultureName)).ToList(); } if (type != null) { reviews = reviews.Where(x => x.ReviewType?.EqualsInvariant(type) ?? true).ToList(); } return(reviews); }); Field <DescriptionType>("description", arguments: new QueryArguments(new QueryArgument <StringGraphType> { Name = "type" }), resolve: context => { var reviews = context.Source.IndexedProduct.Reviews; var type = context.GetArgumentOrValue <string>("type"); var cultureName = context.GetArgumentOrValue <string>("cultureName"); if (!reviews.IsNullOrEmpty()) { return(reviews.Where(x => x.ReviewType.EqualsInvariant(type ?? "FullReview")).FirstBestMatchForLanguage(cultureName) as EditorialReview ?? reviews.FirstBestMatchForLanguage(cultureName) as EditorialReview); } return(null); }); FieldAsync <CategoryType>( "category", resolve: async context => { var categoryId = context.Source.IndexedProduct.CategoryId; var loadCategoryQuery = context.GetCatalogQuery <LoadCategoryQuery>(); loadCategoryQuery.ObjectIds = new[] { categoryId }; loadCategoryQuery.IncludeFields = context.SubFields.Values.GetAllNodesPaths(); var responce = await mediator.Send(loadCategoryQuery); return(responce.Categories.FirstOrDefault()); }); Field <StringGraphType>( "imgSrc", description: "The product main image URL.", resolve: context => context.Source.IndexedProduct.ImgSrc); Field(d => d.IndexedProduct.OuterId, nullable: true).Description("The outer identifier"); Field <StringGraphType>( "brandName", description: "Get brandName for product.", resolve: context => { var brandName = context.Source.IndexedProduct.Properties ?.FirstOrDefault(x => x.Name.EqualsInvariant("Brand")) ?.Values ?.FirstOrDefault(x => x.Value != null) ?.Value; return(brandName?.ToString()); }); FieldAsync <VariationType>( "masterVariation", resolve: async context => { if (string.IsNullOrEmpty(context.Source.IndexedProduct.MainProductId)) { return(null); } var query = context.GetCatalogQuery <LoadProductsQuery>(); query.ObjectIds = new[] { context.Source.IndexedProduct.MainProductId }; query.IncludeFields = context.SubFields.Values.GetAllNodesPaths(); var response = await mediator.Send(query); return(response.Products.Select(expProduct => new ExpVariation(expProduct)).FirstOrDefault()); }); FieldAsync <ListGraphType <VariationType> >( "variations", resolve: async context => { var productIds = context.Source.IndexedVariationIds.ToArray(); if (productIds.IsNullOrEmpty()) { return(new List <ExpVariation>()); } var query = context.GetCatalogQuery <LoadProductsQuery>(); query.ObjectIds = context.Source.IndexedVariationIds.ToArray(); query.IncludeFields = context.SubFields.Values.GetAllNodesPaths(); var response = await mediator.Send(query); return(response.Products.Select(expProduct => new ExpVariation(expProduct))); }); Field <BooleanGraphType>( "hasVariations", resolve: context => { var result = context.Source.IndexedVariationIds?.Any() ?? false; return(result); }); Field( GraphTypeExtenstionHelper.GetActualType <AvailabilityDataType>(), "availabilityData", "Product availability data", resolve: context => new ExpAvailabilityData { AvailableQuantity = context.Source.AvailableQuantity, InventoryAll = context.Source.AllInventories, IsBuyable = context.Source.IsBuyable, IsAvailable = context.Source.IsAvailable, IsInStock = context.Source.IsInStock, IsActive = context.Source.IndexedProduct.IsActive ?? false, IsTrackInventory = context.Source.IndexedProduct.TrackInventory ?? false, }); Field <ListGraphType <ImageType> >( "images", "Product images", resolve: context => { var images = context.Source.IndexedProduct.Images; return(context.GetValue <string>("cultureName") switch { // Get images with null or current cultureName value if cultureName is passed string languageCode => images.Where(x => string.IsNullOrEmpty(x.LanguageCode) || x.LanguageCode.EqualsInvariant(languageCode)).ToList(), // CultureName is null _ => images });
public void Build(ISchema schema) { //Queries //We can't use the fluent syntax for new types registration provided by dotnet graphql here, because we have the strict requirement for underlying types extensions //and must use GraphTypeExtenstionHelper to resolve the effective type on execution time var cartField = new FieldType { Name = "cart", Arguments = new QueryArguments( new QueryArgument <NonNullGraphType <StringGraphType> > { Name = "storeId", Description = "Store Id" }, new QueryArgument <StringGraphType> { Name = "userId", Description = "User Id" }, new QueryArgument <NonNullGraphType <StringGraphType> > { Name = "currencyCode", Description = "Currency code (\"USD\")" }, new QueryArgument <StringGraphType> { Name = "cultureName", Description = "Culture name (\"en-Us\")" }, new QueryArgument <StringGraphType> { Name = "cartName", Description = "Cart name" }, new QueryArgument <StringGraphType> { Name = "type", Description = "Cart type" }), Type = GraphTypeExtenstionHelper.GetActualType <CartType>(), Resolver = new AsyncFieldResolver <object>(async context => { var getCartQuery = context.GetCartQuery <GetCartQuery>(); getCartQuery.IncludeFields = context.SubFields.Values.GetAllNodesPaths().ToArray(); context.CopyArgumentsToUserContext(); var cartAggregate = await _mediator.Send(getCartQuery); if (cartAggregate == null) { var createCartCommand = new CreateCartCommand(getCartQuery.StoreId, getCartQuery.CartType, getCartQuery.CartName, getCartQuery.UserId, getCartQuery.CurrencyCode, getCartQuery.CultureName); cartAggregate = await _mediator.Send(createCartCommand); } context.SetExpandedObjectGraph(cartAggregate); return(cartAggregate); }) }; schema.Query.AddField(cartField); var orderConnectionBuilder = GraphTypeExtenstionHelper.CreateConnection <CartType, object>() .Name("carts") .Argument <StringGraphType>("storeId", "") .Argument <StringGraphType>("userId", "") .Argument <StringGraphType>("currencyCode", "") .Argument <StringGraphType>("cultureName", "") .Argument <StringGraphType>("cartType", "") .Argument <StringGraphType>("filter", "This parameter applies a filter to the query results") .Argument <StringGraphType>("sort", "The sort expression") .Unidirectional() .PageSize(20); orderConnectionBuilder.ResolveAsync(async context => await ResolveConnectionAsync(_mediator, context)); schema.Query.AddField(orderConnectionBuilder.FieldType); //Mutations /// <example> /// This is an example JSON request for a mutation /// { /// "query": "mutation ($command:InputAddItemType!){ addItem(command: $command) { total { formatedAmount } } }", /// "variables": { /// "command": { /// "storeId": "Electronics", /// "cartName": "default", /// "userId": "b57d06db-1638-4d37-9734-fd01a9bc59aa", /// "language": "en-US", /// "currency": "USD", /// "cartType": "cart", /// "productId": "9cbd8f316e254a679ba34a900fccb076", /// "quantity": 1 /// } /// } /// } /// </example> var addItemField = FieldBuilder.Create <CartAggregate, CartAggregate>(typeof(CartType)) .Name("addItem") .Argument <NonNullGraphType <InputAddItemType> >(_commandName) //TODO: Write the unit-tests for successfully mapping input variable to the command .ResolveAsync(async context => { //TODO: Need to refactor later to prevent ugly code duplication //We need to add cartAggregate to the context to be able use it on nested cart types resolvers (e.g for currency) var cartAggregate = await _mediator.Send(context.GetCartCommand <AddCartItemCommand>()); //store cart aggregate in the user context for future usage in the graph types resolvers context.SetExpandedObjectGraph(cartAggregate); return(cartAggregate); }) .FieldType; schema.Mutation.AddField(addItemField); /// <example> /// This is an example JSON request for a mutation /// { /// "query": "mutation ($command:InputClearCartType!){ clearCart(command: $command) { total { formatedAmount } } }", /// "variables": { /// "command": { /// "storeId": "Electronics", /// "cartName": "default", /// "userId": "b57d06db-1638-4d37-9734-fd01a9bc59aa", /// "language": "en-US", /// "currency": "USD", /// "cartType": "cart" /// } /// } /// } /// </example> var clearCartField = FieldBuilder.Create <CartAggregate, CartAggregate>(typeof(CartType)) .Name("clearCart") .Argument <NonNullGraphType <InputClearCartType> >(_commandName) .ResolveAsync(async context => { //TODO: Need to refactor later to prevent ugly code duplication //We need to add cartAggregate to the context to be able use it on nested cart types resolvers (e.g for currency) var cartAggregate = await _mediator.Send(context.GetCartCommand <ClearCartCommand>()); //store cart aggregate in the user context for future usage in the graph types resolvers context.SetExpandedObjectGraph(cartAggregate); return(cartAggregate); }).FieldType; schema.Mutation.AddField(clearCartField); /// <example> /// This is an example JSON request for a mutation /// { /// "query": "mutation ($command:InputChangeCommentType!){ changeComment(command: $command) { total { formatedAmount } } }", /// "variables": { /// "command": { /// "storeId": "Electronics", /// "cartName": "default", /// "userId": "b57d06db-1638-4d37-9734-fd01a9bc59aa", /// "language": "en-US", /// "currency": "USD", /// "cartType": "cart", /// "comment": "Hi, Virto!" /// } /// } /// } /// </example> var changeCommentField = FieldBuilder.Create <CartAggregate, CartAggregate>(typeof(CartType)) .Name("changeComment") .Argument <InputChangeCommentType>(_commandName) .ResolveAsync(async context => { //TODO: Need to refactor later to prevent ugly code duplication //We need to add cartAggregate to the context to be able use it on nested cart types resolvers (e.g for currency) var cartAggregate = await _mediator.Send(context.GetCartCommand <ChangeCommentCommand>()); //store cart aggregate in the user context for future usage in the graph types resolvers context.SetExpandedObjectGraph(cartAggregate); return(cartAggregate); }) .FieldType; schema.Mutation.AddField(changeCommentField); /// <example> /// This is an example JSON request for a mutation /// { /// "query": "mutation ($command:InputChangeCartItemPriceType!){ changeCartItemPrice(command: $command) { total { formatedAmount } } }", /// "variables": { /// "command": { /// "storeId": "Electronics", /// "cartName": "default", /// "userId": "b57d06db-1638-4d37-9734-fd01a9bc59aa", /// "language": "en-US", /// "currency": "USD", /// "cartType": "cart", /// "lineItemId": "9cbd8f316e254a679ba34a900fccb076", /// "price": 777 /// } /// } /// } /// </example> var changeCartItemPriceField = FieldBuilder.Create <CartAggregate, CartAggregate>(typeof(CartType)) .Name("changeCartItemPrice") .Argument <NonNullGraphType <InputChangeCartItemPriceType> >(_commandName) .ResolveAsync(async context => { //TODO: Need to refactor later to prevent ugly code duplication //We need to add cartAggregate to the context to be able use it on nested cart types resolvers (e.g for currency) var cartAggregate = await _mediator.Send(context.GetCartCommand <ChangeCartItemPriceCommand>()); //store cart aggregate in the user context for future usage in the graph types resolvers context.SetExpandedObjectGraph(cartAggregate); return(cartAggregate); }).FieldType; schema.Mutation.AddField(changeCartItemPriceField); /// <example> /// This is an example JSON request for a mutation /// { /// "query": "mutation ($command:InputChangeCartItemQuantityType!){ changeCartItemQuantity(command: $command) { total { formatedAmount } } }", /// "variables": { /// "command": { /// "storeId": "Electronics", /// "cartName": "default", /// "userId": "b57d06db-1638-4d37-9734-fd01a9bc59aa", /// "language": "en-US", /// "currency": "USD", /// "cartType": "cart", /// "lineItemId": "9cbd8f316e254a679ba34a900fccb076", /// "quantity": 777 /// } /// } /// } /// </example> var changeCartItemQuantityField = FieldBuilder.Create <CartAggregate, CartAggregate>(typeof(CartType)) .Name("changeCartItemQuantity") .Argument <NonNullGraphType <InputChangeCartItemQuantityType> >(_commandName) .ResolveAsync(async context => { //TODO: Need to refactor later to prevent ugly code duplication //We need to add cartAggregate to the context to be able use it on nested cart types resolvers (e.g for currency) var cartAggregate = await _mediator.Send(context.GetCartCommand <ChangeCartItemQuantityCommand>()); //store cart aggregate in the user context for future usage in the graph types resolvers context.SetExpandedObjectGraph(cartAggregate); return(cartAggregate); }).FieldType; schema.Mutation.AddField(changeCartItemQuantityField); /// <example> /// This is an example JSON request for a mutation /// { /// "query": "mutation ($command:InputChangeCartItemCommentType!){ changeCartItemComment(command: $command) { total { formatedAmount } } }", /// "variables": { /// "command": { /// "storeId": "Electronics", /// "cartName": "default", /// "userId": "b57d06db-1638-4d37-9734-fd01a9bc59aa", /// "language": "en-US", /// "currency": "USD", /// "cartType": "cart", /// "lineItemId": "9cbd8f316e254a679ba34a900fccb076", /// "comment": "verynicecomment" /// } /// } /// } /// </example> var changeCartItemCommentField = FieldBuilder.Create <CartAggregate, CartAggregate>(typeof(CartType)) .Name("changeCartItemComment") .Argument <InputChangeCartItemCommentType>(_commandName) .ResolveAsync(async context => { //TODO: Need to refactor later to prevent ugly code duplication //We need to add cartAggregate to the context to be able use it on nested cart types resolvers (e.g for currency) var cartAggregate = await _mediator.Send(context.GetCartCommand <ChangeCartItemCommentCommand>()); //store cart aggregate in the user context for future usage in the graph types resolvers context.SetExpandedObjectGraph(cartAggregate); return(cartAggregate); }).FieldType; schema.Mutation.AddField(changeCartItemCommentField); /// <example> /// This is an example JSON request for a mutation /// { /// "query": "mutation ($command:InputRemoveItemType!){ removeCartItem(command: $command) { total { formatedAmount } } }", /// "variables": { /// "command": { /// "storeId": "Electronics", /// "cartName": "default", /// "userId": "b57d06db-1638-4d37-9734-fd01a9bc59aa", /// "language": "en-US", /// "currency": "USD", /// "cartType": "cart", /// "lineItemId": "9cbd8f316e254a679ba34a900fccb076" /// } /// } /// } /// </example> var removeCartItemField = FieldBuilder.Create <CartAggregate, CartAggregate>(typeof(CartType)) .Name("removeCartItem") .Argument <NonNullGraphType <InputRemoveItemType> >(_commandName) .ResolveAsync(async context => { //TODO: Need to refactor later to prevent ugly code duplication //We need to add cartAggregate to the context to be able use it on nested cart types resolvers (e.g for currency) var cartAggregate = await _mediator.Send(context.GetCartCommand <RemoveCartItemCommand>()); //store cart aggregate in the user context for future usage in the graph types resolvers context.SetExpandedObjectGraph(cartAggregate); return(cartAggregate); }).FieldType; schema.Mutation.AddField(removeCartItemField); /// <example> /// This is an example JSON request for a mutation /// { /// "query": "mutation ($command:InputAddCouponType!){ addCoupon(command: $command) { total { formatedAmount } } }", /// "variables": { /// "command": { /// "storeId": "Electronics", /// "cartName": "default", /// "userId": "b57d06db-1638-4d37-9734-fd01a9bc59aa", /// "language": "en-US", /// "currency": "USD", /// "cartType": "cart", /// "couponCode": "verynicecouponcode" /// } /// } /// } /// </example> var addCouponField = FieldBuilder.Create <CartAggregate, CartAggregate>(typeof(CartType)) .Name("addCoupon") .Argument <NonNullGraphType <InputAddCouponType> >(_commandName) .ResolveAsync(async context => { //TODO: Need to refactor later to prevent ugly code duplication //We need to add cartAggregate to the context to be able use it on nested cart types resolvers (e.g for currency) var cartAggregate = await _mediator.Send(context.GetCartCommand <AddCouponCommand>()); //store cart aggregate in the user context for future usage in the graph types resolvers context.SetExpandedObjectGraph(cartAggregate); return(cartAggregate); }).FieldType; schema.Mutation.AddField(addCouponField); /// <example> /// This is an example JSON request for a mutation /// { /// "query": "mutation ($command:InputRemoveCouponType!){ removeCoupon(command: $command) { total { formatedAmount } } }", /// "variables": { /// "command": { /// "storeId": "Electronics", /// "cartName": "default", /// "userId": "b57d06db-1638-4d37-9734-fd01a9bc59aa", /// "language": "en-US", /// "currency": "USD", /// "cartType": "cart", /// "couponCode": "verynicecouponcode" /// } /// } /// } /// </example> var removeCouponField = FieldBuilder.Create <CartAggregate, CartAggregate>(typeof(CartType)) .Name("removeCoupon") .Argument <NonNullGraphType <InputRemoveCouponType> >(_commandName) .ResolveAsync(async context => { //TODO: Need to refactor later to prevent ugly code duplication //We need to add cartAggregate to the context to be able use it on nested cart types resolvers (e.g for currency) var cartAggregate = await _mediator.Send(context.GetCartCommand <RemoveCouponCommand>()); //store cart aggregate in the user context for future usage in the graph types resolvers context.SetExpandedObjectGraph(cartAggregate); return(cartAggregate); }).FieldType; schema.Mutation.AddField(removeCouponField); /// <example> /// This is an example JSON request for a mutation /// { /// "query": "mutation ($command:InputRemoveShipmentType!){ removeShipment(command: $command) { total { formatedAmount } } }", /// "variables": { /// "command": { /// "storeId": "Electronics", /// "cartName": "default", /// "userId": "b57d06db-1638-4d37-9734-fd01a9bc59aa", /// "language": "en-US", /// "currency": "USD", /// "cartType": "cart", /// "shipmentId": "7777-7777-7777-7777" /// } /// } /// } /// </example> var removeShipmentField = FieldBuilder.Create <CartAggregate, CartAggregate>(typeof(CartType)) .Name("removeShipment") .Argument <NonNullGraphType <InputRemoveShipmentType> >(_commandName) .ResolveAsync(async context => { //TODO: Need to refactor later to prevent ugly code duplication //We need to add cartAggregate to the context to be able use it on nested cart types resolvers (e.g for currency) var cartAggregate = await _mediator.Send(context.GetCartCommand <RemoveShipmentCommand>()); //store cart aggregate in the user context for future usage in the graph types resolvers context.SetExpandedObjectGraph(cartAggregate); return(cartAggregate); }).FieldType; schema.Mutation.AddField(removeShipmentField); //TODO: add shipment model to example /// <example> /// This is an example JSON request for a mutation /// { /// "query": "mutation ($command:InputAddOrUpdateCartShipmentType!){ addOrUpdateCartShipment(command: $command) { total { formatedAmount } } }", /// "variables": { /// "command": { /// "storeId": "Electronics", /// "cartName": "default", /// "userId": "b57d06db-1638-4d37-9734-fd01a9bc59aa", /// "language": "en-US", /// "currency": "USD", /// "cartType": "cart", /// "shipment": { } /// } /// } /// } /// </example> var addOrUpdateCartShipmentField = FieldBuilder.Create <CartAggregate, CartAggregate>(typeof(CartType)) .Name("addOrUpdateCartShipment") .Argument <NonNullGraphType <InputAddOrUpdateCartShipmentType> >(_commandName) .ResolveAsync(async context => { //TODO: Need to refactor later to prevent ugly code duplication //We need to add cartAggregate to the context to be able use it on nested cart types resolvers (e.g for currency) var cartAggregate = await _mediator.Send(context.GetCartCommand <AddOrUpdateCartShipmentCommand>()); //store cart aggregate in the user context for future usage in the graph types resolvers context.SetExpandedObjectGraph(cartAggregate); return(cartAggregate); }).FieldType; schema.Mutation.AddField(addOrUpdateCartShipmentField); //TODO: add payment model to example /// <example> /// This is an example JSON request for a mutation /// { /// "query": "mutation ($command:InputAddOrUpdateCartPaymentType!){ addOrUpdateCartPayment(command: $command) { total { formatedAmount } } }", /// "variables": { /// "command": { /// "storeId": "Electronics", /// "cartName": "default", /// "userId": "b57d06db-1638-4d37-9734-fd01a9bc59aa", /// "language": "en-US", /// "currency": "USD", /// "cartType": "cart", /// "payment": { } /// } /// } /// } /// </example> var addOrUpdateCartPaymentField = FieldBuilder.Create <CartAggregate, CartAggregate>(typeof(CartType)) .Name("addOrUpdateCartPayment") .Argument <NonNullGraphType <InputAddOrUpdateCartPaymentType> >(_commandName) .ResolveAsync(async context => { //TODO: Need to refactor later to prevent ugly code duplication //We need to add cartAggregate to the context to be able use it on nested cart types resolvers (e.g for currency) var cartAggregate = await _mediator.Send(context.GetCartCommand <AddOrUpdateCartPaymentCommand>()); //store cart aggregate in the user context for future usage in the graph types resolvers context.SetExpandedObjectGraph(cartAggregate); return(cartAggregate); }).FieldType; schema.Mutation.AddField(addOrUpdateCartPaymentField); /// <example> /// This is an example JSON request for a mutation /// { /// "query": "mutation ($command:InputValidateCouponType!){ validateCoupon(command: $command) }", /// "variables": { /// "command": { /// "storeId": "Electronics", /// "cartName": "default", /// "userId": "b57d06db-1638-4d37-9734-fd01a9bc59aa", /// "language": "en-US", /// "currency": "USD", /// "cartType": "cart", /// "coupon": { /// "code":"verynicecodeforvalidation" /// } /// } /// } /// } /// </example> var validateCouponField = FieldBuilder.Create <CartAggregate, bool>(typeof(BooleanGraphType)) .Name("validateCoupon") .Argument <NonNullGraphType <InputValidateCouponType> >(_commandName) .ResolveAsync(async context => await _mediator.Send(context.GetArgument <ValidateCouponCommand>(_commandName))) .FieldType; schema.Mutation.AddField(validateCouponField); /// <example> /// This is an example JSON request for a mutation /// { /// "query": "mutation ($command:MergeCartType!){ mergeCart(command: $command) { total { formatedAmount } } }", /// "variables": { /// "command": { /// "storeId": "Electronics", /// "cartName": "default", /// "userId": "b57d06db-1638-4d37-9734-fd01a9bc59aa", /// "language": "en-US", /// "currency": "USD", /// "cartType": "cart", /// "secondCartId": "7777-7777-7777-7777" /// } /// } /// } /// </example> var margeCartField = FieldBuilder.Create <CartAggregate, CartAggregate>(typeof(CartType)) .Name("mergeCart") .Argument <NonNullGraphType <InputMergeCartType> >(_commandName) .ResolveAsync(async context => { //TODO: Need to refactor later to prevent ugly code duplication //We need to add cartAggregate to the context to be able use it on nested cart types resolvers (e.g for currency) var cartAggregate = await _mediator.Send(context.GetCartCommand <MergeCartCommand>()); //store cart aggregate in the user context for future usage in the graph types resolvers context.SetExpandedObjectGraph(cartAggregate); return(cartAggregate); }).FieldType; schema.Mutation.AddField(margeCartField); /// <example> /// This is an example JSON request for a mutation /// { /// "query": "mutation ($command:InputRemoveCartType!){ removeCart(command: $command) { total { formatedAmount } } }", /// "variables": { /// "command": { /// "cartId": "7777-7777-7777-7777" /// } /// } /// } /// </example> var removeCartField = FieldBuilder.Create <CartAggregate, bool>(typeof(BooleanGraphType)) .Name("removeCart") .Argument <NonNullGraphType <InputRemoveCartType> >(_commandName) .ResolveAsync(async context => await _mediator.Send(context.GetArgument <RemoveCartCommand>(_commandName))) .FieldType; schema.Mutation.AddField(removeCartField); /// <example> /// This is an example JSON request for a mutation /// { /// "query": "mutation ($command:InputClearShipmentsType!){ clearShipments(command: $command) { total { formatedAmount } } }", /// "variables": { /// "command": { /// "cartId": "7777-7777-7777-7777" /// } /// } /// } /// </example> var clearShipmentsField = FieldBuilder.Create <CartAggregate, CartAggregate>(typeof(CartType)) .Name("clearShipments") .Argument <NonNullGraphType <InputClearShipmentsType> >(_commandName) .ResolveAsync(async context => { //TODO: Need to refactor later to prevent ugly code duplication //We need to add cartAggregate to the context to be able use it on nested cart types resolvers (e.g for currency) var cartAggregate = await _mediator.Send(context.GetArgument <ClearShipmentsCommand>(_commandName)); //store cart aggregate in the user context for future usage in the graph types resolvers context.SetExpandedObjectGraph(cartAggregate); return(cartAggregate); }) .FieldType; schema.Mutation.AddField(clearShipmentsField); /// <example> /// This is an example JSON request for a mutation /// { /// "query": "mutation ($command:InputClearPaymentsType!){ clearPayments(command: $command) { total { formatedAmount } } }", /// "variables": { /// "command": { /// "cartId": "7777-7777-7777-7777" /// } /// } /// } /// </example> var clearPaymentsField = FieldBuilder.Create <CartAggregate, CartAggregate>(typeof(CartType)) .Name("clearPayments") .Argument <NonNullGraphType <InputClearPaymentsType> >(_commandName) .ResolveAsync(async context => { //TODO: Need to refactor later to prevent ugly code duplication //We need to add cartAggregate to the context to be able use it on nested cart types resolvers (e.g for currency) var cartAggregate = await _mediator.Send(context.GetArgument <ClearPaymentsCommand>(_commandName)); //store cart aggregate in the user context for future usage in the graph types resolvers context.SetExpandedObjectGraph(cartAggregate); return(cartAggregate); }) .FieldType; schema.Mutation.AddField(clearPaymentsField); /// <example> /// This is an example JSON request for a mutation /// { /// "query": "mutation ($command:InputAddOrUpdateCartAddressType!){ addOrUpdateCartAddress(command: $command) { total { formatedAmount } } }", /// "variables": { /// "command": { /// "storeId": "Electronics", /// "cartName": "default", /// "userId": "b57d06db-1638-4d37-9734-fd01a9bc59aa", /// "language": "en-US", /// "currency": "USD", /// "cartType": "cart", /// "address": { /// "line1":"st street 1" /// } /// } /// } /// } /// </example> var addOrUpdateCartAddress = FieldBuilder.Create <CartAggregate, CartAggregate>(typeof(CartType)) .Name("addOrUpdateCartAddress") .Argument <NonNullGraphType <InputAddOrUpdateCartAddressType> >(_commandName) .ResolveAsync(async context => { //TODO: Need to refactor later to prevent ugly code duplication //We need to add cartAggregate to the context to be able use it on nested cart types resolvers (e.g for currency) var cartAggregate = await _mediator.Send(context.GetArgument <AddOrUpdateCartAddressCommand>(_commandName)); //store cart aggregate in the user context for future usage in the graph types resolvers context.SetExpandedObjectGraph(cartAggregate); return(cartAggregate); }) .FieldType; schema.Mutation.AddField(addOrUpdateCartAddress); /// <example> /// This is an example JSON request for a mutation /// { /// "query": "mutation ($command:InputRemoveCartAddressType!){ removeCartAddress(command: $command) { total { formatedAmount } } }", /// "variables": { /// "command": { /// "cartId": "7777-7777-7777-7777", /// "addressId": "111" /// } /// } /// } /// </example> var removeCartAddressField = FieldBuilder.Create <CartAggregate, CartAggregate>(typeof(CartType)) .Name("removeCartAddress") .Argument <NonNullGraphType <InputRemoveCartAddressType> >(_commandName) .ResolveAsync(async context => await _mediator.Send(context.GetArgument <RemoveCartAddressCommand>(_commandName))) .FieldType; schema.Mutation.AddField(removeCartAddressField); }
public OrderLineItemType(IMediator mediator, IDataLoaderContextAccessor dataLoader, IDynamicPropertyResolverService dynamicPropertyResolverService) { Field(x => x.Id); Field(x => x.ProductType, true); Field(x => x.Name); Field(x => x.Comment, true); Field(x => x.ImageUrl, true); Field(x => x.IsGift, true); Field(x => x.ShippingMethodCode, true); Field(x => x.FulfillmentLocationCode, true); Field(x => x.FulfillmentCenterId, true); Field(x => x.FulfillmentCenterName, true); Field(x => x.OuterId, true); Field(x => x.WeightUnit, true); Field(x => x.Weight, true); Field(x => x.MeasureUnit, true); Field(x => x.Height, true); Field(x => x.Length, true); Field(x => x.Width, true); Field(x => x.IsCancelled); Field(x => x.CancelledDate, true); Field(x => x.CancelReason, true); Field(x => x.ObjectType); Field(x => x.CategoryId, true); Field(x => x.CatalogId); Field(x => x.Sku); Field(x => x.PriceId, true); Field <MoneyType>(nameof(LineItem.Price).ToCamelCase(), resolve: context => new Money(context.Source.Price, context.GetOrderCurrency())); Field <MoneyType>(nameof(LineItem.PriceWithTax).ToCamelCase(), resolve: context => new Money(context.Source.PriceWithTax, context.GetOrderCurrency())); Field(x => x.TaxType, true); Field(x => x.TaxPercentRate); Field(x => x.ReserveQuantity); Field(x => x.Quantity); Field(x => x.ProductId); Field <CurrencyType>(nameof(LineItem.Currency).ToCamelCase(), resolve: context => context.GetOrderCurrency()); Field <MoneyType>(nameof(LineItem.DiscountAmount).ToCamelCase(), resolve: context => new Money(context.Source.DiscountAmount, context.GetOrderCurrency())); Field <MoneyType>(nameof(LineItem.DiscountAmountWithTax).ToCamelCase(), resolve: context => new Money(context.Source.DiscountAmountWithTax, context.GetOrderCurrency())); Field <MoneyType>(nameof(LineItem.DiscountTotal).ToCamelCase(), resolve: context => new Money(context.Source.DiscountTotal, context.GetOrderCurrency())); Field <MoneyType>(nameof(LineItem.DiscountTotalWithTax).ToCamelCase(), resolve: context => new Money(context.Source.DiscountTotalWithTax, context.GetOrderCurrency())); Field <MoneyType>(nameof(LineItem.ExtendedPrice).ToCamelCase(), resolve: context => new Money(context.Source.ExtendedPrice, context.GetOrderCurrency())); Field <MoneyType>(nameof(LineItem.ExtendedPriceWithTax).ToCamelCase(), resolve: context => new Money(context.Source.ExtendedPriceWithTax, context.GetOrderCurrency())); Field <MoneyType>(nameof(LineItem.PlacedPrice).ToCamelCase(), resolve: context => new Money(context.Source.PlacedPrice, context.GetOrderCurrency())); Field <MoneyType>(nameof(LineItem.PlacedPriceWithTax).ToCamelCase(), resolve: context => new Money(context.Source.PlacedPriceWithTax, context.GetOrderCurrency())); Field <MoneyType>(nameof(LineItem.TaxTotal).ToCamelCase(), resolve: context => new Money(context.Source.TaxTotal, context.GetOrderCurrency())); Field <NonNullGraphType <ListGraphType <OrderTaxDetailType> > >(nameof(LineItem.TaxDetails), resolve: x => x.Source.TaxDetails); Field <NonNullGraphType <ListGraphType <OrderDiscountType> > >(nameof(LineItem.Discounts), resolve: x => x.Source.Discounts); var productField = new FieldType { Name = "product", Type = GraphTypeExtenstionHelper.GetActualType <ProductType>(), Resolver = new FuncFieldResolver <LineItem, IDataLoaderResult <ExpProduct> >(context => { var includeFields = context.SubFields.Values.GetAllNodesPaths(); var loader = dataLoader.Context.GetOrAddBatchLoader <string, ExpProduct>("order_lineItems_products", async(ids) => { //Get currencies and store only from one order. //We intentionally ignore the case when there are ma be the orders with the different currencies and stores in the resulting set var order = context.GetValueForSource <CustomerOrderAggregate>().Order; var request = new LoadProductsQuery { StoreId = order.StoreId, CurrencyCode = order.Currency, ObjectIds = ids.ToArray(), IncludeFields = includeFields.ToArray() }; if (!context.UserContext.ContainsKey("storeId")) { context.UserContext.Add("storeId", order.StoreId); } var response = await mediator.Send(request); return(response.Products.ToDictionary(x => x.Id)); }); return(loader.LoadAsync(context.Source.ProductId)); }) }; AddField(productField); ExtendableField <ListGraphType <DynamicPropertyValueType> >( "dynamicProperties", "Customer order Line item dynamic property values", QueryArgumentPresets.GetArgumentForDynamicProperties(), context => dynamicPropertyResolverService.LoadDynamicPropertyValues(context.Source, context.GetArgumentOrValue <string>("cultureName"))); }
public void Build(ISchema schema) { _ = schema.Query.AddField(new FieldType { Name = "order", Arguments = new QueryArguments( new QueryArgument <StringGraphType> { Name = "id" }, new QueryArgument <StringGraphType> { Name = "number" }, new QueryArgument <StringGraphType> { Name = "cultureName", Description = "Culture name (\"en-US\")" }), Type = GraphTypeExtenstionHelper.GetActualType <CustomerOrderType>(), Resolver = new AsyncFieldResolver <object>(async context => { var request = new GetOrderQuery { Number = context.GetArgument <string>("number"), OrderId = context.GetArgument <string>("id"), CultureName = context.GetArgument <string>(nameof(Currency.CultureName)) }; var orderAggregate = await _mediator.Send(request); var authorizationResult = await _authorizationService.AuthorizeAsync(context.GetCurrentPrincipal(), orderAggregate.Order, new CanAccessOrderAuthorizationRequirement()); if (!authorizationResult.Succeeded) { throw new ExecutionError($"Access denied"); } var allCurrencies = await _currencyService.GetAllCurrenciesAsync(); //Store all currencies in the user context for future resolve in the schema types context.SetCurrencies(allCurrencies, request.CultureName); //store order aggregate in the user context for future usage in the graph types resolvers context.SetExpandedObjectGraph(orderAggregate); return(orderAggregate); }) }); var orderConnectionBuilder = GraphTypeExtenstionHelper.CreateConnection <CustomerOrderType, object>() .Name("orders") .Argument <StringGraphType>("filter", "This parameter applies a filter to the query results") .Argument <StringGraphType>("sort", "The sort expression") .Argument <StringGraphType>("cultureName", "Culture name (\"en-US\")") .Argument <StringGraphType>("userId", "") .Unidirectional() .PageSize(20); orderConnectionBuilder.ResolveAsync(async context => await ResolveOrdersConnectionAsync(_mediator, context)); schema.Query.AddField(orderConnectionBuilder.FieldType); var paymentsConnectionBuilder = GraphTypeExtenstionHelper.CreateConnection <PaymentInType, object>() .Name("payments") .Argument <StringGraphType>("filter", "This parameter applies a filter to the query results") .Argument <StringGraphType>("sort", "The sort expression") .Argument <StringGraphType>("cultureName", "Culture name (\"en-US\")") .Argument <NonNullGraphType <StringGraphType> >("userId", "") .Unidirectional() .PageSize(20); paymentsConnectionBuilder.ResolveAsync(async context => await ResolvePaymentsConnectionAsync(_mediator, context)); schema.Query.AddField(paymentsConnectionBuilder.FieldType); _ = schema.Mutation.AddField(FieldBuilder.Create <object, CustomerOrderAggregate>(typeof(CustomerOrderType)) .Name("createOrderFromCart") .Argument <NonNullGraphType <InputCreateOrderFromCartType> >(_commandName) .ResolveAsync(async context => { var response = await _mediator.Send(context.GetArgument <CreateOrderFromCartCommand>(_commandName)); context.SetExpandedObjectGraph(response); return(response); }) .FieldType); _ = schema.Mutation.AddField(FieldBuilder.Create <object, bool>(typeof(BooleanGraphType)) .Name("changeOrderStatus") .Argument <NonNullGraphType <InputChangeOrderStatusType> >(_commandName) .ResolveAsync(async context => { var command = context.GetArgument <ChangeOrderStatusCommand>(_commandName); var order = await _customerOrderService.GetByIdAsync(command.OrderId); var authorizationResult = await _authorizationService.AuthorizeAsync(context.GetCurrentPrincipal(), order, new CanAccessOrderAuthorizationRequirement()); if (!authorizationResult.Succeeded) { throw new ExecutionError($"Access denied"); } return(await _mediator.Send(command)); }) .FieldType); _ = schema.Mutation.AddField(FieldBuilder.Create <object, bool>(typeof(BooleanGraphType)) .Name("confirmOrderPayment") .Argument <NonNullGraphType <InputConfirmOrderPaymentType> >(_commandName) .ResolveAsync(async context => { var command = context.GetArgument <ConfirmOrderPaymentCommand>(_commandName); var order = await _customerOrderService.GetByIdAsync(command.Payment.OrderId); var authorizationResult = await _authorizationService.AuthorizeAsync(context.GetCurrentPrincipal(), order, new CanAccessOrderAuthorizationRequirement()); if (!authorizationResult.Succeeded) { throw new ExecutionError($"Access denied"); } return(await _mediator.Send(command)); }) .FieldType); _ = schema.Mutation.AddField(FieldBuilder.Create <object, bool>(typeof(BooleanGraphType)) .Name("cancelOrderPayment") .Argument <NonNullGraphType <InputCancelOrderPaymentType> >(_commandName) .ResolveAsync(async context => { var command = context.GetArgument <CancelOrderPaymentCommand>(_commandName); var order = await _customerOrderService.GetByIdAsync(command.Payment.OrderId); var authorizationResult = await _authorizationService.AuthorizeAsync(context.GetCurrentPrincipal(), order, new CanAccessOrderAuthorizationRequirement()); if (!authorizationResult.Succeeded) { throw new ExecutionError($"Access denied"); } return(await _mediator.Send(command)); }) .FieldType); }
public CartType(ICartAvailMethodsService cartAvailMethods) { Field(x => x.Cart.Id, nullable: true).Description("Shopping cart Id"); Field(x => x.Cart.Name, nullable: false).Description("Shopping cart name"); Field(x => x.Cart.Status, nullable: true).Description("Shopping cart status"); Field(x => x.Cart.StoreId, nullable: true).Description("Shopping cart store id"); Field(x => x.Cart.ChannelId, nullable: true).Description("Shopping cart channel id"); Field <BooleanGraphType>("hasPhysicalProducts", resolve: context => AbstractTypeFactory <CartHasPhysicalProductsSpecification> .TryCreateInstance().IsSatisfiedBy(context.Source.Cart)); Field(x => x.Cart.IsAnonymous, nullable: true).Description("Sign that shopping cart is anonymous"); //Field(x => x.Customer, nullable: true).Description("Shopping cart user"); //todo: add resolver Field(x => x.Cart.CustomerId, nullable: true).Description("Shopping cart user id"); Field(x => x.Cart.CustomerName, nullable: true).Description("Shopping cart user name"); Field(x => x.Cart.OrganizationId, nullable: true).Description("Shopping cart organization id"); Field(x => x.Cart.IsRecuring, nullable: true).Description("Sign that shopping cart is recurring"); Field(x => x.Cart.Comment, nullable: true).Description("Shopping cart text comment"); // Characteristics Field(x => x.Cart.VolumetricWeight, nullable: true).Description("Shopping cart value of volumetric weight"); Field(x => x.Cart.WeightUnit, nullable: true).Description("Shopping cart value of weight unit"); Field(x => x.Cart.Weight, nullable: true).Description("Shopping cart value of shopping cart weight"); //TODO: //Field(x => x.MeasureUnit, nullable: true).Description("Shopping cart value of measurement unit"); //Field(x => x.Height, nullable: true).Description("Shopping cart value of height"); //Field(x => x.Length, nullable: true).Description("Shopping cart value of length"); //Field(x => x.Width, nullable: true).Description("Shopping cart value of width"); // Money Field <MoneyType>("total", resolve: context => context.Source.Cart.Total.ToMoney(context.Source.Currency)); Field <MoneyType>("subTotal", resolve: context => context.Source.Cart.SubTotal.ToMoney(context.Source.Currency)); Field <MoneyType>("subTotalWithTax", resolve: context => context.Source.Cart.SubTotalWithTax.ToMoney(context.Source.Currency)); Field <MoneyType>("extendedPriceTotal", resolve: context => context.Source.Cart.Items.Sum(i => i.ExtendedPrice).ToMoney(context.Source.Currency)); Field <MoneyType>("extendedPriceTotalWithTax", resolve: context => context.Source.Cart.Items.Sum(i => i.ExtendedPriceWithTax).ToMoney(context.Source.Currency)); Field <CurrencyType>("currency", resolve: context => context.Source.Currency); Field <MoneyType>("taxTotal", resolve: context => context.Source.Cart.TaxTotal.ToMoney(context.Source.Currency)); Field(x => x.Cart.TaxPercentRate, nullable: true).Description("Tax percent rate"); Field(x => x.Cart.TaxType, nullable: true).Description("Shipping tax type"); Field <ListGraphType <TaxDetailType> >("taxDetails", resolve: context => context.Source.Cart.TaxDetails); // Shipping Field <MoneyType>("shippingPrice", resolve: context => context.Source.Cart.ShippingTotal.ToMoney(context.Source.Currency)); Field <MoneyType>("shippingPriceWithTax", resolve: context => context.Source.Cart.ShippingTotalWithTax.ToMoney(context.Source.Currency)); Field <MoneyType>("shippingTotal", resolve: context => context.Source.Cart.ShippingTotal.ToMoney(context.Source.Currency)); Field <MoneyType>("shippingTotalWithTax", resolve: context => context.Source.Cart.ShippingTotalWithTax.ToMoney(context.Source.Currency)); //Field<ListGraphType<ShipmentType>>("shipments", resolve: context => context.Source.Cart.Shipments); //TODO: By this registration we support the schema types extensions. Need to move this code into extensions and replace everywhere to this version. var cartShipmentsField = new FieldType { Name = "shipments", Type = typeof(ListGraphType <>).MakeGenericType(GraphTypeExtenstionHelper.GetActualType <ShipmentType>()), Resolver = new FuncFieldResolver <CartAggregate, object>(context => context.Source.Cart.Shipments) }; AddField(cartShipmentsField); FieldAsync <ListGraphType <ShippingMethodType> >("availableShippingMethods", resolve: async context => { var rates = await cartAvailMethods.GetAvailableShippingRatesAsync(context.Source); //store the pair ShippingMethodType and cart aggregate in the user context for future usage in the ShippingMethodType fields resolvers if (rates != null) { rates.Apply(x => context.UserContext[x.GetCacheKey()] = context.Source); } return(rates); }); // Payment Field <MoneyType>("paymentPrice", resolve: context => context.Source.Cart.PaymentTotal.ToMoney(context.Source.Currency)); Field <MoneyType>("paymentPriceWithTax", resolve: context => context.Source.Cart.PaymentTotalWithTax.ToMoney(context.Source.Currency)); Field <MoneyType>("paymentTotal", resolve: context => context.Source.Cart.PaymentTotal.ToMoney(context.Source.Currency)); Field <MoneyType>("paymentTotalWithTax", resolve: context => context.Source.Cart.PaymentTotalWithTax.ToMoney(context.Source.Currency)); Field <ListGraphType <PaymentType> >("payments", resolve: context => context.Source.Cart.Payments); FieldAsync <ListGraphType <PaymentMethodType> >("availablePaymentMethods", resolve: async context => { var methods = await cartAvailMethods.GetAvailablePaymentMethodsAsync(context.Source); //store the pair ShippingMethodType and cart aggregate in the user context for future usage in the ShippingMethodType fields resolvers if (methods != null) { methods.Apply(x => context.UserContext[x.Id] = context.Source); } return(methods); }); //TODO: //Field<ListGraphType<PaymentPlanType>>("paymentPlan", resolve: context => context.Source.PaymentPlan); // Extended money //TODO: //Field<MoneyType>("extendedPriceTotal", resolve: context => context.Source.ExtendedPriceTotal); //Field<MoneyType>("extendedPriceTotalWithTax", resolve: context => context.Source.ExtendedPriceTotalWithTax); // Handling totals Field <MoneyType>("handlingTotal", resolve: context => context.Source.Cart.HandlingTotal.ToMoney(context.Source.Currency)); Field <MoneyType>("handlingTotalWithTax", resolve: context => context.Source.Cart.HandlingTotalWithTax.ToMoney(context.Source.Currency)); // Discounts Field <MoneyType>("discountTotal", resolve: context => context.Source.Cart.DiscountTotal.ToMoney(context.Source.Currency)); Field <MoneyType>("discountTotalWithTax", resolve: context => context.Source.Cart.DiscountTotalWithTax.ToMoney(context.Source.Currency)); Field <ListGraphType <DiscountType> >("discounts", resolve: context => context.Source.Cart.Discounts); // Addresses Field <ListGraphType <AddressType> >("addresses", resolve: context => context.Source.Cart.Addresses); // Items Field <ListGraphType <LineItemType> >("items", resolve: context => context.Source.Cart.Items); Field <IntGraphType>("itemsCount", "Count of different items", resolve: context => context.Source.Cart.Items.Count); Field <IntGraphType>("itemsQuantity", "Quantity of items", resolve: context => context.Source.Cart.Items.Sum(x => x.Quantity)); //TODO: //Field<LineItemType>("recentlyAddedItem", resolve: context => context.Source.Cart.RecentlyAddedItem); // Coupons Field <ListGraphType <CouponType> >("coupons", resolve: context => context.Source.Coupons); // Other //Field<ListGraphType<DynamicPropertyType>>("dynamicProperties", resolve: context => context.Source.DynamicProperties); //todo add dynamic properties //TODO: Field(x => x.IsValid, nullable: true).Description("Is cart valid"); Field <ListGraphType <ValidationErrorType> >("validationErrors", resolve: context => context.Source.ValidationErrors.OfType <CartValidationError>()); Field(x => x.Cart.Type, nullable: true).Description("Shopping cart type"); }
public LineItemType(IMediator mediator, IDataLoaderContextAccessor dataLoader) { var productField = new FieldType { Name = "product", Type = GraphTypeExtenstionHelper.GetActualType <ProductType>(), Resolver = new FuncFieldResolver <LineItem, IDataLoaderResult <ExpProduct> >(context => { var includeFields = context.SubFields.Values.GetAllNodesPaths(); var loader = dataLoader.Context.GetOrAddBatchLoader <string, ExpProduct>("order_lineItems_products", async(ids) => { //Get currencies and store only from one cart. //We intentionally ignore the case when there are ma be the carts with the different currencies and stores in the resulting set var cart = context.GetValueForSource <CartAggregate>().Cart; var request = new LoadProductsQuery { StoreId = cart.StoreId, CurrencyCode = cart.Currency, ObjectIds = ids.ToArray(), IncludeFields = includeFields.ToArray() }; var response = await mediator.Send(request); return(response.Products.ToDictionary(x => x.Id)); }); return(loader.LoadAsync(context.Source.ProductId)); }) }; AddField(productField); //Field<MoneyType>("paymentPlan", resolve: context => context.Source.PaymentPlan); Field <IntGraphType>("inStockQuantity", resolve: context => context.GetCart().CartProducts[context.Source.ProductId]?.AvailableQuantity ?? 0); Field <StringGraphType>("warehouseLocation", resolve: context => context.GetCart().CartProducts[context.Source.ProductId]?.Inventory?.FulfillmentCenter?.Address); Field <BooleanGraphType>("IsValid", resolve: context => !context.GetCart().ValidationErrors.GetEntityCartErrors(context.Source).Any()); Field <ListGraphType <ValidationErrorType> >("validationErrors", resolve: context => context.GetCart().ValidationErrors.GetEntityCartErrors(context.Source)); Field(x => x.CatalogId, nullable: true).Description("Value of catalog id"); Field(x => x.CategoryId, nullable: true).Description("Value of category id"); Field(x => x.CreatedDate, nullable: true).Description("Line item created date"); Field(x => x.Height, nullable: true).Description("Value of height"); Field(x => x.Id, nullable: false).Description("Line item id"); Field(x => x.ImageUrl, nullable: true).Description("Value of line item image absolute URL"); Field(x => x.IsGift, nullable: true).Description("flag of line item is a gift"); Field(x => x.IsReadOnly, nullable: true).Description("Is readOnly"); Field(x => x.IsReccuring, nullable: true).Description("flag of line item is recurring"); Field(x => x.LanguageCode, nullable: true).Description("Culture name in ISO 3166-1 alpha-3 format"); Field(x => x.Length, nullable: true).Description("Value of length"); Field(x => x.MeasureUnit, nullable: true).Description("Value of measurement unit"); Field(x => x.Name, nullable: true).Description("Value of line item name"); Field(x => x.Note, nullable: true).Description("Value of line item comment"); Field(x => x.ObjectType, nullable: true).Description("Value of line item quantity"); Field(x => x.ProductId, nullable: true).Description("Value of product id"); Field(x => x.ProductType, nullable: true).Description("type of product (can be Physical, Digital or Subscription)"); Field(x => x.Quantity, nullable: true).Description("Value of line item quantity"); Field(x => x.RequiredShipping, nullable: true).Description("requirement for line item shipping"); Field(x => x.ShipmentMethodCode, nullable: true).Description("Value of line item shipping method code"); Field(x => x.Sku, nullable: true).Description("Value of product SKU"); Field(x => x.TaxPercentRate, nullable: true).Description("Value of total shipping tax amount"); Field(x => x.TaxType, nullable: true).Description("Value of shipping tax type"); Field(x => x.ThumbnailImageUrl, nullable: true).Description("Value of line item thumbnail image absolute URL"); Field(x => x.VolumetricWeight, nullable: true).Description("Value of volumetric weight"); Field(x => x.Weight, nullable: true).Description("Value of shopping cart weight"); Field(x => x.WeightUnit, nullable: true).Description("Value of weight unit"); Field(x => x.Width, nullable: true).Description("Value of width"); Field <ListGraphType <DiscountType> >("discounts", resolve: context => context.Source.Discounts); Field <ListGraphType <TaxDetailType> >("taxDetails", resolve: context => context.Source.TaxDetails); Field <MoneyType>("discountAmount", resolve: context => context.Source.DiscountAmount.ToMoney(context.GetCart().Currency)); Field <MoneyType>("discountAmountWithTax", resolve: context => context.Source.DiscountAmountWithTax.ToMoney(context.GetCart().Currency)); Field <MoneyType>("discountTotal", resolve: context => context.Source.DiscountTotal.ToMoney(context.GetCart().Currency)); Field <MoneyType>("discountTotalWithTax", resolve: context => context.Source.DiscountTotalWithTax.ToMoney(context.GetCart().Currency)); Field <MoneyType>("extendedPrice", resolve: context => context.Source.ExtendedPrice.ToMoney(context.GetCart().Currency)); Field <MoneyType>("extendedPriceWithTax", resolve: context => context.Source.ExtendedPriceWithTax.ToMoney(context.GetCart().Currency)); Field <MoneyType>("listPrice", resolve: context => context.Source.ListPrice.ToMoney(context.GetCart().Currency)); Field <MoneyType>("listPriceWithTax", resolve: context => context.Source.ListPriceWithTax.ToMoney(context.GetCart().Currency)); Field <MoneyType>("placedPrice", resolve: context => context.Source.PlacedPrice.ToMoney(context.GetCart().Currency)); Field <MoneyType>("placedPriceWithTax", resolve: context => context.Source.PlacedPriceWithTax.ToMoney(context.GetCart().Currency)); Field <MoneyType>("salePrice", resolve: context => context.Source.SalePrice.ToMoney(context.GetCart().Currency)); Field <MoneyType>("salePriceWithTax", resolve: context => context.Source.SalePriceWithTax.ToMoney(context.GetCart().Currency)); Field <MoneyType>("taxTotal", resolve: context => context.Source.TaxTotal.ToMoney(context.GetCart().Currency)); }