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.Standard.Base.App; using Saxonite.Net.Standard.Base.Bus; using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Threading.Tasks; using AssociationTypeOption = Saxonite.Net.Core.Web.Admin.Models.Model_OrganisationAssociations.AssociationTypeOption; namespace Saxonite.Net.Core.Web.Admin.Controllers { //======================================================================= // Controller: Organisation - Ajax - Associations //======================================================================= partial class OrganisationController { //------------------------------------------------------------------- // Association type combinations. //------------------------------------------------------------------- private static readonly String optionLabel_AffiliatedTo = "Affiliated to"; private static readonly String optionLabel_Affiliate = "Affiliate"; private static readonly String optionLabel_Partner = "Partner"; // Associations are between two items (From & To) but in the context of // displaying associations for an organisation, the organisation may be // the 'From' item (normal) or the 'To' item (reversed). private class AssociationTypeData { public AssociationTypeData() { // No parameter construction - populating association details for individual item (see Populate()). } public AssociationTypeData(AssociationTypeOption associationTypeOption) { // Population on construction - generic association type definitions, eg. for drop down menu options. Populate(associationTypeOption); } public void Populate(AssociationTypeOption associationTypeOption) { // Default labels - option to select association etc. Type = ((int)associationTypeOption).ToString(); Label = GetOptionLabel(associationTypeOption); } public void Populate(Sax.AssociationType associationType, bool reversed) { // Default labels - option to select association etc. Populate(GetAssociationTypeOption(associationType, reversed)); } public void Populate(Sax.AssociationType associationType, bool reversed, String label) { // Populate for specific labels, eg. to identify nature of associated organisation. AssociationTypeOption associationTypeOption = GetAssociationTypeOption(associationType, reversed); Type = ((int)associationTypeOption).ToString(); Label = label; } // Properties. public String Type { get; set; } public String Label { get; set; } // Utilities. public static AssociationTypeOption GetAssociationTypeOption(Sax.AssociationType associationType, bool reversed) { switch (associationType) { case Sax.AssociationType.Affiliate: return reversed ? AssociationTypeOption.AffiliatedTo : AssociationTypeOption.AffiliateParent; case Sax.AssociationType.Partner: return AssociationTypeOption.Partner; } return AssociationTypeOption.Unknown; } public static String GetOptionLabel(AssociationTypeOption associationTypeOption) { switch (associationTypeOption) { case AssociationTypeOption.AffiliateParent: return optionLabel_AffiliatedTo; case AssociationTypeOption.AffiliatedTo: return optionLabel_Affiliate; case AssociationTypeOption.Partner: return optionLabel_Partner; } return ""; } } //------------------------------------------------------------------- // Association data. //------------------------------------------------------------------- private class AssociationListData : AjaxResponse_Data.ItemData_Base { public class OrganisationData { public String Id { get; set; } public String Name { get; set; } } public OrganisationData Organisation { get; } = new OrganisationData(); public OrganisationData OrganisationAssoc { get; } = new OrganisationData(); public AssociationTypeData Assoc { get; } = new AssociationTypeData(); } private class AssociationItemData : AssociationListData { } private void PopulateAssociationResponseListData(AssociationListData data, SaxItemAssociation itemAssociation, SaxOrganisation organisation, SaxOrganisation organisationAssoc) { data.Id = SysId.ToString(itemAssociation.Id); // Organisation. data.Organisation.Id = SysId.ToString(organisation.Id); data.Organisation.Name = organisation.Name; // Associated Organisation. data.OrganisationAssoc.Id = SysId.ToString(organisationAssoc.Id); data.OrganisationAssoc.Name = organisationAssoc.Name; // Association type. bool associationReversed = itemAssociation.ItemIdTo.Id.Equals(organisation.Id); String associationLabel = ""; if (itemAssociation.AssociationType == Sax.AssociationType.Affiliate) associationLabel = associationReversed ? "Member organisation" : associationLabel = "Parent organisation"; else if (itemAssociation.AssociationType == Sax.AssociationType.Partner) associationLabel = "Partner organisation"; data.Assoc.Populate(itemAssociation.AssociationType, associationReversed, associationLabel); // Common properties. data.StatusCode = itemAssociation.StatusCode; data.StatusDesc = itemAssociation.StatusDesc; } private void PopulateAssociationResponseItemData(AssociationItemData data, SaxItemAssociation itemAssociation, SaxOrganisation organisation, SaxOrganisation organisationAssoc) { PopulateAssociationResponseListData(data, itemAssociation, organisation, organisationAssoc); } //------------------------------------------------------------------- // Get Organisation Association List ajax request. //------------------------------------------------------------------- private class AjaxResponse_AssociationList : AjaxResponse_Data { // Construction. public AjaxResponse_AssociationList(SaxModel_Admin model) : base(model) { } // Association list. public List Associations { get; } = new List(); // Reference data. public List AssociationTypes { get; } = new List(); public List Statuses { get; } = new List(); public String DefaultStatusCode { get; set; } } //------------------------------------------------------------------- [HttpPost] [Route("Organisation/Ajax/GetAssociationList")] [Route("Organisation/Ajax/GetAssociations")] public IActionResult Ajax_GetAssociationList(Model_OrganisationAssociations model) { String fn = GetType().Name + ".Ajax_GetAssociationList"; String messageTitle = Localiser["caption.organisation.associations"]; AjaxResponse_AssociationList responseData = new AjaxResponse_AssociationList(model); // Validate session. if (!ValidUserSession) return GetAjaxResult_InvalidSession(responseData); // Organisation Id is mandatory. SysId organisationId = model.Filter.OrganisationId.ToSysId(); if (!SysId.IsValid(organisationId)) { SaLogger.Warn(fn + " Request to retrieve associations without valid organisation Id."); return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.item.id.not.specified"])); } // Reference data - association types. // 'Label' is option caption to add new association of the specified type. responseData.AssociationTypes.Add(new AssociationTypeData(AssociationTypeOption.AffiliateParent)); responseData.AssociationTypes.Add(new AssociationTypeData(AssociationTypeOption.AffiliatedTo)); responseData.AssociationTypes.Add(new AssociationTypeData(AssociationTypeOption.Partner)); // Reference data - statuses. foreach (SaStatus status in SaxItemAssociation.ValidStatuses.FindAll(item => item != SaStatus.Deleted)) responseData.Statuses.Add(SacsSystem.GetStatusCode(status), Localiser.GetStatusCaption(status)); responseData.DefaultStatusCode = SacsSystem.GetStatusCode(SaxItemAssociation.DefaultStatus); // Get organisation associations. GetOrganisationAssociations(model, organisationId, responseData.Associations); if (model.Paging.IsPaged) model.Paging.ItemCount = (ushort)responseData.Associations.Count; // Complete response. responseData.SetPaging(model); responseData.Success = true; return Json(responseData); } private void GetOrganisationAssociations(SaxModel_Admin model, SysId organisationId, List associations) { String fn = GetType().Name + ".GetOrganisationAssociations"; // Record disposable items as they are created so all can be disposed when needed. using (DisposableCollection disposableItems = new DisposableCollection()) { // Item filter. SaxItemAssociation.Params prmItemAssociation = new SaxItemAssociation.Params(); prmItemAssociation.ItemIdsIncluded.Add(new ItemId((short)Sax.DataItemType.Organisation, organisationId)); prmItemAssociation.StatusCat = SaxItemAssociation.StatusCat.NotDeleted; model.Paging.ItemTotal = (ulong)ItemDataMgr.GetItemAssociationCount(prmItemAssociation); model.PopulatePagingTo(prmItemAssociation.ResultsPaging); // Item columns. ColumnDfn colId = ItemDataMgr.GetItemAssociationColumnDfn(SaxItemAssociation.Column.Id); ColumnDfn colItemTypeFrom = ItemDataMgr.GetItemAssociationColumnDfn(SaxItemAssociation.Column.ItemTypeFrom); ColumnDfn colItemIdFrom = ItemDataMgr.GetItemAssociationColumnDfn(SaxItemAssociation.Column.ItemIdFrom); ColumnDfn colItemTypeTo = ItemDataMgr.GetItemAssociationColumnDfn(SaxItemAssociation.Column.ItemTypeTo); ColumnDfn colItemIdTo = ItemDataMgr.GetItemAssociationColumnDfn(SaxItemAssociation.Column.ItemIdTo); ColumnDfn colAssociationType = ItemDataMgr.GetItemAssociationColumnDfn(SaxItemAssociation.Column.AssociationType); ColumnDfn colStatus = ItemDataMgr.GetItemAssociationColumnDfn(SaxItemAssociation.Column.Status); List columns = new List() { colId, colItemTypeFrom, colItemIdFrom, colItemTypeTo, colItemIdTo, colAssociationType, colStatus }; // Query items. List organisationIds = new List(); using (DbResultSet resultSet = ItemDataMgr.ExecuteItemAssociationQuery(columns, prmItemAssociation)) { while (resultSet != null && resultSet.HasRows && resultSet.NextRecord()) { NamedValue.Map values = resultSet.GetRecordValues(); AssociationListData associationData = new AssociationListData() { Id = values.GetString(colId.DataName), StatusCode = values.GetString(colStatus.DataName), StatusDesc = SacsSystem.GetStatusDescForCode(values.GetString(colStatus.DataName)), }; // Items. bool assiationReversed = false; 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))); if (ItemId.IsValid(itemIdFrom) && ItemId.IsValid(itemIdTo) && itemIdFrom.Type == (int)Sax.DataItemType.Organisation && itemIdTo.Type == (int)Sax.DataItemType.Organisation) { organisationIds.AddId(itemIdFrom.Id); organisationIds.AddId(itemIdTo.Id); if (itemIdFrom.Id.Equals(organisationId)) { associationData.Organisation.Id = SysId.ToString(itemIdFrom.Id); associationData.OrganisationAssoc.Id = SysId.ToString(itemIdTo.Id); } else if (itemIdTo.Id.Equals(organisationId)) { assiationReversed = true; associationData.Organisation.Id = SysId.ToString(itemIdTo.Id); associationData.OrganisationAssoc.Id = SysId.ToString(itemIdFrom.Id); } else if (SacsSystem.DebugMode) // Track invalid associations, ie. where neither item is this organisation. Debugger.Break(); } else if (SacsSystem.DebugMode) // Track invalid associations, ie. where either item is not an organisation. Debugger.Break(); // Association type. Sax.AssociationType associationType = (Sax.AssociationType)values.GetLong(colAssociationType.DataName); associationData.Assoc.Populate(associationType, assiationReversed); // Add association to the list. associations.Add(associationData); } } // Populate organisation details. SaxOrganisation.Params prmOrganisation = new SaxOrganisation.Params(); prmOrganisation.IdsIncluded.AddRange(organisationIds); prmOrganisation.StatusCat = SaxOrganisation.StatusCat.Any; List organisations = AccountMgr.GetOrganisationList(prmOrganisation); disposableItems.AddRange(organisations); foreach (AssociationListData associationData in associations) { associationData.Organisation.Name = organisations.GetOrganisationName(new SysId(StringUtil.ToLong(associationData.Organisation.Id))); associationData.OrganisationAssoc.Name = organisations.GetOrganisationName(new SysId(StringUtil.ToLong(associationData.OrganisationAssoc.Id))); } } } //------------------------------------------------------------------- // Get Organisation Association ajax request. //------------------------------------------------------------------- private class AjaxResponse_Association : AjaxResponse_Data { // Construction. public AjaxResponse_Association(SaxModel_Admin model) : base(model) { } // Association details. public AssociationItemData Association { get; } = new AssociationItemData(); } //------------------------------------------------------------------- [HttpPost] [Route("Organisation/Ajax/GetAssociation")] public IActionResult Ajax_GetAssociation(Model_OrganisationAssociations model) { String fn = GetType().Name + ".Ajax_GetAssociation"; String messageTitle = Localiser["caption.organisation.association"]; AjaxResponse_Association responseData = new AjaxResponse_Association(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 itemAssociationId = model.ItemAssociationId.ToSysId(); if (!SysId.IsValid(itemAssociationId)) return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.item.id.not.specified"])); // Retrieve association. SaxItemAssociation itemAssociation = ItemDataMgr.GetItemAssociationById(itemAssociationId); disposableItems.Add(itemAssociation); if (itemAssociation == null) { SaLogger.Warn(fn + " Failed to retrieve Item Association for Id: '" + model.ItemAssociationId + "'"); return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.item.id.not.found"])); } // Identify organisations. SysId organisationId = model.OrganisationId.ToSysId(); SysId organisationIdAssoc = null; if (!SysId.IsValid(organisationId)) { SaLogger.Warn(fn + " Organisation Id must be supplied."); return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.data.incomplete"])); } // Validate the association. if (itemAssociation.ItemIdFrom.Type != (int)Sax.DataItemType.Organisation) { SaLogger.Warn(fn + " Inconsistent association 'From' item type: " + AssociationTypeCodes.GetCodeForType(itemAssociation.ItemIdFrom.Type) + ". Expected: Organisation."); return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.data.inconsistent"])); } if (itemAssociation.ItemIdTo.Type != (int)Sax.DataItemType.Organisation) { SaLogger.Warn(fn + " Inconsistent association 'To' item type: " + AssociationTypeCodes.GetCodeForType(itemAssociation.ItemIdTo.Type) + ". Expected: Organisation."); return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.data.inconsistent"])); } // Identify organisations from association items. // The specified organisation must be one or other of the association's items. if (itemAssociation.ItemIdFrom.Id.Equals(organisationId)) organisationIdAssoc = itemAssociation.ItemIdTo.Id; else if (itemAssociation.ItemIdTo.Id.Equals(organisationId)) organisationIdAssoc = itemAssociation.ItemIdFrom.Id; else { SaLogger.Warn(fn + " Inconsistent association - Specified organisation is neither item."); return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.data.inconsistent"])); } // Retrieve Organisation. SaxOrganisation organisation = AccountMgr.GetOrganisationById(organisationId); disposableItems.Add(organisation); if (organisation == null) { SaLogger.Warn(fn + " Failed to retrieve Organisation for Id: '" + organisationId + "'"); return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.system"])); } // Retrieve associated Organisation. SaxOrganisation organisationAssoc = AccountMgr.GetOrganisationById(organisationIdAssoc); disposableItems.Add(organisationAssoc); if (organisationAssoc == null) { SaLogger.Warn(fn + " Failed to retrieve Organisation for Id: '" + organisationIdAssoc + "'"); return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.system"])); } // Construct response. PopulateAssociationResponseItemData(responseData.Association, itemAssociation, organisation, organisationAssoc); } responseData.Success = true; return Json(responseData); } //------------------------------------------------------------------- // Store Organisation Association ajax request. //------------------------------------------------------------------- [HttpPost] [Route("Organisation/Ajax/StoreAssociation")] public IActionResult Ajax_StoreAssociation(Model_OrganisationAssociations model) { String fn = GetType().Name + ".Ajax_StoreAssociation"; String messageTitle = Localiser["caption.organisation.association"]; AjaxResponse_Association responseData = new AjaxResponse_Association(model); // Validate session. if (!ValidUserSession) return GetAjaxResult_InvalidSession(responseData); // Validate item properties. model.ValidateOrganisationAssociationData(responseData); if (responseData.HasControlErrors()) return Json(responseData); // Record disposable items as they are created so all can be disposed when needed. using (DisposableCollection disposableItems = new DisposableCollection()) { // Organisation. SysId organisationId = model.OrganisationId.ToSysId(); 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.data.incomplete"])); } // Associated Organisation. SysId organisationIdAssoc = model.OrganisationIdAssoc.ToSysId(); SaxOrganisation organisationAssoc = AccountMgr.GetOrganisationById(organisationIdAssoc); disposableItems.Add(organisationAssoc); if (organisationAssoc == null) { SaLogger.Warn(fn + " Failed to retrieve associated Organisation for Id: " + model.OrganisationIdAssoc); return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.data.incomplete"])); } if (organisationIdAssoc.Equals(organisationId)) { SaLogger.Warn(fn + " Associated organisation must not be the same as the organisation."); return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.data.inconsistent"])); } // Association type. Sax.AssociationType associationType = model.GetAssociationTypeForOption(model.Association.GetAssociationTypeOption()); if ((int)associationType < 1) { SaLogger.Warn(fn + " Association Type must be specified."); return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.data.inconsistent"])); } AssociationTypeOption associationTypeOption = model.Association.GetAssociationTypeOption(); if ((int)associationTypeOption < 1) { SaLogger.Warn(fn + " Association Type Option must be specified."); return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.data.inconsistent"])); } if (!model.IsConsistentWith(associationTypeOption, associationType)) { SaLogger.Warn(fn + " Association Type Option (" + associationTypeOption + ") is inconsistent with Association Type (" + associationType + ")."); return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.data.inconsistent"])); } // Identify From/To items. ItemId itemIdFrom = organisation.GetItemId(); ItemId itemIdTo = organisationAssoc.GetItemId(); if (model.IsAssociationTypeDirectionReversed(associationTypeOption)) { itemIdFrom = organisationAssoc.GetItemId(); itemIdTo = organisation.GetItemId(); } // Retrieve existing association. SysId itemAssociationId = model.ItemAssociationId.ToSysId(); if (SysId.IsValid(itemAssociationId) == StringUtil.ToBool(model.NewItem)) { // Inconsistentcy between the 'Existing' flag and whether the Item Association Id has been specified. SaLogger.Warn(fn + " Item Association Id " + (StringUtil.ToBool(model.NewItem) ? "specified for new item" : "not specified for existing item") + "."); return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.data.inconsistent"])); } SaxItemAssociation itemAssociation = ItemDataMgr.GetItemAssociationById(itemAssociationId); disposableItems.Add(itemAssociation); if (itemAssociation == null && SysId.IsValid(itemAssociationId)) { SaLogger.Warn(fn + " Failed to retrieve item association for Id: '" + itemAssociationId + "'"); return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.item.id.not.found"])); } if (itemAssociation != null) { // Validate From/To items. if (!itemAssociation.ItemIdFrom.Equals(itemIdFrom)) { SaLogger.Warn(fn + " Inconsistent association - expected 'From' Item Id: " + SysId.ToString(organisation.Id) + ". Found: " + SysId.ToString(itemAssociation.ItemIdFrom.Id)); return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.system"])); } if (!itemAssociation.ItemIdTo.Equals(itemIdTo)) { SaLogger.Warn(fn + " Inconsistent association - expected 'To' Item Id: " + SysId.ToString(organisation.Id) + ". Found: " + SysId.ToString(itemAssociation.ItemIdTo.Id)); return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.system"])); } } else { // Item Association not identified. // Check for deleted association that can be reused. SaxItemAssociation.Params itemAssociationParams = new SaxItemAssociation.Params(); if (itemAssociation != null) itemAssociation.Status = SaxItemAssociation.DefaultStatus; else { // Association not found - create a new one. itemAssociation = ItemDataMgr.CreateItemAssociation(itemIdFrom, itemIdTo, associationType); } disposableItems.Add(itemAssociation); } // Populate item properties. if (model.Association.StatusCode != null) itemAssociation.Status = model.Association.GetStatus(); // Store item. if (!SysId.IsValid(itemAssociation.Id)) { if (!ItemDataMgr.InsertItemAssociation(itemAssociation, DbUpdateInfo)) { SaLogger.Warn(fn + " Failed to insert user organisation: " + ItemDataMgr.ErrorStateMessage); return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.item.insert.failed"] + "\n\n" + ItemDataMgr.ErrorStateMessage)); } } else { if (!ItemDataMgr.UpdateItemAssociation(itemAssociation, DbUpdateInfo)) { SaLogger.Warn(fn + " Failed to update user organisation [Id:" + SysId.ToString(itemAssociation.Id) + "]: " + ItemDataMgr.ErrorStateMessage); return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.item.update.failed"] + "\n\n" + ItemDataMgr.ErrorStateMessage)); } } // Construct response. PopulateAssociationResponseItemData(responseData.Association, itemAssociation, organisation, organisationAssoc); } responseData.Success = true; return Json(responseData); } //------------------------------------------------------------------- // Remove Organisation Association ajax request. //------------------------------------------------------------------- [HttpPost] [Route("Organisation/Ajax/RemoveAssociation")] public IActionResult Ajax_RemoveAssociation(Model_OrganisationAssociations model) { String fn = GetType().Name + ".Ajax_RemoveAssociation"; String messageTitle = Localiser["caption.organisation.association"]; AjaxResponse_Association responseData = new AjaxResponse_Association(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()) { // Organisation. SysId organisationId = model.OrganisationId.ToSysId(); 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.data.incomplete"])); } // Association Organisation. SysId organisationIdAssoc = model.OrganisationIdAssoc.ToSysId(); SaxOrganisation organisationAssoc = AccountMgr.GetOrganisationById(organisationIdAssoc); disposableItems.Add(organisationAssoc); if (organisationAssoc == null) { SaLogger.Warn(fn + " Failed to retrieve associated Organisation for Id: '" + model.OrganisationIdAssoc + "'"); return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.data.incomplete"])); } if (organisationIdAssoc.Equals(organisationId)) { SaLogger.Warn(fn + " Associated organisation must not be the same as the organisation."); return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.data.inconsistent"])); } // Item Association. SysId itemAssociationId = model.ItemAssociationId.ToSysId(); SaxItemAssociation itemAssociation = ItemDataMgr.GetItemAssociationById(itemAssociationId); disposableItems.Add(itemAssociation); if (itemAssociation == null) { SaLogger.Warn(fn + " Failed to retrieve Item Association for Id: '" + itemAssociationId + "'"); return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.item.id.not.found"])); } // Validate association Item Ids. if (!itemAssociation.ItemIdFrom.Id.Equals(organisation.Id) && !itemAssociation.ItemIdTo.Id.Equals(organisation.Id)) { SaLogger.Warn(fn + " Inconsistent user organisation properties. Organisation must be 'From' or 'To' item"); return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.data.inconsistent"])); } if (!itemAssociation.ItemIdFrom.Id.Equals(organisationAssoc.Id) && !itemAssociation.ItemIdTo.Id.Equals(organisationAssoc.Id)) { SaLogger.Warn(fn + " Inconsistent user organisation properties. Associated Organisation must be 'From' or 'To' item"); return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.data.inconsistent"])); } // Logically delete item. itemAssociation.Status = SaStatus.Deleted; if (!ItemDataMgr.UpdateItemAssociation(itemAssociation, DbUpdateInfo)) { SaLogger.Warn(fn + " Failed to update Item Association [Id:" + SysId.ToString(itemAssociation.Id) + "]: " + ItemDataMgr.ErrorStateMessage); return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.item.update.failed"] + "\n\n" + ItemDataMgr.ErrorStateMessage)); } // Construct response. PopulateAssociationResponseItemData(responseData.Association, itemAssociation, organisation, organisationAssoc); } responseData.Success = true; return Json(responseData); } //------------------------------------------------------------------- } //======================================================================= }