mirror of
https://github.com/Part-DB/Part-DB-server.git
synced 2025-06-21 01:25:55 +02:00
Added constraints to filter for the number of orderdetails and attachments
This commit is contained in:
parent
768618cede
commit
5402d3b031
6 changed files with 91 additions and 6 deletions
|
@ -47,10 +47,16 @@ trait FilterTrait
|
|||
*/
|
||||
protected function addSimpleAndConstraint(QueryBuilder $queryBuilder, string $property, string $parameterIdentifier, string $comparison_operator, $value): void
|
||||
{
|
||||
if($this->useHaving || $this->isAggregateFunctionString($property)) { //If the property is an aggregate function, we have to use the "having" instead of the "where"
|
||||
$queryBuilder->andHaving(sprintf("%s %s (:%s)", $property, $comparison_operator, $parameterIdentifier));
|
||||
if ($comparison_operator === 'IN') {
|
||||
$expression = sprintf("%s %s (:%s)", $property, $comparison_operator, $parameterIdentifier);
|
||||
} else {
|
||||
$queryBuilder->andWhere(sprintf("%s %s (:%s)", $property, $comparison_operator, $parameterIdentifier));
|
||||
$expression = sprintf("%s %s :%s", $property, $comparison_operator, $parameterIdentifier);
|
||||
}
|
||||
|
||||
if($this->useHaving || $this->isAggregateFunctionString($property)) { //If the property is an aggregate function, we have to use the "having" instead of the "where"
|
||||
$queryBuilder->andHaving($expression);
|
||||
} else {
|
||||
$queryBuilder->andWhere($expression);
|
||||
}
|
||||
|
||||
$queryBuilder->setParameter($parameterIdentifier, $value);
|
||||
|
|
|
@ -68,10 +68,13 @@ class PartFilter implements FilterInterface
|
|||
/** @var EntityConstraint */
|
||||
protected $supplier;
|
||||
|
||||
/** @var IntConstraint */
|
||||
protected $orderdetailsCount;
|
||||
|
||||
/** @var EntityConstraint */
|
||||
protected $storelocation;
|
||||
|
||||
/** @var NumberConstraint */
|
||||
/** @var IntConstraint */
|
||||
protected $lotCount;
|
||||
|
||||
/** @var EntityConstraint */
|
||||
|
@ -83,6 +86,9 @@ class PartFilter implements FilterInterface
|
|||
/** @var TextConstraint */
|
||||
protected $manufacturer_product_number;
|
||||
|
||||
/** @var IntConstraint */
|
||||
protected $attachmentsCount;
|
||||
|
||||
public function __construct(NodesListBuilder $nodesListBuilder)
|
||||
{
|
||||
$this->name = new TextConstraint('part.name');
|
||||
|
@ -108,7 +114,10 @@ class PartFilter implements FilterInterface
|
|||
$this->manufacturer_product_url = new TextConstraint('part.manufacturer_product_url');
|
||||
|
||||
$this->storelocation = new EntityConstraint($nodesListBuilder, Storelocation::class, 'partLots.storage_location');
|
||||
|
||||
$this->lotCount = new IntConstraint('COUNT(partLots)');
|
||||
$this->attachmentsCount = new IntConstraint('COUNT(attachments)');
|
||||
$this->orderdetailsCount = new IntConstraint('COUNT(orderdetails)');
|
||||
}
|
||||
|
||||
public function apply(QueryBuilder $queryBuilder): void
|
||||
|
@ -261,4 +270,22 @@ class PartFilter implements FilterInterface
|
|||
{
|
||||
return $this->tags;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return IntConstraint
|
||||
*/
|
||||
public function getOrderdetailsCount(): IntConstraint
|
||||
{
|
||||
return $this->orderdetailsCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return IntConstraint
|
||||
*/
|
||||
public function getAttachmentsCount(): IntConstraint
|
||||
{
|
||||
return $this->attachmentsCount;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -348,7 +348,10 @@ final class PartsDataTable implements DataTableTypeInterface
|
|||
->leftJoin('part.orderdetails', 'orderdetails')
|
||||
->leftJoin('orderdetails.supplier', 'suppliers')
|
||||
->leftJoin('part.attachments', 'attachments')
|
||||
->leftJoin('part.partUnit', 'partUnit');
|
||||
->leftJoin('part.partUnit', 'partUnit')
|
||||
|
||||
->groupBy('part')
|
||||
;
|
||||
}
|
||||
|
||||
private function buildCriteria(QueryBuilder $builder, array $options): void
|
||||
|
|
|
@ -17,6 +17,7 @@ use App\Form\Filters\Constraints\TextConstraintType;
|
|||
use Svg\Tag\Text;
|
||||
use Symfony\Component\Form\AbstractType;
|
||||
use Symfony\Component\Form\Extension\Core\Type\DateTimeType;
|
||||
use Symfony\Component\Form\Extension\Core\Type\ResetType;
|
||||
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
use Symfony\Component\Form\SubmitButton;
|
||||
|
@ -72,6 +73,7 @@ class PartFilterType extends AbstractType
|
|||
$builder->add('dbId', NumberConstraintType::class, [
|
||||
'label' => 'part.filter.dbId',
|
||||
'min' => 1,
|
||||
'step' => 1,
|
||||
]);
|
||||
|
||||
$builder->add('favorite', BooleanConstraintType::class, [
|
||||
|
@ -128,6 +130,12 @@ class PartFilterType extends AbstractType
|
|||
'entity_class' => Manufacturer::class
|
||||
]);
|
||||
|
||||
$builder->add('orderdetailsCount', NumberConstraintType::class, [
|
||||
'label' => 'part.filter.orderdetails_count',
|
||||
'step' => 1,
|
||||
'min' => 0,
|
||||
]);
|
||||
|
||||
|
||||
/*
|
||||
* Stocks tabs
|
||||
|
@ -144,12 +152,26 @@ class PartFilterType extends AbstractType
|
|||
|
||||
$builder->add('lotCount', NumberConstraintType::class, [
|
||||
'label' => 'part.filter.lot_count',
|
||||
'min' => 0
|
||||
'min' => 0,
|
||||
'step' => 1,
|
||||
]);
|
||||
|
||||
/**
|
||||
* Attachments count
|
||||
*/
|
||||
$builder->add('attachmentsCount', NumberConstraintType::class, [
|
||||
'label' => 'part.filter.attachments_count',
|
||||
'step' => 1,
|
||||
'min' => 0,
|
||||
]);
|
||||
|
||||
$builder->add('submit', SubmitType::class, [
|
||||
'label' => 'Update',
|
||||
]);
|
||||
|
||||
$builder->add('reset', ResetType::class, [
|
||||
'label' => 'Reset',
|
||||
]);
|
||||
|
||||
}
|
||||
}
|
|
@ -14,6 +14,9 @@
|
|||
<li class="nav-item" role="presentation">
|
||||
<button class="nav-link" id="filter-stocks-tab" data-bs-toggle="tab" data-bs-target="#filter-stocks"><i class="fas fa-boxes fa-fw"></i> {% trans %}part.edit.tab.part_lots{% endtrans %}</button>
|
||||
</li>
|
||||
<li class="nav-item" role="presentation">
|
||||
<button class="nav-link" id="filter-attachments-tab" data-bs-toggle="tab" data-bs-target="#filter-attachments"><i class="fas fa-paperclip fa-fw"></i> {% trans %}part.edit.tab.attachments{% endtrans %}</button>
|
||||
</li>
|
||||
<li class="nav-item" role="presentation">
|
||||
<button class="nav-link" id="filter-orderdetails-tab" data-bs-toggle="tab" data-bs-target="#filter-orderdetails"><i class="fas fa-shopping-cart fa-fw"></i> {% trans %}part.edit.tab.orderdetails{% endtrans %}</button>
|
||||
</li>
|
||||
|
@ -50,10 +53,16 @@
|
|||
<div class="tab-pane pt-3" id="filter-stocks" role="tabpanel" aria-labelledby="filter-stocks-tab" tabindex="0">
|
||||
{{ form_row(filterForm.storelocation) }}
|
||||
{{ form_row(filterForm.minAmount) }}
|
||||
{{ form_row(filterForm.lotCount) }}
|
||||
</div>
|
||||
|
||||
<div class="tab-pane pt-3" id="filter-attachments" role="tabpanel" aria-labelledby="filter-attachments-tab" tabindex="0">
|
||||
{{ form_row(filterForm.attachmentsCount) }}
|
||||
</div>
|
||||
|
||||
<div class="tab-pane pt-3" id="filter-orderdetails" role="tabpanel" aria-labelledby="filter-orderdetails-tab" tabindex="0">
|
||||
{{ form_row(filterForm.supplier) }}
|
||||
{{ form_row(filterForm.orderdetailsCount) }}
|
||||
</div>
|
||||
|
||||
|
||||
|
|
|
@ -9459,5 +9459,23 @@ Element 3</target>
|
|||
<target>None of the tags</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="wgXINWq" name="part.filter.lot_count">
|
||||
<segment>
|
||||
<source>part.filter.lot_count</source>
|
||||
<target>Number of lots</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="tjfJAIq" name="part.filter.attachments_count">
|
||||
<segment>
|
||||
<source>part.filter.attachments_count</source>
|
||||
<target>Number of attachments</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="6Bt9ZhB" name="part.filter.orderdetails_count">
|
||||
<segment>
|
||||
<source>part.filter.orderdetails_count</source>
|
||||
<target>Number of orderdetails</target>
|
||||
</segment>
|
||||
</unit>
|
||||
</file>
|
||||
</xliff>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue