mirror of
https://github.com/Part-DB/Part-DB-server.git
synced 2026-05-18 17:31:35 +00:00
Add unit price and extended price columns to project BOM table
Adds two optional columns to the project BOM datatable (hidden by default, toggleable via column visibility): - **Price**: unit price for the BOM entry in the base currency, looked up via PricedetailHelper. For parts whose BOM quantity falls below the minimum order amount the minimum order amount is used for the price tier lookup so that a price is always returned. - **Extended Price**: unit price multiplied by the BOM quantity. Prices are rendered via MoneyFormatter (locale-aware, with currency symbol). Both columns round up to 2 decimal places to avoid displaying 0.00 for very small prices.
This commit is contained in:
parent
5b86d6f652
commit
1611b6cd41
1 changed files with 44 additions and 2 deletions
|
|
@ -29,12 +29,16 @@ use App\DataTables\Column\LocaleDateTimeColumn;
|
||||||
use App\DataTables\Column\MarkdownColumn;
|
use App\DataTables\Column\MarkdownColumn;
|
||||||
use App\DataTables\Helpers\PartDataTableHelper;
|
use App\DataTables\Helpers\PartDataTableHelper;
|
||||||
use App\Doctrine\Helpers\FieldHelper;
|
use App\Doctrine\Helpers\FieldHelper;
|
||||||
use App\Entity\Parts\Part;
|
|
||||||
use App\Entity\Parts\ManufacturingStatus;
|
use App\Entity\Parts\ManufacturingStatus;
|
||||||
|
use App\Entity\Parts\Part;
|
||||||
use App\Entity\ProjectSystem\ProjectBOMEntry;
|
use App\Entity\ProjectSystem\ProjectBOMEntry;
|
||||||
use App\Services\ElementTypeNameGenerator;
|
use App\Services\ElementTypeNameGenerator;
|
||||||
use App\Services\EntityURLGenerator;
|
use App\Services\EntityURLGenerator;
|
||||||
use App\Services\Formatters\AmountFormatter;
|
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\AbstractQuery;
|
||||||
use Doctrine\ORM\Query;
|
use Doctrine\ORM\Query;
|
||||||
use Doctrine\ORM\QueryBuilder;
|
use Doctrine\ORM\QueryBuilder;
|
||||||
|
|
@ -50,7 +54,9 @@ class ProjectBomEntriesDataTable implements DataTableTypeInterface
|
||||||
protected EntityURLGenerator $entityURLGenerator,
|
protected EntityURLGenerator $entityURLGenerator,
|
||||||
protected TranslatorInterface $translator,
|
protected TranslatorInterface $translator,
|
||||||
protected AmountFormatter $amountFormatter,
|
protected AmountFormatter $amountFormatter,
|
||||||
protected PartDataTableHelper $partDataTableHelper
|
protected PartDataTableHelper $partDataTableHelper,
|
||||||
|
protected PricedetailHelper $pricedetailHelper,
|
||||||
|
protected MoneyFormatter $moneyFormatter,
|
||||||
) {
|
) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -202,6 +208,27 @@ class ProjectBomEntriesDataTable implements DataTableTypeInterface
|
||||||
return '';
|
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, [
|
->add('addedDate', LocaleDateTimeColumn::class, [
|
||||||
'label' => $this->translator->trans('part.table.addedDate'),
|
'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
|
private function getFilterQuery(QueryBuilder $builder, array $options): void
|
||||||
{
|
{
|
||||||
$builder
|
$builder
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue