Skip to content

Instantly share code, notes, and snippets.

@marvinsjsu
Created August 26, 2015 06:07
Show Gist options
  • Save marvinsjsu/42f8e614a5bec07c92e5 to your computer and use it in GitHub Desktop.
Save marvinsjsu/42f8e614a5bec07c92e5 to your computer and use it in GitHub Desktop.
({
className: 'import-csv',
FILE_TO_PROCESS: null,
FILE_CONTENTS: null,
PAYLOAD: null,
TIMEPERIOD_LEAF_INTERVAL: null,
REFRESH_PAGE: false,
COMMITTED_COUNT: 0,
RECALCULATED_COUNT: 0,
FAILED: 0,
RESULTS: null,
initialize: function(options) {
_.bindAll(this);
this._super("initialize", [options]);
this.events = _.extend({}, this.events, {
'click [name=mass-commit]': 'sendMassQuotas',
'change [type=file]' : 'validateThisFile',
'mouseenter [rel="tooltip"]': 'showTooltip',
'mouseleave [rel="tooltip"]': 'hideTooltip'
});
this.TIMEPERIOD_LEAF_INTERVAL = app.metadata.getModule('Forecasts', 'config').timeperiod_leaf_interval;
this.RESULTS = [];
app.routing.before("route", this.beforeRouteChange, this, true);
$(window).on('beforeunload.' + this.cid, _.bind(this.warnBeforeLeavingPage, this));
},
beforeRouteChange: function() {
this._targetUrl = Backbone.history.getFragment();
console.log("TEST: " + this._targetUrl);
app.router.navigate(this._currentUrl, {trigger: false, replace: true});
debugger;
var onConfirm = function(e){
console.log(e);
debugger;
};
var onCancel = function(e){
console.log(e);
debugger;
};
app.alert.show('leave_confirmation', {
level: 'confirmation',
messages: app.lang.get('LBL_WARN_UNSAVED_CHANGES', this.module),
onConfirm: onConfirm,
onCancel: onCancel
});
debugger;
},
warnBeforeLeavingPage: function() {
debugger;
},
_render: function () {
this._super("_render");
this.setExampleDisplay();
},
setExampleDisplay: function(){
var months = {
0 : "January",
1 : "February",
2 : "March",
3 : "April",
4 : "May",
5 : "June",
6 : "July",
7 : "August",
8 : "September",
9 : "October",
10 : "November",
11 : "December"
};
if (this.TIMEPERIOD_LEAF_INTERVAL == "Month") {
var example_label = "Month / Year";
var example1 = months[app.date().month()] + " " + app.date().year();
var example2 = months[app.date().month() + 1] + " " + app.date().year();
this.$el.find("th#time_leaf_label").html(example_label);
this.$el.find("td#example1_timeperiod").html(example1);
this.$el.find("td#example2_timeperiod").html(example2);
}
},
validateThisFile: function(e){
var files = e.target.files;
var file = files[0];
this.FILE_TO_PROCESS = file;
if(!this.isCSV(file)) {
app.alert.show('error_while_mass_update', {
'level' : 'error',
'messages' : 'This is not a valid CSV file. Please correct this and try again.'
});
this.$el.find("table#csv-contents tbody").empty();
this.$el.find("#csv-display").addClass("hide");
} else {
this.parseFileToDisplay(file);
}
},
parseFileToDisplay: function(file){
var reader = new FileReader();
var payload = {
quotas : []
};
var that = this;
reader.onload = function(evt){
var contents = evt.target.result;
that.FILE_CONTENTS = contents;
//trim to get rid of extra carriage returns and extra space on initial string content
//then split into rows
var rows = contents.trim().split("\r");
var count = 0;
_.each(rows, function(row){
var columns = row.split(",");
var quota = {};
_.each(columns, function(item, idx, list){
list[idx] = item.trim();
});
quota["data_id"] = count;
quota["timeperiod_name"] = columns[0];
quota["quota"] = columns[1];
quota["name"] = columns[2];
quota["user_id"] = columns[3];
quota["assigned_by_user_id"] = columns[4];
//exclude first row, this is our header
if(count > 0){
payload.quotas.push(quota);
}
count++;
});
that.PAYLOAD = payload;
that.display(payload);
}
reader.readAsText(file);
},
isCSV: function(file) {
var name = file.name;
var size = file.size;
var ext = name.substr((Math.max(0, name.lastIndexOf(".")) || Infinity) + 1);
if(ext != 'csv' || size == 0) {
return false;
}
return true;
},
display: function(payload) {
var table = this.$el.find("table#csv-contents tbody");
var summary_table = this.$el.find("div#summary-status table");
var row = "";
var csv_count = 0, csv_valid = 0, csv_invalid = 0;
var id_format = /[a-zA-Z0-9]{8}(-[a-zA-Z0-9]{4}){3}-[a-zA-Z0-9]{12}/;
var quota_format = /(?:\d*\.)?\d+/;
var timeperiod_format = /(\d{4} [q|Q][1-4])|(?:Jan(?:uary)? \d{4})|(?:Feb(?:ruary)? \d{4})|(?:Mar(?:ch)? \d{4})|(?:Apr(?:il)? \d{4})|(?:May? \d{4})|(?:Jun(?:e)? \d{4})|(?:Jul(?:y)? \d{4})|(?:Aug(?:ust)? \d{4})|(?:Sep(?:tember)? \d{4})|(?:Oct(?:ober)? \d{4})|(?:Nov(?:ember)? \d{4})|(?:Dec(?:ember)? \d{4})/;
var name_format = /([a-zàâçéèêëîïôûùüÿñæœA-Z][ ||-]*)+/;
var that = this;
var show_commit_button = true;
_.each(payload.quotas, function(quota){
var timeperiod_val = quota.timeperiod_name;
var quota_val = quota.quota;
var name_val = quota.name;
var assigned_user_id_val = quota.user_id;
var data_id = quota.data_id;
var assigned_by_user_id_val = quota.assigned_by_user_id;
var status_val = true;
if (!that.checkValid(quota_format, quota_val)) {
quota_val = "<strong class='alert-danger'>" + quota_val + "</strong>";
show_commit_button = false;
status_val = false;
}
if (!that.checkValid(timeperiod_format, timeperiod_val)) {
timeperiod_val = "<strong class='alert-danger'>" + timeperiod_val + "</strong>";
show_commit_button = false;
status_val = false;
}
if (!that.checkValid(id_format, assigned_user_id_val)) {
assigned_user_id_val = "<strong class='alert-danger'>" + assigned_user_id_val + "</strong>";
show_commit_button = false;
status_val = false;
}
if (!that.checkValid(id_format, assigned_by_user_id_val)) {
assigned_by_user_id_val = "<strong class='alert-danger'>" + assigned_by_user_id_val + "</strong>";
show_commit_button = false;
status_val = false;
}
if (!that.checkValid(name_format, name_val)) {
name_val = "<strong class='alert-danger'>" + name_val + "</strong>";
show_commit_button = false;
status_val = false;
}
(status_val) ? csv_valid++ : csv_invalid++;
csv_count++;
var status_val = status_val ? "ready" : "invalid value(s)";
row += "<tr data-id='" + data_id + "'>";
row += "<td class='timeperiod'>" + timeperiod_val + "</td>";
row += "<td class='quota'>" + quota_val + "</td>";
row += "<td class='name'>" + name_val + "</td>";
row += "<td class='assigned_user'>" + assigned_user_id_val + "</td>";
row += "<td class='assigned_by_user_id'>" + assigned_by_user_id_val + "</td>";
row += "<td class='status'>" + status_val + "</td>";
row += "</tr>";
});
table.empty().append(row);
summary_table.find("#csv-count").html("<button class='btn btn-info' rel='tooltip' data-title='Total number of entries in the CSV file'>" + csv_count + "</button>");
summary_table.find("#csv-valid").html("<button class='btn btn-success' rel='tooltip' data-title='Number of valid entries in the CSV file'>" + csv_valid + "</button>");
summary_table.find("#csv-invalid").html("<button class='btn btn-danger' rel='tooltip' data-title='Number of invalid entries in the CSV file'>" + csv_invalid + "</button>");
if(show_commit_button) {
this.$el.find("button[name=mass-commit]").removeClass("hide");
} else {
this.$el.find("button[name=mass-commit]").addClass("hide");
app.alert.show('error_while_mass_update', {
'level' : 'error',
'messages' : 'There are invalid values in the csv file (listed below in red). Please correct these and try again.'
});
}
this.$el.find("#csv-display").removeClass("hide");
},
sendMassQuotas: function(){
var that = this;
this.context.parent.trigger("forecasts:quota:assigning");
var chunkedPayload = this.chunkPayload(this.PAYLOAD);
var prevPromise = Promise.resolve();
chunkedPayload.forEach(function(payload) {
var first = payload.quotas[0].data_id;
var last = payload.quotas[payload.quotas.length - 1].data_id;
prevPromise = prevPromise.then(function(){
app.alert.show('committing-quotas', {level: 'process', title: 'assigning quotas: ' + first + " to " + last + " quotas."});
app.alert.dismiss('success_mass_commit');
return that.sendPayload(payload);
}).then(function(data) {
app.alert.dismiss('committing-quotas');
app.alert.show('success_mass_commit', {
'level' : 'success',
'messages' : 'Quotas: ' + first + ' to ' + last + ' have been assigned.'
});
that.RESULTS = that.RESULTS.concat([], JSON.parse(data.xhr.responseText));
}).catch(function(error) {
app.alert.dismiss('committing-quotas');
app.alert.show("error_assigning_quotas", {
'level' : 'error',
'messages' : error
});
}).then(function() {
app.alert.dismiss('committing-quotas');
app.alert.show('success_mass_commit', {
'level' : 'success',
'messages' : 'Quotas have been assigned.'
});
});
});
prevPromise.then(function(){
that.sendEmailConfirmation();
});
},
sendEmailConfirmation: function() {
var url = app.api.buildURL("ForecastManagerWorksheets", "sendEmailConfirmation");
var method = "create";
var callbacks = {
success: function(data, response) {
app.alert.show("success_email_notification", {
'level' : 'success',
'messages' : "Email confirmation sent."
});
},
error: function(xhr, status, error) {
app.alert.dismiss('committing-quotas');
app.alert.show("error_email_notification", {
'level' : 'error',
'messages' : "Status: " + xhr.status + ": " + xhr.errorThrown
});
}
};
var payload = {
"results" : this.RESULTS
};
app.api.call(method, url, payload, callbacks);
},
sendPayload: function(payload) {
var that = this;
return new Promise(function(resolve, reject) {
var url = app.api.buildURL("ForecastManagerWorksheets", "uploadQuotas");
var method = "create";
var callbacks = {
success: function(data, response) {
_.each(data, function(result){
that.updateDisplay(result);
if(result.status == "failed") {
that.FAILED++;//failed++;
} else {
(result.recalculated) ? that.RECALCULATED_COUNT++ : that.COMMITTED_COUNT++;//recalculated_count++ : committed_count++;
}
});
that.$el.find(".validation-result").addClass("hide");
that.$el.find("button[name=mass-commit]").addClass("hide");
$("#committed-count").html("<button class='btn btn-success' rel='tooltip' data-title='Number of committed quotas'>" + that.COMMITTED_COUNT + "</button>");
$("#recalculated-count").html("<button class='btn btn-warning' rel='tooltip' data-title='Number of recalculated quotas'>" + that.RECALCULATED_COUNT + "</button>");
$("#failed").html("<button class='btn btn-danger' rel='tooltip' data-title='Number of failed commits'>" + that.FAILED + "</button>");
that.REFRESH_PAGE = true;
resolve(response);
},
error: function(xhr, status, error) {
app.alert.dismiss('committing-quotas');
app.alert.show("error_mass_commit", {
'level' : 'error',
'messages' : "Status: " + xhr.status + ": " + xhr.errorThrown
});
reject(status);
}
};
app.api.call(method, url, payload, callbacks);
});
},
chunkPayload: function(payload) {
var i, j, chunkedQuotas = [], chunk = 50;
for(i = 0, j = chunk; i < payload.quotas.length; i = j, j += chunk) {
var c = [];
if (i + chunk > payload.quotas.length) {
c = payload.quotas.slice(i, payload.quotas.length);
} else {
c = payload.quotas.slice(i, j);
}
var test = {
"quotas" : c
}
chunkedQuotas.push(test);
}
return chunkedQuotas;
},
updateDisplay: function(result){
var data_id = result.data_id;
var name = result.name;
var csv_quota = result.csv_quota;
var recalculated = result.recalculated;
var worksheet_quota = (parseFloat(result.worksheet_quota)).toFixed(2);
var timeperiod = result.timeperiod;
var status = result.status;
var message = result.message;
var status_display = "";
if(status == "failed") {
status_display = "<button class='btn btn-danger' rel='tooltip' data-title='" + message + "'>failed</button>";
} else {
status_display = (recalculated) ? "<button class='btn btn-warning' rel='tooltip' data-title='quota was recalculated, diff = " + (worksheet_quota - csv_quota) +" '>" + worksheet_quota + "</button>" : "committed";
}
this.$el.find('tr[data-id="' + data_id + '"] .status').html(status_display);
},
checkValid: function(expr, val) {
if(typeof val == 'undefined' || val == '') {
return false;
}
var match = val.match(expr);
return match != null && val == match[0];
},
_dispose: function() {
app.drawer.off();
this._super('_dispose');
if(this.REFRESH_PAGE) {
app.utils.hardRefresh();
}
},
showTooltip: function(e) {
this.$(e.currentTarget).tooltip("show");
},
hideTooltip: function(e) {
this.$(e.currentTarget).tooltip("hide");
},
unbindDom: function() {
// Unbind all tooltips on page
var unbindTooltips = _.bind(function(sel) {
this.$(sel).each(function() {
$(this).tooltip('destroy');
});
}, this);
unbindTooltips('[rel="tooltip"]');
app.view.Field.prototype.unbindDom.call(this);
}
})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment