Example #1
0
        private static void AddNavigationForEachLedger(XmlNode AMenuNode, ALedgerTable AAvailableLedgers, bool ADontUseDefaultLedger)
        {
            XmlNode      childNode = AMenuNode.FirstChild;
            int          PotentialCurrentLedger;
            ALedgerRow   ProcessedLedger;
            XmlAttribute enabledAttribute;
            bool         LedgersAvailableToUserCreatedInThisIteration = false;

            //Iterate through all children nodes of the node
            while (childNode != null)
            {
                if (TXMLParser.GetAttribute(childNode, "DependsOnLedger").ToLower() == "true")
                {
                    // If there is more than one Ledger in the system, show a 'Select Ledger' Collapsible Panel with a Task (=LinkLabel)
                    // for each Ledger.
                    if (AAvailableLedgers.Rows.Count > 1)
                    {
                        LedgersAvailableToUserCreatedInThisIteration = false;
                        AAvailableLedgers.DefaultView.Sort           = ALedgerTable.GetLedgerNumberDBName() + " ASC";

                        FMultiLedgerSite = true;

                        // Create 'Select Ledger' Node
                        XmlAttribute LabelAttributeLedger = childNode.OwnerDocument.CreateAttribute("Label");
                        XmlElement   SelLedgerElmnt       = childNode.OwnerDocument.CreateElement("SelectLedger");
                        XmlNode      SelectLedgerNode     = childNode.AppendChild(SelLedgerElmnt);
                        SelectLedgerNode.Attributes.Append(LabelAttributeLedger);
                        SelectLedgerNode.Attributes["Label"].Value = Catalog.GetString("Select Ledger");

                        // Create 1..n 'Ledger xyz' Nodes
                        foreach (DataRowView Drv in AAvailableLedgers.DefaultView)
                        {
                            ProcessedLedger = (ALedgerRow)Drv.Row;

                            XmlElement   SpecificLedgerElmnt          = childNode.OwnerDocument.CreateElement("Ledger" + ProcessedLedger.LedgerNumber);
                            XmlNode      SpecificLedgerNode           = SelectLedgerNode.AppendChild(SpecificLedgerElmnt);
                            XmlAttribute LabelAttributeSpecificLedger = childNode.OwnerDocument.CreateAttribute("Label");
                            SpecificLedgerNode.Attributes.Append(LabelAttributeSpecificLedger);
                            XmlAttribute ledgerNumberAttribute = childNode.OwnerDocument.CreateAttribute("LedgerNumber");
                            ledgerNumberAttribute.Value = ProcessedLedger.LedgerNumber.ToString();
                            SpecificLedgerNode.Attributes.Append(ledgerNumberAttribute);
                            XmlAttribute ledgerNameAttribute = childNode.OwnerDocument.CreateAttribute("LedgerName");
                            ledgerNameAttribute.Value = ProcessedLedger.LedgerName;
                            SpecificLedgerNode.Attributes.Append(ledgerNameAttribute);

                            if (ProcessedLedger.LedgerName != String.Empty)
                            {
                                SpecificLedgerNode.Attributes["Label"].Value = String.Format(Catalog.GetString(
                                                                                                 "Ledger {0} (#{1})"), ProcessedLedger.LedgerName, ProcessedLedger.LedgerNumber);
                            }
                            else
                            {
                                SpecificLedgerNode.Attributes["Label"].Value = String.Format(Catalog.GetString(
                                                                                                 "Ledger #{0}"), ProcessedLedger.LedgerNumber);
                            }

                            // Check access permission for Ledger
                            if (!HasAccessPermission(SpecificLedgerNode, UserInfo.GUserInfo.UserID, true))
                            {
                                enabledAttribute       = childNode.OwnerDocument.CreateAttribute("Enabled");
                                enabledAttribute.Value = "false";
                                SpecificLedgerNode.Attributes.Append(enabledAttribute);
                            }
                            else
                            {
                                if (FLedgersAvailableToUser == null)
                                {
                                    // (Re-)Calculate which Ledgers the user has access to
                                    FLedgersAvailableToUser = new List <string>();
                                    LedgersAvailableToUserCreatedInThisIteration = true;
                                }

                                if (LedgersAvailableToUserCreatedInThisIteration)
                                {
                                    // Add Ledger to the List of Ledgers that are available to the user
                                    if (!FLedgersAvailableToUser.Contains(FormatLedgerNumberForModuleAccess(ProcessedLedger.LedgerNumber)))
                                    {
                                        FLedgersAvailableToUser.Add(FormatLedgerNumberForModuleAccess(ProcessedLedger.LedgerNumber));
                                    }
                                }
                            }
                        }

                        if ((LedgersAvailableToUserCreatedInThisIteration) ||
                            (FLedgersAvailableToUser == null))
                        {
                            if (!ADontUseDefaultLedger)
                            {
                                // Set the 'Current Ledger' to the users' Default Ledger, or if he/she hasn't got one, to the first Ledger of the Site.
                                PotentialCurrentLedger = TUserDefaults.GetInt32Default(TUserDefaults.FINANCE_DEFAULT_LEDGERNUMBER,
                                                                                       ((ALedgerRow)AAvailableLedgers.DefaultView[0].Row).LedgerNumber);

                                if ((FLedgersAvailableToUser != null) &&
                                    (FLedgersAvailableToUser.Contains(FormatLedgerNumberForModuleAccess(PotentialCurrentLedger))))
                                {
                                    FCurrentLedger = PotentialCurrentLedger;
                                }
                                else
                                {
                                    if (FLedgersAvailableToUser != null)
                                    {
                                        FCurrentLedger = Convert.ToInt32(FLedgersAvailableToUser[0].Substring(6)); // Skip "LEDGER"
                                    }
                                    else                                                                           // = no Ledgers available to the user at all!
                                    {
                                        FCurrentLedger = LEDGERNUMBER_NO_ACCESS_TO_ANY_LEDGER;
                                    }
                                }
                            }
                        }
                    }
                    else if (AAvailableLedgers.Rows.Count == 1)
                    {
                        // Dynamically add Attribute 'SkipThisLevel' to the next child, which would be the child for the Collapsible Panel,
                        // which we don't need/want for a 'Single Ledger' Site!
                        XmlAttribute LabelSkipCollapsibleLevel = childNode.OwnerDocument.CreateAttribute("SkipThisLevel");
                        childNode.ChildNodes[0].Attributes.Append(LabelSkipCollapsibleLevel);
                        childNode.ChildNodes[0].Attributes["SkipThisLevel"].Value = "true";

                        // Check access permission for Ledger
                        if (UserInfo.GUserInfo.IsInModule(FormatLedgerNumberForModuleAccess(AAvailableLedgers[0].LedgerNumber)))
                        {
                            // Set the 'Current Ledger' to the only Ledger of the Site.
                            FCurrentLedger = AAvailableLedgers[0].LedgerNumber;
                        }
                        else   // = no Ledgers available to the user at all!
                        {
                            FCurrentLedger = LEDGERNUMBER_NO_ACCESS_TO_ANY_LEDGER;
                        }
                    }
                    else   // = no Ledgers available to the user at all!
                    {
                        FCurrentLedger = LEDGERNUMBER_NO_ACCESS_TO_ANY_LEDGER;
                    }

                    childNode = childNode.NextSibling;
                }
                else
                {
                    // Recurse into deeper levels!
                    AddNavigationForEachLedger(childNode, AAvailableLedgers, ADontUseDefaultLedger);

                    childNode = childNode.NextSibling;
                }
            }
        }
Example #2
0
        /// <summary>
        /// generate a person record and update the associated family partner
        /// </summary>
        /// <param name="ACurrentNode"></param>
        /// <param name="AFamilyRow"></param>
        /// <param name="APrefix"></param>
        /// <param name="AMainDS"></param>
        public static void GeneratePersonRecord(XmlNode ACurrentNode, PFamilyRow AFamilyRow, string APrefix, PartnerEditTDS AMainDS)
        {
            PPersonRow  PersonRow  = AMainDS.PPerson.NewRowTyped();
            PPartnerRow PartnerRow = AMainDS.PPartner.NewRowTyped();

            if (NumberOfPartnerKeysReserved == 0)
            {
                NumberOfPartnerKeysReserved = 100;
                NextPartnerKey = TNewPartnerKey.ReservePartnerKeys(-1, ref NumberOfPartnerKeysReserved);
            }

            long PartnerKey = NextPartnerKey;

            NextPartnerKey++;
            NumberOfPartnerKeysReserved--;

            PartnerRow.PartnerKey = PartnerKey;
            PersonRow.PartnerKey  = PartnerRow.PartnerKey;
            PersonRow.FamilyKey   = AFamilyRow.PartnerKey;

            // create family id: count existing family members
            DataView FamilyView = new DataView(AMainDS.PPerson);

            FamilyView.RowFilter = PPersonTable.GetFamilyKeyDBName() + " = " + AFamilyRow.PartnerKey.ToString();
            FamilyView.Sort      = PPersonTable.GetFamilyIdDBName();

            PersonRow.FamilyId = FamilyView.Count;

            PersonRow.FirstName   = TXMLParser.GetAttribute(ACurrentNode, APrefix + "FirstName");
            PersonRow.MiddleName1 = TXMLParser.GetAttribute(ACurrentNode, APrefix + "MiddleName");
            PersonRow.FamilyName  = AFamilyRow.FamilyName;

            if (FamilyView.Count == 1)
            {
                PartnerRow.PreviousName = TXMLParser.GetAttribute(ACurrentNode, APrefix + "FamilyName");
            }

            PersonRow.Title = TXMLParser.GetAttribute(ACurrentNode, APrefix + "Title");

            PartnerRow.PartnerShortName = Calculations.DeterminePartnerShortName(
                PersonRow.FamilyName,
                PersonRow.Title,
                PersonRow.FirstName);
            PartnerRow.PartnerClass = MPartnerConstants.PARTNERCLASS_PERSON;
            PartnerRow.StatusCode   = MPartnerConstants.PARTNERSTATUS_ACTIVE;

            PersonRow.DateOfBirth = Convert.ToDateTime(TXMLParser.GetAttribute(ACurrentNode, APrefix + "DateOfBirth"));

            string gender = TXMLParser.GetAttribute(ACurrentNode, APrefix + "Gender");

            if ((APrefix == "Male") || (gender == "MALE"))
            {
                PersonRow.Gender             = MPartnerConstants.GENDER_MALE;
                PartnerRow.AddresseeTypeCode = MPartnerConstants.ADDRESSEETYPE_MALE;
            }
            else if ((APrefix == "Female") || (gender == "FEMALE"))
            {
                PersonRow.Gender             = MPartnerConstants.GENDER_FEMALE;
                PartnerRow.AddresseeTypeCode = MPartnerConstants.ADDRESSEETYPE_FEMALE;
            }

            PPartnerRow FamilyPartnerRow = (PPartnerRow)AMainDS.PPartner.Rows.Find(AFamilyRow.PartnerKey);

            if (FamilyView.Count == 0)
            {
                FamilyPartnerRow.AddresseeTypeCode = PartnerRow.AddresseeTypeCode;
            }
            else if (FamilyView.Count == 1)
            {
                // this is a couple
                PersonRow.MaritalStatus = MPartnerConstants.MARITALSTATUS_MARRIED;

                // find first person record as well
                PPersonRow Husband = (PPersonRow)FamilyView[0].Row;
                Husband.MaritalStatus = MPartnerConstants.MARITALSTATUS_MARRIED;

                AFamilyRow.MaritalStatus = MPartnerConstants.MARITALSTATUS_MARRIED;

                AFamilyRow.FirstName = Husband.FirstName + " and " + PersonRow.FirstName;
                AFamilyRow.Title     = Husband.Title + " and " + PersonRow.Title;

                // update family shortname
                FamilyPartnerRow.AddresseeTypeCode = MPartnerConstants.ADDRESSEETYPE_COUPLE;
                FamilyPartnerRow.PartnerShortName  = Calculations.DeterminePartnerShortName(
                    AFamilyRow.FamilyName,
                    AFamilyRow.Title,
                    AFamilyRow.FirstName);
            }
            else if (FamilyView.Count > 1)
            {
                FamilyPartnerRow.AddresseeTypeCode = MPartnerConstants.ADDRESSEETYPE_FAMILY;
            }

            AMainDS.PPerson.Rows.Add(PersonRow);
            AMainDS.PPartner.Rows.Add(PartnerRow);
        }
