Forums › Forums › OroPlatform › OroPlatform – How do I? Questions › Datagrid: select ids that are not part of another select from the same table
This topic contains 10 replies, has 2 voices, and was last updated by Mike Kudelya 7 years, 4 months ago.
Starting from March 1, 2020 the forum has been switched to the read-only mode. Please head to StackOverflow for support.
- CreatorTopic
- November 15, 2016 at 6:01 am #36363
Hi,
I want to build a datagrid that selects all users who have not been updated in a date interval. Something like this:
SELECT u1.id, u1.username FROM oro_user u1 WHERE u1.id NOT IN (SELECT u2.id FROM oro_user u2 WHERE u2.updatedAt BETWEEN ‘2016-07-01’ AND ‘2016-11-30’)
Can i write a datagrid.yml to do this? I do not figure out how to write the condition!!!
Thanks!
- CreatorTopic
- AuthorReplies
- November 16, 2016 at 8:01 am #36364
Hi
I think subselect is not necessary.
XHTML1{{ dataGrid.renderGrid(gridName, {from: '2016-11-16 00:00:00', to: '2016-11-17 00:00:00'}, renderParams) }}datagrid.yml:
YAML123456789query:select:.......where:and:- u.createdAt < :from OR u.createdAt > :tobind_parameters:- from- toNovember 16, 2016 at 11:49 pm #36365Thanks Mike! Above i did not choose the best example to describe my problem.
I have a table with resources and a table with events related to those resources. What i need is a datagrid filled with all resources that do not have events that do not overlap with a time interval.
So, with standard select i would write:
MySQL12345678SELECT res.id FROM resources resWHERE res.id NOT IN (SELECT ev.resource_id FROM events evWHERE (ev.start >= :start AND ev.start <= :end) OR(ev.end >= :start AND ev.end <= :end) OR(ev.start >= :start AND ev.end <= :end) OR(ev.start <= :start AND ev.end >= :end))I did it this way:
YAML1234567891011121314151617query:select:- res.id...join:left:-join: res.eventsalias: evconditionType: WITHcondition: '(ev.start >= :start AND ev.start <= :end) OR (ev.end >= :start AND ev.end <= :end) OR (ev.start >= :start AND ev.end <= :end) OR (ev.start <= :start AND ev.end >= :end)'where:and:- ev.resource IS NULLbind_parameters:- start- endSo this is DONE.
Next i implemented a workflow to select start and end dates in the first step, and in the second step i extended oro_multiple_entity to use with the above grid in the 2nd workflow transition. The problem appears after i choose the rows from datagrid widget, which have to be added to the form field after pressing the <select> button. They render fine on the view, but when i submit the form it says “This value should not be blank.”
After digging a while i figured out that it does not sets the ids to the hidden form element to be saved (oro_workflow_transition_offer_resources_added)!!!
If i press on “x” it removes those coresponding ids from the view and also sets the ids to the hidden form element to be removed after submit. (oro_workflow_transition_offer_resources_removed)Do you have any idea why is this happening and how to fix it?!
Thanks!
November 17, 2016 at 1:07 am #36366I’ve found the missing code:
YAML12345678options:routerEnabled: falserowSelection:dataField: idcolumnName: hasContactselectors:included: '#appendPanelViews'excluded: '#removePanelViews'Thanks!
November 17, 2016 at 4:14 am #36367Back :(
Can you help me setting initial_elements of the oro_multiple_entity in a workflow step? I cannot figure it out!!!
November 17, 2016 at 6:57 am #36368Hi
Can you give me workflow config, templates so that i can emulate you case. Screenshots would be very useful. Can you give me more information, what do you want to achieve? What is wrong ?
November 17, 2016 at 8:20 am #36369This is my workflow config:
YAML123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146workflows:offer:label: 'Create new offer'entity: CB\Bundle\NewAgeBundle\Entity\Offerentity_attribute: offerattributes:offer_name:property_path: offer.nameoffer_start:property_path: offer.startoffer_end:property_path: offer.endoffer_campaign:property_path: offer.campaignoffer_panel_views:label: 'Panel Views'property_path: offer.panelViewssteps:started:label: 'Initiated'order: 10allowed_transitions:- create- filtersfiltered:label: 'Panel Views selected'order: 20allowed_transitions:- filters- closeclosed:label: 'Finished'order: 30allowed_transitions:transitions:create:label: 'Create offer'step_to: startedis_start: trueis_hidden: falseis_unavailable_hidden: falseacl_resource: cb_newage_offer_createdisplay_type: pagefrontend_options:icon: 'icon-edit'class: 'btn-primary'page:parent_route: 'cb_newage_offer_index'parent_label: cb.newage.offer.entity_plural_labelform_options:attribute_fields:offer_name:form_type: textoptions:required: trueconstraints:- NotBlank: ~offer_start:options:required: trueconstraints:- NotBlank: ~offer_end:options:required: trueconstraints:- NotBlank: ~offer_campaign:form_type: entityoptions:required: trueclass: CB\Bundle\NewAgeBundle\Entity\Campaignconstraints:- NotBlank: ~init_actions:- @create_date:attribute: $offer_start- @create_date:attribute: $offer_endtransition_definition: create_definitionfilters:label: 'Select panel views'step_to: filteredis_unavailable_hidden: falseacl_resource: cb_newage_offer_updatedisplay_type: pagefrontend_options:icon: 'icon-filter'class: 'btn-success'page:parent_route: 'cb_newage_offer_index'parent_label: cb.newage.offer.entity_plural_labelform_options:attribute_fields:offer_panel_views:form_type: cb_panel_view_multiple_entityoptions:required: trueclass: 'CBNewAgeBundle:PanelView'add_acl_resource: 'cb_newage_panel_view_view'selector_window_title: 'cb.newage.offer.form.select_panel_views'selection_route: 'cb_offer_widget_panel_views_info'constraints:- NotBlank: ~transition_definition: filters_definitionclose:label: 'Close'step_to: closedis_unavailable_hidden: falsefrontend_options:icon: 'icon-ok'transition_definition: closed_definitiontransition_definitions:create_definition:post_actions:- @create_related_entity: # create Offer if it not exist yetconditions:@empty: [$offer.id]parameters: ~- @redirect: # redirect to Offer view pageroute: 'cb_newage_offer_view'route_parameters:id: $offer.idworkflow: truefilters_definition:post_actions:- @tree:- actions:- @call_method:object: $offermethod: setPanelViewsmethod_parameters: $offer.panelViews- @redirect: # redirect to Offer view pageroute: 'cb_newage_offer_view'route_parameters:id: $offer.idclosed_definition: ~This is my type config:
PHP1234567891011121314151617181920212223<?phpnamespace CB\Bundle\NewAgeBundle\Form\Type;use Symfony\Component\Form\AbstractType;use Symfony\Component\OptionsResolver\OptionsResolverInterface;class PanelViewMultipleEntityType extends AbstractType{/*** {@inheritdoc}*/public function getParent(){return 'oro_multiple_entity';}/*** {@inheritdoc}*/public function getName(){return 'cb_panel_view_multiple_entity';}}First step in workflow is to create a new entity (offer). This is where i give a name and the time interval (start/end):
After that it redirects to the entity view:
Second step in the workflow is to select related entity records using a custom oro_multiselect_entity, with datagrid filtered by previous start and end date (datagrid config can be seen in above posts):
As you see in the picture there are no records added.Then i press <+Add> to add records:
Here i select the first two records and add them to the form.
And finally i save them, redirect to the entity view page and can be seen in the datagrid:
The problem appears when i go back one step, where i have to select new records/deselect currently selected. Previously selected records does not appear on the form so i can remove them.
Also if i press the <+Add> button to open the grid, they do not appear as selected in the grid:
I’d appreciate if you could help me with this issue.
Thanks!November 18, 2016 at 8:52 am #36370Hi
I found the way how to resolve the problem. I want to show here code which you probably wrote and new, which fixed the problem. Here is example how i added contacts to my opportunity entity.
I modified filters transition, main idea – give opportunity id to controller (custom_oro_contact_grid):
YAML12345678910111213141516171819202122232425filters:label: 'Select panel views'step_to: filteredis_unavailable_hidden: falsedisplay_type: pagefrontend_options:icon: 'icon-filter'class: 'btn-success'page:parent_route: 'orocrm_sales_opportunity_index'parent_label: cb.newage.offer.entity_plural_labelform_options:attribute_fields:test_contact:form_type: custom_multiple_entityoptions:required: trueclass: 'OroCRMContactBundle:Contact'selector_window_title: 'cb.newage.offer.form.select_panel_views'selection_route: 'custom_oro_contact_grid'selection_route_parameters:id: $opportunity.idconstraints:- NotBlank: ~transition_definition: filters_definitionHere is action (it returns list of contact ids which will be selected on grid):
PHP1234567891011121314151617/*** @Route("/widget/contact_grid/{id}", name="custom_contact_grid", requirements={"id"="\d+"}, defaults={"id"=0})* @Template*/public function contactGridAction(Opportunity $opportunity){$contactIds = [];$contacts = $opportunity->getTestContact();foreach ($contacts as $contact) {$contactIds[] = $contact->getId();}return ['contactIds' => $contactIds];}Action template:
XHTML12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182{% import 'OroDataGridBundle::macros.html.twig' as dataGrid %}{% set gridName = 'contacts-grid' %}<div class="widget-content grid-widget-content">{% set data_id = app.request.get('added') ? app.request.get('added')|split(',') : [] %}{% set params = {'_parameters' : {'data_in': data_id|merge(contactIds),'data_not_in': app.request.get('removed') ? app.request.get('removed')|split(','): []}} %}{% block content %}{{ dataGrid.renderGrid(gridName, params) }}<input type="hidden" name="appendTestContacts" id="appendTestContacts" value="{{ app.request.get('added') }}" /><input type="hidden" name="removeTestContacts" id="removeTestContacts" value="{{ app.request.get('removed') }}" />{% endblock %}<script type="text/javascript">{% set wid = app.request.get('_wid') %}require(['jquery', 'routing', 'orodatagrid/js/datagrid/listener/callback-listener', 'oroui/js/widget-manager','oroform/js/multiple-entity/model', 'orolocale/js/formatter/name'],function($, routing, CallbackListener, WidgetManager, MultipleEntityModel, nameFormatter) {var addedModels = {};WidgetManager.getWidgetInstance({{ wid|json_encode|raw }}, function (widget) {widget.getAction('select', 'adopted', function (selectBtn) {selectBtn.click(function () {var addedVal = $('#appendTestContacts').val();var removedVal = $('#removeTestContacts').val();var appendedIds = addedVal.length ? addedVal.split(',') : [];var removedIds = removedVal.length ? removedVal.split(',') : [];widget.trigger('completeSelection', appendedIds, addedModels, removedIds);});});});var gridName = {{ gridName|json_encode|raw }};$(function () {/** @type {orodatagrid.datagrid.listener.CallbackListener} */new CallbackListener({$gridContainer: $('[data-wid="{{ wid }}"]'),gridName: gridName,dataField: 'id',columnName: 'hasContact',processCallback: function (value, model, listener) {var isActive = model.get(listener.columnName);var id = model.get('id');if (isActive) {addedModels[id] = new MultipleEntityModel({'id': model.get('id'),'link': routing.generate('orocrm_contact_info', {id: model.get('id')}),'label': model.get('firstName') + ' ' + model.get('lastName'),'extraData': [{'label': 'Phone','value': model.get('phone')},{'label': 'Email','value': model.get('email')}]});} else if (addedModels.hasOwnProperty(id)) {delete addedModels[id];}}});});});</script><div class="widget-actions"><button type="reset" class="btn">{{ 'Cancel'|trans }}</button><button type="button" class="btn btn-primary" data-action-name="select">{{ 'Select'|trans }}</button></div></div>Here is my contact grid:
PHP123456789101112131415161718192021222324252627contacts-grid:extended_entity_name: %orocrm_contact.entity.class%source:type: ormquery:select:....- >(CASE WHEN (c.id IN (:data_in)) AND c.id NOT IN (:data_not_in)THEN true ELSE false END) as hasContactcolumns:hasContact:label: orocrm.account.assigned.labeleditable: truefrontend_type: booleanoptions:entityHint: contactexport: trueentity_pagination: truerouterEnabled: falserowSelection:dataField: idcolumnName: hasContactselectors:included: '#appendTestContacts'excluded: '#removeTestContacts'and last thing, custom multiple entity type (it is printing saved contacts on page):
PHP12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788<?phpnamespace Custom\Bundle\OroBundle\Form\Type;use Doctrine\Common\Collections\Collection;use Symfony\Component\Form\AbstractType;use Symfony\Component\Form\FormInterface;use Symfony\Component\Form\FormView;use Symfony\Component\Routing\Router;use Oro\Bundle\EntityBundle\Provider\EntityNameResolver;class CustomMultipleEntityType extends AbstractType{/*** @var Router*/protected $router;/*** @var EntityNameResolver*/protected $entityNameResolver;/*** @param Router $router* @param EntityNameResolver $entityNameResolver*/public function __construct(Router $router, EntityNameResolver $entityNameResolver){$this->entityNameResolver = $entityNameResolver;$this->router = $router;}/*** {@inheritdoc}*/public function finishView(FormView $view, FormInterface $form, array $options){$contactCollection = $form->getData();$view->vars['initial_elements'] = $this->getInitialElements($contactCollection);}/*** @param Collection $contacts* @param int|null $default* @return array*/protected function getInitialElements(Collection $contacts){$result = array();foreach ($contacts as $contact) {if (!$contact->getId()) {continue;}$primaryPhone = $contact->getPrimaryPhone();$primaryEmail = $contact->getPrimaryEmail();$result[] = array('id' => $contact->getId(),'label' => $this->entityNameResolver->getName($contact),'link' => $this->router->generate('orocrm_contact_info', array('id' => $contact->getId())),'extraData' => array(array('label' => 'Phone', 'value' => $primaryPhone ? $primaryPhone->getPhone() : null),array('label' => 'Email', 'value' => $primaryEmail ? $primaryEmail->getEmail() : null),));}return $result;}/*** {@inheritdoc}*/public function getParent(){return 'oro_multiple_entity';}/*** {@inheritdoc}*/public function getName(){return 'custom_multiple_entity';}}November 22, 2016 at 12:51 am #36371Thanks Mike!
Giving id to the controller fixed the problem. What i’ve encountered next is that when i apply a filter to the datagrid, in a workflow step, i get:
Catchable Fatal Error: Argument 1 passed to Doctrine\DBAL\Connection::resolveParams() must be of the type array, null given, called in /var/www/html/crm-application/vendor/doctrine/dbal/lib/Doctrine/DBAL/Connection.php on line 836 and defined in /var/www/html/crm-application/vendor/doctrine/dbal/lib/Doctrine/DBAL/Connection.php on line 1524
Outside of the workflow datagrid filters works fine. Any idea what could cause this?
November 22, 2016 at 4:35 am #36372My bad here, i was sending a datetime value, instead of a date.
Tnank you!
November 22, 2016 at 4:55 am #36373Hi
It is strange, i have modified contacts-grid and all works fine. Maybe you forgot set value (or column type) to binded parameter.. Try to make grid as easy as possible, to understand what is wrong. Here is my filters:
- AuthorReplies
The forum ‘OroPlatform – How do I? Questions’ is closed to new topics and replies.