</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>
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;
var perm_codes = {};
var osGroups = {};
var searchAssist = [];
+var pcrud;
+var osHistory = {};
function osInit(data) {
authtoken = new openils.CGI().param('ses') || dojo.cookie('ses');
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);
}
}
}
- 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,
<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' />
}
</style>
</head>
+
<body class="tundra tall">
<div dojoType="dijit.layout.LayoutContainer" orientation="vertical" class="tall">
<div dojoType="dijit.layout.ContentPane" layoutAlign='top'>
<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>
]]
}];
</script>
- <div dojoType='dojox.Grid' jsId='osGrid'> </div>
+ <div dojoType='dojox.Grid' jsId='osGrid' />
</div>
</div>
</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>
<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>
<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