Example #3
0
        private static GiftBatchTDS CreateGiftBatches(SortedList <DateTime, List <XmlNode> > AGiftsPerDate, int APeriodNumber)
        {
            GiftBatchTDS MainDS      = new GiftBatchTDS();
            ALedgerTable LedgerTable = null;

            TDBTransaction ReadTransaction = null;

            DBAccess.GDBAccessObj.BeginAutoReadTransaction(IsolationLevel.ReadCommitted, ref ReadTransaction,
                                                           delegate
            {
                // get a list of potential donors (all class FAMILY)
                string sqlGetFamilyPartnerKeys = "SELECT p_partner_key_n FROM PUB_p_family";
                DataTable FamilyKeys           = DBAccess.GDBAccessObj.SelectDT(sqlGetFamilyPartnerKeys,
                                                                                "keys",
                                                                                ReadTransaction);

                // get a list of workers (all class FAMILY, with special type WORKER)
                string sqlGetWorkerPartnerKeys =
                    "SELECT PUB_p_family.p_partner_key_n FROM PUB_p_family, PUB_p_partner_type WHERE PUB_p_partner_type.p_partner_key_n = PUB_p_family.p_partner_key_n AND p_type_code_c = 'WORKER'";
                DataTable WorkerKeys = DBAccess.GDBAccessObj.SelectDT(sqlGetWorkerPartnerKeys, "keys", ReadTransaction);

                // get a list of fields (all class UNIT, with unit type F)
                string sqlGetFieldPartnerKeys =
                    String.Format(
                        "SELECT U.p_partner_key_n FROM PUB_p_unit U WHERE u_unit_type_code_c = 'F' AND EXISTS (SELECT * FROM PUB_a_valid_ledger_number V WHERE V.a_ledger_number_i = {0} AND V.p_partner_key_n = U.p_partner_key_n)",
                        FLedgerNumber);
                DataTable FieldKeys = DBAccess.GDBAccessObj.SelectDT(sqlGetFieldPartnerKeys, "keys", ReadTransaction);

                // get a list of key ministries (all class UNIT, with unit type KEY-MIN), and their field ledger number and cost centre code
                string sqlGetKeyMinPartnerKeys =
                    "SELECT u.p_partner_key_n, us.um_parent_unit_key_n, vl.a_cost_centre_code_c " +
                    "FROM PUB_p_unit u, PUB_um_unit_structure us, PUB_a_valid_ledger_number vl " +
                    "WHERE u.u_unit_type_code_c = 'KEY-MIN' " +
                    "AND us.um_child_unit_key_n = u.p_partner_key_n " +
                    "AND vl.p_partner_key_n = us.um_parent_unit_key_n " +
                    "AND vl.a_ledger_number_i = " + FLedgerNumber.ToString();
                DataTable KeyMinistries = DBAccess.GDBAccessObj.SelectDT(sqlGetKeyMinPartnerKeys, "keys", ReadTransaction);

                LedgerTable = ALedgerAccess.LoadByPrimaryKey(FLedgerNumber, ReadTransaction);

                AAccountingPeriodRow AccountingPeriodRow = AAccountingPeriodAccess.LoadByPrimaryKey(FLedgerNumber,
                                                                                                    APeriodNumber,
                                                                                                    ReadTransaction)[0];

                // create a gift batch for each day.
                // TODO: could create one batch per month, if there are not so many gifts (less than 100 per month)
                foreach (DateTime GlEffectiveDate in AGiftsPerDate.Keys)
                {
                    if ((GlEffectiveDate.CompareTo(AccountingPeriodRow.PeriodStartDate) < 0) ||
                        (GlEffectiveDate.CompareTo(AccountingPeriodRow.PeriodEndDate) > 0))
                    {
                        // only create gifts in that period
                        continue;
                    }

                    AGiftBatchRow giftBatch = TGiftBatchFunctions.CreateANewGiftBatchRow(ref MainDS,
                                                                                         ref ReadTransaction,
                                                                                         ref LedgerTable,
                                                                                         FLedgerNumber,
                                                                                         GlEffectiveDate);

                    TLogging.LogAtLevel(1, "create gift batch for " + GlEffectiveDate.ToShortDateString());
                    giftBatch.BatchDescription = "Benerator Batch for " + GlEffectiveDate.ToShortDateString();
                    giftBatch.BatchTotal       = 0.0m;

                    foreach (XmlNode RecordNode in AGiftsPerDate[GlEffectiveDate])
                    {
                        AGiftRow gift              = MainDS.AGift.NewRowTyped();
                        gift.LedgerNumber          = giftBatch.LedgerNumber;
                        gift.BatchNumber           = giftBatch.BatchNumber;
                        gift.GiftTransactionNumber = giftBatch.LastGiftNumber + 1;
                        gift.DateEntered           = GlEffectiveDate;

                        // set donorKey
                        int donorID   = Convert.ToInt32(TXMLParser.GetAttribute(RecordNode, "donor")) % FamilyKeys.Rows.Count;
                        gift.DonorKey = Convert.ToInt64(FamilyKeys.Rows[donorID].ItemArray[0]);

                        // calculate gift detail information
                        int countDetails = Convert.ToInt32(TXMLParser.GetAttribute(RecordNode, "splitgift"));

                        for (int counter = 1; counter <= countDetails; counter++)
                        {
                            AGiftDetailRow giftDetail        = MainDS.AGiftDetail.NewRowTyped();
                            giftDetail.LedgerNumber          = gift.LedgerNumber;
                            giftDetail.BatchNumber           = gift.BatchNumber;
                            giftDetail.GiftTransactionNumber = gift.GiftTransactionNumber;

                            giftDetail.MotivationGroupCode   = "GIFT";
                            giftDetail.GiftTransactionAmount = Convert.ToDecimal(TXMLParser.GetAttribute(RecordNode, "amount_" + counter.ToString()));
                            giftDetail.GiftAmount            = giftDetail.GiftTransactionAmount;
                            giftBatch.BatchTotal            += giftDetail.GiftAmount;

                            string motivation = TXMLParser.GetAttribute(RecordNode, "motivation_" + counter.ToString());

                            if (motivation == "SUPPORT")
                            {
                                if (WorkerKeys.Rows.Count == 0)
                                {
                                    continue;
                                }

                                giftDetail.MotivationDetailCode = "SUPPORT";
                                int recipientID =
                                    Convert.ToInt32(TXMLParser.GetAttribute(RecordNode, "recipient_support_" +
                                                                            counter.ToString())) % WorkerKeys.Rows.Count;
                                giftDetail.RecipientKey = Convert.ToInt64(WorkerKeys.Rows[recipientID].ItemArray[0]);

                                giftDetail.RecipientLedgerNumber = TGiftTransactionWebConnector.GetRecipientFundNumber(giftDetail.RecipientKey,
                                                                                                                       giftBatch.GlEffectiveDate);

                                // ignore this gift detail, if there is no valid commitment period for the worker
                                if (giftDetail.RecipientLedgerNumber == 0)
                                {
                                    continue;
                                }
                            }
                            else if (motivation == "FIELD")
                            {
                                if (FieldKeys.Rows.Count == 0)
                                {
                                    continue;
                                }

                                giftDetail.MotivationDetailCode = "FIELD";
                                int recipientID =
                                    Convert.ToInt32(TXMLParser.GetAttribute(RecordNode, "recipient_field_" +
                                                                            counter.ToString())) % FieldKeys.Rows.Count;
                                giftDetail.RecipientKey          = Convert.ToInt64(FieldKeys.Rows[recipientID].ItemArray[0]);
                                giftDetail.RecipientLedgerNumber = giftDetail.RecipientKey;
                                giftDetail.CostCentreCode        = (giftDetail.RecipientKey / 10000).ToString("0000");
                            }
                            else if (motivation == "KEYMIN")
                            {
                                if (KeyMinistries.Rows.Count == 0)
                                {
                                    continue;
                                }

                                giftDetail.MotivationDetailCode = "KEYMIN";
                                int recipientID =
                                    Convert.ToInt32(TXMLParser.GetAttribute(RecordNode, "recipient_keymin_" +
                                                                            counter.ToString())) % KeyMinistries.Rows.Count;
                                giftDetail.RecipientKey = Convert.ToInt64(KeyMinistries.Rows[recipientID].ItemArray[0]);

                                giftDetail.RecipientLedgerNumber = Convert.ToInt64(KeyMinistries.Rows[recipientID].ItemArray[1]);
                                // TTransactionWebConnector.GetRecipientFundNumber(giftDetail.RecipientKey);
                                giftDetail.CostCentreCode = KeyMinistries.Rows[recipientID].ItemArray[2].ToString();
                                // TTransactionWebConnector.IdentifyPartnerCostCentre(FLedgerNumber, giftDetail.RecipientLedgerNumber);
                            }

                            giftDetail.DetailNumber = gift.LastDetailNumber + 1;
                            MainDS.AGiftDetail.Rows.Add(giftDetail);
                            gift.LastDetailNumber = giftDetail.DetailNumber;
                        }

                        if (gift.LastDetailNumber > 0)
                        {
                            MainDS.AGift.Rows.Add(gift);
                            giftBatch.LastGiftNumber = gift.GiftTransactionNumber;
                        }

                        if (giftBatch.LastGiftNumber >= MaxGiftsPerBatch)
                        {
                            break;
                        }
                    }

                    if (TLogging.DebugLevel > 0)
                    {
                        TLogging.Log(
                            GlEffectiveDate.ToShortDateString() + " " + giftBatch.LastGiftNumber.ToString());
                    }
                }
            });

            // need to save the last gift batch number in a_ledger
            if (LedgerTable != null)
            {
                TDBTransaction WriteTransaction = null;
                bool           SubmissionOk     = false;
                DBAccess.GDBAccessObj.BeginAutoTransaction(IsolationLevel.Serializable, ref WriteTransaction, ref SubmissionOk,
                                                           delegate
                {
                    ALedgerAccess.SubmitChanges(LedgerTable, WriteTransaction);
                    SubmissionOk = true;
                });

                if (!SubmissionOk)
                {
                    TLogging.Log("An Exception occured during the creation of Gift Batches" + Environment.NewLine);
                }
            }

            return(MainDS);
        }
