Merge pull request #53 from ttam/feature/format-currency

Format currency in users locale
This commit is contained in:
Miguel Ribeiro 2023-11-16 13:46:34 +01:00 committed by GitHub
commit 732aed35a2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 46 additions and 48 deletions

View File

@ -10,9 +10,10 @@ RUN apk add --no-cache sqlite-dev \
&& docker-php-ext-enable pdo pdo_sqlite && docker-php-ext-enable pdo pdo_sqlite
# Install additional PHP extensions and dependencies # Install additional PHP extensions and dependencies
RUN apk add --no-cache libpng libpng-dev libjpeg-turbo libjpeg-turbo-dev freetype freetype-dev curl autoconf libgomp \ RUN apk add --no-cache libpng libpng-dev libjpeg-turbo libjpeg-turbo-dev freetype freetype-dev curl autoconf libgomp icu-dev \
&& docker-php-ext-configure gd --with-freetype --with-jpeg \ && docker-php-ext-configure gd --with-freetype --with-jpeg \
&& docker-php-ext-install -j$(nproc) gd && docker-php-ext-install -j$(nproc) gd \
&& docker-php-ext-install intl
# Install Imagick extension # Install Imagick extension
RUN apk add --no-cache imagemagick imagemagick-dev \ RUN apk add --no-cache imagemagick imagemagick-dev \

View File

@ -49,6 +49,7 @@ See instructions to run Wallos below.
- curl - curl
- gd - gd
- imagick - imagick
- intl
- openssl - openssl
- sqlite3 - sqlite3

View File

