Store cost price on timesheet line

issue4977
review23421002
This commit is contained in:
Cédric Krier committed 2015-09-22 19:26:13 +02:00
1 parent 8659660df9
commit 0bf157cc01
8 files changed
+126 -55

No files matched your search

+3 -1
View File
@@ -1,3 +1,5 @@
* Store cost price on timesheet line
Version 3.6.0 - 2015-04-20
* Bug fixes (see mercurial logs for details)
* Add support for PyPy
@@ -8,4 +10,4 @@ Version 3.2.0 - 2014-04-21
* Bug fixes (see mercurial logs for details)
Version 3.0.0 - 2013-10-21
* Initial release
* Initial release
+2
View File
@@ -5,8 +5,10 @@ Prerequisites
-------------
* Python 2.7 or later (http://www.python.org/)
* python-sql 0.4 or later (http://pypi.python.org/pypi/python-sql)
* trytond (http://www.tryton.org/)
* trytond_timesheet (http://www.tryton.org/)
* trytond_party (http://www.tryton.org/)
* trytond_company (http://www.tryton.org/)
Installation
+8 -41
View File
@@ -2,25 +2,26 @@
# this repository contains the full copyright notices and license terms.
from decimal import Decimal
from trytond.model import ModelView, ModelSQL, fields, Unique
from trytond.pyson import Eval
from trytond.cache import Cache
from trytond.transaction import Transaction
from trytond.pool import Pool, PoolMeta
from trytond import backend
from trytond.config import config
__all__ = ['Employee', 'EmployeeCostPrice']
__all__ = ['Employee', 'EmployeeCostPrice', 'price_digits']
__metaclass__ = PoolMeta
price_digits = (16, config.getint(
'timesheet_cost', 'price_decimal', default=4))
class Employee:
__name__ = 'company.employee'
cost_price = fields.Function(fields.Numeric('Cost Price',
digits=(16, Eval('currency_digits', 2)), depends=['currency_digits'],
help="Hourly cost price for this Employee"), 'get_cost_price')
digits=price_digits,
help="Hourly cost price for this Employee"), 'get_cost_price')
cost_prices = fields.One2Many('company.employee_cost_price', 'employee',
'Cost Prices', help="List of hourly cost price over time")
currency_digits = fields.Function(fields.Integer('Currency Digits'),
'on_change_with_currency_digits')
_cost_prices_cache = Cache('company_employee.cost_prices')
def get_cost_price(self, name):
@@ -68,21 +69,6 @@ class Employee:
break
return cost
@fields.depends('company')
def on_change_with_currency_digits(self, name=None):
if self.company:
return self.company.currency.digits
return 2
@staticmethod
def default_currency_digits():
Company = Pool().get('company.company')
company = Transaction().context.get('company')
if company:
company = Company(company)
return company.currency.digits
return 2
class EmployeeCostPrice(ModelSQL, ModelView):
'Employee Cost Price'
@@ -90,12 +76,8 @@ class EmployeeCostPrice(ModelSQL, ModelView):
_rec_name = 'date'
date = fields.Date('Date', required=True, select=True)
cost_price = fields.Numeric('Cost Price',
digits=(16, Eval('currency_digits', 2)),
required=True, depends=['currency_digits'],
help="Hourly cost price")
digits=price_digits, required=True, help="Hourly cost price")
employee = fields.Many2One('company.employee', 'Employee')
currency_digits = fields.Function(fields.Integer('Currency Digits'),
'on_change_with_currency_digits')
@classmethod
def __register__(cls, module_name):
@@ -145,18 +127,3 @@ class EmployeeCostPrice(ModelSQL, ModelView):
Employee = Pool().get('company.employee')
super(EmployeeCostPrice, cls).write(*args)
Employee._cost_prices_cache.clear()
@fields.depends('employee')
def on_change_with_currency_digits(self, name=None):
if self.employee:
return self.employee.company.currency.digits
return 2
@staticmethod
def default_currency_digits():
Company = Pool().get('company.company')
company = Transaction().context.get('company')
if company:
company = Company(company)
return company.currency.digits
return 2
+33
View File
@@ -20,5 +20,38 @@ this repository contains the full copyright notices and license terms. -->
<field name="inherit" ref="company.employee_view_form"/>
<field name="name">employee_form</field>
</record>
<record model="ir.model.access" id="access_employee_cost_price">
<field name="model"
search="[('model', '=', 'company.employee_cost_price')]"/>
<field name="perm_read" eval="False"/>
<field name="perm_write" eval="False"/>
<field name="perm_create" eval="False"/>
<field name="perm_delete" eval="False"/>
</record>
<record model="ir.model.access" id="access_employee_cost_price_admin">
<field name="model"
search="[('model', '=', 'company.employee_cost_price')]"/>
<field name="group" ref="party.group_party_admin"/>
<field name="perm_read" eval="True"/>
<field name="perm_write" eval="True"/>
<field name="perm_create" eval="True"/>
<field name="perm_delete" eval="True"/>
</record>
<record model="ir.model.field.access"
id="model_field_access_employee_cost_price">
<field name="field"
search="[('model.model', '=', 'company.employee'), ('name', '=', 'cost_price')]"/>
<field name="perm_read" eval="False"/>
<field name="perm_write" eval="False"/>
</record>
<record model="ir.model.field.access"
id="model_field_access_employee_cost_price_admin">
<field name="field"
search="[('model.model', '=', 'company.employee'), ('name', '=', 'cost_price')]"/>
<field name="group" ref="party.group_party_admin"/>
<field name="perm_read" eval="True"/>
<field name="perm_write" eval="True"/>
</record>
</data>
</tryton>
+1 -1
View File
@@ -41,7 +41,7 @@ if minor_version % 2:
'hg+http://hg.tryton.org/modules/%s#egg=%s-%s' % (
name[8:], name, version))
requires = []
requires = ['python-sql >= 0.4']
for dep in info.get('depends', []):
if not re.match(r'(ir|res|webdav)(\W|$)', dep):
requires.append(get_require_version('trytond_%s' % dep))
+55 -12
View File
@@ -1,8 +1,12 @@
# This file is part of Tryton. The COPYRIGHT file at the top level of
# this repository contains the full copyright notices and license terms.
from decimal import Decimal
from sql import Null
from trytond.transaction import Transaction
from trytond.pool import Pool, PoolMeta
from trytond.model import fields
from .company import price_digits
__all__ = ['TimesheetLine']
__metaclass__ = PoolMeta
@@ -11,17 +15,56 @@ __metaclass__ = PoolMeta
class TimesheetLine:
__name__ = 'timesheet.line'
def compute_cost(self):
Currency = Pool().get('currency.currency')
cost_price = fields.Numeric('Cost Price',
digits=price_digits, required=True, readonly=True)
cost_price = self.employee.compute_cost_price(date=self.date)
@classmethod
def __register__(cls, module_name):
pool = Pool()
Employee = pool.get('company.employee')
line_company = self.employee.company
work_company = self.work.company
if (line_company != work_company and
line_company.currency != work_company.currency):
with Transaction().set_context(date=self.date):
cost_price = Currency.compute(line_company.currency,
cost_price, work_company.currency)
cursor = Transaction().cursor
table = cls.__table__()
return Decimal(str(self.hours)) * cost_price
super(TimesheetLine, cls).__register__(module_name)
# Migration from 3.6: add cost_price
cursor.execute(*table.select(table.id, table.employee, table.date,
where=(table.cost_price == Null)
& (table.employee != Null)
& (table.date != Null)))
for line_id, employee_id, date in cursor.fetchall():
employee = Employee(employee_id)
cost_price = employee.compute_cost_price(date=date)
cursor.execute(*table.update(
[table.cost_price],
[cost_price],
where=table.id == line_id))
@classmethod
def default_cost_price(cls):
# Needed at creation as cost_price is required
return 0
@classmethod
def create(cls, vlist):
lines = super(TimesheetLine, cls).create(vlist)
cls.sync_cost(lines)
return lines
@classmethod
def write(cls, *args):
super(TimesheetLine, cls).write(*args)
cls.sync_cost(sum(args[0:None:2], []))
@classmethod
def sync_cost(cls, lines):
with Transaction().set_context(_check_access=False):
to_write = []
lines = cls.browse(lines)
for line in lines:
cost_price = line.employee.compute_cost_price(date=line.date)
if cost_price != line.cost_price:
to_write.extend([[line], {'cost_price': cost_price}])
if to_write:
cls.write(*to_write)
+22
View File
@@ -0,0 +1,22 @@
<?xml version="1.0"?>
<!-- This file is part of Tryton. The COPYRIGHT file at the top level of
this repository contains the full copyright notices and license terms. -->
<tryton>
<data>
<record model="ir.model.field.access"
id="model_field_access_timesheet_cost_price">
<field name="field"
search="[('model.model', '=', 'timesheet.line'), ('name', '=', 'cost_price')]"/>
<field name="perm_read" eval="False"/>
<field name="perm_write" eval="False"/>
</record>
<record model="ir.model.field.access"
id="model_field_access_timesheet_cost_price_admin">
<field name="field"
search="[('model.model', '=', 'timesheet.line'), ('name', '=', 'cost_price')]"/>
<field name="group" ref="party.group_party_admin"/>
<field name="perm_read" eval="True"/>
<field name="perm_write" eval="True"/>
</record>
</data>
</tryton>
+2
View File
@@ -3,6 +3,8 @@ version=3.7.0
depends:
ir
company
party
timesheet
xml:
company.xml
timesheet.xml