mirror of
https://github.com/Part-DB/Part-DB-server.git
synced 2025-06-24 10:49:00 +02:00
Merge branch 'master' into log_detail_page
This commit is contained in:
commit
4c6ceab8e8
291 changed files with 1994 additions and 1621 deletions
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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> '
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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 '';
|
||||
|
|
|
@ -21,7 +21,6 @@
|
|||
namespace App\DataTables\Filters\Constraints;
|
||||
|
||||
use App\DataTables\Filters\FilterInterface;
|
||||
use Doctrine\ORM\QueryBuilder;
|
||||
|
||||
abstract class AbstractConstraint implements FilterInterface
|
||||
{
|
||||
|
|
|
@ -20,7 +20,6 @@
|
|||
|
||||
namespace App\DataTables\Filters\Constraints;
|
||||
|
||||
use App\DataTables\Filters\FilterInterface;
|
||||
use Doctrine\ORM\QueryBuilder;
|
||||
|
||||
class BooleanConstraint extends AbstractConstraint
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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';
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue