Cleaning - Article autocomplete, ForestDisplay and more
K-Psul - Improve article autocompletion. ArticleManager - "selected" property becomes a reference to an article in the data properties. ForestDisplay - Add data property "object" linked to object being represented - Use class to identify objects instead of id. Allow multiple displays of same ModelForest. - New get_class method returns the class selector to find an object container in the DOM. - New get_dom method returns the DOM element from an object in the ModelForest. Cancellation view - Fix 500 on cancel with already canceled opes/transfers
This commit is contained in:
parent
51083f9195
commit
eff1b7ff19
5 changed files with 121 additions and 132 deletions
|
@ -254,6 +254,8 @@ input[type=number]::-webkit-outer-spin-button {
|
||||||
#article_selection {
|
#article_selection {
|
||||||
height:40px;
|
height:40px;
|
||||||
width:100%;
|
width:100%;
|
||||||
|
border-bottom: 1px solid #c8102e;
|
||||||
|
line-height: 39px;
|
||||||
}
|
}
|
||||||
|
|
||||||
#article_selection input, #article_selection span {
|
#article_selection input, #article_selection span {
|
||||||
|
@ -261,7 +263,6 @@ input[type=number]::-webkit-outer-spin-button {
|
||||||
float:left;
|
float:left;
|
||||||
border:0;
|
border:0;
|
||||||
border-right:1px solid #c8102e;
|
border-right:1px solid #c8102e;
|
||||||
border-bottom:1px solid #c8102e;
|
|
||||||
border-radius:0;
|
border-radius:0;
|
||||||
font-size:16px;
|
font-size:16px;
|
||||||
font-weight:bold;
|
font-weight:bold;
|
||||||
|
@ -276,27 +277,17 @@ input[type=number]::-webkit-outer-spin-button {
|
||||||
padding-left:10px;
|
padding-left:10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
#article_number {
|
#article_number, #article_stock {
|
||||||
width:10%;
|
width:10%;
|
||||||
text-align:center;
|
text-align:center;
|
||||||
}
|
}
|
||||||
|
|
||||||
#article_stock {
|
|
||||||
width:10%;
|
|
||||||
line-height:38px;
|
|
||||||
text-align:center;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (min-width:1200px) {
|
@media (min-width:1200px) {
|
||||||
#article_autocomplete {
|
#article_autocomplete {
|
||||||
width:84%
|
width:84%
|
||||||
}
|
}
|
||||||
|
|
||||||
#article_number {
|
#article_number, #article_stock {
|
||||||
width:8%;
|
|
||||||
}
|
|
||||||
|
|
||||||
#article_stock {
|
|
||||||
width:8%;
|
width:8%;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -145,12 +145,14 @@ class KHistory {
|
||||||
'canceled_at': ope.canceled_at,
|
'canceled_at': ope.canceled_at,
|
||||||
'canceled_by': ope.canceled_by,
|
'canceled_by': ope.canceled_by,
|
||||||
};
|
};
|
||||||
if (ope.modelname === 'ope') {
|
|
||||||
this.data.update('purchase', ope.id, update_data)
|
let model;
|
||||||
|| this.data.update('specialope', ope.id, update_data);
|
if (ope.modelname === 'ope')
|
||||||
} else if (ope.modelname === 'transfer') {
|
model = Operation;
|
||||||
this.data.update('transfer', ope.id, update_data);
|
else if (ope.modelname === 'transfer')
|
||||||
}
|
model = Transfer;
|
||||||
|
|
||||||
|
this.data.update(model, ope.id, update_data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -165,8 +167,6 @@ class KHistory {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var nb_opes = this._$container.find('.ope[canceled="false"]').length;
|
|
||||||
$('#nb_opes').text(nb_opes);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -198,14 +198,16 @@ class KHistorySelection {
|
||||||
}
|
}
|
||||||
|
|
||||||
get_selected() {
|
get_selected() {
|
||||||
var selected = {'transfers': [], 'opes': [],};
|
var selected = {
|
||||||
|
transfers: [],
|
||||||
|
opes: []
|
||||||
|
};
|
||||||
this._$container.find('.ope.ui-selected').each(function() {
|
this._$container.find('.ope.ui-selected').each(function() {
|
||||||
var [type, id] = $(this).parent().attr('id').split('-');
|
let object = $(this).parent().data("object");
|
||||||
|
if (object instanceof Transfer)
|
||||||
if (type === 'transfer')
|
selected.transfers.push(object.id);
|
||||||
selected['transfers'].push(id);
|
|
||||||
else
|
else
|
||||||
selected['opes'].push(id);
|
selected.opes.push(object.id);
|
||||||
});
|
});
|
||||||
|
|
||||||
return selected;
|
return selected;
|
||||||
|
|
|
@ -623,7 +623,7 @@ class HistoryGroup extends ModelObject {
|
||||||
* @see {@link Models.ModelObject.props|ModelObject.props}
|
* @see {@link Models.ModelObject.props|ModelObject.props}
|
||||||
*/
|
*/
|
||||||
static get props() {
|
static get props() {
|
||||||
return ['id', 'at', 'comment', 'valid_by', 'day'];
|
return ['id', 'at', 'comment', 'valid_by'];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -634,8 +634,7 @@ class HistoryGroup extends ModelObject {
|
||||||
*/
|
*/
|
||||||
static get default_data() {
|
static get default_data() {
|
||||||
return {
|
return {
|
||||||
'id': 0, 'at': moment(), 'comment': '',
|
'id': 0, 'at': null, 'comment': '', 'valid_by': ''
|
||||||
'valid_by': '', 'day': new Day()
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -757,7 +756,7 @@ class Operation extends ModelObject {
|
||||||
*/
|
*/
|
||||||
static get default_data() {
|
static get default_data() {
|
||||||
return {
|
return {
|
||||||
'id': '', 'amount': 0, 'canceled_at': undefined, 'canceled_by': '',
|
'id': '', 'amount': 0, 'canceled_at': null, 'canceled_by': '',
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -769,7 +768,7 @@ class Operation extends ModelObject {
|
||||||
if (v)
|
if (v)
|
||||||
this._canceled_at = dateUTCToParis(v);
|
this._canceled_at = dateUTCToParis(v);
|
||||||
else
|
else
|
||||||
this._canceled_at = undefined;
|
this._canceled_at = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1435,7 +1434,8 @@ class ForestDisplay {
|
||||||
options = options || {};
|
options = options || {};
|
||||||
|
|
||||||
var $container = $('<div></div>');
|
var $container = $('<div></div>');
|
||||||
$container.attr('id', modelname+'-'+node.id);
|
$container.addClass(this.get_class(node));
|
||||||
|
$container.data('object', node);
|
||||||
|
|
||||||
var $rendered = node.display($(template), options);
|
var $rendered = node.display($(template), options);
|
||||||
$container.append($rendered);
|
$container.append($rendered);
|
||||||
|
@ -1459,6 +1459,14 @@ class ForestDisplay {
|
||||||
return $container;
|
return $container;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get_class(object) {
|
||||||
|
return `${object.constructor.verbose_name}-${object.id}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
get_dom(object) {
|
||||||
|
return this._$container.find("."+this.get_class(object));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Renders node and adds it to the container.<br>
|
* Renders node and adds it to the container.<br>
|
||||||
|
@ -1470,15 +1478,15 @@ class ForestDisplay {
|
||||||
var existing = this.data.get_parent(node);
|
var existing = this.data.get_parent(node);
|
||||||
var first_missing = node;
|
var first_missing = node;
|
||||||
|
|
||||||
while (existing && !(this._$container.find('#'+existing.modelname+'-'+existing.id))) {
|
while (existing && !(this.get_dom(existing))) {
|
||||||
first_missing = existing;
|
first_missing = existing;
|
||||||
existing = this.data.get_parent(existing);
|
existing = this.data.get_parent(existing);
|
||||||
}
|
}
|
||||||
|
|
||||||
var $to_insert = this.render_element(first_missing, options);
|
var $to_insert = this.render_element(first_missing, options);
|
||||||
if (existing)
|
if (existing)
|
||||||
this._$container
|
this.get_dom(existing)
|
||||||
.find('#'+existing.constructor.verbose_name+'-'+existing.id+'>.children')
|
.children(".children")
|
||||||
.prepend($to_insert);
|
.prepend($to_insert);
|
||||||
else
|
else
|
||||||
this._$container.prepend($to_insert);
|
this._$container.prepend($to_insert);
|
||||||
|
@ -1492,12 +1500,9 @@ class ForestDisplay {
|
||||||
render(options) {
|
render(options) {
|
||||||
var forest = this.data;
|
var forest = this.data;
|
||||||
|
|
||||||
if (forest.is_empty())
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (forest.constructor.root_sort)
|
if (forest.constructor.root_sort)
|
||||||
forest.roots.sort(forest.constructor.root_sort);
|
forest.roots.sort(forest.constructor.root_sort);
|
||||||
else
|
else if (forest.roots.length)
|
||||||
forest.roots.sort(forest.roots[0].constructor.compare);
|
forest.roots.sort(forest.roots[0].constructor.compare);
|
||||||
|
|
||||||
for (let root of forest.roots) {
|
for (let root of forest.roots) {
|
||||||
|
@ -1515,13 +1520,12 @@ class ForestDisplay {
|
||||||
var modelname = data.constructor.verbose_name;
|
var modelname = data.constructor.verbose_name;
|
||||||
var $new_elt = data.display($(this._templates[modelname]), {});
|
var $new_elt = data.display($(this._templates[modelname]), {});
|
||||||
|
|
||||||
var $to_replace = this._$container.find('#'+modelname+'-'+data.id+'>:first-child');
|
var $to_replace = this.get_dom(data).children(":first-child");
|
||||||
$to_replace.replaceWith($new_elt);
|
$to_replace.replaceWith($new_elt);
|
||||||
}
|
}
|
||||||
|
|
||||||
delete(data) {
|
delete(data) {
|
||||||
let modelname = data.constructor.verbose_name;
|
this.get_dom(data).remove();
|
||||||
this._$container.find('#'+modelname+'-'+data.id).remove();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -2055,7 +2059,7 @@ class ItemBasketFormatter extends Formatter {
|
||||||
class PurchaseBasketFormatter extends ItemBasketFormatter {
|
class PurchaseBasketFormatter extends ItemBasketFormatter {
|
||||||
|
|
||||||
static get attrs() {
|
static get attrs() {
|
||||||
return ['article_id', 'low_stock'];
|
return ['low_stock'];
|
||||||
}
|
}
|
||||||
|
|
||||||
static prop_number(o) {
|
static prop_number(o) {
|
||||||
|
@ -2066,10 +2070,6 @@ class PurchaseBasketFormatter extends ItemBasketFormatter {
|
||||||
return o.article.name;
|
return o.article.name;
|
||||||
}
|
}
|
||||||
|
|
||||||
static attr_article_id(o) {
|
|
||||||
return o.article.id;
|
|
||||||
}
|
|
||||||
|
|
||||||
static attr_low_stock(o) {
|
static attr_low_stock(o) {
|
||||||
let stock = o.article.stock;
|
let stock = o.article.stock;
|
||||||
return -5 <= stock && stock <= 5;
|
return -5 <= stock && stock <= 5;
|
||||||
|
|
|
@ -32,7 +32,7 @@ class KPsulManager {
|
||||||
this.checkout_manager.reset();
|
this.checkout_manager.reset();
|
||||||
this.previous_basket.reset();
|
this.previous_basket.reset();
|
||||||
Config.reset( () => {
|
Config.reset( () => {
|
||||||
this.article_manager.reset_data();
|
this.article_manager.fetch_data();
|
||||||
this.history.fetch();
|
this.history.fetch();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -282,7 +282,9 @@ class AccountSearch {
|
||||||
|
|
||||||
class CheckoutManager {
|
class CheckoutManager {
|
||||||
|
|
||||||
constructor() {
|
constructor(kpsul) {
|
||||||
|
this.kpsul = kpsul;
|
||||||
|
|
||||||
this._$container = $('#checkout');
|
this._$container = $('#checkout');
|
||||||
this.display_prefix = '#checkout-';
|
this.display_prefix = '#checkout-';
|
||||||
|
|
||||||
|
@ -314,9 +316,8 @@ class CheckoutManager {
|
||||||
|
|
||||||
this.checkout.get_by_apipk(id, api_options)
|
this.checkout.get_by_apipk(id, api_options)
|
||||||
.done( (data) => this._update_on_success(data) )
|
.done( (data) => this._update_on_success(data) )
|
||||||
.fail( () => this.reset_data() );
|
.fail( () => this.reset_data() )
|
||||||
|
.always( () => this.kpsul.focus() );
|
||||||
kpsul.focus();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_update_on_success(data) {
|
_update_on_success(data) {
|
||||||
|
@ -445,7 +446,7 @@ class ArticleManager {
|
||||||
this._$nb = $('#article_number');
|
this._$nb = $('#article_number');
|
||||||
this._$stock = $('#article_stock');
|
this._$stock = $('#article_stock');
|
||||||
|
|
||||||
this.selected = new Article();
|
this.selected = null;
|
||||||
this.data = new ArticleList();
|
this.data = new ArticleList();
|
||||||
var $container = $('#articles_data');
|
var $container = $('#articles_data');
|
||||||
var templates = {
|
var templates = {
|
||||||
|
@ -464,7 +465,7 @@ class ArticleManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
validate(article) {
|
validate(article) {
|
||||||
this.selected.from(article);
|
this.selected = article;
|
||||||
this._$input.val(article.name);
|
this._$input.val(article.name);
|
||||||
this._$nb.val('1');
|
this._$nb.val('1');
|
||||||
this._$stock.text('/'+article.stock);
|
this._$stock.text('/'+article.stock);
|
||||||
|
@ -472,22 +473,20 @@ class ArticleManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
unset() {
|
unset() {
|
||||||
this.selected.clear();
|
this.selected = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
is_empty() {
|
is_empty() {
|
||||||
return this.selected.is_empty();
|
return !this.selected || this.selected.is_empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
reset_data() {
|
fetch_data() {
|
||||||
this.display.clear();
|
|
||||||
this.data.clear();
|
|
||||||
this.data.fromAPI();
|
this.data.fromAPI();
|
||||||
}
|
}
|
||||||
|
|
||||||
update_data(data) {
|
update_data(data) {
|
||||||
for (let article_dict of data.articles)
|
for (let article_data of data.articles)
|
||||||
this.data.update('article', article_dict.id, article_dict);
|
this.data.update('article', article_data.id, article_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
reset() {
|
reset() {
|
||||||
|
@ -514,15 +513,13 @@ class ArticleManager {
|
||||||
});
|
});
|
||||||
|
|
||||||
this._$container.on('click', '.article', function() {
|
this._$container.on('click', '.article', function() {
|
||||||
var id = $(this).parent().attr('id').split('-')[1];
|
let article = $(this).parent().data("object");
|
||||||
var article = that.data.find('article', id);
|
that.validate(article);
|
||||||
if (article)
|
|
||||||
that.validate(article);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
this._$nb.on('keydown', function(e) {
|
this._$nb.on('keydown', function(e) {
|
||||||
if (e.keyCode == 13 && that.constructor.check_nb(that.nb) && !that.is_empty()) {
|
if (e.keyCode == 13 && that.constructor.check_nb(that.nb) && !that.is_empty()) {
|
||||||
that.kpsul.basket.add_purchase(that.selected.id, parseInt(that.nb));
|
that.kpsul.basket.add_purchase(that.selected, parseInt(that.nb));
|
||||||
that.reset().focus();
|
that.reset().focus();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -573,85 +570,78 @@ class ArticleAutocomplete {
|
||||||
_init_events() {
|
_init_events() {
|
||||||
var that = this;
|
var that = this;
|
||||||
|
|
||||||
// 8:Backspace|9:Tab|13:Enter|46:DEL|112-117:F1-6|119-123:F8-F12
|
// 8:Backspace|9:Tab|13:Enter|35:End|36:Home|37-40:Arrows|46:DEL|112-123:F1-F12
|
||||||
var normalKeys = /^(8|9|13|46|112|113|114|115|116|117|119|120|121|122|123)$/;
|
var normalKeys = /^(8|9|13|35|36|37|38|39|40|46|112|113|114|115|116|117|119|120|121|122|123)$/;
|
||||||
var arrowKeys = /^(37|38|39|40)$/;
|
|
||||||
|
|
||||||
this._$input
|
this._$input
|
||||||
.on('keydown', function(e) {
|
.on('keydown', function(e) {
|
||||||
var text = that._$input.val();
|
|
||||||
if (normalKeys.test(e.keyCode) || arrowKeys.test(e.keyCode) || e.ctrlKey) {
|
if (normalKeys.test(e.keyCode) || e.ctrlKey)
|
||||||
// For the backspace key, we suppose the cursor is at the very end
|
|
||||||
if(e.keyCode == 8) {
|
|
||||||
that.update(text.substring(0, text.length-1), true);
|
|
||||||
}
|
|
||||||
return true;
|
return true;
|
||||||
}
|
|
||||||
that.update(text+e.key, false);
|
let initial = that._$input.val();
|
||||||
|
let future = initial.substr(0, this.selectionStart)
|
||||||
|
+ e.key
|
||||||
|
+ initial.substr(this.selectionEnd);
|
||||||
|
|
||||||
|
that.update(future);
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
this._$input
|
||||||
|
.on('input', () => this.update(this._$input.val(), false));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
update(prefix, backspace) {
|
update(prefix, autofill) {
|
||||||
|
if (autofill === undefined)
|
||||||
|
autofill = true;
|
||||||
|
|
||||||
this.resetMatch();
|
this.matching = this.find_matching(prefix);
|
||||||
var article_list = this.manager.data;
|
|
||||||
var lower = prefix.toLowerCase();
|
|
||||||
var that = this;
|
|
||||||
|
|
||||||
article_list.traverse('article', function(article) {
|
if (this.matching.length === 1 && autofill) {
|
||||||
if (article.name.toLowerCase().startsWith(lower))
|
this.manager.validate(this.matching[0]);
|
||||||
that.matching.push(article);
|
this.showAll();
|
||||||
});
|
} else {
|
||||||
|
|
||||||
if (this.matching.length == 1) {
|
|
||||||
if (!backspace) {
|
|
||||||
this.manager.validate(this.matching[0]);
|
|
||||||
this.showAll();
|
|
||||||
} else {
|
|
||||||
this.manager.unset();
|
|
||||||
this.updateDisplay();
|
|
||||||
}
|
|
||||||
} else if (this.matching.length > 1) {
|
|
||||||
this.manager.unset();
|
this.manager.unset();
|
||||||
this.updateDisplay();
|
if (this.matching.length >= 1) {
|
||||||
if (!backspace)
|
this.updateDisplay();
|
||||||
this.updatePrefix();
|
if (autofill)
|
||||||
|
this.updateInput();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
updateDisplay() {
|
updateDisplay() {
|
||||||
var that = this;
|
let that = this;
|
||||||
|
let display = this.manager.display;
|
||||||
|
|
||||||
this.manager.data.traverse('category', function(category) {
|
this.manager.data.traverse('category', function(category) {
|
||||||
var is_active = false;
|
var is_active = false;
|
||||||
for (let article of category.articles) {
|
for (let article of category.articles) {
|
||||||
|
let $article = display.get_dom(article);
|
||||||
if (that.matching.indexOf(article) != -1) {
|
if (that.matching.indexOf(article) != -1) {
|
||||||
is_active = true;
|
is_active = true;
|
||||||
that._$container.find('#article-'+article.id).show();
|
$article.show();
|
||||||
} else {
|
} else {
|
||||||
that._$container.find('#article-'+article.id).hide();
|
$article.hide();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_active) {
|
let $category = display.get_dom(category);
|
||||||
that._$container.find('#category-'+category.id).show();
|
is_active ? $category.show() : $category.hide();
|
||||||
} else {
|
|
||||||
that._$container.find('#category-'+category.id).hide();
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
updatePrefix() {
|
updateInput() {
|
||||||
var lower = this.matching.map(function (article) {
|
if (!this.matching.length)
|
||||||
return article.name.toLowerCase();
|
return;
|
||||||
});
|
|
||||||
|
|
||||||
lower.sort();
|
let names = this.matching.map( article => article.name.toLowerCase() ).sort();
|
||||||
var first = lower[0], last = lower[lower.length-1],
|
|
||||||
|
let first = names[0], last = names[names.length-1],
|
||||||
length = first.length, i = 0;
|
length = first.length, i = 0;
|
||||||
while (i < length && first.charAt(i) === last.charAt(i)) i++;
|
while (i < length && first.charAt(i) === last.charAt(i)) i++;
|
||||||
|
|
||||||
|
@ -659,17 +649,20 @@ class ArticleAutocomplete {
|
||||||
}
|
}
|
||||||
|
|
||||||
showAll() {
|
showAll() {
|
||||||
var that = this;
|
this.matching = this.find_matching("");
|
||||||
this.resetMatch();
|
|
||||||
this.manager.data.traverse('article', function(article) {
|
|
||||||
that.matching.push(article);
|
|
||||||
});
|
|
||||||
this.updateDisplay();
|
this.updateDisplay();
|
||||||
}
|
}
|
||||||
|
|
||||||
resetMatch() {
|
find_matching(start) {
|
||||||
this.matching = [];
|
let lower = start.toLowerCase();
|
||||||
|
let matching = [];
|
||||||
|
this.manager.data.traverse('article', function(article) {
|
||||||
|
if (article.name.toLowerCase().startsWith(lower))
|
||||||
|
matching.push(article);
|
||||||
|
});
|
||||||
|
return matching;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -717,8 +710,8 @@ class BasketManager {
|
||||||
return total;
|
return total;
|
||||||
}
|
}
|
||||||
|
|
||||||
add_purchase(article_id, nb) {
|
add_purchase(article, nb) {
|
||||||
let found = this.find_purchase(article_id);
|
let found = this.find_purchase(article);
|
||||||
if (found) {
|
if (found) {
|
||||||
let new_nb = found.article_nb + nb;
|
let new_nb = found.article_nb + nb;
|
||||||
if (new_nb > 0) {
|
if (new_nb > 0) {
|
||||||
|
@ -733,15 +726,15 @@ class BasketManager {
|
||||||
} else {
|
} else {
|
||||||
let created = this.data.create("purchase", {
|
let created = this.data.create("purchase", {
|
||||||
id: this.formset.new_index(),
|
id: this.formset.new_index(),
|
||||||
article: this.kpsul.article_manager.data.find("article", article_id),
|
article: article,
|
||||||
article_nb: nb
|
article_nb: nb
|
||||||
});
|
});
|
||||||
this.formset.create(created.for_formset());
|
this.formset.create(created.for_formset());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
find_purchase(article_id) {
|
find_purchase(article) {
|
||||||
return this.data.find("purchase", (purchase) => purchase.article.id === article_id);
|
return this.data.find("purchase", (purchase) => purchase.article.id === article.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
add_deposit(amount) {
|
add_deposit(amount) {
|
||||||
|
@ -942,21 +935,24 @@ class BasketSelection {
|
||||||
case 46:
|
case 46:
|
||||||
// DEL (Suppr)
|
// DEL (Suppr)
|
||||||
basket._$container.find('.ui-selected').each( function() {
|
basket._$container.find('.ui-selected').each( function() {
|
||||||
let dom_id = $(this).parent().attr("id");
|
let item = $(this).parent().data("object");
|
||||||
let id = parseInt(dom_id.split("-")[1]);
|
basket.delete(item.id);
|
||||||
basket.delete(id);
|
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
case 38:
|
case 38:
|
||||||
// Arrow up
|
// Arrow up
|
||||||
basket._$container.find('.ui-selected').each( function() {
|
basket._$container.find('.ui-selected').each( function() {
|
||||||
basket.add_purchase(parseInt($(this).attr('article_id')), 1);
|
let item = $(this).parent().data("object");
|
||||||
|
if (item instanceof PurchaseBasket)
|
||||||
|
basket.add_purchase(item.article, 1);
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
case 40:
|
case 40:
|
||||||
// Arrow down
|
// Arrow down
|
||||||
basket._$container.find('.ui-selected').each( function() {
|
basket._$container.find('.ui-selected').each( function() {
|
||||||
basket.add_purchase(parseInt($(this).attr('article_id')), -1);
|
let item = $(this).parent().data("object");
|
||||||
|
if (item instanceof PurchaseBasket)
|
||||||
|
basket.add_purchase(item.article, -1);
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1286,7 +1286,7 @@ def kpsul_cancel_operations(request):
|
||||||
data['errors']['opes_notexisting'] = opes_notexisting
|
data['errors']['opes_notexisting'] = opes_notexisting
|
||||||
return JsonResponse(data, status=400)
|
return JsonResponse(data, status=400)
|
||||||
|
|
||||||
already_canceled = {} # Opération/Transfert déjà annulé
|
already_canceled = defaultdict(list)
|
||||||
opes = [] # Pas déjà annulée
|
opes = [] # Pas déjà annulée
|
||||||
transfers = []
|
transfers = []
|
||||||
required_perms = set()
|
required_perms = set()
|
||||||
|
|
Loading…
Reference in a new issue