Browse Source

[FIX] python formatting and cleanings

pull/2/head
Guewen Baconnier @ Camptocamp 12 years ago
parent
commit
c60a8d0d46
  1. 24
      analytic_hours_block/__openerp__.py
  2. 265
      analytic_hours_block/hours_block.py
  3. 23
      analytic_hours_block/report/hours_block.py
  4. 4
      analytic_hours_block/report/hours_block.rml

24
analytic_hours_block/__openerp__.py

@ -20,25 +20,29 @@
##############################################################################
{
"name" : "Project Hours Blocks Management",
"description" : """
"name": "Project Hours Blocks Management",
"description": """
Project Hours Blocks Management
===============================
This module allows you to handle hours blocks, to follow for example the user support contracts.
This means, you sell a product of type "hours block" then you input the spent hours on the hours block and
This module allows you to handle hours blocks,
to follow for example the user support contracts.
This means, you sell a product of type "hours block"
then you input the spent hours on the hours block and
you can track and follow how much has been used.
""",
"version" : "1.2",
"author" : "Camptocamp",
"category" : "Generic Modules/Projects & Services",
"version": "1.3",
"author": "Camptocamp",
"license": 'AGPL-3',
"category": "Generic Modules/Projects & Services",
"website": "http://www.camptocamp.com",
"depends" : [
"depends": [
"account",
"hr_timesheet_invoice",
"analytic"
],
"init_xml" : [],
"update_xml" : [
"data": [
"hours_block_view.xml",
"hours_block_menu.xml",
"report.xml",

265
analytic_hours_block/hours_block.py

@ -19,77 +19,59 @@
#
##############################################################################
import time
import string
from openerp.osv import orm, fields
from osv import osv, fields
import netsvc
############################################################################
## Add hours blocks on invoice
############################################################################
class AccountHoursBlock(osv.osv):
class AccountHoursBlock(orm.Model):
_name = "account.hours.block"
def _get_last_action(self, cr, uid, ids, name, arg, context=None):
"""TODO"""
context = context or {}
""" Return the last analytic line date for an invoice"""
res = {}
for block in self.browse(cr, uid, ids):
for block in self.browse(cr, uid, ids, context=context):
cr.execute("SELECT max(al.date) FROM account_analytic_line AS al"
" WHERE al.invoice_id = %s", (block.invoice_id.id,))
fetch_res = cr.fetchone()
if fetch_res:
date = fetch_res[0]
else:
date = False
res[block.id] = date
res[block.id] = fetch_res[0] if fetch_res else False
return res
def _compute_hours(self, cr, uid, ids, fields, args, context=None):
"""Return a dict of [id][fields]"""
context = context or {}
if not isinstance(ids, list):
ids=[ids]
if isinstance(ids, (int, long)):
ids = [ids]
result = {}
aal_obj = self.pool.get('account.analytic.line')
for block in self.browse(cr,uid,ids):
result[block.id] = {'amount_hours_block' : 0.0,
'amount_hours_block_done' : 0.0,
'amount_hours_block_delta' : 0.0}
for block in self.browse(cr, uid, ids, context=context):
result[block.id] = {'amount_hours_block': 0.0,
'amount_hours_block_done': 0.0}
# Compute hours bought
for line in block.invoice_id.invoice_line:
hours_bought = 0.0
if line.product_id:
## We will now calculate the product_quantity
# We will now calculate the product_quantity
factor = line.uos_id.factor
if factor == 0.0:
factor = 1.0
amount = line.quantity
hours_bought += (amount / factor)
result[block.id]['amount_hours_block'] += hours_bought
# Compute hours spent
hours_used = 0.0
# Get ids of analytic line generated from timesheet associated to current block
# Get ids of analytic line generated from
# timesheet associated to the current block
cr.execute("SELECT al.id "
" FROM account_analytic_line AS al,account_analytic_journal AS aj"
" WHERE aj.id = al.journal_id AND"
" aj.type='general' AND"
" al.invoice_id = %s", (block.invoice_id.id,))
res2 = cr.fetchall()
if res2:
ids2 = [x[0] for x in res2]
else:
ids2 = []
for line in aal_obj.browse(cr, uid, ids2, context):
if line.product_uom_id:
factor = line.product_uom_id.factor
if factor == 0.0:
factor = 1.0
else:
"FROM account_analytic_line AS al, "
" account_analytic_journal AS aj "
"WHERE aj.id = al.journal_id "
"AND aj.type = 'general' "
"AND al.invoice_id = %s", (block.invoice_id.id,))
res_line_ids = cr.fetchall()
line_ids = [l[0] for l in res_line_ids] if res_line_ids else []
for line in aal_obj.browse(cr, uid, line_ids, context=context):
factor = 1.0
if line.product_uom_id and line.product_uom_id.factor != 0.0:
factor = line.product_uom_id.factor
factor_invoicing = 1.0
if line.to_invoice and line.to_invoice.factor != 0.0:
factor_invoicing = 1.0 - line.to_invoice.factor / 100
@ -97,14 +79,15 @@ class AccountHoursBlock(osv.osv):
result[block.id]['amount_hours_block_done'] = hours_used
return result
def _compute_amount(self, cr, uid, ids, fields, args, context):
def _compute_amount(self, cr, uid, ids, fields, args, context=None):
if context is None:
context = {}
result = {}
aal_obj = self.pool.get('account.analytic.line')
pricelist_obj = self.pool.get('product.pricelist')
for block in self.browse(cr,uid,ids):
for block in self.browse(cr, uid, ids, context=context):
result[block.id] = {'amount_hours_block' : 0.0,
'amount_hours_block_done' : 0.0,
'amount_hours_block_delta' : 0.0}
'amount_hours_block_done' : 0.0}
# Compute amount bought
for line in block.invoice_id.invoice_line:
@ -125,19 +108,17 @@ class AccountHoursBlock(osv.osv):
" WHERE aj.id = al.journal_id"
" AND aj.type='general'"
" AND al.invoice_id = %s", (block.invoice_id.id,))
res2 = cr.fetchall()
if res2:
ids2 = [x[0] for x in res2]
else:
ids2 = []
res_line_ids = cr.fetchall()
line_ids = [l[0] for l in res_line_ids] if res_line_ids else []
total_amount = 0.0
for line in aal_obj.browse(cr, uid, ids2, context):
for line in aal_obj.browse(cr, uid, line_ids, context=context):
factor_invoicing = 1.0
if line.to_invoice and line.to_invoice.factor != 0.0:
factor_invoicing = 1.0 - line.to_invoice.factor / 100
ctx = {'uom': line.product_uom_id.id}
amount = pricelist_obj.price_get(cr, uid,
ctx = dict(context, uom=line.product_uom_id.id)
amount = pricelist_obj.price_get(
cr, uid,
[line.account_id.pricelist_id.id],
line.product_id.id,
line.unit_amount or 1.0,
@ -148,53 +129,148 @@ class AccountHoursBlock(osv.osv):
return result
def _compute(self, cr, uid, ids, fields, args, context):
def _compute(self, cr, uid, ids, fields, args, context=None):
result = {}
block_per_types = {}
for block in self.browse(cr, uid, ids, context=context):
if not block.type in block_per_types.keys():
block_per_types[block.type] = []
block_per_types[block.type].append(block.id)
block_per_types.setdefault(block.type, []).append(block.id)
for block_type in block_per_types:
if block_type:
func = getattr(self, "_compute_%s" % (block_type,))
result.update(func(cr, uid, ids, fields, args, context))
func = getattr(self, "_compute_%s" % block_type)
result.update(func(cr, uid, ids, fields, args, context=context))
for block in result:
result[block]['amount_hours_block_delta'] = \
result[block]['amount_hours_block'] - result[block]['amount_hours_block_done']
result[block]['amount_hours_block'] - \
result[block]['amount_hours_block_done']
return result
_columns = {
'amount_hours_block': fields.function(_compute, method=True, type='float', string='Quantity /Amount bought', store=True,
'amount_hours_block': fields.function(
_compute,
type='float',
string='Quantity / Amount bought',
store=True,
multi='amount_hours_block_delta',
help="Amount bought by the customer. This amount is expressed in the base UoM (factor=1.0)"),
'amount_hours_block_done': fields.function(_compute, method=True, type='float', string='Quantity / Amount used', store=True,
help="Amount bought by the customer. "
"This amount is expressed in the base Unit of Measure "
"(factor=1.0)"),
'amount_hours_block_done': fields.function(
_compute,
type='float',
string='Quantity / Amount used',
store=True,
multi='amount_hours_block_delta',
help="Amount done by the staff. This amount is expressed in the base UoM (factor=1.0)"),
'amount_hours_block_delta': fields.function(_compute, method=True, type='float', string='Difference', store=True,
help="Amount done by the staff. "
"This amount is expressed in the base Unit of Measure "
"(factor=1.0)"),
'amount_hours_block_delta': fields.function(
_compute,
type='float',
string='Difference',
store=True,
multi='amount_hours_block_delta',
help="Difference between bought and used. This amount is expressed in the base UoM (factor=1.0)"),
'last_action_date': fields.function(_get_last_action, method=True, type='date', string='Last action date',
help="Date of the last analytic line linked to the invoice related to this block hours."),
help="Difference between bought and used. "
"This amount is expressed in the base Unit of Measure "
"(factor=1.0)"),
'last_action_date': fields.function(
_get_last_action,
type='date',
string='Last action date',
help="Date of the last analytic line linked to the invoice "
"related to this block hours."),
'close_date': fields.date('Closed Date'),
'invoice_id': fields.many2one('account.invoice', 'Invoice', ondelete='cascade', required=True),
'type': fields.selection([('hours','Hours'), ('amount','Amount')], 'Type of Block',
required=True, help="Choose if you want a time or amount base block."),
'invoice_id': fields.many2one(
'account.invoice',
'Invoice',
ondelete='cascade',
required=True),
'type': fields.selection(
[('hours','Hours'),
('amount','Amount')],
string='Type of Block',
required=True,
help="The block is based on the quantity of hours "
"or on the amount."),
# Invoices related infos
'date_invoice': fields.related('invoice_id', 'date_invoice', type="date", string="Invoice Date", store=True, readonly=True),
'user_id': fields.related('invoice_id', 'user_id', type="many2one", relation="res.users", string="Salesman", store=True, readonly=True),
'partner_id': fields.related('invoice_id', 'partner_id', type="many2one", relation="res.partner", string="Partner", store=True, readonly=True),
'name': fields.related('invoice_id', 'name', type="char",size=64, string="Description", store=True,readonly=True),
'number': fields.related('invoice_id', 'number', type="char",size=64, string="Number", store=True,readonly=True),
'journal_id': fields.related('invoice_id', 'journal_id', type="many2one", relation="account.journal", string="Journal", store=True,readonly=True),
'period_id': fields.related('invoice_id', 'period_id', type="many2one", relation="account.period", string="Period", store=True,readonly=True),
'company_id': fields.related('invoice_id', 'company_id', type="many2one", relation="res.company", string="Company", store=True,readonly=True),
'currency_id': fields.related('invoice_id', 'currency_id', type="many2one", relation="res.currency", string="Currency", store=True,readonly=True),
'residual': fields.related('invoice_id', 'residual', type="float", string="Residual", store=True,readonly=True),
'amount_total': fields.related('invoice_id', 'amount_total', type="float", string="Total", store=True,readonly=True),
'state':fields.related('invoice_id','state',
'date_invoice': fields.related(
'invoice_id', 'date_invoice',
type="date",
string="Invoice Date",
store=True,
readonly=True),
'user_id': fields.related(
'invoice_id', 'user_id',
type="many2one",
relation="res.users",
string="Salesman",
store=True,
readonly=True),
'partner_id': fields.related(
'invoice_id', 'partner_id',
type="many2one",
relation="res.partner",
string="Partner",
store=True,
readonly=True),
'name': fields.related(
'invoice_id', 'name',
type="char",
size=64,
string="Description",
store=True,
readonly=True),
'number': fields.related(
'invoice_id', 'number',
type="char",
size=64,
string="Number",
store=True,
readonly=True),
'journal_id': fields.related(
'invoice_id', 'journal_id',
type="many2one",
relation="account.journal",
string="Journal",
store=True,
readonly=True),
'period_id': fields.related(
'invoice_id', 'period_id',
type="many2one",
relation="account.period",
string="Period",
store=True,
readonly=True),
'company_id': fields.related(
'invoice_id', 'company_id',
type="many2one",
relation="res.company",
string="Company",
store=True,
readonly=True),
'currency_id': fields.related(
'invoice_id', 'currency_id',
type="many2one",
relation="res.currency",
string="Currency",
store=True,
readonly=True),
'residual': fields.related(
'invoice_id', 'residual',
type="float",
string="Residual",
store=True,
readonly=True),
'amount_total': fields.related(
'invoice_id', 'amount_total',
type="float",
string="Total",
store=True,
readonly=True),
'state':fields.related(
'invoice_id','state',
type='selection',
selection=[
('draft','Draft'),
@ -202,18 +278,23 @@ class AccountHoursBlock(osv.osv):
('proforma2','Pro-forma'),
('open','Open'),
('paid','Paid'),
('cancel','Cancelled')
('cancel','Cancelled'),
],
string='State', readonly=True, store=True),
string='State',
readonly=True,
store=True),
}
AccountHoursBlock()
class AccountInvoice(osv.osv):
############################################################################
## Add hours blocks on invoice
############################################################################
class AccountInvoice(orm.Model):
_inherit = 'account.invoice'
_columns = {
'account_hours_block_ids': fields.one2many('account.hours.block', 'invoice_id', 'Hours Block')
'account_hours_block_ids': fields.one2many(
'account.hours.block',
'invoice_id',
string='Hours Block')
}
AccountInvoice()

23
analytic_hours_block/report/hours_block.py

@ -20,31 +20,26 @@
##############################################################################
import time
from report import report_sxw
from openerp.report import report_sxw
class account_hours_block(report_sxw.rml_parse):
def __init__(self, cr, uid, name, context=None):
super(account_hours_block, self).__init__(cr, uid, name, context)
super(account_hours_block, self).__init__(cr, uid, name, context=context)
self.localcontext.update({
'time': time,
'format_date': self._get_and_change_date_format_for_swiss,
'analytic_lines': self._get_analytic_lines,
})
self.context = context
def _get_analytic_lines(self, hours_block):
al_pool = self.pool.get('account.analytic.line')
al_ids = al_pool.search(self.cr, self.uid,
[['invoice_id', '=', hours_block.invoice_id.id]],
order='date desc')
res = al_pool.browse(self.cr, self.uid, al_ids)
return res
def _get_and_change_date_format_for_swiss(self, date_to_format):
date_formatted = ''
if date_to_format:
date_formatted = strptime(date_to_format, '%Y-%m-%d').strftime('%d.%m.%Y')
return date_formatted
al_ids = al_pool.search(
self.cr,
self.uid,
[('invoice_id', '=', hours_block.invoice_id.id)],
order='date desc',
context=self.context)
return al_pool.browse(self.cr, self.uid, al_ids, context=self.context)
report_sxw.report_sxw('report.account.hours.block', 'account.hours.block', 'addons/analytic_hours_block/report/hours_block.rml', parser=account_hours_block)

4
analytic_hours_block/report/hours_block.rml

@ -184,7 +184,7 @@
<para style="P12a">Invoice Date : </para>
</td>
<td>
<para style="P2">[[ o.date_invoice and format_date(o.date_invoice) or '' ]]</para>
<para style="P2">[[ o.date_invoice and formatLang(o.date_invoice, date=True) or '' ]]</para>
</td>
</tr>
<tr>
@ -243,7 +243,7 @@
<tr>
[[ repeatIn(analytic_lines(o),'l') ]]
<td>
<para style="P2">[[ l.date and format_date(l.date) or '' ]]</para>
<para style="P2">[[ l.date and formatLang(l.date, date=True) or '' ]]</para>
</td>
<td>
<para style="P2">[[ l.name or '' ]]</para>

Loading…
Cancel
Save