Skip to content

Commit

Permalink
Tenant phone resolver (#151)
Browse files Browse the repository at this point in the history
* Applying Unique ieds in all models

* Added ThumbnailName field to image input and tied image to phones associated with the tenant selected

* Fixed many-to-many paging/projection clashing that broke Tenant and Phone edges

* Implemented GlobalIDsm update packages, fixed verify address, removed commented and serializations
  • Loading branch information
JamesBock authored Feb 25, 2021
1 parent c6e6237 commit 53b2d4c
Show file tree
Hide file tree
Showing 28 changed files with 349 additions and 129 deletions.
12 changes: 2 additions & 10 deletions TenantFile/Api/Models/Entities/Address.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,21 +11,13 @@ public class Address : IEntity
{

public int Id { get; set; }

[XmlElement("Address2")]
public string Line1 { get; set; } = null!;
[XmlElement("Address1")]
public string? Line2 { get; set; }
public string Line1 { get; set; } = null!;
public string? Line2 { get; set; }
public string? Line3 { get; set; }
public string? Line4 { get; set; }
[XmlElement("City")]
public string City { get; set; } = null!;
[XmlElement("State")]
public string State { get; set; } = null!;
[XmlElement("Zip5")]
public string PostalCode { get; set; } = null!;

[XmlElement("ReturnText")]
public string? ValidationMessage { get; set; }
}
}
6 changes: 3 additions & 3 deletions TenantFile/Api/Models/Entities/Organizer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@ namespace TenantFile.Api.Models.Entities
{
public class Organizer
{

public string Uid { get; set; } = null!;
public string Name { get; set; } = null!;

public virtual ICollection<Phone> Phones{ get; set; } = null!;
public virtual ICollection<Property> Properties { get; set; } = null!;
public ICollection<Phone> Phones { get; set; } = new List<Phone>();
public ICollection<Property> Properties { get; set; } = new List<Property>();

}
}
6 changes: 3 additions & 3 deletions TenantFile/Api/Models/Entities/Phone.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,12 @@ namespace TenantFile.Api.Models.Entities
{
public class Phone : IEntity
{

public int Id { get; set; }
public string PhoneNumber { get; set; } = null!;

public virtual ICollection<Tenant> Tenants { get; set; } = null!;
public virtual ICollection<Image> Images { get; set; } = null!;
public ICollection<Tenant> Tenants { get; set; } = new List<Tenant>();
public ICollection<Image> Images { get; set; } = new List<Image>();

}
}
8 changes: 4 additions & 4 deletions TenantFile/Api/Models/Entities/Property.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,16 @@
using TenantFile.Api.Common;
using TenantFile.Api.Models.Entities;

namespace TenantFile.Api.Models.Entities
namespace TenantFile.Api.Models.Entities
{
public class Property : IEntity
{
public int Id { get; set; }
public string? Name { get; set; }
public int AddressId { get; set; }
public virtual Address Address { get; set; } = null!;
public int AddressId { get; set; }
public Address Address { get; set; } = null!;

public virtual ICollection<Residence> Residences { get; set; } = null!;
public ICollection<Residence> Residences { get; set; } = new List<Residence>();
//public virtual Complex Complex { get; set; } = null!;
}
}
4 changes: 2 additions & 2 deletions TenantFile/Api/Models/Entities/Residence.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@ public class Residence : IEntity
public int Id { get; set; }

public int? PropertyId { get; set; }
public virtual Property? Property { get; set; }
public Property? Property { get; set; }

public int AddressId { get; set; }
public virtual Address Address { get; set; } = null!;
public Address Address { get; set; } = null!;
}
}
4 changes: 2 additions & 2 deletions TenantFile/Api/Models/Entities/ResidenceRecord.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ public class ResidenceRecord : IEntity
public DateTime MoveIn { get; set; }
public DateTime MoveOut { get; set; }

public virtual Tenant Tenant { get; set; } = null!;
public virtual Residence Residence { get; set; } = null!;
public Tenant Tenant { get; set; } = null!;
public Residence Residence { get; set; } = null!;

}

Expand Down
2 changes: 1 addition & 1 deletion TenantFile/Api/Models/Entities/Tenant.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,6 @@ public class Tenant : IEntity
public int? ResidenceId { get; set; }
public Residence? CurrentResidence { get; set; }

