initial commit
This commit is contained in:
commit
252dac3143
1516 changed files with 694271 additions and 0 deletions
379
App_Code/Data Access Layer/Shared/BaseFormulaEvaluator.vb
Normal file
379
App_Code/Data Access Layer/Shared/BaseFormulaEvaluator.vb
Normal file
|
@ -0,0 +1,379 @@
|
|||
Imports Microsoft.VisualBasic
|
||||
Imports System.IO
|
||||
Imports BaseClasses.Data
|
||||
Imports Ciloci.Flee
|
||||
Imports BaseClasses.Utils
|
||||
|
||||
Namespace Persons.Data
|
||||
|
||||
''' <summary>
|
||||
''' The BaseFormulaEvaluator class evaluates a formula passed to the Evaluate function.
|
||||
''' </summary>
|
||||
''' <remarks></remarks>
|
||||
Public Class BaseFormulaEvaluator
|
||||
''' <summary>
|
||||
''' Evaluator class that actually evaluates the formula.
|
||||
''' This is available as a public property, so additional options
|
||||
''' can be added to the evaluator from the calling functions.
|
||||
''' </summary>
|
||||
Protected _evaluator As ExpressionContext
|
||||
Public ReadOnly Property Evaluator() As ExpressionContext
|
||||
Get
|
||||
Return _evaluator
|
||||
End Get
|
||||
End Property
|
||||
|
||||
''' <summary>
|
||||
''' The Variables collection allows the passing of the variables to the Evaluator
|
||||
''' </summary>
|
||||
Public ReadOnly Property Variables() As Ciloci.Flee.VariableCollection
|
||||
Get
|
||||
Return Evaluator.Variables
|
||||
End Get
|
||||
End Property
|
||||
|
||||
''' <summary>
|
||||
''' DataSource object from which each of the variables are
|
||||
''' determined. This allows direct referencing of the
|
||||
''' fields in the DataSource. For example, if the DataSource
|
||||
''' is an Order_Details record, then the formula can use something like:
|
||||
''' = UnitPrice * Quantity * (1 - Discount)
|
||||
''' to calculate the Extended Price.
|
||||
''' </summary>
|
||||
Private _dataSource As BaseRecord = Nothing
|
||||
Public Property DataSource() As BaseRecord
|
||||
Get
|
||||
Return _dataSource
|
||||
End Get
|
||||
Set(ByVal value As BaseRecord)
|
||||
_dataSource = value
|
||||
End Set
|
||||
End Property
|
||||
|
||||
|
||||
|
||||
''' <summary>
|
||||
''' Create a new evaluator and prepare for evaluation.
|
||||
''' </summary>
|
||||
Public Sub New(Optional ByVal mainObj As Object = Nothing)
|
||||
|
||||
' pass mainObj to contructor so that formula like = mainObj.<functionName> can be evaluated
|
||||
If mainObj Is Nothing Then
|
||||
_evaluator = New ExpressionContext()
|
||||
Else
|
||||
_evaluator = New ExpressionContext(mainObj)
|
||||
End If
|
||||
|
||||
|
||||
' The order of adding types is important. First we add our own
|
||||
' formula functions, followed by the generic types.
|
||||
|
||||
Evaluator.Imports.AddType(GetType(BaseFormulaUtils))
|
||||
|
||||
' ADVANCED. For advanced usage, generic types can also be imported into
|
||||
' the formula evaluator. This is done by adding types of some generic types
|
||||
' such as Math, DateTime, Convert, and String. For example, if you add the
|
||||
' Convert type, you can then use Convert.ToDecimal("string"). The second
|
||||
' parameter to the AddType is the namespace that will be used in the formula.
|
||||
' These functions expect a certain type. For example, Math functions expect
|
||||
' a Double for the most part. If you pass a string, they will throw an exception.
|
||||
' As such, we have written separate functions in FormulaUtils that are more
|
||||
' loosely-typed than the standard libraries available here.
|
||||
' Examples:
|
||||
Evaluator.Imports.AddType(GetType(Math), "Math")
|
||||
Evaluator.Imports.AddType(GetType(DateTime), "DateTime")
|
||||
Evaluator.Imports.AddType(GetType(Convert), "Convert")
|
||||
Evaluator.Imports.AddType(GetType(String), "String")
|
||||
|
||||
' We want a loosely-typed evaluation language - so do not
|
||||
' type-check any variables.
|
||||
Evaluator.Options.Checked = False
|
||||
|
||||
' Our policy is to always treat real numbers as Decimal instead of
|
||||
' Double or Single to make it consistent across the entire
|
||||
' evaluator.
|
||||
Evaluator.Options.RealLiteralDataType = RealLiteralDataType.Decimal
|
||||
|
||||
' The variable event handler handles the variables based on the DataSource.
|
||||
AddHandler _evaluator.Variables.ResolveVariableType, AddressOf variables_ResolveVariableType
|
||||
AddHandler _evaluator.Variables.ResolveVariableValue, AddressOf variables_ResolveVariableValue
|
||||
End Sub
|
||||
|
||||
|
||||
|
||||
''' <summary>
|
||||
''' Evaluate the expression passed in as the string
|
||||
''' </summary>
|
||||
''' <param name="expression">The input whose absolute value is to be found.</param>
|
||||
''' <returns>The result of the evaluation. Can we be any data type including string, datetime, decimal, etc.</returns>
|
||||
Public Overridable Function Evaluate(ByVal expression As String) As Object
|
||||
If IsNothing(expression) Then Return Nothing
|
||||
If expression = "" Then Return ""
|
||||
|
||||
' Strip of the = in the front of the forumula - the Expression evaluator
|
||||
' does not need it. Also, make sure to trim the result to remove any
|
||||
' spaces in the front and the back.
|
||||
expression = expression.TrimStart(New Char() {"="c, " "c}).Trim()
|
||||
|
||||
|
||||
' If there are any exceptions when parsing or evaluating, they are
|
||||
' thrown so that the end user can see the error. As such, there is no
|
||||
' Try-Catch block here.
|
||||
Try
|
||||
Dim eDynamic As IDynamicExpression = _evaluator.CompileDynamic(expression)
|
||||
Return eDynamic.Evaluate()
|
||||
Catch ex As Exception
|
||||
Return "ERROR: " & ex.Message
|
||||
End Try
|
||||
End Function
|
||||
|
||||
|
||||
''' <summary>
|
||||
''' Return the type of the given variable if it exists in the data source.
|
||||
''' If the Return Type is Nothing, the evaluator assumes this is an invalid
|
||||
''' variable and tries other methods to get its value.
|
||||
''' </summary>
|
||||
''' <param name="sender">The sender that sent this event.</param>
|
||||
''' <param name="e">The event argument. Set e.VariableType.</param>
|
||||
Protected Sub variables_ResolveVariableType(ByVal sender As Object, ByVal e As ResolveVariableTypeEventArgs)
|
||||
Dim col As BaseColumn
|
||||
|
||||
' Returning Nothing indicates that we do not recognize this variable.
|
||||
e.VariableType = Nothing
|
||||
|
||||
' If no DataSource was set, we do not have variables that we can use
|
||||
' directly.
|
||||
If IsNothing(DataSource) Then Return
|
||||
|
||||
Try
|
||||
' Find a column in the datasource using a variable name.
|
||||
col = DataSource.TableAccess.TableDefinition.ColumnList.GetByCodeName(e.VariableName)
|
||||
If IsNothing(col) Then
|
||||
' if the variable name ended with "DefaultValue", remmove it and then try to get the column name again.
|
||||
If BaseClasses.Utils.InvariantLCase(e.VariableName).EndsWith("defaultvalue") Then
|
||||
col = DataSource.TableAccess.TableDefinition.ColumnList.GetByCodeName(e.VariableName.Substring(0, e.VariableName.Length - 12))
|
||||
End If
|
||||
End If
|
||||
|
||||
If IsNothing(col) Then
|
||||
Return
|
||||
End If
|
||||
|
||||
Select Case col.ColumnType
|
||||
Case BaseColumn.ColumnTypes.Number, _
|
||||
BaseColumn.ColumnTypes.Percentage, _
|
||||
BaseColumn.ColumnTypes.Star
|
||||
' By default, all our internal data types use Decimal.
|
||||
' This may result in problems when using the Math library
|
||||
' but it reduces the problem by allowing us to loosely-type
|
||||
' all data source properties.
|
||||
e.VariableType = GetType(Decimal)
|
||||
|
||||
Case BaseColumn.ColumnTypes.Currency
|
||||
' Convert currency into decimal to allow easier use in formulas
|
||||
e.VariableType = GetType(Decimal)
|
||||
|
||||
Case BaseColumn.ColumnTypes.Boolean
|
||||
' Boolean data types are maintained as Boolean and not
|
||||
' converted to Integer as the Binary data type is.
|
||||
e.VariableType = GetType(Boolean)
|
||||
|
||||
Case BaseColumn.ColumnTypes.Credit_Card_Date, _
|
||||
BaseColumn.ColumnTypes.Date
|
||||
' Use DateTme even for Credit Card Date.
|
||||
e.VariableType = GetType(DateTime)
|
||||
|
||||
Case BaseColumn.ColumnTypes.Country, _
|
||||
BaseColumn.ColumnTypes.Credit_Card_Number, _
|
||||
BaseColumn.ColumnTypes.Email, _
|
||||
BaseColumn.ColumnTypes.Password, _
|
||||
BaseColumn.ColumnTypes.String, _
|
||||
BaseColumn.ColumnTypes.Unique_Identifier, _
|
||||
BaseColumn.ColumnTypes.USA_Phone_Number, _
|
||||
BaseColumn.ColumnTypes.USA_State, _
|
||||
BaseColumn.ColumnTypes.USA_Zip_Code, _
|
||||
BaseColumn.ColumnTypes.Very_Large_String, _
|
||||
BaseColumn.ColumnTypes.Web_Url
|
||||
' For the purpose of formula's, all of the above field types
|
||||
' are treated as strings.
|
||||
e.VariableType = GetType(String)
|
||||
|
||||
Case BaseColumn.ColumnTypes.Binary, _
|
||||
BaseColumn.ColumnTypes.File, _
|
||||
BaseColumn.ColumnTypes.Image
|
||||
' For the purpose of formula's we ignore BLOB fields since they
|
||||
' cannot be used in any calculations or string functions.
|
||||
e.VariableType = Nothing
|
||||
|
||||
Case Else
|
||||
' Unknown data type.
|
||||
e.VariableType = Nothing
|
||||
End Select
|
||||
|
||||
Catch ex As Exception
|
||||
' Ignore the error in case we cannot find the variable or its type - simply say that
|
||||
' the Variable Type is Nothing - implying that we do not recognize this variable.
|
||||
End Try
|
||||
End Sub
|
||||
|
||||
|
||||
''' <summary>
|
||||
''' Return the value of the given variable if it exists in the data source
|
||||
''' </summary>
|
||||
''' <param name="sender">The input whose absolute value is to be found.</param>
|
||||
''' <param name="e">The input whose absolute value is to be found.</param>
|
||||
Protected Sub variables_ResolveVariableValue(ByVal sender As Object, ByVal e As ResolveVariableValueEventArgs)
|
||||
Dim col As BaseColumn
|
||||
|
||||
' Default value is Nothing
|
||||
e.VariableValue = Nothing
|
||||
|
||||
' If no DataSource was set, we do not have variables that we can use
|
||||
' directly. We should not get here since the request for Type should have
|
||||
' caught this.
|
||||
If IsNothing(DataSource) Then Return
|
||||
|
||||
Try
|
||||
|
||||
' Find a column in the datasource using a variable name.
|
||||
col = DataSource.TableAccess.TableDefinition.ColumnList.GetByCodeName(e.VariableName)
|
||||
If IsNothing(col) Then
|
||||
' if the variable name ended with "DefaultValue", remmove it and then try to get the column name again.
|
||||
If BaseClasses.Utils.InvariantLCase(e.VariableName).EndsWith("defaultvalue") Then
|
||||
col = DataSource.TableAccess.TableDefinition.ColumnList.GetByCodeName(e.VariableName.Substring(0, e.VariableName.Length - 12))
|
||||
|
||||
Select Case col.ColumnType
|
||||
Case BaseColumn.ColumnTypes.Number, _
|
||||
BaseColumn.ColumnTypes.Percentage, _
|
||||
BaseColumn.ColumnTypes.Star
|
||||
' The Number and Percentage values are saved as Single. So we first
|
||||
' retrieve the Single value and then convert to Decimal. Our policy is
|
||||
' always to return Decimal (never to return Single or Double) to be constent
|
||||
' and avoid type conversion in the evaluator.
|
||||
e.VariableValue = BaseFormulaUtils.ParseDecimal(col.DefaultValue)
|
||||
|
||||
Case BaseColumn.ColumnTypes.Currency
|
||||
e.VariableValue = Me.DataSource.GetValue(col).ToDecimal
|
||||
|
||||
Case BaseColumn.ColumnTypes.Boolean
|
||||
e.VariableValue = col.DefaultValue
|
||||
Case BaseColumn.ColumnTypes.Credit_Card_Date, _
|
||||
BaseColumn.ColumnTypes.Date
|
||||
e.VariableValue = BaseFormulaUtils.ParseDate(col.DefaultValue)
|
||||
|
||||
Case BaseColumn.ColumnTypes.Country, _
|
||||
BaseColumn.ColumnTypes.Credit_Card_Number, _
|
||||
BaseColumn.ColumnTypes.Email, _
|
||||
BaseColumn.ColumnTypes.Password, _
|
||||
BaseColumn.ColumnTypes.String, _
|
||||
BaseColumn.ColumnTypes.Unique_Identifier, _
|
||||
BaseColumn.ColumnTypes.USA_Phone_Number, _
|
||||
BaseColumn.ColumnTypes.USA_State, _
|
||||
BaseColumn.ColumnTypes.USA_Zip_Code, _
|
||||
BaseColumn.ColumnTypes.Very_Large_String, _
|
||||
BaseColumn.ColumnTypes.Web_Url
|
||||
e.VariableValue = col.DefaultValue
|
||||
|
||||
Case BaseColumn.ColumnTypes.File, _
|
||||
BaseColumn.ColumnTypes.Image
|
||||
' Can't do anything here.
|
||||
e.VariableValue = Nothing
|
||||
|
||||
Case Else
|
||||
e.VariableValue = Nothing
|
||||
End Select
|
||||
End If
|
||||
|
||||
|
||||
Else
|
||||
|
||||
|
||||
Select Case col.ColumnType
|
||||
Case BaseColumn.ColumnTypes.Number, _
|
||||
BaseColumn.ColumnTypes.Percentage, _
|
||||
BaseColumn.ColumnTypes.Star
|
||||
' The Number and Percentage values are saved as Single. So we first
|
||||
' retrieve the Single value and then convert to Decimal. Our policy is
|
||||
' always to return Decimal (never to return Single or Double) to be constent
|
||||
' and avoid type conversion in the evaluator.
|
||||
e.VariableValue = Decimal.Parse(Me.DataSource.GetValue(col).ToDouble().ToString())
|
||||
|
||||
Case BaseColumn.ColumnTypes.Currency
|
||||
e.VariableValue = Me.DataSource.GetValue(col).ToDecimal
|
||||
|
||||
Case BaseColumn.ColumnTypes.Boolean
|
||||
e.VariableValue = Me.DataSource.GetValue(col).ToBoolean
|
||||
|
||||
Case BaseColumn.ColumnTypes.Credit_Card_Date, _
|
||||
BaseColumn.ColumnTypes.Date
|
||||
e.VariableValue = Me.DataSource.GetValue(col).ToDateTime
|
||||
|
||||
Case BaseColumn.ColumnTypes.Country, _
|
||||
BaseColumn.ColumnTypes.Credit_Card_Number, _
|
||||
BaseColumn.ColumnTypes.Email, _
|
||||
BaseColumn.ColumnTypes.Password, _
|
||||
BaseColumn.ColumnTypes.String, _
|
||||
BaseColumn.ColumnTypes.Unique_Identifier, _
|
||||
BaseColumn.ColumnTypes.USA_Phone_Number, _
|
||||
BaseColumn.ColumnTypes.USA_State, _
|
||||
BaseColumn.ColumnTypes.USA_Zip_Code, _
|
||||
BaseColumn.ColumnTypes.Very_Large_String, _
|
||||
BaseColumn.ColumnTypes.Web_Url
|
||||
e.VariableValue = Me.DataSource.GetValue(col).ToString
|
||||
|
||||
Case BaseColumn.ColumnTypes.File, _
|
||||
BaseColumn.ColumnTypes.Image
|
||||
' Can't do anything here.
|
||||
e.VariableValue = Nothing
|
||||
|
||||
Case Else
|
||||
e.VariableValue = Nothing
|
||||
End Select
|
||||
|
||||
|
||||
End If
|
||||
|
||||
|
||||
Catch ex As Exception
|
||||
' Ignore the error in case we cannot find the variable or its type - simply say that
|
||||
' the Variable Type is Nothing - implying that we do not recognize this variable.
|
||||
End Try
|
||||
End Sub
|
||||
|
||||
'This method returns true or false value stating whether to apply GlobalWhereClause to a particular page or not.
|
||||
'Use this method to exclude pages from applying Global Where Clauses sepcified in Batch Meister Wizard.
|
||||
Public Shared Function ShouldApplyGlobalWhereClause(ByVal globalWhereClauseFormula As String) As Boolean
|
||||
|
||||
If System.Web.HttpContext.Current Is Nothing Then
|
||||
Return False
|
||||
End If
|
||||
|
||||
'Comment out the following code if you want to apply GlobalWhereClause to SignIn and SignOut pages
|
||||
If Not (BaseClasses.Configuration.ApplicationSettings.Current.AuthenticationType = BaseClasses.Configuration.SecurityConstants.None) Then
|
||||
If Not BaseClasses.Configuration.ApplicationSettings.Current.SecurityDisabled Then
|
||||
If globalWhereClauseFormula.ToLower().Contains("userid()") Or globalWhereClauseFormula.ToLower().Contains("username()") Or _
|
||||
globalWhereClauseFormula.ToLower().Contains("roles()") Then
|
||||
|
||||
If (System.Web.HttpContext.Current.Request.Url.AbsolutePath.ToLower().Contains(BaseClasses.Configuration.ApplicationSettings.Current.SignInPageUrl.ToString().ToLower())) Then
|
||||
Return False
|
||||
End If
|
||||
If (System.Web.HttpContext.Current.Request.Url.AbsolutePath.ToLower().Contains(BaseClasses.Configuration.ApplicationSettings.Current.SignedOutPageUrl.ToString().ToLower())) Then
|
||||
Return False
|
||||
End If
|
||||
If (System.Web.HttpContext.Current.Request.Url.AbsolutePath.ToLower().Contains(BaseClasses.Configuration.ApplicationSettings.Current.ForgotUserPageUrl.ToString().ToLower())) Then
|
||||
Return False
|
||||
End If
|
||||
If (System.Web.HttpContext.Current.Request.Url.AbsolutePath.ToLower().Contains(BaseClasses.Configuration.ApplicationSettings.Current.SendUserInfoEmailUrl.ToString().ToLower())) Then
|
||||
Return False
|
||||
End If
|
||||
|
||||
End If
|
||||
End If
|
||||
End If
|
||||
Return True
|
||||
End Function
|
||||
|
||||
|
||||
End Class
|
||||
|
||||
End Namespace
|
Loading…
Add table
Add a link
Reference in a new issue