14.0 account budget forecast #4

Merged
stephansainleger merged 9 commits from 14.0-account_budget_forecast into 14.0 2022-06-30 12:17:46 +00:00
9 changed files with 94 additions and 70 deletions
Showing only changes of commit d76796bfa7 - Show all commits

View File

@@ -77,7 +77,6 @@ This module is maintained by ELABORE.
"wizard/budget_forecast_model_choice.xml", "wizard/budget_forecast_model_choice.xml",
"views/account_analytic_account.xml", "views/account_analytic_account.xml",
"views/account_analytic_account_categories.xml", "views/account_analytic_account_categories.xml",
"views/account_invoice.xml",
"views/sale_order.xml", "views/sale_order.xml",
"views/budget_forecast.xml", "views/budget_forecast.xml",
"views/budget_coefficient.xml", "views/budget_coefficient.xml",

View File

@@ -2,7 +2,6 @@
from . import account_analytic_account from . import account_analytic_account
from . import account_analytic_line from . import account_analytic_line
from . import account_move
from . import budget_forecast from . import budget_forecast
from . import budget_forecast_model from . import budget_forecast_model
from . import sale_order from . import sale_order

View File

@@ -6,4 +6,16 @@ from odoo import models, fields, api
class AccountAnalyticLine(models.Model): class AccountAnalyticLine(models.Model):
_inherit = "account.analytic.line" _inherit = "account.analytic.line"
budget_forecast_id = fields.Many2one("budget.forecast", store=True) timesheet_entry = fields.Boolean(
help="Technical field to identify analytic lines created from timesheet vies",
store=True,
default=False,
)
@api.model_create_multi
def create(self, vals_list):
lines = super(AccountAnalyticLine, self).create(vals_list)
for line, values in zip(lines, vals_list):
if line.project_id: # applied only for timesheet
line.timesheet_entry = True
return lines

View File

@@ -1,24 +0,0 @@
# -*- coding: utf-8 -*-
from odoo import models, fields, api
class AccountMoveLine(models.Model):
_inherit = "account.move.line"
budget_forecast_id = fields.Many2one(
"budget.forecast",
string="Budget line",
index=True,
store=True,
readonly=False,
copy=False,
)
@api.depends("budget_forecast_id")
def _transfer_budget_forecast_line(self):
for record in self:
import pdb
pdb.set_trace()
record.analytic_line_ids.budget_forecast_id = record.budget_forecast_id.id

View File

@@ -19,6 +19,13 @@ class BudgetForecast(models.Model):
index=True, index=True,
copy=True, copy=True,
) )
analytic_tag = fields.Many2one(
"account.analytic.tag",
"Analytic tag",
index=True,
copy=False,
ondelete="cascade",
)
budget_category = fields.Selection( budget_category = fields.Selection(
[ [
@@ -61,9 +68,6 @@ class BudgetForecast(models.Model):
copy=False, copy=False,
) )
analytic_line_ids = fields.One2many(
"account.analytic.line", "budget_forecast_id", copy=False
)
actual_qty = fields.Float( actual_qty = fields.Float(
"Actual Quantity", "Actual Quantity",
compute="_calc_actual", compute="_calc_actual",
@@ -114,6 +118,9 @@ class BudgetForecast(models.Model):
"line_subsection", "line_subsection",
]: ]:
record._create_category_sections() record._create_category_sections()
record.analytic_tag = self.env["account.analytic.tag"].create(
{"name": record._calculate_name()}
)
return records return records
def _create_category_sections(self): def _create_category_sections(self):
@@ -193,6 +200,12 @@ class BudgetForecast(models.Model):
values = {"name": record._calculate_name()} values = {"name": record._calculate_name()}
record.write(values, False) record.write(values, False)
@api.onchange("name")
def _compute_analytic_tag_name(self):
for record in self:
if record.analytic_tag:
record.analytic_tag.name = record.name
def _sync_sections_data(self): def _sync_sections_data(self):
for record in self: for record in self:
if record.display_type in ["line_section", "line_subsection"]: if record.display_type in ["line_section", "line_subsection"]:
@@ -329,29 +342,66 @@ class BudgetForecast(models.Model):
elif record.display_type == "line_note": elif record.display_type == "line_note":
record.plan_price = 0.00 record.plan_price = 0.00
def _find_analytic_lines(self, move_type, with_timesheets=False):
self.ensure_one()
if with_timesheets:
domain = [
"|",
(
"move_id.move_id.move_type",
"in",
move_type,
),
("timesheet_entry", "=", True),
]
else:
domain = [
(
"move_id.move_id.move_type",
"in",
move_type,
)
]
analytic_lines = (
self.env["account.analytic.line"]
.search(domain)
.filtered(lambda x: self.analytic_tag in x.tag_ids)
)
return analytic_lines
def _find_draft_invoice_lines(self, move_type):
self.ensure_one()
domain = [
("analytic_account_id", "=", self.analytic_id.id),
("parent_state", "in", ["draft"]),
("move_id.move_type", "in", move_type),
]
invoice_lines = (
self.env["account.move.line"]
.search(domain)
.filtered(lambda x: self.analytic_tag in x.analytic_tag_ids)
)
return invoice_lines
@api.depends("analytic_id.line_ids.amount") @api.depends("analytic_id.line_ids.amount")
def _calc_actual(self): def _calc_actual(self):
for record in self: for record in self:
# Section or Sub-section
if record.display_type in ["line_section", "line_subsection"]: if record.display_type in ["line_section", "line_subsection"]:
if record.child_ids: if record.child_ids:
# Actual expenses are calculated with the child lines # Actual expenses are calculated with the child lines
record.actual_qty = sum(record.mapped("child_ids.actual_qty")) record.actual_qty = sum(record.mapped("child_ids.actual_qty"))
record.actual_amount = sum(record.mapped("child_ids.actual_amount")) record.actual_amount = sum(record.mapped("child_ids.actual_amount"))
# Incomes are calculated with the analytic lines # Incomes are calculated with the analytic lines
line_ids = record.analytic_line_ids.filtered( line_ids = record._find_analytic_lines(
lambda x: x.move_id.move_id.move_type ["out_invoice", "out_refund", "out_receipt"]
in ["out_invoice", "out_refund"]
) )
record.incomes = sum(line_ids.mapped("amount")) record.incomes = sum(line_ids.mapped("amount"))
# Add Draft Invoice lines ids to incomes
# Add Invoice lines ids invoice_lines = record._find_draft_invoice_lines(
domain = [ ["out_invoice", "out_refund"]
("analytic_account_id", "=", record.analytic_id.id), )
("parent_state", "in", ["draft", "posted"]),
("budget_forecast_id", "=", record.id),
("move_id.move_type", "in", ["out_invoice", "out_refund"]),
]
invoice_lines = self.env["account.move.line"].search(domain)
for invoice_line in invoice_lines: for invoice_line in invoice_lines:
if invoice_line.move_id.move_type == "out_invoice": if invoice_line.move_id.move_type == "out_invoice":
record.incomes = ( record.incomes = (
@@ -363,25 +413,23 @@ class BudgetForecast(models.Model):
) )
record.balance = record.incomes - record.actual_amount record.balance = record.incomes - record.actual_amount
# Note
elif record.display_type == "line_note": elif record.display_type == "line_note":
record.actual_qty = 0 record.actual_qty = 0
record.actual_amount = 0.00 record.actual_amount = 0.00
# Product
else: else:
line_ids = record.analytic_line_ids.filtered( line_ids = record._find_analytic_lines(
lambda x: x.move_id.move_id.move_type ["in_invoice", "in_refund", "in_receipt"], True
not in ["out_invoice", "out_refund"]
) )
record.actual_qty = abs(sum(line_ids.mapped("unit_amount"))) record.actual_qty = abs(sum(line_ids.mapped("unit_amount")))
record.actual_amount = -sum(line_ids.mapped("amount")) record.actual_amount = -sum(line_ids.mapped("amount"))
# Add Invoice lines ids # Add Draft Invoice lines ids
domain = [ invoice_lines = record._find_draft_invoice_lines(
("analytic_account_id", "=", record.analytic_id.id), ["in_invoice", "in_refund"]
("parent_state", "in", ["draft", "posted"]), )
("budget_forecast_id", "=", record.id),
("move_id.move_type", "in", ["in_invoice", "in_refund"]),
]
invoice_lines = self.env["account.move.line"].search(domain)
for invoice_line in invoice_lines: for invoice_line in invoice_lines:
if invoice_line.move_id.move_type == "in_invoice": if invoice_line.move_id.move_type == "in_invoice":
record.actual_qty = record.actual_qty + invoice_line.quantity record.actual_qty = record.actual_qty + invoice_line.quantity

View File

@@ -1,13 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="invoice_budget_form" model="ir.ui.view">
<field name="name">account.invoice.budget.form</field>
<field name="model">account.move</field>
<field name="inherit_id" ref="account.view_move_form" />
<field name="arch" type="xml">
<xpath expr="//field[@name='invoice_line_ids']/tree/field[@name='analytic_tag_ids']" position="after">
<field name="budget_forecast_id" domain="[('analytic_id', '=', analytic_account_id), ('product_id', '=', product_id)]" />
</xpath>
</field>
</record>
</odoo>

View File

@@ -9,8 +9,10 @@
<sheet> <sheet>
<group> <group>
<group> <group>
<field name="name" />
<field name="product_id" /> <field name="product_id" />
<field name="description" /> <field name="description" />
<field name="analytic_tag" />
</group> </group>
<group> <group>
<field name="analytic_id" /> <field name="analytic_id" />
@@ -36,7 +38,8 @@
</group> </group>
</group> </group>
<group string="Analytic Lines"> <group string="Analytic Lines">
<field name="analytic_line_ids" nolabel="1"> <!-- TODO: Ajouter bouton vers vue Tree affichant les lignes analytics -->
<!-- <field name="analytic_line_ids" nolabel="1">
<tree> <tree>
<field name="date" /> <field name="date" />
<field name="employee_id" /> <field name="employee_id" />
@@ -45,7 +48,7 @@
<field name="unit_amount" string="Quantity" /> <field name="unit_amount" string="Quantity" />
<field name="amount" /> <field name="amount" />
</tree> </tree>
</field> </field>-->
</group> </group>
<group string="Childs" attrs="{'invisible' : [('child_ids','=', False)]}"> <group string="Childs" attrs="{'invisible' : [('child_ids','=', False)]}">
<field name="child_ids" nolabel="1"> <field name="child_ids" nolabel="1">

View File

@@ -8,7 +8,7 @@
<field name="inherit_id" ref="hr_timesheet.hr_timesheet_line_tree" /> <field name="inherit_id" ref="hr_timesheet.hr_timesheet_line_tree" />
<field name="arch" type="xml"> <field name="arch" type="xml">
<xpath expr="//field[@name='task_id']" position="after"> <xpath expr="//field[@name='task_id']" position="after">
<field name="budget_forecast_id" domain="[('display_type', '=', 'line_article')]" /> <field name="tag_ids" widget="many2many_tags" /> <!--domain="[('display_type', '=', 'line_article')]" />-->
</xpath> </xpath>
</field> </field>
</record> </record>

View File

@@ -6,7 +6,7 @@
<field name="inherit_id" ref="hr_timesheet.view_task_form2_inherited" /> <field name="inherit_id" ref="hr_timesheet.view_task_form2_inherited" />
<field name="arch" type="xml"> <field name="arch" type="xml">
<xpath expr="//field[@name='timesheet_ids']/tree/field[@name='name']" position="after"> <xpath expr="//field[@name='timesheet_ids']/tree/field[@name='name']" position="after">
<field name="budget_forecast_id" domain="[('display_type', '=', 'line_article')]" /> <field name="tag_ids" /> <!--domain="[('display_type', '=', 'line_article')]" />-->
</xpath> </xpath>
</field> </field>
</record> </record>