From 2bd617b543e1502e81d36ca9b5fe52d91f11bd6e Mon Sep 17 00:00:00 2001
From: Philip Sargent <philip.sargent@klebos.com>
Date: Tue, 5 Jul 2022 20:24:51 +0300
Subject: [PATCH] Fixed QM report for survex-imported QMs

---
 core/models/caves.py          | 20 +++++++++-----------
 core/views/caves.py           | 13 +++++++++----
 parsers/survex.py             | 35 +++++++++++++++++++++++++++++++++--
 templates/cave_qms.html       |  9 +++++++--
 templates/errors/badslug.html |  2 +-
 templates/qm.html             |  7 ++++++-
 6 files changed, 65 insertions(+), 21 deletions(-)

diff --git a/core/models/caves.py b/core/models/caves.py
index 5ba4804..d623963 100644
--- a/core/models/caves.py
+++ b/core/models/caves.py
@@ -178,12 +178,6 @@ class Cave(TroggleModel):
         return str(self.slug())
 
     def get_QMs(self):
-        '''Does not work because found_by is a string == cave_slug not an object identifier
-        This chnage was made to remove tricky __get_attribute__ code whihc is hard for
-        most folks to maintain and is not really necessary. Need to do a proper search for the cave.
-        Seems pretty broken - all needs re-doing more cleanly.
-        '''
-        #return QM.objects.filter(found_by__cave_slug=self.slug) 
         return QM.objects.filter(cave=self)
         
 
@@ -484,7 +478,6 @@ class LogbookEntry(TroggleModel):
 class QM(TroggleModel):
     """This is based on qm.csv in trunk/expoweb/1623/204 which has the fields:
     "Number","Grade","Area","Description","Page reference","Nearest station","Completion description","Comment"
-    Note that there is NO LINK TO THE CAVE that the QM is in !
     """
     cave = models.ForeignKey(Cave, related_name='QMs',blank=True, null=True,on_delete=models.SET_NULL )
     found_by = models.ForeignKey(LogbookEntry, related_name='QMs_found',blank=True, null=True,on_delete=models.SET_NULL )
@@ -511,20 +504,25 @@ class QM(TroggleModel):
 
     def code(self):
         if self.found_by:
-            return "%s-%s-%s" % (str(self.found_by.cave_slug)[6:], self.found_by.date.year, self.number)
+            return f'{str(self.found_by.cave_slug)[5:]}-{self.found_by.date.year}-{self.number}' 
         else:
-            return "%s" % (self.number)
+            return f'{self.cave.slug()[5:]}-xxxx-{self.number}'
 
     def get_absolute_url(self):
+        if self.found_by:
+            qmyear = self.found_by.date.year
+        else:
+            qmyear = "1986" # HACK to check if other bits work
         #return settings.URL_ROOT + '/cave/' + self.found_by.cave.kataster_number + '/' + str(self.found_by.date.year) + '-' + '%02d' %self.number
-        return urljoin(settings.URL_ROOT, reverse('qm',kwargs={'cave_id':self.cave.slug(),'year':self.found_by.date.year,'qm_id':self.number,'grade':self.grade}))
+        return urljoin(settings.URL_ROOT, reverse('qm',kwargs={'cave_id':self.cave.slug(),'year':qmyear,'qm_id':self.number,'grade':self.grade}))
+            
 
     def get_next_by_id(self):
         return QM.objects.get(id=self.id+1)
 
     def get_previous_by_id(self):
         return QM.objects.get(id=self.id-1)
-
+        
     # def wiki_link(self):
         # return "%s%s%s" % ('[[QM:',self.code(),']]')
 
diff --git a/core/views/caves.py b/core/views/caves.py
index 0349836..3fbc934 100644
--- a/core/views/caves.py
+++ b/core/views/caves.py
@@ -467,7 +467,7 @@ def get_entrances(request, caveslug):
     return render(request,'options.html', {"items": [(e.entrance.slug(), e.entrance.slug()) for e in cave.entrances()]})
 
 def caveQMs(request, slug):
