From 902704d20310f6fd9caee77948e60f12bd9a4cc8 Mon Sep 17 00:00:00 2001
From: janek37 <none@none>
Date: Mon, 1 Jul 2013 17:14:12 +0200
Subject: [PATCH] ostrzeganie przed usunięciem klasyfikacji, poprawki z powodu zmienionych tabel

---
 .idea/sqldialects.xml          |   2 +-
 dictionary/ajax_lexeme_view.py |   8 ++++++++
 dictionary/export.py           |  16 ++++++++--------
 dictionary/history.py          |   8 ++++----
 dictionary/views.py            |   1 +
 dictionary/wsjp.py             |  20 ++++++++++----------
 media/js/lexeme-view.js        | 101 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-----------------
 sql/drop.sql                   |   3 ++-
 sql/history.sql                |  10 +++++-----
 urls.py                        |   5 +++--
 10 files changed, 126 insertions(+), 48 deletions(-)

diff --git a/.idea/sqldialects.xml b/.idea/sqldialects.xml
index 63e2137..ed8d076 100644
--- a/.idea/sqldialects.xml
+++ b/.idea/sqldialects.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <project version="4">
   <component name="SqlDialectMappings">
-    <file url="file://$PROJECT_DIR$/sql/history.sql" dialect="PostgreSQL" />
+    <file url="file://$PROJECT_DIR$/sql" dialect="PostgreSQL" />
   </component>
 </project>
 
diff --git a/dictionary/ajax_lexeme_view.py b/dictionary/ajax_lexeme_view.py
index 2def009..4a00de2 100644
--- a/dictionary/ajax_lexeme_view.py
+++ b/dictionary/ajax_lexeme_view.py
@@ -145,6 +145,14 @@ def lexeme_edit_form(request, id):
   to_return['cross_references'] = crs
   return to_return
 
+@ajax(method='get')
+def check_classifications(request, owner_id, pos):
+  part_of_speech = PartOfSpeech.objects.get(symbol=pos)
+  owner = Vocabulary.objects.get(pk=owner_id)
+  classifications = owner.classifications.filter(
+    parts_of_speech=part_of_speech)
+  return {'classifications': list(classifications.values_list('pk', flat=True))}
+
 def make_classification_forms(lexeme, vocabulary=None, part_of_speech=None,
                               editable=True):
   if not vocabulary:
