Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[ADD] estate : added the sprinkles. #214

Draft
wants to merge 16 commits into
base: 18.0
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions budget/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
from . import models
from . import wizard
15 changes: 15 additions & 0 deletions budget/__manifest__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"name": "Budget",
"version": "1.0",
"depends": ["base","account"],
"data": [
"security/ir.model.access.csv",
"wizard/budget_wizard_views.xml",
"views/budget_views.xml",
"views/budget_line_views.xml",
"views/budget_menu_views.xml",
],
"installable": True,
"application": True,
"license": "LGPL-3",
}
3 changes: 3 additions & 0 deletions budget/models/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
from . import budget
from . import budget_lines
from . import res_account_analytic_line
104 changes: 104 additions & 0 deletions budget/models/budget.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
from odoo import models, fields, api
from odoo.exceptions import ValidationError,UserError

class Budget(models.Model):
_name = "budget.budget"
_description = "Budget"
_inherit = ['mail.thread']

name = fields.Char('Budget Name', compute='_compute_budget_name', store=True)

color= fields.Integer(default=5)
user_id = fields.Many2one('res.users', 'Responsible', default=lambda self: self.env.user)
date_from = fields.Date('Start Date')
date_to = fields.Date('End Date')
active= fields.Boolean(default=True)
revision_id = fields.Many2one('budget.budget', string="Revision_id", readonly=True , tracking=True)
is_favorite = fields.Boolean(default=False)
state = fields.Selection(selection=[
('draft', 'Draft'),
('confirmed', 'Confirmed'),
('revised', 'Revised'),
('done', 'Done'),
], string='Status', default='draft', required=True, readonly=True, copy=False)


on_over_budget = fields.Selection([
('warning', 'Show a warning'),
('restriction', 'Restrict on creation'),
], string='Over Budget Policy',default="restriction")
currency_id = fields.Many2one('res.currency', string='Currency', required=True, default=lambda self: self.env.company.currency_id)
budget_lines = fields.One2many('budget.budget.lines', 'budget_id', 'Budget Lines', copy=True)
company_id = fields.Many2one('res.company', 'Company', required=True, default=lambda self: self.env.company)
analytic_account_ids = fields.Many2many('account.analytic.account')
warnings = fields.Text(compute="_check_over_budget")


@api.constrains('date_from', 'date_to')
def _check_dates(self):
for record in self:
if record.date_from == record.date_to:
raise ValidationError("Start Date and End Date cannot be the same.")
elif record.date_to < record.date_from:
raise ValidationError("End Date must be after Start Date.")
else:
if record.state in ['draft', 'confirmed']:
overlapping_budgets = self.search([
('id', '!=', record.id), # Exclude the current record
('state', 'in', ['draft', 'confirmed']),
('date_from', '<=', record.date_to),
('date_to', '>=', record.date_from),
])
if overlapping_budgets:
raise UserError("Cannot create or update this budget because it overlaps with another budget")
@api.depends("budget_lines.over_budget")
def _check_over_budget(self):
for record in self:
if (
record.on_over_budget == "warning"
and any(ob > 0 for ob in record.budget_lines.mapped("over_budget")) > 0
):
record.warnings = "Achieved amount exceeds the budget!"
else:
record.warnings = False

@api.depends('date_from', 'date_to')
def _compute_budget_name(self):
for record in self:
record.name = f"Budget:({record.date_from} to {record.date_to})"

def action_budget_confirm(self):
if self.state != 'draft':
raise ValidationError("Only budgets in draft state can be confirmed.")
self.write({'state': 'confirmed'})


def action_budget_revise(self):
if self.state != "confirmed":
raise UserError("Only confirmed budgets can be revised.")
self.ensure_one()
new_budget_vals = self.copy_data()[0]
new_budget_vals['revision_id'] = self.id
new_budget_vals['state'] = 'draft'

self.active = False
self.state = 'revised'
new_budget = self.create(new_budget_vals)
self.message_post(
body=f"The budget has been revised. A new draft budget has been created with ID {new_budget.id}.",
subtype_xmlid="mail.mt_note"
)

return new_budget


def action_budget_draft(self):
if self.state not in ['confirmed', 'revised']:
raise ValidationError("Only confirmed or revised budgets can be set back to draft.")
self.write({'state': 'draft'})


def action_budget_done(self):
if self.state != 'revised':
raise ValidationError("Only revised budgets can be marked as done.")
self.write({'state': 'done'})
68 changes: 68 additions & 0 deletions budget/models/budget_lines.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
from odoo import fields, models,api
from odoo.exceptions import ValidationError,UserError

class BudgetLines(models.Model):
_name = "budget.budget.lines"
_description = "Budget Line"
user_id = fields.Many2one('res.users', 'Responsible', default=lambda self: self.env.user)
budget_start_date = fields.Date(related="budget_id.date_from", readonly=True)
budget_end_date = fields.Date(related="budget_id.date_to", readonly=True)

