mirror of
https://github.com/Part-DB/Part-DB-server.git
synced 2025-06-21 01:25:55 +02:00
Allow to order and filter by the amount sum of parts.
This commit is contained in:
parent
ec5e956e31
commit
8f94a58c71
8 changed files with 42 additions and 3 deletions
|
@ -32,4 +32,5 @@ doctrine:
|
|||
|
||||
dql:
|
||||
string_functions:
|
||||
regexp: DoctrineExtensions\Query\Mysql\Regexp
|
||||
regexp: DoctrineExtensions\Query\Mysql\Regexp
|
||||
ifnull: DoctrineExtensions\Query\Mysql\IfNull
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
namespace App\DataTables\Filters\Constraints;
|
||||
|
||||
use Doctrine\DBAL\ParameterType;
|
||||
use Doctrine\ORM\QueryBuilder;
|
||||
|
||||
trait FilterTrait
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
namespace App\DataTables\Filters\Constraints;
|
||||
|
||||
use Doctrine\DBAL\ParameterType;
|
||||
use Doctrine\ORM\QueryBuilder;
|
||||
use \RuntimeException;
|
||||
|
||||
|
|
|
@ -19,7 +19,6 @@ use App\Entity\Parts\Storelocation;
|
|||
use App\Entity\Parts\Supplier;
|
||||
use App\Services\Trees\NodesListBuilder;
|
||||
use Doctrine\ORM\QueryBuilder;
|
||||
use Svg\Tag\Text;
|
||||
|
||||
class PartFilter implements FilterInterface
|
||||
{
|
||||
|
@ -83,6 +82,9 @@ class PartFilter implements FilterInterface
|
|||
/** @var IntConstraint */
|
||||
protected $lotCount;
|
||||
|
||||
/** @var NumberConstraint */
|
||||
protected $amountSum;
|
||||
|
||||
/** @var BooleanConstraint */
|
||||
protected $lotNeedsRefill;
|
||||
|
||||
|
@ -127,7 +129,12 @@ class PartFilter implements FilterInterface
|
|||
$this->addedDate = new DateTimeConstraint('part.addedDate');
|
||||
$this->lastModified = new DateTimeConstraint('part.lastModified');
|
||||
|
||||
$this->minAmount = new NumberConstraint('part.minAmount');
|
||||
$this->minAmount = new NumberConstraint('part.minamount');
|
||||
/* We have to use an IntConstraint here because otherwise we get just an empty result list when applying the filter
|
||||
This seems to be related to the fact, that PDO does not have an float parameter type and using string type does not work in this situation (at least in SQLite)
|
||||
TODO: Find a better solution here
|
||||
*/
|
||||
$this->amountSum = new IntConstraint('amountSum');
|
||||
$this->lotCount = new IntConstraint('COUNT(partLots)');
|
||||
$this->supplier = new EntityConstraint($nodesListBuilder, Supplier::class, 'orderdetails.supplier');
|
||||
$this->lotNeedsRefill = new BooleanConstraint('partLots.needs_refill');
|
||||
|
@ -360,6 +367,10 @@ class PartFilter implements FilterInterface
|
|||
return $this->manufacturing_status;
|
||||
}
|
||||
|
||||
public function getAmountSum(): NumberConstraint
|
||||
{
|
||||
return $this->amountSum;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -53,6 +53,7 @@ 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\AmountFormatter;
|
||||
|
@ -232,6 +233,7 @@ final class PartsDataTable implements DataTableTypeInterface
|
|||
|
||||
return $this->amountFormatter->format($amount, $context->getPartUnit());
|
||||
},
|
||||
'orderField' => 'amountSum'
|
||||
])
|
||||
->add('minamount', TextColumn::class, [
|
||||
'label' => $this->translator->trans('part.table.minamount'),
|
||||
|
@ -326,6 +328,7 @@ final class PartsDataTable implements DataTableTypeInterface
|
|||
|
||||
private function getQuery(QueryBuilder $builder): void
|
||||
{
|
||||
|
||||
$builder->distinct()->select('part')
|
||||
->addSelect('category')
|
||||
->addSelect('footprint')
|
||||
|
@ -337,6 +340,16 @@ final class PartsDataTable implements DataTableTypeInterface
|
|||
->addSelect('orderdetails')
|
||||
->addSelect('attachments')
|
||||
->addSelect('storelocations')
|
||||
//Calculate amount sum using a subquery, so we can filter and sort by it
|
||||
->addSelect(
|
||||
'(
|
||||
SELECT IFNULL(SUM(partLot.amount), 0.0)
|
||||
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())
|
||||
) AS HIDDEN amountSum'
|
||||
)
|
||||
->from(Part::class, 'part')
|
||||
->leftJoin('part.category', 'category')
|
||||
->leftJoin('part.master_picture_attachment', 'master_picture_attachment')
|
||||
|
|
|
@ -173,6 +173,11 @@ class PartFilterType extends AbstractType
|
|||
'step' => 1,
|
||||
]);
|
||||
|
||||
$builder->add('amountSum', NumberConstraintType::class, [
|
||||
'label' => 'part.filter.amount_sum',
|
||||
'min' => 0,
|
||||
]);
|
||||
|
||||
$builder->add('lotNeedsRefill', BooleanConstraintType::class, [
|
||||
'label' => 'part.filter.lotNeedsRefill'
|
||||
]);
|
||||
|
|
|
@ -54,6 +54,7 @@
|
|||
<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.amountSum) }}
|
||||
{{ form_row(filterForm.lotCount) }}
|
||||
{{ form_row(filterForm.lotExpirationDate) }}
|
||||
{{ form_row(filterForm.lotNeedsRefill) }}
|
||||
|
|
|
@ -9513,5 +9513,11 @@ Element 3</target>
|
|||
<target>None of</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="ZnYcxRf" name="part.filter.amount_sum">
|
||||
<segment>
|
||||
<source>part.filter.amount_sum</source>
|
||||
<target>Total amount</target>
|
||||
</segment>
|
||||
</unit>
|
||||
</file>
|
||||
</xliff>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue