$options ||= {};
my $flesh = {flesh => 2, flesh_fields => {acqf => []}};
+ if ($options->{"flesh_tags"}) {
+ push @{$flesh->{"flesh_fields"}->{"acqf"}}, "tags";
+ $flesh->{"flesh_fields"}->{"acqftm"} = ["tag"];
+ }
push(@{$flesh->{flesh_fields}->{acqf}}, 'debits') if $$options{flesh_debits};
push(@{$flesh->{flesh_fields}->{acqf}}, 'allocations') if $$options{flesh_allocations};
push(@{$flesh->{flesh_fields}->{acqfa}}, 'funding_source') if $$options{flesh_allocation_sources};
}
#oils-acq-metapo-summary td { text-align: right; }
+#oils-acq-tag-manager-display { padding: 8px 2px; }
+#oils-acq-tag-manager-add { padding: 8px 2px; border-top: 1px dotted #ccc; }
+.oils-acq-fund-tag {
+ border: 1px #666 dashed;
+ margin: 2px 8px;
+ padding: 4px;
+}
+.oils-acq-fund-tag A { margin-left: 10px; }
+
/* li search page */
h1.oils-acq-li-search { font-size: 150%;font-weight: bold;margin-bottom: 12px; }
h2.oils-acq-li-search { font-size: 138%;font-weight: bold;margin-bottom: 11px; }
'VENDOR_SAYS_PREPAY_NOT_NEEDED': "The selected vendor does not necessarily require prepayment, according\nto records. Require prepayment on this PO anyway?",
'VENDOR_SAYS_PREPAY_NEEDED': "The selected vendor requires prepayment, according to records.\nProceed anyway without required prepayment on this PO?",
'PREPAYMENT_REQUIRED_REMINDER': "This PO requires prepayment. Are you certain you're ready to activate it?",
- 'LI_FORMAT_ERROR': "Unexpected error retrieving formatted lineitem information."
+ 'LI_FORMAT_ERROR': "Unexpected error retrieving formatted lineitem information.",
+ 'FUND_NOT_YET_LOADED': "Fund not yet loaded. Try coming back to this display later.",
+ 'CONFIRM_DELETE_MAPPING': "Are you sure you want to remove this tag from this fund?",
+ 'COULD_NOT_CREATE_MAPPING': "Error tagging fund.",
+ 'COULD_NOT_DELETE_MAPPING': "Error removing tag from fund."
}
--- /dev/null
+dojo.require("openils.PermaCrud");
+dojo.require("dojo.data.ItemFileReadStore");
+
+if (typeof(localeStrings) == "undefined") {
+ dojo.requireLocalization("openils.acq", "acq");
+ var localeStrings = dojo.i18n.getLocalization("openils.acq", "acq");
+}
+
+function TagManager(displayNode) {
+ var self = this;
+ this.tagCache = {};
+ this.displayNode = displayNode;
+
+ this.pcrud = new openils.PermaCrud();
+
+// selected (by checkbox) id's from an autogrid of objects:
+// return grid.getSelectedItems().map(function(o) { return o.id[0]; });
+
+ this.displayFund = function(fund) {
+ if (!fund) {
+ this.displayNode.innerHTML = localeStrings.FUND_NOT_YET_LOADED;
+ return;
+ }
+
+ dojo.empty(this.displayNode);
+ fund.tags().forEach(
+ function(o) {
+ dojo.place(self.renderTagMapping(o), self.displayNode, "last");
+ }
+ );
+ };
+
+ this.renderTagMapping = function(mapping) {
+ var span = dojo.create(
+ "span", {
+ "id": "oils-acq-fund-tag-mapping-" + mapping.id(),
+ "className": "oils-acq-fund-tag",
+ "innerHTML": mapping.tag().name()
+ }
+ );
+ dojo.create(
+ "a", {
+ "href": "javascript:void(0);",
+ "innerHTML": "X",
+ "onclick": function() { self.deleteMapping(mapping); },
+ },
+ span, "last"
+ );
+ return span;
+ };
+
+ this.deleteMapping = function(mapping) {
+ if (confirm(localeStrings.CONFIRM_DELETE_MAPPING)) {
+ this.pcrud.eliminate(
+ mapping, {
+ "oncomplete": function(r) {
+ dojo.destroy(
+ "oils-acq-fund-tag-mapping-" + mapping.id()
+ );
+ },
+ "onerror": function() {
+ /* XXX does onerror not actually work? */
+ alert(localeStrings.COULD_NOT_DELETE_MAPPING);
+ }
+ }
+ );
+ }
+ };
+
+ this.addMapping = function(fund, tag) {
+ var mapping = new acqftm();
+ mapping.fund(fund.id());
+ mapping.tag(tag.id());
+
+ this.pcrud.create(
+ mapping, {
+ "onerror": function(r) {
+ /* XXX does onerror not actually work? */
+ alert(localeStrings.COULD_NOT_CREATE_MAPPING);
+ },
+ "oncomplete": function(r, list) {
+ mapping = list[0]; /* get the new mapping's ID this way */
+ mapping.tag(tag); /* re-"flesh" */
+ dojo.place(
+ self.renderTagMapping(mapping),
+ self.displayNode, "last"
+ );
+ }
+ }
+ );
+ };
+
+ this.prepareTagSelector = function(selector) {
+ this.pcrud.search(
+ "acqft", {
+ "owner": fieldmapper.aou.orgNodeTrail(
+ fieldmapper.aou.findOrgUnit(openils.User.user.ws_ou()),
+ true /* asId */
+ )
+ }, {
+ "async": true,
+ "oncomplete": function(r) {
+ if ((r = openils.Util.readResponse(r))) {
+ selector.store = new dojo.data.ItemFileReadStore(
+ {"data": acqft.toStoreData(r)}
+ );
+ selector.startup();
+ }
+ }
+ }
+ );
+ };
+}
loadYearSelector();
loadFundGrid();
+
+ tagManager = new TagManager(lfGrid);
}
function loadFundGrid(year) {
}
openils.Util.addOnLoad(initPage);
-
dojo.require('openils.Util');
var fund = null;
+var tagManager;
function getSummaryInfo(rowIndex, item) {
if(!item) return'';
{ async: true,
params: [
openils.User.authtoken, fundID,
- {flesh_summary:1, flesh_allocations:1, flesh_debits:1}
+ {flesh_summary:1, flesh_allocations:1, flesh_debits:1, flesh_tags:1}
/* TODO grab allocations and debits only on as-needed basis */
],
oncomplete: function(r) {
);
}
-openils.Util.addOnLoad(fetchFund);
+function load() {
+ tagManager = new TagManager(dojo.byId("oils-acq-tag-manager-display"));
+ tagManager.prepareTagSelector(tagSelector);
+ fetchFund();
+}
+
+openils.Util.addOnLoad(load);
<!-- load the page-specific JS -->
<script src='[% ctx.media_prefix %]/js/ui/default/acq/financial/list_funds.js'> </script>
+<script type="text/javascript">
+ function getFundName(rowIndex, item) {
+ if (!item) return null;
+ return {
+ "name": this.grid.store.getValue(item, "name"),
+ "id": this.grid.store.getValue(item, "id")
+ };
+ }
+
+ function formatName(value) {
+ if (!value) return "XXX"; // XXX
+
+ var link = "<a href='/eg/acq/financial/view_fund/" +
+ value.id + "'>" +
+ value.name + "</a>";
+
+ /* TODO: add another element here to which we can attach a tooltip
+ showing tags */
+ return link;
+ }
+</script>
<table style='width:100%;'>
<tr>
<td style='text-align:left;font-size:130%;font-weight: bold;'>Funds</td>
<td style='text-align:right;width:90%;'>
- <span>
- <span>Context Org Unit</span>
- <select
- dojoType="openils.widget.OrgUnitFilteringSelect"
- jsId='contextOrgSelector'
- searchAttr='shortname'
- labelAttr='shortname'>
- </select>
- </span>
-
- Year <select dojoType='dijit.form.FilteringSelect'
- jsId='fundFilterYearSelect' labelAttr='year' searchAttr='year'> </select>
-
<button dojoType='dijit.form.Button' onClick='lfGrid.showCreateDialog()'>New Fund</button>
<button dojoType='dijit.form.Button' onClick='lfGrid.deleteSelected()'>Delete Selected</button>
<tr>
<td colspan='2'>
<div style='width:400px;border-bottom:2px solid #888'>
- Propagation creates new funds for the sugsequent fiscal year based on the
+ Propagation creates new funds for the sugsequent fiscal year based on the
funds for the selected fiscal year. Only funds with the propagate setting
enabled will be affected. No money or encumbrances are altered
- during this process.
- <div>
+ during this process.
+ </div>
</td>
</tr>
<tr>
<td colspan='2'>
<div style='width:400px;border-bottom:2px solid #888'>
The year end close out operation moves encumbrances from the selected fiscal
- year to the analogous funds in the subsequent fiscal year and it deactivates
- funds for the selected fiscal year. Additionally, for all funds that have
- the "Rollver" setting enabled, this process will move all unspent money to
+ year to the analogous funds in the subsequent fiscal year and it deactivates
+ funds for the selected fiscal year. Additionally, for all funds that have
+ the "Rollver" setting enabled, this process will move all unspent money to
the analogous fund in the subsequent fiscal year.
</div>
</td>
<tr>
<td colspan='2'>
<div style='width:400px;border-bottom:2px solid #888'>
- When Dry Run is selected, the system will generate a summary of
- the changes that would occur during the selected operation(s).
+ When Dry Run is selected, the system will generate a summary of
+ the changes that would occur during the selected operation(s).
No data will be changed.
</div>
</td>
</tr>
</table>
</div>
- </div>
+ </div>
</td>
</tr>
</table>
+<div class="oils-acq-basic-roomy">
+ <span>Context Org Unit</span>
+ <select
+ dojoType="openils.widget.OrgUnitFilteringSelect"
+ jsId="contextOrgSelector"
+ searchAttr="shortname"
+ labelAttr="shortname">
+ </select>
+
+ <span>Year</span>
+ <select dojoType="dijit.form.FilteringSelect"
+ jsId="fundFilterYearSelect"
+ labelAttr="year"
+ searchAttr="year">
+ </select>
+</div>
+
<div dojoType="dijit.layout.ContentPane" layoutAlign="client">
<table jsId="lfGrid"
autoHeight='true'
editOnEnter='true'>
<thead>
<tr>
- <th field='combined_balance' name="Combined Balance" get='getBalanceInfo'></th>
+ <th field="name" get="getFundName" formatter="formatName"></th>
+ <th field="combined_balance" name="Combined Balance" get="getBalanceInfo"></th>
</tr>
</thead>
</table>
</div>
-<div dojoType='openils.widget.ProgressDialog' jsId='progressDialog'/>
-
-
+<div dojoType="openils.widget.ProgressDialog" jsId="progressDialog"></div>
[% END %]
</script>
<!-- load the page-specific JS -->
+<script src="[% ctx.media_prefix %]/js/ui/default/acq/common/tag_manager.js"> </script>
<script src='[% ctx.media_prefix %]/js/ui/default/acq/financial/view_fund.js'> </script>
<div id='oils-acq-list-header' class='container'>
</div>
</div>
</div>
+ <div dojoType="dijit.layout.ContentPane" class="oils-acq-detail-content-pane" title="Tags">
+ <script type="dojo/connect" event="onShow">
+ tagManager.displayFund(fund);
+ </script>
+ <div id="oils-acq-tag-manager-display"></div>
+ <div id="oils-acq-tag-manager-add">
+ <div dojoType="dijit.form.DropDownButton">
+ <span>Add Tag</span>
+ <div dojoType="dijit.TooltipDialog">
+ <select dojoType="dijit.form.FilteringSelect"
+ jsId="tagSelector">
+ </select>
+ <button onclick="tagManager.addMapping(
+ fund, new acqft().fromStoreItem(tagSelector.item)
+ );" type="submit" dojoType="dijit.form.Button">
+ Add
+ </button>
+ </div>
+ </div>
+ </div>
+ </div>
</div>
</div>
[% END %]