Initial commit: OCA Mrp packages (117 packages)

This commit is contained in:
Ernad Husremovic 2025-08-29 15:43:05 +02:00
commit 277e84fd7a
4403 changed files with 395154 additions and 0 deletions

View file

@ -0,0 +1,46 @@
# Sale timesheet budget
Odoo addon: sale_timesheet_budget
## Installation
```bash
pip install odoo-bringout-oca-timesheet-sale_timesheet_budget
```
## Dependencies
This addon depends on:
- sale_timesheet
## Manifest Information
- **Name**: Sale timesheet budget
- **Version**: 16.0.1.0.0
- **Category**: Timesheet
- **License**: AGPL-3
- **Installable**: True
## Source
Based on [OCA/timesheet](https://github.com/OCA/timesheet) branch 16.0, addon `sale_timesheet_budget`.
## License
This package maintains the original AGPL-3 license from the upstream Odoo project.
## 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 Sale_timesheet_budget Module - sale_timesheet_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 sale_timesheet_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:
- [sale_timesheet](../../odoo-bringout-oca-ocb-sale_timesheet)

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 sale_timesheet_budget or install in UI.

View file

@ -0,0 +1,7 @@
# Install
```bash
pip install odoo-bringout-oca-timesheet-sale_timesheet_budget"
# or
uv pip install odoo-bringout-oca-timesheet-sale_timesheet_budget"
```

View file

@ -0,0 +1,13 @@
# Models
Detected core models and extensions in sale_timesheet_budget.
```mermaid
classDiagram
class project_project_budget
class project_project
```
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: sale_timesheet_budget. Provides features documented in upstream Odoo 16 under this addon.
- Source: OCA/OCB 16.0, addon sale_timesheet_budget
- License: LGPL-3

View file

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

View file

@ -0,0 +1,34 @@
# Security
Access control and security definitions in sale_timesheet_budget.
## Access Control Lists (ACLs)
Model access permissions defined in:
- **[ir.model.access.csv](../sale_timesheet_budget/security/ir.model.access.csv)**
- 2 model access rules
## Record Rules
Row-level security rules defined in:
```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:
- **[ir.model.access.csv](../sale_timesheet_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 sale_timesheet_budget
```

View file

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

View file

@ -0,0 +1,42 @@
[project]
name = "odoo-bringout-oca-timesheet-sale_timesheet_budget"
version = "16.0.0"
description = "Sale timesheet budget - Odoo addon"
authors = [
{ name = "Ernad Husremovic", email = "hernad@bring.out.ba" }
]
dependencies = [
"odoo-bringout-oca-timesheet-sale_timesheet>=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 = ["sale_timesheet_budget"]
[tool.rye]
managed = true
dev-dependencies = [
"pytest>=8.4.1",
]

View file

@ -0,0 +1,105 @@
=====================
Sale timesheet budget
=====================
..
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! source digest: sha256:94c50545cb7e13598acd735a98923efa2edb830462176c6259628dffccba56be
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png
:target: https://odoo-community.org/page/development-status
:alt: Beta
.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png
:target: http://www.gnu.org/licenses/agpl-3.0-standalone.html
:alt: License: AGPL-3
.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Ftimesheet-lightgray.png?logo=github
:target: https://github.com/OCA/timesheet/tree/16.0/sale_timesheet_budget
:alt: OCA/timesheet
.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png
:target: https://translation.odoo-community.org/projects/timesheet-16-0/timesheet-16-0-sale_timesheet_budget
:alt: Translate me on Weblate
.. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png
:target: https://runboat.odoo-community.org/builds?repo=OCA/timesheet&target_branch=16.0
:alt: Try me on Runboat
|badge1| |badge2| |badge3| |badge4| |badge5|
This module adds the "Budget" tab to the projects/sales orders to be able to set
some additional lines (incomes/expenses) linked to a planned budget.
**Table of contents**
.. contents::
:local:
Usage
=====
#. Go to *Projects* and create a new one, setting Customer, analytic account and Billable.
#. Go to *Sales -> Orders -> Quotations* and create a new one setting the same
customer and project previously created.
#. Alternatively, you can create a sales order with lines that creates a project.
#. Go to the project, and edit it.
#. Add some records (positive or negative) in the "Budget" tab.
#. Go to *Project Updates* button and a new line (Budget) in the
*Profitability > Revenues* section will appear with the total amount of the lines.
Known issues / Roadmap
======================
* Consider the planned hours of the tasks based on price/hour profiles.
Bug Tracker
===========
Bugs are tracked on `GitHub Issues <https://github.com/OCA/timesheet/issues>`_.
In case of trouble, please check there if your issue has already been reported.
If you spotted it first, help us to smash it by providing a detailed and welcomed
`feedback <https://github.com/OCA/timesheet/issues/new?body=module:%20sale_timesheet_budget%0Aversion:%2016.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.
Do not contact contributors directly about support or help with technical issues.
Credits
=======
Authors
~~~~~~~
* Tecnativa
Contributors
~~~~~~~~~~~~
* `Tecnativa <https://www.tecnativa.com>`_:
* Víctor Martínez
* Pedro M. Baeza
Maintainers
~~~~~~~~~~~
This module is maintained by the OCA.
.. image:: https://odoo-community.org/logo.png
:alt: Odoo Community Association
:target: https://odoo-community.org
OCA, or the Odoo Community Association, is a nonprofit organization whose
mission is to support the collaborative development of Odoo features and
promote its widespread use.
.. |maintainer-victoralmau| image:: https://github.com/victoralmau.png?size=40px
:target: https://github.com/victoralmau
:alt: victoralmau
Current `maintainer <https://odoo-community.org/page/maintainer-role>`__:
|maintainer-victoralmau|
This module is part of the `OCA/timesheet <https://github.com/OCA/timesheet/tree/16.0/sale_timesheet_budget>`_ project on GitHub.
You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.

View file

@ -0,0 +1 @@
from . import models

View file

@ -0,0 +1,17 @@
# Copyright 2022 Tecnativa - Víctor Martínez
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
{
"name": "Sale timesheet budget",
"version": "16.0.1.0.0",
"category": "Timesheet",
"website": "https://github.com/OCA/timesheet",
"author": "Tecnativa, Odoo Community Association (OCA)",
"license": "AGPL-3",
"depends": ["sale_timesheet"],
"installable": True,
"data": [
"security/ir.model.access.csv",
"views/project_project_view.xml",
],
"maintainers": ["victoralmau"],
}

View file

@ -0,0 +1,129 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * sale_timesheet_budget
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 16.0\n"
"Report-Msgid-Bugs-To: \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: sale_timesheet_budget
#: model:ir.model.fields,field_description:sale_timesheet_budget.field_project_project_budget__amount
#: model_terms:ir.ui.view,arch_db:sale_timesheet_budget.view_project_project_budget_tree
msgid "Amount"
msgstr "Iznos"
#. module: sale_timesheet_budget
#: model:ir.model.fields,field_description:sale_timesheet_budget.field_project_project_budget__analytic_account_id
msgid "Analytic Account"
msgstr "Analitički konto"
#. module: sale_timesheet_budget
#: model:ir.model.fields,help:sale_timesheet_budget.field_project_project_budget__analytic_account_id
msgid ""
"Analytic account to which this project, its tasks and its timesheets are linked. \n"
"Track the costs and revenues of your project by setting this analytic account on your related documents (e.g. sales orders, invoices, purchase orders, vendor bills, expenses etc.).\n"
"This analytic account can be changed on each task individually if necessary.\n"
"An analytic account is required in order to use timesheets."
msgstr ""
#. module: sale_timesheet_budget
#: model:ir.model.fields,field_description:sale_timesheet_budget.field_project_project__budget_amount
msgid "Budget Amount"
msgstr "Iznos budžeta"
#. module: sale_timesheet_budget
#. odoo-python
#: code:addons/sale_timesheet_budget/models/project_project.py:0
#: model:ir.model.fields,field_description:sale_timesheet_budget.field_project_project__budget_ids
#: model_terms:ir.ui.view,arch_db:sale_timesheet_budget.project_project_view_form
#, python-format
msgid "Budgets"
msgstr "Budžeti"
#. module: sale_timesheet_budget
#: model:ir.model.fields,field_description:sale_timesheet_budget.field_project_project_budget__name
msgid "Concept"
msgstr "Koncept"
#. module: sale_timesheet_budget
#: model:ir.model.fields,field_description:sale_timesheet_budget.field_project_project_budget__create_uid
msgid "Created by"
msgstr "Kreirao"
#. module: sale_timesheet_budget
#: model:ir.model.fields,field_description:sale_timesheet_budget.field_project_project_budget__create_date
msgid "Created on"
msgstr "Kreirano"
#. module: sale_timesheet_budget
#: model:ir.model.fields,field_description:sale_timesheet_budget.field_project_project_budget__date
msgid "Date"
msgstr "Datum"
#. module: sale_timesheet_budget
#: model:ir.model.fields,field_description:sale_timesheet_budget.field_project_project_budget__display_name
msgid "Display Name"
msgstr "Prikazani naziv"
#. module: sale_timesheet_budget
#: model:ir.model.fields,field_description:sale_timesheet_budget.field_project_project_budget__id
msgid "ID"
msgstr "ID"
#. module: sale_timesheet_budget
#: model:ir.model.fields,field_description:sale_timesheet_budget.field_project_project_budget____last_update
msgid "Last Modified on"
msgstr "Zadnje mijenjano"
#. module: sale_timesheet_budget
#: model:ir.model.fields,field_description:sale_timesheet_budget.field_project_project_budget__write_uid
msgid "Last Updated by"
msgstr "Zadnji ažurirao"
#. module: sale_timesheet_budget
#: model:ir.model.fields,field_description:sale_timesheet_budget.field_project_project_budget__write_date
msgid "Last Updated on"
msgstr "Zadnje ažurirano"
#. module: sale_timesheet_budget
#: model:ir.model.fields,field_description:sale_timesheet_budget.field_project_project_budget__price_unit
msgid "Product Price"
msgstr "Cijena proizvoda"
#. module: sale_timesheet_budget
#: model:ir.model,name:sale_timesheet_budget.model_project_project
#: model:ir.model.fields,field_description:sale_timesheet_budget.field_project_project_budget__project_id
msgid "Project"
msgstr "Projekat"
#. module: sale_timesheet_budget
#: model:ir.actions.act_window,name:sale_timesheet_budget.action_project_project_budget
msgid "Project Budgets"
msgstr "Budžeti projekata"
#. module: sale_timesheet_budget
#: model:ir.model,name:sale_timesheet_budget.model_project_project_budget
msgid "Project Project Budget"
msgstr "Budžet projekta"
#. module: sale_timesheet_budget
#: model:ir.model.fields,field_description:sale_timesheet_budget.field_project_project_budget__quantity
msgid "Quantity"
msgstr "Količina"
#. module: sale_timesheet_budget
#: model:ir.model.fields,field_description:sale_timesheet_budget.field_project_project_budget__sale_order_id
msgid "Sale Order"
msgstr "Prodajni nalog"
#. module: sale_timesheet_budget
#: model:ir.model.fields,field_description:sale_timesheet_budget.field_project_project_budget__sale_order_id_domain
msgid "Sale Order Id Domain"
msgstr "Domen ID-a prodajnog naloga"

View file

@ -0,0 +1,149 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * sale_timesheet_budget
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 14.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2022-06-27 11:03+0000\n"
"PO-Revision-Date: 2022-06-27 13:04+0200\n"
"Last-Translator: \n"
"Language-Team: \n"
"Language: es\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: \n"
"X-Generator: Poedit 2.3\n"
#. module: sale_timesheet_budget
#: model:ir.model.fields,field_description:sale_timesheet_budget.field_project_project_budget__amount
#: model_terms:ir.ui.view,arch_db:sale_timesheet_budget.view_project_project_budget_tree
msgid "Amount"
msgstr "Importe"
#. module: sale_timesheet_budget
#: model:ir.model.fields,field_description:sale_timesheet_budget.field_project_project_budget__analytic_account_id
msgid "Analytic Account"
msgstr "Cuenta analítica"
#. module: sale_timesheet_budget
#: model:ir.model.fields,help:sale_timesheet_budget.field_project_project_budget__analytic_account_id
msgid ""
"Analytic account to which this project, its tasks and its timesheets are "
"linked. \n"
"Track the costs and revenues of your project by setting this analytic "
"account on your related documents (e.g. sales orders, invoices, purchase "
"orders, vendor bills, expenses etc.).\n"
"This analytic account can be changed on each task individually if "
"necessary.\n"
"An analytic account is required in order to use timesheets."
msgstr ""
#. module: sale_timesheet_budget
#: model:ir.model.fields,field_description:sale_timesheet_budget.field_project_project__budget_amount
msgid "Budget Amount"
msgstr "Importe de presupuesto"
#. module: sale_timesheet_budget
#. odoo-python
#: code:addons/sale_timesheet_budget/models/project_project.py:0
#: model:ir.model.fields,field_description:sale_timesheet_budget.field_project_project__budget_ids
#: model_terms:ir.ui.view,arch_db:sale_timesheet_budget.project_project_view_form
#, python-format
msgid "Budgets"
msgstr "Presupuestos"
#. module: sale_timesheet_budget
#: model:ir.model.fields,field_description:sale_timesheet_budget.field_project_project_budget__name
msgid "Concept"
msgstr ""
#. module: sale_timesheet_budget
#: model:ir.model.fields,field_description:sale_timesheet_budget.field_project_project_budget__create_uid
msgid "Created by"
msgstr "Creado por"
#. module: sale_timesheet_budget
#: model:ir.model.fields,field_description:sale_timesheet_budget.field_project_project_budget__create_date
msgid "Created on"
msgstr "Creado el"
#. module: sale_timesheet_budget
#: model:ir.model.fields,field_description:sale_timesheet_budget.field_project_project_budget__date
msgid "Date"
msgstr ""
#. module: sale_timesheet_budget
#: model:ir.model.fields,field_description:sale_timesheet_budget.field_project_project_budget__display_name
msgid "Display Name"
msgstr "Nombre mostrado"
#. module: sale_timesheet_budget
#: model:ir.model.fields,field_description:sale_timesheet_budget.field_project_project_budget__id
msgid "ID"
msgstr "ID"
#. module: sale_timesheet_budget
#: model:ir.model.fields,field_description:sale_timesheet_budget.field_project_project_budget____last_update
msgid "Last Modified on"
msgstr "Última modificación el"
#. module: sale_timesheet_budget
#: model:ir.model.fields,field_description:sale_timesheet_budget.field_project_project_budget__write_uid
msgid "Last Updated by"
msgstr "Última Actualización por"
#. module: sale_timesheet_budget
#: model:ir.model.fields,field_description:sale_timesheet_budget.field_project_project_budget__write_date
msgid "Last Updated on"
msgstr "Actualizado el"
#. module: sale_timesheet_budget
#: model:ir.model.fields,field_description:sale_timesheet_budget.field_project_project_budget__price_unit
msgid "Product Price"
msgstr "Precio de producto"
#. module: sale_timesheet_budget
#: model:ir.model,name:sale_timesheet_budget.model_project_project
#: model:ir.model.fields,field_description:sale_timesheet_budget.field_project_project_budget__project_id
msgid "Project"
msgstr "Proyecto"
#. module: sale_timesheet_budget
#: model:ir.actions.act_window,name:sale_timesheet_budget.action_project_project_budget
msgid "Project Budgets"
msgstr ""
#. module: sale_timesheet_budget
#: model:ir.model,name:sale_timesheet_budget.model_project_project_budget
msgid "Project Project Budget"
msgstr ""
#. module: sale_timesheet_budget
#: model:ir.model.fields,field_description:sale_timesheet_budget.field_project_project_budget__quantity
msgid "Quantity"
msgstr "Cantidad"
#. module: sale_timesheet_budget
#: model:ir.model.fields,field_description:sale_timesheet_budget.field_project_project_budget__sale_order_id
msgid "Sale Order"
msgstr "Pedido de venta"
#. module: sale_timesheet_budget
#: model:ir.model.fields,field_description:sale_timesheet_budget.field_project_project_budget__sale_order_id_domain
msgid "Sale Order Id Domain"
msgstr ""
#~ msgid ""
#~ "Analytic account to which this project is linked for financial "
#~ "management. Use an analytic account to record cost and revenue on your "
#~ "project."
#~ msgstr ""
#~ "Cuenta analítica a la que se vincula este proyecto para la gestión "
#~ "financiera. Utilice una cuenta analítica para registrar los costes y los "
#~ "ingresos de su proyecto."
#~ msgid "Budget"
#~ msgstr "Presupuesto"

View file

@ -0,0 +1,159 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * sale_timesheet_budget
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 14.0\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2024-07-08 08:59+0000\n"
"Last-Translator: mymage <stefano.consolaro@mymage.it>\n"
"Language-Team: none\n"
"Language: it\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
"X-Generator: Weblate 5.6.2\n"
#. module: sale_timesheet_budget
#: model:ir.model.fields,field_description:sale_timesheet_budget.field_project_project_budget__amount
#: model_terms:ir.ui.view,arch_db:sale_timesheet_budget.view_project_project_budget_tree
msgid "Amount"
msgstr "Importo"
#. module: sale_timesheet_budget
#: model:ir.model.fields,field_description:sale_timesheet_budget.field_project_project_budget__analytic_account_id
msgid "Analytic Account"
msgstr "Conto analitico"
#. module: sale_timesheet_budget
#: model:ir.model.fields,help:sale_timesheet_budget.field_project_project_budget__analytic_account_id
msgid ""
"Analytic account to which this project, its tasks and its timesheets are "
"linked. \n"
"Track the costs and revenues of your project by setting this analytic "
"account on your related documents (e.g. sales orders, invoices, purchase "
"orders, vendor bills, expenses etc.).\n"
"This analytic account can be changed on each task individually if "
"necessary.\n"
"An analytic account is required in order to use timesheets."
msgstr ""
"Cono analitico a cui sono collegati il progetto, i suoi lavori e e suoi "
"fogli ore. \n"
"Traccia i costi e i ricavi dei progetti impostando questo conto analitico "
"nei documenti relativi (es. ordini di vendita, fatture, ordini di acquisto, "
"fatture cliente, spese, ecc.).\n"
"Questo conto analitico può esere modificato per singolo lavoro se necessario."
"\n"
"Per l'utilizzo dei fogli ore è richiesto un conto analitico."
#. module: sale_timesheet_budget
#: model:ir.model.fields,field_description:sale_timesheet_budget.field_project_project__budget_amount
msgid "Budget Amount"
msgstr "Valore budget"
#. module: sale_timesheet_budget
#. odoo-python
#: code:addons/sale_timesheet_budget/models/project_project.py:0
#: model:ir.model.fields,field_description:sale_timesheet_budget.field_project_project__budget_ids
#: model_terms:ir.ui.view,arch_db:sale_timesheet_budget.project_project_view_form
#, python-format
msgid "Budgets"
msgstr "Budget"
#. module: sale_timesheet_budget
#: model:ir.model.fields,field_description:sale_timesheet_budget.field_project_project_budget__name
msgid "Concept"
msgstr "Concetto"
#. module: sale_timesheet_budget
#: model:ir.model.fields,field_description:sale_timesheet_budget.field_project_project_budget__create_uid
msgid "Created by"
msgstr "Creato da"
#. module: sale_timesheet_budget
#: model:ir.model.fields,field_description:sale_timesheet_budget.field_project_project_budget__create_date
msgid "Created on"
msgstr "Creato il"
#. module: sale_timesheet_budget
#: model:ir.model.fields,field_description:sale_timesheet_budget.field_project_project_budget__date
msgid "Date"
msgstr "Data"
#. module: sale_timesheet_budget
#: model:ir.model.fields,field_description:sale_timesheet_budget.field_project_project_budget__display_name
msgid "Display Name"
msgstr "Nome visualizzato"
#. module: sale_timesheet_budget
#: model:ir.model.fields,field_description:sale_timesheet_budget.field_project_project_budget__id
msgid "ID"
msgstr "ID"
#. module: sale_timesheet_budget
#: model:ir.model.fields,field_description:sale_timesheet_budget.field_project_project_budget____last_update
msgid "Last Modified on"
msgstr "Ultima modifica il"
#. module: sale_timesheet_budget
#: model:ir.model.fields,field_description:sale_timesheet_budget.field_project_project_budget__write_uid
msgid "Last Updated by"
msgstr "Ultimo aggiornamento di"
#. module: sale_timesheet_budget
#: model:ir.model.fields,field_description:sale_timesheet_budget.field_project_project_budget__write_date
msgid "Last Updated on"
msgstr "Ultimo aggiornamento il"
#. module: sale_timesheet_budget
#: model:ir.model.fields,field_description:sale_timesheet_budget.field_project_project_budget__price_unit
msgid "Product Price"
msgstr "Prezzo prodotto"
#. module: sale_timesheet_budget
#: model:ir.model,name:sale_timesheet_budget.model_project_project
#: model:ir.model.fields,field_description:sale_timesheet_budget.field_project_project_budget__project_id
msgid "Project"
msgstr "Progetto"
#. module: sale_timesheet_budget
#: model:ir.actions.act_window,name:sale_timesheet_budget.action_project_project_budget
msgid "Project Budgets"
msgstr "Budget progetto"
#. module: sale_timesheet_budget
#: model:ir.model,name:sale_timesheet_budget.model_project_project_budget
msgid "Project Project Budget"
msgstr "Progettazione budget progetto"
#. module: sale_timesheet_budget
#: model:ir.model.fields,field_description:sale_timesheet_budget.field_project_project_budget__quantity
msgid "Quantity"
msgstr "Quantità"
#. module: sale_timesheet_budget
#: model:ir.model.fields,field_description:sale_timesheet_budget.field_project_project_budget__sale_order_id
msgid "Sale Order"
msgstr "Ordine di vendita"
#. module: sale_timesheet_budget
#: model:ir.model.fields,field_description:sale_timesheet_budget.field_project_project_budget__sale_order_id_domain
msgid "Sale Order Id Domain"
msgstr "Dominio ID ordine di vendita"
#~ msgid "Allowed Sale Order"
#~ msgstr "Ordine vendita consentito"
#~ msgid ""
#~ "Analytic account to which this project is linked for financial "
#~ "management. Use an analytic account to record cost and revenue on your "
#~ "project."
#~ msgstr ""
#~ "Conto analitico a cui è collegato questo progetto per la gestione "
#~ "finanziaria. Utilizzare un conto analitico per registrare i costi e "
#~ "ricavi del progetto."
#~ msgid "Budget"
#~ msgstr "Budget"

View file

@ -0,0 +1,160 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * sale_timesheet_budget
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 14.0\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2024-07-10 18:58+0000\n"
"Last-Translator: Rodrigo Sottomaior Macedo "
"<sottomaiormacedotec@sottomaiormacedo.tech>\n"
"Language-Team: none\n"
"Language: pt_BR\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Plural-Forms: nplurals=2; plural=n > 1;\n"
"X-Generator: Weblate 5.6.2\n"
#. module: sale_timesheet_budget
#: model:ir.model.fields,field_description:sale_timesheet_budget.field_project_project_budget__amount
#: model_terms:ir.ui.view,arch_db:sale_timesheet_budget.view_project_project_budget_tree
msgid "Amount"
msgstr "Montante"
#. module: sale_timesheet_budget
#: model:ir.model.fields,field_description:sale_timesheet_budget.field_project_project_budget__analytic_account_id
msgid "Analytic Account"
msgstr "Conta Analítica"
#. module: sale_timesheet_budget
#: model:ir.model.fields,help:sale_timesheet_budget.field_project_project_budget__analytic_account_id
msgid ""
"Analytic account to which this project, its tasks and its timesheets are "
"linked. \n"
"Track the costs and revenues of your project by setting this analytic "
"account on your related documents (e.g. sales orders, invoices, purchase "
"orders, vendor bills, expenses etc.).\n"
"This analytic account can be changed on each task individually if "
"necessary.\n"
"An analytic account is required in order to use timesheets."
msgstr ""
"Conta analítica à qual estão vinculados este projeto, suas tarefas e suas "
"planilhas de horas.\n"
"Acompanhe os custos e receitas do seu projeto definindo esta conta analítica "
"nos seus documentos relacionados (por exemplo, pedidos de vendas, faturas, "
"pedidos de compra, contas de fornecedores, despesas, etc.).\n"
"Esta conta analítica pode ser alterada em cada tarefa individualmente, se "
"necessário.\n"
"É necessária uma conta analítica para usar planilhas de horas."
#. module: sale_timesheet_budget
#: model:ir.model.fields,field_description:sale_timesheet_budget.field_project_project__budget_amount
msgid "Budget Amount"
msgstr "Montante Orçado"
#. module: sale_timesheet_budget
#. odoo-python
#: code:addons/sale_timesheet_budget/models/project_project.py:0
#: model:ir.model.fields,field_description:sale_timesheet_budget.field_project_project__budget_ids
#: model_terms:ir.ui.view,arch_db:sale_timesheet_budget.project_project_view_form
#, python-format
msgid "Budgets"
msgstr "Orçamentos"
#. module: sale_timesheet_budget
#: model:ir.model.fields,field_description:sale_timesheet_budget.field_project_project_budget__name
msgid "Concept"
msgstr "Conceito"
#. module: sale_timesheet_budget
#: model:ir.model.fields,field_description:sale_timesheet_budget.field_project_project_budget__create_uid
msgid "Created by"
msgstr "Criado Por"
#. module: sale_timesheet_budget
#: model:ir.model.fields,field_description:sale_timesheet_budget.field_project_project_budget__create_date
msgid "Created on"
msgstr "Criado Em"
#. module: sale_timesheet_budget
#: model:ir.model.fields,field_description:sale_timesheet_budget.field_project_project_budget__date
msgid "Date"
msgstr "Data"
#. module: sale_timesheet_budget
#: model:ir.model.fields,field_description:sale_timesheet_budget.field_project_project_budget__display_name
msgid "Display Name"
msgstr "Nome exibido"
#. module: sale_timesheet_budget
#: model:ir.model.fields,field_description:sale_timesheet_budget.field_project_project_budget__id
msgid "ID"
msgstr "ID"
#. module: sale_timesheet_budget
#: model:ir.model.fields,field_description:sale_timesheet_budget.field_project_project_budget____last_update
msgid "Last Modified on"
msgstr "Última Modificação Em"
#. module: sale_timesheet_budget
#: model:ir.model.fields,field_description:sale_timesheet_budget.field_project_project_budget__write_uid
msgid "Last Updated by"
msgstr "Última modificação feita por"
#. module: sale_timesheet_budget
#: model:ir.model.fields,field_description:sale_timesheet_budget.field_project_project_budget__write_date
msgid "Last Updated on"
msgstr "Última Atualização Feita em"
#. module: sale_timesheet_budget
#: model:ir.model.fields,field_description:sale_timesheet_budget.field_project_project_budget__price_unit
msgid "Product Price"
msgstr "Preço do Produto"
#. module: sale_timesheet_budget
#: model:ir.model,name:sale_timesheet_budget.model_project_project
#: model:ir.model.fields,field_description:sale_timesheet_budget.field_project_project_budget__project_id
msgid "Project"
msgstr "Projeto"
#. module: sale_timesheet_budget
#: model:ir.actions.act_window,name:sale_timesheet_budget.action_project_project_budget
msgid "Project Budgets"
msgstr "Orçamentos de projetos"
#. module: sale_timesheet_budget
#: model:ir.model,name:sale_timesheet_budget.model_project_project_budget
msgid "Project Project Budget"
msgstr "Projeção do Orçamento do Projeto"
#. module: sale_timesheet_budget
#: model:ir.model.fields,field_description:sale_timesheet_budget.field_project_project_budget__quantity
msgid "Quantity"
msgstr "Quantidade"
#. module: sale_timesheet_budget
#: model:ir.model.fields,field_description:sale_timesheet_budget.field_project_project_budget__sale_order_id
msgid "Sale Order"
msgstr "Pedido de Venda"
#. module: sale_timesheet_budget
#: model:ir.model.fields,field_description:sale_timesheet_budget.field_project_project_budget__sale_order_id_domain
msgid "Sale Order Id Domain"
msgstr "Domínio de ID do pedido de venda"
#~ msgid "Allowed Sale Order"
#~ msgstr "Pedido de Venda Permitido"
#~ msgid ""
#~ "Analytic account to which this project is linked for financial "
#~ "management. Use an analytic account to record cost and revenue on your "
#~ "project."
#~ msgstr ""
#~ "Conta analítica a qual este projeto é relacionado por gerenciamento "
#~ "financeiro. Use uma conta analítica para registrar o custo e receita em "
#~ "seu projeto."
#~ msgid "Budget"
#~ msgstr "Orçamento"

View file

@ -0,0 +1,129 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * sale_timesheet_budget
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 16.0\n"
"Report-Msgid-Bugs-To: \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: sale_timesheet_budget
#: model:ir.model.fields,field_description:sale_timesheet_budget.field_project_project_budget__amount
#: model_terms:ir.ui.view,arch_db:sale_timesheet_budget.view_project_project_budget_tree
msgid "Amount"
msgstr ""
#. module: sale_timesheet_budget
#: model:ir.model.fields,field_description:sale_timesheet_budget.field_project_project_budget__analytic_account_id
msgid "Analytic Account"
msgstr ""
#. module: sale_timesheet_budget
#: model:ir.model.fields,help:sale_timesheet_budget.field_project_project_budget__analytic_account_id
msgid ""
"Analytic account to which this project, its tasks and its timesheets are linked. \n"
"Track the costs and revenues of your project by setting this analytic account on your related documents (e.g. sales orders, invoices, purchase orders, vendor bills, expenses etc.).\n"
"This analytic account can be changed on each task individually if necessary.\n"
"An analytic account is required in order to use timesheets."
msgstr ""
#. module: sale_timesheet_budget
#: model:ir.model.fields,field_description:sale_timesheet_budget.field_project_project__budget_amount
msgid "Budget Amount"
msgstr ""
#. module: sale_timesheet_budget
#. odoo-python
#: code:addons/sale_timesheet_budget/models/project_project.py:0
#: model:ir.model.fields,field_description:sale_timesheet_budget.field_project_project__budget_ids
#: model_terms:ir.ui.view,arch_db:sale_timesheet_budget.project_project_view_form
#, python-format
msgid "Budgets"
msgstr ""
#. module: sale_timesheet_budget
#: model:ir.model.fields,field_description:sale_timesheet_budget.field_project_project_budget__name
msgid "Concept"
msgstr ""
#. module: sale_timesheet_budget
#: model:ir.model.fields,field_description:sale_timesheet_budget.field_project_project_budget__create_uid
msgid "Created by"
msgstr ""
#. module: sale_timesheet_budget
#: model:ir.model.fields,field_description:sale_timesheet_budget.field_project_project_budget__create_date
msgid "Created on"
msgstr ""
#. module: sale_timesheet_budget
#: model:ir.model.fields,field_description:sale_timesheet_budget.field_project_project_budget__date
msgid "Date"
msgstr ""
#. module: sale_timesheet_budget
#: model:ir.model.fields,field_description:sale_timesheet_budget.field_project_project_budget__display_name
msgid "Display Name"
msgstr ""
#. module: sale_timesheet_budget
#: model:ir.model.fields,field_description:sale_timesheet_budget.field_project_project_budget__id
msgid "ID"
msgstr ""
#. module: sale_timesheet_budget
#: model:ir.model.fields,field_description:sale_timesheet_budget.field_project_project_budget____last_update
msgid "Last Modified on"
msgstr ""
#. module: sale_timesheet_budget
#: model:ir.model.fields,field_description:sale_timesheet_budget.field_project_project_budget__write_uid
msgid "Last Updated by"
msgstr ""
#. module: sale_timesheet_budget
#: model:ir.model.fields,field_description:sale_timesheet_budget.field_project_project_budget__write_date
msgid "Last Updated on"
msgstr ""
#. module: sale_timesheet_budget
#: model:ir.model.fields,field_description:sale_timesheet_budget.field_project_project_budget__price_unit
msgid "Product Price"
msgstr ""
#. module: sale_timesheet_budget
#: model:ir.model,name:sale_timesheet_budget.model_project_project
#: model:ir.model.fields,field_description:sale_timesheet_budget.field_project_project_budget__project_id
msgid "Project"
msgstr ""
#. module: sale_timesheet_budget
#: model:ir.actions.act_window,name:sale_timesheet_budget.action_project_project_budget
msgid "Project Budgets"
msgstr ""
#. module: sale_timesheet_budget
#: model:ir.model,name:sale_timesheet_budget.model_project_project_budget
msgid "Project Project Budget"
msgstr ""
#. module: sale_timesheet_budget
#: model:ir.model.fields,field_description:sale_timesheet_budget.field_project_project_budget__quantity
msgid "Quantity"
msgstr ""
#. module: sale_timesheet_budget
#: model:ir.model.fields,field_description:sale_timesheet_budget.field_project_project_budget__sale_order_id
msgid "Sale Order"
msgstr ""
#. module: sale_timesheet_budget
#: model:ir.model.fields,field_description:sale_timesheet_budget.field_project_project_budget__sale_order_id_domain
msgid "Sale Order Id Domain"
msgstr ""

View file

@ -0,0 +1,3 @@
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from . import project_project

View file

@ -0,0 +1,100 @@
# Copyright 2022-2024 Tecnativa - Víctor Martínez
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from odoo import _lt, api, fields, models
class ProjectProject(models.Model):
_inherit = "project.project"
budget_ids = fields.One2many(
comodel_name="project.project.budget",
inverse_name="project_id",
string="Budgets",
copy=False,
)
budget_amount = fields.Float(compute="_compute_budget_amount")
@api.depends("budget_ids")
def _compute_budget_amount(self):
data = self.env["project.project.budget"].read_group(
domain=[("project_id", "in", self.ids)],
fields=["project_id", "amount:sum"],
groupby=["project_id"],
)
mapped_data = {x["project_id"][0]: x["amount"] for x in data}
for item in self:
item.budget_amount = mapped_data.get(item.id, 0)
def action_profitability_budget_item(self):
action = self.env["ir.actions.act_window"]._for_xml_id(
"sale_timesheet_budget.action_project_project_budget"
)
action["domain"] = [("project_id", "=", self.id)]
return action
def _get_profitability_labels(self):
res = super()._get_profitability_labels()
res["budgets"] = _lt("Budgets")
return res
def _get_profitability_items(self, with_action=True):
items = super()._get_profitability_items(with_action)
if not self.budget_ids:
return items
last_sequence = len(items["revenues"]["data"])
items["revenues"]["data"].append(
{
"id": "budgets",
"sequence": last_sequence + 1,
"invoiced": 0,
"to_invoice": self.budget_amount,
"action": {
"name": "action_profitability_budget_item",
"type": "object",
},
}
)
items["revenues"]["total"]["to_invoice"] += self.budget_amount
return items
class ProjectProjectBudget(models.Model):
_name = "project.project.budget"
_description = "Project Project Budget"
_order = "date, id"
date = fields.Date()
name = fields.Char(string="Concept")
project_id = fields.Many2one(
comodel_name="project.project", string="Project", required=True
)
sale_order_id_domain = fields.Binary(compute="_compute_sale_order_id_domain")
sale_order_id = fields.Many2one(
comodel_name="sale.order",
string="Sale Order",
)
analytic_account_id = fields.Many2one(related="project_id.analytic_account_id")
quantity = fields.Float(digits="Account", default=1, required=True)
price_unit = fields.Float(string="Product Price", digits="Account", required=True)
amount = fields.Float(compute="_compute_amount", store=True)
@api.depends(
"project_id", "project_id.partner_id", "project_id.analytic_account_id"
)
def _compute_sale_order_id_domain(self):
for item in self:
item.sale_order_id_domain = [
("partner_id", "=", item.project_id.partner_id.id),
(
"analytic_account_id",
"=",
item.project_id.analytic_account_id.id,
),
("state", "!=", "cancel"),
]
@api.depends("quantity", "price_unit")
def _compute_amount(self):
for item in self:
item.amount = item.quantity * item.price_unit

View file

@ -0,0 +1,4 @@
* `Tecnativa <https://www.tecnativa.com>`_:
* Víctor Martínez
* Pedro M. Baeza

View file

@ -0,0 +1,2 @@
This module adds the "Budget" tab to the projects/sales orders to be able to set
some additional lines (incomes/expenses) linked to a planned budget.

View file

@ -0,0 +1 @@
* Consider the planned hours of the tasks based on price/hour profiles.

View file

@ -0,0 +1,8 @@
#. Go to *Projects* and create a new one, setting Customer, analytic account and Billable.
#. Go to *Sales -> Orders -> Quotations* and create a new one setting the same
customer and project previously created.
#. Alternatively, you can create a sales order with lines that creates a project.
#. Go to the project, and edit it.
#. Add some records (positive or negative) in the "Budget" tab.
#. Go to *Project Updates* button and a new line (Budget) in the
*Profitability > Revenues* section will appear with the total amount of the lines.

View file

@ -0,0 +1,3 @@
id,name,model_id/id,group_id/id,perm_read,perm_write,perm_create,perm_unlink
access_project_project_budget_admin,project_project_budget_portal,model_project_project_budget,project.group_project_manager,1,1,1,1
access_project_project_budget_user,project_project_budget_user,model_project_project_budget,project.group_project_user,1,0,0,0
1 id name model_id/id group_id/id perm_read perm_write perm_create perm_unlink
2 access_project_project_budget_admin project_project_budget_portal model_project_project_budget project.group_project_manager 1 1 1 1
3 access_project_project_budget_user project_project_budget_user model_project_project_budget project.group_project_user 1 0 0 0

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.2 KiB

View file

@ -0,0 +1,451 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="generator" content="Docutils: https://docutils.sourceforge.io/" />
<title>Sale timesheet budget</title>
<style type="text/css">
/*
:Author: David Goodger (goodger@python.org)
:Id: $Id: html4css1.css 9511 2024-01-13 09:50:07Z milde $
:Copyright: This stylesheet has been placed in the public domain.
Default cascading style sheet for the HTML output of Docutils.
Despite the name, some widely supported CSS2 features are used.
See https://docutils.sourceforge.io/docs/howto/html-stylesheets.html for how to
customize this style sheet.
*/
/* used to remove borders from tables and images */
.borderless, table.borderless td, table.borderless th {
border: 0 }
table.borderless td, table.borderless th {
/* Override padding for "table.docutils td" with "! important".
The right padding separates the table cells. */
padding: 0 0.5em 0 0 ! important }
.first {
/* Override more specific margin styles with "! important". */
margin-top: 0 ! important }
.last, .with-subtitle {
margin-bottom: 0 ! important }
.hidden {
display: none }
.subscript {
vertical-align: sub;
font-size: smaller }
.superscript {
vertical-align: super;
font-size: smaller }
a.toc-backref {
text-decoration: none ;
color: black }
blockquote.epigraph {
margin: 2em 5em ; }
dl.docutils dd {
margin-bottom: 0.5em }
object[type="image/svg+xml"], object[type="application/x-shockwave-flash"] {
overflow: hidden;
}
/* Uncomment (and remove this text!) to get bold-faced definition list terms
dl.docutils dt {
font-weight: bold }
*/
div.abstract {
margin: 2em 5em }
div.abstract p.topic-title {
font-weight: bold ;
text-align: center }
div.admonition, div.attention, div.caution, div.danger, div.error,
div.hint, div.important, div.note, div.tip, div.warning {
margin: 2em ;
border: medium outset ;
padding: 1em }
div.admonition p.admonition-title, div.hint p.admonition-title,
div.important p.admonition-title, div.note p.admonition-title,
div.tip p.admonition-title {
font-weight: bold ;
font-family: sans-serif }
div.attention p.admonition-title, div.caution p.admonition-title,
div.danger p.admonition-title, div.error p.admonition-title,
div.warning p.admonition-title, .code .error {
color: red ;
font-weight: bold ;
font-family: sans-serif }
/* Uncomment (and remove this text!) to get reduced vertical space in
compound paragraphs.
div.compound .compound-first, div.compound .compound-middle {
margin-bottom: 0.5em }
div.compound .compound-last, div.compound .compound-middle {
margin-top: 0.5em }
*/
div.dedication {
margin: 2em 5em ;
text-align: center ;
font-style: italic }
div.dedication p.topic-title {
font-weight: bold ;
font-style: normal }
div.figure {
margin-left: 2em ;
margin-right: 2em }
div.footer, div.header {
clear: both;
font-size: smaller }
div.line-block {
display: block ;
margin-top: 1em ;
margin-bottom: 1em }
div.line-block div.line-block {
margin-top: 0 ;
margin-bottom: 0 ;
margin-left: 1.5em }
div.sidebar {
margin: 0 0 0.5em 1em ;
border: medium outset ;
padding: 1em ;
background-color: #ffffee ;
width: 40% ;
float: right ;
clear: right }
div.sidebar p.rubric {
font-family: sans-serif ;
font-size: medium }
div.system-messages {
margin: 5em }
div.system-messages h1 {
color: red }
div.system-message {
border: medium outset ;
padding: 1em }
div.system-message p.system-message-title {
color: red ;
font-weight: bold }
div.topic {
margin: 2em }
h1.section-subtitle, h2.section-subtitle, h3.section-subtitle,
h4.section-subtitle, h5.section-subtitle, h6.section-subtitle {
margin-top: 0.4em }
h1.title {
text-align: center }
h2.subtitle {
text-align: center }
hr.docutils {
width: 75% }
img.align-left, .figure.align-left, object.align-left, table.align-left {
clear: left ;
float: left ;
margin-right: 1em }
img.align-right, .figure.align-right, object.align-right, table.align-right {
clear: right ;
float: right ;
margin-left: 1em }
img.align-center, .figure.align-center, object.align-center {
display: block;
margin-left: auto;
margin-right: auto;
}
table.align-center {
margin-left: auto;
margin-right: auto;
}
.align-left {
text-align: left }
.align-center {
clear: both ;
text-align: center }
.align-right {
text-align: right }
/* reset inner alignment in figures */
div.align-right {
text-align: inherit }
/* div.align-center * { */
/* text-align: left } */
.align-top {
vertical-align: top }
.align-middle {
vertical-align: middle }
.align-bottom {
vertical-align: bottom }
ol.simple, ul.simple {
margin-bottom: 1em }
ol.arabic {
list-style: decimal }
ol.loweralpha {
list-style: lower-alpha }
ol.upperalpha {
list-style: upper-alpha }
ol.lowerroman {
list-style: lower-roman }
ol.upperroman {
list-style: upper-roman }
p.attribution {
text-align: right ;
margin-left: 50% }
p.caption {
font-style: italic }
p.credits {
font-style: italic ;
font-size: smaller }
p.label {
white-space: nowrap }
p.rubric {
font-weight: bold ;
font-size: larger ;
color: maroon ;
text-align: center }
p.sidebar-title {
font-family: sans-serif ;
font-weight: bold ;
font-size: larger }
p.sidebar-subtitle {
font-family: sans-serif ;
font-weight: bold }
p.topic-title {
font-weight: bold }
pre.address {
margin-bottom: 0 ;
margin-top: 0 ;
font: inherit }
pre.literal-block, pre.doctest-block, pre.math, pre.code {
margin-left: 2em ;
margin-right: 2em }
pre.code .ln { color: gray; } /* line numbers */
pre.code, code { background-color: #eeeeee }
pre.code .comment, code .comment { color: #5C6576 }
pre.code .keyword, code .keyword { color: #3B0D06; font-weight: bold }
pre.code .literal.string, code .literal.string { color: #0C5404 }
pre.code .name.builtin, code .name.builtin { color: #352B84 }
pre.code .deleted, code .deleted { background-color: #DEB0A1}
pre.code .inserted, code .inserted { background-color: #A3D289}
span.classifier {
font-family: sans-serif ;
font-style: oblique }
span.classifier-delimiter {
font-family: sans-serif ;
font-weight: bold }
span.interpreted {
font-family: sans-serif }
span.option {
white-space: nowrap }
span.pre {
white-space: pre }
span.problematic, pre.problematic {
color: red }
span.section-subtitle {
/* font-size relative to parent (h1..h6 element) */
font-size: 80% }
table.citation {
border-left: solid 1px gray;
margin-left: 1px }
table.docinfo {
margin: 2em 4em }
table.docutils {
margin-top: 0.5em ;
margin-bottom: 0.5em }
table.footnote {
border-left: solid 1px black;
margin-left: 1px }
table.docutils td, table.docutils th,
table.docinfo td, table.docinfo th {
padding-left: 0.5em ;
padding-right: 0.5em ;
vertical-align: top }
table.docutils th.field-name, table.docinfo th.docinfo-name {
font-weight: bold ;
text-align: left ;
white-space: nowrap ;
padding-left: 0 }
/* "booktabs" style (no vertical lines) */
table.docutils.booktabs {
border: 0px;
border-top: 2px solid;
border-bottom: 2px solid;
border-collapse: collapse;
}
table.docutils.booktabs * {
border: 0px;
}
table.docutils.booktabs th {
border-bottom: thin solid;
text-align: left;
}
h1 tt.docutils, h2 tt.docutils, h3 tt.docutils,
h4 tt.docutils, h5 tt.docutils, h6 tt.docutils {
font-size: 100% }
ul.auto-toc {
list-style-type: none }
</style>
</head>
<body>
<div class="document" id="sale-timesheet-budget">
<h1 class="title">Sale timesheet budget</h1>
<!-- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! source digest: sha256:94c50545cb7e13598acd735a98923efa2edb830462176c6259628dffccba56be
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->
<p><a class="reference external image-reference" href="https://odoo-community.org/page/development-status"><img alt="Beta" src="https://img.shields.io/badge/maturity-Beta-yellow.png" /></a> <a class="reference external image-reference" href="http://www.gnu.org/licenses/agpl-3.0-standalone.html"><img alt="License: AGPL-3" src="https://img.shields.io/badge/licence-AGPL--3-blue.png" /></a> <a class="reference external image-reference" href="https://github.com/OCA/timesheet/tree/16.0/sale_timesheet_budget"><img alt="OCA/timesheet" src="https://img.shields.io/badge/github-OCA%2Ftimesheet-lightgray.png?logo=github" /></a> <a class="reference external image-reference" href="https://translation.odoo-community.org/projects/timesheet-16-0/timesheet-16-0-sale_timesheet_budget"><img alt="Translate me on Weblate" src="https://img.shields.io/badge/weblate-Translate%20me-F47D42.png" /></a> <a class="reference external image-reference" href="https://runboat.odoo-community.org/builds?repo=OCA/timesheet&amp;target_branch=16.0"><img alt="Try me on Runboat" src="https://img.shields.io/badge/runboat-Try%20me-875A7B.png" /></a></p>
<p>This module adds the “Budget” tab to the projects/sales orders to be able to set
some additional lines (incomes/expenses) linked to a planned budget.</p>
<p><strong>Table of contents</strong></p>
<div class="contents local topic" id="contents">
<ul class="simple">
<li><a class="reference internal" href="#usage" id="toc-entry-1">Usage</a></li>
<li><a class="reference internal" href="#known-issues-roadmap" id="toc-entry-2">Known issues / Roadmap</a></li>
<li><a class="reference internal" href="#bug-tracker" id="toc-entry-3">Bug Tracker</a></li>
<li><a class="reference internal" href="#credits" id="toc-entry-4">Credits</a><ul>
<li><a class="reference internal" href="#authors" id="toc-entry-5">Authors</a></li>
<li><a class="reference internal" href="#contributors" id="toc-entry-6">Contributors</a></li>
<li><a class="reference internal" href="#maintainers" id="toc-entry-7">Maintainers</a></li>
</ul>
</li>
</ul>
</div>
<div class="section" id="usage">
<h1><a class="toc-backref" href="#toc-entry-1">Usage</a></h1>
<ol class="arabic simple">
<li>Go to <em>Projects</em> and create a new one, setting Customer, analytic account and Billable.</li>
<li>Go to <em>Sales -&gt; Orders -&gt; Quotations</em> and create a new one setting the same
customer and project previously created.</li>
<li>Alternatively, you can create a sales order with lines that creates a project.</li>
<li>Go to the project, and edit it.</li>
<li>Add some records (positive or negative) in the “Budget” tab.</li>
<li>Go to <em>Project Updates</em> button and a new line (Budget) in the
<em>Profitability &gt; Revenues</em> section will appear with the total amount of the lines.</li>
</ol>
</div>
<div class="section" id="known-issues-roadmap">
<h1><a class="toc-backref" href="#toc-entry-2">Known issues / Roadmap</a></h1>
<ul class="simple">
<li>Consider the planned hours of the tasks based on price/hour profiles.</li>
</ul>
</div>
<div class="section" id="bug-tracker">
<h1><a class="toc-backref" href="#toc-entry-3">Bug Tracker</a></h1>
<p>Bugs are tracked on <a class="reference external" href="https://github.com/OCA/timesheet/issues">GitHub Issues</a>.
In case of trouble, please check there if your issue has already been reported.
If you spotted it first, help us to smash it by providing a detailed and welcomed
<a class="reference external" href="https://github.com/OCA/timesheet/issues/new?body=module:%20sale_timesheet_budget%0Aversion:%2016.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**">feedback</a>.</p>
<p>Do not contact contributors directly about support or help with technical issues.</p>
</div>
<div class="section" id="credits">
<h1><a class="toc-backref" href="#toc-entry-4">Credits</a></h1>
<div class="section" id="authors">
<h2><a class="toc-backref" href="#toc-entry-5">Authors</a></h2>
<ul class="simple">
<li>Tecnativa</li>
</ul>
</div>
<div class="section" id="contributors">
<h2><a class="toc-backref" href="#toc-entry-6">Contributors</a></h2>
<ul class="simple">
<li><a class="reference external" href="https://www.tecnativa.com">Tecnativa</a>:<ul>
<li>Víctor Martínez</li>
<li>Pedro M. Baeza</li>
</ul>
</li>
</ul>
</div>
<div class="section" id="maintainers">
<h2><a class="toc-backref" href="#toc-entry-7">Maintainers</a></h2>
<p>This module is maintained by the OCA.</p>
<a class="reference external image-reference" href="https://odoo-community.org">
<img alt="Odoo Community Association" src="https://odoo-community.org/logo.png" />
</a>
<p>OCA, or the Odoo Community Association, is a nonprofit organization whose
mission is to support the collaborative development of Odoo features and
promote its widespread use.</p>
<p>Current <a class="reference external" href="https://odoo-community.org/page/maintainer-role">maintainer</a>:</p>
<p><a class="reference external image-reference" href="https://github.com/victoralmau"><img alt="victoralmau" src="https://github.com/victoralmau.png?size=40px" /></a></p>
<p>This module is part of the <a class="reference external" href="https://github.com/OCA/timesheet/tree/16.0/sale_timesheet_budget">OCA/timesheet</a> project on GitHub.</p>
<p>You are welcome to contribute. To learn how please visit <a class="reference external" href="https://odoo-community.org/page/Contribute">https://odoo-community.org/page/Contribute</a>.</p>
</div>
</div>
</div>
</body>
</html>

View file

@ -0,0 +1,3 @@
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from . import test_sale_timesheet_budget

View file

@ -0,0 +1,65 @@
# Copyright 2022 Tecnativa - Víctor Martínez
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from odoo.tests import Form
from odoo.addons.base.tests.common import BaseCommon
class TestSaleTimesheetBudget(BaseCommon):
@classmethod
def setUpClass(cls):
super().setUpClass()
cls.customer = cls.env["res.partner"].create({"name": "Mr Odoo"})
cls.plan = cls.env["account.analytic.plan"].create({"name": "Test plan"})
cls.analytic_account = cls.env["account.analytic.account"].create(
{
"name": "Test account",
"partner_id": cls.customer.id,
"plan_id": cls.plan.id,
}
)
cls.sale_order = cls.env["sale.order"].create(
{
"partner_id": cls.customer.id,
"analytic_account_id": cls.analytic_account.id,
}
)
cls.project = cls.env["project.project"].create(
{
"name": "Test project",
"partner_id": cls.customer.id,
"analytic_account_id": cls.analytic_account.id,
"allow_billable": True,
}
)
def test_project_budget(self):
project_form = Form(self.project)
with project_form.budget_ids.new() as budget_form:
budget_form.sale_order_id = self.sale_order
budget_form.quantity = 2
budget_form.price_unit = 10
with project_form.budget_ids.new() as budget_form:
budget_form.sale_order_id = self.sale_order
budget_form.quantity = -1
budget_form.price_unit = 10
project_form.save()
self.assertEqual(self.project.budget_amount, 10)
labels = self.project._get_profitability_labels()
self.assertIn("budgets", labels)
data = self.project.get_panel_data()
revenues = data["profitability_items"]["revenues"]
self.assertEqual(len(revenues["data"]), 1)
revenues_data = revenues["data"][0]
self.assertEqual(revenues_data["id"], "budgets")
self.assertEqual(revenues_data["invoiced"], 0)
self.assertEqual(revenues_data["to_invoice"], 10)
expected_action = {"name": "action_profitability_budget_item", "type": "object"}
self.assertEqual(revenues_data["action"], expected_action)
self.assertEqual(revenues["total"]["invoiced"], 0)
self.assertEqual(revenues["total"]["to_invoice"], 10)
res = self.project.action_profitability_budget_item()
records = self.env[res["res_model"]].search(res["domain"])
self.assertEqual(len(records), 2)
self.assertEqual(sum(records.mapped("amount")), 10)

View file

@ -0,0 +1,53 @@
<odoo>
<record id="view_project_project_budget_tree" model="ir.ui.view">
<field name="model">project.project.budget</field>
<field name="arch" type="xml">
<tree editable="bottom">
<field name="project_id" />
<field name="sale_order_id_domain" invisible="1" />
<field
name="sale_order_id"
required="1"
attrs="{'column_invisible': [('parent.sale_order_id', '!=', False)]}"
domain="sale_order_id_domain"
/>
<field name="date" optional="show" />
<field name="name" optional="show" />
<field name="quantity" optional="show" />
<field name="price_unit" />
<field name="amount" sum="Amount" optional="show" />
</tree>
</field>
</record>
<record id="view_project_project_budget_tree_custom" model="ir.ui.view">
<field name="model">project.project.budget</field>
<field name="inherit_id" ref="view_project_project_budget_tree" />
<field name="mode">primary</field>
<field name="priority">1000</field>
<field name="arch" type="xml">
<field name="project_id" position="attributes">
<attribute name="invisible">1</attribute>
</field>
</field>
</record>
<record id="project_project_view_form" model="ir.ui.view">
<field name="name">project.project.form.inherit - Add budget</field>
<field name="model">project.project</field>
<field name="inherit_id" ref="sale_timesheet.project_project_view_form" />
<field name="arch" type="xml">
<page name="settings" position="after">
<page name="budgets" string="Budgets">
<field
name="budget_ids"
context="{'default_sale_order_id': sale_order_id, 'tree_view_ref': 'sale_timesheet_budget.view_project_project_budget_tree_custom', 'default_project_id': id}"
/>
</page>
</page>
</field>
</record>
<record id="action_project_project_budget" model="ir.actions.act_window">
<field name="name">Project Budgets</field>
<field name="res_model">project.project.budget</field>
<field name="view_mode">tree</field>
</record>
</odoo>