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.
200 lines
6.7 KiB
PHP
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'];
|
|
}
|
|
|
|
} |