Пример #1
0
        public void SaveLedger( Ledger ledger )
        {
            ledger.ValidateReferentialIntegrity();

            // Ensure that identifiers match appropriately before saving.
            ValidateIdentifierLinks( ledger );

            /*
            // TODO: Remove this after testing
            ledger.RecurringTransactions.Clear();
            RecurringTransaction r = new RecurringTransaction();
            r.StartingDate = new DateTime( 2007, 10, 15 );
            r.EndingDate = DateTime.MaxValue;
            r.Date = new DateTime( 2007, 10, 15 );
            r.Amount = 129.69M;
            r.Description = "Ameriprise Financial";
            r.Memo = "Life insurance payment";
            r.LineItems.Add( new LineItemCredit( ledger.GetAccount( "Suntrust" ), r.Amount ) );
            r.LineItems.Add( new LineItemDebit( ledger.GetAccount( "Expenses" ), r.Amount ) );
            r.AddMonths = 1;
            ledger.RecurringTransactions.Add( r );
            */

            StreamWriter writer = File.CreateText( filename );
            try
            {
                XmlTextWriter xmlWriter = new XmlTextWriter( writer );
                try
                {
                    xmlWriter.WriteStartDocument();
                    xmlWriter.WriteWhitespace( Environment.NewLine );
                    xmlWriter.WriteStartElement( "Ledger" );
                    xmlWriter.WriteAttributeString( "xmlns", "http://www.uvteksoftware.com/xsd/UvMoneyLedger.xsd" );
                    xmlWriter.WriteAttributeString( "Version", "1.2" );
                    xmlWriter.WriteWhitespace( Environment.NewLine );

                    xmlWriter.WriteElementString( "MergeDate", ledger.MergeDate.ToString() );
                    xmlWriter.WriteWhitespace( Environment.NewLine );

                    // Write accounts
                    xmlWriter.WriteWhitespace( Environment.NewLine );
                    xmlWriter.WriteStartElement( "Accounts" );
                    xmlWriter.WriteWhitespace( Environment.NewLine );
                    foreach( Account account in ledger.Accounts )
                    {
                        SerializeAccount( xmlWriter, account );
                        xmlWriter.WriteWhitespace( Environment.NewLine );
                    }
                    xmlWriter.WriteEndElement(); // </Accounts>
                    xmlWriter.WriteWhitespace( Environment.NewLine );

                    // Write recurring transactions
                    if( ledger.RecurringTransactions.Count > 0 )
                    {
                        xmlWriter.WriteWhitespace( Environment.NewLine );
                        xmlWriter.WriteStartElement( "RecurringTransactions" );
                        xmlWriter.WriteWhitespace( Environment.NewLine );
                        foreach( RecurringTransaction retrans in ledger.RecurringTransactions )
                        {
                            SerializeRecurringTransaction( xmlWriter, retrans );
                            xmlWriter.WriteWhitespace( Environment.NewLine );
                        }
                        xmlWriter.WriteEndElement(); // </RecurringTransactions>
                        xmlWriter.WriteWhitespace( Environment.NewLine );
                    }

                    // Write transactions
                    xmlWriter.WriteWhitespace( Environment.NewLine );
                    xmlWriter.WriteStartElement( "Transactions" );
                    xmlWriter.WriteWhitespace( Environment.NewLine );
                    foreach( Transaction trans in ledger.Transactions )
                    {
                        // Do not serialize auto-generated transactions
                        if( !( trans is MissingTransaction ) )
                        {
                            trans.Validate();
                            SerializeTransaction( xmlWriter, trans );
                            xmlWriter.WriteWhitespace( Environment.NewLine );
                        }
                    }

                    xmlWriter.WriteWhitespace( Environment.NewLine );
                    xmlWriter.WriteComment( "Insert new transactions here." );
                    xmlWriter.WriteWhitespace( Environment.NewLine );

                    // Write out a transaction template
                    StringBuilder sb = new StringBuilder();
                    sb.Append( Environment.NewLine );
                    sb.Append( "<Transaction>" );
                    sb.Append( Environment.NewLine );
                    sb.Append( "<Date></Date>" );
                    sb.Append( Environment.NewLine );
                    sb.Append( "<Number></Number>" );
                    sb.Append( Environment.NewLine );
                    sb.Append( "<Amount>0.00</Amount>" );
                    sb.Append( Environment.NewLine );
                    sb.Append( "<Description>Payee</Description>" );
                    sb.Append( Environment.NewLine );
                    sb.Append( "<Memo></Memo>" );
                    sb.Append( Environment.NewLine );
                    sb.Append( "<LineItems>" );
                    sb.Append( Environment.NewLine );
                    sb.Append( "<Credit Account=\"\" />" );
                    sb.Append( Environment.NewLine );
                    sb.Append( "<Debit Account=\"Expenses\" Category=\"\" />" );
                    sb.Append( Environment.NewLine );
                    sb.Append( "</LineItems>" );
                    sb.Append( Environment.NewLine );
                    sb.Append( "</Transaction>" );
                    sb.Append( Environment.NewLine );
                    xmlWriter.WriteComment( sb.ToString() );
                    xmlWriter.WriteWhitespace( Environment.NewLine );
                    xmlWriter.WriteWhitespace( Environment.NewLine );

                    xmlWriter.WriteEndElement(); // </Transactions>
                    xmlWriter.WriteWhitespace( Environment.NewLine );

                    OnlineTransactionStorageXml ostorage = new OnlineTransactionStorageXml();

                    // Write online transactions that are missing from the ledger
                    if( ledger.MissingTransactions.Count > 0 )
                    {
                        xmlWriter.WriteStartElement( "MissingOnlineTransactions" );
                        xmlWriter.WriteWhitespace( Environment.NewLine );
                        foreach( OnlineTransaction otrans in ledger.MissingTransactions )
                        {
                            ostorage.SerializeTransaction( xmlWriter, otrans );
                            xmlWriter.WriteWhitespace( Environment.NewLine );
                        }
                        xmlWriter.WriteEndElement(); // </MissingOnlineTransactions>
                        xmlWriter.WriteWhitespace( Environment.NewLine );
                    }

                    xmlWriter.WriteEndElement(); // </Ledger>
                    xmlWriter.WriteWhitespace( Environment.NewLine );
                    xmlWriter.WriteEndDocument();
                }
                finally
                {
                    xmlWriter.Close();
                }
            }
            finally
            {
                writer.Close();
            }
        }
