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. public class OpportunityData_List { public String Id { get; set; } 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; } public String CreatedOnFmt { get; set; } public String StatusCode { get; set; } public String StatusDesc { get; set; } } public 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 = DateUtil.Format(opportunity.CreateStamp.On, "d-MMM-yyyy"); data.PublishedOnFmt = DateUtil.Format(opportunity.PublishedAt, "d-MMM-yyyy"); data.ExpiresOnFmt = DateUtil.Format(opportunity.ExpiresAt, "d-MMM-yyyy"); 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. //------------------------------------------------------------------- public class AjaxResponse_OpportunityList : AjaxResponse_Data { 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(); // Validate session and referrer. if (!ValidReferer) return Forbid(); if (!ValidUserSession) return GetAjaxResult_InvalidSession(responseData); // Organisation. SysId organisationId = model.Filter.OrganisationId.ToSysId(); 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.StatusCat = SaxUserOrganisation.StatusCat.ActiveOnly; SaxUserOrganisation userOrganisation = AccountMgr.GetUserOrganisation(prmUserOrganisation); // User details. responseData.User.CanManage = userOrganisation?.OrganisationRoles.Contains(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.DataItemTotal = (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. model.DataItemCount = 0; using (DbResultSet resultSet = ActivityMgr.ExecuteOrganisationOpportunityQuery(columns, prmOpportunity)) { while (resultSet != null && resultSet.HasRows && resultSet.NextRecord()) { model.DataItemCount++; 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 = DateUtil.Format(values.GetDateTime(colCreatedOn.DataName), "d-MMM-yyyy"), PublishedOnFmt = DateUtil.Format(values.GetDateTime(colPublishedOn.DataName), "d-MMM-yyyy"), ExpiresOnFmt = DateUtil.Format(values.GetDateTime(colExpiresOn.DataName), "d-MMM-yyyy"), StatusCode = values.GetString(colStatus.DataName), StatusDesc = SacsSystem.GetStatusDescForCode(values.GetString(colStatus.DataName)) }; responseData.Opportunities.Add(opportunityData); } } } // Complete response. responseData.SetPaging(model); responseData.Success = true; return Json(responseData); } //------------------------------------------------------------------- // Get Opportunity ajax request. //------------------------------------------------------------------- public class AjaxResponse_Opportunity : AjaxResponse_Data { 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(); // 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. 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. 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); 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(); // 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"])); } // Retrieve existing item. SaxOrganisationOpportunity opportunity = ActivityMgr.GetOrganisationOpportunityById(opportunityId); 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); 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 not 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); // 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"] + "\n\n" + ActivityMgr.ErrorStateMessage)); } } 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"] + "\n\n" + ActivityMgr.ErrorStateMessage)); } } // Store Opportunity Activity Index data. ActivityConsole.StoreActivityIndex(opportunity, DbUpdateInfo); // Construct response. PopulateOpportunityResponseData(model, opportunity, responseData.Opportunity); responseData.Success = true; return Json(responseData); } //------------------------------------------------------------------- } //======================================================================= }