From ddfdd0ce75aa04ec90d25785d671a5009d54d4b3 Mon Sep 17 00:00:00 2001
From: Joseph Lewis <joehms22@gmail.com>
Date: Mon, 13 Jun 2011 16:54:06 -0600
Subject: [PATCH] Added revision logging to oust, updated fm_IDL.xml to reflect
 that and changed org_unit_settings.js and org_unit_settings.xhtml to add some
 functionality of revisions.

Signed-off-by: Joseph Lewis <joehms22@gmail.com>
Signed-off-by: Thomas Berezansky <tsbere@mvlc.org>
Signed-off-by: Jason Etheridge <jason@esilibrary.com>
---
 Open-ILS/examples/fm_IDL.xml                       | 23 ++++++++++
 Open-ILS/src/sql/Pg/002.schema.config.sql          | 49 ++++++++++++++++++++++
 .../staff_client/server/admin/org_unit_settings.js | 15 +++++--
 .../server/admin/org_unit_settings.xhtml           | 26 ++++++++----
 4 files changed, 100 insertions(+), 13 deletions(-)

diff --git a/Open-ILS/examples/fm_IDL.xml b/Open-ILS/examples/fm_IDL.xml
index cbf09bdd22..2c1c1862a4 100644
--- a/Open-ILS/examples/fm_IDL.xml
+++ b/Open-ILS/examples/fm_IDL.xml
@@ -9158,6 +9158,29 @@ SELECT  usr,
 		</permacrud>
 	</class>
 
+	<class id="coustl" controller="open-ils.cstore open-ils.pcrud" oils_obj:fieldmapper="config::org_unit_setting_type_log" oils_persist:tablename="config.org_unit_setting_type_log" reporter:label="Organizational Unit Setting Type Log">
+		<fields oils_persist:primary="date_applied">
+			<field name="date_applied" reporter:datatype="timestamp"/>
+			<field name="org" reporter:datatype="link"/>
+			<field name="original_value" reporter:datatype="text"/>
+			<field name="new_value" reporter:datatype="text"/>
+			<field name="field_name" reporter:datatype="link"/>
+		</fields>
+		<links>
+			<link field="field_name" reltype="has_a" key="name" map="" class="coust"/>
+			<link field="org" reltype="has_a" key="id" map="" class="aou"/>
+		</links>
+		<permacrud xmlns="http://open-ils.org/spec/opensrf/IDL/permacrud/v1">
+			<actions>
+				<create permission="ADMIN_ORG_UNIT_SETTING_TYPE" global_required="true"/>
+				<retrieve/>
+				<update permission="ADMIN_ORG_UNIT_SETTING_TYPE_LOG" global_required="true"/>
+				<delete permission="ADMIN_ORG_UNIT_SETTING_TYPE_LOG" global_required="true"/>
+			</actions>
+		</permacrud>
+	</class>
+
+
 	<!-- ********************************************************************************************************************* -->
 
 </IDL>
diff --git a/Open-ILS/src/sql/Pg/002.schema.config.sql b/Open-ILS/src/sql/Pg/002.schema.config.sql
index c29ae278e8..476cc2ffff 100644
--- a/Open-ILS/src/sql/Pg/002.schema.config.sql
+++ b/Open-ILS/src/sql/Pg/002.schema.config.sql
@@ -913,4 +913,53 @@ CREATE TABLE config.barcode_completion (
 
 CREATE TYPE evergreen.barcode_set AS (type TEXT, id BIGINT, barcode TEXT);
 
+-- Add support for logging, only keep the most recent five rows for each category. 
+
+
+CREATE TABLE config.org_unit_setting_type_log (
+    date_applied    TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW() PRIMARY KEY,
+    org             SERIAL    REFERENCES actor.org_unit (id),
+    original_value  TEXT,
+    new_value       TEXT,
+    field_name      TEXT      REFERENCES config.org_unit_setting_type (name)
+);
+
+CREATE OR REPLACE FUNCTION limit_oustl() RETURNS TRIGGER AS $oustl_limit$
+    BEGIN
+        -- Only keeps the most recent five settings changes.
+        DELETE FROM config.org_unit_setting_type_log WHERE field_name = NEW.field_name AND date_applied NOT IN 
+        (SELECT date_applied FROM config.org_unit_setting_type_log WHERE field_name = NEW.field_name ORDER BY date_applied DESC LIMIT 4);
+        
+        IF (TG_OP = 'UPDATE') THEN
+            RETURN NEW;
+        ELSIF (TG_OP = 'INSERT') THEN
+            RETURN NEW;
+        END IF;
+        RETURN NULL;
+    END;
+$oustl_limit$ LANGUAGE plpgsql;
+
+CREATE TRIGGER limit_logs_oust
+    BEFORE INSERT OR UPDATE ON config.org_unit_setting_type_log
+    FOR EACH ROW EXECUTE PROCEDURE limit_oustl();
+    
+
+-- Log each change in oust to oustl, so admins can see what they messed up if someting stops working.
+CREATE OR REPLACE FUNCTION ous_change_log() RETURNS TRIGGER AS $ous_change_log$
+    DECLARE
+    original TEXT;
+    BEGIN
+        -- Check for which setting is being updated, and log it.
+        SELECT INTO original value FROM actor.org_unit_setting WHERE name = NEW.name AND org_unit = NEW.org_unit;
+                
+        INSERT INTO config.org_unit_setting_type_log (org,original_value,new_value,field_name) VALUES (NEW.org_unit, original, NEW.value, NEW.name);
+        
+        RETURN NEW;
+    END;
+$ous_change_log$ LANGUAGE plpgsql;    
+
+CREATE TRIGGER log_ous_change
+    BEFORE INSERT OR UPDATE ON actor.org_unit_setting
+    FOR EACH ROW EXECUTE PROCEDURE ous_change_log();
+
 COMMIT;
diff --git a/Open-ILS/xul/staff_client/server/admin/org_unit_settings.js b/Open-ILS/xul/staff_client/server/admin/org_unit_settings.js
index daea5193d9..e7435340b5 100644
--- a/Open-ILS/xul/staff_client/server/admin/org_unit_settings.js
+++ b/Open-ILS/xul/staff_client/server/admin/org_unit_settings.js
@@ -27,6 +27,8 @@ var osEditAutoWidget;
 var perm_codes = {};
 var osGroups = {};
 var searchAssist = [];
+var pcrud;
+var osHistory = {};
 
 function osInit(data) {
     authtoken = new openils.CGI().param('ses') || dojo.cookie('ses');
@@ -34,10 +36,13 @@ function osInit(data) {
     contextOrg = user.user.ws_ou();
     openils.User.authtoken = authtoken;
     
-    var grps = new openils.PermaCrud({authtoken:authtoken}).retrieveAll('csg');
+    pcrud = new openils.PermaCrud({authtoken:authtoken});
+    
+    var grps = pcrud.retrieveAll('csg');
     dojo.forEach(grps, function(grp) { osGroups[grp.name()] = grp.label(); });
-
     
+    //osHistory = pcrud.retrieveAll('coustl');
+        
     var connect = function() { 
         dojo.connect(contextOrg, 'onChange', osChangeContext); 
 
@@ -442,10 +447,12 @@ function osEditSetting(deleteMe) {
             }
         }
     }
-    osUpdateSetting(obj, osEditContextSelector.getValue());
+    osUpdateSetting(obj, osEditContextSelector.getValue(), name);
 }
 
-function osUpdateSetting(obj, context) {
+function osUpdateSetting(obj, context, name) {
+    
+    
     fieldmapper.standardRequest(
         ['open-ils.actor', 'open-ils.actor.org_unit.settings.update'],
         {   async: true,
diff --git a/Open-ILS/xul/staff_client/server/admin/org_unit_settings.xhtml b/Open-ILS/xul/staff_client/server/admin/org_unit_settings.xhtml
index 4265fa7464..96a463af6b 100644
--- a/Open-ILS/xul/staff_client/server/admin/org_unit_settings.xhtml
+++ b/Open-ILS/xul/staff_client/server/admin/org_unit_settings.xhtml
@@ -23,7 +23,7 @@
     <head>
         <title>&staff.server.admin.org_unit_settings.title;</title>
         <link type='text/css' rel='stylesheet' href='admin.css' />
-        <script type="text/javascript" src='/IDL2js?aou,aout,pgt,au,coust,aous,csg' />
+        <script type="text/javascript" src='/IDL2js?aou,aout,pgt,au,coust,aous,csg,coustl' />
         <script type="text/javascript" djConfig="parseOnLoad: true,isDebug:false" src="/js/dojo/dojo/dojo.js" />
         <script type="text/javascript" djConfig="parseOnLoad: true,isDebug:false" src="/js/dojo/dojo/openils_dojo.js" />
         <script type="text/javascript" src='org_unit_settings.js' />
@@ -35,6 +35,7 @@
             }
         </style>
     </head>
+
     <body class="tundra tall">
         <div dojoType="dijit.layout.LayoutContainer" orientation="vertical" class="tall">
             <div dojoType="dijit.layout.ContentPane" layoutAlign='top'>
@@ -51,9 +52,8 @@
                         <button type="submit" dojoType='dijit.form.Button'>&staff.server.admin.org_unit_settings.filter;</button>
                         <button dojoType='dijit.form.Button' onClick="clearSearch();">&staff.server.admin.org_unit_settings.clear_filter;</button>
                     </form>
-                        <button dojoType='dijit.form.Button' onClick="osToJson();">&staff.server.admin.org_unit_settings.export;</button>
-                        <button dojoType='dijit.form.Button' onClick="osFromJson();">&staff.server.admin.org_unit_settings.import;</button>
-
+                    <button dojoType='dijit.form.Button' onClick="osToJson();">&staff.server.admin.org_unit_settings.export;</button>
+                    <button dojoType='dijit.form.Button' onClick="osFromJson();">&staff.server.admin.org_unit_settings.import;</button>
             </div>
             <div dojoType="dijit.layout.ContentPane" layoutAlign='client'>
                 <div class='hide_me' id='no-perms'><b>&staff.server.admin.org_unit_settings.no_perms;</b></div>
@@ -75,7 +75,7 @@
                         ]]
                     }];
                 </script>
