mirror of
https://github.com/OCA/contract.git
synced 2025-02-13 17:57:24 +02:00
[MIGR] migration of analytic_hours_block to OpenERP version 7.0
This commit is contained in:
@@ -1,27 +1,21 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
##############################################################################
|
##############################################################################
|
||||||
#
|
#
|
||||||
# @author Renaville Vincent, ported by Joel Grand-Guillaume
|
# Author: Vincent Renaville, ported by Joel Grand-Guillaume
|
||||||
# WARNING: This program as such is intended to be used by professional
|
# Copyright 2010-2012 Camptocamp SA
|
||||||
# programmers who take the whole responsability of assessing all potential
|
|
||||||
# consequences resulting from its eventual inadequacies and bugs
|
|
||||||
# End users who are looking for a ready-to-use solution with commercial
|
|
||||||
# garantees and support are strongly adviced to contract a Free Software
|
|
||||||
# Service Company
|
|
||||||
#
|
#
|
||||||
# This program is Free Software; you can redistribute it and/or
|
# This program is free software: you can redistribute it and/or modify
|
||||||
# modify it under the terms of the GNU General Public License
|
# it under the terms of the GNU Affero General Public License as
|
||||||
# as published by the Free Software Foundation; either version 2
|
# published by the Free Software Foundation, either version 3 of the
|
||||||
# of the License, or (at your option) any later version.
|
# License, or (at your option) any later version.
|
||||||
#
|
#
|
||||||
# This program is distributed in the hope that it will be useful,
|
# This program is distributed in the hope that it will be useful,
|
||||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
# GNU General Public License for more details.
|
# GNU Affero General Public License for more details.
|
||||||
#
|
#
|
||||||
# You should have received a copy of the GNU General Public License
|
# You should have received a copy of the GNU Affero General Public License
|
||||||
# along with this program; if not, write to the Free Software
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
||||||
#
|
#
|
||||||
##############################################################################
|
##############################################################################
|
||||||
import hours_block
|
import hours_block
|
||||||
|
|||||||
@@ -1,60 +1,54 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
##############################################################################
|
##############################################################################
|
||||||
#
|
#
|
||||||
# Copyright (c) 2011 Camptocamp SA (http://www.camptocamp.com)
|
# Author: Vincent Renaville, ported by Joel Grand-Guillaume
|
||||||
# All Right Reserved
|
# Copyright 2010-2012 Camptocamp SA
|
||||||
#
|
#
|
||||||
# Author : Joël Grand-Guillaume (Camptocamp)
|
# This program is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU Affero General Public License as
|
||||||
|
# published by the Free Software Foundation, either version 3 of the
|
||||||
|
# License, or (at your option) any later version.
|
||||||
#
|
#
|
||||||
# WARNING: This program as such is intended to be used by professional
|
# This program is distributed in the hope that it will be useful,
|
||||||
# programmers who take the whole responsability of assessing all potential
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
# consequences resulting from its eventual inadequacies and bugs
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
# End users who are looking for a ready-to-use solution with commercial
|
# GNU Affero General Public License for more details.
|
||||||
# garantees and support are strongly adviced to contract a Free Software
|
|
||||||
# Service Company
|
|
||||||
#
|
#
|
||||||
# This program is Free Software; you can redistribute it and/or
|
# You should have received a copy of the GNU Affero General Public License
|
||||||
# modify it under the terms of the GNU General Public License
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
# as published by the Free Software Foundation; either version 2
|
|
||||||
# of the License, or (at your option) any later version.
|
|
||||||
#
|
|
||||||
# This program is distributed in the hope that it will be useful,
|
|
||||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
# GNU General Public License for more details.
|
|
||||||
#
|
|
||||||
# You should have received a copy of the GNU General Public License
|
|
||||||
# along with this program; if not, write to the Free Software
|
|
||||||
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
||||||
#
|
#
|
||||||
##############################################################################
|
##############################################################################
|
||||||
|
|
||||||
{
|
{
|
||||||
"name" : "Project Hours Blocks Management",
|
"name": "Project Hours Blocks Management",
|
||||||
"description" : """
|
"description": """
|
||||||
|
Project Hours Blocks Management
|
||||||
|
===============================
|
||||||
|
|
||||||
This module allows you to handle hours blocks, to follow for example the user support contracts.
|
This module allows you to handle hours blocks,
|
||||||
This means, you sell a product of type "hours block" then you input the spent hours on the hours block and
|
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",
|
"version": "1.3",
|
||||||
"author" : "Camptocamp",
|
"author": "Camptocamp",
|
||||||
"category" : "Generic Modules/Projects & Services",
|
"license": 'AGPL-3',
|
||||||
|
"category": "Generic Modules/Projects & Services",
|
||||||
"website": "http://www.camptocamp.com",
|
"website": "http://www.camptocamp.com",
|
||||||
"depends" : [
|
"depends": [
|
||||||
"account",
|
"account",
|
||||||
"hr_timesheet_invoice",
|
"hr_timesheet_invoice",
|
||||||
"analytic"
|
"analytic"
|
||||||
],
|
],
|
||||||
"init_xml" : [],
|
"data": [
|
||||||
"update_xml" : [
|
"hours_block_view.xml",
|
||||||
"hours_block_view.xml",
|
"hours_block_menu.xml",
|
||||||
"hours_block_menu.xml",
|
"report.xml",
|
||||||
"report.xml",
|
"security/hours_block_security.xml",
|
||||||
"security/hours_block_security.xml",
|
"security/ir.model.access.csv",
|
||||||
"security/ir.model.access.csv",
|
],
|
||||||
],
|
|
||||||
"active": False,
|
"active": False,
|
||||||
"installable": True
|
"installable": True
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,120 +1,93 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
##############################################################################
|
##############################################################################
|
||||||
#
|
#
|
||||||
# Copyright (c) 2010 Camptocamp SA
|
# Author: Vincent Renaville, ported by Joel Grand-Guillaume
|
||||||
# All Rights Reserved
|
# Copyright 2010-2012 Camptocamp SA
|
||||||
#
|
#
|
||||||
# Author : Vincent Renaville, ported by Joel Grand-Guillaume
|
# This program is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU Affero General Public License as
|
||||||
|
# published by the Free Software Foundation, either version 3 of the
|
||||||
|
# License, or (at your option) any later version.
|
||||||
#
|
#
|
||||||
# WARNING: This program as such is intended to be used by professional
|
# This program is distributed in the hope that it will be useful,
|
||||||
# programmers who take the whole responsability of assessing all potential
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
# consequences resulting from its eventual inadequacies and bugs
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
# End users who are looking for a ready-to-use solution with commercial
|
# GNU Affero General Public License for more details.
|
||||||
# garantees and support are strongly adviced to contract a Free Software
|
|
||||||
# Service Company
|
|
||||||
#
|
#
|
||||||
# This program is Free Software; you can redistribute it and/or
|
# You should have received a copy of the GNU Affero General Public License
|
||||||
# modify it under the terms of the GNU General Public License
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
# as published by the Free Software Foundation; either version 2
|
|
||||||
# of the License, or (at your option) any later version.
|
|
||||||
#
|
|
||||||
# This program is distributed in the hope that it will be useful,
|
|
||||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
# GNU General Public License for more details.
|
|
||||||
#
|
|
||||||
# You should have received a copy of the GNU General Public License
|
|
||||||
# along with this program; if not, write to the Free Software
|
|
||||||
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
||||||
#
|
#
|
||||||
##############################################################################
|
##############################################################################
|
||||||
|
|
||||||
import time
|
from openerp.osv import orm, fields
|
||||||
import string
|
|
||||||
|
|
||||||
from osv import osv, fields
|
|
||||||
import netsvc
|
|
||||||
|
|
||||||
|
|
||||||
############################################################################
|
class AccountHoursBlock(orm.Model):
|
||||||
## Add hours blocks on invoice
|
|
||||||
############################################################################
|
|
||||||
|
|
||||||
class AccountHoursBlock(osv.osv):
|
|
||||||
_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"""
|
""" Return the last analytic line date for an invoice"""
|
||||||
context = context or {}
|
|
||||||
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:
|
res[block.id] = fetch_res[0] if fetch_res else False
|
||||||
date = fetch_res[0]
|
|
||||||
else:
|
|
||||||
date = False
|
|
||||||
res[block.id] = date
|
|
||||||
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 isinstance(ids, (int, long)):
|
||||||
if not isinstance(ids, list):
|
ids = [ids]
|
||||||
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):
|
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_done': 0.0}
|
||||||
'amount_hours_block_delta' : 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"
|
"FROM account_analytic_line AS al, "
|
||||||
" WHERE aj.id = al.journal_id AND"
|
" account_analytic_journal AS aj "
|
||||||
" aj.type='general' AND"
|
"WHERE aj.id = al.journal_id "
|
||||||
" al.invoice_id = %s", (block.invoice_id.id,))
|
"AND aj.type = 'general' "
|
||||||
res2 = cr.fetchall()
|
"AND al.invoice_id = %s", (block.invoice_id.id,))
|
||||||
if res2:
|
res_line_ids = cr.fetchall()
|
||||||
ids2 = [x[0] for x in res2]
|
line_ids = [l[0] for l in res_line_ids] if res_line_ids else []
|
||||||
else:
|
for line in aal_obj.browse(cr, uid, line_ids, context=context):
|
||||||
ids2 = []
|
factor = 1.0
|
||||||
for line in aal_obj.browse(cr, uid, ids2, context):
|
if line.product_uom_id and line.product_uom_id.factor != 0.0:
|
||||||
if line.product_uom_id:
|
|
||||||
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_done': 0.0}
|
||||||
'amount_hours_block_delta' : 0.0}
|
|
||||||
|
|
||||||
# Compute amount bought
|
# Compute amount bought
|
||||||
for line in block.invoice_id.invoice_line:
|
for line in block.invoice_id.invoice_line:
|
||||||
@@ -135,95 +108,218 @@ 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()
|
res_line_ids = cr.fetchall()
|
||||||
if res2:
|
line_ids = [l[0] for l in res_line_ids] if res_line_ids else []
|
||||||
ids2 = [x[0] for x in res2]
|
|
||||||
else:
|
|
||||||
ids2 = []
|
|
||||||
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
|
factor_invoicing = 1.0 - line.to_invoice.factor / 100
|
||||||
|
|
||||||
ctx = {'uom': line.product_uom_id.id}
|
ctx = dict(context, uom=line.product_uom_id.id)
|
||||||
amount = pricelist_obj.price_get(cr, uid,
|
amount = pricelist_obj.price_get(
|
||||||
[line.account_id.pricelist_id.id],
|
cr, uid,
|
||||||
line.product_id.id,
|
[line.account_id.pricelist_id.id],
|
||||||
line.unit_amount or 1.0,
|
line.product_id.id,
|
||||||
line.account_id.partner_id.id or False,
|
line.unit_amount or 1.0,
|
||||||
ctx)[line.account_id.pricelist_id.id]
|
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.setdefault(block.type, []).append(block.id)
|
||||||
block_per_types[block.type] = []
|
|
||||||
block_per_types[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,))
|
func = getattr(self, "_compute_%s" % block_type)
|
||||||
result.update(func(cr, uid, ids, fields, args, context))
|
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
|
||||||
|
|
||||||
|
def _get_analytic_line(self, cr, uid, ids, context=None):
|
||||||
|
invoice_ids = []
|
||||||
|
an_lines_obj = self.pool.get('account.analytic.line')
|
||||||
|
block_obj = self.pool.get('account.hours.block')
|
||||||
|
for line in an_lines_obj.browse(cr, uid, ids, context=context):
|
||||||
|
if line.invoice_id:
|
||||||
|
invoice_ids.append(line.invoice_id.id)
|
||||||
|
return block_obj.search(
|
||||||
|
cr, uid, [('invoice_id', 'in', invoice_ids)], context=context)
|
||||||
|
|
||||||
|
def _get_invoice(self, cr, uid, ids, context=None):
|
||||||
|
block_ids = set()
|
||||||
|
inv_obj = self.pool.get('account.invoice')
|
||||||
|
for invoice in inv_obj.browse(cr, uid, ids, context=context):
|
||||||
|
block_ids.update([inv.id for inv in invoice.account_hours_block_ids])
|
||||||
|
return list(block_ids)
|
||||||
|
|
||||||
|
_recompute_triggers = {
|
||||||
|
'account.hours.block': (lambda self, cr, uid, ids, c=None:
|
||||||
|
ids, ['invoice_id', 'type'], 10),
|
||||||
|
'account.invoice': (_get_invoice, ['analytic_line_ids'], 10),
|
||||||
|
'account.analytic.line': (
|
||||||
|
_get_analytic_line,
|
||||||
|
['product_uom_id', 'unit_amount', 'to_invoice', 'invoice_id'],
|
||||||
|
10),
|
||||||
|
}
|
||||||
|
|
||||||
_columns = {
|
_columns = {
|
||||||
'amount_hours_block': fields.function(_compute, method=True, type='float', string='Quantity /Amount bought', store=True,
|
'amount_hours_block': fields.function(
|
||||||
multi='amount_hours_block_delta',
|
_compute,
|
||||||
help="Amount bought by the customer. This amount is expressed in the base UoM (factor=1.0)"),
|
type='float',
|
||||||
'amount_hours_block_done': fields.function(_compute, method=True, type='float', string='Quantity / Amount used', store=True,
|
string='Quantity / Amount bought',
|
||||||
multi='amount_hours_block_delta',
|
store=_recompute_triggers,
|
||||||
help="Amount done by the staff. This amount is expressed in the base UoM (factor=1.0)"),
|
multi='amount_hours_block_delta',
|
||||||
'amount_hours_block_delta': fields.function(_compute, method=True, type='float', string='Difference', store=True,
|
help="Amount bought by the customer. "
|
||||||
multi='amount_hours_block_delta',
|
"This amount is expressed in the base Unit of Measure "
|
||||||
help="Difference between bought and used. This amount is expressed in the base UoM (factor=1.0)"),
|
"(factor=1.0)"),
|
||||||
'last_action_date': fields.function(_get_last_action, method=True, type='date', string='Last action date',
|
'amount_hours_block_done': fields.function(
|
||||||
help="Date of the last analytic line linked to the invoice related to this block hours."),
|
_compute,
|
||||||
|
type='float',
|
||||||
|
string='Quantity / Amount used',
|
||||||
|
store=_recompute_triggers,
|
||||||
|
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=_recompute_triggers,
|
||||||
|
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),
|
'invoice_id': fields.many2one(
|
||||||
'type': fields.selection([('hours','Hours'), ('amount','Amount')], 'Type of Block',
|
'account.invoice',
|
||||||
required=True, help="Choose if you want a time or amount base block."),
|
'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),
|
'date_invoice': fields.related(
|
||||||
'user_id': fields.related('invoice_id', 'user_id', type="many2one", relation="res.users", string="Salesman", store=True, readonly=True),
|
'invoice_id', 'date_invoice',
|
||||||
'partner_id': fields.related('invoice_id', 'partner_id', type="many2one", relation="res.partner", string="Partner", store=True, readonly=True),
|
type="date",
|
||||||
'name': fields.related('invoice_id', 'name', type="char",size=64, string="Description", store=True,readonly=True),
|
string="Invoice Date",
|
||||||
'number': fields.related('invoice_id', 'number', type="char",size=64, string="Number", store=True,readonly=True),
|
store=True,
|
||||||
'journal_id': fields.related('invoice_id', 'journal_id', type="many2one", relation="account.journal", string="Journal", store=True,readonly=True),
|
readonly=True),
|
||||||
'period_id': fields.related('invoice_id', 'period_id', type="many2one", relation="account.period", string="Period", store=True,readonly=True),
|
'user_id': fields.related(
|
||||||
'company_id': fields.related('invoice_id', 'company_id', type="many2one", relation="res.company", string="Company", store=True,readonly=True),
|
'invoice_id', 'user_id',
|
||||||
'currency_id': fields.related('invoice_id', 'currency_id', type="many2one", relation="res.currency", string="Currency", store=True,readonly=True),
|
type="many2one",
|
||||||
'residual': fields.related('invoice_id', 'residual', type="float", string="Residual", store=True,readonly=True),
|
relation="res.users",
|
||||||
'amount_total': fields.related('invoice_id', 'amount_total', type="float", string="Total", store=True,readonly=True),
|
string="Salesman",
|
||||||
'state':fields.related('invoice_id','state',
|
store=True,
|
||||||
type='selection',
|
readonly=True),
|
||||||
selection=[
|
'partner_id': fields.related(
|
||||||
('draft','Draft'),
|
'invoice_id', 'partner_id',
|
||||||
('proforma','Pro-forma'),
|
type="many2one",
|
||||||
('proforma2','Pro-forma'),
|
relation="res.partner",
|
||||||
('open','Open'),
|
string="Partner",
|
||||||
('paid','Paid'),
|
store=True,
|
||||||
('cancel','Cancelled')
|
readonly=True),
|
||||||
],
|
'name': fields.related(
|
||||||
string='State', readonly=True, store=True),
|
'invoice_id', 'name',
|
||||||
|
type="char",
|
||||||
|
string="Description",
|
||||||
|
store=True,
|
||||||
|
readonly=True),
|
||||||
|
'number': fields.related(
|
||||||
|
'invoice_id', 'number',
|
||||||
|
type="char",
|
||||||
|
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 = {
|
|
||||||
'account_hours_block_ids': fields.one2many('account.hours.block', 'invoice_id', 'Hours Block')
|
|
||||||
}
|
|
||||||
|
|
||||||
AccountInvoice()
|
_columns = {
|
||||||
|
'account_hours_block_ids': fields.one2many(
|
||||||
|
'account.hours.block',
|
||||||
|
'invoice_id',
|
||||||
|
string='Hours Block')
|
||||||
|
}
|
||||||
|
|||||||
@@ -2,13 +2,11 @@
|
|||||||
<openerp>
|
<openerp>
|
||||||
<data>
|
<data>
|
||||||
|
|
||||||
|
<!--
|
||||||
#---------------------------------------------------------------------------------------------------------
|
Hours block menu
|
||||||
# Hours block menu
|
-->
|
||||||
#---------------------------------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
<record model="ir.actions.act_window" id="action_all_block_hour">
|
<record model="ir.actions.act_window" id="action_all_block_hour">
|
||||||
<field name="name">Hours Block</field>
|
<field name="name">Hours Blocks</field>
|
||||||
<field name="res_model">account.hours.block</field>
|
<field name="res_model">account.hours.block</field>
|
||||||
<field name="view_type">form</field>
|
<field name="view_type">form</field>
|
||||||
<field name="view_mode">tree,form</field>
|
<field name="view_mode">tree,form</field>
|
||||||
|
|||||||
@@ -2,13 +2,12 @@
|
|||||||
<openerp>
|
<openerp>
|
||||||
<data>
|
<data>
|
||||||
|
|
||||||
#---------------------------------------------------------------------
|
<!--
|
||||||
# Hours block search form
|
Hours block search form
|
||||||
#---------------------------------------------------------------------
|
-->
|
||||||
<record id="view_account_invoice_filter" model="ir.ui.view">
|
<record id="view_account_invoice_filter" model="ir.ui.view">
|
||||||
<field name="name">account.hours.block.select</field>
|
<field name="name">account.hours.block.select</field>
|
||||||
<field name="model">account.hours.block</field>
|
<field name="model">account.hours.block</field>
|
||||||
<field name="type">search</field>
|
|
||||||
<field name="arch" type="xml">
|
<field name="arch" type="xml">
|
||||||
<search string="Search Invoice">
|
<search string="Search Invoice">
|
||||||
<group col="7" colspan="4">
|
<group col="7" colspan="4">
|
||||||
@@ -28,67 +27,77 @@
|
|||||||
<group expand="0" string="Group By...">
|
<group expand="0" string="Group By...">
|
||||||
<filter string="Partner" icon="terp-partner" domain="[]" context="{'group_by':'partner_id'}"/>
|
<filter string="Partner" icon="terp-partner" domain="[]" context="{'group_by':'partner_id'}"/>
|
||||||
<filter string="Responsible" icon="terp-personal" domain="[]" context="{'group_by':'user_id'}"/>
|
<filter string="Responsible" icon="terp-personal" domain="[]" context="{'group_by':'user_id'}"/>
|
||||||
<filter string="State" icon="terp-stock_effects-object-colorize" domain="[]" context="{'group_by':'state'}"/>
|
<filter string="Invoice State" icon="terp-stock_effects-object-colorize" domain="[]" context="{'group_by':'state'}"/>
|
||||||
</group>
|
</group>
|
||||||
</search>
|
</search>
|
||||||
</field>
|
</field>
|
||||||
</record>
|
</record>
|
||||||
|
|
||||||
#------------------------------------------------------------------------
|
<!--
|
||||||
# Hours Block View
|
Hours Block View
|
||||||
#------------------------------------------------------------------------
|
-->
|
||||||
<record id="hours_block_invoice_form" model="ir.ui.view">
|
<record id="hours_block_invoice_form" model="ir.ui.view">
|
||||||
<field name="name">account.hours.block.form</field>
|
<field name="name">account.hours.block.form</field>
|
||||||
<field name="model">account.hours.block</field>
|
<field name="model">account.hours.block</field>
|
||||||
<field name="type">form</field>
|
|
||||||
<field name="arch" type="xml">
|
<field name="arch" type="xml">
|
||||||
<form string="Invoice">
|
<form string="Hours Blocks" version="7.0">
|
||||||
<field name="type" />
|
<sheet>
|
||||||
<field name="invoice_id" />
|
<h1>
|
||||||
<field name="last_action_date" />
|
<field name="invoice_id" placeholder="Choose an invoice..."/>
|
||||||
<field name="close_date" />
|
<label for="type" string="Based on:" class="oe_inline"/>
|
||||||
<group col="6" colspan="4">
|
<field name="type" class="oe_inline"/>
|
||||||
<separator colspan="6" string="Hours Quantity / Amount"/>
|
</h1>
|
||||||
|
|
||||||
|
<group>
|
||||||
|
<field name="last_action_date" />
|
||||||
|
<field name="close_date" />
|
||||||
|
</group>
|
||||||
|
|
||||||
|
<group>
|
||||||
|
<separator colspan="4" string="Hours Quantity / Amount"/>
|
||||||
<field name="amount_hours_block" string="Bought"/>
|
<field name="amount_hours_block" string="Bought"/>
|
||||||
<field name="amount_hours_block_done" string="Used"/>
|
<field name="amount_hours_block_done" string="Used"/>
|
||||||
<field name="amount_hours_block_delta" string="Difference"/>
|
<field name="amount_hours_block_delta" string="Difference"/>
|
||||||
</group>
|
</group>
|
||||||
<separator colspan="4" string="Invoice's related information"/>
|
|
||||||
<field name="date_invoice"/>
|
<group>
|
||||||
<field name="name"/>
|
<separator colspan="4" string="Invoice's related information"/>
|
||||||
<field name="number"/>
|
<field name="date_invoice"/>
|
||||||
<field name="partner_id" groups="base.group_user"/>
|
<field name="name"/>
|
||||||
<field name="user_id"/>
|
<field name="number"/>
|
||||||
<field name="company_id" groups="base.group_multi_company" widget="selection"/>
|
<field name="partner_id" groups="base.group_user"/>
|
||||||
|
<field name="user_id"/>
|
||||||
<field name="journal_id" invisible="1"/>
|
<field name="company_id" groups="base.group_multi_company" widget="selection"/>
|
||||||
<field name="period_id" invisible="1" groups="account.group_account_user"/>
|
|
||||||
|
<field name="journal_id" invisible="1"/>
|
||||||
<field name="currency_id"/>
|
<field name="period_id" invisible="1" groups="account.group_account_user"/>
|
||||||
<newline/>
|
|
||||||
<field name="residual" sum="Residual Amount"/>
|
<field name="currency_id"/>
|
||||||
<field name="amount_total" sum="Total Amount"/>
|
<newline/>
|
||||||
<field name="state"/>
|
<field name="residual" sum="Residual Amount"/>
|
||||||
|
<field name="amount_total" sum="Total Amount"/>
|
||||||
|
<field name="state"/>
|
||||||
|
</group>
|
||||||
|
</sheet>
|
||||||
</form>
|
</form>
|
||||||
</field>
|
</field>
|
||||||
</record>
|
</record>
|
||||||
|
|
||||||
<record model="ir.ui.view" id="invoice_tree_hour_block">
|
<record model="ir.ui.view" id="invoice_tree_hour_block">
|
||||||
<field name="name">account.hours.block.tree</field>
|
<field name="name">account.hours.block.tree</field>
|
||||||
<field name="model">account.hours.block</field>
|
<field name="model">account.hours.block</field>
|
||||||
<field name="type">tree</field>
|
|
||||||
<field name="arch" type="xml">
|
<field name="arch" type="xml">
|
||||||
<tree colors="blue:state in ('draft');black:state in ('proforma','proforma2','open');gray:state in ('cancel')" string="Invoice">
|
<tree colors="blue:state in ('draft');black:state in ('proforma','proforma2','open');gray:state in ('cancel')" string="Invoice">
|
||||||
<field name="date_invoice"/>
|
<field name="date_invoice"/>
|
||||||
<field name="partner_id" groups="base.group_user"/>
|
<field name="partner_id" groups="base.group_user"/>
|
||||||
<field name="name"/>
|
<field name="name"/>
|
||||||
|
|
||||||
<field name="amount_hours_block" sum="Quantity of hours bought"/>
|
<field name="amount_hours_block" sum="Quantity of hours bought"/>
|
||||||
<field name="amount_hours_block_done" sum="Quantity of hours used" />
|
<field name="amount_hours_block_done" sum="Quantity of hours used" />
|
||||||
<field name="amount_hours_block_delta" sum="Quantity of hours difference"/>
|
<field name="amount_hours_block_delta" sum="Quantity of hours difference"/>
|
||||||
<field name="last_action_date" />
|
<field name="last_action_date" />
|
||||||
<field name="close_date" />
|
<field name="close_date" />
|
||||||
|
|
||||||
<field name="journal_id" invisible="1"/>
|
<field name="journal_id" invisible="1"/>
|
||||||
<field name="period_id" invisible="1" groups="account.group_account_user"/>
|
<field name="period_id" invisible="1" groups="account.group_account_user"/>
|
||||||
<field name="company_id" groups="base.group_multi_company" widget="selection"/>
|
<field name="company_id" groups="base.group_multi_company" widget="selection"/>
|
||||||
@@ -100,21 +109,20 @@
|
|||||||
</tree>
|
</tree>
|
||||||
</field>
|
</field>
|
||||||
</record>
|
</record>
|
||||||
|
|
||||||
|
|
||||||
#---------------------------------------------------------------------------------------------------------
|
<!--
|
||||||
# Add related act_window from partner and Hours Block
|
Add related act_window from partner and Hours Block
|
||||||
#---------------------------------------------------------------------------------------------------------
|
-->
|
||||||
<act_window name="All blocks hours"
|
<act_window name="All blocks hours"
|
||||||
domain="[('partner_id', '=', active_id)]"
|
domain="[('partner_id', '=', active_id)]"
|
||||||
res_model="account.hours.block"
|
res_model="account.hours.block"
|
||||||
src_model="res.partner"
|
src_model="res.partner"
|
||||||
id="act_block_hour_from_partner"/>
|
id="act_block_hour_from_partner"/>
|
||||||
|
|
||||||
|
|
||||||
#---------------------------------------------------------------------------------------------------------
|
<!--
|
||||||
# Link to invoice on hours block view
|
Link to invoice on hours block view
|
||||||
#---------------------------------------------------------------------------------------------------------
|
-->
|
||||||
<act_window
|
<act_window
|
||||||
domain="[('account_hours_block_ids', '=', active_id)]"
|
domain="[('account_hours_block_ids', '=', active_id)]"
|
||||||
id="act_invoice_from_hours_block"
|
id="act_invoice_from_hours_block"
|
||||||
@@ -124,9 +132,9 @@
|
|||||||
view_mode="tree,form"
|
view_mode="tree,form"
|
||||||
view_type="form"/>
|
view_type="form"/>
|
||||||
|
|
||||||
#---------------------------------------------------------------------------------------------------------
|
<!--
|
||||||
# Link to analytic lines on hours block view
|
Link to analytic lines on hours block view
|
||||||
#---------------------------------------------------------------------------------------------------------
|
-->
|
||||||
<act_window
|
<act_window
|
||||||
domain="[('invoice_id.account_hours_block_ids', '=', active_id)]"
|
domain="[('invoice_id.account_hours_block_ids', '=', active_id)]"
|
||||||
id="act_analytic_lines_from_hours_block"
|
id="act_analytic_lines_from_hours_block"
|
||||||
@@ -136,9 +144,9 @@
|
|||||||
view_mode="tree,form"
|
view_mode="tree,form"
|
||||||
view_type="form"/>
|
view_type="form"/>
|
||||||
|
|
||||||
#---------------------------------------------------------------------------------------------------------
|
<!--
|
||||||
# Link to hours block on invoice view
|
Link to hours block on invoice view
|
||||||
#---------------------------------------------------------------------------------------------------------
|
-->
|
||||||
<act_window
|
<act_window
|
||||||
domain="[('invoice_id', '=', active_id)]"
|
domain="[('invoice_id', '=', active_id)]"
|
||||||
id="act_hours_block_from_invoice"
|
id="act_hours_block_from_invoice"
|
||||||
@@ -148,6 +156,5 @@
|
|||||||
view_mode="tree,form,calendar,graph"
|
view_mode="tree,form,calendar,graph"
|
||||||
view_type="form"/>
|
view_type="form"/>
|
||||||
|
|
||||||
|
|
||||||
</data>
|
</data>
|
||||||
</openerp>
|
</openerp>
|
||||||
|
|||||||
@@ -1,27 +1,21 @@
|
|||||||
# -*- encoding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
##############################################################################
|
##############################################################################
|
||||||
#
|
#
|
||||||
|
# Author: Vincent Renaville, ported by Joel Grand-Guillaume
|
||||||
|
# Copyright 2010-2012 Camptocamp SA
|
||||||
#
|
#
|
||||||
# WARNING: This program as such is intended to be used by professional
|
# This program is free software: you can redistribute it and/or modify
|
||||||
# programmers who take the whole responsability of assessing all potential
|
# it under the terms of the GNU Affero General Public License as
|
||||||
# consequences resulting from its eventual inadequacies and bugs
|
# published by the Free Software Foundation, either version 3 of the
|
||||||
# End users who are looking for a ready-to-use solution with commercial
|
# License, or (at your option) any later version.
|
||||||
# garantees and support are strongly adviced to contract a Free Software
|
|
||||||
# Service Company
|
|
||||||
#
|
#
|
||||||
# This program is Free Software; you can redistribute it and/or
|
# This program is distributed in the hope that it will be useful,
|
||||||
# modify it under the terms of the GNU General Public License
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
# as published by the Free Software Foundation; either version 2
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
# of the License, or (at your option) any later version.
|
# GNU Affero General Public License for more details.
|
||||||
#
|
#
|
||||||
# This program is distributed in the hope that it will be useful,
|
# You should have received a copy of the GNU Affero General Public License
|
||||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
# GNU General Public License for more details.
|
|
||||||
#
|
|
||||||
# You should have received a copy of the GNU General Public License
|
|
||||||
# along with this program; if not, write to the Free Software
|
|
||||||
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
||||||
#
|
#
|
||||||
##############################################################################
|
##############################################################################
|
||||||
import hours_block
|
import hours_block
|
||||||
|
|||||||
@@ -1,59 +1,47 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
##############################################################################
|
##############################################################################
|
||||||
#
|
#
|
||||||
# Copyright (c) 2005-2006 TINY SPRL. (http://tiny.be) All Rights Reserved.
|
# Author: Vincent Renaville, ported by Joel Grand-Guillaume
|
||||||
|
# Copyright 2010-2012 Camptocamp SA
|
||||||
#
|
#
|
||||||
# WARNING: This program as such is intended to be used by professional
|
# This program is free software: you can redistribute it and/or modify
|
||||||
# programmers who take the whole responsability of assessing all potential
|
# it under the terms of the GNU Affero General Public License as
|
||||||
# consequences resulting from its eventual inadequacies and bugs
|
# published by the Free Software Foundation, either version 3 of the
|
||||||
# End users who are looking for a ready-to-use solution with commercial
|
# License, or (at your option) any later version.
|
||||||
# garantees and support are strongly adviced to contract a Free Software
|
|
||||||
# Service Company
|
|
||||||
#
|
#
|
||||||
# This program is Free Software; you can redistribute it and/or
|
# This program is distributed in the hope that it will be useful,
|
||||||
# modify it under the terms of the GNU General Public License
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
# as published by the Free Software Foundation; either version 2
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
# of the License, or (at your option) any later version.
|
# GNU Affero General Public License for more details.
|
||||||
#
|
#
|
||||||
# This program is distributed in the hope that it will be useful,
|
# You should have received a copy of the GNU Affero General Public License
|
||||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
# GNU General Public License for more details.
|
|
||||||
#
|
|
||||||
# You should have received a copy of the GNU General Public License
|
|
||||||
# along with this program; if not, write to the Free Software
|
|
||||||
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
||||||
#
|
#
|
||||||
##############################################################################
|
##############################################################################
|
||||||
|
|
||||||
import time
|
import time
|
||||||
from report import report_sxw
|
from openerp.report import report_sxw
|
||||||
|
from openerp.tools import DEFAULT_SERVER_DATE_FORMAT
|
||||||
#import xml.dom.minidom
|
|
||||||
#import re
|
|
||||||
|
|
||||||
|
|
||||||
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,
|
'date_format': DEFAULT_SERVER_DATE_FORMAT,
|
||||||
'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,
|
al_ids = al_pool.search(
|
||||||
[['invoice_id', '=', hours_block.invoice_id.id]],
|
self.cr,
|
||||||
order='date desc')
|
self.uid,
|
||||||
res = al_pool.browse(self.cr, self.uid, al_ids)
|
[('invoice_id', '=', hours_block.invoice_id.id)],
|
||||||
return res
|
order='date desc',
|
||||||
|
context=self.context)
|
||||||
def _get_and_change_date_format_for_swiss(self, date_to_format):
|
return al_pool.browse(self.cr, self.uid, al_ids, context=self.context)
|
||||||
date_formatted = ''
|
|
||||||
if date_to_format:
|
|
||||||
date_formatted = strptime(date_to_format, '%Y-%m-%d').strftime('%d.%m.%Y')
|
|
||||||
return date_formatted
|
|
||||||
|
|
||||||
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)
|
||||||
|
|||||||
@@ -10,13 +10,13 @@
|
|||||||
<drawString x="17.7cm" y="28.1cm">Maintenance And Support Summary</drawString>
|
<drawString x="17.7cm" y="28.1cm">Maintenance And Support Summary</drawString>
|
||||||
|
|
||||||
<setFont name="Helvetica" size="9"/>
|
<setFont name="Helvetica" size="9"/>
|
||||||
<drawString x="1.0cm" y="2cm"> [[ time.strftime("%m-%d-%y %H:%M", time.localtime()) ]]</drawString>
|
<drawString x="1.0cm" y="2cm"> [[ formatLang(time.strftime(date_format), date=True) ]]</drawString>
|
||||||
<drawString x="17.7cm" y="2cm">Page <pageNumber/></drawString>
|
<drawString x="17.7cm" y="2cm">Page <pageNumber/></drawString>
|
||||||
|
|
||||||
<lineMode width="0.7"/>
|
<lineMode width="0.7"/>
|
||||||
<lines>0.6cm 27.9cm 20.3cm 27.9cm</lines>
|
<lines>0.6cm 27.9cm 20.3cm 27.9cm</lines>
|
||||||
<setFont name="Helvetica" size="8"/>
|
<setFont name="Helvetica" size="8"/>
|
||||||
</pageGraphics>
|
</pageGraphics>
|
||||||
|
|
||||||
</pageTemplate>
|
</pageTemplate>
|
||||||
</template>
|
</template>
|
||||||
@@ -35,7 +35,7 @@
|
|||||||
<blockBackground colorName="#e6e6e6" start="0,1" stop="0,-1"/>
|
<blockBackground colorName="#e6e6e6" start="0,1" stop="0,-1"/>
|
||||||
<blockBackground colorName="#e6e6e6" start="1,1" stop="1,-1"/>
|
<blockBackground colorName="#e6e6e6" start="1,1" stop="1,-1"/>
|
||||||
<blockBackground colorName="#e6e6e6" start="2,1" stop="2,-1"/>
|
<blockBackground colorName="#e6e6e6" start="2,1" stop="2,-1"/>
|
||||||
|
|
||||||
</blockTableStyle>
|
</blockTableStyle>
|
||||||
<blockTableStyle id="Table6">
|
<blockTableStyle id="Table6">
|
||||||
<blockAlignment value="LEFT"/>
|
<blockAlignment value="LEFT"/>
|
||||||
@@ -165,7 +165,7 @@
|
|||||||
<blockTable colWidths="258.0,259.0" style="Table1" repeatRows="1">
|
<blockTable colWidths="258.0,259.0" style="Table1" repeatRows="1">
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
<para style="P12a">Description :</para>
|
<para style="P12a">Description: </para>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<para style="P2">[[ o.name ]]</para>
|
<para style="P2">[[ o.name ]]</para>
|
||||||
@@ -173,24 +173,24 @@
|
|||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
<para style="P12a">Report Date : </para>
|
<para style="P12a">Report Date: </para>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<para style="P2">[[ time.strftime("%d.%m.%Y", time.localtime()) ]]</para>
|
<para style="P2">[[ formatLang(time.strftime(date_format), date=True) ]]</para>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
<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>
|
||||||
<td>
|
<td>
|
||||||
<para style="P12a">Amount bought : [[ (o.type == 'amount' or removeParentNode('para')) and '' ]]</para>
|
<para style="P12a">Amount bought: [[ (o.type == 'amount' or removeParentNode('para')) and '' ]]</para>
|
||||||
<para style="P12a">Quantity of hours bought : [[ (o.type == 'hours' or removeParentNode('para')) and '' ]]</para>
|
<para style="P12a">Quantity of hours bought: [[ (o.type == 'hours' or removeParentNode('para')) and '' ]]</para>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<para style="P2">[[ o.amount_hours_block ]]</para>
|
<para style="P2">[[ o.amount_hours_block ]]</para>
|
||||||
@@ -198,9 +198,8 @@
|
|||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
<!-- <para style="P12a">[[ o.type == 'hours' and "Quantity of hours" or "Amount"]] used : </para> -->
|
<para style="P12a">Amount used: [[ (o.type == 'amount' or removeParentNode('para')) and '' ]]</para>
|
||||||
<para style="P12a">Amount used : [[ (o.type == 'amount' or removeParentNode('para')) and '' ]]</para>
|
<para style="P12a">Quantity of hours used: [[ (o.type == 'hours' or removeParentNode('para')) and '' ]]</para>
|
||||||
<para style="P12a">Quantity of hours used : [[ (o.type == 'hours' or removeParentNode('para')) and '' ]]</para>
|
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<para style="P2">[[ round(o.amount_hours_block_done, 2) ]]</para>
|
<para style="P2">[[ round(o.amount_hours_block_done, 2) ]]</para>
|
||||||
@@ -208,10 +207,9 @@
|
|||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
<!-- <para style="P12a">Remaining [[ o.type == 'hours' and "hours" or "amount"]] : </para> -->
|
<para style="P12a">Remaining amount: [[ (o.type == 'amount' or removeParentNode('para')) and '' ]]</para>
|
||||||
<para style="P12a">Remaining amount : [[ (o.type == 'amount' or removeParentNode('para')) and '' ]]</para>
|
<para style="P12a">Remaining hours: [[ (o.type == 'hours' or removeParentNode('para')) and '' ]]</para>
|
||||||
<para style="P12a">Remaining hours : [[ (o.type == 'hours' or removeParentNode('para')) and '' ]]</para>
|
|
||||||
|
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<para style="P2">[[ o.amount_hours_block and round(o.amount_hours_block_delta, 2) or '' ]]</para>
|
<para style="P2">[[ o.amount_hours_block and round(o.amount_hours_block_delta, 2) or '' ]]</para>
|
||||||
@@ -239,23 +237,23 @@
|
|||||||
<para style="P12a">Deduced</para>
|
<para style="P12a">Deduced</para>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
||||||
<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 if formatLang(l.date, date=True) else '' ]]</para>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<para style="P2">[[ l.name or '' ]]</para>
|
<para style="P2">[[ l.name or '' ]]</para>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<para style="P2c">[[ round(l.unit_amount or '0.0', 2) ]]</para>
|
<para style="P2c">[[ round(l.unit_amount, 2) or '0.0' ]]</para>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<para style="P2c">[[ l.to_invoice.customer_name ]]</para>
|
<para style="P2c">[[ l.to_invoice.customer_name ]]</para>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<para style="P2c">[[ round((l.unit_amount and l.to_invoice) and (l.unit_amount - (l.unit_amount * l.to_invoice.factor) / 100 ) or '0.0', 2) ]]</para>
|
<para style="P2c">[[ round((l.unit_amount and l.to_invoice) and (l.unit_amount - (l.unit_amount * l.to_invoice.factor) / 100 ), 2) or '0.0' ]]</para>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</blockTable>
|
</blockTable>
|
||||||
|
|||||||
@@ -7,5 +7,5 @@
|
|||||||
<field eval="True" name="global"/>
|
<field eval="True" name="global"/>
|
||||||
<field name="domain_force">[]</field>
|
<field name="domain_force">[]</field>
|
||||||
</record>
|
</record>
|
||||||
|
|
||||||
</data></openerp>
|
</data></openerp>
|
||||||
|
|||||||
Reference in New Issue
Block a user