-    '''Lists the QMs on a particular cave
+    '''Lists all the QMs on a particular cave
     relies on the template to find all the QMs for the cave specified in the slug, e.g. '1623-161'
     Now working in July 2022
     '''
@@ -482,7 +482,9 @@ def caveQMs(request, slug):
         return render(request,'cave_qms.html', {'cave': cave})
 
 def qm(request,cave_id,qm_id,year,grade=None):
-    '''Not checked, tested or revised in 2022
+    '''Reports on one specific QM
+    Fixed and working July 2022, for both CSV imported QMs and for survex-imported QMs,
+    need refactoring though.
     '''
     year=int(year)
     try:
@@ -493,6 +495,8 @@ def qm(request,cave_id,qm_id,year,grade=None):
         return render(request, 'svxcaveseveral.html', {'settings': settings, "caves":caves })
 
     except QM.DoesNotExist:
+        return render(request,'errors/badslug.html', {'badslug': f'{cave_id=} {year=} {qm_id=}'})
+   
         # Ouch, this does not look like what we want to do. We need to replace this with something better.
         url=urllib.parse.urljoin(settings.URL_ROOT, r'/admin/core/qm/add/'+'?'+  r'number=' + qm_id)
         if grade:
@@ -500,10 +504,11 @@ def qm(request,cave_id,qm_id,year,grade=None):
         return HttpResponseRedirect(url)
 
 def get_qms(request, caveslug):
