using System;
using System.IO;
using System.Runtime.CompilerServices;
using System.Text;
using System.Xml;
using System.Linq;
using System.Collections.Generic;
using DataContracts;
using System.Text.RegularExpressions;

namespace Ato.EN.IntegrationServices.CodeGenerationRDTIS
{

    public partial class RDTIS2023Validator
    {
        /// <summary>
        /// The max parameter name length is restricted by the SBR1 and SBR2 schemas - the lowest common denominator of SBR 1 is used as the default
        /// </summary>
        private int _maxParameterNameLength;

        /// <summary>
        /// The max parameter value length is restricted by the SBR1 and SBR2 schemas
        /// </summary>
        private int _maxParameterValueLength;

        /// <summary>
        /// The SBR1 and ebms3 schemas do not allow parameter names or values to be the empty string
        /// </summary>
        private string _emptyParameterValue;

        /// <summary>
        /// The report parameter
        /// </summary>
        private RDTIS2023 report;

        /// <summary>
        /// The response parameter
        /// </summary>
        public List<ProcessMessageDocument> response {get; private set;}

        /// <summary>
        /// Initializes a new instance of the <see cref="RDTIS2023Validator" /> class.
        /// </summary>
        /// <param name="maxParameterNameLength">Maximum length of the parameter name.</param>
        /// <param name="maxParameterValueLength">Maximum length of the parameter value.</param>
        /// <param name="emptyParameterValue">This value will be used in place of any parameter values that result in a null or empty value.</param>
        public RDTIS2023Validator(int maxParameterNameLength = 20, int maxParameterValueLength = 4096, string emptyParameterValue = "EMPTY")
        {
            _maxParameterNameLength = maxParameterNameLength;
            _maxParameterValueLength = maxParameterValueLength;
            _emptyParameterValue = emptyParameterValue;
            this.response = new List<ProcessMessageDocument>();
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="RDTIS2023Validator" /> class.
        /// </summary>
        /// <param name="report">Report variable </param>                
        /// <param name="maxParameterNameLength">Maximum length of the parameter name.</param>
        /// <param name="maxParameterValueLength">Maximum length of the parameter value.</param>
        /// <param name="emptyParameterValue">This value will be used in place of any parameter values that result in a null or empty value.</param>
        public RDTIS2023Validator(RDTIS2023 reportIn, int maxParameterNameLength = 20, int maxParameterValueLength = 4096, string emptyParameterValue = "EMPTY"):this(maxParameterNameLength,maxParameterValueLength,emptyParameterValue)
        {                   
            this.ConsumedReport = reportIn;                    
        }

        #region Functions
        private static IEnumerable<string> Union(IEnumerable<string> list1, IEnumerable<string> list2)
        {
            IEnumerable<string> response;

            if (list1 == null && list2 == null)
            {
                response = null;
            }
            else if (list1 == null)
            {
                response = list2.Distinct();
            }
            else if (list2 == null)
            {
                response = list1.Distinct();
            }
            else
            {
                response = list1.Union(list2);
            }

            return response;
        }

        private static bool IsMatch(int? field, string expression, RegexOptions options = RegexOptions.None)
        {
            if (field == null)
                return false;
            else
                return Regex.IsMatch(Convert.ToString(field.Value), expression, options);
        }

        private static bool IsMatch(string field, string expression, RegexOptions options = RegexOptions.None)
        {
            if (field == null)
                return false;
            else
                return Regex.IsMatch(field, expression, options);
        }

        // This is just context and tuple counts where they are integer values - easier that changing the parsing logic to just return the value
        private static int Count(int count)
        {
            return count;
        }


        private static int Count<T>(IEnumerable<T> values)
        {
            return values == null ? 0 : values.Where(f => f != null).Count();
        }


        private static int Count<T>(ICollection<T> values)
        {
            return values == null ? 0 : values.Where(f => f != null).Count();
        }

        private static bool exists(bool value)
        {
            return value;
        }

        private static string GetValueOrEmpty(bool? val)
        {
            return (val.HasValue) ? val.ToString().ToLower() : string.Empty;
        }

        private static string GetValueOrEmptyDate(DateTime? val)
        {
            return (val.HasValue) ? val.Value.ToString("yyyy-MM-dd") : string.Empty;
        }

        private static string GetValueOrEmptyDate(string val)
        {
            DateTime dateTimeOut;
            if (DateTime.TryParse(val, out dateTimeOut))
            {
                return dateTimeOut.ToString("yyyy-MM-dd");
            }
            return !string.IsNullOrWhiteSpace(val) ? val : string.Empty;
        }

        private static string GetValueOrEmptyDateTime(string val)
        {
            DateTime dateTimeOut;
            if (DateTime.TryParse(val, out dateTimeOut))
            {
                return dateTimeOut.ToString("yyyy-MM-ddTHH:mm:ssZ");
            }
            return !string.IsNullOrWhiteSpace(val) ? val : string.Empty;
        }

        private static string GetValueOrEmptyDateTime(DateTime? val)
        {
            return (val.HasValue) ? val.Value.ToString("yyyy-MM-ddTHH:mm:ssZ") : string.Empty;
        }

        private static string GetValueOrEmpty(string val)
        {
            return !string.IsNullOrWhiteSpace(val) ? val : string.Empty;
        }

        private static string GetValueOrEmpty(decimal? val)
        {
            return (val.HasValue) ? val.ToString() : string.Empty;
        }

        private static string GetValueOrEmpty(int? val)
        {
            return (val.HasValue) ? val.ToString() : string.Empty;
        }

         /// <summary>
         /// Get string value between [first] a and [last] b.
         /// </summary>
        public static string Between(string value, string a, string b)
        {
            int posA = value.IndexOf(a);
            int posB = value.LastIndexOf(b);
            if (posA == -1)
            {
                return "";
            }
            if (posB == -1)
            {
                return "";
            }
            int adjustedPosA = posA + a.Length;
            if (adjustedPosA >= posB)
            {
                return "";
            }
            return value.Substring(adjustedPosA, posB - adjustedPosA);
        }

         /// <summary>
         /// Get string value after [first] a.
         /// </summary>
        public static string Before(string value, string a)
        {
            int posA = value.IndexOf(a);
            if (posA == -1)
            {
                return "";
            }
            return value.Substring(0, posA);
        }

         /// <summary>
         /// Get string value after [last] a.
         /// </summary>
        public static string After(string value, string a)
        {
            int posA = value.LastIndexOf(a);
            if (posA == -1)
            {
                return "";
            }
            int adjustedPosA = posA + a.Length;
            if (adjustedPosA >= value.Length)
            {
                return "";
            }
            return value.Substring(adjustedPosA);
        }

        private static int Length(object field)
        {
            if (field == null)
            return 0;
            else
            return field.ToString().Trim().Length;
        }

        private static bool NotSameValues(IEnumerable<object> nodes)
        {
            if (nodes == null)
                return false;

            object[] nodesArray = nodes.Cast<object>().ToArray();
            return NotSameValues(nodesArray);
        }

        private static bool NotSameValues(params object[] nodes)
        {
            if (nodes == null)
                return false;

            return (from x in nodes select x).Distinct().Count() != 1;
        }

        private static bool HasDuplicateValues(IEnumerable<DateTime> nodes)
        {
            if (nodes == null)
                return false;

            object[] nodesArray = nodes.Cast<object>().ToArray();
            return HasDuplicateValues(nodesArray);
        }

        private static bool HasDuplicateValues(IEnumerable<DateTime?> nodes)
        {
            if (nodes == null)
                return false;

            object[] nodesArray = nodes.Cast<object>().ToArray();
            return HasDuplicateValues(nodesArray);
        }

        private static bool NotSameValues(IEnumerable<DateTime> nodes)
        {
            if (nodes == null)
                return false;

            object[] nodesArray = nodes.Cast<object>().ToArray();
            return NotSameValues(nodesArray);
        }

        private static bool NotSameValues(IEnumerable<DateTime?> nodes)
        {
            if (nodes == null)
                return false;

            object[] nodesArray = nodes.Cast<object>().ToArray();
            return NotSameValues(nodesArray);
        }

        private static bool HasDuplicateValues(IEnumerable<object> nodes)
        {
            if (nodes == null)
                return false;

            object[] nodesArray = nodes.Cast<object>().ToArray();
            return HasDuplicateValues(nodesArray);
        }

        private static bool HasDuplicateValues(params object[] nodes)
        {
           if (nodes == null)
                return false;

            nodes = nodes.Where(x => x != null).ToArray();
            return !((from x in nodes select x).Distinct().Count() == nodes.Count());
        
        }

        private int DuplicateValueIndex(IEnumerable<object> values)
        {
            int response = 0;
            var hashset = new HashSet<object>();
            foreach (var value in values)
            {
                if (!hashset.Add(value))
                {
                    return response;
                }
                response++;
            }
            return response;
        }

        private int DuplicateValueIndex<T>(IEnumerable<T?> values) where T : struct
        {
            int response = 0;
            var hashset = new HashSet<T?>();
            foreach (var value in values)
            {
                if (!hashset.Add(value))
                {
                    return response;
                }
                response++;
            }
            return response;
        }

        private static bool IsDate(object value)
        {
            DateTime dateValue;
            return (value != null && DateTime.TryParse(value.ToString(), out dateValue));
        }

        public DateTime AsDate(string dateAsString)
        {
            DateTime response = DateTime.MinValue;
            DateTime date;

            if (DateTime.TryParse(dateAsString, out date))
            {
                response = date;
            }

            return response;
        }

        public DateTime Date(DateTime? datetime)
        {                   
            return datetime.GetValueOrDefault().Date;
        }

				//The logic in After function expects "---" for day and "--" for month. 
				//Since hyphen was missing the date always returned null
        public DateTime? ConvertToDate(int day, int month, int year)
        {
					return ConvertToDate(day == 0 ? null : "---" + day.ToString(), month == 0 ? null : "--" + month.ToString(), year == 0 ? null : year.ToString());
        }

        public DateTime? ConvertToDate(string day, string month, string year)
        {
            DateTime? response;
            DateTime result;

            if (year == null || month == null || day == null)
            {
                return null;
            }
            string dateAsString = year + "-" + After(month, "--") + "-" + After(day, "---");
            if (DateTime.TryParse(dateAsString, out result))
            {
                response = result;
            }
            else
            {
                response = null;
            }
            return response;
        }


        public DateTime? ConvertToDate(string day, string month, int year)
        {
            DateTime? response;
            DateTime result;

            if (year == 0 || month == null || day == null)
            {
                return null;
            }
            string dateAsString = year.ToString() + "-" + After(month, "--") + "-" + After(day, "---");
            if (DateTime.TryParse(dateAsString, out result))
            {
                response = result;
            }
            else
            {
                response = null;
            }
            return response;
        }


        private static int Day(string dateAsString)
        {
            int response = 0;
            DateTime date;

            if (DateTime.TryParse(dateAsString, out date))
            {
                response = date.Day;
            }

            return response;
        }


        private static int Day(DateTime? date)
        {
            if (date == null)
                return 0;
            else
                return date.Value.Day;

        }


        private static string Month(string dateAsString)
        {
            string response = null;
            DateTime date;

            if (DateTime.TryParse(dateAsString, out date))
            {
                response = date.ToString("MMMM");
            }
            else
            {
                return "NotAMonth";
            }

            return response;
        }

        private static string Month(DateTime? date)
        {
            if (date == null)
                return "NotAMonth";
            else
                return date.Value.ToString("MMMM");
        }


        private static int MonthAsInt(string dateAsString)
        {
            int response = 0;
            DateTime date;

            if (DateTime.TryParse(dateAsString, out date))
            {
                response = date.Month;
            }

            return response;
        }

        private static int MonthAsInt(DateTime? date)
        {
            if (date == null)
            {
                return 0;
            }
            return date.Value.Month;
        }


        private static int Year(string dateAsString)
        {
            int response = 0;
            DateTime date;

            if (DateTime.TryParse(dateAsString, out date))
            {
                response = date.Year;
            }

            return response;
        }

        private static int Year(DateTime? date)
        {
            if (date == null)
                return 0;
            else
                return date.Value.Year;
        }


        private static int CurrentFinancialYear()
        {
            return DateToFinancialYear(DateTime.Now, 7);
        }

        private static int FinancialYear(string dateAsString)
        {
            return DateToFinancialYear(dateAsString, 7);
        }

        private static int FinancialYear(DateTime? date)
        {
            return DateToFinancialYear(date, 7);
        }

        private static int DateToFinancialYear(string dateAsString, int startingMonth)
        {
            int response = 0;
            DateTime date;
            if (DateTime.TryParse(dateAsString, out date))
            {
                response = DateToFinancialYear(date, startingMonth);
            }

            return response;
        }
        private static int DateToFinancialYear(DateTime? date, int startingMonth)
        {
            int response;
            if (date == null)
            {
                response = 0;
            }
            else
            {
                int year = date.Value.Year;
                int month = date.Value.Month;

                if (startingMonth > month)
                    response = year;
                else
                    response = year + 1;
            }
            return response;
        }


        private static int FBTYear(string dateAsString)
        {
            int response = 0;
            DateTime date;

            if (DateTime.TryParse(dateAsString, out date))
                response = FBTYear(date);
            return response;
        }

        private static int FBTYear(DateTime? date)
        {
            if (date == null)
            {
                return 0;
            }
            else
            {
                if (date.Value.Month > 3)
                    return date.Value.Year + 1;
                else
                    return date.Value.Year;
            }
        }

        private static DateTime? AddMonthsToDate(DateTime? dateTime, int months)
        {
            return dateTime == null ? null : (DateTime?)dateTime.Value.AddMonths(months);
        }

        private static bool IsNumeric(object value)
        {
            decimal numbervalue;
            return (value != null && decimal.TryParse(value.ToString(), out numbervalue));
        }

        private static bool NotMonetary(decimal? field, string sign, int digits, int decimals)
        {
            if (field == null)
            {
                return false;
            }
            else
            {
                string signExpression;
                string decimalExpression;
                int digitsToUse = digits - decimals;

                if (sign == "U")
                    signExpression = "^";
                else
                    signExpression = "^-?";

                if (decimals > 0)
                    decimalExpression = @"(\.\d{1," + decimals + "})?$";
                else
                    decimalExpression = @"$";

                return !(Regex.IsMatch(field.Value.ToString("0.#########################"), signExpression + @"\d{1," + digitsToUse + "}" + decimalExpression));
            }
        }

        private static bool NotNumeric(decimal? field, string sign, int digits, int decimals)
        {
            if (field == null)
            {
                return false;
            }
            else
            {
                string signExpression;
                string decimalExpression;
                int digitsToUse = digits - decimals;

                if (sign == "U")
                    signExpression = "^";
                else
                    signExpression = "^-?";

                if (decimals > 0)
                    decimalExpression = @"(\.\d{1," + decimals + "})?$";
                else
                    decimalExpression = @"$";

                return !(Regex.IsMatch(field.Value.ToString("0.#########################"), signExpression + @"\d{1," + digitsToUse + "}" + decimalExpression));
            }
        }

        private static bool NotNumeric(int? field, string sign, int digits, int decimals = 0)
        {
            if (field == null)
            {
                return false;
            }
            else
            {
                string signExpression;

                if (sign == "U")
                    signExpression = "^";
                else
                    signExpression = "^-?";

                return !(Regex.IsMatch(field.Value.ToString(), signExpression + @"\d{1," + digits + "}$"));
            }
        }

        private static bool NotNumeric(long? field, string sign, int digits, int decimals = 0)
        {
            if (field == null)
            {
                return false;
            }
            else
            {
                string signExpression;

                if (sign == "U")
                    signExpression = "^";
                else
                    signExpression = "^-?";

                return !(Regex.IsMatch(field.Value.ToString(), signExpression + @"\d{1," + digits + "}$"));
            }
        }


        private static bool OutsideRange(decimal field, decimal expression, int range)
        {
            bool response;

            response = (field < (expression - range)) || (field > (expression + range));

            return response;
        }


        private static bool FailsUSIAlgorithm(string usi, string abn)
        {
            bool response = true;
            if (usi == null || abn == null)
            {
                response = false;
            }
            else
            {
                usi = usi.Trim();
                abn = abn.Trim();
                if (usi.Length == 14)
                {
                    int numeric;
                    if (usi.Substring(0, 11) == abn && int.TryParse(usi.Substring(11, 3), out numeric))
                        response = false;

                }
                else if (usi.Length == 9)
                {

                    if (Regex.IsMatch(usi, @"^([a-zA-Z]{3}\d{4}[a-zA-Z]{2})$"))
                        response = false;
                }
            }
            return response;
        }

        private static bool FailsTANAlgorithm(string tan)
        {
            bool response;
            decimal decimalTan;

            if (tan == null)
                return false;

            tan = tan.Trim();

            if (!decimal.TryParse(tan, out decimalTan))
                return true;

            if (tan.Length != 8)
                return true;

            decimal tanSum =
                7 * int.Parse(tan.Substring(0, 1)) +
                9 * int.Parse(tan.Substring(1, 1)) +
                8 * int.Parse(tan.Substring(2, 1)) +
                4 * int.Parse(tan.Substring(3, 1)) +
                6 * int.Parse(tan.Substring(4, 1)) +
                3 * int.Parse(tan.Substring(5, 1)) +
                5 * int.Parse(tan.Substring(6, 1)) +
                1 * int.Parse(tan.Substring(7, 1));

            if ((tanSum % 11) == 0)
                response = false;
            else
                response = true;

            return response;
        }


        private static bool FailsABNAlgorithm(string abn)
        {
            bool response;
            decimal decimalAbn;

            if (abn == null)
                return false;

            abn = abn.Trim();

            if (!decimal.TryParse(abn, out decimalAbn))
                return true;

            if (abn.Length != 11)
                return true;

            decimal abnSum =
                10 * (int.Parse(abn.Substring(0, 1)) - 1) +
                1 * int.Parse(abn.Substring(1, 1)) +
                3 * int.Parse(abn.Substring(2, 1)) +
                5 * int.Parse(abn.Substring(3, 1)) +
                7 * int.Parse(abn.Substring(4, 1)) +
                9 * int.Parse(abn.Substring(5, 1)) +
                11 * int.Parse(abn.Substring(6, 1)) +
                13 * int.Parse(abn.Substring(7, 1)) +
                15 * int.Parse(abn.Substring(8, 1)) +
                17 * int.Parse(abn.Substring(9, 1)) +
                19 * int.Parse(abn.Substring(10, 1));

            if ((abnSum % 89) == 0)
                response = false;
            else
                response = true;

            return response;
        }
        private static bool FailsACNAlgorithm(string acn)
        {
            bool response;
            decimal decimalAbn;
            if (acn == null)
                return false;

            acn = acn.Trim();

            if (!decimal.TryParse(acn, out decimalAbn))
                return true;

            if (acn.Length != 9)
                return true;

            decimal abnSum =
                8 * int.Parse(acn.Substring(0, 1)) +
                7 * int.Parse(acn.Substring(1, 1)) +
                6 * int.Parse(acn.Substring(2, 1)) +
                5 * int.Parse(acn.Substring(3, 1)) +
                4 * int.Parse(acn.Substring(4, 1)) +
                3 * int.Parse(acn.Substring(5, 1)) +
                2 * int.Parse(acn.Substring(6, 1)) +
                1 * int.Parse(acn.Substring(7, 1));

            decimal checkDigit = int.Parse(acn.Substring(8, 1));
            decimal acnRemainder = abnSum % 10;

            if (((10 - acnRemainder) % 10) == checkDigit)
                response = false;
            else
                response = true;

            return response;
        }


        private static bool FailsTFNAlgorithm(string tfn)
        {
            bool response;
            decimal decimalTfn;

            if (tfn == null)
                return false;

            tfn = tfn.Trim();
            tfn = Regex.Replace(tfn, "^0+", "");

            if (!decimal.TryParse(tfn, out decimalTfn))
                return true;

            if (tfn.Length < 8)
                return true;


            decimal tfn1To7Sum =
                1 * int.Parse(tfn.Substring(0, 1)) +
                4 * int.Parse(tfn.Substring(1, 1)) +
                3 * int.Parse(tfn.Substring(2, 1)) +
                7 * int.Parse(tfn.Substring(3, 1)) +
                5 * int.Parse(tfn.Substring(4, 1)) +
                8 * int.Parse(tfn.Substring(5, 1)) +
                6 * int.Parse(tfn.Substring(6, 1));

            decimal tfn8 = 9 * int.Parse(tfn.Substring(7, 1));

            if (tfn.Length == 8)
            {
                decimal tFNLg8WSum9 = 10 * int.Parse(tfn.Substring(7, 1));
                decimal tFNLg8WSum = tfn1To7Sum + tFNLg8WSum9;

                if ((tFNLg8WSum % 11) == 0)
                    response = false;
                else
                    response = true;
            }
            else if (tfn.Length == 9)
            {
                decimal tfn9 = 10 * int.Parse(tfn.Substring(8, 1));
                decimal tFNLg9WSum = tfn1To7Sum + tfn8 + tfn9;

                if ((tFNLg9WSum % 11) == 0)
                    response = false;
                else
                    response = true;
            }
            else
            {
                response = true;
            }

            return response;
        }


        private static decimal ConditionalValue(bool expression, decimal? trueVal, decimal? falseVal)
        {
             return expression ? trueVal.GetValueOrDefault() : falseVal.GetValueOrDefault();
        }

        private static decimal AsNumeric(string value)
        {
             decimal numberValue;
             decimal.TryParse(value, out numberValue);
             return numberValue;
        }

        private static bool RegexMatch(int? field, string expression, string flags="")
        {
            return IsMatch(field, expression, GetRegexOption(flags));
        }

        private static bool RegexMatch(string field, string expression, string flags="")
        {
            return IsMatch(field, expression, GetRegexOption(flags));
        }

        private static RegexOptions GetRegexOption(string flags)
        {
            RegexOptions options = RegexOptions.None;

            char[] characters = flags.ToCharArray();

            foreach (char character in characters)
            {
                switch (character)
                {
                    case 'i':                        
                        options = options | RegexOptions.IgnoreCase;                       
                        break;
                    case 'm':                        
                        options = options | RegexOptions.Multiline;                       
                        break;
                    case 's':                        
                            options = options | RegexOptions.Singleline;                       
                        break;
                    case 'n':                        
                            options = options | RegexOptions.ExplicitCapture;                       
                        break;
                    case 'x':                       
                            options = options | RegexOptions.IgnorePatternWhitespace;                       
                        break;
                }
            }

            return options;
        }

        private static string Substring(object field, int start, int length)
        {
            return field.ToString().Substring(start, length);
        }
        
        /// <summary>
        /// Returns an occurrence index as [occurrenceIndex] of occurrenceIndex > 0, otherwise the empty string
        /// </summary>
        /// <param name="occurrenceIndex">Index of the occurrence.</param>
        /// <returns>Occurrence in XPath [#] format</returns>
        public string OccurrenceIndex(int occurrenceIndex)
        {
            return occurrenceIndex > 0 ? "[" + occurrenceIndex + "]" : "";
        }

        #endregion // Functions

        public RDTIS2023 ConsumedReport { get {return report;} private set {report = value;}}

        private static Dictionary<string, ProcessMessageDocument> _processMessageDocuments = new Dictionary<string,ProcessMessageDocument>();				

        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public List<ProcessMessageDocument> ValidateReport(RDTIS2023 reportIn)
        {
            ProcessMessageDocument processMessage;
            ProcessMessageParameter parameter;
            bool assertion;

            this.ConsumedReport = reportIn;

            // ------------------------------------------------------------------------------
            // Validations are now done in code.
            // This version supports full validation of a report - for those rules that have successfully parsed and could be generated.
            // Generated Validations include:
            //   - Validation logic in C#.
            //   - Production of errors in EBMS, SBR and SWS format.
            // 
            // The generation at this stage does not support the following - and has to be completed manually (later versions of the generation will do this for you)
            //   - Business Rules that did not parse.  The ESR team will help support you where this happens as an effort is being made to rectify these
            //   - You will get TODO tasks for those that the parser could not cope with
            // ------------------------------------------------------------------------------
    #region Manual Rules - Rules marked for manual coding
    
        #region VR.ATO.RDTIS.438109

        /*  VR.ATO.RDTIS.438109
            If Tax rate is provided, then the Tax rate must be one of the following values 30, 30.00, 25, 25.00

        Legacy Rule Format:
            IF [RDTIS78] <> NULL AND ([RDTIS78] <> SET("30", "30.00", "25", "25.00"))
               RETURN VALIDATION MESSAGE
            ENDIF
    
        Technical Business Rule Format:
            ^RDTIS78 <> NULL AND (NotInSet(^RDTIS78, '"30", 30, "25", 25'))

        Data Elements:

        ^RDTIS78 = RDTIS:RP:TaxRate.Designation.Rate
        */
    VRATORDTIS438109(response, report);
    #endregion // VR.ATO.RDTIS.438109

    #region VR.ATO.RDTIS.438111

/*  VR.ATO.RDTIS.438111
            If R&D intensity is provided, then a valid range for R&D intensity is 0.01 - 100.00

        Legacy Rule Format:
            IF [RDTIS82] <> NULL AND ([RDTIS82] <> SET(0.01 - 100.00))
               RETURN VALIDATION MESSAGE
            ENDIF

    Technical Business Rule Format:
            ^RDTIS82 <> NULL AND (NotInSet(^RDTIS82, '0.01-100.00'))

Data Elements:
    
    ^RDTIS82 = RDTIS:RP:NonRefundableTaxOffset:Miscellaneous.ResearchAndDevelopmentIntensity.Rate
    */
    VRATORDTIS438111(response, report);
    #endregion // VR.ATO.RDTIS.438111
#endregion Manual Rules - Rules marked for manual coding

            #region Repeating report.RP_AggregatedTurnover_GroupMemberCollection  
            if (report.RP_AggregatedTurnover_GroupMemberCollection != null)
            {    
                int itemIndex3 = 0;
                foreach (RDTIS2023.RP_AggregatedTurnover_GroupMember groupMember in report.RP_AggregatedTurnover_GroupMemberCollection)
                {
                    itemIndex3++;
                        VRATORDTIS410038(groupMember, itemIndex3);
                        VRATORDTIS410039(groupMember, itemIndex3);
                        VRATORDTIS428258(groupMember, itemIndex3);
                        VRATORDTIS428259(groupMember, itemIndex3);
                        VRATORDTIS428260(groupMember, itemIndex3);
                        VRATORDTIS428261(groupMember, itemIndex3);
                        VRATORDTIS438108(groupMember, itemIndex3);
                    }
                }
        
                #endregion // Foreach loop
                VRATORDTIS438021();
                VRATORDTIS438022();
                VRATORDTIS438024();
                VRATORDTIS438025();
                VRATORDTIS438026();
                VRATORDTIS438037();
                VRATORDTIS438039();
                VRATORDTIS438043();
                VRATORDTIS438049();
                VRATORDTIS438050();
                VRATORDTIS438052();
                VRATORDTIS438053();
                VRATORDTIS438057();
                VRATORDTIS438065();
                VRATORDTIS438066();
                VRATORDTIS438101();
                VRATORDTIS438106();
                VRATORDTIS438107();
                VRATORDTIS438110();
                VRATORDTIS438112();
                VRATORDTIS438113();
                VRATORDTIS438114();
                VRATORDTIS438115();

            foreach (ProcessMessageDocument currentProcessMessage in response)
            {
                if (currentProcessMessage.Parameters != null)
                {
                    foreach (ProcessMessageParameter currentParameter in currentProcessMessage.Parameters)
                    {
                        if (string.IsNullOrEmpty(currentParameter.Name))
                        {
                            currentParameter.Name = _emptyParameterValue;
                        }

                        if (currentParameter.Name.Length > _maxParameterNameLength)
                        {
                            currentParameter.Name = currentParameter.Name.Substring(0, _maxParameterNameLength - 1);
                        }

                        if (string.IsNullOrEmpty(currentParameter.Value))
                        {
                            currentParameter.Value = _emptyParameterValue;
                        }

                        if (currentParameter.Value.Length > _maxParameterValueLength)
                        {
                            currentParameter.Value = currentParameter.Value.Substring(0, _maxParameterValueLength - 1);
                        }
                    }
                }
            }

            return response;
        }
				
			
    
      #region VR.ATO.RDTIS.410038
      [MethodImpl(MethodImplOptions.AggressiveInlining)]
      public virtual void VRATORDTIS410038(RDTIS2023.RP_AggregatedTurnover_GroupMember groupMember, int itemIndex3)
      {
        ProcessMessageDocument processMessage;
        bool assertion;
            
                    /*  VR.ATO.RDTIS.410038
                    Non Individual Name cannot contain 'Pship', 'P'ship or 'P/Ship'
    
                    Legacy Rule Format:
                    IF ([RDTIS41] STARTSWITH "T/A ") AND ([RDTIS41] ENDSWITH SET(" Pship"," P'ship"," P/ship"))
                      RETURN VALIDATION MESSAGE
                    ENDIF
        
                    Technical Business Rule Format:
                    (StartsWith(^RDTIS41, 'T/A ')) AND (EndsWithSet(^RDTIS41, '" Pship"," P'ship"," P/ship"'))
            
                    Data Elements:
            
                    ^RDTIS41 = RDTIS:RP:AggregatedTurnover:GroupMember:OrganisationNameDetails.OrganisationalName.Text
                    */
                    assertion = (IsMatch(groupMember.RDTIS41, @"^(T/A )",RegexOptions.IgnoreCase) && IsMatch(groupMember.RDTIS41, @"( Pship| P'ship| P/ship)$",RegexOptions.IgnoreCase));
                    if (assertion)
                    {
                        processMessage = new ProcessMessageDocument()
                        {
                            Code = "CMN.ATO.GEN.410038", Severity = ProcessMessageSeverity.Error,
                            Description = @"Non-individual name field cannot start with 'T/A' and end with 'Pship', 'P'ship or 'P/Ship'",
                            Location = "/tns:RDTIS/tns:RP/tns:AggregatedTurnover/tns:GroupMemberCollection/tns:GroupMember" + OccurrenceIndex(groupMember.OccurrenceIndex) + "/tns:OrganisationNameDetailsOrganisationalNameT",
                            Parameters = new ProcessMessageParameters() { new ProcessMessageParameter() {Name = "RuleIdentifier", Value = "VR.ATO.RDTIS.410038"} },
                        };
                        processMessage.Parameters.Add(new ProcessMessageParameter
                            { Name = "RDTIS41", Value = groupMember.RDTIS41 });
            
                        response.Add(processMessage);
                    }
              }
              #endregion 
    
      #region VR.ATO.RDTIS.410039
      [MethodImpl(MethodImplOptions.AggressiveInlining)]
      public virtual void VRATORDTIS410039(RDTIS2023.RP_AggregatedTurnover_GroupMember groupMember, int itemIndex3)
      {
        ProcessMessageDocument processMessage;
        bool assertion;
            
                    /*  VR.ATO.RDTIS.410039
                    Organisation name must contain at least one alpha or numeric character
    
                    Legacy Rule Format:
                    IF [RDTIS41] DOES NOT CONTAIN SET("a-z", "A-Z", "0-9")
                       RETURN VALIDATION MESSAGE
                    ENDIF
        
                    Technical Business Rule Format:
                    NotContainsSet(^RDTIS41, '"a-z", "A-Z", "0-9"')
            
                    Data Elements:
            
                    ^RDTIS41 = RDTIS:RP:AggregatedTurnover:GroupMember:OrganisationNameDetails.OrganisationalName.Text
                    */
                    assertion = !(IsMatch(groupMember.RDTIS41, @"[a-z]|[A-Z]|[0-9]",RegexOptions.IgnoreCase));
                    if (assertion)
                    {
                        processMessage = new ProcessMessageDocument()
                        {
                            Code = "CMN.ATO.GEN.410039", Severity = ProcessMessageSeverity.Error,
                            Description = @"Organisation name must contain at least one alpha or numeric character",
                            Location = "/tns:RDTIS/tns:RP/tns:AggregatedTurnover/tns:GroupMemberCollection/tns:GroupMember" + OccurrenceIndex(groupMember.OccurrenceIndex) + "/tns:OrganisationNameDetailsOrganisationalNameT",
                            Parameters = new ProcessMessageParameters() { new ProcessMessageParameter() {Name = "RuleIdentifier", Value = "VR.ATO.RDTIS.410039"} },
                        };
                        processMessage.Parameters.Add(new ProcessMessageParameter
                            { Name = "RDTIS41", Value = groupMember.RDTIS41 });
            
                        response.Add(processMessage);
                    }
              }
              #endregion 
    
      #region VR.ATO.RDTIS.428258
      [MethodImpl(MethodImplOptions.AggressiveInlining)]
      public virtual void VRATORDTIS428258(RDTIS2023.RP_AggregatedTurnover_GroupMember groupMember, int itemIndex3)
      {
        ProcessMessageDocument processMessage;
        bool assertion;
            
                    /*  VR.ATO.RDTIS.428258
                    Non Individual Name cannot contain space hyphen space combinations
    
                    Legacy Rule Format:
                    IF [RDTIS41] CONTAINS  " - "
                       RETURN VALIDATION MESSAGE
                    ENDIF
        
                    Technical Business Rule Format:
                    Contains(^RDTIS41, ' - ')
            
                    Data Elements:
            
                    ^RDTIS41 = RDTIS:RP:AggregatedTurnover:GroupMember:OrganisationNameDetails.OrganisationalName.Text
                    */
                    assertion = (groupMember.RDTIS41 == null ? false : groupMember.RDTIS41.ToUpperInvariant().Contains(@" - "));
                    if (assertion)
                    {
                        processMessage = new ProcessMessageDocument()
                        {
                            Code = "CMN.ATO.GEN.000413", Severity = ProcessMessageSeverity.Error,
                            Description = @"Non Individual Name cannot contain space hyphen space combinations",
                            Location = "/tns:RDTIS/tns:RP/tns:AggregatedTurnover/tns:GroupMemberCollection/tns:GroupMember" + OccurrenceIndex(groupMember.OccurrenceIndex) + "/tns:OrganisationNameDetailsOrganisationalNameT",
                            Parameters = new ProcessMessageParameters() { new ProcessMessageParameter() {Name = "RuleIdentifier", Value = "VR.ATO.RDTIS.428258"} },
                        };
                        processMessage.Parameters.Add(new ProcessMessageParameter
                            { Name = "RDTIS41", Value = groupMember.RDTIS41 });
            
                        response.Add(processMessage);
                    }
              }
              #endregion 
    
      #region VR.ATO.RDTIS.428259
      [MethodImpl(MethodImplOptions.AggressiveInlining)]
      public virtual void VRATORDTIS428259(RDTIS2023.RP_AggregatedTurnover_GroupMember groupMember, int itemIndex3)
      {
        ProcessMessageDocument processMessage;
        bool assertion;
            
                    /*  VR.ATO.RDTIS.428259
                    Non Individual Name cannot contain "P/L"
    
                    Legacy Rule Format:
                    IF [RDTIS41] CONTAINS "P/L"
                       RETURN VALIDATION MESSAGE
                    ENDIF
        
                    Technical Business Rule Format:
                    Contains(^RDTIS41, 'P/L')
            
                    Data Elements:
            
                    ^RDTIS41 = RDTIS:RP:AggregatedTurnover:GroupMember:OrganisationNameDetails.OrganisationalName.Text
                    */
                    assertion = (groupMember.RDTIS41 == null ? false : groupMember.RDTIS41.ToUpperInvariant().Contains(@"P/L"));
                    if (assertion)
                    {
                        processMessage = new ProcessMessageDocument()
                        {
                            Code = "CMN.ATO.GEN.000414", Severity = ProcessMessageSeverity.Error,
                            Description = @"Non Individual Name cannot contain ""P/L""",
                            Location = "/tns:RDTIS/tns:RP/tns:AggregatedTurnover/tns:GroupMemberCollection/tns:GroupMember" + OccurrenceIndex(groupMember.OccurrenceIndex) + "/tns:OrganisationNameDetailsOrganisationalNameT",
                            Parameters = new ProcessMessageParameters() { new ProcessMessageParameter() {Name = "RuleIdentifier", Value = "VR.ATO.RDTIS.428259"} },
                        };
                        processMessage.Parameters.Add(new ProcessMessageParameter
                            { Name = "RDTIS41", Value = groupMember.RDTIS41 });
            
                        response.Add(processMessage);
                    }
              }
              #endregion 
    
      #region VR.ATO.RDTIS.428260
      [MethodImpl(MethodImplOptions.AggressiveInlining)]
      public virtual void VRATORDTIS428260(RDTIS2023.RP_AggregatedTurnover_GroupMember groupMember, int itemIndex3)
      {
        ProcessMessageDocument processMessage;
        bool assertion;
            
                    /*  VR.ATO.RDTIS.428260
                    Non Individual Name cannot contain repeated hyphen, apostrophe, or space characters
    
                    Legacy Rule Format:
                    IF [RDTIS41] CONTAINS SET("--","''","  ")
                       RETURN VALIDATION MESSAGE
                    ENDIF
        
                    Technical Business Rule Format:
                    ContainsSet(^RDTIS41, '"--","''","  "')
            
                    Data Elements:
            
                    ^RDTIS41 = RDTIS:RP:AggregatedTurnover:GroupMember:OrganisationNameDetails.OrganisationalName.Text
                    */
                    assertion = IsMatch(groupMember.RDTIS41, @"--|''|  ",RegexOptions.IgnoreCase);
                    if (assertion)
                    {
                        processMessage = new ProcessMessageDocument()
                        {
                            Code = "CMN.ATO.GEN.000416", Severity = ProcessMessageSeverity.Error,
                            Description = @"Non Individual Name cannot contain repeated hyphen, apostrophe, or space characters",
                            Location = "/tns:RDTIS/tns:RP/tns:AggregatedTurnover/tns:GroupMemberCollection/tns:GroupMember" + OccurrenceIndex(groupMember.OccurrenceIndex) + "/tns:OrganisationNameDetailsOrganisationalNameT",
                            Parameters = new ProcessMessageParameters() { new ProcessMessageParameter() {Name = "RuleIdentifier", Value = "VR.ATO.RDTIS.428260"} },
                        };
                        processMessage.Parameters.Add(new ProcessMessageParameter
                            { Name = "RDTIS41", Value = groupMember.RDTIS41 });
            
                        response.Add(processMessage);
                    }
              }
              #endregion 
    
      #region VR.ATO.RDTIS.428261
      [MethodImpl(MethodImplOptions.AggressiveInlining)]
      public virtual void VRATORDTIS428261(RDTIS2023.RP_AggregatedTurnover_GroupMember groupMember, int itemIndex3)
      {
        ProcessMessageDocument processMessage;
        bool assertion;
            
                    /*  VR.ATO.RDTIS.428261
                    Non Individual Name cannot end with "T/A", "T/A P'ship", "T/A Pship", "T/A P/Ship" or "T/A Partnership"
    
                    Legacy Rule Format:
                    IF [RDTIS41] ENDSWITH SET(" T/A"," T/A P'ship"," T/A Pship"," T/A P/Ship"," T/A Partnership")
                      RETURN VALIDATION MESSAGE
                    ENDIF
        
                    Technical Business Rule Format:
                    EndsWithSet(^RDTIS41, '" T/A"," T/A P'ship"," T/A Pship"," T/A P/Ship"," T/A Partnership"')
            
                    Data Elements:
            
                    ^RDTIS41 = RDTIS:RP:AggregatedTurnover:GroupMember:OrganisationNameDetails.OrganisationalName.Text
                    */
                    assertion = IsMatch(groupMember.RDTIS41, @"( T/A| T/A P'ship| T/A Pship| T/A P/Ship| T/A Partnership)$",RegexOptions.IgnoreCase);
                    if (assertion)
                    {
                        processMessage = new ProcessMessageDocument()
                        {
                            Code = "CMN.ATO.GEN.000417", Severity = ProcessMessageSeverity.Error,
                            Description = @"Non Individual Name cannot end with ""T/A"", ""T/A P'ship"", ""T/A Pship"", ""T/A P/Ship"" or ""T/A Partnership""",
                            Location = "/tns:RDTIS/tns:RP/tns:AggregatedTurnover/tns:GroupMemberCollection/tns:GroupMember" + OccurrenceIndex(groupMember.OccurrenceIndex) + "/tns:OrganisationNameDetailsOrganisationalNameT",
                            Parameters = new ProcessMessageParameters() { new ProcessMessageParameter() {Name = "RuleIdentifier", Value = "VR.ATO.RDTIS.428261"} },
                        };
                        processMessage.Parameters.Add(new ProcessMessageParameter
                            { Name = "RDTIS41", Value = groupMember.RDTIS41 });
            
                        response.Add(processMessage);
                    }
              }
              #endregion 
    
      #region VR.ATO.RDTIS.438021
      [MethodImpl(MethodImplOptions.AggressiveInlining)]
      public virtual void VRATORDTIS438021()
      {
        ProcessMessageDocument processMessage;
        bool assertion;
    
            /*  VR.ATO.RDTIS.438021
            Australian owned R&D Total of allocated notional deductions must equal the sum of Australian owned R&D amounts
    
            Legacy Rule Format:
            IF [RDTIS22] <> NULL AND [RDTIS22] <> ([RDTIS4] + [RDTIS6] + [RDTIS8] + [RDTIS10] + [RDTIS12] + [RDTIS14] + [RDTIS16] + [RDTIS20])
               RETURN VALIDATION MESSAGE
            ENDIF

            Technical Business Rule Format:
            ^RDTIS22 <> NULL AND ^RDTIS22 <> (^RDTIS4 + ^RDTIS6 + ^RDTIS8 + ^RDTIS10 + ^RDTIS12 + ^RDTIS14 + ^RDTIS16 + ^RDTIS20)
    
            Data Elements:
    
            ^RDTIS22 = RDTIS:RP:NotionalDeductionsCalculation:AustralianOwned:Expense.ResearchAndDevelopment.AllocatedTotal.Amount
    
            ^RDTIS4 = RDTIS:RP:NotionalDeductionsCalculation:AustralianOwned:Expense.ResearchAndDevelopment.ContractedExpenditureResearchServiceProvider.Amount
    
            ^RDTIS6 = RDTIS:RP:NotionalDeductionsCalculation:AustralianOwned:Expense.ResearchAndDevelopment.ContractedExpenditureNonResearchServiceProvider.Amount
    
            ^RDTIS8 = RDTIS:RP:NotionalDeductionsCalculation:AustralianOwned:Remuneration.WagesAndSalaries.Salary.Amount
    
            ^RDTIS10 = RDTIS:RP:NotionalDeductionsCalculation:AustralianOwned:Expense.ResearchAndDevelopment.OtherExpenditureRegisteredResearchAgency.Amount
    
            ^RDTIS12 = RDTIS:RP:NotionalDeductionsCalculation:AustralianOwned:Expense.ResearchAndDevelopment.Feedstock.Amount
    
            ^RDTIS14 = RDTIS:RP:NotionalDeductionsCalculation:AustralianOwned:Expense.ResearchAndDevelopment.AssociatesExpenditure.Amount
    
            ^RDTIS16 = RDTIS:RP:NotionalDeductionsCalculation:AustralianOwned:Expense.ResearchAndDevelopment.DeclineInValuePlantAndDepreciatingAssets.Amount
    
            ^RDTIS20 = RDTIS:RP:NotionalDeductionsCalculation:AustralianOwned:Expense.ResearchAndDevelopment.CooperativeResearchCentreContributions.Amount
            */
            assertion = (report.RDTIS22 != null && report.RDTIS22.GetValueOrDefault() != report.RDTIS4.GetValueOrDefault() + report.RDTIS6.GetValueOrDefault() + report.RDTIS8.GetValueOrDefault() + report.RDTIS10.GetValueOrDefault() + report.RDTIS12.GetValueOrDefault() + report.RDTIS14.GetValueOrDefault() + report.RDTIS16.GetValueOrDefault() + report.RDTIS20.GetValueOrDefault());
            if (assertion)
            {
                processMessage = new ProcessMessageDocument()
                {
                    Code = "CMN.ATO.RDTIS.438021", Severity = ProcessMessageSeverity.Error,
                    Description = @"Australian owned R&D Total of allocated notional deductions is incorrect",
                    LongDescription = @"Australian owned R&D Total of allocated notional deductions must equal the sum of Australian owned R&D amounts",
                    Location = "/tns:RDTIS/tns:RP/tns:NotionalDeductionsCalculation/tns:AustralianOwned/tns:ExpenseResearchAndDevelopmentAllocatedTotalA",
                    Parameters = new ProcessMessageParameters() { new ProcessMessageParameter() {Name = "RuleIdentifier", Value = "VR.ATO.RDTIS.438021"} },
                };
                processMessage.Parameters.Add(new ProcessMessageParameter
                    { Name = "RDTIS22", Value = GetValueOrEmpty(report.RDTIS22) });
    
                processMessage.Parameters.Add(new ProcessMessageParameter
                    { Name = "RDTIS4", Value = GetValueOrEmpty(report.RDTIS4) });
    
                processMessage.Parameters.Add(new ProcessMessageParameter
                    { Name = "RDTIS6", Value = GetValueOrEmpty(report.RDTIS6) });
    
                processMessage.Parameters.Add(new ProcessMessageParameter
                    { Name = "RDTIS8", Value = GetValueOrEmpty(report.RDTIS8) });
    
                processMessage.Parameters.Add(new ProcessMessageParameter
                    { Name = "RDTIS10", Value = GetValueOrEmpty(report.RDTIS10) });
    
                processMessage.Parameters.Add(new ProcessMessageParameter
                    { Name = "RDTIS12", Value = GetValueOrEmpty(report.RDTIS12) });
    
                processMessage.Parameters.Add(new ProcessMessageParameter
                    { Name = "RDTIS14", Value = GetValueOrEmpty(report.RDTIS14) });
    
                processMessage.Parameters.Add(new ProcessMessageParameter
                    { Name = "RDTIS16", Value = GetValueOrEmpty(report.RDTIS16) });
    
                processMessage.Parameters.Add(new ProcessMessageParameter
                    { Name = "RDTIS20", Value = GetValueOrEmpty(report.RDTIS20) });
    
                response.Add(processMessage);
            }
      }
      #endregion 
    
      #region VR.ATO.RDTIS.438022
      [MethodImpl(MethodImplOptions.AggressiveInlining)]
      public virtual void VRATORDTIS438022()
      {
        ProcessMessageDocument processMessage;
        bool assertion;
    
            /*  VR.ATO.RDTIS.438022
            Foreign owned R&D Total of allocated notional deductions must equal the sum of Foreign owned R&D amounts
    
            Legacy Rule Format:
            IF [RDTIS23] <> NULL AND [RDTIS23] <> ([RDTIS5] + [RDTIS7] + [RDTIS9] + [RDTIS11] + [RDTIS13] + [RDTIS15] + [RDTIS17] + [RDTIS21])
               RETURN VALIDATION MESSAGE
            ENDIF

            Technical Business Rule Format:
            ^RDTIS23 <> NULL AND ^RDTIS23 <> (^RDTIS5 + ^RDTIS7 + ^RDTIS9 + ^RDTIS11 + ^RDTIS13 + ^RDTIS15 + ^RDTIS17 + ^RDTIS21)
    
            Data Elements:
    
            ^RDTIS23 = RDTIS:RP:NotionalDeductionsCalculation:ForeignOwned:Expense.ResearchAndDevelopment.AllocatedTotal.Amount
    
            ^RDTIS5 = RDTIS:RP:NotionalDeductionsCalculation:ForeignOwned:Expense.ResearchAndDevelopment.ContractedExpenditureResearchServiceProvider.Amount
    
            ^RDTIS7 = RDTIS:RP:NotionalDeductionsCalculation:ForeignOwned:Expense.ResearchAndDevelopment.ContractedExpenditureNonResearchServiceProvider.Amount
    
            ^RDTIS9 = RDTIS:RP:NotionalDeductionsCalculation:ForeignOwned:Remuneration.WagesAndSalaries.Salary.Amount
    
            ^RDTIS11 = RDTIS:RP:NotionalDeductionsCalculation:ForeignOwned:Expense.ResearchAndDevelopment.OtherExpenditureRegisteredResearchAgency.Amount
    
            ^RDTIS13 = RDTIS:RP:NotionalDeductionsCalculation:ForeignOwned:Expense.ResearchAndDevelopment.Feedstock.Amount
    
            ^RDTIS15 = RDTIS:RP:NotionalDeductionsCalculation:ForeignOwned:Expense.ResearchAndDevelopment.AssociatesExpenditure.Amount
    
            ^RDTIS17 = RDTIS:RP:NotionalDeductionsCalculation:ForeignOwned:Expense.ResearchAndDevelopment.DeclineInValuePlantAndDepreciatingAssets.Amount
    
            ^RDTIS21 = RDTIS:RP:NotionalDeductionsCalculation:ForeignOwned:Expense.ResearchAndDevelopment.CooperativeResearchCentreContributions.Amount
            */
            assertion = (report.RDTIS23 != null && report.RDTIS23.GetValueOrDefault() != report.RDTIS5.GetValueOrDefault() + report.RDTIS7.GetValueOrDefault() + report.RDTIS9.GetValueOrDefault() + report.RDTIS11.GetValueOrDefault() + report.RDTIS13.GetValueOrDefault() + report.RDTIS15.GetValueOrDefault() + report.RDTIS17.GetValueOrDefault() + report.RDTIS21.GetValueOrDefault());
            if (assertion)
            {
                processMessage = new ProcessMessageDocument()
                {
                    Code = "CMN.ATO.RDTIS.438022", Severity = ProcessMessageSeverity.Error,
                    Description = @"Foreign owned R&D Total of allocated notional deductions is incorrect",
                    LongDescription = @"Foreign owned R&D Total of allocated notional deductions must equal the sum of Foreign owned R&D amounts",
                    Location = "/tns:RDTIS/tns:RP/tns:NotionalDeductionsCalculation/tns:ForeignOwned/tns:ExpenseResearchAndDevelopmentAllocatedTotalA",
                    Parameters = new ProcessMessageParameters() { new ProcessMessageParameter() {Name = "RuleIdentifier", Value = "VR.ATO.RDTIS.438022"} },
                };
                processMessage.Parameters.Add(new ProcessMessageParameter
                    { Name = "RDTIS23", Value = GetValueOrEmpty(report.RDTIS23) });
    
                processMessage.Parameters.Add(new ProcessMessageParameter
                    { Name = "RDTIS5", Value = GetValueOrEmpty(report.RDTIS5) });
    
                processMessage.Parameters.Add(new ProcessMessageParameter
                    { Name = "RDTIS7", Value = GetValueOrEmpty(report.RDTIS7) });
    
                processMessage.Parameters.Add(new ProcessMessageParameter
                    { Name = "RDTIS9", Value = GetValueOrEmpty(report.RDTIS9) });
    
                processMessage.Parameters.Add(new ProcessMessageParameter
                    { Name = "RDTIS11", Value = GetValueOrEmpty(report.RDTIS11) });
    
                processMessage.Parameters.Add(new ProcessMessageParameter
                    { Name = "RDTIS13", Value = GetValueOrEmpty(report.RDTIS13) });
    
                processMessage.Parameters.Add(new ProcessMessageParameter
                    { Name = "RDTIS15", Value = GetValueOrEmpty(report.RDTIS15) });
    
                processMessage.Parameters.Add(new ProcessMessageParameter
                    { Name = "RDTIS17", Value = GetValueOrEmpty(report.RDTIS17) });
    
                processMessage.Parameters.Add(new ProcessMessageParameter
                    { Name = "RDTIS21", Value = GetValueOrEmpty(report.RDTIS21) });
    
                response.Add(processMessage);
            }
      }
      #endregion 
    
      #region VR.ATO.RDTIS.438024
      [MethodImpl(MethodImplOptions.AggressiveInlining)]
      public virtual void VRATORDTIS438024()
      {
        ProcessMessageDocument processMessage;
        bool assertion;
    
            /*  VR.ATO.RDTIS.438024
            If lodging the Research and Development Tax Incentive Schedule the Total Notional R&D deductions must be greater than zero
    
            Legacy Rule Format:
            IF [RDTIS24] = 0
               RETURN VALIDATION MESSAGE
            ENDIF

            Technical Business Rule Format:
            ^RDTIS24 = 0
    
            Data Elements:
    
            ^RDTIS24 = RDTIS:RP:NotionalDeductionsCalculation:Expense.ResearchAndDevelopment.AllocatedTotal.Amount
            */
            assertion = (report.RDTIS24 == 0);
            if (assertion)
            {
                processMessage = new ProcessMessageDocument()
                {
                    Code = "CMN.ATO.RDTIS.438024", Severity = ProcessMessageSeverity.Error,
                    Description = @"Total Notional R&D deductions must be greater than zero",
                    LongDescription = @"If lodging the Research and Development Tax Incentive Schedule the Total Notional R&D deductions must be greater than zero",
                    Location = "/tns:RDTIS/tns:RP/tns:NotionalDeductionsCalculation/tns:ExpenseResearchAndDevelopmentAllocatedTotalA",
                    Parameters = new ProcessMessageParameters() { new ProcessMessageParameter() {Name = "RuleIdentifier", Value = "VR.ATO.RDTIS.438024"} },
                };
                processMessage.Parameters.Add(new ProcessMessageParameter
                    { Name = "RDTIS24", Value = GetValueOrEmpty(report.RDTIS24) });
    
                response.Add(processMessage);
            }
      }
      #endregion 
    
      #region VR.ATO.RDTIS.438025
      [MethodImpl(MethodImplOptions.AggressiveInlining)]
      public virtual void VRATORDTIS438025()
      {
        ProcessMessageDocument processMessage;
        bool assertion;
    
            /*  VR.ATO.RDTIS.438025
            Total Notional R&D deductions must equal the sum of Australian and Foreign owned R&D Total of allocated notional deductions
    
            Legacy Rule Format:
            IF ([RDTIS22] + [RDTIS23]) >= 20000 AND [RDTIS24] <> ([RDTIS22] + [RDTIS23])
               RETURN VALIDATION MESSAGE
            ENDIF

            Technical Business Rule Format:
            (^RDTIS22 + ^RDTIS23) >= 20000 AND ^RDTIS24 <> (^RDTIS22 + ^RDTIS23)
    
            Data Elements:
    
            ^RDTIS24 = RDTIS:RP:NotionalDeductionsCalculation:Expense.ResearchAndDevelopment.AllocatedTotal.Amount
    
            ^RDTIS22 = RDTIS:RP:NotionalDeductionsCalculation:AustralianOwned:Expense.ResearchAndDevelopment.AllocatedTotal.Amount
    
            ^RDTIS23 = RDTIS:RP:NotionalDeductionsCalculation:ForeignOwned:Expense.ResearchAndDevelopment.AllocatedTotal.Amount
            */
            assertion = (report.RDTIS22.GetValueOrDefault() + report.RDTIS23.GetValueOrDefault() >= 20000 && report.RDTIS24.GetValueOrDefault() != report.RDTIS22.GetValueOrDefault() + report.RDTIS23.GetValueOrDefault());
            if (assertion)
            {
                processMessage = new ProcessMessageDocument()
                {
                    Code = "CMN.ATO.RDTIS.438025", Severity = ProcessMessageSeverity.Error,
                    Description = @"Total Notional R&D deductions is incorrect",
                    LongDescription = @"If the sum of Australian and Foreign owned R&D Total of allocated notional deductions is equal to or greater than $20,000 then the Total Notional R&D deductions must equal the sum of Australian and Foreign owned R&D Total of allocated notional deductions",
                    Location = "/tns:RDTIS/tns:RP/tns:NotionalDeductionsCalculation/tns:ExpenseResearchAndDevelopmentAllocatedTotalA",
                    Parameters = new ProcessMessageParameters() { new ProcessMessageParameter() {Name = "RuleIdentifier", Value = "VR.ATO.RDTIS.438025"} },
                };
                processMessage.Parameters.Add(new ProcessMessageParameter
                    { Name = "RDTIS22", Value = GetValueOrEmpty(report.RDTIS22) });
    
                processMessage.Parameters.Add(new ProcessMessageParameter
                    { Name = "RDTIS23", Value = GetValueOrEmpty(report.RDTIS23) });
    
                processMessage.Parameters.Add(new ProcessMessageParameter
                    { Name = "RDTIS24", Value = GetValueOrEmpty(report.RDTIS24) });
    
                response.Add(processMessage);
            }
      }
      #endregion 
    
      #region VR.ATO.RDTIS.438026
      [MethodImpl(MethodImplOptions.AggressiveInlining)]
      public virtual void VRATORDTIS438026()
      {
        ProcessMessageDocument processMessage;
        bool assertion;
    
            /*  VR.ATO.RDTIS.438026
            Total Notional R&D deductions must equal the sum of Australian and Foreign owned R&D expenditure Research service provider amounts plus the sum of Australian and Foreign owned R&D expenditure Cooperative Research Centre contributions amounts
    
            Legacy Rule Format:
            IF ([RDTIS22] + [RDTIS23]) < 20000 AND [RDTIS24] <> ([RDTIS4] + [RDTIS5] + [RDTIS20] + [RDTIS21])
               RETURN VALIDATION MESSAGE
            ENDIF

            Technical Business Rule Format:
            (^RDTIS22 + ^RDTIS23) < 20000 AND ^RDTIS24 <> (^RDTIS4 + ^RDTIS5 + ^RDTIS20 + ^RDTIS21)
    
            Data Elements:
    
            ^RDTIS24 = RDTIS:RP:NotionalDeductionsCalculation:Expense.ResearchAndDevelopment.AllocatedTotal.Amount
    
            ^RDTIS22 = RDTIS:RP:NotionalDeductionsCalculation:AustralianOwned:Expense.ResearchAndDevelopment.AllocatedTotal.Amount
    
            ^RDTIS23 = RDTIS:RP:NotionalDeductionsCalculation:ForeignOwned:Expense.ResearchAndDevelopment.AllocatedTotal.Amount
    
            ^RDTIS4 = RDTIS:RP:NotionalDeductionsCalculation:AustralianOwned:Expense.ResearchAndDevelopment.ContractedExpenditureResearchServiceProvider.Amount
    
            ^RDTIS5 = RDTIS:RP:NotionalDeductionsCalculation:ForeignOwned:Expense.ResearchAndDevelopment.ContractedExpenditureResearchServiceProvider.Amount
    
            ^RDTIS20 = RDTIS:RP:NotionalDeductionsCalculation:AustralianOwned:Expense.ResearchAndDevelopment.CooperativeResearchCentreContributions.Amount
    
            ^RDTIS21 = RDTIS:RP:NotionalDeductionsCalculation:ForeignOwned:Expense.ResearchAndDevelopment.CooperativeResearchCentreContributions.Amount
            */
            assertion = (report.RDTIS22.GetValueOrDefault() + report.RDTIS23.GetValueOrDefault() < 20000 && report.RDTIS24.GetValueOrDefault() != report.RDTIS4.GetValueOrDefault() + report.RDTIS5.GetValueOrDefault() + report.RDTIS20.GetValueOrDefault() + report.RDTIS21.GetValueOrDefault());
            if (assertion)
            {
                processMessage = new ProcessMessageDocument()
                {
                    Code = "CMN.ATO.RDTIS.438026", Severity = ProcessMessageSeverity.Error,
                    Description = @"Total Notional R&D deductions is incorrect",
                    LongDescription = @"If the sum of Australian and Foreign owned R&D Total of allocated notional deductions is less than $20,000 then Total Notional R&D deductions must equal the sum of Australian and Foreign owned R&D expenditure Research service provider amounts plus the sum of Australian and Foreign owned R&D expenditure Cooperative Research Centre contributions amounts",
                    Location = "/tns:RDTIS/tns:RP/tns:NotionalDeductionsCalculation/tns:ExpenseResearchAndDevelopmentAllocatedTotalA",
                    Parameters = new ProcessMessageParameters() { new ProcessMessageParameter() {Name = "RuleIdentifier", Value = "VR.ATO.RDTIS.438026"} },
                };
                processMessage.Parameters.Add(new ProcessMessageParameter
                    { Name = "RDTIS22", Value = GetValueOrEmpty(report.RDTIS22) });
    
                processMessage.Parameters.Add(new ProcessMessageParameter
                    { Name = "RDTIS23", Value = GetValueOrEmpty(report.RDTIS23) });
    
                processMessage.Parameters.Add(new ProcessMessageParameter
                    { Name = "RDTIS24", Value = GetValueOrEmpty(report.RDTIS24) });
    
                processMessage.Parameters.Add(new ProcessMessageParameter
                    { Name = "RDTIS4", Value = GetValueOrEmpty(report.RDTIS4) });
    
                processMessage.Parameters.Add(new ProcessMessageParameter
                    { Name = "RDTIS5", Value = GetValueOrEmpty(report.RDTIS5) });
    
                processMessage.Parameters.Add(new ProcessMessageParameter
                    { Name = "RDTIS20", Value = GetValueOrEmpty(report.RDTIS20) });
    
                processMessage.Parameters.Add(new ProcessMessageParameter
                    { Name = "RDTIS21", Value = GetValueOrEmpty(report.RDTIS21) });
    
                response.Add(processMessage);
            }
      }
      #endregion 
    
      #region VR.ATO.RDTIS.438037
      [MethodImpl(MethodImplOptions.AggressiveInlining)]
      public virtual void VRATORDTIS438037()
      {
        ProcessMessageDocument processMessage;
        bool assertion;
    
            /*  VR.ATO.RDTIS.438037
            R&D expenditure paid to associates in the current year does not match the sum of Australian and Foreign owned R&D expenditure paid to associates in the current year
    
            Legacy Rule Format:
            IF [RDTIS34] <> NULL AND [RDTIS34] <> ([RDTIS14] + [RDTIS15])
               RETURN VALIDATION MESSAGE
            ENDIF

            Technical Business Rule Format:
            ^RDTIS34 <> NULL AND ^RDTIS34 <> (^RDTIS14 + ^RDTIS15)
    
            Data Elements:
    
            ^RDTIS34 = RDTIS:RP:ExpenditureToAssociates:IncurredOrPaid:Expense.ResearchAndDevelopment.AssociatesNotClaimed.Amount
    
            ^RDTIS14 = RDTIS:RP:NotionalDeductionsCalculation:AustralianOwned:Expense.ResearchAndDevelopment.AssociatesExpenditure.Amount
    
            ^RDTIS15 = RDTIS:RP:NotionalDeductionsCalculation:ForeignOwned:Expense.ResearchAndDevelopment.AssociatesExpenditure.Amount
            */
            assertion = (report.RDTIS34 != null && report.RDTIS34.GetValueOrDefault() != report.RDTIS14.GetValueOrDefault() + report.RDTIS15.GetValueOrDefault());
            if (assertion)
            {
                processMessage = new ProcessMessageDocument()
                {
                    Code = "CMN.ATO.RDTIS.438037", Severity = ProcessMessageSeverity.Error,
                    Description = @"R&D expenditure paid to associates is incorrect",
                    LongDescription = @"R&D expenditure paid to associates in the current year must equal the sum of Australian and Foreign owned R&D expenditure paid to associates in the current year",
                    Location = "/tns:RDTIS/tns:RP/tns:ExpenditureToAssociates/tns:IncurredOrPaid/tns:ExpenseResearchAndDevelopmentAssociatesNotClaimedA",
                    Parameters = new ProcessMessageParameters() { new ProcessMessageParameter() {Name = "RuleIdentifier", Value = "VR.ATO.RDTIS.438037"} },
                };
                processMessage.Parameters.Add(new ProcessMessageParameter
                    { Name = "RDTIS34", Value = GetValueOrEmpty(report.RDTIS34) });
    
                processMessage.Parameters.Add(new ProcessMessageParameter
                    { Name = "RDTIS14", Value = GetValueOrEmpty(report.RDTIS14) });
    
                processMessage.Parameters.Add(new ProcessMessageParameter
                    { Name = "RDTIS15", Value = GetValueOrEmpty(report.RDTIS15) });
    
                response.Add(processMessage);
            }
      }
      #endregion 
    
      #region VR.ATO.RDTIS.438039
      [MethodImpl(MethodImplOptions.AggressiveInlining)]
      public virtual void VRATORDTIS438039()
      {
        ProcessMessageDocument processMessage;
        bool assertion;
    
            /*  VR.ATO.RDTIS.438039
            "R&D expenditure incurred to associates to be carried forward" must equal "R&D expenditure to associates incurred in prior year, not paid, not claimed (carried forward)" plus "Current year R&D expenditure incurred to associates" minus "Current year R&D expenditure incurred to associates claimed under other provisions" minus "R&D expenditure paid to associates in the current year".
    
            Legacy Rule Format:
            IF [RDTIS35] <> NULL AND [RDTIS35] <> ([RDTIS51]+[RDTIS32] - [RDTIS33] - [RDTIS34])
               RETURN VALIDATION MESSAGE
            ENDIF

            Technical Business Rule Format:
            ^RDTIS35 <> NULL AND ^RDTIS35 <> (^RDTIS51+^RDTIS32 - ^RDTIS33 - ^RDTIS34)
    
            Data Elements:
    
            ^RDTIS35 = RDTIS:RP:ExpenditureToAssociates:Expense.ResearchAndDevelopment.AssociatesCarriedForward.Amount
    
            ^RDTIS51 = RDTIS:RP:ExpenditureToAssociates:IncurredOrPaid:Expense.ResearchAndDevelopment.AssociatesCarriedForward.Amount
    
            ^RDTIS32 = RDTIS:RP:ExpenditureToAssociates:IncurredOrPaid:Expense.ResearchAndDevelopment.AssociatesUnpaid.Amount
    
            ^RDTIS33 = RDTIS:RP:ExpenditureToAssociates:IncurredOrPaid:Expense.ResearchAndDevelopment.AssociatesClaimed.Amount
    
            ^RDTIS34 = RDTIS:RP:ExpenditureToAssociates:IncurredOrPaid:Expense.ResearchAndDevelopment.AssociatesNotClaimed.Amount
            */
            assertion = (report.RDTIS35 != null && report.RDTIS35.GetValueOrDefault() != report.RDTIS51.GetValueOrDefault() + report.RDTIS32.GetValueOrDefault() - report.RDTIS33.GetValueOrDefault() - report.RDTIS34.GetValueOrDefault());
            if (assertion)
            {
                processMessage = new ProcessMessageDocument()
                {
                    Code = "CMN.ATO.RDTIS.438061", Severity = ProcessMessageSeverity.Error,
                    Description = @"R&D expenditure incurred to associates to be carried forward is incorrect.",
                    LongDescription = @"""R&D expenditure incurred to associates to be carried forward"" must equal ""R&D expenditure to associates incurred in prior year, not paid, not claimed (carried forward)"" plus ""Current year R&D expenditure incurred to associates"" minus ""Current year R&D expenditure incurred to associates claimed under other provisions"" minus ""R&D expenditure paid to associates in the current year"".",
                    Location = "/tns:RDTIS/tns:RP/tns:ExpenditureToAssociates/tns:ExpenseResearchAndDevelopmentAssociatesCarriedForwardA",
                    Parameters = new ProcessMessageParameters() { new ProcessMessageParameter() {Name = "RuleIdentifier", Value = "VR.ATO.RDTIS.438039"} },
                };
                processMessage.Parameters.Add(new ProcessMessageParameter
                    { Name = "RDTIS35", Value = GetValueOrEmpty(report.RDTIS35) });
    
                processMessage.Parameters.Add(new ProcessMessageParameter
                    { Name = "RDTIS51", Value = GetValueOrEmpty(report.RDTIS51) });
    
                processMessage.Parameters.Add(new ProcessMessageParameter
                    { Name = "RDTIS32", Value = GetValueOrEmpty(report.RDTIS32) });
    
                processMessage.Parameters.Add(new ProcessMessageParameter
                    { Name = "RDTIS33", Value = GetValueOrEmpty(report.RDTIS33) });
    
                processMessage.Parameters.Add(new ProcessMessageParameter
                    { Name = "RDTIS34", Value = GetValueOrEmpty(report.RDTIS34) });
    
                response.Add(processMessage);
            }
      }
      #endregion 
    
      #region VR.ATO.RDTIS.438043
      [MethodImpl(MethodImplOptions.AggressiveInlining)]
      public virtual void VRATORDTIS438043()
      {
        ProcessMessageDocument processMessage;
        bool assertion;
    
            /*  VR.ATO.RDTIS.438043
            One or more Group Member Turnover is present and the reporting Company turnover is not present
    
            Legacy Rule Format:
            IF (ANY OCCURRENCE OF ([RDTIS42]) <> NULL) AND [RDTIS38] = NULL
               RETURN VALIDATION MESSAGE
            ENDIF

            Technical Business Rule Format:
            (AnyOccurrence(^RDTIS42, ^RDTIS42 <> NULL)) AND ^RDTIS38 = NULL
    
            Data Elements:
    
            ^RDTIS38 = RDTIS:RP:AggregatedTurnover:TaxConcession.ResearchAndDevelopment.TaxOffsetEntityTurnover.Amount
    
            ^RDTIS42 = RDTIS:RP:AggregatedTurnover:GroupMember:TaxConcession.ResearchAndDevelopment.TaxOffsetEntityTurnover.Amount
            */
            assertion = ((report.RP_AggregatedTurnover_GroupMemberCollection == null ? false : report.RP_AggregatedTurnover_GroupMemberCollection.Any(RDTIS42Repeat => RDTIS42Repeat.RDTIS42 != null)) && report.RDTIS38 == null);
            if (assertion)
            {
                processMessage = new ProcessMessageDocument()
                {
                    Code = "CMN.ATO.RDTIS.438043", Severity = ProcessMessageSeverity.Error,
                    Description = @"With one or more Group Members present, the reporting Company turnover must be present",
                    Location = "/tns:RDTIS/tns:RP/tns:AggregatedTurnover/tns:TaxConcessionResearchAndDevelopmentTaxOffsetEntityTurnoverA",
                    Parameters = new ProcessMessageParameters() { new ProcessMessageParameter() {Name = "RuleIdentifier", Value = "VR.ATO.RDTIS.438043"} },
                };
                processMessage.Parameters.Add(new ProcessMessageParameter
                    { Name = "RDTIS42", Value = "RDTIS42" });
    
                processMessage.Parameters.Add(new ProcessMessageParameter
                    { Name = "RDTIS38", Value = GetValueOrEmpty(report.RDTIS38) });
    
                response.Add(processMessage);
            }
      }
      #endregion 
    
      #region VR.ATO.RDTIS.438049
      [MethodImpl(MethodImplOptions.AggressiveInlining)]
      public virtual void VRATORDTIS438049()
      {
        ProcessMessageDocument processMessage;
        bool assertion;
    
            /*  VR.ATO.RDTIS.438049
            Aggregated Turnover of $20 million or greater' question is 'False' and the Aggregated Turnover is not present or present but is greater than or equal to $20 million
    
            Legacy Rule Format:
            IF [RDTIS37] = FALSE AND ([RDTIS44] = NULL OR [RDTIS44] >=20000000)
               RETURN VALIDATION MESSAGE
            ENDIF

            Technical Business Rule Format:
            ^RDTIS37 = FALSE AND (^RDTIS44 = NULL OR ^RDTIS44 >=20000000)
    
            Data Elements:
    
            ^RDTIS44 = RDTIS:RP:AggregatedTurnover:TaxConcession.ResearchAndDevelopment.TaxOffsetTurnoverTotal.Amount
    
            ^RDTIS37 = RDTIS:RP:AggregatedTurnover:TaxConcession.AggregatedTurnoverAtOrAboveThreshold.Indicator
            */
            assertion = (report.RDTIS37 == false && (report.RDTIS44 == null || report.RDTIS44.GetValueOrDefault() >= 20000000));
            if (assertion)
            {
                processMessage = new ProcessMessageDocument()
                {
                    Code = "CMN.ATO.RDTIS.438049", Severity = ProcessMessageSeverity.Error,
                    Description = @"The indicated Aggregated Turnover is incorrect",
                    LongDescription = @"With an indicated Aggregated Turnover of less than $20 million, the Aggregated Turnover must be present and less than $20 million",
                    Location = "/tns:RDTIS/tns:RP/tns:AggregatedTurnover/tns:TaxConcessionResearchAndDevelopmentTaxOffsetTurnoverTotalA",
                    Parameters = new ProcessMessageParameters() { new ProcessMessageParameter() {Name = "RuleIdentifier", Value = "VR.ATO.RDTIS.438049"} },
                };
                processMessage.Parameters.Add(new ProcessMessageParameter
                    { Name = "RDTIS37", Value = GetValueOrEmpty(report.RDTIS37) });
    
                processMessage.Parameters.Add(new ProcessMessageParameter
                    { Name = "RDTIS44", Value = GetValueOrEmpty(report.RDTIS44) });
    
                response.Add(processMessage);
            }
      }
      #endregion 
    
      #region VR.ATO.RDTIS.438050
      [MethodImpl(MethodImplOptions.AggressiveInlining)]
      public virtual void VRATORDTIS438050()
      {
        ProcessMessageDocument processMessage;
        bool assertion;
    
            /*  VR.ATO.RDTIS.438050
            Aggregated Turnover is not equal to the reporting Company turnover plus the sum of the Group Member turnovers minus amounts excluded from aggregated turnover
    
            Legacy Rule Format:
            IF [RDTIS44] <> NULL AND [RDTIS44] <> ([RDTIS38] + SUM([RDTIS42]) + [RDTIS52] - [RDTIS43])
               RETURN VALIDATION MESSAGE
            ENDIF

            Technical Business Rule Format:
            ^RDTIS44 <> NULL AND ^RDTIS44 <> (^RDTIS38 + Sum(^RDTIS42) + ^RDTIS52 - ^RDTIS43)
    
            Data Elements:
    
            ^RDTIS44 = RDTIS:RP:AggregatedTurnover:TaxConcession.ResearchAndDevelopment.TaxOffsetTurnoverTotal.Amount
    
            ^RDTIS38 = RDTIS:RP:AggregatedTurnover:TaxConcession.ResearchAndDevelopment.TaxOffsetEntityTurnover.Amount
    
            ^RDTIS42 = RDTIS:RP:AggregatedTurnover:GroupMember:TaxConcession.ResearchAndDevelopment.TaxOffsetEntityTurnover.Amount
    
            ^RDTIS52 = RDTIS:RP:AggregatedTurnover:TaxConcession.ResearchAndDevelopment.TaxOffsetAdditionalEntitiesTurnover.Amount
    
            ^RDTIS43 = RDTIS:RP:AggregatedTurnover:TaxConcession.ResearchAndDevelopment.TaxOffsetTurnoverExclusion.Amount
            */
            assertion = (report.RDTIS44 != null && report.RDTIS44.GetValueOrDefault() != report.RDTIS38.GetValueOrDefault() + (report.RP_AggregatedTurnover_GroupMemberCollection == null ? 0 : report.RP_AggregatedTurnover_GroupMemberCollection.Sum(f => f.RDTIS42.GetValueOrDefault())) + report.RDTIS52.GetValueOrDefault() - report.RDTIS43.GetValueOrDefault());
            if (assertion)
            {
                processMessage = new ProcessMessageDocument()
                {
                    Code = "CMN.ATO.RDTIS.438050", Severity = ProcessMessageSeverity.Error,
                    Description = @"Aggregated Turnover is incorrect",
                    LongDescription = @"Aggregated Turnover must equal the reporting Company turnover plus the sum of Group Member turnovers minus amounts excluded from aggregated turnover",
                    Location = "/tns:RDTIS/tns:RP/tns:AggregatedTurnover/tns:TaxConcessionResearchAndDevelopmentTaxOffsetTurnoverTotalA",
                    Parameters = new ProcessMessageParameters() { new ProcessMessageParameter() {Name = "RuleIdentifier", Value = "VR.ATO.RDTIS.438050"} },
                };
                processMessage.Parameters.Add(new ProcessMessageParameter
                    { Name = "RDTIS44", Value = GetValueOrEmpty(report.RDTIS44) });
    
                processMessage.Parameters.Add(new ProcessMessageParameter
                    { Name = "RDTIS38", Value = GetValueOrEmpty(report.RDTIS38) });
    
                processMessage.Parameters.Add(new ProcessMessageParameter
                    { Name = "RDTIS42", Value = "RDTIS42" });
    
                processMessage.Parameters.Add(new ProcessMessageParameter
                    { Name = "RDTIS52", Value = GetValueOrEmpty(report.RDTIS52) });
    
                processMessage.Parameters.Add(new ProcessMessageParameter
                    { Name = "RDTIS43", Value = GetValueOrEmpty(report.RDTIS43) });
    
                response.Add(processMessage);
            }
      }
      #endregion 
    
      #region VR.ATO.RDTIS.438052
      [MethodImpl(MethodImplOptions.AggressiveInlining)]
      public virtual void VRATORDTIS438052()
      {
        ProcessMessageDocument processMessage;
        bool assertion;
    
            /*  VR.ATO.RDTIS.438052
            The Refundable R&D tax offset is being claimed: 'Exempt entity ownership of 50% or greater' question is 'False', 'Aggregated turnover of $20 million or greater' question is 'False' and the Refundable tax offset Total notional R&D deductions is not equal to the Total notional R&D deductions
    
            Legacy Rule Format:
            IF [RDTIS36] = FALSE AND [RDTIS37] = FALSE AND [RDTIS45] <> [RDTIS24]
               RETURN VALIDATION MESSAGE
            ENDIF

            Technical Business Rule Format:
            ^RDTIS36 = FALSE AND ^RDTIS37 = FALSE AND ^RDTIS45 <> ^RDTIS24
    
            Data Elements:
    
            ^RDTIS45 = RDTIS:RP:RefundableTaxOffset:TaxConcession.ResearchAndDevelopment.NotionalDeductionsRefundable.Amount
    
            ^RDTIS36 = RDTIS:RP:AggregatedTurnover:TaxConcession.ExemptEntityOwnership.Indicator
    
            ^RDTIS37 = RDTIS:RP:AggregatedTurnover:TaxConcession.AggregatedTurnoverAtOrAboveThreshold.Indicator
    
            ^RDTIS24 = RDTIS:RP:NotionalDeductionsCalculation:Expense.ResearchAndDevelopment.AllocatedTotal.Amount
            */
            assertion = (report.RDTIS36 == false && report.RDTIS37 == false && report.RDTIS45.GetValueOrDefault() != report.RDTIS24.GetValueOrDefault());
            if (assertion)
            {
                processMessage = new ProcessMessageDocument()
                {
                    Code = "CMN.ATO.RDTIS.438052", Severity = ProcessMessageSeverity.Error,
                    Description = @"Refundable tax offset Total notional R&D deductions must equal the Total notional R&D deductions",
                    LongDescription = @"The Refundable R&D tax offset is being claimed: 'Exempt entity ownership of 50% or greater' question is 'No', 'Aggregated turnover of $20 million or greater' question is 'No' and the Refundable tax offset Total notional R&D deductions is not equal to the Total notional R&D deductions",
                    Location = "/tns:RDTIS/tns:RP/tns:RefundableTaxOffset/tns:TaxConcessionResearchAndDevelopmentNotionalDeductionsRefundableA",
                    Parameters = new ProcessMessageParameters() { new ProcessMessageParameter() {Name = "RuleIdentifier", Value = "VR.ATO.RDTIS.438052"} },
                };
                processMessage.Parameters.Add(new ProcessMessageParameter
                    { Name = "RDTIS36", Value = GetValueOrEmpty(report.RDTIS36) });
    
                processMessage.Parameters.Add(new ProcessMessageParameter
                    { Name = "RDTIS37", Value = GetValueOrEmpty(report.RDTIS37) });
    
                processMessage.Parameters.Add(new ProcessMessageParameter
                    { Name = "RDTIS45", Value = GetValueOrEmpty(report.RDTIS45) });
    
                processMessage.Parameters.Add(new ProcessMessageParameter
                    { Name = "RDTIS24", Value = GetValueOrEmpty(report.RDTIS24) });
    
                response.Add(processMessage);
            }
      }
      #endregion 
    
      #region VR.ATO.RDTIS.438053
      [MethodImpl(MethodImplOptions.AggressiveInlining)]
      public virtual void VRATORDTIS438053()
      {
        ProcessMessageDocument processMessage;
        bool assertion;
    
            /*  VR.ATO.RDTIS.438053
            Refundable tax offset Total notional R&D deductions and Non-refundable tax offset Total notional R&D deductions are both present
    
            Legacy Rule Format:
            IF [RDTIS45] <> NULL AND [RDTIS47] <> NULL
               RETURN VALIDATION MESSAGE
            ENDIF

            Technical Business Rule Format:
            ^RDTIS45 <> NULL AND ^RDTIS47 <> NULL
    
            Data Elements:
    
            ^RDTIS45 = RDTIS:RP:RefundableTaxOffset:TaxConcession.ResearchAndDevelopment.NotionalDeductionsRefundable.Amount
    
            ^RDTIS47 = RDTIS:RP:NonRefundableTaxOffset:TaxConcession.ResearchAndDevelopment.NotionalDeductionsNonRefundable.Amount
            */
            assertion = (report.RDTIS45 != null && report.RDTIS47 != null);
            if (assertion)
            {
                processMessage = new ProcessMessageDocument()
                {
                    Code = "CMN.ATO.RDTIS.438053", Severity = ProcessMessageSeverity.Error,
                    Description = @"Only a Refundable or Non-refundable tax offset is claimable.",
                    LongDescription = @"Only a Refundable or Non-refunable tax offset Total notional R&D deductions should be present",
                    Location = "/tns:RDTIS/tns:RP/tns:RefundableTaxOffset/tns:TaxConcessionResearchAndDevelopmentNotionalDeductionsRefundableA",
                    Parameters = new ProcessMessageParameters() { new ProcessMessageParameter() {Name = "RuleIdentifier", Value = "VR.ATO.RDTIS.438053"} },
                };
                processMessage.Parameters.Add(new ProcessMessageParameter
                    { Name = "RDTIS45", Value = GetValueOrEmpty(report.RDTIS45) });
    
                processMessage.Parameters.Add(new ProcessMessageParameter
                    { Name = "RDTIS47", Value = GetValueOrEmpty(report.RDTIS47) });
    
                response.Add(processMessage);
            }
      }
      #endregion 
    
      #region VR.ATO.RDTIS.438057
      [MethodImpl(MethodImplOptions.AggressiveInlining)]
      public virtual void VRATORDTIS438057()
      {
        ProcessMessageDocument processMessage;
        bool assertion;
    
            /*  VR.ATO.RDTIS.438057
            The Non-refundable R&D tax offset is being claimed: Group Totals Turnover is $20 million or greater or 'Exempt entity ownership of 50% or greater' question is 'True' or 'Aggregated turnover of $20 million or greater' question is 'True' and the Non-refundable tax offset Total notional R&D deductions is not equal to the Total notional R&D deductions
    
            Legacy Rule Format:
            IF ([RDTIS36] = TRUE OR [RDTIS37] = TRUE) AND [RDTIS47] <> [RDTIS24]
               RETURN VALIDATION MESSAGE
            ENDIF

            Technical Business Rule Format:
            (^RDTIS36 = TRUE OR ^RDTIS37 = TRUE) AND ^RDTIS47 <> ^RDTIS24
    
            Data Elements:
    
            ^RDTIS47 = RDTIS:RP:NonRefundableTaxOffset:TaxConcession.ResearchAndDevelopment.NotionalDeductionsNonRefundable.Amount
    
            ^RDTIS36 = RDTIS:RP:AggregatedTurnover:TaxConcession.ExemptEntityOwnership.Indicator
    
            ^RDTIS37 = RDTIS:RP:AggregatedTurnover:TaxConcession.AggregatedTurnoverAtOrAboveThreshold.Indicator
    
            ^RDTIS24 = RDTIS:RP:NotionalDeductionsCalculation:Expense.ResearchAndDevelopment.AllocatedTotal.Amount
            */
            assertion = ((report.RDTIS36 == true || report.RDTIS37 == true) && report.RDTIS47.GetValueOrDefault() != report.RDTIS24.GetValueOrDefault());
            if (assertion)
            {
                processMessage = new ProcessMessageDocument()
                {
                    Code = "CMN.ATO.RDTIS.438057", Severity = ProcessMessageSeverity.Error,
                    Description = @"Non-refundable tax offset Total notional R&D deductions must equal the Total notional R&D deductions",
                    LongDescription = @"The Non-refundable R&D tax offset is being claimed: Group Totals Turnover is $20 million or greater or 'Exempt entity ownership of 50% or greater' question is 'Yes' or 'Aggregated turnover of $20 million or greater' question is 'Yes' and the Non-refundable tax offset Total notional R&D deductions is not equal to the Total notional R&D deductions",
                    Location = "/tns:RDTIS/tns:RP/tns:NonRefundableTaxOffset/tns:TaxConcessionResearchAndDevelopmentNotionalDeductionsNonRefundableA",
                    Parameters = new ProcessMessageParameters() { new ProcessMessageParameter() {Name = "RuleIdentifier", Value = "VR.ATO.RDTIS.438057"} },
                };
                processMessage.Parameters.Add(new ProcessMessageParameter
                    { Name = "RDTIS36", Value = GetValueOrEmpty(report.RDTIS36) });
    
                processMessage.Parameters.Add(new ProcessMessageParameter
                    { Name = "RDTIS37", Value = GetValueOrEmpty(report.RDTIS37) });
    
                processMessage.Parameters.Add(new ProcessMessageParameter
                    { Name = "RDTIS47", Value = GetValueOrEmpty(report.RDTIS47) });
    
                processMessage.Parameters.Add(new ProcessMessageParameter
                    { Name = "RDTIS24", Value = GetValueOrEmpty(report.RDTIS24) });
    
                response.Add(processMessage);
            }
      }
      #endregion 
    
      #region VR.ATO.RDTIS.438065
      [MethodImpl(MethodImplOptions.AggressiveInlining)]
      public virtual void VRATORDTIS438065()
      {
        ProcessMessageDocument processMessage;
        bool assertion;
    
            /*  VR.ATO.RDTIS.438065
            Additional Group Members - Annual Turnover must not be completed if there are less then 19 specified group members
    
            Legacy Rule Format:
            IF [RDTIS52] <> NULL AND COUNT([RDTIS10010]) < 19 
              RETURN VALIDATION MESSAGE
            ENDIF

            Technical Business Rule Format:
            ^RDTIS52 <> NULL AND Count(^RDTIS10010) < 19
    
            Data Elements:
    
            ^RDTIS52 = RDTIS:RP:AggregatedTurnover:TaxConcession.ResearchAndDevelopment.TaxOffsetAdditionalEntitiesTurnover.Amount
    
            ^RDTIS10010 = RDTIS:RP:AggregatedTurnover:GroupMember
            */
            assertion = (report.RDTIS52 != null && Count(report.RP_AggregatedTurnover_GroupMemberCollectionCount) < 19);
            if (assertion)
            {
                processMessage = new ProcessMessageDocument()
                {
                    Code = "CMN.ATO.RDTIS.438065", Severity = ProcessMessageSeverity.Error,
                    Description = @"Additional Group Members - Annual Turnover must not be completed",
                    LongDescription = @"Additional Group Members - Annual Turnover must not be completed if there are less then 19 specified group members",
                    Location = "/tns:RDTIS/tns:RP/tns:AggregatedTurnover/tns:TaxConcessionResearchAndDevelopmentTaxOffsetAdditionalEntitiesTurnoverA",
                    Parameters = new ProcessMessageParameters() { new ProcessMessageParameter() {Name = "RuleIdentifier", Value = "VR.ATO.RDTIS.438065"} },
                };
                processMessage.Parameters.Add(new ProcessMessageParameter
                    { Name = "RDTIS52", Value = GetValueOrEmpty(report.RDTIS52) });
    
                response.Add(processMessage);
            }
      }
      #endregion 
    
      #region VR.ATO.RDTIS.438066
      [MethodImpl(MethodImplOptions.AggressiveInlining)]
      public virtual void VRATORDTIS438066()
      {
        ProcessMessageDocument processMessage;
        bool assertion;
    
            /*  VR.ATO.RDTIS.438066
            Aggregated turnover of $20 million or greater question is required if the answer to Exempt entity ownership of 50% or greater question is answered with a 'NO'
    
            Legacy Rule Format:
            IF [RDTIS36] = FALSE AND [RDTIS37] = NULL
               RETURN VALIDATION MESSAGE
            ENDIF

            Technical Business Rule Format:
            ^RDTIS36 = FALSE AND ^RDTIS37 = NULL
    
            Data Elements:
    
            ^RDTIS37 = RDTIS:RP:AggregatedTurnover:TaxConcession.AggregatedTurnoverAtOrAboveThreshold.Indicator
    
            ^RDTIS36 = RDTIS:RP:AggregatedTurnover:TaxConcession.ExemptEntityOwnership.Indicator
            */
            assertion = (report.RDTIS36 == false && report.RDTIS37 == null);
            if (assertion)
            {
                processMessage = new ProcessMessageDocument()
                {
                    Code = "CMN.ATO.RDTIS.438166", Severity = ProcessMessageSeverity.Error,
                    Description = @"Answer to 'Do you have an aggregated turnover of $20 million or greater?' is required",
                    LongDescription = @"Aggregated turnover of $20 million or greater question is required if the answer to Exempt entity ownership of 50% or greater question is answered with a 'NO'",
                    Location = "/tns:RDTIS/tns:RP/tns:AggregatedTurnover/tns:TaxConcessionAtOrAboveThresholdI",
                    Parameters = new ProcessMessageParameters() { new ProcessMessageParameter() {Name = "RuleIdentifier", Value = "VR.ATO.RDTIS.438066"} },
                };
                processMessage.Parameters.Add(new ProcessMessageParameter
                    { Name = "RDTIS36", Value = GetValueOrEmpty(report.RDTIS36) });
    
                processMessage.Parameters.Add(new ProcessMessageParameter
                    { Name = "RDTIS37", Value = GetValueOrEmpty(report.RDTIS37) });
    
                response.Add(processMessage);
            }
      }
      #endregion 
    
      #region VR.ATO.RDTIS.438101
      [MethodImpl(MethodImplOptions.AggressiveInlining)]
      public virtual void VRATORDTIS438101()
      {
        ProcessMessageDocument processMessage;
        bool assertion;
    
            /*  VR.ATO.RDTIS.438101
            Group Member TFN must not be the same as the reporting Company TFN
    
            Legacy Rule Format:
            IF ANY OCCURRENCE OF [RDTIS60] = [RDTIS70]
               RETURN VALIDATION MESSAGE
            ENDIF

            Technical Business Rule Format:
            AnyOccurrence(^RDTIS60, ^RDTIS60 = ^RDTIS70)
    
            Data Elements:
    
            ^RDTIS60 = RDTIS:RP:AggregatedTurnover:GroupMember:Identifiers.TaxFileNumber.Identifier
    
            ^RDTIS70 = RDTIS:RP:Identifiers.TaxFileNumber.Identifier
            */
            assertion = (report.RP_AggregatedTurnover_GroupMemberCollection == null ? false : report.RP_AggregatedTurnover_GroupMemberCollection.Any(RDTIS60Repeat => RDTIS60Repeat.RDTIS60 == report.RDTIS70));
            if (assertion)
            {
                processMessage = new ProcessMessageDocument()
                {
                    Code = "CMN.ATO.RDTIS.438101", Severity = ProcessMessageSeverity.Error,
                    Description = @"The supplied Group Member TFN must not be the same as the reporting Company TFN",
                    Location = "/tns:RDTIS/tns:RP/tns:AggregatedTurnover/tns:GroupMemberCollection/tns:GroupMember/tns:TaxFileNumberId",
                    Parameters = new ProcessMessageParameters() { new ProcessMessageParameter() {Name = "RuleIdentifier", Value = "VR.ATO.RDTIS.438101"} },
                };
                processMessage.Parameters.Add(new ProcessMessageParameter
                    { Name = "RDTIS60", Value = "RDTIS60" });
    
                processMessage.Parameters.Add(new ProcessMessageParameter
                    { Name = "RDTIS70", Value = "RDTIS70" });
    
                response.Add(processMessage);
            }
      }
      #endregion 
    
      #region VR.ATO.RDTIS.438106
      [MethodImpl(MethodImplOptions.AggressiveInlining)]
      public virtual void VRATORDTIS438106()
      {
        ProcessMessageDocument processMessage;
        bool assertion;
    
            /*  VR.ATO.RDTIS.438106
            Entities that have an exempt entity ownership of 50% or greater or have an aggregated turnover of $20 million or greater should claim the non-refundable R&D tax offset.
    
            Legacy Rule Format:
            IF ([RDTIS36] = TRUE OR [RDTIS37] = TRUE) AND ([RDTIS46] <> NULL)
               RETURN VALIDATION MESSAGE
            ENDIF

            Technical Business Rule Format:
            (^RDTIS36 = TRUE OR ^RDTIS37 = TRUE) AND (^RDTIS46 <> NULL)
    
            Data Elements:
    
            ^RDTIS46 = RDTIS:RP:RefundableTaxOffset:TaxConcession.ResearchAndDevelopment.TaxOffsetRefundable.Amount
    
            ^RDTIS36 = RDTIS:RP:AggregatedTurnover:TaxConcession.ExemptEntityOwnership.Indicator
    
            ^RDTIS37 = RDTIS:RP:AggregatedTurnover:TaxConcession.AggregatedTurnoverAtOrAboveThreshold.Indicator
            */
            assertion = ((report.RDTIS36 == true || report.RDTIS37 == true) && report.RDTIS46 != null);
            if (assertion)
            {
                processMessage = new ProcessMessageDocument()
                {
                    Code = "CMN.ATO.RDTIS.438106", Severity = ProcessMessageSeverity.Error,
                    Description = @"Refundable R&D tax offset must not be claimed.",
                    LongDescription = @"Entities that have an exempt entity ownership of 50% or greater or have an aggregated turnover of $20 million or greater should claim the non-refundable R&D tax offset.",
                    Location = "/tns:RDTIS/tns:RP/tns:RefundableTaxOffset/tns:TaxConcessionResearchAndDevelopmentTaxOffsetRefundableA",
                    Parameters = new ProcessMessageParameters() { new ProcessMessageParameter() {Name = "RuleIdentifier", Value = "VR.ATO.RDTIS.438106"} },
                };
                processMessage.Parameters.Add(new ProcessMessageParameter
                    { Name = "RDTIS36", Value = GetValueOrEmpty(report.RDTIS36) });
    
                processMessage.Parameters.Add(new ProcessMessageParameter
                    { Name = "RDTIS37", Value = GetValueOrEmpty(report.RDTIS37) });
    
                processMessage.Parameters.Add(new ProcessMessageParameter
                    { Name = "RDTIS46", Value = GetValueOrEmpty(report.RDTIS46) });
    
                response.Add(processMessage);
            }
      }
      #endregion 
    
      #region VR.ATO.RDTIS.438107
      [MethodImpl(MethodImplOptions.AggressiveInlining)]
      public virtual void VRATORDTIS438107()
      {
        ProcessMessageDocument processMessage;
        bool assertion;
    
            /*  VR.ATO.RDTIS.438107
            Entities that do not have an exempt entity ownership of 50% or greater and do not have an aggregated turnover of $20 million or greater should claim the refundable R&D tax offset.
    
            Legacy Rule Format:
            IF [RDTIS36] = FALSE AND [RDTIS37] = FALSE AND [RDTIS48] <> NULL
               RETURN VALIDATION MESSAGE
            ENDIF

            Technical Business Rule Format:
            ^RDTIS36 = FALSE AND ^RDTIS37 = FALSE AND ^RDTIS48 <> NULL
    
            Data Elements:
    
            ^RDTIS48 = RDTIS:RP:NonRefundableTaxOffset:TaxConcession.ResearchAndDevelopment.TaxOffsetNonRefundable.Amount
    
            ^RDTIS36 = RDTIS:RP:AggregatedTurnover:TaxConcession.ExemptEntityOwnership.Indicator
    
            ^RDTIS37 = RDTIS:RP:AggregatedTurnover:TaxConcession.AggregatedTurnoverAtOrAboveThreshold.Indicator
            */
            assertion = (report.RDTIS36 == false && report.RDTIS37 == false && report.RDTIS48 != null);
            if (assertion)
            {
                processMessage = new ProcessMessageDocument()
                {
                    Code = "CMN.ATO.RDTIS.438107", Severity = ProcessMessageSeverity.Error,
                    Description = @"Non-refundable R&D tax offset must not be claimed.",
                    LongDescription = @"Entities that do not have an exempt entity ownership of 50% or greater and do not have an aggregated turnover of $20 million or greater should claim the refundable R&D tax offset.",
                    Location = "/tns:RDTIS/tns:RP/tns:NonRefundableTaxOffset/tns:TaxConcessionResearchAndDevelopmentTaxOffsetNonRefundableA",
                    Parameters = new ProcessMessageParameters() { new ProcessMessageParameter() {Name = "RuleIdentifier", Value = "VR.ATO.RDTIS.438107"} },
                };
                processMessage.Parameters.Add(new ProcessMessageParameter
                    { Name = "RDTIS36", Value = GetValueOrEmpty(report.RDTIS36) });
    
                processMessage.Parameters.Add(new ProcessMessageParameter
                    { Name = "RDTIS37", Value = GetValueOrEmpty(report.RDTIS37) });
    
                processMessage.Parameters.Add(new ProcessMessageParameter
                    { Name = "RDTIS48", Value = GetValueOrEmpty(report.RDTIS48) });
    
                response.Add(processMessage);
            }
      }
      #endregion 
    
      #region VR.ATO.RDTIS.438108
      [MethodImpl(MethodImplOptions.AggressiveInlining)]
      public virtual void VRATORDTIS438108(RDTIS2023.RP_AggregatedTurnover_GroupMember groupMember, int itemIndex3)
      {
        ProcessMessageDocument processMessage;
        bool assertion;
            
                    /*  VR.ATO.RDTIS.438108
                    Tax File Number must pass the TFN algorithm check.
    
                    Legacy Rule Format:
                    IF (ANY OCCURRENCE OF [RDTIS60] <> NULL AND (TFNALGORITHM([RDTIS60]) = FALSE))
                       RETURN VALIDATION MESSAGE
                    ENDIF
        
                    Technical Business Rule Format:
                    (AnyOccurrence(^RDTIS60, ^RDTIS60 <> NULL) AND (FailsTFNAlgorithm(^RDTIS60)))
            
                    Data Elements:
            
                    ^RDTIS60 = RDTIS:RP:AggregatedTurnover:GroupMember:Identifiers.TaxFileNumber.Identifier
                    */
                    assertion = ((report.RP_AggregatedTurnover_GroupMemberCollection == null ? false : report.RP_AggregatedTurnover_GroupMemberCollection.Any(RDTIS60Repeat => RDTIS60Repeat.RDTIS60 != null)) && FailsTFNAlgorithm(groupMember.RDTIS60));
                    if (assertion)
                    {
                        processMessage = new ProcessMessageDocument()
                        {
                            Code = "CMN.ATO.GEN.428016", Severity = ProcessMessageSeverity.Error,
                            Description = @"Tax File Number has failed the algorithm check",
                            Location = "/tns:RDTIS/tns:RP/tns:AggregatedTurnover/tns:GroupMemberCollection/tns:GroupMember" + OccurrenceIndex(groupMember.OccurrenceIndex) + "/tns:TaxFileNumberId",
                            Parameters = new ProcessMessageParameters() { new ProcessMessageParameter() {Name = "RuleIdentifier", Value = "VR.ATO.RDTIS.438108"} },
                        };
                        processMessage.Parameters.Add(new ProcessMessageParameter
                            { Name = "RDTIS60", Value = "RDTIS60" });
            
                        response.Add(processMessage);
                    }
              }
              #endregion 
    
      #region VR.ATO.RDTIS.438110
      [MethodImpl(MethodImplOptions.AggressiveInlining)]
      public virtual void VRATORDTIS438110()
      {
        ProcessMessageDocument processMessage;
        bool assertion;
    
            /*  VR.ATO.RDTIS.438110
            Tax Rate must be provided if the Refundable R&D tax offset or Non-refundable R&D tax offset is being claimed.
    
            Legacy Rule Format:
            IF ([RDTIS46] > 0 OR [RDTIS48] > 0) AND [RDTIS78] = NULL
               RETURN VALIDATION MESSAGE
            ENDIF

            Technical Business Rule Format:
            (^RDTIS46 > 0 OR ^RDTIS48 > 0) AND ^RDTIS78 = NULL
    
            Data Elements:
    
            ^RDTIS78 = RDTIS:RP:TaxRate.Designation.Rate
    
            ^RDTIS46 = RDTIS:RP:RefundableTaxOffset:TaxConcession.ResearchAndDevelopment.TaxOffsetRefundable.Amount
    
            ^RDTIS48 = RDTIS:RP:NonRefundableTaxOffset:TaxConcession.ResearchAndDevelopment.TaxOffsetNonRefundable.Amount
            */
            assertion = ((report.RDTIS46.GetValueOrDefault() > 0 || report.RDTIS48.GetValueOrDefault() > 0) && report.RDTIS78 == null);
            if (assertion)
            {
                processMessage = new ProcessMessageDocument()
                {
                    Code = "CMN.ATO.RDTIS.438110", Severity = ProcessMessageSeverity.Error,
                    Description = @"Tax Rate must be provided if the Refundable R&D tax offset or Non-refundable R&D tax offset is being claimed.",
                    LongDescription = @"Tax Rate must be provided if the Refundable R&D tax offset or Non-refundable R&D tax offset is being claimed.",
                    Location = "/tns:RDTIS/tns:RP/tns:TaxRateDesignationR",
                    Parameters = new ProcessMessageParameters() { new ProcessMessageParameter() {Name = "RuleIdentifier", Value = "VR.ATO.RDTIS.438110"} },
                };
                processMessage.Parameters.Add(new ProcessMessageParameter
                    { Name = "RDTIS46", Value = GetValueOrEmpty(report.RDTIS46) });
    
                processMessage.Parameters.Add(new ProcessMessageParameter
                    { Name = "RDTIS48", Value = GetValueOrEmpty(report.RDTIS48) });
    
                processMessage.Parameters.Add(new ProcessMessageParameter
                    { Name = "RDTIS78", Value = GetValueOrEmpty(report.RDTIS78) });
    
                response.Add(processMessage);
            }
      }
      #endregion 
    
      #region VR.ATO.RDTIS.438112
      [MethodImpl(MethodImplOptions.AggressiveInlining)]
      public virtual void VRATORDTIS438112()
      {
        ProcessMessageDocument processMessage;
        bool assertion;
    
            /*  VR.ATO.RDTIS.438112
            R&D entity total expenses must be present and equal to or greater than zero if Non-Refundable R&D tax offset is being claimed.
    
            Legacy Rule Format:
            IF ([RDTIS36] = TRUE OR [RDTIS37] = TRUE) AND [RDTIS81] = NULL
               RETURN VALIDATION MESSAGE
            ENDIF

            Technical Business Rule Format:
            (^RDTIS36 = TRUE OR ^RDTIS37 = TRUE) AND ^RDTIS81 = NULL
    
            Data Elements:
    
            ^RDTIS81 = RDTIS:RP:NonRefundableTaxOffset:Expense.ResearchAndDevelopment.Total.Amount
    
            ^RDTIS36 = RDTIS:RP:AggregatedTurnover:TaxConcession.ExemptEntityOwnership.Indicator
    
            ^RDTIS37 = RDTIS:RP:AggregatedTurnover:TaxConcession.AggregatedTurnoverAtOrAboveThreshold.Indicator
            */
            assertion = ((report.RDTIS36 == true || report.RDTIS37 == true) && report.RDTIS81 == null);
            if (assertion)
            {
                processMessage = new ProcessMessageDocument()
                {
                    Code = "CMN.ATO.RDTIS.438212", Severity = ProcessMessageSeverity.Error,
                    Description = @"R&D entity total expenses must be present and equal to or greater than zero if Non-Refundable R&D tax offset is being claimed.",
                    LongDescription = @"R&D entity total expenses must be present and equal to or greater than zero if Non-Refundable R&D tax offset is being claimed.",
                    Location = "/tns:RDTIS/tns:RP/tns:NonRefundableTaxOffset/tns:ExpenseResearchAndDevelopmentTotalA",
                    Parameters = new ProcessMessageParameters() { new ProcessMessageParameter() {Name = "RuleIdentifier", Value = "VR.ATO.RDTIS.438112"} },
                };
                processMessage.Parameters.Add(new ProcessMessageParameter
                    { Name = "RDTIS36", Value = GetValueOrEmpty(report.RDTIS36) });
    
                processMessage.Parameters.Add(new ProcessMessageParameter
                    { Name = "RDTIS37", Value = GetValueOrEmpty(report.RDTIS37) });
    
                processMessage.Parameters.Add(new ProcessMessageParameter
                    { Name = "RDTIS81", Value = GetValueOrEmpty(report.RDTIS81) });
    
                response.Add(processMessage);
            }
      }
      #endregion 
    
      #region VR.ATO.RDTIS.438113
      [MethodImpl(MethodImplOptions.AggressiveInlining)]
      public virtual void VRATORDTIS438113()
      {
        ProcessMessageDocument processMessage;
        bool assertion;
    
            /*  VR.ATO.RDTIS.438113
            Mandatory field not supplied
    
            Legacy Rule Format:
            IF [RDTIS36] = NULL
               RETURN VALIDATION MESSAGE
            ENDIF

            Technical Business Rule Format:
            ^RDTIS36 = NULL
    
            Data Elements:
    
            ^RDTIS36 = RDTIS:RP:AggregatedTurnover:TaxConcession.ExemptEntityOwnership.Indicator
            */
            assertion = (report.RDTIS36 == null);
            if (assertion)
            {
                processMessage = new ProcessMessageDocument()
                {
                    Code = "CMN.ATO.GEN.001001", Severity = ProcessMessageSeverity.Error,
                    Description = @"Mandatory field not supplied",
                    Location = "/tns:RDTIS/tns:RP/tns:AggregatedTurnover/tns:TaxConcessionExemptEntityOwnershipI",
                    Parameters = new ProcessMessageParameters() { new ProcessMessageParameter() {Name = "RuleIdentifier", Value = "VR.ATO.RDTIS.438113"} },
                };
                processMessage.Parameters.Add(new ProcessMessageParameter
                    { Name = "RDTIS36", Value = GetValueOrEmpty(report.RDTIS36) });
    
                response.Add(processMessage);
            }
      }
      #endregion 
    
      #region VR.ATO.RDTIS.438114
      [MethodImpl(MethodImplOptions.AggressiveInlining)]
      public virtual void VRATORDTIS438114()
      {
        ProcessMessageDocument processMessage;
        bool assertion;
    
            /*  VR.ATO.RDTIS.438114
            Reporting entity - Annual turnover must be provided if the answer to both 'Do you have exempt entity ownership of 50% or greater' question and 'Do you have an aggregated turnover of $20 million or greater' question are answered ‘NO’
    
            Legacy Rule Format:
            IF ([RDTIS36] = FALSE AND [RDTIS37] = FALSE) AND [RDTIS38] = NULL
               RETURN VALIDATION MESSAGE
            ENDIF

            Technical Business Rule Format:
            (^RDTIS36 = FALSE AND ^RDTIS37 = FALSE) AND ^RDTIS38 = NULL
    
            Data Elements:
    
            ^RDTIS38 = RDTIS:RP:AggregatedTurnover:TaxConcession.ResearchAndDevelopment.TaxOffsetEntityTurnover.Amount
    
            ^RDTIS36 = RDTIS:RP:AggregatedTurnover:TaxConcession.ExemptEntityOwnership.Indicator
    
            ^RDTIS37 = RDTIS:RP:AggregatedTurnover:TaxConcession.AggregatedTurnoverAtOrAboveThreshold.Indicator
            */
            assertion = (report.RDTIS36 == false && report.RDTIS37 == false && report.RDTIS38 == null);
            if (assertion)
            {
                processMessage = new ProcessMessageDocument()
                {
                    Code = "CMN.ATO.RDTIS.438214", Severity = ProcessMessageSeverity.Error,
                    Description = @"Reporting entity - Annual turnover must be supplied if the answer to both 'Do you have exempt entity ownership of 50% or greater' and 'Do you have an aggregated turnover of $20 million or greater?' are FALSE.",
                    LongDescription = @"Reporting entity - Annual turnover must be provided if the answer to both 'Do you have exempt entity ownership of 50% or greater' question and 'Do you have an aggregated turnover of $20 million or greater' question are answered 'NO'",
                    Location = "/tns:RDTIS/tns:RP/tns:AggregatedTurnover/tns:TaxConcessionResearchAndDevelopmentTaxOffsetEntityTurnoverA",
                    Parameters = new ProcessMessageParameters() { new ProcessMessageParameter() {Name = "RuleIdentifier", Value = "VR.ATO.RDTIS.438114"} },
                };
                processMessage.Parameters.Add(new ProcessMessageParameter
                    { Name = "RDTIS36", Value = GetValueOrEmpty(report.RDTIS36) });
    
                processMessage.Parameters.Add(new ProcessMessageParameter
                    { Name = "RDTIS37", Value = GetValueOrEmpty(report.RDTIS37) });
    
                processMessage.Parameters.Add(new ProcessMessageParameter
                    { Name = "RDTIS38", Value = GetValueOrEmpty(report.RDTIS38) });
    
                response.Add(processMessage);
            }
      }
      #endregion 
    
      #region VR.ATO.RDTIS.438115
      [MethodImpl(MethodImplOptions.AggressiveInlining)]
      public virtual void VRATORDTIS438115()
      {
        ProcessMessageDocument processMessage;
        bool assertion;
    
            /*  VR.ATO.RDTIS.438115
            If Aggregated Turnover is equal to or greater than $20 million, then Refundable R&D tax offset must not be claimed and Non-refundable R&D tax offset must be claimed
    
            Legacy Rule Format:
            IF [RDTIS44] >= 20000000 AND ([RDTIS46] <> NULL OR [RDTIS48] = NULL)
               RETURN VALIDATION MESSAGE
            ENDIF

            Technical Business Rule Format:
            ^RDTIS44 >= 20000000 AND (^RDTIS46 <> NULL OR ^RDTIS48 = NULL)
    
            Data Elements:
    
            ^RDTIS44 = RDTIS:RP:AggregatedTurnover:TaxConcession.ResearchAndDevelopment.TaxOffsetTurnoverTotal.Amount
    
            ^RDTIS46 = RDTIS:RP:RefundableTaxOffset:TaxConcession.ResearchAndDevelopment.TaxOffsetRefundable.Amount
    
            ^RDTIS48 = RDTIS:RP:NonRefundableTaxOffset:TaxConcession.ResearchAndDevelopment.TaxOffsetNonRefundable.Amount
            */
            assertion = (report.RDTIS44.GetValueOrDefault() >= 20000000 && (report.RDTIS46 != null || report.RDTIS48 == null));
            if (assertion)
            {
                processMessage = new ProcessMessageDocument()
                {
                    Code = "CMN.ATO.RDTIS.438215", Severity = ProcessMessageSeverity.Error,
                    Description = @"Refundable R&D tax offset must not be claimed and Non-refundable R&D tax offset must be claimed if the Aggregated Turnover is equal to or greater than $20 million",
                    LongDescription = @"If Aggregated Turnover is equal to or greater than $20 million, then Refundable R&D tax offset must not be claimed and Non-refundable R&D tax offset must be claimed",
                    Location = "/tns:RDTIS/tns:RP/tns:AggregatedTurnover/tns:TaxConcessionResearchAndDevelopmentTaxOffsetTurnoverTotalA",
                    Parameters = new ProcessMessageParameters() { new ProcessMessageParameter() {Name = "RuleIdentifier", Value = "VR.ATO.RDTIS.438115"} },
                };
                processMessage.Parameters.Add(new ProcessMessageParameter
                    { Name = "RDTIS44", Value = GetValueOrEmpty(report.RDTIS44) });
    
                processMessage.Parameters.Add(new ProcessMessageParameter
                    { Name = "RDTIS46", Value = GetValueOrEmpty(report.RDTIS46) });
    
                processMessage.Parameters.Add(new ProcessMessageParameter
                    { Name = "RDTIS48", Value = GetValueOrEmpty(report.RDTIS48) });
    
                response.Add(processMessage);
            }
      }
      #endregion 

    }
} 
