
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.CodeGenerationRS
{

    public partial class RS2018Validator
    {
        /// <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>
        /// Initializes a new instance of the <see cref="RS2018Validator" /> 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 RS2018Validator(int maxParameterNameLength = 20, int maxParameterValueLength = 4096, string emptyParameterValue = "EMPTY")
        {
            _maxParameterNameLength = maxParameterNameLength;
            _maxParameterValueLength = maxParameterValueLength;
            _emptyParameterValue = emptyParameterValue;
        }

        #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() : string.Empty;
        }

        private static string GetValueOrEmpty(DateTime? 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() == nodes.Count());
        }

        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;
        }
				//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;
            if (usi == null || abn == null)
            {
                response = false;
            }
            else
            {
                usi = usi.Trim();
                abn = abn.Trim();
                if (usi.Length < 13 || abn.Length < 11)
                {
                    response = false;
                }
                else
                {
                    int numeric;
                    if (usi.Substring(0, 11) == abn && int.TryParse(usi.Substring(11, 2), out numeric))
                        response = false;
                    else if (Regex.IsMatch(usi, @"^[a-zA-Z]{3}\d{4}[a-zA-Z]{2}"))
                        response = false;
                    else
                        response = true;
                }
            }
            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;
        }

        /// <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 RS2018 ConsumedReport { get; private set; }

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

        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public List<ProcessMessageDocument> ValidateReport(RS2018 report)
        {

            List<ProcessMessageDocument> response = new List<ProcessMessageDocument>();
            ProcessMessageDocument processMessage;
            ProcessMessageParameter parameter;
            bool assertion;

            this.ConsumedReport = report;


    
            #region VR.ATO.GEN.000209
    
            /*  VR.ATO.GEN.000209
            Invalid context. The number of Reporting party contexts must equal 1
    
            Legacy Rule Format:
            IF COUNT(RP) <> 1
            RETURN VALIDATION MESSAGE
            ENDIF

            Technical Business Rule Format:
            Count(^Context) <> 1
    
            Data Elements:
    
            ^Context = RP
            */
            assertion = (Count(report.RPCount) != 1);
            if (assertion)
            {
                processMessage = new ProcessMessageDocument()
                {
                    Code = "CMN.ATO.GEN.430296", Severity = ProcessMessageSeverity.Error,
                    Description = @"Invalid context. The number of Reporting party contexts must equal 1",
                    Location = "/xbrli:xbrl/xbrli:context" + OccurrenceIndex(report.RPLastOccurrenceIndex),
                    Parameters = new ProcessMessageParameters() { new ProcessMessageParameter() {Name = "RuleIdentifier", Value = "VR.ATO.GEN.000209"} },
                };
                response.Add(processMessage);
            }
            #endregion // VR.ATO.GEN.000209
    
            #region VR.ATO.GEN.000406
    
            /*  VR.ATO.GEN.000406
            Address field contains incorrect 'care of' reference.  The only acceptable 'care of' reference is C/-.
    
            Legacy Rule Format:
            IF (pyde.xx.xx:AddressDetails.Line1.Text <> NULLORBLANK) AND (pyde.xx.xx:AddressDetails.Line1.Text STARTSWITH SET("C/O ","C/ ","Care Of ","CO ")) OR (pyde.xx.xx:AddressDetails.Line1.Text CONTAINS SET(" C/O "," C/ "," Care Of "))
               RETURN VALIDATION MESSAGE
            ENDIF

            Technical Business Rule Format:
            (^RS17 <> BLANK) AND (StartsWithSet(^RS17,'"C/O ","C/ ","Care Of ","CO "')) OR (ContainsSet(^RS17, '" C/O "," C/ "," Care Of "'))
    
            Data Elements:
    
            RP:^RS17 = tns:AddressDetails.Line1.Text
            */
            assertion = (string.IsNullOrWhiteSpace(report.RS17) != true && IsMatch(report.RS17, @"^(C/O |C/ |Care Of |CO )",RegexOptions.IgnoreCase) || IsMatch(report.RS17, @" C/O | C/ | Care Of ",RegexOptions.IgnoreCase));
            if (assertion)
            {
                processMessage = new ProcessMessageDocument()
                {
                    Code = "CMN.ATO.GEN.000406", Severity = ProcessMessageSeverity.Error,
                    Description = @"Address line 1 contains incorrect 'care of' reference.  The only acceptable 'care of' reference is C/-",
                    Location = "/xbrli:xbrl/tns:AddressDetails.Line1.Text",
                    Parameters = new ProcessMessageParameters() { new ProcessMessageParameter() {Name = "RuleIdentifier", Value = "VR.ATO.GEN.000406"} },
                };
                processMessage.Parameters.Add(new ProcessMessageParameter
                    { Name = "RS17", Value = report.RS17 });
    
                response.Add(processMessage);
            }
            #endregion // VR.ATO.GEN.000406
    
            #region VR.ATO.GEN.000408
    
            /*  VR.ATO.GEN.000408
            Address line 2 field cannot contain 'care of' reference.
    
            Legacy Rule Format:
            IF (pyde.xx.xx:AddressDetails.Line2.Text <> NULLORBLANK) AND (pyde.xx.xx:AddressDetails.Line2.Text STARTSWITH SET("C/- ","C/O ","C/ ","Care Of ","CO ") OR pyde.xx.xx:AddressDetails.Line2.Text CONTAINS SET(" C/- "," C/O "," C/ "," Care Of "))
               RETURN VALIDATION MESSAGE
            ENDIF

            Technical Business Rule Format:
            (^RS18 <> BLANK) AND (StartsWithSet(^RS18,'"C/- ","C/O ","C/ ","Care Of ","CO "') OR ContainsSet(^RS18, '" C/- "," C/O "," C/ "," Care Of "'))
    
            Data Elements:
    
            RP:^RS18 = tns:AddressDetails.Line2.Text
            */
            assertion = (string.IsNullOrWhiteSpace(report.RS18) != true && (IsMatch(report.RS18, @"^(C/- |C/O |C/ |Care Of |CO )",RegexOptions.IgnoreCase) || IsMatch(report.RS18, @" C/- | C/O | C/ | Care Of ",RegexOptions.IgnoreCase)));
            if (assertion)
            {
                processMessage = new ProcessMessageDocument()
                {
                    Code = "CMN.ATO.GEN.000408", Severity = ProcessMessageSeverity.Error,
                    Description = @"Care of' is not valid for address line 2",
                    Location = "/xbrli:xbrl/tns:AddressDetails.Line2.Text",
                    Parameters = new ProcessMessageParameters() { new ProcessMessageParameter() {Name = "RuleIdentifier", Value = "VR.ATO.GEN.000408"} },
                };
                processMessage.Parameters.Add(new ProcessMessageParameter
                    { Name = "RS18", Value = report.RS18 });
    
                response.Add(processMessage);
            }
            #endregion // VR.ATO.GEN.000408
    
            #region VR.ATO.GEN.428026
    
            /*  VR.ATO.GEN.428026
            Address line 1 contains 'Care of' reference and no street address in Address line 2. If 'Care of' reference is on Address line 1, it must be followed by a name then Address line 2 must contain the street address.
    
            Legacy Rule Format:
            IF ((pyde.xx.xx:AddressDetails.Line1.Text CONTAINS "C/-") AND (pyde.xx.xx:AddressDetails.Line 2.Text = NULLORBLANK))
               RETURN VALIDATION MESSAGE
            ENDIF

            Technical Business Rule Format:
            ((Contains(^RS17, 'C/-')) AND (^RS18 = BLANK))
    
            Data Elements:
    
            RP:^RS17 = tns:AddressDetails.Line1.Text
    
            RP:^RS18 = tns:AddressDetails.Line2.Text
            */
            assertion = ((report.RS17 == null ? false : report.RS17.ToUpperInvariant().Contains(@"C/-")) && string.IsNullOrWhiteSpace(report.RS18) == true);
            if (assertion)
            {
                processMessage = new ProcessMessageDocument()
                {
                    Code = "CMN.ATO.GEN.428026", Severity = ProcessMessageSeverity.Error,
                    Description = @"C/- must be followed by a Name and the Address on line 2",
                    Location = "/xbrli:xbrl/tns:AddressDetails.Line1.Text",
                    Parameters = new ProcessMessageParameters() { new ProcessMessageParameter() {Name = "RuleIdentifier", Value = "VR.ATO.GEN.428026"} },
                };
                processMessage.Parameters.Add(new ProcessMessageParameter
                    { Name = "RS17", Value = report.RS17 });
    
                processMessage.Parameters.Add(new ProcessMessageParameter
                    { Name = "RS18", Value = report.RS18 });
    
                response.Add(processMessage);
            }
            #endregion // VR.ATO.GEN.428026
    
            #region VR.ATO.GEN.428036
    
            /*  VR.ATO.GEN.428036
            Value entered is not a valid code/value for that field.
    
            Legacy Rule Format:
            IF (pyde.xx.xx:AddressDetails.StateOrTerritory.Code <> NULLORBLANK) AND (pyde.xx.xx:AddressDetails.StateOrTerritory.Code <> SET("QLD","NSW","VIC","SA","WA","NT","ACT","TAS"))
               RETURN VALIDATION MESSAGE
            ENDIF

            Technical Business Rule Format:
            (^RS21 <> BLANK) AND (NotInSet(^RS21, '"QLD","NSW","VIC","SA","WA","NT","ACT","TAS"'))
    
            Data Elements:
    
            RP:^RS21 = tns:AddressDetails.StateOrTerritory.Code
            */
            assertion = (string.IsNullOrWhiteSpace(report.RS21) != true && !(IsMatch(report.RS21, @"^(QLD|NSW|VIC|SA|WA|NT|ACT|TAS)$",RegexOptions.IgnoreCase)));
            if (assertion)
            {
                processMessage = new ProcessMessageDocument()
                {
                    Code = "CMN.ATO.GEN.428036", Severity = ProcessMessageSeverity.Error,
                    Description = @"Invalid State code",
                    LongDescription = @"The State code in the Current address is not Valid (Valid States are ""QLD "",""NSW "",""VIC "",""SA "",""WA "",""NT "",""ACT "",""TAS)",
                    Location = "/xbrli:xbrl/tns:AddressDetails.StateOrTerritory.Code",
                    Parameters = new ProcessMessageParameters() { new ProcessMessageParameter() {Name = "RuleIdentifier", Value = "VR.ATO.GEN.428036"} },
                };
                processMessage.Parameters.Add(new ProcessMessageParameter
                    { Name = "RS21", Value = report.RS21 });
    
                response.Add(processMessage);
            }
            #endregion // VR.ATO.GEN.428036
    
            #region VR.ATO.GEN.428041
    
            /*  VR.ATO.GEN.428041
            Value entered is not a valid code/value for that field.
    
            Legacy Rule Format:
            IF (pyde.xx.xx:AddressDetails.Postcode.Text <> NULLORBLANK) AND (pyde.xx.xx:AddressDetails.Postcode.Text  <> SET(0200-9999))
               RETURN VALIDATION MESSAGE
            ENDIF

            Technical Business Rule Format:
            (^RS20 <> BLANK) AND (NotInSet(^RS20, '0200-9999'))
    
            Data Elements:
    
            RP:^RS20 = tns:AddressDetails.Postcode.Text
            */
            assertion = (string.IsNullOrWhiteSpace(report.RS20) != true && !(IsMatch(report.RS20, @"^([0200-9999])*$",RegexOptions.IgnoreCase)));
            if (assertion)
            {
                processMessage = new ProcessMessageDocument()
                {
                    Code = "CMN.ATO.GEN.428041", Severity = ProcessMessageSeverity.Error,
                    Description = @"For an Australian address, postcode is invalid. Valid range is 0200 - 9999",
                    Location = "/xbrli:xbrl/tns:AddressDetails.Postcode.Text",
                    Parameters = new ProcessMessageParameters() { new ProcessMessageParameter() {Name = "RuleIdentifier", Value = "VR.ATO.GEN.428041"} },
                };
                processMessage.Parameters.Add(new ProcessMessageParameter
                    { Name = "RS20", Value = report.RS20 });
    
                response.Add(processMessage);
            }
            #endregion // VR.ATO.GEN.428041
    
            #region VR.ATO.GEN.428230
    
            /*  VR.ATO.GEN.428230
            Suburb/Town/City cannot contain state code
    
            Legacy Rule Format:
            IF (pyde.xx.xx:AddressDetails.LocalityName.Text = FOUND("QLD","NSW","VIC","SA","WA","NT","ACT","TAS"))
               RETURN VALIDATION MESSAGE
            ENDIF

            Technical Business Rule Format:
            (FoundSet(^RS19, '"QLD","NSW","VIC","SA","WA","NT","ACT","TAS"'))
    
            Data Elements:
    
            RP:^RS19 = tns:AddressDetails.LocalityName.Text
            */
            assertion = IsMatch(report.RS19, @"(^(QLD|NSW|VIC|SA|WA|NT|ACT|TAS)$)|(^(.*)( QLD | NSW | VIC | SA | WA | NT | ACT | TAS )(.*)$)|(^(QLD |NSW |VIC |SA |WA |NT |ACT |TAS )(.*)$)|(^(.*)( QLD| NSW| VIC| SA| WA| NT| ACT| TAS)$)",RegexOptions.IgnoreCase);
            if (assertion)
            {
                processMessage = new ProcessMessageDocument()
                {
                    Code = "CMN.ATO.GEN.000411", Severity = ProcessMessageSeverity.Error,
                    Description = @"Suburb/Town/City cannot contain state code",
                    Location = "/xbrli:xbrl/tns:AddressDetails.LocalityName.Text",
                    Parameters = new ProcessMessageParameters() { new ProcessMessageParameter() {Name = "RuleIdentifier", Value = "VR.ATO.GEN.428230"} },
                };
                processMessage.Parameters.Add(new ProcessMessageParameter
                    { Name = "RS19", Value = report.RS19 });
    
                response.Add(processMessage);
            }
            #endregion // VR.ATO.GEN.428230
    
            #region VR.ATO.GEN.428257
    
            /*  VR.ATO.GEN.428257
            Suburb/Town/City cannot contain numeric characters
    
            Legacy Rule Format:
            IF (pyde.xx.xx:AddressDetails.LocalityName.Text CONTAINS NUMERICS SET(0-9))
               RETURN VALIDATION MESSAGE
            ENDIF

            Technical Business Rule Format:
            (ContainsSet(^RS19, '0-9'))
    
            Data Elements:
    
            RP:^RS19 = tns:AddressDetails.LocalityName.Text
            */
            assertion = IsMatch(report.RS19, @"[0-9]",RegexOptions.IgnoreCase);
            if (assertion)
            {
                processMessage = new ProcessMessageDocument()
                {
                    Code = "CMN.ATO.GEN.000410", Severity = ProcessMessageSeverity.Error,
                    Description = @"Suburb/Town/City cannot contain numeric characters",
                    Location = "/xbrli:xbrl/tns:AddressDetails.LocalityName.Text",
                    Parameters = new ProcessMessageParameters() { new ProcessMessageParameter() {Name = "RuleIdentifier", Value = "VR.ATO.GEN.428257"} },
                };
                processMessage.Parameters.Add(new ProcessMessageParameter
                    { Name = "RS19", Value = report.RS19 });
    
                response.Add(processMessage);
            }
            #endregion // VR.ATO.GEN.428257
    
            #region VR.ATO.GEN.500009
    
            /*  VR.ATO.GEN.500009
            The TFN has failed the algorithm check.
    
            Legacy Rule Format:
            IF (TFNALGORITHM (RP:entity.identifier.TFN) = FALSE)
               RETURN VALIDATION MESSAGE
            ENDIF

            Technical Business Rule Format:
            (FailsTFNAlgorithm(^TFN))
    
            Data Elements:
    
            ^TFN = RP
            */
            assertion = FailsTFNAlgorithm(report.RPIdentifierTFN);
            if (assertion)
            {
                processMessage = new ProcessMessageDocument()
                {
                    Code = "CMN.ATO.GEN.500009", Severity = ProcessMessageSeverity.Error,
                    Description = @"Reporting Party Tax File Number has failed the algorithm check",
                    Location = "/xbrli:xbrl/xbrli:context" + OccurrenceIndex(report.RPOccurrenceIndex) + "/xbrli:entity/xbrli:identifier",
                    Parameters = new ProcessMessageParameters() { new ProcessMessageParameter() {Name = "RuleIdentifier", Value = "VR.ATO.GEN.500009"} },
                };
                response.Add(processMessage);
            }
            #endregion // VR.ATO.GEN.500009
    
            #region VR.ATO.GEN.500018
    
            /*  VR.ATO.GEN.500018
            Address Line 1 has a maximum field length of 38
    
            Legacy Rule Format:
            IF LENGTH(pyde.xx.xx:AddressDetails.Line1.Text) > 38
                 RETURN VALIDATION MESSAGE
            ENDIF

            Technical Business Rule Format:
            Length(^RS17) > 38
    
            Data Elements:
    
            RP:^RS17 = tns:AddressDetails.Line1.Text
            */
            assertion = (Length(report.RS17) > 38);
            if (assertion)
            {
                processMessage = new ProcessMessageDocument()
                {
                    Code = "CMN.ATO.GEN.500018", Severity = ProcessMessageSeverity.Error,
                    Description = @"Address Line 1 must not exceed 38 characters",
                    LongDescription = @"For Address Line 1, the maximum allowable characters for this form is 38",
                    Location = "/xbrli:xbrl/tns:AddressDetails.Line1.Text",
                    Parameters = new ProcessMessageParameters() { new ProcessMessageParameter() {Name = "RuleIdentifier", Value = "VR.ATO.GEN.500018"} },
                };
                processMessage.Parameters.Add(new ProcessMessageParameter
                    { Name = "RS17", Value = report.RS17 });
    
                response.Add(processMessage);
            }
            #endregion // VR.ATO.GEN.500018
    
            #region VR.ATO.GEN.500019
    
            /*  VR.ATO.GEN.500019
            Address Line 2 has a maximum field length of 38
    
            Legacy Rule Format:
            IF LENGTH(pyde.xx.xx:AddressDetails.Line2.Text) > 38
                 RETURN VALIDATION MESSAGE
            ENDIF

            Technical Business Rule Format:
            Length(^RS18) > 38
    
            Data Elements:
    
            RP:^RS18 = tns:AddressDetails.Line2.Text
            */
            assertion = (Length(report.RS18) > 38);
            if (assertion)
            {
                processMessage = new ProcessMessageDocument()
                {
                    Code = "CMN.ATO.GEN.500019", Severity = ProcessMessageSeverity.Error,
                    Description = @"Address Line 2 must not exceed 38 characters",
                    LongDescription = @"For Address Line 2, the maximum allowable characters for this form is 38",
                    Location = "/xbrli:xbrl/tns:AddressDetails.Line2.Text",
                    Parameters = new ProcessMessageParameters() { new ProcessMessageParameter() {Name = "RuleIdentifier", Value = "VR.ATO.GEN.500019"} },
                };
                processMessage.Parameters.Add(new ProcessMessageParameter
                    { Name = "RS18", Value = report.RS18 });
    
                response.Add(processMessage);
            }
            #endregion // VR.ATO.GEN.500019
    
            #region VR.ATO.GEN.500020
    
            /*  VR.ATO.GEN.500020
            Locality Name has a maximum field length of 27
    
            Legacy Rule Format:
            IF LENGTH(pyde.xx.xx:AddressDetails.LocalityName.Text) > 27
                 RETURN VALIDATION MESSAGE
            ENDIF

            Technical Business Rule Format:
            Length(^RS19) > 27
    
            Data Elements:
    
            RP:^RS19 = tns:AddressDetails.LocalityName.Text
            */
            assertion = (Length(report.RS19) > 27);
            if (assertion)
            {
                processMessage = new ProcessMessageDocument()
                {
                    Code = "CMN.ATO.GEN.500020", Severity = ProcessMessageSeverity.Error,
                    Description = @"Suburb/Town/City must not exceed 27 characters",
                    LongDescription = @"For Locality Name, the maximum allowable characters for this form is 27",
                    Location = "/xbrli:xbrl/tns:AddressDetails.LocalityName.Text",
                    Parameters = new ProcessMessageParameters() { new ProcessMessageParameter() {Name = "RuleIdentifier", Value = "VR.ATO.GEN.500020"} },
                };
                processMessage.Parameters.Add(new ProcessMessageParameter
                    { Name = "RS19", Value = report.RS19 });
    
                response.Add(processMessage);
            }
            #endregion // VR.ATO.GEN.500020
    
            #region VR.ATO.GEN.500026
    
            /*  VR.ATO.GEN.500026
            A text character must be one of the following: A to Z a to z 0 to 9 ! @ $ % & * ( ) - = [ ] ; : ' " , . ? / or a space character.
    
            Legacy Rule Format:
            IF (pyde.xx.xx:AddressDetails.Line1.Text <> NULLORBLANK) AND (ANY CHARACTER OF pyde.xx.xx:AddressDetails.Line1.Text <> SET(a-z,A-Z,0-9,"!","@","$","%","&","*","(",")","-","=","[","]",";",":","'",""",",",".","?","/"," "))
               RETURN VALIDATION MESSAGE
            ENDIF

            Technical Business Rule Format:
            (^RS17 <> BLANK) AND (NotCharacterInSet(^RS17, 'a-z,A-Z,0-9,"!","@","$","%","&","*","(",")","-","=","[","]",";",":","'",""",",",".","?","/"," "'))
    
            Data Elements:
    
            RP:^RS17 = tns:AddressDetails.Line1.Text
            */
            assertion = (string.IsNullOrWhiteSpace(report.RS17) != true && !(IsMatch(report.RS17, @"^[a-z,A-Z,0-9,""!@\$%&\*\(\)\-=\[\];:'"",\.\?/ ""]*$",RegexOptions.IgnoreCase)));
            if (assertion)
            {
                processMessage = new ProcessMessageDocument()
                {
                    Code = "CMN.ATO.GEN.500026", Severity = ProcessMessageSeverity.Error,
                    Description = @"Address Line 1 contains invalid text",
                    LongDescription = @"A text character must be one of the following: A to Z a to z 0 to 9 ! @ $ % & * ( ) - = [ ] ; : ' "" , . ? / or a space character",
                    Location = "/xbrli:xbrl/tns:AddressDetails.Line1.Text",
                    Parameters = new ProcessMessageParameters() { new ProcessMessageParameter() {Name = "RuleIdentifier", Value = "VR.ATO.GEN.500026"} },
                };
                processMessage.Parameters.Add(new ProcessMessageParameter
                    { Name = "RS17", Value = report.RS17 });
    
                response.Add(processMessage);
            }
            #endregion // VR.ATO.GEN.500026
    
            #region VR.ATO.GEN.500027
    
            /*  VR.ATO.GEN.500027
            A text character must be one of the following: A to Z a to z 0 to 9 ! @ $ % & * ( ) - = [ ] ; : ' " , . ? / or a space character.
    
            Legacy Rule Format:
            IF (pyde.xx.xx:AddressDetails.Line2.Text <> NULLORBLANK) AND (ANY CHARACTER OF pyde.xx.xx:AddressDetails.Line2.Text <> SET(a-z,A-Z,0-9,"!","@","$","%","&","*","(",")","-","=","[","]",";",":","'",""",",",".","?","/"," "))
               RETURN VALIDATION MESSAGE
            ENDIF

            Technical Business Rule Format:
            (^RS18 <> BLANK) AND (NotCharacterInSet(^RS18, 'a-z,A-Z,0-9,"!","@","$","%","&","*","(",")","-","=","[","]",";",":","'",""",",",".","?","/"," "'))
    
            Data Elements:
    
            RP:^RS18 = tns:AddressDetails.Line2.Text
            */
            assertion = (string.IsNullOrWhiteSpace(report.RS18) != true && !(IsMatch(report.RS18, @"^[a-z,A-Z,0-9,""!@\$%&\*\(\)\-=\[\];:'"",\.\?/ ""]*$",RegexOptions.IgnoreCase)));
            if (assertion)
            {
                processMessage = new ProcessMessageDocument()
                {
                    Code = "CMN.ATO.GEN.500027", Severity = ProcessMessageSeverity.Error,
                    Description = @"Address Line 2 contains invalid text",
                    LongDescription = @"A text character must be one of the following: A to Z a to z 0 to 9 ! @ $ % & * ( ) - = [ ] ; : ' "" , . ? / or a space character",
                    Location = "/xbrli:xbrl/tns:AddressDetails.Line2.Text",
                    Parameters = new ProcessMessageParameters() { new ProcessMessageParameter() {Name = "RuleIdentifier", Value = "VR.ATO.GEN.500027"} },
                };
                processMessage.Parameters.Add(new ProcessMessageParameter
                    { Name = "RS18", Value = report.RS18 });
    
                response.Add(processMessage);
            }
            #endregion // VR.ATO.GEN.500027
    
            #region VR.ATO.GEN.500028
    
            /*  VR.ATO.GEN.500028
            A text character must be one of the following: A to Z a to z 0 to 9 ! @ $ % & * ( ) - = [ ] ; : ' " , . ? / or a space character.
    
            Legacy Rule Format:
            IF (pyde.xx.xx:AddressDetails.LocalityName.Text <> NULLORBLANK) AND (ANY CHARACTER OF pyde.xx.xx:AddressDetails.LocalityName.Text <> SET(a-z,A-Z,0-9,"!","@","$","%","&","*","(",")","-","=","[","]",";",":","'",""",",",".","?","/"," "))
               RETURN VALIDATION MESSAGE
            ENDIF

            Technical Business Rule Format:
            (^RS19 <> BLANK) AND (NotCharacterInSet(^RS19, 'a-z,A-Z,0-9,"!","@","$","%","&","*","(",")","-","=","[","]",";",":","'",""",",",".","?","/"," "'))
    
            Data Elements:
    
            RP:^RS19 = tns:AddressDetails.LocalityName.Text
            */
            assertion = (string.IsNullOrWhiteSpace(report.RS19) != true && !(IsMatch(report.RS19, @"^[a-z,A-Z,0-9,""!@\$%&\*\(\)\-=\[\];:'"",\.\?/ ""]*$",RegexOptions.IgnoreCase)));
            if (assertion)
            {
                processMessage = new ProcessMessageDocument()
                {
                    Code = "CMN.ATO.GEN.500028", Severity = ProcessMessageSeverity.Error,
                    Description = @"Suburb/Town/City contains invalid text",
                    LongDescription = @"A text character must be one of the following: A to Z a to z 0 to 9 ! @ $ % & * ( ) - = [ ] ; : ' "" , . ? / or a space character",
                    Location = "/xbrli:xbrl/tns:AddressDetails.LocalityName.Text",
                    Parameters = new ProcessMessageParameters() { new ProcessMessageParameter() {Name = "RuleIdentifier", Value = "VR.ATO.GEN.500028"} },
                };
                processMessage.Parameters.Add(new ProcessMessageParameter
                    { Name = "RS19", Value = report.RS19 });
    
                response.Add(processMessage);
            }
            #endregion // VR.ATO.GEN.500028
    
            #region VR.ATO.GEN.500075
    
            /*  VR.ATO.GEN.500075
            Entity identifier scheme for ReportingParty must be"http://www.ato.gov.au/tfn"
    
            Legacy Rule Format:
            IF (RP:entity.identifier.scheme <> "http://www.ato.gov.au/tfn")
                RETURN VALIDATION MESSAGE
            ENDIF

            Technical Business Rule Format:
            ^IdentifierScheme <> 'http://www.ato.gov.au/tfn'
    
            Data Elements:
    
            ^IdentifierScheme = RP
            */
            assertion = ((report.RPExists == true) && (report.RPIdentifierScheme != @"http://www.ato.gov.au/tfn"));
            if (assertion)
            {
                processMessage = new ProcessMessageDocument()
                {
                    Code = "CMN.ATO.GEN.438029", Severity = ProcessMessageSeverity.Error,
                    Description = @"Entity identifier scheme for ReportingParty must be ""http://www.ato.gov.au/tfn""",
                    Location = "/xbrli:xbrl/xbrli:context" + OccurrenceIndex(report.RPOccurrenceIndex) + "/xbrli:entity/xbrli:identifier/@scheme",
                    Parameters = new ProcessMessageParameters() { new ProcessMessageParameter() {Name = "RuleIdentifier", Value = "VR.ATO.GEN.500075"} },
                };
                response.Add(processMessage);
            }
            #endregion // VR.ATO.GEN.500075
    
            #region VR.ATO.GEN.500129
    
            /*  VR.ATO.GEN.500129
            Value entered is not a valid code/value for that field.
    
            Legacy Rule Format:
            IF (pyde.xx.xx:AddressDetails.Postcode.Text <> NULL) AND (pyde.xx.xx:AddressDetails.Postcode.Text < "0200")
               RETURN VALIDATION MESSAGE
            ENDIF

            Technical Business Rule Format:
            (^RS20 <> NULL) AND (^RS20 < 0200)
    
            Data Elements:
    
            RP:^RS20 = tns:AddressDetails.Postcode.Text
            */
            assertion = (report.RS20 != null && AsNumeric(report.RS20) < 200);
            if (assertion)
            {
                processMessage = new ProcessMessageDocument()
                {
                    Code = "CMN.ATO.GEN.428041", Severity = ProcessMessageSeverity.Error,
                    Description = @"For an Australian address, postcode is invalid. Valid range is 0200 - 9999",
                    Location = "/xbrli:xbrl/tns:AddressDetails.Postcode.Text",
                    Parameters = new ProcessMessageParameters() { new ProcessMessageParameter() {Name = "RuleIdentifier", Value = "VR.ATO.GEN.500129"} },
                };
                processMessage.Parameters.Add(new ProcessMessageParameter
                    { Name = "RS20", Value = report.RS20 });
    
                response.Add(processMessage);
            }
            #endregion // VR.ATO.GEN.500129
    
            #region VR.ATO.RS.000003
    
            /*  VR.ATO.RS.000003
            Value entered is not a valid code/value for that field.
    
            Legacy Rule Format:
            IF [RS12] <> SET("117","161","212")
               RETURN VALIDATION MESSAGE
            ENDIF

            Technical Business Rule Format:
            NotInSet(^RS12, '"117","161","212"')
    
            Data Elements:
    
            RP:^RS12 = tns:Party.Type.Code
            */
            assertion = !(IsMatch(report.RS12, @"^(117|161|212)$",RegexOptions.IgnoreCase));
            if (assertion)
            {
                processMessage = new ProcessMessageDocument()
                {
                    Code = "CMN.ATO.RS.000151", Severity = ProcessMessageSeverity.Error,
                    Description = @"Entity Type is invalid. The only valid code for this submission is 117, 161 or 212",
                    Location = "/xbrli:xbrl/tns:Party.Type.Code",
                    Parameters = new ProcessMessageParameters() { new ProcessMessageParameter() {Name = "RuleIdentifier", Value = "VR.ATO.RS.000003"} },
                };
                processMessage.Parameters.Add(new ProcessMessageParameter
                    { Name = "RS12", Value = report.RS12 });
    
                response.Add(processMessage);
            }
            #endregion // VR.ATO.RS.000003
    
            #region VR.ATO.RS.000004
    
            /*  VR.ATO.RS.000004
            Entity Type is mandatory
    
            Legacy Rule Format:
            IF ([RS12] = NULL)
               RETURN VALIDATION MESSAGE
            ENDIF

            Technical Business Rule Format:
            ^RS12 = NULL
    
            Data Elements:
    
            RP:^RS12 = tns:Party.Type.Code
            */
            assertion = (report.RS12 == null);
            if (assertion)
            {
                processMessage = new ProcessMessageDocument()
                {
                    Code = "CMN.ATO.RS.000004", Severity = ProcessMessageSeverity.Error,
                    Description = @"Entity Type must be provided",
                    Location = "/xbrli:xbrl/tns:Party.Type.Code",
                    Parameters = new ProcessMessageParameters() { new ProcessMessageParameter() {Name = "RuleIdentifier", Value = "VR.ATO.RS.000004"} },
                };
                processMessage.Parameters.Add(new ProcessMessageParameter
                    { Name = "RS12", Value = report.RS12 });
    
                response.Add(processMessage);
            }
            #endregion // VR.ATO.RS.000004
    
            #region VR.ATO.RS.000009
    
            /*  VR.ATO.RS.000009
            The date entered is a future date. Date property first earned rental income cannot be any day in the future.
    
            Legacy Rule Format:
            IF ([RS24] > RP:period.endDate)
               RETURN VALIDATION MESSAGE
            ENDIF

            Technical Business Rule Format:
            ^RS24 > ^EndDate
    
            Data Elements:
    
            RP:^RS24 = tns:RealEstateProperty.RentalIncomeFirstEarned.Date
    
            RP:^EndDate = RP
            */
            assertion = (report.RS24.GetValueOrDefault() > report.RPEndDate);
            if (assertion)
            {
                processMessage = new ProcessMessageDocument()
                {
                    Code = "CMN.ATO.RS.000009", Severity = ProcessMessageSeverity.Error,
                    Description = @"Date property first earned rental income must be prior to form submission date",
                    LongDescription = @"The date entered is a future date. Date property first earned rental income cannot be any day in the future.",
                    Location = "/xbrli:xbrl/tns:RealEstateProperty.RentalIncomeFirstEarned.Date",
                    Parameters = new ProcessMessageParameters() { new ProcessMessageParameter() {Name = "RuleIdentifier", Value = "VR.ATO.RS.000009"} },
                };
                processMessage.Parameters.Add(new ProcessMessageParameter
                    { Name = "RS24", Value = GetValueOrEmpty(report.RS24) });
    
                response.Add(processMessage);
            }
            #endregion // VR.ATO.RS.000009
    
            #region VR.ATO.RS.000011
    
            /*  VR.ATO.RS.000011
            When Entity Type code is equal to 117 (for individual), then all fields in the Non Individuals only section - Trusts and Partnerships must not be populated
    
            Legacy Rule Format:
            IF ([RS12] = "117" AND ([RS27] <> NULL OR [RS28] <> NULL OR [RS29] <> NULL OR [RS30] <> NULL OR [RS31] <> NULL OR [RS32] <> NULL OR [RS33] <> NULL OR [RS34] <> NULL OR [RS35] <> NULL OR [RS36] <> NULL OR [RS14] <> NULLORBLANK))
               RETURN VALIDATION MESSAGE
            ENDIF

            Technical Business Rule Format:
            (^RS12 = '117' AND (^RS27 <> NULL OR ^RS28 <> NULL OR ^RS29 <> NULL OR ^RS30 <> NULL OR ^RS31 <> NULL OR ^RS32 <> NULL OR ^RS33 <> NULL OR ^RS34 <> NULL OR ^RS35 <> NULL OR ^RS36 <> NULL OR ^RS14 <> BLANK))
    
            Data Elements:
    
            RP:^RS27 = tns:RealEstateProperty.RentalWeeksAvailable.Count
    
            RP:^RS12 = tns:Party.Type.Code
    
            RP:^RS28 = tns:RealEstateProperty.Ownership.Percent
    
            RP:^RS29 = tns:RealEstateProperty.Acquisition.Date
    
            RP:^RS30 = tns:Assets.Investment.RealEstatePropertyPurchase.Amount
    
            RP:^RS31 = tns:RealEstateProperty.Disposal.Date
    
            RP:^RS32 = tns:Assets.Investment.RealEstatePropertySale.Amount
    
            RP:^RS33 = tns:Income.RealEstateProperty.CapitalGainsNet.Amount
    
            RP:^RS34 = tns:Expense.RealEstateProperty.PlantRecoupedDepreciationOnSale.Amount
    
            RP:^RS35 = tns:Expense.RealEstateProperty.CapitalWorksDeductionRecouped.Amount
    
            RP:^RS36 = tns:RealEstateProperty.LoanRenegotiated.Indicator
    
            RP:^RS14 = tns:OrganisationNameDetails.OrganisationalName.Text
            */
            assertion = (report.RS12 == @"117" && (report.RS27 != null || report.RS28 != null || report.RS29 != null || report.RS30 != null || report.RS31 != null || report.RS32 != null || report.RS33 != null || report.RS34 != null || report.RS35 != null || report.RS36 != null || string.IsNullOrWhiteSpace(report.RS14) != true));
            if (assertion)
            {
                processMessage = new ProcessMessageDocument()
                {
                    Code = "CMN.ATO.RS.000011", Severity = ProcessMessageSeverity.Error,
                    Description = @"The Non Individuals only section - Trusts and Partnerships cannot be populated",
                    LongDescription = @"When Entity Type code is equal to 117 (for individual), then all fields in the Non Individuals only section - Trusts and Partnerships must not be populated",
                    Location = "/xbrli:xbrl/tns:RealEstateProperty.RentalWeeksAvailable.Count",
                    Parameters = new ProcessMessageParameters() { new ProcessMessageParameter() {Name = "RuleIdentifier", Value = "VR.ATO.RS.000011"} },
                };
                processMessage.Parameters.Add(new ProcessMessageParameter
                    { Name = "RS12", Value = report.RS12 });
    
                processMessage.Parameters.Add(new ProcessMessageParameter
                    { Name = "RS27", Value = report.RS27.GetValueOrDefault().ToString() });
    
                processMessage.Parameters.Add(new ProcessMessageParameter
                    { Name = "RS28", Value = report.RS28.GetValueOrDefault().ToString() });
    
                processMessage.Parameters.Add(new ProcessMessageParameter
                    { Name = "RS29", Value = GetValueOrEmpty(report.RS29) });
    
                processMessage.Parameters.Add(new ProcessMessageParameter
                    { Name = "RS30", Value = report.RS30.GetValueOrDefault().ToString() });
    
                processMessage.Parameters.Add(new ProcessMessageParameter
                    { Name = "RS31", Value = GetValueOrEmpty(report.RS31) });
    
                processMessage.Parameters.Add(new ProcessMessageParameter
                    { Name = "RS32", Value = report.RS32.GetValueOrDefault().ToString() });
    
                processMessage.Parameters.Add(new ProcessMessageParameter
                    { Name = "RS33", Value = report.RS33.GetValueOrDefault().ToString() });
    
                processMessage.Parameters.Add(new ProcessMessageParameter
                    { Name = "RS34", Value = report.RS34.GetValueOrDefault().ToString() });
    
                processMessage.Parameters.Add(new ProcessMessageParameter
                    { Name = "RS35", Value = report.RS35.GetValueOrDefault().ToString() });
    
                processMessage.Parameters.Add(new ProcessMessageParameter
                    { Name = "RS36", Value = GetValueOrEmpty(report.RS36) });
    
                processMessage.Parameters.Add(new ProcessMessageParameter
                    { Name = "RS14", Value = report.RS14 });
    
                response.Add(processMessage);
            }
            #endregion // VR.ATO.RS.000011
    
            #region VR.ATO.RS.000012
    
            /*  VR.ATO.RS.000012
            The net rental income figure is not equal to the sum of rental income less the sum of rental expenses.
    
            Legacy Rule Format:
            IF ([RS59] <> NULL AND OutsideRange([RS59], ([RS38] + [RS39]) - ([RS40] + [RS41] + [RS42] + [RS43] + [RS44] + [RS45] + [RS46] + [RS47] + [RS48] + [RS49] + [RS50] + [RS51] + [RS52] + [RS53] + [RS54]+ [RS55] + [RS56] + [RS57] + [RS58]), 1))
               RETURN VALIDATION MESSAGE
            ENDIF

            Technical Business Rule Format:
            (^RS59 <> NULL AND OutsideRange(^RS59, (^RS38 + ^RS39) - (^RS40 + ^RS41 + ^RS42 + ^RS43 + ^RS44 + ^RS45 + ^RS46 + ^RS47 + ^RS48 + ^RS49 + ^RS50 + ^RS51 + ^RS52 + ^RS53 + ^RS54+ ^RS55 + ^RS56 + ^RS57 + ^RS58), 1))
    
            Data Elements:
    
            RP:^RS59 = tns:Income.RealEstateProperty.RentalNet.Amount
    
            RP:^RS38 = tns:Income.RealEstateProperty.Rental.Amount
    
            RP:^RS39 = tns:Income.RealEstateProperty.RentalRelatedOther.Amount
    
            RP:^RS40 = tns:Expense.RealEstateProperty.Marketing.Amount
    
            RP:^RS41 = tns:Expense.RealEstateProperty.BodyCorporate.Amount
    
            RP:^RS42 = tns:Expense.RealEstateProperty.Borrowing.Amount
    
            RP:^RS43 = tns:Expense.RealEstateProperty.Cleaning.Amount
    
            RP:^RS44 = tns:Expense.RealEstateProperty.CouncilRates.Amount
    
            RP:^RS45 = tns:Expense.DepreciationandAmortisation.Amount
    
            RP:^RS46 = tns:Expense.RealEstateProperty.Gardening.Amount
    
            RP:^RS47 = tns:Expense.RealEstateProperty.Insurance.Amount
    
            RP:^RS48 = tns:Expense.RealEstateProperty.LoanInterest.Amount
    
            RP:^RS49 = tns:Expense.LandTax.Amount
    
            RP:^RS50 = tns:Expense.RealEstateProperty.LegalFees.Amount
    
            RP:^RS51 = tns:Expense.RealEstateProperty.PestControl.Amount
    
            RP:^RS52 = tns:Expense.RealEstateProperty.AgentFeesCommission.Amount
    
            RP:^RS53 = tns:Expense.RealEstateProperty.RepairsAndMaintenance.Amount
    
            RP:^RS54 = tns:Expense.RealEstateProperty.CapitalWorksDeduction.Amount
    
            RP:^RS55 = tns:Expense.RealEstateProperty.OfficeSupplies.Amount
    
            RP:^RS56 = tns:Expense.Travel.Amount
    
            RP:^RS57 = tns:Expense.RealEstateProperty.Water.Amount
    
            RP:^RS58 = tns:Expense.RealEstateProperty.Sundry.Amount
            */
            assertion = (report.RS59 != null && OutsideRange(report.RS59.GetValueOrDefault(), report.RS38.GetValueOrDefault() + report.RS39.GetValueOrDefault() - (report.RS40.GetValueOrDefault() + report.RS41.GetValueOrDefault() + report.RS42.GetValueOrDefault() + report.RS43.GetValueOrDefault() + report.RS44.GetValueOrDefault() + report.RS45.GetValueOrDefault() + report.RS46.GetValueOrDefault() + report.RS47.GetValueOrDefault() + report.RS48.GetValueOrDefault() + report.RS49.GetValueOrDefault() + report.RS50.GetValueOrDefault() + report.RS51.GetValueOrDefault() + report.RS52.GetValueOrDefault() + report.RS53.GetValueOrDefault() + report.RS54.GetValueOrDefault() + report.RS55.GetValueOrDefault() + report.RS56.GetValueOrDefault() + report.RS57.GetValueOrDefault() + report.RS58.GetValueOrDefault()), 1));
            if (assertion)
            {
                processMessage = new ProcessMessageDocument()
                {
                    Code = "CMN.ATO.RS.000012", Severity = ProcessMessageSeverity.Error,
                    Description = @"Net rent is incorrect",
                    LongDescription = @"The net rental income figure is not equal to the sum of rental income less the sum of rental expenses",
                    Location = "/xbrli:xbrl/tns:Income.RealEstateProperty.RentalNet.Amount",
                    Parameters = new ProcessMessageParameters() { new ProcessMessageParameter() {Name = "RuleIdentifier", Value = "VR.ATO.RS.000012"} },
                };
                processMessage.Parameters.Add(new ProcessMessageParameter
                    { Name = "RS59", Value = report.RS59.GetValueOrDefault().ToString() });
    
                processMessage.Parameters.Add(new ProcessMessageParameter
                    { Name = "RS38", Value = report.RS38.GetValueOrDefault().ToString() });
    
                processMessage.Parameters.Add(new ProcessMessageParameter
                    { Name = "RS39", Value = report.RS39.GetValueOrDefault().ToString() });
    
                processMessage.Parameters.Add(new ProcessMessageParameter
                    { Name = "RS40", Value = report.RS40.GetValueOrDefault().ToString() });
    
                processMessage.Parameters.Add(new ProcessMessageParameter
                    { Name = "RS41", Value = report.RS41.GetValueOrDefault().ToString() });
    
                processMessage.Parameters.Add(new ProcessMessageParameter
                    { Name = "RS42", Value = report.RS42.GetValueOrDefault().ToString() });
    
                processMessage.Parameters.Add(new ProcessMessageParameter
                    { Name = "RS43", Value = report.RS43.GetValueOrDefault().ToString() });
    
                processMessage.Parameters.Add(new ProcessMessageParameter
                    { Name = "RS44", Value = report.RS44.GetValueOrDefault().ToString() });
    
                processMessage.Parameters.Add(new ProcessMessageParameter
                    { Name = "RS45", Value = report.RS45.GetValueOrDefault().ToString() });
    
                processMessage.Parameters.Add(new ProcessMessageParameter
                    { Name = "RS46", Value = report.RS46.GetValueOrDefault().ToString() });
    
                processMessage.Parameters.Add(new ProcessMessageParameter
                    { Name = "RS47", Value = report.RS47.GetValueOrDefault().ToString() });
    
                processMessage.Parameters.Add(new ProcessMessageParameter
                    { Name = "RS48", Value = report.RS48.GetValueOrDefault().ToString() });
    
                processMessage.Parameters.Add(new ProcessMessageParameter
                    { Name = "RS49", Value = report.RS49.GetValueOrDefault().ToString() });
    
                processMessage.Parameters.Add(new ProcessMessageParameter
                    { Name = "RS50", Value = report.RS50.GetValueOrDefault().ToString() });
    
                processMessage.Parameters.Add(new ProcessMessageParameter
                    { Name = "RS51", Value = report.RS51.GetValueOrDefault().ToString() });
    
                processMessage.Parameters.Add(new ProcessMessageParameter
                    { Name = "RS52", Value = report.RS52.GetValueOrDefault().ToString() });
    
                processMessage.Parameters.Add(new ProcessMessageParameter
                    { Name = "RS53", Value = report.RS53.GetValueOrDefault().ToString() });
    
                processMessage.Parameters.Add(new ProcessMessageParameter
                    { Name = "RS54", Value = report.RS54.GetValueOrDefault().ToString() });
    
                processMessage.Parameters.Add(new ProcessMessageParameter
                    { Name = "RS55", Value = report.RS55.GetValueOrDefault().ToString() });
    
                processMessage.Parameters.Add(new ProcessMessageParameter
                    { Name = "RS56", Value = report.RS56.GetValueOrDefault().ToString() });
    
                processMessage.Parameters.Add(new ProcessMessageParameter
                    { Name = "RS57", Value = report.RS57.GetValueOrDefault().ToString() });
    
                processMessage.Parameters.Add(new ProcessMessageParameter
                    { Name = "RS58", Value = report.RS58.GetValueOrDefault().ToString() });
    
                response.Add(processMessage);
            }
            #endregion // VR.ATO.RS.000012
    
            #region VR.ATO.RS.000013
    
            /*  VR.ATO.RS.000013
            Rental income is mandatory
    
            Legacy Rule Format:
            IF ([RS38] = NULL)
               RETURN VALIDATION MESSAGE
            ENDIF

            Technical Business Rule Format:
            ^RS38 = NULL
    
            Data Elements:
    
            RP:^RS38 = tns:Income.RealEstateProperty.Rental.Amount
            */
            assertion = (report.RS38 == null);
            if (assertion)
            {
                processMessage = new ProcessMessageDocument()
                {
                    Code = "CMN.ATO.RS.000013", Severity = ProcessMessageSeverity.Error,
                    Description = @"Rental income must be provided",
                    Location = "/xbrli:xbrl/tns:Income.RealEstateProperty.Rental.Amount",
                    Parameters = new ProcessMessageParameters() { new ProcessMessageParameter() {Name = "RuleIdentifier", Value = "VR.ATO.RS.000013"} },
                };
                processMessage.Parameters.Add(new ProcessMessageParameter
                    { Name = "RS38", Value = report.RS38.GetValueOrDefault().ToString() });
    
                response.Add(processMessage);
            }
            #endregion // VR.ATO.RS.000013
    
            #region VR.ATO.RS.000014
    
            /*  VR.ATO.RS.000014
            Net rent is mandatory
    
            Legacy Rule Format:
            IF ([RS59] = NULL)
               RETURN VALIDATION MESSAGE
            ENDIF

            Technical Business Rule Format:
            ^RS59 = NULL
    
            Data Elements:
    
            RP:^RS59 = tns:Income.RealEstateProperty.RentalNet.Amount
            */
            assertion = (report.RS59 == null);
            if (assertion)
            {
                processMessage = new ProcessMessageDocument()
                {
                    Code = "CMN.ATO.RS.000014", Severity = ProcessMessageSeverity.Error,
                    Description = @"Net rent must be provided",
                    Location = "/xbrli:xbrl/tns:Income.RealEstateProperty.RentalNet.Amount",
                    Parameters = new ProcessMessageParameters() { new ProcessMessageParameter() {Name = "RuleIdentifier", Value = "VR.ATO.RS.000014"} },
                };
                processMessage.Parameters.Add(new ProcessMessageParameter
                    { Name = "RS59", Value = report.RS59.GetValueOrDefault().ToString() });
    
                response.Add(processMessage);
            }
            #endregion // VR.ATO.RS.000014
    
            #region VR.ATO.RS.000015
    
            /*  VR.ATO.RS.000015
            Rental Property - Address line 1 is mandatory
    
            Legacy Rule Format:
            IF ([RS17] = NULLORBLANK)
               RETURN VALIDATION MESSAGE
            ENDIF

            Technical Business Rule Format:
            ^RS17 = BLANK
    
            Data Elements:
    
            RP:^RS17 = tns:AddressDetails.Line1.Text
            */
            assertion = (string.IsNullOrWhiteSpace(report.RS17) == true);
            if (assertion)
            {
                processMessage = new ProcessMessageDocument()
                {
                    Code = "CMN.ATO.RS.000015", Severity = ProcessMessageSeverity.Error,
                    Description = @"Rental Property - Address line 1 must be provided",
                    Location = "/xbrli:xbrl/tns:AddressDetails.Line1.Text",
                    Parameters = new ProcessMessageParameters() { new ProcessMessageParameter() {Name = "RuleIdentifier", Value = "VR.ATO.RS.000015"} },
                };
                processMessage.Parameters.Add(new ProcessMessageParameter
                    { Name = "RS17", Value = report.RS17 });
    
                response.Add(processMessage);
            }
            #endregion // VR.ATO.RS.000015
    
            #region VR.ATO.RS.000016
    
            /*  VR.ATO.RS.000016
            Rental Property - Suburb/Town is mandatory
    
            Legacy Rule Format:
            IF ([RS19] = NULLORBLANK)
               RETURN VALIDATION MESSAGE
            ENDIF

            Technical Business Rule Format:
            ^RS19 = BLANK
    
            Data Elements:
    
            RP:^RS19 = tns:AddressDetails.LocalityName.Text
            */
            assertion = (string.IsNullOrWhiteSpace(report.RS19) == true);
            if (assertion)
            {
                processMessage = new ProcessMessageDocument()
                {
                    Code = "CMN.ATO.RS.000016", Severity = ProcessMessageSeverity.Error,
                    Description = @"Rental Property - Suburb/Town must be provided",
                    Location = "/xbrli:xbrl/tns:AddressDetails.LocalityName.Text",
                    Parameters = new ProcessMessageParameters() { new ProcessMessageParameter() {Name = "RuleIdentifier", Value = "VR.ATO.RS.000016"} },
                };
                processMessage.Parameters.Add(new ProcessMessageParameter
                    { Name = "RS19", Value = report.RS19 });
    
                response.Add(processMessage);
            }
            #endregion // VR.ATO.RS.000016
    
            #region VR.ATO.RS.000017
    
            /*  VR.ATO.RS.000017
            Rental Property - Postcode is mandatory
    
            Legacy Rule Format:
            IF ([RS20] = NULL)
               RETURN VALIDATION MESSAGE
            ENDIF

            Technical Business Rule Format:
            ^RS20 = NULL
    
            Data Elements:
    
            RP:^RS20 = tns:AddressDetails.Postcode.Text
            */
            assertion = (report.RS20 == null);
            if (assertion)
            {
                processMessage = new ProcessMessageDocument()
                {
                    Code = "CMN.ATO.RS.000017", Severity = ProcessMessageSeverity.Error,
                    Description = @"Rental Property - Postcode must be provided",
                    Location = "/xbrli:xbrl/tns:AddressDetails.Postcode.Text",
                    Parameters = new ProcessMessageParameters() { new ProcessMessageParameter() {Name = "RuleIdentifier", Value = "VR.ATO.RS.000017"} },
                };
                processMessage.Parameters.Add(new ProcessMessageParameter
                    { Name = "RS20", Value = report.RS20 });
    
                response.Add(processMessage);
            }
            #endregion // VR.ATO.RS.000017
    
            #region VR.ATO.RS.000018
    
            /*  VR.ATO.RS.000018
            Rental Property - State is mandatory
    
            Legacy Rule Format:
            IF ([RS21] = NULL)
               RETURN VALIDATION MESSAGE
            ENDIF

            Technical Business Rule Format:
            ^RS21 = NULL
    
            Data Elements:
    
            RP:^RS21 = tns:AddressDetails.StateOrTerritory.Code
            */
            assertion = (report.RS21 == null);
            if (assertion)
            {
                processMessage = new ProcessMessageDocument()
                {
                    Code = "CMN.ATO.RS.000018", Severity = ProcessMessageSeverity.Error,
                    Description = @"Rental Property - State must be provided",
                    Location = "/xbrli:xbrl/tns:AddressDetails.StateOrTerritory.Code",
                    Parameters = new ProcessMessageParameters() { new ProcessMessageParameter() {Name = "RuleIdentifier", Value = "VR.ATO.RS.000018"} },
                };
                processMessage.Parameters.Add(new ProcessMessageParameter
                    { Name = "RS21", Value = report.RS21 });
    
                response.Add(processMessage);
            }
            #endregion // VR.ATO.RS.000018
    
            #region VR.ATO.RS.000019
    
            /*  VR.ATO.RS.000019
            Date property first earned rental income is mandatory
    
            Legacy Rule Format:
            IF ([RS24] = NULL)
               RETURN VALIDATION MESSAGE
            ENDIF

            Technical Business Rule Format:
            ^RS24 = NULL
    
            Data Elements:
    
            RP:^RS24 = tns:RealEstateProperty.RentalIncomeFirstEarned.Date
            */
            assertion = (report.RS24 == null);
            if (assertion)
            {
                processMessage = new ProcessMessageDocument()
                {
                    Code = "CMN.ATO.RS.000019", Severity = ProcessMessageSeverity.Error,
                    Description = @"Date property first earned rental income must be provided",
                    Location = "/xbrli:xbrl/tns:RealEstateProperty.RentalIncomeFirstEarned.Date",
                    Parameters = new ProcessMessageParameters() { new ProcessMessageParameter() {Name = "RuleIdentifier", Value = "VR.ATO.RS.000019"} },
                };
                processMessage.Parameters.Add(new ProcessMessageParameter
                    { Name = "RS24", Value = GetValueOrEmpty(report.RS24) });
    
                response.Add(processMessage);
            }
            #endregion // VR.ATO.RS.000019
    
            #region VR.ATO.RS.000020
    
            /*  VR.ATO.RS.000020
            Rental income has a maximum field length of 11
    
            Legacy Rule Format:
            IF [RS38] <> MONETARY(U,11,0)
                 RETURN VALIDATION MESSAGE
            ENDIF

            Technical Business Rule Format:
            NotMonetary(^RS38, 'U', 11, 0)
    
            Data Elements:
    
            RP:^RS38 = tns:Income.RealEstateProperty.Rental.Amount
            */
            assertion = NotMonetary(report.RS38, @"U", 11, 0);
            if (assertion)
            {
                processMessage = new ProcessMessageDocument()
                {
                    Code = "CMN.ATO.RS.000020", Severity = ProcessMessageSeverity.Error,
                    Description = @"Rental income is not in a valid monetary format",
                    LongDescription = @"Rental income must be unsigned, not exceed 11 digits; no other characters are allowed except for the preceding sign",
                    Location = "/xbrli:xbrl/tns:Income.RealEstateProperty.Rental.Amount",
                    Parameters = new ProcessMessageParameters() { new ProcessMessageParameter() {Name = "RuleIdentifier", Value = "VR.ATO.RS.000020"} },
                };
                processMessage.Parameters.Add(new ProcessMessageParameter
                    { Name = "RS38", Value = report.RS38.GetValueOrDefault().ToString() });
    
                response.Add(processMessage);
            }
            #endregion // VR.ATO.RS.000020
    
            #region VR.ATO.RS.000021
    
            /*  VR.ATO.RS.000021
            Other rental related income has a maximum field length of 11
    
            Legacy Rule Format:
            IF [RS39] <> MONETARY(U,11,0)
                 RETURN VALIDATION MESSAGE
            ENDIF

            Technical Business Rule Format:
            NotMonetary(^RS39, 'U', 11, 0)
    
            Data Elements:
    
            RP:^RS39 = tns:Income.RealEstateProperty.RentalRelatedOther.Amount
            */
            assertion = NotMonetary(report.RS39, @"U", 11, 0);
            if (assertion)
            {
                processMessage = new ProcessMessageDocument()
                {
                    Code = "CMN.ATO.RS.000021", Severity = ProcessMessageSeverity.Error,
                    Description = @"Other rental related income is not in a valid monetary format",
                    LongDescription = @"Other rental related income must be unsigned, not exceed 11 digits; no other characters are allowed except for the preceding sign",
                    Location = "/xbrli:xbrl/tns:Income.RealEstateProperty.RentalRelatedOther.Amount",
                    Parameters = new ProcessMessageParameters() { new ProcessMessageParameter() {Name = "RuleIdentifier", Value = "VR.ATO.RS.000021"} },
                };
                processMessage.Parameters.Add(new ProcessMessageParameter
                    { Name = "RS39", Value = report.RS39.GetValueOrDefault().ToString() });
    
                response.Add(processMessage);
            }
            #endregion // VR.ATO.RS.000021
    
            #region VR.ATO.RS.000022
    
            /*  VR.ATO.RS.000022
            Advertising for tenants has a maximum field length of 11
    
            Legacy Rule Format:
            IF [RS40] <> MONETARY(U,11,0)
                 RETURN VALIDATION MESSAGE
            ENDIF

            Technical Business Rule Format:
            NotMonetary(^RS40, 'U', 11, 0)
    
            Data Elements:
    
            RP:^RS40 = tns:Expense.RealEstateProperty.Marketing.Amount
            */
            assertion = NotMonetary(report.RS40, @"U", 11, 0);
            if (assertion)
            {
                processMessage = new ProcessMessageDocument()
                {
                    Code = "CMN.ATO.RS.000022", Severity = ProcessMessageSeverity.Error,
                    Description = @"Advertising for tenants is not in a valid monetary format",
                    LongDescription = @"Advertising for tenants must be unsigned, not exceed 11 digits; no other characters are allowed except for the preceding sign",
                    Location = "/xbrli:xbrl/tns:Expense.RealEstateProperty.Marketing.Amount",
                    Parameters = new ProcessMessageParameters() { new ProcessMessageParameter() {Name = "RuleIdentifier", Value = "VR.ATO.RS.000022"} },
                };
                processMessage.Parameters.Add(new ProcessMessageParameter
                    { Name = "RS40", Value = report.RS40.GetValueOrDefault().ToString() });
    
                response.Add(processMessage);
            }
            #endregion // VR.ATO.RS.000022
    
            #region VR.ATO.RS.000023
    
            /*  VR.ATO.RS.000023
            Body corporate fees has a maximum field length of 11
    
            Legacy Rule Format:
            IF [RS41] <> MONETARY(U,11,0)
                 RETURN VALIDATION MESSAGE
            ENDIF

            Technical Business Rule Format:
            NotMonetary(^RS41, 'U', 11, 0)
    
            Data Elements:
    
            RP:^RS41 = tns:Expense.RealEstateProperty.BodyCorporate.Amount
            */
            assertion = NotMonetary(report.RS41, @"U", 11, 0);
            if (assertion)
            {
                processMessage = new ProcessMessageDocument()
                {
                    Code = "CMN.ATO.RS.000023", Severity = ProcessMessageSeverity.Error,
                    Description = @"Body corporate fees is not in a valid monetary format",
                    LongDescription = @"Body corporate fees must be unsigned, not exceed 11 digits; no other characters are allowed except for the preceding sign",
                    Location = "/xbrli:xbrl/tns:Expense.RealEstateProperty.BodyCorporate.Amount",
                    Parameters = new ProcessMessageParameters() { new ProcessMessageParameter() {Name = "RuleIdentifier", Value = "VR.ATO.RS.000023"} },
                };
                processMessage.Parameters.Add(new ProcessMessageParameter
                    { Name = "RS41", Value = report.RS41.GetValueOrDefault().ToString() });
    
                response.Add(processMessage);
            }
            #endregion // VR.ATO.RS.000023
    
            #region VR.ATO.RS.000024
    
            /*  VR.ATO.RS.000024
            Borrowing expenses has a maximum field length of 11
    
            Legacy Rule Format:
            IF [RS42] <> MONETARY(U,11,0)
                 RETURN VALIDATION MESSAGE
            ENDIF

            Technical Business Rule Format:
            NotMonetary(^RS42, 'U', 11, 0)
    
            Data Elements:
    
            RP:^RS42 = tns:Expense.RealEstateProperty.Borrowing.Amount
            */
            assertion = NotMonetary(report.RS42, @"U", 11, 0);
            if (assertion)
            {
                processMessage = new ProcessMessageDocument()
                {
                    Code = "CMN.ATO.RS.000024", Severity = ProcessMessageSeverity.Error,
                    Description = @"Borrowing expenses is not in a valid monetary format",
                    LongDescription = @"Borrowing expenses must be unsigned, not exceed 11 digits; no other characters are allowed except for the preceding sign",
                    Location = "/xbrli:xbrl/tns:Expense.RealEstateProperty.Borrowing.Amount",
                    Parameters = new ProcessMessageParameters() { new ProcessMessageParameter() {Name = "RuleIdentifier", Value = "VR.ATO.RS.000024"} },
                };
                processMessage.Parameters.Add(new ProcessMessageParameter
                    { Name = "RS42", Value = report.RS42.GetValueOrDefault().ToString() });
    
                response.Add(processMessage);
            }
            #endregion // VR.ATO.RS.000024
    
            #region VR.ATO.RS.000025
    
            /*  VR.ATO.RS.000025
            Cleaning has a maximum field length of 11
    
            Legacy Rule Format:
            IF [RS43] <> MONETARY(U,11,0)
                 RETURN VALIDATION MESSAGE
            ENDIF

            Technical Business Rule Format:
            NotMonetary(^RS43, 'U', 11, 0)
    
            Data Elements:
    
            RP:^RS43 = tns:Expense.RealEstateProperty.Cleaning.Amount
            */
            assertion = NotMonetary(report.RS43, @"U", 11, 0);
            if (assertion)
            {
                processMessage = new ProcessMessageDocument()
                {
                    Code = "CMN.ATO.RS.000025", Severity = ProcessMessageSeverity.Error,
                    Description = @"Cleaning is not in a valid monetary format",
                    LongDescription = @"Cleaning must be unsigned, not exceed 11 digits; no other characters are allowed except for the preceding sign",
                    Location = "/xbrli:xbrl/tns:Expense.RealEstateProperty.Cleaning.Amount",
                    Parameters = new ProcessMessageParameters() { new ProcessMessageParameter() {Name = "RuleIdentifier", Value = "VR.ATO.RS.000025"} },
                };
                processMessage.Parameters.Add(new ProcessMessageParameter
                    { Name = "RS43", Value = report.RS43.GetValueOrDefault().ToString() });
    
                response.Add(processMessage);
            }
            #endregion // VR.ATO.RS.000025
    
            #region VR.ATO.RS.000026
    
            /*  VR.ATO.RS.000026
            Council rates has a maximum field length of 11
    
            Legacy Rule Format:
            IF [RS44] <> MONETARY(U,11,0)
                 RETURN VALIDATION MESSAGE
            ENDIF

            Technical Business Rule Format:
            NotMonetary(^RS44, 'U', 11, 0)
    
            Data Elements:
    
            RP:^RS44 = tns:Expense.RealEstateProperty.CouncilRates.Amount
            */
            assertion = NotMonetary(report.RS44, @"U", 11, 0);
            if (assertion)
            {
                processMessage = new ProcessMessageDocument()
                {
                    Code = "CMN.ATO.RS.000026", Severity = ProcessMessageSeverity.Error,
                    Description = @"Council rates is not in a valid monetary format",
                    LongDescription = @"Council rates must be unsigned, not exceed 11 digits; no other characters are allowed except for the preceding sign",
                    Location = "/xbrli:xbrl/tns:Expense.RealEstateProperty.CouncilRates.Amount",
                    Parameters = new ProcessMessageParameters() { new ProcessMessageParameter() {Name = "RuleIdentifier", Value = "VR.ATO.RS.000026"} },
                };
                processMessage.Parameters.Add(new ProcessMessageParameter
                    { Name = "RS44", Value = report.RS44.GetValueOrDefault().ToString() });
    
                response.Add(processMessage);
            }
            #endregion // VR.ATO.RS.000026
    
            #region VR.ATO.RS.000027
    
            /*  VR.ATO.RS.000027
            Capital allowances (depreciation on plant) has a maximum field length of 11
    
            Legacy Rule Format:
            IF [RS45] <> MONETARY(U,11,0)
                 RETURN VALIDATION MESSAGE
            ENDIF

            Technical Business Rule Format:
            NotMonetary(^RS45, 'U', 11, 0)
    
            Data Elements:
    
            RP:^RS45 = tns:Expense.DepreciationandAmortisation.Amount
            */
            assertion = NotMonetary(report.RS45, @"U", 11, 0);
            if (assertion)
            {
                processMessage = new ProcessMessageDocument()
                {
                    Code = "CMN.ATO.RS.000027", Severity = ProcessMessageSeverity.Error,
                    Description = @"Capital allowances (depreciation on plant) is not in a valid monetary format",
                    LongDescription = @"Capital allowances (depreciation on plant) must be unsigned, not exceed 11 digits; no other characters are allowed except for the preceding sign",
                    Location = "/xbrli:xbrl/tns:Expense.DepreciationandAmortisation.Amount",
                    Parameters = new ProcessMessageParameters() { new ProcessMessageParameter() {Name = "RuleIdentifier", Value = "VR.ATO.RS.000027"} },
                };
                processMessage.Parameters.Add(new ProcessMessageParameter
                    { Name = "RS45", Value = report.RS45.GetValueOrDefault().ToString() });
    
                response.Add(processMessage);
            }
            #endregion // VR.ATO.RS.000027
    
            #region VR.ATO.RS.000028
    
            /*  VR.ATO.RS.000028
            Gardening/lawn mowing has a maximum field length of 11
    
            Legacy Rule Format:
            IF [RS46] <> MONETARY(U,11,0)
                 RETURN VALIDATION MESSAGE
            ENDIF

            Technical Business Rule Format:
            NotMonetary(^RS46, 'U', 11, 0)
    
            Data Elements:
    
            RP:^RS46 = tns:Expense.RealEstateProperty.Gardening.Amount
            */
            assertion = NotMonetary(report.RS46, @"U", 11, 0);
            if (assertion)
            {
                processMessage = new ProcessMessageDocument()
                {
                    Code = "CMN.ATO.RS.000028", Severity = ProcessMessageSeverity.Error,
                    Description = @"Gardening/lawn mowing is not in a valid monetary format",
                    LongDescription = @"Gardening/lawn mowing must be unsigned, not exceed 11 digits; no other characters are allowed except for the preceding sign",
                    Location = "/xbrli:xbrl/tns:Expense.RealEstateProperty.Gardening.Amount",
                    Parameters = new ProcessMessageParameters() { new ProcessMessageParameter() {Name = "RuleIdentifier", Value = "VR.ATO.RS.000028"} },
                };
                processMessage.Parameters.Add(new ProcessMessageParameter
                    { Name = "RS46", Value = report.RS46.GetValueOrDefault().ToString() });
    
                response.Add(processMessage);
            }
            #endregion // VR.ATO.RS.000028
    
            #region VR.ATO.RS.000029
    
            /*  VR.ATO.RS.000029
            Insurance has a maximum field length of 11
    
            Legacy Rule Format:
            IF [RS47] <> MONETARY(U,11,0)
                 RETURN VALIDATION MESSAGE
            ENDIF

            Technical Business Rule Format:
            NotMonetary(^RS47, 'U', 11, 0)
    
            Data Elements:
    
            RP:^RS47 = tns:Expense.RealEstateProperty.Insurance.Amount
            */
            assertion = NotMonetary(report.RS47, @"U", 11, 0);
            if (assertion)
            {
                processMessage = new ProcessMessageDocument()
                {
                    Code = "CMN.ATO.RS.000029", Severity = ProcessMessageSeverity.Error,
                    Description = @"Insurance is not in a valid monetary format",
                    LongDescription = @"Insurance must be unsigned, not exceed 11 digits; no other characters are allowed except for the preceding sign",
                    Location = "/xbrli:xbrl/tns:Expense.RealEstateProperty.Insurance.Amount",
                    Parameters = new ProcessMessageParameters() { new ProcessMessageParameter() {Name = "RuleIdentifier", Value = "VR.ATO.RS.000029"} },
                };
                processMessage.Parameters.Add(new ProcessMessageParameter
                    { Name = "RS47", Value = report.RS47.GetValueOrDefault().ToString() });
    
                response.Add(processMessage);
            }
            #endregion // VR.ATO.RS.000029
    
            #region VR.ATO.RS.000030
    
            /*  VR.ATO.RS.000030
            Interest on loans has a maximum field length of 11
    
            Legacy Rule Format:
            IF [RS48] <> MONETARY(U,11,0)
                 RETURN VALIDATION MESSAGE
            ENDIF

            Technical Business Rule Format:
            NotMonetary(^RS48, 'U', 11, 0)
    
            Data Elements:
    
            RP:^RS48 = tns:Expense.RealEstateProperty.LoanInterest.Amount
            */
            assertion = NotMonetary(report.RS48, @"U", 11, 0);
            if (assertion)
            {
                processMessage = new ProcessMessageDocument()
                {
                    Code = "CMN.ATO.RS.000030", Severity = ProcessMessageSeverity.Error,
                    Description = @"Interest on loans is not in a valid monetary format",
                    LongDescription = @"Interest on loans must be unsigned, not exceed 11 digits; no other characters are allowed except for the preceding sign",
                    Location = "/xbrli:xbrl/tns:Expense.RealEstateProperty.LoanInterest.Amount",
                    Parameters = new ProcessMessageParameters() { new ProcessMessageParameter() {Name = "RuleIdentifier", Value = "VR.ATO.RS.000030"} },
                };
                processMessage.Parameters.Add(new ProcessMessageParameter
                    { Name = "RS48", Value = report.RS48.GetValueOrDefault().ToString() });
    
                response.Add(processMessage);
            }
            #endregion // VR.ATO.RS.000030
    
            #region VR.ATO.RS.000031
    
            /*  VR.ATO.RS.000031
            Land tax has a maximum field length of 11
    
            Legacy Rule Format:
            IF [RS49] <> MONETARY(U,11,0)
                 RETURN VALIDATION MESSAGE
            ENDIF

            Technical Business Rule Format:
            NotMonetary(^RS49, 'U', 11, 0)
    
            Data Elements:
    
            RP:^RS49 = tns:Expense.LandTax.Amount
            */
            assertion = NotMonetary(report.RS49, @"U", 11, 0);
            if (assertion)
            {
                processMessage = new ProcessMessageDocument()
                {
                    Code = "CMN.ATO.RS.000031", Severity = ProcessMessageSeverity.Error,
                    Description = @"Land tax is not in a valid monetary format",
                    LongDescription = @"Land tax must be unsigned, not exceed 11 digits; no other characters are allowed except for the preceding sign",
                    Location = "/xbrli:xbrl/tns:Expense.LandTax.Amount",
                    Parameters = new ProcessMessageParameters() { new ProcessMessageParameter() {Name = "RuleIdentifier", Value = "VR.ATO.RS.000031"} },
                };
                processMessage.Parameters.Add(new ProcessMessageParameter
                    { Name = "RS49", Value = report.RS49.GetValueOrDefault().ToString() });
    
                response.Add(processMessage);
            }
            #endregion // VR.ATO.RS.000031
    
            #region VR.ATO.RS.000032
    
            /*  VR.ATO.RS.000032
            Legal fees has a maximum field length of 11
    
            Legacy Rule Format:
            IF [RS50] <> MONETARY(U,11,0)
                 RETURN VALIDATION MESSAGE
            ENDIF

            Technical Business Rule Format:
            NotMonetary(^RS50, 'U', 11, 0)
    
            Data Elements:
    
            RP:^RS50 = tns:Expense.RealEstateProperty.LegalFees.Amount
            */
            assertion = NotMonetary(report.RS50, @"U", 11, 0);
            if (assertion)
            {
                processMessage = new ProcessMessageDocument()
                {
                    Code = "CMN.ATO.RS.000032", Severity = ProcessMessageSeverity.Error,
                    Description = @"Legal fees is not in a valid monetary format",
                    LongDescription = @"Legal fees must be unsigned, not exceed 11 digits; no other characters are allowed except for the preceding sign",
                    Location = "/xbrli:xbrl/tns:Expense.RealEstateProperty.LegalFees.Amount",
                    Parameters = new ProcessMessageParameters() { new ProcessMessageParameter() {Name = "RuleIdentifier", Value = "VR.ATO.RS.000032"} },
                };
                processMessage.Parameters.Add(new ProcessMessageParameter
                    { Name = "RS50", Value = report.RS50.GetValueOrDefault().ToString() });
    
                response.Add(processMessage);
            }
            #endregion // VR.ATO.RS.000032
    
            #region VR.ATO.RS.000033
    
            /*  VR.ATO.RS.000033
            Pest control has a maximum field length of 11
    
            Legacy Rule Format:
            IF [RS51] <> MONETARY(U,11,0)
                 RETURN VALIDATION MESSAGE
            ENDIF

            Technical Business Rule Format:
            NotMonetary(^RS51, 'U', 11, 0)
    
            Data Elements:
    
            RP:^RS51 = tns:Expense.RealEstateProperty.PestControl.Amount
            */
            assertion = NotMonetary(report.RS51, @"U", 11, 0);
            if (assertion)
            {
                processMessage = new ProcessMessageDocument()
                {
                    Code = "CMN.ATO.RS.000033", Severity = ProcessMessageSeverity.Error,
                    Description = @"Pest control is not in a valid monetary format",
                    LongDescription = @"Pest control must be unsigned, not exceed 11 digits; no other characters are allowed except for the preceding sign",
                    Location = "/xbrli:xbrl/tns:Expense.RealEstateProperty.PestControl.Amount",
                    Parameters = new ProcessMessageParameters() { new ProcessMessageParameter() {Name = "RuleIdentifier", Value = "VR.ATO.RS.000033"} },
                };
                processMessage.Parameters.Add(new ProcessMessageParameter
                    { Name = "RS51", Value = report.RS51.GetValueOrDefault().ToString() });
    
                response.Add(processMessage);
            }
            #endregion // VR.ATO.RS.000033
    
            #region VR.ATO.RS.000034
    
            /*  VR.ATO.RS.000034
            Property agent fees/commission has a maximum field length of 11
    
            Legacy Rule Format:
            IF [RS52] <> MONETARY(U,11,0)
                 RETURN VALIDATION MESSAGE
            ENDIF

            Technical Business Rule Format:
            NotMonetary(^RS52, 'U', 11, 0)
    
            Data Elements:
    
            RP:^RS52 = tns:Expense.RealEstateProperty.AgentFeesCommission.Amount
            */
            assertion = NotMonetary(report.RS52, @"U", 11, 0);
            if (assertion)
            {
                processMessage = new ProcessMessageDocument()
                {
                    Code = "CMN.ATO.RS.000034", Severity = ProcessMessageSeverity.Error,
                    Description = @"Property agent fees/commission is not in a valid monetary format",
                    LongDescription = @"Property agent fees/commission must be unsigned, not exceed 11 digits; no other characters are allowed except for the preceding sign",
                    Location = "/xbrli:xbrl/tns:Expense.RealEstateProperty.AgentFeesCommission.Amount",
                    Parameters = new ProcessMessageParameters() { new ProcessMessageParameter() {Name = "RuleIdentifier", Value = "VR.ATO.RS.000034"} },
                };
                processMessage.Parameters.Add(new ProcessMessageParameter
                    { Name = "RS52", Value = report.RS52.GetValueOrDefault().ToString() });
    
                response.Add(processMessage);
            }
            #endregion // VR.ATO.RS.000034
    
            #region VR.ATO.RS.000035
    
            /*  VR.ATO.RS.000035
            Repairs and maintenance has a maximum field length of 11
    
            Legacy Rule Format:
            IF [RS53] <> MONETARY(U,11,0)
                 RETURN VALIDATION MESSAGE
            ENDIF

            Technical Business Rule Format:
            NotMonetary(^RS53, 'U', 11, 0)
    
            Data Elements:
    
            RP:^RS53 = tns:Expense.RealEstateProperty.RepairsAndMaintenance.Amount
            */
            assertion = NotMonetary(report.RS53, @"U", 11, 0);
            if (assertion)
            {
                processMessage = new ProcessMessageDocument()
                {
                    Code = "CMN.ATO.RS.000035", Severity = ProcessMessageSeverity.Error,
                    Description = @"Repairs and maintenance is not in a valid monetary format",
                    LongDescription = @"Repairs and maintenance must be unsigned, not exceed 11 digits; no other characters are allowed except for the preceding sign",
                    Location = "/xbrli:xbrl/tns:Expense.RealEstateProperty.RepairsAndMaintenance.Amount",
                    Parameters = new ProcessMessageParameters() { new ProcessMessageParameter() {Name = "RuleIdentifier", Value = "VR.ATO.RS.000035"} },
                };
                processMessage.Parameters.Add(new ProcessMessageParameter
                    { Name = "RS53", Value = report.RS53.GetValueOrDefault().ToString() });
    
                response.Add(processMessage);
            }
            #endregion // VR.ATO.RS.000035
    
            #region VR.ATO.RS.000036
    
            /*  VR.ATO.RS.000036
            Capital works deductions (special building write off) has a maximum field length of 11
    
            Legacy Rule Format:
            IF [RS54] <> MONETARY(U,11,0)
                 RETURN VALIDATION MESSAGE
            ENDIF

            Technical Business Rule Format:
            NotMonetary(^RS54, 'U', 11, 0)
    
            Data Elements:
    
            RP:^RS54 = tns:Expense.RealEstateProperty.CapitalWorksDeduction.Amount
            */
            assertion = NotMonetary(report.RS54, @"U", 11, 0);
            if (assertion)
            {
                processMessage = new ProcessMessageDocument()
                {
                    Code = "CMN.ATO.RS.000036", Severity = ProcessMessageSeverity.Error,
                    Description = @"Capital works deductions (special building write off) is not in a valid monetary format",
                    LongDescription = @"Capital works deductions (special building write off) must be unsigned, not exceed 11 digits; no other characters are allowed except for the preceding sign",
                    Location = "/xbrli:xbrl/tns:Expense.RealEstateProperty.CapitalWorksDeduction.Amount",
                    Parameters = new ProcessMessageParameters() { new ProcessMessageParameter() {Name = "RuleIdentifier", Value = "VR.ATO.RS.000036"} },
                };
                processMessage.Parameters.Add(new ProcessMessageParameter
                    { Name = "RS54", Value = report.RS54.GetValueOrDefault().ToString() });
    
                response.Add(processMessage);
            }
            #endregion // VR.ATO.RS.000036
    
            #region VR.ATO.RS.000037
    
            /*  VR.ATO.RS.000037
            Stationery, telephone, and postage has a maximum field length of 11
    
            Legacy Rule Format:
            IF [RS55] <> MONETARY(U,11,0)
                 RETURN VALIDATION MESSAGE
            ENDIF

            Technical Business Rule Format:
            NotMonetary(^RS55, 'U', 11, 0)
    
            Data Elements:
    
            RP:^RS55 = tns:Expense.RealEstateProperty.OfficeSupplies.Amount
            */
            assertion = NotMonetary(report.RS55, @"U", 11, 0);
            if (assertion)
            {
                processMessage = new ProcessMessageDocument()
                {
                    Code = "CMN.ATO.RS.000037", Severity = ProcessMessageSeverity.Error,
                    Description = @"Stationery, telephone, and postage is not in a valid monetary format",
                    LongDescription = @"Stationery, telephone, and postage must be unsigned, not exceed 11 digits; no other characters are allowed except for the preceding sign",
                    Location = "/xbrli:xbrl/tns:Expense.RealEstateProperty.OfficeSupplies.Amount",
                    Parameters = new ProcessMessageParameters() { new ProcessMessageParameter() {Name = "RuleIdentifier", Value = "VR.ATO.RS.000037"} },
                };
                processMessage.Parameters.Add(new ProcessMessageParameter
                    { Name = "RS55", Value = report.RS55.GetValueOrDefault().ToString() });
    
                response.Add(processMessage);
            }
            #endregion // VR.ATO.RS.000037
    
            #region VR.ATO.RS.000038
    
            /*  VR.ATO.RS.000038
            Travel expenses has a maximum field length of 11
    
            Legacy Rule Format:
            IF [RS56] <> MONETARY(U,11,0)
                 RETURN VALIDATION MESSAGE
            ENDIF

            Technical Business Rule Format:
            NotMonetary(^RS56, 'U', 11, 0)
    
            Data Elements:
    
            RP:^RS56 = tns:Expense.Travel.Amount
            */
            assertion = NotMonetary(report.RS56, @"U", 11, 0);
            if (assertion)
            {
                processMessage = new ProcessMessageDocument()
                {
                    Code = "CMN.ATO.RS.000038", Severity = ProcessMessageSeverity.Error,
                    Description = @"Travel expenses is not in a valid monetary format",
                    LongDescription = @"Travel expenses must be unsigned, not exceed 11 digits; no other characters are allowed except for the preceding sign",
                    Location = "/xbrli:xbrl/tns:Expense.Travel.Amount",
                    Parameters = new ProcessMessageParameters() { new ProcessMessageParameter() {Name = "RuleIdentifier", Value = "VR.ATO.RS.000038"} },
                };
                processMessage.Parameters.Add(new ProcessMessageParameter
                    { Name = "RS56", Value = report.RS56.GetValueOrDefault().ToString() });
    
                response.Add(processMessage);
            }
            #endregion // VR.ATO.RS.000038
    
            #region VR.ATO.RS.000039
    
            /*  VR.ATO.RS.000039
            Water charges has a maximum field length of 11
    
            Legacy Rule Format:
            IF [RS57] <> MONETARY(U,11,0)
                 RETURN VALIDATION MESSAGE
            ENDIF

            Technical Business Rule Format:
            NotMonetary(^RS57, 'U', 11, 0)
    
            Data Elements:
    
            RP:^RS57 = tns:Expense.RealEstateProperty.Water.Amount
            */
            assertion = NotMonetary(report.RS57, @"U", 11, 0);
            if (assertion)
            {
                processMessage = new ProcessMessageDocument()
                {
                    Code = "CMN.ATO.RS.000039", Severity = ProcessMessageSeverity.Error,
                    Description = @"Water charges is not in a valid monetary format",
                    LongDescription = @"Water charges must be unsigned, not exceed 11 digits; no other characters are allowed except for the preceding sign",
                    Location = "/xbrli:xbrl/tns:Expense.RealEstateProperty.Water.Amount",
                    Parameters = new ProcessMessageParameters() { new ProcessMessageParameter() {Name = "RuleIdentifier", Value = "VR.ATO.RS.000039"} },
                };
                processMessage.Parameters.Add(new ProcessMessageParameter
                    { Name = "RS57", Value = report.RS57.GetValueOrDefault().ToString() });
    
                response.Add(processMessage);
            }
            #endregion // VR.ATO.RS.000039
    
            #region VR.ATO.RS.000040
    
            /*  VR.ATO.RS.000040
            Sundry rental expenses has a maximum field length of 11
    
            Legacy Rule Format:
            IF [RS58] <> MONETARY(U,11,0)
                 RETURN VALIDATION MESSAGE
            ENDIF

            Technical Business Rule Format:
            NotMonetary(^RS58, 'U', 11, 0)
    
            Data Elements:
    
            RP:^RS58 = tns:Expense.RealEstateProperty.Sundry.Amount
            */
            assertion = NotMonetary(report.RS58, @"U", 11, 0);
            if (assertion)
            {
                processMessage = new ProcessMessageDocument()
                {
                    Code = "CMN.ATO.RS.000040", Severity = ProcessMessageSeverity.Error,
                    Description = @"Sundry rental expenses is not in a valid monetary format",
                    LongDescription = @"Sundry rental expenses must be unsigned, not exceed 11 digits; no other characters are allowed except for the preceding sign",
                    Location = "/xbrli:xbrl/tns:Expense.RealEstateProperty.Sundry.Amount",
                    Parameters = new ProcessMessageParameters() { new ProcessMessageParameter() {Name = "RuleIdentifier", Value = "VR.ATO.RS.000040"} },
                };
                processMessage.Parameters.Add(new ProcessMessageParameter
                    { Name = "RS58", Value = report.RS58.GetValueOrDefault().ToString() });
    
                response.Add(processMessage);
            }
            #endregion // VR.ATO.RS.000040
    
            #region VR.ATO.RS.000041
    
            /*  VR.ATO.RS.000041
            Net rent has a maximum field length of 11
    
            Legacy Rule Format:
            IF [RS59] <> MONETARY(S,11,0)
                 RETURN VALIDATION MESSAGE
            ENDIF

            Technical Business Rule Format:
            NotMonetary(^RS59, 'S', 11, 0)
    
            Data Elements:
    
            RP:^RS59 = tns:Income.RealEstateProperty.RentalNet.Amount
            */
            assertion = NotMonetary(report.RS59, @"S", 11, 0);
            if (assertion)
            {
                processMessage = new ProcessMessageDocument()
                {
                    Code = "CMN.ATO.RS.000041", Severity = ProcessMessageSeverity.Error,
                    Description = @"Net rent is not in a valid monetary format",
                    LongDescription = @"Net rent may be signed, not exceed 11 digits; no other characters are allowed except for the preceding sign",
                    Location = "/xbrli:xbrl/tns:Income.RealEstateProperty.RentalNet.Amount",
                    Parameters = new ProcessMessageParameters() { new ProcessMessageParameter() {Name = "RuleIdentifier", Value = "VR.ATO.RS.000041"} },
                };
                processMessage.Parameters.Add(new ProcessMessageParameter
                    { Name = "RS59", Value = report.RS59.GetValueOrDefault().ToString() });
    
                response.Add(processMessage);
            }
            #endregion // VR.ATO.RS.000041
    
            #region VR.ATO.RS.000043
    
            /*  VR.ATO.RS.000043
            Number of weeks property was rented this year is mandatory
    
            Legacy Rule Format:
            IF ([RS25] = NULL) 
              RETURN VALIDATION MESSAGE 
            ENDIF

            Technical Business Rule Format:
            ^RS25 = NULL
    
            Data Elements:
    
            RP:^RS25 = tns:RealEstateProperty.RentalWeeks.Count
            */
            assertion = (report.RS25 == null);
            if (assertion)
            {
                processMessage = new ProcessMessageDocument()
                {
                    Code = "CMN.ATO.RS.000043", Severity = ProcessMessageSeverity.Error,
                    Description = @"Number of weeks property was rented this year must be provided",
                    Location = "/xbrli:xbrl/tns:RealEstateProperty.RentalWeeks.Count",
                    Parameters = new ProcessMessageParameters() { new ProcessMessageParameter() {Name = "RuleIdentifier", Value = "VR.ATO.RS.000043"} },
                };
                processMessage.Parameters.Add(new ProcessMessageParameter
                    { Name = "RS25", Value = report.RS25.GetValueOrDefault().ToString() });
    
                response.Add(processMessage);
            }
            #endregion // VR.ATO.RS.000043
    
            #region VR.ATO.RS.000125
    
            /*  VR.ATO.RS.000125
            Value of capital allowances (depreciation on plant) recouped on the sale of the property has a maximum field length of 11
    
            Legacy Rule Format:
            IF ([RS34] <> NULL) AND ([RS34] <> MONETARY(U,11,0))
                 RETURN VALIDATION MESSAGE
            ENDIF

            Technical Business Rule Format:
            NotMonetary(^RS34, 'U', 11, 0)
    
            Data Elements:
    
            RP:^RS34 = tns:Expense.RealEstateProperty.PlantRecoupedDepreciationOnSale.Amount
            */
            assertion = NotMonetary(report.RS34, @"U", 11, 0);
            if (assertion)
            {
                processMessage = new ProcessMessageDocument()
                {
                    Code = "CMN.ATO.RS.000125", Severity = ProcessMessageSeverity.Error,
                    Description = @"Value of capital allowances (depreciation on plant) recouped on the sale of the property is not in a valid monetary format",
                    Location = "/xbrli:xbrl/tns:Expense.RealEstateProperty.PlantRecoupedDepreciationOnSale.Amount",
                    Parameters = new ProcessMessageParameters() { new ProcessMessageParameter() {Name = "RuleIdentifier", Value = "VR.ATO.RS.000125"} },
                };
                processMessage.Parameters.Add(new ProcessMessageParameter
                    { Name = "RS34", Value = report.RS34.GetValueOrDefault().ToString() });
    
                response.Add(processMessage);
            }
            #endregion // VR.ATO.RS.000125
    
            #region VR.ATO.RS.000126
    
            /*  VR.ATO.RS.000126
            Sale price of property has a maximum field length of 11
    
            Legacy Rule Format:
            IF ([RS32] <> NULL) AND ([RS32] <> MONETARY(U,11,0))
                 RETURN VALIDATION MESSAGE
            ENDIF

            Technical Business Rule Format:
            NotMonetary(^RS32, 'U', 11, 0)
    
            Data Elements:
    
            RP:^RS32 = tns:Assets.Investment.RealEstatePropertySale.Amount
            */
            assertion = NotMonetary(report.RS32, @"U", 11, 0);
            if (assertion)
            {
                processMessage = new ProcessMessageDocument()
                {
                    Code = "CMN.ATO.RS.000126", Severity = ProcessMessageSeverity.Error,
                    Description = @"Sale price of property is not in a valid monetary format",
                    Location = "/xbrli:xbrl/tns:Assets.Investment.RealEstatePropertySale.Amount",
                    Parameters = new ProcessMessageParameters() { new ProcessMessageParameter() {Name = "RuleIdentifier", Value = "VR.ATO.RS.000126"} },
                };
                processMessage.Parameters.Add(new ProcessMessageParameter
                    { Name = "RS32", Value = report.RS32.GetValueOrDefault().ToString() });
    
                response.Add(processMessage);
            }
            #endregion // VR.ATO.RS.000126
    
            #region VR.ATO.RS.000127
    
            /*  VR.ATO.RS.000127
            Purchase price of property has a maximum field length of 11
    
            Legacy Rule Format:
            IF ([RS30] <> NULL) AND ([RS30] <> MONETARY(U,11,0))
                 RETURN VALIDATION MESSAGE
            ENDIF

            Technical Business Rule Format:
            NotMonetary(^RS30, 'U', 11, 0)
    
            Data Elements:
    
            RP:^RS30 = tns:Assets.Investment.RealEstatePropertyPurchase.Amount
            */
            assertion = NotMonetary(report.RS30, @"U", 11, 0);
            if (assertion)
            {
                processMessage = new ProcessMessageDocument()
                {
                    Code = "CMN.ATO.RS.000127", Severity = ProcessMessageSeverity.Error,
                    Description = @"Purchase price of property is not in a valid monetary format",
                    Location = "/xbrli:xbrl/tns:Assets.Investment.RealEstatePropertyPurchase.Amount",
                    Parameters = new ProcessMessageParameters() { new ProcessMessageParameter() {Name = "RuleIdentifier", Value = "VR.ATO.RS.000127"} },
                };
                processMessage.Parameters.Add(new ProcessMessageParameter
                    { Name = "RS30", Value = report.RS30.GetValueOrDefault().ToString() });
    
                response.Add(processMessage);
            }
            #endregion // VR.ATO.RS.000127
    
            #region VR.ATO.RS.000128
    
            /*  VR.ATO.RS.000128
            Capital gain/loss on sale of this property has a maximum field length of 11
    
            Legacy Rule Format:
            IF ([RS33] <> NULL) AND([RS33] <> MONETARY(S,11,0))
                 RETURN VALIDATION MESSAGE
            ENDIF

            Technical Business Rule Format:
            NotMonetary(^RS33, 'S', 11, 0)
    
            Data Elements:
    
            RP:^RS33 = tns:Income.RealEstateProperty.CapitalGainsNet.Amount
            */
            assertion = NotMonetary(report.RS33, @"S", 11, 0);
            if (assertion)
            {
                processMessage = new ProcessMessageDocument()
                {
                    Code = "CMN.ATO.RS.000128", Severity = ProcessMessageSeverity.Error,
                    Description = @"Capital gain/loss on sale of this property is not in a valid monetary format",
                    Location = "/xbrli:xbrl/tns:Income.RealEstateProperty.CapitalGainsNet.Amount",
                    Parameters = new ProcessMessageParameters() { new ProcessMessageParameter() {Name = "RuleIdentifier", Value = "VR.ATO.RS.000128"} },
                };
                processMessage.Parameters.Add(new ProcessMessageParameter
                    { Name = "RS33", Value = report.RS33.GetValueOrDefault().ToString() });
    
                response.Add(processMessage);
            }
            #endregion // VR.ATO.RS.000128
    
            #region VR.ATO.RS.000129
    
            /*  VR.ATO.RS.000129
            Value of capital works deductions (special building write-off) recouped on the sale of the property has a maximum field length of 11
    
            Legacy Rule Format:
            IF [RS35] <> MONETARY(U,11,0)
                 RETURN VALIDATION MESSAGE
            ENDIF

            Technical Business Rule Format:
            NotMonetary(^RS35, 'U', 11, 0)
    
            Data Elements:
    
            RP:^RS35 = tns:Expense.RealEstateProperty.CapitalWorksDeductionRecouped.Amount
            */
            assertion = NotMonetary(report.RS35, @"U", 11, 0);
            if (assertion)
            {
                processMessage = new ProcessMessageDocument()
                {
                    Code = "CMN.ATO.RS.000129", Severity = ProcessMessageSeverity.Error,
                    Description = @"Value of capital works deductions (special building write-off) recouped on the sale of the property is not in a valid monetary format",
                    LongDescription = @"Value of capital works deductions (special building write-off) recouped on the sale of the property may be signed, not exceed 11 digits; no other characters are allowed except for the preceding sign",
                    Location = "/xbrli:xbrl/tns:Expense.RealEstateProperty.CapitalWorksDeductionRecouped.Amount",
                    Parameters = new ProcessMessageParameters() { new ProcessMessageParameter() {Name = "RuleIdentifier", Value = "VR.ATO.RS.000129"} },
                };
                processMessage.Parameters.Add(new ProcessMessageParameter
                    { Name = "RS35", Value = report.RS35.GetValueOrDefault().ToString() });
    
                response.Add(processMessage);
            }
            #endregion // VR.ATO.RS.000129
    
            #region VR.ATO.RS.000139
    
            /*  VR.ATO.RS.000139
            Field is mandatory
    
            Legacy Rule Format:
            IF [RS12] = SET("161","212") AND
              [RS28] = NULL
              RETURN VALIDATION MESSAGE 
            ENDIF

            Technical Business Rule Format:
            InSet(^RS12, '"161","212"') AND  ^RS28 = NULL
    
            Data Elements:
    
            RP:^RS28 = tns:RealEstateProperty.Ownership.Percent
    
            RP:^RS12 = tns:Party.Type.Code
            */
            assertion = (IsMatch(report.RS12, @"^(161|212)$") && report.RS28 == null);
            if (assertion)
            {
                processMessage = new ProcessMessageDocument()
                {
                    Code = "CMN.ATO.GEN.001001", Severity = ProcessMessageSeverity.Error,
                    Description = @"Mandatory field not supplied",
                    Location = "/xbrli:xbrl/tns:RealEstateProperty.Ownership.Percent",
                    Parameters = new ProcessMessageParameters() { new ProcessMessageParameter() {Name = "RuleIdentifier", Value = "VR.ATO.RS.000139"} },
                };
                processMessage.Parameters.Add(new ProcessMessageParameter
                    { Name = "RS12", Value = report.RS12 });
    
                processMessage.Parameters.Add(new ProcessMessageParameter
                    { Name = "RS28", Value = report.RS28.GetValueOrDefault().ToString() });
    
                response.Add(processMessage);
            }
            #endregion // VR.ATO.RS.000139
    
            #region VR.ATO.RS.000140
    
            /*  VR.ATO.RS.000140
            Percentage of ownership of the property must not exceed 100
    
            Legacy Rule Format:
            IF [RS28] > 100 
              RETURN VALIDATION MESSAGE 
            ENDIF

            Technical Business Rule Format:
            ^RS28 > 100
    
            Data Elements:
    
            RP:^RS28 = tns:RealEstateProperty.Ownership.Percent
            */
            assertion = (report.RS28.GetValueOrDefault() > 100);
            if (assertion)
            {
                processMessage = new ProcessMessageDocument()
                {
                    Code = "CMN.ATO.RS.000140", Severity = ProcessMessageSeverity.Error,
                    Description = @"Percentage must not exceed 100%",
                    Location = "/xbrli:xbrl/tns:RealEstateProperty.Ownership.Percent",
                    Parameters = new ProcessMessageParameters() { new ProcessMessageParameter() {Name = "RuleIdentifier", Value = "VR.ATO.RS.000140"} },
                };
                processMessage.Parameters.Add(new ProcessMessageParameter
                    { Name = "RS28", Value = report.RS28.GetValueOrDefault().ToString() });
    
                response.Add(processMessage);
            }
            #endregion // VR.ATO.RS.000140
    
            #region VR.ATO.RS.000141
    
            /*  VR.ATO.RS.000141
            Field is mandatory
    
            Legacy Rule Format:
            IF [RS12] = SET("161","212") AND
              [RS29] = NULL
              RETURN VALIDATION MESSAGE 
            ENDIF

            Technical Business Rule Format:
            InSet(^RS12, '"161","212"') AND  ^RS29 = NULL
    
            Data Elements:
    
            RP:^RS29 = tns:RealEstateProperty.Acquisition.Date
    
            RP:^RS12 = tns:Party.Type.Code
            */
            assertion = (IsMatch(report.RS12, @"^(161|212)$") && report.RS29 == null);
            if (assertion)
            {
                processMessage = new ProcessMessageDocument()
                {
                    Code = "CMN.ATO.GEN.001001", Severity = ProcessMessageSeverity.Error,
                    Description = @"Mandatory field not supplied",
                    Location = "/xbrli:xbrl/tns:RealEstateProperty.Acquisition.Date",
                    Parameters = new ProcessMessageParameters() { new ProcessMessageParameter() {Name = "RuleIdentifier", Value = "VR.ATO.RS.000141"} },
                };
                processMessage.Parameters.Add(new ProcessMessageParameter
                    { Name = "RS12", Value = report.RS12 });
    
                processMessage.Parameters.Add(new ProcessMessageParameter
                    { Name = "RS29", Value = GetValueOrEmpty(report.RS29) });
    
                response.Add(processMessage);
            }
            #endregion // VR.ATO.RS.000141
    
            #region VR.ATO.RS.000142
    
            /*  VR.ATO.RS.000142
            Field is mandatory
    
            Legacy Rule Format:
            IF [RS12] = SET("161","212") AND
              [RS30] = NULL
              RETURN VALIDATION MESSAGE 
            ENDIF

            Technical Business Rule Format:
            InSet(^RS12, '"161","212"') AND  ^RS30 = NULL
    
            Data Elements:
    
            RP:^RS30 = tns:Assets.Investment.RealEstatePropertyPurchase.Amount
    
            RP:^RS12 = tns:Party.Type.Code
            */
            assertion = (IsMatch(report.RS12, @"^(161|212)$") && report.RS30 == null);
            if (assertion)
            {
                processMessage = new ProcessMessageDocument()
                {
                    Code = "CMN.ATO.GEN.001001", Severity = ProcessMessageSeverity.Error,
                    Description = @"Mandatory field not supplied",
                    Location = "/xbrli:xbrl/tns:Assets.Investment.RealEstatePropertyPurchase.Amount",
                    Parameters = new ProcessMessageParameters() { new ProcessMessageParameter() {Name = "RuleIdentifier", Value = "VR.ATO.RS.000142"} },
                };
                processMessage.Parameters.Add(new ProcessMessageParameter
                    { Name = "RS12", Value = report.RS12 });
    
                processMessage.Parameters.Add(new ProcessMessageParameter
                    { Name = "RS30", Value = report.RS30.GetValueOrDefault().ToString() });
    
                response.Add(processMessage);
            }
            #endregion // VR.ATO.RS.000142
    
            #region VR.ATO.RS.000143
    
            /*  VR.ATO.RS.000143
            If this numeric field is populated ensure it complies with the numeric field format rules and also is unsigned with a maximum of 2  digits with no decimal places
    
            Legacy Rule Format:
            IF ([RS27] <> NULL) AND ([RS27] <> NUMBER(U,2,0))
               RETURN VALIDATION MESSAGE
            ENDIF

            Technical Business Rule Format:
            NotNumeric(^RS27, 'U', 2, 0)
    
            Data Elements:
    
            RP:^RS27 = tns:RealEstateProperty.RentalWeeksAvailable.Count
            */
            assertion = NotNumeric(report.RS27, @"U", 2, 0);
            if (assertion)
            {
                processMessage = new ProcessMessageDocument()
                {
                    Code = "CMN.ATO.RS.000143", Severity = ProcessMessageSeverity.Error,
                    Description = @"Field incorrect format. Exceeds maximum digits and/or contains illegal characters",
                    Location = "/xbrli:xbrl/tns:RealEstateProperty.RentalWeeksAvailable.Count",
                    Parameters = new ProcessMessageParameters() { new ProcessMessageParameter() {Name = "RuleIdentifier", Value = "VR.ATO.RS.000143"} },
                };
                processMessage.Parameters.Add(new ProcessMessageParameter
                    { Name = "RS27", Value = report.RS27.GetValueOrDefault().ToString() });
    
                response.Add(processMessage);
            }
            #endregion // VR.ATO.RS.000143
    
            #region VR.ATO.RS.000144
    
            /*  VR.ATO.RS.000144
            Number field must be numeric, a maximum of 3 digits with 0 decimal places, unsigned.
    
            Legacy Rule Format:
            IF [RS28] <> NULL AND [RS28] <> NUMBER(U,3,0) 
              RETURN VALIDATION MESSAGE 
            ENDIF

            Technical Business Rule Format:
            NotNumeric(^RS28, 'U', 3, 0)
    
            Data Elements:
    
            RP:^RS28 = tns:RealEstateProperty.Ownership.Percent
            */
            assertion = NotNumeric(report.RS28, @"U", 3, 0);
            if (assertion)
            {
                processMessage = new ProcessMessageDocument()
                {
                    Code = "CMN.ATO.RS.000144", Severity = ProcessMessageSeverity.Error,
                    Description = @"Field incorrect format. Exceeds maximum digits and/or contains illegal characters",
                    Location = "/xbrli:xbrl/tns:RealEstateProperty.Ownership.Percent",
                    Parameters = new ProcessMessageParameters() { new ProcessMessageParameter() {Name = "RuleIdentifier", Value = "VR.ATO.RS.000144"} },
                };
                processMessage.Parameters.Add(new ProcessMessageParameter
                    { Name = "RS28", Value = report.RS28.GetValueOrDefault().ToString() });
    
                response.Add(processMessage);
            }
            #endregion // VR.ATO.RS.000144
    
            #region VR.ATO.RS.000145
    
            /*  VR.ATO.RS.000145
            If this numeric field is populated it must be numeric, unsigned with a maximum of 2 digits with no decimal places
    
            Legacy Rule Format:
            IF ([RS25] <> NULL) AND ([RS25] <> NUMBER(U,2,0))
               RETURN VALIDATION MESSAGE
            ENDIF

            Technical Business Rule Format:
            NotNumeric(^RS25, 'U', 2, 0)
    
            Data Elements:
    
            RP:^RS25 = tns:RealEstateProperty.RentalWeeks.Count
            */
            assertion = NotNumeric(report.RS25, @"U", 2, 0);
            if (assertion)
            {
                processMessage = new ProcessMessageDocument()
                {
                    Code = "CMN.ATO.RS.000145", Severity = ProcessMessageSeverity.Error,
                    Description = @"Field incorrect format. Exceeds maximum digits and/or contains illegal characters",
                    Location = "/xbrli:xbrl/tns:RealEstateProperty.RentalWeeks.Count",
                    Parameters = new ProcessMessageParameters() { new ProcessMessageParameter() {Name = "RuleIdentifier", Value = "VR.ATO.RS.000145"} },
                };
                processMessage.Parameters.Add(new ProcessMessageParameter
                    { Name = "RS25", Value = report.RS25.GetValueOrDefault().ToString() });
    
                response.Add(processMessage);
            }
            #endregion // VR.ATO.RS.000145
    
            #region VR.ATO.RS.000147
    
            /*  VR.ATO.RS.000147
            Field is mandatory
    
            Legacy Rule Format:
            IF [RS12] = SET("161","212") AND
              [RS36] = NULL
              RETURN VALIDATION MESSAGE 
            ENDIF

            Technical Business Rule Format:
            InSet(^RS12, '"161","212"') AND  ^RS36 = NULL
    
            Data Elements:
    
            RP:^RS36 = tns:RealEstateProperty.LoanRenegotiated.Indicator
    
            RP:^RS12 = tns:Party.Type.Code
            */
            assertion = (IsMatch(report.RS12, @"^(161|212)$") && report.RS36 == null);
            if (assertion)
            {
                processMessage = new ProcessMessageDocument()
                {
                    Code = "CMN.ATO.GEN.001001", Severity = ProcessMessageSeverity.Error,
                    Description = @"Mandatory field not supplied",
                    Location = "/xbrli:xbrl/tns:RealEstateProperty.LoanRenegotiated.Indicator",
                    Parameters = new ProcessMessageParameters() { new ProcessMessageParameter() {Name = "RuleIdentifier", Value = "VR.ATO.RS.000147"} },
                };
                processMessage.Parameters.Add(new ProcessMessageParameter
                    { Name = "RS12", Value = report.RS12 });
    
                processMessage.Parameters.Add(new ProcessMessageParameter
                    { Name = "RS36", Value = GetValueOrEmpty(report.RS36) });
    
                response.Add(processMessage);
            }
            #endregion // VR.ATO.RS.000147
    
            #region VR.ATO.RS.000148
    
            /*  VR.ATO.RS.000148
            Organisation name must be present
    
            Legacy Rule Format:
            IF [RS12] = SET("161","212") AND
              [RS14] = NULLORBLANK
              RETURN VALIDATION MESSAGE
            ENDIF

            Technical Business Rule Format:
            InSet(^RS12, '"161","212"') AND  ^RS14 = BLANK
    
            Data Elements:
    
            RP:^RS14 = tns:OrganisationNameDetails.OrganisationalName.Text
    
            RP:^RS12 = tns:Party.Type.Code
            */
            assertion = (IsMatch(report.RS12, @"^(161|212)$") && string.IsNullOrWhiteSpace(report.RS14) == true);
            if (assertion)
            {
                processMessage = new ProcessMessageDocument()
                {
                    Code = "CMN.ATO.RS.000148", Severity = ProcessMessageSeverity.Error,
                    Description = @"Organisation name must be present",
                    Location = "/xbrli:xbrl/tns:OrganisationNameDetails.OrganisationalName.Text",
                    Parameters = new ProcessMessageParameters() { new ProcessMessageParameter() {Name = "RuleIdentifier", Value = "VR.ATO.RS.000148"} },
                };
                processMessage.Parameters.Add(new ProcessMessageParameter
                    { Name = "RS12", Value = report.RS12 });
    
                processMessage.Parameters.Add(new ProcessMessageParameter
                    { Name = "RS14", Value = report.RS14 });
    
                response.Add(processMessage);
            }
            #endregion // VR.ATO.RS.000148

            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;
        }


    }
} 