3 Commits
v1.2 ... master

8 changed files with 54 additions and 12 deletions

View File

@@ -19,6 +19,12 @@ class FinanceHelper extends Base
const INSTALLMENT_CURRENT_KEY = 'financebuddy_installment_current'; const INSTALLMENT_CURRENT_KEY = 'financebuddy_installment_current';
const INSTALLMENT_TOTAL_KEY = 'financebuddy_installment_total'; const INSTALLMENT_TOTAL_KEY = 'financebuddy_installment_total';
// Per-board currency symbol shown before every amount (default "R$"). Up to 4 chars; the stored
// value is trimmed, capped, and defaulted on read, so an empty or oversized value is harmless.
const CURRENCY_KEY = 'financebuddy_currency';
const CURRENCY_DEFAULT = 'R$';
const CURRENCY_MAX_LENGTH = 4;
// Per-column opt-out of the header total. Stored per column in PROJECT metadata as // Per-column opt-out of the header total. Stored per column in PROJECT metadata as
// financebuddy_hide_total_<column_id> = 'on' (hidden) or 'off' (shown, the default). Literal // financebuddy_hide_total_<column_id> = 'on' (hidden) or 'off' (shown, the default). Literal
// on/off, never 1/0, so the flag is never dropped by the metadata save (PHP empty("0") === true). // on/off, never 1/0, so the flag is never dropped by the metadata save (PHP empty("0") === true).
@@ -33,6 +39,9 @@ class FinanceHelper extends Base
// Memoized per project_id: the board hooks below call isEnabled() once per card. // Memoized per project_id: the board hooks below call isEnabled() once per card.
private static $enabledCache = array(); private static $enabledCache = array();
// Memoized per project_id: currency() is likewise resolved once per card/column render.
private static $currencyCache = array();
/** /**
* Is FinanceBuddy enabled for this board? * Is FinanceBuddy enabled for this board?
* *
@@ -50,6 +59,26 @@ class FinanceHelper extends Base
return self::$enabledCache[$project_id]; return self::$enabledCache[$project_id];
} }
/**
* Per-board currency symbol shown before amounts: the stored value trimmed and capped to
* CURRENCY_MAX_LENGTH, or CURRENCY_DEFAULT ("R$") when empty. Memoized per project.
*
* @param integer $project_id
* @return string
*/
public function currency($project_id)
{
$project_id = (int) $project_id;
if (! isset(self::$currencyCache[$project_id])) {
$symbol = trim((string) $this->projectMetadataModel->get($project_id, self::CURRENCY_KEY, ''));
$symbol = mb_substr($symbol, 0, self::CURRENCY_MAX_LENGTH);
self::$currencyCache[$project_id] = $symbol === '' ? self::CURRENCY_DEFAULT : $symbol;
}
return self::$currencyCache[$project_id];
}
/** /**
* Stored finance values for a task, with defaults. One query (getAll) since the board renders * Stored finance values for a task, with defaults. One query (getAll) since the board renders
* this per card. * this per card.

View File

@@ -85,7 +85,7 @@ class Plugin extends Base
public function getPluginVersion() public function getPluginVersion()
{ {
return '1.2.0'; return '1.3.0';
} }
public function getPluginHomepage() public function getPluginHomepage()

View File

@@ -30,7 +30,7 @@ Once a board is enabled:
The task edit/create form gains a **Finance** section in the middle column: The task edit/create form gains a **Finance** section in the middle column:
- **Amount** in R$. - **Amount** in the board's currency (default R$).
- **Debit** or **Credit** (money out vs money in). - **Debit** or **Credit** (money out vs money in).
- **Installment** current / total (for example `2` of `10`). Leave the total blank for an - **Installment** current / total (for example `2` of `10`). Leave the total blank for an
open-ended recurring bill. open-ended recurring bill.
@@ -66,9 +66,13 @@ counting.
## Money format ## Money format
Amounts show in R$ with a comma decimal and no thousand separator (for example `R$1234,56`). Amounts show with a comma decimal and no thousand separator (for example `R$1234,56`). Input
Input accepts either a dot or a comma as the decimal separator, so `1234.56` and `1234,56` are accepts either a dot or a comma as the decimal separator, so `1234.56` and `1234,56` are the same
the same value. value.
The currency symbol shown before every amount is **per board**: set it under
Settings -> Integrations next to the enable checkbox (up to 4 characters, e.g. `US$`, `EUR`, `GBP`).
Leave it empty for the default `R$`.
## How it stores data ## How it stores data
@@ -92,13 +96,16 @@ Settings -> Integrations and tick "Enable FinanceBuddy on this board".
AGPL-3.0. See LICENSE. AGPL-3.0. See LICENSE.
## More Kanboard plugins by Ruben (drbeco) ## More Kanboard plugins by Dr. Beco
All free and AGPL-3.0, at [code.beco.cc](https://code.beco.cc/beco): All free and AGPL-3.0, at [code.beco.cc](https://code.beco.cc/beco):
- **[RecoReco](https://code.beco.cc/beco/RecoReco)** -- calendar-scheduled recurring cards (yearly, - **[RecoReco](https://code.beco.cc/beco/RecoReco)** -- calendar-scheduled recurring cards (yearly,
monthly, weekly, daily), driven by the card due date. Pairs directly with FinanceBuddy: recurring monthly, weekly, daily), driven by the card due date.
bills spawn on schedule and their installments count down until the plan is paid off. - **[QualKard](https://code.beco.cc/beco/QualKard)** -- flashcard spaced repetition: grade a card by
dragging it to a column, and it comes back when due (needs RecoReco).
- **[WorkspaceOrg](https://code.beco.cc/beco/WorkspaceOrg)** -- group your projects into personal
per-user workspaces, shown on a "My workspaces" dashboard page with a badge on each project.
- **[OrganonTweaks](https://code.beco.cc/beco/OrganonTweaks)** -- an umbrella of small - **[OrganonTweaks](https://code.beco.cc/beco/OrganonTweaks)** -- an umbrella of small
quality-of-life board tweaks: remove an empty column, always show the comment icon, emphasize due quality-of-life board tweaks: remove an empty column, always show the comment icon, emphasize due
dates, extra search keywords and shared board filters, and more. dates, extra search keywords and shared board filters, and more.

View File

@@ -26,5 +26,5 @@ if ($net > 0) {
} }
?> ?>
<div class="fb-column-total"> <div class="fb-column-total">
<span class="fb-total-pill"><?= t('Total') ?>: <span class="fb-amount <?= $amount_class ?>"><?= $sign ?>R$<?= \Kanboard\Plugin\FinanceBuddy\Helper\FinanceHelper::money(abs($net)) ?></span></span> <span class="fb-total-pill"><?= t('Total') ?>: <span class="fb-amount <?= $amount_class ?>"><?= $sign ?><?= $this->text->e($this->FinanceHelper->currency($column['project_id'])) ?><?= \Kanboard\Plugin\FinanceBuddy\Helper\FinanceHelper::money(abs($net)) ?></span></span>
</div> </div>

View File

@@ -24,7 +24,7 @@ $current_display = $current !== '' ? $current : '1';
?> ?>
<div class="fb-line"> <div class="fb-line">
<span class="fb-badge <?= $credit ? 'fb-badge-credit' : 'fb-badge-debit' ?>"> <span class="fb-badge <?= $credit ? 'fb-badge-credit' : 'fb-badge-debit' ?>">
<?= $sign ?>R$<?= \Kanboard\Plugin\FinanceBuddy\Helper\FinanceHelper::money($fb['amount']) ?> <?= $sign ?><?= $this->text->e($this->FinanceHelper->currency($task['project_id'])) ?><?= \Kanboard\Plugin\FinanceBuddy\Helper\FinanceHelper::money($fb['amount']) ?>
</span> </span>
<?php if ($show_installments): ?> <?php if ($show_installments): ?>
<span class="fb-installments">p<?= $this->text->e($current_display) ?><?= $total !== '' ? '/'.$this->text->e($total) : '' ?></span> <span class="fb-installments">p<?= $this->text->e($current_display) ?><?= $total !== '' ? '/'.$this->text->e($total) : '' ?></span>

View File

@@ -13,6 +13,12 @@
<p class="form-help"> <p class="form-help">
<?= t('When enabled, cards on this board can carry a money value (debit or credit, with optional installments), shown on the card and totalled per column. Boards left disabled are unaffected.') ?> <?= t('When enabled, cards on this board can carry a money value (debit or credit, with optional installments), shown on the card and totalled per column. Boards left disabled are unaffected.') ?>
</p> </p>
<?= $this->form->label(t('Currency symbol'), 'financebuddy_currency') ?>
<?= $this->form->text('financebuddy_currency', $values, array(), array('maxlength="4"', 'placeholder="R$"')) ?>
<p class="form-help">
<?= t('Shown before every amount on this board (up to 4 characters). Leave empty for the default R$.') ?>
</p>
</div> </div>
<div class="form-actions"> <div class="form-actions">

View File

@@ -5,7 +5,7 @@
<div class="fb-form"> <div class="fb-form">
<input type="hidden" name="<?= \Kanboard\Plugin\FinanceBuddy\Helper\FinanceHelper::FORM_MARKER ?>" value="1"> <input type="hidden" name="<?= \Kanboard\Plugin\FinanceBuddy\Helper\FinanceHelper::FORM_MARKER ?>" value="1">
<label for="financebuddy_amount"><?= t('Amount (R$)') ?></label> <label for="financebuddy_amount"><?= $this->text->e(t('Amount (%s)', $this->FinanceHelper->currency($values['project_id']))) ?></label>
<input type="text" id="financebuddy_amount" name="financebuddy_amount" value="<?= $this->text->e($fb['amount']) ?>" placeholder="0,00" autocomplete="off"> <input type="text" id="financebuddy_amount" name="financebuddy_amount" value="<?= $this->text->e($fb['amount']) ?>" placeholder="0,00" autocomplete="off">
<label><?= t('Type') ?></label> <label><?= t('Type') ?></label>

View File

@@ -1 +1 @@
FinanceBuddy v1.2.0 FinanceBuddy v1.3.0