diff --git a/CHANGELOG b/CHANGELOG
index 1b06dc3d47..874cf4a35c 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -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
\ No newline at end of file
+* Initial release
diff --git a/INSTALL b/INSTALL
index dfd0a5a374..87ed3d7294 100644
--- a/INSTALL
+++ b/INSTALL
@@ -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
diff --git a/company.py b/company.py
index 76df8d7aba..0f6fbd667e 100644
--- a/company.py
+++ b/company.py
@@ -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
diff --git a/company.xml b/company.xml
index 1c3fdbf3cb..a5ded29fab 100644
--- a/company.xml
+++ b/company.xml
@@ -20,5 +20,38 @@ this repository contains the full copyright notices and license terms. -->
employee_form
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/setup.py b/setup.py
index 57b51fc716..491a800ecc 100644
--- a/setup.py
+++ b/setup.py
@@ -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))
diff --git a/timesheet.py b/timesheet.py
index 367da06115..9c8af79acb 100644
--- a/timesheet.py
+++ b/timesheet.py
@@ -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)
diff --git a/timesheet.xml b/timesheet.xml
new file mode 100644
index 0000000000..c8b33c898c
--- /dev/null
+++ b/timesheet.xml
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/tryton.cfg b/tryton.cfg
index fc4d3c7c8f..05ba5feca5 100644
--- a/tryton.cfg
+++ b/tryton.cfg
@@ -3,6 +3,8 @@ version=3.7.0
depends:
ir
company
+ party
timesheet
xml:
company.xml
+ timesheet.xml