private void importQIFSimpleTransaction(QifTransaction qTrans)
        {
            // Easy stuff (date, type, account, description, confNum, complete, amount, creditdebit)
            FFDataSet.LineItemRow newLine = this.getEasyLineData(qTrans);

            // Set oppAccount and envelopeID, and import envelope Lines
            byte cat = (qTrans.Amount > 0.0m) ? SpclAccountCat.INCOME : SpclAccountCat.EXPENSE;

            newLine.oppAccountID = this.ffDataSet.myImportAccount(qTrans.Payee, "", cat);
            newLine.envelopeID   = this.importEnvelopeLines(qTrans, newLine.id);

            if (newLine.accountID == newLine.oppAccountID)
            {
                newLine.oppAccountID = this.ffDataSet.myImportAccount(qTrans.Payee + "-Payee", "", cat);
            }

            // Build the oppLine
            FFDataSet.LineItemRow payeeLine = this.ffDataSet.LineItem.NewLineItemRow();
            payeeLine.transactionID      = newLine.transactionID;
            payeeLine.date               = newLine.date;
            payeeLine.typeID             = newLine.typeID;
            payeeLine.accountID          = newLine.oppAccountID;
            payeeLine.oppAccountID       = newLine.accountID;
            payeeLine.description        = newLine.description;
            payeeLine.confirmationNumber = newLine.confirmationNumber;
            payeeLine.envelopeID         = SpclEnvelope.NULL;
            payeeLine.complete           = newLine.complete;
            payeeLine.amount             = newLine.amount;
            payeeLine.creditDebit        = !newLine.creditDebit;

            // Add the lines to the table
            this.ffDataSet.LineItem.AddLineItemRow(newLine);
            this.ffDataSet.LineItem.AddLineItemRow(payeeLine);
        }
        private FFDataSet.LineItemRow getEasyLineData(QifTransaction qTrans)
        {
            FFDataSet.LineItemRow newLine = this.ffDataSet.LineItem.NewLineItemRow();

            newLine.date        = qTrans.Date;
            newLine.accountID   = qTrans.AccountID;
            newLine.description = qTrans.Memo + " " + qTrans.Address;

            // Set the amount and creditDebit
            if (qTrans.Amount >= 0)
            {
                newLine.amount      = qTrans.Amount;
                newLine.creditDebit = LineCD.DEBIT;
            }
            else
            {
                newLine.amount      = Decimal.Negate(qTrans.Amount);
                newLine.creditDebit = LineCD.CREDIT;
            }

            // Set the complete
            switch (qTrans.ClearedStatus)
            {
            case "S":
                newLine.complete = LineState.RECONSILED;
                break;

            case "X":
                newLine.complete = LineState.RECONSILED;
                break;

            case "*":
                newLine.complete = LineState.CLEARED;
                break;

            case "":
                newLine.complete = LineState.PENDING;
                break;

            default:
                newLine.complete = LineState.PENDING;
                break;
            }

            // Set the Num/Type and Confermation number if needed.
            try
            {
                Convert.ToInt32(qTrans.Num);
                newLine.typeID             = this.ffDataSet.myImportLineType("Check");
                newLine.confirmationNumber = "Check Number: " + qTrans.Num;
            }
            catch (FormatException)
            {
                newLine.typeID = this.ffDataSet.myImportLineType(qTrans.Num);
            }

            return(newLine);
        }
