private TrxOutputType GetPayeeUsage(BankTrx trx) { Account.SubType subType = trx.Register.Account.AcctSubType; if (subType == Account.SubType.Asset_CheckingAccount || subType == Account.SubType.Asset_SavingsAccount) { if (trx.Amount < 0) { return(TrxOutputType.Check); } else if (trx.Amount > 0) { if (ContainsPayablesSplit(trx.Splits)) { return(TrxOutputType.JournalEntry); } else { return(TrxOutputType.Deposit); } } } else if (subType == Account.SubType.Liability_AccountsPayable) { if (trx.Amount < 0) { return(TrxOutputType.Bill); } else { return(TrxOutputType.BillCredit); } } return(TrxOutputType.JournalEntry); }
private void OutputOneTransaction(BankTrx trx, string exportAccountName, PayeeDef payee, string intuitTrxType, bool usePayeeOnTrx) { OutputNormalTrx(trx, intuitTrxType, exportAccountName, usePayeeOnTrx ? payee.ExportName : "", trx.Amount); foreach (TrxSplit split in trx.Splits) { OutputSplit(split, intuitTrxType, ""); } OutputLine("ENDTRNS"); }
private void OutputTransactionPerSplit(BankTrx trx, string exportAccountName, PayeeDef payee, string intuitTrxType, Func <TrxSplit, bool> usePayeeOnSplit) { foreach (TrxSplit split in trx.Splits) { // Notice we pass the split amount instead of the trx amount, because every split // of this transaction type must be a separate transaction in an IIF file. OutputNormalTrx(trx, intuitTrxType, exportAccountName, payee.ExportName, split.Amount); OutputSplit(split, intuitTrxType, usePayeeOnSplit(split) ? payee.ExportName : ""); OutputLine("ENDTRNS"); } }
public void AddToNormalTrx(BankTrx trx) { trx.AddSplit( strCategoryKey_: strCatKey, strPONumber_: strPONumber ?? "", strInvoiceNum_: strInvoiceNum ?? "", datInvoiceDate_: (datInvoice <= Utilities.EmptyDate) ? Utilities.EmptyDate : datInvoice, datDueDate_: (datDue <= Utilities.EmptyDate) ? Utilities.EmptyDate : datDue, strTerms_: strTerms ?? "", strBudgetKey_: strBudgetKey ?? "", strMemo_: strMemo ?? "", curAmount_: curAmount); }
protected override void BeginProcessing() { BankTrx normalTrx = new BankTrx(Register); normalTrx.NewStartNormal(blnWillAddToRegister: true, strNumber_: Number, datDate_: Date, strDescription_: Description, strMemo_: Memo == null ? "" : Memo, lngStatus_: Status, blnFake_: Fake.IsPresent, curNormalMatchRange_: NormalMatchRange, blnAwaitingReview_: AwaitingReview.IsPresent, blnAutoGenerated_: false, intRepeatSeq_: 0, strImportKey_: ImportKey == null ? "" : ImportKey, strRepeatKey_: ""); if (OneSplit != null && Splits != null) { ThrowTerminatingError(ErrorUtilities.CreateInvalidOperation("-OneSplit and -Splits may not both be specified", "DupeSplits")); } else if (OneSplit != null) { OneSplit.AddToNormalTrx(normalTrx); } else if (Splits != null) { foreach (SplitContent split in Splits) { split.AddToNormalTrx(normalTrx); } } else { ThrowTerminatingError(ErrorUtilities.CreateInvalidOperation("Either -OneSplit or -Splits must be specified", "NoSplits")); } Register.ValidationError += Register_ValidationError; try { normalTrx.Validate(); if (TrxValidationError != null) { ThrowTerminatingError(ErrorUtilities.CreateInvalidOperation(TrxValidationError, "InvalidTrx")); } Register.NewAddEnd(normalTrx, new LogAdd(), "PowershellAddNormalTrx"); } finally { Register.ValidationError -= Register_ValidationError; } }
private void OutputNormalTrx(BankTrx trx) { PayeeDef payee = Payees[TrimPayeeName(trx.Description).ToLower()]; TrxOutputType usage = GetPayeeUsage(trx); string exportAccountName = Categories[GetBalanceSheetExportKey(trx.Register.Account.AccountKey.ToString())].ExportName; switch (usage) { case TrxOutputType.Check: if (ContainsPayablesSplit(trx.Splits)) { OutputTransactionPerSplit(trx, exportAccountName, payee, "CHECK", usePayeeOnSplit: SplitIsToAccountsPayable); } else { OutputOneTransaction(trx, exportAccountName, payee, "CHECK", usePayeeOnTrx: true); } break; case TrxOutputType.Deposit: OutputOneTransaction(trx, exportAccountName, payee, "DEPOSIT", usePayeeOnTrx: false); break; case TrxOutputType.JournalEntry: if (ContainsPayablesSplit(trx.Splits)) { OutputTransactionPerSplit(trx, exportAccountName, payee, "GENERAL JOURNAL", usePayeeOnSplit: SplitIsToAccountsPayable); } else { OutputOneTransaction(trx, exportAccountName, payee, "GENERAL JOURNAL", usePayeeOnTrx: true); } break; case TrxOutputType.Bill: OutputOneTransaction(trx, exportAccountName, payee, "BILL", usePayeeOnTrx: true); break; case TrxOutputType.BillCredit: OutputOneTransaction(trx, exportAccountName, payee, "BILL REFUND", usePayeeOnTrx: true); break; } }
private void LoadTrx(BaseTrx trx) { int period = GetPeriod(trx.TrxDate); BankTrx normalTrx = trx as BankTrx; if (normalTrx != null) { if (Handler.IncludeNormalTrx(normalTrx)) { foreach (TrxSplit split in normalTrx.Splits) { if (Handler.IncludeSplit(split)) { if (split.Budget == null) { SplitDetailRow row = GetSplitDetailRow(split); row.Cells[period].Splits.Add(split); } else { BudgetDetailRow budgetRow = GetBudgetDetailRow(split.Budget); budgetRow.Cells[period].Splits.Add(split); } } } } } else { BudgetTrx budgetTrx = trx as BudgetTrx; if (budgetTrx != null) { if (Handler.IncludeBudgetTrx(budgetTrx)) { BudgetDetailRow row = GetBudgetDetailRow(budgetTrx); row.Cells[period].Budgets.Add(budgetTrx); } } } }
private void OutputNormalTrx(BankTrx trx, string transType, string exportAccountName, string payeeName, decimal amount) { OutputLine("TRNS\t\t" + transType + "\t" + trx.TrxDate.ToString("MM/dd/yyyy") + "\t" + exportAccountName + "\t" + payeeName + "\t" + amount.ToString("##############0.00") + "\t" + trx.Number + "\t" + trx.Memo + "\tY\tN"); }
/// <summary> /// Determine all names associated with the transaction, and add any /// new ones to the list that must be defined in the IIF file. /// Does not actually output anything to the IIF file here. /// </summary> /// <param name="trx"></param> private void AnalyzeNormalTrx(BankTrx trx) { PayeeDef payee; string trimmedPayee = TrimPayeeName(trx.Description); string normalizedPayee = trimmedPayee.ToLower(); if (!Payees.TryGetValue(normalizedPayee, out payee)) { payee = new PayeeDef(trimmedPayee, MakeUniquePayeeExportName(trimmedPayee)); Payees.Add(normalizedPayee, payee); } if (trx.TrxDate >= StartDate) { switch (GetPayeeUsage(trx)) { case TrxOutputType.JournalEntry: payee.UsedForGeneralJournal = true; break; case TrxOutputType.Check: payee.UsedForCheck = true; break; } } foreach (TrxSplit split in trx.Splits) { CatDef cat; // Create CatDef objects for balance sheet accounts as well as income/expense accounts. string catExportKey = GetCatExportKey(split.CategoryKey); if (!Categories.TryGetValue(catExportKey, out cat)) { string catName = CatTrans.KeyToValue1(split.CategoryKey); // Categories includes balance sheet accounts StringTransElement catElem = this.Company.Categories.get_GetElement(this.Company.Categories.FindIndexOfKey(split.CategoryKey)); // A null intuitCatType value will cause this category to NOT be output to the IIF file. // This is how we prevent categories that are actually asset, liability and equity accounts // from being output to the IIF as income, expense or COGS account. string intuitCatType; if (split.CategoryKey.IndexOf('.') >= 0) { intuitCatType = null; } else { string catType; intuitCatType = null; if (!catElem.ExtraValues.TryGetValue(CategoryTranslator.TypeKey, out catType)) { catType = CategoryTranslator.TypeOfficeExpense; } if (catType == CategoryTranslator.TypeCOGS) { intuitCatType = "COGS"; } else if (catType == CategoryTranslator.TypeOtherIncome) { intuitCatType = "EXINC"; } else if (catType == CategoryTranslator.TypeOtherExpense) { intuitCatType = "EXEXP"; } else if (catType == CategoryTranslator.TypeTaxes) { intuitCatType = "EXEXP"; } else if (catName.ToUpper().StartsWith("E:")) { intuitCatType = "EXP"; } else if (catName.ToUpper().StartsWith("I:")) { intuitCatType = "INC"; } } cat = new CatDef(catName, MakeCatExportName(split, catName), intuitCatType); Categories.Add(catExportKey, cat); } } }
/// <summary> /// Scan all transactions before generating any output. Used to assemble /// the list of account and payee names, and resolve things like /// duplicate names. /// </summary> /// <returns>Returns "true" unless there was a problem or the user canceled.</returns> private bool AnalyzeTransactions() { // We collect all trx and sort them in date order before analyzing // so that trx payee names and category names are given consistent // export names each time we run the software with later and later // ending dates. The idea is that the export names are assigned the // the first time that name is encountered in date order, and will // not be different for different runs of the software unless old // transactions are changed (which should never happen). List <BankTrx> normalTrxToAnalyze = new List <BankTrx>(); foreach (Account acct in Company.Accounts) { if (!SkipAccount(acct)) { foreach (Register reg in acct.Registers) { bool fakeReportedInReg = false; foreach (BaseTrx trx in reg.GetAllTrx <BaseTrx>()) { if (trx.TrxDate > EndDate) { break; } BankTrx normalTrx = trx as BankTrx; if (normalTrx != null) { if (normalTrx.IsFake) { if (!fakeReportedInReg) { var fakeFoundResponse = HostUI.OkCancelMessageBox("Register \"" + reg.Title + "\" contains fake transaction(s) " + "dated on or before the end date of this export. These transactions will not be included " + "in this export, and likely will be missed in future exports as well even if their " + "\"fake\" box is unchecked because future exports will almost always be for dates " + "after this export. In general you should move all fake transactions past the export end " + "date before doing an export." + Environment.NewLine + Environment.NewLine + "Are you sure you want to continue with this export?"); if (fakeFoundResponse != System.Windows.Forms.DialogResult.OK) { return(false); } fakeReportedInReg = true; } } else { normalTrxToAnalyze.Add(normalTrx); } } } } } } // The important part of this sort order is the date - it must be increasing. // The only purpose of the rest is to make the order consistent from run to run. normalTrxToAnalyze.Sort( delegate(BankTrx trx1, BankTrx trx2) { int result = trx1.TrxDate.CompareTo(trx2.TrxDate); if (result != 0) { return(result); } result = trx1.Number.CompareTo(trx2.Number); if (result != 0) { return(result); } result = trx1.Description.CompareTo(trx2.Description); if (result != 0) { return(result); } return(trx1.Amount.CompareTo(trx2.Amount)); } ); foreach (BankTrx trx in normalTrxToAnalyze) { AnalyzeNormalTrx(trx); } return(true); }
public override bool IncludeNormalTrx(BankTrx normalTrx) { return(true); }
private void btnCalculate_Click(object sender, EventArgs e) { try { DateTime startDate = ctlStartDate.Value.Date; DateTime endDate = ctlEndDate.Value.Date; int interestDays = endDate.Subtract(startDate).Days + 1; if (interestDays < 1) { HostUI.ErrorMessageBox("Start date must be before end date."); return; } IInterestCalculator calculator = (IInterestCalculator)cboInterestType.SelectedItem; if (calculator == null) { HostUI.ErrorMessageBox("Please select an interest type."); return; } string interestCatKey = GetInterestCategoryKey(); if (interestCatKey == null) { HostUI.ErrorMessageBox("Please select an interest category."); return; } decimal annualRate; if (!decimal.TryParse(txtAnnualRate.Text, out annualRate)) { HostUI.ErrorMessageBox("Please enter a valid annual interest rate, like \"9.5\" for 9.5%."); return; } // Compute daily balances from all selected registers decimal startingBalance = 0M; decimal[] dailyTotals = new decimal[interestDays]; foreach (ListViewItem itm in lvwRegisters.CheckedItems) { Register reg = (Register)itm.Tag; foreach (BaseTrx baseTrx in new RegIterator <BaseTrx>(reg)) { if (!baseTrx.IsFake && ((baseTrx is BankTrx) || (baseTrx is ReplicaTrx))) { if (baseTrx.TrxDate < startDate) { startingBalance += baseTrx.Amount; } else if (baseTrx.TrxDate <= endDate) { dailyTotals[baseTrx.TrxDate.Subtract(startDate).Days] += baseTrx.Amount; } else { break; } } } } decimal[] dailyBalances = new decimal[interestDays]; decimal prevBalance = startingBalance; decimal sumDailyBalances = 0M; for (int i = 0; i < interestDays; i++) { dailyBalances[i] = prevBalance + dailyTotals[i]; sumDailyBalances += dailyBalances[i]; prevBalance = dailyBalances[i]; } // Calculate interest decimal annualRateFraction = annualRate / 100M; decimal avgDailyBal = Math.Round(sumDailyBalances / interestDays, 2); decimal totalInterest = Math.Round(calculator.Calculate(startDate, dailyBalances, annualRateFraction), 2); string memo = calculator.Memo(annualRateFraction, avgDailyBal); // Create bank trx in current register BankTrx interestTrx = new BankTrx(HostUI.GetCurrentRegister()); DateTime dummy = DateTime.MinValue; string trxDescription = PersonalAcctExists ? "Interest:DIVIDE" : "Interest"; interestTrx.NewStartNormal(true, "Inv", endDate, trxDescription, memo, BaseTrx.TrxStatus.Unreconciled, false, 0M, false, false, 0, "", ""); interestTrx.AddSplit("", interestCatKey, "", "", Utilities.EmptyDate, Utilities.EmptyDate, "", "", totalInterest); if (!HostUI.AddNormalTrx(interestTrx, ref dummy, false, "Calculate Interest")) { this.Close(); } } catch (Exception ex) { ErrorHandling.TopException(ex); } }
public abstract bool IncludeNormalTrx(BankTrx normalTrx);