Initial commit: Odoomates Odoo packages (12 packages)

This commit is contained in:
Ernad Husremovic 2025-08-29 15:49:21 +02:00
commit 3b38c49bf0
526 changed files with 34983 additions and 0 deletions

View file

@ -0,0 +1,46 @@
# Odoo 16 Budget Management
Use budgets to compare actual with expected revenues and costs
## Installation
```bash
pip install odoo-bringout-odoomates-om_account_budget
```
## Dependencies
This addon depends on:
- account
## Manifest Information
- **Name**: Odoo 16 Budget Management
- **Version**: 16.0.1.0.0
- **Category**: Accounting
- **License**: LGPL-3
- **Installable**: False
## Source
Custom addon from bringout-odoomates vendor, addon `om_account_budget`.
## License
This package maintains the original LGPL-3 license from the addon.
## Documentation
- Overview: doc/OVERVIEW.md
- Architecture: doc/ARCHITECTURE.md
- Models: doc/MODELS.md
- Controllers: doc/CONTROLLERS.md
- Wizards: doc/WIZARDS.md
- Reports: doc/REPORTS.md
- Security: doc/SECURITY.md
- Install: doc/INSTALL.md
- Usage: doc/USAGE.md
- Configuration: doc/CONFIGURATION.md
- Dependencies: doc/DEPENDENCIES.md
- Troubleshooting: doc/TROUBLESHOOTING.md
- FAQ: doc/FAQ.md

View file

@ -0,0 +1,32 @@
# Architecture
```mermaid
flowchart TD
U[Users] -->|HTTP| V[Views and QWeb Templates]
V --> C[Controllers]
V --> W[Wizards Transient Models]
C --> M[Models and ORM]
W --> M
M --> R[Reports]
DX[Data XML] --> M
S[Security ACLs and Groups] -. enforces .-> M
subgraph Om_account_budget Module - om_account_budget
direction LR
M:::layer
W:::layer
C:::layer
V:::layer
R:::layer
S:::layer
DX:::layer
end
classDef layer fill:#eef8ff,stroke:#6ea8fe,stroke-width:1px
```
Notes
- Views include tree/form/kanban templates and report templates.
- Controllers provide website/portal routes when present.
- Wizards are UI flows implemented with `models.TransientModel`.
- Data XML loads data/demo records; Security defines groups and access.

View file

@ -0,0 +1,3 @@
# Configuration
Refer to Odoo settings for om_account_budget. Configure related models, access rights, and options as needed.

View file

@ -0,0 +1,3 @@
# Controllers
This module does not define custom HTTP controllers.

View file

@ -0,0 +1,5 @@
# Dependencies
This addon depends on:
- [account](../../odoo-bringout-oca-ocb-account)

View file

@ -0,0 +1,4 @@
# FAQ
- Q: Which Odoo version? A: 16.0 (OCA/OCB packaged).
- Q: How to enable? A: Start server with --addon om_account_budget or install in UI.

View file

@ -0,0 +1,7 @@
# Install
```bash
pip install odoo-bringout-odoomates-om_account_budget"
# or
uv pip install odoo-bringout-odoomates-om_account_budget"
```

View file

@ -0,0 +1,15 @@
# Models
Detected core models and extensions in om_account_budget.
```mermaid
classDiagram
class account_budget_post
class crossovered_budget
class crossovered_budget_lines
class account_analytic_account
```
Notes
- Classes show model technical names; fields omitted for brevity.
- Items listed under _inherit are extensions of existing models.

View file

@ -0,0 +1,6 @@
# Overview
Packaged Odoo addon: om_account_budget. Provides features documented in upstream Odoo 16 under this addon.
- Source: OCA/OCB 16.0, addon om_account_budget
- License: LGPL-3

View file

@ -0,0 +1,3 @@
# Reports
This module does not define custom reports.

View file

@ -0,0 +1,41 @@
# Security
Access control and security definitions in om_account_budget.
## Access Control Lists (ACLs)
Model access permissions defined in:
- **[ir.model.access.csv](../om_account_budget/security/ir.model.access.csv)**
- 6 model access rules
## Record Rules
Row-level security rules defined in:
## Security Groups & Configuration
Security groups and permissions defined in:
- **[account_budget_security.xml](../om_account_budget/security/account_budget_security.xml)**
```mermaid
graph TB
subgraph "Security Layers"
A[Users] --> B[Groups]
B --> C[Access Control Lists]
C --> D[Models]
B --> E[Record Rules]
E --> F[Individual Records]
end
```
Security files overview:
- **[account_budget_security.xml](../om_account_budget/security/account_budget_security.xml)**
- Security groups, categories, and XML-based rules
- **[ir.model.access.csv](../om_account_budget/security/ir.model.access.csv)**
- Model access permissions (CRUD rights)
Notes
- Access Control Lists define which groups can access which models
- Record Rules provide row-level security (filter records by user/group)
- Security groups organize users and define permission sets
- All security is enforced at the ORM level by Odoo

View file

@ -0,0 +1,5 @@
# Troubleshooting
- Ensure Python and Odoo environment matches repo guidance.
- Check database connectivity and logs if startup fails.
- Validate that dependent addons listed in DEPENDENCIES.md are installed.

View file

@ -0,0 +1,7 @@
# Usage
Start Odoo including this addon (from repo root):
```bash
python3 scripts/nix_odoo_web_server.py --db-name mydb --addon om_account_budget
```

View file

@ -0,0 +1,3 @@
# Wizards
This module does not include UI wizards.

View file

@ -0,0 +1,4 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from . import models

View file

@ -0,0 +1,24 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
{
'name': 'Odoo 16 Budget Management',
'author': 'Odoo Mates, Odoo SA',
'category': 'Accounting',
'version': '16.0.1.0.0',
'description': """Use budgets to compare actual with expected revenues and costs""",
'summary': 'Odoo 16 Budget Management',
'sequence': 10,
'website': 'https://www.odoomates.tech',
'depends': ['account'],
'license': 'LGPL-3',
'data': [
'security/ir.model.access.csv',
'security/account_budget_security.xml',
'views/account_analytic_account_views.xml',
'views/account_budget_views.xml',
'views/res_config_settings_views.xml',
],
"images": ['static/description/banner.gif'],
'demo': ['data/account_budget_demo.xml'],
}

View file

@ -0,0 +1,232 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<data noupdate="1">
<record id="crossovered_budget_budgetoptimistic0" model="crossovered.budget">
<field eval="'Budget '+str(datetime.now().year+1)+': Optimistic'" name="name"/>
<field eval="str(datetime.now().year+1)+'-01-01'" name="date_from"/>
<field eval="&quot;&quot;&quot;draft&quot;&quot;&quot;" name="state"/>
<field eval="str(datetime.now().year+1)+'-12-31'" name="date_to"/>
<field name="user_id" ref="base.user_root"/>
</record>
<record id="budget_line_analytic_admin" model="crossovered.budget.lines">
<field name="crossovered_budget_id" ref="crossovered_budget_budgetoptimistic0"/>
<field eval="str(datetime.now().year+1)+'-01-01'" name="date_from"/>
<field eval="str(datetime.now().year+1)+'-12-31'" name="date_to"/>
<field name="planned_amount">-35000</field>
<field name="analytic_account_id" ref="analytic.analytic_administratif"/>
</record>
<record id="budget_line_analytic_agrolait1" model="crossovered.budget.lines">
<field name="crossovered_budget_id" ref="crossovered_budget_budgetoptimistic0"/>
<field eval="str(datetime.now().year+1)+'-01-01'" name="date_from"/>
<field eval="str(datetime.now().year+1)+'-01-31'" name="date_to"/>
<field name="planned_amount">10000</field>
<field name="analytic_account_id" ref="analytic.analytic_agrolait"/>
</record>
<record id="budget_line_analytic_agrolait2" model="crossovered.budget.lines">
<field name="crossovered_budget_id" ref="crossovered_budget_budgetoptimistic0"/>
<field eval="str(datetime.now().year+1)+'-02-01'" name="date_from"/>
<field eval="str(datetime.now().year+1)+'-02-28'" name="date_to"/>
<field name="planned_amount">10000</field>
<field name="analytic_account_id" ref="analytic.analytic_agrolait"/>
</record>
<record id="budget_line_analytic_agrolait3" model="crossovered.budget.lines">
<field name="crossovered_budget_id" ref="crossovered_budget_budgetoptimistic0"/>
<field eval="str(datetime.now().year+1)+'-03-01'" name="date_from"/>
<field eval="str(datetime.now().year+1)+'-03-31'" name="date_to"/>
<field name="planned_amount">12000</field>
<field name="analytic_account_id" ref="analytic.analytic_agrolait"/>
</record>
<record id="budget_line_analytic_agrolait4" model="crossovered.budget.lines">
<field name="crossovered_budget_id" ref="crossovered_budget_budgetoptimistic0"/>
<field eval="str(datetime.now().year+1)+'-04-01'" name="date_from"/>
<field eval="str(datetime.now().year+1)+'-04-30'" name="date_to"/>
<field name="planned_amount">15000</field>
<field name="analytic_account_id" ref="analytic.analytic_agrolait"/>
</record>
<record id="budget_line_analytic_agrolait5" model="crossovered.budget.lines">
<field name="crossovered_budget_id" ref="crossovered_budget_budgetoptimistic0"/>
<field eval="str(datetime.now().year+1)+'-05-01'" name="date_from"/>
<field eval="str(datetime.now().year+1)+'-05-31'" name="date_to"/>
<field name="planned_amount">15000</field>
<field name="analytic_account_id" ref="analytic.analytic_agrolait"/>
</record>
<record id="budget_line_analytic_agrolait6" model="crossovered.budget.lines">
<field name="crossovered_budget_id" ref="crossovered_budget_budgetoptimistic0"/>
<field eval="str(datetime.now().year+1)+'-06-01'" name="date_from"/>
<field eval="str(datetime.now().year+1)+'-06-30'" name="date_to"/>
<field name="planned_amount">15000</field>
<field name="analytic_account_id" ref="analytic.analytic_agrolait"/>
</record>
<record id="budget_line_analytic_agrolait7" model="crossovered.budget.lines">
<field name="crossovered_budget_id" ref="crossovered_budget_budgetoptimistic0"/>
<field eval="str(datetime.now().year+1)+'-07-01'" name="date_from"/>
<field eval="str(datetime.now().year+1)+'-07-31'" name="date_to"/>
<field name="planned_amount">13000</field>
<field name="analytic_account_id" ref="analytic.analytic_agrolait"/>
</record>
<record id="budget_line_analytic_agrolait8" model="crossovered.budget.lines">
<field name="crossovered_budget_id" ref="crossovered_budget_budgetoptimistic0"/>
<field eval="str(datetime.now().year+1)+'-08-01'" name="date_from"/>
<field eval="str(datetime.now().year+1)+'-08-31'" name="date_to"/>
<field name="planned_amount">9000</field>
<field name="analytic_account_id" ref="analytic.analytic_agrolait"/>
</record>
<record id="budget_line_analytic_agrolait9" model="crossovered.budget.lines">
<field name="crossovered_budget_id" ref="crossovered_budget_budgetoptimistic0"/>
<field eval="str(datetime.now().year+1)+'-09-01'" name="date_from"/>
<field eval="str(datetime.now().year+1)+'-09-30'" name="date_to"/>
<field name="planned_amount">8000</field>
<field name="analytic_account_id" ref="analytic.analytic_agrolait"/>
</record>
<record id="budget_line_analytic_agrolait10" model="crossovered.budget.lines">
<field name="crossovered_budget_id" ref="crossovered_budget_budgetoptimistic0"/>
<field eval="str(datetime.now().year+1)+'-10-01'" name="date_from"/>
<field eval="str(datetime.now().year+1)+'-10-31'" name="date_to"/>
<field name="planned_amount">15000</field>
<field name="analytic_account_id" ref="analytic.analytic_agrolait"/>
</record>
<record id="budget_line_analytic_agrolait11" model="crossovered.budget.lines">
<field name="crossovered_budget_id" ref="crossovered_budget_budgetoptimistic0"/>
<field eval="str(datetime.now().year+1)+'-11-01'" name="date_from"/>
<field eval="str(datetime.now().year+1)+'-11-30'" name="date_to"/>
<field name="planned_amount">15000</field>
<field name="analytic_account_id" ref="analytic.analytic_agrolait"/>
</record>
<record id="budget_line_analytic_agrolait12" model="crossovered.budget.lines">
<field name="crossovered_budget_id" ref="crossovered_budget_budgetoptimistic0"/>
<field eval="str(datetime.now().year+1)+'-12-01'" name="date_from"/>
<field eval="str(datetime.now().year+1)+'-12-31'" name="date_to"/>
<field name="planned_amount">18000</field>
<field name="analytic_account_id" ref="analytic.analytic_agrolait"/>
</record>
<!-- pessimistic-->
<record id="crossovered_budget_budgetpessimistic0" model="crossovered.budget">
<field eval="'Budget '+str(datetime.now().year+1)+': Pessimistic'" name="name"/>
<field eval="str(datetime.now().year+1)+'-01-01'" name="date_from"/>
<field eval="&quot;&quot;&quot;draft&quot;&quot;&quot;" name="state"/>
<field eval="str(datetime.now().year+1)+'-12-31'" name="date_to"/>
<field name="user_id" ref="base.user_root"/>
</record>
<record id="budget_line_analytic_admin_pessim" model="crossovered.budget.lines">
<field name="crossovered_budget_id" ref="crossovered_budget_budgetpessimistic0"/>
<field eval="str(datetime.now().year+1)+'-01-01'" name="date_from"/>
<field eval="str(datetime.now().year+1)+'-12-31'" name="date_to"/>
<field name="planned_amount">-55000</field>
<field name="analytic_account_id" ref="analytic.analytic_administratif"/>
</record>
<record id="budget_line_analytic_agrolait_pessim1" model="crossovered.budget.lines">
<field name="crossovered_budget_id" ref="crossovered_budget_budgetpessimistic0"/>
<field eval="str(datetime.now().year+1)+'-01-01'" name="date_from"/>
<field eval="str(datetime.now().year+1)+'-01-31'" name="date_to"/>
<field name="planned_amount">9000</field>
<field name="analytic_account_id" ref="analytic.analytic_agrolait"/>
</record>
<record id="budget_line_analytic_agrolait_pessim2" model="crossovered.budget.lines">
<field name="crossovered_budget_id" ref="crossovered_budget_budgetpessimistic0"/>
<field eval="str(datetime.now().year+1)+'-02-01'" name="date_from"/>
<field eval="str(datetime.now().year+1)+'-02-28'" name="date_to"/>
<field name="planned_amount">8000</field>
<field name="analytic_account_id" ref="analytic.analytic_agrolait"/>
</record>
<record id="budget_line_analytic_agrolait_pessim3" model="crossovered.budget.lines">
<field name="crossovered_budget_id" ref="crossovered_budget_budgetpessimistic0"/>
<field eval="str(datetime.now().year+1)+'-03-01'" name="date_from"/>
<field eval="str(datetime.now().year+1)+'-03-31'" name="date_to"/>
<field name="planned_amount">10000</field>
<field name="analytic_account_id" ref="analytic.analytic_agrolait"/>
</record>
<record id="budget_line_analytic_agrolait_pessim4" model="crossovered.budget.lines">
<field name="crossovered_budget_id" ref="crossovered_budget_budgetpessimistic0"/>
<field eval="str(datetime.now().year+1)+'-04-01'" name="date_from"/>
<field eval="str(datetime.now().year+1)+'-04-30'" name="date_to"/>
<field name="planned_amount">14000</field>
<field name="analytic_account_id" ref="analytic.analytic_agrolait"/>
</record>
<record id="budget_line_analytic_agrolait_pessim5" model="crossovered.budget.lines">
<field name="crossovered_budget_id" ref="crossovered_budget_budgetpessimistic0"/>
<field eval="str(datetime.now().year+1)+'-05-01'" name="date_from"/>
<field eval="str(datetime.now().year+1)+'-05-31'" name="date_to"/>
<field name="planned_amount">16000</field>
<field name="analytic_account_id" ref="analytic.analytic_agrolait"/>
</record>
<record id="budget_line_analytic_agrolait_pessim6" model="crossovered.budget.lines">
<field name="crossovered_budget_id" ref="crossovered_budget_budgetpessimistic0"/>
<field eval="str(datetime.now().year+1)+'-06-01'" name="date_from"/>
<field eval="str(datetime.now().year+1)+'-06-30'" name="date_to"/>
<field name="planned_amount">13000</field>
<field name="analytic_account_id" ref="analytic.analytic_agrolait"/>
</record>
<record id="budget_line_analytic_agrolait_pessim7" model="crossovered.budget.lines">
<field name="crossovered_budget_id" ref="crossovered_budget_budgetpessimistic0"/>
<field eval="str(datetime.now().year+1)+'-07-01'" name="date_from"/>
<field eval="str(datetime.now().year+1)+'-07-31'" name="date_to"/>
<field name="planned_amount">10000</field>
<field name="analytic_account_id" ref="analytic.analytic_agrolait"/>
</record>
<record id="budget_line_analytic_agrolait_pessim8" model="crossovered.budget.lines">
<field name="crossovered_budget_id" ref="crossovered_budget_budgetpessimistic0"/>
<field eval="str(datetime.now().year+1)+'-08-01'" name="date_from"/>
<field eval="str(datetime.now().year+1)+'-08-31'" name="date_to"/>
<field name="planned_amount">8000</field>
<field name="analytic_account_id" ref="analytic.analytic_agrolait"/>
</record>
<record id="budget_line_analytic_agrolait_pessim9" model="crossovered.budget.lines">
<field name="crossovered_budget_id" ref="crossovered_budget_budgetpessimistic0"/>
<field eval="str(datetime.now().year+1)+'-09-01'" name="date_from"/>
<field eval="str(datetime.now().year+1)+'-09-30'" name="date_to"/>
<field name="planned_amount">7000</field>
<field name="analytic_account_id" ref="analytic.analytic_agrolait"/>
</record>
<record id="budget_line_analytic_agrolait_pessim10" model="crossovered.budget.lines">
<field name="crossovered_budget_id" ref="crossovered_budget_budgetpessimistic0"/>
<field eval="str(datetime.now().year+1)+'-10-01'" name="date_from"/>
<field eval="str(datetime.now().year+1)+'-10-31'" name="date_to"/>
<field name="planned_amount">12000</field>
<field name="analytic_account_id" ref="analytic.analytic_agrolait"/>
</record>
<record id="budget_line_analytic_agrolait_pessim11" model="crossovered.budget.lines">
<field name="crossovered_budget_id" ref="crossovered_budget_budgetpessimistic0"/>
<field eval="str(datetime.now().year+1)+'-11-01'" name="date_from"/>
<field eval="str(datetime.now().year+1)+'-11-30'" name="date_to"/>
<field name="planned_amount">17000</field>
<field name="analytic_account_id" ref="analytic.analytic_agrolait"/>
</record>
<record id="budget_line_analytic_agrolait_pessim12" model="crossovered.budget.lines">
<field name="crossovered_budget_id" ref="crossovered_budget_budgetpessimistic0"/>
<field eval="str(datetime.now().year+1)+'-12-01'" name="date_from"/>
<field eval="str(datetime.now().year+1)+'-12-31'" name="date_to"/>
<field name="planned_amount">17000</field>
<field name="analytic_account_id" ref="analytic.analytic_agrolait"/>
</record>
</data>
</odoo>

View file

@ -0,0 +1,8 @@
## Module <om_account_budget>
#### 22.07.2022
#### Version 16.0.1.0.0
##### ADD
- initial release

View file

@ -0,0 +1,490 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * om_account_budget
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 16.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-04-26 14:55+0000\n"
"PO-Revision-Date: 2024-04-26 14:55+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: om_account_budget
#. odoo-python
#: code:addons/om_account_budget/models/account_budget.py:0
#, python-format
msgid ""
"\"End Date\" of the budget line should be included in the Period of the "
"budget"
msgstr ""
#. module: om_account_budget
#. odoo-python
#: code:addons/om_account_budget/models/account_budget.py:0
#, python-format
msgid ""
"\"Start Date\" of the budget line should be included in the Period of the "
"budget"
msgstr ""
#. module: om_account_budget
#: model_terms:ir.ui.view,arch_db:om_account_budget.view_crossovered_budget_kanban
msgid "<i class=\"fa fa-clock-o\" role=\"img\" aria-label=\"Period\" title=\"Period\"/>"
msgstr "<i class=\"fa fa-clock-o\" role=\"img\" aria-label=\"Period\" title=\"Period\"/>"
#. module: om_account_budget
#: model:ir.model.fields,field_description:om_account_budget.field_account_budget_post__account_ids
#: model_terms:ir.ui.view,arch_db:om_account_budget.view_budget_post_form
msgid "Accounts"
msgstr "Konta"
#. module: om_account_budget
#: model:ir.model.fields,field_description:om_account_budget.field_crossovered_budget_lines__percentage
msgid "Achievement"
msgstr "Achievement"
#. module: om_account_budget
#: model:ir.model.fields,field_description:om_account_budget.field_crossovered_budget__message_needaction
msgid "Action Needed"
msgstr "Potrebna akcija"
#. module: om_account_budget
#: model:ir.model.fields,help:om_account_budget.field_crossovered_budget_lines__practical_amount
msgid "Amount really earned/spent."
msgstr "Iznos really earned/spent."
#. module: om_account_budget
#: model:ir.model.fields,help:om_account_budget.field_crossovered_budget_lines__theoritical_amount
msgid "Amount you are supposed to have earned/spent at this date."
msgstr "Iznos you are supposed to have earned/spent at this date."
#. module: om_account_budget
#: model:ir.model.fields,help:om_account_budget.field_crossovered_budget_lines__planned_amount
msgid ""
"Amount you plan to earn/spend. Record a positive amount if it is a revenue "
"and a negative amount if it is a cost."
msgstr ""
#. module: om_account_budget
#: model:ir.model,name:om_account_budget.model_account_analytic_account
#: model:ir.model.fields,field_description:om_account_budget.field_crossovered_budget_lines__analytic_account_id
msgid "Analytic Account"
msgstr "Analitički konto"
#. module: om_account_budget
#: model:ir.model.fields,field_description:om_account_budget.field_crossovered_budget_lines__analytic_plan_id
msgid "Analytic Plan"
msgstr "Analitički plan"
#. module: om_account_budget
#: model_terms:ir.ui.view,arch_db:om_account_budget.crossovered_budget_view_form
msgid "Approve"
msgstr "Odobri"
#. module: om_account_budget
#: model:ir.model.fields,field_description:om_account_budget.field_crossovered_budget__message_attachment_count
msgid "Attachment Count"
msgstr "Broj priloga"
#. module: om_account_budget
#: model:ir.model,name:om_account_budget.model_crossovered_budget
#: model:ir.model.fields,field_description:om_account_budget.field_crossovered_budget_lines__crossovered_budget_id
#: model_terms:ir.ui.view,arch_db:om_account_budget.crossovered_budget_view_form
#: model_terms:ir.ui.view,arch_db:om_account_budget.crossovered_budget_view_tree
#: model_terms:ir.ui.view,arch_db:om_account_budget.view_crossovered_budget_search
msgid "Budget"
msgstr "Budžet"
#. module: om_account_budget
#: model:ir.actions.act_window,name:om_account_budget.act_account_analytic_account_cb_lines
#: model_terms:ir.ui.view,arch_db:om_account_budget.view_account_analytic_account_form_inherit_budget
msgid "Budget Items"
msgstr "Stavke budžeta"
#. module: om_account_budget
#: model:ir.model,name:om_account_budget.model_crossovered_budget_lines
msgid "Budget Line"
msgstr "Budžet Stavka"
#. module: om_account_budget
#: model:ir.model.fields,field_description:om_account_budget.field_account_analytic_account__crossovered_budget_line
#: model:ir.model.fields,field_description:om_account_budget.field_crossovered_budget__crossovered_budget_line
#: model_terms:ir.ui.view,arch_db:om_account_budget.crossovered_budget_view_form
#: model_terms:ir.ui.view,arch_db:om_account_budget.view_crossovered_budget_line_form
#: model_terms:ir.ui.view,arch_db:om_account_budget.view_crossovered_budget_line_graph
#: model_terms:ir.ui.view,arch_db:om_account_budget.view_crossovered_budget_line_pivot
#: model_terms:ir.ui.view,arch_db:om_account_budget.view_crossovered_budget_line_search
#: model_terms:ir.ui.view,arch_db:om_account_budget.view_crossovered_budget_line_tree
msgid "Budget Lines"
msgstr "Linije budžeta"
#. module: om_account_budget
#: model:ir.model.fields,field_description:om_account_budget.field_crossovered_budget__name
#: model_terms:ir.ui.view,arch_db:om_account_budget.crossovered_budget_view_form
msgid "Budget Name"
msgstr "Budžet Naziv"
#. module: om_account_budget
#: model:ir.model.fields,field_description:om_account_budget.field_crossovered_budget_lines__crossovered_budget_state
msgid "Budget State"
msgstr "Budžet Stanje"
#. module: om_account_budget
#: model:ir.model,name:om_account_budget.model_account_budget_post
#: model:ir.model.fields,field_description:om_account_budget.field_crossovered_budget_lines__general_budget_id
#: model_terms:ir.ui.view,arch_db:om_account_budget.view_budget_post_form
#: model_terms:ir.ui.view,arch_db:om_account_budget.view_budget_post_search
#: model_terms:ir.ui.view,arch_db:om_account_budget.view_budget_post_tree
msgid "Budgetary Position"
msgstr "Budžetary Position"
#. module: om_account_budget
#: model:ir.actions.act_window,name:om_account_budget.open_budget_post_form
#: model:ir.ui.menu,name:om_account_budget.menu_budget_post_form
msgid "Budgetary Positions"
msgstr "Budžetary Positions"
#. module: om_account_budget
#: model:ir.actions.act_window,name:om_account_budget.act_crossovered_budget_view
#: model:ir.ui.menu,name:om_account_budget.menu_act_crossovered_budget_view
#: model_terms:ir.ui.view,arch_db:om_account_budget.view_crossovered_budget_line_search
msgid "Budgets"
msgstr "Budžeti"
#. module: om_account_budget
#: model:ir.actions.act_window,name:om_account_budget.act_crossovered_budget_lines_view
#: model:ir.ui.menu,name:om_account_budget.menu_act_crossovered_budget_lines_view
msgid "Budgets Analysis"
msgstr "Budžets Analiza"
#. module: om_account_budget
#: model_terms:ir.ui.view,arch_db:om_account_budget.crossovered_budget_view_form
msgid "Cancel Budget"
msgstr "Otkaži Budžet"
#. module: om_account_budget
#: model:ir.model.fields.selection,name:om_account_budget.selection__crossovered_budget__state__cancel
msgid "Cancelled"
msgstr "Otkazan"
#. module: om_account_budget
#: model_terms:ir.actions.act_window,help:om_account_budget.act_crossovered_budget_view
msgid "Click to create a new budget."
msgstr "Click to create a new budget."
#. module: om_account_budget
#: model:ir.model.fields,field_description:om_account_budget.field_account_budget_post__company_id
#: model:ir.model.fields,field_description:om_account_budget.field_crossovered_budget__company_id
#: model:ir.model.fields,field_description:om_account_budget.field_crossovered_budget_lines__company_id
msgid "Company"
msgstr "Preduzeće"
#. module: om_account_budget
#: model:ir.model.fields,help:om_account_budget.field_crossovered_budget_lines__percentage
msgid ""
"Comparison between practical and theoretical amount. This measure tells you "
"if you are below or over budget."
msgstr ""
#. module: om_account_budget
#: model_terms:ir.ui.view,arch_db:om_account_budget.crossovered_budget_view_form
msgid "Confirm"
msgstr "Potvrdi"
#. module: om_account_budget
#: model:ir.model.fields.selection,name:om_account_budget.selection__crossovered_budget__state__confirm
msgid "Confirmed"
msgstr "Potvrđeno"
#. module: om_account_budget
#: model:ir.model.fields,field_description:om_account_budget.field_account_budget_post__create_uid
#: model:ir.model.fields,field_description:om_account_budget.field_crossovered_budget__create_uid
#: model:ir.model.fields,field_description:om_account_budget.field_crossovered_budget_lines__create_uid
msgid "Created by"
msgstr "Kreirao"
#. module: om_account_budget
#: model:ir.model.fields,field_description:om_account_budget.field_account_budget_post__create_date
#: model:ir.model.fields,field_description:om_account_budget.field_crossovered_budget__create_date
#: model:ir.model.fields,field_description:om_account_budget.field_crossovered_budget_lines__create_date
msgid "Created on"
msgstr "Kreirano"
#. module: om_account_budget
#: model:ir.model.fields,field_description:om_account_budget.field_crossovered_budget_lines__currency_id
msgid "Currency"
msgstr "Valuta"
#. module: om_account_budget
#: model:ir.model.fields,field_description:om_account_budget.field_account_budget_post__display_name
#: model:ir.model.fields,field_description:om_account_budget.field_crossovered_budget__display_name
#: model:ir.model.fields,field_description:om_account_budget.field_crossovered_budget_lines__display_name
msgid "Display Name"
msgstr "Prikazani naziv"
#. module: om_account_budget
#: model:ir.model.fields.selection,name:om_account_budget.selection__crossovered_budget__state__done
#: model_terms:ir.ui.view,arch_db:om_account_budget.crossovered_budget_view_form
msgid "Done"
msgstr "Gotovo"
#. module: om_account_budget
#: model:ir.model.fields.selection,name:om_account_budget.selection__crossovered_budget__state__draft
#: model_terms:ir.ui.view,arch_db:om_account_budget.view_crossovered_budget_search
msgid "Draft"
msgstr "U pripremi"
#. module: om_account_budget
#: model_terms:ir.ui.view,arch_db:om_account_budget.view_crossovered_budget_search
msgid "Draft Budgets"
msgstr "Nacrt Budžets"
#. module: om_account_budget
#: model:ir.model.fields,field_description:om_account_budget.field_crossovered_budget__date_to
#: model:ir.model.fields,field_description:om_account_budget.field_crossovered_budget_lines__date_to
msgid "End Date"
msgstr "Datum završetka"
#. module: om_account_budget
#: model_terms:ir.ui.view,arch_db:om_account_budget.crossovered_budget_view_form
msgid "Entries..."
msgstr "Entries..."
#. module: om_account_budget
#: model:ir.model.fields,field_description:om_account_budget.field_crossovered_budget__message_follower_ids
msgid "Followers"
msgstr "Pratioci"
#. module: om_account_budget
#: model:ir.model.fields,field_description:om_account_budget.field_crossovered_budget__message_partner_ids
msgid "Followers (Partners)"
msgstr "Pratioci (Partneri)"
#. module: om_account_budget
#: model_terms:ir.ui.view,arch_db:om_account_budget.view_crossovered_budget_line_search
msgid "Group By"
msgstr "Grupiši po"
#. module: om_account_budget
#: model:ir.model.fields,field_description:om_account_budget.field_crossovered_budget__has_message
msgid "Has Message"
msgstr "Ima poruku"
#. module: om_account_budget
#: model:ir.model.fields,field_description:om_account_budget.field_account_budget_post__id
#: model:ir.model.fields,field_description:om_account_budget.field_crossovered_budget__id
#: model:ir.model.fields,field_description:om_account_budget.field_crossovered_budget_lines__id
msgid "ID"
msgstr "ID"
#. module: om_account_budget
#: model:ir.model.fields,help:om_account_budget.field_crossovered_budget__message_needaction
msgid "If checked, new messages require your attention."
msgstr "Ako je zakačeno, nove poruke će zahtjevati vašu pažnju"
#. module: om_account_budget
#: model:ir.model.fields,help:om_account_budget.field_crossovered_budget__message_has_error
msgid "If checked, some messages have a delivery error."
msgstr "Ako je označeno neke poruke mogu imati grešku u dostavi."
#. module: om_account_budget
#: model:ir.model.fields,field_description:om_account_budget.field_crossovered_budget_lines__is_above_budget
msgid "Is Above Budget"
msgstr "Is Above Budžet"
#. module: om_account_budget
#: model:ir.model.fields,field_description:om_account_budget.field_crossovered_budget__message_is_follower
msgid "Is Follower"
msgstr "Pratilac"
#. module: om_account_budget
#: model:ir.model.fields,field_description:om_account_budget.field_account_budget_post____last_update
#: model:ir.model.fields,field_description:om_account_budget.field_crossovered_budget____last_update
#: model:ir.model.fields,field_description:om_account_budget.field_crossovered_budget_lines____last_update
msgid "Last Modified on"
msgstr "Zadnje mijenjano"
#. module: om_account_budget
#: model:ir.model.fields,field_description:om_account_budget.field_account_budget_post__write_uid
#: model:ir.model.fields,field_description:om_account_budget.field_crossovered_budget__write_uid
#: model:ir.model.fields,field_description:om_account_budget.field_crossovered_budget_lines__write_uid
msgid "Last Updated by"
msgstr "Zadnji ažurirao"
#. module: om_account_budget
#: model:ir.model.fields,field_description:om_account_budget.field_account_budget_post__write_date
#: model:ir.model.fields,field_description:om_account_budget.field_crossovered_budget__write_date
#: model:ir.model.fields,field_description:om_account_budget.field_crossovered_budget_lines__write_date
msgid "Last Updated on"
msgstr "Zadnje ažurirano"
#. module: om_account_budget
#: model:ir.model.fields,field_description:om_account_budget.field_crossovered_budget__message_main_attachment_id
msgid "Main Attachment"
msgstr "Glavna zakačka"
#. module: om_account_budget
#: model:ir.model.fields,field_description:om_account_budget.field_crossovered_budget__message_has_error
msgid "Message Delivery error"
msgstr "Greška pri isporuci poruke"
#. module: om_account_budget
#: model:ir.model.fields,field_description:om_account_budget.field_crossovered_budget__message_ids
msgid "Messages"
msgstr "Poruke"
#. module: om_account_budget
#: model:ir.model.fields,field_description:om_account_budget.field_account_budget_post__name
#: model:ir.model.fields,field_description:om_account_budget.field_crossovered_budget_lines__name
msgid "Name"
msgstr "Naziv:"
#. module: om_account_budget
#: model_terms:ir.ui.view,arch_db:om_account_budget.view_crossovered_budget_line_search
msgid "Not Cancelled"
msgstr "Not Otkažiled"
#. module: om_account_budget
#: model:ir.model.fields,field_description:om_account_budget.field_crossovered_budget__message_needaction_counter
msgid "Number of Actions"
msgstr "Broj akcija"
#. module: om_account_budget
#: model:ir.model.fields,field_description:om_account_budget.field_crossovered_budget__message_has_error_counter
msgid "Number of errors"
msgstr "Broj grešaka"
#. module: om_account_budget
#: model:ir.model.fields,help:om_account_budget.field_crossovered_budget__message_needaction_counter
msgid "Number of messages requiring action"
msgstr "Broj poruka koje zahtijevaju aktivnost"
#. module: om_account_budget
#: model:ir.model.fields,help:om_account_budget.field_crossovered_budget__message_has_error_counter
msgid "Number of messages with delivery error"
msgstr "Broj poruka sa greškama pri isporuci"
#. module: om_account_budget
#: model:ir.model.fields,field_description:om_account_budget.field_crossovered_budget_lines__paid_date
msgid "Paid Date"
msgstr "Paid Datum"
#. module: om_account_budget
#: model_terms:ir.ui.view,arch_db:om_account_budget.crossovered_budget_view_form
msgid "Period"
msgstr "Period"
#. module: om_account_budget
#: model:ir.model.fields,field_description:om_account_budget.field_crossovered_budget_lines__planned_amount
#: model_terms:ir.ui.view,arch_db:om_account_budget.crossovered_budget_view_form
msgid "Planned Amount"
msgstr "Planirano Iznos"
#. module: om_account_budget
#: model_terms:ir.ui.view,arch_db:om_account_budget.view_crossovered_budget_line_graph
#: model_terms:ir.ui.view,arch_db:om_account_budget.view_crossovered_budget_line_pivot
msgid "Planned amount"
msgstr "Planirano amount"
#. module: om_account_budget
#: model:ir.model.fields,field_description:om_account_budget.field_crossovered_budget_lines__practical_amount
#: model_terms:ir.ui.view,arch_db:om_account_budget.crossovered_budget_view_form
#: model_terms:ir.ui.view,arch_db:om_account_budget.view_account_analytic_account_form_inherit_budget
msgid "Practical Amount"
msgstr "Practical Iznos"
#. module: om_account_budget
#: model_terms:ir.ui.view,arch_db:om_account_budget.view_crossovered_budget_line_graph
#: model_terms:ir.ui.view,arch_db:om_account_budget.view_crossovered_budget_line_pivot
msgid "Practical amount"
msgstr "Practical amount"
#. module: om_account_budget
#: model_terms:ir.ui.view,arch_db:om_account_budget.crossovered_budget_view_form
msgid "Reset to Draft"
msgstr "Vrati u pripremu"
#. module: om_account_budget
#: model:ir.model.fields,field_description:om_account_budget.field_crossovered_budget__user_id
msgid "Responsible"
msgstr "Odgovoran"
#. module: om_account_budget
#: model:ir.model.fields,field_description:om_account_budget.field_crossovered_budget__date_from
#: model:ir.model.fields,field_description:om_account_budget.field_crossovered_budget_lines__date_from
msgid "Start Date"
msgstr "Početni datum"
#. module: om_account_budget
#: model:ir.model.fields,field_description:om_account_budget.field_crossovered_budget__state
msgid "Status"
msgstr "Status"
#. module: om_account_budget
#. odoo-python
#: code:addons/om_account_budget/models/account_budget.py:0
#, python-format
msgid "The budget must have at least one account."
msgstr "The budget must have at least one account."
#. module: om_account_budget
#: model:ir.model.fields,field_description:om_account_budget.field_crossovered_budget_lines__theoritical_amount
#: model_terms:ir.ui.view,arch_db:om_account_budget.crossovered_budget_view_form
msgid "Theoretical Amount"
msgstr "Theoretical Iznos"
#. module: om_account_budget
#: model_terms:ir.ui.view,arch_db:om_account_budget.view_account_analytic_account_form_inherit_budget
msgid "Theoritical Amount"
msgstr "Theoritical Iznos"
#. module: om_account_budget
#: model_terms:ir.ui.view,arch_db:om_account_budget.view_crossovered_budget_line_graph
#: model_terms:ir.ui.view,arch_db:om_account_budget.view_crossovered_budget_line_pivot
msgid "Theoritical amount"
msgstr "Theoritical amount"
#. module: om_account_budget
#: model_terms:ir.ui.view,arch_db:om_account_budget.view_crossovered_budget_search
msgid "To Approve"
msgstr "Za odobriti"
#. module: om_account_budget
#: model_terms:ir.ui.view,arch_db:om_account_budget.view_crossovered_budget_search
msgid "To Approve Budgets"
msgstr "To Approve Budžets"
#. module: om_account_budget
#: model_terms:ir.actions.act_window,help:om_account_budget.act_crossovered_budget_view
msgid "Use budgets to compare actual with expected revenues and costs"
msgstr "Koristite proračune za usporedbu stvarnih s očekivanim prihodima i troškovima"
#. module: om_account_budget
#: model:ir.model.fields.selection,name:om_account_budget.selection__crossovered_budget__state__validate
msgid "Validated"
msgstr "Odobreno"
#. module: om_account_budget
#: model:ir.model.fields,field_description:om_account_budget.field_crossovered_budget__website_message_ids
msgid "Website Messages"
msgstr "Poruke sa website-a"
#. module: om_account_budget
#: model:ir.model.fields,help:om_account_budget.field_crossovered_budget__website_message_ids
msgid "Website communication history"
msgstr "Povijest komunikacije Web stranice"
#. module: om_account_budget
#. odoo-python
#: code:addons/om_account_budget/models/account_budget.py:0
#, python-format
msgid ""
"You have to enter at least a budgetary position or analytic account on a "
"budget line."
msgstr ""

