Web app logon.
This commit is contained in:
@@ -154,7 +154,6 @@ namespace Sarand.BusinessMgr.Net.Core.Procs.Consoles
|
||||
//----------------------------------------------------------------
|
||||
// Log process definition.
|
||||
SaLogger.Info("Running process: " + processDfn.ProcessName + "." + (processDfn.Params.Count > 0 ? " Params: " + processDfn.Params.Concat() : ""), true);
|
||||
SbmProcessConsole_Notifier processNotifier = new SbmProcessConsole_Notifier();
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// Hapag-Lloyd EDI.
|
||||
@@ -170,7 +169,6 @@ namespace Sarand.BusinessMgr.Net.Core.Procs.Consoles
|
||||
configInterface.ImportNotifications = true;
|
||||
configInterface.Automated = true;
|
||||
SbmInterface_System_HapagLloyd_Import process = new SbmInterface_System_HapagLloyd_Import(configInterface);
|
||||
process.ProcessNotifier = processNotifier;
|
||||
process.RunProcess();
|
||||
if (process.HasProcessError())
|
||||
SaLogger.Warn(caption + " reported: " + process.GetProcessError(), true);
|
||||
@@ -219,20 +217,4 @@ namespace Sarand.BusinessMgr.Net.Core.Procs.Consoles
|
||||
//-------------------------------------------------------------------
|
||||
}
|
||||
//=======================================================================
|
||||
/// <summary>
|
||||
/// Process Notificer for Process Console.
|
||||
/// </summary>
|
||||
class SbmProcessConsole_Notifier : ISacsProcessNotifier
|
||||
{
|
||||
public void OnStartProcess()
|
||||
{
|
||||
}
|
||||
public void OnEndProcess()
|
||||
{
|
||||
}
|
||||
public void SetProgressInfo(List<string> progressInfo)
|
||||
{
|
||||
}
|
||||
}
|
||||
//=======================================================================
|
||||
}
|
||||
|
||||
@@ -78,6 +78,10 @@ namespace Sarand.BusinessMgr.Net.Core.Procs.Interfaces
|
||||
{
|
||||
this.config = config;
|
||||
interfaceObj = InterfaceConsole.GetInterfaceById(config.InterfaceId);
|
||||
// Events.
|
||||
base.OnProcessStarting += SbmInterfaceProcess_OnProcessStarting;
|
||||
base.OnProgressInfoUpdated += SbmInterfaceProcess_OnProgressInfoUpdated;
|
||||
base.OnProcessCompleted += SbmInterfaceProcess_OnProcessCompleted;
|
||||
}
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
@@ -132,16 +136,19 @@ namespace Sarand.BusinessMgr.Net.Core.Procs.Interfaces
|
||||
//-------------------------------------------------------------------
|
||||
// P r o c e s s i n g E v e n t s
|
||||
//-------------------------------------------------------------------
|
||||
protected override void OnProcessStarting()
|
||||
private void SbmInterfaceProcess_OnProcessStarting(object sender, ProcessStartingEventArgs e)
|
||||
{
|
||||
base.OnProcessStarting();
|
||||
if (config.InterfaceProcessCreation == InterfaceProcessCreation.OnStartProcessing)
|
||||
OpenInterfaceProcess();
|
||||
}
|
||||
protected override void OnProcessEnding()
|
||||
|
||||
private void SbmInterfaceProcess_OnProgressInfoUpdated(object sender, ProgressInfoUpdatedEventArgs e)
|
||||
{
|
||||
}
|
||||
|
||||
private void SbmInterfaceProcess_OnProcessCompleted(object sender, ProcessCompletedEventArgs e)
|
||||
{
|
||||
CloseInterfaceProcess();
|
||||
base.OnProcessEnding();
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
@@ -176,13 +183,13 @@ namespace Sarand.BusinessMgr.Net.Core.Procs.Interfaces
|
||||
{
|
||||
// Process has not completed.
|
||||
interfaceProcess.Status = SaStatus.Cancelled;
|
||||
if (HasProcessError()) LogInterfaceProcessMessage(GetProcessError(), SaMessageLevel.Error);
|
||||
if (HasErrorMessage()) LogInterfaceProcessMessage(GetErrorMessage(), SaMessageLevel.Error);
|
||||
if (IsInterrupted) LogInterfaceProcessMessage("Processing cancelled by user", SaMessageLevel.Warning);
|
||||
}
|
||||
if (InterfaceConsole.StoreInterfaceProcess(interfaceProcess, DbUpdateInfo))
|
||||
{ }
|
||||
else if (!HasProcessError())
|
||||
SetProcessError("Failed to store interface process: " + InterfaceConsole.ErrorStateMessage);
|
||||
else if (!HasErrorMessage())
|
||||
AddErrorMessage("Failed to store interface process: " + InterfaceConsole.ErrorStateMessage);
|
||||
|
||||
// Clean-up.
|
||||
interfaceProcess.Dispose();
|
||||
@@ -229,7 +236,7 @@ namespace Sarand.BusinessMgr.Net.Core.Procs.Interfaces
|
||||
|
||||
// Store interface data item.
|
||||
if (!InterfaceConsole.StoreInterfaceDataItem(interfaceDataItem, DbUpdateInfo))
|
||||
SetProcessError("Failed to save Interface data item" + (!StringUtil.IsEmpty(itemCaption) ? " for " + itemCaption : "") + " - " + InterfaceConsole.ErrorStateMessage);
|
||||
AddErrorMessage("Failed to save Interface data item" + (!StringUtil.IsEmpty(itemCaption) ? " for " + itemCaption : "") + " - " + InterfaceConsole.ErrorStateMessage);
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ namespace Sarand.BusinessMgr.Net.Core.Procs.Interfaces
|
||||
// Configuration.
|
||||
public new class Config : SbmInterfaceProcess.Config
|
||||
{
|
||||
public Config (ISbmUserContext userContext) : base(userContext)
|
||||
public Config(ISbmUserContext userContext) : base(userContext)
|
||||
{
|
||||
ItemType = Sbm.ItemType.Commodity;
|
||||
ProcessType = ProcessType.ExportData;
|
||||
@@ -117,12 +117,12 @@ namespace Sarand.BusinessMgr.Net.Core.Procs.Interfaces
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Construction.
|
||||
public SbmInterfaceProcess_Commodity_Export (Config config) : base(config)
|
||||
public SbmInterfaceProcess_Commodity_Export(Config config) : base(config)
|
||||
{
|
||||
this.config = config;
|
||||
interfaceOptions = SbmSystem.GetCodesOfType(UserContext, Sbm.SystemCode.InterfaceOption);
|
||||
}
|
||||
protected override void Dispose (bool disposing)
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing)
|
||||
{
|
||||
@@ -159,7 +159,7 @@ namespace Sarand.BusinessMgr.Net.Core.Procs.Interfaces
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Utilities.
|
||||
private void CalculateItemCount ()
|
||||
private void CalculateItemCount()
|
||||
{
|
||||
if (Params.CommodityCountTotal >= 0 || !OK) return;
|
||||
Params.CommodityCountTotal = CommodityMgr.GetCommodityCount(GetParams());
|
||||
@@ -168,7 +168,7 @@ namespace Sarand.BusinessMgr.Net.Core.Procs.Interfaces
|
||||
//-------------------------------------------------------------------
|
||||
// I n t e r f a c e P a r a m e t e r s
|
||||
//-------------------------------------------------------------------
|
||||
private bool PopulateInterfaceParams ()
|
||||
private bool PopulateInterfaceParams()
|
||||
{
|
||||
interfaceParams = new InterfaceParams();
|
||||
|
||||
@@ -230,7 +230,7 @@ namespace Sarand.BusinessMgr.Net.Core.Procs.Interfaces
|
||||
int columnPos = StringUtil.ToInt(columnOption.Context);
|
||||
SbmCommodity.Column eCol = (SbmCommodity.Column)optionValues_Column.GetTypeForCode(columnOption.Value);
|
||||
if (columnPos <= previousColumnPos)
|
||||
return SetProcessError("Out of sequence column found in configuration: '" + columnOption.Value + "' for column '" + columnOption.Context + "'");
|
||||
return AddErrorMessage("Out of sequence column found in configuration: '" + columnOption.Value + "' for column '" + columnOption.Context + "'");
|
||||
if (columnPos > 0 && columnPos <= kiMaxDataColumn)
|
||||
{
|
||||
ColumnDfn col = CommodityMgr.GetCommodityColumnDfn(eCol);
|
||||
@@ -241,9 +241,9 @@ namespace Sarand.BusinessMgr.Net.Core.Procs.Interfaces
|
||||
interfaceParams.Columns.Add(columnNull);
|
||||
interfaceParams.Columns[columnPos - 1] = col;
|
||||
}
|
||||
else return SetProcessError("Invalid field specified in configuration: '" + columnOption.Value + "' for column '" + columnOption.Context + "'");
|
||||
else return AddErrorMessage("Invalid field specified in configuration: '" + columnOption.Value + "' for column '" + columnOption.Context + "'");
|
||||
}
|
||||
else return SetProcessError("Invalid column specified in configuration: '" + columnOption.Value + "'");
|
||||
else return AddErrorMessage("Invalid column specified in configuration: '" + columnOption.Value + "'");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -251,7 +251,7 @@ namespace Sarand.BusinessMgr.Net.Core.Procs.Interfaces
|
||||
//-------------------------------------------------------------------
|
||||
// P r o c e s s i n g
|
||||
//-------------------------------------------------------------------
|
||||
protected override bool Run ()
|
||||
protected override bool Run()
|
||||
{
|
||||
SetProgress("Preparing to export commodities.");
|
||||
SaLogger.Info("Process: " + ProcessDescription);
|
||||
@@ -265,17 +265,17 @@ namespace Sarand.BusinessMgr.Net.Core.Procs.Interfaces
|
||||
ExportCommodityData_Csv();
|
||||
else if (interfaceParams.ExportMode == Sbm.FileInterface_Mode.MsExcel)
|
||||
ExportCommodityData_Excel();
|
||||
else return SetProcessError("Invalid Commodity export mode: " + interfaceParams.ExportMode.ToString());
|
||||
else return AddErrorMessage("Invalid Commodity export mode: " + interfaceParams.ExportMode.ToString());
|
||||
|
||||
// Log statistics.
|
||||
int commoditiesExported = GetStatistic(ProcessingStatistic.CommoditiesExported);
|
||||
if (commoditiesExported > 0) LogInterfaceProcessMessage("Commodites exported: " + commoditiesExported.ToString());
|
||||
|
||||
return !HasProcessError();
|
||||
return !HasErrorMessage();
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
protected override void ResetProcess ()
|
||||
protected override void ResetProcess()
|
||||
{
|
||||
base.ResetProcess();
|
||||
|
||||
@@ -288,42 +288,42 @@ namespace Sarand.BusinessMgr.Net.Core.Procs.Interfaces
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
protected override bool ValidateConfig ()
|
||||
protected override bool ValidateConfig()
|
||||
{
|
||||
if (!base.ValidateConfig()) return false;
|
||||
|
||||
// Configuration:
|
||||
if (!SysId.IsValid(config.InterfaceId)) return SetProcessError("Interface Id must be supplied.");
|
||||
if (!config.ExportCommodities) return SetProcessError("No processing options selected.");
|
||||
if (!SysId.IsValid(config.InterfaceId)) return AddErrorMessage("Interface Id must be supplied.");
|
||||
if (!config.ExportCommodities) return AddErrorMessage("No processing options selected.");
|
||||
|
||||
// Processing parameters.
|
||||
if (!PopulateInterfaceParams()) return false;
|
||||
if (interfaceParams.ExportMode <= 0) return SetProcessError("Invalid export mode specified.");
|
||||
if (interfaceParams.ExportMode <= 0) return AddErrorMessage("Invalid export mode specified.");
|
||||
if (interfaceParams.ExportMode == Sbm.FileInterface_Mode.Csv && StringUtil.IsEmpty(interfaceParams.OutputFolder))
|
||||
return SetProcessError("Output folder must be specified for 'CSV' mode.");
|
||||
return AddErrorMessage("Output folder must be specified for 'CSV' mode.");
|
||||
|
||||
if (interfaceParams.FirstDataRow < 1 || interfaceParams.FirstDataRow > 100)
|
||||
return SetProcessError("Invalid first data row (" + (interfaceParams.FirstDataRow) + ")");
|
||||
return AddErrorMessage("Invalid first data row (" + (interfaceParams.FirstDataRow) + ")");
|
||||
|
||||
// Validate the output folder.
|
||||
if (!StringUtil.IsEmpty(interfaceParams.OutputFolder) && !DirectoryUtil.DirectoryExists(interfaceParams.OutputFolder))
|
||||
return SetProcessError("Invalid export folder specified - " + interfaceParams.OutputFolder);
|
||||
return AddErrorMessage("Invalid export folder specified - " + interfaceParams.OutputFolder);
|
||||
|
||||
if (interfaceParams.Columns.Count < 1)
|
||||
return SetProcessError("At least one data column must be specified");
|
||||
return AddErrorMessage("At least one data column must be specified");
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
/// <summary>Construct the commodity filter parameters.</summary>
|
||||
public SbmCommodity.Params GetParams ()
|
||||
public SbmCommodity.Params GetParams()
|
||||
{
|
||||
SbmCommodity.Params prmCommodity = config.CommodityParams ?? new SbmCommodity.Params();
|
||||
prmCommodity.IncludedIds.AddRange(config.ItemIds);
|
||||
return prmCommodity;
|
||||
}
|
||||
private DbResultSet ExecuteQuery ()
|
||||
private DbResultSet ExecuteQuery()
|
||||
{
|
||||
if (!OK) return null;
|
||||
|
||||
@@ -333,12 +333,12 @@ namespace Sarand.BusinessMgr.Net.Core.Procs.Interfaces
|
||||
if (!queryColumns.HasId(SbmCommodity.Column.Id)) queryColumns.Add(CommodityMgr.GetCommodityColumnDfn(SbmCommodity.Column.Id));
|
||||
if (!queryColumns.HasId(SbmCommodity.Column.Code)) queryColumns.Add(CommodityMgr.GetCommodityColumnDfn(SbmCommodity.Column.Code));
|
||||
// Query data.
|
||||
SbmCommodity.Params prmCommodity =GetParams();
|
||||
SbmCommodity.Params prmCommodity = GetParams();
|
||||
DbResultSet resultSet = CommodityMgr.ExecuteCommodityQuery(queryColumns, prmCommodity);
|
||||
if (resultSet == null) SetProcessError("Failed to query data - " + CommodityMgr.ErrorStateMessage);
|
||||
if (resultSet == null) AddErrorMessage("Failed to query data - " + CommodityMgr.ErrorStateMessage);
|
||||
return resultSet;
|
||||
}
|
||||
private DataValue GetDataValue (ColumnDfn column, NamedValue.Map values)
|
||||
private DataValue GetDataValue(ColumnDfn column, NamedValue.Map values)
|
||||
{
|
||||
DataValue value = new DataValue();
|
||||
SbmCommodity.Column columnId = (SbmCommodity.Column)column.Id;
|
||||
@@ -362,7 +362,7 @@ namespace Sarand.BusinessMgr.Net.Core.Procs.Interfaces
|
||||
//-------------------------------------------------------------------
|
||||
// E x p o r t T o C S V
|
||||
//-------------------------------------------------------------------
|
||||
private bool ExportCommodityData_Csv ()
|
||||
private bool ExportCommodityData_Csv()
|
||||
{
|
||||
String fn = this.GetFn("ExportCommodityData_Csv");
|
||||
if (!OK) return false;
|
||||
@@ -374,10 +374,10 @@ namespace Sarand.BusinessMgr.Net.Core.Procs.Interfaces
|
||||
{
|
||||
// Progress is refreshed every few rows.
|
||||
Params.CommodityCountTotal = CommodityMgr.GetCommodityCount(GetParams());
|
||||
int progressRefreshRows = (int)Math.Max(5,Params.CommodityCountTotal/(Params.CommodityCountTotal>1000?1000:100));
|
||||
int progressRefreshRows = (int)Math.Max(5, Params.CommodityCountTotal / (Params.CommodityCountTotal > 1000 ? 1000 : 100));
|
||||
|
||||
// Open the output file.
|
||||
String sFilename = FileUtil.FormatFilename("SaBusMgr_CommodityExport_" + DateUtil.Format(DateTime.Now,"yyyyMMddHHmmss") + ".csv");
|
||||
String sFilename = FileUtil.FormatFilename("SaBusMgr_CommodityExport_" + DateUtil.Format(DateTime.Now, "yyyyMMddHHmmss") + ".csv");
|
||||
String sOutputPath = interfaceParams.OutputFolder + FileUtil.GetPathDelim(interfaceParams.OutputFolder) + sFilename;
|
||||
using (StreamWriter textWriter = new StreamWriter(sFilename, false))
|
||||
{
|
||||
@@ -390,8 +390,8 @@ namespace Sarand.BusinessMgr.Net.Core.Procs.Interfaces
|
||||
SetProgress(progressPrefix + "\nQuerying data");
|
||||
using (DbResultSet resultSet = ExecuteQuery())
|
||||
{
|
||||
if (resultSet.HasErrorState()) return SetProcessError(resultSet.ErrorState.Message);
|
||||
if (resultSet == null) return SetProcessError("Failed to query commodity data");
|
||||
if (resultSet.HasErrorState()) return AddErrorMessage(resultSet.ErrorState.Message);
|
||||
if (resultSet == null) return AddErrorMessage("Failed to query commodity data");
|
||||
while (OK && resultSet != null && resultSet.NextRecord())
|
||||
{
|
||||
Params.ItemBeingExported++;
|
||||
@@ -416,7 +416,7 @@ namespace Sarand.BusinessMgr.Net.Core.Procs.Interfaces
|
||||
catch (Exception exc)
|
||||
{
|
||||
SaLogger.Warn(fn + " " + ExceptionUtil.GetLogMessage(exc));
|
||||
return SetProcessError(ExceptionUtil.GetErrorStateMessage(exc));
|
||||
return AddErrorMessage(ExceptionUtil.GetErrorStateMessage(exc));
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
@@ -424,7 +424,7 @@ namespace Sarand.BusinessMgr.Net.Core.Procs.Interfaces
|
||||
//-------------------------------------------------------------------
|
||||
// E x p o r t T o E x c e l
|
||||
//-------------------------------------------------------------------
|
||||
private bool ExportCommodityData_Excel ()
|
||||
private bool ExportCommodityData_Excel()
|
||||
{
|
||||
String fn = this.GetFn("ExportCommodityData_Excel");
|
||||
if (!OK) return false;
|
||||
@@ -438,14 +438,15 @@ namespace Sarand.BusinessMgr.Net.Core.Procs.Interfaces
|
||||
using (SaMsSpreadsheet spreadsheet = new SaMsSpreadsheet_POI())
|
||||
{
|
||||
spreadsheet.CreateWorkbook();
|
||||
|
||||
SaMsExcelStyleAttr attrSheet = new SaMsExcelStyleAttr();
|
||||
attrSheet.FontAttr.Name = interfaceParams.Font_Name;
|
||||
attrSheet.FontAttr.HeightInPoints = interfaceParams.Font_Size_Data;
|
||||
spreadsheet.ApplyDefaultStyle(attrSheet);
|
||||
|
||||
spreadsheet.SetWorksheetCount(1);
|
||||
OpenWorkSheet(spreadsheet, 1, "Commodities");
|
||||
|
||||
SaMsExcelItemAttr attrSheet = new SaMsExcelItemAttr();
|
||||
attrSheet.FontName = interfaceParams.Font_Name;
|
||||
attrSheet.FontSize = interfaceParams.Font_Size_Data;
|
||||
spreadsheet.SetWorksheetAttr(attrSheet);
|
||||
|
||||
// Margins.
|
||||
SaMsExcelPageSetup_Config cfgPageSetup = new SaMsExcelPageSetup_Config();
|
||||
cfgPageSetup.Unit = SaExcelLogicalUnit.Cm;
|
||||
@@ -462,14 +463,14 @@ namespace Sarand.BusinessMgr.Net.Core.Procs.Interfaces
|
||||
{
|
||||
SetProgress(progressPrefix + "\nPopulating column headers");
|
||||
SaMsExcelColumnHeading_Config cfgHeadings = new SaMsExcelColumnHeading_Config();
|
||||
cfgHeadings.HeadingFontSize = interfaceParams.Font_Size_Header;
|
||||
cfgHeadings.FirstHeadingRow = Params.FirstDataRow;
|
||||
cfgHeadings.FontAttr.HeightInPoints = interfaceParams.Font_Size_Header;
|
||||
cfgHeadings.FirstHeadingRowPos = Params.FirstDataRow;
|
||||
int colPos_Code = interfaceParams.Columns.GetPosForId(SbmCommodity.Column.Code);
|
||||
if (colPos_Code > 0)
|
||||
Params.FreezeColumn = (uint)(colPos_Code + Params.FirstDataColumn);
|
||||
cfgHeadings.FreezeColumn = Params.FreezeColumn;
|
||||
cfgHeadings.FreezeColPos = Params.FreezeColumn;
|
||||
if (interfaceParams.BackgroundColour_Header != -1)
|
||||
cfgHeadings.InteriorColour = interfaceParams.BackgroundColour_Header;
|
||||
cfgHeadings.ForegroundColourRGB = interfaceParams.BackgroundColour_Header;
|
||||
spreadsheet.SetColumnHeadings(interfaceParams.Columns, cfgHeadings);
|
||||
Params.FirstDataRow++;
|
||||
}
|
||||
@@ -488,28 +489,28 @@ namespace Sarand.BusinessMgr.Net.Core.Procs.Interfaces
|
||||
catch (Exception exc)
|
||||
{
|
||||
SaLogger.Warn(fn + " " + ExceptionUtil.GetLogMessage(exc));
|
||||
return SetProcessError(ExceptionUtil.GetErrorStateMessage(exc));
|
||||
return AddErrorMessage(ExceptionUtil.GetErrorStateMessage(exc));
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
private bool ExportDataToExcel (SaMsSpreadsheet spreadsheet, String progressPrefix)
|
||||
private bool ExportDataToExcel(SaMsSpreadsheet spreadsheet, String progressPrefix)
|
||||
{
|
||||
if (!OK) return false;
|
||||
String dataName_Code = CommodityMgr.GetCommodityColumnDfn(SbmCommodity.Column.Code).DataName;
|
||||
|
||||
// Progress is refreshed every few rows.
|
||||
Params.CommodityCountTotal = CommodityMgr.GetCommodityCount(GetParams());
|
||||
int progressRefreshRows = (int)Math.Max(5,Params.CommodityCountTotal/(Params.CommodityCountTotal>1000?1000:100));
|
||||
int progressRefreshRows = (int)Math.Max(5, Params.CommodityCountTotal / (Params.CommodityCountTotal > 1000 ? 1000 : 100));
|
||||
|
||||
// Query data.
|
||||
SetProgress(progressPrefix + "\nQuerying data");
|
||||
using (DbResultSet resultSet = ExecuteQuery())
|
||||
{
|
||||
if (resultSet.HasErrorState()) return SetProcessError(resultSet.ErrorState.Message);
|
||||
if (resultSet == null) return SetProcessError("Failed to query commodity data");
|
||||
if (resultSet.HasErrorState()) return AddErrorMessage(resultSet.ErrorState.Message);
|
||||
if (resultSet == null) return AddErrorMessage("Failed to query commodity data");
|
||||
while (OK && resultSet != null && resultSet.NextRecord())
|
||||
{
|
||||
Params.ItemBeingExported++;
|
||||
@@ -544,50 +545,50 @@ namespace Sarand.BusinessMgr.Net.Core.Procs.Interfaces
|
||||
case SbmCommodity.Column.Id:
|
||||
break;
|
||||
case SbmCommodity.Column.Image:
|
||||
{
|
||||
// Retrieve the image path.
|
||||
String sImagePath = GetDataValue(columnDfn, values).ToString();
|
||||
// Configure image.
|
||||
SaMsExcelImage_Config cfgImg = new SaMsExcelImage_Config();
|
||||
cfgImg.ImagePath = CommodityMgr.GetActualImagePath(sImagePath);
|
||||
cfgImg.ColPos = colPos;
|
||||
cfgImg.RowPos = rowPos;
|
||||
cfgImg.Unit = SaExcelLogicalUnit.Cm;
|
||||
if (FileUtil.IsFile(cfgImg.ImagePath))
|
||||
{
|
||||
if (interfaceParams.DataRowHeightCm > 0)
|
||||
cfgImg.TargetHeight = interfaceParams.DataRowHeightCm;
|
||||
spreadsheet.InsertImage(cfgImg);
|
||||
// Retrieve the image path.
|
||||
String sImagePath = GetDataValue(columnDfn, values).ToString();
|
||||
// Configure image.
|
||||
SaMsExcelImage_Config cfgImg = new SaMsExcelImage_Config();
|
||||
cfgImg.ImagePath = CommodityMgr.GetActualImagePath(sImagePath);
|
||||
cfgImg.ColPos = colPos;
|
||||
cfgImg.RowPos = rowPos;
|
||||
cfgImg.Unit = SaExcelLogicalUnit.Cm;
|
||||
if (FileUtil.IsFile(cfgImg.ImagePath))
|
||||
{
|
||||
if (interfaceParams.DataRowHeightCm > 0)
|
||||
cfgImg.TargetHeight = interfaceParams.DataRowHeightCm;
|
||||
spreadsheet.InsertImage(cfgImg);
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SbmCommodity.Column.BarcodeImage:
|
||||
{
|
||||
SaMsExcelImage_Config cfgImg = new SaMsExcelImage_Config();
|
||||
cfgImg.ImagePath = CommodityMgr.GetBarcodeImagePath(commodityCode);
|
||||
cfgImg.ColPos = colPos;
|
||||
cfgImg.RowPos = rowPos;
|
||||
cfgImg.Unit = SaExcelLogicalUnit.Cm;
|
||||
if (FileUtil.IsFile(cfgImg.ImagePath))
|
||||
{
|
||||
if (interfaceParams.DataRowHeightCm > 0)
|
||||
cfgImg.TargetHeight = interfaceParams.DataRowHeightCm;
|
||||
spreadsheet.InsertImage(cfgImg);
|
||||
SaMsExcelImage_Config cfgImg = new SaMsExcelImage_Config();
|
||||
cfgImg.ImagePath = CommodityMgr.GetBarcodeImagePath(commodityCode);
|
||||
cfgImg.ColPos = colPos;
|
||||
cfgImg.RowPos = rowPos;
|
||||
cfgImg.Unit = SaExcelLogicalUnit.Cm;
|
||||
if (FileUtil.IsFile(cfgImg.ImagePath))
|
||||
{
|
||||
if (interfaceParams.DataRowHeightCm > 0)
|
||||
cfgImg.TargetHeight = interfaceParams.DataRowHeightCm;
|
||||
spreadsheet.InsertImage(cfgImg);
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
cellValue = GetDataValue(columnDfn, values);
|
||||
if (!columnDfn.ShowZeroValues && cellValue.IsNumeric() && cellValue.ToNumeric() == 0.0)
|
||||
cellValue = new DataValue(); // Blank value.
|
||||
break;
|
||||
}
|
||||
{
|
||||
cellValue = GetDataValue(columnDfn, values);
|
||||
if (!columnDfn.ShowZeroValues && cellValue.IsNumeric() && cellValue.ToNumeric() == 0.0)
|
||||
cellValue = new DataValue(); // Blank value.
|
||||
break;
|
||||
}
|
||||
}
|
||||
cellValues.Add(cellValue);
|
||||
}
|
||||
// Populate values to spreadesheet row.
|
||||
spreadsheet.SetRangeFormulas(new SaMsExcelRange(Params.FirstDataColumn, rowPos, (uint)(Params.FirstDataColumn + cellValues.Count - 1), rowPos), cellValues.ToObjectList());
|
||||
spreadsheet.SetRangeValues(new SaMsExcelRange(Params.FirstDataColumn, rowPos, (uint)(Params.FirstDataColumn + cellValues.Count - 1), rowPos), cellValues);
|
||||
IncrementStatistic(ProcessingStatistic.CommoditiesExported);
|
||||
//if (Params.ItemBeingExported >= 10) break;
|
||||
}
|
||||
@@ -600,7 +601,7 @@ namespace Sarand.BusinessMgr.Net.Core.Procs.Interfaces
|
||||
// P r o g r e s s I n f o r m a t i o n
|
||||
//-------------------------------------------------------------------
|
||||
// Display progress information - redirected to dialog:
|
||||
protected void SetProgress (String message)
|
||||
protected void SetProgress(String message)
|
||||
{
|
||||
// Progress message:
|
||||
List<String> progressMessages = new List<string>();
|
||||
@@ -620,7 +621,7 @@ namespace Sarand.BusinessMgr.Net.Core.Procs.Interfaces
|
||||
//-------------------------------------------------------------------
|
||||
// I n t e r f a c e I t e m O p t i o n s
|
||||
//-------------------------------------------------------------------
|
||||
public List<SaItemOptionDfn> GetInterfaceItemOptionDfns ()
|
||||
public List<SaItemOptionDfn> GetInterfaceItemOptionDfns()
|
||||
{
|
||||
InitOptionDefinitions();
|
||||
List<SaItemOptionDfn> interfaceOptionDfns = new List<SaItemOptionDfn>();
|
||||
@@ -648,7 +649,7 @@ namespace Sarand.BusinessMgr.Net.Core.Procs.Interfaces
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
private void InitOptionDefinitions ()
|
||||
private void InitOptionDefinitions()
|
||||
{
|
||||
if (optionContexts_Value == null)
|
||||
{
|
||||
@@ -1019,7 +1020,7 @@ namespace Sarand.BusinessMgr.Net.Core.Procs.Interfaces
|
||||
}
|
||||
}
|
||||
}
|
||||
private bool AddColumnValue (SbmCommodity.Column eCol, String sCode, String sDesc)
|
||||
private bool AddColumnValue(SbmCommodity.Column eCol, String sCode, String sDesc)
|
||||
{
|
||||
return AddColumnValue(eCol, sCode, sDesc, null, null, null);
|
||||
}
|
||||
@@ -1073,7 +1074,7 @@ namespace Sarand.BusinessMgr.Net.Core.Procs.Interfaces
|
||||
Export_Commodities,
|
||||
}
|
||||
/// <summary>Configure processing options.</summary>
|
||||
public static List<SaProcess_Base.GroupData> GetProcessingOptions (ISbmUserContext userContext, SaInterface interfaceObj)
|
||||
public static List<SaProcess_Base.GroupData> GetProcessingOptions(ISbmUserContext userContext, SaInterface interfaceObj)
|
||||
{
|
||||
List<SaProcess_Base.GroupData> optionGroups = new List<SaProcess_Base.GroupData>();
|
||||
|
||||
@@ -1088,7 +1089,7 @@ namespace Sarand.BusinessMgr.Net.Core.Procs.Interfaces
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
/// <summary>Process interface using selected options.</summary>
|
||||
public static SbmInterfaceProcess ConfigureProcess (ISbmUserContext userContext, SaInterface interfaceObj, SaProcess_Base.GroupData processGroup)
|
||||
public static SbmInterfaceProcess ConfigureProcess(ISbmUserContext userContext, SaInterface interfaceObj, SaProcess_Base.GroupData processGroup)
|
||||
{
|
||||
if (processGroup.OptionGroup.Type == (int)InterfaceProcessGroup.Export)
|
||||
{
|
||||
|
||||
@@ -81,7 +81,7 @@ namespace Sarand.BusinessMgr.Net.Core.Procs.Procs
|
||||
catch (Exception exc)
|
||||
{
|
||||
SaLogger.Warn(fn + " " + exc.GetType().Name + ": " + exc.Message, true);
|
||||
return SetProcessError("Unable to connect to FTP host");
|
||||
return AddErrorMessage("Unable to connect to FTP host");
|
||||
}
|
||||
finally
|
||||
{
|
||||
|
||||
@@ -38,7 +38,7 @@ namespace Sarand.BusinessMgr.Net.Core.Procs.Procs
|
||||
}
|
||||
public new class Config : SaProcess.Config
|
||||
{
|
||||
protected Config(ISbmUserContext userContext) : base()
|
||||
protected Config(ISbmUserContext userContext) : base(userContext.DbUpdateInfo)
|
||||
{
|
||||
UserContext = userContext;
|
||||
}
|
||||
|
||||
@@ -221,7 +221,7 @@ namespace Sarand.BusinessMgr.Net.Core.Procs.Procs
|
||||
// ToDo Save Folder...
|
||||
String saveFolder = ""; //GetOption_SaveFolder();
|
||||
if (OK && !StringUtil.IsEmpty(saveFolder) && !DirectoryUtil.DirectoryExists(saveFolder))
|
||||
SetProcessError("Invalid output folder specified.");
|
||||
AddErrorMessage("Invalid output folder specified.");
|
||||
|
||||
// Perform export.
|
||||
if (OK)
|
||||
@@ -248,11 +248,11 @@ namespace Sarand.BusinessMgr.Net.Core.Procs.Procs
|
||||
if (!OK) return false;
|
||||
|
||||
// Validate environment.
|
||||
if (CommodityMgr == null) return SetProcessError("Unable to initialise commodity manager");
|
||||
if (ProcessMgr == null) return SetProcessError("Unable to initialise process manager");
|
||||
if (ReferenceDataConsole == null) return SetProcessError("Reference data console not available");
|
||||
if (CommodityMgr == null) return AddErrorMessage("Unable to initialise commodity manager");
|
||||
if (ProcessMgr == null) return AddErrorMessage("Unable to initialise process manager");
|
||||
if (ReferenceDataConsole == null) return AddErrorMessage("Reference data console not available");
|
||||
|
||||
if (config.DataFormat != DataFormatType.Excel) return SetProcessError("Only Excel export format supported.");
|
||||
if (config.DataFormat != DataFormatType.Excel) return AddErrorMessage("Only Excel export format supported.");
|
||||
|
||||
// Data field columns.
|
||||
Params.IncludeCol_MaterialCost = StringUtil.ToBool(GetProcessingOptionValue(OptionName_Flag, optionContexts_Flag.GetCodeForType(ProcessOptionFlag.IncludeCol_MaterialCost)));
|
||||
@@ -293,14 +293,14 @@ namespace Sarand.BusinessMgr.Net.Core.Procs.Procs
|
||||
// Headings.
|
||||
SetProgressInfo(progressPrefix + " - Populating headings");
|
||||
SaMsExcelColumnHeading_Config configHeadings = new SaMsExcelColumnHeading_Config();
|
||||
configHeadings.HeadingFontSize = 10;
|
||||
configHeadings.FirstHeadingRow = 1;
|
||||
configHeadings.InteriorColour = ColorTranslator.ToOle(ExcelColumnHeadingColor);
|
||||
configHeadings.FontAttr.HeightInPoints = 10;
|
||||
configHeadings.FirstHeadingRowPos = 1;
|
||||
configHeadings.ForegroundColourRGB = ExcelColumnHeadingColor.ToArgb();
|
||||
configHeadings.BorderWeight = SaXlBorderWeight.Thin;
|
||||
configHeadings.FreezeColumn = (uint)(displayColumns.GetPosForId(SbmCommodity.Column.Code) + 1);
|
||||
configHeadings.FreezeColPos = (uint)(displayColumns.GetPosForId(SbmCommodity.Column.Code) + 1);
|
||||
spreadsheet.SetColumnHeadings(displayColumns, configHeadings);
|
||||
|
||||
Params.HomeColumn = configHeadings.FreezeColumn + 1;
|
||||
Params.HomeColumn = configHeadings.FreezeColPos + 1;
|
||||
Params.HomeRow = Params.FirstDataRow;
|
||||
|
||||
ExportCommoditiesToExcel(spreadsheet);
|
||||
@@ -315,7 +315,7 @@ namespace Sarand.BusinessMgr.Net.Core.Procs.Procs
|
||||
catch (Exception exc)
|
||||
{
|
||||
SaLogger.Error(fn + " " + ExceptionUtil.GetLogMessage(exc));
|
||||
return SetProcessError(exc.GetType().Name + " exporting data to Excel.");
|
||||
return AddErrorMessage(exc.GetType().Name + " exporting data to Excel.");
|
||||
}
|
||||
|
||||
return OK;
|
||||
@@ -625,8 +625,8 @@ namespace Sarand.BusinessMgr.Net.Core.Procs.Procs
|
||||
|
||||
using (DbResultSet resultSet = CommodityMgr.ExecuteCommodityQuery(queryColumns, config.CommodityParams))
|
||||
{
|
||||
if (resultSet.HasErrorState()) return SetProcessError(resultSet.ErrorState.Message);
|
||||
if (resultSet == null) return SetProcessError("Failed to query commodity data");
|
||||
if (resultSet.HasErrorState()) return AddErrorMessage(resultSet.ErrorState.Message);
|
||||
if (resultSet == null) return AddErrorMessage("Failed to query commodity data");
|
||||
while (OK && resultSet != null && resultSet.NextRecord())
|
||||
{
|
||||
if (++commodityCount % progressRefreshRows == 0 || commodityCount == 1)
|
||||
@@ -670,7 +670,7 @@ namespace Sarand.BusinessMgr.Net.Core.Procs.Procs
|
||||
for (int columnIdx = 0; columnIdx < displayColumns.Count; columnIdx++)
|
||||
{
|
||||
ColumnDfn column = displayColumns[columnIdx];
|
||||
SaMsExcelItemAttr attrCell = new SaMsExcelItemAttr();
|
||||
SaMsExcelStyleAttr attrCell = new SaMsExcelStyleAttr();
|
||||
bool cellAttributesPopulated = false;
|
||||
|
||||
// Intercept specific values.
|
||||
@@ -687,8 +687,8 @@ namespace Sarand.BusinessMgr.Net.Core.Procs.Procs
|
||||
if (SacsSystem.GetStatusForCode(statusCode) != SaStatus.Current)
|
||||
{
|
||||
value = new DataValue("X");
|
||||
attrCell.Bold = true;
|
||||
attrCell.FontColourIndex = SaXlColourIndex.Red;
|
||||
attrCell.FontAttr.Bold = true;
|
||||
attrCell.FontAttr.ColourIndex = SaXlColourIndex.Red;
|
||||
cellAttributesPopulated = true;
|
||||
}
|
||||
}
|
||||
@@ -705,8 +705,8 @@ namespace Sarand.BusinessMgr.Net.Core.Procs.Procs
|
||||
value = new DataValue(availableStock);
|
||||
if (availableStock < -0.001m)
|
||||
{
|
||||
attrCell.Bold = true;
|
||||
attrCell.FontColourIndex = SaXlColourIndex.Red; //38; // Pale red (pink).
|
||||
attrCell.FontAttr.Bold = true;
|
||||
attrCell.FontAttr.ColourIndex = SaXlColourIndex.Red; //38; // Pale red (pink).
|
||||
cellAttributesPopulated = true;
|
||||
}
|
||||
}
|
||||
@@ -744,9 +744,9 @@ namespace Sarand.BusinessMgr.Net.Core.Procs.Procs
|
||||
decimal imminentAvailablePropReorder = (imminentAvailable * 100.0m) / reorderLevel;
|
||||
value = new DataValue(imminentAvailablePropReorder);
|
||||
if (imminentAvailablePropReorder < ReorderPercRed)
|
||||
attrCell.InteriorColourIndex = SaXlColourIndex.Rose;
|
||||
attrCell.ForegroundColourIndex = SaXlColourIndex.Rose;
|
||||
else if (imminentAvailablePropReorder < ReorderPercGreen)
|
||||
attrCell.InteriorColourIndex = SaXlColourIndex.Tan;
|
||||
attrCell.ForegroundColourIndex = SaXlColourIndex.Tan;
|
||||
cellAttributesPopulated = true;
|
||||
}
|
||||
}
|
||||
@@ -771,9 +771,9 @@ namespace Sarand.BusinessMgr.Net.Core.Procs.Procs
|
||||
decimal percSoldVsBudget = salesProjPeriod > 0.0m ? stockSoldPeriod / salesProjPeriod * 100.0m : 0.0m;
|
||||
value = new DataValue(stockSoldPeriod);
|
||||
if (percSoldVsBudget < BudgetPercRed)
|
||||
attrCell.InteriorColourIndex = SaXlColourIndex.Rose;
|
||||
attrCell.ForegroundColourIndex = SaXlColourIndex.Rose;
|
||||
else if (percSoldVsBudget < BudgetPercGreen)
|
||||
attrCell.InteriorColourIndex = SaXlColourIndex.Tan;
|
||||
attrCell.ForegroundColourIndex = SaXlColourIndex.Tan;
|
||||
cellAttributesPopulated = true;
|
||||
}
|
||||
}
|
||||
@@ -803,9 +803,9 @@ namespace Sarand.BusinessMgr.Net.Core.Procs.Procs
|
||||
|
||||
// Check month end stock level against reorder level.
|
||||
if (projSales.EndOfMonth < 0.0m)
|
||||
attrCell.InteriorColourIndex = SaXlColourIndex.Rose;
|
||||
attrCell.ForegroundColourIndex = SaXlColourIndex.Rose;
|
||||
else if (reorderLevel > 0.0m && projSales.EndOfMonth <= reorderLevel)
|
||||
attrCell.InteriorColourIndex = SaXlColourIndex.Tan;
|
||||
attrCell.ForegroundColourIndex = SaXlColourIndex.Tan;
|
||||
cellAttributesPopulated = true;
|
||||
}
|
||||
}
|
||||
@@ -837,16 +837,16 @@ namespace Sarand.BusinessMgr.Net.Core.Procs.Procs
|
||||
cellValues.Add(value);
|
||||
|
||||
// Populate the cell's attributes.
|
||||
if (attrCell.InteriorColourIndex != SaXlColourIndex.NotSpecified)
|
||||
if (attrCell.ForegroundColourIndex != SaXlColourIndex.NotSpecified)
|
||||
{
|
||||
attrCell.InteriorPattern = SaXlPattern.Solid;
|
||||
attrCell.InteriorPatternColourIndex = SaXlColourIndex.Automatic;
|
||||
attrCell.ForegroundColourIndex = SaXlColourIndex.Automatic;
|
||||
cellAttributesPopulated = true;
|
||||
}
|
||||
if (cellAttributesPopulated)
|
||||
spreadsheet.SetRangeAttr(new SaMsExcelRange(Params.FirstDataColumn + (uint)columnIdx, iRow), attrCell);
|
||||
}
|
||||
spreadsheet.SetRangeFormulas(new SaMsExcelRange(Params.FirstDataColumn, iRow, Params.FirstDataColumn + (uint)cellValues.Count - 1, iRow), cellValues.ToObjectList());
|
||||
spreadsheet.SetRangeValues(new SaMsExcelRange(Params.FirstDataColumn, iRow, Params.FirstDataColumn + (uint)cellValues.Count - 1, iRow), cellValues);
|
||||
IncrementStatistic(ProcessingStatistic.CommoditiesExported);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,23 +1,19 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netcoreapp3.1</TargetFramework>
|
||||
<RootNamespace>Sarand.BusinessMgr.Net.Core</RootNamespace>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<RootNamespace>Sarand.BusinessMgr.Net.Core</RootNamespace>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\..\Common-VS\Workspace\SacsStandardBase\SacsStandardBase.csproj" />
|
||||
<ProjectReference Include="..\..\..\Common-VS\Workspace\SacsStandardProc\SacsStandardProc.csproj" />
|
||||
<ProjectReference Include="..\SaBusMgrStandardBase\SaBusMgrStandardBase.csproj" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\..\Common-VS\Workspace\SacsStandardBase\SacsStandardBase.csproj" />
|
||||
<ProjectReference Include="..\..\..\Common-VS\Workspace\SacsStandardProc\SacsStandardProc.csproj" />
|
||||
<ProjectReference Include="..\SaBusMgrStandardBase\SaBusMgrStandardBase.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Folder Include="Procs\DataHelpers\" />
|
||||
<Folder Include="Procs\Utils\" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="System.Drawing.Common" Version="5.0.2" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Folder Include="Procs\DataHelpers\" />
|
||||
<Folder Include="Procs\Utils\" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
||||
@@ -1,25 +1,25 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netcoreapp3.1</TargetFramework>
|
||||
<RootNamespace>Sarand.BusinessMgr.Net.Core</RootNamespace>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<RootNamespace>Sarand.BusinessMgr.Net.Core</RootNamespace>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation" Version="3.1.16" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation" Version="6.0.31" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\..\Common-VS\Workspace\SacsCoreWeb\SacsCoreWeb.csproj" />
|
||||
<ProjectReference Include="..\..\..\Common-VS\Workspace\SacsStandardBase\SacsStandardBase.csproj" />
|
||||
<ProjectReference Include="..\..\..\Common-VS\Workspace\SacsStandardDbas\SacsStandardDbas.csproj" />
|
||||
<ProjectReference Include="..\..\..\Common-VS\Workspace\SacsStandardProc\SacsStandardProc.csproj" />
|
||||
<ProjectReference Include="..\SaBusMgrStandardBase\SaBusMgrStandardBase.csproj" />
|
||||
<ProjectReference Include="..\SaBusMgrStandardDbas\SaBusMgrStandardDbas.csproj" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\..\Common-VS\Workspace\SacsCoreWeb\SacsCoreWeb.csproj" />
|
||||
<ProjectReference Include="..\..\..\Common-VS\Workspace\SacsStandardBase\SacsStandardBase.csproj" />
|
||||
<ProjectReference Include="..\..\..\Common-VS\Workspace\SacsStandardDbas\SacsStandardDbas.csproj" />
|
||||
<ProjectReference Include="..\..\..\Common-VS\Workspace\SacsStandardProc\SacsStandardProc.csproj" />
|
||||
<ProjectReference Include="..\SaBusMgrStandardBase\SaBusMgrStandardBase.csproj" />
|
||||
<ProjectReference Include="..\SaBusMgrStandardDbas\SaBusMgrStandardDbas.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Folder Include="Web\Core\" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Folder Include="Web\Core\" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
||||
@@ -38,61 +38,87 @@ namespace Sarand.BusinessMgr.Net.Core.Web.App
|
||||
if (configSection != null)
|
||||
{
|
||||
// Environments.
|
||||
foreach (ConfigurationSection environment in configSection.GetSection("Environments").GetChildren())
|
||||
environments.Add(StringUtil.TrimAll(environment.Value));
|
||||
foreach (ConfigurationSection environmentSection in configSection.GetSection("Environments").GetChildren())
|
||||
environments.Add(StringUtil.TrimAll(environmentSection.Value));
|
||||
Instance = StringUtil.OnEmpty(configSection["Instance"], Instance);
|
||||
// Security.
|
||||
IConfigurationSection security = configSection.GetSection("Security");
|
||||
if (security.Exists())
|
||||
IConfigurationSection securitySection = configSection.GetSection("Security");
|
||||
if (securitySection.Exists())
|
||||
{
|
||||
// Security - Password.
|
||||
IConfigurationSection securityPassword = security.GetSection("Password");
|
||||
if (securityPassword.Exists())
|
||||
IConfigurationSection securityPasswordSection = securitySection.GetSection("Password");
|
||||
if (securityPasswordSection.Exists())
|
||||
{
|
||||
Security.Password.MinLength = StringUtil.ToInt(securityPassword["MinLength"], Security.Password.MinLength);
|
||||
Security.Password.MinLength = StringUtil.ToInt(securityPasswordSection["MinLength"], Security.Password.MinLength);
|
||||
}
|
||||
// Security - Sign-Up.
|
||||
IConfigurationSection securitySignUp = security.GetSection("SignUp");
|
||||
if (securitySignUp.Exists())
|
||||
IConfigurationSection securitySignUpSection = securitySection.GetSection("SignUp");
|
||||
if (securitySignUpSection.Exists())
|
||||
{
|
||||
}
|
||||
// Security - Sign-In.
|
||||
IConfigurationSection securitySignIn = security.GetSection("SignIn");
|
||||
if (securitySignIn.Exists())
|
||||
IConfigurationSection securitySignInSection = securitySection.GetSection("SignIn");
|
||||
if (securitySignInSection.Exists())
|
||||
{
|
||||
IConfigurationSection keepLoggedIn = securitySignIn.GetSection("SignIn");
|
||||
if (keepLoggedIn.Exists())
|
||||
IConfigurationSection keepLoggedInSection = securitySignInSection.GetSection("SignIn");
|
||||
if (keepLoggedInSection.Exists())
|
||||
{
|
||||
Security.SignIn.KeepLoggedIn.Allowed = StringUtil.ToBool(StringUtil.OnEmpty(keepLoggedIn["Allowed"], Security.SignIn.KeepLoggedIn.Allowed.ToString()));
|
||||
Security.SignIn.KeepLoggedIn.CookieExpiresDays = StringUtil.ToInt(keepLoggedIn["CookieExpiresDays"], Security.SignIn.KeepLoggedIn.CookieExpiresDays);
|
||||
Security.SignIn.KeepLoggedIn.Allowed = StringUtil.ToBool(StringUtil.OnEmpty(keepLoggedInSection["Allowed"], Security.SignIn.KeepLoggedIn.Allowed.ToString()));
|
||||
Security.SignIn.KeepLoggedIn.CookieExpiresDays = StringUtil.ToInt(keepLoggedInSection["CookieExpiresDays"], Security.SignIn.KeepLoggedIn.CookieExpiresDays);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Email.
|
||||
IConfigurationSection email = configSection.GetSection("Email");
|
||||
if (email.Exists())
|
||||
IConfigurationSection emailSection = configSection.GetSection("Email");
|
||||
if (emailSection.Exists())
|
||||
{
|
||||
Email.Context = email["Context"];
|
||||
PopulateEmailConfig(Email.ContactUs, email.GetSection("ContactUs"));
|
||||
PopulateEmailConfig(Email.Signup_Activate, email.GetSection("Signup").GetSection("Activate"));
|
||||
PopulateEmailConfig(Email.Signup_Welcome, email.GetSection("Signup").GetSection("Welcome"));
|
||||
Email.Context = emailSection["Context"];
|
||||
PopulateEmailConfig(Email.ContactUs, emailSection.GetSection("ContactUs"));
|
||||
PopulateEmailConfig(Email.Signup_Activate, emailSection.GetSection("Signup").GetSection("Activate"));
|
||||
PopulateEmailConfig(Email.Signup_Welcome, emailSection.GetSection("Signup").GetSection("Welcome"));
|
||||
}
|
||||
|
||||
// Documents.
|
||||
IConfigurationSection documents = configSection.GetSection("Documents");
|
||||
if (documents.Exists())
|
||||
IConfigurationSection documentsSection = configSection.GetSection("Documents");
|
||||
if (documentsSection.Exists())
|
||||
{
|
||||
Documents.RootFolder = StringUtil.OnEmpty(documents["RootFolder"], Documents.RootFolder);
|
||||
Documents.RootFolder = StringUtil.OnEmpty(documentsSection["RootFolder"], Documents.RootFolder);
|
||||
}
|
||||
|
||||
// Logging.
|
||||
IConfigurationSection logging = configSection.GetSection("Logging");
|
||||
if (logging.Exists())
|
||||
IConfigurationSection loggingSection = configSection.GetSection("Logging");
|
||||
if (loggingSection.Exists())
|
||||
{
|
||||
Logging.RootFolder = StringUtil.OnEmpty(logging["RootFolder"], Logging.RootFolder);
|
||||
Logging.RootFolder = StringUtil.OnEmpty(loggingSection["RootFolder"], Logging.RootFolder);
|
||||
}
|
||||
// Databases.
|
||||
extractDatabaseConfig(ControlDatabase, configSection.GetSection("ControlDatabase"));
|
||||
extractDatabaseConfig(BusMgrDatabase, configSection.GetSection("BusMgrDatabase"));
|
||||
extractDatabaseConfig(TemplateDatabase, configSection.GetSection("TemplateDatabase"));
|
||||
|
||||
// Control database.
|
||||
IConfigurationSection controlDatabaseSection = configSection.GetSection("ControlDatabase");
|
||||
if (controlDatabaseSection.Exists())
|
||||
{
|
||||
ControlDatabase = new DatabaseConfig();
|
||||
extractDatabaseConfig(ControlDatabase, controlDatabaseSection);
|
||||
}
|
||||
// Template database.
|
||||
IConfigurationSection templateDatabaseSection = configSection.GetSection("TemplateDatabase");
|
||||
if (templateDatabaseSection.Exists())
|
||||
{
|
||||
TemplateDatabase = new DatabaseConfig();
|
||||
extractDatabaseConfig(TemplateDatabase, templateDatabaseSection);
|
||||
}
|
||||
// BusinessMgr databases.
|
||||
IConfigurationSection busMgrDatabasesSection = configSection.GetSection("BusMgrDatabases");
|
||||
if (busMgrDatabasesSection.Exists())
|
||||
{
|
||||
foreach (IConfigurationSection busMgrDbSection in busMgrDatabasesSection.GetChildren())
|
||||
{
|
||||
SbmAppConfig.DatabaseConfig dbConfig = new SbmAppConfig.DatabaseConfig();
|
||||
extractDatabaseConfig(dbConfig, busMgrDbSection);
|
||||
BusMgrDatabases.Add(dbConfig);
|
||||
}
|
||||
}
|
||||
|
||||
// Variants.
|
||||
foreach (ConfigurationSection variantSection in configSection.GetSection("Variants").GetChildren())
|
||||
{
|
||||
@@ -117,6 +143,12 @@ namespace Sarand.BusinessMgr.Net.Core.Web.App
|
||||
private void extractDatabaseConfig(DatabaseConfig database, IConfigurationSection databaseSection)
|
||||
{
|
||||
if (!databaseSection.Exists()) return;
|
||||
IConfigurationSection identifiersSection = databaseSection.GetSection("Identifiers");
|
||||
if (identifiersSection.Exists())
|
||||
{
|
||||
foreach (var identifier in identifiersSection.GetChildren())
|
||||
database.Identifiers.Add(StringUtil.TrimAll(identifier.Value));
|
||||
}
|
||||
database.Location = StringUtil.OnEmpty(databaseSection["Location"], database.Location);
|
||||
database.User = StringUtil.OnEmpty(databaseSection["User"], database.User);
|
||||
database.Password = StringUtil.OnEmpty(databaseSection["Password"], database.Password);
|
||||
@@ -179,13 +211,14 @@ namespace Sarand.BusinessMgr.Net.Core.Web.App
|
||||
// Databases.
|
||||
public class DatabaseConfig
|
||||
{
|
||||
public List<String> Identifiers { get; } = new List<string>();
|
||||
public String Location { get; internal set; }
|
||||
public String User { get; internal set; }
|
||||
public String Password { get; internal set; }
|
||||
}
|
||||
public DatabaseConfig ControlDatabase { get; } = new DatabaseConfig();
|
||||
public DatabaseConfig BusMgrDatabase { get; } = new DatabaseConfig();
|
||||
public DatabaseConfig TemplateDatabase { get; } = new DatabaseConfig();
|
||||
public DatabaseConfig ControlDatabase { get; private set; }
|
||||
public DatabaseConfig TemplateDatabase { get; private set; }
|
||||
public List<DatabaseConfig> BusMgrDatabases { get; } = new List<DatabaseConfig>();
|
||||
// Documents.
|
||||
public class DocumentsConfig
|
||||
{
|
||||
|
||||
@@ -68,7 +68,8 @@ namespace Sarand.BusinessMgr.Net.Core.Web.App
|
||||
applicationParams.Add("Configuration", SbmSystem.DebugMode ? "Debug" : "Release");
|
||||
applicationParams.Add("Environment", EnvironmentName);
|
||||
applicationParams.Add("Control database", AppConfig.ControlDatabase.Location);
|
||||
applicationParams.Add("BusMgr database", AppConfig.BusMgrDatabase.Location);
|
||||
foreach (SbmAppConfig.DatabaseConfig dbConfig in AppConfig.BusMgrDatabases)
|
||||
applicationParams.Add("BusMgr database", (dbConfig.Identifiers.Any() ? $"[{String.Join(",", dbConfig.Identifiers)}] " : "") + dbConfig.Location);
|
||||
applicationParams.Add("Application root", SbmSystem.ApplicationFolder);
|
||||
if (!StringUtil.IsEmpty(AppConfig.Documents.RootFolder))
|
||||
applicationParams.Add("Documents root", AppConfig.Documents.RootFolder);
|
||||
|
||||
@@ -20,16 +20,22 @@ namespace Sarand.BusinessMgr.Net.Core.Web.App
|
||||
{
|
||||
securityProfile = new SbmSecurityProfile(this, false);
|
||||
}
|
||||
// Protected construction.
|
||||
protected SbmSessionData_Web(SbmSessionContext sessionContext, SaSecurityItem securityItemUser, SbmAffiliate affiliateUser, List<SysIdString> supervisedOrganisations, SbmAssociation associationOrganisation, SbmAffiliate affiliateOrganisation) :
|
||||
base(sessionContext, securityItemUser, affiliateUser, supervisedOrganisations, associationOrganisation, affiliateOrganisation)
|
||||
{
|
||||
securityProfile = new SbmSecurityProfile(this, false);
|
||||
}
|
||||
// Protected construction.
|
||||
protected SbmSessionData_Web(SbmSessionContext sessionContext) :
|
||||
base(sessionContext)
|
||||
{
|
||||
securityProfile = new SbmSecurityProfile(this, false);
|
||||
}
|
||||
// Protected construction.
|
||||
protected SbmSessionData_Web(SbmSessionContext sessionContext, SaSecurityItem securityItemUser, SbmAffiliate affiliateUser, List<SysIdString> supervisedOrganisations, SbmAssociation associationOrganisation, SbmAffiliate affiliateOrganisation) :
|
||||
base(sessionContext, securityItemUser, affiliateUser, supervisedOrganisations, associationOrganisation, affiliateOrganisation)
|
||||
{
|
||||
securityProfile = new SbmSecurityProfile(this, false);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Security Profile.
|
||||
private readonly SbmSecurityProfile securityProfile;
|
||||
//-------------------------------------------------------------------
|
||||
// Security Profile.
|
||||
private readonly SbmSecurityProfile securityProfile;
|
||||
public ISbmSecurityProfile SecurityProfile { get { return securityProfile; } }
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
|
||||
@@ -9,7 +9,7 @@ namespace Sarand.BusinessMgr.Net.Core.Web.App
|
||||
public class SbmUserContext_Web : SbmUserContext
|
||||
{
|
||||
//-------------------------------------------------------------------
|
||||
// Data memebrs.
|
||||
// Data members.
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Construction.
|
||||
|
||||
@@ -6,6 +6,7 @@ using Microsoft.AspNetCore.Routing;
|
||||
using Microsoft.Net.Http.Headers;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Serialization;
|
||||
using Sacs.Web.Components;
|
||||
using Sarand.BusinessMgr.Net.Core.Web.App;
|
||||
using Sarand.BusinessMgr.Net.Core.Web.Models;
|
||||
using Sarand.BusinessMgr.Net.Standard.Base.App;
|
||||
@@ -40,7 +41,7 @@ using System.Web;
|
||||
namespace Sarand.BusinessMgr.Net.Core.Web.Controllers
|
||||
{
|
||||
//=======================================================================
|
||||
public abstract class SbmController_Base : Controller
|
||||
public abstract class SbmController_Base : SaController
|
||||
{
|
||||
//-------------------------------------------------------------------
|
||||
// Data members.
|
||||
@@ -67,27 +68,11 @@ namespace Sarand.BusinessMgr.Net.Core.Web.Controllers
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Properties.
|
||||
public bool DebugMode { get; } = SacsSystem.DebugMode;
|
||||
protected SbmApplication_Web App { get { return SbmGlobals_Web.Application; } }
|
||||
public SbmAppConfig AppConfig { get { return App.AppConfig; } }
|
||||
public SbmSessionContext SessionContext { get { return SessionData?.SessionContext ?? null; } }
|
||||
public ISbmUserContext UserContext { get { return SessionData; } }
|
||||
protected SbmLocaliser Localiser { get; }
|
||||
/// <summary>
|
||||
/// Indicate whether session data should be stored by action.
|
||||
/// <para>Any action that might modify the session data must store it.</para>
|
||||
/// <para>Some actions such as scoring a password's complexity don't need to.</para>
|
||||
/// </summary>
|
||||
public virtual bool StoreSessionData { get; protected set; } = true;
|
||||
// Culture.
|
||||
private string LanguageIso2
|
||||
{
|
||||
get
|
||||
{
|
||||
var feature = HttpContext.Features.Get<IRequestCultureFeature>();
|
||||
return feature.RequestCulture.UICulture.TwoLetterISOLanguageName.ToLower();
|
||||
}
|
||||
}
|
||||
// Business components.
|
||||
public SbmInternals Internals { get { if (internals == null) internals = new SbmInternals(UserContext); return internals; } }
|
||||
// Managers.
|
||||
@@ -119,36 +104,6 @@ namespace Sarand.BusinessMgr.Net.Core.Web.Controllers
|
||||
public SaEmailConfig EmailConfig { get { return Internals.EmailConfig; } }
|
||||
public SbmEmailConsole EmailConsole { get { return Internals.EmailConsole; } }
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Redirection locations.
|
||||
//-------------------------------------------------------------------
|
||||
public static readonly String ParamName_SessionExpired = "SessionExpired";
|
||||
protected enum RedirectLocation
|
||||
{
|
||||
WebAppBase,
|
||||
WebAppHome,
|
||||
WebAppHome_SessionExpired,
|
||||
}
|
||||
protected String GetRedirectLocation(RedirectLocation redirectLocation)
|
||||
{
|
||||
string protocol = Request.Scheme;
|
||||
var parameters = new RouteValueDictionary();
|
||||
String homeAction = Url.Action("Index", "Home", parameters, protocol);
|
||||
switch (redirectLocation)
|
||||
{
|
||||
case RedirectLocation.WebAppBase:
|
||||
return Regex.Replace(homeAction, "\\/$", "") + "/";
|
||||
case RedirectLocation.WebAppHome:
|
||||
return homeAction;
|
||||
case RedirectLocation.WebAppHome_SessionExpired:
|
||||
// Set the session expired parameter so that the page can report it.
|
||||
// NB Paramater must have a value to be included in the URL query string.
|
||||
parameters.Add(ParamName_SessionExpired, "1");
|
||||
return homeAction;
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Action execution events.
|
||||
//-------------------------------------------------------------------
|
||||
@@ -205,6 +160,7 @@ namespace Sarand.BusinessMgr.Net.Core.Web.Controllers
|
||||
if (model == null) return;
|
||||
|
||||
// Session data.
|
||||
model.Controller = this;
|
||||
model.SessionData_Web = SessionData;
|
||||
|
||||
// Redirect locations.
|
||||
@@ -213,73 +169,6 @@ namespace Sarand.BusinessMgr.Net.Core.Web.Controllers
|
||||
model.RedirectLocation.Home_SessionExpired = GetRedirectLocation(RedirectLocation.WebAppHome_SessionExpired);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Parameters.
|
||||
//-------------------------------------------------------------------
|
||||
public String EncryptParameters(NameValueCollection parameters, String base64IV, String base64Key)
|
||||
{
|
||||
String fn = nameof(ControllerBase) + ".EncryptParameters";
|
||||
try
|
||||
{
|
||||
// Copy the list of parameters, adding a random name/value pair to randomise the encryption.
|
||||
NameValueCollection parametersToEncrypt = new NameValueCollection(parameters);
|
||||
// NB Range 10-189 intended to have equal chance of 2 or 3 digit number.
|
||||
parametersToEncrypt.Add("!" + SacsRandomHelper.GetInt32(10, 190).ToString(), SacsRandomHelper.GetInt32(10, 190).ToString());
|
||||
|
||||
// Sort the keys to ensure that the random '!' param is first in the query string.
|
||||
String[] paramKeys = parametersToEncrypt.AllKeys;
|
||||
Array.Sort(paramKeys);
|
||||
|
||||
// Serialise parameters as if in a URL query string - so that they can be deserialised in DecryptParameters() below.
|
||||
string queryString = String.Join("&", paramKeys.Select(a => a + "=" + HttpUtility.UrlEncode(parametersToEncrypt[a])));
|
||||
String encrypted = SacsEncryptionHelper.Encrypt(queryString, base64IV, base64Key);
|
||||
if (DebugMode)
|
||||
{
|
||||
SaLogger.Debug(fn + " Encrypted: " + encrypted);
|
||||
NameValueCollection decryptedParams = DecryptParameters(encrypted, base64IV, base64Key);
|
||||
}
|
||||
return encrypted;
|
||||
}
|
||||
catch (Exception exc) { SaLogger.Warn(fn + " " + ExceptionUtil.GetErrorStateMessage(exc)); }
|
||||
return "";
|
||||
}
|
||||
public NameValueCollection DecryptParameters(String encrypted, String base64IV, String base64Key)
|
||||
{
|
||||
String fn = nameof(ControllerBase) + ".DecryptParameters";
|
||||
if (DebugMode) SaLogger.Debug(fn + " \n\tEncrypted: " + encrypted + "\n\tIV: " + base64IV + "\n\tKey: " + base64Key);
|
||||
try
|
||||
{
|
||||
String queryString = SacsEncryptionHelper.Decrypt(encrypted, base64IV, base64Key);
|
||||
return HttpUtility.ParseQueryString(queryString);
|
||||
}
|
||||
catch (Exception exc) { SaLogger.Warn(fn + " " + ExceptionUtil.GetErrorStateMessage(exc)); }
|
||||
return new NameValueCollection();
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Cookies.
|
||||
//-------------------------------------------------------------------
|
||||
/// <summary>Retrieve the value from the named request cookie.</summary>
|
||||
public String GetRequestCookie(String key)
|
||||
{
|
||||
if (Request.Cookies.ContainsKey(key))
|
||||
return Request.Cookies[key];
|
||||
return null;
|
||||
}
|
||||
/// <summary>Set the value against the named response cookie.</summary>
|
||||
public void SetResponseCookie(string key, string value, DateTime? expiresAt = null, bool isEssential = false)
|
||||
{
|
||||
CookieOptions options = new CookieOptions();
|
||||
options.HttpOnly = true;
|
||||
options.Secure = true;
|
||||
options.SameSite = Microsoft.AspNetCore.Http.SameSiteMode.Strict;
|
||||
if (expiresAt.HasValue)
|
||||
options.Expires = expiresAt;
|
||||
if (isEssential)
|
||||
options.IsEssential = true;
|
||||
Response.Cookies.Append(key, value, options);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Session.
|
||||
//-------------------------------------------------------------------
|
||||
@@ -366,193 +255,6 @@ namespace Sarand.BusinessMgr.Net.Core.Web.Controllers
|
||||
}
|
||||
protected abstract SbmSessionData_Web DeserializeSessionData(String sessionDataJson);
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Ajax actions.
|
||||
//-------------------------------------------------------------------
|
||||
protected static readonly Encoding ajaxResponseEncoding = Encoding.UTF8;
|
||||
protected IActionResult GetAjaxResult_GoHome(AjaxResponse_Base responseData)
|
||||
{
|
||||
responseData.SetGoHome();
|
||||
return Json(responseData);
|
||||
}
|
||||
protected IActionResult GetAjaxResult_InvalidSession(AjaxResponse_Base responseData)
|
||||
{
|
||||
responseData.SetGoHome();
|
||||
return Json(responseData);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Base Ajax Response Data.
|
||||
//-------------------------------------------------------------------
|
||||
public class AjaxResponse_Base
|
||||
{
|
||||
// Response status.
|
||||
public bool? Success { get; set; } = null;
|
||||
public bool? Error { get; set; } = null;
|
||||
public bool? SessionExpired { get; protected set; } = null;
|
||||
public bool? GoHome { get; protected set; } = null;
|
||||
public AjaxResponse_Base SetSessionExpired(String title, String text)
|
||||
{
|
||||
SessionExpired = true;
|
||||
return SetMessage(title, text);
|
||||
}
|
||||
public AjaxResponse_Base SetGoHome()
|
||||
{
|
||||
GoHome = true;
|
||||
return this;
|
||||
}
|
||||
public AjaxResponse_Base SetGoHome(String title, String text)
|
||||
{
|
||||
GoHome = true;
|
||||
return SetMessage(title, text);
|
||||
}
|
||||
// Message - displays alert popup.
|
||||
public class MessageData
|
||||
{
|
||||
public String Title { get; set; }
|
||||
public String Text { get; set; }
|
||||
}
|
||||
public MessageData Message { get; private set; }
|
||||
public AjaxResponse_Base SetMessage(String title, String text)
|
||||
{
|
||||
if (!StringUtil.IsEmpty(text))
|
||||
Message = new MessageData() { Title = title, Text = text };
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Ajax Response Data.
|
||||
//-------------------------------------------------------------------
|
||||
public class AjaxResponse_Data : AjaxResponse_Base
|
||||
{
|
||||
//---------------------------------------------------------------
|
||||
// Construction.
|
||||
protected AjaxResponse_Data(SbmModel_Base model)
|
||||
{
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------
|
||||
/// <summary>
|
||||
/// Common item response data properties.
|
||||
/// <para>- Null values are ignored by the JSON serialiser.</para>
|
||||
/// <para>- Return null for false boolean values where possible.</para>
|
||||
/// <para>- Return null for blank string values where possible.</para>
|
||||
/// </summary>
|
||||
public class ItemData
|
||||
{
|
||||
public String Id { get; set; }
|
||||
private String notes;
|
||||
public String Notes { get { return StringUtil.OnEmpty(notes, null); } set { notes = StringUtil.EmptyOnNull(value).Trim(); } }
|
||||
public String StatusCode { get; set; }
|
||||
public String StatusDesc { get; set; }
|
||||
public bool? Awaiting { get { return StatusCode.EqualsCI(SacsSystem.GetStatusCode(SaStatus.Awaiting)) ? true : (bool?)null; } }
|
||||
public bool? Active { get { return StatusCode.EqualsCI(SacsSystem.GetStatusCode(SaStatus.Active)) ? true : (bool?)null; } }
|
||||
public bool? Deleted { get { return StatusCode.EqualsCI(SacsSystem.GetStatusCode(SaStatus.Deleted)) ? true : (bool?)null; } }
|
||||
public String CreatedOn { get; set; }
|
||||
public String CreatedOnFmt { get; set; }
|
||||
public String UpdatedOn { get; set; }
|
||||
public String UpdatedOnFmt { get; set; }
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------
|
||||
// Form data.
|
||||
public class FormControlValue
|
||||
{
|
||||
public FormControlValue(String controlName, String value, String error)
|
||||
{
|
||||
ControlName = controlName;
|
||||
Value = value;
|
||||
Error = error;
|
||||
}
|
||||
public String ControlName { get; }
|
||||
public String Value { get; set; }
|
||||
public String Error { get; set; }
|
||||
}
|
||||
private readonly Dictionary<String, FormControlValue> controlValues = new Dictionary<String, FormControlValue>();
|
||||
public List<FormControlValue> ControlValues { get { return controlValues.Count > 0 ? controlValues.Values.ToList() : null; } }
|
||||
public void SetControlValue(String controlName, String value, String error = null)
|
||||
{
|
||||
if (controlValues.ContainsKey(controlName))
|
||||
{
|
||||
// Modify existing entry in the list.
|
||||
FormControlValue controlValue = controlValues[controlName];
|
||||
if (value != null) controlValue.Value = value;
|
||||
if (error != null) controlValue.Error = error;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Add new control to list.
|
||||
controlValues.Add(controlName, new FormControlValue(controlName, value, error));
|
||||
}
|
||||
}
|
||||
/// <summary>Assign the error to the control by name and return this response data.</summary>
|
||||
public AjaxResponse_Data SetControlError(String controlName, String error)
|
||||
{
|
||||
return SetControlError(controlName, error, this);
|
||||
}
|
||||
/// <summary>
|
||||
/// Assign the error to the control by name and return the specified value.
|
||||
/// <para>- Allows alternative return values to be specified (eg. 'false') to avoid separate return statement in calling routine.</para>
|
||||
/// </summary>
|
||||
public T SetControlError<T>(String controlName, String error, T returnValue)
|
||||
{
|
||||
SetControlValue(controlName, null, error);
|
||||
return returnValue;
|
||||
}
|
||||
public bool HasControlErrors()
|
||||
{
|
||||
foreach (FormControlValue controlValue in controlValues.Values)
|
||||
{
|
||||
if (!StringUtil.IsEmpty(controlValue.Error)) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------
|
||||
// Notification - briefly displays after response received.
|
||||
public class NotificationData
|
||||
{
|
||||
public String Title { get; set; }
|
||||
public String Message { get; set; }
|
||||
}
|
||||
public NotificationData Notification { get; private set; }
|
||||
public AjaxResponse_Data SetNotification(String title, String message)
|
||||
{
|
||||
Notification = new NotificationData() { Title = title, Message = message };
|
||||
return this;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------
|
||||
// Paged data.
|
||||
public class PagingData
|
||||
{
|
||||
public PagingData(SbmModel_Base model) :
|
||||
this(model.Paging.PageNo, model.Paging.PageLength, model.Paging.ItemCount, model.Paging.ItemTotal)
|
||||
{ }
|
||||
public PagingData(uint pageNo, ushort pageLength, ushort itemCount, ulong itemTotal)
|
||||
{
|
||||
PageNo = pageNo;
|
||||
PageLength = pageLength;
|
||||
ItemCount = itemCount;
|
||||
ItemTotal = itemTotal;
|
||||
}
|
||||
public bool Paged { get { return (PageNo > 0 && PageLength > 0 && ItemTotal > PageLength); } }
|
||||
public uint PageNo { get; } = 0;
|
||||
public ushort PageLength { get; } = 0;
|
||||
public uint PageCount { get { return (PageLength > 0 ? (uint)Math.Ceiling((decimal)ItemTotal / PageLength) : 0); } }
|
||||
public ushort ItemCount { get; } = 0;
|
||||
public ulong ItemTotal { get; } = 0;
|
||||
}
|
||||
public PagingData Paging { get; private set; }
|
||||
public void SetPaging(SbmModel_Base model)
|
||||
{
|
||||
Paging = new PagingData(model);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
}
|
||||
//=======================================================================
|
||||
|
||||
@@ -37,13 +37,13 @@ namespace Sarand.BusinessMgr.Net.Core.Web.Helpers
|
||||
/// Identify the session context that corresponds with the BusinessMgr
|
||||
/// database for the specified user by email address.
|
||||
/// </summary>
|
||||
public static List<ushort> GetSessionContextIdxsForUsersBusMgrDatabase(String emailAddress)
|
||||
public static List<ushort> GetSessionContextIdxsForContextUserEmail(String dbIdentifier, String emailAddress)
|
||||
{
|
||||
String fn = className + ".GetSessionContextIdxForUsersBusMgrDatabase";
|
||||
String alias_SecurityItem = "SecItm";
|
||||
String alias_Affiliate = "Affil";
|
||||
List<ushort> sessionContextIdxs = new List<ushort>();
|
||||
if (StringUtil.IsEmpty(emailAddress)) return sessionContextIdxs;
|
||||
if (SacsSystem.DebugMode) SaLogger.Info($"{SysUtil.Fn} Searching for database. Identifier: {dbIdentifier}. Email address: {emailAddress}");
|
||||
|
||||
// Get the session context indices defined by the application.
|
||||
SbmApplication_Web app = SbmGlobals_Web.Application;
|
||||
@@ -53,16 +53,20 @@ namespace Sarand.BusinessMgr.Net.Core.Web.Helpers
|
||||
SbmSessionContext sessionContext = app.GetSessionContext(sessionContextIdx);
|
||||
if (sessionContext == null)
|
||||
{
|
||||
SaLogger.Warn(fn + " Failed to retrieve SessionContext for idx: " + sessionContextIdx);
|
||||
SaLogger.Warn($"{SysUtil.Fn} Failed to retrieve SessionContext for idx: " + sessionContextIdx);
|
||||
continue;
|
||||
}
|
||||
// Retrieve the BusinessMgr database.
|
||||
ISacsDatabase db = app.GetBusMgrDatabase(sessionContext);
|
||||
// Verify Db Identifier.
|
||||
List<string> dbIdentifiers = app.GetDbIdentifiers(sessionContext);
|
||||
if (!dbIdentifiers.ContainsCI(dbIdentifier))
|
||||
continue;
|
||||
ISacsDatabase db = app.GetBusMgrDatabase(sessionContext);
|
||||
if (db == null)
|
||||
{
|
||||
SaLogger.Warn(fn + " Failed to retrieve SessionContext for idx: " + sessionContextIdx);
|
||||
SaLogger.Warn($"{SysUtil.Fn} Failed to retrieve Database for idx: " + sessionContextIdx);
|
||||
continue;
|
||||
}
|
||||
if (SacsSystem.DebugMode) SaLogger.Info($"{SysUtil.Fn} Database: " + db.DatabaseName);
|
||||
|
||||
// Query to check for Security Item matching the email with associated Affiliate.
|
||||
// NB This is done independently for each database in case there are different
|
||||
@@ -70,6 +74,7 @@ namespace Sarand.BusinessMgr.Net.Core.Web.Helpers
|
||||
DbQuery qry = new DbQuery(db.DbmsType);
|
||||
qry.Tables.Add(SaSecurityDbDfn.GetTableName(SaSecurityDbDfn.TableIdx.SaSecItem), alias_SecurityItem);
|
||||
qry.Columns.Add(SaSecurityDbDfn.GetColumnNameQual(SaSecurityDbDfn.ColumnIdx.SaSecItem_Id, alias_SecurityItem));
|
||||
qry.Columns.Add(SaSecurityDbDfn.GetColumnNameQual(SaSecurityDbDfn.ColumnIdx.SaSecItem_Id, alias_SecurityItem));
|
||||
qry.Filters.Add(SaSecurityDbDfn.GetColumnNameQual(SaSecurityDbDfn.ColumnIdx.SaSecItem_EmailAddress, alias_SecurityItem) + "='" + DbQuery.FormatForCondition(emailAddress) + "'");
|
||||
// Join to the Affiliate table.
|
||||
DbQueryJoin joinAffiliate = new DbQueryJoin(DbJoinType.FullOuter);
|
||||
@@ -80,7 +85,10 @@ namespace Sarand.BusinessMgr.Net.Core.Web.Helpers
|
||||
using (DbResultSet resultSet = DbResultSet_DataReader.ExecuteQuery(db, qry.BuildQuery()))
|
||||
{
|
||||
if (resultSet != null && resultSet.NextRecord())
|
||||
{
|
||||
if (SacsSystem.DebugMode) SaLogger.Info($"{SysUtil.Fn} Database contains email: " + db.DatabaseName);
|
||||
sessionContextIdxs.Add(sessionContextIdx);
|
||||
}
|
||||
}
|
||||
}
|
||||
return sessionContextIdxs;
|
||||
|
||||
@@ -36,6 +36,7 @@ namespace Sarand.BusinessMgr.Net.Core.Web.Middleware
|
||||
protected override async Task<AuthenticateResult> HandleAuthenticateAsync()
|
||||
{
|
||||
Context.Response.StatusCode = (int)HttpStatusCode.Unauthorized;
|
||||
await Task.CompletedTask;
|
||||
return AuthenticateResult.NoResult();
|
||||
}
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ using Sarand.Net.Standard.Base.Utils;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection.PortableExecutable;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
@@ -56,10 +57,12 @@ namespace Sarand.BusinessMgr.Net.Core.Web.Middleware
|
||||
string fn = GetType().Name + ".SetProperty";
|
||||
//if (SbmSystem.DebugMode) Logger.Debug(fn + " Form property " + modelName + ": '" + result.Model.ToString() + ".");
|
||||
object originalValue = result.Model;
|
||||
// Exclude properties that retain leading/trailing whitespace.
|
||||
if (result.Model is string)
|
||||
// Anything that looks like a password will be left as is.
|
||||
bool password = modelName.ContainsCI("Password");
|
||||
// Exclude properties that retain leading/trailing whitespace.
|
||||
if (result.Model is string)
|
||||
{
|
||||
if (!modelName.ContainsCI("Password"))
|
||||
if (!password)
|
||||
{
|
||||
string value = result.Model as string;
|
||||
|
||||
@@ -89,9 +92,16 @@ namespace Sarand.BusinessMgr.Net.Core.Web.Middleware
|
||||
result = ModelBindingResult.Success(value);
|
||||
}
|
||||
}
|
||||
if (result.Model != null && SbmSystem.DebugMode)
|
||||
SaLogger.Debug(fn + " Form property " + modelName + ": '" + result.Model.ToString() + "'." + (originalValue != null && !originalValue.Equals(result.Model) ? " Original value: '" + originalValue.ToString() + "'" : ""));
|
||||
base.SetProperty(bindingContext, modelName, propertyMetadata, result);
|
||||
// Log property details.
|
||||
if (result.Model != null && SbmSystem.DebugMode &&
|
||||
// Ignore passwords.
|
||||
!password &&
|
||||
// Ignore items that correspond with objects in the model rather than values.
|
||||
!result.Model.ToString().Equals(result.Model.GetType().FullName) &&
|
||||
// Ignore form files.
|
||||
!result.Model.ToString().ContainsCI("Microsoft.AspNetCore.Http.IFormFile"))
|
||||
SaLogger.Debug(SysUtil.Fn + " Form property " + modelName + ": '" + result.Model.ToString() + "'." + (originalValue != null && !originalValue.Equals(result.Model) ? " Original value: '" + originalValue.ToString() + "'" : ""));
|
||||
base.SetProperty(bindingContext, modelName, propertyMetadata, result);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
|
||||
@@ -60,7 +60,7 @@ namespace Sarand.BusinessMgr.Net.Core.Web.Middleware
|
||||
catch (Exception exc)
|
||||
{
|
||||
SaLogger.Warn(fn + " " + ExceptionUtil.GetLogMessage(exc));
|
||||
throw exc;
|
||||
throw;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
using Microsoft.AspNetCore.Html;
|
||||
using Microsoft.AspNetCore.Mvc.Rendering;
|
||||
using Sacs.Web.Components;
|
||||
using Sarand.BusinessMgr.Net.Core.Web.App;
|
||||
using Sarand.BusinessMgr.Net.Core.Web.Controllers;
|
||||
using Sarand.BusinessMgr.Net.Standard.Base.App;
|
||||
using Sarand.BusinessMgr.Net.Standard.Base.Bus;
|
||||
using Sarand.BusinessMgr.Net.Standard.Base.Mgr;
|
||||
@@ -18,19 +20,17 @@ using Sarand.Net.Standard.Base.UpdateLog;
|
||||
using Sarand.Net.Standard.Base.Utils;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Text;
|
||||
|
||||
namespace Sarand.BusinessMgr.Net.Core.Web.Models
|
||||
{
|
||||
//=======================================================================
|
||||
public class SbmModel_Base
|
||||
public class SbmModel_Base : SaModel
|
||||
{
|
||||
//-------------------------------------------------------------------
|
||||
// Data members.
|
||||
private SbmInternals internals;
|
||||
private readonly List<String> infoMessages = new List<string>();
|
||||
private readonly List<String> warningMessages = new List<string>();
|
||||
private readonly List<String> errorMessages = new List<string>();
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Protected construction.
|
||||
@@ -49,16 +49,14 @@ namespace Sarand.BusinessMgr.Net.Core.Web.Models
|
||||
public SbmSessionData_Web SessionData_Web { get; set; }
|
||||
public SbmSessionContext SessionContext { get { return SessionData?.SessionContext ?? null; } }
|
||||
public DbUpdateInfo DbUpdateInfo { get { return SessionData?.DbUpdateInfo ?? new DbUpdateInfo(null, "", SbmSystem.ComputerName); } }
|
||||
public bool DebugMode { get { return SbmSystem.DebugMode; } }
|
||||
public SbmLocaliser Localiser { get; }
|
||||
// Request properties.
|
||||
public SbmController_Base Controller { get; set; }
|
||||
public CultureInfo SessionCulture { get { return Controller?.SessionCulture ?? CultureInfo.InvariantCulture; } }
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Page configuration.
|
||||
public bool OK { get { return !HasMessages(); } }
|
||||
public virtual bool ProhibitCache { get; set; } = true;
|
||||
public String PageCaption { get; set; }
|
||||
public String InstanceVersion { get { return !StringUtil.IsEmpty(App.AppConfig.Instance) ? App.AppConfig.Instance + " v" + Sbm.Version.GetFullVersion() : "v" + Sbm.Version.GetAppVersion(); } }
|
||||
public bool IncludeGoogleAnalytics { get; set; } = false;
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Business components.
|
||||
@@ -100,7 +98,23 @@ namespace Sarand.BusinessMgr.Net.Core.Web.Models
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
/// <summary>
|
||||
/// Form control value max length.
|
||||
/// Form control value max length - Security tables.
|
||||
/// <para>In many cases the database columns allow plenty of extra space for the value, in case they need to be encrypted.</para>
|
||||
/// <para>Hence, several cases where the value entered in the control isn't allowed the full database length.</para>
|
||||
/// </summary>
|
||||
public int GetControlMaxLength(SaSecurityDbDfn.ColumnIdx column)
|
||||
{
|
||||
int maxLength = (int)SaSecurityDbDfn.GetColTextLen(column);
|
||||
switch (column)
|
||||
{
|
||||
case SaSecurityDbDfn.ColumnIdx.SaSecItem_EmailAddress:
|
||||
return Math.Min(maxLength, 100);
|
||||
}
|
||||
return maxLength;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Form control value max length - BusinessMgr tables.
|
||||
/// <para>In many cases the database columns allow plenty of extra space for the value, in case they need to be encrypted.</para>
|
||||
/// <para>Hence, several cases where the value entered in the control isn't allowed the full database length.</para>
|
||||
/// </summary>
|
||||
@@ -110,7 +124,7 @@ namespace Sarand.BusinessMgr.Net.Core.Web.Models
|
||||
switch (column)
|
||||
{
|
||||
case SbmDbDfn.ColumnIdx.Affiliate_Email:
|
||||
return Math.Min(maxLength, 60);
|
||||
return Math.Min(maxLength, 100);
|
||||
case SbmDbDfn.ColumnIdx.Affiliate_FirstName:
|
||||
case SbmDbDfn.ColumnIdx.Affiliate_LastName:
|
||||
return Math.Min(maxLength, 40);
|
||||
@@ -138,6 +152,17 @@ namespace Sarand.BusinessMgr.Net.Core.Web.Models
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Display data - Dates.
|
||||
public String FormatDateForDisplay(DateTime value)
|
||||
{
|
||||
return DateUtil.Format(value, "d-MMM-yy", SessionCulture);
|
||||
}
|
||||
public String FormatDateTimeForDisplay(DateTime value)
|
||||
{
|
||||
return StringUtil.TrimAll(DateUtil.Format(value, "d-MMM-yy HH:mm", SessionCulture));
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Form data - Dates.
|
||||
// Format may depend on locale, but as long as these methods are used consistently,
|
||||
@@ -208,71 +233,10 @@ namespace Sarand.BusinessMgr.Net.Core.Web.Models
|
||||
/// <summary>List of Commodity Types for dropdown.</summary>
|
||||
public IEnumerable<SelectListItem> GetCommodityTypeCodesForSelect()
|
||||
{
|
||||
|
||||
|
||||
return new SelectList(GetCodesOfType(Sbm.SystemCode.CommodityType), "Code", "Desc");
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Version parameter for includes.
|
||||
public String HrefVersion
|
||||
{
|
||||
get
|
||||
{
|
||||
DateTime versionDate = SbmSystem.AssemblyBuildAt;
|
||||
if (!DateUtil.IsValid(versionDate) || SbmSystem.DebugMode)
|
||||
versionDate = DateTime.Now;
|
||||
return DateUtil.Format(versionDate, "yyyyMMdd" /*+ (SacsSystem.Debug ? "HHmm" : "")*/);
|
||||
}
|
||||
}
|
||||
// Additional includes.
|
||||
public List<String> AdditionalFiles_CSS { get; set; } = new List<string>();
|
||||
public List<String> AdditionalFiles_JS { get; set; } = new List<string>();
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Redirection locations.
|
||||
public class RedirectLocationData
|
||||
{
|
||||
// Properties populated in Controller_Base.OnActionExecuted.
|
||||
public String Base { get; internal set; }
|
||||
public String Home { get; internal set; }
|
||||
public String Home_SessionExpired { get; internal set; }
|
||||
}
|
||||
public RedirectLocationData RedirectLocation { get; } = new RedirectLocationData();
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Paging properties.
|
||||
public class DataPaging
|
||||
{
|
||||
private DbQuery.Paging paging { get; } = new DbQuery.Paging();
|
||||
public void PopulatePagingTo(DbQuery.Paging resultsPaging)
|
||||
{
|
||||
resultsPaging.PageLength = paging.PageLength;
|
||||
resultsPaging.PageNo = paging.PageNo;
|
||||
}
|
||||
public bool IsPaged { get { return paging.Paged; } }
|
||||
public uint PageNo { get { return paging.PageNo; } set { paging.PageNo = value; } }
|
||||
public ushort PageLength { get { return paging.PageLength; } set { paging.PageLength = value; } }
|
||||
public uint PageCount { get { return (PageLength > 0 ? (uint)Math.Ceiling((decimal)ItemTotal / PageLength) : 0); } }
|
||||
public ushort ItemCount { get; set; }
|
||||
private ulong itemTotal = 0;
|
||||
public ulong ItemTotal
|
||||
{
|
||||
get { return itemTotal; }
|
||||
set
|
||||
{
|
||||
itemTotal = value;
|
||||
// Check whether the total number of items is less than the current page and reduce page no if needed.
|
||||
if (IsPaged && (PageNo - 1) * PageLength > itemTotal)
|
||||
PageNo = (uint)((itemTotal - 1) / PageLength + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
public DataPaging Paging { get; } = new DataPaging();
|
||||
public void PopulatePagingTo(DbQuery.Paging resultsPaging)
|
||||
{
|
||||
Paging.PopulatePagingTo(resultsPaging);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Form properties.
|
||||
/// <summary>
|
||||
@@ -280,38 +244,9 @@ namespace Sarand.BusinessMgr.Net.Core.Web.Models
|
||||
/// <para>Equivalent to the Site index on the login form.</para>
|
||||
/// <para>Populates value on logout form to identify default site for next login.</para>
|
||||
/// </summary>
|
||||
public ushort SessionIdx { get { return SessionContext.Index; } }
|
||||
public ushort SessionIdx { get { return SessionContext?.Index ?? 0; } }
|
||||
public String FormAction { get; set; }
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Messages.
|
||||
//-------------------------------------------------------------------
|
||||
public bool HasMessages()
|
||||
{
|
||||
return infoMessages.Count > 0 || warningMessages.Count > 0 || errorMessages.Count > 0;
|
||||
}
|
||||
public List<String> InfoMessages { get { return new List<string>(infoMessages); } }
|
||||
public List<String> WarningMessages { get { return new List<string>(warningMessages); } }
|
||||
public List<String> ErrorMessages { get { return new List<string>(errorMessages); } }
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Form messages.
|
||||
public void AddInfoMessage(String message)
|
||||
{
|
||||
if (StringUtil.IsEmpty(StringUtil.TrimAll(message))) return;
|
||||
infoMessages.Add(message);
|
||||
}
|
||||
public void AddWarningMessage(String message)
|
||||
{
|
||||
if (StringUtil.IsEmpty(StringUtil.TrimAll(message))) return;
|
||||
warningMessages.Add(message);
|
||||
}
|
||||
public void AddErrorMessage(String message)
|
||||
{
|
||||
if (StringUtil.IsEmpty(StringUtil.TrimAll(message))) return;
|
||||
errorMessages.Add(message);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
}
|
||||
//=======================================================================
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using Sarand.Net.Standard.Base.App;
|
||||
using Sarand.Net.Standard.Base.Core;
|
||||
using Sarand.Net.Standard.Base.Dbas;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
@@ -41,6 +42,13 @@ namespace Sarand.BusinessMgr.Net.Standard.Base.App
|
||||
}
|
||||
}
|
||||
}
|
||||
public class Database
|
||||
{
|
||||
public class Identifier
|
||||
{
|
||||
public static int MaxLength { get; } = 16;
|
||||
}
|
||||
}
|
||||
public class Portal
|
||||
{
|
||||
public static class Session
|
||||
@@ -82,6 +90,7 @@ namespace Sarand.BusinessMgr.Net.Standard.Base.App
|
||||
//-------------------------------------------------------------------
|
||||
// Definitions.
|
||||
public static String ApplicationCaption { get; } = "Sarand BusinessMgr";
|
||||
public static DbUpdateInfo DbUpdateInfo_Anon { get; } = new DbUpdateInfo(null, "", "");
|
||||
// Option values.
|
||||
public static String ValueYes { get; } = "YES";
|
||||
public static String ValueNo { get; } = "NO";
|
||||
|
||||
@@ -12,6 +12,7 @@ using Sarand.Net.Standard.Base.ReferenceData;
|
||||
using Sarand.Net.Standard.Base.Security;
|
||||
using Sarand.Net.Standard.Base.UpdateLog;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Sarand.BusinessMgr.Net.Standard.Base.App
|
||||
{
|
||||
@@ -47,14 +48,12 @@ namespace Sarand.BusinessMgr.Net.Standard.Base.App
|
||||
//-------------------------------------------------------------------
|
||||
// Properties.
|
||||
public abstract SbmSystem System { get; }
|
||||
// Control Database.
|
||||
public abstract ISacsDatabase GetControlDatabase(SbmSessionContext sessionContext);
|
||||
public IDatabaseInfo CreateControlDbInfo(SbmSessionContext sessionContext)
|
||||
{
|
||||
return GetControlDatabase(sessionContext).CreateDbInfo();
|
||||
}
|
||||
// Control & Template Databases.
|
||||
public abstract ISacsDatabase GetControlDatabase();
|
||||
public abstract ISacsDatabase GetTemplateDatabase();
|
||||
// Business Mgr Database.
|
||||
public abstract ISacsDatabase GetBusMgrDatabase(SbmSessionContext sessionContext);
|
||||
public abstract List<string> GetDbIdentifiers(SbmSessionContext sessionContext);
|
||||
public abstract ISacsDatabase GetBusMgrDatabase(SbmSessionContext sessionContext);
|
||||
public IDatabaseInfo CreateBusMgrDbInfo(SbmSessionContext sessionContext)
|
||||
{
|
||||
return GetBusMgrDatabase(sessionContext).CreateDbInfo();
|
||||
|
||||
@@ -115,6 +115,7 @@ namespace Sarand.BusinessMgr.Net.Standard.Base.App
|
||||
return new List<TypeCodeDesc>(systemCodeCache.GetValueOrDefault(systemCode, new List<TypeCodeDesc>()));
|
||||
}
|
||||
public List<TypeCodeDesc> AffiliateTypeCodes { get { return GetCodesOfType(Sbm.SystemCode.AffiliateType); } }
|
||||
public List<TypeCodeDesc> AssociationTypeCodes { get { return GetCodesOfType(Sbm.SystemCode.AssociationType); } }
|
||||
public List<TypeCodeDesc> CommodityTypeCodes { get { return GetCodesOfType(Sbm.SystemCode.CommodityType); } }
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
|
||||
@@ -44,20 +44,20 @@ namespace Sarand.BusinessMgr.Net.Standard.Base.App
|
||||
switch (textResource)
|
||||
{
|
||||
case TextResource.SaBaseCss:
|
||||
return SacsResourceHelper.GetTextResource(SacsResourceHelper.TextResource.SaBaseCss);
|
||||
return SacsResourceHelper.GetResourceText(SacsResourceHelper.TextResource.SaBaseCss);
|
||||
case TextResource.SaBaseJs:
|
||||
return SacsResourceHelper.GetTextResource(SacsResourceHelper.TextResource.SaBaseJs);
|
||||
return SacsResourceHelper.GetResourceText(SacsResourceHelper.TextResource.SaBaseJs);
|
||||
case TextResource.SbmBaseCss:
|
||||
return SacsResourceHelper.GetTextResource(SacsResourceHelper.TextResource.SaBaseCss) + SacsResourceHelper.GetManifestResourceAsText(Assembly, "", "sbm_base.css");
|
||||
return SacsResourceHelper.GetResourceText(SacsResourceHelper.TextResource.SaBaseCss) + SacsResourceHelper.GetManifestResourceAsText(Assembly, "", "sbm_base.css");
|
||||
case TextResource.SbmBaseJs:
|
||||
return SacsResourceHelper.GetTextResource(SacsResourceHelper.TextResource.SaBaseJs) + SacsResourceHelper.GetManifestResourceAsText(Assembly, "", "sbm_base.js");
|
||||
return SacsResourceHelper.GetResourceText(SacsResourceHelper.TextResource.SaBaseJs) + SacsResourceHelper.GetManifestResourceAsText(Assembly, "", "sbm_base.js");
|
||||
|
||||
case TextResource.JQueryJs:
|
||||
return SacsResourceHelper.GetTextResource(SacsResourceHelper.TextResource.JQueryJs);
|
||||
return SacsResourceHelper.GetResourceText(SacsResourceHelper.TextResource.JQueryJs);
|
||||
case TextResource.JQueryUiCss:
|
||||
return SacsResourceHelper.GetTextResource(SacsResourceHelper.TextResource.JQueryUiCss);
|
||||
return SacsResourceHelper.GetResourceText(SacsResourceHelper.TextResource.JQueryUiCss);
|
||||
case TextResource.JQueryUiJs:
|
||||
return SacsResourceHelper.GetTextResource(SacsResourceHelper.TextResource.JQueryUiJs);
|
||||
return SacsResourceHelper.GetResourceText(SacsResourceHelper.TextResource.JQueryUiJs);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
@@ -31,27 +31,39 @@ namespace Sarand.BusinessMgr.Net.Standard.Base.App
|
||||
userData = CreateUserData(SessionContext, null, null, null);
|
||||
organisationData = new OrganisationData(null, null);
|
||||
}
|
||||
/// <summary>
|
||||
/// Primary constructor - on user login.
|
||||
/// <para>SessionContext and UserAccount must be supplied.</para>
|
||||
/// <para>Roles list is optional.</para>
|
||||
/// </summary>
|
||||
protected SbmSessionData(SbmSessionContext sessionContext, SaSecurityItem securityItemUser, SbmAffiliate affiliateUser, List<SysIdString> supervisedOrganisations, SbmAssociation associationOrganisation, SbmAffiliate affiliateOrganisation)
|
||||
{
|
||||
SessionIdx = ++sessionIdxRoot;
|
||||
ItemIdx = 1000;
|
||||
SessionContext = sessionContext;
|
||||
userData = CreateUserData(SessionContext, securityItemUser, affiliateUser, supervisedOrganisations);
|
||||
organisationData = new OrganisationData(associationOrganisation, affiliateOrganisation);
|
||||
}
|
||||
/// <summary>
|
||||
/// Plain constructor - Contorl application.
|
||||
/// <para>SessionContext must be supplied.</para>
|
||||
/// </summary>
|
||||
protected SbmSessionData(SbmSessionContext sessionContext)
|
||||
{
|
||||
SessionIdx = ++sessionIdxRoot;
|
||||
ItemIdx = 1000;
|
||||
SessionContext = sessionContext;
|
||||
}
|
||||
/// <summary>
|
||||
/// Primary constructor - on user login.
|
||||
/// <para>SessionContext and UserAccount must be supplied.</para>
|
||||
/// <para>Roles list is optional.</para>
|
||||
/// </summary>
|
||||
protected SbmSessionData(SbmSessionContext sessionContext, SaSecurityItem securityItemUser, SbmAffiliate affiliateUser, List<SysIdString> supervisedOrganisations, SbmAssociation associationOrganisation, SbmAffiliate affiliateOrganisation)
|
||||
{
|
||||
SessionIdx = ++sessionIdxRoot;
|
||||
ItemIdx = 1000;
|
||||
SessionContext = sessionContext;
|
||||
userData = CreateUserData(SessionContext, securityItemUser, affiliateUser, supervisedOrganisations);
|
||||
organisationData = new OrganisationData(associationOrganisation, affiliateOrganisation);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Properties.
|
||||
// Session and Item indexers.
|
||||
public long SessionIdx { get; }
|
||||
//-------------------------------------------------------------------
|
||||
// Properties.
|
||||
|
||||
// Session and Item indexers.
|
||||
public long SessionIdx { get; }
|
||||
public int ItemIdx { get; private set; }
|
||||
[JsonIgnore]
|
||||
public int NextItemIdx { get { return ++ItemIdx; } }
|
||||
|
||||
// Session context.
|
||||
public SbmSessionContext SessionContext { get; }
|
||||
[JsonIgnore]
|
||||
|
||||
@@ -874,8 +874,9 @@ namespace Sarand.BusinessMgr.Net.Standard.Base.Bus
|
||||
public Sbm.AssociationType AssociationType { get; set; } = Sbm.AssociationType.Any;
|
||||
public SysId AffiliateIdOwner { get; set; }
|
||||
public SysId AffiliateIdTarget { get; set; }
|
||||
public SysId PriceSetId { get; set; }
|
||||
public SysId AffiliateIdContactGroup { get; set; }
|
||||
/// <summary>Generic search value - code, name, phone, website, email, address etc.</summary>
|
||||
public String Search { get; set; }
|
||||
public String Code { get; set; }
|
||||
public String CodePartial { get; set; }
|
||||
public String NameTargetFull { get; set; }
|
||||
@@ -884,6 +885,7 @@ namespace Sarand.BusinessMgr.Net.Standard.Base.Bus
|
||||
public String GroupPartial { get; set; }
|
||||
public String AddressPartial { get; set; }
|
||||
public String PostcodePartial { get; set; }
|
||||
public SysId PriceSetId { get; set; }
|
||||
// Association codes.
|
||||
public String DefaultNominalCodeFull { get; set; }
|
||||
public String DefaultNominalCodePartial { get; set; }
|
||||
@@ -929,6 +931,14 @@ namespace Sarand.BusinessMgr.Net.Standard.Base.Bus
|
||||
public DateTime ApplicableFrom { get; set; }
|
||||
/// <summary>Status category.</summary>
|
||||
public StatusCat StatusCat { get; set; } = StatusCat.NotDeleted;
|
||||
|
||||
// Aliases for tables included in the query.
|
||||
public String Alias_Affiliate_Owner { get; set; }
|
||||
public String Alias_Affiliate_Target { get; set; }
|
||||
public String Alias_Address_Target { get; set; }
|
||||
public String Alias_Association_Member { get; set; }
|
||||
public String Alias_Address_Member { get; set; }
|
||||
public String Alias_PriceSet { get; set; }
|
||||
}
|
||||
}
|
||||
//=======================================================================
|
||||
|
||||
@@ -38,7 +38,7 @@ namespace Sarand.BusinessMgr.Net.Standard.Base.Core
|
||||
IUserData User { get; }
|
||||
bool ValidUser { get; }
|
||||
|
||||
/// <summary>Database upfate info - user session specific properties for database inserts/updates.</summary>
|
||||
/// <summary>Database update info - user session specific properties for database inserts/updates.</summary>
|
||||
DbUpdateInfo DbUpdateInfo { get; }
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
|
||||
@@ -542,10 +542,10 @@ namespace Sarand.BusinessMgr.Net.Standard.Base.Mgr
|
||||
ClearErrorState();
|
||||
if (!SysId.IsValid(affiliateIdOwner) || (int)associationType < 1 || !SysId.IsValid(affiliateIdTarget)) return null;
|
||||
SbmAssociation.Params prmAssociation = new SbmAssociation.Params();
|
||||
prmAssociation.IncludedIds.Add(affiliateIdOwner);
|
||||
prmAssociation.AffiliateIdOwner = affiliateIdOwner;
|
||||
prmAssociation.AssociationType = associationType;
|
||||
prmAssociation.IncludedIds.Add(affiliateIdTarget);
|
||||
prmAssociation.StatusCat = SbmAssociation.StatusCat.Any;
|
||||
prmAssociation.AffiliateIdTarget = affiliateIdTarget;
|
||||
prmAssociation.StatusCat = SbmAssociation.StatusCat.NotDeleted;
|
||||
return GetAssociation(prmAssociation);
|
||||
}
|
||||
public SbmAssociation GetAssociationByTypeCode(Sbm.AssociationType associationType, String associationCode)
|
||||
@@ -556,8 +556,8 @@ namespace Sarand.BusinessMgr.Net.Standard.Base.Mgr
|
||||
{
|
||||
AssociationType = associationType,
|
||||
Code = associationCode,
|
||||
StatusCat = SbmAssociation.StatusCat.Any
|
||||
};
|
||||
StatusCat = SbmAssociation.StatusCat.NotDeleted
|
||||
};
|
||||
return GetAssociation(prmAssociation);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netstandard2.1</TargetFramework>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<RootNamespace>Sarand.BusinessMgr.Net.Standard</RootNamespace>
|
||||
</PropertyGroup>
|
||||
|
||||
|
||||
@@ -1318,6 +1318,7 @@ namespace Sarand.BusinessMgr.Net.Standard.Dbas.Mgr
|
||||
{
|
||||
List<String> filter = new List<String>();
|
||||
|
||||
//---------------------------------------------------------------
|
||||
// Association Id.
|
||||
String colAssociation_Id = SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Association_Id, aliasAssociation);
|
||||
String includedIds = prm.IncludedIds.Concat(",");
|
||||
@@ -1332,6 +1333,7 @@ namespace Sarand.BusinessMgr.Net.Standard.Dbas.Mgr
|
||||
if (prm.AssociationType > 0)
|
||||
filter.Add(colAssociation_Type + "=" + ((int)prm.AssociationType).ToString());
|
||||
|
||||
//---------------------------------------------------------------
|
||||
// Owner affiliate.
|
||||
String colAssociation_AffIdOwner = SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Association_AffIdOwner, aliasAssociation);
|
||||
if (SysId.IsValid(prm.AffiliateIdOwner))
|
||||
@@ -1342,13 +1344,8 @@ namespace Sarand.BusinessMgr.Net.Standard.Dbas.Mgr
|
||||
if (SysId.IsValid(prm.AffiliateIdTarget))
|
||||
filter.Add(colAssociation_AffIdTarget + "=" + prm.AffiliateIdTarget.ToString());
|
||||
|
||||
// Price Set.
|
||||
String colAssociation_PriceSetId = SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Association_PriceSetId, aliasAssociation);
|
||||
if (SysId.IsValid(prm.PriceSetId))
|
||||
filter.Add(colAssociation_PriceSetId + "=" + prm.PriceSetId.ToString());
|
||||
|
||||
//---------------------------------------------------------------
|
||||
// Contact Group:
|
||||
// Contact Group.
|
||||
if (SysId.IsValid(prm.AffiliateIdContactGroup))
|
||||
{
|
||||
//Association must also be a member of this contact group.
|
||||
@@ -1368,54 +1365,80 @@ namespace Sarand.BusinessMgr.Net.Standard.Dbas.Mgr
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------
|
||||
// Affiliate TargetName & Partial TargetName attributes.
|
||||
// Code.
|
||||
String colAssociation_Code = SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Association_Code, aliasAssociation);
|
||||
if (!prm.Code.IsEmpty())
|
||||
filter.Add(colAssociation_Code + "='" + DbQuery.FormatForCondition(prm.Code) + "'");
|
||||
else if (!prm.CodePartial.IsEmpty())
|
||||
filter.Add(DbQuery.FormatFn_Left(colAssociation_Code, prm.CodePartial.Length) + " Like '%" + DbQuery.FormatForLike(prm.CodePartial) + "%'");
|
||||
|
||||
// Group.
|
||||
String colAssociation_Group = SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Association_Group, aliasAssociation);
|
||||
if (!prm.GroupFull.IsEmpty())
|
||||
filter.Add(colAssociation_Group + "='" + DbQuery.FormatForCondition(prm.GroupFull) + "'");
|
||||
else if (!prm.GroupPartial.IsEmpty())
|
||||
filter.Add(DbQuery.FormatFn_Left(colAssociation_Group, prm.GroupPartial.Length) + " Like '%" + DbQuery.FormatForLike(prm.GroupPartial) + "%'");
|
||||
|
||||
//---------------------------------------------------------------
|
||||
// Target Name.
|
||||
if (!prm.NameTargetFull.IsEmpty() || !prm.NameTargetPartial.IsEmpty())
|
||||
{
|
||||
// Target name has been specified.
|
||||
String tableAffiliate = SbmDbDfn.GetTableName(SbmDbDfn.TableIdx.Affiliate);
|
||||
String colAffiliate_Id = SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Affiliate_Id);
|
||||
String colAffiliate_Name = SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Affiliate_Name);
|
||||
String colAffiliate_FirstName = SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Affiliate_FirstName);
|
||||
String colAfiliate_LastName = SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Affiliate_LastName);
|
||||
// Target affiliate alias.
|
||||
String aliasAffiliateTarget = StringUtil.OnEmpty(prm.Alias_Affiliate_Target, aliasAssociation_Affiliate_Target);
|
||||
|
||||
// Clause to identify associations with targets that match the partial name.
|
||||
DbQuery queryAffTarget = new DbQuery(db.DbmsType);
|
||||
queryAffTarget.Tables.Add(tableAffiliate);
|
||||
queryAffTarget.Columns.Add(colAffiliate_Id);
|
||||
queryAffTarget.Filters.Add(colAffiliate_Id + "=" + colAssociation_AffIdTarget);
|
||||
// Target affiliate columns.
|
||||
String colAffiliate_Id = SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Affiliate_Id, aliasAffiliateTarget);
|
||||
String colAffiliate_Name = SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Affiliate_Name, aliasAffiliateTarget);
|
||||
String colAffiliate_FirstName = SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Affiliate_FirstName, aliasAffiliateTarget);
|
||||
String colAffiliate_LastName = SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Affiliate_LastName, aliasAffiliateTarget);
|
||||
|
||||
// Filters.
|
||||
List<String> affiliateFilter = new List<string>();
|
||||
String nameTargetFull = DbQuery.FormatForCondition(StringUtil.EmptyOnNull(prm.NameTargetFull));
|
||||
String nameTargetPartial = DbQuery.FormatForCondition(StringUtil.EmptyOnNull(prm.NameTargetPartial));
|
||||
String nameTargetPartial = DbQuery.FormatForLike(StringUtil.EmptyOnNull(prm.NameTargetPartial));
|
||||
if (!nameTargetFull.IsEmpty())
|
||||
queryAffTarget.Filters.Add(colAffiliate_Name + "='" + nameTargetFull + "' OR " + colAfiliate_LastName + "='" + nameTargetFull + "'");
|
||||
affiliateFilter.Add(colAffiliate_Name + "='" + nameTargetFull + "' OR " + colAffiliate_LastName + "='" + nameTargetFull + "'");
|
||||
if (!nameTargetPartial.IsEmpty())
|
||||
queryAffTarget.Filters.Add(
|
||||
DbQuery.FormatFn_Left(colAffiliate_Name, nameTargetPartial.Length) + "='" + nameTargetPartial + "' OR " +
|
||||
DbQuery.FormatFn_Left(colAffiliate_FirstName, nameTargetPartial.Length) + "='" + nameTargetPartial + "' OR " +
|
||||
DbQuery.FormatFn_Left(colAfiliate_LastName, nameTargetPartial.Length) + "='" + nameTargetPartial + "'");
|
||||
filter.Add("EXISTS (" + queryAffTarget.BuildQuery() + ")");
|
||||
affiliateFilter.Add(
|
||||
colAffiliate_Name + " Like '%" + nameTargetPartial + "%' OR " +
|
||||
colAffiliate_FirstName + " Like '%" + nameTargetPartial + "%' OR " +
|
||||
colAffiliate_LastName + " Like '%" + nameTargetPartial + "%'");
|
||||
|
||||
if (prm.Alias_Affiliate_Target.IsEmpty())
|
||||
{
|
||||
// Target affiliate alias not supplied - table is not joined in main query.
|
||||
// Sub query on target affiliate.
|
||||
DbQuery queryAffTarget = new DbQuery(db.DbmsType);
|
||||
queryAffTarget.Tables.Add(SbmDbDfn.GetTableName(SbmDbDfn.TableIdx.Affiliate), aliasAffiliateTarget);
|
||||
queryAffTarget.Columns.Add(colAffiliate_Id);
|
||||
queryAffTarget.Filters.Add(colAffiliate_Id + "=" + colAssociation_AffIdTarget);
|
||||
queryAffTarget.Filters.AddRange(affiliateFilter);
|
||||
filter.Add("EXISTS (" + queryAffTarget.BuildQuery() + ")");
|
||||
}
|
||||
else
|
||||
{
|
||||
// Target affiliate alias supplied - table is joined in main query.
|
||||
// Simply filter directly on joined table.
|
||||
filter.AddRange(affiliateFilter);
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------
|
||||
// Partial Address & Postcode for AddTarget.
|
||||
// Target Address & Postcode.
|
||||
if (!StringUtil.IsEmpty(prm.AddressPartial) || !StringUtil.IsEmpty(prm.PostcodePartial))
|
||||
{
|
||||
// Clause to identify associations with target addresses that match the details specified.
|
||||
String aliasAddTarget = "aAddTarget";
|
||||
DbQuery queryAddTarget = new DbQuery(db.DbmsType);
|
||||
String tableAddress = SbmDbDfn.GetTableName(SbmDbDfn.TableIdx.Address);
|
||||
queryAddTarget.Tables.Add(tableAddress, aliasAddTarget);
|
||||
// Target Address alias.
|
||||
String aliasAddTarget = StringUtil.OnEmpty(prm.Alias_Address_Target, "aAddTarget");
|
||||
|
||||
// Target address columns.
|
||||
String colAddress_Id = SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Address_Id, aliasAddTarget);
|
||||
queryAddTarget.Columns.Add(colAddress_Id);
|
||||
String colAddress_ItemType = SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Address_ItemType, aliasAddTarget);
|
||||
queryAddTarget.Filters.Add(colAddress_ItemType + "=" + ((int)Sbm.ItemType.Affiliate).ToString());
|
||||
String colAddress_ItemId = SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Address_ItemId, aliasAddTarget);
|
||||
queryAddTarget.Filters.Add(colAddress_ItemId + "=" + colAssociation_AffIdTarget);
|
||||
|
||||
// Address filter.
|
||||
String addressLike = DbQuery.FormatForLike(StringUtil.EmptyOnNull(prm.AddressPartial));
|
||||
if (!StringUtil.IsEmpty(addressLike))
|
||||
// Filters.
|
||||
List<String> addressFilter = new List<string>();
|
||||
String addressPartial = DbQuery.FormatForLike(StringUtil.EmptyOnNull(prm.AddressPartial));
|
||||
if (!StringUtil.IsEmpty(addressPartial))
|
||||
{
|
||||
List<SbmDbDfn.ColumnIdx> addressCols = new List<SbmDbDfn.ColumnIdx>()
|
||||
{
|
||||
@@ -1427,45 +1450,133 @@ namespace Sarand.BusinessMgr.Net.Standard.Dbas.Mgr
|
||||
SbmDbDfn.ColumnIdx.Address_Province,
|
||||
SbmDbDfn.ColumnIdx.Address_Contact,
|
||||
};
|
||||
List<String> filterAddress = new List<String>();
|
||||
foreach (SbmDbDfn.ColumnIdx addressCol in addressCols)
|
||||
filterAddress.Add(SbmDbDfn.GetColumnNameQual(addressCol, aliasAddTarget) + " LIKE '%" + addressLike + "%'");
|
||||
queryAddTarget.Filters.Add(filterAddress.Concat(" OR ", "(", ")"));
|
||||
String partialAddressFilter = addressCols.Select(item => SbmDbDfn.GetColumnNameQual(item, aliasAddTarget) + " LIKE '%" + addressPartial + "%'").Concat(" OR ", "(", ")");
|
||||
addressFilter.Add(partialAddressFilter);
|
||||
}
|
||||
// Postcode filter.
|
||||
String postcodeCond = DbQuery.FormatForCondition(StringUtil.EmptyOnNull(prm.PostcodePartial));
|
||||
String colAddress_PostcodeFmt = SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Address_PostcodeFmt, aliasAddTarget);
|
||||
if (!StringUtil.IsEmpty(postcodeCond))
|
||||
queryAddTarget.Filters.Add(DbQuery.FormatFn_Left(colAddress_PostcodeFmt, prm.PostcodePartial.Length) + "='" + postcodeCond + "'");
|
||||
filter.Add("EXISTS (" + queryAddTarget.BuildQuery() + ")");
|
||||
addressFilter.Add(DbQuery.FormatFn_Left(colAddress_PostcodeFmt, prm.PostcodePartial.Length) + "='" + postcodeCond + "'");
|
||||
|
||||
if (prm.Alias_Address_Target.IsEmpty())
|
||||
{
|
||||
// Target address alias not supplied - table is not joined in main query.
|
||||
// Sub query on target address.
|
||||
DbQuery queryAddTarget = new DbQuery(db.DbmsType);
|
||||
queryAddTarget.Tables.Add(SbmDbDfn.GetTableName(SbmDbDfn.TableIdx.Address), aliasAddTarget);
|
||||
queryAddTarget.Columns.Add(colAddress_Id);
|
||||
queryAddTarget.Filters.Add(colAddress_ItemType + "=" + ((int)Sbm.ItemType.Affiliate).ToString());
|
||||
queryAddTarget.Filters.Add(colAddress_ItemId + "=" + colAssociation_AffIdTarget);
|
||||
queryAddTarget.Filters.AddRange(addressFilter);
|
||||
filter.Add("EXISTS (" + queryAddTarget.BuildQuery() + ")");
|
||||
}
|
||||
else
|
||||
{
|
||||
// Target address alias supplied - table is joined in main query.
|
||||
// Simply filter directly on joined table.
|
||||
filter.AddRange(addressFilter);
|
||||
}
|
||||
}
|
||||
|
||||
// Full & Partial DefaultNominalCode.
|
||||
//---------------------------------------------------------------
|
||||
// Generic search.
|
||||
if (!StringUtil.IsEmpty(prm.Search))
|
||||
{
|
||||
List<String> searchFilter = new List<string>();
|
||||
foreach (String rawSearchValue in prm.Search.Split(new char[] { ' ', ',', ';' }))
|
||||
{
|
||||
String searchValue = DbQuery.FormatForLike(StringUtil.TrimAll(rawSearchValue));
|
||||
if (StringUtil.IsEmpty(searchValue)) continue;
|
||||
|
||||
// Association filters.
|
||||
List<String> searchValueFilter = new List<string>();
|
||||
searchValueFilter.Add(colAssociation_Code + " LIKE '%" + searchValue + "%'");
|
||||
searchValueFilter.Add(colAssociation_Group + " LIKE '%" + searchValue + "%'");
|
||||
|
||||
// Target affiliate.
|
||||
String aliasAffiliateTarget = StringUtil.OnEmpty(prm.Alias_Affiliate_Target, aliasAssociation_Affiliate_Target);
|
||||
String colAffiliate_Id = SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Affiliate_Id, aliasAffiliateTarget);
|
||||
String colAffiliate_Name = SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Affiliate_Name, aliasAffiliateTarget);
|
||||
List<String> affiliateFilter = new List<string>();
|
||||
affiliateFilter.Add(colAffiliate_Name + " Like '%" + searchValue + "%'");
|
||||
if (prm.Alias_Affiliate_Target.IsEmpty())
|
||||
{
|
||||
// Target affiliate alias not supplied - table is not joined in main query.
|
||||
// Sub query on target affiliate.
|
||||
DbQuery queryAffTarget = new DbQuery(db.DbmsType);
|
||||
queryAffTarget.Tables.Add(SbmDbDfn.GetTableName(SbmDbDfn.TableIdx.Affiliate), aliasAffiliateTarget);
|
||||
queryAffTarget.Columns.Add(colAffiliate_Id);
|
||||
queryAffTarget.Filters.Add(colAffiliate_Id + "=" + colAssociation_AffIdTarget);
|
||||
queryAffTarget.Filters.AddRange(affiliateFilter);
|
||||
filter.Add("EXISTS (" + queryAffTarget.BuildQuery() + ")");
|
||||
}
|
||||
else
|
||||
{
|
||||
// Target affiliate alias supplied - table is joined in main query.
|
||||
// Simply filter directly on joined table.
|
||||
searchValueFilter.AddRange(affiliateFilter);
|
||||
}
|
||||
|
||||
// Target address.
|
||||
String aliasAddTarget = StringUtil.OnEmpty(prm.Alias_Address_Target, "aAddTarget");
|
||||
String colAddress_Id = SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Address_Id, aliasAddTarget);
|
||||
String colAddress_ItemType = SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Address_ItemType, aliasAddTarget);
|
||||
String colAddress_ItemId = SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Address_ItemId, aliasAddTarget);
|
||||
List<String> addressFilter = new List<string>();
|
||||
List<SbmDbDfn.ColumnIdx> addressCols = new List<SbmDbDfn.ColumnIdx>()
|
||||
{
|
||||
SbmDbDfn.ColumnIdx.Address_Name,
|
||||
SbmDbDfn.ColumnIdx.Address_Line1,
|
||||
SbmDbDfn.ColumnIdx.Address_Line2,
|
||||
SbmDbDfn.ColumnIdx.Address_Line3,
|
||||
SbmDbDfn.ColumnIdx.Address_City,
|
||||
SbmDbDfn.ColumnIdx.Address_Province,
|
||||
SbmDbDfn.ColumnIdx.Address_Postcode,
|
||||
SbmDbDfn.ColumnIdx.Address_PostcodeFmt,
|
||||
SbmDbDfn.ColumnIdx.Address_Contact,
|
||||
};
|
||||
String partialAddressFilter = addressCols.Select(item => SbmDbDfn.GetColumnNameQual(item, aliasAddTarget) + " LIKE '%" + searchValue + "%'").Concat(" OR ", "(", ")");
|
||||
addressFilter.Add(partialAddressFilter);
|
||||
if (prm.Alias_Address_Target.IsEmpty())
|
||||
{
|
||||
// Target address alias not supplied - table is not joined in main query.
|
||||
// Sub query on target address.
|
||||
DbQuery queryAddTarget = new DbQuery(db.DbmsType);
|
||||
queryAddTarget.Tables.Add(SbmDbDfn.GetTableName(SbmDbDfn.TableIdx.Address), aliasAddTarget);
|
||||
queryAddTarget.Columns.Add(colAddress_Id);
|
||||
queryAddTarget.Filters.Add(colAddress_ItemType + "=" + ((int)Sbm.ItemType.Affiliate).ToString());
|
||||
queryAddTarget.Filters.Add(colAddress_ItemId + "=" + colAssociation_AffIdTarget);
|
||||
queryAddTarget.Filters.AddRange(addressFilter);
|
||||
filter.Add("EXISTS (" + queryAddTarget.BuildQuery() + ")");
|
||||
}
|
||||
else
|
||||
{
|
||||
// Target address alias supplied - table is joined in main query.
|
||||
// Simply filter directly on joined table.
|
||||
searchValueFilter.AddRange(addressFilter);
|
||||
}
|
||||
|
||||
searchFilter.Add(searchValueFilter.Concat(" OR ", "(", ")"));
|
||||
}
|
||||
filter.AddRange(searchFilter);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------
|
||||
// Default Nominal Code.
|
||||
String defaultNominalCodeFull = DbQuery.FormatForCondition(StringUtil.EmptyOnNull(prm.DefaultNominalCodeFull));
|
||||
String defaultNominalCodePartial = DbQuery.FormatForCondition(StringUtil.EmptyOnNull(prm.DefaultNominalCodePartial));
|
||||
String colAssociation_DefaultNominalCode = SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Association_DefaultNominalCode, aliasAssociation);
|
||||
if (!defaultNominalCodeFull.IsEmpty())
|
||||
filter.Add(colAssociation_DefaultNominalCode + "='" + defaultNominalCodeFull + "'");
|
||||
filter.Add(colAssociation_DefaultNominalCode + "='" + DbQuery.FormatForCondition(defaultNominalCodeFull) + "'");
|
||||
else if (!defaultNominalCodePartial.IsEmpty())
|
||||
filter.Add(DbQuery.FormatFn_Left(colAssociation_DefaultNominalCode, prm.DefaultNominalCodePartial.Length) + "='" + defaultNominalCodePartial + "'");
|
||||
filter.Add(DbQuery.FormatFn_Left(colAssociation_DefaultNominalCode, prm.DefaultNominalCodePartial.Length) + " Like '%" + DbQuery.FormatForLike(defaultNominalCodePartial) + "%'");
|
||||
|
||||
// Full & Partial Code.
|
||||
String codeFull = DbQuery.FormatForCondition(StringUtil.EmptyOnNull(prm.Code));
|
||||
String codePartial = DbQuery.FormatForCondition(StringUtil.EmptyOnNull(prm.CodePartial));
|
||||
String colAssociation_Code = SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Association_Code, aliasAssociation);
|
||||
if (!codeFull.IsEmpty())
|
||||
filter.Add(colAssociation_Code + "='" + codeFull + "'");
|
||||
else if (!codePartial.IsEmpty())
|
||||
filter.Add(DbQuery.FormatFn_Left(colAssociation_Code, prm.CodePartial.Length) + "='" + codePartial + "'");
|
||||
|
||||
// Full & Partial Group.
|
||||
String groupFull = DbQuery.FormatForCondition(StringUtil.EmptyOnNull(prm.GroupFull));
|
||||
String groupPartial = DbQuery.FormatForCondition(StringUtil.EmptyOnNull(prm.GroupPartial));
|
||||
String colAssociation_Group = SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Association_Group, aliasAssociation);
|
||||
if (!groupFull.IsEmpty())
|
||||
filter.Add(colAssociation_Group + "='" + groupFull + "'");
|
||||
else if (!groupPartial.IsEmpty())
|
||||
filter.Add(DbQuery.FormatFn_Left(colAssociation_Group, prm.GroupPartial.Length) + "='" + groupPartial + "'");
|
||||
//---------------------------------------------------------------
|
||||
// Price Set.
|
||||
String colAssociation_PriceSetId = SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Association_PriceSetId, aliasAssociation);
|
||||
if (SysId.IsValid(prm.PriceSetId))
|
||||
filter.Add(colAssociation_PriceSetId + "=" + prm.PriceSetId.ToString());
|
||||
|
||||
//---------------------------------------------------------------
|
||||
// Codings.
|
||||
@@ -1943,20 +2054,20 @@ namespace Sarand.BusinessMgr.Net.Standard.Dbas.Mgr
|
||||
query.Columns.Add(SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Association_UpdateOn, aliasAssociation));
|
||||
|
||||
//---------------------------------------------------------------
|
||||
// Owner affiliate columns
|
||||
// Owner affiliate.
|
||||
bool hasColsAffOwner = false;
|
||||
if (!hasColsAffOwner)
|
||||
hasColsAffOwner = columns.HasId((int)SbmAssociation.Column.Owner_Name);
|
||||
|
||||
bool hasColsAffOwnerAddress = false;
|
||||
if (hasColsAffOwner || hasColsAffOwnerAddress)
|
||||
{
|
||||
// Join to the owner affiliate.
|
||||
DbQueryJoin joinPriceSetOwner = new DbQueryJoin(DbJoinType.LeftOuter);
|
||||
joinPriceSetOwner.Table = new StringPair(SbmDbDfn.GetTableName(SbmDbDfn.TableIdx.Affiliate), aliasAssociation_Affiliate_Owner);
|
||||
joinPriceSetOwner.Filters.Add(SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Affiliate_Id, aliasAssociation_Affiliate_Owner) + "=" + SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Association_AffIdOwner, aliasAssociation));
|
||||
query.Joins.Add(joinPriceSetOwner);
|
||||
// Add the owner affiliate columns.
|
||||
prm.Alias_Affiliate_Owner = aliasAssociation_Affiliate_Owner;
|
||||
DbQueryJoin joinAffiliateOwner = new DbQueryJoin(DbJoinType.LeftOuter);
|
||||
joinAffiliateOwner.Table = new StringPair(SbmDbDfn.GetTableName(SbmDbDfn.TableIdx.Affiliate), aliasAssociation_Affiliate_Owner);
|
||||
joinAffiliateOwner.Filters.Add(SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Affiliate_Id, aliasAssociation_Affiliate_Owner) + "=" + SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Association_AffIdOwner, aliasAssociation));
|
||||
query.Joins.Add(joinAffiliateOwner);
|
||||
// Columns.
|
||||
List<SbmDbDfn.ColumnIdx> affiliateOwnerCols = new List<SbmDbDfn.ColumnIdx>()
|
||||
{
|
||||
SbmDbDfn.ColumnIdx.Affiliate_Id,
|
||||
@@ -1979,7 +2090,7 @@ namespace Sarand.BusinessMgr.Net.Standard.Dbas.Mgr
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------
|
||||
// Target affiliate columns.
|
||||
// Target affiliate.
|
||||
bool hasColsAffTarget = false;
|
||||
if (!hasColsAffTarget) hasColsAffTarget = columns.HasId((int)SbmAssociation.Column.Target_Type) || columns.HasId((int)SbmAssociation.Column.Target_TypeDesc);
|
||||
if (!hasColsAffTarget) hasColsAffTarget = columns.HasId((int)SbmAssociation.Column.Target_Name);
|
||||
@@ -2021,10 +2132,11 @@ namespace Sarand.BusinessMgr.Net.Standard.Dbas.Mgr
|
||||
if (hasColsAffTarget || hasColsAffTargetAddress)
|
||||
{
|
||||
// Join to the target affiliate - NB Use an alias to avoid clashing with the owner affiliate.
|
||||
DbQueryJoin joinPriceSetTarget = new DbQueryJoin(DbJoinType.LeftOuter);
|
||||
joinPriceSetTarget.Table = new StringPair(SbmDbDfn.GetTableName(SbmDbDfn.TableIdx.Affiliate), aliasAssociation_Affiliate_Target);
|
||||
joinPriceSetTarget.Filters.Add(SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Affiliate_Id, aliasAssociation_Affiliate_Target) + "=" + SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Association_AffIdTarget, aliasAssociation));
|
||||
query.Joins.Add(joinPriceSetTarget);
|
||||
prm.Alias_Affiliate_Target = aliasAssociation_Affiliate_Target;
|
||||
DbQueryJoin joinAffiliateTarget = new DbQueryJoin(DbJoinType.LeftOuter);
|
||||
joinAffiliateTarget.Table = new StringPair(SbmDbDfn.GetTableName(SbmDbDfn.TableIdx.Affiliate), aliasAssociation_Affiliate_Target);
|
||||
joinAffiliateTarget.Filters.Add(SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Affiliate_Id, aliasAssociation_Affiliate_Target) + "=" + SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Association_AffIdTarget, aliasAssociation));
|
||||
query.Joins.Add(joinAffiliateTarget);
|
||||
// Add the target affiliate columns.
|
||||
List<SbmDbDfn.ColumnIdx> affiliateTargetCols = new List<SbmDbDfn.ColumnIdx>();
|
||||
affiliateTargetCols.Add(SbmDbDfn.ColumnIdx.Affiliate_Id);
|
||||
@@ -2053,6 +2165,7 @@ namespace Sarand.BusinessMgr.Net.Standard.Dbas.Mgr
|
||||
if (hasColsAffTargetAddress)
|
||||
{
|
||||
// Join to the target contact's primary address.
|
||||
prm.Alias_Address_Target = aliasAssociation_Target_Address;
|
||||
DbQueryJoin joinTargetAddress = new DbQueryJoin(DbJoinType.LeftOuter);
|
||||
joinTargetAddress.Table = new StringPair(SbmDbDfn.GetTableName(SbmDbDfn.TableIdx.Address), aliasAssociation_Target_Address);
|
||||
// Address context.
|
||||
@@ -2174,6 +2287,7 @@ namespace Sarand.BusinessMgr.Net.Standard.Dbas.Mgr
|
||||
if (hasColsMember || hasColsMemberAddress)
|
||||
{
|
||||
// Join to the member association - NB Use an alias to avoid clashing with the target affiliate.
|
||||
prm.Alias_Association_Member = aliasAssociation_Member_Association;
|
||||
DbQueryJoin joinPriceSetMemberAss = new DbQueryJoin(DbJoinType.LeftOuter);
|
||||
joinPriceSetMemberAss.Table = new StringPair(SbmDbDfn.GetTableName(SbmDbDfn.TableIdx.Association), aliasAssociation_Member_Association);
|
||||
joinPriceSetMemberAss.Filters.Add(SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Association_AffIdOwner, aliasAssociation_Member_Association) + "=" + SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Association_AffIdTarget));
|
||||
@@ -2215,6 +2329,7 @@ namespace Sarand.BusinessMgr.Net.Standard.Dbas.Mgr
|
||||
if (hasColsMemberAddress)
|
||||
{
|
||||
// Join to the Member affiliate - NB Use an alias to avoid clashing with the owner affiliate.
|
||||
prm.Alias_Address_Member = aliasAssociation_Member_Address;
|
||||
DbQueryJoin joinPriceSetMemberAddress = new DbQueryJoin(DbJoinType.LeftOuter);
|
||||
joinPriceSetMemberAddress.Table = new StringPair(SbmDbDfn.GetTableName(SbmDbDfn.TableIdx.Address), aliasAssociation_Member_Address);
|
||||
joinPriceSetMemberAddress.Filters.Add(SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Address_AffIdOwner, aliasAssociation_Member_Address) + "=" + SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Affiliate_Id, aliasAssociation_Member_Affiliate));
|
||||
@@ -2254,6 +2369,7 @@ namespace Sarand.BusinessMgr.Net.Standard.Dbas.Mgr
|
||||
if (hasColsPriceSet)
|
||||
{
|
||||
// Join to the Price Set.
|
||||
prm.Alias_PriceSet = aliasAssociation_PriceSet;
|
||||
DbQueryJoin joinPriceSet = new DbQueryJoin(DbJoinType.LeftOuter);
|
||||
joinPriceSet.Table = new StringPair(SbmDbDfn.GetTableName(SbmDbDfn.TableIdx.SaPriceSet), aliasAssociation_PriceSet);
|
||||
joinPriceSet.Filters.Add(SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.SaPriceSet_Id, aliasAssociation_PriceSet) + "=" + SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Association_PriceSetId, aliasAssociation));
|
||||
|
||||
@@ -57,7 +57,7 @@ namespace Sarand.BusinessMgr.Net.Standard.Dbas.Utils
|
||||
OutputDirectory = directory
|
||||
};
|
||||
// Schema - Tables.
|
||||
config.Schema.Tables_Excluded.AddRange(new String[] { });
|
||||
config.Schema.Tables_Excluded.UnionWith(new String[] { });
|
||||
// Schema - Columns.
|
||||
config.Schema.InsertOnlyColumns.Add(".*", "CreateOn,CreateBy,CreateHost");
|
||||
// Database definition class.
|
||||
|
||||
@@ -63,7 +63,7 @@ namespace Sarand.BusinessMgr.Net.Standard.Dbas.Utils
|
||||
OutputDirectory = directory
|
||||
};
|
||||
// Schema - Tables.
|
||||
config.Schema.Tables_Excluded.AddRange(new String[] { "NextId", "SaCode", "SaCodeType", "SaSecItem", "SaSecurityItem", "SaSecLink", "SaSecurityLink", "SaItemData", "SaItemDoc", "SaItemOption", "SaInterface", "SaInterfaceProcess", "SaInterfaceProcessMessage", "SaInterfaceDataItem", "SaInterfaceProcessDataItem", "SaAttrUpdate" });
|
||||
config.Schema.Tables_Excluded.UnionWith(new String[] { "NextId", "SaCode", "SaCodeType", "SaSecItem", "SaSecurityItem", "SaSecLink", "SaSecurityLink", "SaItemData", "SaItemDoc", "SaItemOption", "SaInterface", "SaInterfaceProcess", "SaInterfaceProcessMessage", "SaInterfaceDataItem", "SaInterfaceProcessDataItem", "SaAttrUpdate" });
|
||||
// Schema - Columns.
|
||||
config.Schema.InsertOnlyColumns.Add(".*", "CreateOn,CreateBy,CreateHost");
|
||||
// Database definition class.
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netstandard2.1</TargetFramework>
|
||||
<RootNamespace>Sarand.BusinessMgr.Net.Standard</RootNamespace>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<RootNamespace>Sarand.BusinessMgr.Net.Standard</RootNamespace>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\..\Common-VS\Workspace\SacsStandardBase\SacsStandardBase.csproj" />
|
||||
<ProjectReference Include="..\..\..\Common-VS\Workspace\SacsStandardDbas\SacsStandardDbas.csproj" />
|
||||
<ProjectReference Include="..\SaBusMgrStandardBase\SaBusMgrStandardBase.csproj" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\..\Common-VS\Workspace\SacsStandardBase\SacsStandardBase.csproj" />
|
||||
<ProjectReference Include="..\..\..\Common-VS\Workspace\SacsStandardDbas\SacsStandardDbas.csproj" />
|
||||
<ProjectReference Include="..\SaBusMgrStandardBase\SaBusMgrStandardBase.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Folder Include="Dbas\Internal\Control\" />
|
||||
<Folder Include="Resources\Database\" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Folder Include="Dbas\Internal\Control\" />
|
||||
<Folder Include="Resources\Database\" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
||||
@@ -1,54 +1,57 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<SSDTUnitTestPath Condition="'$(SSDTUnitTestPath)' == ''">$(VsInstallRoot)\Common7\IDE\Extensions\Microsoft\SQLDB</SSDTUnitTestPath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<SSDTPath Condition="'$(SSDTPath)' == ''">$(VsInstallRoot)\Common7\IDE\Extensions\Microsoft\SQLDB\DAC\130</SSDTPath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">10.0</VisualStudioVersion>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netcoreapp3.1</TargetFramework>
|
||||
<IsPackable>false</IsPackable>
|
||||
<RootNamespace>Sarand.BusinessMgr</RootNamespace>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.5.0" />
|
||||
<PackageReference Include="Moq" Version="4.16.1" />
|
||||
<PackageReference Include="MSTest.TestAdapter" Version="2.1.0" />
|
||||
<PackageReference Include="MSTest.TestFramework" Version="2.1.0" />
|
||||
<PackageReference Include="coverlet.collector" Version="1.2.0" />
|
||||
</ItemGroup>
|
||||
<ItemGroup Condition="$(VisualStudioVersion) == '16.0'">
|
||||
<Reference Include="Microsoft.Data.Tools.Schema.Sql, Version=15.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>$(SSDTPath)\Microsoft.Data.Tools.Schema.Sql.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.Data.Tools.Schema.Sql.UnitTesting, Version=16.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>$(SSDTUnitTestPath)\Microsoft.Data.Tools.Schema.Sql.UnitTesting.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.Data.Tools.Schema.Sql.UnitTestingAdapter, Version=16.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>$(SSDTUnitTestPath)\Microsoft.Data.Tools.Schema.Sql.UnitTestingAdapter.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\..\Common-VS\Workspace\SacsCoreWeb\SacsCoreWeb.csproj" />
|
||||
<ProjectReference Include="..\..\..\Common-VS\Workspace\SacsStandardAccounts\SacsStandardAccounts.csproj" />
|
||||
<ProjectReference Include="..\..\..\Common-VS\Workspace\SacsStandardBase\SacsStandardBase.csproj" />
|
||||
<ProjectReference Include="..\..\..\Common-VS\Workspace\SacsStandardDbas\SacsStandardDbas.csproj" />
|
||||
<ProjectReference Include="..\..\..\Common-VS\Workspace\SacsStandardProc\SacsStandardProc.csproj" />
|
||||
<ProjectReference Include="..\SaBusinessMgrCoreWebPortal\SaBusinessMgrCoreWebPortal.csproj" />
|
||||
<ProjectReference Include="..\SaBusMgrCoreProcs\SaBusMgrCoreProcs.csproj" />
|
||||
<ProjectReference Include="..\SaBusMgrCoreWeb\SaBusMgrCoreWeb.csproj" />
|
||||
<ProjectReference Include="..\SaBusMgrStandardBase\SaBusMgrStandardBase.csproj" />
|
||||
<ProjectReference Include="..\SaBusMgrStandardDbas\SaBusMgrStandardDbas.csproj" />
|
||||
</ItemGroup>
|
||||
<PropertyGroup>
|
||||
<SsdtUnitTestVersion>3.1</SsdtUnitTestVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(SQLDBExtensionsRefPath)\Microsoft.Data.Tools.Schema.Sql.UnitTesting.targets" Condition="$(VisualStudioVersion) != '15.0' And '$(SQLDBExtensionsRefPath)' != ''" />
|
||||
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\SSDT\Microsoft.Data.Tools.Schema.Sql.UnitTesting.targets" Condition="$(VisualStudioVersion) != '15.0' And '$(SQLDBExtensionsRefPath)' == ''" />
|
||||
<PropertyGroup>
|
||||
<SSDTUnitTestPath Condition="'$(SSDTUnitTestPath)' == ''">$(VsInstallRoot)\Common7\IDE\Extensions\Microsoft\SQLDB</SSDTUnitTestPath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<SSDTPath Condition="'$(SSDTPath)' == ''">$(VsInstallRoot)\Common7\IDE\Extensions\Microsoft\SQLDB\DAC\130</SSDTPath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">10.0</VisualStudioVersion>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<IsPackable>false</IsPackable>
|
||||
<RootNamespace>Sarand.BusinessMgr</RootNamespace>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.10.0" />
|
||||
<PackageReference Include="Moq" Version="4.20.70" />
|
||||
<PackageReference Include="MSTest.TestAdapter" Version="3.4.3" />
|
||||
<PackageReference Include="MSTest.TestFramework" Version="3.4.3" />
|
||||
<PackageReference Include="coverlet.collector" Version="6.0.2">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup Condition="$(VisualStudioVersion) == '16.0'">
|
||||
<Reference Include="Microsoft.Data.Tools.Schema.Sql, Version=15.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>$(SSDTPath)\Microsoft.Data.Tools.Schema.Sql.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.Data.Tools.Schema.Sql.UnitTesting, Version=16.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>$(SSDTUnitTestPath)\Microsoft.Data.Tools.Schema.Sql.UnitTesting.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.Data.Tools.Schema.Sql.UnitTestingAdapter, Version=16.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>$(SSDTUnitTestPath)\Microsoft.Data.Tools.Schema.Sql.UnitTestingAdapter.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\..\Common-VS\Workspace\SacsCoreWeb\SacsCoreWeb.csproj" />
|
||||
<ProjectReference Include="..\..\..\Common-VS\Workspace\SacsStandardAccounts\SacsStandardAccounts.csproj" />
|
||||
<ProjectReference Include="..\..\..\Common-VS\Workspace\SacsStandardBase\SacsStandardBase.csproj" />
|
||||
<ProjectReference Include="..\..\..\Common-VS\Workspace\SacsStandardDbas\SacsStandardDbas.csproj" />
|
||||
<ProjectReference Include="..\..\..\Common-VS\Workspace\SacsStandardProc\SacsStandardProc.csproj" />
|
||||
<ProjectReference Include="..\SaBusinessMgrCoreWebPortal\SaBusinessMgrCoreWebPortal.csproj" />
|
||||
<ProjectReference Include="..\SaBusMgrCoreProcs\SaBusMgrCoreProcs.csproj" />
|
||||
<ProjectReference Include="..\SaBusMgrCoreWeb\SaBusMgrCoreWeb.csproj" />
|
||||
<ProjectReference Include="..\SaBusMgrStandardBase\SaBusMgrStandardBase.csproj" />
|
||||
<ProjectReference Include="..\SaBusMgrStandardDbas\SaBusMgrStandardDbas.csproj" />
|
||||
</ItemGroup>
|
||||
<PropertyGroup>
|
||||
<SsdtUnitTestVersion>3.1</SsdtUnitTestVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(SQLDBExtensionsRefPath)\Microsoft.Data.Tools.Schema.Sql.UnitTesting.targets" Condition="$(VisualStudioVersion) != '15.0' And '$(SQLDBExtensionsRefPath)' != ''" />
|
||||
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\SSDT\Microsoft.Data.Tools.Schema.Sql.UnitTesting.targets" Condition="$(VisualStudioVersion) != '15.0' And '$(SQLDBExtensionsRefPath)' == ''" />
|
||||
</Project>
|
||||
@@ -37,7 +37,7 @@ namespace Sarand.BusinessMgr.Test.Net.Core.Web.Portal.App
|
||||
Mock<IConfiguration> mockConfiguration = new Mock<IConfiguration>();
|
||||
Mock<IWebHostEnvironment> mockEnvironment = new Mock<IWebHostEnvironment>();
|
||||
mockEnvironment.Setup(m => m.EnvironmentName).Returns(Environments.Development);
|
||||
mockEnvironment.Setup(m => m.ContentRootPath).Returns(@"D:\Sarand\Projects\Users\AHoward\VS2019\BusinessMgr\Workspace\SaBusinessMgrCoreWebPortal");
|
||||
mockEnvironment.Setup(m => m.ContentRootPath).Returns(@"D:\Sarand\Projects\Users\AHoward\VS2022\BusinessMgr\Workspace\SaBusinessMgrCoreWebPortal");
|
||||
App = new SbmApplication_Portal_Test(mockConfiguration.Object, mockEnvironment.Object);
|
||||
|
||||
// Session configuration.
|
||||
|
||||
@@ -40,13 +40,16 @@ namespace Sarand.BusinessMgr.Test.Net.Core.Web.Portal.App
|
||||
SbmAccountMgr accountMgr = Internals.AccountMgr;
|
||||
Assert.IsNotNull(accountMgr);
|
||||
|
||||
// Database context.
|
||||
String dbIdentifier = "SBMDB4321";
|
||||
|
||||
// Security item.
|
||||
SaSecurityItem securityItemUser = securityConsole.GetUserByEmail("andy@sarand.com");
|
||||
Assert.IsNotNull(securityItemUser);
|
||||
|
||||
// User account.
|
||||
SbmAffiliate affiliateUser = accountMgr.GetAffiliateByUserId(securityItemUser.Id);
|
||||
Assert.IsNotNull(affiliateUser );
|
||||
Assert.IsNotNull(affiliateUser);
|
||||
|
||||
// Organisations.
|
||||
List<SysIdString> supervisedOrganisations = accountMgr.GetAffiliatesSupervisedBy(affiliateUser.Id);
|
||||
@@ -62,7 +65,7 @@ namespace Sarand.BusinessMgr.Test.Net.Core.Web.Portal.App
|
||||
|
||||
|
||||
// Populate User Session.
|
||||
SbmSessionData_Portal sessionData = new SbmSessionData_Portal(SessionContext, securityItemUser, affiliateUser, supervisedOrganisations, associationOrganisation, affiliateOrganisation);
|
||||
SbmSessionData_Portal sessionData = new SbmSessionData_Portal(SessionContext, dbIdentifier, securityItemUser, affiliateUser, supervisedOrganisations, associationOrganisation, affiliateOrganisation);
|
||||
Assert.IsNotNull(sessionData);
|
||||
|
||||
// Validate user session.
|
||||
@@ -88,13 +91,16 @@ namespace Sarand.BusinessMgr.Test.Net.Core.Web.Portal.App
|
||||
Assert.IsNotNull(sessionDataJson);
|
||||
|
||||
// Deserialise data.
|
||||
SbmSessionData_Web sessionDataDeserialized = JsonConvert.DeserializeObject<SbmSessionData_Portal>(sessionDataJson, SbmController_Base.SbmSessionDataJsonSerializerSettings);
|
||||
SbmSessionData_Portal sessionDataDeserialized = JsonConvert.DeserializeObject<SbmSessionData_Portal>(sessionDataJson, SbmController_Base.SbmSessionDataJsonSerializerSettings);
|
||||
Assert.IsNotNull(sessionDataDeserialized);
|
||||
|
||||
|
||||
// Validate deserialised data.
|
||||
Assert.IsNotNull(sessionDataDeserialized.User);
|
||||
|
||||
|
||||
// Database context.
|
||||
Assert.AreEqual(dbIdentifier, sessionDataDeserialized.DbIdentifier);
|
||||
|
||||
// Security item.
|
||||
Assert.AreEqual(securityItemUser.Id, sessionDataDeserialized.User.SecurityItemId);
|
||||
Assert.AreEqual(securityItemUser.EmailAddress, sessionDataDeserialized.User.EmailAddress);
|
||||
|
||||
@@ -29,9 +29,12 @@ namespace Sarand.BusinessMgr.Net.Core.Web.Control.App
|
||||
private PropertySet propertySet;
|
||||
private Dictionary<String, SbmAppConfig> appConfigs = new Dictionary<string, SbmAppConfig>();
|
||||
private Dictionary<String, SbmEmailConfig> emailConfigs = new Dictionary<string, SbmEmailConfig>();
|
||||
ushort sessionContextIdx_Control = 0;
|
||||
// Singular databases.
|
||||
private ISacsDatabase controlDatabase = null;
|
||||
private ISacsDatabase templateDatabase = null;
|
||||
// Session contexts.
|
||||
private static ushort sessionContextIdx_Next = 100;
|
||||
private ushort sessionContextIdx_Control = 0;
|
||||
private class SessionContextData
|
||||
{
|
||||
public SessionContextData(SbmSessionContext_Web sessionContext)
|
||||
@@ -39,8 +42,8 @@ namespace Sarand.BusinessMgr.Net.Core.Web.Control.App
|
||||
SessionContext = sessionContext;
|
||||
}
|
||||
public SbmSessionContext_Web SessionContext { get; }
|
||||
public ISacsDatabase ControlDatabase { get; set; }
|
||||
public ISacsDatabase BusMgrDatabase { get; set; }
|
||||
public List<string> DbIdentifiers { get; } = new List<string>();
|
||||
public ISacsDatabase BusMgrDatabase { get; set; }
|
||||
}
|
||||
private readonly Dictionary<ushort, SessionContextData> sessionContexts = new Dictionary<ushort, SessionContextData>();
|
||||
|
||||
@@ -58,7 +61,7 @@ namespace Sarand.BusinessMgr.Net.Core.Web.Control.App
|
||||
catch (Exception exc)
|
||||
{
|
||||
SaLogger.Error(GetType().Name + ".CTR " + ExceptionUtil.GetErrorStateMessage(exc));
|
||||
throw exc;
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -76,11 +79,19 @@ namespace Sarand.BusinessMgr.Net.Core.Web.Control.App
|
||||
{
|
||||
return sessionContexts.GetValue(index, null)?.SessionContext ?? null;
|
||||
}
|
||||
public override ISacsDatabase GetControlDatabase(SbmSessionContext sessionContext)
|
||||
public override ISacsDatabase GetControlDatabase()
|
||||
{
|
||||
return sessionContexts.GetValue(sessionContext.Index, null)?.ControlDatabase;
|
||||
return controlDatabase;
|
||||
}
|
||||
public override ISacsDatabase GetBusMgrDatabase(SbmSessionContext sessionContext)
|
||||
public override ISacsDatabase GetTemplateDatabase()
|
||||
{
|
||||
return templateDatabase;
|
||||
}
|
||||
public override List<string> GetDbIdentifiers(SbmSessionContext sessionContext)
|
||||
{
|
||||
return sessionContexts.GetValue(sessionContext.Index, null)?.DbIdentifiers ?? new List<string>();
|
||||
}
|
||||
public override ISacsDatabase GetBusMgrDatabase(SbmSessionContext sessionContext)
|
||||
{
|
||||
return sessionContexts.GetValue(sessionContext.Index, null)?.BusMgrDatabase;
|
||||
}
|
||||
@@ -136,29 +147,46 @@ namespace Sarand.BusinessMgr.Net.Core.Web.Control.App
|
||||
LogApplicationStart(fn);
|
||||
|
||||
// Control database connection.
|
||||
SacsDatabaseConsole.OdbcConfig config = new SacsDatabaseConsole.OdbcConfig();
|
||||
config.location = AppConfig.ControlDatabase.Location;
|
||||
config.user = AppConfig.ControlDatabase.User;
|
||||
config.pword = AppConfig.ControlDatabase.Password;
|
||||
SacsDatabase controlDatabase = SacsDatabaseConsole.OpenOdbcDatabase(config);
|
||||
SacsDatabaseConsole.OdbcConfig odbcConfig = new SacsDatabaseConsole.OdbcConfig();
|
||||
odbcConfig.location = AppConfig.ControlDatabase.Location;
|
||||
odbcConfig.user = AppConfig.ControlDatabase.User;
|
||||
odbcConfig.pword = AppConfig.ControlDatabase.Password;
|
||||
controlDatabase = SacsDatabaseConsole.OpenOdbcDatabase(odbcConfig);
|
||||
if (controlDatabase.HasErrorState())
|
||||
SaLogger.Warn(fn + " Control Database initialisation error: " + controlDatabase.ErrorStateMessage);
|
||||
|
||||
// BusinessMgr database connection.
|
||||
config = new SacsDatabaseConsole.OdbcConfig();
|
||||
config.location = AppConfig.BusMgrDatabase.Location;
|
||||
config.user = AppConfig.BusMgrDatabase.User;
|
||||
config.pword = AppConfig.BusMgrDatabase.Password;
|
||||
SacsDatabase busMgrDatabase = SacsDatabaseConsole.OpenOdbcDatabase(config);
|
||||
if (busMgrDatabase.HasErrorState())
|
||||
SaLogger.Warn(fn + " BusMgr Database initialisation error: " + busMgrDatabase.ErrorStateMessage);
|
||||
// Template database connection.
|
||||
if (AppConfig.TemplateDatabase != null)
|
||||
{
|
||||
odbcConfig = new SacsDatabaseConsole.OdbcConfig();
|
||||
odbcConfig.location = AppConfig.TemplateDatabase.Location;
|
||||
odbcConfig.user = AppConfig.TemplateDatabase.User;
|
||||
odbcConfig.pword = AppConfig.TemplateDatabase.Password;
|
||||
templateDatabase = SacsDatabaseConsole.OpenOdbcDatabase(odbcConfig);
|
||||
if (templateDatabase.HasErrorState())
|
||||
SaLogger.Warn(fn + " Template Database initialisation error: " + controlDatabase.ErrorStateMessage);
|
||||
}
|
||||
|
||||
// Session context - only one context available/necessary (for now).
|
||||
sessionContextIdx_Control = sessionContextIdx_Next++;
|
||||
SessionContextData sessionContextData = new SessionContextData(new SbmSessionContext_Web(sessionContextIdx_Control, Sbm.Application.WebControl));
|
||||
sessionContextData.ControlDatabase = controlDatabase;
|
||||
sessionContextData.BusMgrDatabase = busMgrDatabase;
|
||||
sessionContexts.Add(sessionContextData.SessionContext.Index, sessionContextData);
|
||||
// BusinessMgr database connections.
|
||||
foreach (SbmAppConfig.DatabaseConfig dbConfig in AppConfig.BusMgrDatabases)
|
||||
{
|
||||
odbcConfig = new SacsDatabaseConsole.OdbcConfig();
|
||||
odbcConfig.location = dbConfig.Location;
|
||||
odbcConfig.user = dbConfig.User;
|
||||
odbcConfig.pword = dbConfig.Password;
|
||||
SacsDatabase busMgrDatabase = SacsDatabaseConsole.OpenOdbcDatabase(odbcConfig);
|
||||
if (busMgrDatabase.HasErrorState())
|
||||
SaLogger.Warn(fn + " BusMgr Database: " + busMgrDatabase.DatabaseName + ". Initialisation error: " + busMgrDatabase.ErrorStateMessage);
|
||||
|
||||
// Session context.
|
||||
ushort sessionContextIdx = sessionContextIdx_Next++;
|
||||
if (sessionContextIdx_Control < 1)
|
||||
sessionContextIdx_Control = sessionContextIdx;
|
||||
SessionContextData sessionContextData = new SessionContextData(new SbmSessionContext_Web(sessionContextIdx, Sbm.Application.WebControl));
|
||||
sessionContextData.DbIdentifiers.AddRange(dbConfig.Identifiers);
|
||||
sessionContextData.BusMgrDatabase = busMgrDatabase;
|
||||
sessionContexts.Add(sessionContextData.SessionContext.Index, sessionContextData);
|
||||
}
|
||||
}
|
||||
catch (Exception exc)
|
||||
{
|
||||
@@ -166,9 +194,8 @@ namespace Sarand.BusinessMgr.Net.Core.Web.Control.App
|
||||
}
|
||||
|
||||
// Occasional startup processing.
|
||||
SbmSessionContext sessionContext = GetSessionContext(sessionContextIdx_Control);
|
||||
if (generateDatabaseDefinitions_Control)
|
||||
GenerateDatabaseDefinition(sessionContext, SbmDbDfnGenerator.DatabaseInstance.Control, GetControlDatabase(sessionContext));
|
||||
GenerateDatabaseDefinition(SbmDbDfnGenerator.DatabaseInstance.Control, GetControlDatabase());
|
||||
if (generateDatabaseDefinitions_BusMgr)
|
||||
{
|
||||
// Use the 'template' database connection parameters.
|
||||
@@ -176,24 +203,24 @@ namespace Sarand.BusinessMgr.Net.Core.Web.Control.App
|
||||
config.location = AppConfig.TemplateDatabase.Location;
|
||||
config.user = AppConfig.TemplateDatabase.User;
|
||||
config.pword = AppConfig.TemplateDatabase.Password;
|
||||
GenerateDatabaseDefinition(sessionContext, SbmDbDfnGenerator.DatabaseInstance.BusinessMgr, SacsDatabaseConsole.GenerateConnectionString(config));
|
||||
GenerateDatabaseDefinition(SbmDbDfnGenerator.DatabaseInstance.BusinessMgr, GetTemplateDatabase());
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Generate database definition.
|
||||
private void GenerateDatabaseDefinition(SbmSessionContext sessionContext, SbmDbDfnGenerator.DatabaseInstance dbInstance, ISacsDatabase db)
|
||||
private void GenerateDatabaseDefinition(SbmDbDfnGenerator.DatabaseInstance dbInstance, ISacsDatabase db)
|
||||
{
|
||||
if (!generateDatabaseDefinitions_BusMgr || !SbmSystem.DebugMode || sessionContext == null) return;
|
||||
if (!generateDatabaseDefinitions_BusMgr || !SbmSystem.DebugMode) return;
|
||||
if (!StringUtil.EmptyOnNull(EnvironmentName).EqualsCI("Development")) return;
|
||||
if (db == null || StringUtil.IsEmpty(db.ConnectionString)) return;
|
||||
|
||||
// Generate database definitions.
|
||||
GenerateDatabaseDefinition(sessionContext, dbInstance, db.ConnectionString);
|
||||
GenerateDatabaseDefinition(dbInstance, db.ConnectionString);
|
||||
}
|
||||
private void GenerateDatabaseDefinition(SbmSessionContext sessionContext, SbmDbDfnGenerator.DatabaseInstance dbInstance, String connectionString)
|
||||
private void GenerateDatabaseDefinition(SbmDbDfnGenerator.DatabaseInstance dbInstance, String connectionString)
|
||||
{
|
||||
if (!generateDatabaseDefinitions_BusMgr || !SbmSystem.DebugMode || sessionContext == null) return;
|
||||
if (!generateDatabaseDefinitions_BusMgr || !SbmSystem.DebugMode) return;
|
||||
if (!StringUtil.EmptyOnNull(EnvironmentName).EqualsCI("Development")) return;
|
||||
if (StringUtil.IsEmpty(connectionString)) return;
|
||||
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
using Sarand.BusinessMgr.Net.Core.Web.App;
|
||||
using Sarand.BusinessMgr.Net.Standard.Base.App;
|
||||
using Sarand.BusinessMgr.Net.Standard.Base.Bus;
|
||||
using Sarand.Net.Standard.Base.Bus;
|
||||
using Sarand.Net.Standard.Base.Security;
|
||||
using static Sarand.BusinessMgr.Net.Standard.Base.App.Sbm.Config.Database;
|
||||
using System.Collections.Generic;
|
||||
using System;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Sarand.BusinessMgr.Net.Core.Web.Control.App
|
||||
{
|
||||
//=======================================================================
|
||||
public class SbmSessionData_Control : SbmSessionData_Web
|
||||
{
|
||||
//-------------------------------------------------------------------
|
||||
// Construction.
|
||||
[JsonConstructor]
|
||||
private SbmSessionData_Control(long sessionIdx, int itemIdx, SbmSessionContext sessionContext) :
|
||||
base(sessionIdx, itemIdx, sessionContext)
|
||||
{ }
|
||||
/// <summary>
|
||||
/// SessionData construction.
|
||||
/// <para>SessionContext and UserAccount must be supplied.</para>
|
||||
/// <para>Organisation is optional.</para>
|
||||
/// </summary>
|
||||
public SbmSessionData_Control(SbmSessionContext sessionContext) :
|
||||
base(sessionContext)
|
||||
{
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
protected override UserData CreateUserData(SbmSessionContext sessionContext, SaSecurityItem securityItemUser, SbmAffiliate affiliateUser, List<SysIdString> supervisedOrganisations)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
}
|
||||
//=======================================================================
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Sarand.BusinessMgr.Net.Core.Web.App;
|
||||
using Sarand.BusinessMgr.Net.Core.Web.Control.Models;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
@@ -9,29 +10,39 @@ using System.Threading.Tasks;
|
||||
|
||||
namespace Sarand.BusinessMgr.Net.Core.Web.Control.Controllers
|
||||
{
|
||||
public class HomeController : Controller
|
||||
{
|
||||
private readonly ILogger<HomeController> _logger;
|
||||
//======================================================================
|
||||
public class HomeController : SbmController_Control
|
||||
{
|
||||
//-------------------------------------------------------------------
|
||||
// Data members.
|
||||
|
||||
public HomeController(ILogger<HomeController> logger)
|
||||
{
|
||||
_logger = logger;
|
||||
//-------------------------------------------------------------------
|
||||
// Construction.
|
||||
public HomeController(SbmLocaliser localiser, ILogger<HomeController> logger) :
|
||||
base(localiser, logger)
|
||||
{
|
||||
}
|
||||
|
||||
public IActionResult Index()
|
||||
//-------------------------------------------------------------------
|
||||
public IActionResult Index()
|
||||
{
|
||||
// Home page.
|
||||
Model_Home model = new Model_Home(Localiser);
|
||||
return View();
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
public IActionResult Privacy()
|
||||
{
|
||||
return View();
|
||||
}
|
||||
|
||||
public IActionResult Privacy()
|
||||
{
|
||||
return View();
|
||||
}
|
||||
|
||||
[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
|
||||
//-------------------------------------------------------------------
|
||||
[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
|
||||
public IActionResult Error()
|
||||
{
|
||||
return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });
|
||||
}
|
||||
}
|
||||
//======================================================================
|
||||
}
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Newtonsoft.Json;
|
||||
using Sarand.BusinessMgr.Net.Core.Web.App;
|
||||
using Sarand.BusinessMgr.Net.Core.Web.Control.App;
|
||||
using Sarand.BusinessMgr.Net.Core.Web.Controllers;
|
||||
using System;
|
||||
|
||||
namespace Sarand.BusinessMgr.Net.Core.Web.Control.Controllers
|
||||
{
|
||||
//======================================================================
|
||||
public class SbmController_Control : SbmController_Base
|
||||
{
|
||||
//-------------------------------------------------------------------
|
||||
// Data members.
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Protected construction.
|
||||
protected SbmController_Control(SbmLocaliser localiser, Microsoft.Extensions.Logging.ILogger<SbmController_Control> logger) : base(localiser)
|
||||
{
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Session data.
|
||||
//-------------------------------------------------------------------
|
||||
/// <summary>Online session data</summary>
|
||||
protected SbmSessionData_Control SessionData_Control { get { return SessionData as SbmSessionData_Control; } }
|
||||
protected override SbmSessionData_Web DeserializeSessionData(String sessionDataJson)
|
||||
{
|
||||
return JsonConvert.DeserializeObject<SbmSessionData_Control>(sessionDataJson, SbmSessionDataJsonSerializerSettings);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
}
|
||||
//======================================================================
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
using Sarand.BusinessMgr.Net.Core.Web.App;
|
||||
|
||||
namespace Sarand.BusinessMgr.Net.Core.Web.Control.Models
|
||||
{
|
||||
//=======================================================================
|
||||
public class Model_Home : SbmModel_Control
|
||||
{
|
||||
//-------------------------------------------------------------------
|
||||
// Construction.
|
||||
public Model_Home(SbmLocaliser localiser) :
|
||||
base(localiser)
|
||||
{
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
}
|
||||
//=======================================================================
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
using Sarand.BusinessMgr.Net.Core.Web.App;
|
||||
using Sarand.BusinessMgr.Net.Core.Web.Models;
|
||||
|
||||
namespace Sarand.BusinessMgr.Net.Core.Web.Control.Models
|
||||
{
|
||||
//=======================================================================
|
||||
public class SbmModel_Control : SbmModel_Base
|
||||
{
|
||||
//-------------------------------------------------------------------
|
||||
// Protected construction.
|
||||
protected SbmModel_Control(SbmLocaliser localiser) :
|
||||
base(localiser)
|
||||
{
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
}
|
||||
//=======================================================================
|
||||
}
|
||||
@@ -1,52 +1,52 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netcoreapp3.1</TargetFramework>
|
||||
<CopyRefAssembliesToPublishDirectory>false</CopyRefAssembliesToPublishDirectory>
|
||||
<RootNamespace>Sarand.BusinessMgr.Net.Core.Web</RootNamespace>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<CopyRefAssembliesToPublishDirectory>false</CopyRefAssembliesToPublishDirectory>
|
||||
<RootNamespace>Sarand.BusinessMgr.Net.Core.Web</RootNamespace>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="jQuery.UI.Combined" Version="1.12.1" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation" Version="3.1.16" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="jQuery.UI.Combined" Version="1.13.2" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation" Version="6.0.31" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\..\Common-VS\Workspace\SacsCoreWeb\SacsCoreWeb.csproj" />
|
||||
<ProjectReference Include="..\..\..\Common-VS\Workspace\SacsStandardBase\SacsStandardBase.csproj" />
|
||||
<ProjectReference Include="..\..\..\Common-VS\Workspace\SacsStandardDbas\SacsStandardDbas.csproj" />
|
||||
<ProjectReference Include="..\..\..\Common-VS\Workspace\SacsStandardProc\SacsStandardProc.csproj" />
|
||||
<ProjectReference Include="..\SaBusMgrCoreProcs\SaBusMgrCoreProcs.csproj" />
|
||||
<ProjectReference Include="..\SaBusMgrCoreWeb\SaBusMgrCoreWeb.csproj" />
|
||||
<ProjectReference Include="..\SaBusMgrStandardBase\SaBusMgrStandardBase.csproj" />
|
||||
<ProjectReference Include="..\SaBusMgrStandardDbas\SaBusMgrStandardDbas.csproj" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\..\Common-VS\Workspace\SacsCoreWeb\SacsCoreWeb.csproj" />
|
||||
<ProjectReference Include="..\..\..\Common-VS\Workspace\SacsStandardBase\SacsStandardBase.csproj" />
|
||||
<ProjectReference Include="..\..\..\Common-VS\Workspace\SacsStandardDbas\SacsStandardDbas.csproj" />
|
||||
<ProjectReference Include="..\..\..\Common-VS\Workspace\SacsStandardProc\SacsStandardProc.csproj" />
|
||||
<ProjectReference Include="..\SaBusMgrCoreProcs\SaBusMgrCoreProcs.csproj" />
|
||||
<ProjectReference Include="..\SaBusMgrCoreWeb\SaBusMgrCoreWeb.csproj" />
|
||||
<ProjectReference Include="..\SaBusMgrStandardBase\SaBusMgrStandardBase.csproj" />
|
||||
<ProjectReference Include="..\SaBusMgrStandardDbas\SaBusMgrStandardDbas.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Folder Include="Control\Consoles\" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Folder Include="Control\Consoles\" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Content Update="appsettings.Development.json">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
<ExcludeFromSingleFile>true</ExcludeFromSingleFile>
|
||||
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
|
||||
</Content>
|
||||
<Content Update="appsettings.json">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
<ExcludeFromSingleFile>true</ExcludeFromSingleFile>
|
||||
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
|
||||
</Content>
|
||||
<Content Update="appsettings.Machine.Sarand107.json">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
<ExcludeFromSingleFile>true</ExcludeFromSingleFile>
|
||||
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
|
||||
</Content>
|
||||
<Content Update="appsettings.Production.json">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
<ExcludeFromSingleFile>true</ExcludeFromSingleFile>
|
||||
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
|
||||
</Content>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Update="appsettings.Development.json">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
<ExcludeFromSingleFile>true</ExcludeFromSingleFile>
|
||||
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
|
||||
</Content>
|
||||
<Content Update="appsettings.json">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
<ExcludeFromSingleFile>true</ExcludeFromSingleFile>
|
||||
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
|
||||
</Content>
|
||||
<Content Update="appsettings.Machine.Sarand110.json">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
<ExcludeFromSingleFile>true</ExcludeFromSingleFile>
|
||||
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
|
||||
</Content>
|
||||
<Content Update="appsettings.Production.json">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
<ExcludeFromSingleFile>true</ExcludeFromSingleFile>
|
||||
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
|
||||
</Content>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
||||
@@ -1,4 +1,12 @@
|
||||
<!DOCTYPE html>
|
||||
@model SbmModel_Control
|
||||
@inject Microsoft.AspNetCore.Antiforgery.IAntiforgery AntiForgery;
|
||||
@inject SbmLocaliser Localiser
|
||||
@*
|
||||
Application: BusinessMgr Web Control
|
||||
Purpose: Page template.
|
||||
*@
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
@@ -34,7 +42,7 @@
|
||||
|
||||
<footer class="border-top footer text-muted">
|
||||
<div class="container">
|
||||
© 2021 - Sarand BusinessMgr
|
||||
@(Model.CopyrightNotice) - Sarand BusinessMgr
|
||||
</div>
|
||||
</footer>
|
||||
<script src="~/lib/jquery/dist/jquery.min.js"></script>
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
@using Sarand.BusinessMgr.Net.Core.Web.Control
|
||||
@using Sarand.BusinessMgr.Net.Core.Web.App
|
||||
@using Sarand.BusinessMgr.Net.Core.Web.Control
|
||||
@using Sarand.BusinessMgr.Net.Core.Web.Control.Models
|
||||
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
|
||||
|
||||
@@ -1,48 +0,0 @@
|
||||
{
|
||||
"AppConfigs": {
|
||||
"SaBusMgr-Dev": {
|
||||
"Environments": [ "Development" ],
|
||||
"Instance": "Dev",
|
||||
"ControlDatabase": {
|
||||
"Location": "MsSql:Sarand107\\SQL2016.SaBusinessMgr_Control",
|
||||
"User": "SaBusMgr-Control",
|
||||
"Password": "sbm-c0Ntrul-dev-2021"
|
||||
},
|
||||
"BusMgrDatabases": [
|
||||
{
|
||||
"Code": "Sarand",
|
||||
"Location": "MsSql:Sarand106\\SQL2014.SaBusinessMgr_Sarand"
|
||||
},
|
||||
{
|
||||
"Code": "Cadix",
|
||||
"Location": "MsSql:Sarand107\\SQL2016.SaBusinessMgr_Cadix",
|
||||
"User": "SaBusMgr-Cadix",
|
||||
"Password": "sbm-cul-dev-2021"
|
||||
}
|
||||
],
|
||||
"BusMgrDatabase": {
|
||||
"Code": "Cadix",
|
||||
"Location": "MsSql:Sarand107\\SQL2016.SaBusinessMgr_Cadix",
|
||||
"User": "SaBusMgr-Cadix",
|
||||
"Password": "sbm-cul-dev-2021"
|
||||
},
|
||||
"TemplateDatabase": {
|
||||
"Location": "MsSql:Sarand107\\SQL2016.SaBusinessMgr_Template",
|
||||
"User": "SaBusMgr-Control",
|
||||
"Password": "sbm-c0Ntrul-dev-2021"
|
||||
},
|
||||
"Email": {
|
||||
"Context": "SBM-Dev",
|
||||
"ContactUs": {
|
||||
"AddressesTo": [ "dev@SaBusinessMgr.com" ]
|
||||
}
|
||||
},
|
||||
"Documents": {
|
||||
"RootFolder": "D:\\Sarand\\Projects\\Users\\AHoward\\VS2019\\BusinessMgr\\Docs"
|
||||
},
|
||||
"Logging": {
|
||||
"RootFolder": "D:\\Sarand\\Projects\\Users\\AHoward\\VS2019\\BusinessMgr\\Logs\\WebControl"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
{
|
||||
"AppConfigs": {
|
||||
"SaBusMgr-Dev": {
|
||||
"Environments": [ "Development" ],
|
||||
"Instance": "Dev",
|
||||
"ControlDatabase": {
|
||||
"Location": "MsSql:Roman\\SQL2016.SaBusinessMgr_Control",
|
||||
"User": "sapphire",
|
||||
"Password": "sarand"
|
||||
},
|
||||
"TemplateDatabase": {
|
||||
"Location": "MsSql:Roman\\SQL2016.SaBusinessMgr_Template",
|
||||
"User": "sapphire",
|
||||
"Password": "sarand"
|
||||
},
|
||||
"BusMgrDatabases": [
|
||||
{
|
||||
"Identifiers": [ "Sarand" ],
|
||||
"Location": "MsSql:Roman\\SQL2016.SaBusinessMgr_Sarand_Dev",
|
||||
"User": "sapphire",
|
||||
"Password": "sarand"
|
||||
},
|
||||
{
|
||||
"Identifiers": [ "Cadix" ],
|
||||
"Location": "MsSql:Roman\\SQL2016.SaBusinessMgr_Cadix",
|
||||
"User": "sapphire",
|
||||
"Password": "sarand"
|
||||
},
|
||||
{
|
||||
"Identifiers": [ "BPE" ],
|
||||
"Location": "MsSql:Roman\\SQL2016.SaBusinessMgr_BPE",
|
||||
"User": "sapphire",
|
||||
"Password": "sarand"
|
||||
}
|
||||
],
|
||||
"Email": {
|
||||
"Context": "SBM-Dev",
|
||||
"ContactUs": {
|
||||
"AddressesTo": [ "dev@SaBusinessMgr.com" ]
|
||||
}
|
||||
},
|
||||
"Documents": {
|
||||
"RootFolder": "D:\\Sarand\\Projects\\Users\\AHoward\\VS2022\\BusinessMgr\\Docs"
|
||||
},
|
||||
"Logging": {
|
||||
"RootFolder": "D:\\Sarand\\Projects\\Users\\AHoward\\VS2022\\BusinessMgr\\Logs\\WebControl"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -117,6 +117,18 @@
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<data name="association.caption.association" xml:space="preserve">
|
||||
<value>Association</value>
|
||||
</data>
|
||||
<data name="association.caption.association.create" xml:space="preserve">
|
||||
<value>Create Association</value>
|
||||
</data>
|
||||
<data name="association.caption.association.update" xml:space="preserve">
|
||||
<value>Update Association</value>
|
||||
</data>
|
||||
<data name="association.caption.associations" xml:space="preserve">
|
||||
<value>Associations</value>
|
||||
</data>
|
||||
<data name="commodity.caption.commodities" xml:space="preserve">
|
||||
<value>Commodities</value>
|
||||
</data>
|
||||
@@ -156,6 +168,9 @@
|
||||
<data name="label.any" xml:space="preserve">
|
||||
<value>Any</value>
|
||||
</data>
|
||||
<data name="label.association" xml:space="preserve">
|
||||
<value>Association</value>
|
||||
</data>
|
||||
<data name="label.associations" xml:space="preserve">
|
||||
<value>Associations</value>
|
||||
</data>
|
||||
@@ -189,6 +204,9 @@
|
||||
<data name="label.contacts" xml:space="preserve">
|
||||
<value>Contacts</value>
|
||||
</data>
|
||||
<data name="label.context" xml:space="preserve">
|
||||
<value>Context</value>
|
||||
</data>
|
||||
<data name="label.create" xml:space="preserve">
|
||||
<value>Create</value>
|
||||
</data>
|
||||
@@ -198,6 +216,9 @@
|
||||
<data name="label.create.organisation" xml:space="preserve">
|
||||
<value>Create Organisation</value>
|
||||
</data>
|
||||
<data name="label.customers" xml:space="preserve">
|
||||
<value>Customers</value>
|
||||
</data>
|
||||
<data name="label.description" xml:space="preserve">
|
||||
<value>Description</value>
|
||||
</data>
|
||||
@@ -279,6 +300,9 @@
|
||||
<data name="label.signout" xml:space="preserve">
|
||||
<value>Sign-out</value>
|
||||
</data>
|
||||
<data name="label.Suppliers" xml:space="preserve">
|
||||
<value>Suppliers</value>
|
||||
</data>
|
||||
<data name="label.type" xml:space="preserve">
|
||||
<value>Type</value>
|
||||
</data>
|
||||
|
||||
@@ -18,142 +18,164 @@ using System.Threading.Tasks;
|
||||
|
||||
namespace Sarand.BusinessMgr.Net.Core.Web.Portal.App
|
||||
{
|
||||
//=======================================================================
|
||||
public class SbmApplication_Portal : SbmApplication_Web
|
||||
{
|
||||
//-------------------------------------------------------------------
|
||||
// Data members.
|
||||
private PropertySet properties;
|
||||
private Dictionary<String, SbmAppConfig> appConfigs = new Dictionary<string, SbmAppConfig>();
|
||||
private Dictionary<String, SbmEmailConfig> emailConfigs = new Dictionary<string, SbmEmailConfig>();
|
||||
// Session contexts.
|
||||
private static ushort sessionContextIdx_Next = 100;
|
||||
private ushort sessionContextIdx_Control = 0;
|
||||
private class SessionContextData
|
||||
{
|
||||
public SessionContextData(SbmSessionContext_Web sessionContext)
|
||||
{
|
||||
SessionContext = sessionContext;
|
||||
}
|
||||
public SbmSessionContext_Web SessionContext { get; }
|
||||
public ISacsDatabase ControlDatabase { get; set; }
|
||||
public ISacsDatabase BusMgrDatabase { get; set; }
|
||||
}
|
||||
private readonly Dictionary<int, SessionContextData> sessionContexts = new Dictionary<int, SessionContextData>();
|
||||
//=======================================================================
|
||||
public class SbmApplication_Portal : SbmApplication_Web
|
||||
{
|
||||
//-------------------------------------------------------------------
|
||||
// Data members.
|
||||
private PropertySet properties;
|
||||
private Dictionary<String, SbmAppConfig> appConfigs = new Dictionary<string, SbmAppConfig>();
|
||||
private Dictionary<String, SbmEmailConfig> emailConfigs = new Dictionary<string, SbmEmailConfig>();
|
||||
private ISacsDatabase controlDatabase = null;
|
||||
// Session contexts.
|
||||
private static ushort sessionContextIdx_Next = 100;
|
||||
private class SessionContextData
|
||||
{
|
||||
public SessionContextData(SbmSessionContext_Web sessionContext)
|
||||
{
|
||||
SessionContext = sessionContext;
|
||||
}
|
||||
public SbmSessionContext_Web SessionContext { get; }
|
||||
public List<string> DbIdentifiers { get; } = new List<string>();
|
||||
public ISacsDatabase BusMgrDatabase { get; set; }
|
||||
}
|
||||
private readonly Dictionary<int, SessionContextData> sessionContexts = new Dictionary<int, SessionContextData>();
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Construction.
|
||||
public SbmApplication_Portal(IConfiguration configuration) : base ()
|
||||
{
|
||||
InitialiseTemporaryLoggingFolder();
|
||||
try
|
||||
{
|
||||
properties = new PropertySet();
|
||||
SbmGlobals.System = (SbmGlobals_Web.System = (System_Web = new SbmSystem_Web(properties)));
|
||||
Configuration = configuration;
|
||||
}
|
||||
catch (Exception exc)
|
||||
{
|
||||
SaLogger.Error(GetType().Name + ".CTR " + ExceptionUtil.GetErrorStateMessage(exc));
|
||||
throw exc;
|
||||
}
|
||||
}
|
||||
//-------------------------------------------------------------------
|
||||
// Construction.
|
||||
public SbmApplication_Portal(IConfiguration configuration) : base()
|
||||
{
|
||||
InitialiseTemporaryLoggingFolder();
|
||||
try
|
||||
{
|
||||
properties = new PropertySet();
|
||||
SbmGlobals.System = (SbmGlobals_Web.System = (System_Web = new SbmSystem_Web(properties)));
|
||||
Configuration = configuration;
|
||||
}
|
||||
catch (Exception exc)
|
||||
{
|
||||
SaLogger.Error(GetType().Name + ".CTR " + ExceptionUtil.GetErrorStateMessage(exc));
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Properties.
|
||||
// Application Configuration.
|
||||
public override SbmAppConfig AppConfig { get { return appConfigs.Values.ToList().getConfigForApplication(); } }
|
||||
// Session Configuration.
|
||||
public override String SessionCookieName { get { return Sbm.Config.Portal.Session.Cookie.Name; } }
|
||||
public override List<ushort> GetSessionContextIdxs()
|
||||
{
|
||||
return sessionContexts.Values.Select(item => item.SessionContext.Index).ToList();
|
||||
}
|
||||
public override SbmSessionContext GetSessionContext(ushort index)
|
||||
{
|
||||
return sessionContexts.GetValue(index, null)?.SessionContext ?? null;
|
||||
}
|
||||
public override ISacsDatabase GetControlDatabase(SbmSessionContext sessionContext)
|
||||
{
|
||||
return sessionContexts.GetValue(sessionContext.Index, null)?.ControlDatabase;
|
||||
}
|
||||
public override ISacsDatabase GetBusMgrDatabase(SbmSessionContext sessionContext)
|
||||
{
|
||||
return sessionContexts.GetValue(sessionContext.Index, null)?.BusMgrDatabase;
|
||||
}
|
||||
public override SbmEmailConfig EmailConfig { get { return emailConfigs.Values.ToList().getConfigForSession(AppConfig); } }
|
||||
//-------------------------------------------------------------------
|
||||
// Properties.
|
||||
// Application Configuration.
|
||||
public override SbmAppConfig AppConfig { get { return appConfigs.Values.ToList().getConfigForApplication(); } }
|
||||
// Session Configuration.
|
||||
public override String SessionCookieName { get { return Sbm.Config.Portal.Session.Cookie.Name; } }
|
||||
public override List<ushort> GetSessionContextIdxs()
|
||||
{
|
||||
return sessionContexts.Values.Select(item => item.SessionContext.Index).ToList();
|
||||
}
|
||||
public override SbmSessionContext GetSessionContext(ushort index)
|
||||
{
|
||||
return sessionContexts.GetValue(index, null)?.SessionContext ?? null;
|
||||
}
|
||||
public override ISacsDatabase GetControlDatabase()
|
||||
{
|
||||
return controlDatabase;
|
||||
}
|
||||
public override ISacsDatabase GetTemplateDatabase()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
public override List<string> GetDbIdentifiers(SbmSessionContext sessionContext)
|
||||
{
|
||||
return sessionContexts.GetValue(sessionContext.Index, null)?.DbIdentifiers ?? new List<string>();
|
||||
}
|
||||
public override ISacsDatabase GetBusMgrDatabase(SbmSessionContext sessionContext)
|
||||
{
|
||||
return sessionContexts.GetValue(sessionContext.Index, null)?.BusMgrDatabase;
|
||||
}
|
||||
public override SbmEmailConfig EmailConfig { get { return emailConfigs.Values.ToList().getConfigForSession(AppConfig); } }
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Initialisation.
|
||||
/// <summary>Initialise environment - from Startup.</summary>
|
||||
internal void InitWebHostEnvironment(IWebHostEnvironment env)
|
||||
{
|
||||
InitEnvironment(env);
|
||||
}
|
||||
/// <summary>Initialise environment - from internal (above) or unit tests.</summary>
|
||||
protected void InitEnvironment(IWebHostEnvironment env)
|
||||
{
|
||||
String fn = GetType().Name + ".InitEnvironment";
|
||||
Development = env.IsDevelopment();
|
||||
environmentName = env.EnvironmentName;
|
||||
SaLogger.LogFilenamePrefix = "Sbm-Web-Onl";
|
||||
SaLogger.IncludeHostInFileMessage = false;
|
||||
SaLogger.IncludeUserInFileMessage = false;
|
||||
//-------------------------------------------------------------------
|
||||
// Initialisation.
|
||||
/// <summary>Initialise environment - from Startup.</summary>
|
||||
internal void InitWebHostEnvironment(IWebHostEnvironment env)
|
||||
{
|
||||
InitEnvironment(env);
|
||||
}
|
||||
/// <summary>Initialise environment - from internal (above) or unit tests.</summary>
|
||||
protected void InitEnvironment(IWebHostEnvironment env)
|
||||
{
|
||||
String fn = GetType().Name + ".InitEnvironment";
|
||||
Development = env.IsDevelopment();
|
||||
environmentName = env.EnvironmentName;
|
||||
SaLogger.LogFilenamePrefix = "Sbm-Web-Onl";
|
||||
SaLogger.IncludeHostInFileMessage = false;
|
||||
SaLogger.IncludeUserInFileMessage = false;
|
||||
|
||||
try
|
||||
{
|
||||
// Load server configuration.
|
||||
var builder = new ConfigurationBuilder()
|
||||
.SetBasePath(env.ContentRootPath)
|
||||
.AddJsonFile("appsettings.json", optional: true, reloadOnChange: false)
|
||||
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: false)
|
||||
.AddJsonFile($"appsettings.machine.{SbmSystem.ComputerName}.json", optional: false, reloadOnChange: false)
|
||||
.AddEnvironmentVariables();
|
||||
SbmConfiguration = builder.Build();
|
||||
try
|
||||
{
|
||||
// Load server configuration.
|
||||
var builder = new ConfigurationBuilder()
|
||||
.SetBasePath(env.ContentRootPath)
|
||||
.AddJsonFile("appsettings.json", optional: true, reloadOnChange: false)
|
||||
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: false)
|
||||
.AddJsonFile($"appsettings.machine.{SbmSystem.ComputerName}.json", optional: false, reloadOnChange: false)
|
||||
.AddEnvironmentVariables();
|
||||
SbmConfiguration = builder.Build();
|
||||
|
||||
// Application configuration.
|
||||
appConfigs = SbmAppConfigHelper.ExtractAppConfigs(SbmConfiguration.GetSection("AppConfigs"));
|
||||
emailConfigs = SbmEmailConfigHelper.ExtractEmailConfigs(SbmConfiguration.GetSection("EmailConfigs"));
|
||||
LoggingRootFolder = AppConfig.Logging.RootFolder;
|
||||
// Application configuration.
|
||||
appConfigs = SbmAppConfigHelper.ExtractAppConfigs(SbmConfiguration.GetSection("AppConfigs"));
|
||||
emailConfigs = SbmEmailConfigHelper.ExtractEmailConfigs(SbmConfiguration.GetSection("EmailConfigs"));
|
||||
LoggingRootFolder = AppConfig.Logging.RootFolder;
|
||||
|
||||
// Application instance.
|
||||
if (AppConfig.Instance.EqualsCI("Dev")) instanceType = Sbm.InstanceType.Dev;
|
||||
else if (AppConfig.Instance.ContainsCI("Q")) instanceType = Sbm.InstanceType.QC;
|
||||
else if (AppConfig.Instance.ContainsCI("UAT")) instanceType = Sbm.InstanceType.UAT;
|
||||
else if (AppConfig.Instance.EqualsCI("PreProd")) instanceType = Sbm.InstanceType.UAT;
|
||||
// Application instance.
|
||||
if (AppConfig.Instance.EqualsCI("Dev")) instanceType = Sbm.InstanceType.Dev;
|
||||
else if (AppConfig.Instance.ContainsCI("Q")) instanceType = Sbm.InstanceType.QC;
|
||||
else if (AppConfig.Instance.ContainsCI("UAT")) instanceType = Sbm.InstanceType.UAT;
|
||||
else if (AppConfig.Instance.EqualsCI("PreProd")) instanceType = Sbm.InstanceType.UAT;
|
||||
|
||||
// Initialise hard-coded logging path.
|
||||
if (StringUtil.IsEmpty(LoggingRootFolder))
|
||||
{
|
||||
if (SbmSystem.ComputerName.EqualsCI("WIN-BPCLM1QUOMT"))
|
||||
LoggingRootFolder = @"D:\Sbmonite\Logs\" + (Development ? "Dev" : "Test");
|
||||
}
|
||||
if (DirectoryUtil.DirectoryExists(LoggingRootFolder))
|
||||
SaLogger.LogFolder = LoggingRootFolder;
|
||||
LogApplicationStart(fn);
|
||||
// Initialise hard-coded logging path.
|
||||
if (StringUtil.IsEmpty(LoggingRootFolder))
|
||||
{
|
||||
if (SbmSystem.ComputerName.EqualsCI("WIN-BPCLM1QUOMT"))
|
||||
LoggingRootFolder = @"D:\Sbmonite\Logs\" + (Development ? "Dev" : "Test");
|
||||
}
|
||||
if (DirectoryUtil.DirectoryExists(LoggingRootFolder))
|
||||
SaLogger.LogFolder = LoggingRootFolder;
|
||||
LogApplicationStart(fn);
|
||||
|
||||
// Configure database connection.
|
||||
SacsDatabaseConsole.OdbcConfig config = new SacsDatabaseConsole.OdbcConfig();
|
||||
config.location = AppConfig.BusMgrDatabase.Location;
|
||||
config.user = AppConfig.BusMgrDatabase.User;
|
||||
config.pword = AppConfig.BusMgrDatabase.Password;
|
||||
SacsDatabase coreDatabase = SacsDatabaseConsole.OpenOdbcDatabase(config);
|
||||
if (coreDatabase.HasErrorState())
|
||||
SaLogger.Warn(fn + " Database initialisation error: " + coreDatabase.ErrorStateMessage);
|
||||
// Control database connection.
|
||||
SacsDatabaseConsole.OdbcConfig odbcConfig = new SacsDatabaseConsole.OdbcConfig();
|
||||
odbcConfig.location = AppConfig.ControlDatabase.Location;
|
||||
odbcConfig.user = AppConfig.ControlDatabase.User;
|
||||
odbcConfig.pword = AppConfig.ControlDatabase.Password;
|
||||
controlDatabase = SacsDatabaseConsole.OpenOdbcDatabase(odbcConfig);
|
||||
if (controlDatabase.HasErrorState())
|
||||
SaLogger.Warn(fn + " Control Database initialisation error: " + controlDatabase.ErrorStateMessage);
|
||||
|
||||
// Session context - only one context available/necessary (for now).
|
||||
sessionContextIdx_Control = sessionContextIdx_Next++;
|
||||
SessionContextData sessionContextData = new SessionContextData(new SbmSessionContext_Web(sessionContextIdx_Control, Sbm.Application.WebPortal));
|
||||
sessionContextData.BusMgrDatabase = coreDatabase;
|
||||
sessionContexts.Add(sessionContextData.SessionContext.Index, sessionContextData);
|
||||
}
|
||||
catch (Exception exc)
|
||||
{
|
||||
SaLogger.Error(fn + " " + ExceptionUtil.GetLogMessage(exc));
|
||||
}
|
||||
}
|
||||
// Configure BusMgr database connections.
|
||||
foreach (SbmAppConfig.DatabaseConfig dbConfig in AppConfig.BusMgrDatabases)
|
||||
{
|
||||
SacsDatabaseConsole.OdbcConfig config = new SacsDatabaseConsole.OdbcConfig();
|
||||
config.location = dbConfig.Location;
|
||||
config.user = dbConfig.User;
|
||||
config.pword = dbConfig.Password;
|
||||
SacsDatabase coreDatabase = SacsDatabaseConsole.OpenOdbcDatabase(config);
|
||||
if (!coreDatabase.HasErrorState())
|
||||
{
|
||||
// Session context.
|
||||
ushort sessionContextIdx = sessionContextIdx_Next++;
|
||||
SessionContextData sessionContextData = new SessionContextData(new SbmSessionContext_Web(sessionContextIdx, Sbm.Application.WebPortal));
|
||||
sessionContextData.BusMgrDatabase = coreDatabase;
|
||||
sessionContextData.DbIdentifiers.AddRange(dbConfig.Identifiers);
|
||||
sessionContexts.Add(sessionContextData.SessionContext.Index, sessionContextData);
|
||||
}
|
||||
else SaLogger.Warn(fn + " Database: " + coreDatabase.DatabaseName + ". Initialisation error: " + coreDatabase.ErrorStateMessage);
|
||||
}
|
||||
}
|
||||
catch (Exception exc)
|
||||
{
|
||||
SaLogger.Error(fn + " " + ExceptionUtil.GetLogMessage(exc));
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
}
|
||||
//=======================================================================
|
||||
//-------------------------------------------------------------------
|
||||
}
|
||||
//=======================================================================
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using static Sarand.BusinessMgr.Net.Standard.Base.App.Sbm.Config.Database;
|
||||
|
||||
namespace Sarand.BusinessMgr.Net.Core.Web.Portal.App
|
||||
{
|
||||
@@ -22,15 +23,16 @@ namespace Sarand.BusinessMgr.Net.Core.Web.Portal.App
|
||||
[JsonConstructor]
|
||||
private SbmSessionData_Portal(long sessionIdx, int itemIdx, SbmSessionContext sessionContext) :
|
||||
base(sessionIdx, itemIdx, sessionContext)
|
||||
{ }
|
||||
{}
|
||||
/// <summary>
|
||||
/// SessionData construction.
|
||||
/// <para>SessionContext and UserAccount must be supplied.</para>
|
||||
/// <para>Organisation is optional.</para>
|
||||
/// </summary>
|
||||
public SbmSessionData_Portal(SbmSessionContext sessionContext, SaSecurityItem securityItemUser, SbmAffiliate affiliateUser, List<SysIdString> supervisedOrganisations, SbmAssociation associationOrganisation, SbmAffiliate affiliateOrganisation) :
|
||||
public SbmSessionData_Portal(SbmSessionContext sessionContext, String dbIdentifier, SaSecurityItem securityItemUser, SbmAffiliate affiliateUser, List<SysIdString> supervisedOrganisations, SbmAssociation associationOrganisation, SbmAffiliate affiliateOrganisation) :
|
||||
base(sessionContext, securityItemUser, affiliateUser, supervisedOrganisations, associationOrganisation, affiliateOrganisation)
|
||||
{
|
||||
DbIdentifier = dbIdentifier;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
@@ -68,6 +70,12 @@ namespace Sarand.BusinessMgr.Net.Core.Web.Portal.App
|
||||
return false;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Database context.
|
||||
|
||||
/// <summary>Database context specified on sign-in.</summary>
|
||||
public String DbIdentifier { get; set; }
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
/// <summary>
|
||||
/// User Profile.
|
||||
@@ -98,11 +106,22 @@ namespace Sarand.BusinessMgr.Net.Core.Web.Portal.App
|
||||
}
|
||||
public FilterData Filter { get; } = new FilterData();
|
||||
}
|
||||
/// <summary>
|
||||
/// Contacts filter properties.
|
||||
/// </summary>
|
||||
/// <summary>Contacts filter properties.</summary>
|
||||
public ContactsData Contacts { get; } = new ContactsData();
|
||||
|
||||
// Associations filter.
|
||||
public class AssociationsData
|
||||
{
|
||||
public class FilterData
|
||||
{
|
||||
public uint PageNo { get; set; } = 1;
|
||||
public ushort PageLength { get; set; } = 16;
|
||||
}
|
||||
public FilterData Filter { get; } = new FilterData();
|
||||
}
|
||||
/// <summary>Associations filter properties.</summary>
|
||||
public AssociationsData Associations { get; } = new AssociationsData();
|
||||
|
||||
// Commodities filter.
|
||||
public class CommoditiesData
|
||||
{
|
||||
@@ -113,9 +132,7 @@ namespace Sarand.BusinessMgr.Net.Core.Web.Portal.App
|
||||
}
|
||||
public FilterData Filter { get; } = new FilterData();
|
||||
}
|
||||
/// <summary>
|
||||
/// Commodities filter properties.
|
||||
/// </summary>
|
||||
/// <summary>Commodities filter properties.</summary>
|
||||
public CommoditiesData Commodities { get; } = new CommoditiesData();
|
||||
}
|
||||
public UserProfileData Profile { get; protected set; } = new UserProfileData();
|
||||
|
||||
@@ -0,0 +1,400 @@
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Sarand.BusinessMgr.Net.Core.Web.App;
|
||||
using Sarand.BusinessMgr.Net.Core.Web.Helpers;
|
||||
using Sarand.BusinessMgr.Net.Core.Web.Portal.Models;
|
||||
using Sarand.BusinessMgr.Net.Standard.Base.App;
|
||||
using Sarand.BusinessMgr.Net.Standard.Base.Bus;
|
||||
using Sarand.BusinessMgr.Net.Standard.Base.Consoles;
|
||||
using Sarand.BusinessMgr.Net.Standard.Base.Helpers;
|
||||
using Sarand.BusinessMgr.Net.Standard.Base.Mgr;
|
||||
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.Email;
|
||||
using Sarand.Net.Standard.Base.Helpers;
|
||||
using Sarand.Net.Standard.Base.Security;
|
||||
using Sarand.Net.Standard.Base.Utils;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Specialized;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using System.Web;
|
||||
|
||||
namespace Sarand.BusinessMgr.Net.Core.Web.Portal.Controllers
|
||||
{
|
||||
//=======================================================================
|
||||
// Portal Association Controller - Ajax actions.
|
||||
//=======================================================================
|
||||
partial class AssociationController
|
||||
{
|
||||
//-------------------------------------------------------------------
|
||||
// Association data.
|
||||
private class AssociationData_List : AjaxResponse_Data.ItemData_Base
|
||||
{
|
||||
public String OwnerId { get; set; }
|
||||
public String OwnerName { get; set; }
|
||||
public String TargetId { get; set; }
|
||||
public String TargetName { get; set; }
|
||||
public String TypeCode { get; set; }
|
||||
public String TypeDesc { get; set; }
|
||||
public String Code { get; set; }
|
||||
public String ReferenceExt { get; set; }
|
||||
public String Group { get; set; }
|
||||
public String DescDetail { get; set; }
|
||||
// Address.
|
||||
public String AddressSummary { get; set; }
|
||||
}
|
||||
private class AssociationData_Full : AssociationData_List
|
||||
{
|
||||
// Association properties.
|
||||
public String Location { get; set; }
|
||||
public String Role { get; set; }
|
||||
public String PhoneMain { get; set; }
|
||||
public String Email { get; set; }
|
||||
public String NominalCodeDefault { get; set; }
|
||||
}
|
||||
private void PopulateAssociationResponseData(SbmAssociation association, AssociationData_List data)
|
||||
{
|
||||
data.Id = SysId.ToString(association.Id);
|
||||
data.TypeCode = Internals.AssociationTypeCodes.GetCodeForType(association.AssociationType);
|
||||
data.TypeDesc = Internals.AssociationTypeCodes.GetDescForType(association.AssociationType);
|
||||
data.Code = association.Code;
|
||||
data.ReferenceExt = association.RefExt;
|
||||
data.Group = association.Group;
|
||||
data.DescDetail = association.DescDetail;
|
||||
// Common properties.
|
||||
data.Notes = association.Notes;
|
||||
data.StatusCode = association.StatusCode;
|
||||
data.StatusDesc = association.StatusDesc;
|
||||
}
|
||||
private void PopulateAssociationResponseData(SbmAssociation association, AssociationData_Full data)
|
||||
{
|
||||
PopulateAssociationResponseData(association, data as AssociationData_List);
|
||||
// Association properties.
|
||||
data.Location = association.Location;
|
||||
data.Role = association.Role;
|
||||
data.PhoneMain = association.PhoneMain;
|
||||
data.Email = association.Email;
|
||||
data.NominalCodeDefault = association.DefaultNominalCode;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Association list.
|
||||
//-------------------------------------------------------------------
|
||||
private class AjaxResponse_AssociationList : AjaxResponse_Data
|
||||
{
|
||||
// Construction.
|
||||
public AjaxResponse_AssociationList(SbmModel_Portal model) : base(model) { }
|
||||
// Association list.
|
||||
public List<AssociationData_List> Associations { get; } = new List<AssociationData_List>();
|
||||
// Reference data.
|
||||
public List<CodeDesc> Statuses { get; } = new List<CodeDesc>();
|
||||
public String DefaultStatusCode { get; set; }
|
||||
}
|
||||
// Ajax request.
|
||||
[HttpPost]
|
||||
[Route("Association/Ajax/List")]
|
||||
[Route("Association/Ajax/GetList")]
|
||||
public IActionResult Ajax_AssociationList(Model_Association model)
|
||||
{
|
||||
String fn = GetType().Name + ".Ajax_AssociationList";
|
||||
AjaxResponse_AssociationList responseData = new AjaxResponse_AssociationList(model);
|
||||
String messageTitle = Localiser["association.caption.associations"];
|
||||
|
||||
// Validate session and referrer.
|
||||
if (!ValidUserSession) return GetAjaxResult_InvalidSession(responseData);
|
||||
if (!ValidReferer) return Forbid();
|
||||
RefreshModel(model);
|
||||
|
||||
// Reference data - statuses.
|
||||
foreach (SaStatus status in SbmAssociation.ValidStatuses.FindAll(item => item != SaStatus.Deleted))
|
||||
responseData.Statuses.Add(SacsSystem.GetStatusCode(status), Localiser.GetStatusCaption(status));
|
||||
responseData.DefaultStatusCode = SacsSystem.GetStatusCode(SbmAssociation.DefaultStatus);
|
||||
|
||||
// Item filter.
|
||||
SbmAssociation.Params prmAssociation = new SbmAssociation.Params();
|
||||
prmAssociation.AffiliateIdOwner = SessionData.Organisation.AffiliateId;
|
||||
prmAssociation.Search = model.Filter.AssociationSearch;
|
||||
prmAssociation.AssociationType = model.GetFilterAssociationType();
|
||||
prmAssociation.StatusCat = SbmAssociation.StatusCat.NotDeleted;
|
||||
prmAssociation.SortColumns.Add(AccountMgr.GetAssociationColumnDfn(SbmAssociation.Column.Target_Name));
|
||||
model.Paging.ItemTotal = (ulong)AccountMgr.GetAssociationCount(prmAssociation);
|
||||
model.PopulatePagingTo(prmAssociation.ResultsPaging);
|
||||
|
||||
// Item columns.
|
||||
ColumnDfn colId = AccountMgr.GetAssociationColumnDfn(SbmAssociation.Column.Id);
|
||||
ColumnDfn colAffIdTarget = AccountMgr.GetAssociationColumnDfn(SbmAssociation.Column.AffIdTarget);
|
||||
ColumnDfn colTargetName = AccountMgr.GetAssociationColumnDfn(SbmAssociation.Column.Target_Name);
|
||||
ColumnDfn colAssociationType = AccountMgr.GetAssociationColumnDfn(SbmAssociation.Column.Type_Desc);
|
||||
ColumnDfn colCode = AccountMgr.GetAssociationColumnDfn(SbmAssociation.Column.Code);
|
||||
ColumnDfn colExtRef = AccountMgr.GetAssociationColumnDfn(SbmAssociation.Column.ExtRef);
|
||||
ColumnDfn colGroup = AccountMgr.GetAssociationColumnDfn(SbmAssociation.Column.Group);
|
||||
ColumnDfn colDescDetail = AccountMgr.GetAssociationColumnDfn(SbmAssociation.Column.DescDetail);
|
||||
ColumnDfn colNotes = AccountMgr.GetAssociationColumnDfn(SbmAssociation.Column.Notes);
|
||||
ColumnDfn colStatus = AccountMgr.GetAssociationColumnDfn(SbmAssociation.Column.Status);
|
||||
ColumnDfn colCreatedOn = AccountMgr.GetAssociationColumnDfn(SbmAssociation.Column.CreateOn_Date);
|
||||
ColumnDfn colUpdatedOn = AccountMgr.GetAssociationColumnDfn(SbmAssociation.Column.UpdateOn_Date);
|
||||
List<ColumnDfn> columns = new List<ColumnDfn>()
|
||||
{
|
||||
colId, colAffIdTarget, colTargetName, colAssociationType,
|
||||
colCode, colExtRef, colGroup, colDescDetail,
|
||||
colNotes, colStatus, colCreatedOn, colUpdatedOn
|
||||
};
|
||||
|
||||
// Query items.
|
||||
using (DbResultSet resultSet = AccountMgr.ExecuteAssociationQuery(columns, prmAssociation))
|
||||
{
|
||||
while (resultSet != null && resultSet.HasRows && resultSet.NextRecord())
|
||||
{
|
||||
NamedValue.Map values = resultSet.GetRecordValues();
|
||||
Sbm.AssociationType associationType = (Sbm.AssociationType)values.GetLong(colAssociationType.DataName);
|
||||
AssociationData_List associationData = new AssociationData_List()
|
||||
{
|
||||
Id = values.GetString(colId.DataName),
|
||||
TargetId = values.GetString(colAffIdTarget.DataName),
|
||||
TargetName = values.GetString(colTargetName.DataName),
|
||||
TypeCode = Internals.AssociationTypeCodes.GetCodeForType(associationType),
|
||||
TypeDesc = Internals.AssociationTypeCodes.GetDescForType(associationType),
|
||||
Code = values.GetString(colCode.DataName),
|
||||
ReferenceExt = values.GetString(colExtRef.DataName),
|
||||
Group = values.GetString(colGroup.DataName),
|
||||
DescDetail = values.GetString(colDescDetail.DataName),
|
||||
Notes = values.GetString(colNotes.DataName),
|
||||
StatusCode = values.GetString(colStatus.DataName),
|
||||
StatusDesc = SacsSystem.GetStatusDescForCode(values.GetString(colStatus.DataName)),
|
||||
CreatedOn = DateUtil.Format(values.GetDate(colCreatedOn.DataName), "yyyyMMdd"),
|
||||
CreatedOnFmt = Localiser.FormatDate(values.GetDate(colCreatedOn.DataName)),
|
||||
UpdatedOn = DateUtil.Format(values.GetDate(colUpdatedOn.DataName), "yyyyMMdd"),
|
||||
UpdatedOnFmt = Localiser.FormatDate(values.GetDate(colUpdatedOn.DataName))
|
||||
};
|
||||
responseData.Associations.Add(associationData);
|
||||
}
|
||||
}
|
||||
|
||||
// Refresh paging info.
|
||||
if (model.Paging.IsPaged)
|
||||
model.Paging.ItemCount = (ushort)responseData.Associations.Count;
|
||||
SessionData_Portal.Profile.Associations.Filter.PageNo = model.Paging.PageNo;
|
||||
SessionData_Portal.Profile.Associations.Filter.PageLength = model.Paging.PageLength;
|
||||
responseData.SetPaging(model);
|
||||
|
||||
// Complete response.
|
||||
responseData.Success = true;
|
||||
return Json(responseData);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Get Association ajax request.
|
||||
//-------------------------------------------------------------------
|
||||
private class AjaxResponse_Association : AjaxResponse_Data
|
||||
{
|
||||
// Construction.
|
||||
public AjaxResponse_Association(SbmModel_Portal model) : base(model) { }
|
||||
// Association details.
|
||||
public AssociationData_Full association { get; } = new AssociationData_Full();
|
||||
}
|
||||
//-------------------------------------------------------------------
|
||||
[HttpPost]
|
||||
[Route("Association/Ajax/Item")]
|
||||
[Route("Association/Ajax/GetItem")]
|
||||
public IActionResult Ajax_GetItem(Model_Association model)
|
||||
{
|
||||
String fn = GetType().Name + ".Ajax_GetItem";
|
||||
String messageTitle = Localiser["association.caption.association"];
|
||||
AjaxResponse_Association responseData = new AjaxResponse_Association(model);
|
||||
|
||||
// Validate session and referrer.
|
||||
if (!ValidUserSession) return GetAjaxResult_InvalidSession(responseData);
|
||||
if (!ValidReferer) return Forbid();
|
||||
RefreshModel(model);
|
||||
|
||||
// Identify item.
|
||||
SysId associationId = model.AssociationId.ToSysId();
|
||||
if (!SysId.IsValid(associationId))
|
||||
return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.item.id.not.specified"]));
|
||||
|
||||
// Retrieve item.
|
||||
SbmAssociation association = AccountMgr.GetAssociationById(associationId);
|
||||
if (association == null)
|
||||
{
|
||||
SaLogger.Warn(fn + " Failed to retrieve association for Id: '" + model.AssociationId + "'");
|
||||
return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.item.id.not.found"]));
|
||||
}
|
||||
|
||||
// Construct response.
|
||||
PopulateAssociationResponseData(association, responseData.association);
|
||||
|
||||
// Complete response.
|
||||
responseData.Success = true;
|
||||
|
||||
return Json(responseData);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Store Association ajax request.
|
||||
//-------------------------------------------------------------------
|
||||
[HttpPost]
|
||||
[Route("Association/Ajax/Store")]
|
||||
[Route("Association/Ajax/StoreItem")]
|
||||
public IActionResult Ajax_StoreItem(Model_Association model)
|
||||
{
|
||||
String fn = GetType().Name + ".Ajax_StoreItem";
|
||||
String messageTitle = Localiser["association.caption.association"];
|
||||
AjaxResponse_Association responseData = new AjaxResponse_Association(model);
|
||||
|
||||
// Validate session and referrer.
|
||||
if (!ValidUserSession) return GetAjaxResult_InvalidSession(responseData);
|
||||
if (!ValidReferer) return Forbid();
|
||||
RefreshModel(model);
|
||||
|
||||
// Validate item properties.
|
||||
model.ValidateAssociationData(responseData);
|
||||
if (responseData.HasControlErrors())
|
||||
return Json(responseData);
|
||||
|
||||
// Validate item Id against 'Exists' flag.
|
||||
SysId associationId = model.AssociationId.ToSysId();
|
||||
bool associationExists = StringUtil.ToBool(model.AssociationExists);
|
||||
if (associationExists && !SysId.IsValid(associationId))
|
||||
{
|
||||
SaLogger.Warn(fn + " Id not specified for existing Association.");
|
||||
return Json(responseData.SetGoHome(messageTitle, Localiser["msg.error.system"]));
|
||||
}
|
||||
if (!associationExists && SysId.IsValid(associationId))
|
||||
{
|
||||
SaLogger.Warn(fn + " Id specified for new Association: '" + model.AssociationId + "'");
|
||||
return Json(responseData.SetGoHome(messageTitle, Localiser["msg.error.system"]));
|
||||
}
|
||||
|
||||
// Retrieve existing item.
|
||||
SbmAssociation association = AccountMgr.GetAssociationById(associationId);
|
||||
if (association == null && SysId.IsValid(associationId))
|
||||
{
|
||||
SaLogger.Warn(fn + " Failed to retrieve association for Id: '" + model.AssociationId + "'");
|
||||
return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.item.id.not.found"]));
|
||||
}
|
||||
|
||||
// Create new item if required.
|
||||
if (association == null)
|
||||
{
|
||||
association = AccountMgr.CreateAssociation(SessionData.Organisation.AffiliateId, model.GetAssociationType(), model.AffiliateIdTarget.ToSysId());
|
||||
}
|
||||
|
||||
// Populate item properties.
|
||||
if (model.AssociationCode != null)
|
||||
association.Code = model.AssociationCode;
|
||||
if (model.AssociationReferenceExt != null)
|
||||
association.RefExt = model.AssociationReferenceExt;
|
||||
if (model.AssociationLocation != null)
|
||||
association.Location = model.AssociationLocation;
|
||||
if (model.AssociationRole != null)
|
||||
association.Role = model.AssociationRole;
|
||||
if (model.AssociationPhoneMain != null)
|
||||
association.PhoneMain = model.AssociationPhoneMain;
|
||||
if (model.AssociationEmail != null)
|
||||
association.Email = model.AssociationEmail;
|
||||
if (model.AssociationGroup != null)
|
||||
association.Group = model.AssociationGroup;
|
||||
if (model.AssociationDescDetail != null)
|
||||
association.DescDetail = model.AssociationDescDetail;
|
||||
if (model.AssociationNominalCodeDefault != null)
|
||||
association.DefaultNominalCode = model.AssociationNominalCodeDefault;
|
||||
// Account.
|
||||
if (model.AssociationAccountManagerCode != null)
|
||||
association.AccountManagerCode = model.AssociationAccountManagerCode;
|
||||
if (model.AssociationAccountHandlerCode != null)
|
||||
association.AccountHandlerCode = model.AssociationAccountHandlerCode;
|
||||
if (model.AssociationAccountTypeCode != null)
|
||||
association.AccountTypeCode = model.AssociationAccountTypeCode;
|
||||
if (model.AssociationAccountRatingCode != null)
|
||||
association.AccountRatingCode = model.AssociationAccountRatingCode;
|
||||
// Contact.
|
||||
if (model.AssociationContactAreaCode != null)
|
||||
association.ContactAreaCode = model.AssociationContactAreaCode;
|
||||
if (model.AssociationContactHandlerCode != null)
|
||||
association.ContactHandlerCode = model.AssociationContactHandlerCode;
|
||||
if (model.AssociationContactMethodCode != null)
|
||||
association.ContactMethodCode = model.AssociationContactMethodCode;
|
||||
if (model.AssociationContactCallCycleCode != null)
|
||||
association.ContactCallCycleCode = model.AssociationContactCallCycleCode;
|
||||
if (model.AssociationCallsPerYear != null)
|
||||
association.CallsPerYear = StringUtil.ToInt(model.AssociationCallsPerYear);
|
||||
if (model.AssociationLastCallDate != null)
|
||||
association.LastCall = model.ParseDateFromForm(model.AssociationLastCallDate);
|
||||
// Customer.
|
||||
if (model.AssociationCommodityIdSalesDefault != null)
|
||||
association.CommodityIdSalesDefault = model.AssociationCommodityIdSalesDefault.ToSysId();
|
||||
if (model.AssociationOrderLeadTimeCode != null)
|
||||
association.OrderLeadTimeCode = model.AssociationOrderLeadTimeCode;
|
||||
if (model.AssociationDeliveryTypeCode != null)
|
||||
association.DeliveryTypeCode = model.AssociationDeliveryTypeCode;
|
||||
if (model.AssociationDeliveryMethodCode != null)
|
||||
association.DeliveryMethodCode = model.AssociationDeliveryMethodCode;
|
||||
if (model.AssociationDeliveryCourierCode != null)
|
||||
association.DeliveryCourierCode = model.AssociationDeliveryCourierCode;
|
||||
if (model.AssociationDeliveryBookInCode != null)
|
||||
association.DeliveryBookInCode = model.AssociationDeliveryBookInCode;
|
||||
// Transactions.
|
||||
if (model.AssociationAmountTransMax != null)
|
||||
association.AmountTransMax = StringUtil.ToDecimal(model.AssociationAmountTransMax);
|
||||
if (model.AssociationAnnualSalesTarget != null)
|
||||
association.AnnualSalesTarget = StringUtil.ToDecimal(model.AssociationAnnualSalesTarget);
|
||||
if (model.AssociationCreditLimit != null)
|
||||
association.CreditLimit = StringUtil.ToDecimal(model.AssociationCreditLimit);
|
||||
if (model.AssociationAccountBalance != null)
|
||||
association.AccountBalance = StringUtil.ToDecimal(model.AssociationAccountBalance);
|
||||
if (model.AssociationDiscountType != null)
|
||||
association.DiscountType = model.GetAssociationDiscountType();
|
||||
if (model.AssociationDiscountRate != null)
|
||||
association.DiscountRate = StringUtil.ToDecimal(model.AssociationDiscountRate);
|
||||
if (model.AssociationPriceSetId != null)
|
||||
association.PriceSetId = model.AssociationPriceSetId.ToSysId();
|
||||
if (model.AssociationTaxCodeId != null)
|
||||
association.TaxCodeId = model.AssociationTaxCodeId.ToSysId();
|
||||
if (model.AssociationPaymentTerms != null)
|
||||
association.PaymentTerms = StringUtil.ToShort(model.AssociationPaymentTerms);
|
||||
if (model.AssociationInvoiceDesc != null)
|
||||
association.InvoiceDesc = model.AssociationInvoiceDesc;
|
||||
if (model.AssociationTerminatedDate != null)
|
||||
association.Terminated = model.ParseDateFromForm(model.AssociationTerminatedDate);
|
||||
// Common properties.
|
||||
if (model.AssociationNotes != null)
|
||||
association.Notes = model.AssociationNotes;
|
||||
if (model.AssociationStatusCode != null)
|
||||
association.Status = model.AssociationStatus;
|
||||
|
||||
// Store item.
|
||||
if (!SysId.IsValid(association.Id))
|
||||
{
|
||||
if (!AccountMgr.InsertAssociation(association, DbUpdateInfo))
|
||||
{
|
||||
SaLogger.Warn(fn + " Failed to insert association: " + AccountMgr.ErrorStateMessage);
|
||||
return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.item.insert.failed"] + "\n\n" + AccountMgr.ErrorStateMessage));
|
||||
}
|
||||
responseData.SetNotification(messageTitle, Localiser["msg.item.created"]);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!AccountMgr.UpdateAssociation(association, DbUpdateInfo))
|
||||
{
|
||||
SaLogger.Warn(fn + " Failed to update association [Id:" + SysId.ToString(association.Id) + "]: " + AccountMgr.ErrorStateMessage);
|
||||
return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.item.update.failed"] + "\n\n" + AccountMgr.ErrorStateMessage));
|
||||
}
|
||||
responseData.SetNotification(messageTitle, Localiser["msg.item.updated"]);
|
||||
}
|
||||
|
||||
// Construct response.
|
||||
PopulateAssociationResponseData(association, responseData.association);
|
||||
|
||||
// Complete response.
|
||||
responseData.Success = true;
|
||||
|
||||
return Json(responseData);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
}
|
||||
//=======================================================================
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Sarand.BusinessMgr.Net.Core.Web.App;
|
||||
using Sarand.BusinessMgr.Net.Core.Web.Helpers;
|
||||
using Sarand.BusinessMgr.Net.Core.Web.Portal.Models;
|
||||
using Sarand.BusinessMgr.Net.Standard.Base.App;
|
||||
using Sarand.BusinessMgr.Net.Standard.Base.Bus;
|
||||
using Sarand.BusinessMgr.Net.Standard.Base.Mgr;
|
||||
using Sarand.Net.Standard.Base.App;
|
||||
using Sarand.Net.Standard.Base.Bus;
|
||||
using Sarand.Net.Standard.Base.Security;
|
||||
using Sarand.Net.Standard.Base.Utils;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Sarand.BusinessMgr.Net.Core.Web.Portal.Controllers
|
||||
{
|
||||
//=======================================================================
|
||||
public partial class AssociationController : SbmController_Portal
|
||||
{
|
||||
//-------------------------------------------------------------------
|
||||
// Data members.
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Construction.
|
||||
public AssociationController(SbmLocaliser localiser, ILogger<AssociationController> logger) :
|
||||
base(localiser, logger)
|
||||
{
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
[HttpGet]
|
||||
public IActionResult Index()
|
||||
{
|
||||
String fn = GetType().Name + ".Index";
|
||||
|
||||
if (!ValidUserSession)
|
||||
return RedirectToAction("", "");
|
||||
|
||||
// Association page.
|
||||
Model_Association model = new Model_Association(Localiser);
|
||||
model.Paging.PageNo = SessionData_Portal.Profile.Associations.Filter.PageNo;
|
||||
model.Paging.PageLength = SessionData_Portal.Profile.Associations.Filter.PageLength;
|
||||
return View(model);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
}
|
||||
//=======================================================================
|
||||
}
|
||||
@@ -31,7 +31,7 @@ namespace Sarand.BusinessMgr.Net.Core.Web.Portal.Controllers
|
||||
{
|
||||
//-------------------------------------------------------------------
|
||||
// Commodity data.
|
||||
private class CommodityData_List : AjaxResponse_Data.ItemData
|
||||
private class CommodityData_List : AjaxResponse_Data.ItemData_Base
|
||||
{
|
||||
public String TypeCode { get; set; }
|
||||
public String TypeDesc { get; set; }
|
||||
|
||||
@@ -31,7 +31,7 @@ namespace Sarand.BusinessMgr.Net.Core.Web.Portal.Controllers
|
||||
{
|
||||
//-------------------------------------------------------------------
|
||||
// Affiliate data.
|
||||
private class AffiliateData_List : AjaxResponse_Data.ItemData
|
||||
private class AffiliateData_List : AjaxResponse_Data.ItemData_Base
|
||||
{
|
||||
public String DisplayName { get; set; }
|
||||
public String TypeCode { get; set; }
|
||||
|
||||
@@ -18,103 +18,102 @@ using System.Threading.Tasks;
|
||||
|
||||
namespace Sarand.BusinessMgr.Net.Core.Web.Portal.Controllers
|
||||
{
|
||||
//=======================================================================
|
||||
public class HomeController : SbmController_Portal
|
||||
{
|
||||
//-------------------------------------------------------------------
|
||||
// Data members.
|
||||
//=======================================================================
|
||||
public class HomeController : SbmController_Portal
|
||||
{
|
||||
//-------------------------------------------------------------------
|
||||
// Data members.
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Construction.
|
||||
public HomeController(SbmLocaliser localiser, ILogger<HomeController> logger) :
|
||||
base(localiser, logger)
|
||||
{
|
||||
}
|
||||
//-------------------------------------------------------------------
|
||||
// Construction.
|
||||
public HomeController(SbmLocaliser localiser, ILogger<HomeController> logger) :
|
||||
base(localiser, logger)
|
||||
{
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
[HttpGet]
|
||||
public IActionResult Index()
|
||||
{
|
||||
String fn = GetType().Name + ".Index";
|
||||
//-------------------------------------------------------------------
|
||||
[HttpGet]
|
||||
public IActionResult Index()
|
||||
{
|
||||
|
||||
// Check for 'Keep Logged In' cookie.
|
||||
// NB Only allowed if there isn't a current user session.
|
||||
if (!ValidUserSession && AppConfig.Security.SignIn.KeepLoggedIn.Allowed)
|
||||
{
|
||||
// Extract parameters and validate that they are populated.
|
||||
String encryptedParams = GetRequestCookie(CookieName_KeepLoggedIn);
|
||||
KeepLoggedInParams keepLoggedInParams = ExtractKeepLoggedInParams(encryptedParams);
|
||||
String logPrefix = fn + " 'Keep Logged In' cookie found but ";
|
||||
String logSuffix = keepLoggedInParams.GetValidParams().Concat("", " ", ".");
|
||||
if (keepLoggedInParams.IsValid())
|
||||
{
|
||||
// User may be defined on any one of the BusinessMgr databases - need to find out which.
|
||||
// Identify session contexts with a BusMgr database that hosts the specified email address.
|
||||
List<ushort> sessionContextIdxs = SbmSessionContextHelper_Web.GetSessionContextIdxsForUsersBusMgrDatabase(keepLoggedInParams.EmailAddress);
|
||||
foreach (ushort sessionContextIdx in sessionContextIdxs)
|
||||
{
|
||||
// Consoles and Managers must be associated with the specific context.
|
||||
SbmSessionContext sessionContext = SbmSessionContextHelper_Web.GetSessionContext(sessionContextIdx);
|
||||
SbmUserContext_Web userContext = new SbmUserContext_Web(sessionContext);
|
||||
using (SaSecurityConsole securityConsoleForUser = App.CreateSecurityConsole(userContext))
|
||||
using (SbmAccountMgr accountMgrForUser = App.System.CreateAccountMgr(userContext))
|
||||
{
|
||||
using (SaSecurityItem securityItemUser = securityConsoleForUser.GetUserByEmail(keepLoggedInParams.EmailAddress))
|
||||
using (SbmAffiliate affiliateUser = accountMgrForUser.GetAffiliateById(keepLoggedInParams.AffiliateIdUser))
|
||||
using (SbmAssociation associationOrganisation = accountMgrForUser.GetAssociationById(keepLoggedInParams.AssociationIdOrganisation))
|
||||
using (SbmAffiliate affiliateOrganisation = accountMgrForUser.GetAffiliateById(associationOrganisation?.AffiliateIdOwner ?? null))
|
||||
{
|
||||
if (securityItemUser != null && affiliateUser != null && associationOrganisation != null && affiliateOrganisation != null)
|
||||
{
|
||||
if (securityItemUser.Id.Equals(keepLoggedInParams.SecurityItemId) && affiliateUser.UserId.Equals(securityItemUser.Id))
|
||||
{
|
||||
if (affiliateUser.IsStatusCurrent)
|
||||
{
|
||||
List<SysIdString> supervisedOrganisations = accountMgrForUser.GetAffiliatesSupervisedBy(affiliateUser.Id);
|
||||
String errorMessage = "";
|
||||
if (SignUserIn(userContext, securityItemUser, affiliateUser, supervisedOrganisations, associationOrganisation, affiliateOrganisation, true, ref errorMessage))
|
||||
{
|
||||
SaLogger.Info(logPrefix + " 'Keep Logged In' cookie found." + logSuffix);
|
||||
break;
|
||||
}
|
||||
else SaLogger.Warn(logPrefix + "failed to sign user in: " + errorMessage + "." + logSuffix);
|
||||
}
|
||||
else SaLogger.Warn(logPrefix + "Affiliate is not active." + logSuffix);
|
||||
}
|
||||
else SaLogger.Warn(logPrefix + "Security Item and Affiliate are inconsistent. " + logSuffix);
|
||||
}
|
||||
else SaLogger.Warn(logPrefix + "Security Item or Affiliate not found. " + logSuffix);
|
||||
}
|
||||
}
|
||||
if (ValidUserSession)
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (!StringUtil.IsEmpty(encryptedParams))
|
||||
SaLogger.Warn(fn + " Keep Logged In cookie found but with incomplete details." + logSuffix);
|
||||
}
|
||||
// Check for 'Keep Logged In' cookie.
|
||||
// NB Only allowed if there isn't a current user session.
|
||||
if (!ValidUserSession && AppConfig.Security.SignIn.KeepLoggedIn.Allowed)
|
||||
{
|
||||
// Extract parameters and validate that they are populated.
|
||||
String encryptedParams = GetRequestCookie(CookieName_KeepLoggedIn);
|
||||
KeepLoggedInParams keepLoggedInParams = ExtractKeepLoggedInParams(encryptedParams);
|
||||
String logPrefix = $"{SysUtil.Fn} 'Keep Logged In' cookie found but ";
|
||||
String logSuffix = keepLoggedInParams.GetValidParams().Concat("", " ", ".");
|
||||
if (keepLoggedInParams.IsValid())
|
||||
{
|
||||
// User may be defined on any one of the BusinessMgr databases - need to find out which.
|
||||
// Identify session contexts with a BusMgr database that hosts the specified email address.
|
||||
List<ushort> sessionContextIdxs = SbmSessionContextHelper_Web.GetSessionContextIdxsForContextUserEmail(keepLoggedInParams.DbIdentifier, keepLoggedInParams.EmailAddress);
|
||||
foreach (ushort sessionContextIdx in sessionContextIdxs)
|
||||
{
|
||||
// Consoles and Managers must be associated with the specific context.
|
||||
SbmSessionContext sessionContext = SbmSessionContextHelper_Web.GetSessionContext(sessionContextIdx);
|
||||
SbmUserContext_Web userContext = new SbmUserContext_Web(sessionContext);
|
||||
using (SaSecurityConsole securityConsoleForUser = App.CreateSecurityConsole(userContext))
|
||||
using (SbmAccountMgr accountMgrForUser = App.System.CreateAccountMgr(userContext))
|
||||
{
|
||||
using (SaSecurityItem securityItemUser = securityConsoleForUser.GetUserByEmail(keepLoggedInParams.EmailAddress))
|
||||
using (SbmAffiliate affiliateUser = accountMgrForUser.GetAffiliateById(keepLoggedInParams.AffiliateIdUser))
|
||||
using (SbmAssociation associationOrganisation = accountMgrForUser.GetAssociationById(keepLoggedInParams.AssociationIdOrganisation))
|
||||
using (SbmAffiliate affiliateOrganisation = accountMgrForUser.GetAffiliateById(associationOrganisation?.AffiliateIdOwner ?? null))
|
||||
{
|
||||
if (securityItemUser != null && affiliateUser != null && associationOrganisation != null && affiliateOrganisation != null)
|
||||
{
|
||||
if (securityItemUser.Id.Equals(keepLoggedInParams.SecurityItemId) && affiliateUser.UserId.Equals(securityItemUser.Id))
|
||||
{
|
||||
if (affiliateUser.IsStatusCurrent)
|
||||
{
|
||||
List<SysIdString> supervisedOrganisations = accountMgrForUser.GetAffiliatesSupervisedBy(affiliateUser.Id);
|
||||
String errorMessage = "";
|
||||
if (SignUserIn(userContext, keepLoggedInParams.DbIdentifier, securityItemUser, affiliateUser, supervisedOrganisations, associationOrganisation, affiliateOrganisation, true, ref errorMessage))
|
||||
{
|
||||
SaLogger.Info(logPrefix + " 'Keep Logged In' cookie found." + logSuffix);
|
||||
break;
|
||||
}
|
||||
else SaLogger.Warn(logPrefix + "failed to sign user in: " + errorMessage + "." + logSuffix);
|
||||
}
|
||||
else SaLogger.Warn(logPrefix + "Affiliate is not active." + logSuffix);
|
||||
}
|
||||
else SaLogger.Warn(logPrefix + "Security Item and Affiliate are inconsistent. " + logSuffix);
|
||||
}
|
||||
else SaLogger.Warn(logPrefix + "Security Item or Affiliate not found. " + logSuffix);
|
||||
}
|
||||
}
|
||||
if (ValidUserSession)
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (!StringUtil.IsEmpty(encryptedParams))
|
||||
SaLogger.Warn($"{SysUtil.Fn} Keep Logged In cookie found but with incomplete details." + logSuffix);
|
||||
}
|
||||
|
||||
// Redirect to sign-in if not signed-in.
|
||||
if (!ValidUserSession)
|
||||
{
|
||||
ClearKeepLoggedInCookie();
|
||||
return RedirectToAction("", "Security");
|
||||
}
|
||||
// Redirect to sign-in if not signed-in.
|
||||
if (!ValidUserSession)
|
||||
{
|
||||
ClearKeepLoggedInCookie();
|
||||
return RedirectToAction("", "Security");
|
||||
}
|
||||
|
||||
// Home page.
|
||||
Model_Home model = new Model_Home(Localiser);
|
||||
model.ProhibitCache = false;
|
||||
return View(model);
|
||||
}
|
||||
// Home page.
|
||||
Model_Home model = new Model_Home(Localiser);
|
||||
model.ProhibitCache = false;
|
||||
return View(model);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
|
||||
public IActionResult Error()
|
||||
{
|
||||
return View(new ErrorViewModel(Localiser) { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });
|
||||
}
|
||||
//-------------------------------------------------------------------
|
||||
[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
|
||||
public IActionResult Error()
|
||||
{
|
||||
return View(new ErrorViewModel(Localiser) { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
}
|
||||
//=======================================================================
|
||||
//-------------------------------------------------------------------
|
||||
}
|
||||
//=======================================================================
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ using System.Collections.Specialized;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using System.Web;
|
||||
using static Sarand.BusinessMgr.Net.Standard.Base.App.Sbm.Config.Database;
|
||||
|
||||
namespace Sarand.BusinessMgr.Net.Core.Web.Portal.Controllers
|
||||
{
|
||||
@@ -52,7 +53,7 @@ namespace Sarand.BusinessMgr.Net.Core.Web.Portal.Controllers
|
||||
/// <para>- Open user session - store details against Sesion Data.</para>
|
||||
/// <para>- Set 'Keep logged in' cookie if required.</para>
|
||||
/// </summary>
|
||||
protected bool SignUserIn(ISbmUserContext userContext, SaSecurityItem securityItemUser, SbmAffiliate affiliateUser, List<SysIdString> supervisedOrganisations, SbmAssociation associationOrganisation, SbmAffiliate affiliateOrganisation, bool keepLoggedIn, ref String errorMessage)
|
||||
protected bool SignUserIn(ISbmUserContext userContext, String dbIdentifier, SaSecurityItem securityItemUser, SbmAffiliate affiliateUser, List<SysIdString> supervisedOrganisations, SbmAssociation associationOrganisation, SbmAffiliate affiliateOrganisation, bool keepLoggedIn, ref String errorMessage)
|
||||
{
|
||||
String fn = GetType().Name + ".SignUserIn";
|
||||
|
||||
@@ -125,7 +126,7 @@ namespace Sarand.BusinessMgr.Net.Core.Web.Portal.Controllers
|
||||
}
|
||||
|
||||
// Create session.
|
||||
OpenUserSession(userContext.SessionContext, securityItemUser, affiliateUser, supervisedOrganisations, associationOrganisation, affiliateOrganisation);
|
||||
OpenUserSession(userContext.SessionContext, dbIdentifier, securityItemUser, affiliateUser, supervisedOrganisations, associationOrganisation, affiliateOrganisation);
|
||||
|
||||
// Send the 'Keep Logged In' cookie if requested.
|
||||
if (affiliateUser.KeepLoggedIn_Portal)
|
||||
@@ -153,7 +154,7 @@ namespace Sarand.BusinessMgr.Net.Core.Web.Portal.Controllers
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
/// <summary>Start a new user session on sign-in.</summary>
|
||||
protected bool OpenUserSession(SbmSessionContext sessionContext, SaSecurityItem securityItemUser, SbmAffiliate affiliateUser, List<SysIdString> supervisedOrganisations, SbmAssociation associationOrganisation, SbmAffiliate affiliateOrganisation)
|
||||
protected bool OpenUserSession(SbmSessionContext sessionContext, String dbIdentifier, SaSecurityItem securityItemUser, SbmAffiliate affiliateUser, List<SysIdString> supervisedOrganisations, SbmAssociation associationOrganisation, SbmAffiliate affiliateOrganisation)
|
||||
{
|
||||
// Validate user properties.
|
||||
if (!SysId.IsValid(affiliateUser.Id)) return false;
|
||||
@@ -163,7 +164,7 @@ namespace Sarand.BusinessMgr.Net.Core.Web.Portal.Controllers
|
||||
CloseUserSession();
|
||||
|
||||
// Open session.
|
||||
return SetSessionData(new SbmSessionData_Portal(sessionContext, securityItemUser, affiliateUser, supervisedOrganisations, associationOrganisation, affiliateOrganisation));
|
||||
return SetSessionData(new SbmSessionData_Portal(sessionContext, dbIdentifier, securityItemUser, affiliateUser, supervisedOrganisations, associationOrganisation, affiliateOrganisation));
|
||||
}
|
||||
protected void CloseUserSession()
|
||||
{
|
||||
@@ -205,6 +206,7 @@ namespace Sarand.BusinessMgr.Net.Core.Web.Portal.Controllers
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Keep-logged-in cookie value.
|
||||
private static readonly String ParamName_KeepLoggedIn_DbIdentifier = "dbi";
|
||||
private static readonly String ParamName_KeepLoggedIn_EmailAddress = "ema";
|
||||
private static readonly String ParamName_KeepLoggedIn_SecurityItemId = "sii";
|
||||
private static readonly String ParamName_KeepLoggedIn_AffiliateIdUser = "afiu";
|
||||
@@ -212,6 +214,7 @@ namespace Sarand.BusinessMgr.Net.Core.Web.Portal.Controllers
|
||||
private String GenerateKeepLoggedInCookieValue()
|
||||
{
|
||||
NameValueCollection keepLoggedInParams = new NameValueCollection();
|
||||
keepLoggedInParams.Add(ParamName_KeepLoggedIn_DbIdentifier, SessionData_Portal.DbIdentifier);
|
||||
keepLoggedInParams.Add(ParamName_KeepLoggedIn_EmailAddress, SessionData_Portal.User.EmailAddress);
|
||||
keepLoggedInParams.Add(ParamName_KeepLoggedIn_SecurityItemId, SysId.ToString(SessionData_Portal.User.SecurityItemId));
|
||||
keepLoggedInParams.Add(ParamName_KeepLoggedIn_AffiliateIdUser, SysId.ToString(SessionData_Portal.User.AffiliateId));
|
||||
@@ -222,6 +225,7 @@ namespace Sarand.BusinessMgr.Net.Core.Web.Portal.Controllers
|
||||
//-------------------------------------------------------------------
|
||||
public class KeepLoggedInParams
|
||||
{
|
||||
public String DbIdentifier { get; set; }
|
||||
public String EmailAddress { get; set; }
|
||||
public SysId SecurityItemId { get; set; }
|
||||
public SysId AffiliateIdUser { get; set; }
|
||||
@@ -230,7 +234,9 @@ namespace Sarand.BusinessMgr.Net.Core.Web.Portal.Controllers
|
||||
public List<String> GetValidParams()
|
||||
{
|
||||
List<String> values = new List<String>();
|
||||
if (!StringUtil.IsEmpty(EmailAddress))
|
||||
if (!StringUtil.IsBlank(DbIdentifier))
|
||||
values.Add("DbIdentifier: " + DbIdentifier);
|
||||
if (!StringUtil.IsBlank(EmailAddress))
|
||||
values.Add("EmailAddress: " + EmailAddress);
|
||||
if (SysId.IsValid(SecurityItemId))
|
||||
values.Add("SecurityItemId: " + SysId.ToString(SecurityItemId));
|
||||
@@ -244,7 +250,8 @@ namespace Sarand.BusinessMgr.Net.Core.Web.Portal.Controllers
|
||||
public bool IsValid()
|
||||
{
|
||||
return
|
||||
!StringUtil.IsEmpty(EmailAddress) &&
|
||||
!StringUtil.IsBlank(DbIdentifier) &&
|
||||
StringUtil.IsBlank(EmailAddress) &&
|
||||
SysId.IsValid(SecurityItemId) &&
|
||||
SysId.IsValid(AffiliateIdUser) &&
|
||||
SysId.IsValid(AssociationIdOrganisation);
|
||||
@@ -256,6 +263,7 @@ namespace Sarand.BusinessMgr.Net.Core.Web.Portal.Controllers
|
||||
if (!StringUtil.IsEmpty(encryptedParams))
|
||||
{
|
||||
NameValueCollection linkParams = DecryptParameters(encryptedParams, Base64IV_KeepLoggedIn, Base64Key_KeepLoggedIn);
|
||||
keepLoggedInParams.DbIdentifier = linkParams.Get(ParamName_KeepLoggedIn_DbIdentifier);
|
||||
keepLoggedInParams.EmailAddress = linkParams.Get(ParamName_KeepLoggedIn_EmailAddress);
|
||||
keepLoggedInParams.SecurityItemId = linkParams.Get(ParamName_KeepLoggedIn_SecurityItemId).ToSysId();
|
||||
keepLoggedInParams.AffiliateIdUser = linkParams.Get(ParamName_KeepLoggedIn_AffiliateIdUser).ToSysId();
|
||||
|
||||
@@ -54,16 +54,20 @@ namespace Sarand.BusinessMgr.Net.Core.Web.Portal.Controllers
|
||||
model.ValidateSignInData(responseData);
|
||||
if (responseData.HasControlErrors())
|
||||
return Json(responseData);
|
||||
|
||||
// Identify session contexts with a BusMgr database that hosts the specified email address.
|
||||
List<ushort> sessionContextIdxs = SbmSessionContextHelper_Web.GetSessionContextIdxsForUsersBusMgrDatabase(model.EmailAddress);
|
||||
foreach (ushort sessionContextIdx in sessionContextIdxs)
|
||||
using (DisposableCollection<IDisposable> disposableItems = new DisposableCollection<IDisposable>())
|
||||
{
|
||||
SbmSessionContext sessionContext = SbmSessionContextHelper_Web.GetSessionContext(sessionContextIdx);
|
||||
SbmUserContext_Web userContext = new SbmUserContext_Web(sessionContext);
|
||||
|
||||
using (DisposableCollection<IDisposable> disposableItems = new DisposableCollection<IDisposable>())
|
||||
// Identify session contexts with a BusMgr database that hosts the specified email address.
|
||||
List<ushort> sessionContextIdxs = SbmSessionContextHelper_Web.GetSessionContextIdxsForContextUserEmail(model.DbIdentifier, model.EmailAddress);
|
||||
if (sessionContextIdxs.IsEmpty())
|
||||
return Json(responseData.SetControlError(nameof(model.EmailAddress), model.Localiser["security.msg.signin.invalid"]));
|
||||
foreach (ushort sessionContextIdx in sessionContextIdxs)
|
||||
{
|
||||
SbmSessionContext sessionContext = SbmSessionContextHelper_Web.GetSessionContext(sessionContextIdx);
|
||||
SbmUserContext_Web userContext = new SbmUserContext_Web(sessionContext);
|
||||
ISacsDatabase busMgrDatabase = App.GetBusMgrDatabase(sessionContext);
|
||||
if (busMgrDatabase == null) continue;
|
||||
|
||||
// Account manager.
|
||||
SaSecurityConsole securityConsoleForUser = App.CreateSecurityConsole(userContext);
|
||||
disposableItems.Add(securityConsoleForUser);
|
||||
@@ -73,27 +77,36 @@ namespace Sarand.BusinessMgr.Net.Core.Web.Portal.Controllers
|
||||
// User's security item.
|
||||
SaSecurityItem securityItemUser = GetSecurityItemForSignin(securityConsoleForUser, model);
|
||||
if (securityItemUser == null)
|
||||
return Json(responseData.SetControlError(nameof(model.EmailAddress), model.Localiser["security.msg.signin.invalid"]));
|
||||
{
|
||||
SaLogger.Warn(fn + " Failed to retrieve Security Item. Database: " + busMgrDatabase.DatabaseName + ". Email: " + model.EmailAddress);
|
||||
continue;
|
||||
}
|
||||
disposableItems.Add(securityItemUser);
|
||||
|
||||
// User's affiliate.
|
||||
SbmAffiliate affiliateUser = GetAffiliateForSignin(accountMgrForUser, model, securityItemUser);
|
||||
if (affiliateUser == null)
|
||||
return Json(responseData.SetControlError(nameof(model.EmailAddress), model.Localiser["security.msg.signin.invalid"]));
|
||||
{
|
||||
SaLogger.Warn(fn + " Failed to retrieve Affiliate for signin. Database: " + busMgrDatabase.DatabaseName + ". UserId: " + SysId.ToString(securityItemUser.Id));
|
||||
continue;
|
||||
}
|
||||
disposableItems.Add(affiliateUser);
|
||||
|
||||
// User's supervised organisations.
|
||||
List<SysIdString> supervisedOrganisations = accountMgrForUser.GetAffiliatesSupervisedBy(affiliateUser.Id);
|
||||
if (supervisedOrganisations.IsEmpty())
|
||||
{
|
||||
SaLogger.Warn(fn + " User has no supervised organisations. Email: " + model.EmailAddress);
|
||||
return Json(responseData.SetControlError(nameof(model.EmailAddress), model.Localiser["security.msg.signin.invalid"]));
|
||||
SaLogger.Warn(fn + " User has no supervised organisations. Database: " + busMgrDatabase.DatabaseName + ". Email: " + model.EmailAddress);
|
||||
continue;
|
||||
}
|
||||
|
||||
// User's organisation association.
|
||||
SbmAssociation associationOrganisation = GetOrganisationAssociationForSignIn(accountMgrForUser, model, affiliateUser, supervisedOrganisations);
|
||||
if (associationOrganisation == null)
|
||||
return Json(responseData.SetControlError(nameof(model.EmailAddress), model.Localiser["security.msg.signin.invalid"]));
|
||||
{
|
||||
SaLogger.Warn(fn + " Failed to identify Organisation Association. Database: " + busMgrDatabase.DatabaseName + ". Email: " + model.EmailAddress);
|
||||
continue;
|
||||
}
|
||||
disposableItems.Add(associationOrganisation);
|
||||
|
||||
// User's organisation affiliate.
|
||||
@@ -101,15 +114,22 @@ namespace Sarand.BusinessMgr.Net.Core.Web.Portal.Controllers
|
||||
disposableItems.Add(affiliateOrganisation);
|
||||
if (affiliateOrganisation == null)
|
||||
{
|
||||
SaLogger.Warn(fn + " Failed to retrieve Affiliate for organisation. Id: " + SysId.ToString(associationOrganisation?.Id ?? null));
|
||||
return Json(responseData.SetControlError(nameof(model.EmailAddress), model.Localiser["security.msg.signin.invalid"]));
|
||||
SaLogger.Warn(fn + " Failed to retrieve Affiliate for organisation. Database: " + busMgrDatabase.DatabaseName + ". Id: " + SysId.ToString(associationOrganisation?.Id ?? null));
|
||||
continue;
|
||||
}
|
||||
|
||||
// Initialise user session.
|
||||
String errorMessage = "";
|
||||
if (!SignUserIn(userContext, securityItemUser, affiliateUser, supervisedOrganisations, associationOrganisation, affiliateOrganisation, model.KeepMeSignedIn, ref errorMessage))
|
||||
return Json(responseData.SetControlError(nameof(model.EmailAddress), errorMessage));
|
||||
if (SignUserIn(userContext, model.DbIdentifier, securityItemUser, affiliateUser, supervisedOrganisations, associationOrganisation, affiliateOrganisation, model.KeepMeSignedIn, ref errorMessage))
|
||||
break;
|
||||
else return Json(responseData.SetControlError(nameof(model.EmailAddress), errorMessage));
|
||||
}
|
||||
}
|
||||
if (!(SessionData_Portal?.ValidUserSession ?? false))
|
||||
{
|
||||
SaLogger.Warn(fn + " Failed to identify Suitable database. Email: " + model.EmailAddress);
|
||||
return Json(responseData.SetControlError(nameof(model.EmailAddress), model.Localiser["security.msg.signin.invalid"]));
|
||||
}
|
||||
|
||||
// Construct response.
|
||||
responseData.Success = SessionData_Portal?.ValidUserSession ?? false;
|
||||
@@ -131,7 +151,7 @@ namespace Sarand.BusinessMgr.Net.Core.Web.Portal.Controllers
|
||||
}
|
||||
|
||||
// Validate password.
|
||||
if (!SbmPasswordHelper.VerifyHashedPassword(securityItemUser, model.Password) && !(DebugMode && model.EmailAddress.EqualsCI("ahoward@sarand.com")))
|
||||
if (!SbmPasswordHelper.VerifyHashedPassword(securityItemUser, model.Password) && !(DebugMode && model.EmailAddress.EqualsCI("andy@sarand.com")))
|
||||
{
|
||||
// Record invalid login attempt.
|
||||
securityItemUser.InvalidLoginCount++;
|
||||
@@ -331,8 +351,8 @@ namespace Sarand.BusinessMgr.Net.Core.Web.Portal.Controllers
|
||||
if (requestPasswordParams.IsValid())
|
||||
{
|
||||
// User may be defined on any one of the BusinessMgr databases - need to find out which.
|
||||
// Identify session contexts with a BusMgr database that hosts the specified email address.
|
||||
List<ushort> sessionContextIdxs = SbmSessionContextHelper_Web.GetSessionContextIdxsForUsersBusMgrDatabase(requestPasswordParams.EmailAddress);
|
||||
// Identify session contexts for databases with specified Id that hosts the specified email address.
|
||||
List<ushort> sessionContextIdxs = SbmSessionContextHelper_Web.GetSessionContextIdxsForContextUserEmail(requestPasswordParams.DbIdentifier, requestPasswordParams.EmailAddress);
|
||||
foreach (ushort sessionContextIdx in sessionContextIdxs)
|
||||
{
|
||||
// Consoles and Managers must be associated with the specific context.
|
||||
@@ -460,7 +480,7 @@ namespace Sarand.BusinessMgr.Net.Core.Web.Portal.Controllers
|
||||
if (responseData.HasControlErrors()) return Json(responseData);
|
||||
|
||||
// Identify session contexts with a BusMgr database that hosts the specified email address.
|
||||
List<ushort> sessionContextIdxs = SbmSessionContextHelper_Web.GetSessionContextIdxsForUsersBusMgrDatabase(model.EmailAddress);
|
||||
List<ushort> sessionContextIdxs = SbmSessionContextHelper_Web.GetSessionContextIdxsForContextUserEmail(model.DbIdentifier, model.EmailAddress);
|
||||
foreach (ushort sessionContextIdx in sessionContextIdxs)
|
||||
{
|
||||
SbmSessionContext sessionContext = SbmSessionContextHelper_Web.GetSessionContext(sessionContextIdx);
|
||||
@@ -519,13 +539,14 @@ namespace Sarand.BusinessMgr.Net.Core.Web.Portal.Controllers
|
||||
emailConsole.ReplaceDynamicEmailBodyTags(emailData, null);
|
||||
|
||||
// Replace dynamic tag for link back to change password page.
|
||||
SaEmailConsole.ReplaceDynamicEmailTag(emailData, "[#Link.RequestPassword]", GenerateRequestPasswordLink(securityItemUser.Id, affiliateUser.Id, securityItemUser.EmailAddress, ""));
|
||||
SaEmailConsole.ReplaceDynamicEmailTag(emailData, "[#Link.RequestPassword]", GenerateRequestPasswordLink(SessionData_Portal.DbIdentifier, securityItemUser.Id, affiliateUser.Id, securityItemUser.EmailAddress, ""));
|
||||
SaEmailConsole.ReplaceDynamicEmailTag(emailData, "[#Link.ExpiresMinutes]", GetRequestPasswordEmailLinkExpiresMinutes().ToString());
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Password request link.
|
||||
private static String ParamName_RequestPasswordEncrypted { get; } = "rpe";
|
||||
private static String ParamName_DbIdentifier { get; } = "dbi";
|
||||
private static String ParamName_EmailAddress { get; } = "ema";
|
||||
private static String ParamName_SecurityItemId { get; } = "sei";
|
||||
private static String ParamName_AffiliateId { get; } = "afi";
|
||||
@@ -536,9 +557,10 @@ namespace Sarand.BusinessMgr.Net.Core.Web.Portal.Controllers
|
||||
private static String Base64Key_RequestPassword { get; } = SacsEncryptionHelper.EncodePlainKey("[-SaBusMgr+<Request=Password>!^]", SacsEncryptionHelper.KeyLength);
|
||||
//private static String Base64IV_RequestPassword_Generated { get; } = SacsEncryptionHelper.InitSymmetricEncryptionIV(Base64Key_RequestPassword);
|
||||
private static String Base64IV_RequestPassword { get; } = "iALRIxzrZIfrB4boNFRXfA==";
|
||||
private String GenerateRequestPasswordLink(SysId securityItemId, SysId affiliateId, String emailAddress, String requestPasswordToken)
|
||||
private String GenerateRequestPasswordLink(String dbIdentifier, SysId securityItemId, SysId affiliateId, String emailAddress, String requestPasswordToken)
|
||||
{
|
||||
NameValueCollection parameters = new NameValueCollection();
|
||||
parameters.Add(ParamName_DbIdentifier, dbIdentifier);
|
||||
parameters.Add(ParamName_EmailAddress, emailAddress);
|
||||
parameters.Add(ParamName_SecurityItemId, SysId.ToString(securityItemId));
|
||||
parameters.Add(ParamName_AffiliateId, SysId.ToString(affiliateId));
|
||||
@@ -558,6 +580,7 @@ namespace Sarand.BusinessMgr.Net.Core.Web.Portal.Controllers
|
||||
}
|
||||
private class RequestPasswordParams
|
||||
{
|
||||
public String DbIdentifier { get; set; }
|
||||
public String EmailAddress { get; set; }
|
||||
public SysId SecurityItemId { get; set; }
|
||||
public SysId AffiliateId { get; set; }
|
||||
@@ -567,7 +590,9 @@ namespace Sarand.BusinessMgr.Net.Core.Web.Portal.Controllers
|
||||
public List<String> GetValidParams()
|
||||
{
|
||||
List<String> values = new List<String>();
|
||||
if (!StringUtil.IsEmpty(EmailAddress))
|
||||
if (!StringUtil.IsBlank(DbIdentifier))
|
||||
values.Add("DbIdentifier: " + DbIdentifier);
|
||||
if (!StringUtil.IsBlank(EmailAddress))
|
||||
values.Add("Email: " + EmailAddress);
|
||||
if (SysId.IsValid(SecurityItemId))
|
||||
values.Add("SecurityItemId: " + SysId.ToString(SecurityItemId));
|
||||
@@ -575,7 +600,7 @@ namespace Sarand.BusinessMgr.Net.Core.Web.Portal.Controllers
|
||||
values.Add("AffiliateId: " + SysId.ToString(AffiliateId));
|
||||
if (DateUtil.IsValid(ExpiresAt))
|
||||
values.Add("Expires: " + DateUtil.FormatXmlDateTime(ExpiresAt));
|
||||
if (!StringUtil.IsEmpty(Token))
|
||||
if (!StringUtil.IsBlank(Token))
|
||||
values.Add("Token: " + Token);
|
||||
return values;
|
||||
}
|
||||
@@ -583,7 +608,8 @@ namespace Sarand.BusinessMgr.Net.Core.Web.Portal.Controllers
|
||||
public bool IsValid()
|
||||
{
|
||||
return
|
||||
!StringUtil.IsEmpty(EmailAddress) &&
|
||||
!StringUtil.IsBlank(DbIdentifier) &&
|
||||
StringUtil.IsBlank(EmailAddress) &&
|
||||
SysId.IsValid(SecurityItemId) &&
|
||||
SysId.IsValid(AffiliateId) &&
|
||||
DateUtil.IsValid(ExpiresAt) && ExpiresAt >= DateTime.Now;
|
||||
@@ -606,6 +632,7 @@ namespace Sarand.BusinessMgr.Net.Core.Web.Portal.Controllers
|
||||
if (!StringUtil.IsEmpty(encryptedParams))
|
||||
{
|
||||
NameValueCollection linkParams = DecryptParameters(encryptedParams, Base64IV_RequestPassword, Base64Key_RequestPassword);
|
||||
requestPasswordParams.DbIdentifier = linkParams.Get(ParamName_DbIdentifier);
|
||||
requestPasswordParams.EmailAddress = linkParams.Get(ParamName_EmailAddress);
|
||||
requestPasswordParams.SecurityItemId = new SysId(StringUtil.ToInt(linkParams.Get(ParamName_SecurityItemId)));
|
||||
requestPasswordParams.AffiliateId = new SysId(StringUtil.ToInt(linkParams.Get(ParamName_AffiliateId)));
|
||||
|
||||
@@ -78,7 +78,7 @@ namespace Sarand.BusinessMgr.Net.Core.Web.Portal.Controllers
|
||||
String logSuffix = requestPasswordParams.GetValidParams().Concat("", " ", ".");
|
||||
// User may be defined on any one of the BusinessMgr databases - need to find out which.
|
||||
// Identify session contexts with a BusMgr database that hosts the specified email address.
|
||||
List<ushort> sessionContextIdxs = SbmSessionContextHelper_Web.GetSessionContextIdxsForUsersBusMgrDatabase(requestPasswordParams.EmailAddress);
|
||||
List<ushort> sessionContextIdxs = SbmSessionContextHelper_Web.GetSessionContextIdxsForContextUserEmail(requestPasswordParams.DbIdentifier, requestPasswordParams.EmailAddress);
|
||||
foreach (ushort sessionContextIdx in sessionContextIdxs)
|
||||
{
|
||||
// Consoles and Managers must be associated with the specific context.
|
||||
|
||||
@@ -0,0 +1,272 @@
|
||||
using Sarand.BusinessMgr.Net.Core.Web.App;
|
||||
using Sarand.BusinessMgr.Net.Core.Web.Controllers;
|
||||
using Sarand.BusinessMgr.Net.Standard.Base.App;
|
||||
using Sarand.BusinessMgr.Net.Standard.Base.Bus;
|
||||
using Sarand.BusinessMgr.Net.Standard.Base.Helpers;
|
||||
using Sarand.Net.Standard.Base.App;
|
||||
using Sarand.Net.Standard.Base.Core;
|
||||
using Sarand.Net.Standard.Base.Helpers;
|
||||
using Sarand.Net.Standard.Base.Utils;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Sarand.BusinessMgr.Net.Core.Web.Portal.Models
|
||||
{
|
||||
//=======================================================================
|
||||
public class Model_Association : SbmModel_Portal
|
||||
{
|
||||
//-------------------------------------------------------------------
|
||||
// Construction.
|
||||
public Model_Association(SbmLocaliser localiser) :
|
||||
base(localiser)
|
||||
{
|
||||
AdditionalFiles_JS.Add("js/sbm-association.js");
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Filter properties.
|
||||
public class FilterData
|
||||
{
|
||||
public String AssociationSearch { get; set; }
|
||||
public String AssociationType { get; set; }
|
||||
}
|
||||
public FilterData Filter { get; } = new FilterData();
|
||||
public Sbm.AssociationType GetFilterAssociationType()
|
||||
{
|
||||
return (Sbm.AssociationType)Internals.AssociationTypeCodes.GetTypeForCode(Filter.AssociationType);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Association properties.
|
||||
public String AssociationId { get; set; }
|
||||
public String AssociationExists { get; set; }
|
||||
public String AffiliateIdOwner { get; set; }
|
||||
public String AffiliateIdTarget { get; set; }
|
||||
public String AssociationType { get; set; }
|
||||
public Sbm.AssociationType GetAssociationType()
|
||||
{
|
||||
return (Sbm.AssociationType)Internals.AssociationTypeCodes.GetTypeForCode(AssociationType);
|
||||
}
|
||||
public String AssociationCode { get; set; }
|
||||
public String AssociationReferenceExt { get; set; }
|
||||
public String AssociationLocation { get; set; }
|
||||
public String AssociationRole { get; set; }
|
||||
public String AssociationPhoneMain { get; set; }
|
||||
public String AssociationEmail { get; set; }
|
||||
public String AssociationGroup { get; set; }
|
||||
public String AssociationDescDetail { get; set; }
|
||||
public String AssociationNominalCodeDefault { get; set; }
|
||||
// Account.
|
||||
public String AssociationAccountManagerCode { get; set; }
|
||||
public String AssociationAccountHandlerCode { get; set; }
|
||||
public String AssociationAccountTypeCode { get; set; }
|
||||
public String AssociationAccountRatingCode { get; set; }
|
||||
// Contact.
|
||||
public String AssociationContactAreaCode { get; set; }
|
||||
public String AssociationContactHandlerCode { get; set; }
|
||||
public String AssociationContactMethodCode { get; set; }
|
||||
public String AssociationContactCallCycleCode { get; set; }
|
||||
public String AssociationCallsPerYear { get; set; }
|
||||
public String AssociationLastCallDate { get; set; }
|
||||
// Customer.
|
||||
public String AssociationCommodityIdSalesDefault { get; set; }
|
||||
public String AssociationOrderLeadTimeCode { get; set; }
|
||||
public String AssociationDeliveryTypeCode { get; set; }
|
||||
public String AssociationDeliveryMethodCode { get; set; }
|
||||
public String AssociationDeliveryCourierCode { get; set; }
|
||||
public String AssociationDeliveryBookInCode { get; set; }
|
||||
// Transactions.
|
||||
public String AssociationAmountTransMax { get; set; }
|
||||
public String AssociationAnnualSalesTarget { get; set; }
|
||||
public String AssociationCreditLimit { get; set; }
|
||||
public String AssociationAccountBalance { get; set; }
|
||||
public String AssociationDiscountType { get; set; }
|
||||
public Sbm.DiscountType GetAssociationDiscountType()
|
||||
{
|
||||
return Sbm.DiscountType.NoDiscount;
|
||||
}
|
||||
public String AssociationDiscountRate { get; set; }
|
||||
public String AssociationPriceSetId { get; set; }
|
||||
public String AssociationTaxCodeId { get; set; }
|
||||
public String AssociationPaymentTerms { get; set; }
|
||||
public String AssociationInvoiceDesc { get; set; }
|
||||
public String AssociationTerminatedDate { get; set; }
|
||||
// Common properties.
|
||||
public String AssociationNotes { get; set; }
|
||||
public String AssociationStatusCode { get; set; }
|
||||
public SaStatus AssociationStatus { get { return SacsSystem.GetStatusForCode(AssociationStatusCode); } }
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Validation.
|
||||
//-------------------------------------------------------------------
|
||||
// Association validation.
|
||||
public bool ValidateAssociationData(SbmController_Base.AjaxResponse_Data responseData)
|
||||
{
|
||||
//---------------------------------------------------------------
|
||||
|
||||
// Association Type.
|
||||
if (AssociationType != null)
|
||||
{
|
||||
if (StringUtil.IsEmpty(AssociationType))
|
||||
responseData.SetControlError(nameof(AssociationType), Localiser["msg.validation.mandatory.value"]);
|
||||
}
|
||||
|
||||
// Association Code.
|
||||
if (AssociationCode != null)
|
||||
{
|
||||
responseData.SetControlValue(nameof(AssociationCode), AssociationCode);
|
||||
if (StringUtil.IsEmpty(AssociationCode))
|
||||
responseData.SetControlError(nameof(AssociationCode), Localiser["msg.validation.mandatory.value"]);
|
||||
if (StringUtil.GetLength(AssociationCode) > GetControlMaxLength(SbmDbDfn.ColumnIdx.Association_Code))
|
||||
responseData.SetControlError(nameof(AssociationCode), Localiser["msg.validation.maximum.length", GetControlMaxLength(SbmDbDfn.ColumnIdx.Association_Code)]);
|
||||
}
|
||||
|
||||
// Association External Reference.
|
||||
if (AssociationReferenceExt != null)
|
||||
{
|
||||
responseData.SetControlValue(nameof(AssociationReferenceExt), AssociationReferenceExt);
|
||||
if (StringUtil.GetLength(AssociationReferenceExt) > GetControlMaxLength(SbmDbDfn.ColumnIdx.Association_ExtRef))
|
||||
responseData.SetControlError(nameof(AssociationReferenceExt), Localiser["msg.validation.maximum.length", GetControlMaxLength(SbmDbDfn.ColumnIdx.Association_ExtRef)]);
|
||||
}
|
||||
|
||||
// Association Location.
|
||||
if (AssociationLocation != null)
|
||||
{
|
||||
responseData.SetControlValue(nameof(AssociationLocation), AssociationLocation);
|
||||
if (StringUtil.GetLength(AssociationLocation) > GetControlMaxLength(SbmDbDfn.ColumnIdx.Association_Location))
|
||||
responseData.SetControlError(nameof(AssociationLocation), Localiser["msg.validation.maximum.length", GetControlMaxLength(SbmDbDfn.ColumnIdx.Association_Location)]);
|
||||
}
|
||||
|
||||
// Association Role.
|
||||
if (AssociationRole != null)
|
||||
{
|
||||
responseData.SetControlValue(nameof(AssociationRole), AssociationRole);
|
||||
if (StringUtil.GetLength(AssociationRole) > GetControlMaxLength(SbmDbDfn.ColumnIdx.Association_Role))
|
||||
responseData.SetControlError(nameof(AssociationRole), Localiser["msg.validation.maximum.length", GetControlMaxLength(SbmDbDfn.ColumnIdx.Association_Role)]);
|
||||
}
|
||||
|
||||
// Association Phone Main.
|
||||
if (AssociationPhoneMain != null)
|
||||
{
|
||||
responseData.SetControlValue(nameof(AssociationPhoneMain), AssociationPhoneMain);
|
||||
if (StringUtil.GetLength(AssociationPhoneMain) > GetControlMaxLength(SbmDbDfn.ColumnIdx.Association_PhoneMain))
|
||||
responseData.SetControlError(nameof(AssociationPhoneMain), Localiser["msg.validation.maximum.length", GetControlMaxLength(SbmDbDfn.ColumnIdx.Association_PhoneMain)]);
|
||||
}
|
||||
|
||||
// Association Email.
|
||||
if (AssociationEmail != null)
|
||||
{
|
||||
responseData.SetControlValue(nameof(AssociationEmail), AssociationEmail);
|
||||
if (StringUtil.GetLength(AssociationEmail) > GetControlMaxLength(SbmDbDfn.ColumnIdx.Association_Email))
|
||||
responseData.SetControlError(nameof(AssociationEmail), Localiser["msg.validation.maximum.length", GetControlMaxLength(SbmDbDfn.ColumnIdx.Association_Email)]);
|
||||
}
|
||||
|
||||
// Association Group.
|
||||
if (AssociationGroup != null)
|
||||
{
|
||||
responseData.SetControlValue(nameof(AssociationGroup), AssociationGroup);
|
||||
if (StringUtil.GetLength(AssociationGroup) > GetControlMaxLength(SbmDbDfn.ColumnIdx.Association_Group))
|
||||
responseData.SetControlError(nameof(AssociationGroup), Localiser["msg.validation.maximum.length", GetControlMaxLength(SbmDbDfn.ColumnIdx.Association_Group)]);
|
||||
}
|
||||
|
||||
// Association Description.
|
||||
if (AssociationDescDetail != null)
|
||||
{
|
||||
responseData.SetControlValue(nameof(AssociationDescDetail), AssociationDescDetail);
|
||||
if (StringUtil.IsEmpty(AssociationDescDetail))
|
||||
responseData.SetControlError(nameof(AssociationDescDetail), Localiser["msg.validation.mandatory.value"]);
|
||||
if (StringUtil.GetLength(AssociationDescDetail) > GetControlMaxLength(SbmDbDfn.ColumnIdx.Association_DescDetail))
|
||||
responseData.SetControlError(nameof(AssociationDescDetail), Localiser["msg.validation.maximum.length", GetControlMaxLength(SbmDbDfn.ColumnIdx.Association_DescDetail)]);
|
||||
}
|
||||
|
||||
// Association Default Nominal Code.
|
||||
if (AssociationNominalCodeDefault != null)
|
||||
{
|
||||
responseData.SetControlValue(nameof(AssociationNominalCodeDefault), AssociationNominalCodeDefault);
|
||||
if (StringUtil.GetLength(AssociationNominalCodeDefault) > GetControlMaxLength(SbmDbDfn.ColumnIdx.Association_DefaultNominalCode))
|
||||
responseData.SetControlError(nameof(AssociationNominalCodeDefault), Localiser["msg.validation.maximum.length", GetControlMaxLength(SbmDbDfn.ColumnIdx.Association_DefaultNominalCode)]);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------
|
||||
// Account.
|
||||
|
||||
// Account Manager code - AssociationAccountManagerCode
|
||||
|
||||
// Account Handler code - AssociationAccountHandlerCode
|
||||
|
||||
// Account Type code - AssociationAccountTypeCode
|
||||
|
||||
// Account Rating code - AssociationAccountRatingCode
|
||||
|
||||
//---------------------------------------------------------------
|
||||
// Contact.
|
||||
|
||||
// Contact Area code - AssociationContactAreaCode
|
||||
|
||||
// Contact Handler code - AssociationContactHandlerCode
|
||||
|
||||
// Contact Method code - AssociationContactMethodCode
|
||||
|
||||
// Contact Call Cycle code - AssociationContactCallCycleCode
|
||||
|
||||
// Calls per year - AssociationCallsPerYear
|
||||
|
||||
// Last Call date - AssociationLastCallDate
|
||||
|
||||
//---------------------------------------------------------------
|
||||
// Customer.
|
||||
|
||||
// AssociationCommodityIdSalesDefault
|
||||
// AssociationOrderLeadTimeCode
|
||||
// AssociationDeliveryTypeCode
|
||||
// AssociationDeliveryMethodCode
|
||||
// AssociationDeliveryCourierCode
|
||||
// AssociationDeliveryBookInCode
|
||||
|
||||
//---------------------------------------------------------------
|
||||
// Transactions.
|
||||
|
||||
// AssociationAmountTransMax
|
||||
// AssociationAnnualSalesTarget
|
||||
// AssociationCreditLimit
|
||||
// AssociationAccountBalance
|
||||
// AssociationDiscountType
|
||||
// AssociationDiscountRate
|
||||
// AssociationPriceSetId
|
||||
// AssociationTaxCodeId
|
||||
// AssociationPaymentTerms
|
||||
// AssociationInvoiceDesc
|
||||
// AssociationTerminatedDate
|
||||
// AssociationAssociation
|
||||
|
||||
//---------------------------------------------------------------
|
||||
// Common properties.
|
||||
|
||||
// Association Notes.
|
||||
if (AssociationNotes != null)
|
||||
{
|
||||
responseData.SetControlValue(nameof(AssociationNotes), AssociationNotes);
|
||||
if (!StringUtil.IsEmpty(AssociationNotes) && StringUtil.GetLength(AssociationNotes) > GetControlMaxLength(SbmDbDfn.ColumnIdx.Association_Notes))
|
||||
responseData.SetControlError(nameof(AssociationNotes), Localiser["msg.validation.maximum.length", GetControlMaxLength(SbmDbDfn.ColumnIdx.Association_Notes)]);
|
||||
}
|
||||
|
||||
// Association status.
|
||||
if (AssociationStatusCode != null)
|
||||
{
|
||||
if (StringUtil.IsEmpty(AssociationStatusCode))
|
||||
responseData.SetControlError(nameof(AssociationStatusCode), Localiser["msg.validation.mandatory.value"]);
|
||||
else if (!SbmAssociation.ValidStatuses.Contains(AssociationStatus))
|
||||
responseData.SetControlError(nameof(AssociationStatusCode), Localiser["msg.validation.invalid.value"]);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------
|
||||
|
||||
return !responseData.HasControlErrors();
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
}
|
||||
//=======================================================================
|
||||
}
|
||||
@@ -30,6 +30,8 @@ namespace Sarand.BusinessMgr.Net.Core.Web.Portal.Models
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Form properties.
|
||||
/// <summary>Database config identifier.</summary>
|
||||
public String DbIdentifier { get; set; }
|
||||
public String EmailAddress { get; set; }
|
||||
public String PasswordCurrent { get; set; }
|
||||
public String Password { get; set; }
|
||||
@@ -44,17 +46,31 @@ namespace Sarand.BusinessMgr.Net.Core.Web.Portal.Models
|
||||
// Sign-in.
|
||||
public bool ValidateSignInData(SbmController_Base.AjaxResponse_Data responseData)
|
||||
{
|
||||
// Email address.
|
||||
responseData.SetControlValue(nameof(EmailAddress), EmailAddress);
|
||||
if (StringUtil.IsEmpty(EmailAddress))
|
||||
responseData.SetControlError(nameof(EmailAddress), Localiser["msg.validation.mandatory.value"]);
|
||||
else if (!SacsDataValidationHelper.IsValidEmailAddress(EmailAddress))
|
||||
responseData.SetControlError(nameof(EmailAddress), Localiser["msg.validation.invalid.value"]);
|
||||
{
|
||||
// Database context.
|
||||
String controlName = nameof(DbIdentifier);
|
||||
responseData.SetControlValue(controlName, DbIdentifier);
|
||||
if (StringUtil.IsEmpty(DbIdentifier))
|
||||
responseData.SetControlError(controlName, Localiser["msg.validation.mandatory.value"]);
|
||||
}
|
||||
|
||||
// Password.
|
||||
// NB Do not return the password value in the response.
|
||||
if (StringUtil.IsEmpty(Password))
|
||||
responseData.SetControlError(nameof(Password), Localiser["msg.validation.mandatory.value"]);
|
||||
{
|
||||
// Email address.
|
||||
String controlName = nameof(EmailAddress);
|
||||
responseData.SetControlValue(controlName, EmailAddress);
|
||||
if (StringUtil.IsEmpty(EmailAddress))
|
||||
responseData.SetControlError(controlName, Localiser["msg.validation.mandatory.value"]);
|
||||
else if (!SacsDataValidationHelper.IsValidEmailAddress(EmailAddress))
|
||||
responseData.SetControlError(controlName, Localiser["msg.validation.invalid.value"]);
|
||||
}
|
||||
|
||||
{
|
||||
// Password.
|
||||
// NB Do not return the password value in the response.
|
||||
String controlName = nameof(Password);
|
||||
if (StringUtil.IsEmpty(Password))
|
||||
responseData.SetControlError(controlName, Localiser["msg.validation.mandatory.value"]);
|
||||
}
|
||||
|
||||
return !responseData.HasControlErrors();
|
||||
}
|
||||
@@ -96,12 +112,23 @@ namespace Sarand.BusinessMgr.Net.Core.Web.Portal.Models
|
||||
// Request Password.
|
||||
public bool ValidateRequestPasswordData(SbmController_Base.AjaxResponse_Data responseData)
|
||||
{
|
||||
// Email address.
|
||||
responseData.SetControlValue(nameof(EmailAddress), EmailAddress);
|
||||
if (StringUtil.IsEmpty(EmailAddress))
|
||||
responseData.SetControlError(nameof(EmailAddress), Localiser["msg.validation.mandatory.value"]);
|
||||
else if (!SacsDataValidationHelper.IsValidEmailAddress(EmailAddress))
|
||||
responseData.SetControlError(nameof(EmailAddress), Localiser["msg.validation.invalid.value"]);
|
||||
{
|
||||
// Database context.
|
||||
String controlName = nameof(DbIdentifier);
|
||||
responseData.SetControlValue(controlName, DbIdentifier);
|
||||
if (StringUtil.IsEmpty(DbIdentifier))
|
||||
responseData.SetControlError(controlName, Localiser["msg.validation.mandatory.value"]);
|
||||
}
|
||||
|
||||
{
|
||||
// Email address.
|
||||
String controlName = nameof(EmailAddress);
|
||||
responseData.SetControlValue(controlName, EmailAddress);
|
||||
if (StringUtil.IsEmpty(EmailAddress))
|
||||
responseData.SetControlError(controlName, Localiser["msg.validation.mandatory.value"]);
|
||||
else if (!SacsDataValidationHelper.IsValidEmailAddress(EmailAddress))
|
||||
responseData.SetControlError(controlName, Localiser["msg.validation.invalid.value"]);
|
||||
}
|
||||
|
||||
return !responseData.HasControlErrors();
|
||||
}
|
||||
|
||||
@@ -1,44 +1,43 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netcoreapp3.1</TargetFramework>
|
||||
<CopyRefAssembliesToPublishDirectory>false</CopyRefAssembliesToPublishDirectory>
|
||||
<RootNamespace>Sarand.BusinessMgr.Net.Core.Web</RootNamespace>
|
||||
<AssemblyName>Sarand.BusinessMgr.Net.Core.Web</AssemblyName>
|
||||
<Description>SaBusinessMgrCoreWebPortal</Description>
|
||||
<PackageId>SaBusinessMgrCoreWebPortal</PackageId>
|
||||
<Authors>Sarand</Authors>
|
||||
<Product>BusinessMgr</Product>
|
||||
<Version>3.0.0</Version>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<CopyRefAssembliesToPublishDirectory>false</CopyRefAssembliesToPublishDirectory>
|
||||
<RootNamespace>Sarand.BusinessMgr.Net.Core.Web</RootNamespace>
|
||||
<AssemblyName>Sarand.BusinessMgr.Net.Core.Web</AssemblyName>
|
||||
<Description>SaBusinessMgrCoreWebPortal</Description>
|
||||
<PackageId>SaBusinessMgrCoreWebPortal</PackageId>
|
||||
<Authors>Sarand</Authors>
|
||||
<Product>BusinessMgr</Product>
|
||||
<Version>3.0.0</Version>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="jQuery.UI.Combined" Version="1.12.1" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation" Version="3.1.16" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="jQuery.UI.Combined" Version="1.13.2" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation" Version="6.0.31" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\..\Common-VS\Workspace\SacsCoreWeb\SacsCoreWeb.csproj" />
|
||||
<ProjectReference Include="..\..\..\Common-VS\Workspace\SacsStandardBase\SacsStandardBase.csproj" />
|
||||
<ProjectReference Include="..\..\..\Common-VS\Workspace\SacsStandardDbas\SacsStandardDbas.csproj" />
|
||||
<ProjectReference Include="..\..\..\Common-VS\Workspace\SacsStandardProc\SacsStandardProc.csproj" />
|
||||
<ProjectReference Include="..\SaBusMgrCoreProcs\SaBusMgrCoreProcs.csproj" />
|
||||
<ProjectReference Include="..\SaBusMgrCoreWeb\SaBusMgrCoreWeb.csproj" />
|
||||
<ProjectReference Include="..\SaBusMgrStandardBase\SaBusMgrStandardBase.csproj" />
|
||||
<ProjectReference Include="..\SaBusMgrStandardDbas\SaBusMgrStandardDbas.csproj" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\..\Common-VS\Workspace\SacsCoreWeb\SacsCoreWeb.csproj" />
|
||||
<ProjectReference Include="..\..\..\Common-VS\Workspace\SacsStandardBase\SacsStandardBase.csproj" />
|
||||
<ProjectReference Include="..\..\..\Common-VS\Workspace\SacsStandardDbas\SacsStandardDbas.csproj" />
|
||||
<ProjectReference Include="..\..\..\Common-VS\Workspace\SacsStandardProc\SacsStandardProc.csproj" />
|
||||
<ProjectReference Include="..\SaBusMgrCoreProcs\SaBusMgrCoreProcs.csproj" />
|
||||
<ProjectReference Include="..\SaBusMgrCoreWeb\SaBusMgrCoreWeb.csproj" />
|
||||
<ProjectReference Include="..\SaBusMgrStandardBase\SaBusMgrStandardBase.csproj" />
|
||||
<ProjectReference Include="..\SaBusMgrStandardDbas\SaBusMgrStandardDbas.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Content Update="appsettings.Machine.Sarand107.json">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
<ExcludeFromSingleFile>true</ExcludeFromSingleFile>
|
||||
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
|
||||
</Content>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Update="appsettings.Machine.Sarand110.json">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
<ExcludeFromSingleFile>true</ExcludeFromSingleFile>
|
||||
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
|
||||
</Content>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Folder Include="Views\Association\" />
|
||||
<Folder Include="Views\Transactions\" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Folder Include="Views\Transactions\" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
||||
@@ -0,0 +1,135 @@
|
||||
@model Model_Association
|
||||
@inject SbmLocaliser Localiser
|
||||
@{
|
||||
/* Associations - Index */
|
||||
ViewData["Title"] = "Associations";
|
||||
}
|
||||
|
||||
<div class="sbm-panel Associations">
|
||||
|
||||
<script type="text/javascript">
|
||||
sbm.lbl.refresh = '@(Localiser.GetJavascriptText("label.refresh"))';
|
||||
sbm.lbl.create = '@(Localiser.GetJavascriptText("label.create"))';
|
||||
sbm.lbl.edit = '@(Localiser.GetJavascriptText("label.edit"))';
|
||||
</script>
|
||||
|
||||
<div class="row">
|
||||
|
||||
<div class="col-md-5 row">
|
||||
|
||||
<div class="col">
|
||||
|
||||
@* Filter Panel *@
|
||||
@using (@Html.BeginForm(FormMethod.Post, new { @id = "frmAssociationFilter", @class = "sbm-form", @onSubmit = "return false;" }))
|
||||
{
|
||||
<div class="sbm-panel-filter">
|
||||
@* Header - Page caption, paging controls, actions. *@
|
||||
<div class="sbm-header">
|
||||
<div class="row">
|
||||
<div class="col"><div class="sbm-caption">@Localiser["association.caption.associations"]</div></div>
|
||||
<div class="fixed row">
|
||||
<div class="col">
|
||||
<partial name="~/Views/Common/ResultsPaging.cshtml" />
|
||||
</div>
|
||||
<div class="fixed row">
|
||||
@* Burger menu *@
|
||||
<ul class="nav navbar-nav navbar-dark navbar-right sbm-burger">
|
||||
<li class="dropdown-toggle caret-off">
|
||||
<a href="#" class="dropdown" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false"><span class="navbar-toggler-icon"></span></a>
|
||||
<ul class="dropdown-menu dropdown-menu-right sbm-dropdown-menu">@* Menu items will be inserted here. *@</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sbm-content">
|
||||
@* Association filter - name etc. *@
|
||||
<div class="row pb4">
|
||||
<div class="col-sm-5 sbm-label text-left text-sm-right">@Localiser["label.search"]</div>
|
||||
<div class="col-sm-7">
|
||||
@Html.TextBoxFor(model => model.Filter.AssociationSearch, new { @id = "", @class = "FilterAssociation", @maxlength = "32" })
|
||||
</div>
|
||||
</div>
|
||||
@* Association Category *@
|
||||
<div class="row pb4">
|
||||
<div class="col-sm-5 sbm-label text-left text-sm-right">@Localiser["label.type"]</div>
|
||||
<div class="col-sm-7">
|
||||
@Html.DropDownListFor(model => model.Filter.AssociationType, Model.GetAssociationTypeCodesForSelect(), Localiser["label.any"], new { @id = "", @class = "FilterAssociationType sbm-select" })
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@* Filter element templates *@
|
||||
<div class="sbm-panel-item-template">
|
||||
@* Burger dropdown item template - ul is ignored *@
|
||||
<ul class="sbm-dropdown-menu AssociationFilter">
|
||||
<li class="sbm-dropdown-item sbm-action"><div class="sbm-label">XXX</div></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
}
|
||||
|
||||
</div>
|
||||
|
||||
@* Separate filter from results when alondside each other. *@
|
||||
<div class="fixed"><div class="d-none d-md-block" style="width:8px;"></div></div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="col-md-7">
|
||||
|
||||
@* Results Panel *@
|
||||
<div class="sbm-panel-results">
|
||||
<div class="sbm-panel-messages"></div>
|
||||
<div class="sbm-panel-item-list"></div>
|
||||
|
||||
@* Element templates *@
|
||||
<div class="sbm-panel-item-template">
|
||||
|
||||
@* Association item template *@
|
||||
<div class="sbm-panel-item Association">
|
||||
<div class="sbm-header row">
|
||||
<div class="col">
|
||||
@* Association caption *@
|
||||
<div class="sbm-caption"><div class="sbm-action sbm-item-update"><span class="AssociationCode"></span> - <span class="AssociationTargetName"></span></div></div>
|
||||
</div>
|
||||
<div class="fixed sbm-actions">
|
||||
@* Burger menu *@
|
||||
<ul class="nav navbar-nav navbar-light navbar-right sbm-burger">
|
||||
<li class="dropdown-toggle caret-off">
|
||||
<a href="#" class="dropdown" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false"><span class="navbar-toggler-icon"></span></a>
|
||||
<ul class="dropdown-menu dropdown-menu-right sbm-dropdown-menu">@* Menu items will be inserted here. *@</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sbm-content">
|
||||
<div class="row">
|
||||
<div class="col-sm-4"><div class="AssociationType"></div></div>
|
||||
<div class="col-sm-4"><div class="AssociationAssociationCount sbm-action-text">@Localiser["label.associations"]: <span class="AssociationCount"></span></div></div>
|
||||
<div class="col-sm-4 text-left text-sm-right"><div class="StatusDesc"></div></div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class=""><div class="AssociationAddress"></div></div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class=""><div class="AssociationNotes sbm-note"></div></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@* Burger dropdown item template - ul is ignored *@
|
||||
<ul class="sbm-dropdown-menu Association">
|
||||
<li class="sbm-dropdown-item sbm-action"><div class="sbm-label">XXX</div></li>
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<partial name="Panel-AssociationDialog.cshtml" />
|
||||
@@ -0,0 +1,81 @@
|
||||
@model Model_Association
|
||||
@inject SbmLocaliser Localiser
|
||||
@{
|
||||
/* Associations - Association dialog panel */
|
||||
}
|
||||
|
||||
<script type="text/javascript">
|
||||
sbm.dlg.title.createAssociation = '@Localiser.GetJavascriptText("association.caption.association.create")';
|
||||
sbm.dlg.title.updateAssociation = '@Localiser.GetJavascriptText("association.caption.association.update")';
|
||||
</script>
|
||||
|
||||
@using (@Html.BeginForm(FormMethod.Post, new { @id = "frmAssociationId", @class = "sbm-form" }))
|
||||
{
|
||||
@Html.HiddenFor(model => model.AssociationId, new { @class = "AssociationId" })
|
||||
}
|
||||
|
||||
<div id="dlgAssociation" class="sbm-dialog" title="">
|
||||
|
||||
@using (@Html.BeginForm(FormMethod.Post, new { @id = "frmAssociation", @class = "sbm-form", @onSubmit = "return false;" }))
|
||||
{
|
||||
@Html.HiddenFor(model => model.AssociationId, new { @id = "", @class = "AssociationId" })
|
||||
@Html.HiddenFor(model => model.AssociationExists, new { @id = "", @class = "AssociationExists" });
|
||||
|
||||
@* Association Type *@
|
||||
<div class="sbm-form-control AssociationType">
|
||||
<div class="sbm-label">
|
||||
<label for="cbAssociationType"><span>@Localiser["label.type"]</span><span class="required"> *</span></label>
|
||||
</div>
|
||||
<div class="sbm-control">
|
||||
@Html.DropDownListFor(model => model.AssociationType, Model.GetAssociationTypeCodesForSelect(), Localiser["label.select"], new { @id = "cbAssociationType", @class = "AssociationType sbm-select" })
|
||||
</div>
|
||||
<div class="sbm-message"></div>
|
||||
</div>
|
||||
|
||||
@* Association Code *@
|
||||
<div class="sbm-form-control AssociationCode">
|
||||
<div class="sbm-label">
|
||||
<label for="ifAssociationCode"><span>@Localiser["label.code"]</span><span class="required"> *</span></label>
|
||||
</div>
|
||||
<div class="sbm-control">
|
||||
@Html.TextBoxFor(model => model.AssociationCode, new { @id = "ifAssociationCode", @class = "AssociationCode sbm-input", @maxlength = @Model.GetControlMaxLength(SbmDbDfn.ColumnIdx.Association_Code) })
|
||||
</div>
|
||||
<div class="sbm-message"></div>
|
||||
</div>
|
||||
|
||||
@* Association Description *@
|
||||
<div class="sbm-form-control AssociationDesc">
|
||||
<div class="sbm-label">
|
||||
<label for="ifAssociationDescDetail"><span>@Localiser["label.description"]</span><span class="required"> *</span></label>
|
||||
</div>
|
||||
<div class="sbm-control">
|
||||
@Html.TextBoxFor(model => model.AssociationDescDetail, new { @id = "ifAssociationDescDetail", @class = "AssociationDescDetail sbm-input", @maxlength = @Model.GetControlMaxLength(SbmDbDfn.ColumnIdx.Association_DescDetail) })
|
||||
</div>
|
||||
<div class="sbm-message"></div>
|
||||
</div>
|
||||
|
||||
@* Association status *@
|
||||
<div class="sbm-form-control AssociationStatus">
|
||||
<div class="sbm-label">
|
||||
<label for="cbAssociationStatus"><span>@Localiser["label.status"]</span><span class="required"> *</span></label>
|
||||
</div>
|
||||
<div class="sbm-control">
|
||||
<select id="cbAssociationStatus" class="sbm-select AssociationStatus" name="AssociationStatusCode"></select>
|
||||
</div>
|
||||
<div class="sbm-message"></div>
|
||||
</div>
|
||||
|
||||
@* Association Notes *@
|
||||
<div class="sbm-form-control AssociationNotes">
|
||||
<div class="sbm-label">
|
||||
<label for="ifAssociationNotes"><span>@Localiser["label.notes"]</span></label>
|
||||
</div>
|
||||
<div class="sbm-control">
|
||||
@Html.TextAreaFor(model => model.AssociationNotes, new { @id = "ifAssociationNotes", @class = "AssociationNotes sbm-textarea", @rows = "3", @maxlength = @Model.GetControlMaxLength(SbmDbDfn.ColumnIdx.Association_Notes) })
|
||||
</div>
|
||||
<div class="sbm-message"></div>
|
||||
</div>
|
||||
|
||||
}
|
||||
|
||||
</div>
|
||||
@@ -85,8 +85,9 @@
|
||||
<div class="sbm-panel-messages"></div>
|
||||
<div class="sbm-panel-item-list"></div>
|
||||
|
||||
@* element templates *@
|
||||
@* Element templates *@
|
||||
<div class="sbm-panel-item-template">
|
||||
|
||||
@* Commodity item template *@
|
||||
<div class="sbm-panel-item Commodity">
|
||||
<div class="sbm-header row">
|
||||
@@ -118,10 +119,12 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@* Burger dropdown item template - ul is ignored *@
|
||||
<ul class="sbm-dropdown-menu Commodity">
|
||||
<li class="sbm-dropdown-item sbm-action"><div class="sbm-label">XXX</div></li>
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -14,6 +14,17 @@
|
||||
@using (@Html.BeginForm(FormMethod.Post, new { @id = "frmRequestPassword", @class = "sbm-form" }))
|
||||
{
|
||||
|
||||
<div class="spacer4"></div>
|
||||
<div class="sbm-form-control DbIdentifier">
|
||||
<div class="sbm-label">
|
||||
<label for="ifEmailAddress"><span>@Localiser["label.context"]</span><span class="required"> *</span></label>
|
||||
</div>
|
||||
<div class="sbm-control">
|
||||
@Html.TextBoxFor(model => model.DbIdentifier, new { @id = "ifDbIdentifier", @class = "sbm-input", @maxlength = @Sbm.Config.Database.Identifier.MaxLength })
|
||||
</div>
|
||||
<div class="sbm-message"></div>
|
||||
</div>
|
||||
|
||||
<div class="spacer4"></div>
|
||||
<div class="sbm-form-control EmailAddress">
|
||||
<div class="sbm-label">
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
@inject SbmLocaliser Localiser
|
||||
@{
|
||||
ViewData["Title"] = "Signin";
|
||||
ulong emailAddressLen = SaSecurityDbDfn.GetColTextLen(SaSecurityDbDfn.ColumnIdx.SaSecItem_EmailAddress);
|
||||
}
|
||||
|
||||
<div class="">
|
||||
@@ -12,23 +11,34 @@
|
||||
|
||||
<div class="sbm-header"><div class="sbm-caption">@Localiser["label.signin"]</div></div>
|
||||
|
||||
<div class="sbm-content">
|
||||
<div class="sbm-content" style="max-height:none;">
|
||||
|
||||
@using (@Html.BeginForm(FormMethod.Post, new { @id = "frmSignIn", @class = "sbm-form" }))
|
||||
{
|
||||
|
||||
<div class="spacer4"></div>
|
||||
<div class="sbm-form-control DbIdentifier">
|
||||
<div class="sbm-label">
|
||||
<label for="ifEmailAddress"><span>@Localiser["label.context"]</span><span class="required"> *</span></label>
|
||||
</div>
|
||||
<div class="sbm-control">
|
||||
@Html.TextBoxFor(model => model.DbIdentifier, new { @id = "ifDbIdentifier", @class = "sbm-input", @maxlength = @Sbm.Config.Database.Identifier.MaxLength })
|
||||
</div>
|
||||
<div class="sbm-message"></div>
|
||||
</div>
|
||||
|
||||
<div class="spacer2"></div>
|
||||
<div class="sbm-form-control EmailAddress">
|
||||
<div class="sbm-label">
|
||||
<label for="ifEmailAddress"><span>@Localiser["label.email"]</span><span class="required"> *</span></label>
|
||||
</div>
|
||||
<div class="sbm-control">
|
||||
@Html.TextBoxFor(model => model.EmailAddress, new { @id = "ifEmailAddress", @class = "sbm-input lower", @maxlength = @emailAddressLen })
|
||||
@Html.TextBoxFor(model => model.EmailAddress, new { @id = "ifEmailAddress", @class = "sbm-input lower", @maxlength = @Model.GetControlMaxLength(SaSecurityDbDfn.ColumnIdx.SaSecItem_EmailAddress) })
|
||||
</div>
|
||||
<div class="sbm-message"></div>
|
||||
</div>
|
||||
|
||||
<div class="spacer4"></div>
|
||||
<div class="spacer2"></div>
|
||||
<div class="sbm-form-control Password">
|
||||
<div class="row">
|
||||
<div class="col-6">
|
||||
@@ -43,7 +53,7 @@
|
||||
<div class="sbm-message"></div>
|
||||
</div>
|
||||
|
||||
<div class="spacer4"></div>
|
||||
<div class="spacer2"></div>
|
||||
<div class="sbm-form-control">
|
||||
<div class="row">
|
||||
<div class="col-6">
|
||||
|
||||
@@ -122,6 +122,7 @@
|
||||
<div class="dropdown-menu" aria-labelledby="navbarDropdown">
|
||||
<div class="dropdown-item text-dark sbm-action" onclick="sbm.goToPage('Contact');">@Localiser["label.contacts"]</div>
|
||||
<div class="dropdown-item text-dark sbm-action" onclick="sbm.goToPage('Commodity');">@Localiser["label.commodities"]</div>
|
||||
<div class="dropdown-item text-dark sbm-action" onclick="sbm.goToPage('Association');">@Localiser["label.associations"]</div>
|
||||
</div>
|
||||
</li>
|
||||
<li class="nav-item dropdown">
|
||||
@@ -151,7 +152,7 @@
|
||||
@* Footer *@
|
||||
<footer id="sbm-page-footer" class="">
|
||||
<div class="container">
|
||||
© 2021 - Sarand BusinessMgr Portal
|
||||
@(Model.CopyrightNotice) - Sarand BusinessMgr Portal
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
@using Sarand.BusinessMgr.Net.Standard.Base.App
|
||||
@using Sarand.BusinessMgr.Net.Core.Web.App
|
||||
@using Sarand.BusinessMgr.Net.Core.Web.App
|
||||
@using Sarand.BusinessMgr.Net.Standard.Base.App
|
||||
@using Sarand.BusinessMgr.Net.Core.Web.Portal.Models
|
||||
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
|
||||
|
||||
@@ -1,30 +0,0 @@
|
||||
{
|
||||
"AppConfigs": {
|
||||
"SaBusMgr-Dev": {
|
||||
"Environments": [ "Development" ],
|
||||
"Instance": "Dev",
|
||||
"ControlDatabase": {
|
||||
"Location": "MsSql:Sarand107\\SQL2016.SaBusinessMgr_Control",
|
||||
"User": "SaBusMgr-Control",
|
||||
"Password": "sbm-c0Ntrul-dev-2021"
|
||||
},
|
||||
"BusMgrDatabase": {
|
||||
"Location": "MsSql:Sarand107\\SQL2016.SaBusinessMgr_Cadix",
|
||||
"User": "SaBusMgr-Cadix",
|
||||
"Password": "sbm-cul-dev-2021"
|
||||
},
|
||||
"Email": {
|
||||
"Context": "SBM-Dev",
|
||||
"ContactUs": {
|
||||
"AddressesTo": [ "dev@SaBusinessMgr.com" ]
|
||||
}
|
||||
},
|
||||
"Documents": {
|
||||
"RootFolder": "D:\\Sarand\\Projects\\Users\\AHoward\\VS2019\\BusinessMgr\\Docs"
|
||||
},
|
||||
"Logging": {
|
||||
"RootFolder": "D:\\Sarand\\Projects\\Users\\AHoward\\VS2019\\BusinessMgr\\Logs\\WebPortal"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
{
|
||||
"AppConfigs": {
|
||||
"SaBusMgr-Dev": {
|
||||
"Environments": [ "Development" ],
|
||||
"Instance": "Dev",
|
||||
"ControlDatabase": {
|
||||
"Location": "MsSql:Roman\\SQL2016.SaBusinessMgr_Control",
|
||||
"User": "sapphire",
|
||||
"Password": "sarand"
|
||||
},
|
||||
"BusMgrDatabases": [
|
||||
{
|
||||
"Identifiers": [ "Sarand" ],
|
||||
"Location": "MsSql:Roman\\SQL2016.SaBusinessMgr_Sarand_Dev",
|
||||
"User": "sapphire",
|
||||
"Password": "sarand"
|
||||
},
|
||||
{
|
||||
"Identifiers": [ "Cadix" ],
|
||||
"Location": "MsSql:Roman\\SQL2016.SaBusinessMgr_Cadix",
|
||||
"User": "sapphire",
|
||||
"Password": "sarand"
|
||||
},
|
||||
{
|
||||
"Identifiers": [ "BPE" ],
|
||||
"Location": "MsSql:Roman\\SQL2016.SaBusinessMgr_BPE",
|
||||
"User": "sapphire",
|
||||
"Password": "sarand"
|
||||
}
|
||||
],
|
||||
"Email": {
|
||||
"Context": "SBM-Dev",
|
||||
"ContactUs": {
|
||||
"AddressesTo": [ "dev@SaBusinessMgr.com" ]
|
||||
}
|
||||
},
|
||||
"Documents": {
|
||||
"RootFolder": "D:\\Sarand\\Projects\\Users\\AHoward\\VS2022\\BusinessMgr\\Docs"
|
||||
},
|
||||
"Logging": {
|
||||
"RootFolder": "D:\\Sarand\\Projects\\Users\\AHoward\\VS2022\\BusinessMgr\\Logs\\WebPortal"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,189 @@
|
||||
/*
|
||||
* Association page scripts.
|
||||
*/
|
||||
|
||||
(function (win, doc, undef)
|
||||
{
|
||||
"use strict";
|
||||
sbm.itemIdPrefix = 'Itm_';
|
||||
let $pnl = sbm.$pnl;
|
||||
let $frm = sbm.$frm;
|
||||
let $dlg = sbm.$dlg;
|
||||
|
||||
//--------------------------------------------------------------
|
||||
sbm.refreshResults = function (delay)
|
||||
{
|
||||
if (!sbm.awaitingRefreshResponse)
|
||||
{
|
||||
$('.sbm-burger', $pnl.filter).hide();
|
||||
$('.sbm-panel-item-list', $pnl.results).fadeOut(200).empty();
|
||||
$('.sbm-panel-messages', $pnl.results).hide().empty().append($('<div class="sbm-message">' + sbm.msg.dataQuerying + '</div>')).fadeIn(200);
|
||||
}
|
||||
sbm.ajax.refreshResults = sbm.ajax.refreshResults || { url: sbm.url.base + 'Association/Ajax/List', formId: 'frmAssociationFilter', callbackFn: sbm.doRefreshResults };
|
||||
sbm.doAjaxRequest(sbm.ajax.refreshResults, delay || 50);
|
||||
sbm.awaitingRefreshResponse = true;
|
||||
}
|
||||
sbm.doRefreshResults = function (response)
|
||||
{
|
||||
//sbm.debug('doRefreshResults', response);
|
||||
delete sbm.awaitingRefreshResponse;
|
||||
sbm.refreshControlValues(response.controlValues);
|
||||
var $msgs = $('.sbm-panel-messages', $pnl.results).hide().empty();
|
||||
var $items = $('.sbm-panel-item-list', $pnl.results).hide().empty();
|
||||
sbm.refreshPaging(response, '#frmAssociationFilter', sbm.refreshResults);
|
||||
if (!response.success) return;
|
||||
// Reference data - Statuses.
|
||||
if (response.defaultStatusCode) sbm.data.defaultStatusCode = response.defaultStatusCode;
|
||||
if (response.statuses)
|
||||
sbm.populateSelectCodeDesc('#cbAssociationStatus', response.statuses);
|
||||
// Menu.
|
||||
var $bgr = $('.sbm-burger', $pnl.filter).hide();
|
||||
var $mnu = $('ul.sbm-dropdown-menu', $bgr).empty();
|
||||
$mnu.append(sbm.getFilterMenuOption(sbm.lbl.refresh, function () { sbm.refreshResults(); }));
|
||||
$mnu.append(sbm.getFilterMenuOption(sbm.lbl.create, function () { sbm.createItem(); }));
|
||||
$bgr.toggle(!!$('.sbm-dropdown-item', $mnu).length);
|
||||
// Items.
|
||||
var items = response.associations;
|
||||
if (!items.length)
|
||||
return $msgs.append($('<div class="sbm-message">' + sbm.msg.dataNoneFound + '</div>')).fadeIn(500);
|
||||
for (let itemIdx = 0; itemIdx < items.length; itemIdx++)
|
||||
$items.append(sbm.populateItem(sbm.getItemTemplate(), items[itemIdx]));
|
||||
$items.fadeIn(50);
|
||||
}
|
||||
sbm.populateItem = function ($item, item)
|
||||
{
|
||||
if (!item) return;
|
||||
$item.prop('id', sbm.itemIdPrefix + item.id);
|
||||
$('.AssociationCode', $item).text(item.code);
|
||||
$('.AssociationTargetName', $item).text(item.targetName);
|
||||
$('.AssociationType', $item).text(item.typeDesc);
|
||||
//$('.AssociationTransactionCount', $item).on('click', function () { sbm.onClickTransactionCount(item.id); }).toggle(item.associationCount).find('.TransactionCount').text(item.associationCount);
|
||||
$('.AssociationAddress', $item).text(item.addressSummary);
|
||||
$('.AssociationNotes', $item).text(item.notes);
|
||||
$('.StatusDesc', $item).text(item.statusDesc).addClass('sbm-status-' + item.statusCode.toLowerCase());
|
||||
$('.sbm-caption .sbm-action').toggleClass('sbm-action', !item.deleted);
|
||||
let $mnu = $('ul.sbm-dropdown-menu', $item);
|
||||
if (!item.deleted)
|
||||
{
|
||||
$mnu.append(sbm.getItemMenuOption(sbm.lbl.edit, function () { sbm.updateItem(item.id) }));
|
||||
$('.sbm-header .sbm-action.sbm-item-update', $item).off('click').on('click', function () { sbm.updateItem(item.id) });
|
||||
$item.off('dblclick').on('dblclick', function () { sbm.updateItem(item.id) });
|
||||
}
|
||||
$('.sbm-burger', $item).toggle(!!$('.sbm-dropdown-item', $mnu).length);
|
||||
$('.sbm-panel-messages', $pnl.results).hide().empty();
|
||||
return $item;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------
|
||||
sbm.getFilterDropdownTemplate = function ()
|
||||
{
|
||||
return $('.sbm-panel-item-template .sbm-dropdown-menu.AssociationFilter li.sbm-dropdown-item', $pnl.filter).clone();
|
||||
}
|
||||
sbm.getItemTemplate = function ()
|
||||
{
|
||||
return $('.sbm-panel-item-template .sbm-panel-item.Association', $pnl.results).clone();
|
||||
}
|
||||
sbm.getItemDropdownTemplate = function ()
|
||||
{
|
||||
return $('.sbm-panel-item-template .sbm-dropdown-menu.Association li.sbm-dropdown-item', $pnl.results).clone();
|
||||
}
|
||||
sbm.getFilterMenuOption = function (lbl, fn)
|
||||
{
|
||||
return sbm.getMenuOption(sbm.getFilterDropdownTemplate(), lbl, fn);
|
||||
}
|
||||
sbm.getItemMenuOption = function (lbl, fn)
|
||||
{
|
||||
return sbm.getMenuOption(sbm.getItemDropdownTemplate(), lbl, fn);
|
||||
}
|
||||
sbm.getMenuOption = function ($opt, lbl, fn)
|
||||
{
|
||||
return $opt.find('div.sbm-label').text(lbl).end().on('click', fn);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------
|
||||
sbm.createItem = function ()
|
||||
{
|
||||
let frm = $frm.association;
|
||||
$('.AssociationId,.AssociationExists,input[type="text"],textarea,select', frm).val('');
|
||||
$('.AssociationStatus', frm).val(sbm.data.defaultStatusCode);
|
||||
sbm.clearControlErrors();
|
||||
sbm.$dlg.association.dialog('option', 'title', sbm.dlg.title.createAssociation);
|
||||
sbm.openDialog(sbm.$dlg.association, 600, 600);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------
|
||||
sbm.updateItem = function (id)
|
||||
{
|
||||
$('.AssociationId', $frm.associationId).val(id);
|
||||
sbm.ajax.updateItem = sbm.ajax.updateItem || { url: sbm.url.base + 'Association/Ajax/GetItem', formId: 'frmAssociationId', callbackFn: sbm.onUpdateItem };
|
||||
sbm.doAjaxRequest(sbm.ajax.updateItem, 50);
|
||||
}
|
||||
sbm.onUpdateItem = function (response)
|
||||
{
|
||||
sbm.debug('onUpdateItem', response);
|
||||
let frm = $frm.association;
|
||||
$('.AssociationId,input[type="text"],textarea,select', frm).val('');
|
||||
if (!response.success) return;
|
||||
let item = response.association;
|
||||
$('.AssociationId', frm).val(item.id);
|
||||
$('.AssociationExists', frm).val(1);
|
||||
$('.AssociationType', frm).val(item.typeCode);
|
||||
$('.AssociationCode', frm).val(item.code);
|
||||
$('.AssociationDesc', frm).val(item.desc);
|
||||
$('.AssociationNotes', frm).val(item.notes);
|
||||
$('.AssociationStatus', frm).val(item.statusCode);
|
||||
sbm.clearControlErrors();
|
||||
sbm.$dlg.association.dialog('option', 'title', sbm.dlg.title.updateAssociation);
|
||||
sbm.openDialog(sbm.$dlg.association, 600, 600);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------
|
||||
sbm.storeItem = function ()
|
||||
{
|
||||
sbm.ajax.storeItem = sbm.ajax.storeItem || { url: sbm.url.base + 'Association/Ajax/StoreItem', formId: 'frmAssociation', callbackFn: sbm.onStoreItem };
|
||||
sbm.doAjaxRequest(sbm.ajax.storeItem, 50);
|
||||
}
|
||||
sbm.onStoreItem = function (response)
|
||||
{
|
||||
//sbm.debug('onStoreItem', response);
|
||||
sbm.refreshControlValues(response.controlValues);
|
||||
if (!response.success) return;
|
||||
sbm.$dlg.association.dialog('close');
|
||||
|
||||
var item = response.association;
|
||||
var $item = $('#' + sbm.itemIdPrefix + item.id);
|
||||
if (!$item.length)
|
||||
{
|
||||
$item = sbm.getItemTemplate();
|
||||
$('.sbm-panel-item-list', $pnl.results).prepend($item).show();
|
||||
}
|
||||
$item.replaceWith(sbm.populateItem(sbm.getItemTemplate(), item));
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------
|
||||
$(function ()
|
||||
{
|
||||
$pnl.associations = $('.sbm-panel.Associations');
|
||||
$pnl.filter = $('.sbm-panel-filter', $pnl.associations);
|
||||
$pnl.results = $('.sbm-panel-results', $pnl.associations);
|
||||
|
||||
$('.sbm-input, .sbm-textarea').on('input', function () { sbm.clearControlError(this); });
|
||||
$('.sbm-select').on('change', function () { sbm.clearControlError(this); });
|
||||
|
||||
$frm.filter = $('#frmAssociationFilter');
|
||||
$('.FilterAssociation', $frm.filter).on('input', function () { sbm.refreshResults(250); });
|
||||
$('.FilterAssociationType,.FilterAssociationStatusCategory', $frm.filter).on('change', function () { sbm.refreshResults(50); });
|
||||
$frm.associationId = $('#frmAssociationId');
|
||||
$frm.association = $('#frmAssociation');
|
||||
|
||||
var opt = sbm.dlgOpts();
|
||||
opt.buttons[sbm.dlg.btn.ok] = function () { sbm.storeItem(); };
|
||||
opt.buttons[sbm.dlg.btn.cancel] = function () { $(this).dialog('close'); };
|
||||
sbm.$dlg.association = $('#dlgAssociation').dialog(opt);
|
||||
|
||||
setTimeout(sbm.refreshResults, 250);
|
||||
});
|
||||
|
||||
}(window, window.document));
|
||||
|
||||
/* The End */
|
||||
@@ -23,18 +23,6 @@
|
||||
sbm.doAjaxRequest(sbm.ajax.refreshResults, delay || 50);
|
||||
sbm.awaitingRefreshResponse = true;
|
||||
}
|
||||
sbm.getFilterDropdownTemplate = function ()
|
||||
{
|
||||
return $('.sbm-panel-item-template .sbm-dropdown-menu.CommodityFilter li.sbm-dropdown-item', $pnl.filter).clone();
|
||||
}
|
||||
sbm.getItemTemplate = function ()
|
||||
{
|
||||
return $('.sbm-panel-item-template .sbm-panel-item.Commodity', $pnl.results).clone();
|
||||
}
|
||||
sbm.getItemDropdownTemplate = function ()
|
||||
{
|
||||
return $('.sbm-panel-item-template .sbm-dropdown-menu.Commodity li.sbm-dropdown-item', $pnl.results).clone();
|
||||
}
|
||||
sbm.doRefreshResults = function (response)
|
||||
{
|
||||
//sbm.debug('doRefreshResults', response);
|
||||
@@ -87,6 +75,18 @@
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------
|
||||
sbm.getFilterDropdownTemplate = function ()
|
||||
{
|
||||
return $('.sbm-panel-item-template .sbm-dropdown-menu.CommodityFilter li.sbm-dropdown-item', $pnl.filter).clone();
|
||||
}
|
||||
sbm.getItemTemplate = function ()
|
||||
{
|
||||
return $('.sbm-panel-item-template .sbm-panel-item.Commodity', $pnl.results).clone();
|
||||
}
|
||||
sbm.getItemDropdownTemplate = function ()
|
||||
{
|
||||
return $('.sbm-panel-item-template .sbm-dropdown-menu.Commodity li.sbm-dropdown-item', $pnl.results).clone();
|
||||
}
|
||||
sbm.getFilterMenuOption = function (lbl, fn)
|
||||
{
|
||||
return sbm.getMenuOption(sbm.getFilterDropdownTemplate(), lbl, fn);
|
||||
|
||||
Reference in New Issue
Block a user