From 42bd40490080f274897f03110cfe4bd91b0a8ae2 Mon Sep 17 00:00:00 2001 From: Pawan Kumar Date: Fri, 18 Dec 2020 16:57:41 +0530 Subject: [PATCH] add timesheet validation and timesheet hours in project --- cor_custom/__manifest__.py | 2 +- .../__pycache__/__init__.cpython-36.pyc | Bin .../__pycache__/__init__.cpython-36.pyc | Bin .../__pycache__/controllers.cpython-36.pyc | Bin .../__pycache__/__init__.cpython-36.pyc | Bin .../__pycache__/analytic.cpython-36.pyc | Bin 1037 -> 1483 bytes .../__pycache__/crm_lead.cpython-36.pyc | Bin .../models/__pycache__/models.cpython-36.pyc | Bin .../models/__pycache__/project.cpython-36.pyc | Bin 2328 -> 2974 bytes .../project_overview.cpython-36.pyc | Bin cor_custom/models/analytic.py | 29 +++++++++++++----- cor_custom/models/project.py | 27 +++++++++++----- .../__pycache__/__init__.cpython-36.pyc | Bin ...ofitability_report_analysis.cpython-36.pyc | Bin cor_custom/views/project_view.xml | 5 ++- 15 files changed, 45 insertions(+), 18 deletions(-) mode change 100644 => 100755 cor_custom/__pycache__/__init__.cpython-36.pyc mode change 100644 => 100755 cor_custom/controllers/__pycache__/__init__.cpython-36.pyc mode change 100644 => 100755 cor_custom/controllers/__pycache__/controllers.cpython-36.pyc mode change 100644 => 100755 cor_custom/models/__pycache__/__init__.cpython-36.pyc mode change 100644 => 100755 cor_custom/models/__pycache__/crm_lead.cpython-36.pyc mode change 100644 => 100755 cor_custom/models/__pycache__/models.cpython-36.pyc mode change 100644 => 100755 cor_custom/models/__pycache__/project_overview.cpython-36.pyc mode change 100644 => 100755 cor_custom/report/__pycache__/__init__.cpython-36.pyc mode change 100644 => 100755 cor_custom/report/__pycache__/project_profitability_report_analysis.cpython-36.pyc diff --git a/cor_custom/__manifest__.py b/cor_custom/__manifest__.py index a118da9..40f44c6 100755 --- a/cor_custom/__manifest__.py +++ b/cor_custom/__manifest__.py @@ -29,7 +29,7 @@ 'views/sale_views.xml', 'views/project_view.xml', 'views/hr_timesheet_templates.xml', - 'views/analytic_view.xml', + #'views/analytic_view.xml', 'report/project_profitability_report_analysis_views.xml', 'views/views.xml', 'views/templates.xml', diff --git a/cor_custom/__pycache__/__init__.cpython-36.pyc b/cor_custom/__pycache__/__init__.cpython-36.pyc old mode 100644 new mode 100755 diff --git a/cor_custom/controllers/__pycache__/__init__.cpython-36.pyc b/cor_custom/controllers/__pycache__/__init__.cpython-36.pyc old mode 100644 new mode 100755 diff --git a/cor_custom/controllers/__pycache__/controllers.cpython-36.pyc b/cor_custom/controllers/__pycache__/controllers.cpython-36.pyc old mode 100644 new mode 100755 diff --git a/cor_custom/models/__pycache__/__init__.cpython-36.pyc b/cor_custom/models/__pycache__/__init__.cpython-36.pyc old mode 100644 new mode 100755 diff --git a/cor_custom/models/__pycache__/analytic.cpython-36.pyc b/cor_custom/models/__pycache__/analytic.cpython-36.pyc index 9cb7089dd0c34a21d1d1cc5152e191aec783a114..6a5202421d65f51ca926378517a19838a00faf45 100644 GIT binary patch literal 1483 zcmb7EOOG5i5Vrd@J&)ZD0g~Ma!km!iurtf!7!W}OF0dB_EG;3c)AsCirysLr&$2U` zy)cn-=9a&J#F-ysapS~a$cZZVOg2(-!7Z1|WxMLD^4I=kZ?E^)?|+NCA!GlrS6YDj z7ufYF3dtldS;Z4xd5Kr~iC+atz{&2FVHG7&)k!*4oW#!Nm))wD^f>#5$v}ornGBU* z^f!JokkR*S)cF^EvQc3Dbe`L2nyXT38&!=|rM6s*eB1p&D|iIZfbBobGNpApIruRx zbD5gFshwfOZBJdz0XLv2Bfq;w8Bo(7qfjj2k|mzxiLZhpe8#3+deVOyZ+H^986l06 z&NCLUBu12xeH$Y;i`qP_({gF@?AyFnt9R4ZI8L|Laf#;4bFmnUaKu_NAG`h&#hMpb zy$wct;=w(`4MyGI{5S4af(?h~P79sJ3SUM?tO#UB#yk7eKgSc--r9rbS6{EaBK(T| z^5EKE`$bfAc7D+R8CqiO-9vUAI6IzO2TuYxbCJ7kelN zr?$VSb0gA<5R_vnx1;rP`GSA8I(glt^E9j)P(w4rSYIyWxiU(+IC`{aeVjs!kbr7zeN|uD zNUIdGnZ2XaQVF^Y@d^|T1KPe%+Xs)g{=|h@+I^E(O3#!sg3_>|Ud$Chk9I~GsMILr zK%iAQwZUbI%O zv}vm2RLZ8-ldOSbS|vraOOy65n7m}yd^Sl|JB`0V77{m*7r`kIfd9dVQ3$v2#LZ>F9h}H zbsvN;!gs(|PW=j;cuu!+wr zv}Bx>9`{P0`_%EQXq5pE%8-YR?iEql=50z|6Y!yRN}wgZY3Ib_T?jsrBwV0BlK9q3 zXSof=xh%lgpj03WW2s1(ZGSOR?`o~I?e1imG^SA!YCH09rcuvTl{q&T>oVC9GLmo# zgfpPrlm4^?3_S497!Objp#{Mi!Z|}tmygMa=QVMAm5UiT1^o{fa4(ozax zJ3?T@dEw+(h_CasIJZP1ulA+RYwen7!;P z0ymx7Mu>15H}r`5Y>mcrjWzrziLLMY(RgdZYFDOiAz&BKGLVOvoYnXMjCQw0hX_1s mOv-%I&b4j5cdw~&c_n<4jmyDC&z2=Wcg~G-bDOTynEeGW00<=j diff --git a/cor_custom/models/__pycache__/crm_lead.cpython-36.pyc b/cor_custom/models/__pycache__/crm_lead.cpython-36.pyc old mode 100644 new mode 100755 diff --git a/cor_custom/models/__pycache__/models.cpython-36.pyc b/cor_custom/models/__pycache__/models.cpython-36.pyc old mode 100644 new mode 100755 diff --git a/cor_custom/models/__pycache__/project.cpython-36.pyc b/cor_custom/models/__pycache__/project.cpython-36.pyc index 46ac86a6c90f6c4ec980849f79527afe5a46cafe..d932a21d5451d38403042bf74c9a9cb29388964a 100644 GIT binary patch delta 1196 zcmZuwOK;Oa5Z+xoiE+|UQJVAtWhqqD5^w+^K!OY9Q6vgg6DU|hmhmo$qr?vDO=+u? z9Lj-956G&-0deQZ9ex0R!9wE9nHvXS)=k^+*l53S0GjjvqK)7(|_>bOZV0^t@71S8)2I!)jb|MqSSf z1@nU%l_7QMzIRgGp$I~!>9>6O<6>yNnIDVF$%MZ`()i?f>ebHMlR^c&GopVW5xsx({-`^BcH}8mNI8?&1b%Xn=Y{W8^K_Bp9W( z%qH3(-5wG1UBa|+w0m~3lYIsgwR0{bh9LLM-Sy9v8+UHZRq1Y-e0G}hR=XLlaqg%~ z<^IBKC-9}?w!%&zEqZh5-aYAoA4U(dX)L%!$6p&)@&2`Q?YL}kpvfaIZ8zY zYlrHVR+YMUs#y6`%+{q+_wIeqKoC-U*8A@B`|-Vdci&b%`_8WGI`7}!gxA(5M|WC` zG06fBED*qhf;2`&sKVkvfC&ODus<4snR|U$Laz%Y@N%yO3kR%OyZX~G^zY&hw{_b* zEPZFHj+&~jf0zd^myz1s5C#|Az|WpDWnw5on=f*_MoW9TW3^VCQ5l>I4rQoZvI`zm zz{Pf+{$h1Y-kb3>PL8G2zpS(KtSs+-!y!ccPLOti)+Na`gi|(R$|oH0Qx=Me3Hc5T zbwzK0Dfwy^)H;&Pn+?Y@J(6-3MoBu$ym^J6!P0@dqWp- remain_hour: + raise ValidationError(_("Your can not fill entry more than Budgeted hours")) + value = super(AccountAnalyticLine, self).create(vals) + return value - @api.onchange('ispercentage', 'percentage_rate', 'per_from_amt') - def onchange_amount(self): - if self.ispercentage == True and self.percentage_rate > 0.0 and self.per_from_amt > 0.0: - self.amount = - (self.per_from_amt * (self.percentage_rate / 100)) \ No newline at end of file + + + def write(self, vals): + if vals.get('unit_amount') == 0.0: + raise ValidationError(_("Your can not fill 0.0 hour entry")) + return super().write(vals) \ No newline at end of file diff --git a/cor_custom/models/project.py b/cor_custom/models/project.py index 95c7d27..67ccf76 100755 --- a/cor_custom/models/project.py +++ b/cor_custom/models/project.py @@ -9,7 +9,7 @@ class Project(models.Model): bill_type = fields.Selection([ ('customer_task', 'Invoice tasks separately to different clients'), ('customer_project', 'Invoice all tasks to a single client') - ], string="Client Type", default="customer_task", + ], string="Client Type", default="customer_project", help='When billing tasks individually, a Sales Order will be created from each task. It is perfect if you would like to bill different services to different clients at different rates. \n When billing the whole project, a Sales Order will be created from the project instead. This option is better if you would like to bill all the tasks of a given project to a specific client either at a fixed rate, or at an employee rate.') pricing_type = fields.Selection([ @@ -18,17 +18,28 @@ class Project(models.Model): ], string="Pricing", default="fixed_rate", help='The fixed rate is perfect if you bill a service at a fixed rate per hour or day worked regardless of the consultant who performed it. The consultant rate is preferable if your employees deliver the same service at a different rate. For instance, junior and senior consultants would deliver the same service (= consultancy), but at a different rate because of their level of seniority.') + project_type = fields.Selection([ + ('hours_in_consultant', 'Hours are budgeted according to a consultant'), + ('hours_no_limit', 'Total hours are budgeted without division to consultant'), + ('no_limit', 'Projects that have no time limit') + ], string="Project Type", default="no_limit") + class InheritProjectProductEmployeeMap(models.Model): _inherit = 'project.sale.line.employee.map' - employee_price = fields.Float("Employee Price") + employee_price = fields.Float("Consultant Price") 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') - @api.onchange('employee_id') - def _onchange_employee_price(self): - if self.employee_id: - self.employee_price = self.employee_id.timesheet_cost - else: - self.employee_price = 0.0 + def _compute_timesheet_hour(self): + for val in self: + self._cr.execute('''SELECT project_id, employee_id, SUM(unit_amount) FROM account_analytic_line + where project_id = %(project_id)s and employee_id = %(employee_id)s + GROUP BY project_id, employee_id''', { 'project_id': val.project_id.id, 'employee_id': val.employee_id.id,}) + res = self._cr.fetchone() + if res and res[2]: + val.timesheet_hour = res[2] + else: + val.timesheet_hour = 0.0 \ No newline at end of file diff --git a/cor_custom/report/__pycache__/__init__.cpython-36.pyc b/cor_custom/report/__pycache__/__init__.cpython-36.pyc old mode 100644 new mode 100755 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 old mode 100644 new mode 100755 diff --git a/cor_custom/views/project_view.xml b/cor_custom/views/project_view.xml index c7330c0..c639a2e 100755 --- a/cor_custom/views/project_view.xml +++ b/cor_custom/views/project_view.xml @@ -31,7 +31,8 @@ attrs="{'invisible': [('allow_billable', '=', False)]}"> - + + @@ -65,12 +66,14 @@ domain="[('order_id','=',parent.sale_order_id), ('is_service', '=', True)]"/> + +