Example #3
0
        public bool isOpposite(QifTransaction trans)
        {
            if (this.AccountID.Equals(trans.OppAccountID) &&
                this.OppAccountID.Equals(trans.AccountID) &&
                this.Date.Equals(trans.Date) &&
                this.Amount.Equals(Decimal.Negate(trans.Amount)))
            {
                return(true);
            }

            return(false);
        }
        private void importQIFTransfers(QifTransaction majorTrans, QifSplit payee)
        {
            List <FFDataSet.LineItemRow> transLines   = new List <FFDataSet.LineItemRow>();
            List <QifTransaction>        oppTransList = new List <QifTransaction>();

            // Match up
            foreach (QifSplit split in majorTrans.OppLines)
            {
                // Skip the payee oppline
                if (split.Catagory.StartsWith("["))
                {
                    foreach (QifTransaction minorTrans in this.qifTransfers)
                    {
                        if (majorTrans.Date.Equals(minorTrans.Date) &&
                            majorTrans.AccountID.Equals(minorTrans.OppAccountID) &&
                            split.OppAccountID.Equals(minorTrans.AccountID) &&
                            split.Amount.Equals(Decimal.Negate(minorTrans.Amount)))
                        {
                            oppTransList.Add(minorTrans);
                        }
                    }
                }
            }

            // Complex transfer between more than two accounts.
            if (payee == null && majorTrans.OppLines.Count == oppTransList.Count)
            {
                // Finish the MajorLine
                FFDataSet.LineItemRow majorLine = this.getEasyLineData(majorTrans);

                majorLine.envelopeID = this.importEnvelopeLines(majorTrans, majorLine.id);

                if (oppTransList.Count == 1)
                {
                    majorLine.oppAccountID = oppTransList[0].AccountID;
                }
                else
                {
                    majorLine.oppAccountID = SpclAccount.MULTIPLE;
                }

                this.ffDataSet.LineItem.AddLineItemRow(majorLine);
                transLines.Add(majorLine);

                this.qifTransfers.Remove(majorTrans);

                // Finish the MinorLines
                foreach (QifTransaction minorTrans in oppTransList)
                {
                    FFDataSet.LineItemRow minorLine = this.getEasyLineData(minorTrans);

                    minorLine.transactionID = majorLine.transactionID;
                    minorLine.oppAccountID  = majorLine.accountID;
                    minorLine.envelopeID    = this.importEnvelopeLines(minorTrans, minorLine.id);

                    this.ffDataSet.LineItem.AddLineItemRow(minorLine);
                    transLines.Add(minorLine);

                    this.qifTransfers.Remove(minorTrans);
                }
            }

            // Complex transfer between atleast two accounts and a payee
            if (payee != null && majorTrans.OppLines.Count == oppTransList.Count + 1)
            {
                // Finish the MajorLine
                FFDataSet.LineItemRow majorLine = this.getEasyLineData(majorTrans);

                majorLine.oppAccountID = SpclAccount.MULTIPLE;
                majorLine.envelopeID   = this.importEnvelopeLines(majorTrans, majorLine.id);

                this.ffDataSet.LineItem.AddLineItemRow(majorLine);
                transLines.Add(majorLine);

                this.qifTransfers.Remove(majorTrans);

                // Make the Payee Line
                FFDataSet.LineItemRow payeeLine = this.getEasyLineData(majorTrans);
                payeeLine.transactionID      = majorLine.transactionID;
                payeeLine.date               = majorLine.date;
                payeeLine.typeID             = majorLine.typeID;
                payeeLine.oppAccountID       = majorLine.accountID;
                payeeLine.confirmationNumber = majorLine.confirmationNumber;
                payeeLine.complete           = majorLine.complete;
                payeeLine.envelopeID         = SpclEnvelope.NULL;
                payeeLine.creditDebit        = !majorLine.creditDebit;

                payeeLine.accountID   = payee.OppAccountID;
                payeeLine.description = payee.Memo;

                if (payee.Amount > 0.0m)
                {
                    payeeLine.amount = payee.Amount;
                }
                else
                {
                    payeeLine.amount = Decimal.Negate(payee.Amount);
                }

                this.ffDataSet.LineItem.AddLineItemRow(payeeLine);
                transLines.Add(payeeLine);

                // Finish the MinorLines
                foreach (QifTransaction minorTrans in oppTransList)
                {
                    FFDataSet.LineItemRow minorLine = this.getEasyLineData(minorTrans);

                    minorLine.transactionID = majorLine.transactionID;
                    minorLine.oppAccountID  = majorLine.accountID;
                    minorLine.envelopeID    = this.importEnvelopeLines(minorTrans, minorLine.id);

                    this.ffDataSet.LineItem.AddLineItemRow(minorLine);
                    transLines.Add(minorLine);

                    this.qifTransfers.Remove(minorTrans);
                }

                // Make sure the oppAccount was set correctly
                int debitCount      = 0;
                int creditCount     = 0;
                int debitAccountID  = SpclAccount.NULL;
                int creditAccountID = SpclAccount.NULL;

                // Count things up
                foreach (FFDataSet.LineItemRow line in transLines)
                {
                    if (line.creditDebit == LineCD.CREDIT)
                    {
                        creditCount++;
                        creditAccountID = line.accountID;
                    }
                    else
                    {
                        debitCount++;
                        debitAccountID = line.accountID;
                    }
                }

                // Set correct values
                foreach (FFDataSet.LineItemRow line in transLines)
                {
                    if (line.creditDebit == LineCD.CREDIT && debitCount == 1)
                    {
                        line.oppAccountID = debitAccountID;
                    }

                    else if (line.creditDebit == LineCD.CREDIT && debitCount > 1)
                    {
                        line.oppAccountID = SpclAccount.MULTIPLE;
                    }

                    else if (line.creditDebit == LineCD.DEBIT && creditCount == 1)
                    {
                        line.oppAccountID = creditAccountID;
                    }

                    else if (line.creditDebit == LineCD.DEBIT && creditCount > 1)
                    {
                        line.oppAccountID = SpclAccount.MULTIPLE;
                    }
                }
            }
        }
        private void importQIFTransfer(QifTransaction qTrans)
        {
            FFDataSet.LineItemRow newLine;
            FFDataSet.LineItemRow oppLine;
            QifTransaction        oppTrans = null;
            int oppAccountID;

            // Determine oppSum that will be used if this is a complex transaction.
            // Mostly a complex transaction in Quicken is for a paycheck where a --Form-- is used.
            // Also a complex transaction can be where a purchase and transfer are combined into one action.
            // For example, a purchase at a store where you get cash back and the cash is then deposited
            // into another account. If this is the case the payee should be an oppAccount also.
            // the money that goes to the store = the purchase total minus the amount transfered.
            decimal oppSum = 0.0m;

            foreach (QifSplit oppLn in qTrans.OppLines)
            {
                oppSum += oppLn.Amount;
            }

            // If a complex transaction. Payee is also an oppAccount
            if (qTrans.EnvLines.Count >= 1 && qTrans.EnvLines.Count >= 1)
            {
                qTrans.OppLines.Add(new QifSplit(qTrans.Payee, qTrans.Memo, qTrans.Amount - oppSum));
            }

            // Determine the oppAccountID of the given transaction
            if (qTrans.OppLines.Count == 0)
            {   // Simple Transfer
                if (!this.ffDataSet.myGetAccount(qTrans.Catagory, out oppAccountID))
                {
                    throw new InvalidDataException("The transactions Catagory is not an account in the map.");
                }
            }
            else if (qTrans.OppLines.Count == 1)
            {   // Don't think this will ever happen, but in case it does...
                if (!this.ffDataSet.myGetAccount(qTrans.OppLines[0].Catagory, out oppAccountID))
                {
                    throw new InvalidDataException("The transactions OppLine.Catagory is not an account in the map.");
                }
            }
            else // Another type of complex transaction.
            {
                oppAccountID = SpclAccount.MULTIPLE;
            }

            qTrans.OppAccountID = oppAccountID;

            // Look for a match to this transfer. This might be the second half of a simple transfer.
            // Once found assign in to oppTrans and remove it from the qifTransfer list
            foreach (QifTransaction trans in this.qifTransfers)
            {
                if (trans.isOpposite(qTrans))
                {
                    oppTrans = trans;
                    this.qifTransfers.Remove(trans);
                    break;
                }
            }

            // If we didn't find an opposite transaction in the transfer list this transfer might be
            // a one sided transaction like an opening balance. If not add it to the transfer list.
            if (oppTrans == null)
            {
                if (qTrans.AccountID == qTrans.OppAccountID)
                {
                    // This is a one sided transaction (Opening Balance.)
                    newLine = this.getEasyLineData(qTrans);
                    newLine.oppAccountID = newLine.accountID;
                    newLine.envelopeID   = this.importEnvelopeLines(qTrans, newLine.id);

                    this.ffDataSet.LineItem.AddLineItemRow(newLine);
                }
                else
                {
                    // Not one sided, add it to the list to be dealt with later.
                    this.qifTransfers.Add(qTrans);
                }

                return;
            }


            // If we get here this is a simple Transfer.
            newLine = this.getEasyLineData(qTrans);
            oppLine = this.getEasyLineData(oppTrans);

            // Finish newLine
            newLine.oppAccountID = oppLine.accountID;
            newLine.envelopeID   = this.importEnvelopeLines(qTrans, newLine.id);

            // Finish the oppLine
            oppLine.transactionID = newLine.transactionID;
            oppLine.oppAccountID  = newLine.accountID;
            oppLine.envelopeID    = this.importEnvelopeLines(oppTrans, oppLine.id);

            // Add the lines to the table
            this.ffDataSet.LineItem.AddLineItemRow(newLine);
            this.ffDataSet.LineItem.AddLineItemRow(oppLine);
        }
        private int importEnvelopeLines(QifTransaction qTrans, int lineID)
        {
            FFDataSet.EnvelopeLineRow eLine;
            int envelopeID  = SpclEnvelope.NULL;
            int countELines = 0;

            if (qTrans.EnvLines.Count > 0)
            {
                // Build the envelope lines from the splits.
                foreach (QifSplit split in qTrans.EnvLines)
                {
                    if (qTrans.Amount < 0.0m)
                    {
                        eLine = this.ffDataSet.EnvelopeLine.NewEnvelopeLineRow();

                        eLine.lineItemID  = lineID;
                        eLine.envelopeID  = envelopeID = this.ffDataSet.myImportEnvelope(split.Catagory);
                        eLine.description = split.Memo;

                        if (qTrans.Amount < 0.0m)
                        {
                            eLine.amount = Decimal.Negate(split.Amount);
                        }
                        else
                        {
                            eLine.amount = split.Amount;
                        }

                        this.ffDataSet.EnvelopeLine.AddEnvelopeLineRow(eLine);
                        countELines++;
                    }
                }
            }
            else if (qTrans.Catagory.StartsWith("["))
            {
                // Filter out the Transfers
                countELines = 0;
            }
            else if (qTrans.Amount < 0.0m)
            {
                // Else there are no splits so build an envelopeLine from the transaction.
                eLine = this.ffDataSet.EnvelopeLine.NewEnvelopeLineRow();

                eLine.lineItemID  = lineID;
                eLine.envelopeID  = envelopeID = this.ffDataSet.myImportEnvelope(qTrans.Catagory);
                eLine.description = qTrans.Memo;

                if (qTrans.Amount < 0.0m)
                {
                    eLine.amount = Decimal.Negate(qTrans.Amount);
                }
                else
                {
                    eLine.amount = qTrans.Amount;
                }

                this.ffDataSet.EnvelopeLine.AddEnvelopeLineRow(eLine);
                countELines++;
            }

            if (countELines == 0)
            {
                envelopeID = SpclEnvelope.NULL;
            }
            else if (countELines > 1)
            {
                envelopeID = SpclEnvelope.SPLIT;
            }

            return(envelopeID);
        }
        private void getTransactionData(QifAccount account, string data)
        {
            string[] transArray = data.Split(new string[] { "\n^" }, StringSplitOptions.RemoveEmptyEntries);

            foreach (string transInfo in transArray)
            {
                string[]       properties     = transInfo.Split(new string[] { "\n" }, StringSplitOptions.RemoveEmptyEntries);
                QifTransaction newTransaction = new QifTransaction();
                QifSplit       newSplit       = null;

                foreach (string property in properties)
                {
                    switch (property[0])
                    {
                    case 'D':        //D    Date
                        newTransaction.Date = myStringToDate(property.Substring(1));
                        continue;

                    case 'T':        //T    Amount
                        newTransaction.Amount = Convert.ToDecimal(property.Substring(1));
                        continue;

                    case 'C':        //C    Cleared status
                        newTransaction.ClearedStatus = property.Substring(1);
                        continue;

                    case 'N':        //N    Num (check or reference number)
                        newTransaction.Num = property.Substring(1);
                        continue;

                    case 'M':        //M    Memo
                        newTransaction.Memo = property.Substring(1);
                        continue;

                    case 'P':        //P    Payee
                        newTransaction.Payee = property.Substring(1);
                        continue;

                    case 'A':        //A    Address (up to five lines; the sixth line is an optional message)
                        newTransaction.Address += property.Substring(1);
                        continue;

                    case 'L':        //L    Category (Category/Subcategory/Transfer/Class)
                        newTransaction.Catagory = property.Substring(1);
                        continue;

                    case 'S':        //S    Category in split (Category/Transfer/Class)
                        newSplit          = new QifSplit();
                        newSplit.Catagory = property.Substring(1);
                        continue;

                    case 'E':         //E   Memo in split
                        newSplit.Memo = property.Substring(1);
                        continue;

                    case '$':        //$    Dollar amount of split
                        newSplit.Amount = Convert.ToDecimal(property.Substring(1));
                        if (newSplit.Catagory.StartsWith("["))
                        {
                            newTransaction.OppLines.Add(newSplit);
                        }
                        else
                        {
                            newTransaction.EnvLines.Add(newSplit);
                        }
                        continue;

                    case 'U':        //Don't know. Always seams to be the same as T (The amount).
                        continue;

                    default:
                        throw new Exception("Not handled " + property);
                    } // End switch
                }     // End foreach property

                account.Transactions.Add(newTransaction);
            }// End foreach accInfo
        }