#!/usr/bin/env python # -*- coding: utf-8 -*- # Copyright (C) 2012-2013 Étienne Loks # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU Affero General Public License as # published by the Free Software Foundation, either version 3 of the # License, or (at your option) any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Affero General Public License for more details. # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . # See the file COPYING for details. from django.conf import settings from django.core.exceptions import ObjectDoesNotExist from django.db.models import Max from django.shortcuts import render_to_response from django.template import RequestContext from django.utils.translation import ugettext_lazy as _ from ishtar_common.wizards import Wizard, ClosingWizard, DeletionWizard, \ SourceWizard import models from forms import ParcelForm class OperationWizard(Wizard): model = models.Operation object_parcel_type = 'operation' parcel_step_key = 'parcelsgeneral-' def get_template_names(self): templates = super(OperationWizard, self).get_template_names() current_step = self.steps.current if current_step.startswith('towns-'): #templates = ['ishtar/wizard/towns_wizard.html'] + templates pass if current_step.startswith('parcels-') or \ current_step.startswith('parcelsgeneral-') : templates = ['ishtar/wizard/parcels_wizard.html'] + templates return templates def get_context_data(self, form, **kwargs): """ Return extra context for templates """ context = super(OperationWizard, self).get_context_data(form, **kwargs) step = self.steps.current if step.startswith('towns-'): context['TOWNS'] = self.get_towns() elif step.startswith('parcels-'): # if a file is acciated to the operation add the button "Add all" general_form_key = 'general-' + self.url_name file_id = self.session_get_value(general_form_key, "associated_file") if file_id: context['add_all'] = True return context def get_towns(self): """ Obtention des villes disponibles """ general_form_key = 'general-' + self.url_name towns = [] file_id = self.session_get_value(general_form_key, "associated_file") if file_id: try: for town in models.File.objects.get(pk=int(file_id) ).towns.all(): towns.append((town.pk, unicode(town))) except (ValueError, ObjectDoesNotExist): pass return sorted(towns, key=lambda x:x[1]) else: return -1 def get_available_parcels(self, file_id): parcels = [] try: for parcel in models.File.objects.get(pk=int(file_id) ).parcels.all(): parcels.append((parcel.pk, parcel.short_label)) except (ValueError, ObjectDoesNotExist): pass return sorted(parcels, key=lambda x:x[1]) def get_form(self, step=None, data=None, files=None): """ Manage specifics fields """ if data: data = data.copy() else: data = {} if not step: #step = self.determine_step(request, storage) step = self.steps.current form = self.get_form_list()[step] general_form_key = 'general-' + self.url_name # manage the dynamic choice of towns if step.startswith('towns-') and hasattr(form, 'management_form'): data['TOWNS'] = self.get_towns() elif step.startswith('parcels') and hasattr(form, 'management_form'): file_id = self.session_get_value(general_form_key, "associated_file") if file_id: data['PARCELS'] = self.get_available_parcels(file_id) else: town_form_key = step.startswith('parcelsgeneral') \ and 'townsgeneral-' or 'towns-' town_form_key += self.url_name town_ids = self.session_get_value(town_form_key, 'town', multi=True) or [] towns = [] for town_id in town_ids: try: town = models.Town.objects.get(pk=int(town_id)) towns.append((town.pk, unicode(town))) except (ValueError, ObjectDoesNotExist): pass data['TOWNS'] = sorted(towns, key=lambda x:x[1]) data = data or None form = super(OperationWizard, self).get_form(step, data, files) return form def get_formated_datas(self, forms): """ Show a specific warning if no archaelogical file is provided """ datas = super(OperationWizard, self).get_formated_datas(forms) # if the general town form is used the advertissement is relevant has_no_af = [form.prefix for form in forms if form.prefix == 'townsgeneral-operation'] and True if has_no_af: datas = [[_(u"Warning: No Archaelogical File is provided. " u"If you have forget it return to the first step."), []]]\ + datas return datas def get_form_initial(self, step, data=None): initial = super(OperationWizard, self).get_form_initial(step) return initial ''' self.form_initialized = False if not step.startswith(self.parcel_step_key): return initial if initial: default = initial[-1].copy() if 'parcel_number' in default: default.pop('parcel_number') initial.append(default) # necessary to get the appropriate form number #self.form_initialized = True elif data: numbers, keys = set(), set() for k in data: items = k.split('-') try: numbers.add(int(items[-2])) except (ValueError, IndexError): continue keys.add(items[-1]) if numbers and max(numbers) - 1 > 0: initial = [dict([(k, data[step+'-'+unicode(max(numbers)-1)+'-'+k]) for k in keys if k != 'parcel_number'])] #self.form_initialized = True return initial''' def post(self, *args, **kwargs): request = self.request post_data = request.POST.copy() # add all parcel from available in the archaelogical file if not post_data.get('add_all_parcels'): return super(Wizard, self).post(*args, **kwargs) general_form_key = 'general-' + self.url_name file_id = self.session_get_value(general_form_key, "associated_file") if not file_id: return super(Wizard, self).post(*args, **kwargs) parcel_form_key = "parcels-" + self.url_name idx = -1 # remove non relevant deleted keys for k in post_data.keys(): if k.startswith(parcel_form_key) and k.endswith('-DELETE'): post_data.pop(k) for idx, parcel in enumerate(self.get_available_parcels(file_id)): parcel_pk, parcel_name = parcel post_data["%s-%d-parcel" % (parcel_form_key, idx)] = parcel_pk post_data[parcel_form_key+'-TOTAL_FORMS'] = idx + 1 request.POST = post_data return super(Wizard, self).post(*args, **kwargs) class OperationModificationWizard(OperationWizard): modification = True class OperationClosingWizard(ClosingWizard): model = models.Operation fields = ['year', 'operation_code', 'operation_type', 'associated_file', 'in_charge', 'start_date', 'excavation_end_date', 'comment', 'towns', 'remains'] class OperationDeletionWizard(DeletionWizard): model = models.Operation fields = OperationClosingWizard.fields class OperationSourceWizard(SourceWizard): model = models.OperationSource def get_form_initial(self, step, data=None): initial = super(OperationSourceWizard, self).get_form_initial(step) # put default index and operation_id field in the main source form general_form_key = 'selec-' + self.url_name if step.startswith('source-'): operation_id = None if self.session_has_key(general_form_key, 'operation'): try: operation_id = int(self.session_get_value(general_form_key, "operation")) except ValueError: pass elif self.session_has_key(general_form_key, "pk"): try: pk = self.session_get_value(general_form_key, "pk") source = models.OperationSource.objects.get(pk=pk) operation_id = source.operation.pk except (ValueError, ObjectDoesNotExist): pass if operation_id: initial['hidden_operation_id'] = operation_id if 'index' not in initial: max_val = models.OperationSource.objects.filter( operation__pk=operation_id).aggregate( Max('index'))["index__max"] initial['index'] = max_val and (max_val + 1) or 1 return initial class OperationSourceDeletionWizard(DeletionWizard): model = models.OperationSource fields = ['operation', 'title', 'source_type', 'authors',] class OperationAdministrativeActWizard(OperationWizard): edit = False def get_extra_model(self, dct, form_list): dct['history_modifier'] = self.request.user return dct def get_associated_item(self, dct): return self.get_current_object() def save_model(self, dct, m2m, whole_associated_models, form_list, return_object): associated_item = self.get_associated_item(dct) if not associated_item: return self.render(form_list[-1]) if isinstance(associated_item, models.File): dct['associated_file'] = associated_item elif isinstance(associated_item, models.Operation): dct['operation'] = associated_item dct['history_modifier'] = self.request.user if 'pk' in dct: dct.pop('pk') if self.edit: admact = self.get_current_object() for k in dct: if hasattr(admact, k): setattr(admact, k, dct[k]) else: admact = models.AdministrativeAct(**dct) admact.save() res = render_to_response('ishtar/wizard/wizard_done.html', {}, context_instance=RequestContext(self.request)) return res class OperationEditAdministrativeActWizard(OperationAdministrativeActWizard): model = models.AdministrativeAct edit = True def get_associated_item(self, dct): return self.get_current_object().operation class AdministrativeActDeletionWizard(ClosingWizard): model = models.AdministrativeAct fields = ['act_type', 'in_charge', 'operator', 'scientific', 'signatory', 'operation', 'associated_file', 'signature_date', 'act_object',] if settings.COUNTRY == 'fr': fields += ['ref_sra'] def done(self, form_list, **kwargs): obj = self.get_current_object() obj.delete() return render_to_response('ishtar/wizard/wizard_delete_done.html', {}, context_instance=RequestContext(self.request)) def is_preventive(form_name, model, type_key='operation_type', key=''): def func(self): request = self.request storage = self.storage if storage.prefix not in request.session or \ 'step_data' not in request.session[storage.prefix] or \ form_name not in request.session[storage.prefix]['step_data'] or\ form_name + '-' + type_key not in \ request.session[storage.prefix]['step_data'][form_name]: return False try: typ = request.session[storage.prefix]['step_data']\ [form_name][form_name+'-'+type_key] if type(typ) in (list, tuple): typ = typ[0] typ = int(typ) return model.is_preventive(typ, key) except ValueError: return False return func def has_associated_file(form_name, file_key='associated_file', negate=False): def func(self): request = self.request storage = self.storage if storage.prefix not in request.session or \ 'step_data' not in request.session[storage.prefix] or \ form_name not in request.session[storage.prefix]['step_data'] or\ form_name + '-' + file_key not in \ request.session[storage.prefix]['step_data'][form_name]: return negate try: file_id = request.session[storage.prefix]['step_data']\ [form_name][form_name+'-'+file_key] if type(file_id) in (list, tuple): file_id = file_id[0] file_id = int(file_id) return not negate except ValueError: return negate return func