View file

@ -0,0 +1,490 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * om_account_budget
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 16.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-04-26 14:55+0000\n"
"PO-Revision-Date: 2024-04-26 14:55+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: om_account_budget
#. odoo-python
#: code:addons/om_account_budget/models/account_budget.py:0
#, python-format
msgid ""
"\"End Date\" of the budget line should be included in the Period of the "
"budget"
msgstr ""
#. module: om_account_budget
#. odoo-python
#: code:addons/om_account_budget/models/account_budget.py:0
#, python-format
msgid ""
"\"Start Date\" of the budget line should be included in the Period of the "
"budget"
msgstr ""
#. module: om_account_budget
#: model_terms:ir.ui.view,arch_db:om_account_budget.view_crossovered_budget_kanban
msgid "<i class=\"fa fa-clock-o\" role=\"img\" aria-label=\"Period\" title=\"Period\"/>"
msgstr ""
#. module: om_account_budget
#: model:ir.model.fields,field_description:om_account_budget.field_account_budget_post__account_ids
#: model_terms:ir.ui.view,arch_db:om_account_budget.view_budget_post_form
msgid "Accounts"
msgstr ""
#. module: om_account_budget
#: model:ir.model.fields,field_description:om_account_budget.field_crossovered_budget_lines__percentage
msgid "Achievement"
msgstr ""
#. module: om_account_budget
#: model:ir.model.fields,field_description:om_account_budget.field_crossovered_budget__message_needaction
msgid "Action Needed"
msgstr ""
#. module: om_account_budget
#: model:ir.model.fields,help:om_account_budget.field_crossovered_budget_lines__practical_amount
msgid "Amount really earned/spent."
msgstr ""
#. module: om_account_budget
#: model:ir.model.fields,help:om_account_budget.field_crossovered_budget_lines__theoritical_amount
msgid "Amount you are supposed to have earned/spent at this date."
msgstr ""
#. module: om_account_budget
#: model:ir.model.fields,help:om_account_budget.field_crossovered_budget_lines__planned_amount
msgid ""
"Amount you plan to earn/spend. Record a positive amount if it is a revenue "
"and a negative amount if it is a cost."
msgstr ""
#. module: om_account_budget
#: model:ir.model,name:om_account_budget.model_account_analytic_account
#: model:ir.model.fields,field_description:om_account_budget.field_crossovered_budget_lines__analytic_account_id
msgid "Analytic Account"
msgstr ""
#. module: om_account_budget
#: model:ir.model.fields,field_description:om_account_budget.field_crossovered_budget_lines__analytic_plan_id
msgid "Analytic Plan"
msgstr ""
#. module: om_account_budget
#: model_terms:ir.ui.view,arch_db:om_account_budget.crossovered_budget_view_form
msgid "Approve"
msgstr ""
#. module: om_account_budget
#: model:ir.model.fields,field_description:om_account_budget.field_crossovered_budget__message_attachment_count
msgid "Attachment Count"
msgstr ""
#. module: om_account_budget
#: model:ir.model,name:om_account_budget.model_crossovered_budget
#: model:ir.model.fields,field_description:om_account_budget.field_crossovered_budget_lines__crossovered_budget_id
#: model_terms:ir.ui.view,arch_db:om_account_budget.crossovered_budget_view_form
#: model_terms:ir.ui.view,arch_db:om_account_budget.crossovered_budget_view_tree
#: model_terms:ir.ui.view,arch_db:om_account_budget.view_crossovered_budget_search
msgid "Budget"
msgstr ""
#. module: om_account_budget
#: model:ir.actions.act_window,name:om_account_budget.act_account_analytic_account_cb_lines
#: model_terms:ir.ui.view,arch_db:om_account_budget.view_account_analytic_account_form_inherit_budget
msgid "Budget Items"
msgstr ""
#. module: om_account_budget
#: model:ir.model,name:om_account_budget.model_crossovered_budget_lines
msgid "Budget Line"
msgstr ""
#. module: om_account_budget
#: model:ir.model.fields,field_description:om_account_budget.field_account_analytic_account__crossovered_budget_line
#: model:ir.model.fields,field_description:om_account_budget.field_crossovered_budget__crossovered_budget_line
#: model_terms:ir.ui.view,arch_db:om_account_budget.crossovered_budget_view_form
#: model_terms:ir.ui.view,arch_db:om_account_budget.view_crossovered_budget_line_form
#: model_terms:ir.ui.view,arch_db:om_account_budget.view_crossovered_budget_line_graph
#: model_terms:ir.ui.view,arch_db:om_account_budget.view_crossovered_budget_line_pivot
#: model_terms:ir.ui.view,arch_db:om_account_budget.view_crossovered_budget_line_search
#: model_terms:ir.ui.view,arch_db:om_account_budget.view_crossovered_budget_line_tree
msgid "Budget Lines"
msgstr ""
#. module: om_account_budget
#: model:ir.model.fields,field_description:om_account_budget.field_crossovered_budget__name
#: model_terms:ir.ui.view,arch_db:om_account_budget.crossovered_budget_view_form
msgid "Budget Name"
msgstr ""
#. module: om_account_budget
#: model:ir.model.fields,field_description:om_account_budget.field_crossovered_budget_lines__crossovered_budget_state
msgid "Budget State"
msgstr ""
#. module: om_account_budget
#: model:ir.model,name:om_account_budget.model_account_budget_post
#: model:ir.model.fields,field_description:om_account_budget.field_crossovered_budget_lines__general_budget_id
#: model_terms:ir.ui.view,arch_db:om_account_budget.view_budget_post_form
#: model_terms:ir.ui.view,arch_db:om_account_budget.view_budget_post_search
#: model_terms:ir.ui.view,arch_db:om_account_budget.view_budget_post_tree
msgid "Budgetary Position"
msgstr ""
#. module: om_account_budget
#: model:ir.actions.act_window,name:om_account_budget.open_budget_post_form
#: model:ir.ui.menu,name:om_account_budget.menu_budget_post_form
msgid "Budgetary Positions"
msgstr ""
#. module: om_account_budget
#: model:ir.actions.act_window,name:om_account_budget.act_crossovered_budget_view
#: model:ir.ui.menu,name:om_account_budget.menu_act_crossovered_budget_view
#: model_terms:ir.ui.view,arch_db:om_account_budget.view_crossovered_budget_line_search
msgid "Budgets"
msgstr ""
#. module: om_account_budget
#: model:ir.actions.act_window,name:om_account_budget.act_crossovered_budget_lines_view
#: model:ir.ui.menu,name:om_account_budget.menu_act_crossovered_budget_lines_view
msgid "Budgets Analysis"
msgstr ""
#. module: om_account_budget
#: model_terms:ir.ui.view,arch_db:om_account_budget.crossovered_budget_view_form
msgid "Cancel Budget"
msgstr ""
#. module: om_account_budget
#: model:ir.model.fields.selection,name:om_account_budget.selection__crossovered_budget__state__cancel
msgid "Cancelled"
msgstr ""
#. module: om_account_budget
#: model_terms:ir.actions.act_window,help:om_account_budget.act_crossovered_budget_view
msgid "Click to create a new budget."
msgstr ""
#. module: om_account_budget
#: model:ir.model.fields,field_description:om_account_budget.field_account_budget_post__company_id
#: model:ir.model.fields,field_description:om_account_budget.field_crossovered_budget__company_id
#: model:ir.model.fields,field_description:om_account_budget.field_crossovered_budget_lines__company_id
msgid "Company"
msgstr ""
#. module: om_account_budget
#: model:ir.model.fields,help:om_account_budget.field_crossovered_budget_lines__percentage
msgid ""
"Comparison between practical and theoretical amount. This measure tells you "
"if you are below or over budget."
msgstr ""
#. module: om_account_budget
#: model_terms:ir.ui.view,arch_db:om_account_budget.crossovered_budget_view_form
msgid "Confirm"
msgstr ""
#. module: om_account_budget
#: model:ir.model.fields.selection,name:om_account_budget.selection__crossovered_budget__state__confirm
msgid "Confirmed"
msgstr ""
#. module: om_account_budget
#: model:ir.model.fields,field_description:om_account_budget.field_account_budget_post__create_uid
#: model:ir.model.fields,field_description:om_account_budget.field_crossovered_budget__create_uid
#: model:ir.model.fields,field_description:om_account_budget.field_crossovered_budget_lines__create_uid
msgid "Created by"
msgstr ""
#. module: om_account_budget
#: model:ir.model.fields,field_description:om_account_budget.field_account_budget_post__create_date
#: model:ir.model.fields,field_description:om_account_budget.field_crossovered_budget__create_date
#: model:ir.model.fields,field_description:om_account_budget.field_crossovered_budget_lines__create_date
msgid "Created on"
msgstr ""
#. module: om_account_budget
#: model:ir.model.fields,field_description:om_account_budget.field_crossovered_budget_lines__currency_id
msgid "Currency"
msgstr ""
#. module: om_account_budget
#: model:ir.model.fields,field_description:om_account_budget.field_account_budget_post__display_name
#: model:ir.model.fields,field_description:om_account_budget.field_crossovered_budget__display_name
#: model:ir.model.fields,field_description:om_account_budget.field_crossovered_budget_lines__display_name
msgid "Display Name"
msgstr ""
#. module: om_account_budget
#: model:ir.model.fields.selection,name:om_account_budget.selection__crossovered_budget__state__done
#: model_terms:ir.ui.view,arch_db:om_account_budget.crossovered_budget_view_form
msgid "Done"
msgstr ""
#. module: om_account_budget
#: model:ir.model.fields.selection,name:om_account_budget.selection__crossovered_budget__state__draft
#: model_terms:ir.ui.view,arch_db:om_account_budget.view_crossovered_budget_search
msgid "Draft"
msgstr ""
#. module: om_account_budget
#: model_terms:ir.ui.view,arch_db:om_account_budget.view_crossovered_budget_search
msgid "Draft Budgets"
msgstr ""
#. module: om_account_budget
#: model:ir.model.fields,field_description:om_account_budget.field_crossovered_budget__date_to
#: model:ir.model.fields,field_description:om_account_budget.field_crossovered_budget_lines__date_to
msgid "End Date"
msgstr ""
#. module: om_account_budget
#: model_terms:ir.ui.view,arch_db:om_account_budget.crossovered_budget_view_form
msgid "Entries..."
msgstr ""
#. module: om_account_budget
#: model:ir.model.fields,field_description:om_account_budget.field_crossovered_budget__message_follower_ids
msgid "Followers"
msgstr ""
#. module: om_account_budget
#: model:ir.model.fields,field_description:om_account_budget.field_crossovered_budget__message_partner_ids
msgid "Followers (Partners)"
msgstr ""
#. module: om_account_budget
#: model_terms:ir.ui.view,arch_db:om_account_budget.view_crossovered_budget_line_search
msgid "Group By"
msgstr ""
#. module: om_account_budget
#: model:ir.model.fields,field_description:om_account_budget.field_crossovered_budget__has_message
msgid "Has Message"
msgstr ""
#. module: om_account_budget
#: model:ir.model.fields,field_description:om_account_budget.field_account_budget_post__id
#: model:ir.model.fields,field_description:om_account_budget.field_crossovered_budget__id
#: model:ir.model.fields,field_description:om_account_budget.field_crossovered_budget_lines__id
msgid "ID"
msgstr ""
#. module: om_account_budget
#: model:ir.model.fields,help:om_account_budget.field_crossovered_budget__message_needaction
msgid "If checked, new messages require your attention."
msgstr ""
#. module: om_account_budget
#: model:ir.model.fields,help:om_account_budget.field_crossovered_budget__message_has_error
msgid "If checked, some messages have a delivery error."
msgstr ""
#. module: om_account_budget
#: model:ir.model.fields,field_description:om_account_budget.field_crossovered_budget_lines__is_above_budget
msgid "Is Above Budget"
msgstr ""
#. module: om_account_budget
#: model:ir.model.fields,field_description:om_account_budget.field_crossovered_budget__message_is_follower
msgid "Is Follower"
msgstr ""
#. module: om_account_budget
#: model:ir.model.fields,field_description:om_account_budget.field_account_budget_post____last_update
#: model:ir.model.fields,field_description:om_account_budget.field_crossovered_budget____last_update
#: model:ir.model.fields,field_description:om_account_budget.field_crossovered_budget_lines____last_update
msgid "Last Modified on"
msgstr ""
#. module: om_account_budget
#: model:ir.model.fields,field_description:om_account_budget.field_account_budget_post__write_uid
#: model:ir.model.fields,field_description:om_account_budget.field_crossovered_budget__write_uid
#: model:ir.model.fields,field_description:om_account_budget.field_crossovered_budget_lines__write_uid
msgid "Last Updated by"
msgstr ""
#. module: om_account_budget
#: model:ir.model.fields,field_description:om_account_budget.field_account_budget_post__write_date
#: model:ir.model.fields,field_description:om_account_budget.field_crossovered_budget__write_date
#: model:ir.model.fields,field_description:om_account_budget.field_crossovered_budget_lines__write_date
msgid "Last Updated on"
msgstr ""
#. module: om_account_budget
#: model:ir.model.fields,field_description:om_account_budget.field_crossovered_budget__message_main_attachment_id
msgid "Main Attachment"
msgstr ""
#. module: om_account_budget
#: model:ir.model.fields,field_description:om_account_budget.field_crossovered_budget__message_has_error
msgid "Message Delivery error"
msgstr ""
#. module: om_account_budget
#: model:ir.model.fields,field_description:om_account_budget.field_crossovered_budget__message_ids
msgid "Messages"
msgstr ""
#. module: om_account_budget
#: model:ir.model.fields,field_description:om_account_budget.field_account_budget_post__name
#: model:ir.model.fields,field_description:om_account_budget.field_crossovered_budget_lines__name
msgid "Name"
msgstr ""
#. module: om_account_budget
#: model_terms:ir.ui.view,arch_db:om_account_budget.view_crossovered_budget_line_search
msgid "Not Cancelled"
msgstr ""
#. module: om_account_budget
#: model:ir.model.fields,field_description:om_account_budget.field_crossovered_budget__message_needaction_counter
msgid "Number of Actions"
msgstr ""
#. module: om_account_budget
#: model:ir.model.fields,field_description:om_account_budget.field_crossovered_budget__message_has_error_counter
msgid "Number of errors"
msgstr ""
#. module: om_account_budget
#: model:ir.model.fields,help:om_account_budget.field_crossovered_budget__message_needaction_counter
msgid "Number of messages requiring action"
msgstr ""
#. module: om_account_budget
#: model:ir.model.fields,help:om_account_budget.field_crossovered_budget__message_has_error_counter
msgid "Number of messages with delivery error"
msgstr ""
#. module: om_account_budget
#: model:ir.model.fields,field_description:om_account_budget.field_crossovered_budget_lines__paid_date
msgid "Paid Date"
msgstr ""
#. module: om_account_budget
#: model_terms:ir.ui.view,arch_db:om_account_budget.crossovered_budget_view_form
msgid "Period"
msgstr ""
#. module: om_account_budget
#: model:ir.model.fields,field_description:om_account_budget.field_crossovered_budget_lines__planned_amount
#: model_terms:ir.ui.view,arch_db:om_account_budget.crossovered_budget_view_form
msgid "Planned Amount"
msgstr ""
#. module: om_account_budget
#: model_terms:ir.ui.view,arch_db:om_account_budget.view_crossovered_budget_line_graph
#: model_terms:ir.ui.view,arch_db:om_account_budget.view_crossovered_budget_line_pivot
msgid "Planned amount"
msgstr ""
#. module: om_account_budget
#: model:ir.model.fields,field_description:om_account_budget.field_crossovered_budget_lines__practical_amount
#: model_terms:ir.ui.view,arch_db:om_account_budget.crossovered_budget_view_form
#: model_terms:ir.ui.view,arch_db:om_account_budget.view_account_analytic_account_form_inherit_budget
msgid "Practical Amount"
msgstr ""
#. module: om_account_budget
#: model_terms:ir.ui.view,arch_db:om_account_budget.view_crossovered_budget_line_graph
#: model_terms:ir.ui.view,arch_db:om_account_budget.view_crossovered_budget_line_pivot
msgid "Practical amount"
msgstr ""
#. module: om_account_budget
#: model_terms:ir.ui.view,arch_db:om_account_budget.crossovered_budget_view_form
msgid "Reset to Draft"
msgstr ""
#. module: om_account_budget
#: model:ir.model.fields,field_description:om_account_budget.field_crossovered_budget__user_id
msgid "Responsible"
msgstr ""
#. module: om_account_budget
#: model:ir.model.fields,field_description:om_account_budget.field_crossovered_budget__date_from
#: model:ir.model.fields,field_description:om_account_budget.field_crossovered_budget_lines__date_from
msgid "Start Date"
msgstr ""
#. module: om_account_budget
#: model:ir.model.fields,field_description:om_account_budget.field_crossovered_budget__state
msgid "Status"
msgstr ""
#. module: om_account_budget
#. odoo-python
#: code:addons/om_account_budget/models/account_budget.py:0
#, python-format
msgid "The budget must have at least one account."
msgstr ""
#. module: om_account_budget
#: model:ir.model.fields,field_description:om_account_budget.field_crossovered_budget_lines__theoritical_amount
#: model_terms:ir.ui.view,arch_db:om_account_budget.crossovered_budget_view_form
msgid "Theoretical Amount"
msgstr ""
#. module: om_account_budget
#: model_terms:ir.ui.view,arch_db:om_account_budget.view_account_analytic_account_form_inherit_budget
msgid "Theoritical Amount"
msgstr ""
#. module: om_account_budget
#: model_terms:ir.ui.view,arch_db:om_account_budget.view_crossovered_budget_line_graph
#: model_terms:ir.ui.view,arch_db:om_account_budget.view_crossovered_budget_line_pivot
msgid "Theoritical amount"
msgstr ""
#. module: om_account_budget
#: model_terms:ir.ui.view,arch_db:om_account_budget.view_crossovered_budget_search
msgid "To Approve"
msgstr ""
#. module: om_account_budget
#: model_terms:ir.ui.view,arch_db:om_account_budget.view_crossovered_budget_search
msgid "To Approve Budgets"
msgstr ""
#. module: om_account_budget
#: model_terms:ir.actions.act_window,help:om_account_budget.act_crossovered_budget_view
msgid "Use budgets to compare actual with expected revenues and costs"
msgstr ""
#. module: om_account_budget
#: model:ir.model.fields.selection,name:om_account_budget.selection__crossovered_budget__state__validate
msgid "Validated"
msgstr ""
#. module: om_account_budget
#: model:ir.model.fields,field_description:om_account_budget.field_crossovered_budget__website_message_ids
msgid "Website Messages"
msgstr ""
#. module: om_account_budget
#: model:ir.model.fields,help:om_account_budget.field_crossovered_budget__website_message_ids
msgid "Website communication history"
msgstr ""
#. module: om_account_budget
#. odoo-python
#: code:addons/om_account_budget/models/account_budget.py:0
#, python-format
msgid ""
"You have to enter at least a budgetary position or analytic account on a "
"budget line."
msgstr ""

View file

@ -0,0 +1,5 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from . import account_budget
from . import account_analytic_account

View file

@ -0,0 +1,10 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from odoo import fields, models
class AccountAnalyticAccount(models.Model):
_inherit = "account.analytic.account"
crossovered_budget_line = fields.One2many('crossovered.budget.lines', 'analytic_account_id', 'Budget Lines')

View file

@ -0,0 +1,265 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from odoo import api, fields, models, _
from odoo.exceptions import ValidationError
# ---------------------------------------------------------
# Budgets
# ---------------------------------------------------------
class AccountBudgetPost(models.Model):
_name = "account.budget.post"
_order = "name"
_description = "Budgetary Position"
name = fields.Char('Name', required=True)
account_ids = fields.Many2many('account.account', 'account_budget_rel', 'budget_id', 'account_id', 'Accounts',
domain=[('deprecated', '=', False)])
company_id = fields.Many2one('res.company', 'Company', required=True, default=lambda self: self.env.company)
def _check_account_ids(self, vals):
# Raise an error to prevent the account.budget.post to have not specified account_ids.
# This check is done on create because require=True doesn't work on Many2many fields.
if 'account_ids' in vals:
account_ids = self.new({'account_ids': vals['account_ids']}, origin=self).account_ids
else:
account_ids = self.account_ids
if not account_ids:
raise ValidationError(_('The budget must have at least one account.'))
@api.model_create_multi
def create(self, vals_list):
for vals in vals_list:
self._check_account_ids(vals)
return super(AccountBudgetPost, self).create(vals_list)
def write(self, vals):
self._check_account_ids(vals)
return super(AccountBudgetPost, self).write(vals)
class CrossoveredBudget(models.Model):
_name = "crossovered.budget"
_description = "Budget"
_inherit = ['mail.thread']
name = fields.Char('Budget Name', required=True, states={'done': [('readonly', True)]})
user_id = fields.Many2one('res.users', 'Responsible', default=lambda self: self.env.user)
date_from = fields.Date('Start Date', required=True, states={'done': [('readonly', True)]})
date_to = fields.Date('End Date', required=True, states={'done': [('readonly', True)]})
state = fields.Selection([
('draft', 'Draft'),
('cancel', 'Cancelled'),
('confirm', 'Confirmed'),
('validate', 'Validated'),
('done', 'Done')
], 'Status', default='draft', index=True, required=True, readonly=True, copy=False, tracking=True)
crossovered_budget_line = fields.One2many('crossovered.budget.lines', 'crossovered_budget_id', 'Budget Lines',
states={'done': [('readonly', True)]}, copy=True)
company_id = fields.Many2one('res.company', 'Company', required=True, default=lambda self: self.env.company)
def action_budget_confirm(self):
self.write({'state': 'confirm'})
def action_budget_draft(self):
self.write({'state': 'draft'})
def action_budget_validate(self):
self.write({'state': 'validate'})
def action_budget_cancel(self):
self.write({'state': 'cancel'})
def action_budget_done(self):
self.write({'state': 'done'})
class CrossoveredBudgetLines(models.Model):
_name = "crossovered.budget.lines"
_description = "Budget Line"
name = fields.Char(compute='_compute_line_name')
crossovered_budget_id = fields.Many2one('crossovered.budget', 'Budget', ondelete='cascade', index=True, required=True)
analytic_account_id = fields.Many2one('account.analytic.account', 'Analytic Account')
analytic_plan_id = fields.Many2one('account.analytic.group', 'Analytic Plan', related='analytic_account_id.plan_id', readonly=True)
general_budget_id = fields.Many2one('account.budget.post', 'Budgetary Position')
date_from = fields.Date('Start Date', required=True)
date_to = fields.Date('End Date', required=True)
paid_date = fields.Date('Paid Date')
currency_id = fields.Many2one('res.currency', related='company_id.currency_id', readonly=True)
planned_amount = fields.Monetary(
'Planned Amount', required=True,
help="Amount you plan to earn/spend. Record a positive amount if it is a revenue and a negative amount if it is a cost.")
practical_amount = fields.Monetary(
compute='_compute_practical_amount', string='Practical Amount', help="Amount really earned/spent.")
theoritical_amount = fields.Monetary(
compute='_compute_theoritical_amount', string='Theoretical Amount',
help="Amount you are supposed to have earned/spent at this date.")
percentage = fields.Float(
compute='_compute_percentage', string='Achievement',
help="Comparison between practical and theoretical amount. This measure tells you if you are below or over budget.")
company_id = fields.Many2one(related='crossovered_budget_id.company_id', comodel_name='res.company',
string='Company', store=True, readonly=True)
is_above_budget = fields.Boolean(compute='_is_above_budget')
crossovered_budget_state = fields.Selection(related='crossovered_budget_id.state', string='Budget State', store=True, readonly=True)
@api.model
def read_group(self, domain, fields, groupby, offset=0, limit=None, orderby=False, lazy=True):
# overrides the default read_group in order to compute the computed fields manually for the group
fields_list = {'practical_amount', 'theoritical_amount', 'percentage'}
fields = {field.split(':', 1)[0] if field.split(':', 1)[0] in fields_list else field for field in fields}
result = super(CrossoveredBudgetLines, self).read_group(domain, fields, groupby, offset=offset, limit=limit,
orderby=orderby, lazy=lazy)
if any(x in fields for x in fields_list):
for group_line in result:
# initialise fields to compute to 0 if they are requested
if 'practical_amount' in fields:
group_line['practical_amount'] = 0
if 'theoritical_amount' in fields:
group_line['theoritical_amount'] = 0
if 'percentage' in fields:
group_line['percentage'] = 0
group_line['practical_amount'] = 0
group_line['theoritical_amount'] = 0
if group_line.get('__domain'):
all_budget_lines_that_compose_group = self.search(group_line['__domain'])
else:
all_budget_lines_that_compose_group = self.search([])
for budget_line_of_group in all_budget_lines_that_compose_group:
if 'practical_amount' in fields or 'percentage' in fields:
group_line['practical_amount'] += budget_line_of_group.practical_amount
if 'theoritical_amount' in fields or 'percentage' in fields:
group_line['theoritical_amount'] += budget_line_of_group.theoritical_amount
if 'percentage' in fields:
if group_line['theoritical_amount']:
# use a weighted average
group_line['percentage'] = float(
(group_line['practical_amount'] or 0.0) / group_line['theoritical_amount']) * 100
return result
def _is_above_budget(self):
for line in self:
if line.theoritical_amount >= 0:
line.is_above_budget = line.practical_amount > line.theoritical_amount
else:
line.is_above_budget = line.practical_amount < line.theoritical_amount
def _compute_line_name(self):
#just in case someone opens the budget line in form view
for line in self:
computed_name = line.crossovered_budget_id.name
if line.general_budget_id:
computed_name += ' - ' + line.general_budget_id.name
if line.analytic_account_id:
computed_name += ' - ' + line.analytic_account_id.name
line.name = computed_name
def _compute_practical_amount(self):
for line in self:
acc_ids = line.general_budget_id.account_ids.ids
date_to = line.date_to
date_from = line.date_from
if line.analytic_account_id.id:
analytic_line_obj = self.env['account.analytic.line']
domain = [('account_id', '=', line.analytic_account_id.id),
('date', '>=', date_from),
('date', '<=', date_to),
]
if acc_ids:
domain += [('general_account_id', 'in', acc_ids)]
where_query = analytic_line_obj._where_calc(domain)
analytic_line_obj._apply_ir_rules(where_query, 'read')
from_clause, where_clause, where_clause_params = where_query.get_sql()
select = "SELECT SUM(amount) from " + from_clause + " where " + where_clause
else:
aml_obj = self.env['account.move.line']
domain = [('account_id', 'in',
line.general_budget_id.account_ids.ids),
('date', '>=', date_from),
('date', '<=', date_to)
]
where_query = aml_obj._where_calc(domain)
aml_obj._apply_ir_rules(where_query, 'read')
from_clause, where_clause, where_clause_params = where_query.get_sql()
select = "SELECT sum(credit)-sum(debit) from " + from_clause + " where " + where_clause
self.env.cr.execute(select, where_clause_params)
line.practical_amount = self.env.cr.fetchone()[0] or 0.0
def _compute_theoritical_amount(self):
# beware: 'today' variable is mocked in the python tests and thus, its implementation matter
today = fields.Date.today()
for line in self:
if line.paid_date:
if today <= line.paid_date:
theo_amt = 0.00
else:
theo_amt = line.planned_amount
else:
line_timedelta = line.date_to - line.date_from
elapsed_timedelta = today - line.date_from
if elapsed_timedelta.days < 0:
# If the budget line has not started yet, theoretical amount should be zero
theo_amt = 0.00
elif line_timedelta.days > 0 and today < line.date_to:
# If today is between the budget line date_from and date_to
theo_amt = (elapsed_timedelta.total_seconds() / line_timedelta.total_seconds()) * line.planned_amount
else:
theo_amt = line.planned_amount
line.theoritical_amount = theo_amt
def _compute_percentage(self):
for line in self:
if line.theoritical_amount != 0.00:
line.percentage = float((line.practical_amount or 0.0) / line.theoritical_amount)
else:
line.percentage = 0.00
@api.constrains('general_budget_id', 'analytic_account_id')
def _must_have_analytical_or_budgetary_or_both(self):
if not self.analytic_account_id and not self.general_budget_id:
raise ValidationError(
_("You have to enter at least a budgetary position or analytic account on a budget line."))
def action_open_budget_entries(self):
if self.analytic_account_id:
# if there is an analytic account, then the analytic items are loaded
action = self.env['ir.actions.act_window']._for_xml_id('analytic.account_analytic_line_action_entries')
action['domain'] = [('account_id', '=', self.analytic_account_id.id),
('date', '>=', self.date_from),
('date', '<=', self.date_to)
]
if self.general_budget_id:
action['domain'] += [('general_account_id', 'in', self.general_budget_id.account_ids.ids)]
else:
# otherwise the journal entries booked on the accounts of the budgetary postition are opened
action = self.env['ir.actions.act_window']._for_xml_id('account.action_account_moves_all_a')
action['domain'] = [('account_id', 'in',
self.general_budget_id.account_ids.ids),
('date', '>=', self.date_from),
('date', '<=', self.date_to)
]
return action
@api.constrains('date_from', 'date_to')
def _line_dates_between_budget_dates(self):
for rec in self:
budget_date_from = rec.crossovered_budget_id.date_from
budget_date_to = rec.crossovered_budget_id.date_to
if rec.date_from:
date_from = rec.date_from
if date_from < budget_date_from or date_from > budget_date_to:
raise ValidationError(_('"Start Date" of the budget line should be included in the Period of the budget'))
if rec.date_to:
date_to = rec.date_to
if date_to < budget_date_from or date_to > budget_date_to:
raise ValidationError(_('"End Date" of the budget line should be included in the Period of the budget'))

