From 5b7847e84f93bd0f2922f111152bed51d8cf62fb Mon Sep 17 00:00:00 2001 From: projectsodoo Date: Sat, 26 Dec 2020 22:05:09 +0530 Subject: [PATCH] Code improved and clear the functionality --- cor_custom/models/hr_employee.py | 11 ++- cor_custom/models/project.py | 3 +- cor_custom/views/hr_employee_views.xml | 14 +++- cor_custom/views/project_view.xml | 6 +- .../wizard/project_create_sale_order.py | 75 +++++++++++++++++-- .../project_create_sale_order_views.xml | 2 +- 6 files changed, 98 insertions(+), 13 deletions(-) diff --git a/cor_custom/models/hr_employee.py b/cor_custom/models/hr_employee.py index 4f42fab..3285c76 100755 --- a/cor_custom/models/hr_employee.py +++ b/cor_custom/models/hr_employee.py @@ -6,9 +6,16 @@ from odoo import api, fields, models, _ class HrEmployee(models.Model): _inherit = 'hr.employee' - budgeted_hour_week = fields.Integer("Budgeted Hours") + budgeted_hour_week = fields.Integer("Working days per week", default=5) + + @api.onchange('resource_calendar_id') + def onchange_(self): + if self.resource_calendar_id and self.resource_calendar_id.attendance_ids: + total_week = [val.dayofweek for val in self.resource_calendar_id.attendance_ids] + res = list(set(total_week)) + self.budgeted_hour_week = len(res) class EmployeePublic(models.Model): _inherit = 'hr.employee.public' - budgeted_hour_week = fields.Integer("Budgeted Hours") + budgeted_hour_week = fields.Integer("Working days per week") diff --git a/cor_custom/models/project.py b/cor_custom/models/project.py index 9e9d176..0fc510b 100755 --- a/cor_custom/models/project.py +++ b/cor_custom/models/project.py @@ -45,6 +45,7 @@ class InheritProjectProductEmployeeMap(models.Model): employee_price = fields.Monetary(string="Consultant Price", related="employee_id.timesheet_cost", readonly=True) budgeted_qty = fields.Float(string='Budgeted Qty', related='sale_line_id.product_uom_qty', readonly=True) 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) budgeted_hour_week = fields.Float("Budgeted Hours per week", compute='_compute_budgeted_hour_week') @@ -61,7 +62,7 @@ class InheritProjectProductEmployeeMap(models.Model): def _compute_budgeted_hour_week(self): for val in self: - if val.employee_id and val.employee_id.budgeted_hour_week and val.budgeted_qty: + if val.employee_id and val.employee_id.budgeted_hour_week > 0 and val.budgeted_qty: val.budgeted_hour_week = (val.budgeted_qty /val.employee_id.budgeted_hour_week) else: val.budgeted_hour_week = 0 diff --git a/cor_custom/views/hr_employee_views.xml b/cor_custom/views/hr_employee_views.xml index 0bcaeef..0c8f6e8 100755 --- a/cor_custom/views/hr_employee_views.xml +++ b/cor_custom/views/hr_employee_views.xml @@ -2,6 +2,17 @@ + hr.employee.form.inherit + hr.employee + + + + + + + + + + diff --git a/cor_custom/views/project_view.xml b/cor_custom/views/project_view.xml index 7a9b29d..bfd0161 100755 --- a/cor_custom/views/project_view.xml +++ b/cor_custom/views/project_view.xml @@ -58,13 +58,13 @@ - - - + + diff --git a/cor_custom/wizard/project_create_sale_order.py b/cor_custom/wizard/project_create_sale_order.py index 0465c0a..d93567c 100755 --- a/cor_custom/wizard/project_create_sale_order.py +++ b/cor_custom/wizard/project_create_sale_order.py @@ -11,8 +11,77 @@ class ProjectCreateSalesOrder(models.TransientModel): partner_id = fields.Many2one('res.partner', string="Client", required=True, help="Client of the sales order") + def _make_billable_at_project_rate(self, sale_order): + self.ensure_one() + task_left = self.project_id.tasks.filtered(lambda task: not task.sale_line_id) + ticket_timesheet_ids = self.env.context.get('ticket_timesheet_ids', []) + for wizard_line in self.line_ids: + task_ids = self.project_id.tasks.filtered(lambda task: not task.sale_line_id and task.timesheet_product_id == wizard_line.product_id) + task_left -= task_ids + # trying to simulate the SO line created a task, according to the product configuration + # To avoid, generating a task when confirming the SO + task_id = False + if task_ids and wizard_line.product_id.service_tracking in ['task_in_project', 'task_global_project']: + task_id = task_ids.ids[0] + + # create SO line + sale_order_line = self.env['sale.order.line'].create({ + 'order_id': sale_order.id, + 'product_id': wizard_line.product_id.id, + 'price_unit': wizard_line.price_unit, + 'project_id': self.project_id.id, # prevent to re-create a project on confirmation + 'task_id': task_id, + 'product_uom_qty': wizard_line.budgeted_qty, + }) + + if ticket_timesheet_ids and not self.project_id.sale_line_id and not task_ids: + # With pricing = "project rate" in project. When the user wants to create a sale order from a ticket in helpdesk + # The project cannot contain any tasks. Thus, we need to give the first sale_order_line created to link + # the timesheet to this first sale order line. + # link the project to the SO line + self.project_id.write({ + 'sale_order_id': sale_order.id, + 'sale_line_id': sale_order_line.id, + 'partner_id': self.partner_id.id, + }) + + # link the tasks to the SO line + task_ids.write({ + 'sale_line_id': sale_order_line.id, + 'partner_id': sale_order.partner_id.id, + 'email_from': sale_order.partner_id.email, + }) + + # assign SOL to timesheets + search_domain = [('task_id', 'in', task_ids.ids), ('so_line', '=', False)] + if ticket_timesheet_ids: + search_domain = [('id', 'in', ticket_timesheet_ids), ('so_line', '=', False)] + + self.env['account.analytic.line'].search(search_domain).write({ + 'so_line': sale_order_line.id + }) + #sale_order_line.with_context({'no_update_planned_hours': True}).write({ + #'product_uom_qty': sale_order_line.qty_delivered + #}) + + if ticket_timesheet_ids and self.project_id.sale_line_id and not self.project_id.tasks and len(self.line_ids) > 1: + # Then, we need to give to the project the last sale order line created + self.project_id.write({ + 'sale_line_id': sale_order_line.id + }) + else: # Otherwise, we are in the normal behaviour + # link the project to the SO line + self.project_id.write({ + 'sale_order_id': sale_order.id, + 'sale_line_id': sale_order_line.id, # we take the last sale_order_line created + 'partner_id': self.partner_id.id, + }) + + if task_left: + task_left.sale_line_id = False + + def _make_billable_at_employee_rate(self, sale_order): - print("mmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm") # trying to simulate the SO line created a task, according to the product configuration # To avoid, generating a task when confirming the SO task_id = self.env['project.task'].search([('project_id', '=', self.project_id.id)], order='create_date DESC', limit=1).id @@ -31,9 +100,6 @@ class ProjectCreateSalesOrder(models.TransientModel): for wizard_line in self.line_ids: map_key = (wizard_line.product_id.id, wizard_line.price_unit) if map_key not in map_product_price_sol: - print("wwwwwwwwww", wizard_line) - print("wwwwwwwwww", wizard_line.budgeted_qty) - values = { 'order_id': sale_order.id, 'product_id': wizard_line.product_id.id, @@ -44,7 +110,6 @@ class ProjectCreateSalesOrder(models.TransientModel): values['task_id'] = task_id if wizard_line.product_id.service_tracking in ['task_in_project', 'project_only']: values['project_id'] = project_id - print("wwwwwwwwww", values) sale_order_line = self.env['sale.order.line'].create(values) map_product_price_sol[map_key] = sale_order_line diff --git a/cor_custom/wizard/project_create_sale_order_views.xml b/cor_custom/wizard/project_create_sale_order_views.xml index 8681d35..ba62fda 100755 --- a/cor_custom/wizard/project_create_sale_order_views.xml +++ b/cor_custom/wizard/project_create_sale_order_views.xml @@ -7,7 +7,7 @@ - +