Пример #2
0
        public Ledger LoadLedger()
        {
            Ledger ledger = new Ledger();

            FileInfo fi = new FileInfo( filename );
            if( !fi.Exists ) return ledger;

            OnlineTransactionStorageXml ostorage = new OnlineTransactionStorageXml();

            Version version = new Version( 1, 0 );

            // I'm not precisely sure why I chose to parse the XML manually
            // instead of using XmlSerializer.
            // I guess I just didn't want to markup my classes with Xml tags.

            StreamReader reader = File.OpenText( filename );
            try
            {
                XmlTextReader xmlReader = new XmlTextReader( reader );
                try
                {
                    while( xmlReader.Read() )
                    {
                        switch( xmlReader.NodeType )
                        {
                            case XmlNodeType.Element:
                                switch( xmlReader.Name )
                                {
                                    case "MergeDate":
                                        ledger.MergeDate = DateTime.Parse( xmlReader.ReadString() );
                                        break;
                                    case "Ledger":
                                        version = new Version( xmlReader.GetAttribute( "Version" ) );
                                        break;
                                    case "Accounts":
                                        break;
                                    case "Account":
                                        Account account = DeserializeAccount( xmlReader, version );
                                        account.Ledger = ledger;
                                        // Verify that we are not adding any duplicate Ids or Names
                                        Account testAccount = ledger.FindAccount( account.Id );
                                        if( testAccount != null )
                                            throw new ApplicationException( "There is already an account with Id " + account.Id );
                                        testAccount = ledger.FindAccount( account.Name );
                                        if( testAccount != null )
                                            throw new ApplicationException( "There is already an account named " + account.Name );
                                        // Passed validation, add the account
                                        ledger.Accounts.Add( account );
                                        break;
                                    case "Transactions":
                                        break;
                                    case "Transaction":
                                        Transaction trans = DeserializeTransaction( xmlReader, version, ledger );
                                        // Migrate from deprecated versions
                                        trans.Migrate( version );
                                        // Validate the transaction
                                        trans.Validate();
                                        if( trans.Id != 0 )
                                        {
                                            // Ensure no other transactions with the same Id are in the ledger
                                            Transaction testTrans = ledger.GetTransaction( trans.Id );
                                            if( testTrans != null )
                                                throw new ApplicationException( "There is already a transaction with Id " + trans.Id );
                                        }
                                        ledger.AddTransaction( trans );
                                        break;
                                    case "MissingOnlineTransactions":
                                        break;
                                    case "OnlineTransaction":
                                        OnlineTransaction otrans = ostorage.DeserializeTransaction( xmlReader, version );
                                        ledger.MissingTransactions.Add( otrans );
                                        break;
                                    case "RecurringTransactions":
                                        break;
                                    case "RecurringTransaction":
                                        RecurringTransaction rtrans = DeserializeRecurringTransaction( xmlReader, version, ledger );
                                        ledger.RecurringTransactions.Add( rtrans );
                                        break;
                                }
                                break;
                        }
                    }
                }
                finally
                {
                    xmlReader.Close();
                }
            }
            finally
            {
                reader.Close();
            }

            AssignTransactionIdentifiers( ledger );
            AssignLineItemIdentifiers( ledger );
            ValidateIdentifierLinks( ledger );

            ledger.ValidateReferentialIntegrity();

            // Set load date so we can determine if data in memory is stale
            ledger.LoadDate = DateTime.Now;

            return ledger;
        }