diff --git a/cor_custom/models/project.py b/cor_custom/models/project.py index 392338f..c9d707c 100755 --- a/cor_custom/models/project.py +++ b/cor_custom/models/project.py @@ -212,7 +212,7 @@ class ProjectConsultantTimesheetHrs(models.Model): class InheritProjectProductEmployeeMap(models.Model): _inherit = 'project.sale.line.employee.map' - budgeted_qty = fields.Float(string='Budgeted Hours') + budgeted_qty = fields.Float(string='Budgeted Hours', digits=(16, 2)) budgeted_uom = fields.Many2one('uom.uom', string='Budgeted UOM', related='sale_line_id.product_uom', readonly=True) # budgeted_uom = fields.Many2one('uom.uom', string='Budgeted UOM', related='timesheet_product_id.uom_id', readonly=True) timesheet_hour = fields.Float("Timesheet Hour", compute='_compute_timesheet_hour', default=0.0) diff --git a/cor_custom/models/project_hours.py b/cor_custom/models/project_hours.py index 41a76fe..6f88ee3 100755 --- a/cor_custom/models/project_hours.py +++ b/cor_custom/models/project_hours.py @@ -18,9 +18,10 @@ class ProjectConsultantHrs(models.Model): employee_id = fields.Many2one('hr.employee', string="Consultant", required=True) start_date = fields.Date('Start Date', required=True) end_date = fields.Date('End Date', required=True) - percentage = fields.Float("Percentage (%)") + percentage = fields.Float("Budgeted Percentage (%)") budgeted_hours = fields.Float("Budgeted Hours for period", compute='_compute_budgeted_hours', store=True) - actual_hours = fields.Float("Actual Hours for period", compute='_compute_actual_hours', store=True) + actual_percentage = fields.Float("Actual Percentage (%)", compute='_compute_actual_calc', store=True) + actual_hours = fields.Float("Actual Hours for period", compute='_compute_actual_calc', store=True) #hours_type = fields.Selection([('Budgeted Hours', 'Budgeted Hours'), ('Actual Hours', 'Actual Hours')], default="Budgeted Hours", string="Type") @api.constrains('start_date', 'end_date') @@ -75,9 +76,9 @@ class ProjectConsultantHrs(models.Model): else: val.budgeted_hours = 0 - @api.depends('project_id', 'start_date', 'end_date', 'project_id.timesheet_ids', 'project_id.timesheet_ids.date', - 'project_id.timesheet_ids.project_id', 'project_id.timesheet_ids.employee_id', 'project_id.timesheet_ids.start_time', 'project_id.timesheet_ids.end_time') - def _compute_actual_hours(self): + @api.depends('project_id', 'start_date', 'end_date', 'project_id.timesheet_ids', 'project_id.timesheet_ids.date', 'project_id.timesheet_ids.project_id', + 'project_id.timesheet_ids.employee_id', 'project_id.timesheet_ids.start_time', 'project_id.timesheet_ids.end_time', 'project_id.timesheet_ids.unit_amount') + def _compute_actual_calc(self): Timesheet = self.env['account.analytic.line'] for val in self: if val.project_id and val.employee_id and val.start_date and val.end_date: @@ -89,8 +90,20 @@ class ProjectConsultantHrs(models.Model): ] timesheets = Timesheet.search(domain) val.actual_hours = sum(timesheet.unit_amount for timesheet in timesheets) + #budgeted = 0 + #for emp in val.project_id.sale_line_employee_ids: + # if emp.employee_id.id == val.employee_id.id: + # budgeted = emp.budgeted_qty + res = sum(timesheet.unit_amount for timesheet in timesheets) + val.actual_hours = res + #budgeted_period = (budgeted * val.percentage / 100) + if val.budgeted_hours > 0: + val.actual_percentage = (res/val.budgeted_hours) * 100 + else: + val.actual_percentage = 0 else: val.actual_hours = 0 + val.actual_percentage = 0 @api.onchange('start_date') def onchange_start_date(self): diff --git a/cor_custom/views/project_hours_view.xml b/cor_custom/views/project_hours_view.xml index bee126d..b10b53a 100755 --- a/cor_custom/views/project_hours_view.xml +++ b/cor_custom/views/project_hours_view.xml @@ -5,14 +5,17 @@ project.consultant.hrs.form project.consultant.hrs -
- - - - - - - + + + + + + + + + + + @@ -21,13 +24,14 @@ project.consultant.hrs.tree project.consultant.hrs - + + diff --git a/cor_custom/views/project_view.xml b/cor_custom/views/project_view.xml index 6f7e6ef..b7bb35f 100755 --- a/cor_custom/views/project_view.xml +++ b/cor_custom/views/project_view.xml @@ -31,6 +31,7 @@ + diff --git a/project_report/static/src/js/graph_renderer.js b/project_report/static/src/js/graph_renderer.js index c979991..6708e77 100755 --- a/project_report/static/src/js/graph_renderer.js +++ b/project_report/static/src/js/graph_renderer.js @@ -1,27 +1,50 @@ odoo.define("project_report.GraphRenderer", function(require) { var GraphRenderer = require("web.GraphRenderer"); var config = require("web.config"); -var field_utils = require("web.field_utils"); +var fieldUtils = require('web.field_utils'); // Hide top legend when too many items for device size var MAX_LEGEND_LENGTH = 25 * (1 + config.device.size_class); +// used to format values in tooltips and yAxes. +var FORMAT_OPTIONS = { + // allow to decide if utils.human_number should be used + humanReadable: function (value) { + return Math.abs(value) >= 1000; + }, + // with the choices below, 1236 is represented by 1.24k + minDigits: 1, + decimals: 2, + // avoid comma separators for thousands in numbers when human_number is used + formatterCallback: function (str) { + return str; + }, +}; + GraphRenderer.include({ init: function(parent, state, params) { this._super.apply(this, arguments); this.context = state.context; this.resModel = this.context && this.context.default_res_model; - console.log("this.resModel", this.resModel, this.context.default_res_model); //if (this.resModel == 'project.budget.hrs.report') { // this.title = 'Time Line'; // } }, + _formatValue: function (value) { + //this._super.apply(this, arguments); + var measureField = this.fields[this.state.measure]; + var formatter = fieldUtils.format.float; + var formatedValue = formatter(value, measureField, FORMAT_OPTIONS); + return formatedValue; + }, + _animationOptions: function () { var animationOptions = {}; - if (this.state.mode === 'bar' && this.resModel == 'project.budget.hrs.report') { + var GraphVal = this; + if (this.state.mode === 'bar') { // && this.resModel == 'project.budget.hrs.report' var animationOptions = { - duration: "0.1", + duration: "1", "onComplete": function() { var chartInstance = this.chart, ctx = chartInstance.ctx; @@ -32,8 +55,10 @@ var MAX_LEGEND_LENGTH = 25 * (1 + config.device.size_class); var meta = chartInstance.controller.getDatasetMeta(i); meta.data.forEach(function(bar, index) { var data = dataset.data[index]; + var value; if(!!data){ - ctx.fillText(data, bar._model.x, bar._model.y - 5); + value = GraphVal._formatValue(data); + ctx.fillText(value, bar._model.x, bar._model.y - 5); } }); });