Search in sources :

Example 1 with Account

use of jgnash.engine.Account in project jgnash by ccavanaugh.

the class BudgetResultsExport method exportBudgetResultsModel.

/**
     * Exports a {@code BudgetResultsModel} to a spreadsheet.
     * 
     * @param file File to save to
     * @param model Results model to export
     * @return Error message
     */
public static String exportBudgetResultsModel(final Path file, final BudgetResultsModel model) {
    String message = null;
    final ResourceBundle rb = ResourceUtils.getBundle();
    final String extension = FileUtils.getFileExtension(file.toString());
    try (final Workbook wb = extension.equals("xlsx") ? new XSSFWorkbook() : new HSSFWorkbook()) {
        final CreationHelper createHelper = wb.getCreationHelper();
        // create a new sheet
        final Sheet s = wb.createSheet(model.getBudget().getName());
        // create header cell styles
        final CellStyle headerStyle = wb.createCellStyle();
        // create 2 fonts objects
        final Font amountFont = wb.createFont();
        final Font headerFont = wb.createFont();
        amountFont.setFontHeightInPoints((short) 10);
        amountFont.setColor(IndexedColors.BLACK.getIndex());
        headerFont.setFontHeightInPoints((short) 11);
        headerFont.setColor(IndexedColors.BLACK.getIndex());
        headerFont.setBoldweight(Font.BOLDWEIGHT_BOLD);
        // Set the other cell style and formatting
        headerStyle.setBorderBottom(CellStyle.BORDER_THIN);
        headerStyle.setBorderTop(CellStyle.BORDER_THIN);
        headerStyle.setBorderLeft(CellStyle.BORDER_THIN);
        headerStyle.setBorderRight(CellStyle.BORDER_THIN);
        headerStyle.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex());
        headerStyle.setFillPattern(CellStyle.SOLID_FOREGROUND);
        DataFormat df_header = wb.createDataFormat();
        headerStyle.setDataFormat(df_header.getFormat("text"));
        headerStyle.setFont(headerFont);
        headerStyle.setAlignment(CellStyle.ALIGN_CENTER);
        int row = 0;
        Row r = s.createRow(row);
        // create period headers
        for (int i = 0; i < model.getDescriptorList().size(); i++) {
            Cell c = r.createCell(i * 3 + 1);
            c.setCellValue(createHelper.createRichTextString(model.getDescriptorList().get(i).getPeriodDescription()));
            c.setCellStyle(headerStyle);
            s.addMergedRegion(new CellRangeAddress(row, row, i * 3 + 1, i * 3 + 3));
        }
        {
            int col = model.getDescriptorList().size() * 3 + 1;
            Cell c = r.createCell(col);
            c.setCellValue(createHelper.createRichTextString(rb.getString("Title.Summary")));
            c.setCellStyle(headerStyle);
            s.addMergedRegion(new CellRangeAddress(row, row, col, col + 2));
        }
        // create results header columns
        row++;
        r = s.createRow(row);
        {
            Cell c = r.createCell(0);
            c.setCellValue(createHelper.createRichTextString(rb.getString("Column.Account")));
            c.setCellStyle(headerStyle);
            for (int i = 0; i <= model.getDescriptorList().size(); i++) {
                c = r.createCell(i * 3 + 1);
                c.setCellValue(createHelper.createRichTextString(rb.getString("Column.Budgeted")));
                c.setCellStyle(headerStyle);
                c = r.createCell(i * 3 + 2);
                c.setCellValue(createHelper.createRichTextString(rb.getString("Column.Actual")));
                c.setCellStyle(headerStyle);
                c = r.createCell(i * 3 + 3);
                c.setCellValue(createHelper.createRichTextString(rb.getString("Column.Remaining")));
                c.setCellStyle(headerStyle);
            }
        }
        // must sort the accounts, otherwise child structure is not correct
        List<Account> accounts = new ArrayList<>(model.getAccounts());
        accounts.sort(Comparators.getAccountByTreePosition(Comparators.getAccountByCode()));
        // create account rows
        for (final Account account : accounts) {
            final DataFormat df = wb.createDataFormat();
            final DecimalFormat format = (DecimalFormat) CommodityFormat.getFullNumberFormat(account.getCurrencyNode());
            final String pattern = format.toLocalizedPattern().replace("¤", account.getCurrencyNode().getPrefix());
            final CellStyle amountStyle = wb.createCellStyle();
            amountStyle.setFont(amountFont);
            amountStyle.setDataFormat(df.getFormat(pattern));
            // Sets cell indentation, only impacts display if users changes the cell formatting to be left aligned.
            amountStyle.setIndention((short) (model.getDepth(account) * 2));
            row++;
            int col = 0;
            r = s.createRow(row);
            CellStyle cs = wb.createCellStyle();
            cs.cloneStyleFrom(headerStyle);
            cs.setAlignment(CellStyle.ALIGN_LEFT);
            cs.setIndention((short) (model.getDepth(account) * 2));
            Cell c = r.createCell(col);
            c.setCellValue(createHelper.createRichTextString(account.getName()));
            c.setCellStyle(cs);
            List<CellReference> budgetedRefList = new ArrayList<>();
            List<CellReference> changeRefList = new ArrayList<>();
            List<CellReference> remainingRefList = new ArrayList<>();
            for (int i = 0; i < model.getDescriptorList().size(); i++) {
                BudgetPeriodResults results = model.getResults(model.getDescriptorList().get(i), account);
                c = r.createCell(++col);
                c.setCellType(Cell.CELL_TYPE_NUMERIC);
                c.setCellValue(results.getBudgeted().doubleValue());
                c.setCellStyle(amountStyle);
                CellReference budgetedRef = new CellReference(row, col);
                budgetedRefList.add(budgetedRef);
                c = r.createCell(++col);
                c.setCellType(Cell.CELL_TYPE_NUMERIC);
                c.setCellValue(results.getChange().doubleValue());
                c.setCellStyle(amountStyle);
                CellReference changeRef = new CellReference(row, col);
                changeRefList.add(changeRef);
                c = r.createCell(++col);
                c.setCellType(Cell.CELL_TYPE_FORMULA);
                c.setCellStyle(amountStyle);
                c.setCellFormula(budgetedRef.formatAsString() + "-" + changeRef.formatAsString());
                CellReference remainingRef = new CellReference(row, col);
                remainingRefList.add(remainingRef);
            }
            // add summary columns                               
            addSummaryCell(r, ++col, budgetedRefList, amountStyle);
            addSummaryCell(r, ++col, changeRefList, amountStyle);
            addSummaryCell(r, ++col, remainingRefList, amountStyle);
        }
        // add group summary rows
        for (final AccountGroup group : model.getAccountGroupList()) {
            final DataFormat df = wb.createDataFormat();
            final CellStyle amountStyle = wb.createCellStyle();
            amountStyle.setFont(amountFont);
            amountStyle.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex());
            amountStyle.setFillPattern(CellStyle.SOLID_FOREGROUND);
            amountStyle.setBorderBottom(CellStyle.BORDER_THIN);
            amountStyle.setBorderTop(CellStyle.BORDER_THIN);
            amountStyle.setBorderLeft(CellStyle.BORDER_THIN);
            amountStyle.setBorderRight(CellStyle.BORDER_THIN);
            final DecimalFormat format = (DecimalFormat) CommodityFormat.getFullNumberFormat(model.getBaseCurrency());
            final String pattern = format.toLocalizedPattern().replace("¤", model.getBaseCurrency().getPrefix());
            amountStyle.setDataFormat(df.getFormat(pattern));
            row++;
            int col = 0;
            r = s.createRow(row);
            CellStyle cs = wb.createCellStyle();
            cs.cloneStyleFrom(headerStyle);
            cs.setAlignment(CellStyle.ALIGN_LEFT);
            Cell c = r.createCell(col);
            c.setCellValue(createHelper.createRichTextString(group.toString()));
            c.setCellStyle(cs);
            List<CellReference> budgetedRefList = new ArrayList<>();
            List<CellReference> changeRefList = new ArrayList<>();
            List<CellReference> remainingRefList = new ArrayList<>();
            for (int i = 0; i < model.getDescriptorList().size(); i++) {
                BudgetPeriodResults results = model.getResults(model.getDescriptorList().get(i), group);
                c = r.createCell(++col);
                c.setCellType(Cell.CELL_TYPE_NUMERIC);
                c.setCellValue(results.getBudgeted().doubleValue());
                c.setCellStyle(amountStyle);
                CellReference budgetedRef = new CellReference(row, col);
                budgetedRefList.add(budgetedRef);
                c = r.createCell(++col);
                c.setCellType(Cell.CELL_TYPE_NUMERIC);
                c.setCellValue(results.getChange().doubleValue());
                c.setCellStyle(amountStyle);
                CellReference changeRef = new CellReference(row, col);
                changeRefList.add(changeRef);
                c = r.createCell(++col);
                c.setCellType(Cell.CELL_TYPE_FORMULA);
                c.setCellStyle(amountStyle);
                c.setCellFormula(budgetedRef.formatAsString() + "-" + changeRef.formatAsString());
                CellReference remainingRef = new CellReference(row, col);
                remainingRefList.add(remainingRef);
            }
            // add summary columns                               
            addSummaryCell(r, ++col, budgetedRefList, amountStyle);
            addSummaryCell(r, ++col, changeRefList, amountStyle);
            addSummaryCell(r, ++col, remainingRefList, amountStyle);
        }
        // force evaluation
        FormulaEvaluator evaluator = wb.getCreationHelper().createFormulaEvaluator();
        evaluator.evaluateAll();
        short columnCount = s.getRow(1).getLastCellNum();
        // autosize all of the columns + 10 pixels
        for (int i = 0; i <= columnCount; i++) {
            s.autoSizeColumn(i);
            s.setColumnWidth(i, s.getColumnWidth(i) + 10);
        }
        Logger.getLogger(BudgetResultsExport.class.getName()).log(Level.INFO, "{0} cell styles were used", wb.getNumCellStyles());
        // Save
        String filename = file.toString();
        if (wb instanceof XSSFWorkbook) {
            filename = FileUtils.stripFileExtension(filename) + ".xlsx";
        } else {
            filename = FileUtils.stripFileExtension(filename) + ".xls";
        }
        try (final OutputStream out = Files.newOutputStream(Paths.get(filename))) {
            wb.write(out);
        } catch (final Exception e) {
            Logger.getLogger(BudgetResultsExport.class.getName()).log(Level.SEVERE, e.getLocalizedMessage(), e);
            message = e.getLocalizedMessage();
        }
    } catch (IOException e) {
        Logger.getLogger(BudgetResultsExport.class.getName()).log(Level.SEVERE, e.getLocalizedMessage(), e);
    }
    return message;
}
Also used : Account(jgnash.engine.Account) DecimalFormat(java.text.DecimalFormat) OutputStream(java.io.OutputStream) ArrayList(java.util.ArrayList) CellReference(org.apache.poi.ss.util.CellReference) Font(org.apache.poi.ss.usermodel.Font) DataFormat(org.apache.poi.ss.usermodel.DataFormat) XSSFWorkbook(org.apache.poi.xssf.usermodel.XSSFWorkbook) Cell(org.apache.poi.ss.usermodel.Cell) CreationHelper(org.apache.poi.ss.usermodel.CreationHelper) IOException(java.io.IOException) XSSFWorkbook(org.apache.poi.xssf.usermodel.XSSFWorkbook) Workbook(org.apache.poi.ss.usermodel.Workbook) HSSFWorkbook(org.apache.poi.hssf.usermodel.HSSFWorkbook) HSSFWorkbook(org.apache.poi.hssf.usermodel.HSSFWorkbook) IOException(java.io.IOException) AccountGroup(jgnash.engine.AccountGroup) ResourceBundle(java.util.ResourceBundle) CellStyle(org.apache.poi.ss.usermodel.CellStyle) Row(org.apache.poi.ss.usermodel.Row) CellRangeAddress(org.apache.poi.ss.util.CellRangeAddress) Sheet(org.apache.poi.ss.usermodel.Sheet) FormulaEvaluator(org.apache.poi.ss.usermodel.FormulaEvaluator)