Example #4
0
        static void Main(string[] args)
        {
            string BugIDs = String.Empty;

            new TAppSettingsManager(false);

            if ((!TAppSettingsManager.HasValue("sf-username")) ||
                (!TAppSettingsManager.HasValue("sf-pwd")) ||
                (!TAppSettingsManager.HasValue("bugs-csv-file")) ||
                (!TAppSettingsManager.HasValue("version-fixed-in-earlier-than"))
                )
            {
                Console.WriteLine(
                    "call: MantisCloseResolvedBugs.exe -sf-username:pokorra -sf-pwd:xyz -bugs-csv-file:resolvedbugs.csv -version-fixed-in-earlier-than:\"Alpha 0.2.20\"");
                return;
            }

            // Process CSV file: turn it into an XmlDocument for ease of use
            string      bugsCSVFile = TAppSettingsManager.GetValue("bugs-csv-file");
            XmlDocument bugsXmlDoc  = TCsv2Xml.ParseCSV2Xml(bugsCSVFile, ",");

            XmlNode RecordNode = bugsXmlDoc.FirstChild.NextSibling.FirstChild;

            // Extract all Bug ID's from the XmlDocument
            while (RecordNode != null)
            {
                BugIDs += TXMLParser.GetAttribute(RecordNode, "Id") + ",";

                RecordNode = RecordNode.NextSibling;
            }

            BugIDs = BugIDs.Substring(0, BugIDs.Length - 1);   // remove last comma ','


            // Start the processing in the web browser
            string loginURL  = TAppSettingsManager.GetValue("login-url", "http://sourceforge.net/account/login.php");
            string mantisURL = TAppSettingsManager.GetValue("mantis-url", "https://sourceforge.net/apps/mantisbt/openpetraorg/");

            IWebDriver driver = new FirefoxDriver();

            try
            {
                LoginToSourceforge(driver, loginURL, TAppSettingsManager.GetValue("sf-username"), TAppSettingsManager.GetValue("sf-pwd"));

                string[] bugids = BugIDs.Split(new char[] { ',' });

                // Process each Bug
                foreach (string bugid in bugids)
                {
                    SetResolvedBugToClosed(
                        driver,
                        mantisURL + "bug_update_page.php?bug_id=" + bugid,
                        TAppSettingsManager.GetValue("version-fixed-in-earlier-than"));
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e.ToString());

                StreamWriter sw = new StreamWriter("error.html");
                sw.WriteLine(driver.PageSource.Replace("a0:", "").Replace(":a0", ""));
                sw.Close();
                Console.WriteLine("please check " + Path.GetFullPath("error.html"));
            }
            finally
            {
                driver.Quit();
            }
        }
        /// <summary>
        /// this loads the contents of the yaml file.
        /// it supports inheritance, base elements are overwritten
        /// </summary>
        /// <param name="AYamlFilename"></param>
        /// <param name="ASelectedLocalisation"></param>
        /// <param name="AAlreadyGotLocalisation"></param>
        /// <param name="depth">0 is the last file that is derived from all base files</param>
        /// <returns></returns>
        protected Boolean LoadRecursively(string AYamlFilename,
                                          string ASelectedLocalisation,
                                          bool AAlreadyGotLocalisation,
                                          Int32 depth)
        {
            // check if file exists for localisation
            string localisedFile = null;

            if ((ASelectedLocalisation != null) && !AAlreadyGotLocalisation)
            {
                localisedFile = Path.GetDirectoryName(AYamlFilename) + Path.DirectorySeparatorChar +
                                Path.GetFileNameWithoutExtension(AYamlFilename) + "." + ASelectedLocalisation + ".yaml";

                // first check if there is such a file
                if (!File.Exists(localisedFile))
                {
                    localisedFile = null;
                }
            }

            if (localisedFile == null)
            {
                localisedFile = AYamlFilename;
            }

            string baseyaml;

            if (!TYml2Xml.ReadHeader(localisedFile, out baseyaml))
            {
                throw new Exception("This is not an OpenPetra Yaml file");
            }

            if ((baseyaml.Length > 0) && baseyaml.EndsWith(".yaml"))
            {
                LoadRecursively(System.IO.Path.GetDirectoryName(AYamlFilename) +
                                System.IO.Path.DirectorySeparatorChar +
                                baseyaml,
                                ASelectedLocalisation,
                                localisedFile != AYamlFilename,
                                depth - 1);
            }

            if ((depth == 0) && (FCodeStorage.FXmlNodes != null))
            {
                // apply the tag, so that we know which things have been changed by the last yml file
                TYml2Xml.Tag((XmlNode)FCodeStorage.FXmlNodes[TParseYAMLFormsDefinition.ROOTNODEYML]);
            }

            XmlDocument newDoc = null;

            localisedFile = Path.GetFullPath(localisedFile);

            if (CachedYamlFiles.ContainsKey(localisedFile))
            {
                newDoc = CachedYamlFiles[localisedFile];
            }
            else
            {
                Console.WriteLine("Loading " + localisedFile + "...");
                TYml2Xml yml2xml = new TYml2Xml(localisedFile);
                newDoc = yml2xml.ParseYML2XML();
                CachedYamlFiles.Add(localisedFile, newDoc);
            }

            TYml2Xml.Merge(ref FCodeStorage.FXmlDocument, newDoc, depth);

            if (TLogging.DebugLevel > 0)
            {
                // for debugging:
                FCodeStorage.FXmlDocument.Save(localisedFile + ".xml");
            }

            FCodeStorage.FXmlNodes = TYml2Xml.ReferenceNodes(FCodeStorage.FXmlDocument);
            FCodeStorage.FRootNode = (XmlNode)FCodeStorage.FXmlNodes[TParseYAMLFormsDefinition.ROOTNODEYML];

            if (baseyaml.Length == 0)
            {
                if (FCodeStorage.FXmlNodes[TYml2Xml.ROOTNODEINTERNAL] == null)
                {
                    throw new Exception("TParseYAMLFormsDefinition.LoadRecursively: YML Document could not be properly parsed");
                }

                if (TXMLParser.GetAttribute((XmlNode)FCodeStorage.FXmlNodes[TParseYAMLFormsDefinition.ROOTNODEYML], "BaseYaml").Length > 0)
                {
                    throw new Exception("The BaseYaml attribute must come first!");
                }
            }

            if (depth == 0)
            {
                FCodeStorage.FFilename = AYamlFilename;
                LoadData(FCodeStorage.FXmlNodes);
            }

            return(true);
        }
