using Microsoft.AspNetCore.Mvc; using Sarand.Net.Standard.Base.App; using Sarand.Net.Standard.Base.Bus; using Sarand.Net.Standard.Base.Core; using Sarand.Net.Standard.Base.Dbas; using Sarand.Net.Standard.Base.Utils; using Saxonite.Net.Core.Web.Admin.Models; using Saxonite.Net.Core.Web.Admin.Procs; using Saxonite.Net.Standard.Base.App; using Saxonite.Net.Standard.Base.Bus; using Saxonite.Net.Standard.Base.Mgr; using System; using System.Collections.Generic; using System.Collections.Specialized; using System.Linq; using System.Threading.Tasks; namespace Saxonite.Net.Core.Web.Admin.Controllers { //======================================================================= // Controller: Organisation - Ajax //======================================================================= partial class OrganisationController { //------------------------------------------------------------------- // Organisation data. private class OrganisationListData : AjaxResponse_Data.ItemData_Base { public String Name { get; set; } public String TypeCode { get; set; } public String TypeDesc { get; set; } public String CategoryCode { get; set; } public String CategoryDesc { get; set; } public long MemberCount { get; set; } // Sport. public String SportId { get; set; } public String SportName { get; set; } // Primary Region. public class RegionData { public String Id { get; set; } public String Name { get; set; } public bool? Country { get; set; } = null; } public RegionData RegionPrimary { get; } = new RegionData(); // Address. public String AddressSummary { get; set; } // Logo. public String LogoImageUrl { get; set; } } private class OrganisationItemData : OrganisationListData { public String About { get; set; } public String Facilities { get; set; } public List ContactMethods { get; set; } public AjaxResponse_Data.AddressData Address { get; set; } } private void PopulateOrganisationResponseListData(SaxOrganisation organisation, OrganisationListData data) { data.Id = SysId.ToString(organisation.Id); data.Name = organisation.Name; data.TypeCode = OrganisationTypeCodes.GetCodeForType(organisation.OrganisationType); data.TypeDesc = OrganisationTypeCodes.GetDescForType(organisation.OrganisationType); data.CategoryCode = OrganisationCategoryCodes.GetCodeForType(organisation.OrganisationCategory); data.CategoryDesc = OrganisationCategoryCodes.GetDescForType(organisation.OrganisationCategory); data.MemberCount = AccountMgr.GetOrganisationMemberCount(organisation.Id); // Sport. data.SportId = SysId.ToString(organisation.SportIdPrimary, null); using (SaxSport sport = ReferenceMgr.GetSportById(organisation.SportIdPrimary)) data.SportName = sport?.Name ?? null; // Primary region. data.RegionPrimary.Id = SysId.ToString(organisation.RegionIdPrimary, null); SaxRegion.Data region = Internals.GetRegion(organisation.RegionIdPrimary); if (region != null) { data.RegionPrimary.Name = region.Name; data.RegionPrimary.Country = region.RegionType == Sax.RegionType.Country ? true : (bool?)null; } // Common properties. data.StatusCode = organisation.StatusCode; data.StatusDesc = organisation.StatusDesc; // Organisation Logo image url. if (ItemDataMgr.ItemHasActiveImage(organisation.GetItemId(), Sax.ImageType.OrganisationLogo)) data.LogoImageUrl = GetOrganisationLogoLink(organisation.Id, false); } private void PopulateOrganisationResponseItemData(SaxOrganisation organisation, SaxItemAddress address, OrganisationItemData data) { PopulateOrganisationResponseListData(organisation, data); data.About = StringUtil.OnEmpty(organisation.About, null); data.Facilities = StringUtil.OnEmpty(organisation.Facilities, null); // Contact methods. SaxContactData contactData = new SaxContactData(organisation.ContactData); foreach (Sax.ContactMethod method in contactData.Methods) { if (data.ContactMethods == null) data.ContactMethods = new List(); data.ContactMethods.Add(new AjaxResponse_Data.ContactMethodData() { Method = method.ToString(), MethodCaption = Localiser.GetContactMethodCaption(method), Value = contactData.GetContactMethodValue(method) }); } // Address. if (address != null && !address.IsStatusDeleted) { data.Address = new AjaxResponse_Data.AddressData(); data.Address.Id = address.Id.ToString(null); data.Address.Line1 = StringUtil.OnEmpty(address.Line1, null); data.Address.Line2 = StringUtil.OnEmpty(address.Line2, null); data.Address.Line3 = StringUtil.OnEmpty(address.Line3, null); data.Address.Town = address.Town; data.Address.RegionIdProvince = SysId.ToString(address.RegionIdProvince, null); data.Address.RegionNameProvince = StringUtil.OnEmpty(address.Province, null); data.Address.RegionIdCountry = SysId.ToString(address.RegionIdCountry, null); data.Address.RegionNameCountry = StringUtil.OnEmpty(address.Country, null); data.Address.PostalCode = StringUtil.OnEmpty(address.PostalCode, null); } // Common properties. data.Notes = organisation.Notes; } //------------------------------------------------------------------- // Get Organisation List ajax request. //------------------------------------------------------------------- private class AjaxResponse_OrganisationList : AjaxResponse_Data { // Construction. public AjaxResponse_OrganisationList(SaxModel_Admin model) : base(model) { } // Organisation list. public List Organisations { get; } = new List(); // Reference data. public List ContactMethods { get; } = new List(); public List Statuses { get; } = new List(); public String DefaultStatusCode { get; set; } public List UploadContentTypes { get; set; } } //------------------------------------------------------------------- [HttpPost] [Route("Organisation/Ajax/GetList")] public IActionResult Ajax_GetList(Model_Organisation model) { String fn = GetType().Name + ".Ajax_GetList"; String messageTitle = Localiser["caption.organisations"]; AjaxResponse_OrganisationList responseData = new AjaxResponse_OrganisationList(model); // Validate session. if (!ValidUserSession) return GetAjaxResult_InvalidSession(responseData); // Reference data - contact methods. List validContactMethods = SaxOrganisation.ValidContactMethods; foreach (TypeCodeDesc contactMethod in ContactMethodCodes.OrderBy(item => item.Desc)) { // Skip methods that aren't associated with Organisations. if (!validContactMethods.Contains((Sax.ContactMethod)contactMethod.Type)) continue; responseData.ContactMethods.Add(new AjaxResponse_Data.ItemCodeDesc() { Code = contactMethod.Code, Desc = Localiser.GetContactMethodCaption((Sax.ContactMethod)contactMethod.Type) }); } // Reference data - statuses. foreach (SaStatus status in SaxOrganisation.ValidStatuses.FindAll(item => item != SaStatus.Deleted)) responseData.Statuses.Add(SacsSystem.GetStatusCode(status), Localiser.GetStatusCaption(status)); responseData.DefaultStatusCode = SacsSystem.GetStatusCode(SaxOrganisation.DefaultStatus); // Reference data - Image content types. responseData.UploadContentTypes = SaxOrganisationUploader.ValidContentTypes; // Store filter values. SysId filterSportId = SysId.ToSysId(model.Filter.OrganisationSportId); SessionData_Admin.Filter.SportId = SysId.IsValid(filterSportId) ? filterSportId : null; SysId filterRegionId = SysId.ToSysId(model.Filter.OrganisationRegionId); SessionData_Admin.Filter.RegionId = SysId.IsValid(filterRegionId) ? filterRegionId : null; // Item filter. SaxOrganisation.Params prmOrganisation = GetOrganisationListFilter(model, AccountMgr); model.Paging.ItemTotal = (ulong)AccountMgr.GetOrganisationCount(prmOrganisation); model.PopulatePagingTo(prmOrganisation.ResultsPaging); // Item columns. ColumnDfn colId = AccountMgr.GetOrganisationColumnDfn(SaxOrganisation.Column.Id); ColumnDfn colName = AccountMgr.GetOrganisationColumnDfn(SaxOrganisation.Column.Name); ColumnDfn colOrganisationType = AccountMgr.GetOrganisationColumnDfn(SaxOrganisation.Column.OrganisationType); ColumnDfn colOrganisationCategory = AccountMgr.GetOrganisationColumnDfn(SaxOrganisation.Column.OrganisationCategory); ColumnDfn colUserCount = AccountMgr.GetOrganisationColumnDfn(SaxOrganisation.Column.User_Count); ColumnDfn colMemberCount = AccountMgr.GetOrganisationColumnDfn(SaxOrganisation.Column.Member_Count); ColumnDfn colLogoCount = AccountMgr.GetOrganisationColumnDfn(SaxOrganisation.Column.LogoImage_Count); ColumnDfn colSportId = AccountMgr.GetOrganisationColumnDfn(SaxOrganisation.Column.SportId); ColumnDfn colSportName = AccountMgr.GetOrganisationColumnDfn(SaxOrganisation.Column.Sport_Name); ColumnDfn colRegionId = AccountMgr.GetOrganisationColumnDfn(SaxOrganisation.Column.RegionId); ColumnDfn colRegionName = AccountMgr.GetOrganisationColumnDfn(SaxOrganisation.Column.Region_Name); ColumnDfn colStatus = AccountMgr.GetOrganisationColumnDfn(SaxOrganisation.Column.Status); List columns = new List() { colId, colName, colOrganisationType, colOrganisationCategory, colUserCount, colMemberCount, colLogoCount, colSportId, colSportName, colRegionId, colRegionName, colStatus }; // Query items. using (DbResultSet resultSet = AccountMgr.ExecuteOrganisationQuery(columns, prmOrganisation)) { while (resultSet != null && resultSet.HasRows && resultSet.NextRecord()) { NamedValue.Map values = resultSet.GetRecordValues(); SysId organisationId = new SysId(values.GetLong(colId.DataName)); OrganisationListData organisationData = new OrganisationListData() { Id = organisationId.ToString(), Name = values.GetString(colName.DataName), TypeCode = values.GetString(colOrganisationType.DataName), TypeDesc = OrganisationTypeCodes.GetDescForCode(values.GetString(colOrganisationType.DataName)), CategoryCode = values.GetString(colOrganisationCategory.DataName), CategoryDesc = OrganisationCategoryCodes.GetDescForCode(values.GetString(colOrganisationCategory.DataName)), MemberCount = StringUtil.ToLong(values.GetString(colMemberCount.DataName)), SportId = SysId.ToString(new SysId(values.GetLong(colSportId.DataName)), null), SportName = StringUtil.OnEmpty(values.GetString(colSportName.DataName), null), StatusCode = values.GetString(colStatus.DataName), StatusDesc = SacsSystem.GetStatusDescForCode(values.GetString(colStatus.DataName)) }; // Logo image. if (StringUtil.ToLong(values.GetString(colLogoCount.DataName)) > 0) organisationData.LogoImageUrl = GetOrganisationLogoLink(organisationId, false); // Primary region. organisationData.RegionPrimary.Id = SysId.ToString(new SysId(values.GetLong(colRegionId.DataName)), null); organisationData.RegionPrimary.Name = StringUtil.OnEmpty(values.GetString(colRegionName.DataName), null); // Add item to list. responseData.Organisations.Add(organisationData); } } if (model.Paging.IsPaged) model.Paging.ItemCount = (ushort)responseData.Organisations.Count; // Complete response. responseData.SetPaging(model); responseData.Success = true; return Json(responseData); } //------------------------------------------------------------------- /// /// Construct Organisation filter params. /// - Shared with Organisation Exporter process. /// /// /// public static SaxOrganisation.Params GetOrganisationListFilter(Model_Organisation model, SaxAccountMgr accountMgr) { // Item filter. SaxOrganisation.Params prmOrganisation = new SaxOrganisation.Params(); prmOrganisation.OrganisationFilter = model.Filter.Organisation; prmOrganisation.OrganisationType = model.FilterOrganisationType; prmOrganisation.OrganisationCategory = model.FilterOrganisationCategory; prmOrganisation.SportIdsIncluded.AddId(SysId.ToSysId(model.Filter.OrganisationSportId)); prmOrganisation.RegionIdsIncluded.AddId(SysId.ToSysId(model.Filter.OrganisationRegionId)); prmOrganisation.StatusCat = model.Filter.OrganisationStatusCategoryCode != null ? model.FilterOrganisationStatusCategory : SaxOrganisation.StatusCat.NotDeleted; prmOrganisation.SortColumns.Add(accountMgr.GetOrganisationColumnDfn(SaxOrganisation.Column.Name)); return prmOrganisation; } //------------------------------------------------------------------- // Get Organisation ajax request. //------------------------------------------------------------------- private class AjaxResponse_Organisation : AjaxResponse_Data { // Construction. public AjaxResponse_Organisation(SaxModel_Admin model) : base(model) { } // Organisation details. public OrganisationItemData organisation { get; } = new OrganisationItemData(); } //------------------------------------------------------------------- [HttpPost] [Route("Organisation/Ajax/GetItem")] public IActionResult Ajax_GetItem(Model_Organisation model) { String fn = GetType().Name + ".Ajax_GetItem"; String messageTitle = Localiser["caption.organisation"]; AjaxResponse_Organisation responseData = new AjaxResponse_Organisation(model); // Validate session. if (!ValidUserSession) return GetAjaxResult_InvalidSession(responseData); // Record disposable items as they are created so all can be disposed when needed. using (DisposableCollection disposableItems = new DisposableCollection()) { // Identify item. SysId organisationId = SysId.ToSysId(model.OrganisationId); if (!SysId.IsValid(organisationId)) return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.item.id.not.specified"])); // Retrieve item. SaxOrganisation organisation = AccountMgr.GetOrganisationById(organisationId); disposableItems.Add(organisation); if (organisation == null) { SaLogger.Warn(fn + " Failed to retrieve organisation for Id: '" + model.OrganisationId + "'"); return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.item.id.not.found"])); } // Organisation address. SaxItemAddress address = ItemDataMgr.GetFirstItemAddressByItemAndType(organisation.GetItemId()); disposableItems.Add(address); // Construct response. PopulateOrganisationResponseItemData(organisation, address, responseData.organisation); // Complete response. responseData.Success = true; } return Json(responseData); } //------------------------------------------------------------------- // Store Organisation ajax request. //------------------------------------------------------------------- [HttpPost] [Route("Organisation/Ajax/StoreItem")] public IActionResult Ajax_StoreItem(Model_Organisation model) { String fn = GetType().Name + ".Ajax_StoreItem"; String messageTitle = Localiser["caption.organisation"]; AjaxResponse_Organisation responseData = new AjaxResponse_Organisation(model); // Validate session. if (!ValidUserSession) return GetAjaxResult_InvalidSession(responseData); // Record disposable items as they are created so all can be disposed when needed. using (DisposableCollection disposableItems = new DisposableCollection()) { // Validate item properties. model.ValidateOrganisationData(responseData); if (responseData.HasControlErrors()) return Json(responseData); // Retrieve existing item. SysId organisationId = SysId.ToSysId(model.OrganisationId); SaxOrganisation organisation = AccountMgr.GetOrganisationById(organisationId); disposableItems.Add(organisation); if (organisation == null && SysId.IsValid(organisationId)) { SaLogger.Warn(fn + " Failed to retrieve organisation for Id: '" + model.OrganisationId + "'"); return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.item.id.not.found"])); } // Create new item if required. if (organisation == null) { organisation = AccountMgr.CreateOrganisation(); disposableItems.Add(organisation); } // Organisation address. SaxItemAddress organisationAddress = ItemDataMgr.GetFirstItemAddressByItemAndType(organisation.GetItemId()); disposableItems.Add(organisationAddress); // Populate item properties. if (model.OrganisationName != null) organisation.Name = model.OrganisationName; if (model.OrganisationTypeValue != null) organisation.OrganisationType = model.OrganisationType; if (model.OrganisationCategoryValue != null) organisation.OrganisationCategory = model.OrganisationCategory; if (model.OrganisationSportId != null) organisation.SportIdPrimary = SysId.ToSysId(model.OrganisationSportId); if (model.OrganisationRegionIdPrimary != null) organisation.RegionIdPrimary = SysId.ToSysId(model.OrganisationRegionIdPrimary); if (model.OrganisationAbout != null) organisation.About = model.OrganisationAbout; if (model.OrganisationFacilities != null) organisation.Facilities = model.OrganisationFacilities; if (model.ContactData != null) organisation.ContactData = model.ContactData.GetContactData(); // Common properties. if (model.OrganisationStatusCode != null) organisation.Status = model.OrganisationStatus; if (model.OrganisationNotes != null) organisation.Notes = model.OrganisationNotes; // Store item. if (!SysId.IsValid(organisation.Id)) { if (!AccountMgr.InsertOrganisation(organisation, DbUpdateInfo)) { SaLogger.Warn(fn + " Failed to insert organisation: " + AccountMgr.ErrorStateMessage); return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.item.insert.failed"] + "\n\n" + AccountMgr.ErrorStateMessage)); } } else { if (!AccountMgr.UpdateOrganisation(organisation, DbUpdateInfo)) { SaLogger.Warn(fn + " Failed to update organisation [Id:" + SysId.ToString(organisation.Id) + "]: " + AccountMgr.ErrorStateMessage); return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.item.update.failed"] + "\n\n" + AccountMgr.ErrorStateMessage)); } } if (model.Address.IsSpecified()) { // The form includes address fields. if (model.Address.IsPopulated()) { // Organisation regions. SaxRegion.Data regionCountry = Internals.GetRegion(SysId.ToSysId(model.Address.RegionIdCountry)); if (regionCountry == null) // Default to Organisation's primary region. regionCountry = Internals.GetRegion(organisation.RegionIdPrimary); if (regionCountry != null && regionCountry.RegionType != Sax.RegionType.Country) regionCountry = null; SaxRegion.Data regionProvince = null; // Create Organisation address if required. if (organisationAddress == null) { organisationAddress = ItemDataMgr.CreateItemAddress(organisation.GetItemId(), SaxItemAddress.DefaultOrganisationAddressType); disposableItems.Add(organisationAddress); } // Store address. if (model.Address.Line1 != null) organisationAddress.Line1 = model.Address.Line1; if (model.Address.Line2 != null) organisationAddress.Line2 = model.Address.Line2; if (model.Address.Line3 != null) organisationAddress.Line3 = model.Address.Line3; if (model.Address.Town != null) organisationAddress.Town = model.Address.Town; if (regionProvince != null) { organisationAddress.Province = regionProvince.Name; organisationAddress.RegionIdProvince = regionProvince.Id; } else { if (model.Address.Province != null) organisationAddress.Province = model.Address.Province; } if (regionCountry != null) { organisationAddress.Country = regionCountry.Name; organisationAddress.RegionIdCountry = regionCountry.Id; } organisationAddress.PostalCode = model.Address.PostalCode; organisationAddress.Status = SaxItemAddress.DefaultStatus; // Store address. if (!SysId.IsValid(organisationAddress.Id)) { // Create new address. if (!ItemDataMgr.InsertItemAddress(organisationAddress, DbUpdateInfo)) { SaLogger.Warn(fn + " Failed to insert organisation address - " + ItemDataMgr.ErrorStateMessage); return Json(responseData.SetGoHome(messageTitle, Localiser["msg.error.system"])); } } else { // Update existing address. if (!ItemDataMgr.UpdateItemAddress(organisationAddress, DbUpdateInfo)) { SaLogger.Warn(fn + " Failed to update organisation address - " + ItemDataMgr.ErrorStateMessage); return Json(responseData.SetGoHome(messageTitle, Localiser["msg.error.system"])); } } } else if (organisationAddress != null && !organisationAddress.IsStatusDeleted) { // Address not populated - delete it. if (!ItemDataMgr.DeleteItemAddress(organisationAddress, DbUpdateInfo)) { SaLogger.Warn(fn + " Failed to delete organisation address - " + ItemDataMgr.ErrorStateMessage); return Json(responseData.SetGoHome(messageTitle, Localiser["msg.error.system"])); } } } // Construct response. PopulateOrganisationResponseItemData(organisation, organisationAddress, responseData.organisation); // Complete response. responseData.Success = true; } return Json(responseData); } //------------------------------------------------------------------- } //======================================================================= }