Example 2 with Account

use of jgnash.engine.Account in project jgnash by ccavanaugh.

the class BudgetResultsModel method loadAccounts.

private void loadAccounts() {
    final Engine engine = EngineFactory.getEngine(EngineFactory.DEFAULT);
    Objects.requireNonNull(engine);
    Set<Account> accountSet = engine.getAccountList().stream().filter(this::includeAccount).collect(Collectors.toSet());
    accountLock.writeLock().lock();
    try {
        accounts = accountSet;
    } finally {
        accountLock.writeLock().unlock();
    }
}
Also used : RootAccount(jgnash.engine.RootAccount) Account(jgnash.engine.Account) Engine(jgnash.engine.Engine)

Example 3 with Account

use of jgnash.engine.Account in project jgnash by ccavanaugh.

the class BudgetResultsModel method processTransactionEvent.

private void processTransactionEvent(final Message message) {
    final Transaction transaction = message.getObject(MessageProperty.TRANSACTION);
    descriptorList.stream().filter(descriptor -> descriptor.isBetween(transaction.getLocalDate())).forEach(descriptor -> {
        final Set<Account> accountSet = new HashSet<>();
        for (Account account : transaction.getAccounts()) {
            accountSet.addAll(account.getAncestors());
        }
        accountSet.forEach(this::clearCached);
    });
}
Also used : Engine(jgnash.engine.Engine) RootAccount(jgnash.engine.RootAccount) Transaction(jgnash.engine.Transaction) EngineFactory(jgnash.engine.EngineFactory) MessageProxy(jgnash.engine.message.MessageProxy) MathConstants(jgnash.engine.MathConstants) HashMap(java.util.HashMap) ReentrantReadWriteLock(java.util.concurrent.locks.ReentrantReadWriteLock) MessageBus(jgnash.engine.message.MessageBus) ArrayList(java.util.ArrayList) HashSet(java.util.HashSet) BigDecimal(java.math.BigDecimal) MessageProperty(jgnash.engine.message.MessageProperty) MessageChannel(jgnash.engine.message.MessageChannel) Map(java.util.Map) AccountType(jgnash.engine.AccountType) EnumSet(java.util.EnumSet) CurrencyNode(jgnash.engine.CurrencyNode) MessageListener(jgnash.engine.message.MessageListener) ReentrantLock(java.util.concurrent.locks.ReentrantLock) EnumMap(java.util.EnumMap) Comparators(jgnash.engine.Comparators) Set(java.util.Set) Collectors(java.util.stream.Collectors) AccountGroup(jgnash.engine.AccountGroup) Objects(java.util.Objects) List(java.util.List) Account(jgnash.engine.Account) Message(jgnash.engine.message.Message) RootAccount(jgnash.engine.RootAccount) Account(jgnash.engine.Account) Transaction(jgnash.engine.Transaction) HashSet(java.util.HashSet)