diff --git a/dictionary/export.py b/dictionary/export.py
index 71c3729..3f82819 100644
--- a/dictionary/export.py
+++ b/dictionary/export.py
@@ -89,10 +89,10 @@ def export_lexemes(data=None, output_file=None):
   cursor = connection.cursor()
   query = """
     select distinct haslo, prefiks||rdzen||zak||sufiks, l.pos, ch.charfl, tag,
-      l.id as leksem_id, refl.lexemeattributevalue_id %(clas_field)s
+      l.id as leksem_id, refl.attribute_value_id %(clas_field)s
     from leksemy l
       join leksemy_w_slownikach ls on (ls.l_id = l.id)
-      left outer join dictionary_lexemeattributevalue_lexemes refl
+      left outer join dictionary_lexemeav refl
         on (l.id = refl.lexeme_id and %(refl)s)
       join odmieniasie o on (o.l_id = l.id)
       join charfle ch on ch.id = o.charfl
@@ -111,13 +111,13 @@ def export_lexemes(data=None, output_file=None):
     union all
     -- wymagające gniazdowania przy hasłowaniu: adjcom, advcom, derywaty:
     select distinct g.haslo as haslo, prefiks||rdzen||zak||sufiks, l.pos,
-      ch.charfl, tag, l.id as leksem_id, refl.lexemeattributevalue_id
+      ch.charfl, tag, l.id as leksem_id, refl.attribute_value_id
       %(clas_field)s
     from leksemy l
       join leksemy_w_slownikach ls on (ls.l_id = l.id)
       join odsylacze on l.id=l_id_od
       join leksemy g on (l_id_do=g.id and g.usuniety = false)
-      left outer join dictionary_lexemeattributevalue_lexemes refl
+      left outer join dictionary_lexemeav refl
         on (g.id = refl.lexeme_id and %(refl)s)
       join odmieniasie o on l.id=o.l_id
       join charfle ch on ch.id = o.charfl
@@ -138,13 +138,13 @@ def export_lexemes(data=None, output_file=None):
       'x_qual': qualifier_clauses,
       'magic': magic_qualifier_clauses,
       'crtype_ids': ', '.join(str(pk) for pk in crtype_ids), # brzydko, oj tam
-      'clas_field': ', classificationvalue_id' if data['commonness'] else '',
+      'clas_field': ', classification_value_id' if data['commonness'] else '',
       'clas_join':
-        'left outer join wartosci_klasyfikacji_lexemes wkl '
-        'on (wkl.lexeme_id=l.id and wkl.classificationvalue_id in (%s))'
+        'left outer join dictionary_lexemecv wkl '
+        'on (wkl.lexeme_id=l.id and wkl.classification_value_id in (%s))'
         % ', '.join(str(pk) for pk in cv_ids) if data['commonness'] else '',
       'refl':
-        'refl.lexemeattributevalue_id in (%s)'
+        'refl.attribute_value_id in (%s)'
         % ', '.join(str(pk) for pk in refls),
     }
   params_part = (list(data['vocabs']) + list(data['antivocabs']) +
diff --git a/dictionary/history.py b/dictionary/history.py
index 759d97f..71b87a1 100644
--- a/dictionary/history.py
+++ b/dictionary/history.py
@@ -106,10 +106,10 @@ def prepare_value(table, column, value):
       prepared = InflectionCharacteristic.objects.get(pk=int(value)).symbol
     elif column == 'w_id':
       prepared = Pattern.objects.get(pk=int(value)).name
-    elif column == 'classificationvalue_id':
+    elif column in ('classification_value_id', 'classificationvalue_id'):
       cv = ClassificationValue.all_objects.get(pk=int(value))
       prepared = (cv.label, cv.classification.name)
-    elif column == 'lexemeattributevalue_id':
+    elif column == 'attribute_value_id':
       av = LexemeAttributeValue.objects.get(pk=int(value))
       prepared = (av.value, av.attribute.name)
     else:
@@ -152,9 +152,9 @@ def transaction_table(transaction_data):
         if item1.row_id not in lips:
           lips[item1.row_id] = {}
         lips[item1.row_id][attr] = before_after
-    if column == 'lexemeattributevalue_id':
+    if column == 'attribute_value_id':
       extra_attributes.append(before_after)
-    if column == 'classificationvalue_id':
+    if column in ('classification_value_id', 'classificationvalue_id'):
       classifications.append(before_after)
     if table == 'kwalifikatory_leksemow' and column == 'qualifier_id':
       qualifiers.append(before_after)
diff --git a/dictionary/views.py b/dictionary/views.py
index 9c1e8e5..99b0b76 100644
--- a/dictionary/views.py
+++ b/dictionary/views.py
@@ -65,6 +65,7 @@ def lexeme_view(request):
     'ajax_prompter_list': reverse('prompter_list'),
     'ajax_check_pos': reverse('check_pos'),
     'ajax_check_pattern': reverse('check_pattern'),
+    'ajax_check_classifications': reverse('check_classifications'),
     'ajax_get_ics': reverse('get_ics'),
     'ajax_save_default_owner': reverse('save_default_owner'),
     'ajax_create_lexeme': reverse('create_lexeme'),
diff --git a/dictionary/wsjp.py b/dictionary/wsjp.py
index 4a8c4d0..9656bad 100644
--- a/dictionary/wsjp.py
+++ b/dictionary/wsjp.py
@@ -20,8 +20,8 @@ def make_data(entries):
       as rodzaj, podparad, row, col, rowspan, colspan, kskl
     from
       leksemy l
-      left outer join dictionary_lexemeattributevalue_lexemes refl
-        on (l.id = refl.lexeme_id and refl.lexemeattributevalue_id in (%(refl)s))
+      left outer join dictionary_lexemeav refl
+        on (l.id = refl.lexeme_id and refl.attribute_value_id in (%(refl)s))
       join odmieniasie o on (l.id = o.l_id)
       join charfle ch on (o.charfl = ch.id)
       join wzory on (o.w_id = wzory.id)
@@ -40,8 +40,8 @@ def make_data(entries):
       join odsylacze ods on l.id = l_id_od
       join typyodsylaczy tods on ods.typods_id = tods.id
       join leksemy g on l_id_do = g.id
-      left outer join dictionary_lexemeattributevalue_lexemes refl
-        on (g.id = refl.lexeme_id and refl.lexemeattributevalue_id in (%(refl)s))
+      left outer join dictionary_lexemeav refl
+        on (g.id = refl.lexeme_id and refl.attribute_value_id in (%(refl)s))
       join odmieniasie o on l.id = o.l_id
       join charfle ch on (o.charfl = ch.id)
       join wzory on (o.w_id = wzory.id)
@@ -57,7 +57,7 @@ def make_data(entries):
         'haslo': 'haslo',
         'entry_placeholders': entry_placeholders,
         'leks_clause': '''l.pos not in ('skrl','skrw') and
-          (l.pos != 'v' or refl.lexemeattributevalue_id in (%s))'''
+          (l.pos != 'v' or refl.attribute_value_id in (%s))'''
           % nonrefl_ids,
         'refl': refl_ids,
       },
@@ -69,7 +69,7 @@ def make_data(entries):
         'haslo_tab': u"haslo||' się'",
         'haslo': 'haslo',
         'entry_placeholders': entry_placeholders,
-        'leks_clause': '''(l.pos='v' and refl.lexemeattributevalue_id <> %s)''',
+        'leks_clause': '''(l.pos='v' and refl.attribute_value_id <> %s)''',
         'refl': refl_ids,
       },
       entries + [empty_refl, 's']
@@ -80,7 +80,7 @@ def make_data(entries):
         'haslo_tab': "'nie '||haslo",
         'haslo': "'nie '||haslo",
         'entry_placeholders': entry_placeholders,
-        'leks_clause': '''l.pos='v' and refl.lexemeattributevalue_id in (%s)'''
+        'leks_clause': '''l.pos='v' and refl.attribute_value_id in (%s)'''
           % nonrefl_ids,
         'refl': refl_ids,
       },
@@ -92,7 +92,7 @@ def make_data(entries):
         'haslo_tab': u"'nie '||haslo||' się'",
         'haslo': "'nie '||haslo",
         'entry_placeholders': entry_placeholders,
-        'leks_clause': '''(l.pos='v' and refl.lexemeattributevalue_id <> %s)''',
+        'leks_clause': '''(l.pos='v' and refl.attribute_value_id <> %s)''',
         'refl': refl_ids,
       },
       entries + [empty_refl, 'ns']
@@ -104,7 +104,7 @@ def make_data(entries):
         'entry_placeholders': entry_placeholders,
         'main_clause': '''typods in ('comadj','comadv','ppasver') and
           l.pos in ('adjcom','advcom','ppas') and
-          (l.pos != 'ppas' or refl.lexemeattributevalue_id in (%s))'''
+          (l.pos != 'ppas' or refl.attribute_value_id in (%s))'''
           % nonrefl_ids,
         'refl': refl_ids,
       },
@@ -116,7 +116,7 @@ def make_data(entries):
         'haslo': u"g.haslo||' się'",
         'entry_placeholders': entry_placeholders,
         'main_clause': '''(typods ='ppasver' and l.pos ='ppas' and
-          refl.lexemeattributevalue_id <> %s)''',
+          refl.attribute_value_id <> %s)''',
         'refl': refl_ids,
       },
       entries + [empty_refl]
diff --git a/media/js/lexeme-view.js b/media/js/lexeme-view.js
index 5e12527..5b01d31 100644
--- a/media/js/lexeme-view.js
+++ b/media/js/lexeme-view.js
@@ -1,5 +1,21 @@
 var prompter_ctrl, created;
 
+function init_selection(jq) {
+  "use strict";
+  jq.find('option:selected').addClass('last-selected');
+}
+
+function revert_selection(jq) {
+  "use strict";
+  jq.find('option.last-selected').prop('selected', true);
+}
+
+function confirm_selection(jq) {
+  "use strict";
+  jq.find('option.last-selected').removeClass('last-selected');
+  jq.find('option:selected').addClass('last-selected');
+}
+
 function selected_qualifiers_text(num, total, checked) {
   "use strict";
   if (num >= 4)
@@ -227,6 +243,11 @@ function get_entry() {
   return $('#id_entry').val();
 }
 
+function get_owner() {
+  "use strict";
+  return $('#id_new_owner').val();
+}
+
 function join_attrs(attrs) {
   "use strict";
   return $.map(attrs, function(attr) {
@@ -234,6 +255,13 @@ function join_attrs(attrs) {
   }).join(', ');
 }
 
+function join_classifications(clas_ids) {
+  "use strict";
+  return $.map(clas_ids, function(c_id) {
+    return $("[for='id_cl" + c_id + "-values']").text().replace(':', '');
+  }).join(', ');
+}
+
 function init_form_widgets() {
   "use strict";
   $(document).on('click', '.lip-row span.remove', function() {
@@ -259,8 +287,7 @@ function init_form_widgets() {
   $(document).on('click', '#add-row', function() {
     var id = lexeme_id();
     var new_row = $(get_new_row_html(id));
-    new_row.find('.inflection-characteristic option:selected')
-      .addClass('last-selected');
+    init_selection(new_row.find('.inflection-characteristic'));
     var pattern_list = $('#pattern-list');
     pattern_list.append(new_row);
     var elem = pattern_list.find('.lip-qualifiers').last();
@@ -381,7 +408,21 @@ function init_form_widgets() {
     $('#move-lexeme').toggleClass('move-hidden');
   });
   $(document).on('change', '#id_part_of_speech', check_pos);
-  $(document).on('change', '#id_new_owner', reload_classifications);
+  $(document).on('change', '#id_new_owner', function() {
+    var stale_classifications = check_classifications(), confirmed;
+    if (stale_classifications.length > 0) {
+      confirmed = window.confirm(
+        'Zostaną usunięte klasyfikacje: ' +
+          join_classifications(stale_classifications) +  'Kontynuować?');
+      if (!confirmed) {
+        revert_selection($(this));
+      }
+    }
+    if (confirmed || stale_classifications.length === 0) {
+      confirm_selection($(this));
+      reload_classifications();
+    }
+  });
   $(document).on('change', '.inflection-characteristic', function() {
     var new_ics = get_ic_symbols();
     var stale_attrs = check_attrs(new_ics);
@@ -390,12 +431,11 @@ function init_form_widgets() {
       confirmed = window.confirm("Atrybuty: " + join_attrs(stale_attrs) +
         ' zostaną usunięte. Kontynouwać?');
       if (!confirmed) {
-        $(this).find('option.last-selected').prop('selected', true);
+        revert_selection($(this));
       }
     }
     if (confirmed || stale_attrs.length === 0) {
-      $(this).find('option.last-selected').removeClass('last-selected');
-      $(this).find('option:selected').addClass('last-selected');
+      confirm_selection($(this));
       reload_attributes();
     }
   });
@@ -413,7 +453,7 @@ function reload_classifications() {
   "use strict";
   var data = {
     lexeme_id: lexeme_id(),
-    vocab_id: $('#id_new_owner').val(),
+    vocab_id: get_owner(),
     pos: get_pos()
   };
   $.ajaxJSON({
@@ -527,8 +567,9 @@ function edit_form_init() {
   deleted = [];
   deleted_cr = [];
   created = false;
-  $('#id_part_of_speech').find('option:selected').addClass('last-selected');
-  $('.inflection-characteristic option:selected').addClass('last-selected');
+  init_selection($('#id_part_of_speech'));
+  init_selection($('.inflection-characteristic'));
+  init_selection(new_owner_elem);
   jqgrid.hide_changed();
   if (jqgrid.ctrl)
     jqgrid.ctrl.remove();
@@ -902,6 +943,26 @@ function input_prompter_pattern() {
   }
 }
 
+function check_classifications() {
+  "use strict";
+  var new_classifications = $.ajaxJSON({
+    method: 'get',
+    url: $dj.ajax_check_classifications,
+    data: {lexeme_id: lexeme_id(), pos: get_pos(), owner_id: get_owner()},
+    async: false
+  }).classifications;
+  var old_classifications = $('#classifications').find('.classification-values')
+    .map(function(i, el) {
+      return parseInt(el.id.replace('id_cl', '').replace('-values', ''), 10);
+    });
+  var stale_classifications = [];
+  old_classifications.each(function(i, c_id) {
+    if (new_classifications.indexOf(c_id) === -1)
+      stale_classifications.push(c_id);
+  });
+  return stale_classifications;
+}
+
 function check_attrs(ics) {
   "use strict";
   var new_attrs = $.ajaxJSON({
@@ -914,7 +975,7 @@ function check_attrs(ics) {
     return parseInt(el.id.split('-')[0].substring('id_attr'.length), 10);
   });
   var stale_attrs = [];
-  $.each(old_attrs, function(i, attr) {
+  old_attrs.each(function(i, attr) {
     if (new_attrs.indexOf(attr) === -1)
       stale_attrs.push(attr);
   });
@@ -943,7 +1004,9 @@ var check_pos = function() {
       good_ics.push(ic_symbol);
   });
   var stale_attrs = check_attrs(good_ics);
-  if (bad_lips.length > 0 || cr_row_elems.length > 0 || stale_attrs.length > 0) {
+  var stale_classifications = check_classifications();
+  if (bad_lips.length > 0 || cr_row_elems.length > 0 ||
+      stale_attrs.length > 0 || stale_classifications.length > 0) {
     var lips_text = '', cr_text = '', lips = [];
     if (bad_lips.length > 0) {
       $.each(bad_lips, function(i, t) {
@@ -956,21 +1019,25 @@ var check_pos = function() {
     if (cr_row_elems.length > 0) {
       cr_text += "wszystkie odsyłacze\n";
     }
-    // TODO ostrzegać przed znikaniem klasyfikacji [kiedyś] (?)
     var attr_text = '';
     if (stale_attrs.length > 0) {
       attr_text = "atrybuty: " + join_attrs(stale_attrs) + '\n';
     }
+    var clas_text = '';
+    if (stale_classifications.length > 0) {
+      clas_text = "klasyfikacje: " +
+        join_classifications(stale_classifications) + '\n';
+    }
     confirmed = window.confirm(
-      'Zostaną usunięte:\n' + lips_text + cr_text + attr_text + 'Kontynuować?');
+      'Zostaną usunięte:\n' + lips_text + cr_text + attr_text + clas_text +
+        'Kontynuować?');
     if (!confirmed) {
-      $(this).find('option.last-selected').prop('selected', true);
+      revert_selection($(this));
     }
   }
   if (confirmed || !(bad_lips.length > 0 || cr_row_elems.length > 0 ||
-        stale_attrs.length > 0)) {
-    $(this).find('option.last-selected').removeClass('last-selected');
-    $(this).find('option:selected').addClass('last-selected');
+        stale_attrs.length > 0 || stale_classifications.length > 0)) {
+    confirm_selection($(this));
     var result = $.ajax({ // znowu brzydko...
       type: 'get',
       url: $dj.ajax_get_ics,
diff --git a/sql/drop.sql b/sql/drop.sql
index 3b37d5c..4015061 100644
--- a/sql/drop.sql
+++ b/sql/drop.sql
@@ -1,3 +1,4 @@
+-- bardzo nieaktualne!
  drop table "auth_group_permissions" cascade;
  drop table "auth_group" cascade;
  drop table "auth_user_user_permissions" cascade;
@@ -11,7 +12,7 @@
  drop table "klasygramatyczne" cascade;
  drop table "kwalifikatory_leksemow" cascade;
  drop table "kwalifikatory_odmieniasiow" cascade;
- drop table "wartosci_klasyfikacji_lexemes" cascade;
+ drop table "dictionary_lexemecv" cascade;
  drop table "odmieniasie" cascade;
  drop table "zakonczenia" cascade;
  drop table "kwalifikatory_zakonczen" cascade;
diff --git a/sql/history.sql b/sql/history.sql
index 2d2d5d8..9095124 100644
--- a/sql/history.sql
+++ b/sql/history.sql
@@ -40,7 +40,7 @@ BEGIN
         lexemeId := temp.id;
     ELSIF (TG_TABLE_NAME IN ('odmieniasie', 'leksemy_w_slownikach')) THEN
         lexemeId := temp.l_id;
-    ELSIF (TG_TABLE_NAME IN ('kwalifikatory_leksemow', 'wartosci_klasyfikacji_lexemes', 'dictionary_lexemeattributevalue_lexemes')) THEN
+    ELSIF (TG_TABLE_NAME IN ('kwalifikatory_leksemow', 'dictionary_lexemeav', 'dictionary_lexemecv')) THEN
         lexemeId := temp.lexeme_id;
     ELSIF (TG_TABLE_NAME = 'odsylacze') THEN
         lexemeId := temp.l_id_od;
@@ -116,16 +116,16 @@ CREATE TRIGGER leksemy_w_slownikach_trigger_history_
 AFTER INSERT OR UPDATE OR DELETE ON leksemy_w_slownikach
 FOR EACH ROW EXECUTE PROCEDURE make_history_();
 
-CREATE TRIGGER wartosci_klasyfikacji_lexemes_trigger_history_
-AFTER INSERT OR UPDATE OR DELETE ON wartosci_klasyfikacji_lexemes -- ta tabela zmieni nazwę
+CREATE TRIGGER dictionary_lexemecv_trigger_history_
+AFTER INSERT OR UPDATE OR DELETE ON dictionary_lexemecv
 FOR EACH ROW EXECUTE PROCEDURE make_history_();
 
 CREATE TRIGGER odsylacze_trigger_history_
 AFTER INSERT OR UPDATE OR DELETE ON odsylacze
 FOR EACH ROW EXECUTE PROCEDURE make_history_();
 
-CREATE TRIGGER lexemeattributevalue_lexemes_trigger_history_
-AFTER INSERT OR UPDATE OR DELETE ON dictionary_lexemeattributevalue_lexemes
+CREATE TRIGGER dictionary_lexemeav_trigger_history_
+AFTER INSERT OR UPDATE OR DELETE ON dictionary_lexemeav
 FOR EACH ROW EXECUTE PROCEDURE make_history_();
 
 -- wzory
diff --git a/urls.py b/urls.py
index efa7ab1..d6b5ded 100644
--- a/urls.py
+++ b/urls.py
@@ -5,8 +5,8 @@ from django.conf import settings
 from common.util import url
 
 # Uncomment the next two lines to enable the admin:
-from django.contrib import admin
-admin.autodiscover()
+#from django.contrib import admin
+#admin.autodiscover()
 
 urlpatterns = patterns('',
   # Example:
@@ -39,6 +39,7 @@ urlpatterns += patterns('dictionary.ajax_lexeme_view',
   url(r'^ajax/delete_lexeme/$', 'delete_lexeme'),
   url(r'^ajax/check-pos/$', 'check_pos'),
   url(r'^ajax/check-pattern/$', 'check_pattern'),
+  url(r'^ajax/check-classifications/$', 'check_classifications'),
   url(r'^ajax/get-ics/$', 'get_ics'),
   url(r'^ajax/create-lexeme/$', 'create_lexeme'),
   url(r'^ajax/classification-forms/$', 'classification_forms'),
--
libgit2 0.22.2