diff --git a/kfet/static/kfet/js/history.js b/kfet/static/kfet/js/history.js
index a41173b2..9578b83d 100644
--- a/kfet/static/kfet/js/history.js
+++ b/kfet/static/kfet/js/history.js
@@ -19,10 +19,10 @@ class KHistory {
this.list = new OperationList();
- if (!options.no_select)
+ if (!options || !options.no_select)
this.selection = new KHistorySelection(this);
- if (options.no_trigramme)
+ if (options && options.no_trigramme)
this.templates['opegroup'] = '
'
this._init_events();
@@ -80,7 +80,7 @@ class KHistory {
add_node(data) {
var node = this.list.get_or_create(data, 0);
- this.list.add_to_container(this._$container, node, this.templates, this.display_options);
+ this.list.add_to_container(this._$container, node, this.templates);
}
update_node(type, id, update_data) {
@@ -88,8 +88,8 @@ class KHistory {
if (!to_update)
return false;
- $.extend(to_update.content, update_data);
- var $new_elt = to_update.content.display($(this.templates[type]), this.display_options);
+ $.extend(to_update, update_data);
+ var $new_elt = to_update.display($(this.templates[type]), {});
var $to_replace = this._$container.find('#'+type+'-'+id+'>:first-child');
$to_replace.replaceWith($new_elt);
@@ -100,22 +100,22 @@ class KHistory {
is_valid(opegroup) {
var options = this.api_options;
- if (options.from && dateUTCToParis(opegroup.content.at).isBefore(moment(options.from)))
+ if (options.from && dateUTCToParis(opegroup.at).isBefore(moment(options.from)))
return false;
- if (options.to && dateUTCToParis(opegroup.content.at).isAfter(moment(options.to)))
+ if (options.to && dateUTCToParis(opegroup.at).isAfter(moment(options.to)))
return false;
- if (options.transfersonly && opegroup.modelname === 'opegroup')
+ if (options.transfersonly && opegroup.constructor.verbose_name === 'opegroup')
return false;
if (options.accounts && options.accounts.length &&
- options.accounts.indexOf(opegroup.content.account_id) < 0)
+ options.accounts.indexOf(opegroup.account_id) < 0)
return false;
if (options.checkouts && options.checkouts.length &&
(opegroup.modelname === 'transfergroup' ||
- options.checkouts.indexOf(opegroup.content.checkout_id) < 0))
+ options.checkouts.indexOf(opegroup.checkout_id) < 0))
return false;
return true;
diff --git a/kfet/static/kfet/js/kfet.api.js b/kfet/static/kfet/js/kfet.api.js
index e08efced..6afc179f 100644
--- a/kfet/static/kfet/js/kfet.api.js
+++ b/kfet/static/kfet/js/kfet.api.js
@@ -565,14 +565,20 @@ class Day extends ModelObject {
* @default ['id', 'date']
* @see {@link Models.ModelObject.props|ModelObject.props}
*/
- static get props() { return ['id', 'date'] }
+ static get props() { return ['id', 'date', 'opegroups'] }
/**
* Default values for Day model instances
* @default {'id': '', 'date': moment()}
* @see {@link Models.ModelObject.default_data|ModelObject.default_data}
*/
- static get default_data() { return {'id': '', 'date': moment()}; }
+ static get default_data() { return {'id': '', 'date': moment(), 'opegroups': []}; }
+
+ /**
+ * Verbose name for Article model
+ * @default 'day'
+ */
+ static get verbose_name() { return 'day'; }
/**
* @default {@link Formatters.DayFormatter}
@@ -610,7 +616,7 @@ class HistoryGroup extends ModelObject {
* @see {@link Models.ModelObject.props|ModelObject.props}
*/
static get props() {
- return ['id', 'at', 'comment', 'valid_by'];
+ return ['id', 'at', 'comment', 'valid_by', 'day'];
}
/**
@@ -621,7 +627,7 @@ class HistoryGroup extends ModelObject {
*/
static get default_data() {
return {'id': 0, 'at': moment(), 'comment': '',
- 'valid_by': '',};
+ 'valid_by': '', 'day': new Day()};
}
/**
@@ -665,9 +671,17 @@ class OperationGroup extends HistoryGroup {
*/
static get default_data() {
return $.extend({}, HistoryGroup.default_data,
- {'amount': 0, 'is_cof': false, 'trigramme': ''});
+ {'amount': 0, 'is_cof': false, 'trigramme': '',
+ 'opes': []});
}
+ /**
+ * Verbose name for OperationGroup model
+ * @default 'opegroup'
+ */
+ static get verbose_name() { return 'opegroup'; }
+
+
/**
* @default {@link Formatters.OpegroupFormatter}
*/
@@ -686,6 +700,24 @@ class OperationGroup extends HistoryGroup {
*/
class TransferGroup extends HistoryGroup {
+ /**
+ * Default values for OperationGroup instances.
+ * @default {@link Models.HistoryGroup.default_data|HistoryGroup.default_data} +
+ * {'transfers': []}
+ * @see {@link Models.ModelObject.default_data|ModelObject.default_data}
+ */
+ static get default_data() {
+ return $.extend({}, HistoryGroup.default_data,
+ {'transfers': []});
+ }
+
+ /**
+ * Verbose name for TransferGroup model
+ * @default 'transfergroup'
+ */
+ static get verbose_name() { return 'transfergroup'; }
+
+
/**
* @default {@link Formatters.TransferGroupFormatter}
*/
@@ -707,7 +739,7 @@ class Operation extends ModelObject {
* @see {@link Models.ModelObject.props|ModelObject.props}
*/
static get props() {
- return ['id', 'amount', 'canceled_at', 'canceled_by'];
+ return ['id', 'amount', 'canceled_at', 'canceled_by', 'group'];
}
/**
@@ -716,7 +748,8 @@ class Operation extends ModelObject {
* @see {@link Models.ModelObject.default_data|ModelObject.default_data}
*/
static get default_data() {
- return {'id': '', 'amount': 0, 'canceled_at': undefined, 'canceled_by': '' };
+ return {'id': '', 'amount': 0, 'canceled_at': undefined, 'canceled_by': '',
+ 'group': new HistoryGroup()};
}
get amount() { return this._amount; }
@@ -765,6 +798,13 @@ class Purchase extends Operation {
});
}
+ /**
+ * Verbose name for Purchase model
+ * @default 'purchase'
+ */
+ static get verbose_name() { return 'purchase'; }
+
+
/**
* @default {@link Formatters.PurchaseFormatter}
*/
@@ -786,9 +826,16 @@ class SpecialOperation extends Operation {
* @see {@link Models.ModelObject.props|ModelObject.props}
*/
static get props() {
- return Operation.props.concat(['type', 'is_checkout']);
+ return Operation.props.concat(['type']);
}
+ /**
+ * Verbose name for SpecialOperation model
+ * @default 'specialope'
+ */
+ static get verbose_name() { return 'specialope'; }
+
+
/**
* Verbose names for operation types
* @type {Object}
@@ -808,7 +855,7 @@ class SpecialOperation extends Operation {
* @see {@link Models.ModelObject.default_data|ModelObject.default_data}
*/
static get default_data() {
- return $.extend({}, Operation.default_data, {'type': '', 'is_checkout': false});
+ return $.extend({}, Operation.default_data, {'type': ''});
}
/**
@@ -835,6 +882,12 @@ class Transfer extends Operation {
return Operation.props.concat(['from_acc', 'to_acc']);
}
+ /**
+ * Verbose name for Transfer model
+ * @default 'transfer'
+ */
+ static get verbose_name() { return 'transfer'; }
+
/**
* Default values for Transfer model instances
* @default {@link Models.Operation.default_data|Operation.default_data} + {'from_acc': '', 'to_acc': ''}
@@ -873,6 +926,13 @@ class ModelForest {
this.from(datalist || []);
}
+ /**
+ * Return true if instance is empty
+ */
+ is_empty() {
+ return this.roots.length == 0;
+ }
+
/**
* Shortcut functions to get parent and children of a given node
*/
@@ -920,11 +980,11 @@ class ModelForest {
if (direction >= 0) {
var child_name = struct_data.children;
- var child_struct = this.constructor.structure[child_name];
if (data.children && data.children.length) {
for (let child_data of data.children) {
var child = this.get_or_create(child_data, 1);
- child[child_struct.parent] = node;
+ var child_parent = this.constructor.structure[child.constructor.verbose_name];
+ child[child_parent] = node;
node[child_name].push(child);
}
}
@@ -1008,7 +1068,8 @@ class ModelForest {
var $to_insert = this.render_element(first_missing, templates, options);
if (existing) {
- $container.find('#'+existing.modelname+'-'+existing.content.id+'>:first-child').after($to_insert);
+ $container.find('#'+existing.constructor.verbose_name+'-'+existing.id+'>:first-child')
+ .after($to_insert);
} else {
$container.prepend($to_insert);
}
@@ -1021,6 +1082,9 @@ class ModelForest {
* @param {Object} [options] Options for element render method
*/
display($container, templates, options) {
+ if (this.is_empty())
+ return;
+
if (this.constructor.root_sort)
this.roots.sort(this.constructor.root_sort);
else
@@ -1161,14 +1225,34 @@ class OperationList extends APIModelForest {
* @default [Operation, OperationGroup, Day]
* @see {@link Models.ModelList.models|ModelList.models}
*/
- static get models() {
+ static get structure() {
return {
- 'day': Day,
- 'opegroup': OperationGroup,
- 'transfergroup': TransferGroup,
- 'purchase': Purchase,
- 'specialope': SpecialOperation,
- 'transfer': Transfer,
+ 'day': {
+ 'model': Day,
+ 'children': 'opegroups'
+ },
+ 'opegroup': {
+ 'model': OperationGroup,
+ 'parent': 'day',
+ 'children': 'opes',
+ },
+ 'transfergroup': {
+ 'model': TransferGroup,
+ 'parent': 'day',
+ 'children': 'transfers'
+ },
+ 'purchase': {
+ 'model': Purchase,
+ 'parent': 'opegroup',
+ },
+ 'specialope': {
+ 'model': SpecialOperation,
+ 'parent': 'opegroup',
+ },
+ 'transfer': {
+ 'model': Transfer,
+ 'parent': 'transfergroup',
+ },
};
}
@@ -1583,10 +1667,10 @@ class OperationFormatter extends Formatter {
/**
* Properties renderable to html.
- * @default ['amount', 'infos1', 'infos2', 'addcost', 'canceled']
+ * @default ['amount', 'infos1', 'infos2', 'canceled']
*/
static get props() {
- return ['amount', 'infos1', 'infos2', 'addcost', 'canceled'];
+ return ['amount', 'infos1', 'infos2', 'canceled'];
}
static get attrs() {
@@ -1597,19 +1681,7 @@ class OperationFormatter extends Formatter {
* a.amount displayed according to a.is_cof and a.trigramme values.
*/
static prop_amount(a) {
- return amountDisplay(a.amount, a.is_cof, a.trigramme);
- }
-
- /**
- * addcost property is displayed iff a.addcost_for is nonempty.
- */
- static prop_addcost(a) {
- if (a.addcost_for) {
- return '('+amountDisplay(a.addcost_amount, a.is_cof)
- +'UKF pour '+a.addcost_for+')';
- } else {
- return '';
- }
+ return amountDisplay(a.amount, a.group.is_cof, a.group.trigramme);
}
/**
@@ -1639,6 +1711,22 @@ class OperationFormatter extends Formatter {
*/
class PurchaseFormatter extends OperationFormatter {
+ static get props() {
+ return OperationFormatter.props.concat(['addcost']);
+ }
+
+ /**
+ * addcost property is displayed iff a.addcost_for is nonempty.
+ */
+ static prop_addcost(a) {
+ if (a.addcost_for) {
+ return '('+amountDisplay(a.addcost_amount, a.is_cof)
+ +'UKF pour '+a.addcost_for+')';
+ } else {
+ return '';
+ }
+ }
+
static prop_infos1(a) {
return a.article_nb;
}
diff --git a/kfet/templates/kfet/kpsul.html b/kfet/templates/kfet/kpsul.html
index 3aefb527..c1e5fec6 100644
--- a/kfet/templates/kfet/kpsul.html
+++ b/kfet/templates/kfet/kpsul.html
@@ -648,72 +648,6 @@ $(document).ready(function() {
}
-<<<<<<< HEAD
-=======
- // -----
- // Cancel from history
- // -----
-
- khistory.$container.selectable({
- filter: 'div.opegroup, div.ope',
- selected: function(e, ui) {
- $(ui.selected).each(function() {
- if ($(this).hasClass('opegroup')) {
- var opegroup = $(this).data('opegroup');
- $(this).siblings('.ope').filter(function() {
- return $(this).data('opegroup') == opegroup
- }).addClass('ui-selected');
- }
- });
- },
- });
-
- $(document).on('keydown', function (e) {
- if (e.keyCode == 46) {
- // DEL (Suppr)
- var opes_to_cancel = [];
- khistory.$container.find('.ope.ui-selected').each(function () {
- opes_to_cancel.push($(this).data('ope'));
- });
- if (opes_to_cancel.length > 0)
- cancelOperations(opes_to_cancel);
- }
- });
-
- // -----
- // Synchronization
- // -----
-
- OperationWebSocket.add_handler(function(data) {
- for (var i=0; i>>>>>> origin/aureplop/kpsul_js_refactor
-
// -----
// General
// -----
diff --git a/kfet/views.py b/kfet/views.py
index 57e7ae95..7826f31d 100644
--- a/kfet/views.py
+++ b/kfet/views.py
@@ -1168,7 +1168,6 @@ def kpsul_perform_operations(request):
websocket_data = {}
websocket_data['opegroups'] = [{
'add': True,
-<<<<<<< HEAD
'modelname': 'opegroup',
'content': {
'id': operationgroup.pk,
@@ -1189,48 +1188,17 @@ def kpsul_perform_operations(request):
'id': operationgroup.at.strftime('%Y%m%d'),
'date': operationgroup.at
},
- 'child_sort': 'opegroup',
},
'children': [],
-=======
- 'id': operationgroup.pk,
- 'amount': operationgroup.amount,
- 'checkout__name': operationgroup.checkout.name,
- 'at': operationgroup.at,
- 'is_cof': operationgroup.is_cof,
- 'comment': operationgroup.comment,
- 'valid_by__trigramme': (operationgroup.valid_by and
- operationgroup.valid_by.trigramme or None),
- 'on_acc__trigramme': operationgroup.on_acc.trigramme,
- 'opes': [],
->>>>>>> origin/aureplop/kpsul_js_refactor
}]
for ope in operations:
ope_data = {
-<<<<<<< HEAD
'content': {
'id': ope.id,
'amount': ope.amount,
- 'canceled_at': ope.canceled_at,
- 'canceled_by':
- ope.canceled_by and ope.canceled_by.trigramme or None,
- 'is_cof': operationgroup.is_cof,
- 'trigramme': (
- operationgroup.on_acc and
- operationgroup.on_acc.trigramme or None),
+ 'canceled_at': None,
+ 'canceled_by': None,
},
-=======
- 'id': operation.pk, 'type': operation.type,
- 'amount': operation.amount,
- 'addcost_amount': operation.addcost_amount,
- 'addcost_for__trigramme': (
- operation.addcost_for and addcost_for.trigramme or None),
- 'article__name': (
- operation.article and operation.article.name or None),
- 'article_nb': operation.article_nb,
- 'group_id': operationgroup.pk,
- 'canceled_by__trigramme': None, 'canceled_at': None,
->>>>>>> origin/aureplop/kpsul_js_refactor
}
if ope.type == Operation.PURCHASE:
@@ -1246,7 +1214,6 @@ def kpsul_perform_operations(request):
ope_data['modelname'] = 'specialope'
ope_data['content'].update({
'type': ope.type,
- 'is_checkout': ope.is_checkout,
})
websocket_data['opegroups'][0]['children'].append(ope_data)
# Need refresh from db cause we used update on queryset
@@ -1586,7 +1553,6 @@ def history_json(request):
'id': opegroup.at.strftime('%Y%m%d'),
'date': opegroup.at
},
- 'child_sort': 'opegroup',
},
'children': [],
}
@@ -1643,7 +1609,6 @@ def history_json(request):
'id': transfergroup.at.strftime('%Y%m%d'),
'date': transfergroup.at
},
- 'child_sort': 'transfergroup',
},
'children': [],
}