Exemple #1
0
// Generate reports to output directory.
func (report *Report) Generate(outputDir string) error {
	var buf bytes.Buffer
	var filename string

	switch report.period {
	case ReportPeriodInfinite:
		fmt.Fprintf(&buf, "All transactions\n\n")
		filename = filepath.Join(outputDir, "all.txt")
	case ReportPeriodYearly:
		fmt.Fprintf(&buf, "%d\n\n", report.from.Year())
		filename = filepath.Join(outputDir, fmt.Sprintf("%d.txt", report.from.Year()))
	case ReportPeriodQuarterly:
		quarterName := fmt.Sprintf("Q%d", (report.from.Month()-1)/3+1)
		fmt.Fprintf(&buf, "%s %d\n\n", quarterName, report.from.Year())
		filename = filepath.Join(outputDir, fmt.Sprintf("%d-%s.txt", report.from.Year(), quarterName))
	case ReportPeriodMonthly:
		fmt.Fprintf(&buf, "%s %d\n\n", report.from.Month(), report.from.Year())
		filename = filepath.Join(outputDir, fmt.Sprintf("%d-%02d.txt", report.from.Year(), report.from.Month()))
	default:
		return fmt.Errorf("unsupported report period %d", report.period)
	}

	file, err := os.Create(filename)
	if err != nil {
		return err
	}
	defer file.Close()

	var accounts []*Account
	for _, account := range report.accounts {
		accounts = append(accounts, account)
	}
	sort.Sort(sortByAccountName(accounts))

	// Account summary
	t := new(table.Table)
	t.SetTitles(table.Row{
		{Content: "account"},
		{Content: "amount"},
		{Content: "cumulative"},
		{Content: "delta"},
	})

	for _, account := range accounts {
		cumulativeStr := balanceToString(account.CumulativeBalance())
		deltaStr := fmt.Sprintf("%+.2f", report.AccountDelta(account.name))

		if cumulativeStr != "-" || deltaStr != "+0.00" {
			t.AddRow(table.Row{
				{Content: account.name.Leaf(), PadLeft: uint(indentAmount * account.name.Depth())},
				{Content: balanceToString(account.FlatBalance()), Align: table.AlignRight},
				{Content: cumulativeStr, Align: table.AlignRight},
				{Content: deltaStr, Align: table.AlignRight},
			})
		}
	}
	buf.Write(t.RenderText())

	// Transaction log
	fmt.Fprintf(&buf, "\nTransactions\n\n")

	t = new(table.Table)
	t.SetTitles(table.Row{
		{Content: "date"},
		{Content: "account"},
		{Content: "debit"},
		{Content: "credit"},
	})

	var prevDate time.Time
	for _, tr := range report.transactions {
		var dateStr string
		if tr.date != prevDate {
			dateStr = tr.date.Format(transactionDateFormat)
		}
		prevDate = tr.date

		t.AddRow(table.Row{
			{Content: dateStr},
			{Content: string(tr.accounts[Dr])},
			{Content: fmt.Sprintf("%.2f", tr.amount), Align: table.AlignRight},
			{Content: ""},
		})
		t.AddRow(table.Row{
			{Content: ""},
			{Content: string(tr.accounts[Cr])},
			{Content: ""},
			{Content: fmt.Sprintf("%.2f", tr.amount), Align: table.AlignRight},
		})
	}
	buf.Write(t.RenderText())

	fmt.Fprintf(file, "%s", buf.Bytes())
	return nil
}