Fixed total amount and less than desired filter on postgresql

This commit is contained in:
Jan Böhmer 2024-06-16 23:26:57 +02:00
parent 6d1553e8d8
commit d3dcefb645
3 changed files with 22 additions and 5 deletions

View file

@ -23,13 +23,20 @@ declare(strict_types=1);
namespace App\DataTables\Filters\Constraints\Part;
use App\DataTables\Filters\Constraints\BooleanConstraint;
use App\Entity\Parts\PartLot;
use Doctrine\ORM\QueryBuilder;
class LessThanDesiredConstraint extends BooleanConstraint
{
public function __construct(string $property = null, string $identifier = null, ?bool $default_value = null)
{
parent::__construct($property ?? 'amountSum', $identifier, $default_value);
parent::__construct($property ?? '(
SELECT COALESCE(SUM(ld_partLot.amount), 0.0)
FROM '.PartLot::class.' ld_partLot
WHERE ld_partLot.part = part.id
AND ld_partLot.instock_unknown = false
AND (ld_partLot.expiration_date IS NULL OR ld_partLot.expiration_date > CURRENT_DATE())
)', $identifier ?? 'amountSumLessThanDesired', $default_value);
}
public function apply(QueryBuilder $queryBuilder): void
@ -41,9 +48,9 @@ class LessThanDesiredConstraint extends BooleanConstraint
//If value is true, we want to filter for parts with stock < desired stock
if ($this->value) {
$queryBuilder->andHaving('amountSum < minamount');
$queryBuilder->andHaving( $this->property . ' < minamount');
} else {
$queryBuilder->andHaving('amountSum >= minamount');
$queryBuilder->andHaving($this->property . ' >= minamount');
}
}
}

View file

@ -37,6 +37,7 @@ use App\Entity\Parts\Category;
use App\Entity\Parts\Footprint;
use App\Entity\Parts\Manufacturer;
use App\Entity\Parts\MeasurementUnit;
use App\Entity\Parts\PartLot;
use App\Entity\Parts\StorageLocation;
use App\Entity\Parts\Supplier;
use App\Entity\ProjectSystem\Project;
@ -123,8 +124,13 @@ class PartFilter implements FilterInterface
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
*/
//We have to use Having here, as we use an alias column which is not supported on the where clause and would result in an error
$this->amountSum = (new IntConstraint('amountSum'))->useHaving();
$this->amountSum = (new IntConstraint('(
SELECT COALESCE(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())
)', identifier: "amountSumWhere"));
$this->lotCount = new IntConstraint('COUNT(_partLots)');
$this->lessThanDesired = new LessThanDesiredConstraint();

View file

@ -99,6 +99,10 @@ class DatatablesAvailabilityTest extends WebTestCase
//Test using filters
yield ['/category/1/parts?part_filter%5Bname%5D%5Boperator%5D=%3D&part_filter%5Bname%5D%5Bvalue%5D=BC547&part_filter%5Bcategory%5D%5Boperator%5D=INCLUDING_CHILDREN&part_filter%5Btags%5D%5Boperator%5D=ANY&part_filter%5Btags%5D%5Bvalue%5D=Test&part_filter%5Bsubmit%5D='];
yield ['/category/1/parts?part_filter%5Bcategory%5D%5Boperator%5D=INCLUDING_CHILDREN&part_filter%5Bstorelocation%5D%5Boperator%5D=%3D&part_filter%5Bstorelocation%5D%5Bvalue%5D=1&part_filter%5BattachmentsCount%5D%5Boperator%5D=%3D&part_filter%5BattachmentsCount%5D%5Bvalue1%5D=3&part_filter%5Bsubmit%5D='];
//Filter over total amount
yield ['/parts?part_filter%5BamountSum%5D%5Boperator%5D=>&part_filter%5BamountSum%5D%5Bvalue1%5D=1&part_filter%5Bsubmit%5D='];
//Less than desired filter:
yield ['/parts?part_filter%5BlessThanDesired%5D%5Bvalue%5D=true&part_filter%5Bsubmit%5D='];
//Test regex search
yield ['/parts/search?category=1&comment=1&description=1&ipn=1&keyword=test&mpn=1&name=1&ordernr=1&regex=1&storelocation=1&tags=1'];