mirror of
https://github.com/Part-DB/Part-DB-server.git
synced 2025-12-17 08:29:31 +00:00
Add makefile to help with development setup, change part_ids in bulk import jobs to junction table and implement filtering based on bulk import jobs status and its associated parts' statuses.
This commit is contained in:
parent
9b4d5e9c27
commit
cc9d50a8fe
22 changed files with 1357 additions and 120 deletions
|
|
@ -0,0 +1,82 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* This file is part of Part-DB (https://github.com/Part-DB/Part-DB-symfony).
|
||||
*
|
||||
* Copyright (C) 2019 - 2023 Jan Böhmer (https://github.com/jbtronics)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published
|
||||
* by the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace App\DataTables\Filters\Constraints\Part;
|
||||
|
||||
use App\DataTables\Filters\Constraints\AbstractConstraint;
|
||||
use App\Entity\BulkInfoProviderImportJobPart;
|
||||
use Doctrine\ORM\QueryBuilder;
|
||||
|
||||
class BulkImportJobExistsConstraint extends AbstractConstraint
|
||||
{
|
||||
/** @var bool|null The value of our constraint */
|
||||
protected ?bool $value = null;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct('bulk_import_job_exists');
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of this constraint. Null means "don't filter", true means "filter for parts in bulk import jobs", false means "filter for parts not in bulk import jobs".
|
||||
*/
|
||||
public function getValue(): ?bool
|
||||
{
|
||||
return $this->value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of this constraint. Null means "don't filter", true means "filter for parts in bulk import jobs", false means "filter for parts not in bulk import jobs".
|
||||
*/
|
||||
public function setValue(?bool $value): void
|
||||
{
|
||||
$this->value = $value;
|
||||
}
|
||||
|
||||
public function isEnabled(): bool
|
||||
{
|
||||
return $this->value !== null;
|
||||
}
|
||||
|
||||
public function apply(QueryBuilder $queryBuilder): void
|
||||
{
|
||||
// Do not apply a filter if value is null (filter is set to ignore)
|
||||
if (!$this->isEnabled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Use EXISTS subquery to avoid join conflicts
|
||||
$existsSubquery = $queryBuilder->getEntityManager()->createQueryBuilder();
|
||||
$existsSubquery->select('1')
|
||||
->from(BulkInfoProviderImportJobPart::class, 'bip_exists')
|
||||
->where('bip_exists.part = part.id');
|
||||
|
||||
if ($this->value === true) {
|
||||
// Filter for parts that ARE in bulk import jobs
|
||||
$queryBuilder->andWhere('EXISTS (' . $existsSubquery->getDQL() . ')');
|
||||
} else {
|
||||
// Filter for parts that are NOT in bulk import jobs
|
||||
$queryBuilder->andWhere('NOT EXISTS (' . $existsSubquery->getDQL() . ')');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,105 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* This file is part of Part-DB (https://github.com/Part-DB/Part-DB-symfony).
|
||||
*
|
||||
* Copyright (C) 2019 - 2023 Jan Böhmer (https://github.com/jbtronics)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published
|
||||
* by the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace App\DataTables\Filters\Constraints\Part;
|
||||
|
||||
use App\DataTables\Filters\Constraints\AbstractConstraint;
|
||||
use App\Entity\BulkInfoProviderImportJobPart;
|
||||
use Doctrine\ORM\QueryBuilder;
|
||||
|
||||
class BulkImportJobStatusConstraint extends AbstractConstraint
|
||||
{
|
||||
/** @var array The status values to filter by */
|
||||
protected array $values = [];
|
||||
|
||||
/** @var string|null The operator to use ('any_of', 'none_of', 'all_of') */
|
||||
protected ?string $operator = null;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct('bulk_import_job_status');
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the status values to filter by.
|
||||
*/
|
||||
public function getValues(): array
|
||||
{
|
||||
return $this->values;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the status values to filter by.
|
||||
*/
|
||||
public function setValues(array $values): void
|
||||
{
|
||||
$this->values = $values;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the operator to use.
|
||||
*/
|
||||
public function getOperator(): ?string
|
||||
{
|
||||
return $this->operator;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the operator to use.
|
||||
*/
|
||||
public function setOperator(?string $operator): void
|
||||
{
|
||||
$this->operator = $operator;
|
||||
}
|
||||
|
||||
public function isEnabled(): bool
|
||||
{
|
||||
return !empty($this->values) && $this->operator !== null;
|
||||
}
|
||||
|
||||
public function apply(QueryBuilder $queryBuilder): void
|
||||
{
|
||||
// Do not apply a filter if values are empty or operator is null
|
||||
if (!$this->isEnabled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Use EXISTS subquery to check if part has a job with the specified status(es)
|
||||
$existsSubquery = $queryBuilder->getEntityManager()->createQueryBuilder();
|
||||
$existsSubquery->select('1')
|
||||
->from(BulkInfoProviderImportJobPart::class, 'bip_status')
|
||||
->join('bip_status.job', 'job_status')
|
||||
->where('bip_status.part = part.id');
|
||||
|
||||
// Add status conditions based on operator
|
||||
if ($this->operator === 'ANY') {
|
||||
$existsSubquery->andWhere('job_status.status IN (:job_status_values)');
|
||||
$queryBuilder->andWhere('EXISTS (' . $existsSubquery->getDQL() . ')');
|
||||
$queryBuilder->setParameter('job_status_values', $this->values);
|
||||
} elseif ($this->operator === 'NONE') {
|
||||
$existsSubquery->andWhere('job_status.status IN (:job_status_values)');
|
||||
$queryBuilder->andWhere('NOT EXISTS (' . $existsSubquery->getDQL() . ')');
|
||||
$queryBuilder->setParameter('job_status_values', $this->values);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,104 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* This file is part of Part-DB (https://github.com/Part-DB/Part-DB-symfony).
|
||||
*
|
||||
* Copyright (C) 2019 - 2023 Jan Böhmer (https://github.com/jbtronics)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published
|
||||
* by the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace App\DataTables\Filters\Constraints\Part;
|
||||
|
||||
use App\DataTables\Filters\Constraints\AbstractConstraint;
|
||||
use App\Entity\BulkInfoProviderImportJobPart;
|
||||
use Doctrine\ORM\QueryBuilder;
|
||||
|
||||
class BulkImportPartStatusConstraint extends AbstractConstraint
|
||||
{
|
||||
/** @var array The status values to filter by */
|
||||
protected array $values = [];
|
||||
|
||||
/** @var string|null The operator to use ('any_of', 'none_of', 'all_of') */
|
||||
protected ?string $operator = null;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct('bulk_import_part_status');
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the status values to filter by.
|
||||
*/
|
||||
public function getValues(): array
|
||||
{
|
||||
return $this->values;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the status values to filter by.
|
||||
*/
|
||||
public function setValues(array $values): void
|
||||
{
|
||||
$this->values = $values;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the operator to use.
|
||||
*/
|
||||
public function getOperator(): ?string
|
||||
{
|
||||
return $this->operator;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the operator to use.
|
||||
*/
|
||||
public function setOperator(?string $operator): void
|
||||
{
|
||||
$this->operator = $operator;
|
||||
}
|
||||
|
||||
public function isEnabled(): bool
|
||||
{
|
||||
return !empty($this->values) && $this->operator !== null;
|
||||
}
|
||||
|
||||
public function apply(QueryBuilder $queryBuilder): void
|
||||
{
|
||||
// Do not apply a filter if values are empty or operator is null
|
||||
if (!$this->isEnabled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Use EXISTS subquery to check if part has the specified status(es)
|
||||
$existsSubquery = $queryBuilder->getEntityManager()->createQueryBuilder();
|
||||
$existsSubquery->select('1')
|
||||
->from(BulkInfoProviderImportJobPart::class, 'bip_part_status')
|
||||
->where('bip_part_status.part = part.id');
|
||||
|
||||
// Add status conditions based on operator
|
||||
if ($this->operator === 'ANY') {
|
||||
$existsSubquery->andWhere('bip_part_status.status IN (:part_status_values)');
|
||||
$queryBuilder->andWhere('EXISTS (' . $existsSubquery->getDQL() . ')');
|
||||
$queryBuilder->setParameter('part_status_values', $this->values);
|
||||
} elseif ($this->operator === 'NONE') {
|
||||
$existsSubquery->andWhere('bip_part_status.status IN (:part_status_values)');
|
||||
$queryBuilder->andWhere('NOT EXISTS (' . $existsSubquery->getDQL() . ')');
|
||||
$queryBuilder->setParameter('part_status_values', $this->values);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -31,6 +31,9 @@ use App\DataTables\Filters\Constraints\NumberConstraint;
|
|||
use App\DataTables\Filters\Constraints\Part\LessThanDesiredConstraint;
|
||||
use App\DataTables\Filters\Constraints\Part\ParameterConstraint;
|
||||
use App\DataTables\Filters\Constraints\Part\TagsConstraint;
|
||||
use App\DataTables\Filters\Constraints\Part\BulkImportJobExistsConstraint;
|
||||
use App\DataTables\Filters\Constraints\Part\BulkImportJobStatusConstraint;
|
||||
use App\DataTables\Filters\Constraints\Part\BulkImportPartStatusConstraint;
|
||||
use App\DataTables\Filters\Constraints\TextConstraint;
|
||||
use App\Entity\Attachments\AttachmentType;
|
||||
use App\Entity\Parts\Category;
|
||||
|
|
@ -42,6 +45,8 @@ use App\Entity\Parts\StorageLocation;
|
|||
use App\Entity\Parts\Supplier;
|
||||
use App\Entity\ProjectSystem\Project;
|
||||
use App\Entity\UserSystem\User;
|
||||
use App\Entity\BulkInfoProviderImportJob;
|
||||
use App\Entity\BulkInfoProviderImportJobPart;
|
||||
use App\Services\Trees\NodesListBuilder;
|
||||
use Doctrine\Common\Collections\ArrayCollection;
|
||||
use Doctrine\ORM\QueryBuilder;
|
||||
|
|
@ -101,6 +106,14 @@ class PartFilter implements FilterInterface
|
|||
public readonly TextConstraint $bomName;
|
||||
public readonly TextConstraint $bomComment;
|
||||
|
||||
/*************************************************
|
||||
* Bulk Import Job tab
|
||||
*************************************************/
|
||||
|
||||
public readonly BulkImportJobExistsConstraint $inBulkImportJob;
|
||||
public readonly BulkImportJobStatusConstraint $bulkImportJobStatus;
|
||||
public readonly BulkImportPartStatusConstraint $bulkImportPartStatus;
|
||||
|
||||
public function __construct(NodesListBuilder $nodesListBuilder)
|
||||
{
|
||||
$this->name = new TextConstraint('part.name');
|
||||
|
|
@ -126,7 +139,7 @@ class PartFilter implements FilterInterface
|
|||
*/
|
||||
$this->amountSum = (new IntConstraint('(
|
||||
SELECT COALESCE(SUM(__partLot.amount), 0.0)
|
||||
FROM '.PartLot::class.' __partLot
|
||||
FROM ' . PartLot::class . ' __partLot
|
||||
WHERE __partLot.part = part.id
|
||||
AND __partLot.instock_unknown = false
|
||||
AND (__partLot.expiration_date IS NULL OR __partLot.expiration_date > CURRENT_DATE())
|
||||
|
|
@ -162,6 +175,11 @@ class PartFilter implements FilterInterface
|
|||
$this->bomName = new TextConstraint('_projectBomEntries.name');
|
||||
$this->bomComment = new TextConstraint('_projectBomEntries.comment');
|
||||
|
||||
// Bulk Import Job filters
|
||||
$this->inBulkImportJob = new BulkImportJobExistsConstraint();
|
||||
$this->bulkImportJobStatus = new BulkImportJobStatusConstraint();
|
||||
$this->bulkImportPartStatus = new BulkImportPartStatusConstraint();
|
||||
|
||||
}
|
||||
|
||||
public function apply(QueryBuilder $queryBuilder): void
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue