From 9f88c08502fea4432ff4fb2a865cad01cbd29ca7 Mon Sep 17 00:00:00 2001 From: oihane Date: Thu, 19 Apr 2018 15:40:46 +0200 Subject: [PATCH 01/24] [ADD] new module project_budget (#18) --- project_budget/README.rst | 47 ++++++++++ project_budget/__init__.py | 4 + project_budget/__manifest__.py | 26 +++++ project_budget/data/project_budget_data.xml | 28 ++++++ project_budget/i18n/es.po | 94 +++++++++++++++++++ project_budget/models/__init__.py | 5 + project_budget/models/crossovered_budget.py | 80 ++++++++++++++++ project_budget/models/project_project.py | 47 ++++++++++ project_budget/tests/__init__.py | 4 + project_budget/tests/test_project_budget.py | 44 +++++++++ .../views/crossovered_budget_view.xml | 54 +++++++++++ project_budget/views/project_project_view.xml | 55 +++++++++++ 12 files changed, 488 insertions(+) create mode 100644 project_budget/README.rst create mode 100644 project_budget/__init__.py create mode 100644 project_budget/__manifest__.py create mode 100644 project_budget/data/project_budget_data.xml create mode 100644 project_budget/i18n/es.po create mode 100644 project_budget/models/__init__.py create mode 100644 project_budget/models/crossovered_budget.py create mode 100644 project_budget/models/project_project.py create mode 100644 project_budget/tests/__init__.py create mode 100644 project_budget/tests/test_project_budget.py create mode 100644 project_budget/views/crossovered_budget_view.xml create mode 100644 project_budget/views/project_project_view.xml diff --git a/project_budget/README.rst b/project_budget/README.rst new file mode 100644 index 00000000..dddcf418 --- /dev/null +++ b/project_budget/README.rst @@ -0,0 +1,47 @@ +.. image:: https://img.shields.io/badge/license-AGPL--3-blue.png + :target: https://www.gnu.org/licenses/agpl + :alt: License: AGPL-3 + +============== +Project Budget +============== + +This module extends the functionality of budgets for projects. When a +project is created it will create a budget for current year with: +* 12 lines of outgoings (one per month) +* 12 lines of incomings (one per month) +* 1 line on december 30th for outgoings +* 1 line on december 30th for incomings + +It also allows creating those 26 budgetary lines for a budget with project +using a button. + +When installing the module it creates two budgetary positions that must be +configured. + +Configuration +============= + +To configure this module, you need to: + +#. Go to *Invoicing* > *Configuration* > *Management* > *Budgetary Positions*. +#. Configure **Income** and **Outcome** accounts. + +Bug Tracker +=========== + +Bugs are tracked on `GitHub Issues +`_. In case of trouble, +please check there if your issue has already been reported. If you spotted +it first, help us smash it by providing detailed and welcomed feedback. + +Credits +======= + +Contributors +------------ + +* Oihane Crucelaegui +* Ana Juaristi + +Do not contact contributors directly about support or help with technical issues. diff --git a/project_budget/__init__.py b/project_budget/__init__.py new file mode 100644 index 00000000..288dc48e --- /dev/null +++ b/project_budget/__init__.py @@ -0,0 +1,4 @@ +# Copyright 2018 Oihane Crucelaegui - AvanzOSC +# License AGPL-3 - See http://www.gnu.org/licenses/agpl-3.0.html + +from . import models diff --git a/project_budget/__manifest__.py b/project_budget/__manifest__.py new file mode 100644 index 00000000..9b04695a --- /dev/null +++ b/project_budget/__manifest__.py @@ -0,0 +1,26 @@ +# Copyright 2018 Oihane Crucelaegui - AvanzOSC +# License AGPL-3 - See http://www.gnu.org/licenses/agpl-3.0.html + +{ + "name": "Project Bugdet", + "summary": "", + "version": "11.0.1.0.0", + "category": "Custom Module", + "license": "AGPL-3", + "author": "AvanzOSC", + "website": "http://www.avanzosc.es", + "contributors": [ + "Oihane Crucelaegui ", + "Ana Juaristi ", + ], + "depends": [ + "account_budget", + "project", + ], + "data": [ + "data/project_budget_data.xml", + "views/crossovered_budget_view.xml", + "views/project_project_view.xml", + ], + "installable": True, +} diff --git a/project_budget/data/project_budget_data.xml b/project_budget/data/project_budget_data.xml new file mode 100644 index 00000000..bb1b9cbc --- /dev/null +++ b/project_budget/data/project_budget_data.xml @@ -0,0 +1,28 @@ + + + + 000 + Income + + True + + + + 001 + Expenses + + True + + + + Income + + + + + Outcome + + + diff --git a/project_budget/i18n/es.po b/project_budget/i18n/es.po new file mode 100644 index 00000000..39a30252 --- /dev/null +++ b/project_budget/i18n/es.po @@ -0,0 +1,94 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * project_budget +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 11.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2018-04-13 09:46+0000\n" +"PO-Revision-Date: 2018-04-13 09:46+0000\n" +"Last-Translator: <>\n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: \n" + +#. module: project_budget +#: model:ir.actions.act_window,help:project_budget.project_budget_action +msgid "A budget is a forecast of your company's income and/or expenses expected for a period in the future. A budget is defined on some financial accounts and/or analytic accounts (that may represent projects, departments, categories of products, etc.)" +msgstr "Un presupuesto es una proyección de los ingresos y/o gastos esperados en su compañía en un período en el futuro. Se define en varias cuentas financieras y/o analíticas (que pueden representar proyectos, departamentos, categorías de productos, etc)" + +#. module: project_budget +#: model:ir.model.fields,field_description:project_budget.field_crossovered_budget_active +msgid "Active" +msgstr "Activo" + +#. module: project_budget +#: model:ir.model,name:project_budget.model_crossovered_budget +msgid "Budget" +msgstr "Presupuesto" + +#. module: project_budget +#: model:ir.actions.act_window,name:project_budget.project_budget_action +#: model:ir.model.fields,field_description:project_budget.field_project_project_budget_count +#: model:ir.model.fields,field_description:project_budget.field_project_project_budget_ids +#: model:ir.ui.view,arch_db:project_budget.project_project_form_view +msgid "Budgets" +msgstr "Presupuestos" + +#. module: project_budget +#: model:ir.actions.act_window,help:project_budget.project_budget_action +msgid "By keeping track of where your money goes, you may be less likely to overspend, and more likely to meet your financial goals. Forecast a budget by detailing the expected revenue per analytic account and monitor its evolution based on the actuals realised during that period." +msgstr "Haciendo un seguimiento de dónde va su dinero, puede ser menos probable gastar demasiado, y más probable alcanzar sus metas financieras. Prevea un presupuesto detallando los ingresos esperados por cuenta analítica y monitorice su evolución basada en lo real obtenido durante ese periodo." + +#. module: project_budget +#: model:ir.actions.act_window,help:project_budget.project_budget_action +msgid "Click to create a new budget." +msgstr "Pulse para crear un nuevo presupuesto." + +#. module: project_budget +#: model:ir.actions.server,name:project_budget.action_create_initial_project_budget +msgid "Create Initial Budget" +msgstr "Crear presupuesto inicial" + +#. module: project_budget +#: model:ir.ui.view,arch_db:project_budget.crossovered_budget_form_view +msgid "Create Lines" +msgstr "Crear líneas" + +#. module: project_budget +#: model:ir.model.fields,field_description:project_budget.field_crossovered_budget_initial +#: model:ir.ui.view,arch_db:project_budget.crossovered_budget_search_view +msgid "Initial" +msgstr "Inicial" + +#. module: project_budget +#: model:ir.ui.view,arch_db:project_budget.crossovered_budget_search_view +msgid "Initial Budgets" +msgstr "Presupuestos iniciales" + +#. module: project_budget +#: code:addons/project_budget/models/project_project.py:33 +#, python-format +msgid "Initial {} budget: {}" +msgstr "Presupuesto inicial {}: {}" + +#. module: project_budget +#: model:ir.model,name:project_budget.model_project_project +#: model:ir.model.fields,field_description:project_budget.field_crossovered_budget_project_id +msgid "Project" +msgstr "Proyecto" + +#. module: project_budget +#: code:addons/project_budget/models/crossovered_budget.py:79 +#, python-format +msgid "There can only be one initial budget per project and year." +msgstr "Sólo puede haber un presupuesto inicial por proyecto y año." + +#. module: project_budget +#: model:ir.model.fields,field_description:project_budget.field_crossovered_budget_year +msgid "Year" +msgstr "Año" + diff --git a/project_budget/models/__init__.py b/project_budget/models/__init__.py new file mode 100644 index 00000000..726f389f --- /dev/null +++ b/project_budget/models/__init__.py @@ -0,0 +1,5 @@ +# Copyright 2018 Oihane Crucelaegui - AvanzOSC +# License AGPL-3 - See http://www.gnu.org/licenses/agpl-3.0.html + +from . import crossovered_budget +from . import project_project diff --git a/project_budget/models/crossovered_budget.py b/project_budget/models/crossovered_budget.py new file mode 100644 index 00000000..7a52ad20 --- /dev/null +++ b/project_budget/models/crossovered_budget.py @@ -0,0 +1,80 @@ +# Copyright 2018 Oihane Crucelaegui - AvanzOSC +# License AGPL-3 - See http://www.gnu.org/licenses/agpl-3.0.html + +from odoo import _, api, exceptions, fields, models +from dateutil.relativedelta import relativedelta + +to_string = fields.Date.to_string +from_string = fields.Date.from_string + + +class CrossoveredBudget(models.Model): + _inherit = 'crossovered.budget' + + project_id = fields.Many2one( + comodel_name='project.project', string='Project', + states={'done': [('readonly', True)]}) + initial = fields.Boolean( + string='Initial', copy=False, states={'done': [('readonly', True)]}) + active = fields.Boolean(string='Active', default=True) + year = fields.Integer(string='Year', compute='_compute_year', store=True) + + @api.depends('date_from') + def _compute_year(self): + for record in self: + record.year = from_string(record.date_from).year + + @api.multi + def action_create_period(self): + budget_line_obj = self.env['crossovered.budget.lines'] + postcome = self.env.ref('project_budget.budget_post_postcome') + income = self.env.ref('project_budget.budget_post_income') + for budget in self.filtered(lambda b: b.project_id and not + b.crossovered_budget_line and + b.state == 'draft'): + vals = { + 'analytic_account_id': + budget.project_id.analytic_account_id.id, + 'crossovered_budget_id': budget.id, + 'planned_amount': 0.0, + } + ds = from_string(budget.date_from) + final_date = ds.replace(day=30, month=12) + while to_string(ds) < budget.date_to: + de = ds + relativedelta(months=1, days=-1) + if to_string(de) > budget.date_to: + de = from_string(budget.date_to) + vals.update({ + 'date_from': to_string(ds), + 'date_to': to_string(de), + 'general_budget_id': postcome.id, + }) + budget_line_obj.create(vals) + vals.update({ + 'general_budget_id': income.id, + }) + budget_line_obj.create(vals) + ds = ds + relativedelta(months=1) + if to_string(final_date) < budget.date_to: + vals.update({ + 'date_from': to_string(final_date), + 'date_to': to_string(final_date), + 'general_budget_id': postcome.id, + }) + budget_line_obj.create(vals) + vals.update({ + 'general_budget_id': income.id, + }) + budget_line_obj.create(vals) + return True + + @api.multi + @api.constrains('project_id', 'initial', 'date_from') + def _check_initial_by_project(self): + for record in self.filtered('project_id'): + if len(self.search([('project_id', '=', record.project_id.id), + ('initial', '=', True), + ('year', '=', record.year)])) > 1: + raise exceptions.ValidationError( + _("There can only be one initial budget per project and " + "year.")) diff --git a/project_budget/models/project_project.py b/project_budget/models/project_project.py new file mode 100644 index 00000000..2f41866d --- /dev/null +++ b/project_budget/models/project_project.py @@ -0,0 +1,47 @@ +# Copyright 2018 Oihane Crucelaegui - AvanzOSC +# License AGPL-3 - See http://www.gnu.org/licenses/agpl-3.0.html + +from odoo import _, api, fields, models + +to_string = fields.Date.to_string +from_string = fields.Date.from_string + + +class ProjectProject(models.Model): + _inherit = 'project.project' + + budget_ids = fields.One2many( + comodel_name='crossovered.budget', inverse_name='project_id', + string='Budgets') + budget_count = fields.Integer( + string='Budgets', compute='_compute_budget_count') + + @api.multi + def _compute_budget_count(self): + for record in self: + record.budget_count = len(record.budget_ids) + + @api.multi + def create_initial_project_budget(self): + budget_obj = self.env['crossovered.budget'] + today = from_string(fields.Date.context_today(self)) + date_from = to_string(today.replace(month=1, day=1)) + date_to = to_string(today.replace(month=12, day=31)) + for record in self.filtered(lambda l: not any(l.budget_ids.filtered( + lambda b: b.initial and b.year == today.year))): + budget = budget_obj.create({ + 'name': _( + u'Initial {} budget: {}').format(today.year, record.name), + 'initial': True, + 'creating_user_id': record.user_id.id, + 'date_from': date_from, + 'date_to': date_to, + 'project_id': record.id, + }) + budget.action_create_period() + + @api.model + def create(self, values): + created = super(ProjectProject, self).create(values) + created.create_initial_project_budget() + return created diff --git a/project_budget/tests/__init__.py b/project_budget/tests/__init__.py new file mode 100644 index 00000000..11d97940 --- /dev/null +++ b/project_budget/tests/__init__.py @@ -0,0 +1,4 @@ +# Copyright 2018 Oihane Crucelaegui - AvanzOSC +# License AGPL-3 - See http://www.gnu.org/licenses/agpl-3.0.html + +from . import test_project_budget diff --git a/project_budget/tests/test_project_budget.py b/project_budget/tests/test_project_budget.py new file mode 100644 index 00000000..072c1b59 --- /dev/null +++ b/project_budget/tests/test_project_budget.py @@ -0,0 +1,44 @@ +# Copyright 2018 Oihane Crucelaegui - AvanzOSC +# License AGPL-3 - See http://www.gnu.org/licenses/agpl-3.0.html + +from odoo.tests import common +from odoo import exceptions, fields + +from_string = fields.Date.from_string +to_string = fields.Date.to_string + + +class TestProjectBudget(common.SavepointCase): + + @classmethod + def setUpClass(cls): + super(TestProjectBudget, cls).setUpClass() + project_model = cls.env['project.project'] + cls.project = project_model.create({ + 'name': 'New Project' + }) + + def test_project_creation(self): + self.assertTrue(self.project.budget_ids) + self.assertTrue(self.project.budget_ids[:1].initial) + self.assertEquals( + len(self.project.budget_ids), self.project.budget_count) + self.assertEquals(len( + self.project.mapped('budget_ids.crossovered_budget_line')), 26) + self.project.create_initial_project_budget() + self.assertEquals(len(self.project.budget_ids), 1) + + def test_initial_budget_per_project_year(self): + new_budget = self.project.budget_ids.copy() + with self.assertRaises(exceptions.ValidationError): + new_budget.initial = True + + def test_budget_line_creation(self): + new_budget = self.project.budget_ids.copy(default={ + 'crossovered_budget_line': [], + }) + new_budget.date_to = from_string(fields.Date.today()).replace( + month=12, day=29) + new_budget.action_create_period() + self.assertEquals(len( + new_budget.crossovered_budget_line), 24) diff --git a/project_budget/views/crossovered_budget_view.xml b/project_budget/views/crossovered_budget_view.xml new file mode 100644 index 00000000..88bb2fff --- /dev/null +++ b/project_budget/views/crossovered_budget_view.xml @@ -0,0 +1,54 @@ + + + + crossovered.budget.form + crossovered.budget + + + + + + + + + + + + + crossovered.budget.tree + crossovered.budget + + + + initial + + + + + + + + + + crossovered.budget.search + crossovered.budget + + + + + + + + + + diff --git a/project_budget/views/project_project_view.xml b/project_budget/views/project_project_view.xml new file mode 100644 index 00000000..6bbf29d8 --- /dev/null +++ b/project_budget/views/project_project_view.xml @@ -0,0 +1,55 @@ + + + + Budgets + crossovered.budget + tree,kanban,form + { + 'search_default_project_id': [active_id], + 'default_project_id': active_id, + } + + + +

+ Click to create a new budget. +

+

+ A budget is a forecast of your company's income and/or expenses expected for a period in the future. A budget is defined on some financial accounts and/or analytic accounts (that may represent projects, departments, categories of products, etc.) +

+

+ By keeping track of where your money goes, you may be less likely to overspend, and more likely to meet your financial goals. Forecast a budget by detailing the expected revenue per analytic account and monitor its evolution based on the actuals realised during that period. +

+
+
+ + + project.project.form + project.project + + + + + + + + + Create Initial Budget + ir.actions.server + code + + + +records.create_initial_project_budget() + + + +
From 3e21eeda1d010def7cd93eb2f5f3e319585c2d05 Mon Sep 17 00:00:00 2001 From: alfredoavanzosc Date: Wed, 16 May 2018 18:23:56 +0200 Subject: [PATCH 02/24] [IMP] project_budget: some modification and code cleaning (#24) * [IMP] project_budget: New menu for budget. * [IMP] project_budget: some modification and code cleaning * changed views not to show theoritical amount and percentage * moved invoice link to new module in odoo-addons * filter last lines directly in budget without new field --- project_budget/README.rst | 1 + project_budget/__manifest__.py | 5 +- project_budget/i18n/es.po | 64 ++++++++++++- project_budget/models/__init__.py | 1 + .../models/account_analytic_account.py | 22 +++++ project_budget/models/crossovered_budget.py | 29 +++++- project_budget/tests/test_project_budget.py | 38 ++++++++ .../views/account_analytic_account_view.xml | 25 +++++ .../views/crossovered_budget_line_view.xml | 96 +++++++++++++++++++ .../views/crossovered_budget_view.xml | 13 +++ 10 files changed, 284 insertions(+), 10 deletions(-) create mode 100644 project_budget/models/account_analytic_account.py create mode 100644 project_budget/views/account_analytic_account_view.xml create mode 100644 project_budget/views/crossovered_budget_line_view.xml diff --git a/project_budget/README.rst b/project_budget/README.rst index dddcf418..32db22b6 100644 --- a/project_budget/README.rst +++ b/project_budget/README.rst @@ -8,6 +8,7 @@ Project Budget This module extends the functionality of budgets for projects. When a project is created it will create a budget for current year with: + * 12 lines of outgoings (one per month) * 12 lines of incomings (one per month) * 1 line on december 30th for outgoings diff --git a/project_budget/__manifest__.py b/project_budget/__manifest__.py index 9b04695a..f5d66b90 100644 --- a/project_budget/__manifest__.py +++ b/project_budget/__manifest__.py @@ -3,8 +3,7 @@ { "name": "Project Bugdet", - "summary": "", - "version": "11.0.1.0.0", + "version": "11.0.2.0.0", "category": "Custom Module", "license": "AGPL-3", "author": "AvanzOSC", @@ -20,7 +19,9 @@ "data": [ "data/project_budget_data.xml", "views/crossovered_budget_view.xml", + "views/crossovered_budget_line_view.xml", "views/project_project_view.xml", + "views/account_analytic_account_view.xml", ], "installable": True, } diff --git a/project_budget/i18n/es.po b/project_budget/i18n/es.po index 39a30252..557e14dc 100644 --- a/project_budget/i18n/es.po +++ b/project_budget/i18n/es.po @@ -6,8 +6,8 @@ msgid "" msgstr "" "Project-Id-Version: Odoo Server 11.0\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2018-04-13 09:46+0000\n" -"PO-Revision-Date: 2018-04-13 09:46+0000\n" +"POT-Creation-Date: 2018-05-16 14:55+0000\n" +"PO-Revision-Date: 2018-05-16 14:55+0000\n" "Last-Translator: <>\n" "Language-Team: \n" "MIME-Version: 1.0\n" @@ -25,15 +25,38 @@ msgstr "Un presupuesto es una proyección de los ingresos y/o gastos esperados e msgid "Active" msgstr "Activo" +#. module: project_budget +#: model:ir.model,name:project_budget.model_account_analytic_account +#: model:ir.ui.view,arch_db:project_budget.crossovered_budget_line_search_view +msgid "Analytic Account" +msgstr "Cuenta analítica" + +#. module: project_budget +#: model:ir.model,name:project_budget.model_account_analytic_line +msgid "Analytic Line" +msgstr "Línea Analítica" + #. module: project_budget #: model:ir.model,name:project_budget.model_crossovered_budget +#: model:ir.ui.view,arch_db:project_budget.crossovered_budget_line_search_view msgid "Budget" msgstr "Presupuesto" +#. module: project_budget +#: model:ir.model,name:project_budget.model_crossovered_budget_lines +msgid "Budget Line" +msgstr "Línea de presupuesto" + +#. module: project_budget +#: model:ir.ui.view,arch_db:project_budget.crossovered_budget_line_search_view +msgid "Budgetary Position" +msgstr "Posición Presupuestaria" + #. module: project_budget #: model:ir.actions.act_window,name:project_budget.project_budget_action #: model:ir.model.fields,field_description:project_budget.field_project_project_budget_count #: model:ir.model.fields,field_description:project_budget.field_project_project_budget_ids +#: model:ir.ui.menu,name:project_budget.menu_act2_crossovered_budget_lines_view #: model:ir.ui.view,arch_db:project_budget.project_project_form_view msgid "Budgets" msgstr "Presupuestos" @@ -56,7 +79,12 @@ msgstr "Crear presupuesto inicial" #. module: project_budget #: model:ir.ui.view,arch_db:project_budget.crossovered_budget_form_view msgid "Create Lines" -msgstr "Crear líneas" +msgstr "Crear elementos" + +#. module: project_budget +#: model:ir.ui.view,arch_db:project_budget.crossovered_budget_line_search_view +msgid "Group By" +msgstr "Agrupar por" #. module: project_budget #: model:ir.model.fields,field_description:project_budget.field_crossovered_budget_initial @@ -64,25 +92,55 @@ msgstr "Crear líneas" msgid "Initial" msgstr "Inicial" +#. module: project_budget +#: model:ir.model.fields,field_description:project_budget.field_crossovered_budget_lines_initial_budget_line_id +msgid "Initial Budget Line" +msgstr "Elemento de presupuesto inicial" + #. module: project_budget #: model:ir.ui.view,arch_db:project_budget.crossovered_budget_search_view msgid "Initial Budgets" msgstr "Presupuestos iniciales" +#. module: project_budget +#: model:ir.model.fields,field_description:project_budget.field_crossovered_budget_lines_initial_planned_amount +#: model:ir.ui.view,arch_db:project_budget.crossovered_budget_form_view +msgid "Initial Planned Amount" +msgstr "Importe planificado inicial" + +#. module: project_budget +#: model:ir.ui.view,arch_db:project_budget.account_analytic_account_last_budget_lines_form_view +msgid "Initial planned amount" +msgstr "Importe planificado inicial" + #. module: project_budget #: code:addons/project_budget/models/project_project.py:33 #, python-format msgid "Initial {} budget: {}" msgstr "Presupuesto inicial {}: {}" +#. module: project_budget +#: model:ir.model.fields,field_description:project_budget.field_account_analytic_line_invoice_id +msgid "Invoice" +msgstr "Factura" + +#. module: project_budget +#: model:ir.model.fields,field_description:project_budget.field_crossovered_budget_lines_notes +#: model:ir.ui.view,arch_db:project_budget.crossovered_budget_line_form_view +msgid "Notes" +msgstr "Notas" + #. module: project_budget #: model:ir.model,name:project_budget.model_project_project +#: model:ir.model.fields,field_description:project_budget.field_crossovered_budget_lines_project_id #: model:ir.model.fields,field_description:project_budget.field_crossovered_budget_project_id +#: model:ir.ui.view,arch_db:project_budget.crossovered_budget_line_search_view msgid "Project" msgstr "Proyecto" #. module: project_budget #: code:addons/project_budget/models/crossovered_budget.py:79 +#: code:addons/project_budget/models/crossovered_budget.py:83 #, python-format msgid "There can only be one initial budget per project and year." msgstr "Sólo puede haber un presupuesto inicial por proyecto y año." diff --git a/project_budget/models/__init__.py b/project_budget/models/__init__.py index 726f389f..228439e4 100644 --- a/project_budget/models/__init__.py +++ b/project_budget/models/__init__.py @@ -3,3 +3,4 @@ from . import crossovered_budget from . import project_project +from . import account_analytic_account diff --git a/project_budget/models/account_analytic_account.py b/project_budget/models/account_analytic_account.py new file mode 100644 index 00000000..452a87a9 --- /dev/null +++ b/project_budget/models/account_analytic_account.py @@ -0,0 +1,22 @@ +# Copyright 2018 Alfredo de la Fuente - AvanzOSC +# License AGPL-3 - See http://www.gnu.org/licenses/agpl-3.0.html +from odoo import api, fields, models + + +class AccountAnalyticAccount(models.Model): + _inherit = 'account.analytic.account' + + @api.multi + def _domain_budget_line(self): + if not self: + return [] + all_lines = self.env['crossovered.budget.lines'].search( + [('analytic_account_id', '=', self.id)]) + last_budget = all_lines.mapped('crossovered_budget_id')[-1:] + domain = ( + [('crossovered_budget_id', '=', last_budget.id)] if last_budget + else []) + return domain + + crossovered_budget_line = fields.One2many( + domain=lambda self: self._domain_budget_line()) diff --git a/project_budget/models/crossovered_budget.py b/project_budget/models/crossovered_budget.py index 7a52ad20..055cfed4 100644 --- a/project_budget/models/crossovered_budget.py +++ b/project_budget/models/crossovered_budget.py @@ -34,7 +34,7 @@ def action_create_period(self): b.state == 'draft'): vals = { 'analytic_account_id': - budget.project_id.analytic_account_id.id, + budget.project_id.analytic_account_id.id, 'crossovered_budget_id': budget.id, 'planned_amount': 0.0, } @@ -49,11 +49,13 @@ def action_create_period(self): 'date_to': to_string(de), 'general_budget_id': postcome.id, }) - budget_line_obj.create(vals) + line = budget_line_obj.create(vals) + line.initial_budget_line_id = line.id vals.update({ 'general_budget_id': income.id, }) - budget_line_obj.create(vals) + line = budget_line_obj.create(vals) + line.initial_budget_line_id = line.id ds = ds + relativedelta(months=1) if to_string(final_date) < budget.date_to: vals.update({ @@ -61,11 +63,13 @@ def action_create_period(self): 'date_to': to_string(final_date), 'general_budget_id': postcome.id, }) - budget_line_obj.create(vals) + line = budget_line_obj.create(vals) + line.initial_budget_line_id = line.id vals.update({ 'general_budget_id': income.id, }) - budget_line_obj.create(vals) + line = budget_line_obj.create(vals) + line.initial_budget_line_id = line.id return True @api.multi @@ -78,3 +82,18 @@ def _check_initial_by_project(self): raise exceptions.ValidationError( _("There can only be one initial budget per project and " "year.")) + + +class CrossoveredBudgetLines(models.Model): + _inherit = "crossovered.budget.lines" + + initial_budget_line_id = fields.Many2one( + comodel_name='crossovered.budget.lines', string='Initial Budget Line', + copy=True) + initial_planned_amount = fields.Float( + string='Initial Planned Amount', digits=0, store=True, + related='initial_budget_line_id.planned_amount') + notes = fields.Text(string='Notes') + project_id = fields.Many2one( + comodel_name='project.project', string='Project', + related='crossovered_budget_id.project_id', store=True) diff --git a/project_budget/tests/test_project_budget.py b/project_budget/tests/test_project_budget.py index 072c1b59..5c539341 100644 --- a/project_budget/tests/test_project_budget.py +++ b/project_budget/tests/test_project_budget.py @@ -42,3 +42,41 @@ def test_budget_line_creation(self): new_budget.action_create_period() self.assertEquals(len( new_budget.crossovered_budget_line), 24) + + def test_initial_budget_duplication(self): + analytic_account = self.project.analytic_account_id + old_budget = self.project.budget_ids[:1] + self.assertEquals( + old_budget.crossovered_budget_line[:1], + old_budget.crossovered_budget_line[:1].initial_budget_line_id) + self.assertEquals( + old_budget.crossovered_budget_line, + analytic_account.crossovered_budget_line) + old_budget.crossovered_budget_line[:1].write({ + 'planned_amount': 50.0, + }) + self.assertEquals( + old_budget.crossovered_budget_line[:1].planned_amount, + old_budget.crossovered_budget_line[:1].initial_planned_amount) + new_budget = old_budget.copy() + self.assertEquals( + len(old_budget.crossovered_budget_line), + len(new_budget.crossovered_budget_line)) + self.assertEquals( + new_budget.crossovered_budget_line, + analytic_account.crossovered_budget_line) + new_budget.crossovered_budget_line[:1].write({ + 'planned_amount': 150.0, + }) + self.assertNotEquals( + new_budget.crossovered_budget_line[:1], + new_budget.crossovered_budget_line[:1].initial_budget_line_id) + self.assertEquals( + old_budget.crossovered_budget_line[:1], + new_budget.crossovered_budget_line[:1].initial_budget_line_id) + self.assertEquals( + old_budget.crossovered_budget_line[:1].planned_amount, + new_budget.crossovered_budget_line[:1].initial_planned_amount) + self.assertNotEquals( + new_budget.crossovered_budget_line[:1].planned_amount, + new_budget.crossovered_budget_line[:1].initial_planned_amount) diff --git a/project_budget/views/account_analytic_account_view.xml b/project_budget/views/account_analytic_account_view.xml new file mode 100644 index 00000000..abc192fe --- /dev/null +++ b/project_budget/views/account_analytic_account_view.xml @@ -0,0 +1,25 @@ + + + + account.analytic.account.last_budget_lines.form + account.analytic.account + + + + + + + + + + True + + + True + + + True + + + + diff --git a/project_budget/views/crossovered_budget_line_view.xml b/project_budget/views/crossovered_budget_line_view.xml new file mode 100644 index 00000000..d4df8ca2 --- /dev/null +++ b/project_budget/views/crossovered_budget_line_view.xml @@ -0,0 +1,96 @@ + + + + + + crossovered.budget.line.form + crossovered.budget.lines + + + + + + + + + + True + + + True + + + True + + + + + + + + + + + crossovered.budget.line.tree + crossovered.budget.lines + + + + + + + + + + + + + top + + + + + + True + + + True + + + True + + + + + + crossovered.budget.line.search + crossovered.budget.lines + + + + + + + + + + + + + + + + + + + + diff --git a/project_budget/views/crossovered_budget_view.xml b/project_budget/views/crossovered_budget_view.xml index 88bb2fff..bc401f72 100644 --- a/project_budget/views/crossovered_budget_view.xml +++ b/project_budget/views/crossovered_budget_view.xml @@ -17,6 +17,19 @@ + + + + + True + + + True + + + True + From 49b607470b14dbd97c7ab2d53082b5b423d86071 Mon Sep 17 00:00:00 2001 From: oihane Date: Mon, 1 Oct 2018 14:29:54 +0200 Subject: [PATCH 03/24] [IMP] project_budget: add new pivot view for budget lines (#38) * [IMP] project_budget: add new pivot view for budget lines * [IMP] project_budget: add new option to action + sum amount --- project_budget/__manifest__.py | 2 +- project_budget/i18n/es.po | 26 +++++++++---------- project_budget/models/crossovered_budget.py | 8 ++++++ project_budget/tests/test_project_budget.py | 11 ++++++++ .../views/crossovered_budget_line_view.xml | 24 +++++++++++++++++ 5 files changed, 57 insertions(+), 14 deletions(-) diff --git a/project_budget/__manifest__.py b/project_budget/__manifest__.py index f5d66b90..265161f5 100644 --- a/project_budget/__manifest__.py +++ b/project_budget/__manifest__.py @@ -3,7 +3,7 @@ { "name": "Project Bugdet", - "version": "11.0.2.0.0", + "version": "11.0.2.0.1", "category": "Custom Module", "license": "AGPL-3", "author": "AvanzOSC", diff --git a/project_budget/i18n/es.po b/project_budget/i18n/es.po index 557e14dc..4c6cad15 100644 --- a/project_budget/i18n/es.po +++ b/project_budget/i18n/es.po @@ -6,8 +6,8 @@ msgid "" msgstr "" "Project-Id-Version: Odoo Server 11.0\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2018-05-16 14:55+0000\n" -"PO-Revision-Date: 2018-05-16 14:55+0000\n" +"POT-Creation-Date: 2018-10-01 10:21+0000\n" +"PO-Revision-Date: 2018-10-01 10:21+0000\n" "Last-Translator: <>\n" "Language-Team: \n" "MIME-Version: 1.0\n" @@ -25,17 +25,17 @@ msgstr "Un presupuesto es una proyección de los ingresos y/o gastos esperados e msgid "Active" msgstr "Activo" +#. module: project_budget +#: model:ir.model.fields,field_description:project_budget.field_crossovered_budget_lines_sum_amount +msgid "Amount Sum" +msgstr "Suma" + #. module: project_budget #: model:ir.model,name:project_budget.model_account_analytic_account #: model:ir.ui.view,arch_db:project_budget.crossovered_budget_line_search_view msgid "Analytic Account" msgstr "Cuenta analítica" -#. module: project_budget -#: model:ir.model,name:project_budget.model_account_analytic_line -msgid "Analytic Line" -msgstr "Línea Analítica" - #. module: project_budget #: model:ir.model,name:project_budget.model_crossovered_budget #: model:ir.ui.view,arch_db:project_budget.crossovered_budget_line_search_view @@ -47,6 +47,11 @@ msgstr "Presupuesto" msgid "Budget Line" msgstr "Línea de presupuesto" +#. module: project_budget +#: model:ir.ui.view,arch_db:project_budget.crossovered_budget_line_pivot_view +msgid "Budget Lines" +msgstr "Líneas de Presupuesto" + #. module: project_budget #: model:ir.ui.view,arch_db:project_budget.crossovered_budget_line_search_view msgid "Budgetary Position" @@ -105,6 +110,7 @@ msgstr "Presupuestos iniciales" #. module: project_budget #: model:ir.model.fields,field_description:project_budget.field_crossovered_budget_lines_initial_planned_amount #: model:ir.ui.view,arch_db:project_budget.crossovered_budget_form_view +#: model:ir.ui.view,arch_db:project_budget.crossovered_budget_line_tree_view msgid "Initial Planned Amount" msgstr "Importe planificado inicial" @@ -119,11 +125,6 @@ msgstr "Importe planificado inicial" msgid "Initial {} budget: {}" msgstr "Presupuesto inicial {}: {}" -#. module: project_budget -#: model:ir.model.fields,field_description:project_budget.field_account_analytic_line_invoice_id -msgid "Invoice" -msgstr "Factura" - #. module: project_budget #: model:ir.model.fields,field_description:project_budget.field_crossovered_budget_lines_notes #: model:ir.ui.view,arch_db:project_budget.crossovered_budget_line_form_view @@ -139,7 +140,6 @@ msgid "Project" msgstr "Proyecto" #. module: project_budget -#: code:addons/project_budget/models/crossovered_budget.py:79 #: code:addons/project_budget/models/crossovered_budget.py:83 #, python-format msgid "There can only be one initial budget per project and year." diff --git a/project_budget/models/crossovered_budget.py b/project_budget/models/crossovered_budget.py index 055cfed4..873fd742 100644 --- a/project_budget/models/crossovered_budget.py +++ b/project_budget/models/crossovered_budget.py @@ -97,3 +97,11 @@ class CrossoveredBudgetLines(models.Model): project_id = fields.Many2one( comodel_name='project.project', string='Project', related='crossovered_budget_id.project_id', store=True) + sum_amount = fields.Float( + string='Amount Sum', compute='_compute_sum_amount') + + @api.depends('planned_amount', 'practical_amount') + def _compute_sum_amount(self): + for record in self: + record.sum_amount = ( + record.planned_amount + record.practical_amount) diff --git a/project_budget/tests/test_project_budget.py b/project_budget/tests/test_project_budget.py index 5c539341..e0f24ae4 100644 --- a/project_budget/tests/test_project_budget.py +++ b/project_budget/tests/test_project_budget.py @@ -58,6 +58,10 @@ def test_initial_budget_duplication(self): self.assertEquals( old_budget.crossovered_budget_line[:1].planned_amount, old_budget.crossovered_budget_line[:1].initial_planned_amount) + self.assertEquals( + old_budget.crossovered_budget_line[:1].sum_amount, + old_budget.crossovered_budget_line[:1].planned_amount + + old_budget.crossovered_budget_line[:1].practical_amount) new_budget = old_budget.copy() self.assertEquals( len(old_budget.crossovered_budget_line), @@ -80,3 +84,10 @@ def test_initial_budget_duplication(self): self.assertNotEquals( new_budget.crossovered_budget_line[:1].planned_amount, new_budget.crossovered_budget_line[:1].initial_planned_amount) + self.assertEquals( + new_budget.crossovered_budget_line[:1].sum_amount, + new_budget.crossovered_budget_line[:1].planned_amount + + new_budget.crossovered_budget_line[:1].practical_amount) + self.assertNotEquals( + old_budget.crossovered_budget_line[:1].sum_amount, + new_budget.crossovered_budget_line[:1].sum_amount) diff --git a/project_budget/views/crossovered_budget_line_view.xml b/project_budget/views/crossovered_budget_line_view.xml index d4df8ca2..f124f7cb 100644 --- a/project_budget/views/crossovered_budget_line_view.xml +++ b/project_budget/views/crossovered_budget_line_view.xml @@ -1,5 +1,9 @@ + + tree,form,pivot + + + + + @@ -64,6 +71,9 @@ True + + + @@ -93,4 +103,18 @@ + + + crossovered.budget.lines + + + + + + + + + + + From 61fafb93f037a92e6a4a70f354d0d912c900d503 Mon Sep 17 00:00:00 2001 From: oihane Date: Mon, 8 Oct 2018 22:27:21 +0200 Subject: [PATCH 04/24] [IMP] project_budget: inactivate a copied budget, translations... (#47) * [IMP] project_budget: inactivate a copied budget, translations... * [IMP] project_budget: current month budget --- project_budget/__manifest__.py | 2 +- project_budget/i18n/es.po | 21 +++++++++---- project_budget/i18n_extra/es.po | 30 +++++++++++++++++++ .../migrations/11.0.3.0.0/pre-migration.py | 23 ++++++++++++++ project_budget/models/crossovered_budget.py | 11 +++++++ project_budget/models/project_project.py | 17 ++++++++++- .../views/crossovered_budget_line_view.xml | 5 ---- .../views/crossovered_budget_view.xml | 25 +++++++++++++++- project_budget/views/project_project_view.xml | 10 +++++++ 9 files changed, 131 insertions(+), 13 deletions(-) create mode 100644 project_budget/i18n_extra/es.po create mode 100644 project_budget/migrations/11.0.3.0.0/pre-migration.py diff --git a/project_budget/__manifest__.py b/project_budget/__manifest__.py index 265161f5..1e2828dd 100644 --- a/project_budget/__manifest__.py +++ b/project_budget/__manifest__.py @@ -3,7 +3,7 @@ { "name": "Project Bugdet", - "version": "11.0.2.0.1", + "version": "11.0.3.0.0", "category": "Custom Module", "license": "AGPL-3", "author": "AvanzOSC", diff --git a/project_budget/i18n/es.po b/project_budget/i18n/es.po index 4c6cad15..d5b08ef2 100644 --- a/project_budget/i18n/es.po +++ b/project_budget/i18n/es.po @@ -6,8 +6,8 @@ msgid "" msgstr "" "Project-Id-Version: Odoo Server 11.0\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2018-10-01 10:21+0000\n" -"PO-Revision-Date: 2018-10-01 10:21+0000\n" +"POT-Creation-Date: 2018-10-05 11:00+0000\n" +"PO-Revision-Date: 2018-10-05 11:00+0000\n" "Last-Translator: <>\n" "Language-Team: \n" "MIME-Version: 1.0\n" @@ -22,13 +22,14 @@ msgstr "Un presupuesto es una proyección de los ingresos y/o gastos esperados e #. module: project_budget #: model:ir.model.fields,field_description:project_budget.field_crossovered_budget_active +#: model:ir.ui.view,arch_db:project_budget.crossovered_budget_search_view msgid "Active" msgstr "Activo" #. module: project_budget #: model:ir.model.fields,field_description:project_budget.field_crossovered_budget_lines_sum_amount msgid "Amount Sum" -msgstr "Suma" +msgstr "Previsión final" #. module: project_budget #: model:ir.model,name:project_budget.model_account_analytic_account @@ -36,12 +37,22 @@ msgstr "Suma" msgid "Analytic Account" msgstr "Cuenta analítica" +#. module: project_budget +#: model:ir.ui.view,arch_db:project_budget.crossovered_budget_search_view +msgid "Archived" +msgstr "Archivado" + #. module: project_budget #: model:ir.model,name:project_budget.model_crossovered_budget #: model:ir.ui.view,arch_db:project_budget.crossovered_budget_line_search_view msgid "Budget" msgstr "Presupuesto" +#. module: project_budget +#: model:ir.model.fields,field_description:project_budget.field_crossovered_budget_budget_date +msgid "Budget Date" +msgstr "Fecha del presupuesto" + #. module: project_budget #: model:ir.model,name:project_budget.model_crossovered_budget_lines msgid "Budget Line" @@ -61,7 +72,6 @@ msgstr "Posición Presupuestaria" #: model:ir.actions.act_window,name:project_budget.project_budget_action #: model:ir.model.fields,field_description:project_budget.field_project_project_budget_count #: model:ir.model.fields,field_description:project_budget.field_project_project_budget_ids -#: model:ir.ui.menu,name:project_budget.menu_act2_crossovered_budget_lines_view #: model:ir.ui.view,arch_db:project_budget.project_project_form_view msgid "Budgets" msgstr "Presupuestos" @@ -112,7 +122,7 @@ msgstr "Presupuestos iniciales" #: model:ir.ui.view,arch_db:project_budget.crossovered_budget_form_view #: model:ir.ui.view,arch_db:project_budget.crossovered_budget_line_tree_view msgid "Initial Planned Amount" -msgstr "Importe planificado inicial" +msgstr "Presupuesto inicial" #. module: project_budget #: model:ir.ui.view,arch_db:project_budget.account_analytic_account_last_budget_lines_form_view @@ -141,6 +151,7 @@ msgstr "Proyecto" #. module: project_budget #: code:addons/project_budget/models/crossovered_budget.py:83 +#: code:addons/project_budget/models/crossovered_budget.py:85 #, python-format msgid "There can only be one initial budget per project and year." msgstr "Sólo puede haber un presupuesto inicial por proyecto y año." diff --git a/project_budget/i18n_extra/es.po b/project_budget/i18n_extra/es.po new file mode 100644 index 00000000..da803de0 --- /dev/null +++ b/project_budget/i18n_extra/es.po @@ -0,0 +1,30 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * account_budget +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 11.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2018-10-01 10:21+0000\n" +"PO-Revision-Date: 2018-10-01 10:21+0000\n" +"Last-Translator: <>\n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: \n" + +#. module: account_budget +#: model:ir.model.fields,field_description:account_budget.field_crossovered_budget_lines_planned_amount +#: model:ir.ui.view,arch_db:account_budget.crossovered_budget_view_form +msgid "Planned Amount" +msgstr "Previsión" + +#. module: account_budget +#: model:ir.model.fields,field_description:account_budget.field_crossovered_budget_lines_practical_amount +#: model:ir.ui.view,arch_db:account_budget.crossovered_budget_view_form +#: model:ir.ui.view,arch_db:account_budget.view_account_analytic_account_form_inherit_budget +msgid "Practical Amount" +msgstr "Contabilizado" + diff --git a/project_budget/migrations/11.0.3.0.0/pre-migration.py b/project_budget/migrations/11.0.3.0.0/pre-migration.py new file mode 100644 index 00000000..87d508de --- /dev/null +++ b/project_budget/migrations/11.0.3.0.0/pre-migration.py @@ -0,0 +1,23 @@ +# Copyright 2018 Oihane Crucelaegui - AvanzOSC +# License AGPL-3 - See http://www.gnu.org/licenses/agpl-3.0.html + + +def update_budget_date(cr): + cr.execute(""" + ALTER TABLE + crossovered_budget + ADD COLUMN + budget_date date; + """) + cr.execute(""" + UPDATE + crossovered_budget + SET + budget_date = create_date; + """) + + +def migrate(cr, version): + if not version: + return + update_budget_date(cr) diff --git a/project_budget/models/crossovered_budget.py b/project_budget/models/crossovered_budget.py index 873fd742..ace4f45a 100644 --- a/project_budget/models/crossovered_budget.py +++ b/project_budget/models/crossovered_budget.py @@ -18,6 +18,8 @@ class CrossoveredBudget(models.Model): string='Initial', copy=False, states={'done': [('readonly', True)]}) active = fields.Boolean(string='Active', default=True) year = fields.Integer(string='Year', compute='_compute_year', store=True) + budget_date = fields.Date( + string='Budget Date', default=lambda s: fields.Date.context_today(s)) @api.depends('date_from') def _compute_year(self): @@ -83,6 +85,15 @@ def _check_initial_by_project(self): _("There can only be one initial budget per project and " "year.")) + @api.multi + @api.returns('self', lambda value: value.id) + def copy(self, default=None): + new = super(CrossoveredBudget, self).copy(default=default) + self.filtered(lambda b: not b.initial).write({ + 'active': False, + }) + return new + class CrossoveredBudgetLines(models.Model): _inherit = "crossovered.budget.lines" diff --git a/project_budget/models/project_project.py b/project_budget/models/project_project.py index 2f41866d..ce9d2e21 100644 --- a/project_budget/models/project_project.py +++ b/project_budget/models/project_project.py @@ -2,6 +2,7 @@ # License AGPL-3 - See http://www.gnu.org/licenses/agpl-3.0.html from odoo import _, api, fields, models +import calendar to_string = fields.Date.to_string from_string = fields.Date.from_string @@ -15,11 +16,25 @@ class ProjectProject(models.Model): string='Budgets') budget_count = fields.Integer( string='Budgets', compute='_compute_budget_count') + current_budget_id = fields.Many2one( + comodel_name='crossovered.budget', compute='_compute_budget_count') + current_budget_count = fields.Integer( + string='Budgets', compute='_compute_budget_count') @api.multi def _compute_budget_count(self): + today = from_string(fields.Date.context_today(self)) + month_start = to_string(today.replace(day=1)) + month_end = \ + to_string(today.replace( + day=calendar.monthrange(today.year, today.month)[1])) for record in self: - record.budget_count = len(record.budget_ids) + record.budget_count = len( + record.with_context(active_test=False).budget_ids) + record.current_budget_id = record.budget_ids.filtered( + lambda b: b.budget_date >= month_start and + b.budget_date <= month_end) + record.current_budget_count = len(record.current_budget_id) @api.multi def create_initial_project_budget(self): diff --git a/project_budget/views/crossovered_budget_line_view.xml b/project_budget/views/crossovered_budget_line_view.xml index f124f7cb..8e218080 100644 --- a/project_budget/views/crossovered_budget_line_view.xml +++ b/project_budget/views/crossovered_budget_line_view.xml @@ -4,11 +4,6 @@ tree,form,pivot - - crossovered.budget.line.form crossovered.budget.lines diff --git a/project_budget/views/crossovered_budget_view.xml b/project_budget/views/crossovered_budget_view.xml index bc401f72..c9eac3fa 100644 --- a/project_budget/views/crossovered_budget_view.xml +++ b/project_budget/views/crossovered_budget_view.xml @@ -1,5 +1,9 @@ + + {'active_test': False} + + crossovered.budget.form crossovered.budget @@ -11,11 +15,20 @@ type="object" attrs="{'invisible': ['|','|',('state','not in',['draft']),('project_id','=',False),'!',('crossovered_budget_line','=',[])]}" /> +
+
+ +
+
+ + + - initial + active == False +
@@ -60,6 +75,14 @@ + + + diff --git a/project_budget/views/project_project_view.xml b/project_budget/views/project_project_view.xml index 6bbf29d8..f426419b 100644 --- a/project_budget/views/project_project_view.xml +++ b/project_budget/views/project_project_view.xml @@ -7,6 +7,7 @@ { 'search_default_project_id': [active_id], 'default_project_id': active_id, + 'active_test': False, } @@ -30,12 +31,21 @@ project.project + + + +
From 3be0cd534dc3a0d47d47d61498fdf1b3664a19e6 Mon Sep 17 00:00:00 2001 From: oihane Date: Wed, 17 Oct 2018 10:13:55 +0200 Subject: [PATCH 05/24] [IMP] project_budget: added more usability (#49) * [IMP] project_budget: added more usability * [IMP] project_budget: increase tests --- project_budget/__manifest__.py | 2 +- project_budget/i18n/es.po | 44 +++++++++++++++++-- project_budget/models/crossovered_budget.py | 20 +++++++++ project_budget/models/project_project.py | 26 +++++++++-- project_budget/tests/test_project_budget.py | 10 ++++- .../views/crossovered_budget_view.xml | 3 ++ project_budget/views/project_project_view.xml | 12 +++++ 7 files changed, 108 insertions(+), 9 deletions(-) diff --git a/project_budget/__manifest__.py b/project_budget/__manifest__.py index 1e2828dd..c97fdd5b 100644 --- a/project_budget/__manifest__.py +++ b/project_budget/__manifest__.py @@ -3,7 +3,7 @@ { "name": "Project Bugdet", - "version": "11.0.3.0.0", + "version": "11.0.3.1.0", "category": "Custom Module", "license": "AGPL-3", "author": "AvanzOSC", diff --git a/project_budget/i18n/es.po b/project_budget/i18n/es.po index d5b08ef2..7cd6fe36 100644 --- a/project_budget/i18n/es.po +++ b/project_budget/i18n/es.po @@ -6,8 +6,8 @@ msgid "" msgstr "" "Project-Id-Version: Odoo Server 11.0\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2018-10-05 11:00+0000\n" -"PO-Revision-Date: 2018-10-05 11:00+0000\n" +"POT-Creation-Date: 2018-10-16 22:02+0000\n" +"PO-Revision-Date: 2018-10-16 22:02+0000\n" "Last-Translator: <>\n" "Language-Team: \n" "MIME-Version: 1.0\n" @@ -15,6 +15,16 @@ msgstr "" "Content-Transfer-Encoding: \n" "Plural-Forms: \n" +#. module: project_budget +#: model:ir.model.fields,field_description:project_budget.field_project_project_budget_count +msgid "# Budgets" +msgstr "Presupuestos" + +#. module: project_budget +#: model:ir.model.fields,field_description:project_budget.field_project_project_current_budget_count +msgid "# Current Budgets" +msgstr "Presupuesto actual" + #. module: project_budget #: model:ir.actions.act_window,help:project_budget.project_budget_action msgid "A budget is a forecast of your company's income and/or expenses expected for a period in the future. A budget is defined on some financial accounts and/or analytic accounts (that may represent projects, departments, categories of products, etc.)" @@ -48,8 +58,14 @@ msgstr "Archivado" msgid "Budget" msgstr "Presupuesto" +#. module: project_budget +#: model:ir.model.fields,field_description:project_budget.field_crossovered_budget_lines_budget_active +msgid "Budget Active" +msgstr "Presupuesto activado" + #. module: project_budget #: model:ir.model.fields,field_description:project_budget.field_crossovered_budget_budget_date +#: model:ir.model.fields,field_description:project_budget.field_crossovered_budget_lines_budget_date msgid "Budget Date" msgstr "Fecha del presupuesto" @@ -63,6 +79,11 @@ msgstr "Línea de presupuesto" msgid "Budget Lines" msgstr "Líneas de Presupuesto" +#. module: project_budget +#: model:ir.ui.view,arch_db:project_budget.crossovered_budget_form_view +msgid "Budget Lines Pivot Report" +msgstr "Informe pivot" + #. module: project_budget #: model:ir.ui.view,arch_db:project_budget.crossovered_budget_line_search_view msgid "Budgetary Position" @@ -70,7 +91,6 @@ msgstr "Posición Presupuestaria" #. module: project_budget #: model:ir.actions.act_window,name:project_budget.project_budget_action -#: model:ir.model.fields,field_description:project_budget.field_project_project_budget_count #: model:ir.model.fields,field_description:project_budget.field_project_project_budget_ids #: model:ir.ui.view,arch_db:project_budget.project_project_form_view msgid "Budgets" @@ -96,11 +116,23 @@ msgstr "Crear presupuesto inicial" msgid "Create Lines" msgstr "Crear elementos" +#. module: project_budget +#: model:ir.model.fields,field_description:project_budget.field_project_project_current_budget_id +#: model:ir.ui.view,arch_db:project_budget.crossovered_budget_search_view +#: model:ir.ui.view,arch_db:project_budget.project_project_form_view +msgid "Current Budget" +msgstr "Presupuesto actual" + #. module: project_budget #: model:ir.ui.view,arch_db:project_budget.crossovered_budget_line_search_view msgid "Group By" msgstr "Agrupar por" +#. module: project_budget +#: model:ir.model.fields,field_description:project_budget.field_project_project_has_current_budget +msgid "Has Current Budget" +msgstr "Tiene presupuesto actual" + #. module: project_budget #: model:ir.model.fields,field_description:project_budget.field_crossovered_budget_initial #: model:ir.ui.view,arch_db:project_budget.crossovered_budget_search_view @@ -131,6 +163,7 @@ msgstr "Importe planificado inicial" #. module: project_budget #: code:addons/project_budget/models/project_project.py:33 +#: code:addons/project_budget/models/project_project.py:67 #, python-format msgid "Initial {} budget: {}" msgstr "Presupuesto inicial {}: {}" @@ -156,6 +189,11 @@ msgstr "Proyecto" msgid "There can only be one initial budget per project and year." msgstr "Sólo puede haber un presupuesto inicial por proyecto y año." +#. module: project_budget +#: model:ir.ui.view,arch_db:project_budget.project_project_search_view +msgid "Unbudgeted" +msgstr "Sin presupuestar" + #. module: project_budget #: model:ir.model.fields,field_description:project_budget.field_crossovered_budget_year msgid "Year" diff --git a/project_budget/models/crossovered_budget.py b/project_budget/models/crossovered_budget.py index ace4f45a..73ac473c 100644 --- a/project_budget/models/crossovered_budget.py +++ b/project_budget/models/crossovered_budget.py @@ -94,6 +94,20 @@ def copy(self, default=None): }) return new + @api.multi + def open_pivot_view(self): + self.ensure_one() + action = self.env.ref( + 'account_budget.act_crossovered_budget_lines_view') + action_dict = action.read()[0] + action_dict.update({ + 'view_mode': 'pivot', + 'view_id': False, + 'views': [], + 'domain': [('crossovered_budget_id', '=', self.id)], + }) + return action_dict + class CrossoveredBudgetLines(models.Model): _inherit = "crossovered.budget.lines" @@ -110,6 +124,12 @@ class CrossoveredBudgetLines(models.Model): related='crossovered_budget_id.project_id', store=True) sum_amount = fields.Float( string='Amount Sum', compute='_compute_sum_amount') + budget_active = fields.Boolean( + string='Budget Active', + related='crossovered_budget_id.active', store=True) + budget_date = fields.Date( + string='Budget Date', + related='crossovered_budget_id.budget_date', store=True) @api.depends('planned_amount', 'practical_amount') def _compute_sum_amount(self): diff --git a/project_budget/models/project_project.py b/project_budget/models/project_project.py index ce9d2e21..b6477515 100644 --- a/project_budget/models/project_project.py +++ b/project_budget/models/project_project.py @@ -15,11 +15,15 @@ class ProjectProject(models.Model): comodel_name='crossovered.budget', inverse_name='project_id', string='Budgets') budget_count = fields.Integer( - string='Budgets', compute='_compute_budget_count') + string='# Budgets', compute='_compute_budget_count') current_budget_id = fields.Many2one( - comodel_name='crossovered.budget', compute='_compute_budget_count') + string='Current Budget', comodel_name='crossovered.budget', + compute='_compute_budget_count') current_budget_count = fields.Integer( - string='Budgets', compute='_compute_budget_count') + string='# Current Budgets', compute='_compute_budget_count') + has_current_budget = fields.Boolean( + string='Has Current Budget', compute='_compute_budget_count', + search='_search_current_budget') @api.multi def _compute_budget_count(self): @@ -35,6 +39,22 @@ def _compute_budget_count(self): lambda b: b.budget_date >= month_start and b.budget_date <= month_end) record.current_budget_count = len(record.current_budget_id) + record.has_current_budget = bool(record.current_budget_id) + + @api.multi + def _search_current_budget(self, operator, value): + today = from_string(fields.Date.context_today(self)) + month_start = to_string(today.replace(day=1)) + month_end = \ + to_string(today.replace( + day=calendar.monthrange(today.year, today.month)[1])) + current_budgets = self.env['crossovered.budget'].search([ + ('project_id', '<>', False), + ('budget_date', '>=', month_start), + ('budget_date', '<=', month_end)]) + operator = 'in' if ((operator == '=' and value) or + (operator == '!=' and not value)) else 'not in' + return [('id', operator, current_budgets.mapped('project_id').ids)] @api.multi def create_initial_project_budget(self): diff --git a/project_budget/tests/test_project_budget.py b/project_budget/tests/test_project_budget.py index e0f24ae4..9a36115a 100644 --- a/project_budget/tests/test_project_budget.py +++ b/project_budget/tests/test_project_budget.py @@ -13,8 +13,8 @@ class TestProjectBudget(common.SavepointCase): @classmethod def setUpClass(cls): super(TestProjectBudget, cls).setUpClass() - project_model = cls.env['project.project'] - cls.project = project_model.create({ + cls.project_model = cls.env['project.project'] + cls.project = cls.project_model.create({ 'name': 'New Project' }) @@ -23,10 +23,16 @@ def test_project_creation(self): self.assertTrue(self.project.budget_ids[:1].initial) self.assertEquals( len(self.project.budget_ids), self.project.budget_count) + self.assertTrue(self.project.has_current_budget) + self.assertEquals( + self.project, + self.project.search([('has_current_budget', '=', True)])) self.assertEquals(len( self.project.mapped('budget_ids.crossovered_budget_line')), 26) self.project.create_initial_project_budget() self.assertEquals(len(self.project.budget_ids), 1) + action_dict = self.project.budget_ids[:1].open_pivot_view() + self.assertEquals(action_dict.get('view_mode'), 'pivot') def test_initial_budget_per_project_year(self): new_budget = self.project.budget_ids.copy() diff --git a/project_budget/views/crossovered_budget_view.xml b/project_budget/views/crossovered_budget_view.xml index c9eac3fa..b3aa1f84 100644 --- a/project_budget/views/crossovered_budget_view.xml +++ b/project_budget/views/crossovered_budget_view.xml @@ -20,6 +20,9 @@ + diff --git a/project_budget/views/project_project_view.xml b/project_budget/views/project_project_view.xml index f426419b..028f2b8c 100644 --- a/project_budget/views/project_project_view.xml +++ b/project_budget/views/project_project_view.xml @@ -50,6 +50,18 @@ + + project.project + + + + + + + + + Create Initial Budget From 9821cfb9cd15861fc0f7a4e45e48720f2e0616ca Mon Sep 17 00:00:00 2001 From: oihane Date: Tue, 30 Oct 2018 08:52:33 +0100 Subject: [PATCH 06/24] [IMP] project_budget: add new fields in views (#67) --- project_budget/__manifest__.py | 2 +- project_budget/views/crossovered_budget_line_view.xml | 2 +- project_budget/views/crossovered_budget_view.xml | 10 ++++++++++ project_budget/views/project_project_view.xml | 2 ++ 4 files changed, 14 insertions(+), 2 deletions(-) diff --git a/project_budget/__manifest__.py b/project_budget/__manifest__.py index c97fdd5b..2e990360 100644 --- a/project_budget/__manifest__.py +++ b/project_budget/__manifest__.py @@ -3,7 +3,7 @@ { "name": "Project Bugdet", - "version": "11.0.3.1.0", + "version": "11.0.3.2.0", "category": "Custom Module", "license": "AGPL-3", "author": "AvanzOSC", diff --git a/project_budget/views/crossovered_budget_line_view.xml b/project_budget/views/crossovered_budget_line_view.xml index 8e218080..fb01aa2d 100644 --- a/project_budget/views/crossovered_budget_line_view.xml +++ b/project_budget/views/crossovered_budget_line_view.xml @@ -105,8 +105,8 @@ - + diff --git a/project_budget/views/crossovered_budget_view.xml b/project_budget/views/crossovered_budget_view.xml index b3aa1f84..344c4c19 100644 --- a/project_budget/views/crossovered_budget_view.xml +++ b/project_budget/views/crossovered_budget_view.xml @@ -3,6 +3,9 @@ {'active_test': False} + + [('budget_active','=',True)] + crossovered.budget.form @@ -37,6 +40,10 @@ + + + True @@ -46,6 +53,9 @@ True + + + diff --git a/project_budget/views/project_project_view.xml b/project_budget/views/project_project_view.xml index 028f2b8c..8f6edd28 100644 --- a/project_budget/views/project_project_view.xml +++ b/project_budget/views/project_project_view.xml @@ -58,6 +58,8 @@ + From c41c64fd4e9e5bf9e17dace0984109ba663920e8 Mon Sep 17 00:00:00 2001 From: oihane Date: Wed, 7 Nov 2018 13:23:02 +0100 Subject: [PATCH 07/24] [IMP] project_budget: translations (#79) --- project_budget/i18n/es.po | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/project_budget/i18n/es.po b/project_budget/i18n/es.po index 7cd6fe36..366ffdf1 100644 --- a/project_budget/i18n/es.po +++ b/project_budget/i18n/es.po @@ -6,8 +6,8 @@ msgid "" msgstr "" "Project-Id-Version: Odoo Server 11.0\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2018-10-16 22:02+0000\n" -"PO-Revision-Date: 2018-10-16 22:02+0000\n" +"POT-Creation-Date: 2018-11-07 09:52+0000\n" +"PO-Revision-Date: 2018-11-07 09:52+0000\n" "Last-Translator: <>\n" "Language-Team: \n" "MIME-Version: 1.0\n" @@ -89,6 +89,11 @@ msgstr "Informe pivot" msgid "Budgetary Position" msgstr "Posición Presupuestaria" +#. module: project_budget +#: model:ir.ui.view,arch_db:project_budget.project_project_search_view +msgid "Budgeted" +msgstr "Presupuestado" + #. module: project_budget #: model:ir.actions.act_window,name:project_budget.project_budget_action #: model:ir.model.fields,field_description:project_budget.field_project_project_budget_ids @@ -162,8 +167,7 @@ msgid "Initial planned amount" msgstr "Importe planificado inicial" #. module: project_budget -#: code:addons/project_budget/models/project_project.py:33 -#: code:addons/project_budget/models/project_project.py:67 +#: code:addons/project_budget/models/project_project.py:68 #, python-format msgid "Initial {} budget: {}" msgstr "Presupuesto inicial {}: {}" @@ -183,7 +187,11 @@ msgid "Project" msgstr "Proyecto" #. module: project_budget -#: code:addons/project_budget/models/crossovered_budget.py:83 +#: model:ir.ui.view,arch_db:project_budget.crossovered_budget_form_view +msgid "Sum Amount Total" +msgstr "Total previsión final" + +#. module: project_budget #: code:addons/project_budget/models/crossovered_budget.py:85 #, python-format msgid "There can only be one initial budget per project and year." From 3e2a0547fe2e22e7d67962791fc4be2133634675 Mon Sep 17 00:00:00 2001 From: oihane Date: Fri, 9 Nov 2018 15:05:40 +0100 Subject: [PATCH 08/24] [IMP] project_budget: add budget date to tree view (#80) --- project_budget/__manifest__.py | 2 +- project_budget/views/crossovered_budget_line_view.xml | 1 + project_budget/views/crossovered_budget_view.xml | 6 +++--- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/project_budget/__manifest__.py b/project_budget/__manifest__.py index 2e990360..f9e5b4e0 100644 --- a/project_budget/__manifest__.py +++ b/project_budget/__manifest__.py @@ -3,7 +3,7 @@ { "name": "Project Bugdet", - "version": "11.0.3.2.0", + "version": "11.0.3.3.0", "category": "Custom Module", "license": "AGPL-3", "author": "AvanzOSC", diff --git a/project_budget/views/crossovered_budget_line_view.xml b/project_budget/views/crossovered_budget_line_view.xml index fb01aa2d..801116b0 100644 --- a/project_budget/views/crossovered_budget_line_view.xml +++ b/project_budget/views/crossovered_budget_line_view.xml @@ -2,6 +2,7 @@ tree,form,pivot + [('budget_active','=',True)] diff --git a/project_budget/views/crossovered_budget_view.xml b/project_budget/views/crossovered_budget_view.xml index 344c4c19..272173c6 100644 --- a/project_budget/views/crossovered_budget_view.xml +++ b/project_budget/views/crossovered_budget_view.xml @@ -3,9 +3,6 @@ {'active_test': False} - - [('budget_active','=',True)] - crossovered.budget.form @@ -69,6 +66,9 @@ initial active == False + + + From 117de41d57691d6d1d9c1a03ee13be6a47afb647 Mon Sep 17 00:00:00 2001 From: Oihane Crucelaegui Date: Fri, 16 Nov 2018 10:35:12 +0100 Subject: [PATCH 09/24] [IMP] project_budget: dependency with account_budget_template --- project_budget/__manifest__.py | 3 +- project_budget/data/project_budget_data.xml | 7 ++ project_budget/models/crossovered_budget.py | 72 ++++++++++----------- project_budget/models/project_project.py | 2 +- project_budget/tests/test_project_budget.py | 26 ++++---- 5 files changed, 57 insertions(+), 53 deletions(-) diff --git a/project_budget/__manifest__.py b/project_budget/__manifest__.py index f9e5b4e0..79ab7fe4 100644 --- a/project_budget/__manifest__.py +++ b/project_budget/__manifest__.py @@ -3,7 +3,7 @@ { "name": "Project Bugdet", - "version": "11.0.3.3.0", + "version": "11.0.3.4.0", "category": "Custom Module", "license": "AGPL-3", "author": "AvanzOSC", @@ -14,6 +14,7 @@ ], "depends": [ "account_budget", + "account_budget_template", "project", ], "data": [ diff --git a/project_budget/data/project_budget_data.xml b/project_budget/data/project_budget_data.xml index bb1b9cbc..fb382fc7 100644 --- a/project_budget/data/project_budget_data.xml +++ b/project_budget/data/project_budget_data.xml @@ -25,4 +25,11 @@ + + + Income / Outcome monthly + + monthly + diff --git a/project_budget/models/crossovered_budget.py b/project_budget/models/crossovered_budget.py index 73ac473c..3c0007d3 100644 --- a/project_budget/models/crossovered_budget.py +++ b/project_budget/models/crossovered_budget.py @@ -2,7 +2,6 @@ # License AGPL-3 - See http://www.gnu.org/licenses/agpl-3.0.html from odoo import _, api, exceptions, fields, models -from dateutil.relativedelta import relativedelta to_string = fields.Date.to_string from_string = fields.Date.from_string @@ -28,12 +27,15 @@ def _compute_year(self): @api.multi def action_create_period(self): + super(CrossoveredBudget, self).action_create_period() budget_line_obj = self.env['crossovered.budget.lines'] - postcome = self.env.ref('project_budget.budget_post_postcome') - income = self.env.ref('project_budget.budget_post_income') - for budget in self.filtered(lambda b: b.project_id and not - b.crossovered_budget_line and + for budget in self.filtered(lambda b: b.project_id and b.state == 'draft'): + budget.crossovered_budget_line.write({ + 'analytic_account_id': + budget.project_id.analytic_account_id.id, + }) + budget_posts = budget.budget_tmpl_id.budget_post_ids vals = { 'analytic_account_id': budget.project_id.analytic_account_id.id, @@ -42,36 +44,14 @@ def action_create_period(self): } ds = from_string(budget.date_from) final_date = ds.replace(day=30, month=12) - while to_string(ds) < budget.date_to: - de = ds + relativedelta(months=1, days=-1) - if to_string(de) > budget.date_to: - de = from_string(budget.date_to) - vals.update({ - 'date_from': to_string(ds), - 'date_to': to_string(de), - 'general_budget_id': postcome.id, - }) - line = budget_line_obj.create(vals) - line.initial_budget_line_id = line.id - vals.update({ - 'general_budget_id': income.id, - }) - line = budget_line_obj.create(vals) - line.initial_budget_line_id = line.id - ds = ds + relativedelta(months=1) if to_string(final_date) < budget.date_to: - vals.update({ - 'date_from': to_string(final_date), - 'date_to': to_string(final_date), - 'general_budget_id': postcome.id, - }) - line = budget_line_obj.create(vals) - line.initial_budget_line_id = line.id - vals.update({ - 'general_budget_id': income.id, - }) - line = budget_line_obj.create(vals) - line.initial_budget_line_id = line.id + for budget_post in budget_posts: + vals.update({ + 'date_from': to_string(final_date), + 'date_to': to_string(final_date), + 'general_budget_id': budget_post.id, + }) + budget_line_obj.create(vals) return True @api.multi @@ -113,11 +93,10 @@ class CrossoveredBudgetLines(models.Model): _inherit = "crossovered.budget.lines" initial_budget_line_id = fields.Many2one( - comodel_name='crossovered.budget.lines', string='Initial Budget Line', - copy=True) + comodel_name='crossovered.budget.lines', string='Initial Budget Line') initial_planned_amount = fields.Float( string='Initial Planned Amount', digits=0, store=True, - related='initial_budget_line_id.planned_amount') + compute='_compute_initial_planned_amount') notes = fields.Text(string='Notes') project_id = fields.Many2one( comodel_name='project.project', string='Project', @@ -131,6 +110,25 @@ class CrossoveredBudgetLines(models.Model): string='Budget Date', related='crossovered_budget_id.budget_date', store=True) + @api.depends('initial_budget_line_id', 'planned_amount', + 'initial_budget_line_id.planned_amount') + def _compute_initial_planned_amount(self): + for line in self: + line.initial_planned_amount = ( + line.initial_budget_line_id.planned_amount + if line.initial_budget_line_id else line.planned_amount) + + @api.multi + @api.returns(None, lambda value: value[0]) + def copy_data(self, default=None): + self.ensure_one() + default = default or {} + default.update({ + 'initial_budget_line_id': + self.initial_budget_line_id.id or self.id, + }) + return super(CrossoveredBudgetLines, self).copy_data(default=default) + @api.depends('planned_amount', 'practical_amount') def _compute_sum_amount(self): for record in self: diff --git a/project_budget/models/project_project.py b/project_budget/models/project_project.py index b6477515..f5583dce 100644 --- a/project_budget/models/project_project.py +++ b/project_budget/models/project_project.py @@ -73,7 +73,7 @@ def create_initial_project_budget(self): 'date_to': date_to, 'project_id': record.id, }) - budget.action_create_period() + budget.button_compute_lines() @api.model def create(self, values): diff --git a/project_budget/tests/test_project_budget.py b/project_budget/tests/test_project_budget.py index 9a36115a..61c29cdb 100644 --- a/project_budget/tests/test_project_budget.py +++ b/project_budget/tests/test_project_budget.py @@ -14,8 +14,11 @@ class TestProjectBudget(common.SavepointCase): def setUpClass(cls): super(TestProjectBudget, cls).setUpClass() cls.project_model = cls.env['project.project'] + cls.env['ir.config_parameter'].sudo().set_param( + 'account_budget_template.budget_template_id', + cls.env.ref('project_budget.project_budget_template').id) cls.project = cls.project_model.create({ - 'name': 'New Project' + 'name': 'New Project', }) def test_project_creation(self): @@ -40,30 +43,28 @@ def test_initial_budget_per_project_year(self): new_budget.initial = True def test_budget_line_creation(self): + self.assertEqual( + self.project.analytic_account_id.crossovered_budget_line, + self.project.budget_ids.crossovered_budget_line) new_budget = self.project.budget_ids.copy(default={ 'crossovered_budget_line': [], }) new_budget.date_to = from_string(fields.Date.today()).replace( month=12, day=29) - new_budget.action_create_period() + new_budget.button_compute_lines() self.assertEquals(len( new_budget.crossovered_budget_line), 24) + self.assertEqual( + self.project.analytic_account_id.crossovered_budget_line, + new_budget.crossovered_budget_line) def test_initial_budget_duplication(self): - analytic_account = self.project.analytic_account_id old_budget = self.project.budget_ids[:1] - self.assertEquals( - old_budget.crossovered_budget_line[:1], + self.assertFalse( old_budget.crossovered_budget_line[:1].initial_budget_line_id) - self.assertEquals( - old_budget.crossovered_budget_line, - analytic_account.crossovered_budget_line) old_budget.crossovered_budget_line[:1].write({ 'planned_amount': 50.0, }) - self.assertEquals( - old_budget.crossovered_budget_line[:1].planned_amount, - old_budget.crossovered_budget_line[:1].initial_planned_amount) self.assertEquals( old_budget.crossovered_budget_line[:1].sum_amount, old_budget.crossovered_budget_line[:1].planned_amount + @@ -72,9 +73,6 @@ def test_initial_budget_duplication(self): self.assertEquals( len(old_budget.crossovered_budget_line), len(new_budget.crossovered_budget_line)) - self.assertEquals( - new_budget.crossovered_budget_line, - analytic_account.crossovered_budget_line) new_budget.crossovered_budget_line[:1].write({ 'planned_amount': 150.0, }) From c9a248786c3c2a7cada88eec9de00a959310dafb Mon Sep 17 00:00:00 2001 From: oihane Date: Fri, 23 Nov 2018 09:19:52 +0100 Subject: [PATCH 10/24] [IMP] project_budget: usability improved (#90) --- project_budget/__manifest__.py | 6 ++-- project_budget/i18n/es.po | 34 ++++++++++++++++--- project_budget/models/__init__.py | 1 + project_budget/models/res_config_settings.py | 12 +++++++ .../security/project_budget_groups.xml | 7 ++++ project_budget/views/project_project_view.xml | 17 ++++++++-- .../views/res_config_settings_view.xml | 25 ++++++++++++++ 7 files changed, 93 insertions(+), 9 deletions(-) create mode 100644 project_budget/models/res_config_settings.py create mode 100644 project_budget/security/project_budget_groups.xml create mode 100644 project_budget/views/res_config_settings_view.xml diff --git a/project_budget/__manifest__.py b/project_budget/__manifest__.py index 79ab7fe4..bf9a3791 100644 --- a/project_budget/__manifest__.py +++ b/project_budget/__manifest__.py @@ -3,8 +3,8 @@ { "name": "Project Bugdet", - "version": "11.0.3.4.0", - "category": "Custom Module", + "version": "11.0.3.4.1", + "category": "Project", "license": "AGPL-3", "author": "AvanzOSC", "website": "http://www.avanzosc.es", @@ -18,11 +18,13 @@ "project", ], "data": [ + "security/project_budget_groups.xml", "data/project_budget_data.xml", "views/crossovered_budget_view.xml", "views/crossovered_budget_line_view.xml", "views/project_project_view.xml", "views/account_analytic_account_view.xml", + "views/res_config_settings_view.xml", ], "installable": True, } diff --git a/project_budget/i18n/es.po b/project_budget/i18n/es.po index 366ffdf1..1b11df3c 100644 --- a/project_budget/i18n/es.po +++ b/project_budget/i18n/es.po @@ -6,8 +6,8 @@ msgid "" msgstr "" "Project-Id-Version: Odoo Server 11.0\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2018-11-07 09:52+0000\n" -"PO-Revision-Date: 2018-11-07 09:52+0000\n" +"POT-Creation-Date: 2018-11-22 12:20+0000\n" +"PO-Revision-Date: 2018-11-22 12:20+0000\n" "Last-Translator: <>\n" "Language-Team: \n" "MIME-Version: 1.0\n" @@ -124,7 +124,7 @@ msgstr "Crear elementos" #. module: project_budget #: model:ir.model.fields,field_description:project_budget.field_project_project_current_budget_id #: model:ir.ui.view,arch_db:project_budget.crossovered_budget_search_view -#: model:ir.ui.view,arch_db:project_budget.project_project_form_view +#: model:ir.ui.view,arch_db:project_budget.project_project_form_view2 msgid "Current Budget" msgstr "Presupuesto actual" @@ -186,13 +186,34 @@ msgstr "Notas" msgid "Project" msgstr "Proyecto" +#. module: project_budget +#: model:ir.ui.view,arch_db:project_budget.project_config_settings_form_view +msgid "Project Budget" +msgstr "Presupuesto de proyecto" + +#. module: project_budget +#: model:ir.ui.view,arch_db:project_budget.project_config_settings_form_view +msgid "Show a smartbutton to access directly to current month budget." +msgstr "Mostrar un smartbutton para acceder directamente al presupuesto del mes en curso." + +#. module: project_budget +#: model:ir.model.fields,field_description:project_budget.field_res_config_settings_group_smartbutton_actual_budget +#: model:res.groups,name:project_budget.smartbutton_actual_budget +msgid "Smartbutton To Current Month Budget" +msgstr "Smartbutton a presupuesto del mes en curso" + +#. module: project_budget +#: model:ir.ui.view,arch_db:project_budget.project_config_settings_form_view +msgid "Specific Settings For Budget" +msgstr "Ajustes de presupuesto de proyecto" + #. module: project_budget #: model:ir.ui.view,arch_db:project_budget.crossovered_budget_form_view msgid "Sum Amount Total" msgstr "Total previsión final" #. module: project_budget -#: code:addons/project_budget/models/crossovered_budget.py:85 +#: code:addons/project_budget/models/crossovered_budget.py:65 #, python-format msgid "There can only be one initial budget per project and year." msgstr "Sólo puede haber un presupuesto inicial por proyecto y año." @@ -207,3 +228,8 @@ msgstr "Sin presupuestar" msgid "Year" msgstr "Año" +#. module: project_budget +#: model:ir.model,name:project_budget.model_res_config_settings +msgid "res.config.settings" +msgstr "res.config.settings" + diff --git a/project_budget/models/__init__.py b/project_budget/models/__init__.py index 228439e4..bfc4cce3 100644 --- a/project_budget/models/__init__.py +++ b/project_budget/models/__init__.py @@ -4,3 +4,4 @@ from . import crossovered_budget from . import project_project from . import account_analytic_account +from . import res_config_settings diff --git a/project_budget/models/res_config_settings.py b/project_budget/models/res_config_settings.py new file mode 100644 index 00000000..dbc11fb2 --- /dev/null +++ b/project_budget/models/res_config_settings.py @@ -0,0 +1,12 @@ +# Copyright 2018 Oihane Crucelaegui - AvanzOSC +# License AGPL-3 - See http://www.gnu.org/licenses/agpl-3.0.html + +from odoo import fields, models + + +class ProjectConfigSettings(models.TransientModel): + _inherit = 'res.config.settings' + + group_smartbutton_actual_budget = fields.Boolean( + string='Smartbutton To Current Month Budget', + implied_group='project_budget.smartbutton_actual_budget') diff --git a/project_budget/security/project_budget_groups.xml b/project_budget/security/project_budget_groups.xml new file mode 100644 index 00000000..a44fccbc --- /dev/null +++ b/project_budget/security/project_budget_groups.xml @@ -0,0 +1,7 @@ + + + + Smartbutton To Current Month Budget + + + diff --git a/project_budget/views/project_project_view.xml b/project_budget/views/project_project_view.xml index 8f6edd28..c4296bdc 100644 --- a/project_budget/views/project_project_view.xml +++ b/project_budget/views/project_project_view.xml @@ -31,15 +31,26 @@ project.project - - - + + + + + + project.project + + + + + + + + + - +