orm entity: prepare decimal

This commit is contained in:
Yuri Kuznetsov
2025-03-18 10:04:49 +02:00
parent 4270a452a7
commit 67702f5a55
2 changed files with 67 additions and 2 deletions
+30
View File
@@ -29,6 +29,7 @@
namespace Espo\ORM;
use Doctrine\DBAL\Types\Types;
use Espo\ORM\DataLoader\EmptyLoader;
use Espo\ORM\DataLoader\Loader;
use Espo\ORM\Defs\Params\AttributeParam;
@@ -482,6 +483,13 @@ class BaseEntity implements Entity
$attributeType = $this->getAttributeType($attribute);
if (
$attributeType === self::VARCHAR &&
$this->getAttributeParam($attribute, AttributeParam::DB_TYPE) === Types::DECIMAL
) {
return $this->prepareAttributeValueDecimal($attribute, $value);
}
if ($attributeType === self::FOREIGN) {
$attributeType = $this->getForeignAttributeType($attribute) ?? $attributeType;
}
@@ -1165,4 +1173,26 @@ class BaseEntity implements Entity
$this->loader->load($this);
}
private function prepareAttributeValueDecimal(string $attribute, mixed $value): ?string
{
if (!is_scalar($value) || !is_numeric($value)) {
return null;
}
$scale = $this->getAttributeParam($attribute, AttributeParam::SCALE);
$value = strval($value);
$parts = explode('.', $value, 2);
$left = $parts[0];
$right = $parts[1] ?? '';
if (strlen($right) < $scale) {
$value = $left . '.' . str_pad($right, $scale, '0');
}
return $value;
}
}
@@ -29,6 +29,7 @@
namespace tests\integration\Espo\Currency;
use Espo\Core\Exceptions\Error;
use Espo\Core\Formula\Manager as FormulaManager;
use Espo\Modules\Crm\Entities\Lead;
use Espo\Tools\Currency\RateService;
@@ -67,6 +68,9 @@ class CurrencyTest extends \tests\integration\Core\BaseTestCase
$this->assertEquals(1.3, $newRates->getRate('EUR'));
}
/**
* @throws Error
*/
public function testDecimal1(): void
{
$this->getMetadata()->set('entityDefs', 'Lead', [
@@ -82,12 +86,20 @@ class CurrencyTest extends \tests\integration\Core\BaseTestCase
$this->getDataManager()->rebuild();
$this->reCreateApplication();
$em = $this->getEntityManager();
$value = Currency::create('10.1', 'USD')
->add(Currency::create('0.1', 'USD'));
/** @var Lead $lead */
$lead = $this->getEntityManager()->getNewEntity(Lead::ENTITY_TYPE);
$lead = $em->getRDBRepositoryByClass(Lead::class)->getNew();
$lead->setValueObject('testCurrency', $value);
$value = $lead->getValueObject('testCurrency');
$this->assertInstanceOf(Currency::class, $value);
$this->assertEquals('10.2000', $value->getAmountAsString());
$this->getEntityManager()->saveEntity($lead);
/** @var Lead $lead */
@@ -98,6 +110,29 @@ class CurrencyTest extends \tests\integration\Core\BaseTestCase
$this->assertInstanceOf(Currency::class, $value);
$this->assertEquals('10.2000', $value->getAmountAsString());
$this->assertEquals(0, $value->compare(Currency::create('10.2', 'USD')));
//
$lead = $em->getRDBRepositoryByClass(Lead::class)->getNew();
$value = Currency::create('10', 'USD');
$lead->setValueObject('testCurrency', $value);
$value = $lead->getValueObject('testCurrency');
$this->assertInstanceOf(Currency::class, $value);
$this->assertEquals('10.0000', $value->getAmountAsString());
//
$lead = $em->getRDBRepositoryByClass(Lead::class)->getNew();
$lead->setValueObject('testCurrency', null);
$value = $lead->getValueObject('testCurrency');
$this->assertEquals(null, $value);
}
public function testFormulaConvert(): void