Beispiel #1
0
        }         // FetchBackdoorData

        /// <summary>
        /// Constructs the Harvester object. The object is not ready to harvest. Call to Init() first.
        /// </summary>
        public Harvester(AccountData oAccountData, ASafeLog log) : base(log)
        {
            ErrorsToEmail = new SortedDictionary <string, string>();

            AccountData    = oAccountData;
            VerboseLogging = false;
            Hopper         = new Hopper(VatReturnSourceType.Linked);
            IsLoggedIn     = false;
        }         // constructor
Beispiel #2
0
        public static void SetBackdoorData(int nCustomerMarketplaceID, Hopper oHopper)
        {
            if (oHopper == null)
            {
                return;
            }

            lock (typeof(Harvester)) {
                if (ms_oBackdoorData == null)
                {
                    ms_oBackdoorData = new SortedDictionary <int, Hopper>();
                }

                ms_oBackdoorData[nCustomerMarketplaceID] = oHopper;
            }     // lock
        }         // SetBackdoorData
Beispiel #3
0
        }         // ForEachFile

        public void FetchBackdoorData(Hopper oHopper)
        {
            lock (this) {
                Clear();

                if (oHopper == null)
                {
                    return;
                }

                Source = oHopper.Source;

                ErrorCount = oHopper.ErrorCount;

                var aryDataTypes = (DataType[])Enum.GetValues(typeof(DataType));

                var oFileTypes = new List <FileType>((FileType[])Enum.GetValues(typeof(FileType)));
                oFileTypes.Remove(FileType.Unknown);

                foreach (DataType dt in aryDataTypes)
                {
                    foreach (FileType ft in oFileTypes)
                    {
                        foreach (KeyValuePair <string, HarvesterError> pair in oHopper.Errors[dt][ft])
                        {
                            Errors[dt][ft][pair.Key] = pair.Value;
                        }

                        foreach (KeyValuePair <string, byte[]> pair in oHopper.Files[dt][ft])
                        {
                            Files[dt][ft][pair.Key] = pair.Value;
                        }
                    }                     // for each file type

                    foreach (KeyValuePair <string, ISeeds> pair in oHopper.Seeds[dt])
                    {
                        Seeds[dt][pair.Key] = pair.Value;
                    }
                } // for each data type
            }     // lock
        }         // FetchBackdoorData
