2171 lines
57 KiB
C#
2171 lines
57 KiB
C#
///////////////////////////////////////////////////////////
|
|
// Global.cs
|
|
// Implementation of Class Global
|
|
// CSLA type: Editable Root
|
|
// Created on: 07-Jun-2004 8:41:25 AM
|
|
// Object design: Joyce
|
|
// Coded: John 30-July-2004
|
|
///////////////////////////////////////////////////////////
|
|
|
|
using System;
|
|
using System.Data;
|
|
using CSLA.Data;
|
|
using GZTW.Data;
|
|
using CSLA;
|
|
using System.Threading;
|
|
using CSLA.Security;
|
|
using System.ComponentModel;
|
|
using System.Text;
|
|
|
|
namespace GZTW.AyaNova.BLL
|
|
{
|
|
/// <summary>
|
|
/// Global settings - stores AyaNova wide defaults and preferences
|
|
/// API users: use the <see cref="AyaBizUtils.GlobalSettings"/> property to ensure you are working with the most current GlobalSettings rather than retrieving this object directly.
|
|
/// </summary>
|
|
[Serializable]
|
|
public class Global : BusinessBase
|
|
{
|
|
|
|
#region Attributes
|
|
|
|
private bool bReadOnly;
|
|
//private Guid mID;
|
|
private SmartDate mCreated;
|
|
private SmartDate mModified;
|
|
private Guid mCreator;
|
|
private Guid mModifier;
|
|
|
|
|
|
|
|
private Address mGoToAddress;
|
|
private Address mMailToAddress;
|
|
private Guid mTaxPartPurchaseID;
|
|
private Guid mTaxPartSaleID;
|
|
private Guid mTaxRateSaleID;
|
|
|
|
private Guid mDefaultServiceTemplateID;
|
|
|
|
private bool mAllowScheduleConflicts;
|
|
private string mDefaultLanguage="";
|
|
//private bool mUseRegions;
|
|
private Guid mWorkorderClosedStatus;
|
|
// O.Global
|
|
|
|
private string mWorkorderSummaryTemplate;
|
|
|
|
private bool mUseInventory;
|
|
private UnitNameDisplayFormats mDefaultUnitNameDisplayFormat=UnitNameDisplayFormats.SerialOnly;
|
|
private ScheduleableUserNameDisplayFormats mDefaultScheduleableUserNameDisplayFormat=ScheduleableUserNameDisplayFormats.FirstLast;
|
|
private PartDisplayFormats mDefaultPartDisplayFormat=PartDisplayFormats.NumberName;
|
|
|
|
private bool mCJKIndex;
|
|
|
|
//start seed update flags
|
|
private bool mUpdateWorkorderServiceStartSeed=false;
|
|
private bool mUpdateQuoteNumberStartSeed=false;
|
|
private bool mUpdatePurchaseOrderStartSeed=false;
|
|
private bool mUpdateInventoryAdjustmentStartSeed=false;
|
|
//private bool mUpdateRentalStartSeed=false;
|
|
|
|
|
|
//start seed current values
|
|
private int mWorkorderServiceStartSeed=1;
|
|
private int mQuoteNumberStartSeed=1;
|
|
private int mPurchaseOrderStartSeed=1;
|
|
private int mInventoryAdjustmentStartSeed=1;
|
|
|
|
|
|
private int mWorkorderCloseByAge=0;
|
|
|
|
private bool mUseNotification;
|
|
private string mNotifySMTPHost="";
|
|
private string mNotifySMTPEncryptionMethod = "";//case 1136
|
|
private string mNotifySMTPAccount="";
|
|
private string mNotifySMTPPassword="";
|
|
private string mNotifySMTPFrom="";
|
|
|
|
private CoordinateTypes mCoordinateStyle=CoordinateTypes.DegreesDecimalMinutes;
|
|
private LatitudeHemisphere mDefaultLatitude=LatitudeHemisphere.North;
|
|
private LongitudeHemisphere mDefaultLongitude=LongitudeHemisphere.West;
|
|
|
|
|
|
private int mMaxFileSizeMB = 50;
|
|
|
|
//case 816
|
|
private int mLaborSchedUserDfltTimeSpan = 60;
|
|
private int mTravelDfltTimeSpan = 60;
|
|
|
|
private bool mSMTPRetry;
|
|
|
|
//case 1194
|
|
private System.Collections.Generic.List<string> mHiddenControls = null;
|
|
|
|
//case 1346
|
|
private string mSignatureHeader = "";
|
|
private string mSignatureFooter = "";
|
|
private string mSignatureTitle = "";
|
|
|
|
|
|
//case 1392
|
|
private SmartDate mSchedUserNonTodayStartTime;
|
|
|
|
//case 1487
|
|
private bool mMainGridAutoRefresh;
|
|
|
|
#endregion
|
|
|
|
#region Constructor
|
|
|
|
/// <summary>
|
|
/// Private constructor to prevent direct instantiation
|
|
/// </summary>
|
|
private Global()
|
|
{
|
|
|
|
|
|
|
|
//Set to read / write initially so that properties
|
|
//can be set
|
|
bReadOnly=false;
|
|
|
|
|
|
// mGoToAddress=Address.NewItem();
|
|
// mGoToAddress.RootObjectID=Guid.Empty;
|
|
// mGoToAddress.RootObjectType=RootObjectTypes.Global;
|
|
// mGoToAddress.AddressType=AddressTypes.Physical;
|
|
//
|
|
// mMailToAddress=Address.NewItem();
|
|
// mMailToAddress.RootObjectID=Guid.Empty;
|
|
// mMailToAddress.RootObjectType=RootObjectTypes.Global;
|
|
// mMailToAddress.AddressType=AddressTypes.Postal;
|
|
|
|
//Set record history to defaults
|
|
mCreated = new SmartDate(DBUtil.CurrentWorkingDateTime);
|
|
mModified=new SmartDate();
|
|
mCreator=Guid.Empty;
|
|
mModifier=Guid.Empty;
|
|
|
|
mUseInventory=false;
|
|
|
|
mUseNotification=false;
|
|
|
|
|
|
|
|
}
|
|
#endregion
|
|
|
|
#region Business properties
|
|
// /// <summary>
|
|
// /// Get internal id number Read only property because it's set internally, not
|
|
// /// externally
|
|
// /// </summary>
|
|
// public Guid ID
|
|
// {
|
|
// get
|
|
// {
|
|
// return mID;
|
|
// }
|
|
// }
|
|
|
|
|
|
|
|
/// <summary>
|
|
/// Get created date
|
|
///
|
|
///
|
|
/// </summary>
|
|
[Browsable(false)]
|
|
public string Created
|
|
{
|
|
get
|
|
{
|
|
return mCreated.ToString();
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get modified date
|
|
///
|
|
///
|
|
/// </summary>
|
|
[Browsable(false)]
|
|
public string Modified
|
|
{
|
|
get
|
|
{
|
|
return mModified.ToString();
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get user record ID of person who created this record
|
|
///
|
|
///
|
|
/// </summary>
|
|
[Browsable(false)]
|
|
public Guid Creator
|
|
{
|
|
get
|
|
{
|
|
return mCreator;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get user ID of person who modified this record
|
|
///
|
|
///
|
|
/// </summary>
|
|
[Browsable(false)]
|
|
public Guid Modifier
|
|
{
|
|
get
|
|
{
|
|
return mModifier;
|
|
}
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// Get service address for this client
|
|
/// </summary>
|
|
|
|
public Address GoToAddress
|
|
{
|
|
get
|
|
{
|
|
return mGoToAddress;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get mailing address object for this client
|
|
/// Returns GoToAddress object if MailToAddress is empty
|
|
/// </summary>
|
|
|
|
public Address MailToAddress
|
|
{
|
|
get
|
|
{
|
|
return mMailToAddress;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Default is true (allow)
|
|
/// False means if schedule coflicts occurs, it gives a pop up message indicating
|
|
/// so that you need to change it.
|
|
/// True means it gives a popup letting you know, but lets you go ahead with
|
|
/// schedule.
|
|
/// We do not have an option to turn off popup as should purchase enough licenses
|
|
/// to cover all users.
|
|
/// </summary>
|
|
[DefaultValue(true)]
|
|
public bool AllowScheduleConflicts
|
|
{
|
|
get
|
|
{
|
|
return mAllowScheduleConflicts;
|
|
}
|
|
set
|
|
{
|
|
if(bReadOnly)
|
|
ThrowSetError();
|
|
else
|
|
{
|
|
if(mAllowScheduleConflicts!=value)
|
|
{
|
|
mAllowScheduleConflicts = value;
|
|
MarkDirty();
|
|
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
///// <summary>
|
|
///// Default is false
|
|
///// If true, displays region settings and fields
|
|
///// If false, still uses a default region behind the scenes so "ready" to go to use
|
|
///// regions
|
|
///// </summary>
|
|
//[DefaultValue(false)]
|
|
//public bool UseRegions
|
|
//{
|
|
// get
|
|
// {
|
|
// return mUseRegions;
|
|
// }
|
|
// set
|
|
// {
|
|
// if(bReadOnly)
|
|
// ThrowSetError();
|
|
// else
|
|
// {
|
|
// if(mUseRegions!=value)
|
|
// {
|
|
// mUseRegions = value;
|
|
// MarkDirty();
|
|
|
|
// }
|
|
// }
|
|
// }
|
|
//}
|
|
/// <summary>
|
|
/// Default locale to use
|
|
/// </summary>
|
|
[DefaultValue("English")]
|
|
[System.ComponentModel.TypeConverter(typeof(LocaleConverter))]
|
|
public string DefaultLanguage
|
|
{
|
|
get
|
|
{
|
|
return mDefaultLanguage;
|
|
}
|
|
set
|
|
{
|
|
if(bReadOnly)
|
|
ThrowSetError();
|
|
else
|
|
{
|
|
if(mDefaultLanguage!=value)
|
|
{
|
|
mDefaultLanguage = value;
|
|
MarkDirty();
|
|
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//[Browsable(false)]
|
|
//public Guid DefaultPurchaseOrderTemplate
|
|
//{
|
|
// get
|
|
// {
|
|
// return mDefaultPurchaseOrderTemplate;
|
|
// }
|
|
// set
|
|
// {
|
|
// if(bReadOnly)
|
|
// ThrowSetError();
|
|
// else
|
|
// {
|
|
// if(mDefaultPurchaseOrderTemplate!=value)
|
|
// {
|
|
// mDefaultPurchaseOrderTemplate = value;
|
|
// MarkDirty();
|
|
|
|
// }
|
|
// }
|
|
// }
|
|
//}
|
|
|
|
//[Browsable(false)]
|
|
//public Guid DefaultQuoteTemplate
|
|
//{
|
|
// get
|
|
// {
|
|
// return mDefaultQuoteTemplate;
|
|
// }
|
|
// set
|
|
// {
|
|
// if(bReadOnly)
|
|
// ThrowSetError();
|
|
// else
|
|
// {
|
|
// if(mDefaultQuoteTemplate!=value)
|
|
// {
|
|
// mDefaultQuoteTemplate = value;
|
|
// MarkDirty();
|
|
|
|
// }
|
|
// }
|
|
// }
|
|
//}
|
|
|
|
/// <summary>
|
|
/// Default tax for selling parts
|
|
/// </summary>
|
|
[System.ComponentModel.TypeConverter(typeof(TaxCodeIDConverter))]
|
|
public Guid TaxPartSaleID
|
|
{
|
|
get
|
|
{
|
|
return mTaxPartSaleID;
|
|
}
|
|
set
|
|
{
|
|
if(bReadOnly)
|
|
ThrowSetError();
|
|
else
|
|
{
|
|
if(mTaxPartSaleID!=value)
|
|
{
|
|
mTaxPartSaleID = value;
|
|
MarkDirty();
|
|
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Default purchase tax code for parts
|
|
/// </summary>
|
|
[System.ComponentModel.TypeConverter(typeof(TaxCodeIDConverter))]
|
|
public Guid TaxPartPurchaseID
|
|
{
|
|
get
|
|
{
|
|
return mTaxPartPurchaseID;
|
|
}
|
|
set
|
|
{
|
|
if(bReadOnly)
|
|
ThrowSetError();
|
|
else
|
|
{
|
|
if(mTaxPartPurchaseID!=value)
|
|
{
|
|
mTaxPartPurchaseID = value;
|
|
MarkDirty();
|
|
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Default tax for selling services / rates
|
|
/// </summary>
|
|
[System.ComponentModel.TypeConverter(typeof(TaxCodeIDConverter))]
|
|
public Guid TaxRateSaleID
|
|
{
|
|
get
|
|
{
|
|
return mTaxRateSaleID;
|
|
}
|
|
set
|
|
{
|
|
if(bReadOnly)
|
|
ThrowSetError();
|
|
else
|
|
{
|
|
if(mTaxRateSaleID!=value)
|
|
{
|
|
mTaxRateSaleID = value;
|
|
MarkDirty();
|
|
|
|
}
|
|
}
|
|
}
|
|
}
|
|
/// <summary>
|
|
/// Default global service template ID to use when no other more specific template applies
|
|
/// </summary>
|
|
[Browsable(false)]
|
|
public Guid DefaultServiceTemplateID
|
|
{
|
|
get
|
|
{
|
|
return mDefaultServiceTemplateID;
|
|
}
|
|
set
|
|
{
|
|
if(bReadOnly)
|
|
ThrowSetError();
|
|
else
|
|
{
|
|
if (mDefaultServiceTemplateID != value)
|
|
{
|
|
mDefaultServiceTemplateID = value;
|
|
MarkDirty();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// /// <summary>
|
|
// /// Default is false
|
|
// /// If true, checks spelling against internal dictionary (do we have a program to
|
|
// /// do this?) following rules set by bool
|
|
// /// NOTE: ignores words with numbers in it
|
|
// /// </summary>
|
|
// [DefaultValue(false)]
|
|
// public bool SpellCheck
|
|
// {
|
|
// get
|
|
// {
|
|
// return mSpellCheck;
|
|
// }
|
|
// set
|
|
// {
|
|
// if(bReadOnly)
|
|
// ThrowSetError();
|
|
// else
|
|
// {
|
|
// if(mSpellCheck!=value)
|
|
// {
|
|
// mSpellCheck = value;
|
|
// MarkDirty();
|
|
//
|
|
// }
|
|
// }
|
|
// }
|
|
// }
|
|
|
|
/// <summary>
|
|
/// Status that identifies when a workorder is completed
|
|
/// Used internally by the program for some functions.
|
|
/// </summary>
|
|
[Browsable(false)]
|
|
public Guid WorkorderClosedStatus
|
|
{
|
|
get
|
|
{
|
|
return mWorkorderClosedStatus;
|
|
}
|
|
set
|
|
{
|
|
if(bReadOnly)
|
|
ThrowSetError();
|
|
else
|
|
{
|
|
if(mWorkorderClosedStatus!=value)
|
|
{
|
|
mWorkorderClosedStatus = value;
|
|
MarkDirty();
|
|
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
#region seed identity start values
|
|
/// <summary>
|
|
///
|
|
/// Reset starting number for auto incrementing workorder number
|
|
/// Can only be set higher than current seed value
|
|
/// </summary>
|
|
public int WorkorderNumberStartSeed
|
|
{
|
|
get
|
|
{
|
|
return mWorkorderServiceStartSeed;
|
|
}
|
|
set
|
|
{
|
|
if(bReadOnly)
|
|
ThrowSetError();
|
|
else
|
|
{
|
|
if(mWorkorderServiceStartSeed!=value)
|
|
{
|
|
mWorkorderServiceStartSeed = value;
|
|
MarkDirty();
|
|
this.mUpdateWorkorderServiceStartSeed=true;
|
|
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Reset starting number for auto incrementing quote number
|
|
/// Can only be set higher than current seed value
|
|
/// </summary>
|
|
public int QuoteNumberStartSeed
|
|
{
|
|
get
|
|
{
|
|
|
|
return mQuoteNumberStartSeed;
|
|
}
|
|
set
|
|
{
|
|
if(bReadOnly)
|
|
ThrowSetError();
|
|
else
|
|
{
|
|
if(mQuoteNumberStartSeed!=value)
|
|
{
|
|
mQuoteNumberStartSeed = value;
|
|
MarkDirty();
|
|
this.mUpdateQuoteNumberStartSeed=true;
|
|
|
|
}
|
|
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// write only
|
|
/// Reset starting number for auto incrementing Purchase Order number
|
|
/// Can only be set higher than current seed value
|
|
/// </summary>
|
|
public int PurchaseOrderStartSeed
|
|
{
|
|
get
|
|
{
|
|
return mPurchaseOrderStartSeed;
|
|
}
|
|
set
|
|
{
|
|
if(bReadOnly)
|
|
ThrowSetError();
|
|
else
|
|
{
|
|
if(mPurchaseOrderStartSeed!=value)
|
|
{
|
|
mPurchaseOrderStartSeed = value;
|
|
MarkDirty();
|
|
this.mUpdatePurchaseOrderStartSeed=true;
|
|
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// write only
|
|
/// Reset starting number for auto incrementing InventoryAdjustment number
|
|
/// Can only be set higher than current seed value
|
|
/// </summary>
|
|
public int InventoryAdjustmentStartSeed
|
|
{
|
|
get
|
|
{
|
|
return mInventoryAdjustmentStartSeed;
|
|
}
|
|
set
|
|
{
|
|
if(bReadOnly)
|
|
ThrowSetError();
|
|
else
|
|
{
|
|
if(mInventoryAdjustmentStartSeed!=value)
|
|
{
|
|
mInventoryAdjustmentStartSeed = value;
|
|
MarkDirty();
|
|
this.mUpdateInventoryAdjustmentStartSeed=true;
|
|
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
/// <summary>
|
|
/// Template for displaying information about a workorder
|
|
/// compactly in summary form on calendars and in lists
|
|
/// and reports
|
|
/// (Maximum 500 characters)
|
|
/// </summary>
|
|
public string WorkorderSummaryTemplate
|
|
{
|
|
get
|
|
{
|
|
return mWorkorderSummaryTemplate;
|
|
}
|
|
set
|
|
{
|
|
if(bReadOnly)
|
|
ThrowSetError();
|
|
else
|
|
{
|
|
if(mWorkorderSummaryTemplate!=value)
|
|
{//TODO: if this is empty will it cause a bomb in the schedule screen?
|
|
//should it default to something if it's set to empty, i.e. just the wo number or...?
|
|
mWorkorderSummaryTemplate = value;
|
|
BrokenRules.Assert("WorkorderSummaryTemplateLength",
|
|
"Error.Object.FieldLengthExceeded,Global.Label.WorkorderSummaryTemplate,500",
|
|
"WorkorderSummaryTemplate",value.Length>500);
|
|
MarkDirty();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Default is false
|
|
/// If true, activates AyaNova inventory tracking and features
|
|
/// </summary>
|
|
[DefaultValue(false)]
|
|
public bool UseInventory
|
|
{
|
|
get
|
|
{
|
|
if (AyaBizUtils.Lite) return false;//case 1172
|
|
return mUseInventory;
|
|
}
|
|
set
|
|
{
|
|
if(bReadOnly)
|
|
ThrowSetError();
|
|
else
|
|
{
|
|
if(mUseInventory!=value)
|
|
{
|
|
mUseInventory = value;
|
|
MarkDirty();
|
|
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Default <see cref="UnitNameDisplayFormats"/>
|
|
/// </summary>
|
|
[System.ComponentModel.TypeConverter(typeof(EnumDescConverter))]
|
|
[DefaultValue(UnitNameDisplayFormats.SerialOnly)]
|
|
public UnitNameDisplayFormats DefaultUnitNameDisplayFormat
|
|
{
|
|
get
|
|
{
|
|
return mDefaultUnitNameDisplayFormat;
|
|
}
|
|
set
|
|
{
|
|
if(bReadOnly)
|
|
ThrowSetError();
|
|
else
|
|
{
|
|
if(mDefaultUnitNameDisplayFormat!=value)
|
|
{
|
|
mDefaultUnitNameDisplayFormat = value;
|
|
MarkDirty();
|
|
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Global default <see cref="ScheduleableUserNameDisplayFormats"/>
|
|
/// </summary>
|
|
[System.ComponentModel.TypeConverter(typeof(EnumDescConverter))]
|
|
[DefaultValue(ScheduleableUserNameDisplayFormats.FirstLast)]
|
|
public ScheduleableUserNameDisplayFormats DefaultScheduleableUserNameDisplayFormat
|
|
{
|
|
get
|
|
{
|
|
return mDefaultScheduleableUserNameDisplayFormat;
|
|
}
|
|
set
|
|
{
|
|
if(bReadOnly)
|
|
ThrowSetError();
|
|
else
|
|
{
|
|
if(mDefaultScheduleableUserNameDisplayFormat!=value)
|
|
{
|
|
mDefaultScheduleableUserNameDisplayFormat = value;
|
|
MarkDirty();
|
|
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Global default <see cref="PartDisplayFormats"/>
|
|
/// </summary>
|
|
[System.ComponentModel.TypeConverter(typeof(EnumDescConverter))]
|
|
[DefaultValue(PartDisplayFormats.NumberName)]
|
|
public PartDisplayFormats DefaultPartDisplayFormat
|
|
{
|
|
get
|
|
{
|
|
return mDefaultPartDisplayFormat;
|
|
}
|
|
set
|
|
{
|
|
if(bReadOnly)
|
|
ThrowSetError();
|
|
else
|
|
{
|
|
if(mDefaultPartDisplayFormat!=value)
|
|
{
|
|
mDefaultPartDisplayFormat = value;
|
|
MarkDirty();
|
|
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
/// Indexing style to use for AyaNova internal search engine
|
|
/// Default is false.
|
|
///
|
|
/// If data entry is primarily in a language with no spacing or punctuation to
|
|
/// identify the boundaries between words (Chinese, Japanese, Korean, Thai etc) then
|
|
/// setting this value to true will use a 2 character segmentation system
|
|
///
|
|
/// In all other languages with spacing and/or punctuation this value should be false to ensure most accurate word indexing
|
|
///
|
|
/// </summary>
|
|
[DefaultValue(false)]
|
|
public bool CJKIndex
|
|
{
|
|
get
|
|
{
|
|
return this.mCJKIndex;
|
|
}
|
|
set
|
|
{
|
|
if(bReadOnly)
|
|
ThrowSetError();
|
|
else
|
|
{
|
|
if(mCJKIndex!=value)
|
|
{
|
|
mCJKIndex = value;
|
|
MarkDirty();
|
|
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Default for how old in minutes a workorder has to be and not be closed before
|
|
/// it's considered "stale" (for purposes of notification and display in some lists)
|
|
///
|
|
/// This is used to catch forgotten workorders.
|
|
/// This value is used to set the default CloseByDate by date/time in a service workorder.
|
|
/// </summary>
|
|
[DefaultValue(0)]
|
|
public int WorkorderCloseByAge
|
|
{
|
|
get
|
|
{
|
|
return this.mWorkorderCloseByAge;
|
|
}
|
|
set
|
|
{
|
|
if(bReadOnly)
|
|
ThrowSetError();
|
|
else
|
|
{
|
|
if(mWorkorderCloseByAge!=value)
|
|
{
|
|
mWorkorderCloseByAge = value;
|
|
MarkDirty();
|
|
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/// <summary>
|
|
/// Default is false
|
|
/// If true, activates AyaNova notification feature
|
|
/// and causes biz objects to check for notification events
|
|
/// and Process them as part of their normal updating routines
|
|
/// </summary>
|
|
[DefaultValue(false)]
|
|
public bool UseNotification
|
|
{
|
|
get
|
|
{
|
|
return this.mUseNotification;
|
|
}
|
|
set
|
|
{
|
|
if(bReadOnly)
|
|
ThrowSetError();
|
|
else
|
|
{
|
|
if(mUseNotification!=value)
|
|
{
|
|
mUseNotification = value;
|
|
MarkDirty();
|
|
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// SMTP server to use for outgoing AyaNova generated email
|
|
/// </summary>
|
|
[DefaultValue("mail.yourserver.com")]
|
|
public string NotifySMTPHost
|
|
{
|
|
get
|
|
{
|
|
return mNotifySMTPHost;
|
|
}
|
|
set
|
|
{
|
|
if(bReadOnly)
|
|
ThrowSetError();
|
|
else
|
|
{
|
|
if(mNotifySMTPHost!=value)
|
|
{
|
|
mNotifySMTPHost = value;
|
|
MarkDirty();
|
|
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//Case 515
|
|
/// <summary>
|
|
/// Extracts the port number if present from the end of the
|
|
/// NotifySMTPHost property
|
|
/// e.g.
|
|
/// mail.yourhost.com:587 returns 587
|
|
/// mail.yourhost.com returns 25
|
|
/// </summary>
|
|
public int NotifySMTPPort
|
|
{
|
|
get
|
|
{
|
|
if (string.IsNullOrEmpty(mNotifySMTPHost)) return 25;
|
|
if (!mNotifySMTPHost.Contains(":")) return 25;
|
|
string [] s=mNotifySMTPHost.Split(':');
|
|
if (s.GetLength(0) < 2) return 25;
|
|
int nPort = 0;
|
|
if (!System.Int32.TryParse(s[1], out nPort)) return 25;
|
|
if (nPort == 0) return 25;
|
|
return nPort;
|
|
|
|
}
|
|
}
|
|
|
|
//Case 515
|
|
/// <summary>
|
|
/// Extracts only host name portion of smtp host that might contain a port number
|
|
/// on it's end
|
|
/// </summary>
|
|
public string NotifySMTPHostPortionOnly
|
|
{
|
|
get
|
|
{
|
|
if (!mNotifySMTPHost.Contains(":")) return mNotifySMTPHost;
|
|
string s=mNotifySMTPHost.Substring(0, mNotifySMTPHost.IndexOf(":"));
|
|
return s;
|
|
}
|
|
}
|
|
|
|
|
|
//case 1136
|
|
/// <summary>
|
|
/// Encryption protocol to use
|
|
/// if value is SSL then ssl encryption is used
|
|
/// if TLS then tls encryption used
|
|
/// Any other value or no value means no encryption is used
|
|
/// </summary>
|
|
[DefaultValue("")]
|
|
public string NotifySMTPEncryptionMethod
|
|
{
|
|
get
|
|
{
|
|
return mNotifySMTPEncryptionMethod;
|
|
}
|
|
set
|
|
{
|
|
if (bReadOnly)
|
|
ThrowSetError();
|
|
else
|
|
{
|
|
if (mNotifySMTPEncryptionMethod != value)
|
|
{
|
|
mNotifySMTPEncryptionMethod = value;
|
|
MarkDirty();
|
|
|
|
}
|
|
}
|
|
}
|
|
}
|
|
/// <summary>
|
|
/// Read only flag used internally
|
|
/// </summary>
|
|
internal bool NotifySMTPUseSSL
|
|
{//case 1136
|
|
get
|
|
{
|
|
if (mNotifySMTPEncryptionMethod.Equals("SSL", StringComparison.CurrentCultureIgnoreCase)) return true;
|
|
return false;
|
|
|
|
}
|
|
}
|
|
/// <summary>
|
|
/// Read only flag used internally
|
|
/// </summary>
|
|
internal bool NotifySMTPUseTLS
|
|
{//case 1136
|
|
get
|
|
{
|
|
if (mNotifySMTPEncryptionMethod.Equals("TLS", StringComparison.CurrentCultureIgnoreCase)) return true;
|
|
return false;
|
|
|
|
}
|
|
}
|
|
/// <summary>
|
|
/// Email account AyaNova should use for sending email
|
|
/// </summary>
|
|
[DefaultValue("senderaccount@yourserver.com")]
|
|
public string NotifySMTPAccount
|
|
{
|
|
get
|
|
{
|
|
return mNotifySMTPAccount;
|
|
}
|
|
set
|
|
{
|
|
if(bReadOnly)
|
|
ThrowSetError();
|
|
else
|
|
{
|
|
if(mNotifySMTPAccount!=value)
|
|
{
|
|
mNotifySMTPAccount = value;
|
|
MarkDirty();
|
|
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// SMTP Server password for NotifySMTPAccount
|
|
/// </summary>
|
|
[DefaultValue("senderaccountpassword")]
|
|
public string NotifySMTPPassword
|
|
{
|
|
get
|
|
{
|
|
return mNotifySMTPPassword;
|
|
}
|
|
set
|
|
{
|
|
if(bReadOnly)
|
|
ThrowSetError();
|
|
else
|
|
{
|
|
if(mNotifySMTPPassword!=value)
|
|
{
|
|
mNotifySMTPPassword = value;
|
|
MarkDirty();
|
|
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Outgoing email messages sent by AyaNova will have the From address set to this value
|
|
/// </summary>
|
|
[DefaultValue("fromaddress@yourserver.com")]
|
|
public string NotifySMTPFrom
|
|
{
|
|
get
|
|
{
|
|
return mNotifySMTPFrom;
|
|
}
|
|
set
|
|
{
|
|
if(bReadOnly)
|
|
ThrowSetError();
|
|
else
|
|
{
|
|
if(mNotifySMTPFrom!=value)
|
|
{
|
|
mNotifySMTPFrom = value;
|
|
MarkDirty();
|
|
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Global default <see cref="CoordinateTypes"/>
|
|
/// </summary>
|
|
[System.ComponentModel.TypeConverter(typeof(EnumDescConverter))]
|
|
[DefaultValue(CoordinateTypes.DegreesDecimalMinutes)]
|
|
public CoordinateTypes CoordinateStyle
|
|
{
|
|
get
|
|
{
|
|
return mCoordinateStyle;
|
|
}
|
|
set
|
|
{
|
|
if(bReadOnly)
|
|
ThrowSetError();
|
|
else
|
|
{
|
|
if(mCoordinateStyle!=value)
|
|
{
|
|
mCoordinateStyle = value;
|
|
MarkDirty();
|
|
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Default hemisphere for interpreting co-ordinates
|
|
/// See <see cref="LatitudeHemisphere"/>
|
|
/// </summary>
|
|
[System.ComponentModel.TypeConverter(typeof(EnumDescConverter))]
|
|
[DefaultValue(LatitudeHemisphere.North)]
|
|
public LatitudeHemisphere DefaultLatitude
|
|
{
|
|
get
|
|
{
|
|
return mDefaultLatitude;
|
|
}
|
|
set
|
|
{
|
|
if(bReadOnly)
|
|
ThrowSetError();
|
|
else
|
|
{
|
|
if(mDefaultLatitude!=value)
|
|
{
|
|
mDefaultLatitude = value;
|
|
MarkDirty();
|
|
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Default prime meridian offset for interpreting co-ordinates
|
|
/// See <see cref="LongitudeHemisphere"/>
|
|
/// </summary>
|
|
[System.ComponentModel.TypeConverter(typeof(EnumDescConverter))]
|
|
[DefaultValue(LongitudeHemisphere.West)]
|
|
public LongitudeHemisphere DefaultLongitude
|
|
{
|
|
get
|
|
{
|
|
return mDefaultLongitude;
|
|
}
|
|
set
|
|
{
|
|
if(bReadOnly)
|
|
ThrowSetError();
|
|
else
|
|
{
|
|
if(mDefaultLongitude!=value)
|
|
{
|
|
mDefaultLongitude = value;
|
|
MarkDirty();
|
|
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Returns true if passed in tax code ID
|
|
/// is used as the default anywhere in global settings
|
|
/// </summary>
|
|
/// <param name="TaxCodeID"></param>
|
|
/// <returns></returns>
|
|
public bool TaxCodeIsADefault(Guid TaxCodeID)
|
|
{
|
|
if(this.mTaxPartPurchaseID==TaxCodeID) return true;
|
|
if(this.mTaxPartSaleID==TaxCodeID) return true;
|
|
if(this.mTaxRateSaleID==TaxCodeID) return true;
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// Maximum file size that users can store in the database
|
|
/// </summary>
|
|
[DefaultValue(50)]
|
|
public int MaxFileSizeMB//case 73
|
|
{
|
|
get
|
|
{
|
|
return this.mMaxFileSizeMB;
|
|
}
|
|
set
|
|
{
|
|
if (bReadOnly)
|
|
ThrowSetError();
|
|
else
|
|
{
|
|
if (value > 50) value = 50;
|
|
if (mMaxFileSizeMB != value)
|
|
{
|
|
mMaxFileSizeMB = value;
|
|
MarkDirty();
|
|
|
|
}
|
|
}
|
|
}
|
|
}
|
|
/// <summary>
|
|
/// Flag - indicates if current user can open the wiki page for this object
|
|
/// Note that in this case there is a special right "Object.GlobalWikiPage" that is checked instead
|
|
/// of the normal process of checking the companion object's rights because many users may want
|
|
/// to allow all users to edit the global wiki but not allow them to edit the global object itself
|
|
///
|
|
///
|
|
/// This is NOT cached for the lifetime of this object
|
|
/// since it could be hanging around between sessions
|
|
/// </summary>
|
|
|
|
public bool CanWiki//case 73
|
|
{
|
|
get
|
|
{
|
|
|
|
return WikiPage.ShowWikiLink(RootObjectTypes.Global, Address.GlobalAddressID);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// <summary>
|
|
/// Default auto complete minutes for new labor or sched user records
|
|
/// when start date / time is first entered
|
|
/// </summary>
|
|
[DefaultValue(60)]
|
|
public int LaborSchedUserDfltTimeSpan//case 816
|
|
{
|
|
get
|
|
{
|
|
return this.mLaborSchedUserDfltTimeSpan;
|
|
}
|
|
set
|
|
{
|
|
if (bReadOnly)
|
|
ThrowSetError();
|
|
else
|
|
{
|
|
|
|
if (mLaborSchedUserDfltTimeSpan != value)
|
|
{
|
|
mLaborSchedUserDfltTimeSpan = value;
|
|
MarkDirty();
|
|
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Default auto complete minutes for new workorderitemtravel records
|
|
/// when start date / time is first entered
|
|
/// </summary>
|
|
[DefaultValue(60)]
|
|
public int TravelDfltTimeSpan//case 816
|
|
{
|
|
get
|
|
{
|
|
return this.mTravelDfltTimeSpan;
|
|
}
|
|
set
|
|
{
|
|
if (bReadOnly)
|
|
ThrowSetError();
|
|
else
|
|
{
|
|
|
|
if (mTravelDfltTimeSpan != value)
|
|
{
|
|
mTravelDfltTimeSpan = value;
|
|
MarkDirty();
|
|
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//case 1382
|
|
/// <summary>
|
|
/// Default is false
|
|
/// If true, notification deliveries via SMTP (SMTP/SMS) that fail
|
|
/// because Generator can not contact and log into the SMTP server will be
|
|
/// kept and retried at next generator process.
|
|
///
|
|
/// Note this only applies to failure to connect to the smtp server, notifications that have other
|
|
/// reasons for not being delivered (i.e. bad email address etc) will still be removed after failed delivery.
|
|
///
|
|
/// If this is false then any failure to deliver a notification via SMTP will result in that notification being
|
|
/// removed permanently. This is the original behaviour.
|
|
/// </summary>
|
|
[DefaultValue(false)]
|
|
public bool SMTPRetry
|
|
{
|
|
get
|
|
{
|
|
return this.mSMTPRetry;
|
|
}
|
|
set
|
|
{
|
|
if (bReadOnly)
|
|
ThrowSetError();
|
|
else
|
|
{
|
|
if (mSMTPRetry != value)
|
|
{
|
|
mSMTPRetry = value;
|
|
MarkDirty();
|
|
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/// <summary>
|
|
/// Form controls to hide as set by administrator
|
|
/// </summary>
|
|
public System.Collections.Generic.List<string> HiddenControls
|
|
{
|
|
get
|
|
{
|
|
if (mHiddenControls == null)
|
|
{
|
|
mHiddenControls = new System.Collections.Generic.List<string>();
|
|
|
|
}
|
|
|
|
return mHiddenControls;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Add a control to the hidden controls collection
|
|
/// </summary>
|
|
/// <param name="sControl"></param>
|
|
[Browsable(false)]
|
|
public void AddHiddenControl(string sControl)
|
|
{
|
|
if (!HiddenControls.Contains(sControl))
|
|
{
|
|
HiddenControls.Add(sControl);
|
|
MarkDirty();
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Remove a control from the hidden controls collection
|
|
/// </summary>
|
|
/// <param name="sControl"></param>
|
|
[Browsable(false)]
|
|
public void RemoveHiddenControl(string sControl)
|
|
{
|
|
if (HiddenControls.Contains(sControl))
|
|
{
|
|
HiddenControls.Remove(sControl);
|
|
MarkDirty();
|
|
}
|
|
}
|
|
|
|
|
|
//case 1346
|
|
/// <summary>
|
|
/// Title above signature pad
|
|
/// </summary>
|
|
[DefaultValue("Please sign below")]
|
|
public string SignatureTitle
|
|
{
|
|
get
|
|
{
|
|
return mSignatureTitle;
|
|
}
|
|
set
|
|
{
|
|
if (bReadOnly)
|
|
ThrowSetError();
|
|
else
|
|
{
|
|
if (mSignatureTitle != value)
|
|
{
|
|
mSignatureTitle = value;
|
|
MarkDirty();
|
|
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// Text above signature area below title
|
|
///
|
|
/// </summary>
|
|
[DefaultValue("By signing below you agree to terms for service provided")]
|
|
public string SignatureHeader
|
|
{
|
|
get
|
|
{
|
|
return mSignatureHeader;
|
|
}
|
|
set
|
|
{
|
|
if (bReadOnly)
|
|
ThrowSetError();
|
|
else
|
|
{
|
|
if (mSignatureHeader != value)
|
|
{
|
|
mSignatureHeader = value;
|
|
MarkDirty();
|
|
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Text below signature area
|
|
///
|
|
/// </summary>
|
|
[DefaultValue("")]
|
|
public string SignatureFooter
|
|
{
|
|
get
|
|
{
|
|
return mSignatureFooter;
|
|
}
|
|
set
|
|
{
|
|
if (bReadOnly)
|
|
ThrowSetError();
|
|
else
|
|
{
|
|
if (mSignatureFooter != value)
|
|
{
|
|
mSignatureFooter = value;
|
|
MarkDirty();
|
|
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
//case 1392
|
|
/// <summary>
|
|
/// Scheduled user default time for new records when choosing start date other than today
|
|
/// </summary>
|
|
public string SchedUserNonTodayStartTime
|
|
{
|
|
get
|
|
{
|
|
mSchedUserNonTodayStartTime.FormatString="t";
|
|
return mSchedUserNonTodayStartTime.Text;
|
|
}
|
|
set
|
|
{
|
|
if (bReadOnly)
|
|
ThrowSetError();
|
|
else
|
|
{
|
|
SmartDate sd = new SmartDate();
|
|
sd.Text = value;
|
|
if (!AyaBizUtils.SmartDateEquals(mSchedUserNonTodayStartTime, sd))
|
|
{
|
|
if (!sd.IsEmpty)
|
|
{
|
|
sd.Date = new DateTime(DateTime.Today.Year, DateTime.Today.Month, DateTime.Today.Day, sd.Date.Hour, sd.Date.Minute, sd.Date.Second);
|
|
}
|
|
mSchedUserNonTodayStartTime = sd;
|
|
|
|
MarkDirty();
|
|
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
//case 1487
|
|
/// <summary>
|
|
/// Default is true
|
|
/// Turns on or off automatic refresh of main grids in AyaNova for windows
|
|
/// </summary>
|
|
[DefaultValue(true)]
|
|
public bool MainGridAutoRefresh
|
|
{
|
|
get
|
|
{
|
|
return this.mMainGridAutoRefresh;
|
|
}
|
|
set
|
|
{
|
|
if (bReadOnly)
|
|
ThrowSetError();
|
|
else
|
|
{
|
|
if (mMainGridAutoRefresh != value)
|
|
{
|
|
mMainGridAutoRefresh = value;
|
|
MarkDirty();
|
|
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Throw an error when a read only user
|
|
/// tries to set a property
|
|
/// (this should normally never be called unless someone is using the developer api since the UI
|
|
/// should prevent it from happening initially)
|
|
/// </summary>
|
|
private void ThrowSetError()
|
|
{
|
|
throw new System.Security.SecurityException
|
|
(
|
|
string.Format
|
|
(
|
|
LocalizedTextTable.GetLocalizedTextDirect("Error.Security.NotAuthorizedToChange"),
|
|
LocalizedTextTable.GetLocalizedTextDirect("O.Global")
|
|
)
|
|
);
|
|
}
|
|
#endregion
|
|
|
|
#region System.Object overrides
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public override string ToString()
|
|
{
|
|
return "Global" ;
|
|
}
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
/// <param name="obj"></param>
|
|
/// <returns></returns>
|
|
public override bool Equals(Object obj)
|
|
{
|
|
return true;
|
|
}
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public override int GetHashCode()
|
|
{
|
|
return ("Global" ).GetHashCode();
|
|
}
|
|
#endregion
|
|
|
|
#region Static methods
|
|
|
|
|
|
/// <summary>
|
|
/// Fetch the one and only Global item
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public static Global GetItem()
|
|
{
|
|
|
|
|
|
|
|
if(!AyaBizUtils.Lite && !User.IsAdmin && ScheduleableUserCountFetcher.GetItem()>AyaBizUtils.GlobalX.ScheduleableUsers )//case 1172
|
|
{
|
|
throw new System.Security.SecurityException(
|
|
"\r\nLICENSE VIOLATION\r\n\r\n" +
|
|
"AyaNova has detected an attempt to circumvent AyaNova licensing.\r\n\r\n" +
|
|
"This database is licensed for " + AyaBizUtils.GlobalX.ScheduleableUsers.ToString() + " scheduleable users\r\n" +
|
|
"Currently there are " + ScheduleableUserCountFetcher.GetItem().ToString() + " scheduleable users active.\r\n\r\n" +
|
|
"All AyaNova accounts other than Manager have been suspended until\r\n" +
|
|
"the extra scheduleable users that are not licensed are\r\n" +
|
|
"set inactive, removed or changed to non-scheduleable users\r\n"+
|
|
"to bring this database back into license compliance.\r\n\r\n"+
|
|
|
|
"Directly editing the AyaNova database can lead to lost or damaged data\r\n"+
|
|
"Please ensure no one tampers with the AyaNova database in future.\r\n\r\n" +
|
|
"** License violations are logged for the protection of the licensee and licensor **");
|
|
}
|
|
|
|
//if(AyaBizUtils.Right("Object.Global")>(int)SecurityLevelTypes.NoAccess || AyaBizUtils.IsGenerator )
|
|
return (Global)DataPortal.Fetch(new Criteria());
|
|
// else
|
|
// throw new System.Security.SecurityException(
|
|
// string.Format(
|
|
// LocalizedTextTable.GetLocalizedTextDirect("Error.Security.NotAuthorizedToRetrieve"),
|
|
// LocalizedTextTable.GetLocalizedTextDirect("O.Global")));
|
|
}
|
|
|
|
[Browsable(false)]
|
|
internal static Global GetItemInternally()
|
|
{
|
|
//Internal version used by util class to verify license etc
|
|
//no security check because this will be fetched
|
|
//before a user has logged in.
|
|
//however it cannot be called from outside this assembly so it's not a risk
|
|
return (Global)DataPortal.Fetch(new Criteria());
|
|
|
|
|
|
}
|
|
|
|
|
|
#endregion
|
|
|
|
#region DAL DATA ACCESS
|
|
|
|
#region Custom concurrency check
|
|
private static void CheckSafeToUpdate(System.DateTime LastUpdated)
|
|
{
|
|
DBCommandWrapper dbCommandWrapper = DBUtil.DB.GetSqlStringCommandWrapper(
|
|
"SELECT aModified, aModifier FROM aGlobal;"
|
|
);
|
|
|
|
SafeDataReader r = new SafeDataReader(DBUtil.DB.ExecuteReader(dbCommandWrapper));
|
|
if(r.Read())
|
|
{
|
|
if(!DBUtil.DatesAreEqualish(DBUtil.ToUTC(LastUpdated),r.GetSmartDate("aModified").Date))
|
|
{
|
|
Guid gModifier=r.GetGuid("aModifier");
|
|
r.Close();
|
|
dbCommandWrapper.Command.Parameters.Clear();
|
|
dbCommandWrapper.AddInParameter("@ID",DbType.Guid,gModifier);
|
|
dbCommandWrapper.Command.CommandText="SELECT aFirstName, aLastName FROM aUser WHERE aID = @ID";
|
|
r=new SafeDataReader(DBUtil.DB.ExecuteReader(dbCommandWrapper));
|
|
if(r.Read())
|
|
{
|
|
string sUser=r.GetString("aFirstName") + " " + r.GetString("aLastName");
|
|
r.Close();
|
|
|
|
throw new System.Exception(string.Format(LocalizedTextTable.GetLocalizedTextDirect("Error.DB.RecordModifiedExternally"),"Global",sUser));
|
|
|
|
}
|
|
|
|
}
|
|
else
|
|
{
|
|
//de nada
|
|
r.Close();
|
|
return;
|
|
}
|
|
}
|
|
//Added: 20-June-2006
|
|
r.Close();
|
|
}
|
|
#endregion
|
|
|
|
#region Fetch
|
|
|
|
///
|
|
/// <param name="Criteria"></param>
|
|
protected override void DataPortal_Fetch(object Criteria)
|
|
{
|
|
//set to false to load items initially
|
|
bReadOnly=false;
|
|
|
|
Criteria crit = (Criteria)Criteria;
|
|
SafeDataReader dr = null;
|
|
|
|
try
|
|
{
|
|
dr=DBUtil.GetReaderFromSQLString("SELECT * FROM aGlobal;");
|
|
if(!dr.Read())
|
|
DBUtil.ThrowFetchError("Global");
|
|
|
|
//Standard fields
|
|
//mID=dr.GetGuid("aID");
|
|
mCreated=DBUtil.ToLocal(dr.GetSmartDate("aCreated"));
|
|
mModified=DBUtil.ToLocal(dr.GetSmartDate("aModified"));
|
|
mCreator=dr.GetGuid("aCreator");
|
|
mModifier=dr.GetGuid("aModifier");
|
|
|
|
|
|
//Global fields
|
|
mTaxPartSaleID=dr.GetGuid("aTaxPartSaleID");
|
|
|
|
//case 1858
|
|
if(AyaBizUtils.Lite)
|
|
mTaxPartPurchaseID = Guid.Empty;
|
|
else
|
|
mTaxPartPurchaseID=dr.GetGuid("aTaxPartPurchaseID");
|
|
mTaxRateSaleID=dr.GetGuid("aTaxRateSaleID");
|
|
|
|
//case 2104 added in schema 46
|
|
if (AyaBizUtils.GlobalX.DBSchemaVersion > 45)
|
|
{
|
|
mDefaultServiceTemplateID = dr.GetGuid("ADEFAULTSERVICETEMPLATEID");
|
|
}
|
|
|
|
mAllowScheduleConflicts=dr.GetBoolean("AALLOWSCHEDULECONFLICTS");//AALLOWSCHEDULECONFLICTS
|
|
mDefaultLanguage=dr.GetString("aLanguage");
|
|
//mUseRegions=dr.GetBoolean("aUseRegions");
|
|
mWorkorderClosedStatus=dr.GetGuid("aWorkorderClosedStatus");
|
|
mWorkorderSummaryTemplate=dr.GetString("aWorkorderSummaryTemplate");
|
|
|
|
mUseInventory=dr.GetBoolean("aUseInventory");
|
|
|
|
mDefaultUnitNameDisplayFormat=(UnitNameDisplayFormats)dr.GetInt16("aUnitNameFormat");
|
|
mDefaultScheduleableUserNameDisplayFormat=(ScheduleableUserNameDisplayFormats)dr.GetInt16("aScheduleableUserNameFormat");
|
|
mCJKIndex=dr.GetBoolean("aCJKIndex");
|
|
mDefaultPartDisplayFormat=(PartDisplayFormats)dr.GetInt16("aPartFormat");
|
|
|
|
mWorkorderCloseByAge=dr.GetInt32("aWorkorderCloseByAge");
|
|
//case 2102 added in schema 64
|
|
if (AyaBizUtils.GlobalX.DBSchemaVersion > 63)
|
|
{
|
|
//case 73
|
|
mMaxFileSizeMB = dr.GetInt32("aMaxFileSizeMB");
|
|
}
|
|
|
|
//case 2102 added in schema 78
|
|
if (AyaBizUtils.GlobalX.DBSchemaVersion > 77)
|
|
{
|
|
//case 816
|
|
mLaborSchedUserDfltTimeSpan = dr.GetInt32("aLaborSchedUserDfltTimeSpan");
|
|
mTravelDfltTimeSpan = dr.GetInt32("aTravelDfltTimeSpan");
|
|
}
|
|
|
|
//Notification fields
|
|
mUseNotification=dr.GetBoolean("aUseNotification");
|
|
mNotifySMTPHost=dr.GetString("aNotifySMTPHost");
|
|
mNotifySMTPAccount=dr.GetString("aNotifySMTPAccount");
|
|
mNotifySMTPPassword=dr.GetString("aNotifySMTPPassword");
|
|
mNotifySMTPFrom=dr.GetString("aNotifySMTPFrom");
|
|
|
|
//case 2100 added in schema 99
|
|
if (AyaBizUtils.GlobalX.DBSchemaVersion > 98)
|
|
{
|
|
//case 1382
|
|
mSMTPRetry = dr.GetBoolean("ASMTPRETRY");
|
|
}
|
|
|
|
//case 2100 added in schema 89
|
|
if (AyaBizUtils.GlobalX.DBSchemaVersion > 88)
|
|
{
|
|
//case 1136
|
|
mNotifySMTPEncryptionMethod = dr.GetString("aNotifyEncryption");
|
|
}
|
|
|
|
mCoordinateStyle=(CoordinateTypes)dr.GetInt16("aCoordinateStyle");
|
|
mDefaultLatitude=(LatitudeHemisphere)dr.GetInt16("aDefaultLatitude");
|
|
mDefaultLongitude=(LongitudeHemisphere)dr.GetInt16("aDefaultLongitude");
|
|
|
|
//case 1194
|
|
mHiddenControls = new System.Collections.Generic.List<string>();
|
|
|
|
//case 2099 update to 7.4 throws exception on aformcustom not a column
|
|
string s = string.Empty;
|
|
if (AyaBizUtils.GlobalX.DBSchemaVersion > 99)
|
|
{
|
|
s = dr.GetString("AFORMCUSTOM");
|
|
}
|
|
if (!string.IsNullOrWhiteSpace(s))
|
|
{
|
|
mHiddenControls.AddRange(s.Split(','));
|
|
}
|
|
|
|
|
|
//case 2099 sigs added in schema 104
|
|
if (AyaBizUtils.GlobalX.DBSchemaVersion > 103)
|
|
{
|
|
//case 1346
|
|
mSignatureTitle = dr.GetString("ASIGNATURETITLE");
|
|
mSignatureHeader = dr.GetString("ASIGNATUREHEADER");
|
|
mSignatureFooter = dr.GetString("ASIGNATUREFOOTER");
|
|
}
|
|
|
|
//case 2099 added in schema 108
|
|
if (AyaBizUtils.GlobalX.DBSchemaVersion > 108)
|
|
{
|
|
//case 1392
|
|
mSchedUserNonTodayStartTime = DBUtil.ToLocal(dr.GetSmartDate("ASCHEDUSERNONTODAYSTARTTIME"));
|
|
}
|
|
|
|
//case 2099 added in schema 110
|
|
if (AyaBizUtils.GlobalX.DBSchemaVersion > 109)
|
|
{
|
|
|
|
//case 1487
|
|
mMainGridAutoRefresh = dr.GetBoolean("AMAINGRIDAUTOREFRESH");
|
|
}
|
|
|
|
if(dr!=null) dr.Close();
|
|
|
|
|
|
/*
|
|
Load child collection objects
|
|
*/
|
|
|
|
//GoToAddress
|
|
dr=DBUtil.GetReaderFromSQLString("SELECT * " +
|
|
"FROM AADDRESS WHERE aRootObjectID=@ID AND " +
|
|
"aRootObjectType=1 AND AADDRESSTYPE=2",Address.GlobalAddressID);
|
|
if(!dr.Read())
|
|
{
|
|
mGoToAddress=Address.NewItem();
|
|
mGoToAddress.RootObjectID=Address.GlobalAddressID;
|
|
mGoToAddress.RootObjectType=RootObjectTypes.Global;
|
|
mGoToAddress.AddressType=AddressTypes.Physical;
|
|
}
|
|
else
|
|
{
|
|
mGoToAddress=Address.GetItem(dr);
|
|
}
|
|
|
|
if(dr!=null) dr.Close();
|
|
//MailToAddress
|
|
dr=DBUtil.GetReaderFromSQLString("SELECT * " +
|
|
"FROM AADDRESS WHERE aRootObjectID=@ID AND " +
|
|
"aRootObjectType=1 AND AADDRESSTYPE=1",Address.GlobalAddressID);
|
|
if(!dr.Read())
|
|
{
|
|
mMailToAddress=Address.NewItem();
|
|
mMailToAddress.RootObjectID=Address.GlobalAddressID;
|
|
mMailToAddress.RootObjectType=RootObjectTypes.Global;
|
|
mMailToAddress.AddressType=AddressTypes.Postal;
|
|
}
|
|
else
|
|
{
|
|
mMailToAddress=Address.GetItem(dr);
|
|
}
|
|
|
|
|
|
//Load start seed values
|
|
Object o=DBUtil.GetScalarFromSQLString(
|
|
"SELECT MAX(aServiceNumber) FROM aWorkorderService"
|
|
);
|
|
if(o==null || o==System.DBNull.Value) o=0;
|
|
mWorkorderServiceStartSeed=(int)o;
|
|
|
|
|
|
o=DBUtil.GetScalarFromSQLString(
|
|
"SELECT MAX(aQuoteNumber) FROM aWorkorderQuote"
|
|
);
|
|
if(o==null || o==System.DBNull.Value) o=0;
|
|
mQuoteNumberStartSeed=(int)o;
|
|
|
|
|
|
o=DBUtil.GetScalarFromSQLString(
|
|
"SELECT MAX(aPONumber) FROM aPurchaseOrder"
|
|
);
|
|
if(o==null || o==System.DBNull.Value) o=0;
|
|
mPurchaseOrderStartSeed=(int)o;
|
|
|
|
|
|
o=DBUtil.GetScalarFromSQLString(
|
|
"SELECT MAX(AADJUSTMENTNUMBER) FROM aPartInventoryAdjustment"
|
|
);
|
|
if(o==null || o==System.DBNull.Value) o=0;
|
|
mInventoryAdjustmentStartSeed=(int)o;
|
|
|
|
|
|
|
|
|
|
}
|
|
finally
|
|
{
|
|
if(dr!=null) dr.Close();
|
|
}
|
|
MarkOld();
|
|
//special code to update the identity with selected values
|
|
//so that a remote dataportal has access to the values for the biz objects
|
|
|
|
//BUGBUG
|
|
|
|
BusinessPrincipal p = ((BusinessPrincipal)Thread.CurrentPrincipal);
|
|
p.CJKIndex=mCJKIndex;
|
|
p.UseNotification=this.mUseNotification;
|
|
|
|
|
|
|
|
//Get access rights level
|
|
bReadOnly=AyaBizUtils.Right("Object.Global")<(int)SecurityLevelTypes.ReadWrite;
|
|
}
|
|
#endregion
|
|
|
|
#region Update
|
|
/// <summary>
|
|
/// Called by DataPortal to delete/add/update data into the database
|
|
/// </summary>
|
|
protected override void DataPortal_Update()
|
|
{
|
|
|
|
// If not a new record, check if record was modified
|
|
//by another user since original retrieval:
|
|
if(!IsNew)
|
|
CheckSafeToUpdate(this.mModified.Date);
|
|
|
|
#region Delete
|
|
if(IsDeleted)
|
|
{
|
|
throw new System.ApplicationException
|
|
(
|
|
string.Format
|
|
(
|
|
LocalizedTextTable.GetLocalizedTextDirect("Error.Object.NotDeleteable"),
|
|
LocalizedTextTable.GetLocalizedTextDirect("O.Global")
|
|
)
|
|
);
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Add / Update
|
|
|
|
//get modification time temporarily, if update succeeds then
|
|
//set to this time
|
|
System.DateTime dtModified = DBUtil.CurrentWorkingDateTime;
|
|
|
|
DBCommandWrapper cm = null;
|
|
|
|
//UPDATE IS THE ONLY VALID OPERATION FOR THE GLOBAL OBJECT
|
|
|
|
cm=DBUtil.GetCommandFromSQL(
|
|
"UPDATE aGlobal SET aTaxPartSaleID=@TaxPartSaleID, " +
|
|
"aTaxRateSaleID=@TaxRateSaleID,aTaxPartPurchaseID=@TaxPartPurchaseID, " +
|
|
"ADEFAULTSERVICETEMPLATEID=@ADEFAULTSERVICETEMPLATEID, " +
|
|
//"aQuoteTemplate=@DefaultQuoteTemplate, " +
|
|
//"aPurchaseOrderTemplate=@DefaultPurchaseOrderTemplate, " +
|
|
/*"aSpellCheck=@SpellCheck, " +*/
|
|
"aMaxFileSizeMB=@MaxFileSizeMB, " +//case 73
|
|
"aLaborSchedUserDfltTimeSpan=@LaborSchedUserDfltTimeSpan, aTravelDfltTimeSpan=@TravelDfltTimeSpan, " + //case 816
|
|
"AALLOWSCHEDULECONFLICTS=@AllowScheduleConflicts, " +
|
|
"aLanguage=@DefaultLanguage, " +
|
|
"aWorkorderClosedStatus=@WorkorderClosedStatus, " +
|
|
"aWorkorderSummaryTemplate=@WorkorderSummaryTemplate, " +
|
|
"aModifier=@CurrentUserID, aUseInventory=@UseInventory, " +
|
|
"aUnitNameFormat=@DefaultUnitNameDisplayFormat, " +
|
|
"aScheduleableUserNameFormat=@DefaultScheduleableUserNameDisplayFormat, " +
|
|
"aWorkorderCloseByAge=@WorkorderCloseByAge,aUseNotification=@UseNotification, " +
|
|
"aNotifySMTPHost=@NotifySMTPHost, aNotifySMTPAccount=@NotifySMTPAccount, " +
|
|
"aNotifySMTPPassword=@NotifySMTPPassword,aNotifySMTPFrom=@NotifySMTPFrom, " +
|
|
"aNotifyEncryption=@NOTIFYENCRYPTION, ASMTPRETRY=@SMTPRETRY, AFORMCUSTOM=@FORMCUSTOM, " +//case 1194
|
|
"aCJKIndex=@CJKIndex,aPartFormat=@PartFormat,aCoordinateStyle=@CoordinateStyle, " +
|
|
"ASIGNATURETITLE=@SIGNATURETITLE, ASIGNATUREHEADER=@SIGNATUREHEADER, ASIGNATUREFOOTER=@SIGNATUREFOOTER, " + // CASE 1346
|
|
"ASCHEDUSERNONTODAYSTARTTIME=@SCHEDUSERNONTODAYSTARTTIME, AMAINGRIDAUTOREFRESH=@MAINGRIDAUTOREFRESH, " + // case 1392 //case 1487
|
|
"aDefaultLatitude=@DefaultLatitude, aDefaultLongitude=@DefaultLongitude, aModified=@Modified;"
|
|
);
|
|
|
|
|
|
|
|
|
|
//Standard fields
|
|
cm.AddInParameter("@CurrentUserID",DbType.Guid, CurrentUserID);
|
|
cm.AddInParameter("@Modified",DbType.DateTime, DBUtil.ToUTC(dtModified));
|
|
|
|
//Global fields
|
|
cm.AddInParameter("@TaxPartSaleID", DbType.Guid, mTaxPartSaleID);
|
|
|
|
//case 1858
|
|
if(AyaBizUtils.Lite)
|
|
mTaxPartPurchaseID = Guid.Empty;
|
|
|
|
cm.AddInParameter("@TaxPartPurchaseID", DbType.Guid, mTaxPartPurchaseID);
|
|
cm.AddInParameter("@TaxRateSaleID", DbType.Guid, mTaxRateSaleID);
|
|
cm.AddInParameter("@ADEFAULTSERVICETEMPLATEID", DbType.Guid, mDefaultServiceTemplateID);
|
|
//cm.AddInParameter("@DefaultQuoteTemplate", DbType.Guid, mDefaultQuoteTemplate);
|
|
//cm.AddInParameter("@DefaultPurchaseOrderTemplate", DbType.Guid, mDefaultPurchaseOrderTemplate);
|
|
//cm.AddInParameter("@SpellCheck", DbType.Boolean, mSpellCheck);
|
|
cm.AddInParameter("@AllowScheduleConflicts", DbType.Boolean, mAllowScheduleConflicts);
|
|
cm.AddInParameter("@DefaultLanguage", DbType.String, mDefaultLanguage);
|
|
//cm.AddInParameter("@UseRegions", DbType.Boolean, mUseRegions);
|
|
cm.AddInParameter("@WorkorderClosedStatus", DbType.Guid, mWorkorderClosedStatus);
|
|
cm.AddInParameter("@WorkorderSummaryTemplate", DbType.String, mWorkorderSummaryTemplate);
|
|
cm.AddInParameter("@UseInventory", DbType.Boolean, mUseInventory);
|
|
cm.AddInParameter("@DefaultUnitNameDisplayFormat", DbType.Int16, (int)mDefaultUnitNameDisplayFormat);
|
|
cm.AddInParameter("@DefaultScheduleableUserNameDisplayFormat", DbType.Int16, (int)mDefaultScheduleableUserNameDisplayFormat);
|
|
cm.AddInParameter("@CJKIndex", DbType.Boolean, mCJKIndex);
|
|
cm.AddInParameter("@PartFormat", DbType.Int16, (int)mDefaultPartDisplayFormat);
|
|
cm.AddInParameter("@WorkorderCloseByAge", DbType.Int32, mWorkorderCloseByAge);
|
|
cm.AddInParameter("@UseNotification", DbType.Boolean, mUseNotification);
|
|
cm.AddInParameter("@NotifySMTPHost", DbType.String, mNotifySMTPHost);
|
|
cm.AddInParameter("@NotifySMTPAccount", DbType.String, mNotifySMTPAccount);
|
|
cm.AddInParameter("@NotifySMTPPassword", DbType.String, mNotifySMTPPassword);
|
|
cm.AddInParameter("@NotifySMTPFrom", DbType.String, mNotifySMTPFrom);
|
|
|
|
//case 1136
|
|
cm.AddInParameter("@NOTIFYENCRYPTION", DbType.String, mNotifySMTPEncryptionMethod);
|
|
|
|
//case 1382
|
|
cm.AddInParameter("@SMTPRETRY", DbType.Boolean, mSMTPRetry);
|
|
|
|
//case 1194
|
|
//Load generic list back into string for saving
|
|
System.Text.StringBuilder sbFormCustom = new StringBuilder();
|
|
foreach (string s in mHiddenControls)
|
|
{
|
|
sbFormCustom.Append(s);
|
|
sbFormCustom.Append(",");
|
|
}
|
|
if (sbFormCustom.Length > 0)
|
|
sbFormCustom.Length = sbFormCustom.Length - 1;
|
|
|
|
cm.AddInParameter("@FORMCUSTOM", DbType.String, sbFormCustom.ToString());
|
|
|
|
cm.AddInParameter("@CoordinateStyle",DbType.Int16,(int)mCoordinateStyle);
|
|
cm.AddInParameter("@DefaultLatitude",DbType.Int16,(int)mDefaultLatitude);
|
|
cm.AddInParameter("@DefaultLongitude",DbType.Int16,(int)mDefaultLongitude);
|
|
|
|
cm.AddInParameter("@MaxFileSizeMB", DbType.Int32, mMaxFileSizeMB);//case 73
|
|
cm.AddInParameter("@LaborSchedUserDfltTimeSpan", DbType.Int32, mLaborSchedUserDfltTimeSpan);//case 816
|
|
cm.AddInParameter("@TravelDfltTimeSpan", DbType.Int32, mTravelDfltTimeSpan);//case 816
|
|
|
|
//case 1346
|
|
cm.AddInParameter("@SIGNATURETITLE", DbType.String, mSignatureTitle);
|
|
cm.AddInParameter("@SIGNATUREHEADER", DbType.String, mSignatureHeader);
|
|
cm.AddInParameter("@SIGNATUREFOOTER", DbType.String, mSignatureFooter);
|
|
|
|
//case 1392
|
|
cm.AddInParameter("@SCHEDUSERNONTODAYSTARTTIME", DbType.DateTime, DBUtil.ToUTC(mSchedUserNonTodayStartTime).DBValue);
|
|
|
|
//case 1487
|
|
cm.AddInParameter("@MAINGRIDAUTOREFRESH", DbType.Boolean, mMainGridAutoRefresh);
|
|
|
|
using (IDbConnection connection = DBUtil.DB.GetConnection())
|
|
{
|
|
connection.Open();
|
|
IDbTransaction transaction = connection.BeginTransaction();
|
|
|
|
try
|
|
{
|
|
|
|
|
|
//Update child objects
|
|
//GoToAddress
|
|
mGoToAddress.Update(RootObjectTypes.Global,Address.GlobalAddressID,AddressTypes.Physical,transaction);
|
|
|
|
//MailToAddress
|
|
mMailToAddress.Update(RootObjectTypes.Global,Address.GlobalAddressID,AddressTypes.Postal,transaction);
|
|
|
|
DBUtil.DB.ExecuteNonQuery(cm, transaction);
|
|
|
|
MarkOld();//db is now synched with object
|
|
// Commit the transaction
|
|
transaction.Commit();
|
|
|
|
}
|
|
catch
|
|
{
|
|
// Rollback transaction
|
|
transaction.Rollback();
|
|
throw;
|
|
}
|
|
finally
|
|
{
|
|
connection.Close();
|
|
}
|
|
//Successful update so
|
|
//change modification time to match
|
|
this.mModified.Date=dtModified;
|
|
|
|
//special code to update the identity with the global settings values
|
|
//so that a remote dataportal has access to these value for the biz objects
|
|
BusinessPrincipal p = ((BusinessPrincipal)Thread.CurrentPrincipal);
|
|
p.CJKIndex=mCJKIndex;
|
|
p.UseNotification=this.mUseNotification;
|
|
}
|
|
|
|
//Set new seed values if required
|
|
if(this.mUpdateWorkorderServiceStartSeed)
|
|
{
|
|
WorkorderService.SetVisibleIDNumber(this.mWorkorderServiceStartSeed);
|
|
}
|
|
|
|
if(this.mUpdateQuoteNumberStartSeed)
|
|
{
|
|
WorkorderQuote.SetVisibleIDNumber(this.mQuoteNumberStartSeed);
|
|
}
|
|
|
|
if(this.mUpdatePurchaseOrderStartSeed)
|
|
{
|
|
PurchaseOrder.SetVisibleIDNumber(this.mPurchaseOrderStartSeed);
|
|
}
|
|
|
|
if(this.mUpdateInventoryAdjustmentStartSeed)
|
|
{
|
|
PartInventoryAdjustment.SetVisibleIDNumber(this.mInventoryAdjustmentStartSeed);
|
|
}
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
//case 1035
|
|
//this is to trigger a reset of the cached global settings object in the dataportal
|
|
//this ensures when global is saved that the changes are reflected when running via dataportal
|
|
DBManager.ResetCacheInDataPortal.Reset();
|
|
|
|
}
|
|
#endregion
|
|
|
|
#endregion
|
|
|
|
#region Override IsValid / IsDirty etc etc
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
[Browsable(false)]
|
|
public override bool IsValid
|
|
{
|
|
get
|
|
{
|
|
return base.IsValid && mGoToAddress.IsValid && mMailToAddress.IsValid;
|
|
}
|
|
}
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
[Browsable(false)]
|
|
public override bool IsDirty
|
|
{
|
|
get
|
|
{
|
|
return base.IsDirty || mGoToAddress.IsDirty || mMailToAddress.IsDirty;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
#region criteria
|
|
/// <summary>
|
|
/// Criteria for identifying existing object
|
|
/// </summary>
|
|
[Serializable]
|
|
private class Criteria
|
|
{
|
|
//public Guid ID;
|
|
public Criteria()
|
|
{
|
|
|
|
}
|
|
|
|
}
|
|
#endregion
|
|
}//end Global
|
|
|
|
}//end namespace GZTW.AyaNova.BLL |