Merge branch 'master' into log_detail_page

This commit is contained in:
Jan Böhmer 2023-04-29 22:46:38 +02:00
commit 4c6ceab8e8
291 changed files with 1994 additions and 1621 deletions

View file

@ -20,7 +20,6 @@
namespace App\DataTables\Adapters;
use Doctrine\ORM\Query;
use Doctrine\ORM\QueryBuilder;
use Doctrine\ORM\Tools\Pagination\Paginator;
use Omines\DataTablesBundle\Adapter\Doctrine\FetchJoinORMAdapter;
@ -38,7 +37,7 @@ use Omines\DataTablesBundle\Adapter\Doctrine\FetchJoinORMAdapter;
*/
class CustomFetchJoinORMAdapter extends FetchJoinORMAdapter
{
public function getCount(QueryBuilder $queryBuilder, $identifier)
public function getCount(QueryBuilder $queryBuilder, $identifier): ?int
{
$qb_without_group_by = clone $queryBuilder;

View file

@ -22,9 +22,7 @@ declare(strict_types=1);
namespace App\DataTables\Column;
use App\Entity\Base\AbstractDBElement;
use App\Entity\Base\AbstractNamedDBElement;
use App\Entity\Parts\Part;
use App\Services\EntityURLGenerator;
use Omines\DataTablesBundle\Column\AbstractColumn;
use Symfony\Component\OptionsResolver\Options;

View file

@ -31,7 +31,7 @@ use Omines\DataTablesBundle\Column\AbstractColumn;
use Symfony\Component\OptionsResolver\OptionsResolver;
/**
* Similar to the built in DateTimeColumn, but the datetime is formatted using a IntlDateFormatter,
* Similar to the built-in DateTimeColumn, but the datetime is formatted using a IntlDateFormatter,
* to get prettier locale based formatting.
*/
class LocaleDateTimeColumn extends AbstractColumn
@ -45,7 +45,9 @@ class LocaleDateTimeColumn extends AbstractColumn
{
if (null === $value) {
return $this->options['nullValue'];
} elseif (!$value instanceof DateTimeInterface) {
}
if (!$value instanceof DateTimeInterface) {
$value = new DateTime((string) $value);
}

View file

@ -41,7 +41,7 @@ class PrettyBoolColumn extends AbstractColumn
return (bool) $value;
}
public function render($value, $context)
public function render($value, $context): string
{
if ($value === true) {
return '<span class="badge bg-success"><i class="fa-solid fa-circle-check fa-fw"></i> '

View file

@ -27,7 +27,7 @@ use Symfony\Component\OptionsResolver\OptionsResolver;
class RowClassColumn extends AbstractColumn
{
public function configureOptions(OptionsResolver $resolver)
public function configureOptions(OptionsResolver $resolver): self
{
parent::configureOptions($resolver);
@ -48,6 +48,9 @@ class RowClassColumn extends AbstractColumn
parent::initialize('$$rowClass', $index, $options, $dataTable); // TODO: Change the autogenerated stub
}
/**
* @return mixed
*/
public function normalize($value)
{
return $value;

View file

@ -33,7 +33,7 @@ class SIUnitNumberColumn extends AbstractColumn
$this->formatter = $formatter;
}
public function configureOptions(OptionsResolver $resolver)
public function configureOptions(OptionsResolver $resolver): self
{
parent::configureOptions($resolver);
@ -43,7 +43,7 @@ class SIUnitNumberColumn extends AbstractColumn
return $this;
}
public function normalize($value)
public function normalize($value): string
{
//Ignore null values
if ($value === null) {

View file

@ -28,7 +28,7 @@ use Symfony\Component\OptionsResolver\OptionsResolver;
*/
class SelectColumn extends AbstractColumn
{
public function configureOptions(OptionsResolver $resolver)
public function configureOptions(OptionsResolver $resolver): self
{
parent::configureOptions($resolver);
@ -43,12 +43,15 @@ class SelectColumn extends AbstractColumn
return $this;
}
/**
* @return mixed
*/
public function normalize($value)
{
return $value;
}
public function render($value, $context)
public function render($value, $context): string
{
//Return empty string, as it this column is filled by datatables on client side
return '';

View file

@ -21,7 +21,6 @@
namespace App\DataTables\Filters\Constraints;
use App\DataTables\Filters\FilterInterface;
use Doctrine\ORM\QueryBuilder;
abstract class AbstractConstraint implements FilterInterface
{

View file

@ -20,7 +20,6 @@
namespace App\DataTables\Filters\Constraints;
use App\DataTables\Filters\FilterInterface;
use Doctrine\ORM\QueryBuilder;
class BooleanConstraint extends AbstractConstraint

View file

@ -20,7 +20,6 @@
namespace App\DataTables\Filters\Constraints;
use Doctrine\DBAL\ParameterType;
use Doctrine\ORM\QueryBuilder;
trait FilterTrait
@ -51,7 +50,7 @@ trait FilterTrait
protected function generateParameterIdentifier(string $property): string
{
//Replace all special characters with underscores
$property = preg_replace('/[^a-zA-Z0-9_]/', '_', $property);
$property = preg_replace('/\W/', '_', $property);
//Add a random number to the end of the property name for uniqueness
return $property . '_' . uniqid("", false);
}

View file

@ -98,7 +98,7 @@ class InstanceOfConstraint extends AbstractConstraint
if ($this->operator === 'ANY' || $this->operator === 'NONE') {
foreach($this->value as $value) {
//We cannnot use an paramater here, as this is the only way to pass the FCQN to the query (via binded params, we would need to use ClassMetaData). See: https://github.com/doctrine/orm/issues/4462
//We can not use a parameter here, as this is the only way to pass the FCQN to the query (via binded params, we would need to use ClassMetaData). See: https://github.com/doctrine/orm/issues/4462
$expressions[] = ($queryBuilder->expr()->isInstanceOf($this->property, $value));
}

View file

@ -20,7 +20,6 @@
namespace App\DataTables\Filters\Constraints;
use Doctrine\DBAL\ParameterType;
use Doctrine\ORM\QueryBuilder;
use RuntimeException;
@ -42,7 +41,7 @@ class NumberConstraint extends AbstractConstraint
protected $value2;
/**
* @var string The operator to use
* @var string|null The operator to use
*/
protected ?string $operator;

View file

@ -24,7 +24,6 @@ use App\DataTables\Filters\Constraints\AbstractConstraint;
use App\DataTables\Filters\Constraints\TextConstraint;
use App\Entity\Parameters\PartParameter;
use Doctrine\ORM\QueryBuilder;
use Svg\Tag\Text;
class ParameterConstraint extends AbstractConstraint
{

View file

@ -101,7 +101,7 @@ class TextConstraint extends AbstractConstraint
return;
}
//The CONTAINS, LIKE, STARTS and ENDS operators use the LIKE operator but we have to build the value string differently
//The CONTAINS, LIKE, STARTS and ENDS operators use the LIKE operator, but we have to build the value string differently
$like_value = null;
if ($this->operator === 'LIKE') {
$like_value = $this->value;

View file

@ -38,11 +38,9 @@ use App\Entity\Parts\MeasurementUnit;
use App\Entity\Parts\Storelocation;
use App\Entity\Parts\Supplier;
use App\Entity\UserSystem\User;
use App\Form\Filters\Constraints\UserEntityConstraintType;
use App\Services\Trees\NodesListBuilder;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\QueryBuilder;
use Svg\Tag\Text;
class PartFilter implements FilterInterface
{
@ -148,9 +146,9 @@ class PartFilter implements FilterInterface
/**
* @return BooleanConstraint|false
* @return BooleanConstraint
*/
public function getFavorite()
public function getFavorite(): BooleanConstraint
{
return $this->favorite;
}

View file

@ -96,7 +96,7 @@ class PartSearchFilter implements FilterInterface
$fields_to_search[] = 'orderdetails.supplierpartnr';
}
if($this->mpn) {
$fields_to_search[] = 'part.manufacturer_product_url';
$fields_to_search[] = 'part.manufacturer_product_number';
}
if($this->supplier) {
$fields_to_search[] = 'suppliers.name';

View file

@ -28,7 +28,6 @@ use App\DataTables\Column\LogEntryExtraColumn;
use App\DataTables\Column\LogEntryTargetColumn;
use App\DataTables\Column\RevertLogColumn;
use App\DataTables\Column\RowClassColumn;
use App\DataTables\Filters\AttachmentFilter;
use App\DataTables\Filters\LogFilter;
use App\Entity\Base\AbstractDBElement;
use App\Entity\Contracts\TimeTravelInterface;
@ -60,8 +59,6 @@ use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Symfony\Component\Security\Core\Security;
use Symfony\Contracts\Translation\TranslatorInterface;
use function Symfony\Component\Translation\t;
class LogDataTable implements DataTableTypeInterface
{
protected ElementTypeNameGenerator $elementTypeNameGenerator;

View file

@ -36,22 +36,14 @@ use App\DataTables\Column\TagsColumn;
use App\DataTables\Filters\PartFilter;
use App\DataTables\Filters\PartSearchFilter;
use App\DataTables\Helpers\PartDataTableHelper;
use App\Entity\Parts\Category;
use App\Entity\Parts\Footprint;
use App\Entity\Parts\Manufacturer;
use App\Entity\Parts\Part;
use App\Entity\Parts\PartLot;
use App\Entity\Parts\Storelocation;
use App\Entity\Parts\Supplier;
use App\Services\Formatters\AmountFormatter;
use App\Services\Attachments\AttachmentURLGenerator;
use App\Services\Attachments\PartPreviewGenerator;
use App\Services\EntityURLGenerator;
use App\Services\Trees\NodesListBuilder;
use Doctrine\ORM\QueryBuilder;
use Omines\DataTablesBundle\Adapter\Doctrine\FetchJoinORMAdapter;
use Omines\DataTablesBundle\Adapter\Doctrine\ORM\SearchCriteriaProvider;
use Omines\DataTablesBundle\Column\BoolColumn;
use Omines\DataTablesBundle\Column\MapColumn;
use Omines\DataTablesBundle\Column\TextColumn;
use Omines\DataTablesBundle\DataTable;
@ -63,27 +55,19 @@ use Symfony\Contracts\Translation\TranslatorInterface;
final class PartsDataTable implements DataTableTypeInterface
{
private TranslatorInterface $translator;
private NodesListBuilder $treeBuilder;
private AmountFormatter $amountFormatter;
private AttachmentURLGenerator $attachmentURLGenerator;
private Security $security;
private PartDataTableHelper $partDataTableHelper;
/**
* @var EntityURLGenerator
*/
private $urlGenerator;
private EntityURLGenerator $urlGenerator;
public function __construct(EntityURLGenerator $urlGenerator, TranslatorInterface $translator,
NodesListBuilder $treeBuilder, AmountFormatter $amountFormatter,PartDataTableHelper $partDataTableHelper,
AttachmentURLGenerator $attachmentURLGenerator, Security $security)
AmountFormatter $amountFormatter,PartDataTableHelper $partDataTableHelper, Security $security)
{
$this->urlGenerator = $urlGenerator;
$this->translator = $translator;
$this->treeBuilder = $treeBuilder;
$this->amountFormatter = $amountFormatter;
$this->attachmentURLGenerator = $attachmentURLGenerator;
$this->security = $security;
$this->partDataTableHelper = $partDataTableHelper;
}
@ -168,6 +152,7 @@ final class PartsDataTable implements DataTableTypeInterface
if ($this->security->isGranted('@storelocations.read')) {
$dataTable->add('storelocation', TextColumn::class, [
'label' => $this->translator->trans('part.table.storeLocations'),
'orderField' => 'storelocations.name',
'render' => function ($value, Part $context) {
$tmp = [];
foreach ($context->getPartLots() as $lot) {
@ -193,7 +178,22 @@ final class PartsDataTable implements DataTableTypeInterface
$amount = $context->getAmountSum();
$expiredAmount = $context->getExpiredAmountSum();
$ret = htmlspecialchars($this->amountFormatter->format($amount, $context->getPartUnit()));
$ret = '';
if ($context->isAmountUnknown()) {
//When all amounts are unknown, we show a question mark
if ($amount === 0.0) {
$ret .= sprintf('<b class="text-primary" title="%s">?</b>',
$this->translator->trans('part_lots.instock_unknown'));
} else { //Otherwise mark it with greater equal and the (known) amount
$ret .= sprintf('<b class="text-primary" title="%s">≥</b>',
$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) {