View file

@ -0,0 +1,35 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<data noupdate="1">
<record id="budget_post_comp_rule" model="ir.rule">
<field name="name">Budget post multi-company</field>
<field name="model_id" ref="model_account_budget_post"/>
<field eval="True" name="global"/>
<field name="domain_force">['|',('company_id','=',False),('company_id', 'in', company_ids)]</field>
</record>
<record id="budget_comp_rule" model="ir.rule">
<field name="name">Budget multi-company</field>
<field name="model_id" ref="model_crossovered_budget"/>
<field eval="True" name="global"/>
<field name="domain_force">['|',('company_id','=',False),('company_id', 'in', company_ids)]</field>
</record>
<record id="budget_lines_comp_rule" model="ir.rule">
<field name="name">Budget lines multi-company</field>
<field name="model_id" ref="model_crossovered_budget_lines"/>
<field eval="True" name="global"/>
<field name="domain_force">['|',('company_id','=',False),('company_id', 'in', company_ids)]</field>
</record>
<record model="res.users" id="base.user_root">
<field eval="[(4,ref('analytic.group_analytic_accounting'))]" name="groups_id"/>
</record>
<record model="res.users" id="base.user_admin">
<field eval="[(4,ref('analytic.group_analytic_accounting'))]" name="groups_id"/>
</record>
</data>
</odoo>