public virtual ICollection<Phone> Phones { get; set; } = null!;
public ICollection<Phone> Phones { get; set; } = new List<Phone>();
}
}
25 changes: 25 additions & 0 deletions TenantFile/Api/Models/GraphQL/Addresses/AddressMutations.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using HotChocolate;
using HotChocolate.Subscriptions;
using HotChocolate.Types;
using TenantFile.Api.Models.Tenants;
using TenantFile.Api.Extensions;
using TenantFile.Api.Models.Entities;
using TenantFile.Api.Services;
using TenantFile.Api.Models.Addresses;

namespace TenantFile.Api.Models.Properties
{
[ExtendObjectType(Name = "Mutation")]
public class AddressMutations
{
public async Task<VerifyAddressPayload> VerifyAddress([Service] IAddressVerificationService service, VerifyAddressInput address)
{
return new VerifyAddressPayload(await service.VerifyAddressAsync(address));
}
}
}
3 changes: 2 additions & 1 deletion TenantFile/Api/Models/GraphQL/Addresses/AddressQueries.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
using TenantFile.Api.DataLoader;
using TenantFile.Api.Extensions;
using TenantFile.Api.Models.Entities;
using HotChocolate.Types.Relay;

namespace TenantFile.Api.Models.Addresses
{
Expand All @@ -23,7 +24,7 @@ public class AddressQueries
[HotChocolate.Data.UseSorting]
public IQueryable<Address> GetAddresses([ScopedService] TenantFileContext tenantContext) => tenantContext.Addresses.AsQueryable();

public Task<Address> GetAddressAsync(int id, AddressByIdDataLoader dataLoader, CancellationToken cancellationToken) => dataLoader.LoadAsync(id, cancellationToken);
public Task<Address> GetAddressAsync([ID(nameof(Address))] int id, AddressByIdDataLoader dataLoader, CancellationToken cancellationToken) => dataLoader.LoadAsync(id, cancellationToken);

}
}
1 change: 0 additions & 1 deletion TenantFile/Api/Models/GraphQL/Addresses/AddressType.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ protected override void Configure(IObjectTypeDescriptor<Address> descriptor)
public class AddressResolvers
{
public async Task<Address> GetAddress(Address address,
//[ScopedService] TenantFileContext context,
AddressByIdDataLoader dataLoader,
CancellationToken cancellationToken)
{
Expand Down
19 changes: 19 additions & 0 deletions TenantFile/Api/Models/GraphQL/Addresses/VerifyAddressInput.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace TenantFile.Api.Models.Addresses
{
public record VerifyAddressInput
(
string? Line1,
string? Line2,
string? Line3,
string? Line4,
string? City,
string? State,
string? PostalCode
);
}
25 changes: 25 additions & 0 deletions TenantFile/Api/Models/GraphQL/Addresses/VerifyAddressPayload.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Serialization;
using TenantFile.Api.Common;
using TenantFile.Api.Models.Entities;
using TenantFile.Api.Services;

namespace TenantFile.Api.Models.Addresses
{
public class VerifyAddressPayload : TPayload<USPSVerifyPayload>
{

public VerifyAddressPayload(USPSVerifyPayload address) : base(address)
{

}
public VerifyAddressPayload(UserError error)
: base(new[] { error })
{
}
}
}
12 changes: 8 additions & 4 deletions TenantFile/Api/Models/GraphQL/Images/AddImageInput.cs
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
using TenantFile.Api.Models.Entities;
using HotChocolate.Types.Relay;
using TenantFile.Api.Models.Entities;

namespace TenantFile.Api.Models.Images
{
public record AddImageInput(
string FileName,
Tenant Tenant,
Residence Residence,
string ThumbnailName,
[ID(nameof(Tenant))]
int Tenant,
[ID(nameof(Residence))]
int Residence,
ImageLabel[] Labels

);

}
30 changes: 24 additions & 6 deletions TenantFile/Api/Models/GraphQL/Images/ImageMutations.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,19 +13,37 @@ namespace TenantFile.Api.Models.Images
[ExtendObjectType(Name = "Mutation")]
public class ImageMutations
{/// <summary>
/// Intended for use by Organizer uploading Images via dashboard, not for SMS/Twilio uploads
/// </summary>
/// <param name="input"></param>
/// <param name="context"></param>
/// <returns></returns>
/// Intended for use by Organizer uploading Images via dashboard, not for SMS/Twilio uploads
/// The relationshiup of the image and the residence is implied as of 2/11 would need to add a Property on the image or Residence Entity
/// </summary>
/// <param name="input"></param>
/// <param name="context"></param>
/// <returns></returns>
[UseTenantFileContext]

public async Task<AddImagePayload> AddImageAsync(
AddImageInput input,
[ScopedService] TenantFileContext context)
{
var image = new Image{ Name = input.FileName };
var (fileName, thumb, tenantId, residenceId, labels) = input;

var image = new Image
{
Name = fileName,
Labels = labels,
ThumbnailName = thumb,

};
context.Images.Add(image);

var phones
= context.Phones.AsQueryable()
.Where(p => p.Tenants.Select(t => t.Id).Contains(tenantId)).ToList();
phones.ForEach(p => p.Images.Add(image));




await context.SaveChangesAsync();
return new AddImagePayload(image);
}
Expand Down
3 changes: 2 additions & 1 deletion TenantFile/Api/Models/GraphQL/Images/ImageQueries.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
using HotChocolate;
using HotChocolate.Data;
using HotChocolate.Types;
using HotChocolate.Types.Relay;
using Microsoft.EntityFrameworkCore;
using TenantFile.Api.DataLoader;
using TenantFile.Api.Extensions;
Expand All @@ -23,6 +24,6 @@ public class ImageQueries
[HotChocolate.Data.UseSorting]
public IQueryable<Image> GetImages([ScopedService] TenantFileContext tenantContext) => tenantContext.Images.AsNoTracking();

public Task<Image> GetImageAsync(int id, ImageByIdDataLoader dataLoader, CancellationToken cancellationToken) => dataLoader.LoadAsync(id, cancellationToken);
public Task<Image> GetImageAsync([ID(nameof(Image))] int id, ImageByIdDataLoader dataLoader, CancellationToken cancellationToken) => dataLoader.LoadAsync(id, cancellationToken);
}
}
42 changes: 25 additions & 17 deletions TenantFile/Api/Models/GraphQL/Phones/PhoneQueries.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,29 +12,37 @@
using TenantFile.Api.DataLoader;
using TenantFile.Api.Extensions;
using TenantFile.Api.Models.Entities;
using HotChocolate.Types.Relay;

namespace TenantFile.Api.Models.Phones
{
[ExtendObjectType(Name = "Query")]
public class PhoneQueries
{
[ExtendObjectType(Name = "Query")]
public class PhoneQueries
{

[UseTenantFileContext]
[UsePaging]
[UseProjection]
[HotChocolate.Data.UseFiltering(typeof(PhoneFilterInputType))]
[HotChocolate.Data.UseSorting]
public IQueryable<Phone> GetPhones([ScopedService] TenantFileContext tenantContext) => tenantContext.Phones.AsQueryable();
[UseTenantFileContext]
[UsePaging(typeof(NonNullType<PhoneType>))]
// [UseProjection]
[HotChocolate.Data.UseFiltering(typeof(PhoneFilterInputType))]
[HotChocolate.Data.UseSorting]
public IQueryable<Phone> GetPhones([ScopedService] TenantFileContext tenantContext) => tenantContext.Phones.AsQueryable().Include(p => p.Tenants);

[UseTenantFileContext]
public async Task<List<Phone>> GetTenantlessPhonesAsync(
[ScopedService] TenantFileContext tenantContext) =>
await tenantContext.Phones
.AsQueryable()
.Where(p => p.Tenants.Count == 0)//default for int is 0 so if Tenants==null, it should still return 0. Evaluating null Tenant list throws implementation exception
.ToListAsync();
public async Task<Phone> GetPhoneAsync([ID(nameof(Phone))] int id,
PhoneByIdDataLoader dataLoader,
CancellationToken cancellationToken) => await dataLoader.LoadAsync(id, cancellationToken);
public async Task<IEnumerable<Phone>> GetPhonesAsync([ID(nameof(Phone))] int[] ids,
PhoneByIdDataLoader dataLoader,
CancellationToken cancellationToken) => await dataLoader.LoadAsync(ids, cancellationToken);

[UseTenantFileContext]
public async Task<List<Phone>> GetTenantlessPhonesAsync(
[ScopedService] TenantFileContext tenantContext) =>
await tenantContext.Phones
.AsQueryable()
.Where(p => p.Tenants.Count == 0)//default for int is 0 so if Tenants==null, it should still return 0. Evaluating null Tenant list throws implementation exception
.ToListAsync();


}

}
}
Loading

0 comments on commit 53b2d4c

Please sign in to comment.