mirror of
https://gitlab.com/flectra-hq/flectra.git
synced 2026-08-17 16:54:42 -05:00
[ADD] account budget module
This commit is contained in:
@@ -0,0 +1,4 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo, Flectra. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from . import models
|
||||
@@ -0,0 +1,26 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo, Flectra. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
{
|
||||
'name': 'Budget Management',
|
||||
'author': 'FlectraHQ, Odoo Mates, Odoo SA',
|
||||
'category': 'Accounting',
|
||||
'version': '2.0.1.0.0',
|
||||
'description': """Use budgets to compare actual with expected revenues and costs""",
|
||||
'summary': 'Budget Management',
|
||||
'sequence': 10,
|
||||
'website': 'https://www.flectrahq.com',
|
||||
'depends': ['account'],
|
||||
'license': 'LGPL-3',
|
||||
'company': 'FlectraHQ',
|
||||
'maintainer': 'FlectraHQ',
|
||||
'data': [
|
||||
'security/ir.model.access.csv',
|
||||
'security/account_budget_security.xml',
|
||||
'views/account_analytic_account_views.xml',
|
||||
'views/account_budget_views.xml',
|
||||
'views/res_config_settings_views.xml',
|
||||
],
|
||||
"images": ['static/description/banner.gif'],
|
||||
'demo': ['data/account_budget_demo.xml'],
|
||||
}
|
||||
@@ -0,0 +1,206 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<flectra>
|
||||
|
||||
<data noupdate="1">
|
||||
<record id="crossovered_budget_budgetoptimistic0" model="crossovered.budget">
|
||||
<field eval="'Budget '+str(datetime.now().year+1)+': Optimistic'" name="name"/>
|
||||
<field eval="str(datetime.now().year+1)+'-01-01'" name="date_from"/>
|
||||
<field eval=""""draft"""" name="state"/>
|
||||
<field eval="str(datetime.now().year+1)+'-12-31'" name="date_to"/>
|
||||
<field name="user_id" ref="base.user_root"/>
|
||||
</record>
|
||||
<record id="budget_line_analytic_admin" model="crossovered.budget.lines">
|
||||
<field name="crossovered_budget_id" ref="crossovered_budget_budgetoptimistic0" />
|
||||
<field eval="str(datetime.now().year+1)+'-01-01'" name="date_from"/>
|
||||
<field eval="str(datetime.now().year+1)+'-12-31'" name="date_to"/>
|
||||
<field name="planned_amount">-35000</field>
|
||||
<field name="analytic_account_id" ref="analytic.analytic_administratif"/>
|
||||
</record>
|
||||
<record id="budget_line_analytic_agrolait1" model="crossovered.budget.lines">
|
||||
<field name="crossovered_budget_id" ref="crossovered_budget_budgetoptimistic0" />
|
||||
<field eval="str(datetime.now().year+1)+'-01-01'" name="date_from"/>
|
||||
<field eval="str(datetime.now().year+1)+'-01-31'" name="date_to"/>
|
||||
<field name="planned_amount">10000</field>
|
||||
<field name="analytic_account_id" ref="analytic.analytic_agrolait"/>
|
||||
</record>
|
||||
<record id="budget_line_analytic_agrolait2" model="crossovered.budget.lines">
|
||||
<field name="crossovered_budget_id" ref="crossovered_budget_budgetoptimistic0" />
|
||||
<field eval="str(datetime.now().year+1)+'-02-01'" name="date_from"/>
|
||||
<field eval="str(datetime.now().year+1)+'-02-28'" name="date_to"/>
|
||||
<field name="planned_amount">10000</field>
|
||||
<field name="analytic_account_id" ref="analytic.analytic_agrolait"/>
|
||||
</record>
|
||||
<record id="budget_line_analytic_agrolait3" model="crossovered.budget.lines">
|
||||
<field name="crossovered_budget_id" ref="crossovered_budget_budgetoptimistic0" />
|
||||
<field eval="str(datetime.now().year+1)+'-03-01'" name="date_from"/>
|
||||
<field eval="str(datetime.now().year+1)+'-03-31'" name="date_to"/>
|
||||
<field name="planned_amount">12000</field>
|
||||
<field name="analytic_account_id" ref="analytic.analytic_agrolait"/>
|
||||
</record>
|
||||
<record id="budget_line_analytic_agrolait4" model="crossovered.budget.lines">
|
||||
<field name="crossovered_budget_id" ref="crossovered_budget_budgetoptimistic0" />
|
||||
<field eval="str(datetime.now().year+1)+'-04-01'" name="date_from"/>
|
||||
<field eval="str(datetime.now().year+1)+'-04-30'" name="date_to"/>
|
||||
<field name="planned_amount">15000</field>
|
||||
<field name="analytic_account_id" ref="analytic.analytic_agrolait"/>
|
||||
</record>
|
||||
<record id="budget_line_analytic_agrolait5" model="crossovered.budget.lines">
|
||||
<field name="crossovered_budget_id" ref="crossovered_budget_budgetoptimistic0" />
|
||||
<field eval="str(datetime.now().year+1)+'-05-01'" name="date_from"/>
|
||||
<field eval="str(datetime.now().year+1)+'-05-31'" name="date_to"/>
|
||||
<field name="planned_amount">15000</field>
|
||||
<field name="analytic_account_id" ref="analytic.analytic_agrolait"/>
|
||||
</record>
|
||||
<record id="budget_line_analytic_agrolait6" model="crossovered.budget.lines">
|
||||
<field name="crossovered_budget_id" ref="crossovered_budget_budgetoptimistic0" />
|
||||
<field eval="str(datetime.now().year+1)+'-06-01'" name="date_from"/>
|
||||
<field eval="str(datetime.now().year+1)+'-06-30'" name="date_to"/>
|
||||
<field name="planned_amount">15000</field>
|
||||
<field name="analytic_account_id" ref="analytic.analytic_agrolait"/>
|
||||
</record>
|
||||
<record id="budget_line_analytic_agrolait7" model="crossovered.budget.lines">
|
||||
<field name="crossovered_budget_id" ref="crossovered_budget_budgetoptimistic0" />
|
||||
<field eval="str(datetime.now().year+1)+'-07-01'" name="date_from"/>
|
||||
<field eval="str(datetime.now().year+1)+'-07-31'" name="date_to"/>
|
||||
<field name="planned_amount">13000</field>
|
||||
<field name="analytic_account_id" ref="analytic.analytic_agrolait"/>
|
||||
</record>
|
||||
<record id="budget_line_analytic_agrolait8" model="crossovered.budget.lines">
|
||||
<field name="crossovered_budget_id" ref="crossovered_budget_budgetoptimistic0" />
|
||||
<field eval="str(datetime.now().year+1)+'-08-01'" name="date_from"/>
|
||||
<field eval="str(datetime.now().year+1)+'-08-31'" name="date_to"/>
|
||||
<field name="planned_amount">9000</field>
|
||||
<field name="analytic_account_id" ref="analytic.analytic_agrolait"/>
|
||||
</record>
|
||||
<record id="budget_line_analytic_agrolait9" model="crossovered.budget.lines">
|
||||
<field name="crossovered_budget_id" ref="crossovered_budget_budgetoptimistic0" />
|
||||
<field eval="str(datetime.now().year+1)+'-09-01'" name="date_from"/>
|
||||
<field eval="str(datetime.now().year+1)+'-09-30'" name="date_to"/>
|
||||
<field name="planned_amount">8000</field>
|
||||
<field name="analytic_account_id" ref="analytic.analytic_agrolait"/>
|
||||
</record>
|
||||
<record id="budget_line_analytic_agrolait10" model="crossovered.budget.lines">
|
||||
<field name="crossovered_budget_id" ref="crossovered_budget_budgetoptimistic0" />
|
||||
<field eval="str(datetime.now().year+1)+'-10-01'" name="date_from"/>
|
||||
<field eval="str(datetime.now().year+1)+'-10-31'" name="date_to"/>
|
||||
<field name="planned_amount">15000</field>
|
||||
<field name="analytic_account_id" ref="analytic.analytic_agrolait"/>
|
||||
</record>
|
||||
<record id="budget_line_analytic_agrolait11" model="crossovered.budget.lines">
|
||||
<field name="crossovered_budget_id" ref="crossovered_budget_budgetoptimistic0" />
|
||||
<field eval="str(datetime.now().year+1)+'-11-01'" name="date_from"/>
|
||||
<field eval="str(datetime.now().year+1)+'-11-30'" name="date_to"/>
|
||||
<field name="planned_amount">15000</field>
|
||||
<field name="analytic_account_id" ref="analytic.analytic_agrolait"/>
|
||||
</record>
|
||||
<record id="budget_line_analytic_agrolait12" model="crossovered.budget.lines">
|
||||
<field name="crossovered_budget_id" ref="crossovered_budget_budgetoptimistic0" />
|
||||
<field eval="str(datetime.now().year+1)+'-12-01'" name="date_from"/>
|
||||
<field eval="str(datetime.now().year+1)+'-12-31'" name="date_to"/>
|
||||
<field name="planned_amount">18000</field>
|
||||
<field name="analytic_account_id" ref="analytic.analytic_agrolait"/>
|
||||
</record>
|
||||
|
||||
<!-- pessimistic-->
|
||||
<record id="crossovered_budget_budgetpessimistic0" model="crossovered.budget">
|
||||
<field eval="'Budget '+str(datetime.now().year+1)+': Pessimistic'" name="name"/>
|
||||
<field eval="str(datetime.now().year+1)+'-01-01'" name="date_from"/>
|
||||
<field eval=""""draft"""" name="state"/>
|
||||
<field eval="str(datetime.now().year+1)+'-12-31'" name="date_to"/>
|
||||
<field name="user_id" ref="base.user_root"/>
|
||||
</record>
|
||||
|
||||
<record id="budget_line_analytic_admin_pessim" model="crossovered.budget.lines">
|
||||
<field name="crossovered_budget_id" ref="crossovered_budget_budgetpessimistic0" />
|
||||
<field eval="str(datetime.now().year+1)+'-01-01'" name="date_from"/>
|
||||
<field eval="str(datetime.now().year+1)+'-12-31'" name="date_to"/>
|
||||
<field name="planned_amount">-55000</field>
|
||||
<field name="analytic_account_id" ref="analytic.analytic_administratif"/>
|
||||
</record>
|
||||
<record id="budget_line_analytic_agrolait_pessim1" model="crossovered.budget.lines">
|
||||
<field name="crossovered_budget_id" ref="crossovered_budget_budgetpessimistic0" />
|
||||
<field eval="str(datetime.now().year+1)+'-01-01'" name="date_from"/>
|
||||
<field eval="str(datetime.now().year+1)+'-01-31'" name="date_to"/>
|
||||
<field name="planned_amount">9000</field>
|
||||
<field name="analytic_account_id" ref="analytic.analytic_agrolait"/>
|
||||
</record>
|
||||
<record id="budget_line_analytic_agrolait_pessim2" model="crossovered.budget.lines">
|
||||
<field name="crossovered_budget_id" ref="crossovered_budget_budgetpessimistic0" />
|
||||
<field eval="str(datetime.now().year+1)+'-02-01'" name="date_from"/>
|
||||
<field eval="str(datetime.now().year+1)+'-02-28'" name="date_to"/>
|
||||
<field name="planned_amount">8000</field>
|
||||
<field name="analytic_account_id" ref="analytic.analytic_agrolait"/>
|
||||
</record>
|
||||
<record id="budget_line_analytic_agrolait_pessim3" model="crossovered.budget.lines">
|
||||
<field name="crossovered_budget_id" ref="crossovered_budget_budgetpessimistic0" />
|
||||
<field eval="str(datetime.now().year+1)+'-03-01'" name="date_from"/>
|
||||
<field eval="str(datetime.now().year+1)+'-03-31'" name="date_to"/>
|
||||
<field name="planned_amount">10000</field>
|
||||
<field name="analytic_account_id" ref="analytic.analytic_agrolait"/>
|
||||
</record>
|
||||
<record id="budget_line_analytic_agrolait_pessim4" model="crossovered.budget.lines">
|
||||
<field name="crossovered_budget_id" ref="crossovered_budget_budgetpessimistic0" />
|
||||
<field eval="str(datetime.now().year+1)+'-04-01'" name="date_from"/>
|
||||
<field eval="str(datetime.now().year+1)+'-04-30'" name="date_to"/>
|
||||
<field name="planned_amount">14000</field>
|
||||
<field name="analytic_account_id" ref="analytic.analytic_agrolait"/>
|
||||
</record>
|
||||
<record id="budget_line_analytic_agrolait_pessim5" model="crossovered.budget.lines">
|
||||
<field name="crossovered_budget_id" ref="crossovered_budget_budgetpessimistic0" />
|
||||
<field eval="str(datetime.now().year+1)+'-05-01'" name="date_from"/>
|
||||
<field eval="str(datetime.now().year+1)+'-05-31'" name="date_to"/>
|
||||
<field name="planned_amount">16000</field>
|
||||
<field name="analytic_account_id" ref="analytic.analytic_agrolait"/>
|
||||
</record>
|
||||
<record id="budget_line_analytic_agrolait_pessim6" model="crossovered.budget.lines">
|
||||
<field name="crossovered_budget_id" ref="crossovered_budget_budgetpessimistic0" />
|
||||
<field eval="str(datetime.now().year+1)+'-06-01'" name="date_from"/>
|
||||
<field eval="str(datetime.now().year+1)+'-06-30'" name="date_to"/>
|
||||
<field name="planned_amount">13000</field>
|
||||
<field name="analytic_account_id" ref="analytic.analytic_agrolait"/>
|
||||
</record>
|
||||
<record id="budget_line_analytic_agrolait_pessim7" model="crossovered.budget.lines">
|
||||
<field name="crossovered_budget_id" ref="crossovered_budget_budgetpessimistic0" />
|
||||
<field eval="str(datetime.now().year+1)+'-07-01'" name="date_from"/>
|
||||
<field eval="str(datetime.now().year+1)+'-07-31'" name="date_to"/>
|
||||
<field name="planned_amount">10000</field>
|
||||
<field name="analytic_account_id" ref="analytic.analytic_agrolait"/>
|
||||
</record>
|
||||
<record id="budget_line_analytic_agrolait_pessim8" model="crossovered.budget.lines">
|
||||
<field name="crossovered_budget_id" ref="crossovered_budget_budgetpessimistic0" />
|
||||
<field eval="str(datetime.now().year+1)+'-08-01'" name="date_from"/>
|
||||
<field eval="str(datetime.now().year+1)+'-08-31'" name="date_to"/>
|
||||
<field name="planned_amount">8000</field>
|
||||
<field name="analytic_account_id" ref="analytic.analytic_agrolait"/>
|
||||
</record>
|
||||
<record id="budget_line_analytic_agrolait_pessim9" model="crossovered.budget.lines">
|
||||
<field name="crossovered_budget_id" ref="crossovered_budget_budgetpessimistic0" />
|
||||
<field eval="str(datetime.now().year+1)+'-09-01'" name="date_from"/>
|
||||
<field eval="str(datetime.now().year+1)+'-09-30'" name="date_to"/>
|
||||
<field name="planned_amount">7000</field>
|
||||
<field name="analytic_account_id" ref="analytic.analytic_agrolait"/>
|
||||
</record>
|
||||
<record id="budget_line_analytic_agrolait_pessim10" model="crossovered.budget.lines">
|
||||
<field name="crossovered_budget_id" ref="crossovered_budget_budgetpessimistic0" />
|
||||
<field eval="str(datetime.now().year+1)+'-10-01'" name="date_from"/>
|
||||
<field eval="str(datetime.now().year+1)+'-10-31'" name="date_to"/>
|
||||
<field name="planned_amount">12000</field>
|
||||
<field name="analytic_account_id" ref="analytic.analytic_agrolait"/>
|
||||
</record>
|
||||
<record id="budget_line_analytic_agrolait_pessim11" model="crossovered.budget.lines">
|
||||
<field name="crossovered_budget_id" ref="crossovered_budget_budgetpessimistic0" />
|
||||
<field eval="str(datetime.now().year+1)+'-11-01'" name="date_from"/>
|
||||
<field eval="str(datetime.now().year+1)+'-11-30'" name="date_to"/>
|
||||
<field name="planned_amount">17000</field>
|
||||
<field name="analytic_account_id" ref="analytic.analytic_agrolait"/>
|
||||
</record>
|
||||
<record id="budget_line_analytic_agrolait_pessim12" model="crossovered.budget.lines">
|
||||
<field name="crossovered_budget_id" ref="crossovered_budget_budgetpessimistic0" />
|
||||
<field eval="str(datetime.now().year+1)+'-12-01'" name="date_from"/>
|
||||
<field eval="str(datetime.now().year+1)+'-12-31'" name="date_to"/>
|
||||
<field name="planned_amount">17000</field>
|
||||
<field name="analytic_account_id" ref="analytic.analytic_agrolait"/>
|
||||
</record>
|
||||
</data>
|
||||
|
||||
</flectra>
|
||||
@@ -0,0 +1,5 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo, Flectra. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from . import account_budget
|
||||
from . import account_analytic_account
|
||||
@@ -0,0 +1,10 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo, Flectra. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from flectra import fields, models
|
||||
|
||||
|
||||
class AccountAnalyticAccount(models.Model):
|
||||
_inherit = "account.analytic.account"
|
||||
|
||||
crossovered_budget_line = fields.One2many('crossovered.budget.lines', 'analytic_account_id', 'Budget Lines')
|
||||
@@ -0,0 +1,269 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo, Flectra. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from flectra import api, fields, models, _
|
||||
from flectra.exceptions import ValidationError
|
||||
|
||||
# ---------------------------------------------------------
|
||||
# Budgets
|
||||
# ---------------------------------------------------------
|
||||
class AccountBudgetPost(models.Model):
|
||||
_name = "account.budget.post"
|
||||
_order = "name"
|
||||
_description = "Budgetary Position"
|
||||
|
||||
name = fields.Char('Name', required=True)
|
||||
account_ids = fields.Many2many('account.account', 'account_budget_rel', 'budget_id', 'account_id', 'Accounts',
|
||||
domain=[('deprecated', '=', False)])
|
||||
company_id = fields.Many2one('res.company', 'Company', required=True, default=lambda self: self.env.company)
|
||||
|
||||
def _check_account_ids(self, vals):
|
||||
# Raise an error to prevent the account.budget.post to have not specified account_ids.
|
||||
# This check is done on create because require=True doesn't work on Many2many fields.
|
||||
if 'account_ids' in vals:
|
||||
account_ids = self.new({'account_ids': vals['account_ids']}, origin=self).account_ids
|
||||
else:
|
||||
account_ids = self.account_ids
|
||||
if not account_ids:
|
||||
raise ValidationError(_('The budget must have at least one account.'))
|
||||
|
||||
@api.model
|
||||
def create(self, vals):
|
||||
self._check_account_ids(vals)
|
||||
return super(AccountBudgetPost, self).create(vals)
|
||||
|
||||
|
||||
def write(self, vals):
|
||||
self._check_account_ids(vals)
|
||||
return super(AccountBudgetPost, self).write(vals)
|
||||
|
||||
|
||||
class CrossoveredBudget(models.Model):
|
||||
_name = "crossovered.budget"
|
||||
_description = "Budget"
|
||||
_inherit = ['mail.thread']
|
||||
|
||||
name = fields.Char('Budget Name', required=True, states={'done': [('readonly', True)]})
|
||||
user_id = fields.Many2one('res.users', 'Responsible', default=lambda self: self.env.user)
|
||||
date_from = fields.Date('Start Date', required=True, states={'done': [('readonly', True)]})
|
||||
date_to = fields.Date('End Date', required=True, states={'done': [('readonly', True)]})
|
||||
state = fields.Selection([
|
||||
('draft', 'Draft'),
|
||||
('cancel', 'Cancelled'),
|
||||
('confirm', 'Confirmed'),
|
||||
('validate', 'Validated'),
|
||||
('done', 'Done')
|
||||
], 'Status', default='draft', index=True, required=True, readonly=True, copy=False, tracking=True)
|
||||
crossovered_budget_line = fields.One2many('crossovered.budget.lines', 'crossovered_budget_id', 'Budget Lines',
|
||||
states={'done': [('readonly', True)]}, copy=True)
|
||||
company_id = fields.Many2one('res.company', 'Company', required=True, default=lambda self: self.env.company)
|
||||
|
||||
def action_budget_confirm(self):
|
||||
self.write({'state': 'confirm'})
|
||||
|
||||
def action_budget_draft(self):
|
||||
self.write({'state': 'draft'})
|
||||
|
||||
def action_budget_validate(self):
|
||||
self.write({'state': 'validate'})
|
||||
|
||||
def action_budget_cancel(self):
|
||||
self.write({'state': 'cancel'})
|
||||
|
||||
def action_budget_done(self):
|
||||
self.write({'state': 'done'})
|
||||
|
||||
|
||||
class CrossoveredBudgetLines(models.Model):
|
||||
_name = "crossovered.budget.lines"
|
||||
_description = "Budget Line"
|
||||
|
||||
name = fields.Char(compute='_compute_line_name')
|
||||
crossovered_budget_id = fields.Many2one('crossovered.budget', 'Budget', ondelete='cascade', index=True, required=True)
|
||||
analytic_account_id = fields.Many2one('account.analytic.account', 'Analytic Account')
|
||||
analytic_group_id = fields.Many2one('account.analytic.group', 'Analytic Group', related='analytic_account_id.group_id', readonly=True)
|
||||
general_budget_id = fields.Many2one('account.budget.post', 'Budgetary Position')
|
||||
date_from = fields.Date('Start Date', required=True)
|
||||
date_to = fields.Date('End Date', required=True)
|
||||
paid_date = fields.Date('Paid Date')
|
||||
currency_id = fields.Many2one('res.currency', related='company_id.currency_id', readonly=True)
|
||||
planned_amount = fields.Monetary(
|
||||
'Planned Amount', required=True,
|
||||
help="Amount you plan to earn/spend. Record a positive amount if it is a revenue and a negative amount if it is a cost.")
|
||||
practical_amount = fields.Monetary(
|
||||
compute='_compute_practical_amount', string='Practical Amount', help="Amount really earned/spent.")
|
||||
theoritical_amount = fields.Monetary(
|
||||
compute='_compute_theoritical_amount', string='Theoretical Amount',
|
||||
help="Amount you are supposed to have earned/spent at this date.")
|
||||
percentage = fields.Float(
|
||||
compute='_compute_percentage', string='Achievement',
|
||||
help="Comparison between practical and theoretical amount. This measure tells you if you are below or over budget.")
|
||||
company_id = fields.Many2one(related='crossovered_budget_id.company_id', comodel_name='res.company',
|
||||
string='Company', store=True, readonly=True)
|
||||
is_above_budget = fields.Boolean(compute='_is_above_budget')
|
||||
crossovered_budget_state = fields.Selection(related='crossovered_budget_id.state', string='Budget State', store=True, readonly=True)
|
||||
|
||||
@api.model
|
||||
def read_group(self, domain, fields, groupby, offset=0, limit=None, orderby=False, lazy=True):
|
||||
# overrides the default read_group in order to compute the computed fields manually for the group
|
||||
|
||||
result = super(CrossoveredBudgetLines, self).read_group(domain, fields, groupby, offset=offset, limit=limit,
|
||||
orderby=orderby, lazy=lazy)
|
||||
fields_list = ['practical_amount', 'theoritical_amount', 'percentage']
|
||||
if any(x in fields for x in fields_list):
|
||||
for group_line in result:
|
||||
|
||||
# initialise fields to compute to 0 if they are requested
|
||||
if 'practical_amount' in fields:
|
||||
group_line['practical_amount'] = 0
|
||||
if 'theoritical_amount' in fields:
|
||||
group_line['theoritical_amount'] = 0
|
||||
if 'percentage' in fields:
|
||||
group_line['percentage'] = 0
|
||||
group_line['practical_amount'] = 0
|
||||
group_line['theoritical_amount'] = 0
|
||||
|
||||
if group_line.get('__domain'):
|
||||
all_budget_lines_that_compose_group = self.search(group_line['__domain'])
|
||||
else:
|
||||
all_budget_lines_that_compose_group = self.search([])
|
||||
for budget_line_of_group in all_budget_lines_that_compose_group:
|
||||
if 'practical_amount' in fields or 'percentage' in fields:
|
||||
group_line['practical_amount'] += budget_line_of_group.practical_amount
|
||||
|
||||
if 'theoritical_amount' in fields or 'percentage' in fields:
|
||||
group_line['theoritical_amount'] += budget_line_of_group.theoritical_amount
|
||||
|
||||
if 'percentage' in fields:
|
||||
if group_line['theoritical_amount']:
|
||||
# use a weighted average
|
||||
group_line['percentage'] = float(
|
||||
(group_line['practical_amount'] or 0.0) / group_line['theoritical_amount']) * 100
|
||||
|
||||
return result
|
||||
|
||||
|
||||
def _is_above_budget(self):
|
||||
for line in self:
|
||||
if line.theoritical_amount >= 0:
|
||||
line.is_above_budget = line.practical_amount > line.theoritical_amount
|
||||
else:
|
||||
line.is_above_budget = line.practical_amount < line.theoritical_amount
|
||||
|
||||
|
||||
def _compute_line_name(self):
|
||||
#just in case someone opens the budget line in form view
|
||||
computed_name = self.crossovered_budget_id.name
|
||||
if self.general_budget_id:
|
||||
computed_name += ' - ' + self.general_budget_id.name
|
||||
if self.analytic_account_id:
|
||||
computed_name += ' - ' + self.analytic_account_id.name
|
||||
self.name = computed_name
|
||||
|
||||
|
||||
def _compute_practical_amount(self):
|
||||
for line in self:
|
||||
acc_ids = line.general_budget_id.account_ids.ids
|
||||
date_to = line.date_to
|
||||
date_from = line.date_from
|
||||
if line.analytic_account_id.id:
|
||||
analytic_line_obj = self.env['account.analytic.line']
|
||||
domain = [('account_id', '=', line.analytic_account_id.id),
|
||||
('date', '>=', date_from),
|
||||
('date', '<=', date_to),
|
||||
]
|
||||
if acc_ids:
|
||||
domain += [('general_account_id', 'in', acc_ids)]
|
||||
|
||||
where_query = analytic_line_obj._where_calc(domain)
|
||||
analytic_line_obj._apply_ir_rules(where_query, 'read')
|
||||
from_clause, where_clause, where_clause_params = where_query.get_sql()
|
||||
select = "SELECT SUM(amount) from " + from_clause + " where " + where_clause
|
||||
|
||||
else:
|
||||
aml_obj = self.env['account.move.line']
|
||||
domain = [('account_id', 'in',
|
||||
line.general_budget_id.account_ids.ids),
|
||||
('date', '>=', date_from),
|
||||
('date', '<=', date_to)
|
||||
]
|
||||
where_query = aml_obj._where_calc(domain)
|
||||
aml_obj._apply_ir_rules(where_query, 'read')
|
||||
from_clause, where_clause, where_clause_params = where_query.get_sql()
|
||||
select = "SELECT sum(credit)-sum(debit) from " + from_clause + " where " + where_clause
|
||||
|
||||
self.env.cr.execute(select, where_clause_params)
|
||||
line.practical_amount = self.env.cr.fetchone()[0] or 0.0
|
||||
|
||||
|
||||
def _compute_theoritical_amount(self):
|
||||
# beware: 'today' variable is mocked in the python tests and thus, its implementation matter
|
||||
today = fields.Date.today()
|
||||
for line in self:
|
||||
if line.paid_date:
|
||||
if today <= line.paid_date:
|
||||
theo_amt = 0.00
|
||||
else:
|
||||
theo_amt = line.planned_amount
|
||||
else:
|
||||
line_timedelta = line.date_to - line.date_from
|
||||
elapsed_timedelta = today - line.date_from
|
||||
|
||||
if elapsed_timedelta.days < 0:
|
||||
# If the budget line has not started yet, theoretical amount should be zero
|
||||
theo_amt = 0.00
|
||||
elif line_timedelta.days > 0 and today < line.date_to:
|
||||
# If today is between the budget line date_from and date_to
|
||||
theo_amt = (elapsed_timedelta.total_seconds() / line_timedelta.total_seconds()) * line.planned_amount
|
||||
else:
|
||||
theo_amt = line.planned_amount
|
||||
line.theoritical_amount = theo_amt
|
||||
|
||||
|
||||
def _compute_percentage(self):
|
||||
for line in self:
|
||||
if line.theoritical_amount != 0.00:
|
||||
line.percentage = float((line.practical_amount or 0.0) / line.theoritical_amount)
|
||||
else:
|
||||
line.percentage = 0.00
|
||||
|
||||
@api.constrains('general_budget_id', 'analytic_account_id')
|
||||
def _must_have_analytical_or_budgetary_or_both(self):
|
||||
if not self.analytic_account_id and not self.general_budget_id:
|
||||
raise ValidationError(
|
||||
_("You have to enter at least a budgetary position or analytic account on a budget line."))
|
||||
|
||||
|
||||
def action_open_budget_entries(self):
|
||||
if self.analytic_account_id:
|
||||
# if there is an analytic account, then the analytic items are loaded
|
||||
action = self.env['ir.actions.act_window'].for_xml_id('analytic', 'account_analytic_line_action_entries')
|
||||
action['domain'] = [('account_id', '=', self.analytic_account_id.id),
|
||||
('date', '>=', self.date_from),
|
||||
('date', '<=', self.date_to)
|
||||
]
|
||||
if self.general_budget_id:
|
||||
action['domain'] += [('general_account_id', 'in', self.general_budget_id.account_ids.ids)]
|
||||
else:
|
||||
# otherwise the journal entries booked on the accounts of the budgetary postition are opened
|
||||
action = self.env['ir.actions.act_window'].for_xml_id('account', 'action_account_moves_all_a')
|
||||
action['domain'] = [('account_id', 'in',
|
||||
self.general_budget_id.account_ids.ids),
|
||||
('date', '>=', self.date_from),
|
||||
('date', '<=', self.date_to)
|
||||
]
|
||||
return action
|
||||
|
||||
@api.constrains('date_from', 'date_to')
|
||||
def _line_dates_between_budget_dates(self):
|
||||
for rec in self:
|
||||
budget_date_from = rec.crossovered_budget_id.date_from
|
||||
budget_date_to = rec.crossovered_budget_id.date_to
|
||||
if rec.date_from:
|
||||
date_from = rec.date_from
|
||||
if date_from < budget_date_from or date_from > budget_date_to:
|
||||
raise ValidationError(_('"Start Date" of the budget line should be included in the Period of the budget'))
|
||||
if rec.date_to:
|
||||
date_to = rec.date_to
|
||||
if date_to < budget_date_from or date_to > budget_date_to:
|
||||
raise ValidationError(_('"End Date" of the budget line should be included in the Period of the budget'))
|
||||
@@ -0,0 +1,35 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<flectra>
|
||||
<data noupdate="1">
|
||||
|
||||
<record id="budget_post_comp_rule" model="ir.rule">
|
||||
<field name="name">Budget post multi-company</field>
|
||||
<field name="model_id" ref="model_account_budget_post"/>
|
||||
<field eval="True" name="global"/>
|
||||
<field name="domain_force">['|',('company_id','=',False),('company_id','child_of',[user.company_id.id])]</field>
|
||||
</record>
|
||||
|
||||
<record id="budget_comp_rule" model="ir.rule">
|
||||
<field name="name">Budget multi-company</field>
|
||||
<field name="model_id" ref="model_crossovered_budget"/>
|
||||
<field eval="True" name="global"/>
|
||||
<field name="domain_force">['|',('company_id','=',False),('company_id','child_of',[user.company_id.id])]</field>
|
||||
</record>
|
||||
|
||||
<record id="budget_lines_comp_rule" model="ir.rule">
|
||||
<field name="name">Budget lines multi-company</field>
|
||||
<field name="model_id" ref="model_crossovered_budget_lines"/>
|
||||
<field eval="True" name="global"/>
|
||||
<field name="domain_force">['|',('company_id','=',False),('company_id','child_of',[user.company_id.id])]</field>
|
||||
</record>
|
||||
|
||||
<record model="res.users" id="base.user_root">
|
||||
<field eval="[(4,ref('analytic.group_analytic_accounting'))]" name="groups_id"/>
|
||||
</record>
|
||||
|
||||
<record model="res.users" id="base.user_admin">
|
||||
<field eval="[(4,ref('analytic.group_analytic_accounting'))]" name="groups_id"/>
|
||||
</record>
|
||||
|
||||
</data>
|
||||
</flectra>
|
||||
@@ -0,0 +1,7 @@
|
||||
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
|
||||
access_crossovered_budget,crossovered.budget,model_crossovered_budget,account.group_account_manager,1,0,0,0
|
||||
access_account_budget_post,account.budget.post,model_account_budget_post,account.group_account_manager,1,0,0,0
|
||||
access_account_budget_post_accountant,account.budget.post accountant,model_account_budget_post,account.group_account_user,1,1,1,1
|
||||
access_crossovered_budget_accountant,crossovered.budget accountant,model_crossovered_budget,account.group_account_user,1,1,1,1
|
||||
access_crossovered_budget_lines_accountant,crossovered.budget.lines accountant,model_crossovered_budget_lines,account.group_account_user,1,1,1,1
|
||||
access_budget,crossovered.budget.lines manager,model_crossovered_budget_lines,base.group_user,1,1,1,0
|
||||
|
Binary file not shown.
|
After Width: | Height: | Size: 1.6 MiB |
Binary file not shown.
|
After Width: | Height: | Size: 116 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 168 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 5.6 KiB |
@@ -0,0 +1,36 @@
|
||||
<section class="oe_container oe_dark">
|
||||
<div class="col-md-12">
|
||||
<h2 class="oe_slogan" style="font-size: 35px;"><b>Budget Management</b></h2>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="oe_container">
|
||||
<div class="oe_row">
|
||||
<div style="text-align:left;">
|
||||
<li style="font-size: 15px;">Use budgets to compare actual with expected revenues and costs.</li>
|
||||
<br/>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="oe_container">
|
||||
<div class="oe_row">
|
||||
<div class="oe_span12">
|
||||
<h3 class="oe_slogan" style="font-size: 28px;">Budgetary Positions</h3>
|
||||
<div>
|
||||
<img class="img-fluid mx-auto mt16 mb16" src="budgetary_postions.png">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="oe_container oe_dark">
|
||||
<div class="oe_row oe_spaced">
|
||||
<div class="oe_span12">
|
||||
<h3 class="oe_slogan" style="font-size: 28px;">Budgets</h3>
|
||||
<div>
|
||||
<img class="img-fluid mx-auto mt16 mb16" src="budgets.png">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
@@ -0,0 +1,40 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<flectra>
|
||||
|
||||
<record model="ir.ui.view" id="view_account_analytic_account_form_inherit_budget">
|
||||
<field name="name">account.analytic.account.form.inherit.budget</field>
|
||||
<field name="model">account.analytic.account</field>
|
||||
<field name="inherit_id" ref="analytic.view_account_analytic_account_form"/>
|
||||
<field name="priority" eval="50"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//group[@name='main']" position='after'>
|
||||
<notebook groups="account.group_account_user">
|
||||
<page string="Budget Items">
|
||||
<field name="crossovered_budget_line" widget="one2many_list" colspan="4" nolabel="1" mode="tree">
|
||||
<tree string="Budget Items" editable="top">
|
||||
<field name="crossovered_budget_id"/>
|
||||
<field name="general_budget_id"/>
|
||||
<field name="date_from"/>
|
||||
<field name="date_to"/>
|
||||
<field name="paid_date"/>
|
||||
<field name="planned_amount" widget="monetary"/>
|
||||
<field name="practical_amount" sum="Practical Amount" widget="monetary"/>
|
||||
<field name="theoritical_amount" sum="Theoritical Amount" widget="monetary"/>
|
||||
<field name="percentage"/>
|
||||
</tree>
|
||||
<form string="Budget Items">
|
||||
<field name="crossovered_budget_id"/>
|
||||
<field name="general_budget_id"/>
|
||||
<field name="date_from"/>
|
||||
<field name="date_to"/>
|
||||
<field name="paid_date"/>
|
||||
<field name="planned_amount" widget="monetary"/>
|
||||
</form>
|
||||
</field>
|
||||
</page>
|
||||
</notebook>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
</flectra>
|
||||
@@ -0,0 +1,359 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<flectra>
|
||||
|
||||
<record id="view_budget_post_search" model="ir.ui.view">
|
||||
<field name="name">account.budget.post.search</field>
|
||||
<field name="model">account.budget.post</field>
|
||||
<field name="arch" type="xml">
|
||||
<search string="Budgetary Position">
|
||||
<field name="name" filter_domain="[('name','ilike',self)]" string="Budgetary Position"/>
|
||||
<field name="company_id" groups="base.group_multi_company"/>
|
||||
</search>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="view_budget_post_tree" model="ir.ui.view">
|
||||
<field name="name">account.budget.post.tree</field>
|
||||
<field name="model">account.budget.post</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Budgetary Position">
|
||||
<field name="name"/>
|
||||
<field name="company_id" options="{'no_create': True}" groups="base.group_multi_company"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="open_budget_post_form" model="ir.actions.act_window">
|
||||
<field name="name">Budgetary Positions</field>
|
||||
<field name="res_model">account.budget.post</field>
|
||||
<field name="view_mode">tree,kanban,form</field>
|
||||
<field name="view_id" ref="view_budget_post_tree"/>
|
||||
<field name="search_view_id" ref="view_budget_post_search"/>
|
||||
</record>
|
||||
<menuitem action="open_budget_post_form" id="menu_budget_post_form"
|
||||
parent="account.account_management_menu" sequence="5"/>
|
||||
|
||||
|
||||
<record model="ir.ui.view" id="view_budget_post_form">
|
||||
<field name="name">account.budget.post.form</field>
|
||||
<field name="model">account.budget.post</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Budgetary Position">
|
||||
<group col="4">
|
||||
<field name="name"/>
|
||||
<field name="company_id" groups="base.group_multi_company" options="{'no_create': True}"/>
|
||||
</group>
|
||||
<notebook>
|
||||
<page string="Accounts">
|
||||
<field name="account_ids">
|
||||
<tree>
|
||||
<field name="code"/>
|
||||
<field name="name"/>
|
||||
</tree>
|
||||
</field>
|
||||
</page>
|
||||
</notebook>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record model="ir.ui.view" id="crossovered_budget_view_form">
|
||||
<field name="name">crossovered.budget.view.form</field>
|
||||
<field name="model">crossovered.budget</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Budget">
|
||||
<header>
|
||||
<button string="Confirm" name="action_budget_confirm" states="draft" type="object"
|
||||
class="oe_highlight"/>
|
||||
<button string="Approve" name="action_budget_validate" states="confirm" type="object"
|
||||
class="oe_highlight"/>
|
||||
<button string="Done" name="action_budget_done" states="validate" type="object"
|
||||
class="oe_highlight"/>
|
||||
<button string="Reset to Draft" name="action_budget_draft" states="cancel" type="object"/>
|
||||
<button string="Cancel Budget" name="action_budget_cancel" states="confirm,validate" type="object"/>
|
||||
<field name="state" widget="statusbar" />
|
||||
</header>
|
||||
<sheet string="Budget">
|
||||
<div class="oe_title">
|
||||
<label for="name" class="oe_edit_only"/>
|
||||
<h1>
|
||||
<field name="name" attrs="{'readonly':[('state','!=','draft')]}" placeholder="Budget Name"/>
|
||||
</h1>
|
||||
</div>
|
||||
<group>
|
||||
<group>
|
||||
<field name="user_id" attrs="{'readonly':[('state','!=','draft')]}"/>
|
||||
</group>
|
||||
<group>
|
||||
<label for="date_from" string="Period"/>
|
||||
<div>
|
||||
<field name="date_from" class="oe_inline"
|
||||
attrs="{'readonly':[('state','!=','draft')]}"/>
|
||||
-
|
||||
<field name="date_to" class="oe_inline" attrs="{'readonly':[('state','!=','draft')]}"
|
||||
nolabel="1"/>
|
||||
</div>
|
||||
<field name="company_id" groups="base.group_multi_company" options="{'no_create': True}"/>
|
||||
</group>
|
||||
</group>
|
||||
<notebook>
|
||||
<page string="Budget Lines">
|
||||
<field name="crossovered_budget_line"
|
||||
context="{'default_date_from': date_from,'default_date_to': date_to}" colspan="4"
|
||||
nolabel="1" attrs="{'readonly':[('state','!=','draft')]}">
|
||||
<tree string="Budget Lines" decoration-success="is_above_budget and planned_amount > 0" decoration-danger="is_above_budget and planned_amount < 0" editable="bottom">
|
||||
<field name="general_budget_id"/>
|
||||
<field name="analytic_account_id" groups="analytic.group_analytic_accounting"/>
|
||||
<field name="date_from"/>
|
||||
<field name="date_to"/>
|
||||
<field name="paid_date" groups="base.group_no_one"/>
|
||||
<field name="currency_id" invisible="1"/>
|
||||
<field name="planned_amount" sum="Planned Amount"/>
|
||||
<field name="practical_amount" sum="Practical Amount"/>
|
||||
<field name="theoritical_amount" sum="Theoretical Amount"/>
|
||||
<field name="percentage" widget="percentage" />
|
||||
<button type="object" name="action_open_budget_entries" string="Entries..."
|
||||
icon="fa-arrow-circle-o-right"/>
|
||||
<field name="is_above_budget" invisible="1"/>
|
||||
</tree>
|
||||
<form string="Budget Lines">
|
||||
<group>
|
||||
<group>
|
||||
<field name="currency_id" invisible="1"/>
|
||||
<field name="general_budget_id"/>
|
||||
<field name="planned_amount"/>
|
||||
<field name="analytic_account_id"
|
||||
groups="analytic.group_analytic_accounting"/>
|
||||
</group>
|
||||
<group>
|
||||
<label for="date_from" string="Period"/>
|
||||
<div>
|
||||
<field name="date_from" class="oe_inline"/>
|
||||
-
|
||||
<field name="date_to" class="oe_inline"/>
|
||||
</div>
|
||||
<field name="paid_date" groups="base.group_no_one"/>
|
||||
<field name="company_id" options="{'no_create': True}"
|
||||
groups="base.group_multi_company"/>
|
||||
</group>
|
||||
</group>
|
||||
</form>
|
||||
</field>
|
||||
</page>
|
||||
</notebook>
|
||||
</sheet>
|
||||
<div class="oe_chatter">
|
||||
<field name="message_follower_ids" widget="mail_followers" groups="base.group_user"/>
|
||||
<field name="message_ids" widget="mail_thread"/>
|
||||
</div>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record model="ir.ui.view" id="crossovered_budget_view_tree">
|
||||
<field name="name">crossovered.budget.view.tree</field>
|
||||
<field name="model">crossovered.budget</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree decoration-info="state == 'draft'" decoration-muted="state in ('done','cancel')" string="Budget">
|
||||
<field name="name" colspan="1"/>
|
||||
<field name="date_from"/>
|
||||
<field name="date_to"/>
|
||||
<field name="company_id" options="{'no_create': True}" groups="base.group_multi_company"/>
|
||||
<field name="user_id"/>
|
||||
<field name="state"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="view_crossovered_budget_kanban" model="ir.ui.view">
|
||||
<field name="name">crossovered.budget.kanban</field>
|
||||
<field name="model">crossovered.budget</field>
|
||||
<field name="arch" type="xml">
|
||||
<kanban class="o_kanban_mobile">
|
||||
<field name="name"/>
|
||||
<field name="date_from"/>
|
||||
<field name="date_to"/>
|
||||
<field name="user_id"/>
|
||||
<field name="state"/>
|
||||
<templates>
|
||||
<t t-name="kanban-box">
|
||||
<div t-attf-class="oe_kanban_global_click">
|
||||
<div class="row mb4">
|
||||
<div class="col-8">
|
||||
<strong>
|
||||
<field name="name"/>
|
||||
</strong>
|
||||
</div>
|
||||
<div class="col-4">
|
||||
<span class="float-right">
|
||||
<field name="state" widget="kanban_label_selection"
|
||||
options="{'classes': {'draft': 'default', 'done': 'success'}}"/>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-10">
|
||||
<i class="fa fa-clock-o" role="img" aria-label="Period" title="Period"/>
|
||||
<t t-esc="record.date_from.value"/>-
|
||||
<t t-esc="record.date_to.value"/>
|
||||
</div>
|
||||
<div class="col-2">
|
||||
<span class="float-right">
|
||||
<img t-att-src="kanban_image('res.users', 'image_small', record.user_id.raw_value)"
|
||||
t-att-title="record.user_id.value" t-att-alt="record.user_id.value" width="24" height="24"
|
||||
class="oe_kanban_avatar float-right"/>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</t>
|
||||
</templates>
|
||||
</kanban>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="view_crossovered_budget_search" model="ir.ui.view">
|
||||
<field name="name">crossovered.budget.search</field>
|
||||
<field name="model">crossovered.budget</field>
|
||||
<field name="arch" type="xml">
|
||||
<search string="Budget">
|
||||
<field name="name" filter_domain="[('name','ilike',self)]" string="Budget"/>
|
||||
<field name="date_from"/>
|
||||
<field name="date_to"/>
|
||||
<filter string="Draft" name="draft" domain="[('state','=','draft')]" help="Draft Budgets"/>
|
||||
<filter string="To Approve" name="toapprove" domain="[('state','=','confirm')]"
|
||||
help="To Approve Budgets"/>
|
||||
<field name="state"/>
|
||||
</search>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record model="ir.actions.act_window" id="act_crossovered_budget_view">
|
||||
<field name="name">Budgets</field>
|
||||
<field name="res_model">crossovered.budget</field>
|
||||
<field name="view_mode">tree,kanban,form</field>
|
||||
<field name="view_id" ref="crossovered_budget_view_tree"/>
|
||||
<field name="search_view_id" ref="view_crossovered_budget_search"/>
|
||||
<field name="help" type="html">
|
||||
<p class="o_view_nocontent_smiling_face">
|
||||
Click to create a new budget.
|
||||
</p>
|
||||
<p>
|
||||
Use budgets to compare actual with expected revenues and costs
|
||||
</p>
|
||||
</field>
|
||||
</record>
|
||||
<menuitem parent="account.menu_finance_entries_management"
|
||||
id="menu_act_crossovered_budget_view"
|
||||
name="Budgets"
|
||||
action="act_crossovered_budget_view" sequence="60"
|
||||
groups="account.group_account_manager"/>
|
||||
|
||||
<record id="view_crossovered_budget_line_search" model="ir.ui.view">
|
||||
<field name="name">account.budget.line.search</field>
|
||||
<field name="model">crossovered.budget.lines</field>
|
||||
<field name="arch" type="xml">
|
||||
<search string="Budget Lines">
|
||||
<field name="analytic_account_id"/>
|
||||
<field name="crossovered_budget_id"/>
|
||||
<filter name="filter_not_cancelled" string="Not Cancelled" domain="[('crossovered_budget_state','!=','cancel')]"/>
|
||||
<group expand="0" string="Group By">
|
||||
<filter name="group_crossevered_budgdet_id" string="Budgets" domain="[]" context="{'group_by':'crossovered_budget_id'}"/>
|
||||
</group>
|
||||
</search>
|
||||
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record model="ir.ui.view" id="view_crossovered_budget_line_tree">
|
||||
<field name="name">crossovered.budget.line.tree</field>
|
||||
<field name="model">crossovered.budget.lines</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Budget Lines" create="0">
|
||||
<field name="currency_id" invisible="1"/>
|
||||
<field name="crossovered_budget_id" invisible="1"/>
|
||||
<field name="general_budget_id" />
|
||||
<field name="analytic_account_id" groups="analytic.group_analytic_accounting" />
|
||||
<field name="date_from" />
|
||||
<field name="date_to" />
|
||||
<field name="paid_date" groups="base.group_no_one" />
|
||||
<field name="planned_amount"/>
|
||||
<field name="practical_amount"/>
|
||||
<field name="theoritical_amount"/>
|
||||
<field name="percentage" widget="percentage"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
<record model="ir.ui.view" id="view_crossovered_budget_line_form">
|
||||
<field name="name">crossovered.budget.line.form</field>
|
||||
<field name="model">crossovered.budget.lines</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Budget Lines">
|
||||
<sheet>
|
||||
<group col="4">
|
||||
<field name="currency_id" invisible="1"/>
|
||||
<field name="crossovered_budget_state" invisible="1"/>
|
||||
<field name="crossovered_budget_id" attrs="{'readonly':[('crossovered_budget_state','!=','draft')]}"/>
|
||||
<field name="analytic_account_id" attrs="{'readonly':[('crossovered_budget_state','!=','draft')]}"/>
|
||||
<field name="general_budget_id" attrs="{'readonly':[('crossovered_budget_state','!=','draft')]}"/>
|
||||
<field name="date_from" attrs="{'readonly':[('crossovered_budget_state','!=','draft')]}"/>
|
||||
<field name="date_to" attrs="{'readonly':[('crossovered_budget_state','!=','draft')]}"/>
|
||||
<field name="paid_date" attrs="{'readonly':[('crossovered_budget_state','!=','draft')]}"/>
|
||||
<field name="planned_amount" attrs="{'readonly':[('crossovered_budget_state','!=','draft')]}"/>
|
||||
<field name="practical_amount" attrs="{'readonly':[('crossovered_budget_state','!=','draft')]}"/>
|
||||
<field name="theoritical_amount" attrs="{'readonly':[('crossovered_budget_state','!=','draft')]}"/>
|
||||
<field name="percentage" widget="percentage" attrs="{'readonly':[('crossovered_budget_state','!=','draft')]}"/>
|
||||
<field name="company_id" options="{'no_create': True}" groups="base.group_multi_company" attrs="{'readonly':[('crossovered_budget_state','!=','draft')]}"/>
|
||||
</group>
|
||||
</sheet>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record model="ir.ui.view" id="view_crossovered_budget_line_pivot">
|
||||
<field name="name">crossovered.budget.line.pivot</field>
|
||||
<field name="model">crossovered.budget.lines</field>
|
||||
<field name="arch" type="xml">
|
||||
<pivot string="Budget Lines">
|
||||
<field name="crossovered_budget_id" type="row"/>
|
||||
<field name="planned_amount" type="measure" string="Planned amount"/>
|
||||
<field name="theoritical_amount" type="measure" string="Theoritical amount"/>
|
||||
<field name="practical_amount" type="measure" string="Practical amount"/>
|
||||
<field name="percentage" type="measure" widget="percentage"/>
|
||||
</pivot>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record model="ir.ui.view" id="view_crossovered_budget_line_graph">
|
||||
<field name="name">crossovered.budget.line.graph</field>
|
||||
<field name="model">crossovered.budget.lines</field>
|
||||
<field name="arch" type="xml">
|
||||
<graph string="Budget Lines">
|
||||
<field name="crossovered_budget_id" type="row"/>
|
||||
<field name="planned_amount" type="measure" string="Planned amount"/>
|
||||
<field name="theoritical_amount" type="measure" string="Theoritical amount"/>
|
||||
<field name="practical_amount" type="measure" string="Practical amount"/>
|
||||
</graph>
|
||||
</field>
|
||||
</record>
|
||||
<record model="ir.actions.act_window" id="act_crossovered_budget_lines_view">
|
||||
<field name="name">Budgets Analysis</field>
|
||||
<field name="res_model">crossovered.budget.lines</field>
|
||||
<field name="view_mode">tree,form,pivot,graph</field>
|
||||
<field name="view_id" eval="False"/>
|
||||
<field name="context">{'search_default_group_crossevered_budgdet_id': True, 'search_default_filter_not_cancelled':True}</field>
|
||||
</record>
|
||||
|
||||
<menuitem parent="account.account_reports_management_menu"
|
||||
id="menu_act_crossovered_budget_lines_view"
|
||||
action="act_crossovered_budget_lines_view" sequence="20"
|
||||
groups="account.group_account_user"/>
|
||||
|
||||
<record id="act_account_analytic_account_cb_lines" model="ir.actions.act_window">
|
||||
<field name="name">Budget Items</field>
|
||||
<field name="res_model">crossovered.budget.lines</field>
|
||||
<field name="view_mode">tree,kanban,form</field>
|
||||
<field name="context">{'search_default_analytic_account_id': [active_id], 'default_analytic_account_id': active_id}</field>
|
||||
</record>
|
||||
|
||||
</flectra>
|
||||
@@ -0,0 +1,15 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<flectra>
|
||||
|
||||
<record id="res_config_settings_view_form" model="ir.ui.view">
|
||||
<field name="name">res.config.settings.view.form.inherit.account.budget</field>
|
||||
<field name="model">res.config.settings</field>
|
||||
<field name="inherit_id" ref="account.res_config_settings_view_form"/>
|
||||
<field name="arch" type="xml">
|
||||
<field name="module_account_budget" position="replace">
|
||||
<field name="module_account_budget"/>
|
||||
</field>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
</flectra>
|
||||
Reference in New Issue
Block a user