Example #1
0
 private Validator(Bill bill)
 {
     _billIn           = bill;
     _billOut          = new Bill();
     _validationResult = new ValidationResult();
 }
Example #2
0
        /// <summary>
        /// Validates the QR bill data and returns the validation messages (if any) and
        /// the cleaned bill data.
        /// </summary>
        /// <param name="bill">The bill data to validate.</param>
        /// <returns>The validation result.</returns>
        internal static ValidationResult Validate(Bill bill)
        {
            Validator validator = new Validator(bill);

            return(validator.ValidateBill());
        }
Example #3
0
 /// <summary>
 /// Validates and cleans the bill data.
 /// <para>
 /// The validation result contains the error and warning messages (if any) and the cleaned bill data.
 /// </para>
 /// <para>
 /// For details about the validation result, see <a href=
 /// "https://github.com/manuelbl/SwissQRBill/wiki/Bill-data-validation">Bill data validation</a>
 /// </para>
 /// </summary>
 /// <param name="bill">The bill data to validate.</param>
 /// <returns>The validation result.</returns>
 public static ValidationResult Validate(Bill bill)
 {
     return(Validator.Validate(bill));
 }
Example #4
0
        /// <summary>
        /// Gets the text embedded in the QR code (according to the data structure defined by SIX).
        /// </summary>
        /// <param name="bill">The bill data.</param>
        /// <returns>The QR code text.</returns>
        public static string Create(Bill bill)
        {
            QRCodeText qrCodeText = new QRCodeText(bill);

            return(qrCodeText.CreateText());
        }
Example #5
0
 private QRCodeText(Bill bill)
 {
     _bill = bill;
 }
Example #6
0
        /// <summary>
        /// Decodes the specified text and returns the bill data.
        /// <para>
        /// The text is assumed to be in the data structured for the QR code defined by SIX.
        /// </para>
        /// <para>
        /// The returned data is only minimally validated. The format and the header are
        /// checked. Amount and date must be parsable.
        /// </para>
        /// </summary>
        /// <param name="text">The text to decode.</param>
        /// <returns>The decoded bill data.</returns>
        /// <exception cref="QRBillValidationException">The text is in an invalid format.</exception>
        public static Bill Decode(string text)
        {
            string[] lines = SplitLines(text);
            if (lines.Length < 31 || lines.Length > 34)
            {
                // A line feed at the end is illegal (cf 4.2.3) but found in practice. Don't be too strict.
                if (!(lines.Length == 35 && lines[34].Length == 0))
                {
                    ThrowSingleValidationError(ValidationConstants.FieldQrType, ValidationConstants.KeyValidDataStructure);
                }
            }

            if ("SPC" != lines[0])
            {
                ThrowSingleValidationError(ValidationConstants.FieldQrType, ValidationConstants.KeyValidDataStructure);
            }

            if ("0200" != lines[1])
            {
                ThrowSingleValidationError(ValidationConstants.FieldVersion, ValidationConstants.KeySupportedVersion);
            }

            if ("1" != lines[2])
            {
                ThrowSingleValidationError(ValidationConstants.FieldCodingType, ValidationConstants.KeySupportedCodingType);
            }

            Bill billData = new Bill
            {
                Version = Bill.QrBillStandardVersion.V2_0,

                Account = lines[3],

                Creditor = DecodeAddress(lines, 4, false)
            };

            if (lines[18].Length > 0)
            {
                if (decimal.TryParse(lines[18], NumberStyles.Number, AmountNumberInfo, out decimal amount))
                {
                    billData.Amount = amount;
                }
                else
                {
                    ThrowSingleValidationError(ValidationConstants.FieldAmount, ValidationConstants.KeyValidNumber);
                }
            }
            else
            {
                billData.Amount = null;
            }

            billData.Currency = lines[19];

            billData.Debtor = DecodeAddress(lines, 20, true);

            // Set reference type and reference in reverse order
            // to retain reference type (as it is updated by setting 'Reference')
            billData.Reference           = lines[28];
            billData.ReferenceType       = lines[27];
            billData.UnstructuredMessage = lines[29];
            if ("EPD" != lines[30])
            {
                ThrowSingleValidationError(ValidationConstants.FieldTrailer, ValidationConstants.KeyValidDataStructure);
            }

            billData.BillInformation = lines.Length > 31 ? lines[31] : "";

            List <AlternativeScheme> alternativeSchemes = null;
            int numSchemes = lines.Length - 32;

            // skip empty schemes at end (due to invalid trailing line feed)
            if (numSchemes > 0 && lines[32 + numSchemes - 1].Length == 0)
            {
                numSchemes--;
            }
            if (numSchemes > 0)
            {
                alternativeSchemes = new List <AlternativeScheme>();
                for (int i = 0; i < numSchemes; i++)
                {
                    AlternativeScheme scheme = new AlternativeScheme
                    {
                        Instruction = lines[32 + i]
                    };
                    alternativeSchemes.Add(scheme);
                }
            }
            billData.AlternativeSchemes = alternativeSchemes;

            return(billData);
        }