Example 4 with Account

use of jgnash.engine.Account in project jgnash by ccavanaugh.

the class BudgetResultsModel method processAccountEvent.

private void processAccountEvent(final Message message) {
    Account account = message.getObject(MessageProperty.ACCOUNT);
    switch(message.getEvent()) {
        case ACCOUNT_ADD:
            accounts.add(account);
            clearCached(account);
            break;
        case ACCOUNT_REMOVE:
            accounts.remove(account);
            clearCached(account);
            break;
        case ACCOUNT_MODIFY:
            // force a reload of accounts, structure is indeterminate
            loadAccounts();
            // indeterminate structure, so dump all cached results
            clearCached();
            break;
        default:
            break;
    }
    // force reload of account groups after accounts have changed
    loadAccountGroups();
}
Also used : RootAccount(jgnash.engine.RootAccount) Account(jgnash.engine.Account)

Example 5 with Account

use of jgnash.engine.Account in project jgnash by ccavanaugh.

the class BudgetResultsModel method processBudgetEvent.

private void processBudgetEvent(final Message message) {
    Budget messageBudget = message.getObject(MessageProperty.BUDGET);
    if (budget.equals(messageBudget)) {
        switch(message.getEvent()) {
            case BUDGET_UPDATE:
                clearCached();
                break;
            case BUDGET_GOAL_UPDATE:
                Account account = message.getObject(MessageProperty.ACCOUNT);
                clearCached(account);
                break;
            case BUDGET_REMOVE:
                unregisterListeners();
                clearCached();
                break;
            default:
        }
    }
}
Also used : RootAccount(jgnash.engine.RootAccount) Account(jgnash.engine.Account)

Aggregations

Account (jgnash.engine.Account)132 Engine (jgnash.engine.Engine)44 BigDecimal (java.math.BigDecimal)40 CurrencyNode (jgnash.engine.CurrencyNode)28 Transaction (jgnash.engine.Transaction)27 ArrayList (java.util.ArrayList)22 LocalDate (java.time.LocalDate)21 ResourceBundle (java.util.ResourceBundle)19 RootAccount (jgnash.engine.RootAccount)18 List (java.util.List)15 AccountType (jgnash.engine.AccountType)15 NumberFormat (java.text.NumberFormat)14 FXML (javafx.fxml.FXML)13 EngineFactory (jgnash.engine.EngineFactory)13 Objects (java.util.Objects)12 Collections (java.util.Collections)11 InvestmentTransaction (jgnash.engine.InvestmentTransaction)11 Tooltip (javafx.scene.control.Tooltip)10 Preferences (java.util.prefs.Preferences)9 Platform (javafx.application.Platform)9