Beispiel #4
0
        }         // ExtractTaxOfficeNumber

        private void FetchRtiTaxYears()
        {
            if (string.IsNullOrWhiteSpace(TaxOfficeNumber))
            {
                Debug("Not fetching RTI Tax Years: Tax Office number is empty.");
                return;
            }             // if

            Debug("Fetching RTI Tax Years started...");

            HtmlDocument doc = GetPage("/paye/org/" + TaxOfficeNumber + "/account");

            if ((doc == null) || (doc.DocumentNode == null))
            {
                throw new HarvesterException("Failed to fetch PAYE account page.");
            }

            var oOutput = new MemoryStream();

            doc.Save(oOutput);

            var smd = new SheafMetaData {
                BaseFileName = "PAYE RTI Tax Year",
                DataType     = DataType.PayeRtiTaxYears,
                FileType     = FileType.Html,
                Thrasher     = null
            };

            Hopper.Add(smd, oOutput.ToArray());

            HtmlNode oTHead = doc.DocumentNode.SelectSingleNode("//*[@id=\"top\"]/div[3]/div[2]/div/div[2]/table[1]/thead");

            if (oTHead == null)
            {
                Info("RTI tax years table head not found.");
                return;
            }             // if

            HtmlNodeCollection oHeadRows = oTHead.SelectNodes("tr");

            if ((oHeadRows == null) || (oHeadRows.Count != 1))
            {
                throw new HarvesterException("RTI tax years table head is empty.");
            }

            HtmlNodeCollection oHeadCells = oHeadRows[0].SelectNodes("th | td");

            string[] aryExpectedColumnHeaders = new [] {
                "Date",
                "Amount paid in period",
                "Amount due in period",
            };

            if ((oHeadCells == null) || (oHeadCells.Count != aryExpectedColumnHeaders.Length))
            {
                throw new HarvesterException(string.Format("Failed to fetch RTI tax years: no cells in header row"));
            }

            for (int i = 0; i < aryExpectedColumnHeaders.Length; i++)
            {
                if (!oHeadCells[i].InnerText.Trim().StartsWith(aryExpectedColumnHeaders[i]))
                {
                    Info(
                        "Not fetching RTI tax years: unexpected column {0} name: {1} (expected: {2})",
                        i, oHeadCells[i].InnerText, aryExpectedColumnHeaders[i]
                        );
                    return;
                }         // if
            }             // for

            HtmlNode oTBody = doc.DocumentNode.SelectSingleNode("//*[@id=\"top\"]/div[3]/div[2]/div/div[2]/table[1]/tbody");

            if (oTBody == null)
            {
                throw new HarvesterException("RTI tax years table body not found.");
            }

            HtmlNodeCollection oRows = oTBody.SelectNodes("tr");

            if ((oRows == null) || (oRows.Count < 1))
            {
                throw new HarvesterException("RTI tax years data not found.");
            }

            bool bFirst  = true;
            int  nRowNum = -1;

            int nFirstYear = 0;
            int nLastYear  = 0;

            var data = new List <RtiTaxYearRowData>();

            foreach (HtmlNode oTR in oRows)
            {
                nRowNum++;

                HtmlNodeCollection oCells = oTR.SelectNodes("th | td");

                if ((oCells == null) || (oCells.Count < 1))
                {
                    throw new HarvesterException(string.Format(
                                                     "Failed to fetch RTI tax years: no cells in row {0}.",
                                                     nRowNum
                                                     ));
                }                 // if

                if (bFirst)
                {
                    bFirst = false;

                    HtmlNode oCell = oCells[0];

                    if (!oCell.Attributes.Contains("colspan") || (oCell.Attributes["colspan"].Value != "3"))
                    {
                        throw new HarvesterException(string.Format(
                                                         "Failed to fetch RTI tax years: incorrect format in row {0}",
                                                         nRowNum
                                                         ));
                    }                     // if

                    if (oCell.InnerText.Trim() == "Previous tax years")
                    {
                        break;
                    }

                    MatchCollection match = Regex.Matches(oCell.InnerText.Trim(), @"^Current tax year (\d\d)(\d\d)-(\d\d)$");

                    if (match.Count != 1)
                    {
                        throw new HarvesterException(string.Format(
                                                         "Failed to fetch RTI tax years: incorrect content in row {0}.",
                                                         nRowNum
                                                         ));
                    }                     // if

                    GroupCollection grp = match[0].Groups;
                    if (grp.Count != 4)
                    {
                        throw new HarvesterException(string.Format(
                                                         "Failed to fetch RTI tax years: unexpected content in row {0}.",
                                                         nRowNum
                                                         ));
                    }                     // if

                    nFirstYear = Convert.ToInt32(grp[1].Value) * 100 + Convert.ToInt32(grp[2].Value);
                    nLastYear  = Convert.ToInt32(grp[1].Value) * 100 + Convert.ToInt32(grp[3].Value);

                    Info("Current tax year: {0} - {1}", nFirstYear, nLastYear);

                    continue;
                }                 // if first row

                string sFirstCell = oCells.Count > 0 ? oCells[0].InnerText.Trim() : string.Empty;

                if (oCells.Count != 3)
                {
                    if ((oCells.Count == 1) && (sFirstCell == "Previous tax years"))
                    {
                        break;
                    }

                    throw new HarvesterException(string.Format(
                                                     "Failed to fetch RTI tax years: unexpected number of cells in row {0}.",
                                                     nRowNum
                                                     ));
                }                 // if

                if (sFirstCell == "Total")
                {
                    break;
                }

                try {
                    data.Add(new RtiTaxYearRowData(sFirstCell, oCells[1].InnerText.Trim(), oCells[2].InnerText.Trim()));
                } catch (Exception e) {
                    throw new HarvesterException(
                              string.Format(
                                  "Failed to fetch RTI tax years: unexpected format in row {0}.",
                                  nRowNum
                                  ),
                              e
                              );
                }         // try
            }             // for each row

            int nCurYear = nFirstYear;

            var rtys = new RtiTaxYearSeeds();

            foreach (RtiTaxYearRowData rd in data.ToArray().Reverse())
            {
                rtys.Months.Add(new RtiTaxMonthSeed {
                    DateStart  = new DateTime(nCurYear, rd.MonthStart, rd.DayStart),
                    DateEnd    = new DateTime(nCurYear, rd.MonthEnd, rd.DayEnd),
                    AmountPaid = new Coin(rd.AmountPaid, "GBP"),
                    AmountDue  = new Coin(rd.AmountDue, "GBP")
                });

                if (rd.MonthStart == 12)
                {
                    nCurYear = nLastYear;
                }
            }             // for each

            Hopper.Add(smd, rtys);

            Debug("Fetching RTI Tax Years complete.");
        } // FetchRtiTaxYears