@ -2,6 +2,7 @@
require_once '../../includes/connect_endpoint.php'; require_once '../../includes/connect_endpoint.php';
session_start(); session_start();
require_once '../../includes/currency_formatter.php';
require_once '../../includes/getdbkeys.php'; require_once '../../includes/getdbkeys.php';
include_once '../../includes/list_subscriptions.php'; include_once '../../includes/list_subscriptions.php';
@ -44,7 +45,7 @@
$frequency = $subscription['frequency']; $frequency = $subscription['frequency'];
$print[$id]['billing_cycle'] = getBillingCycle($cycle, $frequency); $print[$id]['billing_cycle'] = getBillingCycle($cycle, $frequency);
$paymentMethodId = $subscription['payment_method_id']; $paymentMethodId = $subscription['payment_method_id'];
$print[$id]['currency'] = $currencies[$subscription['currency_id']]['symbol']; $print[$id]['currency_code'] = $currencies[$subscription['currency_id']]['code'];
$currencyId = $subscription['currency_id']; $currencyId = $subscription['currency_id'];
$print[$id]['next_payment'] = date('M d, Y', strtotime($subscription['next_payment'])); $print[$id]['next_payment'] = date('M d, Y', strtotime($subscription['next_payment']));
$print[$id]['payment_method_icon'] = "images/uploads/icons/" . $payment_methods[$paymentMethodId]['icon']; $print[$id]['payment_method_icon'] = "images/uploads/icons/" . $payment_methods[$paymentMethodId]['icon'];
@ -55,16 +56,15 @@
if (isset($_COOKIE['convertCurrency']) && $_COOKIE['convertCurrency'] === 'true' && $currencyId != $mainCurrencyId) { if (isset($_COOKIE['convertCurrency']) && $_COOKIE['convertCurrency'] === 'true' && $currencyId != $mainCurrencyId) {
$print[$id]['price'] = getPriceConverted($print[$id]['price'], $currencyId, $db); $print[$id]['price'] = getPriceConverted($print[$id]['price'], $currencyId, $db);
$print[$id]['currency'] = $currencies[$mainCurrencyId]['symbol']; $print[$id]['currency_code'] = $currencies[$mainCurrencyId]['code'];
} }
if (isset($_COOKIE['showMonthlyPrice']) && $_COOKIE['showMonthlyPrice'] === 'true') { if (isset($_COOKIE['showMonthlyPrice']) && $_COOKIE['showMonthlyPrice'] === 'true') {
$print[$id]['price'] = getPricePerMonth($cycle, $frequency, $print[$id]['price']); $print[$id]['price'] = getPricePerMonth($cycle, $frequency, $print[$id]['price']);
} }
$print[$id]['price'] = number_format($print[$id]['price'], 2, ".", "");
} }
if (isset($print)) { if (isset($print)) {
printSubscriptons($print, $sort, $categories, $members); printSubscriptions($print, $sort, $categories, $members);
} }
if (count($subscriptions) == 0) { if (count($subscriptions) == 0) {

View File

@ -0,0 +1,20 @@
<?php
final class CurrencyFormatter
{
private static $instance;
private static function getInstance()
{
if (self::$instance === null) {
self::$instance = new NumberFormatter(Locale::acceptFromHttp($_SERVER['HTTP_ACCEPT_LANGUAGE']), NumberFormatter::CURRENCY);
}
return self::$instance;
}
public static function format($amount, $currency)
{
return self::getInstance()->formatCurrency($amount, $currency);
}
}

View File

@ -2,6 +2,7 @@
require_once 'connect.php'; require_once 'connect.php';
require_once 'checkuser.php'; require_once 'checkuser.php';
require_once 'checksession.php'; require_once 'checksession.php';
require_once 'currency_formatter.php';
if ($userCount == 0) { if ($userCount == 0) {
$db->close(); $db->close();

View File

@ -54,7 +54,7 @@
} }
} }
function printSubscriptons($subscriptions, $sort, $categories, $members) { function printSubscriptions($subscriptions, $sort, $categories, $members) {
if ($sort === "price") { if ($sort === "price") {
usort($subscriptions, function($a, $b) { usort($subscriptions, function($a, $b) {
return $a['price'] < $b['price'] ? 1 : -1; return $a['price'] < $b['price'] ? 1 : -1;
@ -89,7 +89,7 @@
<span class="next"><?= $subscription['next_payment'] ?></span> <span class="next"><?= $subscription['next_payment'] ?></span>
<span class="price"> <span class="price">
<img src="<?= $subscription['payment_method_icon'] ?>" title="Payment Method: <?= $subscription['payment_method_name'] ?>"/> <img src="<?= $subscription['payment_method_icon'] ?>" title="Payment Method: <?= $subscription['payment_method_name'] ?>"/>
<?= $subscription['price'] ?><?= $subscription['currency'] ?> <?= CurrencyFormatter::format($subscription['price'], $subscription['currency_code']) ?>
</span> </span>
<span class="actions"> <span class="actions">
<button class="image-button medium" onClick="openEditSubscription(event, <?= $subscription['id'] ?>)" name="edit"> <button class="image-button medium" onClick="openEditSubscription(event, <?= $subscription['id'] ?>)" name="edit">

View File

@ -72,7 +72,7 @@
$frequency = $subscription['frequency']; $frequency = $subscription['frequency'];
$print[$id]['billing_cycle'] = getBillingCycle($cycle, $frequency); $print[$id]['billing_cycle'] = getBillingCycle($cycle, $frequency);
$paymentMethodId = $subscription['payment_method_id']; $paymentMethodId = $subscription['payment_method_id'];
$print[$id]['currency'] = $currencies[$subscription['currency_id']]['symbol']; $print[$id]['currency_code'] = $currencies[$subscription['currency_id']]['code'];
$currencyId = $subscription['currency_id']; $currencyId = $subscription['currency_id'];
$print[$id]['next_payment'] = date('M d, Y', strtotime($subscription['next_payment'])); $print[$id]['next_payment'] = date('M d, Y', strtotime($subscription['next_payment']));
$print[$id]['payment_method_icon'] = "images/uploads/icons/" . $payment_methods[$paymentMethodId]['icon']; $print[$id]['payment_method_icon'] = "images/uploads/icons/" . $payment_methods[$paymentMethodId]['icon'];
@ -83,16 +83,15 @@
if (isset($_COOKIE['convertCurrency']) && $_COOKIE['convertCurrency'] === 'true' && $currencyId != $mainCurrencyId) { if (isset($_COOKIE['convertCurrency']) && $_COOKIE['convertCurrency'] === 'true' && $currencyId != $mainCurrencyId) {
$print[$id]['price'] = getPriceConverted($print[$id]['price'], $currencyId, $db); $print[$id]['price'] = getPriceConverted($print[$id]['price'], $currencyId, $db);
$print[$id]['currency'] = $currencies[$mainCurrencyId]['symbol']; $print[$id]['currency_code'] = $currencies[$mainCurrencyId]['code'];
} }
if (isset($_COOKIE['showMonthlyPrice']) && $_COOKIE['showMonthlyPrice'] === 'true') { if (isset($_COOKIE['showMonthlyPrice']) && $_COOKIE['showMonthlyPrice'] === 'true') {
$print[$id]['price'] = getPricePerMonth($cycle, $frequency, $print[$id]['price']); $print[$id]['price'] = getPricePerMonth($cycle, $frequency, $print[$id]['price']);
} }
$print[$id]['price'] = number_format($print[$id]['price'], 2, ".", "");
} }
if (isset($print)) { if (isset($print)) {
printSubscriptons($print, $sort, $categories, $members); printSubscriptions($print, $sort, $categories, $members);
} }
$db->close(); $db->close();

View File

@ -1,4 +1,4 @@
function loadGraph(container, dataPoints, symbol, run) { function loadGraph(container, dataPoints, currency, run) {
if (run) { if (run) {
var ctx = document.getElementById(container).getContext('2d'); var ctx = document.getElementById(container).getContext('2d');
@ -8,7 +8,7 @@ function loadGraph(container, dataPoints, symbol, run) {
datasets: [{ datasets: [{
data: dataPoints.map(point => point.y), data: dataPoints.map(point => point.y),
}], }],
labels: dataPoints.map(point => `${point.label} (${point.y}${symbol})`), labels: dataPoints.map(point => `(${new Intl.NumberFormat(navigator.language, { style: 'currency', currency }).format(point.y)})`),
}, },
options: { options: {
animation: { animation: {

View File

@ -64,15 +64,15 @@ while ($row = $result->fetchArray(SQLITE3_ASSOC)) {
$categoryCost[$categoryId]['name'] = $row['name']; $categoryCost[$categoryId]['name'] = $row['name'];
} }
// Get symbol of main currency to display on statistics // Get code of main currency to display on statistics
$query = "SELECT c.symbol $query = "SELECT c.code
FROM currencies c FROM currencies c
INNER JOIN user u ON c.id = u.main_currency INNER JOIN user u ON c.id = u.main_currency
WHERE u.id = 1"; WHERE u.id = 1";
$stmt = $db->prepare($query); $stmt = $db->prepare($query);
$result = $stmt->execute(); $result = $stmt->execute();
$row = $result->fetchArray(SQLITE3_ASSOC); $row = $result->fetchArray(SQLITE3_ASSOC);
$symbol = $row['symbol']; $code = $row['code'];
// Calculate active subscriptions // Calculate active subscriptions
@ -113,16 +113,6 @@ if ($result) {
$mostExpensiveSubscription = $price; $mostExpensiveSubscription = $price;
} }
$memberCost[$payerId]['cost'] = number_format($memberCost[$payerId]['cost'], 2, ".", "");
if ((int)$memberCost[$payerId]['cost'] == $memberCost[$payerId]['cost']) {
$memberCost[$payerId]['cost'] = (int)$memberCost[$payerId]['cost'];
}
$categoryCost[$categoryId]['cost'] = number_format($categoryCost[$categoryId]['cost'], 2, ".", "");
if ((int)$categoryCost[$categoryId]['cost'] == $categoryCost[$categoryId]['cost']) {
$categoryCost[$categoryId]['cost'] = (int)$categoryCost[$categoryId]['cost'];
}
// Calculate ammount due this month // Calculate ammount due this month
$nextPaymentDate = DateTime::createFromFormat('Y-m-d', trim($next_payment)); $nextPaymentDate = DateTime::createFromFormat('Y-m-d', trim($next_payment));
$tomorrow = new DateTime('tomorrow'); $tomorrow = new DateTime('tomorrow');
@ -144,26 +134,12 @@ if ($result) {
} }
} }
$mostExpensiveSubscription = number_format($mostExpensiveSubscription, 2, ".", "");
// Calculate yearly price // Calculate yearly price
$totalCostPerYear = $totalCostPerMonth * 12; $totalCostPerYear = $totalCostPerMonth * 12;
$totalCostPerYear = number_format($totalCostPerYear, 2, ".", "");
if ((int)$totalCostPerYear == $totalCostPerYear) {
$totalCostPerYear = (int)$totalCostPerYear;
}
// Calculate average subscription monthly cost // Calculate average subscription monthly cost
$averageSubscriptionCost = $totalCostPerMonth / $activeSubscriptions; $averageSubscriptionCost = $totalCostPerMonth / $activeSubscriptions;
$averageSubscriptionCost = number_format($averageSubscriptionCost, 2, ".", "");
if ((int)$averageSubscriptionCost == $averageSubscriptionCost) {
$averageSubscriptionCost = (int)$averageSubscriptionCost;
}
$totalCostPerMonth = number_format($totalCostPerMonth, 2, ".", "");
if ((int)$totalCostPerMonth == $totalCostPerMonth) {
$totalCostPerMonth = (int)$totalCostPerMonth;
}
} else { } else {
$totalCostPerYear = 0; $totalCostPerYear = 0;
$averageSubscriptionCost = 0; $averageSubscriptionCost = 0;
@ -179,23 +155,23 @@ if ($result) {
<div class="title">Active Subscriptions</div> <div class="title">Active Subscriptions</div>
</div> </div>
<div class="statistic"> <div class="statistic">
<span><?= $totalCostPerMonth ?><?= $symbol ?></span> <span><?= CurrencyFormatter::format($totalCostPerMonth, $code) ?></span>
<div class="title">Monthly Cost</div> <div class="title">Monthly Cost</div>
</div> </div>
<div class="statistic"> <div class="statistic">
<span><?= $totalCostPerYear ?><?= $symbol ?></span> <span><?= CurrencyFormatter::format($totalCostPerYear, $code) ?></span>
<div class="title">Yearly Cost</div> <div class="title">Yearly Cost</div>
</div> </div>
<div class="statistic"> <div class="statistic">
<span><?= $averageSubscriptionCost ?><?= $symbol ?></span> <span><?= CurrencyFormatter::format($averageSubscriptionCost, $code) ?></span>
<div class="title">Average Monthly Subscription Cost</div> <div class="title">Average Monthly Subscription Cost</div>
</div> </div>
<div class="statistic"> <div class="statistic">
<span><?= $mostExpensiveSubscription ?><?= $symbol ?></span> <span><?= CurrencyFormatter::format($mostExpensiveSubscription, $code) ?></span>
<div class="title">Most Expensive Subscription Cost</div> <div class="title">Most Expensive Subscription Cost</div>
</div> </div>
<div class="statistic"> <div class="statistic">
<span><?= number_format($amountDueThisMonth, 2, ".", "") ?><?= $symbol ?></span> <span><?= CurrencyFormatter::format($amountDueThisMonth, $code) ?></span>
<div class="title">Amount due this month</div> <div class="title">Amount due this month</div>
</div> </div>
<?php <?php
@ -267,8 +243,8 @@ if ($result) {
<script src="scripts/libs/chart.js"></script> <script src="scripts/libs/chart.js"></script>
<script type="text/javascript"> <script type="text/javascript">
window.onload = function() { window.onload = function() {
loadGraph("categorySplitChart", <?php echo json_encode($categoryDataPoints, JSON_NUMERIC_CHECK); ?>, "<?= $symbol ?>", <?= $showCategoryCostGraph ?>); loadGraph("categorySplitChart", <?php echo json_encode($categoryDataPoints, JSON_NUMERIC_CHECK); ?>, "<?= $code ?>", <?= $showCategoryCostGraph ?>);
loadGraph("memberSplitChart", <?php echo json_encode($memberDataPoints, JSON_NUMERIC_CHECK); ?>, "<?= $symbol ?>", <?= $showMemberCostGraph ?>); loadGraph("memberSplitChart", <?php echo json_encode($memberDataPoints, JSON_NUMERIC_CHECK); ?>, "<?= $code ?>", <?= $showMemberCostGraph ?>);
} }
</script> </script>
<?php <?php