diff --git a/addons/hr/static/src/js/hr.js b/addons/hr/static/src/js/hr.js
index 90e37bd35b8..80b978e7fc9 100644
--- a/addons/hr/static/src/js/hr.js
+++ b/addons/hr/static/src/js/hr.js
@@ -1,14 +1,18 @@
-openerp.hr = function(openerp) {
- "use strict";
+odoo.define('hr.hr', ['web_kanban.common'], function(require) {
+"use strict";
- openerp.web_kanban.KanbanRecord.include({
- on_card_clicked: function() {
- if (this.view.dataset.model === 'hr.department') {
- this.$('.oe_kanban_department .oe_kanban_content a').first().click();
- } else {
- this._super.apply(this, arguments);
- }
- },
- });
+var common = require('web_kanban.common');
+
+common.KanbanRecord.include({
+ on_card_clicked: function() {
+ if (this.view.dataset.model === 'hr.department') {
+ this.$('.oe_kanban_department .oe_kanban_content a').first().click();
+ } else {
+ this._super.apply(this, arguments);
+ }
+ },
+});
+
+
+});
-};
diff --git a/addons/hr/static/src/js/suggestions.js b/addons/hr/static/src/js/suggestions.js
index 3bc37e71344..94df0a4ad7b 100644
--- a/addons/hr/static/src/js/suggestions.js
+++ b/addons/hr/static/src/js/suggestions.js
@@ -1,78 +1,83 @@
-openerp.hr = function(session) {
- var _t = session.web._t;
- var QWeb = session.web.qweb;
+odoo.define('hr.suggestions', ['mail.mail', 'web.core', 'web.data', 'web.Widget'], function (require) {
+"use strict";
- var suggestions = session.suggestions;
- var removed_suggested_employee = session.suggestions.removed_suggested_employee = [];
+var mail = require('mail.mail');
+var core = require('web.core');
+var data = require('web.data');
+var Widget = require('web.Widget');
- suggestions.Employees = session.web.Widget.extend({
- events: {
- 'click .oe_suggestion_remove.oe_suggestion_employee': 'stop_employee_suggestion',
- 'click .oe_suggestion_remove_item.oe_suggestion_employee': 'remove_employee_suggestion',
- 'click .oe_suggestion_follow': 'follow_employee',
- },
+var QWeb = core.qweb;
- init: function () {
- this._super(this, arguments);
- this.hr_employee = new session.web.DataSetSearch(this, 'hr.employee');
- this.res_users = new session.web.DataSetSearch(this, 'res.users');
- this.employees = [];
- },
+var removed_suggested_employee = [];
- start: function () {
- this._super.apply(this, arguments);
- return this.fetch_suggested_employee();
- },
+var Employees = Widget.extend({
+ events: {
+ 'click .oe_suggestion_remove.oe_suggestion_employee': 'stop_employee_suggestion',
+ 'click .oe_suggestion_remove_item.oe_suggestion_employee': 'remove_employee_suggestion',
+ 'click .oe_suggestion_follow': 'follow_employee',
+ },
- fetch_suggested_employee: function () {
- var self = this;
- var employee = self.hr_employee.call('get_suggested_thread', {'removed_suggested_threads': removed_suggested_employee}).then(function (res) {
- _(res).each(function (result) {
- result['image']=self.session.url('/web/binary/image', {model: 'hr.employee', field: 'image_small', id: result.id});
- });
- self.employees = res;
+ init: function () {
+ this._super(this, arguments);
+ this.hr_employee = new data.DataSetSearch(this, 'hr.employee');
+ this.res_users = new data.DataSetSearch(this, 'res.users');
+ this.employees = [];
+ },
+
+ start: function () {
+ this._super.apply(this, arguments);
+ return this.fetch_suggested_employee();
+ },
+
+ fetch_suggested_employee: function () {
+ var self = this;
+ var employee = self.hr_employee.call('get_suggested_thread', {'removed_suggested_threads': removed_suggested_employee}).then(function (res) {
+ _(res).each(function (result) {
+ result['image']=self.session.url('/web/binary/image', {model: 'hr.employee', field: 'image_small', id: result.id});
});
- return $.when(employee).done(this.proxy('display_suggested_employees'));
- },
+ self.employees = res;
+ });
+ return $.when(employee).done(this.proxy('display_suggested_employees'));
+ },
- display_suggested_employees: function () {
- var suggested_employees = this.$('.oe_sidebar_suggestion.oe_suggestion_employee');
- if (suggested_employees) {
- suggested_employees.remove();
- }
- if (this.employees.length === 0) {
- return this.$el.empty();
- }
- return this.$el.empty().html(QWeb.render('hr.suggestions.employees', {'widget': this}));
- },
-
- follow_employee: function (event) {
- var self = this;
- var employee_id = parseInt($(event.currentTarget).attr('id'), 10);
- return this.hr_employee.call('message_subscribe_users', [[employee_id], [this.session.uid], undefined]).then(function(res) {
- self.fetch_suggested_employee();
- });
- },
-
- remove_employee_suggestion: function (event) {
- removed_suggested_employee.push($(event.currentTarget).attr('id'));
- return this.fetch_suggested_employee();
- },
-
- stop_employee_suggestion: function (event) {
- var self = this;
- return this.res_users.call('stop_showing_employees_suggestions', [this.session.uid]).then(function(res) {
- self.$(".oe_sidebar_suggestion.oe_suggestion_employee").hide();
- });
+ display_suggested_employees: function () {
+ var suggested_employees = this.$('.oe_sidebar_suggestion.oe_suggestion_employee');
+ if (suggested_employees) {
+ suggested_employees.remove();
}
- });
+ if (this.employees.length === 0) {
+ return this.$el.empty();
+ }
+ return this.$el.empty().html(QWeb.render('hr.suggestions.employees', {'widget': this}));
+ },
- session.mail.WallSidebar.include({
- start: function () {
- this._super.apply(this, arguments);
- var sug_employees = new suggestions.Employees(this);
- return sug_employees.appendTo(this.$('.oe_suggestions_employees'));
- },
- });
+ follow_employee: function (event) {
+ var self = this;
+ var employee_id = parseInt($(event.currentTarget).attr('id'), 10);
+ return this.hr_employee.call('message_subscribe_users', [[employee_id], [this.session.uid], undefined]).then(function(res) {
+ self.fetch_suggested_employee();
+ });
+ },
-};
+ remove_employee_suggestion: function (event) {
+ removed_suggested_employee.push($(event.currentTarget).attr('id'));
+ return this.fetch_suggested_employee();
+ },
+
+ stop_employee_suggestion: function (event) {
+ var self = this;
+ return this.res_users.call('stop_showing_employees_suggestions', [this.session.uid]).then(function(res) {
+ self.$(".oe_sidebar_suggestion.oe_suggestion_employee").hide();
+ });
+ }
+});
+
+mail.WallSidebar.include({
+ start: function () {
+ this._super.apply(this, arguments);
+ var sug_employees = new Employees(this);
+ return sug_employees.appendTo(this.$('.oe_suggestions_employees'));
+ },
+});
+
+});
diff --git a/addons/hr_attendance/static/src/js/attendance.js b/addons/hr_attendance/static/src/js/attendance.js
index 3ec2ca4709f..783728b7d79 100644
--- a/addons/hr_attendance/static/src/js/attendance.js
+++ b/addons/hr_attendance/static/src/js/attendance.js
@@ -1,79 +1,86 @@
+odoo.define('hr_attendance.hr_attendance', ['web.core', 'web.data', 'web.formats', 'web.Model', 'web.SystrayMenu', 'web.time', 'web.Widget'], function(require) {
+"use strict";
-openerp.hr_attendance = function (instance) {
-
- var QWeb = instance.web.qweb;
- var _t = instance.web._t;
- var _lt = instance.web._lt;
+var core = require('web.core');
+var data = require('web.data');
+var formats = require('web.formats');
+var Model = require('web.Model');
+var SystrayMenu = require('web.SystrayMenu');
+var time = require('web.time');
+var Widget = require('web.Widget');
- instance.hr_attendance.AttendanceSlider = instance.web.Widget.extend({
- template: 'AttendanceSlider',
- init: function (parent) {
- this._super(parent);
- this.set({"signed_in": false});
- },
- start: function() {
- var self = this;
- var tmp = function() {
- var $sign_in_out_icon = this.$('#oe_attendance_sign_in_out_icon');
- $sign_in_out_icon.toggleClass("fa-sign-in", ! this.get("signed_in"));
- $sign_in_out_icon.toggleClass("fa-sign-out", this.get("signed_in"));
- };
- this.on("change:signed_in", this, tmp);
- _.bind(tmp, this)();
- this.$(".oe_attendance_sign_in_out").click(function(ev) {
- ev.preventDefault();
- self.do_update_attendance();
- });
- this.$el.tooltip({
- title: function() {
- var last_text = instance.web.format_value(self.last_sign, {type: "datetime"});
- var current_text = instance.web.format_value(new Date(), {type: "datetime"});
- var duration = self.last_sign ? $.timeago(self.last_sign) : "none";
- if (self.get("signed_in")) {
- return _.str.sprintf(_t("Last sign in: %s,
%s.
Click to sign out."), last_text, duration);
- } else {
- return _.str.sprintf(_t("Click to Sign In at %s."), current_text);
- }
- },
- });
- return this.check_attendance();
- },
- do_update_attendance: function () {
- var self = this;
- var hr_employee = new instance.web.DataSet(self, 'hr.employee');
- hr_employee.call('attendance_action_change', [
- [self.employee.id]
- ]).done(function (result) {
- self.last_sign = new Date();
- self.set({"signed_in": ! self.get("signed_in")});
- });
- },
- check_attendance: function () {
- var self = this;
- self.employee = false;
- this.$el.hide();
- var employee = new instance.web.DataSetSearch(self, 'hr.employee', self.session.user_context, [
- ['user_id', '=', self.session.uid]
- ]);
- return employee.read_slice(['id', 'name', 'state', 'last_sign', 'attendance_access']).then(function (res) {
- if (_.isEmpty(res) )
- return;
- if (res[0].attendance_access === false){
- return;
+var _t = core._t;
+
+var AttendanceSlider = Widget.extend({
+ template: 'AttendanceSlider',
+ init: function (parent) {
+ this._super(parent);
+ this.set({"signed_in": false});
+ },
+ start: function() {
+ var self = this;
+ var tmp = function() {
+ var $sign_in_out_icon = this.$('#oe_attendance_sign_in_out_icon');
+ $sign_in_out_icon.toggleClass("fa-sign-in", ! this.get("signed_in"));
+ $sign_in_out_icon.toggleClass("fa-sign-out", this.get("signed_in"));
+ };
+ this.on("change:signed_in", this, tmp);
+ _.bind(tmp, this)();
+ this.$(".oe_attendance_sign_in_out").click(function(ev) {
+ ev.preventDefault();
+ self.do_update_attendance();
+ });
+ this.$el.tooltip({
+ title: function() {
+ var last_text = formats.format_value(self.last_sign, {type: "datetime"});
+ var current_text = formats.format_value(new Date(), {type: "datetime"});
+ var duration = self.last_sign ? $.timeago(self.last_sign) : "none";
+ if (self.get("signed_in")) {
+ return _.str.sprintf(_t("Last sign in: %s,
%s.
Click to sign out."), last_text, duration);
+ } else {
+ return _.str.sprintf(_t("Click to Sign In at %s."), current_text);
}
- self.$el.show();
- self.employee = res[0];
- self.last_sign = instance.web.str_to_datetime(self.employee.last_sign);
- self.set({"signed_in": self.employee.state !== "absent"});
- });
- },
- });
+ },
+ });
+ return this.check_attendance();
+ },
+ do_update_attendance: function () {
+ var self = this;
+ var hr_employee = new data.DataSet(self, 'hr.employee');
+ hr_employee.call('attendance_action_change', [
+ [self.employee.id]
+ ]).done(function (result) {
+ self.last_sign = new Date();
+ self.set({"signed_in": ! self.get("signed_in")});
+ });
+ },
+ check_attendance: function () {
+ var self = this;
+ self.employee = false;
+ this.$el.hide();
+ var employee = new data.DataSetSearch(self, 'hr.employee', self.session.user_context, [
+ ['user_id', '=', self.session.uid]
+ ]);
+ return employee.read_slice(['id', 'name', 'state', 'last_sign', 'attendance_access']).then(function (res) {
+ if (_.isEmpty(res) )
+ return;
+ if (res[0].attendance_access === false){
+ return;
+ }
+ self.$el.show();
+ self.employee = res[0];
+ self.last_sign = time.str_to_datetime(self.employee.last_sign);
+ self.set({"signed_in": self.employee.state !== "absent"});
+ });
+ },
+});
- // Put the AttendanceSlider widget in the systray menu if the user is an employee
- var Users = new instance.web.Model('res.users');
- Users.call('has_group', ['base.group_user']).done(function(is_employee) {
- if (is_employee) {
- instance.web.SystrayItems.push(instance.hr_attendance.AttendanceSlider);
- }
- })
-};
+// Put the AttendanceSlider widget in the systray menu if the user is an employee
+var Users = new Model('res.users');
+Users.call('has_group', ['base.group_user']).done(function(is_employee) {
+ if (is_employee) {
+ SystrayMenu.Items.push(AttendanceSlider);
+ }
+});
+
+});
diff --git a/addons/hr_gamification/static/src/js/gamification.js b/addons/hr_gamification/static/src/js/gamification.js
index a9126464a10..ad065ecfa23 100644
--- a/addons/hr_gamification/static/src/js/gamification.js
+++ b/addons/hr_gamification/static/src/js/gamification.js
@@ -1,19 +1,24 @@
-openerp.hr_gamification = function(instance) {
- instance.web_kanban.KanbanRecord.include({
- on_card_clicked: function() {
- if (this.view.dataset.model === 'gamification.badge.user') {
- var action = {
- type: 'ir.actions.act_window',
- res_model: 'gamification.badge',
- view_mode: 'form',
- view_type: 'form,kanban,tree',
- views: [[false, 'form']],
- res_id: this.record.badge_id.raw_value[0]
- };
- this.do_action(action);
- } else {
- this._super.apply(this, arguments);
- }
+odoo.define('hr_gamification.hr_gamification', ['web_kanban.common'], function(require) {
+"use strict";
+
+var common = require('web_kanban.common');
+
+common.KanbanRecord.include({
+ on_card_clicked: function() {
+ if (this.view.dataset.model === 'gamification.badge.user') {
+ var action = {
+ type: 'ir.actions.act_window',
+ res_model: 'gamification.badge',
+ view_mode: 'form',
+ view_type: 'form,kanban,tree',
+ views: [[false, 'form']],
+ res_id: this.record.badge_id.raw_value[0]
+ };
+ this.do_action(action);
+ } else {
+ this._super.apply(this, arguments);
}
- });
-};
+ }
+});
+
+});
diff --git a/addons/hr_recruitment/static/src/js/job_position.js b/addons/hr_recruitment/static/src/js/job_position.js
index 43150117115..55361fdef2a 100644
--- a/addons/hr_recruitment/static/src/js/job_position.js
+++ b/addons/hr_recruitment/static/src/js/job_position.js
@@ -1,14 +1,16 @@
-openerp.hr_recruitment = function (openerp) {
- "use strict";
+odoo.define('hr_recruitment.hr_recruitment', ['web_kanban.common'], function(require) {
+"use strict";
- openerp.web_kanban.KanbanRecord.include({
- on_card_clicked: function() {
- if (this.view.dataset.model === 'hr.job') {
- this.$('.oe_applications a').first().click();
- } else {
- this._super.apply(this, arguments);
- }
- },
- });
+var common = require('web_kanban.common');
-};
+common.KanbanRecord.include({
+ on_card_clicked: function() {
+ if (this.view.dataset.model === 'hr.job') {
+ this.$('.oe_applications a').first().click();
+ } else {
+ this._super.apply(this, arguments);
+ }
+ },
+});
+
+});
diff --git a/addons/hr_timesheet_sheet/static/src/js/timesheet.js b/addons/hr_timesheet_sheet/static/src/js/timesheet.js
index 400e4c2214a..ef3eb5c4f0a 100644
--- a/addons/hr_timesheet_sheet/static/src/js/timesheet.js
+++ b/addons/hr_timesheet_sheet/static/src/js/timesheet.js
@@ -1,357 +1,368 @@
+odoo.define('hr_timesheet_sheet.sheet', ['web.core', 'web.data', 'web.form_common', 'web.formats', 'web.Model', 'web.time', 'web.utils'], function (require) {
+"use strict";
-openerp.hr_timesheet_sheet = function(instance) {
- var QWeb = instance.web.qweb;
- var _t = instance.web._t;
+var core = require('web.core');
+var data = require('web.data');
+var form_common = require('web.form_common');
+var formats = require('web.formats');
+var Model = require('web.Model');
+var time = require('web.time');
+var utils = require('web.utils');
- instance.hr_timesheet_sheet.WeeklyTimesheet = instance.web.form.FormWidget.extend(instance.web.form.ReinitializeWidgetMixin, {
- events: {
- "click .oe_timesheet_weekly_account a": "go_to",
- },
- ignore_fields: function() {
- return ['line_id'];
- },
- init: function() {
- this._super.apply(this, arguments);
- var self = this;
- this.set({
- sheets: [],
- date_to: false,
- date_from: false,
- });
- this.updating = false;
- this.defs = [];
- this.field_manager.on("field_changed:timesheet_ids", this, this.query_sheets);
- this.field_manager.on("field_changed:date_from", this, function() {
- this.set({"date_from": instance.web.str_to_date(this.field_manager.get_field_value("date_from"))});
- });
- this.field_manager.on("field_changed:date_to", this, function() {
- this.set({"date_to": instance.web.str_to_date(this.field_manager.get_field_value("date_to"))});
- });
- this.field_manager.on("field_changed:user_id", this, function() {
- this.set({"user_id": this.field_manager.get_field_value("user_id")});
- });
- this.on("change:sheets", this, this.update_sheets);
- this.res_o2m_drop = new instance.web.DropMisordered();
- this.render_drop = new instance.web.DropMisordered();
- this.description_line = _t("/");
- // Original save function is overwritten in order to wait all running deferreds to be done before actually applying the save.
- this.view.original_save = _.bind(this.view.save, this.view);
- this.view.save = function(prepend_on_create){
- self.prepend_on_create = prepend_on_create;
- return $.when.apply($, self.defs).then(function(){
- return self.view.original_save(self.prepend_on_create);
- });
- };
- },
- go_to: function(event) {
- var id = JSON.parse($(event.target).data("id"));
- this.do_action({
- type: 'ir.actions.act_window',
- res_model: "account.analytic.account",
- res_id: id,
- views: [[false, 'form']],
- target: 'current'
- });
- },
- query_sheets: function() {
- var self = this;
- if (self.updating)
- return;
- var commands = this.field_manager.get_field_value("timesheet_ids");
- this.res_o2m_drop.add(new instance.web.Model(this.view.model).call("resolve_2many_commands", ["timesheet_ids", commands, [],
- new instance.web.CompoundContext()]))
- .done(function(result) {
- self.querying = true;
- self.set({sheets: result});
- self.querying = false;
- });
- },
- update_sheets: function() {
- var self = this;
- if (self.querying)
- return;
- self.updating = true;
- self.field_manager.set_values({timesheet_ids: self.get("sheets")}).done(function() {
- self.updating = false;
- });
- },
- initialize_field: function() {
- instance.web.form.ReinitializeWidgetMixin.initialize_field.call(this);
- var self = this;
- self.on("change:sheets", self, self.initialize_content);
- self.on("change:date_to", self, self.initialize_content);
- self.on("change:date_from", self, self.initialize_content);
- self.on("change:user_id", self, self.initialize_content);
- },
- initialize_content: function() {
- var self = this;
- if (self.setting)
- return;
- // don't render anything until we have date_to and date_from
- if (!self.get("date_to") || !self.get("date_from"))
- return;
- this.destroy_content();
+var QWeb = core.qweb;
+var _t = core._t;
- // it's important to use those vars to avoid race conditions
- var dates;
- var accounts;
- var account_names;
- var default_get;
- return this.render_drop.add(new instance.web.Model("hr.analytic.timesheet").call("default_get", [
- ['account_id','general_account_id', 'journal_id','date','name','user_id','product_id','product_uom_id','to_invoice','amount','unit_amount'],
- new instance.web.CompoundContext({'user_id': self.get('user_id')})]).then(function(result) {
- default_get = result;
- // calculating dates
- dates = [];
- var start = self.get("date_from");
- var end = self.get("date_to");
- while (start <= end) {
- dates.push(start);
- var m_start = moment(start).add(1,'days');
- start = m_start.toDate();
- }
- // group by account
- accounts = _(self.get("sheets")).chain()
- .map(function(el) {
- // much simpler to use only the id in all cases
- if (typeof(el.account_id) === "object")
- el.account_id = el.account_id[0];
- return el;
- })
- .groupBy("account_id").value();
- var account_ids = _.map(_.keys(accounts), function(el) { return el === "false" ? false : Number(el) });
-
- return new instance.web.Model("hr.analytic.timesheet").call("multi_on_change_account_id", [[], account_ids,
- new instance.web.CompoundContext({'user_id': self.get('user_id')})]).then(function(accounts_defaults) {
- accounts = _(accounts).chain().map(function(lines, account_id) {
- account_defaults = _.extend({}, default_get, (accounts_defaults[account_id] || {}).value || {});
- // group by days
- account_id = account_id === "false" ? false : Number(account_id);
- var index = _.groupBy(lines, "date");
- var days = _.map(dates, function(date) {
- var day = {day: date, lines: index[instance.web.date_to_str(date)] || []};
- // add line where we will insert/remove hours
- var to_add = _.find(day.lines, function(line) { return line.name === self.description_line });
- if (to_add) {
- day.lines = _.without(day.lines, to_add);
- day.lines.unshift(to_add);
- } else {
- day.lines.unshift(_.extend(_.clone(account_defaults), {
- name: self.description_line,
- unit_amount: 0,
- date: instance.web.date_to_str(date),
- account_id: account_id,
- }));
- }
- return day;
- });
- return {account: account_id, days: days, account_defaults: account_defaults};
- }).value();
-
- // we need the name_get of the analytic accounts
- return new instance.web.Model("account.analytic.account").call("name_get", [_.pluck(accounts, "account"),
- new instance.web.CompoundContext()]).then(function(result) {
- account_names = {};
- _.each(result, function(el) {
- account_names[el[0]] = el[1];
- });
- accounts = _.sortBy(accounts, function(el) {
- return account_names[el.account];
- });
- });;
- });
- })).then(function(result) {
- // we put all the gathered data in self, then we render
- self.dates = dates;
- self.accounts = accounts;
- self.account_names = account_names;
- self.default_get = default_get;
- //real rendering
- self.display_data();
+var WeeklyTimesheet = form_common.FormWidget.extend(form_common.ReinitializeWidgetMixin, {
+ events: {
+ "click .oe_timesheet_weekly_account a": "go_to",
+ },
+ ignore_fields: function() {
+ return ['line_id'];
+ },
+ init: function() {
+ this._super.apply(this, arguments);
+ var self = this;
+ this.set({
+ sheets: [],
+ date_to: false,
+ date_from: false,
+ });
+ this.updating = false;
+ this.defs = [];
+ this.field_manager.on("field_changed:timesheet_ids", this, this.query_sheets);
+ this.field_manager.on("field_changed:date_from", this, function() {
+ this.set({"date_from": time.str_to_date(this.field_manager.get_field_value("date_from"))});
+ });
+ this.field_manager.on("field_changed:date_to", this, function() {
+ this.set({"date_to": time.str_to_date(this.field_manager.get_field_value("date_to"))});
+ });
+ this.field_manager.on("field_changed:user_id", this, function() {
+ this.set({"user_id": this.field_manager.get_field_value("user_id")});
+ });
+ this.on("change:sheets", this, this.update_sheets);
+ this.res_o2m_drop = new utils.DropMisordered();
+ this.render_drop = new utils.DropMisordered();
+ this.description_line = _t("/");
+ // Original save function is overwritten in order to wait all running deferreds to be done before actually applying the save.
+ this.view.original_save = _.bind(this.view.save, this.view);
+ this.view.save = function(prepend_on_create){
+ self.prepend_on_create = prepend_on_create;
+ return $.when.apply($, self.defs).then(function(){
+ return self.view.original_save(self.prepend_on_create);
});
- },
- destroy_content: function() {
- if (this.dfm) {
- this.dfm.destroy();
- this.dfm = undefined;
+ };
+ },
+ go_to: function(event) {
+ var id = JSON.parse($(event.target).data("id"));
+ this.do_action({
+ type: 'ir.actions.act_window',
+ res_model: "account.analytic.account",
+ res_id: id,
+ views: [[false, 'form']],
+ target: 'current'
+ });
+ },
+ query_sheets: function() {
+ var self = this;
+ if (self.updating)
+ return;
+ var commands = this.field_manager.get_field_value("timesheet_ids");
+ this.res_o2m_drop.add(new Model(this.view.model).call("resolve_2many_commands", ["timesheet_ids", commands, [],
+ new data.CompoundContext()]))
+ .done(function(result) {
+ self.querying = true;
+ self.set({sheets: result});
+ self.querying = false;
+ });
+ },
+ update_sheets: function() {
+ var self = this;
+ if (self.querying)
+ return;
+ self.updating = true;
+ self.field_manager.set_values({timesheet_ids: self.get("sheets")}).done(function() {
+ self.updating = false;
+ });
+ },
+ initialize_field: function() {
+ form_common.ReinitializeWidgetMixin.initialize_field.call(this);
+ var self = this;
+ self.on("change:sheets", self, self.initialize_content);
+ self.on("change:date_to", self, self.initialize_content);
+ self.on("change:date_from", self, self.initialize_content);
+ self.on("change:user_id", self, self.initialize_content);
+ },
+ initialize_content: function() {
+ var self = this;
+ if (self.setting)
+ return;
+ // don't render anything until we have date_to and date_from
+ if (!self.get("date_to") || !self.get("date_from"))
+ return;
+ this.destroy_content();
+
+ // it's important to use those vars to avoid race conditions
+ var dates;
+ var accounts;
+ var account_names;
+ var default_get;
+ return this.render_drop.add(new Model("hr.analytic.timesheet").call("default_get", [
+ ['account_id','general_account_id', 'journal_id','date','name','user_id','product_id','product_uom_id','to_invoice','amount','unit_amount'],
+ new data.CompoundContext({'user_id': self.get('user_id')})]).then(function(result) {
+ default_get = result;
+ // calculating dates
+ dates = [];
+ var start = self.get("date_from");
+ var end = self.get("date_to");
+ while (start <= end) {
+ dates.push(start);
+ var m_start = moment(start).add(1,'days');
+ start = m_start.toDate();
}
- },
- is_valid_value:function(value){
- var split_value = value.split(":");
- var valid_value = true;
- if (split_value.length > 2)
- return false;
- _.detect(split_value,function(num){
- if(isNaN(num)){
- valid_value = false;
+ // group by account
+ accounts = _(self.get("sheets")).chain()
+ .map(function(el) {
+ // much simpler to use only the id in all cases
+ if (typeof(el.account_id) === "object")
+ el.account_id = el.account_id[0];
+ return el;
+ })
+ .groupBy("account_id").value();
+
+ var account_ids = _.map(_.keys(accounts), function(el) { return el === "false" ? false : Number(el); });
+
+ return new Model("hr.analytic.timesheet").call("multi_on_change_account_id", [[], account_ids,
+ new data.CompoundContext({'user_id': self.get('user_id')})]).then(function(accounts_defaults) {
+ accounts = _(accounts).chain().map(function(lines, account_id) {
+ var account_defaults = _.extend({}, default_get, (accounts_defaults[account_id] || {}).value || {});
+ // group by days
+ account_id = account_id === "false" ? false : Number(account_id);
+ var index = _.groupBy(lines, "date");
+ var days = _.map(dates, function(date) {
+ var day = {day: date, lines: index[time.date_to_str(date)] || []};
+ // add line where we will insert/remove hours
+ var to_add = _.find(day.lines, function(line) { return line.name === self.description_line; });
+ if (to_add) {
+ day.lines = _.without(day.lines, to_add);
+ day.lines.unshift(to_add);
+ } else {
+ day.lines.unshift(_.extend(_.clone(account_defaults), {
+ name: self.description_line,
+ unit_amount: 0,
+ date: time.date_to_str(date),
+ account_id: account_id,
+ }));
+ }
+ return day;
+ });
+ return {account: account_id, days: days, account_defaults: account_defaults};
+ }).value();
+
+ // we need the name_get of the analytic accounts
+ return new Model("account.analytic.account").call("name_get", [_.pluck(accounts, "account"),
+ new data.CompoundContext()]).then(function(result) {
+ account_names = {};
+ _.each(result, function(el) {
+ account_names[el[0]] = el[1];
+ });
+ accounts = _.sortBy(accounts, function(el) {
+ return account_names[el.account];
+ });
+ });
+ });
+ })).then(function(result) {
+ // we put all the gathered data in self, then we render
+ self.dates = dates;
+ self.accounts = accounts;
+ self.account_names = account_names;
+ self.default_get = default_get;
+ //real rendering
+ self.display_data();
+ });
+ },
+ destroy_content: function() {
+ if (this.dfm) {
+ this.dfm.destroy();
+ this.dfm = undefined;
+ }
+ },
+ is_valid_value:function(value){
+ var split_value = value.split(":");
+ var valid_value = true;
+ if (split_value.length > 2)
+ return false;
+ _.detect(split_value,function(num){
+ if(isNaN(num)){
+ valid_value = false;
+ }
+ });
+ return valid_value;
+ },
+ display_data: function() {
+ var self = this;
+ self.$el.html(QWeb.render("hr_timesheet_sheet.WeeklyTimesheet", {widget: self}));
+ _.each(self.accounts, function(account) {
+ _.each(_.range(account.days.length), function(day_count) {
+ if (!self.get('effective_readonly')) {
+ self.get_box(account, day_count).val(self.sum_box(account, day_count, true)).change(function() {
+ var num = $(this).val();
+ if (self.is_valid_value(num)){
+ num = (num === 0)?0:Number(self.parse_client(num));
+ }
+ if (isNaN(num)) {
+ $(this).val(self.sum_box(account, day_count, true));
+ } else {
+ account.days[day_count].lines[0].unit_amount += num - self.sum_box(account, day_count);
+ var product = (account.days[day_count].lines[0].product_id instanceof Array) ? account.days[day_count].lines[0].product_id[0] : account.days[day_count].lines[0].product_id;
+ var journal = (account.days[day_count].lines[0].journal_id instanceof Array) ? account.days[day_count].lines[0].journal_id[0] : account.days[day_count].lines[0].journal_id;
+ self.defs.push(new Model("hr.analytic.timesheet").call("on_change_unit_amount", [[], product, account.days[day_count].lines[0].unit_amount, false, false, journal]).then(function(res) {
+ account.days[day_count].lines[0]['amount'] = res.value.amount || 0;
+ self.display_totals();
+ self.sync();
+ }));
+ if(!isNaN($(this).val())){
+ $(this).val(self.sum_box(account, day_count, true));
+ }
+ }
+ });
+ } else {
+ self.get_box(account, day_count).html(self.sum_box(account, day_count, true));
}
});
- return valid_value;
- },
- display_data: function() {
- var self = this;
- self.$el.html(QWeb.render("hr_timesheet_sheet.WeeklyTimesheet", {widget: self}));
- _.each(self.accounts, function(account) {
- _.each(_.range(account.days.length), function(day_count) {
- if (!self.get('effective_readonly')) {
- self.get_box(account, day_count).val(self.sum_box(account, day_count, true)).change(function() {
- var num = $(this).val();
- if (self.is_valid_value(num)){
- num = (num == 0)?0:Number(self.parse_client(num));
- }
- if (isNaN(num)) {
- $(this).val(self.sum_box(account, day_count, true));
- } else {
- account.days[day_count].lines[0].unit_amount += num - self.sum_box(account, day_count);
- var product = (account.days[day_count].lines[0].product_id instanceof Array) ? account.days[day_count].lines[0].product_id[0] : account.days[day_count].lines[0].product_id
- var journal = (account.days[day_count].lines[0].journal_id instanceof Array) ? account.days[day_count].lines[0].journal_id[0] : account.days[day_count].lines[0].journal_id
- self.defs.push(new instance.web.Model("hr.analytic.timesheet").call("on_change_unit_amount", [[], product, account.days[day_count].lines[0].unit_amount, false, false, journal]).then(function(res) {
- account.days[day_count].lines[0]['amount'] = res.value.amount || 0;
- self.display_totals();
- self.sync();
- }));
- if(!isNaN($(this).val())){
- $(this).val(self.sum_box(account, day_count, true));
- }
+ });
+ self.display_totals();
+ self.$(".oe_timesheet_weekly_adding button").click(_.bind(this.init_add_account, this));
+ },
+ init_add_account: function() {
+ var self = this;
+ if (self.dfm)
+ return;
+ self.$(".oe_timesheet_weekly_add_row").show();
+ self.dfm = new form_common.DefaultFieldManager(self);
+ self.dfm.extend_field_desc({
+ account: {
+ relation: "account.analytic.account",
+ },
+ });
+ var FieldMany2One = core.form_widget_registry.get('many2one');
+ self.account_m2o = new FieldMany2One(self.dfm, {
+ attrs: {
+ name: "account",
+ type: "many2one",
+ domain: [
+ ['type','in',['normal', 'contract']],
+ ['state', '<>', 'close'],
+ ['invoice_on_timesheets','=',1],
+ ['id', 'not in', _.pluck(self.accounts, "account")],
+ ],
+ context: {
+ default_invoice_on_timesheets: 1,
+ default_type: "contract",
+ },
+ modifiers: '{"required": true}',
+ },
+ });
+ self.account_m2o.prependTo(self.$(".oe_timesheet_weekly_add_row td"));
+ self.$(".oe_timesheet_weekly_add_row button").click(function() {
+ var id = self.account_m2o.get_value();
+ if (id === false) {
+ self.dfm.set({display_invalid_fields: true});
+ return;
+ }
+ var ops = self.generate_o2m_value();
+ new Model("hr.analytic.timesheet").call("multi_on_change_account_id", [[], [id],
+ new data.CompoundContext({'user_id': self.get('user_id')})]).then(function(res) {
+ res = res[id];
+ var def = _.extend({}, self.default_get, res.value, {
+ name: self.description_line,
+ unit_amount: 0,
+ date: time.date_to_str(self.dates[0]),
+ account_id: id,
+ });
+ ops.push(def);
+ self.set({"sheets": ops});
+ });
+ });
+ },
+ get_box: function(account, day_count) {
+ return this.$('[data-account="' + account.account + '"][data-day-count="' + day_count + '"]');
+ },
+ get_total: function(account) {
+ return this.$('[data-account-total="' + account.account + '"]');
+ },
+ get_day_total: function(day_count) {
+ return this.$('[data-day-total="' + day_count + '"]');
+ },
+ get_super_total: function() {
+ return this.$('.oe_timesheet_weekly_supertotal');
+ },
+ sum_box: function(account, day_count, show_value_in_hour) {
+ var line_total = 0;
+ _.each(account.days[day_count].lines, function(line) {
+ line_total += line.unit_amount;
+ });
+ return (show_value_in_hour && line_total !== 0)?this.format_client(line_total):line_total;
+ },
+ display_totals: function() {
+ var self = this;
+ var day_tots = _.map(_.range(self.dates.length), function() { return 0; });
+ var super_tot = 0;
+ _.each(self.accounts, function(account) {
+ var acc_tot = 0;
+ _.each(_.range(self.dates.length), function(day_count) {
+ var sum = self.sum_box(account, day_count);
+ acc_tot += sum;
+ day_tots[day_count] += sum;
+ super_tot += sum;
+ });
+ self.get_total(account).html(self.format_client(acc_tot));
+ });
+ _.each(_.range(self.dates.length), function(day_count) {
+ self.get_day_total(day_count).html(self.format_client(day_tots[day_count]));
+ });
+ self.get_super_total().html(self.format_client(super_tot));
+ },
+ sync: function() {
+ var self = this;
+ self.setting = true;
+ self.set({sheets: this.generate_o2m_value()});
+ self.setting = false;
+ },
+ //converts hour value to float
+ parse_client: function(value) {
+ return formats.parse_value(value, { type:"float_time" });
+ },
+ //converts float value to hour
+ format_client:function(value){
+ return formats.format_value(value, { type:"float_time" });
+ },
+ generate_o2m_value: function() {
+ var self = this;
+ var ops = [];
+ var ignored_fields = self.ignore_fields();
+ _.each(self.accounts, function(account) {
+ _.each(account.days, function(day) {
+ _.each(day.lines, function(line) {
+ if (line.unit_amount !== 0) {
+ var tmp = _.clone(line);
+ tmp.id = undefined;
+ _.each(line, function(v, k) {
+ if (v instanceof Array) {
+ tmp[k] = v[0];
}
});
- } else {
- self.get_box(account, day_count).html(self.sum_box(account, day_count, true));
+ // we remove line_id as the reference to the _inherits field will no longer exists
+ tmp = _.omit(tmp, ignored_fields);
+ ops.push(tmp);
}
});
});
- self.display_totals();
- self.$(".oe_timesheet_weekly_adding button").click(_.bind(this.init_add_account, this));
- },
- init_add_account: function() {
- var self = this;
- if (self.dfm)
- return;
- self.$(".oe_timesheet_weekly_add_row").show();
- self.dfm = new instance.web.form.DefaultFieldManager(self);
- self.dfm.extend_field_desc({
- account: {
- relation: "account.analytic.account",
- },
- });
- self.account_m2o = new instance.web.form.FieldMany2One(self.dfm, {
- attrs: {
- name: "account",
- type: "many2one",
- domain: [
- ['type','in',['normal', 'contract']],
- ['state', '<>', 'close'],
- ['invoice_on_timesheets','=',1],
- ['id', 'not in', _.pluck(self.accounts, "account")],
- ],
- context: {
- default_invoice_on_timesheets: 1,
- default_type: "contract",
- },
- modifiers: '{"required": true}',
- },
- });
- self.account_m2o.prependTo(self.$(".oe_timesheet_weekly_add_row td"));
- self.$(".oe_timesheet_weekly_add_row button").click(function() {
- var id = self.account_m2o.get_value();
- if (id === false) {
- self.dfm.set({display_invalid_fields: true});
- return;
- }
- var ops = self.generate_o2m_value();
- new instance.web.Model("hr.analytic.timesheet").call("multi_on_change_account_id", [[], [id],
- new instance.web.CompoundContext({'user_id': self.get('user_id')})]).then(function(res) {
- res = res[id];
- var def = _.extend({}, self.default_get, res.value, {
- name: self.description_line,
- unit_amount: 0,
- date: instance.web.date_to_str(self.dates[0]),
- account_id: id,
- });
- ops.push(def);
- self.set({"sheets": ops});
- });
- });
- },
- get_box: function(account, day_count) {
- return this.$('[data-account="' + account.account + '"][data-day-count="' + day_count + '"]');
- },
- get_total: function(account) {
- return this.$('[data-account-total="' + account.account + '"]');
- },
- get_day_total: function(day_count) {
- return this.$('[data-day-total="' + day_count + '"]');
- },
- get_super_total: function() {
- return this.$('.oe_timesheet_weekly_supertotal');
- },
- sum_box: function(account, day_count, show_value_in_hour) {
- var line_total = 0;
- _.each(account.days[day_count].lines, function(line) {
- line_total += line.unit_amount;
- });
- return (show_value_in_hour && line_total != 0)?this.format_client(line_total):line_total;
- },
- display_totals: function() {
- var self = this;
- var day_tots = _.map(_.range(self.dates.length), function() { return 0 });
- var super_tot = 0;
- _.each(self.accounts, function(account) {
- var acc_tot = 0;
- _.each(_.range(self.dates.length), function(day_count) {
- var sum = self.sum_box(account, day_count);
- acc_tot += sum;
- day_tots[day_count] += sum;
- super_tot += sum;
- });
- self.get_total(account).html(self.format_client(acc_tot));
- });
- _.each(_.range(self.dates.length), function(day_count) {
- self.get_day_total(day_count).html(self.format_client(day_tots[day_count]));
- });
- self.get_super_total().html(self.format_client(super_tot));
- },
- sync: function() {
- var self = this;
- self.setting = true;
- self.set({sheets: this.generate_o2m_value()});
- self.setting = false;
- },
- //converts hour value to float
- parse_client: function(value) {
- return instance.web.parse_value(value, { type:"float_time" });
- },
- //converts float value to hour
- format_client:function(value){
- return instance.web.format_value(value, { type:"float_time" });
- },
- generate_o2m_value: function() {
- var self = this;
- var ops = [];
- var ignored_fields = self.ignore_fields();
- _.each(self.accounts, function(account) {
- _.each(account.days, function(day) {
- _.each(day.lines, function(line) {
- if (line.unit_amount !== 0) {
- var tmp = _.clone(line);
- tmp.id = undefined;
- _.each(line, function(v, k) {
- if (v instanceof Array) {
- tmp[k] = v[0];
- }
- });
- // we remove line_id as the reference to the _inherits field will no longer exists
- tmp = _.omit(tmp, ignored_fields);
- ops.push(tmp);
- }
- });
- });
- });
- return ops;
- },
- });
+ });
+ return ops;
+ },
+});
- instance.web.form.custom_widgets.add('weekly_timesheet', 'instance.hr_timesheet_sheet.WeeklyTimesheet');
+core.form_custom_registry.add('weekly_timesheet', WeeklyTimesheet);
-};
+});