[tryton-debian-vcs] tryton-modules-project-invoice branch debian updated. debian/3.4.1-1-2-ge01152d
Mathias Behrle
tryton-debian-vcs at alioth.debian.org
Thu Apr 23 16:05:17 UTC 2015
The following commit has been merged in the debian branch:
https://alioth.debian.org/plugins/scmgit/cgi-bin/gitweb.cgi/?p=tryton/tryton-modules-project-invoice.git;a=commitdiff;h=debian/3.4.1-1-2-ge01152d
commit e01152db9dbc4d31398d3f8e54f852f8ad253cf8
Author: Mathias Behrle <mathiasb at m9s.biz>
Date: Thu Apr 23 17:00:03 2015 +0200
Merging upstream version 3.6.0.
diff --git a/CHANGELOG b/CHANGELOG
index 21b802a..f9c9c47 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,5 +1,7 @@
-Version 3.4.1 - 2015-02-22
+Version 3.6.0 - 2015-04-20
* Bug fixes (see mercurial logs for details)
+* Add support for PyPy
+* Use TimeDelta field
Version 3.4.0 - 2014-10-20
* Bug fixes (see mercurial logs for details)
diff --git a/PKG-INFO b/PKG-INFO
index de3da34..80fa020 100644
--- a/PKG-INFO
+++ b/PKG-INFO
@@ -1,12 +1,12 @@
Metadata-Version: 1.1
Name: trytond_project_invoice
-Version: 3.4.1
+Version: 3.6.0
Summary: Tryton module to invoice projects
Home-page: http://www.tryton.org/
Author: Tryton
Author-email: issue_tracker at tryton.org
License: GPL-3
-Download-URL: http://downloads.tryton.org/3.4/
+Download-URL: http://downloads.tryton.org/3.6/
Description: trytond_project_invoice
=======================
@@ -65,4 +65,6 @@ Classifier: Natural Language :: Slovenian
Classifier: Natural Language :: Spanish
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 2.7
+Classifier: Programming Language :: Python :: Implementation :: CPython
+Classifier: Programming Language :: Python :: Implementation :: PyPy
Classifier: Topic :: Office/Business
diff --git a/__init__.py b/__init__.py
index 9993976..67b38a4 100644
--- a/__init__.py
+++ b/__init__.py
@@ -1,5 +1,5 @@
-#This file is part of Tryton. The COPYRIGHT file at the top level of
-#this repository contains the full copyright notices and license terms.
+# 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 trytond.pool import Pool
from .work import *
diff --git a/locale/ca_ES.po b/locale/ca_ES.po
index 91bced6..a098c75 100644
--- a/locale/ca_ES.po
+++ b/locale/ca_ES.po
@@ -22,9 +22,9 @@ msgctxt "error:timesheet.line:"
msgid "You can not modify invoiced line."
msgstr "No podeu modificar una línia facturada."
-msgctxt "field:project.work,hours_to_invoice:"
-msgid "Hours to Invoice"
-msgstr "Hores a facturar"
+msgctxt "field:project.work,duration_to_invoice:"
+msgid "Duration to Invoice"
+msgstr "Temps a facturar"
msgctxt "field:project.work,invoice_line:"
msgid "Invoice Line"
@@ -38,9 +38,9 @@ msgctxt "field:project.work,invoiced_amount:"
msgid "Invoiced Amount"
msgstr "Import facturat"
-msgctxt "field:project.work,invoiced_hours:"
-msgid "Invoiced Hours"
-msgstr "Hores facturades"
+msgctxt "field:project.work,invoiced_duration:"
+msgid "Invoiced Duration"
+msgstr "Temps facturat"
msgctxt "field:project.work,project_invoice_method:"
msgid "Invoice Method"
@@ -50,6 +50,10 @@ msgctxt "field:timesheet.line,invoice_line:"
msgid "Invoice Line"
msgstr "Línia de factura"
+msgctxt "model:ir.action,name:act_timesheet_line_form_invoice"
+msgid "Timesheet Lines"
+msgstr "Línies del full de treball"
+
msgctxt "model:ir.action,name:open_invoice"
msgid "Invoices"
msgstr "Factures"
diff --git a/locale/de_DE.po b/locale/de_DE.po
index 13c8d28..4283736 100644
--- a/locale/de_DE.po
+++ b/locale/de_DE.po
@@ -22,9 +22,9 @@ msgctxt "error:timesheet.line:"
msgid "You can not modify invoiced line."
msgstr "Eine abgerechnete Zeile kann nicht geändert werden."
-msgctxt "field:project.work,hours_to_invoice:"
-msgid "Hours to Invoice"
-msgstr "Abrechenbare Stunden"
+msgctxt "field:project.work,duration_to_invoice:"
+msgid "Duration to Invoice"
+msgstr "Fakturierbarer Zeitraum"
msgctxt "field:project.work,invoice_line:"
msgid "Invoice Line"
@@ -38,9 +38,9 @@ msgctxt "field:project.work,invoiced_amount:"
msgid "Invoiced Amount"
msgstr "Abgerechneter Betrag"
-msgctxt "field:project.work,invoiced_hours:"
-msgid "Invoiced Hours"
-msgstr "Abgerechnete Stunden"
+msgctxt "field:project.work,invoiced_duration:"
+msgid "Invoiced Duration"
+msgstr "Fakturierter Zeitraum"
msgctxt "field:project.work,project_invoice_method:"
msgid "Invoice Method"
@@ -50,6 +50,10 @@ msgctxt "field:timesheet.line,invoice_line:"
msgid "Invoice Line"
msgstr "Rechnungsposition"
+msgctxt "model:ir.action,name:act_timesheet_line_form_invoice"
+msgid "Timesheet Lines"
+msgstr "Zeitpositionen"
+
msgctxt "model:ir.action,name:open_invoice"
msgid "Invoices"
msgstr "Rechnungsausgang"
diff --git a/locale/es_AR.po b/locale/es_AR.po
index f138942..ada2fb7 100644
--- a/locale/es_AR.po
+++ b/locale/es_AR.po
@@ -22,9 +22,9 @@ msgctxt "error:timesheet.line:"
msgid "You can not modify invoiced line."
msgstr "No puede modificar una línea facturada."
-msgctxt "field:project.work,hours_to_invoice:"
-msgid "Hours to Invoice"
-msgstr "Horas a facturar"
+msgctxt "field:project.work,duration_to_invoice:"
+msgid "Duration to Invoice"
+msgstr "Duración a facturar"
msgctxt "field:project.work,invoice_line:"
msgid "Invoice Line"
@@ -38,9 +38,9 @@ msgctxt "field:project.work,invoiced_amount:"
msgid "Invoiced Amount"
msgstr "Importe facturado"
-msgctxt "field:project.work,invoiced_hours:"
-msgid "Invoiced Hours"
-msgstr "Horas facturadas"
+msgctxt "field:project.work,invoiced_duration:"
+msgid "Invoiced Duration"
+msgstr "Duración facturada"
msgctxt "field:project.work,project_invoice_method:"
msgid "Invoice Method"
@@ -50,6 +50,10 @@ msgctxt "field:timesheet.line,invoice_line:"
msgid "Invoice Line"
msgstr "Línea de factura"
+msgctxt "model:ir.action,name:act_timesheet_line_form_invoice"
+msgid "Timesheet Lines"
+msgstr "Líneas de parte de trabajo"
+
msgctxt "model:ir.action,name:open_invoice"
msgid "Invoices"
msgstr "Facturas"
diff --git a/locale/es_CO.po b/locale/es_CO.po
index 5107864..54959c2 100644
--- a/locale/es_CO.po
+++ b/locale/es_CO.po
@@ -22,9 +22,9 @@ msgctxt "error:timesheet.line:"
msgid "You can not modify invoiced line."
msgstr "No puede modificar una línea facurada."
-msgctxt "field:project.work,hours_to_invoice:"
-msgid "Hours to Invoice"
-msgstr "Horas a Facturar"
+msgctxt "field:project.work,duration_to_invoice:"
+msgid "Duration to Invoice"
+msgstr "Duración de Factura"
msgctxt "field:project.work,invoice_line:"
msgid "Invoice Line"
@@ -38,9 +38,9 @@ msgctxt "field:project.work,invoiced_amount:"
msgid "Invoiced Amount"
msgstr "Valor Facturado"
-msgctxt "field:project.work,invoiced_hours:"
-msgid "Invoiced Hours"
-msgstr "Horas Facturadas"
+msgctxt "field:project.work,invoiced_duration:"
+msgid "Invoiced Duration"
+msgstr ""
msgctxt "field:project.work,project_invoice_method:"
msgid "Invoice Method"
@@ -50,6 +50,10 @@ msgctxt "field:timesheet.line,invoice_line:"
msgid "Invoice Line"
msgstr "Línea de Factura"
+msgctxt "model:ir.action,name:act_timesheet_line_form_invoice"
+msgid "Timesheet Lines"
+msgstr "Lineas de Registro de Tiempo"
+
msgctxt "model:ir.action,name:open_invoice"
msgid "Invoices"
msgstr "Facturas"
diff --git a/locale/es_EC.po b/locale/es_EC.po
index 0496be7..045b42f 100644
--- a/locale/es_EC.po
+++ b/locale/es_EC.po
@@ -22,13 +22,13 @@ msgctxt "error:timesheet.line:"
msgid "You can not modify invoiced line."
msgstr "No puede modificar una línea facturada."
-msgctxt "field:project.work,hours_to_invoice:"
-msgid "Hours to Invoice"
-msgstr "Horas a Facturar"
+msgctxt "field:project.work,duration_to_invoice:"
+msgid "Duration to Invoice"
+msgstr "Duración a facturar"
msgctxt "field:project.work,invoice_line:"
msgid "Invoice Line"
-msgstr "Línea de Factura"
+msgstr "Línea de factura"
msgctxt "field:project.work,invoice_method:"
msgid "Invoice Method"
@@ -38,9 +38,9 @@ msgctxt "field:project.work,invoiced_amount:"
msgid "Invoiced Amount"
msgstr "Valor Facturado"
-msgctxt "field:project.work,invoiced_hours:"
-msgid "Invoiced Hours"
-msgstr "Horas Facturadas"
+msgctxt "field:project.work,invoiced_duration:"
+msgid "Invoiced Duration"
+msgstr "Duración Facturada"
msgctxt "field:project.work,project_invoice_method:"
msgid "Invoice Method"
@@ -50,6 +50,10 @@ msgctxt "field:timesheet.line,invoice_line:"
msgid "Invoice Line"
msgstr "Línea de Factura"
+msgctxt "model:ir.action,name:act_timesheet_line_form_invoice"
+msgid "Timesheet Lines"
+msgstr "Líneas de parte de trabajo"
+
msgctxt "model:ir.action,name:open_invoice"
msgid "Invoices"
msgstr "Facturas"
diff --git a/locale/es_ES.po b/locale/es_ES.po
index fa04c28..a38f78d 100644
--- a/locale/es_ES.po
+++ b/locale/es_ES.po
@@ -22,9 +22,9 @@ msgctxt "error:timesheet.line:"
msgid "You can not modify invoiced line."
msgstr "No puede modificar una línea facturada."
-msgctxt "field:project.work,hours_to_invoice:"
-msgid "Hours to Invoice"
-msgstr "Horas a facturar"
+msgctxt "field:project.work,duration_to_invoice:"
+msgid "Duration to Invoice"
+msgstr "Tiempo a facturar"
msgctxt "field:project.work,invoice_line:"
msgid "Invoice Line"
@@ -38,9 +38,9 @@ msgctxt "field:project.work,invoiced_amount:"
msgid "Invoiced Amount"
msgstr "Importe facturado"
-msgctxt "field:project.work,invoiced_hours:"
-msgid "Invoiced Hours"
-msgstr "Horas facturadas"
+msgctxt "field:project.work,invoiced_duration:"
+msgid "Invoiced Duration"
+msgstr "Tiempo facturado"
msgctxt "field:project.work,project_invoice_method:"
msgid "Invoice Method"
@@ -50,6 +50,10 @@ msgctxt "field:timesheet.line,invoice_line:"
msgid "Invoice Line"
msgstr "Línea de factura"
+msgctxt "model:ir.action,name:act_timesheet_line_form_invoice"
+msgid "Timesheet Lines"
+msgstr "Líneas de parte de trabajo"
+
msgctxt "model:ir.action,name:open_invoice"
msgid "Invoices"
msgstr "Facturas"
diff --git a/locale/fr_FR.po b/locale/fr_FR.po
index ddbef93..f84995f 100644
--- a/locale/fr_FR.po
+++ b/locale/fr_FR.po
@@ -22,9 +22,9 @@ msgctxt "error:timesheet.line:"
msgid "You can not modify invoiced line."
msgstr "Vous ne pouvez pas modifier une ligne facturée."
-msgctxt "field:project.work,hours_to_invoice:"
-msgid "Hours to Invoice"
-msgstr "Heures à facturer"
+msgctxt "field:project.work,duration_to_invoice:"
+msgid "Duration to Invoice"
+msgstr "Durée à facturer"
msgctxt "field:project.work,invoice_line:"
msgid "Invoice Line"
@@ -38,9 +38,9 @@ msgctxt "field:project.work,invoiced_amount:"
msgid "Invoiced Amount"
msgstr "Montant facturé"
-msgctxt "field:project.work,invoiced_hours:"
-msgid "Invoiced Hours"
-msgstr "Heures facturées"
+msgctxt "field:project.work,invoiced_duration:"
+msgid "Invoiced Duration"
+msgstr "Durée facturée"
msgctxt "field:project.work,project_invoice_method:"
msgid "Invoice Method"
@@ -50,6 +50,10 @@ msgctxt "field:timesheet.line,invoice_line:"
msgid "Invoice Line"
msgstr "Ligne de facture"
+msgctxt "model:ir.action,name:act_timesheet_line_form_invoice"
+msgid "Timesheet Lines"
+msgstr "Lignes de feuille de présence"
+
msgctxt "model:ir.action,name:open_invoice"
msgid "Invoices"
msgstr "Factures"
diff --git a/locale/sl_SI.po b/locale/sl_SI.po
index 5bcd25d..ffb5092 100644
--- a/locale/sl_SI.po
+++ b/locale/sl_SI.po
@@ -22,9 +22,9 @@ msgctxt "error:timesheet.line:"
msgid "You can not modify invoiced line."
msgstr "Obračunane postavke ni možne popraviti."
-msgctxt "field:project.work,hours_to_invoice:"
-msgid "Hours to Invoice"
-msgstr "Ure za obračun"
+msgctxt "field:project.work,duration_to_invoice:"
+msgid "Duration to Invoice"
+msgstr "Čas do zaračunanja"
msgctxt "field:project.work,invoice_line:"
msgid "Invoice Line"
@@ -38,9 +38,9 @@ msgctxt "field:project.work,invoiced_amount:"
msgid "Invoiced Amount"
msgstr "Zaračunan znesek"
-msgctxt "field:project.work,invoiced_hours:"
-msgid "Invoiced Hours"
-msgstr "Zaračunane ure"
+msgctxt "field:project.work,invoiced_duration:"
+msgid "Invoiced Duration"
+msgstr "Zaračunan porabljen čas"
msgctxt "field:project.work,project_invoice_method:"
msgid "Invoice Method"
@@ -50,6 +50,10 @@ msgctxt "field:timesheet.line,invoice_line:"
msgid "Invoice Line"
msgstr "Postavka računa"
+msgctxt "model:ir.action,name:act_timesheet_line_form_invoice"
+msgid "Timesheet Lines"
+msgstr "Evidenca prisotnosti"
+
msgctxt "model:ir.action,name:open_invoice"
msgid "Invoices"
msgstr "Računi"
diff --git a/setup.py b/setup.py
index cb4c355..bcd7b2b 100644
--- a/setup.py
+++ b/setup.py
@@ -1,6 +1,6 @@
#!/usr/bin/env 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.
+# 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 setuptools import setup
import re
@@ -41,7 +41,7 @@ if minor_version % 2:
'hg+http://hg.tryton.org/modules/%s#egg=%s-%s' % (
name[8:], name, version))
-requires = ['python-sql']
+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))
@@ -92,6 +92,8 @@ setup(name=name,
'Natural Language :: Spanish',
'Operating System :: OS Independent',
'Programming Language :: Python :: 2.7',
+ 'Programming Language :: Python :: Implementation :: CPython',
+ 'Programming Language :: Python :: Implementation :: PyPy',
'Topic :: Office/Business',
],
license='GPL-3',
diff --git a/tests/__init__.py b/tests/__init__.py
index 4f749be..738b8b4 100644
--- a/tests/__init__.py
+++ b/tests/__init__.py
@@ -1,5 +1,5 @@
-#This file is part of Tryton. The COPYRIGHT file at the top level of
-#this repository contains the full copyright notices and license terms.
+# 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 .test_project_invoice import suite
diff --git a/tests/scenario_project_invoice_effort.rst b/tests/scenario_project_invoice_effort.rst
index 6d1192c..46ccbcf 100644
--- a/tests/scenario_project_invoice_effort.rst
+++ b/tests/scenario_project_invoice_effort.rst
@@ -2,16 +2,18 @@
Project Invoice Effort Scenario
===============================
-=============
-General Setup
-=============
-
Imports::
>>> import datetime
>>> from dateutil.relativedelta import relativedelta
>>> from decimal import Decimal
>>> from proteus import config, Model, Wizard
+ >>> from trytond.modules.company.tests.tools import create_company, \
+ ... get_company
+ >>> from trytond.modules.account.tests.tools import create_chart, \
+ ... get_accounts
+ >>> from.trytond.modules.account_invoice.tests.tools import \
+ ... create_payment_term
>>> today = datetime.date.today()
Create database::
@@ -25,34 +27,13 @@ Install project_invoice::
>>> module, = Module.find([
... ('name', '=', 'project_invoice'),
... ])
- >>> Module.install([module.id], config.context)
+ >>> module.click('install')
>>> Wizard('ir.module.module.install_upgrade').execute('upgrade')
Create company::
- >>> Currency = Model.get('currency.currency')
- >>> CurrencyRate = Model.get('currency.currency.rate')
- >>> Company = Model.get('company.company')
- >>> Party = Model.get('party.party')
- >>> company_config = Wizard('company.company.config')
- >>> company_config.execute('company')
- >>> company = company_config.form
- >>> party = Party(name='Dunder Mifflin')
- >>> party.save()
- >>> company.party = party
- >>> currencies = Currency.find([('code', '=', 'USD')])
- >>> if not currencies:
- ... currency = Currency(name='Euro', symbol=u'$', code='USD',
- ... rounding=Decimal('0.01'), mon_grouping='[3, 3, 0]',
- ... mon_decimal_point='.')
- ... currency.save()
- ... CurrencyRate(date=today + relativedelta(month=1, day=1),
- ... rate=Decimal('1.0'), currency=currency).save()
- ... else:
- ... currency, = currencies
- >>> company.currency = currency
- >>> company_config.execute('add')
- >>> company, = Company.find()
+ >>> _ = create_company()
+ >>> company = get_company()
Reload the context::
@@ -85,37 +66,13 @@ Create project invoice user::
Create chart of accounts::
- >>> AccountTemplate = Model.get('account.account.template')
- >>> Account = Model.get('account.account')
- >>> account_template, = AccountTemplate.find([('parent', '=', None)])
- >>> create_chart = Wizard('account.create_chart')
- >>> create_chart.execute('account')
- >>> create_chart.form.account_template = account_template
- >>> create_chart.form.company = company
- >>> create_chart.execute('create_account')
- >>> receivable, = Account.find([
- ... ('kind', '=', 'receivable'),
- ... ('company', '=', company.id),
- ... ])
- >>> payable, = Account.find([
- ... ('kind', '=', 'payable'),
- ... ('company', '=', company.id),
- ... ])
- >>> revenue, = Account.find([
- ... ('kind', '=', 'revenue'),
- ... ('company', '=', company.id),
- ... ])
- >>> create_chart.form.account_receivable = receivable
- >>> create_chart.form.account_payable = payable
- >>> create_chart.execute('create_properties')
+ >>> _ = create_chart(company)
+ >>> accounts = get_accounts(company)
+ >>> revenue = accounts['revenue']
Create payment term::
- >>> PaymentTerm = Model.get('account.invoice.payment_term')
- >>> PaymentTermLine = Model.get('account.invoice.payment_term.line')
- >>> payment_term = PaymentTerm(name='Term')
- >>> payment_term_line = PaymentTermLine(type='remainder', days=40)
- >>> payment_term.lines.append(payment_term_line)
+ >>> payment_term = create_payment_term()
>>> payment_term.save()
Create customer::
@@ -167,7 +124,7 @@ Create a Project::
>>> project.party = customer
>>> project.project_invoice_method = 'effort'
>>> project.product = product
- >>> project.effort = 1
+ >>> project.effort_duration = datetime.timedelta(hours=1)
>>> task = ProjectWork()
>>> work = TimesheetWork()
>>> work.name = 'Task 1'
@@ -175,18 +132,18 @@ Create a Project::
>>> task.work = work
>>> task.type = 'task'
>>> task.product = product
- >>> task.effort = 5
+ >>> task.effort_duration = datetime.timedelta(hours=5)
>>> project.children.append(task)
>>> project.save()
>>> task, = project.children
-Check project hours::
+Check project duration::
>>> project.reload()
- >>> project.invoiced_hours
- 0.0
- >>> project.hours_to_invoice
- 0.0
+ >>> project.invoiced_duration
+ datetime.timedelta(0)
+ >>> project.duration_to_invoice
+ datetime.timedelta(0)
>>> project.invoiced_amount
Decimal('0')
@@ -195,25 +152,24 @@ Do 1 task::
>>> task.state = 'done'
>>> task.save()
-Check project hours::
+Check project duration::
>>> project.reload()
- >>> project.invoiced_hours
- 0.0
- >>> project.hours_to_invoice
- 5.0
+ >>> project.invoiced_duration
+ datetime.timedelta(0)
+ >>> project.duration_to_invoice
+ datetime.timedelta(0, 18000)
>>> project.invoiced_amount
Decimal('0')
Invoice project::
>>> config.user = project_invoice_user.id
- >>> ProjectWork.invoice([project.id], config.context)
- >>> project.reload()
- >>> project.invoiced_hours
- 5.0
- >>> project.hours_to_invoice
- 0.0
+ >>> project.click('invoice')
+ >>> project.invoiced_duration
+ datetime.timedelta(0, 18000)
+ >>> project.duration_to_invoice
+ datetime.timedelta(0)
>>> project.invoiced_amount
Decimal('100.00')
@@ -223,24 +179,23 @@ Do project::
>>> project.state = 'done'
>>> project.save()
-Check project hours::
+Check project duration::
>>> project.reload()
- >>> project.invoiced_hours
- 5.0
- >>> project.hours_to_invoice
- 1.0
+ >>> project.invoiced_duration
+ datetime.timedelta(0, 18000)
+ >>> project.duration_to_invoice
+ datetime.timedelta(0, 3600)
>>> project.invoiced_amount
Decimal('100.00')
Invoice again project::
>>> config.user = project_invoice_user.id
- >>> ProjectWork.invoice([project.id], config.context)
- >>> project.reload()
- >>> project.invoiced_hours
- 6.0
- >>> project.hours_to_invoice
- 0.0
+ >>> project.click('invoice')
+ >>> project.invoiced_duration
+ datetime.timedelta(0, 21600)
+ >>> project.duration_to_invoice
+ datetime.timedelta(0)
>>> project.invoiced_amount
Decimal('120.00')
diff --git a/tests/scenario_project_invoice_timesheet.rst b/tests/scenario_project_invoice_timesheet.rst
index 0163f69..351963f 100644
--- a/tests/scenario_project_invoice_timesheet.rst
+++ b/tests/scenario_project_invoice_timesheet.rst
@@ -2,16 +2,18 @@
Project Invoice Timesheet Scenario
==================================
-=============
-General Setup
-=============
-
Imports::
>>> import datetime
>>> from dateutil.relativedelta import relativedelta
>>> from decimal import Decimal
>>> from proteus import config, Model, Wizard
+ >>> from trytond.modules.company.tests.tools import create_company, \
+ ... get_company
+ >>> from trytond.modules.account.tests.tools import create_chart, \
+ ... get_accounts
+ >>> from.trytond.modules.account_invoice.tests.tools import \
+ ... create_payment_term
>>> today = datetime.date.today()
Create database::
@@ -25,34 +27,13 @@ Install project_invoice::
>>> module, = Module.find([
... ('name', '=', 'project_invoice'),
... ])
- >>> Module.install([module.id], config.context)
+ >>> module.click('install')
>>> Wizard('ir.module.module.install_upgrade').execute('upgrade')
Create company::
- >>> Currency = Model.get('currency.currency')
- >>> CurrencyRate = Model.get('currency.currency.rate')
- >>> Company = Model.get('company.company')
- >>> Party = Model.get('party.party')
- >>> company_config = Wizard('company.company.config')
- >>> company_config.execute('company')
- >>> company = company_config.form
- >>> party = Party(name='Dunder Mifflin')
- >>> party.save()
- >>> company.party = party
- >>> currencies = Currency.find([('code', '=', 'USD')])
- >>> if not currencies:
- ... currency = Currency(name='Euro', symbol=u'$', code='USD',
- ... rounding=Decimal('0.01'), mon_grouping='[3, 3, 0]',
- ... mon_decimal_point='.')
- ... currency.save()
- ... CurrencyRate(date=today + relativedelta(month=1, day=1),
- ... rate=Decimal('1.0'), currency=currency).save()
- ... else:
- ... currency, = currencies
- >>> company.currency = currency
- >>> company_config.execute('add')
- >>> company, = Company.find()
+ >>> _ = create_company()
+ >>> company = get_company()
Reload the context::
@@ -85,37 +66,13 @@ Create project invoice user::
Create chart of accounts::
- >>> AccountTemplate = Model.get('account.account.template')
- >>> Account = Model.get('account.account')
- >>> account_template, = AccountTemplate.find([('parent', '=', None)])
- >>> create_chart = Wizard('account.create_chart')
- >>> create_chart.execute('account')
- >>> create_chart.form.account_template = account_template
- >>> create_chart.form.company = company
- >>> create_chart.execute('create_account')
- >>> receivable, = Account.find([
- ... ('kind', '=', 'receivable'),
- ... ('company', '=', company.id),
- ... ])
- >>> payable, = Account.find([
- ... ('kind', '=', 'payable'),
- ... ('company', '=', company.id),
- ... ])
- >>> revenue, = Account.find([
- ... ('kind', '=', 'revenue'),
- ... ('company', '=', company.id),
- ... ])
- >>> create_chart.form.account_receivable = receivable
- >>> create_chart.form.account_payable = payable
- >>> create_chart.execute('create_properties')
+ >>> _ = create_chart(company)
+ >>> accounts = get_accounts(company)
+ >>> revenue = accounts['revenue']
Create payment term::
- >>> PaymentTerm = Model.get('account.invoice.payment_term')
- >>> PaymentTermLine = Model.get('account.invoice.payment_term.line')
- >>> payment_term = PaymentTerm(name='Term')
- >>> payment_term_line = PaymentTermLine(type='remainder', days=40)
- >>> payment_term.lines.append(payment_term_line)
+ >>> payment_term = create_payment_term()
>>> payment_term.save()
Create customer::
@@ -183,34 +140,33 @@ Create timesheets::
>>> TimesheetLine = Model.get('timesheet.line')
>>> line = TimesheetLine()
>>> line.employee = employee
- >>> line.hours = 3
+ >>> line.duration = datetime.timedelta(hours=3)
>>> line.work = task.work
>>> line.save()
>>> line = TimesheetLine()
>>> line.employee = employee
- >>> line.hours = 2
+ >>> line.duration = datetime.timedelta(hours=2)
>>> line.work = project.work
>>> line.save()
-Check project hours::
+Check project duration::
>>> project.reload()
- >>> project.invoiced_hours
- 0.0
- >>> project.hours_to_invoice
- 5.0
+ >>> project.invoiced_duration
+ datetime.timedelta(0)
+ >>> project.duration_to_invoice
+ datetime.timedelta(0, 18000)
>>> project.invoiced_amount
Decimal('0')
Invoice project::
>>> config.user = project_invoice_user.id
- >>> ProjectWork.invoice([project.id], config.context)
- >>> project.reload()
- >>> project.invoiced_hours
- 5.0
- >>> project.hours_to_invoice
- 0.0
+ >>> project.click('invoice')
+ >>> project.invoiced_duration
+ datetime.timedelta(0, 18000)
+ >>> project.duration_to_invoice
+ datetime.timedelta(0)
>>> project.invoiced_amount
Decimal('100.000000000000')
@@ -220,28 +176,27 @@ Create more timesheets::
>>> TimesheetLine = Model.get('timesheet.line')
>>> line = TimesheetLine()
>>> line.employee = employee
- >>> line.hours = 4
+ >>> line.duration = datetime.timedelta(hours=4)
>>> line.work = task.work
>>> line.save()
-Check project hours::
+Check project duration::
>>> project.reload()
- >>> project.invoiced_hours
- 5.0
- >>> project.hours_to_invoice
- 4.0
+ >>> project.invoiced_duration
+ datetime.timedelta(0, 18000)
+ >>> project.duration_to_invoice
+ datetime.timedelta(0, 14400)
>>> project.invoiced_amount
Decimal('100.000000000000')
Invoice again project::
>>> config.user = project_invoice_user.id
- >>> ProjectWork.invoice([project.id], config.context)
- >>> project.reload()
- >>> project.invoiced_hours
- 9.0
- >>> project.hours_to_invoice
- 0.0
+ >>> project.click('invoice')
+ >>> project.invoiced_duration
+ datetime.timedelta(0, 32400)
+ >>> project.duration_to_invoice
+ datetime.timedelta(0)
>>> project.invoiced_amount
Decimal('180.000000000000')
diff --git a/tests/test_project_invoice.py b/tests/test_project_invoice.py
index 22ee69a..7f7f2a6 100644
--- a/tests/test_project_invoice.py
+++ b/tests/test_project_invoice.py
@@ -1,25 +1,15 @@
-#This file is part of Tryton. The COPYRIGHT file at the top level of
-#this repository contains the full copyright notices and license terms.
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
import unittest
import doctest
import trytond.tests.test_tryton
-from trytond.tests.test_tryton import test_view, test_depends
+from trytond.tests.test_tryton import ModuleTestCase
from trytond.tests.test_tryton import doctest_setup, doctest_teardown
-class ProjectInvoiceTestCase(unittest.TestCase):
+class ProjectInvoiceTestCase(ModuleTestCase):
'Test Project Invoice module'
-
- def setUp(self):
- trytond.tests.test_tryton.install_module('project_invoice')
-
- def test0005views(self):
- 'Test views'
- test_view('project_invoice')
-
- def test0006depends(self):
- 'Test depends'
- test_depends()
+ module = 'project_invoice'
def suite():
diff --git a/timesheet.py b/timesheet.py
index c14998f..bbf6cc3 100644
--- a/timesheet.py
+++ b/timesheet.py
@@ -1,5 +1,5 @@
-#This file is part of Tryton. The COPYRIGHT file at the top level of
-#this repository contains the full copyright notices and license terms.
+# 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 trytond.model import fields
from trytond.pool import PoolMeta
diff --git a/timesheet.xml b/timesheet.xml
index c773caf..16436b4 100644
--- a/timesheet.xml
+++ b/timesheet.xml
@@ -14,4 +14,23 @@ this repository contains the full copyright notices and license terms. -->
<field name="group" ref="group_project_invoice"/>
</record>
</data>
+
+ <record model="ir.action.act_window" id="act_timesheet_line_form_invoice">
+ <field name="name">Timesheet Lines</field>
+ <field name="res_model">timesheet.line</field>
+ <field name="domain"
+ eval="[('invoice_line.invoice', 'in', Eval('active_ids'))]"
+ pyson="1"/>
+ </record>
+ <record model="ir.action.keyword"
+ id="act_timesheet_line_form_invoice_keyword1">
+ <field name="keyword">form_relate</field>
+ <field name="model">account.invoice,-1</field>
+ <field name="action" ref="act_timesheet_line_form_invoice"/>
+ </record>
+ <record model="ir.action-res.group"
+ id="act_timesheet_line_form_invoice-group_timesheet_admin">
+ <field name="action" ref="act_timesheet_line_form_invoice"/>
+ <field name="group" ref="timesheet.group_timesheet_admin"/>
+ </record>
</tryton>
diff --git a/tryton.cfg b/tryton.cfg
index a93d565..0c36ed3 100644
--- a/tryton.cfg
+++ b/tryton.cfg
@@ -1,5 +1,5 @@
[tryton]
-version=3.4.1
+version=3.6.0
depends:
ir
project
diff --git a/trytond_project_invoice.egg-info/PKG-INFO b/trytond_project_invoice.egg-info/PKG-INFO
index 67c7953..bb84062 100644
--- a/trytond_project_invoice.egg-info/PKG-INFO
+++ b/trytond_project_invoice.egg-info/PKG-INFO
@@ -1,12 +1,12 @@
Metadata-Version: 1.1
Name: trytond-project-invoice
-Version: 3.4.1
+Version: 3.6.0
Summary: Tryton module to invoice projects
Home-page: http://www.tryton.org/
Author: Tryton
Author-email: issue_tracker at tryton.org
License: GPL-3
-Download-URL: http://downloads.tryton.org/3.4/
+Download-URL: http://downloads.tryton.org/3.6/
Description: trytond_project_invoice
=======================
@@ -65,4 +65,6 @@ Classifier: Natural Language :: Slovenian
Classifier: Natural Language :: Spanish
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 2.7
+Classifier: Programming Language :: Python :: Implementation :: CPython
+Classifier: Programming Language :: Python :: Implementation :: PyPy
Classifier: Topic :: Office/Business
diff --git a/trytond_project_invoice.egg-info/requires.txt b/trytond_project_invoice.egg-info/requires.txt
index 1698eac..ef1f62c 100644
--- a/trytond_project_invoice.egg-info/requires.txt
+++ b/trytond_project_invoice.egg-info/requires.txt
@@ -1,8 +1,8 @@
-python-sql
-trytond_project >= 3.4, < 3.5
-trytond_project_revenue >= 3.4, < 3.5
-trytond_timesheet >= 3.4, < 3.5
-trytond_account >= 3.4, < 3.5
-trytond_account_invoice >= 3.4, < 3.5
-trytond_product >= 3.4, < 3.5
-trytond >= 3.4, < 3.5
\ No newline at end of file
+python-sql >= 0.4
+trytond_project >= 3.6, < 3.7
+trytond_project_revenue >= 3.6, < 3.7
+trytond_timesheet >= 3.6, < 3.7
+trytond_account >= 3.6, < 3.7
+trytond_account_invoice >= 3.6, < 3.7
+trytond_product >= 3.6, < 3.7
+trytond >= 3.6, < 3.7
\ No newline at end of file
diff --git a/view/work_form.xml b/view/work_form.xml
index 57b8b2d..58a479f 100644
--- a/view/work_form.xml
+++ b/view/work_form.xml
@@ -11,14 +11,12 @@ this repository contains the full copyright notices and license terms. -->
<xpath expr="/form/notebook/page[@id='general']/separator[@name='comment']"
position="before">
<newline/>
- <label name="invoiced_hours"/>
- <field name="invoiced_hours" widget="float_time"
- float_time="company_work_time"/>
+ <label name="invoiced_duration"/>
+ <field name="invoiced_duration"/>
<label name="invoiced_amount"/>
<field name="invoiced_amount"/>
- <label name="hours_to_invoice"/>
- <field name="hours_to_invoice" widget="float_time"
- float_time="company_work_time"/>
+ <label name="duration_to_invoice"/>
+ <field name="duration_to_invoice"/>
</xpath>
<xpath expr="/form/notebook/page[@id='general']/group/group[@id='buttons']"
position="inside">
diff --git a/work.py b/work.py
index 7f44401..8734e22 100644
--- a/work.py
+++ b/work.py
@@ -1,7 +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.
+# 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 __future__ import division
+
from itertools import groupby
from decimal import Decimal
+import datetime
+
+from sql import Null
from sql.aggregate import Sum
from trytond.model import ModelView, fields
@@ -28,21 +33,21 @@ class Work:
project_invoice_method = fields.Selection(INVOICE_METHODS,
'Invoice Method',
states={
- 'readonly': Bool(Eval('invoiced_hours')),
+ 'readonly': Bool(Eval('invoiced_duration')),
'required': Eval('type') == 'project',
'invisible': Eval('type') != 'project',
},
- depends=['invoiced_hours', 'type'])
+ depends=['invoiced_duration', 'type'])
invoice_method = fields.Function(fields.Selection(INVOICE_METHODS,
'Invoice Method'), 'get_invoice_method')
- invoiced_hours = fields.Function(fields.Float('Invoiced Hours',
- digits=(16, 2),
+ invoiced_duration = fields.Function(fields.TimeDelta('Invoiced Duration',
+ 'company_work_time',
states={
'invisible': Eval('invoice_method') == 'manual',
},
depends=['invoice_method']), 'get_invoice_values')
- hours_to_invoice = fields.Function(fields.Float('Hours to Invoice',
- digits=(16, 2),
+ duration_to_invoice = fields.Function(fields.TimeDelta(
+ 'Duration to Invoice', 'company_work_time',
states={
'invisible': Eval('invoice_method') == 'manual',
},
@@ -65,7 +70,7 @@ class Work:
'invisible': ((Eval('type') != 'project')
| (Eval('project_invoice_method', 'manual')
== 'manual')),
- 'readonly': ~Eval('hours_to_invoice'),
+ 'readonly': ~Eval('duration_to_invoice'),
},
})
cls._error_messages.update({
@@ -94,39 +99,45 @@ class Work:
else:
return 'manual'
+ @property
+ def effort_hours(self):
+ if not self.effort_duration:
+ return 0
+ return self.effort_duration.total_seconds() / 60 / 60
+
@staticmethod
- def default_invoiced_hours():
- return 0.
+ def default_invoiced_duration():
+ return datetime.timedelta()
@staticmethod
- def _get_invoiced_hours_manual(works):
+ def _get_invoiced_duration_manual(works):
return {}
@staticmethod
- def _get_invoiced_hours_effort(works):
- return dict((w.id, w.effort) for w in works
+ def _get_invoiced_duration_effort(works):
+ return dict((w.id, w.effort_duration) for w in works
if w.invoice_line)
@classmethod
- def _get_invoiced_hours_timesheet(cls, works):
- return cls._get_hours_timesheet(works, True)
+ def _get_invoiced_duration_timesheet(cls, works):
+ return cls._get_duration_timesheet(works, True)
@staticmethod
- def default_hours_to_invoice():
- return 0.
+ def default_duration_to_invoice():
+ return datetime.timedelta()
@staticmethod
- def _get_hours_to_invoice_manual(works):
+ def _get_duration_to_invoice_manual(works):
return {}
@staticmethod
- def _get_hours_to_invoice_effort(works):
- return dict((w.id, w.effort) for w in works
+ def _get_duration_to_invoice_effort(works):
+ return dict((w.id, w.effort_duration) for w in works
if w.state == 'done' and not w.invoice_line)
@classmethod
- def _get_hours_to_invoice_timesheet(cls, works):
- return cls._get_hours_timesheet(works, False)
+ def _get_duration_to_invoice_timesheet(cls, works):
+ return cls._get_duration_timesheet(works, False)
@staticmethod
def default_invoiced_amount():
@@ -178,27 +189,30 @@ class Work:
return amounts
@staticmethod
- def _get_hours_timesheet(works, invoiced):
+ def _get_duration_timesheet(works, invoiced):
pool = Pool()
TimesheetLine = pool.get('timesheet.line')
cursor = Transaction().cursor
line = TimesheetLine.__table__()
- hours = {}
+ durations = {}
twork2work = dict((w.work.id, w.id) for w in works)
ids = twork2work.keys()
for sub_ids in grouped_slice(ids):
red_sql = reduce_ids(line.work, sub_ids)
if invoiced:
- where = line.invoice_line != None
+ where = line.invoice_line != Null
else:
- where = line.invoice_line == None
- cursor.execute(*line.select(line.work, Sum(line.hours),
+ where = line.invoice_line == Null
+ cursor.execute(*line.select(line.work, Sum(line.duration),
where=red_sql & where,
group_by=line.work))
- hours.update(dict((twork2work[w], h)
- for w, h in cursor.fetchall()))
- return hours
+ for twork_id, duration in cursor.fetchall():
+ # SQLite uses float for SUM
+ if not isinstance(duration, datetime.timedelta):
+ duration = datetime.timedelta(seconds=duration)
+ durations[twork2work[twork_id]] = duration
+ return durations
@classmethod
def get_invoice_values(cls, works, name):
@@ -326,14 +340,16 @@ class Work:
return []
def _get_lines_to_invoice_effort(self):
- if not self.invoice_line and self.effort and self.state == 'done':
+ if (not self.invoice_line
+ and self.effort_hours
+ and self.state == 'done'):
if not self.product:
self.raise_user_error('missing_product', (self.rec_name,))
elif self.list_price is None:
self.raise_user_error('missing_list_price', (self.rec_name,))
return [{
'product': self.product,
- 'quantity': self.effort,
+ 'quantity': self.effort_hours,
'unit_price': self.list_price,
'origin': self,
'description': self.work.name,
--
tryton-modules-project-invoice
More information about the tryton-debian-vcs
mailing list