Merge branch 'pawan_branch' into 'development'
Pawan branch See merge request prakash.jain/cor-odoo!17
This commit is contained in:
commit
d1bdafcb72
|
@ -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',
|
||||
|
|
Binary file not shown.
Binary file not shown.
|
@ -2,17 +2,30 @@
|
|||
# Part of Odoo. See LICENSE file for full copyright and licensing details
|
||||
|
||||
from odoo import api, fields, models, _
|
||||
from odoo.exceptions import UserError, AccessError
|
||||
from odoo.exceptions import UserError, AccessError, ValidationError
|
||||
from odoo.osv import expression
|
||||
|
||||
class AccountAnalyticLine(models.Model):
|
||||
_inherit = 'account.analytic.line'
|
||||
|
||||
ispercentage = fields.Boolean(string="Is Percentage", default=False)
|
||||
percentage_rate = fields.Float(string="Percentage (%)")
|
||||
per_from_amt = fields.Float(string="Of", digits=(6, 2))
|
||||
@api.model
|
||||
def create(self, vals):
|
||||
if vals.get('unit_amount') == 0.0:
|
||||
raise ValidationError(_("Your can not fill 0.0 hour entry"))
|
||||
if vals.get('employee_id') and vals.get('project_id'):
|
||||
project = self.env['project.project'].search([('id', '=', vals.get('project_id'))])
|
||||
if project:
|
||||
for rec in project.sale_line_employee_ids:
|
||||
if rec.employee_id.id == vals.get('employee_id'):
|
||||
remain_hour = rec.budgeted_qty - rec.timesheet_hour
|
||||
if vals.get('unit_amount') > 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))
|
||||
|
||||
|
||||
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)
|
|
@ -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
|
0
cor_custom/report/__pycache__/project_profitability_report_analysis.cpython-36.pyc
Normal file → Executable file
0
cor_custom/report/__pycache__/project_profitability_report_analysis.cpython-36.pyc
Normal file → Executable file
|
@ -31,7 +31,8 @@
|
|||
attrs="{'invisible': [('allow_billable', '=', False)]}">
|
||||
<group>
|
||||
<field name="display_create_order" invisible="1"/>
|
||||
<field name="bill_type" widget="radio"/>
|
||||
<field name="project_type" widget="radio"/>
|
||||
<field name="bill_type" widget="radio" invisible="1"/>
|
||||
<field name="pricing_type"
|
||||
attrs="{'invisible': ['|', ('allow_billable', '=', False), ('bill_type', '!=', 'customer_project')], 'required': ['&', ('allow_billable', '=', True), ('allow_timesheets', '=', True)]}"
|
||||
widget="radio"/>
|
||||
|
@ -65,12 +66,14 @@
|
|||
domain="[('order_id','=',parent.sale_order_id), ('is_service', '=', True)]"/>
|
||||
<field name="price_unit" widget="monetary" options="{'currency_field': 'currency_id'}"
|
||||
attrs="{'readonly': [('parent.sale_order_id', '!=', False)]}"/>
|
||||
<field name="timesheet_hour"/>
|
||||
<field name="employee_price" widget="monetary" options="{'currency_field': 'currency_id'}"/>
|
||||
<field name="currency_id" invisible="1" readonly="1"/>
|
||||
</tree>
|
||||
</field>
|
||||
</page>
|
||||
</xpath>
|
||||
|
||||
</field>
|
||||
</record>
|
||||
|
||||
|
|
Loading…
Reference in New Issue