-                <div dojoType='dojox.Grid' jsId='osGrid'> </div>
+                <div dojoType='dojox.Grid' jsId='osGrid' />
             </div>
         </div>
 
@@ -118,12 +118,17 @@
                     </tr>
                 </tbody>
             </table>
-        </div> <!-- edit dialog -->
+        </div> <!-- /edit dialog -->
+        
+        <div dojoType="openils.widget.ProgressDialog" jsId="progressDialog" indeterminate="true" />
+        
+        <!--i18n, use the &translation; here, then grab innerHTML in JS later.-->
+        <div id='proci18n' class='hidden'>&staff.server.admin.org_unit_settings.processing;</div>
+        <div id='noresults' class='hidden'>&staff.server.admin.org_unit_settings.no_results;</div>
         <span id='os-true' class='hidden'>&common.true;</span>
         <span id='os-false' class='hidden'>&common.false;</span>
-        <div dojoType="openils.widget.ProgressDialog" jsId="progressDialog" indeterminate="true"></div>
-        <div id='proci18n' class="hidden">&staff.server.admin.org_unit_settings.processing;</div>
-        <div id="noresults" class="hidden">&staff.server.admin.org_unit_settings.no_results;</div>
+        
+        <!--Export Dialog-->
         <div id="jsonOutputDialog" dojoType="dijit.Dialog" jsId='osJSONOutDialog' title="&staff.server.admin.org_unit_settings.export;">
             <table class="form_table">
                 <tr><td>&staff.server.admin.org_unit_settings.export_copy_label;</td></tr>
@@ -131,6 +136,8 @@
                 <tr><td><button dojoType='dijit.form.Button' onclick='osJsonOutputCopy();'>&staff.server.admin.org_unit_settings.copy;</button></td></tr>
             </table>
         </div>
+        
+        <!--Import Dialog-->
         <div id="jsonInputDialog" dojoType="dijit.Dialog" jsId='osJSONInDialog' title="&staff.server.admin.org_unit_settings.import;">
             <table class="form_table">
                 <tr><td>&staff.server.admin.org_unit_settings.import_paste_label;</td></tr>
@@ -138,5 +145,6 @@
                 <tr><td><button dojoType='dijit.form.Button' onclick='osJsonInputPaste();'>&staff.server.admin.org_unit_settings.paste;</button><button type="submit"  dojoType='dijit.form.Button' onclick='osFromJsonSubmit();'>&staff.server.admin.org_unit_settings.submit;</button></td></tr>
             </table>
         </div>
+        
     </body>
 </html>
\ No newline at end of file
-- 
2.11.0