diff --git a/cor_custom/__init__.py b/cor_custom/__init__.py index 8628669..1099cf8 100755 --- a/cor_custom/__init__.py +++ b/cor_custom/__init__.py @@ -2,4 +2,5 @@ from . import controllers from . import models +from . import wizard from . import report \ No newline at end of file diff --git a/cor_custom/__manifest__.py b/cor_custom/__manifest__.py index f071be5..8b17674 100755 --- a/cor_custom/__manifest__.py +++ b/cor_custom/__manifest__.py @@ -33,6 +33,7 @@ 'report/project_profitability_report_analysis_views.xml', 'views/views.xml', 'views/templates.xml', + 'wizard/project_create_sale_order_views.xml', ], # only loaded in demonstration mode 'demo': [ diff --git a/cor_custom/__pycache__/__init__.cpython-36.pyc b/cor_custom/__pycache__/__init__.cpython-36.pyc deleted file mode 100755 index 638c9ee..0000000 Binary files a/cor_custom/__pycache__/__init__.cpython-36.pyc and /dev/null differ diff --git a/cor_custom/controllers/__pycache__/__init__.cpython-36.pyc b/cor_custom/controllers/__pycache__/__init__.cpython-36.pyc deleted file mode 100755 index a4434d0..0000000 Binary files a/cor_custom/controllers/__pycache__/__init__.cpython-36.pyc and /dev/null differ diff --git a/cor_custom/controllers/__pycache__/controllers.cpython-36.pyc b/cor_custom/controllers/__pycache__/controllers.cpython-36.pyc deleted file mode 100755 index 38c46b7..0000000 Binary files a/cor_custom/controllers/__pycache__/controllers.cpython-36.pyc and /dev/null differ diff --git a/cor_custom/models/__pycache__/__init__.cpython-36.pyc b/cor_custom/models/__pycache__/__init__.cpython-36.pyc deleted file mode 100644 index b5c4e70..0000000 Binary files a/cor_custom/models/__pycache__/__init__.cpython-36.pyc and /dev/null differ diff --git a/cor_custom/models/__pycache__/analytic.cpython-36.pyc b/cor_custom/models/__pycache__/analytic.cpython-36.pyc deleted file mode 100644 index 6a52024..0000000 Binary files a/cor_custom/models/__pycache__/analytic.cpython-36.pyc and /dev/null differ diff --git a/cor_custom/models/__pycache__/crm_lead.cpython-36.pyc b/cor_custom/models/__pycache__/crm_lead.cpython-36.pyc deleted file mode 100755 index dbe16b0..0000000 Binary files a/cor_custom/models/__pycache__/crm_lead.cpython-36.pyc and /dev/null differ diff --git a/cor_custom/models/__pycache__/models.cpython-36.pyc b/cor_custom/models/__pycache__/models.cpython-36.pyc deleted file mode 100755 index 18206e2..0000000 Binary files a/cor_custom/models/__pycache__/models.cpython-36.pyc and /dev/null differ diff --git a/cor_custom/models/__pycache__/product.cpython-36.pyc b/cor_custom/models/__pycache__/product.cpython-36.pyc deleted file mode 100644 index 01e1117..0000000 Binary files a/cor_custom/models/__pycache__/product.cpython-36.pyc and /dev/null differ diff --git a/cor_custom/models/__pycache__/project.cpython-36.pyc b/cor_custom/models/__pycache__/project.cpython-36.pyc deleted file mode 100644 index a02db2e..0000000 Binary files a/cor_custom/models/__pycache__/project.cpython-36.pyc and /dev/null differ diff --git a/cor_custom/models/__pycache__/project_overview.cpython-36.pyc b/cor_custom/models/__pycache__/project_overview.cpython-36.pyc deleted file mode 100755 index 430c331..0000000 Binary files a/cor_custom/models/__pycache__/project_overview.cpython-36.pyc and /dev/null differ diff --git a/cor_custom/models/project.py b/cor_custom/models/project.py index 5d7236c..f9ebade 100755 --- a/cor_custom/models/project.py +++ b/cor_custom/models/project.py @@ -29,7 +29,7 @@ class InheritProjectProductEmployeeMap(models.Model): _inherit = 'project.sale.line.employee.map' employee_price = fields.Float("Consultant Price") - budgeted_qty = fields.Float(string='Budgeted qty', related='sale_line_id.product_uom_qty', 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) timesheet_hour = fields.Float("Timesheet Hour", compute='_compute_timesheet_hour', default=0.0) diff --git a/cor_custom/report/__pycache__/__init__.cpython-36.pyc b/cor_custom/report/__pycache__/__init__.cpython-36.pyc deleted file mode 100755 index af86dae..0000000 Binary files a/cor_custom/report/__pycache__/__init__.cpython-36.pyc and /dev/null differ diff --git a/cor_custom/report/__pycache__/project_profitability_report_analysis.cpython-36.pyc b/cor_custom/report/__pycache__/project_profitability_report_analysis.cpython-36.pyc deleted file mode 100755 index 32c2fd7..0000000 Binary files a/cor_custom/report/__pycache__/project_profitability_report_analysis.cpython-36.pyc and /dev/null differ diff --git a/cor_custom/wizard/__init__.py b/cor_custom/wizard/__init__.py new file mode 100644 index 0000000..7ff7694 --- /dev/null +++ b/cor_custom/wizard/__init__.py @@ -0,0 +1,4 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +from . import project_create_sale_order diff --git a/cor_custom/wizard/project_create_sale_order.py b/cor_custom/wizard/project_create_sale_order.py new file mode 100644 index 0000000..0465c0a --- /dev/null +++ b/cor_custom/wizard/project_create_sale_order.py @@ -0,0 +1,106 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +from odoo import api, fields, models, _ +from odoo.exceptions import UserError + + +class ProjectCreateSalesOrder(models.TransientModel): + _inherit = 'project.create.sale.order' + + + partner_id = fields.Many2one('res.partner', string="Client", required=True, help="Client of the sales order") + + 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 + project_id = self.project_id.id + + lines_already_present = dict([(l.employee_id.id, l) for l in self.project_id.sale_line_employee_ids]) + + non_billable_tasks = self.project_id.tasks.filtered(lambda task: not task.sale_line_id) + non_allow_billable_tasks = self.project_id.tasks.filtered(lambda task: task.non_allow_billable) + + map_entries = self.env['project.sale.line.employee.map'] + EmployeeMap = self.env['project.sale.line.employee.map'].sudo() + + # create SO lines: create on SOL per product/price. So many employee can be linked to the same SOL + map_product_price_sol = {} # (product_id, price) --> SOL + 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, + 'price_unit': wizard_line.price_unit, + 'product_uom_qty': wizard_line.budgeted_qty, + } + if wizard_line.product_id.service_tracking in ['task_in_project', 'task_global_project']: + 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 + + if wizard_line.employee_id.id not in lines_already_present: + map_entries |= EmployeeMap.create({ + 'project_id': self.project_id.id, + 'sale_line_id': map_product_price_sol[map_key].id, + 'employee_id': wizard_line.employee_id.id, + }) + else: + map_entries |= lines_already_present[wizard_line.employee_id.id] + lines_already_present[wizard_line.employee_id.id].write({ + 'sale_line_id': map_product_price_sol[map_key].id + }) + + # link the project to the SO + self.project_id.write({ + 'sale_order_id': sale_order.id, + 'sale_line_id': sale_order.order_line[0].id, + 'partner_id': self.partner_id.id, + }) + non_billable_tasks.write({ + 'partner_id': sale_order.partner_id.id, + 'email_from': sale_order.partner_id.email, + }) + non_allow_billable_tasks.sale_line_id = False + + tasks = self.project_id.tasks.filtered(lambda t: not t.non_allow_billable) + # assign SOL to timesheets + for map_entry in map_entries: + search_domain = [('employee_id', '=', map_entry.employee_id.id), ('so_line', '=', False)] + ticket_timesheet_ids = self.env.context.get('ticket_timesheet_ids', []) + if ticket_timesheet_ids: + search_domain.append(('id', 'in', ticket_timesheet_ids)) + else: + search_domain.append(('task_id', 'in', tasks.ids)) + self.env['account.analytic.line'].search(search_domain).write({ + 'so_line': map_entry.sale_line_id.id + }) + #map_entry.sale_line_id.with_context({'no_update_planned_hours': True}).write({ + # 'product_uom_qty': map_entry.sale_line_id.qty_delivered + #}) + + return map_entries + + +class ProjectCreateSalesOrderLine(models.TransientModel): + _inherit= 'project.create.sale.order.line' + + + employee_id = fields.Many2one('hr.employee', string="Consultant", help="Consultant that has timesheets on the project.") + budgeted_qty = fields.Float(string='Budgeted Qty', digits='Product Unit of Measure', default=1.0) + budgeted_uom = fields.Many2one('uom.uom', string='Budgeted UOM', related='product_id.uom_id', readonly=True) + employee_price = fields.Float("Consultant Price") + + + + + diff --git a/cor_custom/wizard/project_create_sale_order_views.xml b/cor_custom/wizard/project_create_sale_order_views.xml new file mode 100644 index 0000000..8681d35 --- /dev/null +++ b/cor_custom/wizard/project_create_sale_order_views.xml @@ -0,0 +1,16 @@ + + + + + project.create.sale.order.wizard.form.budgeted + project.create.sale.order + + + + + + + + + + diff --git a/odoo-debrand/__pycache__/__init__.cpython-36.pyc b/odoo-debrand/__pycache__/__init__.cpython-36.pyc deleted file mode 100644 index 3678e9e..0000000 Binary files a/odoo-debrand/__pycache__/__init__.cpython-36.pyc and /dev/null differ diff --git a/odoo-debrand/controllers/__pycache__/__init__.cpython-36.pyc b/odoo-debrand/controllers/__pycache__/__init__.cpython-36.pyc deleted file mode 100644 index 1f25061..0000000 Binary files a/odoo-debrand/controllers/__pycache__/__init__.cpython-36.pyc and /dev/null differ diff --git a/odoo-debrand/controllers/__pycache__/controllers.cpython-36.pyc b/odoo-debrand/controllers/__pycache__/controllers.cpython-36.pyc deleted file mode 100644 index c38df28..0000000 Binary files a/odoo-debrand/controllers/__pycache__/controllers.cpython-36.pyc and /dev/null differ diff --git a/odoo-debrand/models/__pycache__/__init__.cpython-36.pyc b/odoo-debrand/models/__pycache__/__init__.cpython-36.pyc deleted file mode 100644 index 8fe12a1..0000000 Binary files a/odoo-debrand/models/__pycache__/__init__.cpython-36.pyc and /dev/null differ diff --git a/odoo-debrand/models/__pycache__/models.cpython-36.pyc b/odoo-debrand/models/__pycache__/models.cpython-36.pyc deleted file mode 100644 index 5f540f8..0000000 Binary files a/odoo-debrand/models/__pycache__/models.cpython-36.pyc and /dev/null differ