Example #6
0
        /// <summary>
        /// generate the partners from a text file that was generated with Benerator
        /// </summary>
        /// <param name="AInputBeneratorFile"></param>
        public static void GenerateFamilyPartners(string AInputBeneratorFile)
        {
            // get a list of banks (all class BANK)
            string    sqlGetBankPartnerKeys = "SELECT p_partner_key_n FROM PUB_p_bank";
            DataTable BankKeys = DBAccess.GDBAccessObj.SelectDT(sqlGetBankPartnerKeys, "keys", null);

            PartnerEditTDS MainDS = new PartnerEditTDS();

            // AlanP: May 2016 - We may no longer need the UTF8 because the method now automatically discovers the encoding even with no BOM
            XmlDocument doc = TCsv2Xml.ParseCSVFile2Xml(AInputBeneratorFile, ",", Encoding.UTF8);

            XmlNode RecordNode = doc.FirstChild.NextSibling.FirstChild;

            while (RecordNode != null)
            {
                string familySituation = TXMLParser.GetAttribute(RecordNode, "familySituation");

                PFamilyRow  familyRecord     = null;
                PPartnerRow FamilyPartnerRow = null;

                if (familySituation == "singleMan")
                {
                    familyRecord = SampleDataWorkers.GenerateFamilyRecord(RecordNode, "Male", MainDS);
                    SampleDataWorkers.GeneratePersonRecord(RecordNode, familyRecord, "Male", MainDS);
                }
                else if (familySituation == "singleWoman")
                {
                    familyRecord = SampleDataWorkers.GenerateFamilyRecord(RecordNode, "Female", MainDS);
                    SampleDataWorkers.GeneratePersonRecord(RecordNode, familyRecord, "Female", MainDS);
                }
                else if (familySituation == "family")
                {
                    familyRecord = SampleDataWorkers.GenerateFamilyRecord(RecordNode, "Male", MainDS);
                    SampleDataWorkers.GeneratePersonRecord(RecordNode, familyRecord, "Male", MainDS);
                    SampleDataWorkers.GeneratePersonRecord(RecordNode, familyRecord, "Female", MainDS);

                    int NumberOfChildren = Convert.ToInt32(TXMLParser.GetAttribute(RecordNode, "numberOfChildren"));

                    if (NumberOfChildren > 0)
                    {
                        FamilyPartnerRow = (PPartnerRow)MainDS.PPartner.Rows.Find(familyRecord.PartnerKey);
                        FamilyPartnerRow.AddresseeTypeCode = MPartnerConstants.ADDRESSEETYPE_FAMILY;
                    }
                }

                FamilyPartnerRow = (PPartnerRow)MainDS.PPartner.Rows.Find(familyRecord.PartnerKey);
                FamilyPartnerRow.ReceiptEachGift        = false;
                FamilyPartnerRow.ReceiptLetterFrequency = "Annual";

                SampleDataWorkers.GenerateAddressForFamily(RecordNode, familyRecord, MainDS);

                SampleDataWorkers.GenerateBankDetails(RecordNode, familyRecord, MainDS, BankKeys);

                if (MainDS.PFamily.Rows.Count % 100 == 0)
                {
                    TLogging.Log("created donor " + MainDS.PFamily.Rows.Count.ToString() + " " + familyRecord.FamilyName);
                }

                RecordNode = RecordNode.NextSibling;
            }

            // we do not save person records for normal family partners
            MainDS.PPerson.Clear();

            // need to clear all partner records of the PERSON partners as well
            DataView PersonPartners = new DataView(MainDS.PPartner);

            PersonPartners.RowFilter =
                string.Format("{0} = '{1}'",
                              PPartnerTable.GetPartnerClassDBName(),
                              MPartnerConstants.PARTNERCLASS_PERSON);

            DataView PartnerLocations = new DataView(MainDS.PPartnerLocation);

            foreach (DataRowView rv in PersonPartners)
            {
                PPartnerRow partnerRow = (PPartnerRow)rv.Row;

                PartnerLocations.RowFilter =
                    string.Format("{0} = {1}",
                                  PPartnerLocationTable.GetPartnerKeyDBName(),
                                  partnerRow.PartnerKey);

                PartnerLocations[0].Row.Delete();

                partnerRow.Delete();
            }

            MainDS.ThrowAwayAfterSubmitChanges = true;

            PartnerEditTDSAccess.SubmitChanges(MainDS);

            TLogging.Log("after saving donors");
        }
        /// load transactions from a CSV file into the currently selected batch
        private void CreateBatchFromCSVFile(string ADataFilename,
                                            XmlNode ARootNode,
                                            AJournalRow ARefJournalRow,
                                            Int32 AFirstTransactionRow,
                                            string ADefaultCostCentre,
                                            out DateTime ALatestTransactionDate)
        {
            StreamReader dataFile = new StreamReader(ADataFilename, System.Text.Encoding.Default);

            XmlNode ColumnsNode        = TXMLParser.GetChild(ARootNode, "Columns");
            string  Separator          = TXMLParser.GetAttribute(ARootNode, "Separator");
            string  DateFormat         = TXMLParser.GetAttribute(ARootNode, "DateFormat");
            string  ThousandsSeparator = TXMLParser.GetAttribute(ARootNode, "ThousandsSeparator");
            string  DecimalSeparator   = TXMLParser.GetAttribute(ARootNode, "DecimalSeparator");
            Int32   lineCounter;

            // read headers
            for (lineCounter = 0; lineCounter < AFirstTransactionRow - 1; lineCounter++)
            {
                dataFile.ReadLine();
            }

            decimal sumDebits  = 0.0M;
            decimal sumCredits = 0.0M;

            ALatestTransactionDate = DateTime.MinValue;

            do
            {
                string line = dataFile.ReadLine();
                lineCounter++;

                GLBatchTDSATransactionRow NewTransaction = FMainDS.ATransaction.NewRowTyped(true);
                FMyForm.GetTransactionsControl().NewRowManual(ref NewTransaction, ARefJournalRow);
                FMainDS.ATransaction.Rows.Add(NewTransaction);

                foreach (XmlNode ColumnNode in ColumnsNode.ChildNodes)
                {
                    string Value = StringHelper.GetNextCSV(ref line, Separator);
                    string UseAs = TXMLParser.GetAttribute(ColumnNode, "UseAs");

                    if (UseAs.ToLower() == "reference")
                    {
                        NewTransaction.Reference = Value;
                    }
                    else if (UseAs.ToLower() == "narrative")
                    {
                        NewTransaction.Narrative = Value;
                    }
                    else if (UseAs.ToLower() == "dateeffective")
                    {
                        NewTransaction.SetTransactionDateNull();

                        if (Value.Trim().ToString().Length > 0)
                        {
                            try
                            {
                                NewTransaction.TransactionDate = XmlConvert.ToDateTime(Value, DateFormat);

                                if (NewTransaction.TransactionDate > ALatestTransactionDate)
                                {
                                    ALatestTransactionDate = NewTransaction.TransactionDate;
                                }
                            }
                            catch (Exception exp)
                            {
                                MessageBox.Show(Catalog.GetString("Problem with date in row " + lineCounter.ToString() + " Error: " + exp.Message));
                            }
                        }
                    }
                    else if (UseAs.ToLower() == "account")
                    {
                        if (Value.Length > 0)
                        {
                            if (Value.Contains(" "))
                            {
                                // cut off currency code; should have been defined in the data description file, for the whole batch
                                Value = Value.Substring(0, Value.IndexOf(" ") - 1);
                            }

                            Value = Value.Replace(ThousandsSeparator, "");
                            Value = Value.Replace(DecimalSeparator, ".");

                            NewTransaction.TransactionAmount    = Convert.ToDecimal(Value, System.Globalization.CultureInfo.InvariantCulture);
                            NewTransaction.CostCentreCode       = ADefaultCostCentre;
                            NewTransaction.AccountCode          = ColumnNode.Name;
                            NewTransaction.DebitCreditIndicator = true;

                            if (TXMLParser.HasAttribute(ColumnNode,
                                                        "CreditDebit") && (TXMLParser.GetAttribute(ColumnNode, "CreditDebit").ToLower() == "credit"))
                            {
                                NewTransaction.DebitCreditIndicator = false;
                            }

                            if (NewTransaction.TransactionAmount < 0)
                            {
                                NewTransaction.TransactionAmount   *= -1.0M;
                                NewTransaction.DebitCreditIndicator = !NewTransaction.DebitCreditIndicator;
                            }

                            if (TXMLParser.HasAttribute(ColumnNode, "AccountCode"))
                            {
                                NewTransaction.AccountCode = TXMLParser.GetAttribute(ColumnNode, "AccountCode");
                            }

                            if (NewTransaction.DebitCreditIndicator)
                            {
                                sumDebits += NewTransaction.TransactionAmount;
                            }
                            else if (!NewTransaction.DebitCreditIndicator)
                            {
                                sumCredits += NewTransaction.TransactionAmount;
                            }
                        }
                    }
                }

                if (!NewTransaction.IsTransactionDateNull())
                {
                    NewTransaction.AmountInBaseCurrency = GLRoutines.Multiply(NewTransaction.TransactionAmount,
                                                                              TExchangeRateCache.GetDailyExchangeRate(
                                                                                  ARefJournalRow.TransactionCurrency,
                                                                                  FMainDS.ALedger[0].BaseCurrency,
                                                                                  NewTransaction.TransactionDate));
                    //
                    // The International currency calculation is changed to "Base -> International", because it's likely
                    // we won't have a "Transaction -> International" conversion rate defined.
                    //
                    NewTransaction.AmountInIntlCurrency = GLRoutines.Multiply(NewTransaction.AmountInBaseCurrency,
                                                                              TExchangeRateCache.GetDailyExchangeRate(
                                                                                  FMainDS.ALedger[0].BaseCurrency,
                                                                                  FMainDS.ALedger[0].IntlCurrency,
                                                                                  NewTransaction.TransactionDate));
                }
            } while (!dataFile.EndOfStream);

            // create a balancing transaction; not sure if this is needed at all???
            if (Convert.ToDecimal(sumCredits - sumDebits) != 0)
            {
                GLBatchTDSATransactionRow BalancingTransaction = FMainDS.ATransaction.NewRowTyped(true);
                FMyForm.GetTransactionsControl().NewRowManual(ref BalancingTransaction, ARefJournalRow);
                FMainDS.ATransaction.Rows.Add(BalancingTransaction);

                BalancingTransaction.TransactionDate      = ALatestTransactionDate;
                BalancingTransaction.DebitCreditIndicator = true;
                BalancingTransaction.TransactionAmount    = sumCredits - sumDebits;

                if (BalancingTransaction.TransactionAmount < 0)
                {
                    BalancingTransaction.TransactionAmount   *= -1;
                    BalancingTransaction.DebitCreditIndicator = !BalancingTransaction.DebitCreditIndicator;
                }

                if (BalancingTransaction.DebitCreditIndicator)
                {
                    sumDebits += BalancingTransaction.TransactionAmount;
                }
                else
                {
                    sumCredits += BalancingTransaction.TransactionAmount;
                }

                BalancingTransaction.AmountInIntlCurrency = GLRoutines.Multiply(BalancingTransaction.TransactionAmount,
                                                                                TExchangeRateCache.GetDailyExchangeRate(
                                                                                    ARefJournalRow.TransactionCurrency,
                                                                                    FMainDS.ALedger[0].IntlCurrency,
                                                                                    BalancingTransaction.TransactionDate));
                BalancingTransaction.AmountInBaseCurrency = GLRoutines.Multiply(BalancingTransaction.TransactionAmount,
                                                                                TExchangeRateCache.GetDailyExchangeRate(
                                                                                    ARefJournalRow.TransactionCurrency,
                                                                                    FMainDS.ALedger[0].BaseCurrency,
                                                                                    BalancingTransaction.TransactionDate));
                BalancingTransaction.Narrative      = Catalog.GetString("Automatically generated balancing transaction");
                BalancingTransaction.CostCentreCode = TXMLParser.GetAttribute(ARootNode, "CashCostCentre");
                BalancingTransaction.AccountCode    = TXMLParser.GetAttribute(ARootNode, "CashAccount");
            }

            ARefJournalRow.JournalCreditTotal = sumCredits;
            ARefJournalRow.JournalDebitTotal  = sumDebits;
            ARefJournalRow.JournalDescription = Path.GetFileNameWithoutExtension(ADataFilename);

            ABatchRow RefBatch = (ABatchRow)FMainDS.ABatch.Rows[FMainDS.ABatch.Rows.Count - 1];

            RefBatch.BatchCreditTotal = sumCredits;
            RefBatch.BatchDebitTotal  = sumDebits;
            // todo RefBatch.BatchControlTotal = sumCredits  - sumDebits;
            // csv !
        }
        /// <summary>
        /// Import a batch from a spreadsheet
        /// </summary>
        /// <param name="ACSVDataFileName"></param>
        /// <param name="ALatestTransactionDate"></param>
        /// <returns></returns>
        public bool ImportFromSpreadsheet(out string ACSVDataFileName, out DateTime ALatestTransactionDate)
        {
            ALatestTransactionDate = DateTime.MinValue;
            ACSVDataFileName       = String.Empty;

            OpenFileDialog dialog = new OpenFileDialog();

            dialog.Title  = Catalog.GetString("Import transactions from spreadsheet file");
            dialog.Filter = Catalog.GetString("Spreadsheet files (*.csv)|*.csv");

            if (dialog.ShowDialog() == DialogResult.OK)
            {
                string   directory          = Path.GetDirectoryName(dialog.FileName);
                string[] ymlFiles           = Directory.GetFiles(directory, "*.yml");
                string   definitionFileName = String.Empty;

                if (ymlFiles.Length == 1)
                {
                    definitionFileName = ymlFiles[0];
                }
                else
                {
                    // show another open file dialog for the description file
                    OpenFileDialog dialogDefinitionFile = new OpenFileDialog();
                    dialogDefinitionFile.Title  = Catalog.GetString("Please select a yml file that describes the content of the spreadsheet");
                    dialogDefinitionFile.Filter = Catalog.GetString("Data description files (*.yml)|*.yml");

                    if (dialogDefinitionFile.ShowDialog() == DialogResult.OK)
                    {
                        definitionFileName = dialogDefinitionFile.FileName;
                    }
                }

                if (File.Exists(definitionFileName))
                {
                    TYml2Xml    parser              = new TYml2Xml(definitionFileName);
                    XmlDocument dataDescription     = parser.ParseYML2XML();
                    XmlNode     RootNode            = TXMLParser.FindNodeRecursive(dataDescription.DocumentElement, "RootNode");
                    Int32       FirstTransactionRow = TXMLParser.GetIntAttribute(RootNode, "FirstTransactionRow");
                    string      DefaultCostCentre   = TXMLParser.GetAttribute(RootNode, "CostCentre");

                    FMyUserControl.CreateNewABatch();
                    GLBatchTDSAJournalRow NewJournal = FMainDS.AJournal.NewRowTyped(true);
                    FMyForm.GetJournalsControl().NewRowManual(ref NewJournal);
                    FMainDS.AJournal.Rows.Add(NewJournal);
                    NewJournal.TransactionCurrency = TXMLParser.GetAttribute(RootNode, "Currency");

                    if (Path.GetExtension(dialog.FileName).ToLower() == ".csv")
                    {
                        ACSVDataFileName = dialog.FileName;

                        CreateBatchFromCSVFile(dialog.FileName,
                                               RootNode,
                                               NewJournal,
                                               FirstTransactionRow,
                                               DefaultCostCentre,
                                               out ALatestTransactionDate);

                        return(true);
                    }
                }
            }

            return(false);
        }
