diff --git a/src/Entity/Parts/Part.php b/src/Entity/Parts/Part.php index 2363ff3f..de6867ea 100644 --- a/src/Entity/Parts/Part.php +++ b/src/Entity/Parts/Part.php @@ -727,7 +727,7 @@ class Part extends AttachmentContainingDBElement { //TODO: Find a method to do this natively in SQL, the current method could be a bit slow $sum = 0; - foreach($this->getPartLots() as $lot) { + foreach ($this->getPartLots() as $lot) { //Dont use the instock value, if it is unkown if ($lot->isInstockUnknown()) { continue; @@ -736,7 +736,7 @@ class Part extends AttachmentContainingDBElement $sum += $lot->getAmount(); } - if(!$this->useFloatAmount()) { + if ($this->useFloatAmount()) { return $sum; } diff --git a/src/Services/AmountFormatter.php b/src/Services/AmountFormatter.php new file mode 100644 index 00000000..52879848 --- /dev/null +++ b/src/Services/AmountFormatter.php @@ -0,0 +1,131 @@ +siFormatter = $siFormatter; + } + + protected function configureOptions(OptionsResolver $resolver) + { + $resolver->setDefaults([ + 'show_prefix' => function (Options $options) { + if ($options['measurement_unit'] !== null) { + /** @var MeasurementUnit $unit */ + $unit = $options['measurement_unit']; + return $unit->isUseSIPrefix(); + } + return true; + }, + 'is_integer' => function (Options $options) { + if ($options['measurement_unit'] !== null) { + /** @var MeasurementUnit $unit */ + $unit = $options['measurement_unit']; + return $unit->isInteger(); + } + return true; + }, + 'unit' => function (Options $options) { + if ($options['measurement_unit'] !== null) { + /** @var MeasurementUnit $unit */ + $unit = $options['measurement_unit']; + return $unit->getUnit(); + } + return ''; + }, + 'decimals' => 2, + 'error_mapping' => [ '.' => 'value'] + ]); + + $resolver->setAllowedTypes('decimals', 'int'); + + $resolver->setNormalizer('decimals', function (Options $options, $value) { + // If the unit is integer based, then dont show any decimals + if ($options['is_integer']) { + return 0; + } + return $value; + }); + } + + /** + * Formats the given value using the measurement unit and options. + * @param $value float|int The value that should be formatted. Must be numeric. + * @param MeasurementUnit|null $unit The measurement unit, whose unit symbol should be used for formatting. + * If set to null, it is assumed that the part amount is measured in pieces. + * @param array $options + * @return string The formatted string + * @throws \InvalidArgumentException Thrown if $value is not numeric. + */ + public function format($value, ?MeasurementUnit $unit = null, array $options = []) + { + if (!is_numeric($value)) { + throw new \InvalidArgumentException('$value must be an numeric value!'); + } + + $value = (float) $value; + + //Find out what options to use + $resolver = new OptionsResolver(); + $resolver->setDefault('measurement_unit', $unit); + $this->configureOptions($resolver); + + $options = $resolver->resolve($options); + + if ($options['is_integer']) { + $value = round($value); + } + + //If the measurement unit uses a SI prefix format it that way. + if ($options['show_prefix']) { + return $this->siFormatter->format($value, $options['unit'], $options['decimals']); + } + + //Otherwise just output it + $format_string = '%.' . $options['decimals'] . 'f ' . $options['unit']; + return sprintf($format_string, $value); + } +} \ No newline at end of file diff --git a/src/Twig/AppExtension.php b/src/Twig/AppExtension.php index f348b342..56ccd17d 100644 --- a/src/Twig/AppExtension.php +++ b/src/Twig/AppExtension.php @@ -31,6 +31,8 @@ namespace App\Twig; use App\Entity\Attachments\Attachment; use App\Entity\Base\DBElement; +use App\Entity\Parts\MeasurementUnit; +use App\Services\AmountFormatter; use App\Services\EntityURLGenerator; use App\Services\MoneyFormatter; use App\Services\SIFormatter; @@ -51,11 +53,12 @@ class AppExtension extends AbstractExtension protected $treeBuilder; protected $moneyFormatter; protected $siformatter; + protected $amountFormatter; public function __construct(EntityURLGenerator $entityURLGenerator, AdapterInterface $cache, SerializerInterface $serializer, TreeBuilder $treeBuilder, MoneyFormatter $moneyFormatter, - SIFormatter $SIFormatter) + SIFormatter $SIFormatter, AmountFormatter $amountFormatter) { $this->entityURLGenerator = $entityURLGenerator; $this->cache = $cache; @@ -63,6 +66,7 @@ class AppExtension extends AbstractExtension $this->treeBuilder = $treeBuilder; $this->moneyFormatter = $moneyFormatter; $this->siformatter = $SIFormatter; + $this->amountFormatter = $amountFormatter; } public function getFilters() @@ -72,6 +76,7 @@ class AppExtension extends AbstractExtension new TwigFilter('bbCode', [$this, 'parseBBCode'], ['pre_escape' => 'html', 'is_safe' => ['html']]), new TwigFilter('moneyFormat', [$this, 'formatCurrency']), new TwigFilter('siFormat', [$this, 'siFormat']), + new TwigFilter('amountFormat', [$this, 'amountFormat']) ]; } @@ -127,4 +132,9 @@ class AppExtension extends AbstractExtension { return $this->siformatter->format($value, $unit, $decimals); } + + public function amountFormat($value, ?MeasurementUnit $unit, array $options = []) + { + return $this->amountFormatter->format($value, $unit, $options); + } } diff --git a/templates/Parts/info/_main_infos.html.twig b/templates/Parts/info/_main_infos.html.twig index 63f4f0da..71a9635c 100644 --- a/templates/Parts/info/_main_infos.html.twig +++ b/templates/Parts/info/_main_infos.html.twig @@ -25,9 +25,9 @@ #}
- {{ part.amountSum }} + {{ part.amountSum | amountFormat(part.partUnit) }} / - {{ part.minAmount }} + {{ part.minAmount | amountFormat(part.partUnit) }}
diff --git a/templates/Parts/info/_part_lots.html.twig b/templates/Parts/info/_part_lots.html.twig index d7470a74..a2009dcb 100644 --- a/templates/Parts/info/_part_lots.html.twig +++ b/templates/Parts/info/_part_lots.html.twig @@ -28,7 +28,7 @@ {% trans %}part_lots.instock_unknown{% endtrans %} {% else %} - {{ lot.amount }} + {{ lot.amount | amountFormat(part.partUnit, {'decimals': 5}) }} {% endif %}