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.Online.Models; using Saxonite.Net.Standard.Base.App; using Saxonite.Net.Standard.Base.Bus; using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; namespace Saxonite.Net.Core.Web.Online.Controllers { //======================================================================= // Online Organisation Controller - Opportunities - Ajax actions. //======================================================================= partial class OrganisationController { //------------------------------------------------------------------- // Organisation Opportunity data. private class OpportunityData_List : AjaxResponse_Data.ItemData_Base { public String TypeCode { get; set; } public String TypeDesc { get; set; } public String Position { get; set; } public String Outline { get; set; } public String RegionCaption { get; set; } public String SportCaption { get; set; } public String PublishedOnFmt { get; set; } public String ExpiresOnFmt { get; set; } } private class OpportunityData_Full : OpportunityData_List { public String RegionIdPrimary { get; set; } public String SportIdPrimary { get; set; } public String PublishedOn_YYYYMMDD { get; set; } public String ExpiresOn_YYYYMMDD { get; set; } } private void PopulateOpportunityResponseData(Model_Organisation_Opportunities model, SaxOrganisationOpportunity opportunity, OpportunityData_List data) { data.Id = SysId.ToString(opportunity.Id); data.TypeCode = OpportunityTypeCodes.GetCodeForType(opportunity.OpportunityType); data.TypeDesc = Localiser.GetOpportunityTypeCaption(opportunity.OpportunityType); data.Position = opportunity.Position; data.Outline = opportunity.Outline; data.RegionCaption = model.GetRegionCaption(opportunity.RegionIdPrimary); data.SportCaption = model.GetSportCaption(opportunity.SportIdPrimary); data.CreatedOnFmt = Localiser.FormatDate(opportunity.CreateStamp.On); data.PublishedOnFmt = Localiser.FormatDate(opportunity.PublishedAt); data.ExpiresOnFmt = Localiser.FormatDate(opportunity.ExpiresAt); data.StatusCode = opportunity.StatusCode; data.StatusDesc = opportunity.StatusDesc; } private void PopulateOpportunityResponseData(Model_Organisation_Opportunities model, SaxOrganisationOpportunity opportunity, OpportunityData_Full data) { PopulateOpportunityResponseData(model, opportunity, data as OpportunityData_List); data.RegionIdPrimary = SysId.ToString(opportunity.RegionIdPrimary); data.SportIdPrimary = SysId.ToString(opportunity.SportIdPrimary); data.PublishedOn_YYYYMMDD = DateUtil.Format(opportunity.PublishedAt, "yyyyMMdd"); data.ExpiresOn_YYYYMMDD = DateUtil.Format(opportunity.ExpiresAt, "yyyyMMdd"); } //------------------------------------------------------------------- // Get Opportunity List ajax request. //------------------------------------------------------------------- private class AjaxResponse_OpportunityList : AjaxResponse_Data { // Construction. public AjaxResponse_OpportunityList(SaxModel_Online model) : base(model) { } // Opportunity list. public List Opportunities { get; } = new List(); // User profile. public class UserData { public bool CanManage { get; set; } } public UserData User { get; } = new UserData(); // Reference data. public List OpportunityTypes { get; } = new List(); } //------------------------------------------------------------------- [HttpPost] [Route("Organisation/Ajax/GetOpportunityList")] [Route("Organisation/Ajax/GetOpportunities")] public IActionResult Ajax_GetOpportunityList(Model_Organisation_Opportunities model) { String fn = GetType().Name + ".Ajax_GetOpportunityList"; String messageTitle = Localiser["organisation.caption.opportunities"]; AjaxResponse_OpportunityList responseData = new AjaxResponse_OpportunityList(model); // Validate session and referrer. if (!ValidReferer) return Forbid(); if (!ValidUserSession) return GetAjaxResult_InvalidSession(responseData); // Organisation. SysId organisationId = model.Filter.OrganisationId.ToSysId(); using (SaxOrganisation organisation = AccountMgr.GetOrganisationById(organisationId)) { if (organisation == null || !organisation.IsStatusActive) { SaLogger.Warn(fn + " " + (organisation == null ? "Invalid" : "Inactive") + " organisation for Opportunity list. OrganisationId: '" + model.Filter.OrganisationId + "'"); return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.system"])); } if (organisation != null) { // Store filter data. SessionData_Online.Filter.SetMemberOrganisation(organisation); // Reference data - opportunity types. foreach (TypeCodeDesc opportunityType in OpportunityTypeCodes) responseData.OpportunityTypes.Add(opportunityType.Code, Localiser.GetOpportunityTypeCaption((Sax.OpportunityType)opportunityType.Type)); // User organisation. SaxUserOrganisation.Params prmUserOrganisation = new SaxUserOrganisation.Params(); prmUserOrganisation.UserAccountIdsIncluded.Add(SessionData.User.UserAccountId); prmUserOrganisation.OrganisationIdsIncluded.Add(organisationId); prmUserOrganisation.UserAccountStatusCat = SaxUserAccount.StatusCat.ActiveOnly; prmUserOrganisation.StatusCat = SaxUserOrganisation.StatusCat.ActiveOnly; using (SaxUserOrganisation userOrganisation = AccountMgr.GetUserOrganisation(prmUserOrganisation)) { // User details. responseData.User.CanManage = userOrganisation?.HasOrganisationRole(Sax.OrganisationRole.OpportunityAdmin) ?? false; // Item filter. SaxOrganisationOpportunity.Params prmOpportunity = new SaxOrganisationOpportunity.Params(); prmOpportunity.UserAccountIdsIncluded.Add(SessionData.User.UserAccountId); prmOpportunity.OrganisationIdsIncluded.Add(organisationId); prmOpportunity.OpportunityFilter = model.Filter.Opportunity; prmOpportunity.StatusCat = SaxOrganisationOpportunity.StatusCat.NotDeleted; model.Paging.ItemTotal = (ulong)ActivityMgr.GetOrganisationOpportunityCount(prmOpportunity); model.PopulatePagingTo(prmOpportunity.ResultsPaging); // Item columns. ColumnDfn colId = ActivityMgr.GetOrganisationOpportunityColumnDfn(SaxOrganisationOpportunity.Column.Id); ColumnDfn colOpportunityTypeCode = ActivityMgr.GetOrganisationOpportunityColumnDfn(SaxOrganisationOpportunity.Column.OpportunityTypeCode); ColumnDfn colPosition = ActivityMgr.GetOrganisationOpportunityColumnDfn(SaxOrganisationOpportunity.Column.Position); ColumnDfn colOutline = ActivityMgr.GetOrganisationOpportunityColumnDfn(SaxOrganisationOpportunity.Column.Outline); ColumnDfn colRegionId = ActivityMgr.GetOrganisationOpportunityColumnDfn(SaxOrganisationOpportunity.Column.RegionIdPrimary); ColumnDfn colRegionName = ActivityMgr.GetOrganisationOpportunityColumnDfn(SaxOrganisationOpportunity.Column.Region_Name); ColumnDfn colSportId = ActivityMgr.GetOrganisationOpportunityColumnDfn(SaxOrganisationOpportunity.Column.SportIdPrimary); ColumnDfn colSportName = ActivityMgr.GetOrganisationOpportunityColumnDfn(SaxOrganisationOpportunity.Column.Sport_Name); ColumnDfn colPublishedOn = ActivityMgr.GetOrganisationOpportunityColumnDfn(SaxOrganisationOpportunity.Column.PublishedAt_Date); ColumnDfn colExpiresOn = ActivityMgr.GetOrganisationOpportunityColumnDfn(SaxOrganisationOpportunity.Column.ExpiresAt_Date); ColumnDfn colStatus = ActivityMgr.GetOrganisationOpportunityColumnDfn(SaxOrganisationOpportunity.Column.Status); ColumnDfn colCreatedOn = ActivityMgr.GetOrganisationOpportunityColumnDfn(SaxOrganisationOpportunity.Column.CreateOn_Date); List columns = new List() { colId, colOpportunityTypeCode, colPosition, colOutline, colRegionId, colRegionName, colSportId, colSportName, colPublishedOn, colExpiresOn, colStatus, colCreatedOn }; // Sort columns. colCreatedOn.SortAscending = false; prmOpportunity.SortColumns.Add(colCreatedOn); // Query items. using (DbResultSet resultSet = ActivityMgr.ExecuteOrganisationOpportunityQuery(columns, prmOpportunity)) { while (resultSet != null && resultSet.HasRows && resultSet.NextRecord()) { NamedValue.Map values = resultSet.GetRecordValues(); OpportunityData_List opportunityData = new OpportunityData_List() { Id = values.GetString(colId.DataName), TypeCode = values.GetString(colOpportunityTypeCode.DataName), TypeDesc = Localiser.GetOpportunityTypeCaption((Sax.OpportunityType)OpportunityTypeCodes.GetTypeForCode(values.GetString(colOpportunityTypeCode.DataName))), Position = values.GetString(colPosition.DataName), Outline = values.GetString(colOutline.DataName), RegionCaption = model.GetRegionCaption(values.GetString(colRegionId.DataName).ToSysId()), SportCaption = model.GetSportCaption(values.GetString(colSportId.DataName).ToSysId()), CreatedOnFmt = Localiser.FormatDate(values.GetDateTime(colCreatedOn.DataName)), PublishedOnFmt = Localiser.FormatDate(values.GetDateTime(colPublishedOn.DataName)), ExpiresOnFmt = Localiser.FormatDate(values.GetDateTime(colExpiresOn.DataName)), StatusCode = values.GetString(colStatus.DataName), StatusDesc = SacsSystem.GetStatusDescForCode(values.GetString(colStatus.DataName)) }; responseData.Opportunities.Add(opportunityData); } } } } } if (model.Paging.IsPaged) model.Paging.ItemCount = (ushort)responseData.Opportunities.Count; // Complete response. responseData.SetPaging(model); responseData.Success = true; return Json(responseData); } //------------------------------------------------------------------- // Get Opportunity ajax request. //------------------------------------------------------------------- private class AjaxResponse_Opportunity : AjaxResponse_Data { // Construction. public AjaxResponse_Opportunity(SaxModel_Online model) : base(model) { } // Opportunity details. public OpportunityData_Full Opportunity { get; } = new OpportunityData_Full(); } //------------------------------------------------------------------- [HttpPost] [Route("Organisation/Ajax/GetOpportunity")] public IActionResult Ajax_GetOpportunity(Model_Organisation_Opportunities model) { String fn = GetType().Name + ".Ajax_GetOpportunity"; String messageTitle = Localiser["organisation.caption.opportunity"]; AjaxResponse_Opportunity responseData = new AjaxResponse_Opportunity(model); // Validate session and referrer. if (!ValidReferer) return Forbid(); if (!ValidUserSession) return GetAjaxResult_InvalidSession(responseData); // Identify item. SysId opportunityId = model.OpportunityId.ToSysId(); if (!SysId.IsValid(opportunityId)) return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.item.id.not.specified"])); // Retrieve item. using (SaxOrganisationOpportunity opportunity = ActivityMgr.GetOrganisationOpportunityById(opportunityId)) { if (opportunity == null) { SaLogger.Warn(fn + " Failed to retrieve Organisation Opportunity for Id: '" + model.OpportunityId + "'"); return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.item.id.not.found"])); } // Validate organisation. using (SaxOrganisation organisation = AccountMgr.GetOrganisationById(opportunity.OrganisationId)) { if (organisation == null || !organisation.IsStatusActive) { SaLogger.Warn(fn + " " + (organisation == null ? "Invalid" : "Inactive") + " organisation for Opportunity. OrganisationId: '" + opportunity.OrganisationId + "'"); return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.system"])); } // Make a note of the selected Organisation. SessionData_Online.Filter.SetMemberOrganisation(organisation); // Construct response. PopulateOpportunityResponseData(model, opportunity, responseData.Opportunity); } } // Complete response. responseData.Success = true; return Json(responseData); } //------------------------------------------------------------------- // Store Opportunity ajax request. //------------------------------------------------------------------- [HttpPost] [Route("Organisation/Ajax/StoreOpportunity")] public IActionResult Ajax_StoreOpportunity(Model_Organisation_Opportunities model) { String fn = GetType().Name + ".Ajax_StoreOpportunity"; String messageTitle = Localiser["organisation.caption.opportunity"]; AjaxResponse_Opportunity responseData = new AjaxResponse_Opportunity(model); // Validate session and referrer. if (!ValidReferer) return Forbid(); if (!ValidUserSession) return GetAjaxResult_InvalidSession(responseData); // Validate item properties. model.ValidateOpportunityData(responseData); if (responseData.HasControlErrors()) return Json(responseData); // Validate Opportunity against Id against 'Exists' flag. SysId opportunityId = model.OpportunityId.ToSysId(); bool opportunityExists = StringUtil.ToBool(model.OpportunityExists); if (opportunityExists && !SysId.IsValid(opportunityId)) { SaLogger.Warn(fn + " Id not specified for existing Opportunity."); return Json(responseData.SetGoHome(messageTitle, Localiser["msg.error.system"])); } if (!opportunityExists && SysId.IsValid(opportunityId)) { SaLogger.Warn(fn + " Id specified for new Opportunity: '" + model.OpportunityId + "'"); return Json(responseData.SetGoHome(messageTitle, Localiser["msg.error.system"])); } // Record disposable items as they are created so all can be disposed when needed. using (DisposableCollection disposableItems = new DisposableCollection()) { // Retrieve existing item. SaxOrganisationOpportunity opportunity = ActivityMgr.GetOrganisationOpportunityById(opportunityId); disposableItems.Add(opportunity); if (opportunity == null && SysId.IsValid(opportunityId)) { SaLogger.Warn(fn + " Failed to retrieve opportunity for Id: '" + model.OpportunityId + "'"); return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.item.id.not.found"])); } // Validate the Organisation. SysId organisationId = model.OpportunityOrganisationId.ToSysId(); if (!SysId.IsValid(organisationId)) { SaLogger.Warn(fn + " Organisation Id not specified for Opportunity."); return Json(responseData.SetGoHome(messageTitle, Localiser["msg.error.system"])); } SaxOrganisation organisation = AccountMgr.GetOrganisationById(organisationId); disposableItems.Add(organisation); if (organisation == null || !organisation.IsStatusActive) { SaLogger.Warn(fn + " " + (organisation == null ? "Invalid" : "Inactive") + " organisation for Opportunity. OrganisationId: '" + model.OpportunityOrganisationId + "'"); return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.system"])); } if (opportunity != null && !opportunity.OrganisationId.Equals(organisationId)) { SaLogger.Warn(fn + " Inconsistent Organisation Id specified for Opportunity. Expected: " + opportunity.OrganisationId + ". Found: " + organisationId); return Json(responseData.SetGoHome(messageTitle, Localiser["msg.error.system"])); } // Ensure that the user has the correct role to update Opportunities for this organisation. if (!AccountMgr.UserHasOrganisationRole(SessionData.User.UserAccountId, organisationId, Sax.OrganisationRole.OpportunityAdmin)) { SaLogger.Warn(fn + " User doesn't have 'Opportunity Admin' role for Organisation Id: " + organisationId); return Json(responseData.SetGoHome(messageTitle, Localiser["msg.error.system"])); } // Create new item if required. if (opportunity == null) { opportunity = ActivityMgr.CreateOrganisationOpportunity(organisationId); disposableItems.Add(opportunity); } // Populate item properties. if (model.OpportunityRegionId != null) opportunity.RegionIdPrimary = model.OpportunityRegionId.ToSysId(); if (model.OpportunitySportId != null) opportunity.SportIdPrimary = model.OpportunitySportId.ToSysId(); if (model.OpportunityTypeCode != null) opportunity.OpportunityType = (Sax.OpportunityType)OpportunityTypeCodes.GetTypeForCode(model.OpportunityTypeCode); if (model.OpportunityPosition != null) opportunity.Position = model.OpportunityPosition; if (model.OpportunityOutline != null) opportunity.Outline = model.OpportunityOutline; if (model.OpportunityStatusCode != null) opportunity.Status = model.OpportunityStatus; // Store item. if (!SysId.IsValid(opportunity.Id)) { if (!ActivityMgr.InsertOrganisationOpportunity(opportunity, DbUpdateInfo)) { SaLogger.Warn(fn + " Failed to insert opportunity: " + ActivityMgr.ErrorStateMessage); return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.item.insert.failed"])); } } else { if (!ActivityMgr.UpdateOrganisationOpportunity(opportunity, DbUpdateInfo)) { SaLogger.Warn(fn + " Failed to update opportunity [Id:" + SysId.ToString(opportunity.Id) + "]: " + ActivityMgr.ErrorStateMessage); return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.item.update.failed"])); } } // Store Opportunity Activity Index data. ActivityConsole.StoreActivityIndex(opportunity, DbUpdateInfo); // Construct response. PopulateOpportunityResponseData(model, opportunity, responseData.Opportunity); } // Complete response. responseData.Success = true; return Json(responseData); } //------------------------------------------------------------------- } //======================================================================= }