diff --git a/src/DataTables/Helpers/PartDataTableHelper.php b/src/DataTables/Helpers/PartDataTableHelper.php
index 8499e303..c33c3a82 100644
--- a/src/DataTables/Helpers/PartDataTableHelper.php
+++ b/src/DataTables/Helpers/PartDataTableHelper.php
@@ -20,14 +20,17 @@ declare(strict_types=1);
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see .
*/
+
namespace App\DataTables\Helpers;
+use App\Entity\Parts\StorageLocation;
use App\Entity\ProjectSystem\Project;
use App\Entity\Attachments\Attachment;
use App\Entity\Parts\Part;
use App\Services\Attachments\AttachmentURLGenerator;
use App\Services\Attachments\PartPreviewGenerator;
use App\Services\EntityURLGenerator;
+use App\Services\Formatters\AmountFormatter;
use Symfony\Contracts\Translation\TranslatorInterface;
/**
@@ -35,8 +38,13 @@ use Symfony\Contracts\Translation\TranslatorInterface;
*/
class PartDataTableHelper
{
- public function __construct(private readonly PartPreviewGenerator $previewGenerator, private readonly AttachmentURLGenerator $attachmentURLGenerator, private readonly EntityURLGenerator $entityURLGenerator, private readonly TranslatorInterface $translator)
- {
+ public function __construct(
+ private readonly PartPreviewGenerator $previewGenerator,
+ private readonly AttachmentURLGenerator $attachmentURLGenerator,
+ private readonly EntityURLGenerator $entityURLGenerator,
+ private readonly TranslatorInterface $translator,
+ private readonly AmountFormatter $amountFormatter,
+ ) {
}
public function renderName(Part $context): string
@@ -45,14 +53,16 @@ class PartDataTableHelper
//Depending on the part status we show a different icon (the later conditions have higher priority)
if ($context->isFavorite()) {
- $icon = sprintf('', $this->translator->trans('part.favorite.badge'));
+ $icon = sprintf('',
+ $this->translator->trans('part.favorite.badge'));
}
if ($context->isNeedsReview()) {
- $icon = sprintf('', $this->translator->trans('part.needs_review.badge'));
+ $icon = sprintf('',
+ $this->translator->trans('part.needs_review.badge'));
}
if ($context->getBuiltProject() instanceof Project) {
$icon = sprintf('',
- $this->translator->trans('part.info.projectBuildPart.hint') . ': ' . $context->getBuiltProject()->getName());
+ $this->translator->trans('part.info.projectBuildPart.hint').': '.$context->getBuiltProject()->getName());
}
@@ -85,4 +95,62 @@ class PartDataTableHelper
$title
);
}
+
+ public function renderStorageLocations(Part $context): string
+ {
+ $tmp = [];
+ foreach ($context->getPartLots() as $lot) {
+ //Ignore lots without storelocation
+ if (!$lot->getStorageLocation() instanceof StorageLocation) {
+ continue;
+ }
+ $tmp[] = sprintf(
+ '%s',
+ $this->entityURLGenerator->listPartsURL($lot->getStorageLocation()),
+ htmlspecialchars($lot->getStorageLocation()->getFullPath()),
+ htmlspecialchars($lot->getStorageLocation()->getName())
+ );
+ }
+
+ return implode('
', $tmp);
+ }
+
+ public function renderAmount(Part $context): string
+ {
+ $amount = $context->getAmountSum();
+ $expiredAmount = $context->getExpiredAmountSum();
+
+ $ret = '';
+
+ if ($context->isAmountUnknown()) {
+ //When all amounts are unknown, we show a question mark
+ if ($amount === 0.0) {
+ $ret .= sprintf('?',
+ $this->translator->trans('part_lots.instock_unknown'));
+ } else { //Otherwise mark it with greater equal and the (known) amount
+ $ret .= sprintf('≥',
+ $this->translator->trans('part_lots.instock_unknown')
+ );
+ $ret .= htmlspecialchars($this->amountFormatter->format($amount, $context->getPartUnit()));
+ }
+ } else {
+ $ret .= htmlspecialchars($this->amountFormatter->format($amount, $context->getPartUnit()));
+ }
+
+ //If we have expired lots, we show them in parentheses behind
+ if ($expiredAmount > 0) {
+ $ret .= sprintf(' (+%s)',
+ $this->translator->trans('part_lots.is_expired'),
+ htmlspecialchars($this->amountFormatter->format($expiredAmount, $context->getPartUnit())));
+ }
+
+ //When the amount is below the minimum amount, we highlight the number red
+ if ($context->isNotEnoughInstock()) {
+ $ret = sprintf('%s',
+ $this->translator->trans('part.info.amount.less_than_desired'),
+ $ret);
+ }
+
+ return $ret;
+ }
}
diff --git a/src/DataTables/PartsDataTable.php b/src/DataTables/PartsDataTable.php
index 1718ca7c..8a5cd42a 100644
--- a/src/DataTables/PartsDataTable.php
+++ b/src/DataTables/PartsDataTable.php
@@ -139,63 +139,11 @@ final class PartsDataTable implements DataTableTypeInterface
->add('storelocation', TextColumn::class, [
'label' => $this->translator->trans('part.table.storeLocations'),
'orderField' => 'storelocations.name',
- 'render' => function ($value, Part $context): string {
- $tmp = [];
- foreach ($context->getPartLots() as $lot) {
- //Ignore lots without storelocation
- if (!$lot->getStorageLocation() instanceof StorageLocation) {
- continue;
- }
- $tmp[] = sprintf(
- '%s',
- $this->urlGenerator->listPartsURL($lot->getStorageLocation()),
- htmlspecialchars($lot->getStorageLocation()->getFullPath()),
- htmlspecialchars($lot->getStorageLocation()->getName())
- );
- }
-
- return implode('
', $tmp);
- },
+ 'render' => fn ($value, Part $context) => $this->partDataTableHelper->renderStorageLocations($context),
], alias: 'storage_location')
->add('amount', TextColumn::class, [
'label' => $this->translator->trans('part.table.amount'),
- 'render' => function ($value, Part $context) {
- $amount = $context->getAmountSum();
- $expiredAmount = $context->getExpiredAmountSum();
-
- $ret = '';
-
- if ($context->isAmountUnknown()) {
- //When all amounts are unknown, we show a question mark
- if ($amount === 0.0) {
- $ret .= sprintf('?',
- $this->translator->trans('part_lots.instock_unknown'));
- } else { //Otherwise mark it with greater equal and the (known) amount
- $ret .= sprintf('≥',
- $this->translator->trans('part_lots.instock_unknown')
- );
- $ret .= htmlspecialchars($this->amountFormatter->format($amount, $context->getPartUnit()));
- }
- } else {
- $ret .= htmlspecialchars($this->amountFormatter->format($amount, $context->getPartUnit()));
- }
-
- //If we have expired lots, we show them in parentheses behind
- if ($expiredAmount > 0) {
- $ret .= sprintf(' (+%s)',
- $this->translator->trans('part_lots.is_expired'),
- htmlspecialchars($this->amountFormatter->format($expiredAmount, $context->getPartUnit())));
- }
-
- //When the amount is below the minimum amount, we highlight the number red
- if ($context->isNotEnoughInstock()) {
- $ret = sprintf('%s',
- $this->translator->trans('part.info.amount.less_than_desired'),
- $ret);
- }
-
- return $ret;
- },
+ 'render' => fn ($value, Part $context) => $this->partDataTableHelper->renderAmount($context),
'orderField' => 'amountSum'
])
->add('minamount', TextColumn::class, [
diff --git a/src/DataTables/ProjectBomEntriesDataTable.php b/src/DataTables/ProjectBomEntriesDataTable.php
index 5a706146..6e3bee5b 100644
--- a/src/DataTables/ProjectBomEntriesDataTable.php
+++ b/src/DataTables/ProjectBomEntriesDataTable.php
@@ -151,6 +151,28 @@ class ProjectBomEntriesDataTable implements DataTableTypeInterface
},
])
+ ->add('instockAmount', TextColumn::class, [
+ 'label' => 'project.bom.instockAmount',
+ 'visible' => false,
+ 'render' => function ($value, ProjectBOMEntry $context) {
+ if ($context->getPart()) {
+ return $this->partDataTableHelper->renderAmount($context->getPart());
+ }
+
+ return '';
+ }
+ ])
+ ->add('storageLocations', TextColumn::class, [
+ 'label' => 'part.table.storeLocations',
+ 'visible' => false,
+ 'render' => function ($value, ProjectBOMEntry $context) {
+ if ($context->getPart()) {
+ return $this->partDataTableHelper->renderStorageLocations($context->getPart());
+ }
+
+ return '';
+ }
+ ])
->add('addedDate', LocaleDateTimeColumn::class, [
'label' => $this->translator->trans('part.table.addedDate'),
diff --git a/translations/messages.en.xlf b/translations/messages.en.xlf
index 7197f3b7..f4449c9e 100644
--- a/translations/messages.en.xlf
+++ b/translations/messages.en.xlf
@@ -11951,5 +11951,11 @@ Please note, that you can not impersonate a disabled user. If you try you will g
Vendor barcode (configured in part lot)
+
+
+ project.bom.instockAmount
+ Stocked amount
+
+