using Microsoft.EntityFrameworkCore; using Newtonsoft.Json; using System; using System.IO; using System.Collections.Generic; using System.Linq; using UnivateProperties_API.Containers.Property; using UnivateProperties_API.Containers.Timeshare; using UnivateProperties_API.Context; using UnivateProperties_API.Model.Logging; using UnivateProperties_API.Model.Properties; using System.Drawing; namespace UnivateProperties_API.Repository.Properties { public class PropertyRepository : IPropertyRepository { private readonly DataContext dBContext; public PropertyRepository(DataContext _dBContext) { dBContext = _dBContext; } public List Get(Func where) { return dBContext.Properties .Include("PropertyType") .Include("Province") .Include("City") .Include("Suburb") .Where(where).ToList(); } public List GetAll() { var properties = dBContext.Properties.ToList(); return properties; } public Property GetDetailed(Func first) { var property = dBContext.Properties.Include("Status").FirstOrDefault(first); if (property != null) { GetDetail(ref property); } return property; } public List GetDetailedAll() { var properties = dBContext.Properties.ToList(); return properties; } private void GetDetail(ref Property property) { int propID = property.Id; var propertyType = dBContext.PropertyTypes.Find(property.PropertyTypeId); property.Province = dBContext.Provinces.Find(property.ProvinceId); property.City = dBContext.Cities.Find(property.CityId); property.Suburb = dBContext.Suburbs.Find(property.SuburbId); property.DisplayData = new List(); var groups = (from g in dBContext.UserDefinedGroups where g.UsageType == propertyType.UsageType || g.UsageType == PropertyUsageType.Both orderby g.Rank select g).ToList(); foreach (UserDefinedGroup uGroup in groups) { var groupFields = (from f in dBContext.PropertyUserFields join uf in dBContext.UserDefinedFields on f.UserDefinedFieldId equals uf.Id join g in dBContext.UserDefinedGroups on uf.GroupId equals g.Id where f.PropertyId == propID && g.Id == uGroup.Id orderby g.Rank, uf.Rank select new { uf.FieldName, f.Value, f.Description }).ToList(); if (groupFields.Count > 0) { PropertyDetailGroup detailGroup = new PropertyDetailGroup() { GroupName = uGroup.Description, Values = new List() }; if (uGroup.Description == "Property Overview") { detailGroup.Values.Add(new PropertyDetail() { Name = "Property Type", Value = property.PropertyType.Description }); } foreach (var val in groupFields) { var irem = new PropertyDetail() { Name = val.FieldName, Description = val.Description }; detailGroup.Values.Add(irem); if ((val.FieldName == "Erf Size" || val.FieldName == "Floor Size") && val.Value.EndsWith("2")) { irem.Value = val.Value.Substring(0, val.Value.Length - 1) + "" + val.Value.Last() + ""; } else irem.Value = val.Value; } property.DisplayData.Add(detailGroup); } } } public void Insert(Property item) { PropertyType pt = dBContext.PropertyTypes.Find(item.PropertyTypeId); if (pt != null) { if (pt.UsageType == PropertyUsageType.Residential) { string type = dBContext.PropertyTypes.Find(item.PropertyTypeId).Description; if (item.PropertyUserFields.Count > 0) { string shortDesc = "{0} {1} {2}"; UserDefinedField bedrooms = dBContext.UserDefinedFields.Where(u => u.FieldName == "Bedrooms").FirstOrDefault(); var udValue = item.PropertyUserFields.Where(u => u.UserDefinedFieldId == bedrooms.Id).FirstOrDefault(); if (udValue != null) item.ShortDescription = string.Format(shortDesc, udValue.Value, "Bedroom", pt.Description).Trim(); else item.ShortDescription = string.Format(shortDesc, "", "", pt.Description).Trim(); } else { item.ShortDescription = type; } } else { item.ShortDescription = pt.Description; } } var images = item.PropertyImages; var fields = item.PropertyUserFields; item.PropertyImages = null; item.PropertyUserFields = null; dBContext.Properties.Add(item); Save(); if (images != null) { var lastID = (from p in dBContext.PropertyImages orderby p.Id descending select p.Id).FirstOrDefault(); bool saveFiles = false; var loc = dBContext.Location.FirstOrDefault().PropertyImageLocation; if (!string.IsNullOrEmpty(loc)) { saveFiles = true; loc += string.Format("\\{0}", item.Id); if (Directory.Exists(loc)) { Directory.CreateDirectory(loc); } } foreach (PropertyImage image in images) { lastID++; image.Id = lastID; image.PropertyId = item.Id; if (saveFiles) { string path = ImageFormatter.Base64ToImage(image.Image, loc, lastID.ToString()); image.Image = path; } dBContext.PropertyImages.Add(image); Save(); } } if (fields != null) { var lastID = (from p in dBContext.PropertyUserFields orderby p.Id descending select p.Id).FirstOrDefault(); foreach (PropertyUserField field in fields) { lastID++; field.Id = lastID; field.PropertyId = item.Id; dBContext.PropertyUserFields.Add(field); Save(); } } } public void Insert(IEnumerable items) { foreach (var item in items) { dBContext.Properties.Add(item); } Save(); } public void Remove(Property item) { dBContext.Properties.Remove(item); Save(); } public void Remove(IEnumerable items) { foreach (var item in items) { dBContext.Properties.Remove(item); } Save(); } public void RemoveAtId(int item) { var property = Get(x => x.Id == item).FirstOrDefault(); if (property != null) { dBContext.Properties.Remove(property); Save(); } } public void Save() { dBContext.SaveChanges(); } public void Update(Property item) { dBContext.Entry(item).State = EntityState.Modified; Save(); } public List GetDisplay() { List props = GetAll(); return GetDisplayDetails(props); } public List GetDisplay(Func where) { List props; if (where != null) props = Get(where); else props = GetAll(); return GetDisplayDetails(props); } public List GetDisplay(PropertySearch search) { SearchObject obj = new SearchObject() { UserName = search.UserName, Type = "Property" }; if (!string.IsNullOrEmpty(search.Keyword) && search.Keyword.ToUpper() != "ALL" && search.Keyword.ToUpper() != "UNDEFINED") { string keyword = search.Keyword.ToLower(); List props = (from p in dBContext.Properties join pr in dBContext.Provinces on p.ProvinceId equals pr.Id join c in dBContext.Cities on p.CityId equals c.Id join s in dBContext.Suburbs on p.SuburbId equals s.Id join pt in dBContext.PropertyTypes on p.PropertyTypeId equals pt.Id where EF.Functions.Like(p.PropertyName.ToLower(), $"%{keyword}%") || EF.Functions.Like(pr.Description.ToLower(), $"%{keyword}%") || EF.Functions.Like(c.Description.ToLower(), $"%{keyword}%") || EF.Functions.Like(s.Description.ToLower(), $"%{keyword}%") || EF.Functions.Like(pt.Description.ToLower(), $"%{keyword}%") select p).ToList(); obj.Property = "Keyword"; obj.Value = search.Keyword; SaveLog(obj); return GetDisplayDetails(props); } else { List props; PropertyUsageType uType = PropertyUsageType.Both; if (!string.IsNullOrEmpty(search.PropertyUsageType) && search.PropertyUsageType != "undefined" && search.PropertyUsageType.ToUpper() != "ALL") { if (search.PropertyUsageType.ToUpper() == "COMMERCIAL") uType = PropertyUsageType.Commercial; else uType = PropertyUsageType.Residential; } props = (from p in dBContext.Properties join pt in dBContext.PropertyTypes on p.PropertyTypeId equals pt.Id where pt.UsageType == uType select p).ToList(); obj.Property = "PropertyUsageType"; obj.Value = search.PropertyUsageType; SaveLog(obj); if (!string.IsNullOrEmpty(search.SalesType) && search.SalesType != "undefined" && search.SalesType.ToUpper() != "ALL") { if (search.SalesType.ToUpper() == "SALE") props = props.Where(p => p.IsSale).ToList(); else props = props.Where(p => !p.IsSale).ToList(); obj.Property = "SalesType"; obj.Value = search.SalesType; SaveLog(obj); } if (!string.IsNullOrEmpty(search.Province) && search.Province != "undefined" && search.Province.ToUpper() != "ALL") { props = (from p in props join pp in dBContext.Provinces on p.ProvinceId equals pp.Id where pp.Description.ToUpper() == search.Province.ToUpper() select p).ToList(); obj.Property = "Province"; obj.Value = search.Province; SaveLog(obj); } if (!string.IsNullOrEmpty(search.City) && search.City != "undefined" && search.City.ToUpper() != "ALL") { props = (from p in props join c in dBContext.Cities on p.CityId equals c.Id where c.Description.ToUpper() == search.City.ToUpper() select p).ToList(); obj.Property = "City"; obj.Value = search.City; SaveLog(obj); } if (!string.IsNullOrEmpty(search.Suburb) && search.Suburb != "undefined" && search.Suburb.ToUpper() != "ALL") { props = (from p in props join s in dBContext.Suburbs on p.SuburbId equals s.Id where s.Description.ToUpper() == search.Suburb.ToUpper() select p).ToList(); obj.Property = "Suburb"; obj.Value = search.Suburb; SaveLog(obj); } if (!string.IsNullOrEmpty(search.PropertyType) && search.PropertyType != "Undefined" && search.PropertyType.ToUpper() != "ALL") { var pType = dBContext.PropertyTypes.Where(t => t.Description == search.PropertyType).FirstOrDefault(); if (pType != null) { props = props.Where(p => p.PropertyTypeId == pType.Id).ToList(); } obj.Property = "PropertyType"; obj.Value = search.PropertyType; SaveLog(obj); } if (search.MinPrice > 0) { props = props.Where(p => p.Price >= search.MinPrice).ToList(); obj.Property = "MinPrice"; obj.Value = search.MinPrice.ToString(); SaveLog(obj); } if (search.MaxPrice > 0) { props = props.Where(p => p.Price <= search.MaxPrice).ToList(); obj.Property = "MaxPrice"; obj.Value = search.MaxPrice.ToString(); SaveLog(obj); } return GetDisplayDetails(props); } } private void SaveLog(SearchObject item) { var searchLog = new SearchLog { Type = item.Type, Search = JsonConvert.SerializeObject(item) }; dBContext.SearchLogs.Add(searchLog); Save(); } private List GetDisplayDetails(List props) { var properties = new List(); foreach (var item in props) { PropertyDisplay display = new PropertyDisplay { Id = item.Id, ShortDescription = item.ShortDescription, IsSale = item.IsSale, DisplayPrice = string.Format("R {0}", item.Price.ToString("N0")), DisplayImage = (from i in dBContext.PropertyImages where i.PropertyId == item.Id && i.IsDefault select i.Image).FirstOrDefault(), Area = (from u in dBContext.PropertyUserFields join f in dBContext.UserDefinedFields on u.UserDefinedFieldId equals f.Id where u.PropertyId == item.Id && f.FieldName == "Floor Size" select u.Value).FirstOrDefault(), Beds = (from u in dBContext.PropertyUserFields join f in dBContext.UserDefinedFields on u.UserDefinedFieldId equals f.Id where u.PropertyId == item.Id && f.FieldName == "Bedrooms" select u.Value).FirstOrDefault(), Baths = (from u in dBContext.PropertyUserFields join f in dBContext.UserDefinedFields on u.UserDefinedFieldId equals f.Id where u.PropertyId == item.Id && f.FieldName == "Bathrooms" select u.Value).FirstOrDefault(), Garages = (from u in dBContext.PropertyUserFields join f in dBContext.UserDefinedFields on u.UserDefinedFieldId equals f.Id where u.PropertyId == item.Id && f.FieldName == "Garages" select u.Value).FirstOrDefault(), Province = (from p in dBContext.Provinces where p.Id == item.ProvinceId select p.Description).FirstOrDefault(), City = (from c in dBContext.Cities where c.Id == item.CityId select c.Description).FirstOrDefault(), Suburb = (from s in dBContext.Suburbs where s.Id == item.SuburbId select s.Description).FirstOrDefault(), Price = item.Price, DateCreated = item.Created, PropertyUsageType = (from p in dBContext.PropertyTypes where p.Id == item.PropertyTypeId select p.UsageType.ToString()).FirstOrDefault() }; if (!display.DisplayImage.StartsWith("data:image")) { display.DisplayImage = ImageFormatter.ImageToBase64(display.DisplayImage); } if (!string.IsNullOrEmpty(display.Area) && display.Area.EndsWith("2")) { display.Area = display.Area.Substring(0, display.Area.Length - 1) + "" + display.Area.Last() + ""; } properties.Add(display); } return properties; } public List GetPropertyTypes(Func where) { List list; if (where != null) list = dBContext.PropertyTypes.Where(where).ToList(); else list = dBContext.PropertyTypes.ToList(); return list; } public List GetLatestDisplay() { List props = GetAll().OrderBy(x => x.Created).Take(3).ToList(); return GetDisplayDetails(props); } public List GetPropertyList(string Type, int By) { var individual = dBContext.Individuals.Where(x => x.UserId == By).FirstOrDefault(); var agent = dBContext.Agents.Where(x => x.UserId == By).FirstOrDefault(); List properties = new List(); if (Type.ToUpper() == "MY") { if (individual != null) properties = Get(x => x.OwnerId == individual.Id); if (agent != null) properties = Get(x => x.AgentId == agent.Id); } else { if (individual != null) properties = Get(x => x.OwnerId == individual.Id); if (agent != null) properties = Get(x => x.AgencyId == agent.AgencyId); } List list = new List(); foreach (Property p in properties) { var prop = new PropertyList() { Id = p.Id, Name = string.IsNullOrEmpty(p.PropertyName) ? p.ShortDescription : p.PropertyName, Price = string.Format("R {0:n}", p.Price), Publish = p.Published.ToString(), Type = dBContext.PropertyTypes.Find(p.PropertyTypeId)?.Description }; prop.Size = (from u in dBContext.PropertyUserFields join f in dBContext.UserDefinedFields on u.UserDefinedFieldId equals f.Id where u.PropertyId == p.Id && f.FieldName == "Floor Size" select u.Value).FirstOrDefault(); if (!string.IsNullOrEmpty(prop.Size) && prop.Size.EndsWith("2")) { prop.Size = prop.Size.Substring(0, prop.Size.Length - 1) + "" + prop.Size.Last() + ""; } prop.UsageType = (dBContext.PropertyTypes.Find(p.PropertyTypeId).UsageType == PropertyUsageType.Residential ? "Residential" : "Commercial"); prop.SaleType = p.IsSale ? "Sale" : "Rental"; list.Add(prop); } return list; } public int NewId() { // Not sure if properties need it return 0; } } }