BusinessMgr web apps
This commit is contained in:
@@ -0,0 +1,244 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Sarand.Net.Standard.Base.App;
|
||||
using Sarand.Net.Standard.Base.Core;
|
||||
using Sarand.Net.Standard.Base.Utils;
|
||||
|
||||
namespace Sarand.Net.Standard.Base.Procs
|
||||
{
|
||||
//=======================================================================
|
||||
public interface ISacsProcessNotifier
|
||||
{
|
||||
void OnStartProcess ();
|
||||
void SetProgressInfo (List<String> progressInfo);
|
||||
void OnEndProcess ();
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
public abstract class SaProcess_Base : SacsDisposable
|
||||
{
|
||||
//-------------------------------------------------------------------
|
||||
// Process options and groups - for configuration of process to run.
|
||||
// See Sarand.Win.Forms.Utility.SaForm_SelectOptions.
|
||||
public class OptionData
|
||||
{
|
||||
public OptionData (TypeCodeDesc option)
|
||||
{
|
||||
Option = option;
|
||||
}
|
||||
public TypeCodeDesc Option { get; set; }
|
||||
public String Notes { get; set; } = "";
|
||||
public bool Selected { get; set; } = false;
|
||||
}
|
||||
public class GroupData
|
||||
{
|
||||
public GroupData (TypeCodeDesc optionGroup)
|
||||
{
|
||||
OptionGroup = optionGroup;
|
||||
}
|
||||
public TypeCodeDesc OptionGroup { get; set; }
|
||||
public List<OptionData> Options { get; } = new List<OptionData>();
|
||||
public bool ExclusiveOptions { get; set; } = false;
|
||||
public bool Selected { get; set; } = false;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Configuration.
|
||||
public enum ProcessType
|
||||
{
|
||||
Unknown = 0,
|
||||
ImportData,
|
||||
ExportData,
|
||||
ImportExportData,
|
||||
Other,
|
||||
}
|
||||
public class Config
|
||||
{
|
||||
protected Config ()
|
||||
{
|
||||
}
|
||||
/// <summary>Identifies the type of process.</summary>
|
||||
public ProcessType ProcessType { get; set; } = ProcessType.Unknown;
|
||||
/// <summary>Is the process to be run in 'Test' mode.</summary>
|
||||
public bool TestProcess{ get; set; } = SacsSystem.DebugMode;
|
||||
/// <summary>Process imports data.</summary>
|
||||
public bool Import { get { return ProcessType == ProcessType.ImportData || ProcessType == ProcessType.ImportExportData; } }
|
||||
/// <summary>Process exports data.</summary>
|
||||
public bool Export { get { return ProcessType == ProcessType.ExportData || ProcessType == ProcessType.ImportExportData; } }
|
||||
/// <summary>Can the process be interrupted?</summary>
|
||||
public bool AllowInterruption { get; set; } = true;
|
||||
/// <summary>Confirm when interruption is requested.</summary>
|
||||
public bool ConfirmInterruption { get; set; } = true;
|
||||
/// <summary>Automated processes must not display desktop coponents - popup messages etc.</summary>
|
||||
public bool Automated { get; set; } = false;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Data members.
|
||||
private Config config;
|
||||
private String processError = "";
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Construction.
|
||||
protected SaProcess_Base (Config config)
|
||||
{
|
||||
this.config = config;
|
||||
}
|
||||
protected override void Dispose (bool disposing)
|
||||
{
|
||||
if (disposing)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Properties.
|
||||
public bool DebugMode { get { return SacsSystem.DebugMode; } }
|
||||
public ISacsProcessNotifier ProcessNotifier { get; set; } = null;
|
||||
public bool Processing { get; protected set; } = false;
|
||||
public bool ProcessEnded { get; protected set; } = false;
|
||||
public DateTime StartedAt { get; private set; } = DateTime.MinValue;
|
||||
public DateTime FinishedAt { get; private set; } = DateTime.MinValue;
|
||||
public int ElapsedSecs
|
||||
{
|
||||
get
|
||||
{
|
||||
if (DateUtil.IsValid(StartedAt))
|
||||
return (int)((DateUtil.IsValid(FinishedAt) ? FinishedAt : DateTime.Now) - StartedAt).TotalSeconds;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Properties.
|
||||
/// <summary>Process caption.</summary>
|
||||
public abstract String ProcessDescription { get; }
|
||||
/// <summary>Process comments - to be displayed with process selection.</summary>
|
||||
public virtual List<String> ProcessComments { get { return new List<String>(); } }
|
||||
/// <summary>Processing statistics.</summary>
|
||||
public virtual List<StringPair> ProcessingStatistics { get { return new List<StringPair>(); } }
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Run process inline.
|
||||
public bool RunProcess ()
|
||||
{
|
||||
String fn = GetType().Name+".RunProcess";
|
||||
if (ProcessNotifier == null)
|
||||
throw new NotSupportedException("Process Notifier must be specified");
|
||||
// Prepare process.
|
||||
bool runProcess = false;
|
||||
Reset();
|
||||
Processing = true;
|
||||
StartedAt = DateTime.Now;
|
||||
try
|
||||
{
|
||||
// Notify start of process and log/ignore exceptions.
|
||||
ProcessNotifier.OnStartProcess();
|
||||
}
|
||||
catch (Exception exc)
|
||||
{
|
||||
SaLogger.Error(fn + " OnStartProcess: " + GetProcessError() + exc.GetStackEntries(6).Concat("", "\n\tat "), true);
|
||||
}
|
||||
try
|
||||
{
|
||||
// Run process.
|
||||
OnProcessStarting();
|
||||
runProcess = Run();
|
||||
OnProcessEnding();
|
||||
}
|
||||
catch (Exception exc)
|
||||
{
|
||||
SetProcessError(exc.GetType().Name + ": " + exc.Message);
|
||||
SaLogger.Error(fn + " " + GetProcessError() + exc.GetStackEntries(6).Concat("", "\n\tat "), true);
|
||||
}
|
||||
// Processing completed.
|
||||
FinishedAt = DateTime.Now;
|
||||
Processing = false;
|
||||
ProcessEnded = true;
|
||||
try
|
||||
{
|
||||
// Notify end of process and log/ignore exceptions.
|
||||
ProcessNotifier.OnEndProcess();
|
||||
}
|
||||
catch (Exception exc)
|
||||
{
|
||||
SaLogger.Error(fn + " OnEndProcess: " + GetProcessError() + exc.GetStackEntries(6).Concat("", "\n\tat "), true);
|
||||
}
|
||||
return runProcess;
|
||||
}
|
||||
protected abstract bool Run ();
|
||||
protected virtual void OnProcessStarting () { }
|
||||
protected virtual void OnProcessEnding () { }
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Process control.
|
||||
public bool OK
|
||||
{
|
||||
get
|
||||
{
|
||||
if (HasProcessError()) return false;
|
||||
if (isInterrupted) return false;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
private void Reset ()
|
||||
{
|
||||
ClearProcessError();
|
||||
isInterrupted = false;
|
||||
ProcessEnded = false;
|
||||
StartedAt = DateTime.MinValue;
|
||||
FinishedAt = DateTime.MinValue;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Progress information.
|
||||
protected void SetProgressInfo (String progressInfo)
|
||||
{
|
||||
SetProgressInfo(StringListUtil.CreateList(progressInfo));
|
||||
}
|
||||
protected void SetProgressInfo (List<String> progressInfo)
|
||||
{
|
||||
if (ProcessNotifier != null)
|
||||
ProcessNotifier.SetProgressInfo(progressInfo);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Error handling.
|
||||
public bool HasProcessError () { return !StringUtil.IsEmpty(processError); }
|
||||
public String GetProcessError () { return StringUtil.EmptyOnNull(processError); }
|
||||
public void ClearProcessError () { processError = ""; }
|
||||
/// <summary>Record the processing error - always returns false.</summary>
|
||||
public bool SetProcessError (String error)
|
||||
{
|
||||
processError = StringUtil.EmptyOnNull(error);
|
||||
return false;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Interruption.
|
||||
private bool isInterrupted = false;
|
||||
public bool IsInterrupted
|
||||
{
|
||||
get { return isInterrupted; }
|
||||
}
|
||||
public bool Interrupt ()
|
||||
{
|
||||
if (!config.AllowInterruption)
|
||||
{
|
||||
SaLogger.Warn("SacsProcess.Interrupt() Interruptions not allowed in " + this.GetType().Name);
|
||||
return false;
|
||||
}
|
||||
if (config.ConfirmInterruption && !IsInterruptionConfirmed()) return false;
|
||||
isInterrupted = true;
|
||||
return true;
|
||||
}
|
||||
protected virtual bool IsInterruptionConfirmed ()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
}
|
||||
//=======================================================================
|
||||
}
|
||||
Reference in New Issue
Block a user