Esempio n. 1
0
        /// <summary>
        /// Creates the single vat return information.
        /// </summary>
        /// <param name="htmlUrl">The HTML URL.</param>
        /// <param name="pdfUrl">The PDF URL.</param>
        /// <param name="browser">The browser.</param>
        /// <returns></returns>
        private async Task <Optional <VatReturnInfo> > CreateSingleVatReturnInfo(string htmlUrl, string pdfUrl, IEzBobWebBrowser browser)
        {
            string html = await browser.DownloadPageAsyncAsString(htmlUrl);

            Optional <VatReturnInfo> optional = this.ParseVatReturnHtml(html);

            if (optional.HasValue)
            {
                byte[] pdfFile = await browser.DownloadPageAsyncAsByteArray(pdfUrl);

                optional.GetValue()
                .PdfFile = pdfFile;
            }
            return(optional);
        }
Esempio n. 2
0
        /// <summary>
        /// Scraps login details.
        /// </summary>
        /// <param name="baseUrl">The base URL.</param>
        /// <param name="browser">The browser.</param>
        /// <returns></returns>
        /// <exception cref="System.IO.InvalidDataException">Login form not found or too many forms on the page.
        /// or
        /// User name field not found.
        /// or
        /// User name field's NAME attribute not specified.
        /// or
        /// Password field not found.
        /// or
        /// Password field's NAME attribute not specified.</exception>
        public async Task <ScrapedLoginRequestDetails> ScrapLoginDetails(string baseUrl, IEzBobWebBrowser browser)
        {
            var html = await browser.DownloadPageAsyncAsString(baseUrl);

            HtmlDocument htmlDocument = new HtmlDocument();

            htmlDocument.LoadHtml(html);

            HtmlNodeCollection forms = htmlDocument.DocumentNode.SelectNodes("//form[contains(@action,'login')]");

            if (forms == null || forms.Count != 1)
            {
                throw new InvalidDataException("Login form not found or too many forms on the page.");
            }

            HtmlNode loginForm = forms[0];

            string loginUrl    = loginForm.Attributes["action"].Value;
            string loginMethod = loginForm.Attributes.Contains("method") ? loginForm.Attributes["method"].Value : "GET";

            HtmlNode userName = loginForm.SelectSingleNode("//input[@id=\"FieldUserID\"]");

            if (userName == null)
            {
                throw new InvalidDataException("User name field not found.");
            }

            if (!userName.Attributes.Contains("name"))
            {
                throw new InvalidDataException("User name field's NAME attribute not specified.");
            }

            HtmlNode password = loginForm.SelectSingleNode("//input[@id=\"FieldPassword\"]");

            if (password == null)
            {
                throw new InvalidDataException("Password field not found.");
            }

            if (!password.Attributes.Contains("name"))
            {
                throw new InvalidDataException("Password field's NAME attribute not specified.");
            }

            var loginDetails = new ScrapedLoginRequestDetails {
                HttpMethod   = loginMethod,
                LoginPageUrl = loginUrl,
                UserName     = userName.Attributes["name"].Value,
                Password     = password.Attributes["name"].Value
            };

            Log.Info(loginDetails.ToString());

            return(loginDetails);
        }
Esempio n. 3
0
        /// <summary>
        /// Obtains the vat returns.
        /// </summary>
        /// <param name="submittedReturns">The submitted returns.</param>
        /// <param name="userVatId">The user vat identifier.</param>
        /// <param name="baseUrl">The base URL.</param>
        /// <param name="browser">The browser.</param>
        /// <returns></returns>
        private IEnumerable <Task <Optional <VatReturnInfo> > > ObtainVatReturns(IDictionary <string, string> submittedReturns, string userVatId, string baseUrl, IEzBobWebBrowser browser)
        {
            foreach (var submitedReturn in submittedReturns)
            {
                string htmlUrl = baseUrl + string.Format(
                    "/vat-file/trader/{0}{1}{2}",
                    userVatId,
                    userVatId.EndsWith("/") || submitedReturn.Key.StartsWith("/") ? "" : "/",
                    submitedReturn.Key);

                string pdfUrl       = htmlUrl + "?format=pdf";
                string baseFileName = submitedReturn.Value.Replace(' ', '_');

                Log.InfoFormat("VatReturns: requesting {0}.html <- {1}", baseFileName, htmlUrl);

                yield return(CreateSingleVatReturnInfo(htmlUrl, pdfUrl, browser));
            }
        }
Esempio n. 4
0
        /// <summary>
        /// Gets the vat returns.
        /// </summary>
        /// <param name="userVatId">The user vat identifier.</param>
        /// <param name="baseUrl">The base URL.</param>
        /// <param name="browser">The browser.</param>
        /// <returns></returns>
        public async Task <IEnumerable <VatReturnInfo> > GetVatReturns(string userVatId, string baseUrl, IEzBobWebBrowser browser)
        {
            InfoAccumulator info = new InfoAccumulator();

            IDictionary <string, string> submittedReturns = await FetchSubmittedReturnsList(userVatId, baseUrl, info, browser);

            if (info.HasErrors || submittedReturns == null || submittedReturns.Count == 0)
            {
                return(null);
            }

            var tasks = this.ObtainVatReturns(submittedReturns, userVatId, baseUrl, browser);

            Optional <VatReturnInfo>[] optionals = await Task.WhenAll(tasks);

            return(optionals.Where(o => o.HasValue)
                   .Select(o => o.GetValue()));
        }
