Files
tryton/work.py
T

146 lines
5.3 KiB
Python
Raw Normal View History

2009-06-04 11:19:01 +02:00
#This file is part of Tryton. The COPYRIGHT file at the top level of
#this repository contains the full copyright notices and license terms.
2010-08-19 22:17:42 +02:00
from decimal import Decimal
2013-09-20 17:34:12 +02:00
import datetime
2012-09-24 22:18:08 +02:00
from trytond.model import fields
2013-05-27 17:55:27 +02:00
from trytond.pyson import Eval, Id
2010-08-19 22:17:42 +02:00
from trytond.transaction import Transaction
2012-09-24 22:18:08 +02:00
from trytond.pool import Pool, PoolMeta
2014-07-17 18:59:36 +02:00
from trytond.tools import reduce_ids, grouped_slice
2012-09-24 22:18:08 +02:00
__all__ = ['Work']
2012-09-24 22:18:08 +02:00
__metaclass__ = PoolMeta
2010-08-19 22:17:42 +02:00
2009-06-04 11:19:01 +02:00
2012-09-24 22:18:08 +02:00
class Work:
__name__ = 'project.work'
2009-06-04 11:19:01 +02:00
product = fields.Many2One('product.product', 'Product',
2013-05-27 17:55:27 +02:00
domain=[
('type', '=', 'service'),
('default_uom_category', '=', Id('product', 'uom_cat_time')),
],
2011-08-21 11:20:49 +02:00
states={
'invisible': ~Eval('timesheet_available'),
},
2014-01-26 14:29:27 +01:00
depends=['timesheet_available'])
2010-01-20 11:03:14 +01:00
list_price = fields.Numeric('List Price',
digits=(16, Eval('currency_digits', 2)), depends=['currency_digits'])
2011-08-21 11:20:49 +02:00
revenue = fields.Function(fields.Numeric('Revenue',
digits=(16, Eval('currency_digits', 2)),
depends=['currency_digits']), 'get_revenue')
2010-03-11 16:52:56 +01:00
cost = fields.Function(fields.Numeric('Cost',
states={
'invisible': ~Eval('timesheet_available'),
},
digits=(16, Eval('currency_digits', 2)),
depends=['currency_digits', 'timesheet_available']), 'get_cost')
2014-01-26 14:29:27 +01:00
currency_digits = fields.Function(fields.Integer('Currency Digits'),
'on_change_with_currency_digits')
2009-06-04 11:19:01 +02:00
2012-09-24 22:18:08 +02:00
@classmethod
def get_cost(cls, works, name):
2013-09-20 17:34:12 +02:00
pool = Pool()
Employee = pool.get('company.employee')
Line = pool.get('timesheet.line')
Work = pool.get('timesheet.work')
transaction = Transaction()
cursor = transaction.cursor
2012-10-17 16:30:06 +02:00
works += cls.search([
2012-09-24 22:18:08 +02:00
('parent', 'child_of', [w.id for w in works]),
('active', '=', True)]) + works
2013-09-20 17:34:12 +02:00
costs = dict.fromkeys([w.id for w in works], 0)
works_to_timesheet = dict((w.work.id, w.id) for w in works)
2012-10-17 16:30:06 +02:00
2013-09-20 17:34:12 +02:00
table_w = Work.__table__()
table_c = Work.__table__()
line = Line.__table__()
timesheet_work_ids = works_to_timesheet.keys()
employee_ids = set()
2014-07-17 18:59:36 +02:00
for sub_ids in grouped_slice(timesheet_work_ids):
2013-09-20 17:34:12 +02:00
red_sql = reduce_ids(table_w.id, sub_ids)
cursor.execute(*table_w.join(table_c,
condition=(table_c.left >= table_w.left)
& (table_c.right <= table_w.right)
).join(line, condition=line.work == table_c.id
).select(line.employee,
where=red_sql,
group_by=line.employee))
employee_ids |= set(r[0] for r in cursor.fetchall())
for employee in Employee.browse(list(employee_ids)):
employee_costs = employee.get_employee_costs()
to_date = None
for from_date, cost in reversed(employee_costs):
with transaction.set_context(
from_date=from_date,
to_date=to_date,
employees=[employee.id]):
for timesheet_work in Work.browse(timesheet_work_ids):
work_id = works_to_timesheet[timesheet_work.id]
costs[work_id] += (
Decimal(str(timesheet_work.hours)) * cost)
to_date = from_date - datetime.timedelta(1)
return costs
2009-06-04 11:19:01 +02:00
2012-09-24 22:18:08 +02:00
@classmethod
def get_revenue(cls, works, name):
2012-10-17 16:30:06 +02:00
works = cls.search([
2012-09-24 22:18:08 +02:00
('parent', 'child_of', [w.id for w in works]),
('active', '=', True)]) + works
2012-10-17 16:30:06 +02:00
2013-03-22 17:49:17 +01:00
def getter(work):
if work.list_price:
return work.list_price * Decimal(str(work.effort))
2009-06-04 11:19:01 +02:00
else:
2013-03-22 17:49:17 +01:00
return Decimal(0)
2009-06-04 11:19:01 +02:00
2013-03-22 17:49:17 +01:00
return cls.sum_tree(works, getter)
2009-06-04 11:19:01 +02:00
2014-01-26 14:29:27 +01:00
@fields.depends('company')
2012-09-24 22:18:08 +02:00
def on_change_with_currency_digits(self, name=None):
if self.company:
return self.company.currency.digits
2009-06-04 13:29:31 +02:00
return 2
2012-09-24 22:18:08 +02:00
@staticmethod
def default_currency_digits():
Company = Pool().get('company.company')
2010-08-19 22:17:42 +02:00
company = Transaction().context.get('company')
if company:
2012-09-24 22:18:08 +02:00
company = Company(company)
2009-06-04 13:29:31 +02:00
return company.currency.digits
return 2
2014-01-26 14:29:27 +01:00
@fields.depends('product', 'party', 'hours', 'company')
2012-09-24 22:18:08 +02:00
def on_change_product(self):
2011-07-03 13:19:08 +02:00
pool = Pool()
2012-09-24 22:18:08 +02:00
User = pool.get('res.user')
ModelData = pool.get('ir.model.data')
Uom = pool.get('product.uom')
Currency = pool.get('currency.currency')
2009-06-04 11:19:01 +02:00
2012-09-24 22:18:08 +02:00
if not self.product:
2009-06-04 11:19:01 +02:00
return {}
2010-08-19 22:17:42 +02:00
context = {}
2009-06-04 11:19:01 +02:00
2012-09-24 22:18:08 +02:00
if self.party:
context['customer'] = self.party.id
2009-06-04 11:19:01 +02:00
2012-09-24 22:18:08 +02:00
hour_uom = Uom(ModelData.get_id('product', 'uom_hour'))
2009-06-04 11:19:01 +02:00
2010-08-19 22:17:42 +02:00
with Transaction().set_context(context):
2012-09-24 22:18:08 +02:00
list_price = Uom.compute_price(self.product.default_uom,
self.product.list_price, hour_uom)
2009-06-04 11:19:01 +02:00
2012-09-24 22:18:08 +02:00
if self.company:
user = User(Transaction().user)
if user.company != self.company:
if user.company.currency != self.company.currency:
list_price = Currency.compute(user.company.currency,
list_price, self.company.currency)
2009-06-04 11:19:01 +02:00
return {'list_price': list_price}