budget_id = fields.Many2one('budget.budget', 'Budget', ondelete='cascade', index=True, required=True)
state = fields.Selection(related="budget_id.state", readonly=True)
analytic_account_id = fields.Many2one('account.analytic.account', 'Analytic Account')
currency_id = fields.Many2one('res.currency', string='Currency', required=True, default=lambda self: self.env.company.currency_id)
planned_amount = fields.Monetary(
'Budget Amount', required=True,
default=0.0,
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(string='Achieved Amount' , default=0.0, store=True)

over_budget = fields.Monetary(
string="Over Budget",
default=0.0,
compute="_compute_practical_amount",
help="The amount by which the budget line exceeds its allocated budget.",
store=True
)
count= fields.Integer('Count',computed="_compute_practical_amount",default=0, readonly=True)
percentage = fields.Float(default=0.0,compute="_compute_achieved_percentage",
help="Comparison between practical and planned amount. This measure tells you if you are below or over budget.")


@api.depends("practical_amount", "planned_amount")
def _compute_achieved_percentage(self):
for record in self:
if record.planned_amount:
record.percentage = (
record.practical_amount / record.planned_amount
) * 100

def action_view_analytic_lines(self):
if not self.budget_id:
raise UserError("No budget linked to this budget line.")

budget_start_date = self.budget_id.date_from
budget_end_date = self.budget_id.date_to

return {
"type": "ir.actions.act_window",
"name": "Analytic Lines",
"res_model": "account.analytic.line",
"view_mode": "list",
"target": "current",
"context": {
"default_account_id": self.analytic_account_id.id,
"budget_start_date": budget_start_date,
"budget_end_date": budget_end_date,
},
"domain": [
("account_id", "=", self.analytic_account_id.id),
("date", ">=", budget_start_date),
("date", "<=", budget_end_date),
("amount", "<", 0),
],
}



11 changes: 11 additions & 0 deletions budget/models/res_account_analytic_line.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
from odoo import models, fields, api
from odoo.exceptions import ValidationError

class AccountAnalyticLine(models.Model):
_inherit = "account.analytic.line"

budget_line_id = fields.Many2one('budget.budget.lines', 'Budget Line')
# account_id = fields.Many2one('account.analytic.account', 'Automatic Account', related='budget_line_id.analytic_account_id.auto_account_id')



4 changes: 4 additions & 0 deletions budget/security/ir.model.access.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
budget.access_budget_budget,access_budget_budget,budget.model_budget_budget,base.group_user,1,1,1,1
access_budget_lines_user,access_budget_lines,model_budget_budget_lines,base.group_user,1,1,1,1
budget.access_budget_wizard,access_budget_wizard,budget.model_budget_wizard,base.group_user,1,1,1,1
65 changes: 65 additions & 0 deletions budget/views/budget_line_views.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>

<record id="view_budget_line_list" model="ir.ui.view">
<field name="name">budget.line.list</field>
<field name="model">budget.budget.lines</field>
<field name="arch" type="xml">
<list string="Budget Lines" default_order="id desc" create="0">

<field name="currency_id" column_invisible="1" />
<field name="budget_id" />
<field string="Analytic Account" name="analytic_account_id" />
<field string="Budget Amount" name="planned_amount" />
<field string="Achieved Amount" name="practical_amount" />
</list>
</field>
</record>


<record model="ir.ui.view" id="view_budget_budget_line_pivot">
<field name="name">budget.budget.line.pivot</field>
<field name="model">budget.budget.lines</field>
<field name="arch" type="xml">
<pivot string="Budget Lines" sample="1">
<field name="analytic_account_id" type="row" />
<field name="count" />
</pivot>
</field>
</record>

<record model="ir.ui.view" id="view_budget_budget_line_graph">
<field name="name">budget.budget.line.graph</field>
<field name="model">budget.budget.lines</field>
<field name="arch" type="xml">
<graph string="Budget Lines" sample="1" disable_linking="1" stacked="0">
<field name="analytic_account_id" type="row" />
<field name="practical_amount" type="measure" operator="+"/>
<field name="over_budget" type="measure" operator="+"/>
</graph>
</field>
</record>

<record id="view_budget_budget_line_gantt" model="ir.ui.view">
<field name="name">budget.budget.line.gantt</field>
<field name="model">budget.budget.lines</field>
<field name="arch" type="xml">
<gantt string="Budget Gantt" color="analytic_account_id" display_mode="sparse" progress_bar="analytic_account_id" date_start="budget_start_date" date_stop="budget_end_date" default_scale="month" default_group_by="budget_id">

<field name="user_id" string="Responsible" widget="many2one_avatar" />
</gantt>
</field>
</record>



<record model="ir.actions.act_window" id="action_budget_budget_line">
<field name="name">Budget lines</field>
<field name="res_model">budget.budget.lines</field>
<field name="view_mode">list,pivot,graph,gantt</field>
<field name="view_id" ref="budget.view_budget_line_list" />

</record>


</odoo>
13 changes: 13 additions & 0 deletions budget/views/budget_menu_views.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<menuitem id="budget_menu_root" name="Budget">
<menuitem id="budget_first_level_menu" name="Budgets">
</menuitem>
<menuitem id="budget_menu_action" action="budget_action"/>


<menuitem id="budget_first_level_menu" name="Budget lines">
</menuitem>
<menuitem id="budget_line_menu_action" action="action_budget_budget_line"/>
</menuitem>
</odoo>
Loading