View file

@ -0,0 +1,7 @@
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_crossovered_budget,crossovered.budget,model_crossovered_budget,account.group_account_manager,1,0,0,0
access_account_budget_post,account.budget.post,model_account_budget_post,account.group_account_manager,1,0,0,0
access_account_budget_post_accountant,account.budget.post accountant,model_account_budget_post,account.group_account_user,1,1,1,1
access_crossovered_budget_accountant,crossovered.budget accountant,model_crossovered_budget,account.group_account_user,1,1,1,1
access_crossovered_budget_lines_accountant,crossovered.budget.lines accountant,model_crossovered_budget_lines,account.group_account_user,1,1,1,1
access_budget,crossovered.budget.lines manager,model_crossovered_budget_lines,base.group_user,1,1,1,0
1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
2 access_crossovered_budget crossovered.budget model_crossovered_budget account.group_account_manager 1 0 0 0
3 access_account_budget_post account.budget.post model_account_budget_post account.group_account_manager 1 0 0 0
4 access_account_budget_post_accountant account.budget.post accountant model_account_budget_post account.group_account_user 1 1 1 1
5 access_crossovered_budget_accountant crossovered.budget accountant model_crossovered_budget account.group_account_user 1 1 1 1
6 access_crossovered_budget_lines_accountant crossovered.budget.lines accountant model_crossovered_budget_lines account.group_account_user 1 1 1 1
7 access_budget crossovered.budget.lines manager model_crossovered_budget_lines base.group_user 1 1 1 0

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 41 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 72 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="70" height="70" viewBox="0 0 70 70"><defs><path id="a" d="M4 0h61c4 0 5 1 5 5v60c0 4-1 5-5 5H4c-3 0-4-1-4-5V5c0-4 1-5 4-5z"/><linearGradient id="c" x1="100%" x2="0%" y1="0%" y2="100%"><stop offset="0%" stop-color="#DA956B"/><stop offset="100%" stop-color="#CC7039"/></linearGradient></defs><g fill="none" fill-rule="evenodd"><mask id="b" fill="#fff"><use xlink:href="#a"/></mask><g mask="url(#b)"><path fill="url(#c)" d="M0 0H70V70H0z"/><path fill="#FFF" fill-opacity=".383" d="M4 1h61c2.667 0 4.333.667 5 2V0H0v3c.667-1.333 2-2 4-2z"/><path fill="#393939" d="M4 69c-2 0-4-.146-4-4.09V40.738L18.16 24H52l1 2.045v6.137l-10.585 11.3 10.05 4.09L37.071 69H4z" opacity=".324"/><path fill="#000" fill-opacity=".383" d="M4 69h61c2.667 0 4.333-1 5-3v4H0v-4c.667 2 2 3 4 3z"/><path fill="#000" d="M53 42.084v5.66c0 1.837-1.111 3.34-3.556 3.34h-28c-2.466 0-4.444-1.503-4.444-3.34V28.34c0-1.837 1.978-3.34 4.444-3.34H49c2.444 0 4 1.368 4 3.205v5.88H37c-2.667 0-4 1.857-4 3.957 0 2.1 1.333 4.042 4 4.042h16zm-15-1.39a2.656 2.656 0 0 1-2.667-2.652A2.656 2.656 0 0 1 38 35.39a2.656 2.656 0 0 1 2.667 2.653A2.656 2.656 0 0 1 38 40.695z" opacity=".3"/><path fill="#FFF" d="M53 40.084v5.66c0 1.837-1.111 3.34-3.556 3.34h-28c-2.466 0-4.444-1.503-4.444-3.34V26.34c0-1.837 1.978-3.34 4.444-3.34H49c2.444 0 4 1.368 4 3.205v5.88H37c-2.667 0-4 1.857-4 3.957 0 2.1 1.333 4.042 4 4.042h16zm-15-1.39a2.656 2.656 0 0 1-2.667-2.652A2.656 2.656 0 0 1 38 33.39a2.656 2.656 0 0 1 2.667 2.653A2.656 2.656 0 0 1 38 38.695z"/></g></g></svg>

After

Width:  |  Height:  |  Size: 1.6 KiB

View file

@ -0,0 +1,84 @@
<section class="oe_container oe_dark">
<div class="col-md-12">
<h2 class="oe_slogan" style="font-size: 35px;color:#2C0091"><b>Odoo 16 Budget Management</b></h2>
</div>
</section>
<section class="oe_container">
<div class="oe_row oe_spaced">
<div style="text-align:center;">
<p class="fa fa-hand-o-right" style="color:CRIMSON;font-size: 25px;">
<span style="color:#2dd280;font-size: 15px;">Use budgets to compare actual with expected revenues and costs.</span>
</p><br/>
</div>
<br/>
</div>
</section>
<section class="oe_container">
<div class="oe_row oe_spaced">
<div class="oe_span12">
<h3 class="oe_slogan" style="color:#332c3c;font-size: 28px;">Budgetary Positions</h3>
<div class="oe_demo oe_picture oe_screenshot">
<img src="budgetary_postions.png">
</div>
</div>
</div>
</section>
<section class="oe_container oe_dark">
<div class="oe_row oe_spaced">
<div class="oe_span12">
<h3 class="oe_slogan" style="color:#332c3c;font-size: 28px;">Budgets</h3>
<div class="oe_demo oe_picture oe_screenshot">
<img src="budgets.png">
</div>
</div>
</div>
</section>
<section class="oe_container">
<div class="oe_row oe_spaced">
<div class="oe_span12">
<h3 class="oe_slogan" style="color:#332c3c;font-size: 28px;">Budget Analysis</h3>
<div class="oe_demo oe_picture oe_screenshot">
<img src="budget_analysis_pivot.png">
</div>
</div>
</div>
</section>
<hr style="width: 100%;height: 4px;background: #2C0091;margin: 0px 0px;">
<hr style="width: 100%;height: 4px;background: #148963;margin: 0px 0px;">
<section class="oe_container oe_dark">
<div class="oe_row ">
<div class="oe_slogan text-center">
<img src="odoo_mates.png"/>
<div style="color:#269900;">
<h3 style="color:#2C0091;font-size: 25px;">If you need any help or want more features, just contact us:</h3><br>
<h3 style="color:#2C0091;font-size: 20px;">Email: <a href="odoomates@gmail.com">odoomates@gmail.com</a> <br></h3>
</div>
<div class="oe_slogan">
<h2>
<a target="_blank" href="https://www.facebook.com/odoomate/" target="new">
<i class="fa fa-facebook-square" style="font-size:38px;"></i>
</a>
<a target="_blank" href="https://twitter.com/odoomates/" target="new">
<i class="fa fa-twitter" style="font-size:38px;"></i>
</a>
<a href="#" target="_blank">
<i class="fa fa-linkedin" style="font-size:38px;"></i>
</a>
<a target="_blank" href="https://www.youtube.com/channel/UCVKlUZP7HAhdQgs-9iTJklQ">
<i class="fa fa-youtube-play" style="font-size:38px;"></i>
</a>
</h2>
</div>
</div>
</div>
</section>
<hr style="width: 100%;height: 4px;background: #148963;margin: 0px 0px;">
<hr style="width: 100%;height: 4px;background: #2C0091;margin: 0px 0px;">

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.6 KiB

View file

@ -0,0 +1,41 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="view_account_analytic_account_form_inherit_budget" model="ir.ui.view">
<field name="name">account.analytic.account.form.inherit.budget</field>
<field name="model">account.analytic.account</field>
<field name="inherit_id" ref="analytic.view_account_analytic_account_form"/>
<field name="priority" eval="50"/>
<field name="arch" type="xml">
<xpath expr="//group[@name='main']" position='after'>
<notebook groups="account.group_account_user">
<page string="Budget Items">
<field name="crossovered_budget_line" widget="one2many_list" colspan="4" nolabel="1"
mode="tree">
<tree string="Budget Items" editable="top">
<field name="crossovered_budget_id"/>
<field name="general_budget_id"/>
<field name="date_from"/>
<field name="date_to"/>
<field name="paid_date"/>
<field name="planned_amount" widget="monetary"/>
<field name="practical_amount" sum="Practical Amount" widget="monetary"/>
<field name="theoritical_amount" sum="Theoritical Amount" widget="monetary"/>
<field name="percentage"/>
</tree>
<form string="Budget Items">
<field name="crossovered_budget_id"/>
<field name="general_budget_id"/>
<field name="date_from"/>
<field name="date_to"/>
<field name="paid_date"/>
<field name="planned_amount" widget="monetary"/>
</form>
</field>
</page>
</notebook>
</xpath>
</field>
</record>
</odoo>

View file

