diff --git a/src/DataTables/ProjectBomEntriesDataTable.php b/src/DataTables/ProjectBomEntriesDataTable.php index 04d8206b..6ee726e8 100644 --- a/src/DataTables/ProjectBomEntriesDataTable.php +++ b/src/DataTables/ProjectBomEntriesDataTable.php @@ -29,12 +29,16 @@ use App\DataTables\Column\LocaleDateTimeColumn; use App\DataTables\Column\MarkdownColumn; use App\DataTables\Helpers\PartDataTableHelper; use App\Doctrine\Helpers\FieldHelper; -use App\Entity\Parts\Part; use App\Entity\Parts\ManufacturingStatus; +use App\Entity\Parts\Part; use App\Entity\ProjectSystem\ProjectBOMEntry; use App\Services\ElementTypeNameGenerator; use App\Services\EntityURLGenerator; use App\Services\Formatters\AmountFormatter; +use App\Services\Formatters\MoneyFormatter; +use App\Services\Parts\PricedetailHelper; +use Brick\Math\BigDecimal; +use Brick\Math\RoundingMode; use Doctrine\ORM\AbstractQuery; use Doctrine\ORM\Query; use Doctrine\ORM\QueryBuilder; @@ -50,7 +54,9 @@ class ProjectBomEntriesDataTable implements DataTableTypeInterface protected EntityURLGenerator $entityURLGenerator, protected TranslatorInterface $translator, protected AmountFormatter $amountFormatter, - protected PartDataTableHelper $partDataTableHelper + protected PartDataTableHelper $partDataTableHelper, + protected PricedetailHelper $pricedetailHelper, + protected MoneyFormatter $moneyFormatter, ) { } @@ -202,6 +208,27 @@ class ProjectBomEntriesDataTable implements DataTableTypeInterface return ''; } ]) + ->add('price', TextColumn::class, [ + 'label' => 'project.bom.price', + 'visible' => false, + 'render' => function ($value, ProjectBOMEntry $context) { + $price = $this->getBomEntryUnitPrice($context); + return $this->moneyFormatter->format($price->toScale(2, RoundingMode::UP)->toFloat(), null, 2, true); + }, + ]) + ->add('ext_price', TextColumn::class, [ + 'label' => 'project.bom.ext_price', + 'visible' => false, + 'render' => function ($value, ProjectBOMEntry $context) { + $price = $this->getBomEntryUnitPrice($context); + return $this->moneyFormatter->format( + $price->multipliedBy($context->getQuantity())->toScale(2, RoundingMode::UP)->toFloat(), + null, + 2, + true + ); + }, + ]) ->add('addedDate', LocaleDateTimeColumn::class, [ 'label' => $this->translator->trans('part.table.addedDate'), @@ -231,6 +258,21 @@ class ProjectBomEntriesDataTable implements DataTableTypeInterface ]); } + private function getBomEntryUnitPrice(ProjectBOMEntry $entry): BigDecimal + { + if ($entry->getPart() instanceof Part) { + $amount = $entry->getQuantity(); + // If the BOM quantity is below the minimum order amount, use the minimum order amount + // for the price lookup — otherwise calculateAvgPrice returns null (no price tier matches). + $minOrderAmount = $this->pricedetailHelper->getMinOrderAmount($entry->getPart()); + if ($minOrderAmount !== null) { + $amount = max($amount, $minOrderAmount); + } + return $this->pricedetailHelper->calculateAvgPrice($entry->getPart(), $amount) ?? BigDecimal::zero(); + } + return $entry->getPrice() ?? BigDecimal::zero(); + } + private function getFilterQuery(QueryBuilder $builder, array $options): void { $builder