366 lines
18 KiB
C#
366 lines
18 KiB
C#
using Microsoft.AspNetCore.Mvc;
|
|
using Microsoft.Extensions.Logging;
|
|
using Saxonite.Net.Core.Web.Online.Models;
|
|
using Saxonite.Net.Core.Web.Base.App;
|
|
using Saxonite.Net.Core.Web.Base.Controllers;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Diagnostics;
|
|
using System.Linq;
|
|
using System.Threading.Tasks;
|
|
using Saxonite.Net.Standard.Base.Bus;
|
|
using Sarand.Net.Standard.Base.App;
|
|
using Sarand.Net.Standard.Base.Bus;
|
|
using Sarand.Net.Standard.Base.Utils;
|
|
using Sarand.Net.Standard.Base.Core;
|
|
using Sarand.Net.Standard.Base.Dbas;
|
|
using Saxonite.Net.Standard.Base.App;
|
|
using Saxonite.Net.Core.Web.Online.Helpers;
|
|
using Org.BouncyCastle.Security;
|
|
using static Saxonite.Net.Standard.Base.App.Sax;
|
|
|
|
namespace Saxonite.Net.Core.Web.Online.Controllers
|
|
{
|
|
//=======================================================================
|
|
// Online Search Controller - Organisations - Ajax actions.
|
|
//=======================================================================
|
|
partial class SearchController
|
|
{
|
|
//-------------------------------------------------------------------
|
|
// Account - Get Organisations.
|
|
//-------------------------------------------------------------------
|
|
private class OrganisationListData : AjaxResponse_Data.ItemData_Base
|
|
{
|
|
public String Name { get; set; }
|
|
public String CategoryDesc { get; set; }
|
|
public String SportName { get; set; }
|
|
public String RegionName { get; set; }
|
|
public String LogoUrl { get; set; }
|
|
}
|
|
private class AjaxResponse_Search_Organisations : AjaxResponse_Data
|
|
{
|
|
// Construction.
|
|
public AjaxResponse_Search_Organisations(SaxModel_Online model) : base(model) { }
|
|
// Organisation list.
|
|
public List<OrganisationListData> Organisations { get; } = new List<OrganisationListData>();
|
|
}
|
|
// Ajax request.
|
|
[HttpPost]
|
|
[Route("Search/Ajax/Organisations")]
|
|
[Route("Search/Ajax/GetOrganisations")]
|
|
public IActionResult Ajax_GetOrganisations(Model_Search_Organisations model)
|
|
{
|
|
String fn = GetType().Name + ".Ajax_GetOrganisations";
|
|
AjaxResponse_Search_Organisations responseData = new AjaxResponse_Search_Organisations(model);
|
|
String messageTitle = Localiser["organisation.caption.organisations"];
|
|
|
|
// Validate session and referrer.
|
|
if (!ValidReferer) return Forbid();
|
|
if (!ValidUserSession) return GetAjaxResult_InvalidSession(responseData);
|
|
RefreshModel(model);
|
|
|
|
// Ensure data is paged to avoid leaking large volumes.
|
|
model.Paging.PageNo = Math.Max(1, model.Paging.PageNo);
|
|
model.Paging.PageLength = Math.Max(Math.Min(Sax.Config.Online.Search.Organisations.PageLengthMax, model.Paging.PageLength), (ushort)1);
|
|
|
|
// Query organisations that user is a member of.
|
|
SaxOrganisation.Params prmOrganisation = new SaxOrganisation.Params();
|
|
prmOrganisation.OrganisationFilter = model.Filter.Organisation;
|
|
prmOrganisation.OrganisationType = model.FilterOrganisationType;
|
|
prmOrganisation.OrganisationCategory = model.FilterOrganisationCategory;
|
|
prmOrganisation.OrganisationCategoriesExcluded.Add(Sax.OrganisationCategory.Partner);
|
|
prmOrganisation.OrganisationCategoriesExcluded.Add(Sax.OrganisationCategory.Other);
|
|
if (SysId.IsValid(model.FilterSportId))
|
|
prmOrganisation.SportIdsIncluded.Add(model.FilterSportId);
|
|
if (SysId.IsValid(model.FilterRegionId))
|
|
prmOrganisation.RegionIdsIncluded.Add(model.FilterRegionId);
|
|
prmOrganisation.StatusCat = SaxOrganisation.StatusCat.ActiveOnly;
|
|
model.Paging.ItemTotal = (ulong)AccountMgr.GetOrganisationCount(prmOrganisation);
|
|
model.PopulatePagingTo(prmOrganisation.ResultsPaging);
|
|
|
|
List<SaxOrganisation> organisations = AccountMgr.GetOrganisationList(prmOrganisation);
|
|
List<SysId> organisationIds = organisations.GetIds();
|
|
|
|
// Item columns.
|
|
ColumnDfn colId = AccountMgr.GetOrganisationColumnDfn(SaxOrganisation.Column.Id);
|
|
ColumnDfn colName = AccountMgr.GetOrganisationColumnDfn(SaxOrganisation.Column.Name);
|
|
ColumnDfn colCategory = AccountMgr.GetOrganisationColumnDfn(SaxOrganisation.Column.OrganisationCategory_Desc);
|
|
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 colLogoCount = AccountMgr.GetOrganisationColumnDfn(SaxOrganisation.Column.LogoImage_Count);
|
|
List<ColumnDfn> columns = new List<ColumnDfn>()
|
|
{
|
|
colId, colName, colCategory,
|
|
colSportId, colSportName,
|
|
colRegionId, colRegionName,
|
|
colLogoCount
|
|
};
|
|
|
|
// Sort columns.
|
|
colName.SortAscending = true;
|
|
prmOrganisation.SortColumns.Add(colName);
|
|
|
|
// 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));
|
|
Sax.OrganisationCategory category = (Sax.OrganisationCategory)OrganisationCategoryCodes.GetTypeForCode(values.GetString(colCategory.DataName));
|
|
OrganisationListData organisationData = new OrganisationListData()
|
|
{
|
|
Id = model.EncryptId(organisationId),
|
|
Name = values.GetString(colName.DataName),
|
|
CategoryDesc = Localiser.GetOrganisationCategoryCaption(category),
|
|
SportName = values.GetString(colSportName.DataName),
|
|
RegionName = values.GetString(colRegionName.DataName),
|
|
};
|
|
// Logo.
|
|
if (values.GetLong(colLogoCount.DataName) > 0)
|
|
organisationData.LogoUrl = GetOrganisationLogoLink(organisationId, false);
|
|
|
|
// Add item to the 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);
|
|
}
|
|
//-------------------------------------------------------------------
|
|
// Account - Get Organisation.
|
|
//-------------------------------------------------------------------
|
|
/// <summary>
|
|
/// Associations are grouped by type and direction (parent->child).
|
|
/// <br>The organisation specified in each case is the 'other' organisation (not the current 'target' organisation).</br>
|
|
/// </summary>
|
|
private class AssociationTypeData
|
|
{
|
|
public String Caption { get; set; }
|
|
public List<AssociationOrganisationData> Organisations { get; } = new List<AssociationOrganisationData>();
|
|
}
|
|
/// <summary>
|
|
/// Association Organisation - the one that is not the current 'target' organisation.
|
|
/// <br>Region and Sport are only populate if different from the 'target' organisation.</br>
|
|
/// </summary>
|
|
private class AssociationOrganisationData
|
|
{
|
|
public String Name { get; set; }
|
|
public String Display
|
|
{
|
|
get
|
|
{
|
|
String display = Name;
|
|
if (!StringUtil.IsBlank(Sport) || !StringUtil.IsBlank(Region))
|
|
display += " (" + String.Join(", ", new List<String> { Sport, Region }.Where(item => !StringUtil.IsBlank(item))) + ")";
|
|
return display;
|
|
}
|
|
}
|
|
public String Region { get; set; }
|
|
public String Sport { get; set; }
|
|
}
|
|
private class OrganisationItemData : OrganisationListData
|
|
{
|
|
public String TypeDesc { get; set; }
|
|
public String About { get; set; }
|
|
public String Facilities { get; set; }
|
|
public List<AjaxResponse_Data.ItemLabelValue> Contacts { get; set; }
|
|
public String Address { get; set; }
|
|
public String PostalCode { get; set; }
|
|
public List<AssociationTypeData> Associations { get; } = new List<AssociationTypeData>();
|
|
}
|
|
private class AjaxResponse_Search_Organisation : AjaxResponse_Data
|
|
{
|
|
// Construction.
|
|
public AjaxResponse_Search_Organisation(SaxModel_Online model) : base(model) { }
|
|
// Organisation list.
|
|
public OrganisationItemData Organisation { get; set; }
|
|
}
|
|
// Ajax request.
|
|
[HttpPost]
|
|
[Route("Search/Ajax/Organisation")]
|
|
[Route("Search/Ajax/GetOrganisation")]
|
|
public IActionResult Ajax_GetOrganisation(Model_Search_Organisations model)
|
|
{
|
|
String fn = GetType().Name + ".Ajax_GetOrganisation";
|
|
AjaxResponse_Search_Organisation responseData = new AjaxResponse_Search_Organisation(model);
|
|
String messageTitle = Localiser["label.organisation"];
|
|
|
|
// Validate session and referrer.
|
|
if (!ValidReferer) return Forbid();
|
|
if (!ValidUserSession) return GetAjaxResult_InvalidSession(responseData);
|
|
RefreshModel(model);
|
|
|
|
|
|
// Record disposable items as they are created so all can be disposed when needed.
|
|
using (DisposableCollection<SacsHierarchyItem> disposableItems = new DisposableCollection<SacsHierarchyItem>())
|
|
{
|
|
|
|
// Retrieve organisation.
|
|
SysId organisationId = model.ExtractSysId(model.OrganisationId);
|
|
if (!SysId.IsValid(organisationId))
|
|
{
|
|
SaLogger.Warn(fn + " Organisation Id not supplied.");
|
|
return Json(responseData);
|
|
}
|
|
SaxOrganisation organisation = AccountMgr.GetOrganisationById(organisationId);
|
|
if (organisation == null)
|
|
{
|
|
SaLogger.Warn(fn + " Failed to retrieve organisation. Id: " + model.OrganisationId);
|
|
return Json(responseData);
|
|
}
|
|
disposableItems.Add(organisation);
|
|
|
|
// ToDo May-2022 TESTING.
|
|
//SaLogger.Info(fn + " Organisation: " + organisation.Name + "\nAbout: " + organisation.About + "\nFacilities: " + organisation.Facilities, true);
|
|
|
|
// Populate response.
|
|
OrganisationItemData organisationData = new OrganisationItemData()
|
|
{
|
|
Id = model.EncryptId(organisation.Id),
|
|
Name = organisation.Name,
|
|
CategoryDesc = Localiser.GetOrganisationCategoryCaption(organisation.OrganisationCategory),
|
|
TypeDesc = Localiser.GetOrganisationTypeCaption(organisation.OrganisationType),
|
|
SportName = model.GetSportCaption(organisation.SportIdPrimary),
|
|
RegionName = model.GetRegionCaption(organisation.RegionIdPrimary),
|
|
About = organisation.About,
|
|
Facilities = organisation.Facilities,
|
|
};
|
|
responseData.Organisation = organisationData;
|
|
|
|
// Contacts.
|
|
SaxContactData contactData = new SaxContactData(organisation.ContactData);
|
|
if (contactData.Methods.Count > 0)
|
|
{
|
|
responseData.Organisation.Contacts = new List<AjaxResponse_Data.ItemLabelValue>();
|
|
foreach (Sax.ContactMethod method in contactData.Methods)
|
|
{
|
|
AjaxResponse_Data.ItemLabelValue contact = new AjaxResponse_Data.ItemLabelValue()
|
|
{
|
|
Label = Localiser.GetContactMethodCaption(method),
|
|
Value = SaxContactMethodHelper_Online.GetContactMethodHtml(method, contactData.GetContactMethodValue(method), Localiser)
|
|
};
|
|
responseData.Organisation.Contacts.Add(contact);
|
|
}
|
|
}
|
|
|
|
// Organisation address.
|
|
SaxItemAddress address = ItemDataMgr.GetFirstItemAddressByItemAndType(organisation.GetItemId());
|
|
if (address != null)
|
|
{
|
|
String addressLines = (new List<string>() { address.Line1, address.Line2, address.Line3 }).Concat(", ", "", "", true, true);
|
|
String addressTownProvince = (new List<string>() { address.Town, address.Province }).Concat(", ", "", "", true, true);
|
|
organisationData.Address = (new List<String>() { addressLines, addressTownProvince }).Concat("\n", "", "", true, true);
|
|
organisationData.PostalCode = address.PostalCode;
|
|
}
|
|
|
|
// Associations.
|
|
Dictionary<SaxItemAssociation.TypeOptionData, List<AssociationOrganisationData>> associationTypeGroups = new Dictionary<SaxItemAssociation.TypeOptionData, List<AssociationOrganisationData>>();
|
|
ColumnDfn colId = ItemDataMgr.GetItemAssociationColumnDfn(SaxItemAssociation.Column.Id);
|
|
ColumnDfn colAssociationType = ItemDataMgr.GetItemAssociationColumnDfn(SaxItemAssociation.Column.AssociationType);
|
|
ColumnDfn colItemTypeFrom = ItemDataMgr.GetItemAssociationColumnDfn(SaxItemAssociation.Column.ItemTypeFrom);
|
|
ColumnDfn colItemIdFrom = ItemDataMgr.GetItemAssociationColumnDfn(SaxItemAssociation.Column.ItemIdFrom);
|
|
ColumnDfn colOrganisationFrom_Name = ItemDataMgr.GetItemAssociationColumnDfn(SaxItemAssociation.Column.OrganisationFrom_Name);
|
|
ColumnDfn colOrganisationFrom_SportIdPrimary = ItemDataMgr.GetItemAssociationColumnDfn(SaxItemAssociation.Column.OrganisationFrom_SportIdPrimary);
|
|
ColumnDfn colOrganisationFrom_RegionIdPrimary = ItemDataMgr.GetItemAssociationColumnDfn(SaxItemAssociation.Column.OrganisationFrom_RegionIdPrimary);
|
|
ColumnDfn colItemTypeTo = ItemDataMgr.GetItemAssociationColumnDfn(SaxItemAssociation.Column.ItemTypeTo);
|
|
ColumnDfn colItemIdTo = ItemDataMgr.GetItemAssociationColumnDfn(SaxItemAssociation.Column.ItemIdTo);
|
|
ColumnDfn colOrganisationTo_Name = ItemDataMgr.GetItemAssociationColumnDfn(SaxItemAssociation.Column.OrganisationTo_Name);
|
|
ColumnDfn colOrganisationTo_SportIdPrimary = ItemDataMgr.GetItemAssociationColumnDfn(SaxItemAssociation.Column.OrganisationTo_SportIdPrimary);
|
|
ColumnDfn colOrganisationTo_RegionIdPrimary = ItemDataMgr.GetItemAssociationColumnDfn(SaxItemAssociation.Column.OrganisationTo_RegionIdPrimary);
|
|
List<ColumnDfn> associationCols = new List<ColumnDfn>()
|
|
{
|
|
colId, colAssociationType,
|
|
colItemTypeFrom, colItemIdFrom, colOrganisationFrom_Name, colOrganisationFrom_SportIdPrimary, colOrganisationFrom_RegionIdPrimary,
|
|
colItemTypeTo, colItemIdTo, colOrganisationTo_Name, colOrganisationTo_SportIdPrimary, colOrganisationTo_RegionIdPrimary
|
|
};
|
|
SaxItemAssociation.Params prmAssociations = new SaxItemAssociation.Params();
|
|
prmAssociations.ItemIdsIncluded.Add(organisation.GetItemId());
|
|
prmAssociations.StatusCat = SaxItemAssociation.StatusCat.ActiveOnly;
|
|
using (DbResultSet resultSet = ItemDataMgr.ExecuteItemAssociationQuery(associationCols, prmAssociations))
|
|
{
|
|
while (resultSet != null && resultSet.HasRows && resultSet.NextRecord())
|
|
{
|
|
NamedValue.Map values = resultSet.GetRecordValues();
|
|
SysId associationId = new SysId(values.GetLong(colId.DataName));
|
|
Sax.AssociationType associationType = (Sax.AssociationType)values.GetLong(colAssociationType.DataName);
|
|
ItemId itemIdFrom = new ItemId((short)values.GetLong(colItemTypeFrom.DataName), new SysId(values.GetLong(colItemIdFrom.DataName)));
|
|
ItemId itemIdTo = new ItemId((short)values.GetLong(colItemTypeTo.DataName), new SysId(values.GetLong(colItemIdTo.DataName)));
|
|
bool associationTypeDirectionReversed = associationType == Sax.AssociationType.Affiliate && itemIdTo.Id.Equals(organisation.Id);
|
|
// Determine association type group.
|
|
SaxItemAssociation.TypeOptionData assocTypeOption = new SaxItemAssociation.TypeOptionData(associationType, associationTypeDirectionReversed, GetAssociationTypeOptionCaption(associationType, associationTypeDirectionReversed));
|
|
List<AssociationOrganisationData> organisations = associationTypeGroups.GetValue(assocTypeOption, null);
|
|
if (organisations == null)
|
|
associationTypeGroups.Add(assocTypeOption, organisations = new List<AssociationOrganisationData>());
|
|
// Populate organisation properties.
|
|
SysId orgSportIdFrom = new SysId(values.GetLong(colOrganisationFrom_SportIdPrimary.DataName));
|
|
SysId orgRegionIdFrom = new SysId(values.GetLong(colOrganisationFrom_RegionIdPrimary.DataName));
|
|
SysId orgSportIdTo = new SysId(values.GetLong(colOrganisationTo_SportIdPrimary.DataName));
|
|
SysId orgRegionIdTo = new SysId(values.GetLong(colOrganisationTo_RegionIdPrimary.DataName));
|
|
if (itemIdTo.Id.Equals(organisation.Id))
|
|
{
|
|
// 'From' item is the 'Other' organisation.
|
|
AssociationOrganisationData assocOrgData = new AssociationOrganisationData();
|
|
assocOrgData.Name = values.GetString(colOrganisationFrom_Name.DataName);
|
|
if (!orgSportIdFrom.Equals(orgSportIdTo))
|
|
assocOrgData.Sport = model.GetSportCaption(orgSportIdFrom);
|
|
if (!orgRegionIdFrom.Equals(orgRegionIdTo))
|
|
assocOrgData.Region = model.GetRegionCaption(orgRegionIdFrom);
|
|
organisations.Add(assocOrgData);
|
|
}
|
|
else
|
|
{
|
|
// 'To' item is the 'Other' organisation.
|
|
AssociationOrganisationData assocOrgData = new AssociationOrganisationData();
|
|
assocOrgData.Name = values.GetString(colOrganisationTo_Name.DataName);
|
|
if (!orgSportIdFrom.Equals(orgSportIdTo))
|
|
assocOrgData.Sport = model.GetSportCaption(orgSportIdTo);
|
|
if (!orgRegionIdFrom.Equals(orgRegionIdTo))
|
|
assocOrgData.Region = model.GetRegionCaption(orgRegionIdTo);
|
|
organisations.Add(assocOrgData);
|
|
}
|
|
}
|
|
}
|
|
// Populate associations to response.
|
|
foreach (SaxItemAssociation.TypeOptionData associationTypeGroup in associationTypeGroups.Keys.OrderBy(item => (int)item.TypeOption))
|
|
{
|
|
AssociationTypeData associationTypeData = new AssociationTypeData();
|
|
associationTypeData.Caption = associationTypeGroup.Caption;
|
|
associationTypeData.Organisations.AddRange(associationTypeGroups.GetValue(associationTypeGroup, new List<AssociationOrganisationData>()).OrderBy(item => item.Name).ToList());
|
|
responseData.Organisation.Associations.Add(associationTypeData);
|
|
}
|
|
|
|
}
|
|
|
|
// Complete response.
|
|
responseData.Success = true;
|
|
return Json(responseData);
|
|
}
|
|
|
|
//-------------------------------------------------------------------
|
|
/// <summary>
|
|
/// Caption to display above list of corresponding associated organisation for the 'target' organisation.
|
|
/// </summary>
|
|
private String GetAssociationTypeOptionCaption(Sax.AssociationType associationType, bool reversed)
|
|
{
|
|
switch (SaxItemAssociation.GetAssociationTypeOption(associationType, reversed))
|
|
{
|
|
case AssociationTypeOption.AffiliateParent: return "Affiliated to";
|
|
case AssociationTypeOption.AffiliateChild: return "Affiliates";
|
|
case AssociationTypeOption.Partner: return "Partners";
|
|
}
|
|
return "Unknown relationship";
|
|
}
|
|
|
|
//-------------------------------------------------------------------
|
|
}
|
|
//=======================================================================
|
|
}
|