From 144ade9f832f626423c56e0fac23c218ac9bedf9 Mon Sep 17 00:00:00 2001 From: BlackbitNeueMedien Date: Tue, 14 Jan 2020 12:38:40 +0100 Subject: [PATCH] [Object grid] Quantity value filter (#5211) * quantity value filter * quantity value filter * quantity value filter * server-side filtering * server-side filtering * SQL fix * code simplification * filter input value should only show value (not unit id) * only show valid units * remove commented code * remove unnecessary code * provide unit store as config option * filter on unit change --- .../AdminBundle/Helper/GridHelperService.php | 17 +-- .../js/pimcore/object/tags/quantityValue.js | 101 ++++++++++++++++++ .../Resources/public/js/pimcore/overrides.js | 2 +- .../ClassDefinition/Data/QuantityValue.php | 43 ++++++++ .../QuantityValue/DefaultConverter.php | 12 +++ 5 files changed, 166 insertions(+), 9 deletions(-) diff --git a/bundles/AdminBundle/Helper/GridHelperService.php b/bundles/AdminBundle/Helper/GridHelperService.php index c46f273fe3d..2bdb546d5ca 100644 --- a/bundles/AdminBundle/Helper/GridHelperService.php +++ b/bundles/AdminBundle/Helper/GridHelperService.php @@ -145,6 +145,7 @@ public function getFilterCondition($filterJson, ClassDefinition $class): string if ($filterJson) { $db = \Pimcore\Db::get(); $filters = json_decode($filterJson, true); + foreach ($filters as $filter) { $operator = '='; @@ -153,14 +154,6 @@ public function getFilterCondition($filterJson, ClassDefinition $class): string if ($filter['type'] == 'string') { $operator = 'LIKE'; - } elseif ($filter['type'] == 'numeric') { - if ($filterOperator == 'lt') { - $operator = '<'; - } elseif ($filterOperator == 'gt') { - $operator = '>'; - } elseif ($filterOperator == 'eq') { - $operator = '='; - } } elseif ($filter['type'] == 'date') { if ($filterOperator == 'lt') { $operator = '<'; @@ -175,6 +168,14 @@ public function getFilterCondition($filterJson, ClassDefinition $class): string } elseif ($filter['type'] == 'boolean') { $operator = '='; $filter['value'] = (int)$filter['value']; + } else { + if ($filterOperator == 'lt') { + $operator = '<'; + } elseif ($filterOperator == 'gt') { + $operator = '>'; + } elseif ($filterOperator == 'eq') { + $operator = '='; + } } $field = $class->getFieldDefinition($filterField); diff --git a/bundles/AdminBundle/Resources/public/js/pimcore/object/tags/quantityValue.js b/bundles/AdminBundle/Resources/public/js/pimcore/object/tags/quantityValue.js index 4ed3cd61a1d..f34e2b89bef 100644 --- a/bundles/AdminBundle/Resources/public/js/pimcore/object/tags/quantityValue.js +++ b/bundles/AdminBundle/Resources/public/js/pimcore/object/tags/quantityValue.js @@ -173,6 +173,107 @@ pimcore.object.tags.quantityValue = Class.create(pimcore.object.tags.abstract, { }; }, + getGridColumnFilter: function (field) { + if(typeof Ext.grid.filters.filter.QuantityValue === 'undefined') { + Ext.define('Ext.grid.filters.filter.QuantityValue', { + extend: 'Ext.grid.filters.filter.Number', + alias: 'grid.filter.quantityValue', + type: 'quantityValue', + constructor: function(config) { + var me = this; + me.callParent([ + config + ]); + + this.store = config.store; + this.defaultUnit = config.defaultUnit; + }, + createMenu: function () { + var me = this; + me.callParent(); + + var cfg = { + xtype: 'combo', + name: 'unit', + labelClsExtra: Ext.baseCSSPrefix + 'grid-filters-icon pimcore_nav_icon_quantityValue', + queryMode: 'local', + editable: false, + forceSelection: true, + hideEmptyLabel: false, + store: this.store, + value: this.defaultUnit, + valueField: 'id', + displayField: 'abbreviation', + margin: 0, + listeners: { + change: function (field) { + var me = this; + + me.onValueChange(field, { + RETURN: 1, + getKey: function () { + return null; + } + }); + + var value = {}; + if(me.filter) { + for(var i in me.filter) { + if (this.filter[i].getValue() !== null) { + value[i] = me.filter[i].getValue()[0][0]; + } + } + } + + me.setValue(value); + }.bind(this) + } + }; + if (me.getItemDefaults()) { + cfg = Ext.merge({}, me.getItemDefaults(), cfg); + } + + me.menu.insert(0, '-'); + me.fields.unit = me.menu.insert(0, cfg); + }, + setValue: function (value) { + var me = this; + var unitId = me.fields.unit.getValue(); + + for (var i in value) { + value[i] = [[value[i], unitId]]; + } + + me.callParent([value]); + }, + showMenu: function (menuItem) { + this.callParent([menuItem]); + + for (var i in this.filter) { + if (this.filter[i].getValue() !== null) { + this.fields[i].setValue(this.filter[i].getValue()[0][0]); + } + } + } + }); + } + + var store = new Ext.data.JsonStore({ + autoDestroy: true, + root: 'data', + fields: ['id', 'abbreviation'] + }); + pimcore.helpers.quantityValue.initUnitStore(function(data) { + store.loadData(data.data); + }, field.layout.validUnits); + + return { + type: 'quantityValue', + dataIndex: field.key, + store: store, + defaultUnit: field.layout.defaultUnit + }; + }, getLayoutShow: function () { this.getLayoutEdit(); diff --git a/bundles/AdminBundle/Resources/public/js/pimcore/overrides.js b/bundles/AdminBundle/Resources/public/js/pimcore/overrides.js index 1de66270e3a..44e7879042e 100644 --- a/bundles/AdminBundle/Resources/public/js/pimcore/overrides.js +++ b/bundles/AdminBundle/Resources/public/js/pimcore/overrides.js @@ -115,7 +115,7 @@ Ext.define('pimcore.filters', { var type = column.filter.type; var theFilter = column.filter.filter; - if (type == "date" || type == "numeric") { + if (column.filter instanceof Ext.grid.filters.filter.TriFilter) { theFilter.lt.config.type = type; theFilter.gt.config.type = type; theFilter.eq.config.type = type; diff --git a/models/DataObject/ClassDefinition/Data/QuantityValue.php b/models/DataObject/ClassDefinition/Data/QuantityValue.php index 6a2c456d1c1..d374804381c 100644 --- a/models/DataObject/ClassDefinition/Data/QuantityValue.php +++ b/models/DataObject/ClassDefinition/Data/QuantityValue.php @@ -18,9 +18,11 @@ use Pimcore\Cache; use Pimcore\Cache\Runtime; +use Pimcore\Db; use Pimcore\Logger; use Pimcore\Model; use Pimcore\Model\DataObject\ClassDefinition\Data; +use Pimcore\Model\DataObject\QuantityValue\UnitConversionService; class QuantityValue extends Data implements ResourcePersistenceAwareInterface, QueryResourcePersistenceAwareInterface { @@ -642,4 +644,45 @@ public static function __set_state($data) return $obj; } + + public function getFilterCondition($value, $operator, $params = []) + { + /** @var UnitConversionService $converter */ + $converter = \Pimcore::getContainer()->get(UnitConversionService::class); + + $filterValue = $value[0]; + $filterUnit = Model\DataObject\QuantityValue\Unit::getById($value[1]); + + if(!$filterUnit instanceof Model\DataObject\QuantityValue\Unit) { + return '0'; + } + + $filterQuantityValue = new Model\DataObject\Data\QuantityValue($filterValue, $filterUnit->getId()); + + $baseUnit = $filterUnit->getBaseunit() ?? $filterUnit; + + $unitListing = new Model\DataObject\QuantityValue\Unit\Listing(); + $unitListing->setCondition('baseunit='.Db::get()->quote($baseUnit->getId()).' OR id='.Db::get()->quote($filterUnit->getId())); + + $conditions = []; + foreach($unitListing->load() as $unit) { + $convertedQuantityValue = $converter->convert($filterQuantityValue, $unit); + + $conditions[] = '('. + $this->getFilterConditionExt( + $convertedQuantityValue->getValue(), + $operator, + ['name' => $this->getName().'__value'] + ). + ' AND '. + $this->getFilterConditionExt( + $convertedQuantityValue->getUnitId(), + '=', + ['name' => $this->getName().'__unit'] + ). + ')'; + } + + return implode(' OR ', $conditions); + } } diff --git a/models/DataObject/QuantityValue/DefaultConverter.php b/models/DataObject/QuantityValue/DefaultConverter.php index e020b287c49..b87c8c7d7af 100644 --- a/models/DataObject/QuantityValue/DefaultConverter.php +++ b/models/DataObject/QuantityValue/DefaultConverter.php @@ -17,7 +17,13 @@ public function convert(QuantityValue $quantityValue, Unit $toUnit): QuantityVal if ($fromBaseUnit === null) { $fromUnit = clone $fromUnit; $fromBaseUnit = $fromUnit; + } + + if($fromUnit->getFactor() === null) { $fromUnit->setFactor(1); + } + + if($fromUnit->getConversionOffset() === null) { $fromUnit->setConversionOffset(0); } @@ -25,7 +31,13 @@ public function convert(QuantityValue $quantityValue, Unit $toUnit): QuantityVal if ($toBaseUnit === null) { $toUnit = clone $toUnit; $toBaseUnit = $toUnit; + } + + if($toUnit->getFactor() === null) { $toUnit->setFactor(1); + } + + if($toUnit->getConversionOffset() === null) { $toUnit->setConversionOffset(0); }