Files
api/services/nginx/app/objects/currency_conversion_rates_o.php
T
Jepp9350 60bcbb6e75 Enhance invoice handling and filtering mechanisms
Refactored invoice draft handling to improve error checks, added support for optional fetch skipping, and enhanced currency management. Expanded filtering capabilities with date range and attribute-based filters. Adjusted Nginx config to increase FastCGI read timeout for long-running processes.
2025-04-07 07:43:47 +02:00

200 lines
6.7 KiB
PHP

<?php
namespace objects;
use classes\db;
use classes\object_property;
use Exception;
use traits\db_object_t;
class currency_conversion_rates_o extends db
{
use db_object_t;
public object_property $currency;
public object_property $rate;
public object_property $updated_at;
public object_property $created_at;
public function structure(): void
{
$this->setTable('currency_conversion_rates');
}
public function asArray(): array
{
return [
'id' => (int)$this->id,
'currency' => (string)$this->currency->value(),
'rate' => (float)$this->rate->value(),
'updated_at' => (string)$this->updated_at->value(),
'created_at' => (string)$this->created_at->value(),
];
}
/**
* Update (or create) the conversion rates
* @param object $currencies The currencies to update (e.g. { "DKK": 1.0, "EUR": 0.5 })
* @return void
* @throws Exception If the currency is not valid
* @throws Exception If the rate is not valid
*/
public function setMany(object $currencies): void
{
// Check if the currencies are valid
if (!is_object($currencies)) {
throw new Exception('The currencies are not valid.');
}
// Check if the currencies are empty
if (empty($currencies)) {
throw new Exception('The currencies are empty.');
}
// Transform the object to an array
$currencies = (array)$currencies;
foreach ( $currencies as $currency => $relative_rate ) {
// Check if the currency is valid
if (!self::validateCurrencyFormat($currency)) {
throw new Exception('The currency is not valid. (' . $currency . ')');
}
// Check if the rate is valid
if ($relative_rate <= 0) {
throw new Exception('The rate is not valid.');
}
// Update the conversion rate
self::set($currency, $relative_rate);
}
}
/**
* Validate the format of a currency
* @note This simply checks if the currency is in the format of up to three uppercase letters.
* @note This does not check if the currency is actually valid.
* @param string $currency
* @return bool
*/
public static function validateCurrencyFormat(string $currency): bool
{
return (bool)preg_match('/^[A-Z]{1,3}$/', $currency);
}
/**
* Update (or create) the conversion rate for a currency
* @param string $currency The currency to update (e.g. "DKK")
* @param float $relative_rate The conversion rate to update (e.g. 1.0)
* @return void
* @throws Exception
*/
public function set(string $currency, float $relative_rate): void
{
global /** @var db $db */
$db;
// Check if the object exists
if (!self::countRowsWhere(['currency' => $currency])) {
// If not, add it
self::add($currency, $relative_rate);
return;
}
// If it does, update it
// Get the object
$result = self::getFieldsWhere(['currency' => $currency], ['id']);
if (empty($result)) {
throw new Exception('The currency conversion rate does exist, but the id was not found.');
}
self::select((int)$result[0]['id']);
// Update the object
$this->rate->set((float)$relative_rate);
self::objectChanged();
}
/**
* Add a new object to the database
* @param string $currency The currency to update (e.g. "DKK")
* @param float $relative_rate The conversion rate to update (e.g. 1.0)
* @return currency_conversion_rates_o
* @throws Exception If the object was not created successfully
*/
public function add(string $currency, float $relative_rate): self
{
global /** @var db $db */
$db;
// Sanitize the input
$currency = $db->escape_string($currency);
$relative_rate = (float)$relative_rate;
// Check if the currency is valid
if (!self::validateCurrencyFormat($currency)) {
throw new Exception('The currency is not valid.');
}
// Check if the rate is valid
if ($relative_rate <= 0) {
throw new Exception('The rate is not valid.');
}
// Add the object
$tmp_id = self::add_object([
'currency' => $currency,
'rate' => $relative_rate,
]);
$this->id = $tmp_id;
self::getObjectProperties();
self::objectChanged();
return $this;
}
public function getObjectProperties(): void
{
$this->currency = new object_property($this->table, $this->id, 'currency', 'string', false);
$this->rate = new object_property($this->table, $this->id, 'rate', 'float', false);
$this->updated_at = new object_property($this->table, $this->id, 'updated_at', 'datetime', false);
$this->created_at = new object_property($this->table, $this->id, 'created_at', 'datetime', false);
}
public function objectChanged(): void
{
//TODO: Add cache invalidation
}
/**
* Convert an amount from the base currency to the target currency
* @param string $currency The target currency (e.g. "EUR")
* @param float $amount The amount to convert in the base currency (e.g. 100) which is 100 DKK
* @throws Exception
*/
public function convertTo(string $currency, float $amount): float
{
// Check if the currency is valid
if (!self::validateCurrencyFormat($currency)) {
throw new Exception('The currency is not valid.');
}
// Check if the amount is valid
if ($amount <= 0) {
throw new Exception('The amount is not valid.');
}
// Convert the amount
return self::getRate($currency) * $amount;
}
/**
* Get the conversion rate for a currency
* @param string $currency The currency to get (e.g. "DKK")
* @return float The conversion rate (e.g. 1.0)
* @throws Exception If the currency is not valid
*/
public function getRate(string $currency): float
{
// Check if the currency is valid
if (!self::validateCurrencyFormat($currency)) {
throw new Exception('The currency is not valid.');
}
// Check if the currency is 'DKK', then return 1.0 (base currency)
if ($currency === 'DKK') {
return 1.0;
}
// Get the conversion rate
$result = self::getFieldsWhere(['currency' => $currency], ['rate']);
if (empty($result)) {
throw new Exception('The currency conversion rate does not exist.');
}
return (float)$result[0]['rate'];
}
}