@ -0,0 +1,381 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="view_budget_post_search" model="ir.ui.view">
<field name="name">account.budget.post.search</field>
<field name="model">account.budget.post</field>
<field name="arch" type="xml">
<search string="Budgetary Position">
<field name="name" filter_domain="[('name','ilike',self)]" string="Budgetary Position"/>
<field name="company_id" groups="base.group_multi_company"/>
</search>
</field>
</record>
<record id="view_budget_post_tree" model="ir.ui.view">
<field name="name">account.budget.post.tree</field>
<field name="model">account.budget.post</field>
<field name="arch" type="xml">
<tree string="Budgetary Position">
<field name="name"/>
<field name="company_id" options="{'no_create': True}" groups="base.group_multi_company"/>
</tree>
</field>
</record>
<record id="open_budget_post_form" model="ir.actions.act_window">
<field name="name">Budgetary Positions</field>
<field name="res_model">account.budget.post</field>
<field name="view_mode">tree,kanban,form</field>
<field name="view_id" ref="view_budget_post_tree"/>
<field name="search_view_id" ref="view_budget_post_search"/>
</record>
<menuitem id="menu_budget_post_form"
action="open_budget_post_form"
parent="account.account_management_menu"
sequence="5"/>
<record id="view_budget_post_form" model="ir.ui.view">
<field name="name">account.budget.post.form</field>
<field name="model">account.budget.post</field>
<field name="arch" type="xml">
<form string="Budgetary Position">
<group col="4">
<field name="name"/>
<field name="company_id" groups="base.group_multi_company" options="{'no_create': True}"/>
</group>
<notebook>
<page string="Accounts">
<field name="account_ids">
<tree>
<field name="code"/>
<field name="name"/>
</tree>
</field>
</page>
</notebook>
</form>
</field>
</record>
<record id="crossovered_budget_view_form" model="ir.ui.view">
<field name="name">crossovered.budget.view.form</field>
<field name="model">crossovered.budget</field>
<field name="arch" type="xml">
<form string="Budget">
<header>
<button string="Confirm" name="action_budget_confirm" states="draft" type="object"
class="oe_highlight"/>
<button string="Approve" name="action_budget_validate" states="confirm" type="object"
class="oe_highlight"/>
<button string="Done" name="action_budget_done" states="validate" type="object"
class="oe_highlight"/>
<button string="Reset to Draft" name="action_budget_draft" states="cancel" type="object"/>
<button string="Cancel Budget" name="action_budget_cancel" states="confirm,validate" type="object"/>
<field name="state" widget="statusbar" />
</header>
<sheet string="Budget">
<div class="oe_title">
<label for="name" class="oe_edit_only"/>
<h1>
<field name="name" attrs="{'readonly':[('state','!=','draft')]}" placeholder="Budget Name"/>
</h1>
</div>
<group>
<group>
<field name="user_id" attrs="{'readonly':[('state','!=','draft')]}"/>
</group>
<group>
<label for="date_from" string="Period"/>
<div>
<field name="date_from" class="oe_inline"
attrs="{'readonly':[('state','!=','draft')]}"/>
-
<field name="date_to" class="oe_inline" attrs="{'readonly':[('state','!=','draft')]}"
nolabel="1"/>
</div>
<field name="company_id" groups="base.group_multi_company" options="{'no_create': True}"/>
</group>
</group>
<notebook>
<page string="Budget Lines">
<field name="crossovered_budget_line"
context="{'default_date_from': date_from,'default_date_to': date_to}" colspan="4"
nolabel="1" attrs="{'readonly':[('state','!=','draft')]}">
<tree string="Budget Lines" decoration-success="is_above_budget and planned_amount &gt; 0" decoration-danger="is_above_budget and planned_amount &lt; 0" editable="bottom">
<field name="general_budget_id"/>
<field name="analytic_account_id" groups="analytic.group_analytic_accounting"/>
<field name="date_from"/>
<field name="date_to"/>
<field name="paid_date" groups="base.group_no_one"/>
<field name="currency_id" invisible="1"/>
<field name="planned_amount" sum="Planned Amount"/>
<field name="practical_amount" sum="Practical Amount"/>
<field name="theoritical_amount" sum="Theoretical Amount"/>
<field name="percentage" widget="percentage" />
<button type="object" name="action_open_budget_entries" string="Entries..."
icon="fa-arrow-circle-o-right"/>
<field name="is_above_budget" invisible="1"/>
</tree>
<form string="Budget Lines">
<group>
<group>
<field name="currency_id" invisible="1"/>
<field name="general_budget_id"/>
<field name="planned_amount"/>
<field name="analytic_account_id"
groups="analytic.group_analytic_accounting"/>
</group>
<group>
<label for="date_from" string="Period"/>
<div>
<field name="date_from" class="oe_inline"/>
-
<field name="date_to" class="oe_inline"/>
</div>
<field name="paid_date" groups="base.group_no_one"/>
<field name="company_id" options="{'no_create': True}"
groups="base.group_multi_company"/>
</group>
</group>
</form>
</field>
</page>
</notebook>
</sheet>
<div class="oe_chatter">
<field name="message_follower_ids" widget="mail_followers" groups="base.group_user"/>
<field name="message_ids" widget="mail_thread"/>
</div>
</form>
</field>
</record>
<record id="crossovered_budget_view_tree" model="ir.ui.view">
<field name="name">crossovered.budget.view.tree</field>
<field name="model">crossovered.budget</field>
<field name="arch" type="xml">
<tree decoration-info="state == 'draft'" decoration-muted="state in ('done','cancel')" string="Budget">
<field name="name" colspan="1"/>
<field name="date_from"/>
<field name="date_to"/>
<field name="company_id" options="{'no_create': True}" groups="base.group_multi_company"/>
<field name="user_id"/>
<field name="state"/>
</tree>
</field>
</record>
<record id="view_crossovered_budget_kanban" model="ir.ui.view">
<field name="name">crossovered.budget.kanban</field>
<field name="model">crossovered.budget</field>
<field name="arch" type="xml">
<kanban class="o_kanban_mobile">
<field name="name"/>
<field name="date_from"/>
<field name="date_to"/>
<field name="user_id"/>
<field name="state"/>
<templates>
<t t-name="kanban-box">
<div t-attf-class="oe_kanban_global_click">
<div class="row mb4">
<div class="col-8">
<strong>
<field name="name"/>
</strong>
</div>
<div class="col-4">
<span class="float-right">
<field name="state" widget="kanban_label_selection"
options="{'classes': {'draft': 'default', 'done': 'success'}}"/>
</span>
</div>
</div>
<div class="row">
<div class="col-10">
<i class="fa fa-clock-o" role="img" aria-label="Period" title="Period"/>
<t t-esc="record.date_from.value"/>-
<t t-esc="record.date_to.value"/>
</div>
<div class="col-2">
<span class="float-right">
<img t-att-src="kanban_image('res.users', 'image_small', record.user_id.raw_value)"
t-att-title="record.user_id.value" t-att-alt="record.user_id.value" width="24" height="24"
class="oe_kanban_avatar float-right"/>
</span>
</div>
</div>
</div>
</t>
</templates>
</kanban>
</field>
</record>
<record id="view_crossovered_budget_search" model="ir.ui.view">
<field name="name">crossovered.budget.search</field>
<field name="model">crossovered.budget</field>
<field name="arch" type="xml">
<search string="Budget">
<field name="name" filter_domain="[('name','ilike',self)]" string="Budget"/>
<field name="date_from"/>
<field name="date_to"/>
<filter string="Draft" name="draft" domain="[('state','=','draft')]" help="Draft Budgets"/>
<filter string="To Approve" name="toapprove" domain="[('state','=','confirm')]"
help="To Approve Budgets"/>
<field name="state"/>
</search>
</field>
</record>
<record id="act_crossovered_budget_view" model="ir.actions.act_window">
<field name="name">Budgets</field>
<field name="res_model">crossovered.budget</field>
<field name="view_mode">tree,kanban,form</field>
<field name="view_id" ref="crossovered_budget_view_tree"/>
<field name="search_view_id" ref="view_crossovered_budget_search"/>
<field name="help" type="html">
<p class="o_view_nocontent_smiling_face">
Click to create a new budget.
</p>
<p>
Use budgets to compare actual with expected revenues and costs
</p>
</field>
</record>
<menuitem id="menu_act_crossovered_budget_view"
parent="account.menu_finance_entries_management"
name="Budgets"
action="act_crossovered_budget_view"
sequence="60"
groups="account.group_account_manager"/>
<record id="view_crossovered_budget_line_search" model="ir.ui.view">
<field name="name">account.budget.line.search</field>
<field name="model">crossovered.budget.lines</field>
<field name="arch" type="xml">
<search string="Budget Lines">
<field name="analytic_account_id"/>
<field name="crossovered_budget_id"/>
<filter name="filter_not_cancelled" string="Not Cancelled"
domain="[('crossovered_budget_state','!=','cancel')]"/>
<group expand="0" string="Group By">
<filter name="group_crossevered_budgdet_id" string="Budgets"
domain="[]" context="{'group_by':'crossovered_budget_id'}"/>
</group>
</search>
</field>
</record>
<record id="view_crossovered_budget_line_tree" model="ir.ui.view">
<field name="name">crossovered.budget.line.tree</field>
<field name="model">crossovered.budget.lines</field>
<field name="arch" type="xml">
<tree string="Budget Lines" create="0">
<field name="currency_id" invisible="1"/>
<field name="crossovered_budget_id" invisible="1"/>
<field name="general_budget_id" />
<field name="analytic_account_id" groups="analytic.group_analytic_accounting" />
<field name="date_from" />
<field name="date_to" />
<field name="paid_date" groups="base.group_no_one" />
<field name="planned_amount"/>
<field name="practical_amount"/>
<field name="theoritical_amount"/>
<field name="percentage" widget="percentage"/>
</tree>
</field>
</record>
<record id="view_crossovered_budget_line_form" model="ir.ui.view">
<field name="name">crossovered.budget.line.form</field>
<field name="model">crossovered.budget.lines</field>
<field name="arch" type="xml">
<form string="Budget Lines">
<sheet>
<group col="4">
<field name="currency_id" invisible="1"/>
<field name="crossovered_budget_state" invisible="1"/>
<field name="crossovered_budget_id"
attrs="{'readonly':[('crossovered_budget_state','!=','draft')]}"/>
<field name="analytic_account_id"
attrs="{'readonly':[('crossovered_budget_state','!=','draft')]}"/>
<field name="general_budget_id"
attrs="{'readonly':[('crossovered_budget_state','!=','draft')]}"/>
<field name="date_from"
attrs="{'readonly':[('crossovered_budget_state','!=','draft')]}"/>
<field name="date_to"
attrs="{'readonly':[('crossovered_budget_state','!=','draft')]}"/>
<field name="paid_date"
attrs="{'readonly':[('crossovered_budget_state','!=','draft')]}"/>
<field name="planned_amount"
attrs="{'readonly':[('crossovered_budget_state','!=','draft')]}"/>
<field name="practical_amount"
attrs="{'readonly':[('crossovered_budget_state','!=','draft')]}"/>
<field name="theoritical_amount"
attrs="{'readonly':[('crossovered_budget_state','!=','draft')]}"/>
<field name="percentage" widget="percentage"
attrs="{'readonly':[('crossovered_budget_state','!=','draft')]}"/>
<field name="company_id" options="{'no_create': True}"
groups="base.group_multi_company"
attrs="{'readonly':[('crossovered_budget_state','!=','draft')]}"/>
</group>
</sheet>
</form>
</field>
</record>
<record id="view_crossovered_budget_line_pivot" model="ir.ui.view">
<field name="name">crossovered.budget.line.pivot</field>
<field name="model">crossovered.budget.lines</field>
<field name="arch" type="xml">
<pivot string="Budget Lines">
<field name="crossovered_budget_id" type="row"/>
<field name="planned_amount" type="measure" string="Planned amount"/>
<field name="theoritical_amount" type="measure" string="Theoritical amount"/>
<field name="practical_amount" type="measure" string="Practical amount"/>
<field name="percentage" type="measure" widget="percentage"/>
</pivot>
</field>
</record>
<record id="view_crossovered_budget_line_graph" model="ir.ui.view">
<field name="name">crossovered.budget.line.graph</field>
<field name="model">crossovered.budget.lines</field>
<field name="arch" type="xml">
<graph string="Budget Lines">
<field name="crossovered_budget_id" type="row"/>
<field name="planned_amount" type="measure" string="Planned amount"/>
<field name="theoritical_amount" type="measure" string="Theoritical amount"/>
<field name="practical_amount" type="measure" string="Practical amount"/>
</graph>
</field>
</record>
<record id="act_crossovered_budget_lines_view" model="ir.actions.act_window">
<field name="name">Budgets Analysis</field>
<field name="res_model">crossovered.budget.lines</field>
<field name="view_mode">tree,form,pivot,graph</field>
<field name="view_id" eval="False"/>
<field name="context">{'search_default_group_crossevered_budgdet_id': True,
'search_default_filter_not_cancelled':True}</field>
</record>
<menuitem id="menu_act_crossovered_budget_lines_view"
parent="account.account_reports_management_menu"
action="act_crossovered_budget_lines_view"
sequence="20"
groups="account.group_account_user"/>
<record id="act_account_analytic_account_cb_lines" model="ir.actions.act_window">
<field name="name">Budget Items</field>
<field name="res_model">crossovered.budget.lines</field>
<field name="view_mode">tree,kanban,form</field>
<field name="context">{'search_default_analytic_account_id': [active_id],
'default_analytic_account_id': active_id}</field>
</record>
</odoo>

View file

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="res_config_settings_view_form" model="ir.ui.view">
<field name="name">res.config.settings.view.form.inherit.account.budget</field>
<field name="model">res.config.settings</field>
<field name="inherit_id" ref="account.res_config_settings_view_form"/>
<field name="arch" type="xml">
<xpath expr="//div[@id='account_budget']" position="replace"/>
</field>
</record>
</odoo>

View file

@ -0,0 +1,42 @@
[project]
name = "odoo-bringout-odoomates-om_account_budget"
version = "16.0.0"
description = "Odoo 16 Budget Management - Odoo 16 Budget Management"
authors = [
{ name = "Ernad Husremovic", email = "hernad@bring.out.ba" }
]
dependencies = [
"odoo-bringout-oca-ocb-account>=16.0.0",
"requests>=2.25.1"
]
readme = "README.md"
requires-python = ">= 3.11"
classifiers = [
"Development Status :: 5 - Production/Stable",
"Intended Audience :: Developers",
"License :: OSI Approved :: GNU Lesser General Public License v3 (LGPLv3)",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Topic :: Office/Business",
]
[project.urls]
homepage = "https://github.com/bringout/0"
repository = "https://github.com/bringout/0"
[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"
[tool.hatch.metadata]
allow-direct-references = true
[tool.hatch.build.targets.wheel]
packages = ["om_account_budget"]
[tool.rye]
managed = true
dev-dependencies = [
"pytest>=8.4.1",
]