Example #9
0
        /// <summary>
        /// Drives a Test Client.
        /// </summary>
        public void Run()
        {
            XmlNode curEvent;
            XmlNode oldEvent;
            String  action;
            Int64   breakTime;
            Int32   NetClientPort;
            Int32   APClientPort;
            String  parameters;

            System.Diagnostics.Process UProgressProcess;
            DateTime TimeFinished;

            curEvent  = curGroup.FirstChild;
            breakTime = 0;

            if ((curEvent != null) && (curEvent.Name.ToLower() == "event"))
            {
                breakTime = main.RandomBreak(curEvent);
            }

            while ((curEvent != null) && (curEvent.Name.ToLower() == "event") && main.ServerStillRunning())
            {
                if (breakTime > 0)
                {
                    System.Console.WriteLine("{0}: Client {1} is sleeping for about " + Convert.ToString(
                                                 breakTime / 1000) + " seconds ...", DateTime.Now.ToLongTimeString(), Id);
                    Thread.Sleep((int)breakTime);
                }

                // System.Console.WriteLine('continue client ' + Id.Tostring() + ' at time ' + DateTime.Now.ToString());
                // we need the breaktime already, to tell the client how long it should run
                oldEvent = curEvent;
                curEvent = curEvent.NextSibling;

                if (curEvent == null)
                {
                    // start again
                    curEvent = curGroup.FirstChild;

                    if (TXMLParser.GetBoolAttribute(curGroup, "loop", true) == false)
                    {
                        curEvent = null;
                    }
                }

                if (curEvent != null)
                {
                    breakTime = main.RandomBreak(curEvent);
                }

                action = TXMLParser.GetAttribute(oldEvent, "action");

                if (action == "connect")
                {
                    System.Console.WriteLine("{0}: connecting client {1}", DateTime.Now.ToLongTimeString(), Id);

                    NetClientPort = 2080 + Id * 2;
                    APClientPort  = 2081 + Id * 2;

                    TimeFinished = DateTime.Now.AddMilliseconds(breakTime);

                    parameters = "-C:" + Global.Configfile + ' ' + "-NetClientPort:" + NetClientPort.ToString() + ' ' + "-APClientPort:" +
                                 APClientPort.ToString() + ' ' + "-AutoLogin:TESTUSER" + Id.ToString() + ' ' + "-AutoLoginPasswd:test" + ' ' +
                                 "-DisconnectTime:" + new TVariant(TimeFinished).EncodeToString() + ' ' + "-RunAutoTests:true" + ' ' +
                                 "-AutoTestConfigFile:" +
                                 TXMLParser.GetAttribute(oldEvent, "testing") + ' ' +
                                 "-AutoTestParameters:" +
                                 TXMLParser.GetAttribute(oldEvent, "params") + ' ' +
                                 "-SingleClient:" +
                                 SingleClient.ToString();

                    // add fixed disconnection datetime; or create a testing file?
                    // add testing file
                    try
                    {
                        System.Console.WriteLine("{0}:   starting {1}", DateTime.Now.ToLongTimeString(), parameters);

                        UProgressProcess = new System.Diagnostics.Process();
                        UProgressProcess.EnableRaisingEvents = false;
                        UProgressProcess.StartInfo.FileName  = Global.Filename;
                        UProgressProcess.StartInfo.Arguments = parameters;
                        UProgressProcess.EnableRaisingEvents = true;

                        if ((!UProgressProcess.Start()))
                        {
                            return;
                        }
                    }
                    catch (Exception Exp)
                    {
                        System.Console.WriteLine("{0}: Trouble in TestClient.Run", DateTime.Now.ToLongTimeString());
                        System.Console.WriteLine("{0}: {1}", DateTime.Now.ToLongTimeString(), Exp.Message);

                        return;
                    }
                }
                else if (action == "disconnect")
                {
                    System.Console.WriteLine("{0}: disconnecting client {1}", DateTime.Now.ToLongTimeString(), Id);
                }
            }
        }