-    '''Not checked, tested or revised in 2022
+    '''Does not crash, but just returns a text list of the entrances for a cave. 
+    Used internally by the JSON export code? Archeology required..
     '''
     try:
         cave = Cave.objects.get(caveslug__slug = caveslug)
     except:
         return render(request,'errors/badslug.html', {'badslug': caveslug})
-    return render(request,'options.html', {"items": [(e.entrance.slug(), e.entrance.slug()) for e in cave.entrances()]})
+    return render(request,'options.html', {"items": [(q.slug(), q.slug()) for q in cave.QMs()]})
diff --git a/parsers/survex.py b/parsers/survex.py
index 7f7c902..76acda6 100644
--- a/parsers/survex.py
+++ b/parsers/survex.py
@@ -12,7 +12,7 @@ from django.utils.timezone import get_current_timezone
 from django.utils.timezone import make_aware
 
 import troggle.settings as settings
-from troggle.core.models.caves import Entrance, QM
+from troggle.core.models.caves import Entrance, QM, LogbookEntry
 from troggle.core.utils import get_process_memory, chaosmonkey
 from troggle.parsers.people import GetPersonExpeditionNameLookup
 from troggle.parsers.logbooks import GetCaveLookup
@@ -529,13 +529,44 @@ class LoadingSurvex():
 
         # NB none of the SurveyStations are in the DB now, so if we want to link to aSurvexStation
         # we would have to create one. But that is not obligatory and no QMs loaded from CSVs have one
+        
+        # Older troggle/CSV assumes a logbook entry 'found_by' for each QM, with a date. 
+        # We have a date from the survexfile. This is needed for the absolute_url resolution..
+        
+        # We don't know if the survexfile has an associated logbook entry as there is no direct link
+        # so we create a dummy one anyway. We should make logbook entry links optional in QMs in future and
+        # remove this hack.
+        qmyear = str(survexblock.date)[:4]
+        logslug = f'DUM_{int(qmyear)}_{int(qm_no):03d}'
+        if survexblock.survexfile.cave:
+            caveslug = survexblock.survexfile.cave.slug()
+            place = survexblock.survexfile.cave
+        else:
+            caveslug = "ugh"
+            place = "oops"
+       
+        
+        message = f' ! - logbook dummy "{logslug}" {str(survexblock.date)[:11]} for cave "{caveslug}" created.'
+
+        placeholder, hadToCreate = LogbookEntry.objects.get_or_create(date__year=qmyear, 
+                        place=place, 
+                        title="placeholder for survex QM", 
+                        text=message, 
+                        entry_type="DUMMY", 
+                        expedition_id=1, 
+                        defaults={"date": survexblock.date,"cave_slug":caveslug, "slug": logslug})
+        print(insp+message)
+        DataIssue.objects.create(parser='survex', message=message)
+  
         try:
             qm = QM.objects.create(number=qm_no,
                                             # nearest_station=a_survex_station_object, # can be null
                                               nearest_station_description=qm_resolve_station,
                                               nearest_station_name=qm_nearest,
                                               grade=qm_grade.upper(),
-                                              location_description=qm_notes)
+                                              location_description=qm_notes,
+                                              found_by = placeholder,
+                                              cave = survexblock.survexfile.cave)
             qm.save
             # message = " ! QM{} '{}' CREATED in DB in '{}'".format(qm_no, qm_nearest,survexblock.survexfile.path)
             # print(insp+message)
diff --git a/templates/cave_qms.html b/templates/cave_qms.html
index e91f49c..25d5ccf 100644
--- a/templates/cave_qms.html
+++ b/templates/cave_qms.html
@@ -4,13 +4,18 @@
 {% block contentheader %}
     <h2>Question marks for {{cave.kataster_number}} - {{cave.official_name|safe}} - {{cave.unofficial_number}}</h2>
     
-    <p>Note that QMs are only loaded for 1623-161, 1623-204 and 1623-234 as these are the only CSV files loaded by the import parser. 
-    No QMs are loaded directly from the survex files (yet, as of July 2022).
+    <p>Note that QMs loaded for 1623-161, 1623-204 and 1623-234 are imported from CSV files . 
+    
     <ul>
     <li><a href="/cave/qms/1623-161">1623-161 QMs</a>
     <li><a href="/cave/qms/1623-204">1623-204 QMs</a>
     <li><a href="/cave/qms/1623-234">1623-234 QMs</a>
     </ul>
+    <p>QMs are also loaded directly from the survex files (possibly buggy, July 2022), e.g. see
+    <ul>
+    <li><a href="/cave/qms/1623-264">1623-264 QMs</a>
+    </ul>
+    
     <p>For full explanation of the current status of the QM system(s), see <a href="/handbook/troggle/scriptsqms.html">scriptsqms page</a>.
 {% endblock %}
 {% block content %}
diff --git a/templates/errors/badslug.html b/templates/errors/badslug.html
index bd507fa..5f90f50 100644
--- a/templates/errors/badslug.html
+++ b/templates/errors/badslug.html
@@ -13,7 +13,7 @@
 	<div class='align-center'>
 		<h3>There has been a Troggle error. </h3>
         <h4>
-        A Cave or an Entrance has been referred to using a label (a 'slug') which does not work. 
+        A Cave, Entrance or QM has been referred to using a label (a 'slug') which does not work. 
         <p>This is the bad slug:
 
         <font color="red">
diff --git a/templates/qm.html b/templates/qm.html
index bf84717..b991b8f 100644
--- a/templates/qm.html
+++ b/templates/qm.html
@@ -2,12 +2,17 @@
 {% load link %}
 {% block title %} QM: {{qm|safe}} {% endblock %}
 {% block contentheader %}
-<h3>QMs only available for these caves</h3>
+<h3>QMs  available for these caves from CSV import</h3>
     <ul>
     <li><a href="/cave/qms/1623-161">1623-161 QMs</a>
     <li><a href="/cave/qms/1623-204">1623-204 QMs</a>
     <li><a href="/cave/qms/1623-234">1623-234 QMs</a>
     </ul>
+    <p>QMs are also loaded directly from the survex files (possibly buggy, July 2022), e.g. see
+    <ul>
+    <li><a href="/cave/qms/1623-264">1623-264 QMs</a>
+    </ul>
+
     <p>For full explanation of the current status of the QM system(s), see <a href="/handbook/troggle/scriptsqms.html">scriptsqms page</a>.
 
 <table id="cavepage">