Beispiel #5
0
        }         // Load

        /// <summary>
        /// Fetches one file from the Field and stores it in the Hopper as byte[].
        /// Adds HarvesterError to the Hopper in case of error.
        /// </summary>
        /// <param name="task">HTTP request result.</param>
        private void GetFile(Task <HttpResponseMessage> task)
        {
            SheafMetaData fi;

            HttpResponseMessage response = task.Result;

            var sUrl = response.RequestMessage.RequestUri.PathAndQuery;

            lock (this.vatReturnsMetaDataLock) {
                fi = this.m_oVatReturnsMetaData[sUrl];
            }             // lock

            Info("GetFile: retrieving {0}", response.RequestMessage);

            if (!response.IsSuccessStatusCode)
            {
                string sErrMsg = response.StatusCode.ToString() + ": " + response.ReasonPhrase;

                Error("Not saving because of error. Status code {0}", sErrMsg);
                Hopper.Add(fi, response);

                lock (ErrorsToEmail) {
                    ErrorsToEmail[sUrl] = sErrMsg;
                }                 // lock

                return;
            }             // if

            Stream oInputStream = response.Content.ReadAsStreamAsync().Result;

            var oOutput = new MemoryStream();

            var outputFile = new BinaryWriter(oOutput);

            const int nBufSize = 8192;
            var       buf      = new byte[nBufSize];

            int nRead = oInputStream.Read(buf, 0, nBufSize);

            while (nRead > 0)
            {
                outputFile.Write(buf, 0, nRead);

                nRead = oInputStream.Read(buf, 0, nBufSize);
            }             // while

            outputFile.Close();

            byte[] oFile = oOutput.ToArray();

            Hopper.Add(fi, oFile);

            if (fi.Thrasher != null)
            {
                ISeeds x = fi.Thrasher.Run(fi, oFile);

                if (x == null)
                {
                    var vrs = (VatReturnSeeds)fi.Thrasher.Seeds;

                    lock (ErrorsToEmail) {
                        ErrorsToEmail[sUrl] = vrs.FatalError;
                    }             // lock
                }                 // if

                Hopper.Add(fi, x);
            }     // if
        }         // GetFile
Beispiel #6
0
        }         // Run

        /// <summary>
        /// Main harvest function. Logs in to hmrc.gov.uk and fetches data.
        /// </summary>
        /// <param name="bValidateCredentialsOnly">true to validate credentials only,
        /// false to login and download data.</param>
        /// <param name="nCustomerMarketplaceID">Customer marketplace id for fetching back-door data.</param>
        public virtual void Run(bool bValidateCredentialsOnly, int nCustomerMarketplaceID)
        {
            Debug(
                "Harvester run mode: {0}.",
                bValidateCredentialsOnly ? "validate credentials only" : "login and download data"
                );

            try {
                if (!bValidateCredentialsOnly)
                {
                    Hopper oBackdoorData = FetchBackdoorData(nCustomerMarketplaceID, this);

                    if (oBackdoorData != null)
                    {
                        Hopper.FetchBackdoorData(oBackdoorData);
                        Debug("Harvester running is complete.");
                        return;
                    }                     // if

                    if (Password == VendorInfo.TopSecret)
                    {
                        if (0 < ObjectFactory.GetInstance <IUsersRepository>().ExternalUserCount(UserName))
                        {
                            Debug(
                                "This HMRC account for customer {0} was created from uploaded files, nothing to retrieve.",
                                UserName
                                );
                            return;
                        }         // if HMRC login is customer's email
                    }             // if the password is...
                }                 // if do retrieve data
            } catch (Exception e) {
                throw new ApiException(e.Message, e);
            }             // try

            try {
                if (!IsLoggedIn)
                {
                    Login(GetLoginRequestDetails(GetPage("")));
                }
            } catch (InvalidCredentialsException) {
                throw;
            } catch (Exception e) {
                throw new ApiException(e.Message, e);
            }             // try

            if (!IsLoggedIn)
            {
                throw new ApiException("Not logged in.");
            }

            if (bValidateCredentialsOnly)
            {
                Debug("Harvester running is complete.");
                return;
            }             // if

            try {
                string sUserVatID = GetUserVatID();

                Debug("Harvester has validated login credentials.");

                Debug("Harvester starts downloading data.");

                VatReturns(sUserVatID);
                FetchRtiTaxYears();

                Debug("Harvester running is complete.");
            } catch (Exception e) {
                Alert(e, "Exception caught during retrieving HMRC data.");
                throw new ApiException(e.Message, e);
            }     // try
        }         // Run