[RENAME] account_analytic_analysis -> sale_contract
This commit is contained in:
@@ -12,7 +12,7 @@ This module is for modifying account analytic view to show some data related to
|
||||
""",
|
||||
'author': 'OpenERP S.A.',
|
||||
'website': 'https://www.odoo.com/',
|
||||
'depends': ['hr_expense','account_analytic_analysis'],
|
||||
'depends': ['hr_expense','sale_contract'],
|
||||
'data': ['analytic_contract_hr_expense_view.xml'],
|
||||
'demo': [],
|
||||
'installable': True,
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<field name="name">account.analytic.account.form.expense.inherit</field>
|
||||
<field name="model">account.analytic.account</field>
|
||||
<field eval="60" name="priority"/>
|
||||
<field name="inherit_id" ref="account_analytic_analysis.account_analytic_account_form_form"/>
|
||||
<field name="inherit_id" ref="sale_contract.account_analytic_account_form_form"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr='//tr[@name="total"]' position='before'>
|
||||
<tr>
|
||||
|
||||
@@ -554,7 +554,7 @@
|
||||
<br/>
|
||||
<h4><b>Time & material</b> <span class="small">(ex: consulting mission)</span></h4>
|
||||
<span>
|
||||
<li><a t-att-href="prepare_backend_url('account_analytic_analysis.action_account_analytic_overdue_all', 'list', 'sale')">Create your contracts</a> and configure your prices</li>
|
||||
<li><a t-att-href="prepare_backend_url('sale_contract.action_account_analytic_overdue_all', 'list', 'sale')">Create your contracts</a> and configure your prices</li>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -26,8 +26,8 @@ class hr_config_settings(osv.osv_memory):
|
||||
help ="""This installs the module hr_evaluation."""),
|
||||
'module_hr_gamification': fields.boolean('Drive engagement with challenges and badges',
|
||||
help ="""This installs the module hr_gamification."""),
|
||||
'module_account_analytic_analysis': fields.boolean('Allow invoicing based on timesheets (the sale application will be installed)',
|
||||
help ="""This installs the module account_analytic_analysis, which will install sales management too."""),
|
||||
'module_sale_contract': fields.boolean('Allow invoicing based on timesheets (the sale application will be installed)',
|
||||
help ="""This installs the module sale_contract, which will install sales management too."""),
|
||||
'module_hr_payroll': fields.boolean('Manage payroll',
|
||||
help ="""This installs the module hr_payroll."""),
|
||||
'module_website_hr_recruitment': fields.boolean('Publish jobs on your website',
|
||||
|
||||
@@ -16,7 +16,7 @@ with the effect of creating, editing and deleting either ways.
|
||||
'author': 'OpenERP SA',
|
||||
'website': 'https://www.odoo.com/page/project-management',
|
||||
'images': ['images/invoice_task_work.jpeg', 'images/my_timesheet.jpeg', 'images/working_hour.jpeg'],
|
||||
'depends': ['resource', 'project', 'account_analytic_analysis', 'procurement'],
|
||||
'depends': ['resource', 'project', 'sale_contract', 'procurement'],
|
||||
'data': [
|
||||
'security/ir.model.access.csv',
|
||||
'security/project_timesheet_security.xml',
|
||||
|
||||
@@ -126,7 +126,7 @@
|
||||
<field name="view_mode">tree,form,graph</field>
|
||||
<field name="context">{}</field>
|
||||
<field name="domain">[('type','=','normal')]</field>
|
||||
<field name="search_view_id" ref="account_analytic_analysis.view_account_analytic_account_overdue_search"/>
|
||||
<field name="search_view_id" ref="sale_contract.view_account_analytic_account_overdue_search"/>
|
||||
<field name="help" type="html">
|
||||
<p class="oe_view_nocontent_create">
|
||||
Click to add a customer contract.
|
||||
@@ -136,6 +136,9 @@
|
||||
</p>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<menuitem id="menu_invoicing_contracts" parent="menu_project_billing" sequence="4"
|
||||
action="sale_contract.action_account_analytic_overdue"/>
|
||||
|
||||
<record model="ir.ui.view" id="view_task_form2_inherited">
|
||||
<field name="name">project.task.form.inherited</field>
|
||||
|
||||
@@ -16,13 +16,13 @@ class sale_configuration(osv.TransientModel):
|
||||
'timesheet': fields.boolean('Prepare invoices based on timesheets',
|
||||
help='For modifying account analytic view to show important data to project manager of services companies.'
|
||||
'You can also view the report of account analytic summary user-wise as well as month wise.\n'
|
||||
'-This installs the module account_analytic_analysis.'),
|
||||
'module_account_analytic_analysis': fields.boolean('Use contracts management',
|
||||
'-This installs the module sale_contract.'),
|
||||
'module_sale_contract': fields.boolean('Use contracts management',
|
||||
help='Allows to define your customer contracts conditions: invoicing '
|
||||
'method (fixed price, on timesheet, advance invoice), the exact pricing '
|
||||
'(650€/day for a developer), the duration (one year support contract).\n'
|
||||
'You will be able to follow the progress of the contract and invoice automatically.\n'
|
||||
'-It installs the account_analytic_analysis module.'),
|
||||
'-It installs the sale_contract module.'),
|
||||
'group_sale_pricelist':fields.boolean("Use pricelists to adapt your price per customers",
|
||||
implied_group='product.group_sale_pricelist',
|
||||
help="""Allows to manage different prices based on rules per category of customers.
|
||||
@@ -79,7 +79,7 @@ Example: 10% for retailers, promotion of 5 EUR on this product, etc."""),
|
||||
def onchange_timesheet(self, cr, uid, ids, timesheet, context=None):
|
||||
return {'value': {
|
||||
'timesheet': timesheet,
|
||||
'module_account_analytic_analysis': timesheet,
|
||||
'module_sale_contract': timesheet,
|
||||
}}
|
||||
|
||||
class account_config_settings(osv.osv_memory):
|
||||
|
||||
@@ -95,10 +95,10 @@
|
||||
<label for="id" string="Contract Features"/>
|
||||
<div>
|
||||
<div>
|
||||
<field name="module_account_analytic_analysis" on_change="onchange_timesheet(module_account_analytic_analysis)" class="oe_inline"/>
|
||||
<label for="module_account_analytic_analysis"/>
|
||||
<field name="module_sale_contract" on_change="onchange_timesheet(module_sale_contract)" class="oe_inline"/>
|
||||
<label for="module_sale_contract"/>
|
||||
</div>
|
||||
<div name="module_analytic_user_function" attrs="{'invisible':[('module_account_analytic_analysis','=',False)]}">
|
||||
<div name="module_analytic_user_function" attrs="{'invisible':[('module_sale_contract','=',False)]}">
|
||||
<field name="module_analytic_user_function" class="oe_inline"/>
|
||||
<label for="module_analytic_user_function"/>
|
||||
</div>
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
import account_analytic_analysis
|
||||
import res_config
|
||||
import models
|
||||
import report
|
||||
import test
|
||||
+6
-5
@@ -18,13 +18,14 @@ Adds menu to show relevant information to each manager.You can also view the rep
|
||||
'data': [
|
||||
'security/ir.model.access.csv',
|
||||
'security/account_analytic_analysis_security.xml',
|
||||
'account_analytic_analysis_view.xml',
|
||||
'account_analytic_analysis_cron.xml',
|
||||
'res_config_view.xml',
|
||||
'views/sale_contract_view.xml',
|
||||
'data/sale_contract_cron.xml',
|
||||
'views/res_config_view.xml',
|
||||
'views/account_analytic_analysis.xml',
|
||||
'views/product_template_view.xml',
|
||||
],
|
||||
'demo': ['analytic_account_demo.xml', 'analytic_account_demo.yml'],
|
||||
'test': ['../account/test/account_minimal_test.xml', 'test/account_analytic_analysis.yml'],
|
||||
'demo': ['demo/sale_contract_demo.xml'],
|
||||
'test': ['test/account_analytic_analysis.yml'],
|
||||
'installable': True,
|
||||
'auto_install': False,
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
import sale_contract
|
||||
import sale
|
||||
import res_config
|
||||
|
||||
+2
-2
@@ -10,7 +10,7 @@ class sale_configuration(osv.osv_memory):
|
||||
|
||||
_columns = {
|
||||
'group_template_required': fields.boolean("Mandatory use of templates.",
|
||||
implied_group='account_analytic_analysis.group_template_required',
|
||||
implied_group='sale_contract.group_template_required',
|
||||
help="Allows you to set the template field as required when creating an analytic account or a contract."),
|
||||
'time_unit': fields.many2one('product.uom', 'The default working time unit.'),
|
||||
}
|
||||
@@ -25,7 +25,7 @@ class sale_configuration(osv.osv_memory):
|
||||
product = ir_model_data.xmlid_to_object(cr, uid, 'product.product_product_consultant')
|
||||
if product and product.exists():
|
||||
res['time_unit'] = product.uom_id.id
|
||||
res['timesheet'] = res.get('module_account_analytic_analysis')
|
||||
res['timesheet'] = res.get('module_sale_contract')
|
||||
return res
|
||||
|
||||
def set_sale_defaults(self, cr, uid, ids, context=None):
|
||||
@@ -0,0 +1,37 @@
|
||||
from openerp import models, fields, api
|
||||
|
||||
|
||||
class product_template(models.Model):
|
||||
""" Add recurrent_invoice field to product template if it is true,
|
||||
it will add to related contract.
|
||||
"""
|
||||
_inherit = "product.template"
|
||||
|
||||
recurring_invoice = fields.Boolean(
|
||||
string='Recurrent Invoice Product', default=False,
|
||||
help="If selected, this product will be added to the "
|
||||
"related contract (which must be associated with the SO). \n"
|
||||
"It will be used as product for invoice lines and generate "
|
||||
"the recurring invoices automatically")
|
||||
|
||||
|
||||
class sale_order_line(models.Model):
|
||||
_inherit = "sale.order.line"
|
||||
|
||||
@api.one
|
||||
def button_confirm(self):
|
||||
if self.product_id.recurring_invoice and self.order_id.project_id:
|
||||
invoice_line_ids = [((0, 0, {
|
||||
'product_id': self.product_id.id,
|
||||
'analytic_account_id': self.order_id.project_id.id,
|
||||
'name': self.name,
|
||||
'quantity': self.product_uom_qty,
|
||||
'uom_id': self.product_uom.id,
|
||||
'price_unit': self.price_unit,
|
||||
'price_subtotal': self.price_subtotal
|
||||
}))]
|
||||
analytic_values = {'recurring_invoices': True, 'recurring_invoice_line_ids': invoice_line_ids}
|
||||
if not self.order_id.project_id.partner_id:
|
||||
analytic_values['partner_id'] = self.order_id.partner_id.id
|
||||
self.order_id.project_id.write(analytic_values)
|
||||
return super(sale_order_line, self).button_confirm()
|
||||
+2
-125
@@ -623,8 +623,8 @@ class account_analytic_account(osv.osv):
|
||||
fill_remind("future", [('state', 'in', ['draft', 'open']), ('date', '!=', False), ('date', '<', (datetime.datetime.now() + datetime.timedelta(30)).strftime("%Y-%m-%d"))])
|
||||
|
||||
context['base_url'] = self.pool.get('ir.config_parameter').get_param(cr, uid, 'web.base.url')
|
||||
context['action_id'] = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'account_analytic_analysis', 'action_account_analytic_overdue_all')[1]
|
||||
template_id = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'account_analytic_analysis', 'account_analytic_cron_email_template')[1]
|
||||
context['action_id'] = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'sale_contract', 'action_account_analytic_overdue_all')[1]
|
||||
template_id = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'sale_contract', 'account_analytic_cron_email_template')[1]
|
||||
for user_id, data in remind.items():
|
||||
context["data"] = data
|
||||
_logger.debug("Sending reminder to uid %s", user_id)
|
||||
@@ -763,126 +763,3 @@ class account_analytic_account(osv.osv):
|
||||
else:
|
||||
raise
|
||||
return invoice_ids
|
||||
|
||||
class account_analytic_account_summary_user(osv.osv):
|
||||
_name = "account_analytic_analysis.summary.user"
|
||||
_description = "Hours Summary by User"
|
||||
_order='user'
|
||||
_auto = False
|
||||
_rec_name = 'user'
|
||||
|
||||
def _unit_amount(self, cr, uid, ids, name, arg, context=None):
|
||||
res = {}
|
||||
account_obj = self.pool.get('account.analytic.account')
|
||||
cr.execute('SELECT MAX(id) FROM res_users')
|
||||
max_user = cr.fetchone()[0]
|
||||
account_ids = [int(str(x/max_user - (x%max_user == 0 and 1 or 0))) for x in ids]
|
||||
user_ids = [int(str(x-((x/max_user - (x%max_user == 0 and 1 or 0)) *max_user))) for x in ids]
|
||||
parent_ids = tuple(account_ids) #We don't want consolidation for each of these fields because those complex computation is resource-greedy.
|
||||
if parent_ids:
|
||||
cr.execute('SELECT id, unit_amount ' \
|
||||
'FROM account_analytic_analysis_summary_user ' \
|
||||
'WHERE account_id IN %s ' \
|
||||
'AND "user" IN %s',(parent_ids, tuple(user_ids),))
|
||||
for sum_id, unit_amount in cr.fetchall():
|
||||
res[sum_id] = unit_amount
|
||||
for id in ids:
|
||||
res[id] = round(res.get(id, 0.0), 2)
|
||||
return res
|
||||
|
||||
_columns = {
|
||||
'account_id': fields.many2one('account.analytic.account', 'Analytic Account', readonly=True),
|
||||
'unit_amount': fields.float('Total Time'),
|
||||
'user': fields.many2one('res.users', 'User'),
|
||||
}
|
||||
|
||||
_depends = {
|
||||
'res.users': ['id'],
|
||||
'account.analytic.line': ['account_id', 'journal_id', 'unit_amount', 'user_id'],
|
||||
'account.analytic.journal': ['type'],
|
||||
}
|
||||
|
||||
def init(self, cr):
|
||||
openerp.tools.sql.drop_view_if_exists(cr, 'account_analytic_analysis_summary_user')
|
||||
cr.execute('''CREATE OR REPLACE VIEW account_analytic_analysis_summary_user AS (
|
||||
with mu as
|
||||
(select max(id) as max_user from res_users)
|
||||
, lu AS
|
||||
(SELECT
|
||||
l.account_id AS account_id,
|
||||
coalesce(l.user_id, 0) AS user_id,
|
||||
SUM(l.unit_amount) AS unit_amount
|
||||
FROM account_analytic_line AS l,
|
||||
account_analytic_journal AS j
|
||||
WHERE (j.type = 'general' ) and (j.id=l.journal_id)
|
||||
GROUP BY l.account_id, l.user_id
|
||||
)
|
||||
select (lu.account_id * mu.max_user) + lu.user_id as id,
|
||||
lu.account_id as account_id,
|
||||
lu.user_id as "user",
|
||||
unit_amount
|
||||
from lu, mu)''')
|
||||
|
||||
class account_analytic_account_summary_month(osv.osv):
|
||||
_name = "account_analytic_analysis.summary.month"
|
||||
_description = "Hours summary by month"
|
||||
_auto = False
|
||||
_rec_name = 'month'
|
||||
|
||||
_columns = {
|
||||
'account_id': fields.many2one('account.analytic.account', 'Analytic Account', readonly=True),
|
||||
'unit_amount': fields.float('Total Time'),
|
||||
'month': fields.char('Month', size=32, readonly=True),
|
||||
}
|
||||
|
||||
_depends = {
|
||||
'account.analytic.line': ['account_id', 'date', 'journal_id', 'unit_amount'],
|
||||
'account.analytic.journal': ['type'],
|
||||
}
|
||||
|
||||
def init(self, cr):
|
||||
openerp.tools.sql.drop_view_if_exists(cr, 'account_analytic_analysis_summary_month')
|
||||
cr.execute('CREATE VIEW account_analytic_analysis_summary_month AS (' \
|
||||
'SELECT ' \
|
||||
'(TO_NUMBER(TO_CHAR(d.month, \'YYYYMM\'), \'999999\') + (d.account_id * 1000000::bigint))::bigint AS id, ' \
|
||||
'd.account_id AS account_id, ' \
|
||||
'TO_CHAR(d.month, \'Mon YYYY\') AS month, ' \
|
||||
'TO_NUMBER(TO_CHAR(d.month, \'YYYYMM\'), \'999999\') AS month_id, ' \
|
||||
'COALESCE(SUM(l.unit_amount), 0.0) AS unit_amount ' \
|
||||
'FROM ' \
|
||||
'(SELECT ' \
|
||||
'd2.account_id, ' \
|
||||
'd2.month ' \
|
||||
'FROM ' \
|
||||
'(SELECT ' \
|
||||
'a.id AS account_id, ' \
|
||||
'l.month AS month ' \
|
||||
'FROM ' \
|
||||
'(SELECT ' \
|
||||
'DATE_TRUNC(\'month\', l.date) AS month ' \
|
||||
'FROM account_analytic_line AS l, ' \
|
||||
'account_analytic_journal AS j ' \
|
||||
'WHERE j.type = \'general\' ' \
|
||||
'GROUP BY DATE_TRUNC(\'month\', l.date) ' \
|
||||
') AS l, ' \
|
||||
'account_analytic_account AS a ' \
|
||||
'GROUP BY l.month, a.id ' \
|
||||
') AS d2 ' \
|
||||
'GROUP BY d2.account_id, d2.month ' \
|
||||
') AS d ' \
|
||||
'LEFT JOIN ' \
|
||||
'(SELECT ' \
|
||||
'l.account_id AS account_id, ' \
|
||||
'DATE_TRUNC(\'month\', l.date) AS month, ' \
|
||||
'SUM(l.unit_amount) AS unit_amount ' \
|
||||
'FROM account_analytic_line AS l, ' \
|
||||
'account_analytic_journal AS j ' \
|
||||
'WHERE (j.type = \'general\') and (j.id=l.journal_id) ' \
|
||||
'GROUP BY l.account_id, DATE_TRUNC(\'month\', l.date) ' \
|
||||
') AS l '
|
||||
'ON (' \
|
||||
'd.account_id = l.account_id ' \
|
||||
'AND d.month = l.month' \
|
||||
') ' \
|
||||
'GROUP BY d.month, d.account_id ' \
|
||||
')')
|
||||
@@ -0,0 +1,2 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
import account_analytic_analysis_summary
|
||||
@@ -0,0 +1,137 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from dateutil.relativedelta import relativedelta
|
||||
import datetime
|
||||
import logging
|
||||
import time
|
||||
|
||||
from openerp.osv import osv, fields
|
||||
import openerp.tools
|
||||
from openerp.tools.translate import _
|
||||
from openerp.exceptions import UserError
|
||||
|
||||
from openerp.addons.decimal_precision import decimal_precision as dp
|
||||
|
||||
_logger = logging.getLogger(__name__)
|
||||
|
||||
class account_analytic_account_summary_user(osv.osv):
|
||||
_name = "account_analytic_analysis.summary.user"
|
||||
_description = "Hours Summary by User"
|
||||
_order='user'
|
||||
_auto = False
|
||||
_rec_name = 'user'
|
||||
|
||||
def _unit_amount(self, cr, uid, ids, name, arg, context=None):
|
||||
res = {}
|
||||
account_obj = self.pool.get('account.analytic.account')
|
||||
cr.execute('SELECT MAX(id) FROM res_users')
|
||||
max_user = cr.fetchone()[0]
|
||||
account_ids = [int(str(x/max_user - (x%max_user == 0 and 1 or 0))) for x in ids]
|
||||
user_ids = [int(str(x-((x/max_user - (x%max_user == 0 and 1 or 0)) *max_user))) for x in ids]
|
||||
parent_ids = tuple(account_ids) #We don't want consolidation for each of these fields because those complex computation is resource-greedy.
|
||||
if parent_ids:
|
||||
cr.execute('SELECT id, unit_amount ' \
|
||||
'FROM account_analytic_analysis_summary_user ' \
|
||||
'WHERE account_id IN %s ' \
|
||||
'AND "user" IN %s',(parent_ids, tuple(user_ids),))
|
||||
for sum_id, unit_amount in cr.fetchall():
|
||||
res[sum_id] = unit_amount
|
||||
for id in ids:
|
||||
res[id] = round(res.get(id, 0.0), 2)
|
||||
return res
|
||||
|
||||
_columns = {
|
||||
'account_id': fields.many2one('account.analytic.account', 'Analytic Account', readonly=True),
|
||||
'unit_amount': fields.float('Total Time'),
|
||||
'user': fields.many2one('res.users', 'User'),
|
||||
}
|
||||
|
||||
_depends = {
|
||||
'res.users': ['id'],
|
||||
'account.analytic.line': ['account_id', 'journal_id', 'unit_amount', 'user_id'],
|
||||
'account.analytic.journal': ['type'],
|
||||
}
|
||||
|
||||
def init(self, cr):
|
||||
openerp.tools.sql.drop_view_if_exists(cr, 'account_analytic_analysis_summary_user')
|
||||
cr.execute('''CREATE OR REPLACE VIEW account_analytic_analysis_summary_user AS (
|
||||
with mu as
|
||||
(select max(id) as max_user from res_users)
|
||||
, lu AS
|
||||
(SELECT
|
||||
l.account_id AS account_id,
|
||||
coalesce(l.user_id, 0) AS user_id,
|
||||
SUM(l.unit_amount) AS unit_amount
|
||||
FROM account_analytic_line AS l,
|
||||
account_analytic_journal AS j
|
||||
WHERE (j.type = 'general' ) and (j.id=l.journal_id)
|
||||
GROUP BY l.account_id, l.user_id
|
||||
)
|
||||
select (lu.account_id * mu.max_user) + lu.user_id as id,
|
||||
lu.account_id as account_id,
|
||||
lu.user_id as "user",
|
||||
unit_amount
|
||||
from lu, mu)''')
|
||||
|
||||
class account_analytic_account_summary_month(osv.osv):
|
||||
_name = "account_analytic_analysis.summary.month"
|
||||
_description = "Hours summary by month"
|
||||
_auto = False
|
||||
_rec_name = 'month'
|
||||
|
||||
_columns = {
|
||||
'account_id': fields.many2one('account.analytic.account', 'Analytic Account', readonly=True),
|
||||
'unit_amount': fields.float('Total Time'),
|
||||
'month': fields.char('Month', size=32, readonly=True),
|
||||
}
|
||||
|
||||
_depends = {
|
||||
'account.analytic.line': ['account_id', 'date', 'journal_id', 'unit_amount'],
|
||||
'account.analytic.journal': ['type'],
|
||||
}
|
||||
|
||||
def init(self, cr):
|
||||
openerp.tools.sql.drop_view_if_exists(cr, 'account_analytic_analysis_summary_month')
|
||||
cr.execute('CREATE VIEW account_analytic_analysis_summary_month AS (' \
|
||||
'SELECT ' \
|
||||
'(TO_NUMBER(TO_CHAR(d.month, \'YYYYMM\'), \'999999\') + (d.account_id * 1000000::bigint))::bigint AS id, ' \
|
||||
'd.account_id AS account_id, ' \
|
||||
'TO_CHAR(d.month, \'Mon YYYY\') AS month, ' \
|
||||
'TO_NUMBER(TO_CHAR(d.month, \'YYYYMM\'), \'999999\') AS month_id, ' \
|
||||
'COALESCE(SUM(l.unit_amount), 0.0) AS unit_amount ' \
|
||||
'FROM ' \
|
||||
'(SELECT ' \
|
||||
'd2.account_id, ' \
|
||||
'd2.month ' \
|
||||
'FROM ' \
|
||||
'(SELECT ' \
|
||||
'a.id AS account_id, ' \
|
||||
'l.month AS month ' \
|
||||
'FROM ' \
|
||||
'(SELECT ' \
|
||||
'DATE_TRUNC(\'month\', l.date) AS month ' \
|
||||
'FROM account_analytic_line AS l, ' \
|
||||
'account_analytic_journal AS j ' \
|
||||
'WHERE j.type = \'general\' ' \
|
||||
'GROUP BY DATE_TRUNC(\'month\', l.date) ' \
|
||||
') AS l, ' \
|
||||
'account_analytic_account AS a ' \
|
||||
'GROUP BY l.month, a.id ' \
|
||||
') AS d2 ' \
|
||||
'GROUP BY d2.account_id, d2.month ' \
|
||||
') AS d ' \
|
||||
'LEFT JOIN ' \
|
||||
'(SELECT ' \
|
||||
'l.account_id AS account_id, ' \
|
||||
'DATE_TRUNC(\'month\', l.date) AS month, ' \
|
||||
'SUM(l.unit_amount) AS unit_amount ' \
|
||||
'FROM account_analytic_line AS l, ' \
|
||||
'account_analytic_journal AS j ' \
|
||||
'WHERE (j.type = \'general\') and (j.id=l.journal_id) ' \
|
||||
'GROUP BY l.account_id, DATE_TRUNC(\'month\', l.date) ' \
|
||||
') AS l '
|
||||
'ON (' \
|
||||
'd.account_id = l.account_id ' \
|
||||
'AND d.month = l.month' \
|
||||
') ' \
|
||||
'GROUP BY d.month, d.account_id ' \
|
||||
')')
|
||||
+5
-5
@@ -19,14 +19,14 @@
|
||||
-
|
||||
!record {model: account.analytic.account, id: contract_main}:
|
||||
partner_id: base.main_partner
|
||||
template_id: account_analytic_analysis.contract_template
|
||||
template_id: sale_contract.contract_template
|
||||
type: contract
|
||||
-
|
||||
I check that the contract inherited from data of the template
|
||||
-
|
||||
!python {model: account.analytic.account}: |
|
||||
contract = self.browse(cr, uid, ref('account_analytic_analysis.contract_main'))
|
||||
template = self.browse(cr, uid, ref('account_analytic_analysis.contract_template'))
|
||||
contract = self.browse(cr, uid, ref('sale_contract.contract_main'))
|
||||
template = self.browse(cr, uid, ref('sale_contract.contract_template'))
|
||||
assert template.recurring_interval == contract.recurring_interval, "The recurring interval of the contract does not match with the contract template"
|
||||
assert template.recurring_invoices == contract.recurring_invoices, "Invoice method of contract does not match with the contract template"
|
||||
-
|
||||
@@ -39,8 +39,8 @@
|
||||
-
|
||||
!python {model: account.invoice}: |
|
||||
from openerp.tools import float_compare
|
||||
aid = ref('account_analytic_analysis.contract_main')
|
||||
ids = self.search(cr, uid, [('invoice_line_ids.account_analytic_id','=',aid)], context=context)
|
||||
aid = ref('sale_contract.contract_main')
|
||||
ids = self.search(cr, uid, [('invoice_line.analytic_account_id','=',aid)], context=context)
|
||||
assert len(ids)>=1, 'No invoice created for the contract'
|
||||
for invoice in self.browse(cr, uid, ids,context=context):
|
||||
assert float_compare(invoice.amount_untaxed, 150.0, precision_digits=2) == 0, "The invoice total is different than 150!"
|
||||
+1
-1
@@ -3,7 +3,7 @@
|
||||
<data>
|
||||
<template id="assets_backend" name="account_analytic_analysis assets" inherit_id="web.assets_backend">
|
||||
<xpath expr="." position="inside">
|
||||
<link rel="stylesheet" href="/account_analytic_analysis/static/src/css/analytic.css"/>
|
||||
<link rel="stylesheet" href="/sale_contract/static/src/css/analytic.css"/>
|
||||
</xpath>
|
||||
</template>
|
||||
</data>
|
||||
@@ -0,0 +1,19 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<openerp>
|
||||
<data>
|
||||
|
||||
<record id="view_product_template_recurrent_form_inherit" model="ir.ui.view">
|
||||
<field name="name">product_template_form_view.inherit</field>
|
||||
<field name="model">product.template</field>
|
||||
<field name="inherit_id" ref="product.product_template_form_view"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//group[@name='sale_condition']" position="after">
|
||||
<group name="contract" string="Contract" colspan="3">
|
||||
<field name="recurring_invoice" class="oe_inline"/>
|
||||
</group>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
</data>
|
||||
</openerp>
|
||||
+1
-1
@@ -17,7 +17,7 @@
|
||||
<attribute name="invisible">0</attribute>
|
||||
</group>
|
||||
<xpath expr="//div[@name='div_default_options']" position="inside">
|
||||
<div name='time_unit' attrs="{'required':[('module_account_analytic_analysis','=',True)]}">
|
||||
<div name='time_unit' attrs="{'required':[('module_sale_contract','=',True)]}">
|
||||
<label for="time_unit"/>
|
||||
<field name="time_unit" domain="[('category_id.name','=','Working Time')]" class="oe_inline"/>
|
||||
</div>
|
||||
+1
-1
@@ -368,7 +368,7 @@
|
||||
|
||||
<menuitem action="template_of_contract_action" id="menu_template_of_contract_action" parent="base.menu_sales_config" sequence="3"/>
|
||||
|
||||
<record id="account_analytic_analysis_form_form" model="ir.ui.view">
|
||||
<record id="sale_contract_form_form" model="ir.ui.view">
|
||||
<field name="name">account.analytic.account.invoice.form.inherit</field>
|
||||
<field name="model">account.analytic.account</field>
|
||||
<field name="inherit_id" ref="analytic.view_account_analytic_account_form"/>
|
||||
Reference in New Issue
Block a user