diff options
author | Étienne Loks <etienne.loks@iggdrasil.net> | 2016-09-12 15:05:16 +0200 |
---|---|---|
committer | Étienne Loks <etienne.loks@iggdrasil.net> | 2016-09-12 15:05:16 +0200 |
commit | 9ad7082177fb9402723fe704c48d63e078e299a0 (patch) | |
tree | 72fc70286340f5f6fd906fe8a2f781368f83612f | |
parent | 84480c3374eafc1c244d9e5491c2142b923e4267 (diff) | |
download | Ishtar-9ad7082177fb9402723fe704c48d63e078e299a0.tar.bz2 Ishtar-9ad7082177fb9402723fe704c48d63e078e299a0.zip |
Manual merge action (refs #3176)
-rw-r--r-- | ishtar_common/forms_common.py | 98 | ||||
-rw-r--r-- | ishtar_common/ishtar_menu.py | 12 | ||||
-rw-r--r-- | ishtar_common/models.py | 4 | ||||
-rw-r--r-- | ishtar_common/templates/blocks/JQueryJqGrid.html | 4 | ||||
-rw-r--r-- | ishtar_common/templates/ishtar/display_item.html | 11 | ||||
-rw-r--r-- | ishtar_common/templates/ishtar/form.html | 5 | ||||
-rw-r--r-- | ishtar_common/urls.py | 17 | ||||
-rw-r--r-- | ishtar_common/views.py | 77 |
8 files changed, 218 insertions, 10 deletions
diff --git a/ishtar_common/forms_common.py b/ishtar_common/forms_common.py index e288745e2..77e9c8972 100644 --- a/ishtar_common/forms_common.py +++ b/ishtar_common/forms_common.py @@ -33,6 +33,7 @@ from django.utils.translation import ugettext_lazy as _ import models import widgets +from ishtar_common.templatetags.link_to_window import link_to_window from forms import FinalForm, FormSet, reverse_lazy, name_validator, \ TableSelect, ManageOldType @@ -228,6 +229,86 @@ class OrganizationFormSelection(forms.Form): validators=[models.valid_id(models.Organization)]) +class ManualMerge(object): + def clean_to_merge(self): + value = self.cleaned_data.get('to_merge', None) or [] + if value: + value = value.split(',') + values = [] + for val in value: + try: + values.append(int(val)) + except ValueError: + pass + if len(values) < 2: + raise forms.ValidationError(_(u"At leat two items have to be " + u"selected.")) + self.cleaned_data['to_merge'] = values + return values + + def get_items(self): + items = [] + model = self.associated_models['to_merge'] + for pk in sorted(self.cleaned_data['to_merge']): + try: + items.append(model.objects.get(pk=pk)) + except model.DoesNotExist: + pass + return items + + +class MergeIntoForm(forms.Form): + main_item = forms.ChoiceField( + label=_("Merge all items into"), choices=[], + widget=forms.RadioSelect()) + + def __init__(self, *args, **kwargs): + self.items = kwargs.pop('items') + super(MergeIntoForm, self).__init__(*args, **kwargs) + self.fields['main_item'].choices = [] + for pk in self.items: + try: + item = self.associated_model.objects.get(pk=pk) + except self.associated_model.DoesNotExist: + continue + self.fields['main_item'].choices.append( + (item.pk, mark_safe(u"{} {}".format(link_to_window(item), + unicode(item))))) + + def merge(self): + model = self.associated_model + try: + main_item = model.objects.get(pk=self.cleaned_data['main_item']) + except model.DoesNotExist: + return + for pk in self.items: + if pk == unicode(main_item.pk): + continue + try: + item = model.objects.get(pk=pk) + except model.DoesNotExist: + continue + main_item.merge(item) + return main_item + + +class OrgaMergeFormSelection(ManualMerge, forms.Form): + form_label = _(u"Organization to merge") + associated_models = {'to_merge': models.Organization} + currents = {'to_merge': models.Organization} + to_merge = forms.CharField( + label="", required=False, + widget=widgets.JQueryJqGrid( + reverse_lazy('get-organization'), OrganizationSelect, + models.Organization, + multiple_select=True, + source_full=reverse_lazy('get-organization-full')),) + + +class OrgaMergeIntoForm(MergeIntoForm): + associated_model = models.Organization + + class BaseOrganizationForm(forms.ModelForm): form_prefix = "orga" @@ -266,6 +347,23 @@ class PersonFormSelection(forms.Form): validators=[models.valid_id(models.Person)]) +class PersonMergeFormSelection(ManualMerge, forms.Form): + form_label = _("Person to merge") + associated_models = {'to_merge': models.Person} + currents = {'to_merge': models.Person} + to_merge = forms.CharField( + label="", required=False, + widget=widgets.JQueryJqGrid( + reverse_lazy('get-person'), + PersonSelect, models.Person, + multiple_select=True, + source_full=reverse_lazy('get-person-full')),) + + +class PersonMergeIntoForm(MergeIntoForm): + associated_model = models.Person + + class SimplePersonForm(ManageOldType, NewItemForm): form_label = _("Identity") associated_models = {'attached_to': models.Organization, diff --git a/ishtar_common/ishtar_menu.py b/ishtar_common/ishtar_menu.py index 39bf7c1d6..1f30bec0f 100644 --- a/ishtar_common/ishtar_menu.py +++ b/ishtar_common/ishtar_menu.py @@ -59,7 +59,11 @@ MENU_SECTIONS = [ model=models.Person, access_controls=['change_person', 'change_own_person']), MenuItem( - 'person_merge', _(u"Merge"), + 'person-merge', _(u"Automatic merge"), + model=models.Person, + access_controls=['merge_person']), + MenuItem( + 'person-manual-merge', _(u"Manual merge"), model=models.Person, access_controls=['merge_person']), MenuItem( @@ -86,7 +90,11 @@ MENU_SECTIONS = [ access_controls=['change_organization', 'change_own_organization']), MenuItem( - 'organization_merge', _(u"Merge"), + 'organization-merge', _(u"Automatic merge"), + model=models.Organization, + access_controls=['merge_organization']), + MenuItem( + 'orga-manual-merge', _(u"Manual merge"), model=models.Organization, access_controls=['merge_organization']), MenuItem( diff --git a/ishtar_common/models.py b/ishtar_common/models.py index f3f9f0778..9ec03b60e 100644 --- a/ishtar_common/models.py +++ b/ishtar_common/models.py @@ -2220,7 +2220,7 @@ pre_delete.connect(pre_delete_import, sender=Import) class Organization(Address, Merge, OwnPerms, ValueGetter): - TABLE_COLS = ('name', 'organization_type',) + TABLE_COLS = ('name', 'organization_type', 'town') SHOW_URL = 'show-organization' name = models.CharField(_(u"Name"), max_length=500) organization_type = models.ForeignKey(OrganizationType, @@ -2298,7 +2298,7 @@ class Person(Address, Merge, OwnPerms, ValueGetter): ('Dr', _(u'Doctor')), ) TABLE_COLS = ('name', 'surname', 'raw_name', 'email', 'person_types_list', - 'attached_to') + 'attached_to', 'town') SHOW_URL = 'show-person' MODIFY_URL = 'person_modify' old_title = models.CharField(_(u"Title"), max_length=100, choices=TYPE, diff --git a/ishtar_common/templates/blocks/JQueryJqGrid.html b/ishtar_common/templates/blocks/JQueryJqGrid.html index 44f4b0ba8..5972208ee 100644 --- a/ishtar_common/templates/blocks/JQueryJqGrid.html +++ b/ishtar_common/templates/blocks/JQueryJqGrid.html @@ -133,7 +133,11 @@ jQuery(document).ready(function(){ {% else %} jQuery("#submit_form").click(function (){ var mygrid = jQuery("#grid_{{name}}"); + {% if multiple_select %} + jQuery("#hidden_{{name}}").val(mygrid.getGridParam('selarrrow')); + {% else %} jQuery("#hidden_{{name}}").val(mygrid.getGridParam('selrow')); + {% endif %} return true; }); {% endif %} diff --git a/ishtar_common/templates/ishtar/display_item.html b/ishtar_common/templates/ishtar/display_item.html new file mode 100644 index 000000000..87dda6dcf --- /dev/null +++ b/ishtar_common/templates/ishtar/display_item.html @@ -0,0 +1,11 @@ +{% extends "base.html" %} +{% load i18n %} +{% load url from future %} +{% block content %} +<h2>{{page_name}}</h2> +<script type='text/javascript'> +$(function() { + load_window("{% url item_url pk %}"); +}); +</script> +{% endblock %} diff --git a/ishtar_common/templates/ishtar/form.html b/ishtar_common/templates/ishtar/form.html index 1e795c540..539bd0408 100644 --- a/ishtar_common/templates/ishtar/form.html +++ b/ishtar_common/templates/ishtar/form.html @@ -3,11 +3,12 @@ {% block content %} <h2>{{page_name}}</h2> <div class='form'> -<form enctype="multipart/form-data" action="." method="post">{% csrf_token %} +<form enctype="multipart/form-data" action="." method="post"{% if confirm %} + onsubmit='return confirm("{{confirm}}");'{% endif %}>{% csrf_token %} <table> {{form}} </table> -<input type="submit" value="{% trans "Validate" %}"/> +<input id="submit_form" type="submit" value="{% if submit_label %}{{submit_label}}{% else%}{% trans "Validate" %}{% endif %}"/> </form> </div> {% endblock %} diff --git a/ishtar_common/urls.py b/ishtar_common/urls.py index 049bcaf7b..27078dd9e 100644 --- a/ishtar_common/urls.py +++ b/ishtar_common/urls.py @@ -35,6 +35,8 @@ urlpatterns = patterns( url(r'^i18n/', include('django.conf.urls.i18n')), # General url(r'shortcut_menu/', views.shortcut_menu, name='shortcut-menu'), + url(r'display/(?P<item_type>\w+)/(?P<pk>\d+)/', + views.DisplayItemView.as_view(), name='display-item'), url(r'person_search/(?P<step>.+)?$', check_rights(['add_person'])( views.person_search_wizard), name='person_search'), @@ -174,10 +176,21 @@ urlpatterns += patterns( 'autocomplete_organization', name='autocomplete-organization'), url(r'admin-globalvar/', views.GlobalVarEdit.as_view(), name='admin-globalvar'), - url(r'person_merge/(?:(?P<page>\d+)/)?$', 'person_merge', + url(r'person-merge/(?:(?P<page>\d+)/)?$', 'person_merge', name='person_merge'), - url(r'organization_merge/(?:(?P<page>\d+)/)?$', 'organization_merge', + url(r'person-manual-merge/$', + views.PersonManualMerge.as_view(), + name='person_manual_merge'), + url(r'person-manual-merge-items/(?P<pks>[0-9_]+?)/$', + views.PersonManualMergeItems.as_view(), + name='person_manual_merge_items'), + url(r'organization-merge/(?:(?P<page>\d+)/)?$', 'organization_merge', name='organization_merge'), + url(r'orga-manual-merge/$', views.OrgaManualMerge.as_view(), + name='orga_manual_merge'), + url(r'orga-manual-merge-items/(?P<pks>[0-9_]+?)/$', + views.OrgaManualMergeItems.as_view(), + name='orga_manual_merge_items'), url(r'reset/$', 'reset_wizards', name='reset_wizards'), url(r'(?P<action_slug>' + actions + r')/$', 'action', name='action'), ) diff --git a/ishtar_common/views.py b/ishtar_common/views.py index d55181067..5f3e80c77 100644 --- a/ishtar_common/views.py +++ b/ishtar_common/views.py @@ -47,8 +47,8 @@ from django.shortcuts import render_to_response, redirect from django.template import RequestContext, loader from django.utils.decorators import method_decorator from django.utils.translation import ugettext, ugettext_lazy as _ -from django.views.generic import ListView, UpdateView -from django.views.generic.edit import CreateView, DeleteView +from django.views.generic import ListView, UpdateView, TemplateView +from django.views.generic.edit import CreateView, DeleteView, FormView from xhtml2odt import xhtml2odt @@ -1359,6 +1359,16 @@ class AdminLoginRequiredMixin(LoginRequiredMixin): request, *args, **kwargs) +class DisplayItemView(IshtarMixin, LoginRequiredMixin, TemplateView): + template_name = 'ishtar/display_item.html' + + def get_context_data(self, *args, **kwargs): + data = super(DisplayItemView, self).get_context_data(*args, **kwargs) + data['pk'] = unicode(kwargs.get('pk')) + '/' + data['item_url'] = 'show-' + kwargs.get('item_type') + return data + + class GlobalVarEdit(IshtarMixin, AdminLoginRequiredMixin, ModelFormSetView): template_name = 'ishtar/formset.html' model = models.GlobalVar @@ -1472,6 +1482,69 @@ class PersonEdit(LoginRequiredMixin, UpdateView): return reverse('person_edit', args=[self.object.pk]) +class ManualMergeMixin(object): + def form_valid(self, form): + self.items = form.get_items() + return super(ManualMergeMixin, self).form_valid(form) + + def get_success_url(self): + return reverse( + self.redir_url, + args=[u"_".join([str(item.pk) for item in self.items])]) + + +class PersonManualMerge(ManualMergeMixin, IshtarMixin, LoginRequiredMixin, + FormView): + form_class = forms.PersonMergeFormSelection + template_name = 'ishtar/form.html' + page_name = _(u"Merge persons") + current_url = 'person-manual-merge' + redir_url = 'person_manual_merge_items' + + +class ManualMergeItemsMixin(object): + def get_form_kwargs(self): + kwargs = super(ManualMergeItemsMixin, self).get_form_kwargs() + kwargs['items'] = self.kwargs['pks'].split('_') + return kwargs + + def form_valid(self, form): + self.item = form.merge() + return super(ManualMergeItemsMixin, self).form_valid(form) + + def get_success_url(self): + return reverse('display-item', args=[self.item_type, self.item.pk]) + + +class PersonManualMergeItems( + ManualMergeItemsMixin, IshtarMixin, + LoginRequiredMixin, FormView): + form_class = forms.PersonMergeIntoForm + template_name = 'ishtar/form.html' + page_name = _(u"Select the main person") + current_url = 'person-manual-merge-items' + item_type = 'person' + + +class OrgaManualMerge(ManualMergeMixin, IshtarMixin, LoginRequiredMixin, + FormView): + form_class = forms.OrgaMergeFormSelection + template_name = 'ishtar/form.html' + page_name = _(u"Merge organization") + current_url = 'orga-manual-merge' + redir_url = 'orga_manual_merge_items' + + +class OrgaManualMergeItems( + ManualMergeItemsMixin, IshtarMixin, + LoginRequiredMixin, FormView): + form_class = forms.OrgaMergeIntoForm + template_name = 'ishtar/form.html' + page_name = _(u"Select the main organization") + current_url = 'orga-manual-merge-items' + item_type = 'organization' + + class OrganizationCreate(LoginRequiredMixin, CreateView): model = models.Organization form_class = forms.BaseOrganizationForm |