Skip to content

Commit

Permalink
Parking ads are now supported.
Browse files Browse the repository at this point in the history
  • Loading branch information
n.bitounis committed May 1, 2019
1 parent ac745ef commit 7e9a359
Show file tree
Hide file tree
Showing 22 changed files with 406 additions and 54 deletions.
18 changes: 5 additions & 13 deletions Projects/xe.bit.property.core/Ads/BaseAd.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ namespace xe.bit.property.core.Ads
public class BaseAd
{
public virtual ItemType AdType { get; protected set; }
public virtual string RefId { get; set; }
public virtual string OwnerId { get; set; }
public virtual string MajorPhone { get; set; }
public virtual string DepartmentOnCategory { get; set; } = "Real Estate";
Expand All @@ -26,8 +25,6 @@ public class BaseAd
public virtual bool? IsOffer { get; set; }
public virtual bool? IsPromo { get; set; }
public virtual bool? IsNegotiable { get; set; }
public virtual Geo Geo { get; } = new Geo();
public virtual List<Asset> Assets { get; } = new List<Asset>();
public virtual IAddSerializer Serializer { get; }

public void AddOtherPhone(string otherPhone)
Expand All @@ -40,16 +37,6 @@ public void ClearOtherPhones()
OtherPhones.Clear();
}

public void AddAsset(Asset asset)
{
Assets.Add(asset);
}

public void ClearAssets()
{
Assets.Clear();
}

public virtual ValidationResult Validate()
{
return ValidationChain.ChainValidators(this);
Expand All @@ -59,5 +46,10 @@ public virtual string Serialize(bool skipAssets)
{
throw new NotImplementedException();
}

public virtual string Serialize()
{
throw new NotImplementedException();
}
}
}
21 changes: 21 additions & 0 deletions Projects/xe.bit.property.core/Ads/BaseResidenceAd.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
using System.Collections.Generic;

namespace xe.bit.property.core.Ads
{
public class BaseResidenceAd : BaseAd
{
public virtual string RefId { get; set; }
public virtual Geo Geo { get; } = new Geo();
public virtual List<Asset> Assets { get; } = new List<Asset>();

public void AddAsset(Asset asset)
{
Assets.Add(asset);
}

public void ClearAssets()
{
Assets.Clear();
}
}
}
36 changes: 36 additions & 0 deletions Projects/xe.bit.property.core/Ads/ParkingAd.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
using FluentValidation.Results;
using xe.bit.property.core.Lookups;
using xe.bit.property.core.Serializers;
using xe.bit.property.core.Serializers.Interfaces;
using xe.bit.property.core.Validators;

namespace xe.bit.property.core.Ads
{
public class ParkingAd : BaseAd
{
public override ItemType AdType { get; protected set; } = ItemType.re_parking;
public virtual decimal? Area { get; set; }
public virtual Usage? Usage { get; set; }
public virtual int? Slots { get; set; }
public virtual ParkingLevel? Level { get; set; }
public virtual bool? HasElectricDoor { get; set; }
public virtual bool? HasAlarm { get; set; }
public virtual bool? IsAgentAccepted { get; set; }
public override IAddSerializer Serializer { get; } = new XmlParkingAdSerializer();

public override ValidationResult Validate()
{
return new ParkingAdValidator().Validate(this);
}

public override string Serialize()
{
return Serializer.Serialize(this);
}

public override string Serialize(bool skipAssets)
{
return Serializer.Serialize(this);
}
}
}
2 changes: 1 addition & 1 deletion Projects/xe.bit.property.core/Ads/ResidenceAd.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