Example #10
0
        /// <summary>
        /// Drives a Test Group.
        /// </summary>
        public void Run()
        {
            Thread     ClientThread;
            TestClient MyClient;
            int        StartId;
            int        EndId;


            Thread.Sleep((int)main.RandomBreak(curGroup));

            Console.WriteLine("{0}: starting group {1}", DateTime.Now.ToLongTimeString(), TXMLParser.GetAttribute(curGroup, "name"));

            StartId = TXMLParser.GetIntAttribute(curGroup, "startid");
            EndId   = TXMLParser.GetIntAttribute(curGroup, "endid");

            for (int Counter = StartId; Counter <= EndId; Counter += 1)
            {
                MyClient = new TestClient(curGroup, Counter + Global.StartClientID, StartId == EndId);

                ClientThread = new Thread(MyClient.Run);
                ClientThread.Start();
            }
        }
Example #11
0
        /// <summary>
        /// generate the invoices from a text file that was generated with Benerator
        /// </summary>
        /// <param name="AInputBeneratorFile"></param>
        /// <param name="AYear">eg. 2013</param>
        public static void GenerateInvoices(string AInputBeneratorFile, int AYear)
        {
            XmlDocument doc = TCsv2Xml.ParseCSV2Xml(AInputBeneratorFile, ",");

            XmlNode RecordNode = doc.FirstChild.NextSibling.FirstChild;

            AccountsPayableTDS MainDS = new AccountsPayableTDS();

            // get a list of potential suppliers
            string sqlGetSupplierPartnerKeys =
                "SELECT PUB_a_ap_supplier.p_partner_key_n, PUB_a_ap_supplier.a_currency_code_c " +
                "FROM PUB_p_organisation, PUB_a_ap_supplier WHERE PUB_a_ap_supplier.p_partner_key_n = PUB_p_organisation.p_partner_key_n";
            DataTable SupplierKeys = DBAccess.GDBAccessObj.SelectDT(sqlGetSupplierPartnerKeys, "keys", null);

            // get a list of potential expense account codes
            string sqlGetExpenseAccountCodes = "SELECT a_account_code_c FROM PUB_a_account WHERE a_ledger_number_i = " +
                                               FLedgerNumber.ToString() +
                                               " AND a_account_type_c = 'Expense' AND a_account_active_flag_l = true AND a_posting_status_l = true";
            DataTable AccountCodes = DBAccess.GDBAccessObj.SelectDT(sqlGetExpenseAccountCodes, "codes", null);

            while (RecordNode != null)
            {
                int            supplierID   = Convert.ToInt32(TXMLParser.GetAttribute(RecordNode, "Supplier")) % SupplierKeys.Rows.Count;
                Int64          SupplierKey  = Convert.ToInt64(SupplierKeys.Rows[supplierID].ItemArray[0]);
                String         CurrencyCode = Convert.ToString(SupplierKeys.Rows[supplierID].ItemArray[1]);
                AApDocumentRow invoiceRow   = MainDS.AApDocument.NewRowTyped(true);

                invoiceRow.LedgerNumber     = FLedgerNumber;
                invoiceRow.ApDocumentId     = (Int32)TSequenceWebConnector.GetNextSequence(TSequenceNames.seq_ap_document);
                invoiceRow.ApNumber         = invoiceRow.ApDocumentId;
                invoiceRow.DocumentCode     = invoiceRow.ApDocumentId.ToString();
                invoiceRow.PartnerKey       = SupplierKey;
                invoiceRow.Reference        = "something";
                invoiceRow.DateIssued       = Convert.ToDateTime(TXMLParser.GetAttribute(RecordNode, "DateIssued"));
                invoiceRow.DateIssued       = new DateTime(AYear, invoiceRow.DateIssued.Month, invoiceRow.DateIssued.Day);
                invoiceRow.DateEntered      = invoiceRow.DateIssued;
                invoiceRow.TotalAmount      = Convert.ToDecimal(TXMLParser.GetAttribute(RecordNode, "Amount")) / 100.0m;
                invoiceRow.CurrencyCode     = CurrencyCode;
                invoiceRow.ApAccount        = "9100";
                invoiceRow.DocumentStatus   = MFinanceConstants.AP_DOCUMENT_APPROVED;
                invoiceRow.LastDetailNumber = 1;

                // TODO reasonable exchange rate for non base currency. need to check currency of supplier
                invoiceRow.ExchangeRateToBase = 1.0m;

                MainDS.AApDocument.Rows.Add(invoiceRow);

                AApDocumentDetailRow detailRow = MainDS.AApDocumentDetail.NewRowTyped(true);
                detailRow.ApDocumentId   = invoiceRow.ApDocumentId;
                detailRow.DetailNumber   = 1;
                detailRow.LedgerNumber   = invoiceRow.LedgerNumber;
                detailRow.CostCentreCode = (FLedgerNumber * 100).ToString("0000");
                int accountID = Convert.ToInt32(TXMLParser.GetAttribute(RecordNode, "ExpenseAccount")) % AccountCodes.Rows.Count;
                detailRow.AccountCode = AccountCodes.Rows[accountID].ItemArray[0].ToString();
                detailRow.Amount      = invoiceRow.TotalAmount;

                MainDS.AApDocumentDetail.Rows.Add(detailRow);

                RecordNode = RecordNode.NextSibling;
            }

            ;
            AccountsPayableTDSAccess.SubmitChanges(MainDS);
        }