Esempio n. 5
0
        /// <summary>
        /// Fetches the submitted returns list.
        /// </summary>
        /// <param name="vatId">The vat identifier.</param>
        /// <param name="baseUrl">The base URL.</param>
        /// <param name="info">The information.</param>
        /// <param name="browser">The browser.</param>
        /// <returns></returns>
        private async Task <IDictionary <string, string> > FetchSubmittedReturnsList(string vatId, string baseUrl, InfoAccumulator info, IEzBobWebBrowser browser)
        {
            Log.Info("Loading list of submitted VAT returns...");

            string html = await browser.DownloadPageAsyncAsString(baseUrl + "/vat-file/trader/" + vatId + "/periods");

            HtmlDocument doc = new HtmlDocument();

            doc.LoadHtml(html);

            bool hasNoPrevious = doc.DocumentNode.InnerText.IndexOf(
                "There are no returns previously submitted available to view.",
                StringComparison.InvariantCulture
                ) >= 0;

            if (hasNoPrevious)
            {
                Log.Info("There are no returns previously submitted available to view.");
                return(null);
            } // if

            HtmlNode listTable = doc.DocumentNode.SelectSingleNode("//*[@id=\"VAT0011\"]/div[2]/table/tbody");

            if (listTable == null)
            {
                info.AddError("Failed to find list of returns.");
                return(null);
            }

            if (listTable.ChildNodes == null)
            {
                Log.Info("Loading list of submitted VAT returns complete, no files found.");
                return(null);
            } // if

            var res = new Dictionary <string, string>();

            foreach (HtmlNode tr in listTable.ChildNodes)
            {
                if (tr.Name.ToUpper() != "TR")
                {
                    continue;
                }

                if (tr.ChildNodes == null)
                {
                    continue;
                }

                HtmlNode td = tr.SelectSingleNode("td");

                if (td == null)
                {
                    continue;
                }

                HtmlNode link = td.SelectSingleNode("a");

                if (link == null)
                {
                    continue;
                }

                if (!link.Attributes.Contains("href"))
                {
                    continue;
                }

                string href = link.Attributes["href"].Value;

                if (string.IsNullOrWhiteSpace(href))
                {
                    continue;
                }

                res[href] = link.InnerText;
            } // for each row

            Log.InfoFormat(
                "Loading list of submitted VAT returns complete, {0} file{1} found.",
                res.Count,
                res.Count == 1 ? "" : "s"
                );

            return(res);
        } // Load
        /// <summary>
        /// Gets the user vat identifier and tax office number.
        /// </summary>
        /// <param name="url">The URL.</param>
        /// <returns></returns>
        public async Task <TaxOfficeNumberAndVatId> GetUserVatIdAndTaxOfficeNumber(string url, IEzBobWebBrowser browser)
        {
            string html = await browser.DownloadPageAsyncAsString(url + "/home/services");

            HtmlDocument document = new HtmlDocument();

            document.LoadHtml(html);

            InfoAccumulator info  = new InfoAccumulator();
            string          vatId = GetUserVatIdOldFashionedWay(document, info);

            if (string.IsNullOrEmpty(vatId))
            {
                vatId = GetUserVatIdNewFashionedWay(document, info);
                if (string.IsNullOrEmpty(vatId))
                {
                    LogErrors(info);
                    return(new TaxOfficeNumberAndVatId(null, null));
                }
            }

            info = new InfoAccumulator();
            string taxOfficeNumber = ExtractTaxOfficeNumber(document, info);

            if (string.IsNullOrEmpty(taxOfficeNumber))
            {
                LogErrors(info);
            }

            return(new TaxOfficeNumberAndVatId(taxOfficeNumber, vatId));
        }
Esempio n. 7
0
        /// <summary>
        /// Gets the rti (real time information) tax years.
        /// </summary>
        /// <param name="taxOfficeNumber">The tax office number.</param>
        /// <param name="baseUrl">The base URL.</param>
        /// <param name="browser">The browser.</param>
        /// <returns></returns>
        /// <exception cref="System.IO.InvalidDataException">Failed to fetch PAYE account page.</exception>
        public async Task <RtiTaxYearInfo> GetRtiTaxYears(string taxOfficeNumber, string baseUrl, IEzBobWebBrowser browser)
        {
            if (!ValidateParameters(taxOfficeNumber, baseUrl))
            {
                return(null);
            }

            string html = await browser.DownloadPageAsyncAsString(baseUrl + "/paye/org/" + taxOfficeNumber + "/account");

            if (string.IsNullOrEmpty(html))
            {
                throw new InvalidDataException("Failed to fetch PAYE account page.");
            }

            HtmlDocument document = new HtmlDocument();

            document.LoadHtml(html);


            return(RtiTaxYearParser.Parse(document));
        }