namespace xe.bit.property.core.Ads
{
public class ResidenceAd : BaseAd
public class ResidenceAd : BaseResidenceAd
{
public override ItemType AdType { get; protected set; } = Lookups.ItemType.re_residence;
public virtual ResidenceItemType ItemType { get; set; }
Expand Down
3 changes: 3 additions & 0 deletions Projects/xe.bit.property.core/Errors/Messages.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,5 +33,8 @@ public static class Messages
public const string AuthTokenCannotBeNullOrEmpty = "XE auth token cannot be null or empty";
public const string SchemaVersionCannotBeNullOrEmpty = "Schema version cannot be null or empty";
public const string PackageIdCannotBeNullOrEmpty = "Package ID cannot be null or empty";
public const string ItemTypeMustBeParking = "Item type must be set to re_parking";
public const string ParkingAreaMustHaveValue = "Parking area must have a value";
public const string ParkingLevelMustHaveValue = "Parking level must have a value";
}
}
26 changes: 16 additions & 10 deletions Projects/xe.bit.property.core/Request/Package.cs
Original file line number Diff line number Diff line change
Expand Up @@ -87,19 +87,25 @@ public void Pack(string directoryWithImages, string packedFileName)
if (SkipAssets.HasValue && !SkipAssets.Value)
{
foreach (var ad in Ads)
foreach (var asset in ad.Assets.Where(x => x.Type == AssetType.IMAGE))
{
var name = string.IsNullOrEmpty(asset.LocalFileName) ? Path.Combine(directoryWithImages, asset.Uri) : asset.LocalFileName;

try
{
archive.AddEntry(asset.Uri, name);
}
catch (FileNotFoundException)
if (ad is ResidenceAd residenceAd)
{
throw new InvalidOperationException($"Asset located at [{name}] was not found");
foreach (var asset in residenceAd.Assets.Where(x => x.Type == AssetType.IMAGE))
{
var name = string.IsNullOrEmpty(asset.LocalFileName)
? Path.Combine(directoryWithImages, asset.Uri)
: asset.LocalFileName;

try
{
archive.AddEntry(asset.Uri, name);
}
catch (FileNotFoundException)
{
throw new InvalidOperationException($"Asset located at [{name}] was not found");
}
}
}

}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ namespace xe.bit.property.core.Serializers.Interfaces
{
public interface IAddSerializer
{
string Serialize(BaseAd ad);
string Serialize(BaseAd ad, bool skipAssets);
}
}
33 changes: 25 additions & 8 deletions Projects/xe.bit.property.core/Serializers/XmlBaseSerializer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,21 +10,33 @@ namespace xe.bit.property.core.Serializers
{
public class XmlBaseSerializer : IAddSerializer
{
public virtual string Serialize(BaseAd ad)
{
throw new NotImplementedException();
}

public virtual string Serialize(BaseAd ad, bool skipAssets)
{
throw new NotImplementedException();
}

public virtual void SerializeGeo(XmlWriter writer, BaseAd ad)
{
if (!(ad is BaseResidenceAd residenceAd))
{
return;
}

var geo = residenceAd.Geo;

writer
.Field("Geo.areaId", ad.Geo.AreaId)
.Field("Geo.subAreaDescription", ad.Geo.SubAreaDescription)
.Field("Geo.streetName", ad.Geo.StreetName)
.Field("Geo.streetNumber", ad.Geo.StreetNumber)
.Field("Geo.longitude", ad.Geo.Longitude, false)
.Field("Geo.latitude", ad.Geo.Latitude, false)
.Field("Geo.postcode", ad.Geo.PostCode);
.Field("Geo.areaId", geo.AreaId)
.Field("Geo.subAreaDescription", geo.SubAreaDescription)
.Field("Geo.streetName", geo.StreetName)
.Field("Geo.streetNumber", geo.StreetNumber)
.Field("Geo.longitude", geo.Longitude, false)
.Field("Geo.latitude", geo.Latitude, false)
.Field("Geo.postcode", geo.PostCode);
}

public virtual void SerializeFinancial(XmlWriter writer, BaseAd ad)
Expand All @@ -41,7 +53,12 @@ public virtual void SerializeFinancial(XmlWriter writer, BaseAd ad)

public virtual void SerializeAssets(XmlWriter writer, BaseAd ad)
{
foreach (var asset in ad.Assets)
if (!(ad is BaseResidenceAd residenceAd))
{
return;
}

foreach (var asset in residenceAd.Assets)
{
writer
.Element("Asset")
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Xml;
using xe.bit.property.core.Ads;
using xe.bit.property.core.Utility.Xml;

namespace xe.bit.property.core.Serializers
{
public class XmlParkingAdSerializer : XmlBaseSerializer
{
public override string Serialize(BaseAd ad)
{
using (var ms = new MemoryStream())
using (var writer = XmlWriter.Create(ms, new XmlWriterSettings { ConformanceLevel = ConformanceLevel.Fragment, OmitXmlDeclaration = true, Encoding = new UTF8Encoding(false) }))
{
SerializeParking((ParkingAd)ad, writer);

writer.CloseElement();

writer.Flush();
writer.Close();
return new UTF8Encoding(false).GetString(ms.ToArray());
}
}

public override string Serialize(BaseAd ad, bool skipAssets)
{
return Serialize(ad);
}

private void SerializeParking(ParkingAd ad, XmlWriter writer)
{
writer
.ElementWithAttributes("Item", new Dictionary<string, string> { { "type", ad.AdType.ToString() }})
.NewLine()
.Field("Item.area", ad.Area)
.Field("Item.usage", ad.Usage)
.Field("Item.slots", ad.Slots)
.Field("Item.level", ad.Level)
.Field("Item.hasElectricDoor", ad.HasElectricDoor)
.Field("Item.hasAlarm", ad.HasAlarm)
.Field("Item.isAgentAccepted", ad.IsAgentAccepted);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ private void SerializeResidence(BaseAd ad, XmlWriter writer)

writer
.ElementWithAttributes("Item",
new Dictionary<string, string> { { "type", ad.AdType.ToString() }, { "refId", ad.RefId } })
new Dictionary<string, string> { { "type", ad.AdType.ToString() }, { "refId", r.RefId } })
.NewLine()
.Element("Item.ownerId", ad.OwnerId)
.Element("Item.majorPhone", ad.MajorPhone)
Expand Down
16 changes: 11 additions & 5 deletions Projects/xe.bit.property.core/Utility/ValidationChain.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,18 @@ public static ValidationResult ChainValidators(BaseAd ad, ValidationResult resul
public static ValidationResult ChainValidators(BaseAd ad)
{
var baseResults = new BaseAdValidator().Validate(ad);
var geoResults = new GeoValidator().Validate(ad.Geo);
var assetsValidator = new AssetsValidator().Validate(ad.Assets);

return new ValidationResult(baseResults.Errors
.Union(geoResults.Errors)
.Union(assetsValidator.Errors));
if (ad is ResidenceAd residenceAd)
{
var geoResults = new GeoValidator().Validate(residenceAd.Geo);
var assetsValidator = new AssetsValidator().Validate(residenceAd.Assets);

return new ValidationResult(baseResults.Errors
.Union(geoResults.Errors)
.Union(assetsValidator.Errors));
}

return baseResults;
}

public static ValidationResult Chain(ValidationResult result1, ValidationResult result2)
Expand Down
5 changes: 0 additions & 5 deletions Projects/xe.bit.property.core/Validators/BaseAdValidator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,6 @@ public class BaseAdValidator : AbstractValidator<BaseAd>
{
public BaseAdValidator()
{
RuleFor(ad => ad.RefId)
.Cascade(CascadeMode.StopOnFirstFailure)
.NotNull().WithMessage(Messages.RefIdCannotBeNullOrEmpty)
.NotEmpty().WithMessage(Messages.RefIdCannotBeNullOrEmpty);

RuleFor(ad => ad.OwnerId)
.Cascade(CascadeMode.StopOnFirstFailure)
.NotNull().WithMessage(Messages.OwnerIdCannotBeNullOrEmpty)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
using FluentValidation;
using xe.bit.property.core.Ads;
using xe.bit.property.core.Errors;

namespace xe.bit.property.core.Validators
{
public class BaseResidenceAdValidator : AbstractValidator<BaseResidenceAd>
{
public BaseResidenceAdValidator()
{
RuleFor(ad => ad.RefId)
.Cascade(CascadeMode.StopOnFirstFailure)
.NotNull().WithMessage(Messages.RefIdCannotBeNullOrEmpty)
.NotEmpty().WithMessage(Messages.RefIdCannotBeNullOrEmpty);

RuleFor(ad => ad.OwnerId)
.Cascade(CascadeMode.StopOnFirstFailure)
.NotNull().WithMessage(Messages.OwnerIdCannotBeNullOrEmpty)
.NotEmpty().WithMessage(Messages.OwnerIdCannotBeNullOrEmpty);

RuleFor(ad => ad.MajorPhone)
.Cascade(CascadeMode.StopOnFirstFailure)
.NotNull().WithMessage(Messages.MajorPhoneCannotBeNullOrEmpty)
.NotEmpty().WithMessage(Messages.MajorPhoneCannotBeNullOrEmpty);
}
}
}
25 changes: 25 additions & 0 deletions Projects/xe.bit.property.core/Validators/ParkingAdValidator.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
using FluentValidation;
using xe.bit.property.core.Ads;
using xe.bit.property.core.Errors;
using xe.bit.property.core.Lookups;

namespace xe.bit.property.core.Validators
{
public class ParkingAdValidator : AbstractValidator<ParkingAd>
{
public ParkingAdValidator()
{
RuleFor(x => x.AdType)
.Equal(ItemType.re_parking)
.WithMessage(Messages.ItemTypeMustBeParking);

RuleFor(x => x.Area.HasValue)
.Equal(true)
.WithMessage(Messages.ParkingAreaMustHaveValue);

RuleFor(x => x.Level.HasValue)
.Equal(true)
.WithMessage(Messages.ParkingLevelMustHaveValue);
}
}
}
4 changes: 2 additions & 2 deletions Projects/xe.bit.property.core/xe.bit.property.core.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,15 @@
<Authors>Xyrisi Eukairia</Authors>
<PackageProjectUrl>https://developers.xe.gr/apis/bit/property/1.4.1/</PackageProjectUrl>
<Description>This is a .Net core client that creates property packages for the xe.gr bit API.</Description>
<Version>0.5.2</Version>
<Version>0.5.3</Version>
</PropertyGroup>

<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
<WarningLevel>1</WarningLevel>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="FluentValidation" Version="8.2.3" />
<PackageReference Include="FluentValidation" Version="8.3.0" />
<PackageReference Include="RestSharp" Version="106.6.9" />
<PackageReference Include="SharpCompress" Version="0.23.0" />
</ItemGroup>
Expand Down
Loading

0 comments on commit 7e9a359

Please sign in to comment.