diff --git a/addons/account/account_analytic_line.py b/addons/account/account_analytic_line.py
index 7a66dd4f175..bb13f1a5776 100644
--- a/addons/account/account_analytic_line.py
+++ b/addons/account/account_analytic_line.py
@@ -75,6 +75,9 @@ class account_analytic_line(osv.osv):
unit=False, journal_id=False, context=None):
if context==None:
context={}
+ if not journal_id:
+ j_ids = self.pool.get('account.analytic.journal').search(cr, uid, [('type','=','purchase')])
+ j_id = j_ids and j_ids[0] or False
if not journal_id or not prod_id:
return {}
product_obj = self.pool.get('product.product')
@@ -86,7 +89,7 @@ class account_analytic_line(osv.osv):
result = 0.0
is_purchase = False
- if j_id.type == 'purchase':
+ if j_id.type <> 'sale':
a = prod.product_tmpl_id.property_account_expense.id
if not a:
a = prod.categ_id.property_account_expense_categ.id
diff --git a/addons/account/project/project.py b/addons/account/project/project.py
index 431d486592b..f082672310e 100644
--- a/addons/account/project/project.py
+++ b/addons/account/project/project.py
@@ -28,8 +28,8 @@ from osv import osv
class account_analytic_journal(osv.osv):
_name = 'account.analytic.journal'
_columns = {
- 'name' : fields.char('Journal name', size=64, required=True),
- 'code' : fields.char('Journal code', size=8),
+ 'name' : fields.char('Journal Name', size=64, required=True),
+ 'code' : fields.char('Journal Code', size=8),
'active' : fields.boolean('Active', help="If the active field is set to true, it will allow you to hide the analytic journal without removing it."),
'type': fields.selection([('sale','Sale'), ('purchase','Purchase'), ('cash','Cash'), ('general','General'), ('situation','Situation')], 'Type', size=32, required=True, help="Gives the type of the analytic journal. When it needs for a document (eg: an invoice) to create analytic entries, OpenERP will look for a matching journal of the same type."),
'line_ids' : fields.one2many('account.analytic.line', 'journal_id', 'Lines'),
diff --git a/addons/account/project/project_view.xml b/addons/account/project/project_view.xml
index 0d335118d3b..fd52619fb10 100644
--- a/addons/account/project/project_view.xml
+++ b/addons/account/project/project_view.xml
@@ -172,19 +172,16 @@
tree
-
+
+
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
@@ -195,22 +192,24 @@
-
-
+
+
+
-
-
-
-
-
-
+
+
+
+
+
+
-
-
+
+
+
-
+
diff --git a/addons/account_analytic_analysis/account_analytic_analysis.py b/addons/account_analytic_analysis/account_analytic_analysis.py
index 5a393e1dd83..d9e9bf3907b 100644
--- a/addons/account_analytic_analysis/account_analytic_analysis.py
+++ b/addons/account_analytic_analysis/account_analytic_analysis.py
@@ -23,6 +23,8 @@ from osv import osv, fields
from osv.orm import intersect
import tools.sql
from tools.translate import _
+from decimal_precision import decimal_precision as dp
+
class account_analytic_account(osv.osv):
_name = "account.analytic.account"
@@ -66,6 +68,8 @@ class account_analytic_account(osv.osv):
and invoice_id is not null \
GROUP BY account_analytic_line.account_id;", (parent_ids,))
for account_id, sum in cr.fetchall():
+ if account_id not in res:
+ res[account_id] = {}
res[account_id][f] = sum
for account in accounts:
for child in account.child_ids:
@@ -102,6 +106,8 @@ class account_analytic_account(osv.osv):
and account_analytic_journal.type in ('purchase','general') \
GROUP BY account_analytic_account.id;""", (parent_ids,))
for account_id, sum in cr.fetchall():
+ if account_id not in res:
+ res[account_id] = {}
res[account_id][f] = round(sum, dp)
for account in accounts:
@@ -142,6 +148,8 @@ class account_analytic_account(osv.osv):
and invoice_id is null \
GROUP BY account_analytic_line.account_id" ,(parent_ids,))
for account_id, lwd in cr.fetchall():
+ if account_id not in res:
+ res[account_id] = {}
res[account_id][f] = lwd
for account in accounts:
for child in account.child_ids:
@@ -161,6 +169,8 @@ class account_analytic_account(osv.osv):
AND to_invoice IS NOT NULL \
GROUP BY account_analytic_line.account_id;",(parent_ids,))
for account_id, sua in cr.fetchall():
+ if account_id not in res:
+ res[account_id] = {}
res[account_id][f] = round(sua, dp)
for account in accounts:
for child in account.child_ids:
@@ -181,10 +191,14 @@ class account_analytic_account(osv.osv):
GROUP BY account_analytic_line.account_id",(parent_ids,))
ff = cr.fetchall()
for account_id, hq in ff:
+ if account_id not in res:
+ res[account_id] = {}
res[account_id][f] = round(hq, dp)
for account in accounts:
for child in account.child_ids:
if account.id != child.id:
+ if account.id not in res:
+ res[account.id] = {f: 0.0}
res[account.id][f] += res.get(child.id, {}).get(f, 0.0)
for id in ids:
res[id][f] = round(res[id][f], dp)
@@ -223,6 +237,8 @@ class account_analytic_account(osv.osv):
res2.setdefault(account.id, 0.0)
for child in account.child_ids:
if account.id != child.id:
+ if account.id not in res:
+ res[account.id] = {f: 0.0}
res[account.id][f] += res.get(child.id, {}).get(f, 0.0)
res[account.id][f] += res2.get(child.id, 0.0)
@@ -337,22 +353,47 @@ class account_analytic_account(osv.osv):
return res
_columns ={
- 'ca_invoiced': fields.function(_ca_invoiced_calc, method=True, type='float', string='Invoiced Amount', help="Total customer invoiced amount for this account."),
- 'total_cost': fields.function(_total_cost_calc, method=True, type='float', string='Total Costs', help="Total of costs for this account. It includes real costs (from invoices) and indirect costs, like time spent on timesheets."),
- 'ca_to_invoice': fields.function(_analysis_all, method=True, multi='analytic_analysis', type='float', string='Uninvoiced Amount', help="If invoice from analytic account, the remaining amount you can invoice to the customer based on the total costs."),
- 'ca_theorical': fields.function(_analysis_all, method=True, multi='analytic_analysis', type='float', string='Theorical Revenue', help="Based on the costs you had on the project, what would have been the revenue if all these costs have been invoiced at the normal sale price provided by the pricelist."),
- 'hours_quantity': fields.function(_analysis_all, method=True, multi='analytic_analysis', type='float', string='Hours Tot', help="Number of hours you spent on the analytic account (from timesheet). It computes on all journal of type 'general'."),
- 'last_invoice_date': fields.function(_analysis_all, method=True, multi='analytic_analysis', type='date', string='Last Invoice Date', help="Date of the last invoice created for this analytic account."),
- 'last_worked_invoiced_date': fields.function(_analysis_all, method=True, multi='analytic_analysis', type='date', string='Date of Last Invoiced Cost', help="If invoice from the costs, this is the date of the latest work or cost that have been invoiced."),
- 'last_worked_date': fields.function(_analysis_all, method=True, multi='analytic_analysis', type='date', string='Date of Last Cost/Work', help="Date of the latest work done on this account."),
- 'hours_qtt_non_invoiced': fields.function(_analysis_all, method=True, multi='analytic_analysis', type='float', string='Uninvoiced Hours', help="Number of hours (from journal of type 'general') that can be invoiced if you invoice based on analytic account."),
- 'hours_qtt_invoiced': fields.function(_hours_qtt_invoiced_calc, method=True, type='float', string='Invoiced Hours', help="Number of hours that can be invoiced plus those that already have been invoiced."),
- 'remaining_hours': fields.function(_remaining_hours_calc, method=True, type='float', string='Remaining Hours', help="Computed using the formula: Maximum Quantity - Hours Tot."),
- 'remaining_ca': fields.function(_remaining_ca_calc, method=True, type='float', string='Remaining Revenue', help="Computed using the formula: Max Invoice Price - Invoiced Amount."),
- 'revenue_per_hour': fields.function(_revenue_per_hour_calc, method=True, type='float', string='Revenue per Hours (real)', help="Computed using the formula: Invoiced Amount / Hours Tot."),
- 'real_margin': fields.function(_real_margin_calc, method=True, type='float', string='Real Margin', help="Computed using the formula: Invoiced Amount - Total Costs."),
- 'theorical_margin': fields.function(_theorical_margin_calc, method=True, type='float', string='Theorical Margin', help="Computed using the formula: Theorial Revenue - Total Costs"),
- 'real_margin_rate': fields.function(_real_margin_rate_calc, method=True, type='float', string='Real Margin Rate (%)', help="Computes using the formula: (Real Margin / Total Costs) * 100."),
+ 'ca_invoiced': fields.function(_ca_invoiced_calc, method=True, type='float', string='Invoiced Amount',
+ help="Total customer invoiced amount for this account.",
+ digits_compute=dp.get_precision('Account')),
+ 'total_cost': fields.function(_total_cost_calc, method=True, type='float', string='Total Costs',
+ help="Total of costs for this account. It includes real costs (from invoices) and indirect costs, like time spent on timesheets.",
+ digits_compute=dp.get_precision('Account')),
+ 'ca_to_invoice': fields.function(_analysis_all, method=True, multi='analytic_analysis', type='float', string='Uninvoiced Amount',
+ help="If invoice from analytic account, the remaining amount you can invoice to the customer based on the total costs.",
+ digits_compute=dp.get_precision('Account')),
+ 'ca_theorical': fields.function(_analysis_all, method=True, multi='analytic_analysis', type='float', string='Theorical Revenue',
+ help="Based on the costs you had on the project, what would have been the revenue if all these costs have been invoiced at the normal sale price provided by the pricelist.",
+ digits_compute=dp.get_precision('Account')),
+ 'hours_quantity': fields.function(_analysis_all, method=True, multi='analytic_analysis', type='float', string='Hours Tot',
+ help="Number of hours you spent on the analytic account (from timesheet). It computes on all journal of type 'general'."),
+ 'last_invoice_date': fields.function(_analysis_all, method=True, multi='analytic_analysis', type='date', string='Last Invoice Date',
+ help="Date of the last invoice created for this analytic account."),
+ 'last_worked_invoiced_date': fields.function(_analysis_all, method=True, multi='analytic_analysis', type='date', string='Date of Last Invoiced Cost',
+ help="If invoice from the costs, this is the date of the latest work or cost that have been invoiced."),
+ 'last_worked_date': fields.function(_analysis_all, method=True, multi='analytic_analysis', type='date', string='Date of Last Cost/Work',
+ help="Date of the latest work done on this account."),
+ 'hours_qtt_non_invoiced': fields.function(_analysis_all, method=True, multi='analytic_analysis', type='float', string='Uninvoiced Hours',
+ help="Number of hours (from journal of type 'general') that can be invoiced if you invoice based on analytic account."),
+ 'hours_qtt_invoiced': fields.function(_hours_qtt_invoiced_calc, method=True, type='float', string='Invoiced Hours',
+ help="Number of hours that can be invoiced plus those that already have been invoiced."),
+ 'remaining_hours': fields.function(_remaining_hours_calc, method=True, type='float', string='Remaining Hours',
+ help="Computed using the formula: Maximum Quantity - Hours Tot."),
+ 'remaining_ca': fields.function(_remaining_ca_calc, method=True, type='float', string='Remaining Revenue',
+ help="Computed using the formula: Max Invoice Price - Invoiced Amount.",
+ digits_compute=dp.get_precision('Account')),
+ 'revenue_per_hour': fields.function(_revenue_per_hour_calc, method=True, type='float', string='Revenue per Hours (real)',
+ help="Computed using the formula: Invoiced Amount / Hours Tot.",
+ digits_compute=dp.get_precision('Account')),
+ 'real_margin': fields.function(_real_margin_calc, method=True, type='float', string='Real Margin',
+ help="Computed using the formula: Invoiced Amount - Total Costs.",
+ digits_compute=dp.get_precision('Account')),
+ 'theorical_margin': fields.function(_theorical_margin_calc, method=True, type='float', string='Theorical Margin',
+ help="Computed using the formula: Theorial Revenue - Total Costs",
+ digits_compute=dp.get_precision('Account')),
+ 'real_margin_rate': fields.function(_real_margin_rate_calc, method=True, type='float', string='Real Margin Rate (%)',
+ help="Computes using the formula: (Real Margin / Total Costs) * 100.",
+ digits_compute=dp.get_precision('Account')),
'month_ids': fields.function(_analysis_all, method=True, multi='analytic_analysis', type='many2many', relation='account_analytic_analysis.summary.month', string='Month'),
'user_ids': fields.function(_analysis_all, method=True, multi='analytic_analysis', type="many2many", relation='account_analytic_analysis.summary.user', string='User'),
}
diff --git a/addons/account_invoice_layout/account_invoice_layout.py b/addons/account_invoice_layout/account_invoice_layout.py
index adb80d787a0..2c2a02d4b9d 100644
--- a/addons/account_invoice_layout/account_invoice_layout.py
+++ b/addons/account_invoice_layout/account_invoice_layout.py
@@ -130,19 +130,22 @@ class account_invoice_line(osv.osv):
default['state'] = self.browse(cr, uid, id).state
return super(account_invoice_line, self).copy_data(cr, uid, id, default, context)
- def _fnct(self, cr, uid, id, name, args, context=None):
+ def _fnct(self, cr, uid, ids, name, args, context=None):
res = {}
- for m in self.browse(cr, uid, id):
- if m.state != 'article':
- if m.state == 'line':
- res[m.id] = '-----------------------------------------'
- elif m.state == 'break':
- res[m.id] = 'PAGE BREAK'
+
+ lines = self.browse(cr, uid, ids)
+ account_ids = [line.account_id.id for line in lines]
+ account_names = dict(self.pool.get('account.account').name_get(cr, uid, account_ids, context=context))
+ for line in lines:
+ if line.state != 'article':
+ if line.state == 'line':
+ res[line.id] = '-----------------------------------------'
+ elif line.state == 'break':
+ res[line.id] = 'PAGE BREAK'
else:
- res[m.id] = ' '
+ res[line.id] = ' '
else:
- [(temp)] = self.pool.get('account.account').name_get(cr, uid, [m.account_id.id], context=context)
- res[m.id] = temp[1]
+ res[line.id] = account_names.get(line.account_id.id, '')
return res
_name = "account.invoice.line"
@@ -205,4 +208,4 @@ class account_invoice(osv.osv):
account_invoice()
-# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
\ No newline at end of file
+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/analytic/analytic.py b/addons/analytic/analytic.py
index cf96028f01c..66c74a72bc9 100644
--- a/addons/analytic/analytic.py
+++ b/addons/analytic/analytic.py
@@ -25,6 +25,7 @@ import operator
from osv import fields, osv
import decimal_precision as dp
+
class account_analytic_account(osv.osv):
_name = 'account.analytic.account'
_description = 'Analytic Account'
@@ -272,7 +273,7 @@ class account_analytic_line(osv.osv):
_columns = {
'name' : fields.char('Description', size=256, required=True),
'date' : fields.date('Date', required=True, select=1),
- 'amount' : fields.float('Amount', required=True, help='Calculated by multiplying the quantity and the price given in the Product\'s cost price. Always expressed in the company main currency.'),
+ 'amount' : fields.float('Amount', required=True, help='Calculated by multiplying the quantity and the price given in the Product\'s cost price. Always expressed in the company main currency.', digits_compute=dp.get_precision('Account')),
'unit_amount' : fields.float('Quantity', help='Specifies the amount of quantity to count.'),
'account_id' : fields.many2one('account.analytic.account', 'Analytic Account', required=True, ondelete='cascade', select=True),
'user_id' : fields.many2one('res.users', 'User'),
diff --git a/addons/analytic_user_function/analytic_user_function.py b/addons/analytic_user_function/analytic_user_function.py
index 0bb9afc3386..21fe0a7da29 100644
--- a/addons/analytic_user_function/analytic_user_function.py
+++ b/addons/analytic_user_function/analytic_user_function.py
@@ -99,7 +99,7 @@ class hr_analytic_timesheet(osv.osv):
(r.product_id.name, r.product_id.id,))
# Compute based on pricetype
amount_unit = self.on_change_unit_amount(cr, uid, ids,
- r.product_id.id, unit_amount, r.product_id.uom_id.id)['value']['amount']
+ r.product_id.id, unit_amount, False, r.product_id.uom_id.id)['value']['amount']
amount = unit_amount * amount_unit
res ['value']['amount']= - round(amount, 2)
@@ -134,7 +134,7 @@ class hr_analytic_timesheet(osv.osv):
(r.product_id.name, r.product_id.id,))
# Compute based on pricetype
amount_unit = self.on_change_unit_amount(cr, uid, ids,
- r.product_id.id, unit_amount, r.product_id.uom_id.id)['value']['amount']
+ r.product_id.id, unit_amount, False, r.product_id.uom_id.id)['value']['amount']
amount = unit_amount * amount_unit
res ['value']['amount']= - round(amount, 2)
diff --git a/addons/base_calendar/base_calendar.py b/addons/base_calendar/base_calendar.py
index b71e2daa447..7ccd07351f0 100644
--- a/addons/base_calendar/base_calendar.py
+++ b/addons/base_calendar/base_calendar.py
@@ -724,7 +724,7 @@ true, it will allow you to hide the event alarm information without removing it.
if alarm_ids:
alarm_obj.unlink(cr, uid, alarm_ids)
cr.execute('Update %s set base_calendar_alarm_id=NULL, alarm_id=NULL\
- where id=%%d' % model_obj._table,(datas.id,))
+ where id=%%s' % model_obj._table,(datas.id,))
return True
res_alarm()
diff --git a/addons/caldav/calendar.py b/addons/caldav/calendar.py
index bcc624d6a67..d22fa98f6e4 100644
--- a/addons/caldav/calendar.py
+++ b/addons/caldav/calendar.py
@@ -716,7 +716,7 @@ class basic_calendar_line(osv.osv):
"""
cr.execute("SELECT COUNT(id) FROM basic_calendar_lines \
- WHERE name='%s' AND calendar_id=%s",
+ WHERE name=%s AND calendar_id=%s",
(vals.get('name'), vals.get('calendar_id')))
res = cr.fetchone()
if res:
diff --git a/addons/event/event.py b/addons/event/event.py
index 7a6e904f6e3..ea4a9cf9b8b 100644
--- a/addons/event/event.py
+++ b/addons/event/event.py
@@ -28,6 +28,7 @@ import time
import tools
import decimal_precision as dp
+
class event_type(osv.osv):
""" Event Type """
_name = 'event.type'
@@ -225,7 +226,7 @@ class event_event(osv.osv):
'product_id': fields.many2one('product.product', 'Product', required=True, readonly=True, states={'draft': [('readonly', False)]}, help="The invoices of this event registration will be created with this Product. Thus it allows you to set the default label and the accounting info you want by default on these invoices."),
'note': fields.text('Notes', help="Description or Summary of Event", readonly=False, states={'done': [('readonly', True)]}),
'pricelist_id': fields.many2one('product.pricelist', 'Pricelist', readonly=True, states={'draft': [('readonly', False)]}, help="Pricelist version for current event."),
- 'unit_price': fields.related('product_id', 'list_price', type='float', string='Registration Cost', readonly=True, states={'draft':[('readonly',False)]}, help="This will be the default price used as registration cost when invoicing this event. Note that you can specify for each registration a specific amount if you want to"),
+ 'unit_price': fields.related('product_id', 'list_price', type='float', string='Registration Cost', readonly=True, states={'draft':[('readonly',False)]}, help="This will be the default price used as registration cost when invoicing this event. Note that you can specify for each registration a specific amount if you want to", digits_compute=dp.get_precision('Sale Price')),
'main_speaker_id': fields.many2one('res.partner','Main Speaker', readonly=False, states={'done': [('readonly', True)]}, help="Speaker who are giving speech on event."),
'speaker_ids':fields.many2many('res.partner', 'event_speaker_rel', 'speaker_id', 'partner_id', 'Other Speakers', readonly=False, states={'done': [('readonly', True)]}),
'address_id': fields.many2one('res.partner.address','Location Address', readonly=False, states={'done': [('readonly', True)]}),
@@ -306,8 +307,8 @@ class event_registration(osv.osv):
'partner_id': fields.many2one('res.partner', 'Partner', states={'done': [('readonly', True)]}),
"partner_invoice_id": fields.many2one('res.partner', 'Partner Invoiced', readonly=True, states={'draft': [('readonly', False)]}),
"contact_id": fields.many2one('res.partner.contact', 'Partner Contact', readonly=False, states={'done': [('readonly', True)]}), #TODO: filter only the contacts that have a function into the selected partner_id
- "unit_price": fields.float('Unit Price', required=True, digits_compute= dp.get_precision('Event Price'), readonly=True, states={'draft': [('readonly', False)]}),
- 'price_subtotal': fields.function(_amount_line, method=True, string='Subtotal', digits_compute= dp.get_precision('Event Price')),
+ "unit_price": fields.float('Unit Price', required=True, digits_compute=dp.get_precision('Sale Price'), readonly=True, states={'draft': [('readonly', False)]}),
+ 'price_subtotal': fields.function(_amount_line, method=True, string='Subtotal', digits_compute=dp.get_precision('Sale Price')),
"badge_ids": fields.one2many('event.registration.badge', 'registration_id', 'Badges', readonly=False, states={'done': [('readonly', True)]}),
"event_product": fields.char("Invoice Name", size=128, readonly=True, states={'draft': [('readonly', False)]}),
"tobe_invoiced": fields.boolean("To be Invoiced", readonly=True, states={'draft': [('readonly', False)]}),
diff --git a/addons/event/wizard/partner_event_registration.py b/addons/event/wizard/partner_event_registration.py
index 8462a812313..00f106ab8ae 100644
--- a/addons/event/wizard/partner_event_registration.py
+++ b/addons/event/wizard/partner_event_registration.py
@@ -24,6 +24,7 @@ import netsvc
import tools
from osv import fields, osv
from tools.translate import _
+from decimal_precision import decimal_precision as dp
class partner_event_registration(osv.osv_memory):
@@ -36,7 +37,7 @@ class partner_event_registration(osv.osv_memory):
_columns = {
'event_id': fields.many2one('event.event', 'Event'),
'event_type': fields.many2one('event.type', 'Type', readonly=True),
- 'unit_price': fields.float('Registration Cost'),
+ 'unit_price': fields.float('Registration Cost', digits_compute=dp.get_precision('Sale Price')),
'start_date': fields.datetime('Start date', required=True, help="Beginning Date of Event", readonly=True),
'end_date': fields.datetime('Closing date', required=True, help="Closing Date of Event", readonly=True),
'nb_register': fields.integer('Number of Registration'),
diff --git a/addons/hr_timesheet/hr_timesheet.py b/addons/hr_timesheet/hr_timesheet.py
index ee4abdb35c4..75ad6101e11 100644
--- a/addons/hr_timesheet/hr_timesheet.py
+++ b/addons/hr_timesheet/hr_timesheet.py
@@ -57,14 +57,14 @@ class hr_analytic_timesheet(osv.osv):
return super(hr_analytic_timesheet, self).unlink(cr, uid, ids, context=context)
- def on_change_unit_amount(self, cr, uid, id, prod_id, unit_amount, unit, context=None):
+ def on_change_unit_amount(self, cr, uid, id, prod_id, unit_amount, company_id, unit=False, journal_id=False, context=None):
if context is None:
context = {}
res = {'value':{}}
if prod_id and unit_amount:
# find company
company_id = self.pool.get('res.company')._company_default_get(cr, uid, 'account.analytic.line', context=context)
- res.update(self.pool.get('account.analytic.line').on_change_unit_amount(cr, uid, id, prod_id, unit_amount, company_id, unit, context=context))
+ res.update(self.pool.get('account.analytic.line').on_change_unit_amount(cr, uid, id, prod_id, unit_amount, company_id, unit, journal_id, context=context))
# update unit of measurement
if prod_id:
uom = self.pool.get('product.product').browse(cr, uid, prod_id, context=context)
diff --git a/addons/hr_timesheet/hr_timesheet_view.xml b/addons/hr_timesheet/hr_timesheet_view.xml
index 4165f71d73f..a47fbf24685 100644
--- a/addons/hr_timesheet/hr_timesheet_view.xml
+++ b/addons/hr_timesheet/hr_timesheet_view.xml
@@ -12,16 +12,17 @@
tree
-
-
+
+
-
-
-
-
-
-
+
+
+
+
+
+
+
@@ -40,9 +41,9 @@
-
-
-
+
+
+
@@ -67,7 +68,7 @@
-
+
@@ -81,32 +82,20 @@
-
-
+
+
-
- My Working Hours
- ir.actions.act_window
- hr.analytic.timesheet
- form
- tree,form
- [('user_id','=',uid)]
-
- {"search_default_user_id":uid, "search_default_my": 1}
-
-
-
Working Hours
ir.actions.act_window
hr.analytic.timesheet
form
tree,form
- {"search_default_user_id":uid}
+ {"search_default_user_id":uid, "search_default_today":1}
This functionality gives you a list of work done by user, product and analytic account (or project). A search tool allows you to make fine-grained analysis.
diff --git a/addons/hr_timesheet/wizard/hr_timesheet_sign_in_out.py b/addons/hr_timesheet/wizard/hr_timesheet_sign_in_out.py
index b308aa69cc8..8d0ed702c0a 100644
--- a/addons/hr_timesheet/wizard/hr_timesheet_sign_in_out.py
+++ b/addons/hr_timesheet/wizard/hr_timesheet_sign_in_out.py
@@ -81,7 +81,7 @@ class hr_so_project(osv.osv_memory):
if not res['product_uom_id']:
raise osv.except_osv(_('UserError'), _('No cost unit defined for this employee !'))
- up = timesheet_obj.on_change_unit_amount(cr, uid, False, res['product_id'], hour, res['product_uom_id'])['value']
+ up = timesheet_obj.on_change_unit_amount(cr, uid, False, res['product_id'], hour,False, res['product_uom_id'])['value']
res['name'] = data['info']
res['account_id'] = data['account_id'].id
diff --git a/addons/hr_timesheet_invoice/hr_timesheet_invoice_view.xml b/addons/hr_timesheet_invoice/hr_timesheet_invoice_view.xml
index c7435127466..4beda0999d0 100644
--- a/addons/hr_timesheet_invoice/hr_timesheet_invoice_view.xml
+++ b/addons/hr_timesheet_invoice/hr_timesheet_invoice_view.xml
@@ -21,17 +21,6 @@
-
hr.analytic.timesheet.form
hr.analytic.timesheet
@@ -83,13 +72,26 @@
+
+ account.analytic.line.search.to_invoice
+ account.analytic.line
+ search
+
+
+
+
+
+
+
+
+
account.analytic.line.tree.to_invoice
account.analytic.line
tree
-
+
@@ -103,18 +105,19 @@
+
- Entries to invoice
+ Costs to Invoice
account.analytic.line
form
tree,form
- [('to_invoice','<>',False)]
- {"search_default_user_id":uid}
+ []
+ {'search_default_to_invoice': 1}
OpenERP automatically group the entries to be invoiced so you can keep an eye on them on real time in one glance.
-
- Uninvoiced Entries
- account.analytic.line
- form
- tree,form
- [('invoice_id','=',False),('to_invoice','!=',False)]
-
-
-
-
- Open Analytic Accounts
- account.analytic.account
- form
- tree,form
- [('state','<>','close'),('type','<>','view')]
-
-
-
- Unclosed Invoiceable Accounts
- account.analytic.account
- form
- tree,form
- [('state','<>','close'),('type','<>','view'),('pricelist_id','<>',False)]
-
-
hr_timesheet_invoice.factor.form
hr_timesheet_invoice.factor
diff --git a/addons/hr_timesheet_invoice/report/report_analytic.py b/addons/hr_timesheet_invoice/report/report_analytic.py
index 0b3d1440f23..d2db7fd4027 100644
--- a/addons/hr_timesheet_invoice/report/report_analytic.py
+++ b/addons/hr_timesheet_invoice/report/report_analytic.py
@@ -21,6 +21,8 @@
from osv import fields,osv
import tools
+from decimal_precision import decimal_precision as dp
+
class report_analytic_account_close(osv.osv):
_name = "report.analytic.account.close"
@@ -70,8 +72,8 @@ class report_account_analytic_line_to_invoice(osv.osv):
'account_id':fields.many2one('account.analytic.account', 'Analytic account', readonly=True),
'product_uom_id':fields.many2one('product.uom', 'UoM', readonly=True),
'unit_amount': fields.float('Units', readonly=True),
- 'sale_price': fields.float('Sale price', readonly=True),
- 'amount': fields.float('Amount', readonly=True),
+ 'sale_price': fields.float('Sale price', readonly=True, digits_compute=dp.get_precision('Sale Price')),
+ 'amount': fields.float('Amount', readonly=True, digits_compute=dp.get_precision('Account')),
'month':fields.selection([('01','January'), ('02','February'), ('03','March'), ('04','April'), ('05','May'), ('06','June'),
('07','July'), ('08','August'), ('09','September'), ('10','October'), ('11','November'), ('12','December')],'Month',readonly=True),
}
diff --git a/addons/hr_timesheet_invoice/wizard/hr_timesheet_invoice_create.py b/addons/hr_timesheet_invoice/wizard/hr_timesheet_invoice_create.py
index 4e1926fe069..1bb7765b372 100644
--- a/addons/hr_timesheet_invoice/wizard/hr_timesheet_invoice_create.py
+++ b/addons/hr_timesheet_invoice/wizard/hr_timesheet_invoice_create.py
@@ -38,7 +38,7 @@ class hr_timesheet_invoice_create(osv.osv_memory):
'accounts': fields.many2many('account.analytic.account', 'invoice_id', 'account_id', 'Analytic Accounts', required=True),
'date': fields.boolean('Date', help='The real date of each work will be displayed on the invoice'),
'time': fields.boolean('Time spent', help='The time of each work done will be displayed on the invoice'),
- 'name': fields.boolean('Name of entry', help='The detail of each work done will be displayed on the invoice'),
+ 'name': fields.boolean('Description', help='The detail of each work done will be displayed on the invoice'),
'price': fields.boolean('Cost', help='The cost of each work done will be displayed on the invoice. You probably don\'t want to check this'),
'product': fields.many2one('product.product', 'Product', help='Complete this field only if you want to force to use a specific product. Keep empty to use the real product that comes from the cost.'),
}
@@ -59,8 +59,10 @@ class hr_timesheet_invoice_create(osv.osv_memory):
return [x[0] for x in account_ids]
_defaults = {
- 'accounts': _get_accounts
- }
+ 'accounts': _get_accounts,
+ 'date': lambda *args: 1,
+ 'name': lambda *args: 1
+ }
def do_create(self, cr, uid, ids, context=None):
mod_obj = self.pool.get('ir.model.data')
diff --git a/addons/hr_timesheet_invoice/wizard/hr_timesheet_invoice_create_view.xml b/addons/hr_timesheet_invoice/wizard/hr_timesheet_invoice_create_view.xml
index d71b385c1f8..fc6d6da911e 100644
--- a/addons/hr_timesheet_invoice/wizard/hr_timesheet_invoice_create_view.xml
+++ b/addons/hr_timesheet_invoice/wizard/hr_timesheet_invoice_create_view.xml
@@ -2,37 +2,33 @@
-
+
hr.timesheet.invoice.create.form
hr.timesheet.invoice.create
form
-
+
@@ -45,7 +41,7 @@
new
-
+
Invoice analytic lines
@@ -55,5 +51,5 @@
account.analytic.line
-
-
\ No newline at end of file
+
+
diff --git a/addons/hr_timesheet_sheet/hr_timesheet_sheet_view.xml b/addons/hr_timesheet_sheet/hr_timesheet_sheet_view.xml
index f078be2dbe1..decf3b16b6b 100644
--- a/addons/hr_timesheet_sheet/hr_timesheet_sheet_view.xml
+++ b/addons/hr_timesheet_sheet/hr_timesheet_sheet_view.xml
@@ -104,11 +104,11 @@
-
+
-
-
+
+
@@ -117,11 +117,11 @@
-
+
-
-
+
+
@@ -201,8 +201,7 @@
id="base.menu_project_management_time_tracking"
name="Time Tracking"
parent="base.menu_main_pm" sequence="5"/>
-
+
diff --git a/addons/hr_timesheet_sheet/wizard/hr_timesheet_current_view.xml b/addons/hr_timesheet_sheet/wizard/hr_timesheet_current_view.xml
index 19eacdae472..f9944d0949f 100644
--- a/addons/hr_timesheet_sheet/wizard/hr_timesheet_current_view.xml
+++ b/addons/hr_timesheet_sheet/wizard/hr_timesheet_current_view.xml
@@ -6,7 +6,7 @@
hr.timesheet.current.open
form
-
- Current Timesheet
+ My Timesheet
hr.timesheet.current.open
form
tree,form
@@ -25,7 +25,11 @@
new
-
+
+
+
diff --git a/addons/marketing_campaign/report/campaign_analysis_view.xml b/addons/marketing_campaign/report/campaign_analysis_view.xml
index aa994fcfc48..fd5a8c0908f 100644
--- a/addons/marketing_campaign/report/campaign_analysis_view.xml
+++ b/addons/marketing_campaign/report/campaign_analysis_view.xml
@@ -84,8 +84,8 @@
-
-
+
+
diff --git a/addons/mrp_repair/mrp_repair.py b/addons/mrp_repair/mrp_repair.py
index 4689295f53f..6cec29650f3 100644
--- a/addons/mrp_repair/mrp_repair.py
+++ b/addons/mrp_repair/mrp_repair.py
@@ -687,8 +687,9 @@ class mrp_repair_line(osv.osv, ProductChangeMixin):
if type == 'add':
stock_id = self.pool.get('stock.location').search(cr, uid, [('name','=','Stock')])[0]
to_invoice = False
- if guarantee_limit and datetime.today() > datetime.strptime(guarantee_limit, '%Y-%m-%d'):
+ if guarantee_limit and datetime.strptime(date.today().strftime('%Y-%m-%d'), '%Y-%m-%d') > datetime.strptime(guarantee_limit, '%Y-%m-%d'):
to_invoice=True
+
return {'value': {
'to_invoice': to_invoice,
'location_id': stock_id,
diff --git a/addons/mrp_repair/report/order.py b/addons/mrp_repair/report/order.py
index 3d6f9200dd8..d6edc1f01e4 100644
--- a/addons/mrp_repair/report/order.py
+++ b/addons/mrp_repair/report/order.py
@@ -33,9 +33,9 @@ class order(report_sxw.rml_parse):
def total(self, repair):
total = 0.0
for operation in repair.operations:
- total+=operation.price_subtotal
+ total += operation.price_subtotal
for fee in repair.fees_lines:
- total+=fee.price_subtotal
+ total += fee.price_subtotal
total = total + repair.amount_tax
return total
diff --git a/addons/mrp_repair/report/order.rml b/addons/mrp_repair/report/order.rml
index 149a2650bfd..328b5e931ee 100644
--- a/addons/mrp_repair/report/order.rml
+++ b/addons/mrp_repair/report/order.rml
@@ -343,7 +343,7 @@
Net Total :
- [[ formatLang(o.amount_untaxed)]] [[ o.pricelist_id.currency_id. symbol ]]
+ [[ formatLang(o.amount_untaxed, digits=get_digits(dp='Sale Price'))]] [[ o.pricelist_id.currency_id. symbol ]]
|
@@ -357,7 +357,7 @@
Taxes:
- [[ formatLang(o.amount_tax)]] [[ o.pricelist_id.currency_id. symbol ]]
+ [[ formatLang(o.amount_tax, digits=get_digits(dp='Account'))]] [[ o.pricelist_id.currency_id. symbol ]]
|
@@ -370,7 +370,7 @@
Total :
|
- [[ formatLang(total(o)) ]] [[ o.pricelist_id.currency_id. symbol ]]
+ [[ formatLang(total(o), digits=get_digits(dp='Sale Price')) ]] [[ o.pricelist_id.currency_id. symbol ]]
|
@@ -391,4 +391,4 @@
-
\ No newline at end of file
+
diff --git a/addons/point_of_sale/report/account_statement.py b/addons/point_of_sale/report/account_statement.py
index 391adb7569f..dc492651bb2 100644
--- a/addons/point_of_sale/report/account_statement.py
+++ b/addons/point_of_sale/report/account_statement.py
@@ -31,10 +31,21 @@ class account_statement(report_sxw.rml_parse):
self.localcontext.update({
'time': time,
'get_total':self._get_total,
+ 'get_data':self._get_data,
})
+
+ def _get_data(self, statement):
+ lines = []
+ for line in statement.line_ids:
+ lines.append(line)
+
+ return lines
+
def _get_total(self, statement_line_ids):
total = 0.0
for line in statement_line_ids:
total += line.amount
return total
+
report_sxw.report_sxw('report.account.statement', 'account.bank.statement', 'addons/statement/report/account_statement.rml', parser=account_statement,header='internal')
+
diff --git a/addons/point_of_sale/report/account_statement.rml b/addons/point_of_sale/report/account_statement.rml
index e4c3b99b6ee..ed26143aa4e 100644
--- a/addons/point_of_sale/report/account_statement.rml
+++ b/addons/point_of_sale/report/account_statement.rml
@@ -216,10 +216,10 @@
[[ formatLang(statement.closing_date,date=True) ]]
- [[ formatLang(statement.balance_start) ]][[ company.currency_id.symbol ]]
+ [[ formatLang(statement.balance_start, digits=get_digits(dp='Account')) ]][[ company.currency_id.symbol ]]
|
- [[ formatLang(statement.balance_end_real) ]][[ company.currency_id.symbol ]]
+ [[ formatLang(statement.balance_end_real, digits=get_digits(dp='Account')) ]][[ company.currency_id.symbol ]]
|
@@ -247,13 +247,14 @@
[[ repeatIn(statement.line_ids,'line_ids') and ' ' or removeParentNode('blockTable') ]]
[[ repeatIn(get_data(statement), 'line_ids')]]
- [[ line_ids.name ]]
+
+ [[ line_ids['name'] ]]
|
[[ line_ids.partner_id.name ]]
|
- [[ formatLang(line_ids.amount) ]][[ company.currency_id.symbol ]]
+ [[ formatLang(line_ids.amount, digits=get_digits(dp='Account')) ]][[ company.currency_id.symbol ]]
|
@@ -268,7 +269,7 @@
Total :
- [[ formatLang(get_total(statement.line_ids)) ]][[ company.currency_id.symbol ]]
+ [[ formatLang(get_total(statement.line_ids), digits=get_digits(dp='Account')) ]][[ company.currency_id.symbol ]]
|
@@ -282,4 +283,4 @@
-
\ No newline at end of file
+
diff --git a/addons/project/project.py b/addons/project/project.py
index 996e79a1f8b..27bbb2f8c7f 100644
--- a/addons/project/project.py
+++ b/addons/project/project.py
@@ -190,7 +190,6 @@ class project(osv.osv):
'active': True,
'priority': 1,
'sequence': 10,
- 'warn_manager': True,
}
def _check_dates(self, cr, uid, ids):
@@ -373,6 +372,11 @@ class task(osv.osv):
return res
+ def onchange_remaining(self, cr, uid, ids, remaining=0.0, planned = 0.0):
+ if remaining and not planned:
+ return {'value':{'planned_hours': remaining}}
+ return {}
+
def onchange_planned(self, cr, uid, ids, planned = 0.0, effective = 0.0):
return {'value':{'remaining_hours': planned - effective}}
@@ -482,7 +486,6 @@ class task(osv.osv):
return True
_constraints = [
- (_check_dates, 'Error! Task start-date must be lower then task end-date.', ['date_start', 'date_end']),
(_check_recursion, _('Error ! You cannot create recursive tasks.'), ['parent_ids'])
]
#
@@ -615,7 +618,10 @@ class task(osv.osv):
def do_open(self, cr, uid, ids, *args):
tasks= self.browse(cr,uid,ids)
for t in tasks:
- self.write(cr, uid, [t.id], {'state': 'open', 'date_start': time.strftime('%Y-%m-%d %H:%M:%S'),})
+ data = {'state': 'open'}
+ if not t.date_start:
+ data['date_start'] = time.strftime('%Y-%m-%d %H:%M:%S')
+ self.write(cr, uid, [t.id], data)
message = _('Task ') + " '" + t.name + "' "+ _("is Open.")
self.log(cr, uid, t.id, message)
return True
@@ -680,7 +686,7 @@ class task(osv.osv):
def prev_type(self, cr, uid, ids, *args):
for task in self.browse(cr, uid, ids):
typeid = task.type_id.id
- types = map(lambda x:x.id, task.project_id.type_ids)
+ types = map(lambda x:x.id, task.project_id and task.project_id.type_ids or [])
if types:
if typeid and typeid in types:
index = types.index(typeid)
diff --git a/addons/project/project_view.xml b/addons/project/project_view.xml
index 6efc64dd494..5e5be5ee4b0 100644
--- a/addons/project/project_view.xml
+++ b/addons/project/project_view.xml
@@ -207,7 +207,7 @@