Browse Source

[FIX] python formatting and cleanings

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

44
analytic_hours_block/__openerp__.py

@ -20,31 +20,35 @@
############################################################################## ##############################################################################
{ {
"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. 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", "website": "http://www.camptocamp.com",
"depends" : [
"account",
"hr_timesheet_invoice",
"analytic"
],
"init_xml" : [],
"update_xml" : [
"hours_block_view.xml",
"hours_block_menu.xml",
"report.xml",
"security/hours_block_security.xml",
"security/ir.model.access.csv",
],
"depends": [
"account",
"hr_timesheet_invoice",
"analytic"
],
"data": [
"hours_block_view.xml",
"hours_block_menu.xml",
"report.xml",
"security/hours_block_security.xml",
"security/ir.model.access.csv",
],
"active": False, "active": False,
"installable": True "installable": True
} }

305
analytic_hours_block/hours_block.py

@ -19,92 +19,75 @@
# #
############################################################################## ##############################################################################
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" _name = "account.hours.block"
def _get_last_action(self, cr, uid, ids, name, arg, context=None): 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 = {} 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" cr.execute("SELECT max(al.date) FROM account_analytic_line AS al"
" WHERE al.invoice_id = %s", (block.invoice_id.id,)) " WHERE al.invoice_id = %s", (block.invoice_id.id,))
fetch_res = cr.fetchone() 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 return res
def _compute_hours(self, cr, uid, ids, fields, args, context=None): def _compute_hours(self, cr, uid, ids, fields, args, context=None):
"""Return a dict of [id][fields]""" """Return a dict of [id][fields]"""
context = context or {}
if not isinstance(ids, list):
ids=[ids]
if isinstance(ids, (int, long)):
ids = [ids]
result = {} result = {}
aal_obj = self.pool.get('account.analytic.line') 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 # Compute hours bought
for line in block.invoice_id.invoice_line: for line in block.invoice_id.invoice_line:
hours_bought = 0.0 hours_bought = 0.0
if line.product_id: if line.product_id:
## We will now calculate the product_quantity
# We will now calculate the product_quantity
factor = line.uos_id.factor factor = line.uos_id.factor
if factor == 0.0: if factor == 0.0:
factor = 1.0 factor = 1.0
amount = line.quantity amount = line.quantity
hours_bought += (amount / factor) hours_bought += (amount / factor)
result[block.id]['amount_hours_block'] += hours_bought result[block.id]['amount_hours_block'] += hours_bought
# Compute hours spent # Compute hours spent
hours_used = 0.0 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 " 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:
"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 = line.product_uom_id.factor
if factor == 0.0:
factor = 1.0
else:
factor = 1.0
factor_invoicing = 1.0 factor_invoicing = 1.0
if line.to_invoice and line.to_invoice.factor != 0.0: if line.to_invoice and line.to_invoice.factor != 0.0:
factor_invoicing = 1.0 - line.to_invoice.factor / 100
factor_invoicing = 1.0 - line.to_invoice.factor / 100
hours_used += ((line.unit_amount / factor) * factor_invoicing) hours_used += ((line.unit_amount / factor) * factor_invoicing)
result[block.id]['amount_hours_block_done'] = hours_used result[block.id]['amount_hours_block_done'] = hours_used
return result 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 = {} result = {}
aal_obj = self.pool.get('account.analytic.line') aal_obj = self.pool.get('account.analytic.line')
pricelist_obj = self.pool.get('product.pricelist') 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, 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 # Compute amount bought
for line in block.invoice_id.invoice_line: for line in block.invoice_id.invoice_line:
@ -125,95 +108,193 @@ class AccountHoursBlock(osv.osv):
" WHERE aj.id = al.journal_id" " WHERE aj.id = al.journal_id"
" AND aj.type='general'" " AND aj.type='general'"
" AND al.invoice_id = %s", (block.invoice_id.id,)) " 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 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 factor_invoicing = 1.0
if line.to_invoice and line.to_invoice.factor != 0.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,
[line.account_id.pricelist_id.id],
line.product_id.id,
line.unit_amount or 1.0,
line.account_id.partner_id.id or False,
ctx)[line.account_id.pricelist_id.id]
factor_invoicing = 1.0 - line.to_invoice.factor / 100
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,
line.account_id.partner_id.id or False,
ctx)[line.account_id.pricelist_id.id]
total_amount += amount * line.unit_amount * factor_invoicing total_amount += amount * line.unit_amount * factor_invoicing
result[block.id]['amount_hours_block_done'] += total_amount result[block.id]['amount_hours_block_done'] += total_amount
return result return result
def _compute(self, cr, uid, ids, fields, args, context):
def _compute(self, cr, uid, ids, fields, args, context=None):
result = {} result = {}
block_per_types = {} block_per_types = {}
for block in self.browse(cr, uid, ids, context=context): 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: for block_type in block_per_types:
if block_type: 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: for block in result:
result[block]['amount_hours_block_delta'] = \ 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 return result
_columns = { _columns = {
'amount_hours_block': fields.function(_compute, method=True, 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,
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,
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."),
'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 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 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 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'), '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 # 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',
type='selection',
selection=[
('draft','Draft'),
('proforma','Pro-forma'),
('proforma2','Pro-forma'),
('open','Open'),
('paid','Paid'),
('cancel','Cancelled')
],
string='State', readonly=True, store=True),
'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'),
('proforma','Pro-forma'),
('proforma2','Pro-forma'),
('open','Open'),
('paid','Paid'),
('cancel','Cancelled'),
],
string='State',
readonly=True,
store=True),
} }
AccountHoursBlock()
class AccountInvoice(osv.osv):
############################################################################
## Add hours blocks on invoice
############################################################################
class AccountInvoice(orm.Model):
_inherit = 'account.invoice' _inherit = 'account.invoice'
_columns = { _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 import time
from report import report_sxw
from openerp.report import report_sxw
class account_hours_block(report_sxw.rml_parse): class account_hours_block(report_sxw.rml_parse):
def __init__(self, cr, uid, name, context=None): 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({ self.localcontext.update({
'time': time, 'time': time,
'format_date': self._get_and_change_date_format_for_swiss,
'analytic_lines': self._get_analytic_lines, 'analytic_lines': self._get_analytic_lines,
}) })
self.context = context self.context = context
def _get_analytic_lines(self, hours_block): def _get_analytic_lines(self, hours_block):
al_pool = self.pool.get('account.analytic.line') 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) 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> <para style="P12a">Invoice Date : </para>
</td> </td>
<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> </td>
</tr> </tr>
<tr> <tr>
@ -243,7 +243,7 @@
<tr> <tr>
[[ repeatIn(analytic_lines(o),'l') ]] [[ repeatIn(analytic_lines(o),'l') ]]
<td> <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>
<td> <td>
<para style="P2">[[ l.name or '' ]]</para> <para style="P2">[[ l.name or '' ]]</para>

Loading…
Cancel
Save