Files
tryton/work.py
T
2012-10-17 16:30:06 +02:00

171 lines
5.8 KiB
Python

#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 trytond.model import fields
from trytond.pyson import Eval
from trytond.transaction import Transaction
from trytond.pool import Pool, PoolMeta
__all__ = ['TimesheetLine', 'Work']
__metaclass__ = PoolMeta
class TimesheetLine:
__name__ = 'timesheet.line'
def compute_cost(self):
Currency = Pool().get('currency.currency')
cost_price = self.employee.compute_cost_price(date=self.date)
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)
return Decimal(str(self.hours)) * cost_price
class Work:
__name__ = 'project.work'
product = fields.Many2One('product.product', 'Product',
states={
'invisible': ~Eval('timesheet_available'),
},
depends=['timesheet_available'],
on_change=['product', 'party', 'hours', 'company'])
list_price = fields.Numeric('List Price',
digits=(16, Eval('currency_digits', 2)), depends=['currency_digits'])
revenue = fields.Function(fields.Numeric('Revenue',
digits=(16, Eval('currency_digits', 2)),
depends=['currency_digits']), 'get_revenue')
cost = fields.Function(fields.Numeric('Cost',
states={
'invisible': ~Eval('timesheet_available'),
},
digits=(16, Eval('currency_digits', 2)),
depends=['currency_digits', 'timesheet_available']), 'get_cost')
currency_digits = fields.Function(fields.Integer('Currency Digits',
on_change_with=['company']), 'on_change_with_currency_digits')
@classmethod
def get_cost(cls, works, name):
works += cls.search([
('parent', 'child_of', [w.id for w in works]),
('active', '=', True)]) + works
works = set(works)
costs = {}
id2work = {}
leafs = set()
for work in works:
id2work[work.id] = work
if not work.children:
leafs.add(work.id)
costs[work.id] = Decimal('0')
for ts_line in work.timesheet_lines:
costs[work.id] += ts_line.compute_cost()
while leafs:
for work_id in leafs:
work = id2work[work_id]
works.remove(work)
if not work.active:
continue
if work.parent and work.parent.id in costs:
costs[work.parent.id] += costs[work_id]
next_leafs = set(w.id for w in works)
for work in works:
if not work.parent:
continue
if work.parent.id in next_leafs and work.parent in works:
next_leafs.remove(work.parent.id)
leafs = next_leafs
return costs
@classmethod
def get_revenue(cls, works, name):
works = cls.search([
('parent', 'child_of', [w.id for w in works]),
('active', '=', True)]) + works
works = set(works)
revenues = {}
id2work = {}
leafs = set()
for work in works:
id2work[work.id] = work
if not work.children:
leafs.add(work.id)
if work.type == 'task' and work.list_price:
revenues[work.id] = (work.list_price
* Decimal(str(work.total_effort)))
else:
revenues[work.id] = Decimal('0')
while leafs:
for work_id in leafs:
work = id2work[work_id]
works.remove(work)
if not work.active:
continue
if work.parent and work.parent.id in revenues:
revenues[work.parent.id] += revenues[work_id]
next_leafs = set(w.id for w in works)
for work in works:
if not work.parent:
continue
if work.parent.id in next_leafs and work.parent in works:
next_leafs.remove(work.parent.id)
leafs = next_leafs
return revenues
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
def on_change_product(self):
pool = Pool()
User = pool.get('res.user')
ModelData = pool.get('ir.model.data')
Uom = pool.get('product.uom')
Currency = pool.get('currency.currency')
if not self.product:
return {}
context = {}
if self.party:
context['customer'] = self.party.id
hour_uom = Uom(ModelData.get_id('product', 'uom_hour'))
with Transaction().set_context(context):
list_price = Uom.compute_price(self.product.default_uom,
self.product.list_price, hour_uom)
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)
return {'list_price': list_price}