mirror of
https://github.com/bringout/oca-ocb-l10n_europe.git
synced 2026-04-27 01:02:01 +02:00
Initial commit: L10N_Europe packages
This commit is contained in:
commit
9803722600
2377 changed files with 380711 additions and 0 deletions
49
odoo-bringout-oca-ocb-l10n_it_edi_doi/README.md
Normal file
49
odoo-bringout-oca-ocb-l10n_it_edi_doi/README.md
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
# Italy - Declaration of Intent
|
||||
|
||||
|
||||
Add support for the Declaration of Intent (Dichiarazione di Intento) to the Italian localization.
|
||||
|
||||
|
||||
## Installation
|
||||
|
||||
```bash
|
||||
pip install odoo-bringout-oca-ocb-l10n_it_edi_doi
|
||||
```
|
||||
|
||||
## Dependencies
|
||||
|
||||
This addon depends on:
|
||||
- l10n_it_edi
|
||||
- sale
|
||||
|
||||
## Manifest Information
|
||||
|
||||
- **Name**: Italy - Declaration of Intent
|
||||
- **Version**: 0.1
|
||||
- **Category**: Accounting/Localizations
|
||||
- **License**: LGPL-3
|
||||
- **Installable**: False
|
||||
|
||||
## Source
|
||||
|
||||
Based on [OCA/OCB](https://github.com/OCA/OCB) branch 16.0, addon `l10n_it_edi_doi`.
|
||||
|
||||
## License
|
||||
|
||||
This package maintains the original LGPL-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
|
||||
32
odoo-bringout-oca-ocb-l10n_it_edi_doi/doc/ARCHITECTURE.md
Normal file
32
odoo-bringout-oca-ocb-l10n_it_edi_doi/doc/ARCHITECTURE.md
Normal 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 L10n_it_edi_doi Module - l10n_it_edi_doi
|
||||
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.
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
# Configuration
|
||||
|
||||
Refer to Odoo settings for l10n_it_edi_doi. Configure related models, access rights, and options as needed.
|
||||
3
odoo-bringout-oca-ocb-l10n_it_edi_doi/doc/CONTROLLERS.md
Normal file
3
odoo-bringout-oca-ocb-l10n_it_edi_doi/doc/CONTROLLERS.md
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
# Controllers
|
||||
|
||||
This module does not define custom HTTP controllers.
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
# Dependencies
|
||||
|
||||
This addon depends on:
|
||||
|
||||
- [l10n_it_edi](../../odoo-bringout-oca-ocb-l10n_it_edi)
|
||||
- [sale](../../odoo-bringout-oca-ocb-sale)
|
||||
4
odoo-bringout-oca-ocb-l10n_it_edi_doi/doc/FAQ.md
Normal file
4
odoo-bringout-oca-ocb-l10n_it_edi_doi/doc/FAQ.md
Normal 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 l10n_it_edi_doi or install in UI.
|
||||
7
odoo-bringout-oca-ocb-l10n_it_edi_doi/doc/INSTALL.md
Normal file
7
odoo-bringout-oca-ocb-l10n_it_edi_doi/doc/INSTALL.md
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
# Install
|
||||
|
||||
```bash
|
||||
pip install odoo-bringout-oca-ocb-l10n_it_edi_doi"
|
||||
# or
|
||||
uv pip install odoo-bringout-oca-ocb-l10n_it_edi_doi"
|
||||
```
|
||||
20
odoo-bringout-oca-ocb-l10n_it_edi_doi/doc/MODELS.md
Normal file
20
odoo-bringout-oca-ocb-l10n_it_edi_doi/doc/MODELS.md
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
# Models
|
||||
|
||||
Detected core models and extensions in l10n_it_edi_doi.
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
class l10n_it_edi_doi_declaration_of_intent
|
||||
class account_chart_template
|
||||
class account_fiscal_position
|
||||
class account_move
|
||||
class account_tax
|
||||
class res_company
|
||||
class res_partner
|
||||
class sale_order
|
||||
class sale_order_line
|
||||
```
|
||||
|
||||
Notes
|
||||
- Classes show model technical names; fields omitted for brevity.
|
||||
- Items listed under _inherit are extensions of existing models.
|
||||
6
odoo-bringout-oca-ocb-l10n_it_edi_doi/doc/OVERVIEW.md
Normal file
6
odoo-bringout-oca-ocb-l10n_it_edi_doi/doc/OVERVIEW.md
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
# Overview
|
||||
|
||||
Packaged Odoo addon: l10n_it_edi_doi. Provides features documented in upstream Odoo 16 under this addon.
|
||||
|
||||
- Source: OCA/OCB 16.0, addon l10n_it_edi_doi
|
||||
- License: LGPL-3
|
||||
3
odoo-bringout-oca-ocb-l10n_it_edi_doi/doc/REPORTS.md
Normal file
3
odoo-bringout-oca-ocb-l10n_it_edi_doi/doc/REPORTS.md
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
# Reports
|
||||
|
||||
This module does not define custom reports.
|
||||
34
odoo-bringout-oca-ocb-l10n_it_edi_doi/doc/SECURITY.md
Normal file
34
odoo-bringout-oca-ocb-l10n_it_edi_doi/doc/SECURITY.md
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
# Security
|
||||
|
||||
Access control and security definitions in l10n_it_edi_doi.
|
||||
|
||||
## Access Control Lists (ACLs)
|
||||
|
||||
Model access permissions defined in:
|
||||
- **[ir.model.access.csv](../l10n_it_edi_doi/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](../l10n_it_edi_doi/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
|
||||
|
|
@ -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.
|
||||
7
odoo-bringout-oca-ocb-l10n_it_edi_doi/doc/USAGE.md
Normal file
7
odoo-bringout-oca-ocb-l10n_it_edi_doi/doc/USAGE.md
Normal 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 l10n_it_edi_doi
|
||||
```
|
||||
8
odoo-bringout-oca-ocb-l10n_it_edi_doi/doc/WIZARDS.md
Normal file
8
odoo-bringout-oca-ocb-l10n_it_edi_doi/doc/WIZARDS.md
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
# Wizards
|
||||
|
||||
Transient models exposed as UI wizards in l10n_it_edi_doi.
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
class SaleAdvancePaymentInv
|
||||
```
|
||||
|
|
@ -0,0 +1,59 @@
|
|||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from . import models
|
||||
from . import wizard
|
||||
|
||||
from odoo import api, SUPERUSER_ID
|
||||
import logging
|
||||
|
||||
_logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def _l10n_it_edi_doi_post_init(cr, registry):
|
||||
""" Update existing companies that have the Italian Chart of Accounts set """
|
||||
env = api.Environment(cr, SUPERUSER_ID, {})
|
||||
chart_template = env.ref('l10n_it.l10n_it_chart_template_generic', raise_if_not_found=False)
|
||||
if chart_template:
|
||||
for company in env['res.company'].search([('chart_template_id', '=', chart_template.id)]):
|
||||
_logger.info("Company %s already has the Italian localization installed, updating...", company.name)
|
||||
|
||||
# Create the declaration of intent fiscal position
|
||||
doi_fp_template = env.ref('l10n_it_edi_doi.declaration_of_intent_fiscal_position')
|
||||
doi_fp_vals = ((doi_fp_template, chart_template._get_fp_vals(company, doi_fp_template)),)
|
||||
doi_fp = chart_template._create_records_with_xmlid('account.fiscal.position', doi_fp_vals, company)
|
||||
|
||||
# Create the declaration of intent tax
|
||||
doi_tax_template = env.ref('l10n_it_edi_doi.00di')
|
||||
tax_template_ref = doi_tax_template._generate_tax(company)['tax_template_to_tax']
|
||||
doi_tax = tax_template_ref[doi_tax_template]
|
||||
doi_tax.write({
|
||||
'l10n_it_has_exoneration': True,
|
||||
'l10n_it_kind_exoneration': 'N3.5',
|
||||
'l10n_it_law_reference': 'art. 8, c. 1, lett. c) D.P.R. 633/1972',
|
||||
})
|
||||
|
||||
# Create the fiscal position tax mappings
|
||||
# Add all the taxes needed for the fiscal position to `tax_template_ref`
|
||||
for tax_template_id, external_xml_id in doi_fp_template.tax_ids.tax_src_id.get_external_id().items():
|
||||
tax_template = env['account.tax.template'].browse(tax_template_id)
|
||||
module, xml_id = external_xml_id.split('.')
|
||||
tax = env.ref('%s.%s_%s' % (module, company.id, xml_id), raise_if_not_found=False)
|
||||
if tax:
|
||||
tax_template_ref[tax_template] = tax
|
||||
# Gather all the info for the tax mappings
|
||||
doi_fp_tax_template_vals = []
|
||||
for tax in doi_fp_template.tax_ids:
|
||||
tax_src_id = tax_template_ref.get(tax.tax_src_id)
|
||||
tax_dest_id = tax_template_ref.get(tax.tax_dest_id)
|
||||
if tax_src_id is None or tax_dest_id is None:
|
||||
continue
|
||||
doi_fp_tax_template_vals.append((tax, {
|
||||
'tax_src_id': tax_src_id.id,
|
||||
'tax_dest_id': tax_dest_id.id or False,
|
||||
'position_id': doi_fp.id,
|
||||
}))
|
||||
chart_template._create_records_with_xmlid('account.fiscal.position.tax', doi_fp_tax_template_vals, company)
|
||||
|
||||
# Set the info on the company
|
||||
company.l10n_it_edi_doi_tax_id = doi_tax
|
||||
company.l10n_it_edi_doi_fiscal_position_id = doi_fp
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
{
|
||||
'name': 'Italy - Declaration of Intent',
|
||||
'version': '0.1',
|
||||
'depends': [
|
||||
'l10n_it_edi',
|
||||
'sale',
|
||||
],
|
||||
'description': """
|
||||
Add support for the Declaration of Intent (Dichiarazione di Intento) to the Italian localization.
|
||||
""",
|
||||
'category': 'Accounting/Localizations',
|
||||
'website': 'https://www.odoo.com/documentation/17.0/applications/finance/fiscal_localizations/italy.html',
|
||||
'data': [
|
||||
'security/ir.model.access.csv',
|
||||
'data/account_tax_template.xml',
|
||||
'data/account_fiscal_position_template_data.xml',
|
||||
'data/invoice_it_template.xml',
|
||||
'views/l10n_it_edi_doi_declaration_of_intent_views.xml',
|
||||
'views/account_move_views.xml',
|
||||
'views/report_invoice.xml',
|
||||
'views/res_partner_views.xml',
|
||||
'views/sale_ir_actions_report_templates.xml',
|
||||
'views/sale_order_views.xml',
|
||||
],
|
||||
'license': 'LGPL-3',
|
||||
'post_init_hook': '_l10n_it_edi_doi_post_init',
|
||||
}
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<record id="declaration_of_intent_fiscal_position" model="account.fiscal.position.template">
|
||||
<field name="sequence">10</field>
|
||||
<field name="name">Declaration of Intent</field>
|
||||
<field name="chart_template_id" ref="l10n_it.l10n_it_chart_template_generic"/>
|
||||
<field name="auto_apply" eval="False" />
|
||||
<field name="vat_required" eval="False" />
|
||||
<field name="note">Not taxable (art. 8, c. 1, lett. c) D.P.R. 633/1972) letter intent</field>
|
||||
</record>
|
||||
|
||||
<record id="afpttn_declaration_of_intent_fiscal_position_1" model="account.fiscal.position.tax.template">
|
||||
<field name="position_id" ref="declaration_of_intent_fiscal_position"/>
|
||||
<field name="tax_src_id" ref="l10n_it.22v"/>
|
||||
<field name="tax_dest_id" ref="00di"/>
|
||||
</record>
|
||||
|
||||
<record id="afpttn_declaration_of_intent_fiscal_position_2" model="account.fiscal.position.tax.template">
|
||||
<field name="position_id" ref="declaration_of_intent_fiscal_position"/>
|
||||
<field name="tax_src_id" ref="l10n_it.10v"/>
|
||||
<field name="tax_dest_id" ref="00di"/>
|
||||
</record>
|
||||
|
||||
<record id="afpttn_declaration_of_intent_fiscal_position_3" model="account.fiscal.position.tax.template">
|
||||
<field name="position_id" ref="declaration_of_intent_fiscal_position"/>
|
||||
<field name="tax_src_id" ref="l10n_it.5v"/>
|
||||
<field name="tax_dest_id" ref="00di"/>
|
||||
</record>
|
||||
|
||||
<record id="afpttn_declaration_of_intent_fiscal_position_4" model="account.fiscal.position.tax.template">
|
||||
<field name="position_id" ref="declaration_of_intent_fiscal_position"/>
|
||||
<field name="tax_src_id" ref="l10n_it.4v"/>
|
||||
<field name="tax_dest_id" ref="00di"/>
|
||||
</record>
|
||||
</odoo>
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<record id="00di" model="account.tax.template">
|
||||
<field name="description">Declaration of Intent</field>
|
||||
<field name="chart_template_id" ref="l10n_it.l10n_it_chart_template_generic"/>
|
||||
<field name="name">0% E</field>
|
||||
<field name="sequence">950</field>
|
||||
<field name="amount">0.0</field>
|
||||
<field name="amount_type">percent</field>
|
||||
<field name="type_tax_use">sale</field>
|
||||
<field name="price_include">False</field>
|
||||
<field name="tax_group_id" ref="l10n_it.tax_group_fuori"/>
|
||||
<field name="invoice_repartition_line_ids" eval="[(5, 0, 0),
|
||||
(0,0, {
|
||||
'repartition_type': 'base',
|
||||
'plus_report_expression_ids': [ref('l10n_it.tax_report_line_vp2_tag')],
|
||||
}),
|
||||
(0,0, {'repartition_type': 'tax'}),
|
||||
]"/>
|
||||
<field name="refund_repartition_line_ids" eval="[(5, 0, 0),
|
||||
(0,0, {
|
||||
'repartition_type': 'base',
|
||||
'minus_report_expression_ids': [ref('l10n_it.tax_report_line_vp2_tag')],
|
||||
}),
|
||||
(0,0, {'repartition_type': 'tax'}),
|
||||
]"/>
|
||||
</record>
|
||||
</odoo>
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<data>
|
||||
|
||||
<template id="account_invoice_line_it_FatturaPA" inherit_id="l10n_it_edi.account_invoice_line_it_FatturaPA">
|
||||
<DettaglioLinee position="inside">
|
||||
<AltriDatiGestionali t-if="record.l10n_it_edi_doi_id">
|
||||
<TipoDato t-translation="off">INTENTO</TipoDato>
|
||||
<RiferimentoTesto t-out="record.l10n_it_edi_doi_id.display_name"/>
|
||||
<RiferimentoData t-out="format_date(record.l10n_it_edi_doi_id.issue_date)"/>
|
||||
</AltriDatiGestionali>
|
||||
</DettaglioLinee>
|
||||
</template>
|
||||
|
||||
</data>
|
||||
</odoo>
|
||||
802
odoo-bringout-oca-ocb-l10n_it_edi_doi/l10n_it_edi_doi/i18n/it.po
Normal file
802
odoo-bringout-oca-ocb-l10n_it_edi_doi/l10n_it_edi_doi/i18n/it.po
Normal file
|
|
@ -0,0 +1,802 @@
|
|||
# Translation of Odoo Server.
|
||||
# This file contains the translation of the following modules:
|
||||
# * l10n_it_edi_doi
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Odoo Server 17.0+e\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2024-06-11 09:25+0000\n"
|
||||
"PO-Revision-Date: 2024-06-11 09:25+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: l10n_it_edi_doi
|
||||
#: model_terms:ir.ui.view,arch_db:l10n_it_edi_doi.view_l10n_it_edi_doi_form
|
||||
msgid "<span class=\"o_form_label mx-3\"> to </span>"
|
||||
msgstr "<span class=\"o_form_label mx-3\"> al </span>"
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model_terms:ir.ui.view,arch_db:l10n_it_edi_doi.view_l10n_it_edi_doi_form
|
||||
msgid "<span class=\"o_form_label mx-3\">/</span>"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model_terms:ir.ui.view,arch_db:l10n_it_edi_doi.view_l10n_it_edi_doi_form
|
||||
msgid "<span class=\"o_form_label\">Amounts:</span>"
|
||||
msgstr "<span class=\"o_form_label\">Importi:</span>"
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model_terms:ir.ui.view,arch_db:l10n_it_edi_doi.view_move_form
|
||||
#: model_terms:ir.ui.view,arch_db:l10n_it_edi_doi.view_order_form
|
||||
msgid "<span class=\"o_stat_text\">Declaration of Intent</span>"
|
||||
msgstr "<span class=\"o_stat_text\">Dichiarazione di Intento</span>"
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model_terms:ir.ui.view,arch_db:l10n_it_edi_doi.view_partner_l10n_form
|
||||
msgid "<span class=\"o_stat_text\">Declarations of Intent</span>"
|
||||
msgstr "<span class=\"o_stat_text\">Dichiarazioni di Intento</span>"
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model_terms:ir.ui.view,arch_db:l10n_it_edi_doi.view_l10n_it_edi_doi_form
|
||||
msgid "<span class=\"o_stat_text\">Invoices</span>"
|
||||
msgstr "<span class=\"o_stat_text\">Fatture</span>"
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model_terms:ir.ui.view,arch_db:l10n_it_edi_doi.view_l10n_it_edi_doi_form
|
||||
msgid "<span class=\"o_stat_text\">Sale Orders</span>"
|
||||
msgstr "<span class=\"o_stat_text\">Ordini di vendita</span>"
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#. odoo-python
|
||||
#: code:addons/l10n_it_edi_doi/models/account_move.py:0
|
||||
#: code:addons/l10n_it_edi_doi/models/sale_order.py:0
|
||||
#, python-format
|
||||
msgid "A line using tax %s should not contain any other taxes"
|
||||
msgstr "Una riga che utilizza la tassa %s non deve contenere altre tasse"
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model:ir.model,name:l10n_it_edi_doi.model_account_chart_template
|
||||
msgid "Account Chart Template"
|
||||
msgstr "Modello piano dei conti"
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model_terms:ir.ui.view,arch_db:l10n_it_edi_doi.view_move_tree
|
||||
msgid "Accounting Date"
|
||||
msgstr "Data contabile"
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model:ir.model.fields,field_description:l10n_it_edi_doi.field_l10n_it_edi_doi_declaration_of_intent__message_needaction
|
||||
msgid "Action Needed"
|
||||
msgstr "Azione richiesta"
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model:ir.model.fields.selection,name:l10n_it_edi_doi.selection__l10n_it_edi_doi_declaration_of_intent__state__active
|
||||
#: model_terms:ir.ui.view,arch_db:l10n_it_edi_doi.view_l10n_it_edi_doi_declaration_of_intent_search
|
||||
msgid "Active"
|
||||
msgstr "Attivo"
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model:ir.model.fields,field_description:l10n_it_edi_doi.field_l10n_it_edi_doi_declaration_of_intent__activity_ids
|
||||
msgid "Activities"
|
||||
msgstr "Attività"
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model:ir.model.fields,field_description:l10n_it_edi_doi.field_l10n_it_edi_doi_declaration_of_intent__activity_exception_decoration
|
||||
msgid "Activity Exception Decoration"
|
||||
msgstr "Decorazione eccezione attività"
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model:ir.model.fields,field_description:l10n_it_edi_doi.field_l10n_it_edi_doi_declaration_of_intent__activity_state
|
||||
msgid "Activity State"
|
||||
msgstr "Stato attività"
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model:ir.model.fields,field_description:l10n_it_edi_doi.field_l10n_it_edi_doi_declaration_of_intent__activity_type_icon
|
||||
msgid "Activity Type Icon"
|
||||
msgstr "Icona tipo di attività"
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model_terms:ir.ui.view,arch_db:l10n_it_edi_doi.view_l10n_it_edi_doi_tree
|
||||
msgid "Add a Declaration of Intent"
|
||||
msgstr "Aggiungi Dichiarazione di Intento"
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model:ir.model.fields,field_description:l10n_it_edi_doi.field_l10n_it_edi_doi_declaration_of_intent__message_attachment_count
|
||||
msgid "Attachment Count"
|
||||
msgstr "Conteggio allegati"
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model:ir.model.fields,field_description:l10n_it_edi_doi.field_res_partner__l10n_it_edi_doi_ids
|
||||
#: model:ir.model.fields,field_description:l10n_it_edi_doi.field_res_users__l10n_it_edi_doi_ids
|
||||
msgid "Available Declarations of Intent of this partner"
|
||||
msgstr "Dichiarazioni di Intento disponibili di questo partner"
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model:ir.model,name:l10n_it_edi_doi.model_res_company
|
||||
msgid "Companies"
|
||||
msgstr "Aziende"
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model:ir.model.fields,field_description:l10n_it_edi_doi.field_l10n_it_edi_doi_declaration_of_intent__company_id
|
||||
msgid "Company"
|
||||
msgstr "Azienda"
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model:ir.model,name:l10n_it_edi_doi.model_res_partner
|
||||
msgid "Contact"
|
||||
msgstr "Contatto"
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model:ir.model.fields,field_description:l10n_it_edi_doi.field_l10n_it_edi_doi_declaration_of_intent__create_uid
|
||||
msgid "Created by"
|
||||
msgstr "Creato da"
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model:ir.model.fields,field_description:l10n_it_edi_doi.field_l10n_it_edi_doi_declaration_of_intent__create_date
|
||||
msgid "Created on"
|
||||
msgstr "Data creazione"
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model:ir.model.fields,field_description:l10n_it_edi_doi.field_l10n_it_edi_doi_declaration_of_intent__currency_id
|
||||
msgid "Currency"
|
||||
msgstr "Valuta"
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model_terms:ir.ui.view,arch_db:l10n_it_edi_doi.view_move_tree
|
||||
msgid "Customer"
|
||||
msgstr "Cliente"
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model_terms:ir.ui.view,arch_db:l10n_it_edi_doi.view_l10n_it_edi_doi_form
|
||||
msgid "Date Range"
|
||||
msgstr "Intervallo Date"
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model:ir.model.fields,field_description:l10n_it_edi_doi.field_l10n_it_edi_doi_declaration_of_intent__issue_date
|
||||
msgid "Date of Issue"
|
||||
msgstr "Data di Emissione"
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model:ir.model.fields,field_description:l10n_it_edi_doi.field_account_bank_statement_line__l10n_it_edi_doi_date
|
||||
#: model:ir.model.fields,field_description:l10n_it_edi_doi.field_account_move__l10n_it_edi_doi_date
|
||||
#: model:ir.model.fields,field_description:l10n_it_edi_doi.field_account_payment__l10n_it_edi_doi_date
|
||||
#: model:ir.model.fields,field_description:l10n_it_edi_doi.field_sale_order__l10n_it_edi_doi_date
|
||||
msgid "Date on which Declaration of Intent is applied"
|
||||
msgstr "Data di applicazione della Dichiarazione di Intento"
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model:ir.model.fields,help:l10n_it_edi_doi.field_l10n_it_edi_doi_declaration_of_intent__issue_date
|
||||
msgid "Date on which the Declaration of Intent was issued"
|
||||
msgstr "Data di emissione della Dichiarazione di Intento"
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model:ir.model,name:l10n_it_edi_doi.model_l10n_it_edi_doi_declaration_of_intent
|
||||
#: model:ir.model.fields,field_description:l10n_it_edi_doi.field_account_bank_statement_line__l10n_it_edi_doi_id
|
||||
#: model:ir.model.fields,field_description:l10n_it_edi_doi.field_account_move__l10n_it_edi_doi_id
|
||||
#: model:ir.model.fields,field_description:l10n_it_edi_doi.field_account_payment__l10n_it_edi_doi_id
|
||||
#: model:ir.model.fields,field_description:l10n_it_edi_doi.field_sale_order__l10n_it_edi_doi_id
|
||||
#: model_terms:ir.ui.view,arch_db:l10n_it_edi_doi.view_account_invoice_filter
|
||||
#: model_terms:ir.ui.view,arch_db:l10n_it_edi_doi.view_sales_order_filter
|
||||
msgid "Declaration of Intent"
|
||||
msgstr "Dichiarazione di Intento"
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model:ir.model.fields,field_description:l10n_it_edi_doi.field_account_bank_statement_line__l10n_it_edi_doi_amount
|
||||
#: model:ir.model.fields,field_description:l10n_it_edi_doi.field_account_move__l10n_it_edi_doi_amount
|
||||
#: model:ir.model.fields,field_description:l10n_it_edi_doi.field_account_payment__l10n_it_edi_doi_amount
|
||||
msgid "Declaration of Intent Amount"
|
||||
msgstr "Dichiarazione di Intento Importo"
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model:ir.model.fields,field_description:l10n_it_edi_doi.field_sale_order__l10n_it_edi_doi_not_yet_invoiced
|
||||
msgid "Declaration of Intent Amount Not Yet Invoiced"
|
||||
msgstr "Dichiarazione di Intento Importo Non Ancora Fatturato"
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model:ir.model.fields,field_description:l10n_it_edi_doi.field_res_company__l10n_it_edi_doi_fiscal_position_id
|
||||
msgid "Declaration of Intent Fiscal Position"
|
||||
msgstr "Dichiarazione di Intento Posizioni Fiscale"
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model:ir.model.fields,field_description:l10n_it_edi_doi.field_res_company__l10n_it_edi_doi_tax_id
|
||||
msgid "Declaration of Intent Tax"
|
||||
msgstr "Dichiarazione di Intento Imposta"
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model:ir.model.fields,field_description:l10n_it_edi_doi.field_account_bank_statement_line__l10n_it_edi_doi_warning
|
||||
#: model:ir.model.fields,field_description:l10n_it_edi_doi.field_account_move__l10n_it_edi_doi_warning
|
||||
#: model:ir.model.fields,field_description:l10n_it_edi_doi.field_account_payment__l10n_it_edi_doi_warning
|
||||
#: model:ir.model.fields,field_description:l10n_it_edi_doi.field_sale_order__l10n_it_edi_doi_warning
|
||||
msgid "Declaration of Intent Threshold Warning"
|
||||
msgstr "Dichiarazione di Intento Avviso di soglia"
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#. odoo-python
|
||||
#: code:addons/l10n_it_edi_doi/models/account_move.py:0
|
||||
#: code:addons/l10n_it_edi_doi/models/sale_order.py:0
|
||||
#, python-format
|
||||
msgid "Declaration of Intent for %s"
|
||||
msgstr "Dichiarazione di Intento per %s"
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#. odoo-python
|
||||
#: code:addons/l10n_it_edi_doi/models/res_partner.py:0
|
||||
#, python-format
|
||||
msgid "Declaration of Intent of %s"
|
||||
msgstr "Dichiarazione di Intento di %s"
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model:ir.model.fields,field_description:l10n_it_edi_doi.field_l10n_it_edi_doi_declaration_of_intent__display_name
|
||||
msgid "Display Name"
|
||||
msgstr "Nome Visualizzato"
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model:ir.model.fields.selection,name:l10n_it_edi_doi.selection__l10n_it_edi_doi_declaration_of_intent__state__draft
|
||||
#: model_terms:ir.ui.view,arch_db:l10n_it_edi_doi.view_l10n_it_edi_doi_declaration_of_intent_search
|
||||
msgid "Draft"
|
||||
msgstr "Bozza"
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model:ir.model.fields,field_description:l10n_it_edi_doi.field_l10n_it_edi_doi_declaration_of_intent__end_date
|
||||
msgid "End Date"
|
||||
msgstr "Data fine"
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model_terms:ir.ui.view,arch_db:l10n_it_edi_doi.res_partner_view_search
|
||||
#: model_terms:ir.ui.view,arch_db:l10n_it_edi_doi.view_account_invoice_filter
|
||||
#: model_terms:ir.ui.view,arch_db:l10n_it_edi_doi.view_sales_order_filter
|
||||
msgid "Exceeded Declaration of Intent"
|
||||
msgstr "Dichiarazione di Intento superata"
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model:ir.model.fields,help:l10n_it_edi_doi.field_l10n_it_edi_doi_declaration_of_intent__start_date
|
||||
msgid "First date on which the Declaration of Intent is valid"
|
||||
msgstr "Prima data di validità della dichiarazione di intento"
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model:ir.model,name:l10n_it_edi_doi.model_account_fiscal_position
|
||||
msgid "Fiscal Position"
|
||||
msgstr "Posizione fiscale"
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model:ir.model.fields,field_description:l10n_it_edi_doi.field_l10n_it_edi_doi_declaration_of_intent__message_follower_ids
|
||||
msgid "Followers"
|
||||
msgstr "Seguito da"
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model:ir.model.fields,field_description:l10n_it_edi_doi.field_l10n_it_edi_doi_declaration_of_intent__message_partner_ids
|
||||
msgid "Followers (Partners)"
|
||||
msgstr "Seguito da (partner)"
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model:ir.model.fields,help:l10n_it_edi_doi.field_l10n_it_edi_doi_declaration_of_intent__activity_type_icon
|
||||
msgid "Font awesome icon e.g. fa-tasks"
|
||||
msgstr "Icona Font Awesome es. fa-tasks"
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#. odoo-python
|
||||
#: code:addons/l10n_it_edi_doi/models/account_move.py:0
|
||||
#: code:addons/l10n_it_edi_doi/models/sale_order.py:0
|
||||
#, python-format
|
||||
msgid ""
|
||||
"Given the tax %s is applied, there should be a Declaration of Intent "
|
||||
"selected."
|
||||
msgstr ""
|
||||
"Data l'applicazione dell'imposta %s, dovrebbe esserci una Dichiarazione di Intento "
|
||||
"selezionata."
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model:ir.model.fields,field_description:l10n_it_edi_doi.field_l10n_it_edi_doi_declaration_of_intent__has_message
|
||||
msgid "Has Message"
|
||||
msgstr "Contiene messaggio"
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model:ir.model.fields,field_description:l10n_it_edi_doi.field_l10n_it_edi_doi_declaration_of_intent__id
|
||||
msgid "ID"
|
||||
msgstr "ID"
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model:ir.model.fields,field_description:l10n_it_edi_doi.field_l10n_it_edi_doi_declaration_of_intent__activity_exception_icon
|
||||
msgid "Icon"
|
||||
msgstr "Icona"
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model:ir.model.fields,help:l10n_it_edi_doi.field_l10n_it_edi_doi_declaration_of_intent__activity_exception_icon
|
||||
msgid "Icon to indicate an exception activity."
|
||||
msgstr "Icona per indicare un'attività eccezione."
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model:ir.model.fields,help:l10n_it_edi_doi.field_l10n_it_edi_doi_declaration_of_intent__message_needaction
|
||||
msgid "If checked, new messages require your attention."
|
||||
msgstr "Se selezionata, nuovi messaggi richiedono attenzione."
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model:ir.model.fields,help:l10n_it_edi_doi.field_l10n_it_edi_doi_declaration_of_intent__message_has_error
|
||||
#: model:ir.model.fields,help:l10n_it_edi_doi.field_l10n_it_edi_doi_declaration_of_intent__message_has_sms_error
|
||||
msgid "If checked, some messages have a delivery error."
|
||||
msgstr "Se selezionata, alcuni messaggi presentano un errore di consegna."
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model_terms:ir.ui.view,arch_db:l10n_it_edi_doi.view_move_tree
|
||||
msgid "Invoice Date"
|
||||
msgstr "Data fattura"
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model:ir.model.fields,field_description:l10n_it_edi_doi.field_l10n_it_edi_doi_declaration_of_intent__invoiced
|
||||
msgid "Invoiced"
|
||||
msgstr "Fatturato"
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model:ir.model.fields,field_description:l10n_it_edi_doi.field_sale_order_line__qty_invoiced_posted
|
||||
msgid "Invoiced Quantity (posted)"
|
||||
msgstr "Quantità fatturata (confermata)"
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model_terms:ir.ui.view,arch_db:l10n_it_edi_doi.view_move_tree
|
||||
msgid "Invoices"
|
||||
msgstr "Fatture"
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model:ir.model.fields,field_description:l10n_it_edi_doi.field_l10n_it_edi_doi_declaration_of_intent__invoice_ids
|
||||
msgid "Invoices / Refunds"
|
||||
msgstr "Fatture / Rimborsi"
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#. odoo-python
|
||||
#: code:addons/l10n_it_edi_doi/models/declaration_of_intent.py:0
|
||||
#, python-format
|
||||
msgid "Invoices using Declaration of Intent %s"
|
||||
msgstr "Fatture con Dichiarazione di Intento %s"
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model:ir.model.fields,field_description:l10n_it_edi_doi.field_l10n_it_edi_doi_declaration_of_intent__message_is_follower
|
||||
msgid "Is Follower"
|
||||
msgstr "Sta seguendo"
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model:ir.model,name:l10n_it_edi_doi.model_account_move
|
||||
msgid "Journal Entry"
|
||||
msgstr "Registrazione contabile"
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model:ir.model.fields,field_description:l10n_it_edi_doi.field_l10n_it_edi_doi_declaration_of_intent__write_uid
|
||||
msgid "Last Updated by"
|
||||
msgstr "Ultimo aggiornamento di"
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model:ir.model.fields,field_description:l10n_it_edi_doi.field_l10n_it_edi_doi_declaration_of_intent__write_date
|
||||
msgid "Last Updated on"
|
||||
msgstr "Ultimo aggiornamento il"
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model:ir.model.fields,help:l10n_it_edi_doi.field_l10n_it_edi_doi_declaration_of_intent__end_date
|
||||
msgid "Last date on which the Declaration of Intent is valid"
|
||||
msgstr "Data ultima di validità della Dichiarazione di Intento"
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model:ir.model.fields,field_description:l10n_it_edi_doi.field_l10n_it_edi_doi_declaration_of_intent__message_main_attachment_id
|
||||
msgid "Main Attachment"
|
||||
msgstr "Allegato principale"
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model:ir.model.fields,field_description:l10n_it_edi_doi.field_l10n_it_edi_doi_declaration_of_intent__message_has_error
|
||||
msgid "Message Delivery error"
|
||||
msgstr "Errore di consegna messaggio"
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model:ir.model.fields,field_description:l10n_it_edi_doi.field_l10n_it_edi_doi_declaration_of_intent__message_ids
|
||||
msgid "Messages"
|
||||
msgstr "Messaggi"
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model:ir.model.fields,field_description:l10n_it_edi_doi.field_l10n_it_edi_doi_declaration_of_intent__my_activity_date_deadline
|
||||
msgid "My Activity Deadline"
|
||||
msgstr "Scadenza mie attività"
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model:ir.model.fields,field_description:l10n_it_edi_doi.field_l10n_it_edi_doi_declaration_of_intent__activity_date_deadline
|
||||
msgid "Next Activity Deadline"
|
||||
msgstr "Scadenza prossima attività"
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model:ir.model.fields,field_description:l10n_it_edi_doi.field_l10n_it_edi_doi_declaration_of_intent__activity_summary
|
||||
msgid "Next Activity Summary"
|
||||
msgstr "Riepilogo prossima attività"
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model:ir.model.fields,field_description:l10n_it_edi_doi.field_l10n_it_edi_doi_declaration_of_intent__activity_type_id
|
||||
msgid "Next Activity Type"
|
||||
msgstr "Tipologia prossima attività"
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model:ir.model.fields,field_description:l10n_it_edi_doi.field_l10n_it_edi_doi_declaration_of_intent__not_yet_invoiced
|
||||
msgid "Not Yet Invoiced"
|
||||
msgstr "Non Ancora Fatturato"
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model_terms:ir.ui.view,arch_db:l10n_it_edi_doi.view_quotation_tree
|
||||
msgid "Not Yet Invoiced Amount"
|
||||
msgstr "Importo Non Ancora Fatturato"
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model_terms:ir.ui.view,arch_db:l10n_it_edi_doi.view_quotation_tree
|
||||
msgid "Number"
|
||||
msgstr "Numero"
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model:ir.model.fields,field_description:l10n_it_edi_doi.field_l10n_it_edi_doi_declaration_of_intent__message_needaction_counter
|
||||
msgid "Number of Actions"
|
||||
msgstr "Numero di azioni"
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model:ir.model.fields,field_description:l10n_it_edi_doi.field_l10n_it_edi_doi_declaration_of_intent__message_has_error_counter
|
||||
msgid "Number of errors"
|
||||
msgstr "Numero di errori"
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model:ir.model.fields,help:l10n_it_edi_doi.field_l10n_it_edi_doi_declaration_of_intent__message_needaction_counter
|
||||
msgid "Number of messages requiring action"
|
||||
msgstr "Numero di messaggi che richiedono un'azione"
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model:ir.model.fields,help:l10n_it_edi_doi.field_l10n_it_edi_doi_declaration_of_intent__message_has_error_counter
|
||||
msgid "Number of messages with delivery error"
|
||||
msgstr "Numero di messaggi con errore di consegna"
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model:ir.model.fields,field_description:l10n_it_edi_doi.field_l10n_it_edi_doi_declaration_of_intent__partner_id
|
||||
msgid "Partner"
|
||||
msgstr "Partner"
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#. odoo-python
|
||||
#: code:addons/l10n_it_edi_doi/models/declaration_of_intent.py:0
|
||||
#, python-format
|
||||
msgid ""
|
||||
"Pay attention, the threshold of your Declaration of Intent %s of %s is exceeded by %s, this document included.\n"
|
||||
"Invoiced: %s; Not Yet Invoiced: %s"
|
||||
msgstr ""
|
||||
"Attenzione, la soglia della tua Dichiarazione di Intento %s di %s è superata da %s, questo documento incluso.\n"
|
||||
"Fatturato: %s; Non ancora fatturato: %s"
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model:ir.model.fields,field_description:l10n_it_edi_doi.field_l10n_it_edi_doi_declaration_of_intent__protocol_number_part1
|
||||
msgid "Protocol 1"
|
||||
msgstr "Protocollo 1"
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model:ir.model.fields,field_description:l10n_it_edi_doi.field_l10n_it_edi_doi_declaration_of_intent__protocol_number_part2
|
||||
msgid "Protocol 2"
|
||||
msgstr "Protocollo 2"
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model_terms:ir.ui.view,arch_db:l10n_it_edi_doi.view_l10n_it_edi_doi_form
|
||||
msgid "Protocol Number"
|
||||
msgstr "Numero di Protocollo"
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model_terms:ir.ui.view,arch_db:l10n_it_edi_doi.view_l10n_it_edi_doi_form
|
||||
msgid "Reactivate"
|
||||
msgstr "Riattivare"
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model:ir.model.fields,field_description:l10n_it_edi_doi.field_l10n_it_edi_doi_declaration_of_intent__remaining
|
||||
msgid "Remaining"
|
||||
msgstr "Rimanente"
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model:ir.model.fields,help:l10n_it_edi_doi.field_l10n_it_edi_doi_declaration_of_intent__remaining_amount
|
||||
msgid ""
|
||||
"Remaining amount after deduction of the Invoiced and Not Yet Invoiced "
|
||||
"amounts."
|
||||
msgstr ""
|
||||
"Importo rimanente dopo la deduzione degli importi Fatturati e Non ancora fatturati "
|
||||
"importi."
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model_terms:ir.ui.view,arch_db:l10n_it_edi_doi.view_l10n_it_edi_doi_form
|
||||
msgid "Reset to Draft"
|
||||
msgstr "Reimposta a bozza"
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model:ir.model.fields,field_description:l10n_it_edi_doi.field_l10n_it_edi_doi_declaration_of_intent__activity_user_id
|
||||
msgid "Responsible User"
|
||||
msgstr "Utente Responsabile"
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model_terms:ir.ui.view,arch_db:l10n_it_edi_doi.view_l10n_it_edi_doi_form
|
||||
msgid "Revoke"
|
||||
msgstr "Revoca"
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model:ir.model.fields.selection,name:l10n_it_edi_doi.selection__l10n_it_edi_doi_declaration_of_intent__state__revoked
|
||||
msgid "Revoked"
|
||||
msgstr "Revocato"
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model:ir.model.fields,field_description:l10n_it_edi_doi.field_l10n_it_edi_doi_declaration_of_intent__message_has_sms_error
|
||||
msgid "SMS Delivery error"
|
||||
msgstr "Errore di consegna SMS"
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model:ir.model,name:l10n_it_edi_doi.model_sale_order
|
||||
msgid "Sales Order"
|
||||
msgstr "Ordini di vendita"
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model:ir.model,name:l10n_it_edi_doi.model_sale_order_line
|
||||
msgid "Sales Order Line"
|
||||
msgstr "Riga ordine di vendita"
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model_terms:ir.ui.view,arch_db:l10n_it_edi_doi.view_quotation_tree
|
||||
msgid "Sales Orders"
|
||||
msgstr "Ordini di vendita"
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model:ir.model.fields,field_description:l10n_it_edi_doi.field_l10n_it_edi_doi_declaration_of_intent__sale_order_ids
|
||||
msgid "Sales Orders / Quotations"
|
||||
msgstr "Ordini di vendita / Preventivi"
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#. odoo-python
|
||||
#: code:addons/l10n_it_edi_doi/models/declaration_of_intent.py:0
|
||||
#, python-format
|
||||
msgid "Sales Orders using Declaration of Intent %s"
|
||||
msgstr "Ordini di vendita con Dichiarazioni di Intento %s"
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model_terms:ir.ui.view,arch_db:l10n_it_edi_doi.view_l10n_it_edi_doi_declaration_of_intent_search
|
||||
msgid "Show active declarations of intent"
|
||||
msgstr "Mostra Dichiarazioni di intento attive"
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model_terms:ir.ui.view,arch_db:l10n_it_edi_doi.view_l10n_it_edi_doi_declaration_of_intent_search
|
||||
msgid "Show draft declarations of intent"
|
||||
msgstr "Mostra bozze di dichiarazioni di intento."
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model_terms:ir.ui.view,arch_db:l10n_it_edi_doi.view_l10n_it_edi_doi_declaration_of_intent_search
|
||||
msgid "Show terminated or revoked Declarations of Intent"
|
||||
msgstr "Mostra dichiarazioni di intento chiuse o revocate"
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model:ir.model.fields,field_description:l10n_it_edi_doi.field_l10n_it_edi_doi_declaration_of_intent__start_date
|
||||
msgid "Start Date"
|
||||
msgstr "Data Inizio"
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model:ir.model.fields,field_description:l10n_it_edi_doi.field_l10n_it_edi_doi_declaration_of_intent__state
|
||||
msgid "State"
|
||||
msgstr "Stato"
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model:ir.model.fields,help:l10n_it_edi_doi.field_l10n_it_edi_doi_declaration_of_intent__activity_state
|
||||
msgid ""
|
||||
"Status based on activities\n"
|
||||
"Overdue: Due date is already passed\n"
|
||||
"Today: Activity date is today\n"
|
||||
"Planned: Future activities."
|
||||
msgstr ""
|
||||
"Stato basato sulle attività\n"
|
||||
"In ritardo: scadenza già superata\n"
|
||||
"Oggi: attività in data odierna\n"
|
||||
"Pianificato: attività future."
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model:ir.model,name:l10n_it_edi_doi.model_account_tax
|
||||
msgid "Tax"
|
||||
msgstr "Imposta"
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model_terms:ir.ui.view,arch_db:l10n_it_edi_doi.view_move_tree
|
||||
msgid "Tax excluded"
|
||||
msgstr "Imposta esclusa"
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model_terms:ir.ui.view,arch_db:l10n_it_edi_doi.view_l10n_it_edi_doi_form
|
||||
msgid "Terminate"
|
||||
msgstr "Terminare"
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model:ir.model.fields.selection,name:l10n_it_edi_doi.selection__l10n_it_edi_doi_declaration_of_intent__state__terminated
|
||||
msgid "Terminated"
|
||||
msgstr "Terminato"
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model_terms:ir.ui.view,arch_db:l10n_it_edi_doi.view_l10n_it_edi_doi_declaration_of_intent_search
|
||||
msgid "Terminated / Revoked"
|
||||
msgstr "Terminato / Revocato"
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#. odoo-python
|
||||
#: code:addons/l10n_it_edi_doi/models/declaration_of_intent.py:0
|
||||
#, python-format
|
||||
msgid "The Declaration of Intent belongs to company %s, not %s."
|
||||
msgstr "La Dichiarazione di Intento appartiene alla società %s, non a %s."
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#. odoo-python
|
||||
#: code:addons/l10n_it_edi_doi/models/declaration_of_intent.py:0
|
||||
#, python-format
|
||||
msgid "The Declaration of Intent belongs to partner %s, not %s."
|
||||
msgstr "La Dichiarazione di Intento appartiene al partner %s, non a %s."
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#. odoo-python
|
||||
#: code:addons/l10n_it_edi_doi/models/declaration_of_intent.py:0
|
||||
#, python-format
|
||||
msgid "The Declaration of Intent is in draft."
|
||||
msgstr "La Dichiarazione di Intento è in bozza."
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#. odoo-python
|
||||
#: code:addons/l10n_it_edi_doi/models/declaration_of_intent.py:0
|
||||
#, python-format
|
||||
msgid "The Declaration of Intent is valid from %s to %s, not on %s."
|
||||
msgstr "La Dichiarazione di Intento è valida dal %s a %s, non il %s."
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#. odoo-python
|
||||
#: code:addons/l10n_it_edi_doi/models/declaration_of_intent.py:0
|
||||
#, python-format
|
||||
msgid "The Declaration of Intent must be active."
|
||||
msgstr "La dichiarazione di Intento deve essere attiva."
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#. odoo-python
|
||||
#: code:addons/l10n_it_edi_doi/models/declaration_of_intent.py:0
|
||||
#, python-format
|
||||
msgid "The Declaration of Intent uses currency %s, not %s."
|
||||
msgstr "La Dichiarazione di Intento utilizza la valuta %s, non %s."
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model:ir.model.constraint,message:l10n_it_edi_doi.constraint_l10n_it_edi_doi_declaration_of_intent_protocol_number_unique
|
||||
msgid ""
|
||||
"The Protocol Number of a Declaration of Intent must be unique! Please choose"
|
||||
" another one."
|
||||
msgstr "Il numero di protocollo di una Dichiarazione di Intento deve essere univoco! Per favore scegline"
|
||||
" un altro."
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model:ir.model.constraint,message:l10n_it_edi_doi.constraint_l10n_it_edi_doi_declaration_of_intent_threshold_positive
|
||||
msgid "The Threshold of a Declaration of Intent must be positive."
|
||||
msgstr "La Soglia di una Dichiarazione di Intento deve essere positiva."
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model:ir.model.fields,help:l10n_it_edi_doi.field_l10n_it_edi_doi_declaration_of_intent__state
|
||||
msgid ""
|
||||
"The state of this Declaration of Intent. \n"
|
||||
"- 'Draft' means that the Declaration of Intent still needs to be confirmed before being usable. \n"
|
||||
"- 'Active' means that the Declaration of Intent is usable. \n"
|
||||
"- 'Terminated' designates that the Declaration of Intent has been marked as not to use anymore without invalidating usages of it. \n"
|
||||
"- 'Revoked' means the Declaration of Intent should not have been used. You will probably need to revert previous usages of it, if any.\n"
|
||||
msgstr ""
|
||||
"Lo stato della presente Dichiarazione di Intento. \n"
|
||||
"- 'Bozza' significa che la Dichiarazione di Intento deve ancora essere confermata prima di essere utilizzabile. \n"
|
||||
"- 'Attiva' significa che la Dichiarazione di Intento è utilizzabile. \n"
|
||||
"- 'Terminata' indica che la Dichiarazione di Intento è stata contrassegnata come non più utilizzabile senza invalidarne gli usi. \n"
|
||||
"- 'Revocata' significa che la Dichiarazione di Intento non deve essere utilizzata. Probabilmente sarà necessario ripristinare gli usi precedenti, se presenti.\n"
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model:ir.model.fields,field_description:l10n_it_edi_doi.field_l10n_it_edi_doi_declaration_of_intent__threshold
|
||||
msgid "Threshold"
|
||||
msgstr "Soglia"
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model_terms:ir.ui.view,arch_db:l10n_it_edi_doi.view_move_tree
|
||||
#: model_terms:ir.ui.view,arch_db:l10n_it_edi_doi.view_quotation_tree
|
||||
msgid "Total"
|
||||
msgstr "Totale"
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model:ir.model.fields,help:l10n_it_edi_doi.field_l10n_it_edi_doi_declaration_of_intent__threshold
|
||||
msgid ""
|
||||
"Total amount of allowed sales without VAT under this Declaration of Intent"
|
||||
msgstr ""
|
||||
"Importo totale delle vendite consentite senza IVA ai sensi della presente Dichiarazione di Intento"
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model:ir.model.fields,help:l10n_it_edi_doi.field_l10n_it_edi_doi_declaration_of_intent__not_yet_invoiced
|
||||
msgid ""
|
||||
"Total amount of planned sales under this Declaration of Intent (i.e. current"
|
||||
" quotation and sales orders) that can still be invoiced"
|
||||
msgstr ""
|
||||
"Importo totale delle vendite pianificate nell'ambito della presente Dichiarazione di "
|
||||
"Intento (cioè l'offerta e gli ordini di vendita attuali) che possono ancora essere fatturati"
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model:ir.model.fields,help:l10n_it_edi_doi.field_account_bank_statement_line__l10n_it_edi_doi_amount
|
||||
#: model:ir.model.fields,help:l10n_it_edi_doi.field_account_move__l10n_it_edi_doi_amount
|
||||
#: model:ir.model.fields,help:l10n_it_edi_doi.field_account_payment__l10n_it_edi_doi_amount
|
||||
msgid "Total amount of sales under the Declaration of Intent of this document"
|
||||
msgstr ""
|
||||
"Importo totale delle vendite ai sensi della Dichiarazione di Intento del presente documento"
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model:ir.model.fields,help:l10n_it_edi_doi.field_l10n_it_edi_doi_declaration_of_intent__invoiced
|
||||
msgid ""
|
||||
"Total amount of sales under this Declaration of Intent"
|
||||
msgstr ""
|
||||
"Importo totale delle vendite ai sensi della presente Dichiarazione di Intento"
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model:ir.model.fields,help:l10n_it_edi_doi.field_sale_order__l10n_it_edi_doi_not_yet_invoiced
|
||||
msgid ""
|
||||
"Total under the Declaration of Intent of this document that can still be "
|
||||
"invoiced"
|
||||
msgstr ""
|
||||
"Totale ai sensi della Dichiarazione di Intento del presente documento che può ancora essere "
|
||||
"fatturati"
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model:ir.model.fields,help:l10n_it_edi_doi.field_l10n_it_edi_doi_declaration_of_intent__activity_exception_decoration
|
||||
msgid "Type of the exception activity on record."
|
||||
msgstr "Tipo di attività eccezione sul record."
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model:ir.model.fields,field_description:l10n_it_edi_doi.field_account_bank_statement_line__l10n_it_edi_doi_use
|
||||
#: model:ir.model.fields,field_description:l10n_it_edi_doi.field_account_move__l10n_it_edi_doi_use
|
||||
#: model:ir.model.fields,field_description:l10n_it_edi_doi.field_account_payment__l10n_it_edi_doi_use
|
||||
#: model:ir.model.fields,field_description:l10n_it_edi_doi.field_sale_order__l10n_it_edi_doi_use
|
||||
msgid "Use Declaration of Intent"
|
||||
msgstr "Utilizzare Dichiarazione di Intento"
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model_terms:ir.ui.view,arch_db:l10n_it_edi_doi.view_l10n_it_edi_doi_form
|
||||
msgid "Validate"
|
||||
msgstr "Validare"
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model:ir.model.fields,field_description:l10n_it_edi_doi.field_l10n_it_edi_doi_declaration_of_intent__website_message_ids
|
||||
msgid "Website Messages"
|
||||
msgstr "Messaggi sito web"
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model:ir.model.fields,help:l10n_it_edi_doi.field_l10n_it_edi_doi_declaration_of_intent__website_message_ids
|
||||
msgid "Website communication history"
|
||||
msgstr "Cronologia comunicazioni sito web"
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#. odoo-python
|
||||
#: code:addons/l10n_it_edi_doi/models/declaration_of_intent.py:0
|
||||
#, python-format
|
||||
msgid ""
|
||||
"You cannot delete Declarations of Intents that are already used on at least "
|
||||
"one Invoice or Sales Order."
|
||||
msgstr ""
|
||||
"Non è possibile eliminare dichiarazioni di intenti già utilizzate in almeno "
|
||||
"una fattura o un ordine di vendita."
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#. odoo-python
|
||||
#: code:addons/l10n_it_edi_doi/models/account_fiscal_position.py:0
|
||||
#, python-format
|
||||
msgid ""
|
||||
"You cannot delete the special fiscal position for Declarations of Intent."
|
||||
msgstr ""
|
||||
"Non è possibile eliminare la posizione fiscale speciale per le dichiarazioni di intento."
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#. odoo-python
|
||||
#: code:addons/l10n_it_edi_doi/models/account_tax.py:0
|
||||
#, python-format
|
||||
msgid "You cannot delete the special tax for Declarations of Intent."
|
||||
msgstr "Non è possibile eliminare la tassa speciale per le dichiarazioni di intento."
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model_terms:ir.ui.view,arch_db:l10n_it_edi_doi.report_invoice_document
|
||||
#: model_terms:ir.ui.view,arch_db:l10n_it_edi_doi.report_saleorder_document
|
||||
msgid "Your Declaration of Intent number"
|
||||
msgstr "Vostra Dichiarazione di Intento nr."
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model_terms:ir.ui.view,arch_db:l10n_it_edi_doi.report_invoice_document
|
||||
#: model_terms:ir.ui.view,arch_db:l10n_it_edi_doi.report_saleorder_document
|
||||
msgid "from"
|
||||
msgstr "del"
|
||||
|
|
@ -0,0 +1,775 @@
|
|||
# Translation of Odoo Server.
|
||||
# This file contains the translation of the following modules:
|
||||
# * l10n_it_edi_doi
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Odoo Server 17.0+e\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2024-06-11 09:25+0000\n"
|
||||
"PO-Revision-Date: 2024-06-11 09:25+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: l10n_it_edi_doi
|
||||
#: model_terms:ir.ui.view,arch_db:l10n_it_edi_doi.view_l10n_it_edi_doi_form
|
||||
msgid "<span class=\"o_form_label mx-3\"> to </span>"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model_terms:ir.ui.view,arch_db:l10n_it_edi_doi.view_l10n_it_edi_doi_form
|
||||
msgid "<span class=\"o_form_label mx-3\">/</span>"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model_terms:ir.ui.view,arch_db:l10n_it_edi_doi.view_l10n_it_edi_doi_form
|
||||
msgid "<span class=\"o_form_label\">Amounts:</span>"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model_terms:ir.ui.view,arch_db:l10n_it_edi_doi.view_move_form
|
||||
#: model_terms:ir.ui.view,arch_db:l10n_it_edi_doi.view_order_form
|
||||
msgid "<span class=\"o_stat_text\">Declaration of Intent</span>"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model_terms:ir.ui.view,arch_db:l10n_it_edi_doi.view_partner_l10n_form
|
||||
msgid "<span class=\"o_stat_text\">Declarations of Intent</span>"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model_terms:ir.ui.view,arch_db:l10n_it_edi_doi.view_l10n_it_edi_doi_form
|
||||
msgid "<span class=\"o_stat_text\">Invoices</span>"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model_terms:ir.ui.view,arch_db:l10n_it_edi_doi.view_l10n_it_edi_doi_form
|
||||
msgid "<span class=\"o_stat_text\">Sale Orders</span>"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#. odoo-python
|
||||
#: code:addons/l10n_it_edi_doi/models/account_move.py:0
|
||||
#: code:addons/l10n_it_edi_doi/models/sale_order.py:0
|
||||
#, python-format
|
||||
msgid "A line using tax %s should not contain any other taxes"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model:ir.model,name:l10n_it_edi_doi.model_account_chart_template
|
||||
msgid "Account Chart Template"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model_terms:ir.ui.view,arch_db:l10n_it_edi_doi.view_move_tree
|
||||
msgid "Accounting Date"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model:ir.model.fields,field_description:l10n_it_edi_doi.field_l10n_it_edi_doi_declaration_of_intent__message_needaction
|
||||
msgid "Action Needed"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model:ir.model.fields.selection,name:l10n_it_edi_doi.selection__l10n_it_edi_doi_declaration_of_intent__state__active
|
||||
#: model_terms:ir.ui.view,arch_db:l10n_it_edi_doi.view_l10n_it_edi_doi_declaration_of_intent_search
|
||||
msgid "Active"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model:ir.model.fields,field_description:l10n_it_edi_doi.field_l10n_it_edi_doi_declaration_of_intent__activity_ids
|
||||
msgid "Activities"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model:ir.model.fields,field_description:l10n_it_edi_doi.field_l10n_it_edi_doi_declaration_of_intent__activity_exception_decoration
|
||||
msgid "Activity Exception Decoration"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model:ir.model.fields,field_description:l10n_it_edi_doi.field_l10n_it_edi_doi_declaration_of_intent__activity_state
|
||||
msgid "Activity State"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model:ir.model.fields,field_description:l10n_it_edi_doi.field_l10n_it_edi_doi_declaration_of_intent__activity_type_icon
|
||||
msgid "Activity Type Icon"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model_terms:ir.ui.view,arch_db:l10n_it_edi_doi.view_l10n_it_edi_doi_tree
|
||||
msgid "Add a Declaration of Intent"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model:ir.model.fields,field_description:l10n_it_edi_doi.field_l10n_it_edi_doi_declaration_of_intent__message_attachment_count
|
||||
msgid "Attachment Count"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model:ir.model.fields,field_description:l10n_it_edi_doi.field_res_partner__l10n_it_edi_doi_ids
|
||||
#: model:ir.model.fields,field_description:l10n_it_edi_doi.field_res_users__l10n_it_edi_doi_ids
|
||||
msgid "Available Declarations of Intent of this partner"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model:ir.model,name:l10n_it_edi_doi.model_res_company
|
||||
msgid "Companies"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model:ir.model.fields,field_description:l10n_it_edi_doi.field_l10n_it_edi_doi_declaration_of_intent__company_id
|
||||
msgid "Company"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model:ir.model,name:l10n_it_edi_doi.model_res_partner
|
||||
msgid "Contact"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model:ir.model.fields,field_description:l10n_it_edi_doi.field_l10n_it_edi_doi_declaration_of_intent__create_uid
|
||||
msgid "Created by"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model:ir.model.fields,field_description:l10n_it_edi_doi.field_l10n_it_edi_doi_declaration_of_intent__create_date
|
||||
msgid "Created on"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model:ir.model.fields,field_description:l10n_it_edi_doi.field_l10n_it_edi_doi_declaration_of_intent__currency_id
|
||||
msgid "Currency"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model_terms:ir.ui.view,arch_db:l10n_it_edi_doi.view_move_tree
|
||||
msgid "Customer"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model_terms:ir.ui.view,arch_db:l10n_it_edi_doi.view_l10n_it_edi_doi_form
|
||||
msgid "Date Range"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model:ir.model.fields,field_description:l10n_it_edi_doi.field_l10n_it_edi_doi_declaration_of_intent__issue_date
|
||||
msgid "Date of Issue"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model:ir.model.fields,field_description:l10n_it_edi_doi.field_account_bank_statement_line__l10n_it_edi_doi_date
|
||||
#: model:ir.model.fields,field_description:l10n_it_edi_doi.field_account_move__l10n_it_edi_doi_date
|
||||
#: model:ir.model.fields,field_description:l10n_it_edi_doi.field_account_payment__l10n_it_edi_doi_date
|
||||
#: model:ir.model.fields,field_description:l10n_it_edi_doi.field_sale_order__l10n_it_edi_doi_date
|
||||
msgid "Date on which Declaration of Intent is applied"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model:ir.model.fields,help:l10n_it_edi_doi.field_l10n_it_edi_doi_declaration_of_intent__issue_date
|
||||
msgid "Date on which the Declaration of Intent was issued"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model:ir.model,name:l10n_it_edi_doi.model_l10n_it_edi_doi_declaration_of_intent
|
||||
#: model:ir.model.fields,field_description:l10n_it_edi_doi.field_account_bank_statement_line__l10n_it_edi_doi_id
|
||||
#: model:ir.model.fields,field_description:l10n_it_edi_doi.field_account_move__l10n_it_edi_doi_id
|
||||
#: model:ir.model.fields,field_description:l10n_it_edi_doi.field_account_payment__l10n_it_edi_doi_id
|
||||
#: model:ir.model.fields,field_description:l10n_it_edi_doi.field_sale_order__l10n_it_edi_doi_id
|
||||
#: model_terms:ir.ui.view,arch_db:l10n_it_edi_doi.view_account_invoice_filter
|
||||
#: model_terms:ir.ui.view,arch_db:l10n_it_edi_doi.view_sales_order_filter
|
||||
msgid "Declaration of Intent"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model:ir.model.fields,field_description:l10n_it_edi_doi.field_account_bank_statement_line__l10n_it_edi_doi_amount
|
||||
#: model:ir.model.fields,field_description:l10n_it_edi_doi.field_account_move__l10n_it_edi_doi_amount
|
||||
#: model:ir.model.fields,field_description:l10n_it_edi_doi.field_account_payment__l10n_it_edi_doi_amount
|
||||
msgid "Declaration of Intent Amount"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model:ir.model.fields,field_description:l10n_it_edi_doi.field_sale_order__l10n_it_edi_doi_not_yet_invoiced
|
||||
msgid "Declaration of Intent Amount Not Yet Invoiced"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model:ir.model.fields,field_description:l10n_it_edi_doi.field_res_company__l10n_it_edi_doi_fiscal_position_id
|
||||
msgid "Declaration of Intent Fiscal Position"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model:ir.model.fields,field_description:l10n_it_edi_doi.field_res_company__l10n_it_edi_doi_tax_id
|
||||
msgid "Declaration of Intent Tax"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model:ir.model.fields,field_description:l10n_it_edi_doi.field_account_bank_statement_line__l10n_it_edi_doi_warning
|
||||
#: model:ir.model.fields,field_description:l10n_it_edi_doi.field_account_move__l10n_it_edi_doi_warning
|
||||
#: model:ir.model.fields,field_description:l10n_it_edi_doi.field_account_payment__l10n_it_edi_doi_warning
|
||||
#: model:ir.model.fields,field_description:l10n_it_edi_doi.field_sale_order__l10n_it_edi_doi_warning
|
||||
msgid "Declaration of Intent Threshold Warning"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#. odoo-python
|
||||
#: code:addons/l10n_it_edi_doi/models/account_move.py:0
|
||||
#: code:addons/l10n_it_edi_doi/models/sale_order.py:0
|
||||
#, python-format
|
||||
msgid "Declaration of Intent for %s"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#. odoo-python
|
||||
#: code:addons/l10n_it_edi_doi/models/res_partner.py:0
|
||||
#, python-format
|
||||
msgid "Declaration of Intent of %s"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model:ir.model.fields,field_description:l10n_it_edi_doi.field_l10n_it_edi_doi_declaration_of_intent__display_name
|
||||
msgid "Display Name"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model:ir.model.fields.selection,name:l10n_it_edi_doi.selection__l10n_it_edi_doi_declaration_of_intent__state__draft
|
||||
#: model_terms:ir.ui.view,arch_db:l10n_it_edi_doi.view_l10n_it_edi_doi_declaration_of_intent_search
|
||||
msgid "Draft"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model:ir.model.fields,field_description:l10n_it_edi_doi.field_l10n_it_edi_doi_declaration_of_intent__end_date
|
||||
msgid "End Date"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model_terms:ir.ui.view,arch_db:l10n_it_edi_doi.res_partner_view_search
|
||||
#: model_terms:ir.ui.view,arch_db:l10n_it_edi_doi.view_account_invoice_filter
|
||||
#: model_terms:ir.ui.view,arch_db:l10n_it_edi_doi.view_sales_order_filter
|
||||
msgid "Exceeded Declaration of Intent"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model:ir.model.fields,help:l10n_it_edi_doi.field_l10n_it_edi_doi_declaration_of_intent__start_date
|
||||
msgid "First date on which the Declaration of Intent is valid"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model:ir.model,name:l10n_it_edi_doi.model_account_fiscal_position
|
||||
msgid "Fiscal Position"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model:ir.model.fields,field_description:l10n_it_edi_doi.field_l10n_it_edi_doi_declaration_of_intent__message_follower_ids
|
||||
msgid "Followers"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model:ir.model.fields,field_description:l10n_it_edi_doi.field_l10n_it_edi_doi_declaration_of_intent__message_partner_ids
|
||||
msgid "Followers (Partners)"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model:ir.model.fields,help:l10n_it_edi_doi.field_l10n_it_edi_doi_declaration_of_intent__activity_type_icon
|
||||
msgid "Font awesome icon e.g. fa-tasks"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#. odoo-python
|
||||
#: code:addons/l10n_it_edi_doi/models/account_move.py:0
|
||||
#: code:addons/l10n_it_edi_doi/models/sale_order.py:0
|
||||
#, python-format
|
||||
msgid ""
|
||||
"Given the tax %s is applied, there should be a Declaration of Intent "
|
||||
"selected."
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model:ir.model.fields,field_description:l10n_it_edi_doi.field_l10n_it_edi_doi_declaration_of_intent__has_message
|
||||
msgid "Has Message"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model:ir.model.fields,field_description:l10n_it_edi_doi.field_l10n_it_edi_doi_declaration_of_intent__id
|
||||
msgid "ID"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model:ir.model.fields,field_description:l10n_it_edi_doi.field_l10n_it_edi_doi_declaration_of_intent__activity_exception_icon
|
||||
msgid "Icon"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model:ir.model.fields,help:l10n_it_edi_doi.field_l10n_it_edi_doi_declaration_of_intent__activity_exception_icon
|
||||
msgid "Icon to indicate an exception activity."
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model:ir.model.fields,help:l10n_it_edi_doi.field_l10n_it_edi_doi_declaration_of_intent__message_needaction
|
||||
msgid "If checked, new messages require your attention."
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model:ir.model.fields,help:l10n_it_edi_doi.field_l10n_it_edi_doi_declaration_of_intent__message_has_error
|
||||
#: model:ir.model.fields,help:l10n_it_edi_doi.field_l10n_it_edi_doi_declaration_of_intent__message_has_sms_error
|
||||
msgid "If checked, some messages have a delivery error."
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model_terms:ir.ui.view,arch_db:l10n_it_edi_doi.view_move_tree
|
||||
msgid "Invoice Date"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model:ir.model.fields,field_description:l10n_it_edi_doi.field_l10n_it_edi_doi_declaration_of_intent__invoiced
|
||||
msgid "Invoiced"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model:ir.model.fields,field_description:l10n_it_edi_doi.field_sale_order_line__qty_invoiced_posted
|
||||
msgid "Invoiced Quantity (posted)"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model_terms:ir.ui.view,arch_db:l10n_it_edi_doi.view_move_tree
|
||||
msgid "Invoices"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model:ir.model.fields,field_description:l10n_it_edi_doi.field_l10n_it_edi_doi_declaration_of_intent__invoice_ids
|
||||
msgid "Invoices / Refunds"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#. odoo-python
|
||||
#: code:addons/l10n_it_edi_doi/models/declaration_of_intent.py:0
|
||||
#, python-format
|
||||
msgid "Invoices using Declaration of Intent %s"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model:ir.model.fields,field_description:l10n_it_edi_doi.field_l10n_it_edi_doi_declaration_of_intent__message_is_follower
|
||||
msgid "Is Follower"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model:ir.model,name:l10n_it_edi_doi.model_account_move
|
||||
msgid "Journal Entry"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model:ir.model.fields,field_description:l10n_it_edi_doi.field_l10n_it_edi_doi_declaration_of_intent__write_uid
|
||||
msgid "Last Updated by"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model:ir.model.fields,field_description:l10n_it_edi_doi.field_l10n_it_edi_doi_declaration_of_intent__write_date
|
||||
msgid "Last Updated on"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model:ir.model.fields,help:l10n_it_edi_doi.field_l10n_it_edi_doi_declaration_of_intent__end_date
|
||||
msgid "Last date on which the Declaration of Intent is valid"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model:ir.model.fields,field_description:l10n_it_edi_doi.field_l10n_it_edi_doi_declaration_of_intent__message_main_attachment_id
|
||||
msgid "Main Attachment"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model:ir.model.fields,field_description:l10n_it_edi_doi.field_l10n_it_edi_doi_declaration_of_intent__message_has_error
|
||||
msgid "Message Delivery error"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model:ir.model.fields,field_description:l10n_it_edi_doi.field_l10n_it_edi_doi_declaration_of_intent__message_ids
|
||||
msgid "Messages"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model:ir.model.fields,field_description:l10n_it_edi_doi.field_l10n_it_edi_doi_declaration_of_intent__my_activity_date_deadline
|
||||
msgid "My Activity Deadline"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model:ir.model.fields,field_description:l10n_it_edi_doi.field_l10n_it_edi_doi_declaration_of_intent__activity_date_deadline
|
||||
msgid "Next Activity Deadline"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model:ir.model.fields,field_description:l10n_it_edi_doi.field_l10n_it_edi_doi_declaration_of_intent__activity_summary
|
||||
msgid "Next Activity Summary"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model:ir.model.fields,field_description:l10n_it_edi_doi.field_l10n_it_edi_doi_declaration_of_intent__activity_type_id
|
||||
msgid "Next Activity Type"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model:ir.model.fields,field_description:l10n_it_edi_doi.field_l10n_it_edi_doi_declaration_of_intent__not_yet_invoiced
|
||||
msgid "Not Yet Invoiced"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model_terms:ir.ui.view,arch_db:l10n_it_edi_doi.view_quotation_tree
|
||||
msgid "Not Yet Invoiced Amount"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model_terms:ir.ui.view,arch_db:l10n_it_edi_doi.view_quotation_tree
|
||||
msgid "Number"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model:ir.model.fields,field_description:l10n_it_edi_doi.field_l10n_it_edi_doi_declaration_of_intent__message_needaction_counter
|
||||
msgid "Number of Actions"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model:ir.model.fields,field_description:l10n_it_edi_doi.field_l10n_it_edi_doi_declaration_of_intent__message_has_error_counter
|
||||
msgid "Number of errors"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model:ir.model.fields,help:l10n_it_edi_doi.field_l10n_it_edi_doi_declaration_of_intent__message_needaction_counter
|
||||
msgid "Number of messages requiring action"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model:ir.model.fields,help:l10n_it_edi_doi.field_l10n_it_edi_doi_declaration_of_intent__message_has_error_counter
|
||||
msgid "Number of messages with delivery error"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model:ir.model.fields,field_description:l10n_it_edi_doi.field_l10n_it_edi_doi_declaration_of_intent__partner_id
|
||||
msgid "Partner"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#. odoo-python
|
||||
#: code:addons/l10n_it_edi_doi/models/declaration_of_intent.py:0
|
||||
#, python-format
|
||||
msgid ""
|
||||
"Pay attention, the threshold of your Declaration of Intent %s of %s is exceeded by %s, this document included.\n"
|
||||
"Invoiced: %s; Not Yet Invoiced: %s"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model:ir.model.fields,field_description:l10n_it_edi_doi.field_l10n_it_edi_doi_declaration_of_intent__protocol_number_part1
|
||||
msgid "Protocol 1"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model:ir.model.fields,field_description:l10n_it_edi_doi.field_l10n_it_edi_doi_declaration_of_intent__protocol_number_part2
|
||||
msgid "Protocol 2"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model_terms:ir.ui.view,arch_db:l10n_it_edi_doi.view_l10n_it_edi_doi_form
|
||||
msgid "Protocol Number"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model_terms:ir.ui.view,arch_db:l10n_it_edi_doi.view_l10n_it_edi_doi_form
|
||||
msgid "Reactivate"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model:ir.model.fields,field_description:l10n_it_edi_doi.field_l10n_it_edi_doi_declaration_of_intent__remaining
|
||||
msgid "Remaining"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model:ir.model.fields,help:l10n_it_edi_doi.field_l10n_it_edi_doi_declaration_of_intent__remaining
|
||||
msgid ""
|
||||
"Remaining amount after deduction of the Invoiced and Not Yet Invoiced "
|
||||
"amounts."
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model_terms:ir.ui.view,arch_db:l10n_it_edi_doi.view_l10n_it_edi_doi_form
|
||||
msgid "Reset to Draft"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model:ir.model.fields,field_description:l10n_it_edi_doi.field_l10n_it_edi_doi_declaration_of_intent__activity_user_id
|
||||
msgid "Responsible User"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model_terms:ir.ui.view,arch_db:l10n_it_edi_doi.view_l10n_it_edi_doi_form
|
||||
msgid "Revoke"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model:ir.model.fields.selection,name:l10n_it_edi_doi.selection__l10n_it_edi_doi_declaration_of_intent__state__revoked
|
||||
msgid "Revoked"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model:ir.model.fields,field_description:l10n_it_edi_doi.field_l10n_it_edi_doi_declaration_of_intent__message_has_sms_error
|
||||
msgid "SMS Delivery error"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model:ir.model,name:l10n_it_edi_doi.model_sale_order
|
||||
msgid "Sales Order"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model:ir.model,name:l10n_it_edi_doi.model_sale_order_line
|
||||
msgid "Sales Order Line"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model_terms:ir.ui.view,arch_db:l10n_it_edi_doi.view_quotation_tree
|
||||
msgid "Sales Orders"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model:ir.model.fields,field_description:l10n_it_edi_doi.field_l10n_it_edi_doi_declaration_of_intent__sale_order_ids
|
||||
msgid "Sales Orders / Quotations"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#. odoo-python
|
||||
#: code:addons/l10n_it_edi_doi/models/declaration_of_intent.py:0
|
||||
#, python-format
|
||||
msgid "Sales Orders using Declaration of Intent %s"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model_terms:ir.ui.view,arch_db:l10n_it_edi_doi.view_l10n_it_edi_doi_declaration_of_intent_search
|
||||
msgid "Show active declarations of intent"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model_terms:ir.ui.view,arch_db:l10n_it_edi_doi.view_l10n_it_edi_doi_declaration_of_intent_search
|
||||
msgid "Show draft declarations of intent"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model_terms:ir.ui.view,arch_db:l10n_it_edi_doi.view_l10n_it_edi_doi_declaration_of_intent_search
|
||||
msgid "Show terminated or revoked Declarations of Intent"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model:ir.model.fields,field_description:l10n_it_edi_doi.field_l10n_it_edi_doi_declaration_of_intent__start_date
|
||||
msgid "Start Date"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model:ir.model.fields,field_description:l10n_it_edi_doi.field_l10n_it_edi_doi_declaration_of_intent__state
|
||||
msgid "State"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model:ir.model.fields,help:l10n_it_edi_doi.field_l10n_it_edi_doi_declaration_of_intent__activity_state
|
||||
msgid ""
|
||||
"Status based on activities\n"
|
||||
"Overdue: Due date is already passed\n"
|
||||
"Today: Activity date is today\n"
|
||||
"Planned: Future activities."
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model:ir.model,name:l10n_it_edi_doi.model_account_tax
|
||||
msgid "Tax"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model_terms:ir.ui.view,arch_db:l10n_it_edi_doi.view_move_tree
|
||||
msgid "Tax excluded"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model_terms:ir.ui.view,arch_db:l10n_it_edi_doi.view_l10n_it_edi_doi_form
|
||||
msgid "Terminate"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model:ir.model.fields.selection,name:l10n_it_edi_doi.selection__l10n_it_edi_doi_declaration_of_intent__state__terminated
|
||||
msgid "Terminated"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model_terms:ir.ui.view,arch_db:l10n_it_edi_doi.view_l10n_it_edi_doi_declaration_of_intent_search
|
||||
msgid "Terminated / Revoked"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#. odoo-python
|
||||
#: code:addons/l10n_it_edi_doi/models/declaration_of_intent.py:0
|
||||
#, python-format
|
||||
msgid "The Declaration of Intent belongs to company %s, not %s."
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#. odoo-python
|
||||
#: code:addons/l10n_it_edi_doi/models/declaration_of_intent.py:0
|
||||
#, python-format
|
||||
msgid "The Declaration of Intent belongs to partner %s, not %s."
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#. odoo-python
|
||||
#: code:addons/l10n_it_edi_doi/models/declaration_of_intent.py:0
|
||||
#, python-format
|
||||
msgid "The Declaration of Intent is in draft."
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#. odoo-python
|
||||
#: code:addons/l10n_it_edi_doi/models/declaration_of_intent.py:0
|
||||
#, python-format
|
||||
msgid "The Declaration of Intent is valid from %s to %s, not on %s."
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#. odoo-python
|
||||
#: code:addons/l10n_it_edi_doi/models/declaration_of_intent.py:0
|
||||
#, python-format
|
||||
msgid "The Declaration of Intent must be active."
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#. odoo-python
|
||||
#: code:addons/l10n_it_edi_doi/models/declaration_of_intent.py:0
|
||||
#, python-format
|
||||
msgid "The Declaration of Intent uses currency %s, not %s."
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model:ir.model.constraint,message:l10n_it_edi_doi.constraint_l10n_it_edi_doi_declaration_of_intent_protocol_number_unique
|
||||
msgid ""
|
||||
"The Protocol Number of a Declaration of Intent must be unique! Please choose"
|
||||
" another one."
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model:ir.model.constraint,message:l10n_it_edi_doi.constraint_l10n_it_edi_doi_declaration_of_intent_threshold_positive
|
||||
msgid "The Threshold of a Declaration of Intent must be positive."
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model:ir.model.fields,help:l10n_it_edi_doi.field_l10n_it_edi_doi_declaration_of_intent__state
|
||||
msgid ""
|
||||
"The state of this Declaration of Intent. \n"
|
||||
"- 'Draft' means that the Declaration of Intent still needs to be confirmed before being usable. \n"
|
||||
"- 'Active' means that the Declaration of Intent is usable. \n"
|
||||
"- 'Terminated' designates that the Declaration of Intent has been marked as not to use anymore without invalidating usages of it. \n"
|
||||
"- 'Revoked' means the Declaration of Intent should not have been used. You will probably need to revert previous usages of it, if any.\n"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model:ir.model.fields,field_description:l10n_it_edi_doi.field_l10n_it_edi_doi_declaration_of_intent__threshold
|
||||
msgid "Threshold"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model_terms:ir.ui.view,arch_db:l10n_it_edi_doi.view_move_tree
|
||||
#: model_terms:ir.ui.view,arch_db:l10n_it_edi_doi.view_quotation_tree
|
||||
msgid "Total"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model:ir.model.fields,help:l10n_it_edi_doi.field_l10n_it_edi_doi_declaration_of_intent__threshold
|
||||
msgid ""
|
||||
"Total amount of allowed sales without VAT under this Declaration of Intent"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model:ir.model.fields,help:l10n_it_edi_doi.field_l10n_it_edi_doi_declaration_of_intent__not_yet_invoiced
|
||||
msgid ""
|
||||
"Total amount of planned sales under this Declaration of Intent (i.e. current"
|
||||
" quotation and sales orders) that can still be invoiced"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model:ir.model.fields,help:l10n_it_edi_doi.field_account_bank_statement_line__l10n_it_edi_doi_amount
|
||||
#: model:ir.model.fields,help:l10n_it_edi_doi.field_account_move__l10n_it_edi_doi_amount
|
||||
#: model:ir.model.fields,help:l10n_it_edi_doi.field_account_payment__l10n_it_edi_doi_amount
|
||||
msgid "Total amount of sales under the Declaration of Intent of this document"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model:ir.model.fields,help:l10n_it_edi_doi.field_l10n_it_edi_doi_declaration_of_intent__invoiced
|
||||
msgid "Total amount of sales under this Declaration of Intent"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model:ir.model.fields,help:l10n_it_edi_doi.field_sale_order__l10n_it_edi_doi_not_yet_invoiced
|
||||
msgid ""
|
||||
"Total under the Declaration of Intent of this document that can still be "
|
||||
"invoiced"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model:ir.model.fields,help:l10n_it_edi_doi.field_l10n_it_edi_doi_declaration_of_intent__activity_exception_decoration
|
||||
msgid "Type of the exception activity on record."
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model:ir.model.fields,field_description:l10n_it_edi_doi.field_account_bank_statement_line__l10n_it_edi_doi_use
|
||||
#: model:ir.model.fields,field_description:l10n_it_edi_doi.field_account_move__l10n_it_edi_doi_use
|
||||
#: model:ir.model.fields,field_description:l10n_it_edi_doi.field_account_payment__l10n_it_edi_doi_use
|
||||
#: model:ir.model.fields,field_description:l10n_it_edi_doi.field_sale_order__l10n_it_edi_doi_use
|
||||
msgid "Use Declaration of Intent"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model_terms:ir.ui.view,arch_db:l10n_it_edi_doi.view_l10n_it_edi_doi_form
|
||||
msgid "Validate"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model:ir.model.fields,field_description:l10n_it_edi_doi.field_l10n_it_edi_doi_declaration_of_intent__website_message_ids
|
||||
msgid "Website Messages"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model:ir.model.fields,help:l10n_it_edi_doi.field_l10n_it_edi_doi_declaration_of_intent__website_message_ids
|
||||
msgid "Website communication history"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#. odoo-python
|
||||
#: code:addons/l10n_it_edi_doi/models/declaration_of_intent.py:0
|
||||
#, python-format
|
||||
msgid ""
|
||||
"You cannot delete Declarations of Intents that are already used on at least "
|
||||
"one Invoice or Sales Order."
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#. odoo-python
|
||||
#: code:addons/l10n_it_edi_doi/models/account_fiscal_position.py:0
|
||||
#, python-format
|
||||
msgid ""
|
||||
"You cannot delete the special fiscal position for Declarations of Intent."
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#. odoo-python
|
||||
#: code:addons/l10n_it_edi_doi/models/account_tax.py:0
|
||||
#, python-format
|
||||
msgid "You cannot delete the special tax for Declarations of Intent."
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model_terms:ir.ui.view,arch_db:l10n_it_edi_doi.report_invoice_document
|
||||
#: model_terms:ir.ui.view,arch_db:l10n_it_edi_doi.report_saleorder_document
|
||||
msgid "Your Declaration of Intent number"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_it_edi_doi
|
||||
#: model_terms:ir.ui.view,arch_db:l10n_it_edi_doi.report_invoice_document
|
||||
#: model_terms:ir.ui.view,arch_db:l10n_it_edi_doi.report_saleorder_document
|
||||
msgid "from"
|
||||
msgstr ""
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
from . import account_chart_template
|
||||
from . import account_fiscal_position
|
||||
from . import account_move
|
||||
from . import account_tax
|
||||
from . import declaration_of_intent
|
||||
from . import res_company
|
||||
from . import res_partner
|
||||
from . import sale_order
|
||||
from . import sale_order_line
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
from odoo import models
|
||||
|
||||
|
||||
class AccountChartTemplate(models.AbstractModel):
|
||||
_inherit = 'account.chart.template'
|
||||
|
||||
def _load(self, company):
|
||||
res = super()._load(company)
|
||||
if self == self.env.ref('l10n_it.l10n_it_chart_template_generic'):
|
||||
doi_tax = self.env.ref(f'l10n_it_edi_doi.{company.id}_00di', raise_if_not_found=False)
|
||||
if doi_tax:
|
||||
doi_tax.write({
|
||||
'l10n_it_has_exoneration': True,
|
||||
'l10n_it_kind_exoneration': 'N3.5',
|
||||
'l10n_it_law_reference': 'art. 8, c. 1, lett. c) D.P.R. 633/1972',
|
||||
})
|
||||
company.l10n_it_edi_doi_tax_id = doi_tax
|
||||
|
||||
doi_fiscal_position = self.env.ref(f'l10n_it_edi_doi.{company.id}_declaration_of_intent_fiscal_position', raise_if_not_found=False)
|
||||
if doi_fiscal_position:
|
||||
company.l10n_it_edi_doi_fiscal_position_id = doi_fiscal_position
|
||||
return res
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from odoo import api, models, _
|
||||
from odoo.exceptions import UserError
|
||||
|
||||
|
||||
class AccountFiscalPosition(models.Model):
|
||||
_inherit = 'account.fiscal.position'
|
||||
|
||||
@api.ondelete(at_uninstall=False)
|
||||
def _never_unlink_declaration_of_intent_fiscal_position(self):
|
||||
for fiscal_position in self:
|
||||
if fiscal_position == fiscal_position.company_id.l10n_it_edi_doi_fiscal_position_id:
|
||||
raise UserError(_('You cannot delete the special fiscal position for Declarations of Intent.'))
|
||||
|
|
@ -0,0 +1,212 @@
|
|||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from odoo import _, api, fields, models
|
||||
from odoo.exceptions import UserError
|
||||
|
||||
|
||||
class AccountMove(models.Model):
|
||||
_inherit = 'account.move'
|
||||
|
||||
l10n_it_edi_doi_date = fields.Date(
|
||||
string="Date on which Declaration of Intent is applied",
|
||||
compute='_compute_l10n_it_edi_doi_date',
|
||||
)
|
||||
|
||||
l10n_it_edi_doi_use = fields.Boolean(
|
||||
string="Use Declaration of Intent",
|
||||
compute='_compute_l10n_it_edi_doi_use',
|
||||
)
|
||||
|
||||
l10n_it_edi_doi_id = fields.Many2one(
|
||||
string="Declaration of Intent",
|
||||
compute='_compute_l10n_it_edi_doi_id',
|
||||
store=True,
|
||||
readonly=False,
|
||||
precompute=True,
|
||||
comodel_name='l10n_it_edi_doi.declaration_of_intent',
|
||||
)
|
||||
|
||||
l10n_it_edi_doi_amount = fields.Monetary(
|
||||
string='Declaration of Intent Amount',
|
||||
compute='_compute_l10n_it_edi_doi_amount',
|
||||
store=True,
|
||||
readonly=True,
|
||||
help="Total amount of sales under the Declaration of Intent of this document",
|
||||
)
|
||||
|
||||
l10n_it_edi_doi_warning = fields.Text(
|
||||
string="Declaration of Intent Threshold Warning",
|
||||
compute='_compute_l10n_it_edi_doi_warning',
|
||||
)
|
||||
|
||||
@api.depends('invoice_date')
|
||||
def _compute_l10n_it_edi_doi_date(self):
|
||||
for move in self:
|
||||
move.l10n_it_edi_doi_date = move.invoice_date or fields.Date.context_today(self)
|
||||
|
||||
@api.depends('l10n_it_edi_doi_id', 'country_code', 'move_type')
|
||||
def _compute_l10n_it_edi_doi_use(self):
|
||||
sale_types = self.env['account.move'].get_sale_types()
|
||||
for move in self:
|
||||
move.l10n_it_edi_doi_use = (
|
||||
move.l10n_it_edi_doi_id
|
||||
or (move.country_code == "IT" and move.move_type in sale_types)
|
||||
)
|
||||
|
||||
@api.depends('company_id', 'partner_id.commercial_partner_id', 'l10n_it_edi_doi_date', 'currency_id')
|
||||
def _compute_l10n_it_edi_doi_id(self):
|
||||
for move in self:
|
||||
if not move.l10n_it_edi_doi_use or move.state != 'draft' and not move.l10n_it_edi_doi_id:
|
||||
move.l10n_it_edi_doi_id = False
|
||||
continue
|
||||
partner = move.partner_id.commercial_partner_id
|
||||
|
||||
# Avoid a query or changing a manually set declaration of intent
|
||||
# (if the declaration is still valid).
|
||||
validity_warnings = move.l10n_it_edi_doi_id._get_validity_warnings(
|
||||
move.company_id, partner, move.currency_id, move.l10n_it_edi_doi_date
|
||||
)
|
||||
if move.l10n_it_edi_doi_id and not validity_warnings:
|
||||
continue
|
||||
|
||||
declaration = self.env['l10n_it_edi_doi.declaration_of_intent']\
|
||||
._fetch_valid_declaration_of_intent(move.company_id, partner, move.currency_id, move.l10n_it_edi_doi_date)
|
||||
move.l10n_it_edi_doi_id = declaration
|
||||
|
||||
@api.depends('l10n_it_edi_doi_id', 'tax_totals', 'move_type')
|
||||
def _compute_l10n_it_edi_doi_amount(self):
|
||||
"""
|
||||
Consider all the lines in self that belong to declaration of intent `declaration`
|
||||
and have the special declaration of intent tax applied.
|
||||
This function computes the signed sum of the price_total of all those lines
|
||||
(the tax amount of the lines is always 0).
|
||||
The direction_sign determines the sign: 1 (-1) for inbound (outbound) types.
|
||||
"""
|
||||
for move in self:
|
||||
tax = move.company_id.l10n_it_edi_doi_tax_id
|
||||
if not tax or not move.l10n_it_edi_doi_id:
|
||||
move.l10n_it_edi_doi_amount = 0
|
||||
continue
|
||||
declaration_lines = move.invoice_line_ids.filtered(
|
||||
# The declaration tax cannot be used with other taxes on a single line
|
||||
# (checked in `_post`)
|
||||
lambda line: line.tax_ids.ids == tax.ids
|
||||
)
|
||||
move.l10n_it_edi_doi_amount = sum(declaration_lines.mapped('price_total')) * -move.direction_sign
|
||||
|
||||
@api.depends('l10n_it_edi_doi_id', 'l10n_it_edi_doi_amount', 'state')
|
||||
def _compute_l10n_it_edi_doi_warning(self):
|
||||
for move in self:
|
||||
move.l10n_it_edi_doi_warning = ''
|
||||
declaration = move.l10n_it_edi_doi_id
|
||||
|
||||
show_warning = (
|
||||
declaration
|
||||
and move.is_sale_document(include_receipts=False)
|
||||
and move.state != 'cancel'
|
||||
)
|
||||
if not show_warning:
|
||||
continue
|
||||
|
||||
declaration_invoiced = declaration.invoiced
|
||||
declaration_not_yet_invoiced = declaration.not_yet_invoiced
|
||||
if move.state != 'posted': # exactly the 'posted' invoices are included in declaration.invoiced
|
||||
# Here we replicate what would happen when posting the invoice.
|
||||
# Note: lines manually added to a move linked to a sales order are not added to the sales order
|
||||
declaration_invoiced += move.l10n_it_edi_doi_amount
|
||||
additional_invoiced_qty = {}
|
||||
linked_orders = self.env['sale.order']
|
||||
for invoice_line in move.invoice_line_ids:
|
||||
for sale_line in invoice_line.sale_line_ids:
|
||||
order = sale_line.order_id
|
||||
if order.l10n_it_edi_doi_id == declaration:
|
||||
linked_orders |= order
|
||||
qty_invoiced = invoice_line.product_uom_id._compute_quantity(invoice_line.quantity, sale_line.product_uom) * -move.direction_sign
|
||||
sale_line_id = sale_line.ids[0] # do not just use `id` in case of NewId
|
||||
additional_invoiced_qty[sale_line_id] = additional_invoiced_qty.get(sale_line_id, 0) + qty_invoiced
|
||||
for order in linked_orders:
|
||||
not_yet_invoiced = order.l10n_it_edi_doi_not_yet_invoiced
|
||||
not_yet_invoiced_after_posting = order._l10n_it_edi_doi_get_amount_not_yet_invoiced(
|
||||
declaration,
|
||||
additional_invoiced_qty=additional_invoiced_qty,
|
||||
)
|
||||
declaration_not_yet_invoiced -= not_yet_invoiced - not_yet_invoiced_after_posting
|
||||
|
||||
validity_warnings = declaration._get_validity_warnings(
|
||||
move.company_id, move.commercial_partner_id, move.currency_id, move.l10n_it_edi_doi_date,
|
||||
invoiced_amount=declaration_invoiced,
|
||||
)
|
||||
|
||||
threshold_warning = declaration._build_threshold_warning_message(declaration_invoiced, declaration_not_yet_invoiced)
|
||||
|
||||
move.l10n_it_edi_doi_warning = '{}\n\n{}'.format('\n'.join(validity_warnings), threshold_warning).strip()
|
||||
|
||||
@api.depends('l10n_it_edi_doi_id')
|
||||
def _compute_fiscal_position_id(self):
|
||||
super()._compute_fiscal_position_id()
|
||||
for move in self:
|
||||
declaration_fiscal_position = move.company_id.l10n_it_edi_doi_fiscal_position_id
|
||||
if declaration_fiscal_position and move.l10n_it_edi_doi_id:
|
||||
move.fiscal_position_id = declaration_fiscal_position
|
||||
|
||||
def copy_data(self, default=None):
|
||||
data_list = super().copy_data(default)
|
||||
for move, data in zip(self, data_list):
|
||||
date = fields.Date.context_today(self)
|
||||
validity_warnings = move.l10n_it_edi_doi_id._get_validity_warnings(
|
||||
move.company_id, move.commercial_partner_id, move.currency_id, date,
|
||||
only_blocking=True,
|
||||
)
|
||||
if validity_warnings:
|
||||
del data['l10n_it_edi_doi_id']
|
||||
del data['fiscal_position_id']
|
||||
return data_list
|
||||
|
||||
@api.constrains('l10n_it_edi_doi_id')
|
||||
def _check_l10n_it_edi_doi_id(self):
|
||||
for move in self:
|
||||
validity_errors = move.l10n_it_edi_doi_id._get_validity_errors(
|
||||
move.company_id, move.partner_id.commercial_partner_id, move.currency_id
|
||||
)
|
||||
if validity_errors:
|
||||
raise UserError('\n'.join(validity_errors))
|
||||
|
||||
def _post(self, soft=True):
|
||||
errors = []
|
||||
for move in self:
|
||||
declaration = move.l10n_it_edi_doi_id
|
||||
if declaration:
|
||||
validity_warnings = declaration._get_validity_warnings(
|
||||
move.company_id, move.commercial_partner_id, move.currency_id, move.l10n_it_edi_doi_date,
|
||||
invoiced_amount=move.l10n_it_edi_doi_amount,
|
||||
only_blocking=True
|
||||
)
|
||||
errors.extend(validity_warnings)
|
||||
|
||||
declaration_of_intent_tax = move.company_id.l10n_it_edi_doi_tax_id
|
||||
if not declaration_of_intent_tax:
|
||||
continue
|
||||
|
||||
declaration_lines = move.invoice_line_ids.filtered(
|
||||
lambda line: declaration_of_intent_tax in line.tax_ids
|
||||
)
|
||||
if declaration_lines and not declaration:
|
||||
errors.append(_('Given the tax %s is applied, there should be a Declaration of Intent selected.',
|
||||
declaration_of_intent_tax.name))
|
||||
if any(line.tax_ids != declaration_of_intent_tax for line in declaration_lines):
|
||||
errors.append(_('A line using tax %s should not contain any other taxes',
|
||||
declaration_of_intent_tax.name))
|
||||
if errors:
|
||||
raise UserError('\n'.join(errors))
|
||||
|
||||
return super()._post(soft)
|
||||
|
||||
def action_open_declaration_of_intent(self):
|
||||
self.ensure_one()
|
||||
return {
|
||||
'name': _("Declaration of Intent for %s", self.display_name),
|
||||
'type': 'ir.actions.act_window',
|
||||
'view_mode': 'form',
|
||||
'res_model': 'l10n_it_edi_doi.declaration_of_intent',
|
||||
'res_id': self.l10n_it_edi_doi_id.id,
|
||||
}
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
from odoo import api, models, _
|
||||
from odoo.exceptions import UserError
|
||||
|
||||
|
||||
class AccountTax(models.Model):
|
||||
_inherit = 'account.tax'
|
||||
|
||||
@api.ondelete(at_uninstall=False)
|
||||
def _never_unlink_declaration_of_intent_tax(self):
|
||||
for tax in self:
|
||||
if tax == tax.company_id.l10n_it_edi_doi_tax_id:
|
||||
raise UserError(_('You cannot delete the special tax for Declarations of Intent.'))
|
||||
|
|
@ -0,0 +1,311 @@
|
|||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from odoo import api, fields, models, _
|
||||
from odoo.exceptions import UserError
|
||||
from odoo.tools.misc import formatLang
|
||||
|
||||
|
||||
class L10nItDeclarationOfIntent(models.Model):
|
||||
_name = "l10n_it_edi_doi.declaration_of_intent"
|
||||
_inherit = ['mail.thread', 'mail.activity.mixin']
|
||||
_description = "Declaration of Intent"
|
||||
_order = 'protocol_number_part1, protocol_number_part2'
|
||||
|
||||
state = fields.Selection([
|
||||
('draft', 'Draft'),
|
||||
('active', 'Active'),
|
||||
('revoked', 'Revoked'),
|
||||
('terminated', 'Terminated'),
|
||||
],
|
||||
string="State",
|
||||
tracking=True,
|
||||
default='draft',
|
||||
required=True,
|
||||
readonly=True,
|
||||
help="The state of this Declaration of Intent. \n"
|
||||
"- 'Draft' means that the Declaration of Intent still needs to be confirmed before being usable. \n"
|
||||
"- 'Active' means that the Declaration of Intent is usable. \n"
|
||||
"- 'Terminated' designates that the Declaration of Intent has been marked as not to use anymore without invalidating usages of it. \n"
|
||||
"- 'Revoked' means the Declaration of Intent should not have been used. You will probably need to revert previous usages of it, if any.\n")
|
||||
|
||||
company_id = fields.Many2one(
|
||||
comodel_name='res.company',
|
||||
string='Company',
|
||||
index=True,
|
||||
required=True,
|
||||
default=lambda self: self.env.company,
|
||||
)
|
||||
|
||||
partner_id = fields.Many2one(
|
||||
comodel_name='res.partner',
|
||||
string='Partner',
|
||||
index=True,
|
||||
required=True,
|
||||
domain="['|', ('is_company', '=', True), ('parent_id', '=', False)]",
|
||||
)
|
||||
|
||||
currency_id = fields.Many2one(
|
||||
comodel_name='res.currency',
|
||||
string='Currency',
|
||||
default=lambda self: self.env.ref('base.EUR', raise_if_not_found=False).id,
|
||||
required=True,
|
||||
readonly=True,
|
||||
)
|
||||
|
||||
issue_date = fields.Date(
|
||||
string='Date of Issue',
|
||||
required=True,
|
||||
copy=False,
|
||||
default=fields.Date.context_today,
|
||||
help="Date on which the Declaration of Intent was issued",
|
||||
)
|
||||
|
||||
start_date = fields.Date(
|
||||
string='Start Date',
|
||||
required=True,
|
||||
copy=False,
|
||||
help="First date on which the Declaration of Intent is valid",
|
||||
)
|
||||
|
||||
end_date = fields.Date(
|
||||
string='End Date',
|
||||
required=True,
|
||||
copy=False,
|
||||
help="Last date on which the Declaration of Intent is valid",
|
||||
)
|
||||
|
||||
threshold = fields.Monetary(
|
||||
string='Threshold',
|
||||
required=True,
|
||||
help="Total amount of allowed sales without VAT under this Declaration of Intent",
|
||||
)
|
||||
|
||||
invoiced = fields.Monetary(
|
||||
string='Invoiced',
|
||||
compute='_compute_invoiced',
|
||||
store=True,
|
||||
readonly=True,
|
||||
help="Total amount of sales under this Declaration of Intent",
|
||||
)
|
||||
|
||||
not_yet_invoiced = fields.Monetary(
|
||||
string='Not Yet Invoiced',
|
||||
compute='_compute_not_yet_invoiced',
|
||||
store=True,
|
||||
readonly=True,
|
||||
help="Total amount of planned sales under this Declaration of Intent (i.e. current quotation and sales orders) that can still be invoiced",
|
||||
)
|
||||
|
||||
remaining = fields.Monetary(
|
||||
string='Remaining',
|
||||
compute='_compute_remaining',
|
||||
store=True,
|
||||
readonly=True,
|
||||
help="Remaining amount after deduction of the Invoiced and Not Yet Invoiced amounts.",
|
||||
)
|
||||
|
||||
protocol_number_part1 = fields.Char(
|
||||
string='Protocol 1',
|
||||
required=True,
|
||||
readonly=False,
|
||||
copy=False,
|
||||
)
|
||||
|
||||
protocol_number_part2 = fields.Char(
|
||||
string='Protocol 2',
|
||||
required=True,
|
||||
readonly=False,
|
||||
copy=False,
|
||||
)
|
||||
|
||||
invoice_ids = fields.One2many(
|
||||
'account.move',
|
||||
'l10n_it_edi_doi_id',
|
||||
string="Invoices / Refunds",
|
||||
copy=False,
|
||||
readonly=True,
|
||||
)
|
||||
|
||||
sale_order_ids = fields.One2many(
|
||||
'sale.order',
|
||||
'l10n_it_edi_doi_id',
|
||||
string="Sales Orders / Quotations",
|
||||
copy=False,
|
||||
readonly=True,
|
||||
)
|
||||
|
||||
_sql_constraints = [
|
||||
('protocol_number_unique',
|
||||
'unique(protocol_number_part1, protocol_number_part2)',
|
||||
"The Protocol Number of a Declaration of Intent must be unique! Please choose another one."),
|
||||
('threshold_positive',
|
||||
'CHECK(threshold > 0)',
|
||||
"The Threshold of a Declaration of Intent must be positive."),
|
||||
]
|
||||
|
||||
def name_get(self):
|
||||
return [(record.id, f"{record.protocol_number_part1}-{record.protocol_number_part2}") for record in self]
|
||||
|
||||
@api.depends('invoice_ids', 'invoice_ids.state', 'invoice_ids.l10n_it_edi_doi_amount')
|
||||
def _compute_invoiced(self):
|
||||
for declaration in self:
|
||||
relevant_invoices = declaration.invoice_ids.filtered(
|
||||
lambda invoice: invoice.state == 'posted'
|
||||
)
|
||||
declaration.invoiced = sum(relevant_invoices.mapped('l10n_it_edi_doi_amount'))
|
||||
|
||||
@api.depends('sale_order_ids', 'sale_order_ids.state', 'sale_order_ids.l10n_it_edi_doi_not_yet_invoiced')
|
||||
def _compute_not_yet_invoiced(self):
|
||||
for declaration in self:
|
||||
relevant_orders = declaration.sale_order_ids.filtered(
|
||||
lambda order: order.state == 'sale'
|
||||
)
|
||||
declaration.not_yet_invoiced = sum(relevant_orders.mapped('l10n_it_edi_doi_not_yet_invoiced'))
|
||||
|
||||
@api.depends('threshold', 'not_yet_invoiced', 'invoiced')
|
||||
def _compute_remaining(self):
|
||||
for record in self:
|
||||
record.remaining = record.threshold - record.invoiced - record.not_yet_invoiced
|
||||
|
||||
def _build_threshold_warning_message(self, invoiced, not_yet_invoiced):
|
||||
"""
|
||||
Build a warning message that will be displayed in a yellow banner on top of a document
|
||||
if the `remaining` of the Declaration of Intent is less than 0 when including the document
|
||||
or the Declaration of Intent is revoked
|
||||
:param float invoiced: The `declaration.invoiced` amount when including the document.
|
||||
:param float not_yet_invoiced: The `declaration.not_yet_invoiced` amount when including the document.
|
||||
:return str: The warning message to be shown.
|
||||
"""
|
||||
self.ensure_one()
|
||||
updated_remaining = self.threshold - invoiced - not_yet_invoiced
|
||||
if self.currency_id.compare_amounts(updated_remaining, 0) >= 0:
|
||||
return ''
|
||||
return _(
|
||||
'Pay attention, the threshold of your Declaration of Intent %s of %s is exceeded by %s, this document included.\n'
|
||||
'Invoiced: %s; Not Yet Invoiced: %s',
|
||||
self.display_name,
|
||||
formatLang(self.env, self.threshold, currency_obj=self.currency_id),
|
||||
formatLang(self.env, - updated_remaining, currency_obj=self.currency_id),
|
||||
formatLang(self.env, invoiced, currency_obj=self.currency_id),
|
||||
formatLang(self.env, not_yet_invoiced, currency_obj=self.currency_id),
|
||||
)
|
||||
|
||||
def _get_validity_errors(self, company, partner, currency):
|
||||
"""
|
||||
Check whether all declarations of intent in self are valid for the specified `company`, `partner`, `date` and `currency'.
|
||||
Violating these constraints leads to errors in the feature. They should not be ignored.
|
||||
Return all errors as a list of strings.
|
||||
"""
|
||||
errors = []
|
||||
for declaration in self:
|
||||
if not company or declaration.company_id != company:
|
||||
errors.append(_("The Declaration of Intent belongs to company %s, not %s.",
|
||||
declaration.company_id.name, company.name))
|
||||
if not currency or declaration.currency_id != currency:
|
||||
errors.append(_("The Declaration of Intent uses currency %s, not %s.",
|
||||
declaration.currency_id.name, currency.name))
|
||||
if not partner or declaration.partner_id != partner.commercial_partner_id:
|
||||
errors.append(_("The Declaration of Intent belongs to partner %s, not %s.",
|
||||
declaration.partner_id.name, partner.commercial_partner_id.name))
|
||||
return errors
|
||||
|
||||
def _get_validity_warnings(self, company, partner, currency, date, invoiced_amount=0, only_blocking=False, sales_order=False):
|
||||
"""
|
||||
Check whether all declarations of intent in self are valid for the specified `company`, `partner`, `date` and `currency'.
|
||||
The checks for `date` and state of the declaration (except draft) are not considered blocking in case `invoiced_amount` is not positive.
|
||||
All other checks are considered blocking (prevent posting).
|
||||
Includes all checks from `_get_validity_errors`.
|
||||
The checks are different for invoices and sales orders (toggled via kwarg `sales_order`).
|
||||
I.e. we do not care about the date for sales orders.
|
||||
Return all errors as a list of strings.
|
||||
"""
|
||||
errors = []
|
||||
for declaration in self:
|
||||
errors.extend(declaration._get_validity_errors(company, partner, currency))
|
||||
if declaration.state == 'draft':
|
||||
errors.append(_("The Declaration of Intent is in draft."))
|
||||
if declaration.currency_id.compare_amounts(invoiced_amount, 0) > 0 or not only_blocking:
|
||||
if declaration.state != 'active':
|
||||
errors.append(_("The Declaration of Intent must be active."))
|
||||
if not sales_order and (not date or declaration.start_date > date or declaration.end_date < date):
|
||||
errors.append(_("The Declaration of Intent is valid from %s to %s, not on %s.",
|
||||
declaration.start_date, declaration.end_date, date))
|
||||
return errors
|
||||
|
||||
@api.model
|
||||
def _fetch_valid_declaration_of_intent(self, company, partner, currency, date):
|
||||
"""
|
||||
Fetch a declaration of intent that is valid for the specified `company`, `partner`, `date` and `currency`
|
||||
and has not reached the threshold yet.
|
||||
"""
|
||||
return self.search([
|
||||
('state', '=', 'active'),
|
||||
('company_id', '=', company.id),
|
||||
('currency_id', '=', currency.id),
|
||||
('partner_id', '=', partner.commercial_partner_id.id),
|
||||
('start_date', '<=', date),
|
||||
('end_date', '>=', date),
|
||||
('remaining', '>', 0),
|
||||
], limit=1)
|
||||
|
||||
@api.ondelete(at_uninstall=False)
|
||||
def _unlink_except_linked_to_document(self):
|
||||
if self.invoice_ids or self.sale_order_ids:
|
||||
raise UserError(_('You cannot delete Declarations of Intents that are already used on at least one Invoice or Sales Order.'))
|
||||
|
||||
def action_validate(self):
|
||||
""" Move a 'draft' Declaration of Intent to 'active'."""
|
||||
for record in self:
|
||||
if record.state == 'draft':
|
||||
record.state = 'active'
|
||||
|
||||
def action_reset_to_draft(self):
|
||||
""" Resets an 'active' Declaration of Intent back to 'draft'."""
|
||||
for record in self:
|
||||
if record.state == 'active':
|
||||
record.state = 'draft'
|
||||
|
||||
def action_reactivate(self):
|
||||
""" Resets a not 'active' Declaration of Intent back to 'active'."""
|
||||
for record in self:
|
||||
if record.state != 'active':
|
||||
record.state = 'active'
|
||||
|
||||
def action_revoke(self):
|
||||
""" Called by the 'revoke' button of the form view."""
|
||||
for record in self:
|
||||
record.state = 'revoked'
|
||||
|
||||
def action_terminate(self):
|
||||
""" Called by the 'terminated' button of the form view."""
|
||||
for record in self:
|
||||
if record.state != 'revoked':
|
||||
record.state = 'terminated'
|
||||
|
||||
def action_open_sale_order_ids(self):
|
||||
self.ensure_one()
|
||||
return {
|
||||
'name': _("Sales Orders using Declaration of Intent %s", self.display_name),
|
||||
'type': 'ir.actions.act_window',
|
||||
'res_model': 'sale.order',
|
||||
'domain': [('id', 'in', self.sale_order_ids.ids)],
|
||||
'views': [(self.env.ref('l10n_it_edi_doi.view_quotation_tree').id, 'tree'), (False, 'form')],
|
||||
'search_view_id': [self.env.ref('sale.sale_order_view_search_inherit_quotation').id],
|
||||
'context': {
|
||||
'search_default_sales': 1,
|
||||
},
|
||||
}
|
||||
|
||||
def action_open_invoice_ids(self):
|
||||
self.ensure_one()
|
||||
return {
|
||||
'name': _("Invoices using Declaration of Intent %s", self.display_name),
|
||||
'type': 'ir.actions.act_window',
|
||||
'res_model': 'account.move',
|
||||
'domain': [('id', 'in', self.invoice_ids.ids)],
|
||||
'views': [(self.env.ref('l10n_it_edi_doi.view_move_tree').id, 'tree'), (False, 'form')],
|
||||
'search_view_id': [self.env.ref('account.view_account_invoice_filter').id],
|
||||
'context': {
|
||||
'search_default_posted': 1,
|
||||
},
|
||||
}
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from odoo import fields, models
|
||||
|
||||
|
||||
class ResCompany(models.Model):
|
||||
_inherit = 'res.company'
|
||||
|
||||
l10n_it_edi_doi_tax_id = fields.Many2one(
|
||||
comodel_name='account.tax',
|
||||
string="Declaration of Intent Tax",
|
||||
)
|
||||
|
||||
l10n_it_edi_doi_fiscal_position_id = fields.Many2one(
|
||||
comodel_name='account.fiscal.position',
|
||||
string="Declaration of Intent Fiscal Position",
|
||||
)
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from odoo import fields, models, _
|
||||
|
||||
|
||||
class ResPartner(models.Model):
|
||||
_inherit = 'res.partner'
|
||||
|
||||
l10n_it_edi_doi_ids = fields.One2many(
|
||||
'l10n_it_edi_doi.declaration_of_intent',
|
||||
'partner_id',
|
||||
string="Available Declarations of Intent of this partner",
|
||||
domain=lambda self: [('company_id', '=', self.env.company.id)],
|
||||
)
|
||||
|
||||
def l10n_it_edi_doi_action_open_declarations(self):
|
||||
self.ensure_one()
|
||||
return {
|
||||
'name': _("Declaration of Intent of %s", self.display_name),
|
||||
'type': 'ir.actions.act_window',
|
||||
'res_model': 'l10n_it_edi_doi.declaration_of_intent',
|
||||
'domain': [('partner_id', '=', self.commercial_partner_id.id)],
|
||||
'views': [(self.env.ref('l10n_it_edi_doi.view_l10n_it_edi_doi_tree').id, 'tree'),
|
||||
(self.env.ref('l10n_it_edi_doi.view_l10n_it_edi_doi_form').id, 'form')],
|
||||
'context': {
|
||||
'default_partner_id': self.id,
|
||||
},
|
||||
}
|
||||
|
|
@ -0,0 +1,256 @@
|
|||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from odoo import api, fields, models, _
|
||||
from odoo.exceptions import UserError, ValidationError
|
||||
|
||||
|
||||
class SaleOrder(models.Model):
|
||||
_inherit = 'sale.order'
|
||||
|
||||
l10n_it_edi_doi_date = fields.Date(
|
||||
string="Date on which Declaration of Intent is applied",
|
||||
compute='_compute_l10n_it_edi_doi_date',
|
||||
)
|
||||
|
||||
l10n_it_edi_doi_use = fields.Boolean(
|
||||
string="Use Declaration of Intent",
|
||||
compute='_compute_l10n_it_edi_doi_use',
|
||||
)
|
||||
|
||||
l10n_it_edi_doi_id = fields.Many2one(
|
||||
string="Declaration of Intent",
|
||||
compute='_compute_l10n_it_edi_doi_id',
|
||||
store=True,
|
||||
readonly=False,
|
||||
precompute=True,
|
||||
comodel_name='l10n_it_edi_doi.declaration_of_intent',
|
||||
)
|
||||
|
||||
l10n_it_edi_doi_not_yet_invoiced = fields.Monetary(
|
||||
string='Declaration of Intent Amount Not Yet Invoiced',
|
||||
compute='_compute_l10n_it_edi_doi_not_yet_invoiced',
|
||||
store=True,
|
||||
readonly=True,
|
||||
help="Total under the Declaration of Intent of this document that can still be invoiced",
|
||||
)
|
||||
|
||||
l10n_it_edi_doi_warning = fields.Text(
|
||||
string="Declaration of Intent Threshold Warning",
|
||||
compute='_compute_l10n_it_edi_doi_warning',
|
||||
)
|
||||
|
||||
@api.depends('date_order')
|
||||
def _compute_l10n_it_edi_doi_date(self):
|
||||
for order in self:
|
||||
order.l10n_it_edi_doi_date = order.date_order or fields.Date.context_today(self)
|
||||
|
||||
@api.depends('l10n_it_edi_doi_id', 'country_code')
|
||||
def _compute_l10n_it_edi_doi_use(self):
|
||||
for order in self:
|
||||
order.l10n_it_edi_doi_use = order.l10n_it_edi_doi_id \
|
||||
or order.country_code == "IT"
|
||||
|
||||
@api.depends('company_id', 'partner_id.commercial_partner_id', 'l10n_it_edi_doi_date', 'currency_id')
|
||||
def _compute_l10n_it_edi_doi_id(self):
|
||||
for order in self:
|
||||
if not order.l10n_it_edi_doi_use or order.state != 'draft' and not order.l10n_it_edi_doi_id:
|
||||
order.l10n_it_edi_doi_id = False
|
||||
continue
|
||||
partner = order.partner_id.commercial_partner_id
|
||||
|
||||
# Avoid a query or changing a manually set declaration of intent
|
||||
# (if the declaration is still valid).
|
||||
validity_warnings = order.l10n_it_edi_doi_id._get_validity_warnings(
|
||||
order.company_id, partner, order.currency_id, order.l10n_it_edi_doi_date, sales_order=True
|
||||
)
|
||||
if order.l10n_it_edi_doi_id and not validity_warnings:
|
||||
continue
|
||||
|
||||
declaration = self.env['l10n_it_edi_doi.declaration_of_intent']\
|
||||
._fetch_valid_declaration_of_intent(order.company_id, partner, order.currency_id, order.l10n_it_edi_doi_date)
|
||||
order.l10n_it_edi_doi_id = declaration
|
||||
|
||||
@api.depends('l10n_it_edi_doi_id', 'tax_totals', 'order_line', 'order_line.qty_invoiced_posted')
|
||||
def _compute_l10n_it_edi_doi_not_yet_invoiced(self):
|
||||
for order in self:
|
||||
declaration = order.l10n_it_edi_doi_id
|
||||
order.l10n_it_edi_doi_not_yet_invoiced = order._l10n_it_edi_doi_get_amount_not_yet_invoiced(declaration)
|
||||
|
||||
@api.depends('l10n_it_edi_doi_id', 'l10n_it_edi_doi_id.remaining', 'state', 'tax_totals')
|
||||
def _compute_l10n_it_edi_doi_warning(self):
|
||||
for order in self:
|
||||
order.l10n_it_edi_doi_warning = ''
|
||||
declaration = order.l10n_it_edi_doi_id
|
||||
|
||||
show_warning = declaration and order.state != 'cancelled'
|
||||
if not show_warning:
|
||||
continue
|
||||
|
||||
declaration_not_yet_invoiced = declaration.not_yet_invoiced
|
||||
# Exactly the confirmed SOs (state == 'sale') are included in `declaration.not_yet_invoiced`.
|
||||
# The amount of `declaration.not_yet_invoiced` may change due to confirming or saving `order`.
|
||||
# * An unconfirmed order is being confirmed:
|
||||
# We have to add the order amount to `declaration.not_yet_invoiced`.
|
||||
# * A confirmed SO is being edited:
|
||||
# The field `declaration.not_yet_invoiced` will be updated when saving.
|
||||
# But we want to update the warning during the editing already (before saving).
|
||||
# We first have to remove the "old amount" from `declaration.not_yet_invoiced`
|
||||
# before adding the current amount.
|
||||
if order.state == 'sale':
|
||||
old_order_state = order._origin
|
||||
declaration_not_yet_invoiced -= old_order_state.l10n_it_edi_doi_not_yet_invoiced
|
||||
declaration_not_yet_invoiced += order.l10n_it_edi_doi_not_yet_invoiced
|
||||
|
||||
validity_warnings = declaration._get_validity_warnings(
|
||||
order.company_id, order.partner_id.commercial_partner_id, order.currency_id, order.l10n_it_edi_doi_date,
|
||||
sales_order=True
|
||||
)
|
||||
|
||||
threshold_warning = declaration._build_threshold_warning_message(declaration.invoiced, declaration_not_yet_invoiced)
|
||||
|
||||
order.l10n_it_edi_doi_warning = '{}\n\n{}'.format('\n'.join(validity_warnings), threshold_warning).strip()
|
||||
|
||||
@api.depends('l10n_it_edi_doi_id')
|
||||
def _compute_fiscal_position_id(self):
|
||||
super()._compute_fiscal_position_id()
|
||||
for order in self:
|
||||
declaration_fiscal_position = order.company_id.l10n_it_edi_doi_fiscal_position_id
|
||||
if declaration_fiscal_position and order.l10n_it_edi_doi_id:
|
||||
order.fiscal_position_id = declaration_fiscal_position
|
||||
|
||||
def _prepare_invoice(self):
|
||||
"""
|
||||
Prepare the dict of values to create the new invoice for a sales order. This method may be
|
||||
overridden to implement custom invoice generation (making sure to call super() to establish
|
||||
a clean extension chain).
|
||||
"""
|
||||
vals = super()._prepare_invoice()
|
||||
declaration = self.l10n_it_edi_doi_id
|
||||
if declaration:
|
||||
date = fields.Date.context_today(self)
|
||||
validity_warnings = declaration._get_validity_warnings(
|
||||
self.company_id, self.partner_id.commercial_partner_id, self.currency_id, date, sales_order=True
|
||||
)
|
||||
if not validity_warnings:
|
||||
vals['l10n_it_edi_doi_id'] = declaration.id
|
||||
return vals
|
||||
|
||||
def copy_data(self, default=None):
|
||||
data_list = super().copy_data(default)
|
||||
for order, data in zip(self, data_list):
|
||||
partner = order.partner_id.commercial_partner_id
|
||||
date = fields.Date.context_today(self)
|
||||
if order.l10n_it_edi_doi_id._get_validity_warnings(order.company_id, partner, order.currency_id, date, sales_order=True):
|
||||
del data['l10n_it_edi_doi_id']
|
||||
del data['fiscal_position_id']
|
||||
return data_list
|
||||
|
||||
def _l10n_it_edi_doi_check_configuration(self):
|
||||
"""
|
||||
Raise a UserError in case the configuration of the sale order is invalid.
|
||||
"""
|
||||
errors = []
|
||||
for order in self:
|
||||
declaration = order.l10n_it_edi_doi_id
|
||||
if declaration:
|
||||
validity_warnings = declaration._get_validity_warnings(
|
||||
order.company_id, order.partner_id.commercial_partner_id, order.currency_id, order.l10n_it_edi_doi_date,
|
||||
only_blocking=True, sales_order=True,
|
||||
)
|
||||
errors.extend(validity_warnings)
|
||||
|
||||
declaration_of_intent_tax = order.company_id.l10n_it_edi_doi_tax_id
|
||||
if not declaration_of_intent_tax:
|
||||
continue
|
||||
declaration_tax_lines = order.order_line.filtered(
|
||||
lambda line: declaration_of_intent_tax in line.tax_id
|
||||
)
|
||||
if declaration_tax_lines and not order.l10n_it_edi_doi_id:
|
||||
errors.append(_('Given the tax %s is applied, there should be a Declaration of Intent selected.',
|
||||
declaration_of_intent_tax.name))
|
||||
if any(line.tax_id != declaration_of_intent_tax for line in declaration_tax_lines):
|
||||
errors.append(_('A line using tax %s should not contain any other taxes',
|
||||
declaration_of_intent_tax.name))
|
||||
if errors:
|
||||
raise UserError('\n'.join(errors))
|
||||
|
||||
def action_quotation_send(self):
|
||||
self._l10n_it_edi_doi_check_configuration()
|
||||
return super().action_quotation_send()
|
||||
|
||||
def action_quotation_sent(self):
|
||||
self._l10n_it_edi_doi_check_configuration()
|
||||
return super().action_quotation_sent()
|
||||
|
||||
def action_confirm(self):
|
||||
self._l10n_it_edi_doi_check_configuration()
|
||||
return super().action_confirm()
|
||||
|
||||
@api.constrains('l10n_it_edi_doi_id')
|
||||
def _check_l10n_it_edi_doi_id(self):
|
||||
for order in self:
|
||||
declaration = order.l10n_it_edi_doi_id
|
||||
if not declaration:
|
||||
return
|
||||
partner = order.partner_id.commercial_partner_id
|
||||
errors = declaration._get_validity_warnings(
|
||||
order.company_id, partner, order.currency_id, order.l10n_it_edi_doi_date, only_blocking=True, sales_order=True
|
||||
)
|
||||
if errors:
|
||||
raise ValidationError('\n'.join(errors))
|
||||
|
||||
def action_open_declaration_of_intent(self):
|
||||
self.ensure_one()
|
||||
return {
|
||||
'name': _("Declaration of Intent for %s", self.display_name),
|
||||
'type': 'ir.actions.act_window',
|
||||
'view_mode': 'form',
|
||||
'res_model': 'l10n_it_edi_doi.declaration_of_intent',
|
||||
'res_id': self.l10n_it_edi_doi_id.id,
|
||||
}
|
||||
|
||||
def _l10n_it_edi_doi_get_amount_not_yet_invoiced(self, declaration, additional_invoiced_qty=None):
|
||||
"""
|
||||
Consider sales orders in self that use declaration of intent `declaration`.
|
||||
For each sales order we compute the amount that is tax exempt due to the declaration of intent
|
||||
(line has special declaration of intent tax applied) but not yet invoiced.
|
||||
For each line of the SO we i.e. use the not yet invoiced quantity to compute this amount.
|
||||
The aforementioned quantity is computed from field `qty_invoiced_posted` and parameter `additional_invoiced_qty`
|
||||
Return the sum of all these amounts on the SOs.
|
||||
:param declaration: We only consider sales orders using Declaration of Intent `declaration`.
|
||||
:param additional_invoiced_qty: Dictionary (sale order line id -> float)
|
||||
The float represents additional invoiced amount qty for the sale order.
|
||||
This can i.e. be used to simulate posting an already linked invoice.
|
||||
"""
|
||||
if not declaration:
|
||||
return 0
|
||||
|
||||
if additional_invoiced_qty is None:
|
||||
additional_invoiced_qty = {}
|
||||
|
||||
tax = declaration.company_id.l10n_it_edi_doi_tax_id
|
||||
if not tax:
|
||||
return 0
|
||||
|
||||
not_yet_invoiced = 0
|
||||
for order in self:
|
||||
if declaration != order.l10n_it_edi_doi_id:
|
||||
continue
|
||||
|
||||
order_lines = order.order_line.filtered(
|
||||
# The declaration tax cannot be used with other taxes on a single line
|
||||
# (checked in `action_confirm`)
|
||||
lambda line: line.tax_id.ids == tax.ids
|
||||
)
|
||||
order_not_yet_invoiced = 0
|
||||
for line in order_lines:
|
||||
price_reduce = line.price_unit * (1 - (line.discount or 0.0) / 100.0)
|
||||
qty_invoiced = line.qty_invoiced_posted
|
||||
if line.ids and additional_invoiced_qty:
|
||||
qty_invoiced += additional_invoiced_qty.get(line.ids[0], 0)
|
||||
qty_to_invoice = line.product_uom_qty - qty_invoiced
|
||||
order_not_yet_invoiced += price_reduce * qty_to_invoice
|
||||
if declaration.currency_id.compare_amounts(order_not_yet_invoiced, 0) > 0:
|
||||
not_yet_invoiced += order_not_yet_invoiced
|
||||
|
||||
return not_yet_invoiced
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from odoo import api, fields, models
|
||||
|
||||
|
||||
class SaleOrderLine(models.Model):
|
||||
_inherit = "sale.order.line"
|
||||
|
||||
qty_invoiced_posted = fields.Float(
|
||||
string="Invoiced Quantity (posted)",
|
||||
compute='_compute_qty_invoiced_posted',
|
||||
digits='Product Unit of Measure',
|
||||
store=True,
|
||||
)
|
||||
|
||||
@api.depends('invoice_lines.move_id.state', 'invoice_lines.quantity')
|
||||
def _compute_qty_invoiced_posted(self):
|
||||
"""
|
||||
This method is almost identical to '_compute_qty_invoiced()'. The only difference lies in the fact that
|
||||
for accounting purposes, we only want the quantities of the posted invoices.
|
||||
We need a dedicated computation because the triggers are different and could lead to incorrect values for
|
||||
'qty_invoiced' when computed together.
|
||||
"""
|
||||
for line in self:
|
||||
qty_invoiced_posted = 0.0
|
||||
for invoice_line in line._get_invoice_lines():
|
||||
if invoice_line.move_id.state == 'posted' or invoice_line.move_id.payment_state == 'invoicing_legacy':
|
||||
qty_unsigned = invoice_line.product_uom_id._compute_quantity(invoice_line.quantity, line.product_uom)
|
||||
qty_signed = qty_unsigned * -invoice_line.move_id.direction_sign
|
||||
qty_invoiced_posted += qty_signed
|
||||
line.qty_invoiced_posted = qty_invoiced_posted
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
|
||||
l10n_it_edi_doi.access_l10n_it_edi_doi_declaration_of_intent_readonly,access_l10n_it_edi_doi_declaration_of_intent,l10n_it_edi_doi.model_l10n_it_edi_doi_declaration_of_intent,account.group_account_readonly,1,0,0,0
|
||||
l10n_it_edi_doi.access_l10n_it_edi_doi_declaration_of_intent_invoice,access_l10n_it_edi_doi_declaration_of_intent,l10n_it_edi_doi.model_l10n_it_edi_doi_declaration_of_intent,account.group_account_invoice,1,1,1,1
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
from . import common
|
||||
from . import test_amounts_and_warnings
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from odoo.tests import tagged
|
||||
from odoo.addons.l10n_it_edi.tests.common import TestItEdi
|
||||
|
||||
|
||||
@tagged('post_install_l10n', 'post_install', '-at_install')
|
||||
class TestItEdiDoi(TestItEdi):
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls, chart_template_ref='l10n_it.l10n_it_chart_template_generic'):
|
||||
super().setUpClass(chart_template_ref=chart_template_ref)
|
||||
|
||||
cls.declaration_1000 = cls.env['l10n_it_edi_doi.declaration_of_intent'].create({
|
||||
'company_id': cls.company.id,
|
||||
'partner_id': cls.italian_partner_a.id,
|
||||
'issue_date': '2019-01-01',
|
||||
'start_date': '2019-01-01',
|
||||
'end_date': '2019-12-31',
|
||||
'threshold': 1000,
|
||||
'protocol_number_part1': 'test 2019',
|
||||
'protocol_number_part2': 'threshold 1000',
|
||||
})
|
||||
cls.declaration_1000.action_validate()
|
||||
|
||||
cls.product_1 = cls.env['product.product'].create([{'name': 'test product 1'}])
|
||||
|
||||
cls.pricelist = cls.env['product.pricelist'].with_company(cls.company).create({
|
||||
'name': 'EUR pricelist',
|
||||
'currency_id': cls.company.currency_id.id,
|
||||
'company_id': False,
|
||||
})
|
||||
|
|
@ -0,0 +1,531 @@
|
|||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from freezegun import freeze_time
|
||||
|
||||
from odoo import Command
|
||||
from odoo.addons.l10n_it_edi_doi.tests.common import TestItEdiDoi
|
||||
from odoo.tests import tagged, Form
|
||||
|
||||
|
||||
@tagged('post_install_l10n', 'post_install', '-at_install')
|
||||
class TestItEdiDoiRemaining(TestItEdiDoi):
|
||||
|
||||
def create_invoice(self, declaration, invoice_line_vals):
|
||||
return self.env['account.move'].create({
|
||||
'move_type': 'out_invoice',
|
||||
'company_id': self.company.id,
|
||||
'partner_id': declaration.partner_id.id,
|
||||
'invoice_date': declaration.start_date,
|
||||
'l10n_it_edi_doi_id': declaration.id,
|
||||
'invoice_line_ids': invoice_line_vals,
|
||||
})
|
||||
|
||||
def get_sale_order_vals(self, declaration, order_line_vals):
|
||||
return {
|
||||
'company_id': self.company.id,
|
||||
'partner_id': declaration.partner_id.id,
|
||||
'date_order': declaration.start_date,
|
||||
'pricelist_id': self.pricelist.id,
|
||||
'l10n_it_edi_doi_id': declaration.id,
|
||||
'order_line': order_line_vals,
|
||||
}
|
||||
|
||||
def create_sale_order(self, declaration, order_line_vals):
|
||||
sale_order_vals = self.get_sale_order_vals(declaration, order_line_vals)
|
||||
return self.env['sale.order'].create(sale_order_vals)
|
||||
|
||||
def test_invoice_line_edit(self):
|
||||
"""
|
||||
Ensure the warnings are computed correctly when editing line values on an invoice.
|
||||
"""
|
||||
declaration = self.declaration_1000
|
||||
declaration_tax = declaration.company_id.l10n_it_edi_doi_tax_id
|
||||
|
||||
self.assertRecordValues(declaration, [{
|
||||
'invoiced': 0.0,
|
||||
'not_yet_invoiced': 0.0,
|
||||
'remaining': 1000.0,
|
||||
}])
|
||||
|
||||
invoice = self.create_invoice(declaration, [
|
||||
Command.create({
|
||||
'name': 'declaration line',
|
||||
'quantity': 2,
|
||||
'price_unit': 1000.0, # == declaration.threshold
|
||||
'tax_ids': [Command.set(declaration_tax.ids)],
|
||||
}),
|
||||
])
|
||||
|
||||
with Form(invoice) as invoice_form:
|
||||
with invoice_form.invoice_line_ids.edit(0) as line_form:
|
||||
line_form.price_unit = 2000
|
||||
line_form.save()
|
||||
self.assertEqual(
|
||||
invoice_form.l10n_it_edi_doi_warning,
|
||||
"Pay attention, the threshold of your Declaration of Intent test 2019-threshold 1000 of 1,000.00\xa0€ is exceeded by 3,000.00\xa0€, this document included.\n"
|
||||
"Invoiced: 4,000.00\xa0€; Not Yet Invoiced: 0.00\xa0€"
|
||||
)
|
||||
with invoice_form.invoice_line_ids.edit(0) as line_form:
|
||||
line_form.quantity = 1
|
||||
line_form.save()
|
||||
self.assertEqual(
|
||||
invoice_form.l10n_it_edi_doi_warning,
|
||||
"Pay attention, the threshold of your Declaration of Intent test 2019-threshold 1000 of 1,000.00\xa0€ is exceeded by 1,000.00\xa0€, this document included.\n"
|
||||
"Invoiced: 2,000.00\xa0€; Not Yet Invoiced: 0.00\xa0€"
|
||||
)
|
||||
|
||||
def test_sale_order_line_edit(self):
|
||||
"""
|
||||
Ensure the warnings are computed correctly when editing line values on a quotation or sale order.
|
||||
"""
|
||||
declaration = self.declaration_1000
|
||||
declaration_tax = declaration.company_id.l10n_it_edi_doi_tax_id
|
||||
|
||||
self.assertRecordValues(declaration, [{
|
||||
'invoiced': 0.0,
|
||||
'not_yet_invoiced': 0.0,
|
||||
'remaining': 1000.0,
|
||||
}])
|
||||
|
||||
order = self.create_sale_order(declaration, [
|
||||
Command.create({
|
||||
'name': 'declaration line',
|
||||
'product_id': self.product_1.id,
|
||||
'price_unit': 1000.0, # == declaration.threshold
|
||||
'product_uom_qty': 2,
|
||||
'tax_id': [Command.set(declaration_tax.ids)],
|
||||
}),
|
||||
])
|
||||
|
||||
with Form(order) as order_form:
|
||||
with order_form.order_line.edit(0) as line_form:
|
||||
line_form.price_unit = 2000
|
||||
line_form.save()
|
||||
self.assertEqual(
|
||||
order_form.l10n_it_edi_doi_warning,
|
||||
"Pay attention, the threshold of your Declaration of Intent test 2019-threshold 1000 of 1,000.00\xa0€ is exceeded by 3,000.00\xa0€, this document included.\n"
|
||||
"Invoiced: 0.00\xa0€; Not Yet Invoiced: 4,000.00\xa0€"
|
||||
)
|
||||
with order_form.order_line.edit(0) as line_form:
|
||||
line_form.product_uom_qty = 1
|
||||
line_form.price_unit = 2000
|
||||
line_form.save()
|
||||
self.assertEqual(
|
||||
order_form.l10n_it_edi_doi_warning,
|
||||
"Pay attention, the threshold of your Declaration of Intent test 2019-threshold 1000 of 1,000.00\xa0€ is exceeded by 1,000.00\xa0€, this document included.\n"
|
||||
"Invoiced: 0.00\xa0€; Not Yet Invoiced: 2,000.00\xa0€"
|
||||
)
|
||||
order_form.save()
|
||||
|
||||
order.action_confirm()
|
||||
# unchanged warning
|
||||
self.assertEqual(
|
||||
order.l10n_it_edi_doi_warning,
|
||||
"Pay attention, the threshold of your Declaration of Intent test 2019-threshold 1000 of 1,000.00\xa0€ is exceeded by 1,000.00\xa0€, this document included.\n"
|
||||
"Invoiced: 0.00\xa0€; Not Yet Invoiced: 2,000.00\xa0€"
|
||||
)
|
||||
with Form(order) as order_form:
|
||||
with order_form.order_line.edit(0) as line_form:
|
||||
line_form.price_unit = 3000
|
||||
line_form.save()
|
||||
self.assertEqual(
|
||||
order_form.l10n_it_edi_doi_warning,
|
||||
"Pay attention, the threshold of your Declaration of Intent test 2019-threshold 1000 of 1,000.00\xa0€ is exceeded by 2,000.00\xa0€, this document included.\n"
|
||||
"Invoiced: 0.00\xa0€; Not Yet Invoiced: 3,000.00\xa0€"
|
||||
)
|
||||
with order_form.order_line.edit(0) as line_form:
|
||||
line_form.product_uom_qty = 2
|
||||
line_form.price_unit = 3000
|
||||
line_form.save()
|
||||
self.assertEqual(
|
||||
order_form.l10n_it_edi_doi_warning,
|
||||
"Pay attention, the threshold of your Declaration of Intent test 2019-threshold 1000 of 1,000.00\xa0€ is exceeded by 5,000.00\xa0€, this document included.\n"
|
||||
"Invoiced: 0.00\xa0€; Not Yet Invoiced: 6,000.00\xa0€"
|
||||
)
|
||||
|
||||
def test_invoice(self):
|
||||
"""
|
||||
Ensure the amounts and warnings are computed correctly in the following flow:
|
||||
We create a single invoice and post it.
|
||||
"""
|
||||
declaration = self.declaration_1000
|
||||
declaration_tax = declaration.company_id.l10n_it_edi_doi_tax_id
|
||||
|
||||
self.assertRecordValues(declaration, [{
|
||||
'invoiced': 0.0,
|
||||
'not_yet_invoiced': 0.0,
|
||||
'remaining': 1000.0,
|
||||
}])
|
||||
|
||||
invoice = self.create_invoice(declaration, [
|
||||
Command.create({
|
||||
'name': 'declaration line',
|
||||
'quantity': 1,
|
||||
'price_unit': 1000.0, # == declaration.threshold
|
||||
'tax_ids': [Command.set(declaration_tax.ids)],
|
||||
}),
|
||||
Command.create({
|
||||
# The line should be ignored since it does not use the special tax
|
||||
'name': 'not a declaration line',
|
||||
'quantity': 1,
|
||||
'price_unit': 2000.0, # > declaration.threshold; not counted
|
||||
'tax_ids': [Command.set(self.company.account_sale_tax_id.ids)],
|
||||
}),
|
||||
])
|
||||
# The amounts have not changed since the invoice has not been posted yet.
|
||||
self.assertRecordValues(declaration, [{
|
||||
'invoiced': 0.0,
|
||||
'not_yet_invoiced': 0.0,
|
||||
'remaining': 1000.0,
|
||||
}])
|
||||
# There is no warning since posting the invoice would not exceed the threshold.
|
||||
# (only lines with the special tax are counted)
|
||||
self.assertEqual(invoice.l10n_it_edi_doi_warning, "")
|
||||
|
||||
# Update the declaration part of the invoice to exceed the threshold
|
||||
invoice.invoice_line_ids[0].price_unit = 2000 # > declaration.threshold
|
||||
# The amounts in the warning are the same as the amounts on the declaration after posting the invoice.
|
||||
self.assertEqual(
|
||||
invoice.l10n_it_edi_doi_warning,
|
||||
"Pay attention, the threshold of your Declaration of Intent test 2019-threshold 1000 of 1,000.00\xa0€ is exceeded by 1,000.00\xa0€, this document included.\n"
|
||||
"Invoiced: 2,000.00\xa0€; Not Yet Invoiced: 0.00\xa0€"
|
||||
)
|
||||
|
||||
invoice.action_post()
|
||||
self.assertRecordValues(declaration, [{
|
||||
'invoiced': 2000.0,
|
||||
'not_yet_invoiced': 0.0,
|
||||
'remaining': -1000.0,
|
||||
}])
|
||||
self.assertEqual(
|
||||
invoice.l10n_it_edi_doi_warning,
|
||||
"Pay attention, the threshold of your Declaration of Intent test 2019-threshold 1000 of 1,000.00\xa0€ is exceeded by 1,000.00\xa0€, this document included.\n"
|
||||
"Invoiced: 2,000.00\xa0€; Not Yet Invoiced: 0.00\xa0€"
|
||||
)
|
||||
|
||||
def test_sale_order_and_independent_invoice(self):
|
||||
"""
|
||||
Ensure the amounts and warnings are computed correctly in the following flow:
|
||||
* We create a quotation and confirm it to sales order.
|
||||
* Then we create a single invoice independent of the sales order and post it.
|
||||
I.e. the invoice should not influence the Not Yet Invoiced amount of the declaration.
|
||||
"""
|
||||
declaration = self.declaration_1000
|
||||
declaration_tax = declaration.company_id.l10n_it_edi_doi_tax_id
|
||||
|
||||
order = self.create_sale_order(declaration, [
|
||||
Command.create({
|
||||
'name': 'declaration line',
|
||||
'product_id': self.product_1.id,
|
||||
'price_unit': 1000.0, # == declaration.threshold
|
||||
'tax_id': [Command.set(declaration_tax.ids)],
|
||||
}),
|
||||
Command.create({
|
||||
'name': 'not a declaration line',
|
||||
'product_id': self.product_1.id,
|
||||
'price_unit': 2000.0, # > declaration.threshold; not counted
|
||||
'tax_id': False,
|
||||
}),
|
||||
])
|
||||
|
||||
# There is no warning since confirming the sale order would not exceed the threshold.
|
||||
# (only lines with the special tax are counted)
|
||||
self.assertEqual(order.l10n_it_edi_doi_warning, "")
|
||||
|
||||
# We only count sales orders not quotations
|
||||
self.assertRecordValues(declaration, [{
|
||||
'invoiced': 0.0,
|
||||
'not_yet_invoiced': 0.0,
|
||||
'remaining': 1000.0,
|
||||
}])
|
||||
|
||||
# Update the declaration part of `order` to exceed the threshold
|
||||
order.order_line[0].price_unit = 2000 # > declaration.threshold
|
||||
# Now we show the warning
|
||||
self.assertEqual(
|
||||
order.l10n_it_edi_doi_warning,
|
||||
"Pay attention, the threshold of your Declaration of Intent test 2019-threshold 1000 of 1,000.00\xa0€ is exceeded by 1,000.00\xa0€, this document included.\n"
|
||||
"Invoiced: 0.00\xa0€; Not Yet Invoiced: 2,000.00\xa0€"
|
||||
)
|
||||
|
||||
order.action_confirm()
|
||||
self.assertRecordValues(declaration, [{
|
||||
'invoiced': 0.0,
|
||||
'not_yet_invoiced': 2000.0,
|
||||
'remaining': -1000.0,
|
||||
}])
|
||||
|
||||
invoice = self.create_invoice(declaration, [
|
||||
Command.create({
|
||||
'name': 'declaration line',
|
||||
'quantity': 1,
|
||||
'price_unit': 1000.0,
|
||||
'tax_ids': [Command.set(declaration_tax.ids)],
|
||||
}),
|
||||
Command.create({
|
||||
# The line should be ignored since it does not use the special tax
|
||||
'name': 'none declaration line',
|
||||
'quantity': 1,
|
||||
'price_unit': 2000.0, # > declaration.threshold; not counted
|
||||
'tax_ids': [Command.set(self.company.account_sale_tax_id.ids)],
|
||||
}),
|
||||
])
|
||||
# The amounts have not changed since the invoice has not been posted yet.
|
||||
self.assertRecordValues(declaration, [{
|
||||
'invoiced': 0.0,
|
||||
'not_yet_invoiced': 2000.0,
|
||||
'remaining': -1000.0,
|
||||
}])
|
||||
|
||||
# The warning has the updated values though
|
||||
self.assertEqual(
|
||||
invoice.l10n_it_edi_doi_warning,
|
||||
"Pay attention, the threshold of your Declaration of Intent test 2019-threshold 1000 of 1,000.00\xa0€ is exceeded by 2,000.00\xa0€, this document included.\n"
|
||||
"Invoiced: 1,000.00\xa0€; Not Yet Invoiced: 2,000.00\xa0€"
|
||||
)
|
||||
|
||||
invoice.action_post()
|
||||
self.assertRecordValues(declaration, [{
|
||||
'invoiced': 1000.0,
|
||||
'not_yet_invoiced': 2000.0,
|
||||
'remaining': -2000.0,
|
||||
}])
|
||||
|
||||
@freeze_time('2019-12-31') # declaration.end_date
|
||||
def test_overinvoiced_sale_order_and_credit_note(self):
|
||||
"""
|
||||
Ensure the amounts and warnings are computed correctly in the following flow:
|
||||
* We create a quotation and confirm it to sales order.
|
||||
* Then we invoice the sales order in 2 downpayment invoices of 50% each.
|
||||
I.e. the Invoiced amount should be transferred correctly from Not Yet Invoiced to Invoiced
|
||||
* We increase the amount on one of the invoices s.t. it exceeds the sales order amount.
|
||||
I.e. the Invoiced amount increases more than the Not Yet Invoiced amount is lowered
|
||||
* We reverse the invoice exceeding the sales order amount by creating a credit note.
|
||||
I.e. check the amounts are computed correctly on the warning.
|
||||
"""
|
||||
|
||||
declaration = self.declaration_1000
|
||||
declaration_tax = declaration.company_id.l10n_it_edi_doi_tax_id
|
||||
|
||||
# Add an order that is not used in the rest of this test.
|
||||
# This way we can always show the warning and that this amount will not be removed from Not Yet Invoiced.
|
||||
independent_order = self.create_sale_order(declaration, [
|
||||
Command.create({
|
||||
'name': 'declaration line',
|
||||
'product_id': self.product_1.id,
|
||||
'price_unit': 2000.0, # > declaration.threshold
|
||||
'tax_id': [Command.set(declaration_tax.ids)],
|
||||
}),
|
||||
Command.create({
|
||||
'name': 'not a declaration line',
|
||||
'product_id': self.product_1.id,
|
||||
'price_unit': 2000.0, # > declaration.threshold; not counted
|
||||
'tax_id': [Command.set(self.company.account_sale_tax_id.ids)],
|
||||
}),
|
||||
])
|
||||
independent_order.action_confirm()
|
||||
self.assertRecordValues(declaration, [{
|
||||
'invoiced': 0.0,
|
||||
'not_yet_invoiced': 2000.0, # 2000 "base" from independent_order
|
||||
'remaining': -1000.0,
|
||||
}])
|
||||
|
||||
order = self.create_sale_order(declaration, [
|
||||
Command.create({
|
||||
'name': 'declaration line',
|
||||
'product_id': self.product_1.id,
|
||||
'price_unit': 1000.0, # == declaration.threshold
|
||||
'tax_id': [Command.set(declaration_tax.ids)],
|
||||
}),
|
||||
Command.create({
|
||||
'name': 'not a declaration line',
|
||||
'product_id': self.product_1.id,
|
||||
'price_unit': 2000.0, # > declaration.threshold; not counted
|
||||
'tax_id': [Command.set(self.company.account_sale_tax_id.ids)],
|
||||
}),
|
||||
])
|
||||
order.action_confirm()
|
||||
self.assertRecordValues(declaration, [{
|
||||
'invoiced': 0.0,
|
||||
'not_yet_invoiced': 3000.0, # 2000 "base" + 1000 from `order`
|
||||
'remaining': -2000.0,
|
||||
}])
|
||||
|
||||
downpayment_product = self.env['product.product'].create({
|
||||
'name': 'Down Payment',
|
||||
'taxes_id': [Command.set(self.company.account_sale_tax_id.copy({'price_include': True}).ids)],
|
||||
'type': 'service',
|
||||
})
|
||||
self.env['ir.config_parameter'].sudo().set_param('sale.default_deposit_product_id', downpayment_product.id)
|
||||
for i in range(2):
|
||||
self.env['sale.advance.payment.inv'].with_context({
|
||||
'active_model': 'sale.order',
|
||||
'active_ids': [order.id],
|
||||
'active_id': order.id,
|
||||
'default_journal_id': self.company_data_2['default_journal_sale'].id,
|
||||
}).create({
|
||||
'advance_payment_method': 'percentage',
|
||||
'amount': 50,
|
||||
'deposit_account_id': self.company_data_2['default_account_revenue'].id,
|
||||
}).create_invoices()
|
||||
|
||||
invoice = order.invoice_ids[0]
|
||||
|
||||
# The invoice just moves amount from `not_invoiced_yet` to `invoiced`.
|
||||
# It does not lower the remaining ammount.
|
||||
self.assertEqual(
|
||||
invoice.l10n_it_edi_doi_warning,
|
||||
"Pay attention, the threshold of your Declaration of Intent test 2019-threshold 1000 of 1,000.00\xa0€ is exceeded by 2,000.00\xa0€, this document included.\n"
|
||||
"Invoiced: 500.00\xa0€; Not Yet Invoiced: 2,500.00\xa0€"
|
||||
)
|
||||
|
||||
invoice.invoice_line_ids.filtered(lambda l: l.tax_ids.ids == declaration_tax.ids).price_unit = 2000 # 1000 more than the sales order declaration amount
|
||||
# Changing an invoice line does not affect the not yet invoiced amount of sale order lines not linked to that line
|
||||
self.assertEqual(
|
||||
invoice.l10n_it_edi_doi_warning,
|
||||
"Pay attention, the threshold of your Declaration of Intent test 2019-threshold 1000 of 1,000.00\xa0€ is exceeded by 3,500.00\xa0€, this document included.\n"
|
||||
"Invoiced: 2,000.00\xa0€; Not Yet Invoiced: 2,500.00\xa0€"
|
||||
)
|
||||
invoice.action_post()
|
||||
self.assertRecordValues(declaration, [{
|
||||
'invoiced': 2000.0, # 2000 from invoice
|
||||
'not_yet_invoiced': 2000.0, # 2000 "base"
|
||||
'remaining': -3000.0,
|
||||
}])
|
||||
|
||||
invoice2 = order.invoice_ids[1]
|
||||
invoice2.action_post()
|
||||
self.assertEqual(
|
||||
invoice2.l10n_it_edi_doi_warning,
|
||||
"Pay attention, the threshold of your Declaration of Intent test 2019-threshold 1000 of 1,000.00\xa0€ is exceeded by 3,500.00\xa0€, this document included.\n"
|
||||
"Invoiced: 2,500.00\xa0€; Not Yet Invoiced: 2,000.00\xa0€"
|
||||
)
|
||||
self.assertRecordValues(declaration, [{
|
||||
'invoiced': 2500.0, # 2000 + 500 from the 2 downpayment invoices
|
||||
'not_yet_invoiced': 2000.0, # 2000 "base"
|
||||
'remaining': -3500.0,
|
||||
}])
|
||||
|
||||
# Reverse the invoice via a credit note
|
||||
self.env['account.move.reversal'].with_company(self.company).create(
|
||||
{
|
||||
'move_ids': [Command.set((invoice.id,))],
|
||||
'date': '2019-12-31',
|
||||
'journal_id': invoice.journal_id.id,
|
||||
}
|
||||
).reverse_moves()
|
||||
|
||||
# The invoice we reversed invoiced more than the sales order amount.
|
||||
credit_note = invoice.reversal_move_id
|
||||
self.assertEqual(
|
||||
credit_note.l10n_it_edi_doi_warning,
|
||||
"Pay attention, the threshold of your Declaration of Intent test 2019-threshold 1000 of 1,000.00\xa0€ is exceeded by 2,000.00\xa0€, this document included.\n"
|
||||
"Invoiced: 500.00\xa0€; Not Yet Invoiced: 2,500.00\xa0€"
|
||||
)
|
||||
|
||||
credit_note.action_post()
|
||||
self.assertRecordValues(declaration, [{
|
||||
'invoiced': 500, # 1 downpayment of 50% on 1000 sale order
|
||||
'not_yet_invoiced': 2500, # 2000 ("base") + 500 (left on sale order)
|
||||
'remaining': -2000,
|
||||
}])
|
||||
|
||||
@freeze_time('2019-12-31') # declaration.end_date
|
||||
def test_consolidated_billing(self):
|
||||
"""
|
||||
Ensure the amounts and warnings are computed correctly in the following flow:
|
||||
1. We create multiple quotations with 1 line each with qty 2 and confirm them all to sales order.
|
||||
2. We create a single invoice for the SOs from the previous step.
|
||||
There is one line per SO.
|
||||
3. We change the amount on the one of the invoice lines without changing the qty.
|
||||
4. We increase the qty on one line.
|
||||
5. We decrease the qty on another line (not from step 4)
|
||||
I.e. we check that:
|
||||
* The not yet invoiced amount on the SO linked to the line from step (3) is still 0.
|
||||
* The lines from step (4) and (5) do not affect each other
|
||||
* Increasing the qty on line (5) to be higher than the SO amount does not lead to a negative amount on the linked SO.
|
||||
"""
|
||||
|
||||
declaration = self.declaration_1000
|
||||
declaration_tax = declaration.company_id.l10n_it_edi_doi_tax_id
|
||||
|
||||
orders = self.env['sale.order'].create([
|
||||
self.get_sale_order_vals(declaration, [
|
||||
Command.create({
|
||||
'name': 'declaration line',
|
||||
'product_id': self.product_1.id,
|
||||
'product_uom_qty': 2,
|
||||
'price_unit': 2000.0, # > declaration.threshold
|
||||
'tax_id': [Command.set(declaration_tax.ids)],
|
||||
}),
|
||||
]) for dummy in range(3)
|
||||
])
|
||||
orders.action_confirm()
|
||||
self.assertRecordValues(declaration, [{
|
||||
'invoiced': 0.0,
|
||||
'not_yet_invoiced': 12000.0,
|
||||
'remaining': -11000.0,
|
||||
}])
|
||||
|
||||
invoice = orders._create_invoices()
|
||||
self.assertRecordValues(declaration, [{
|
||||
'invoiced': 0.0,
|
||||
'not_yet_invoiced': 12000.0,
|
||||
'remaining': -11000.0,
|
||||
}])
|
||||
self.assertEqual(
|
||||
invoice.l10n_it_edi_doi_warning,
|
||||
"Pay attention, the threshold of your Declaration of Intent test 2019-threshold 1000 of 1,000.00\xa0€ is exceeded by 11,000.00\xa0€, this document included.\n"
|
||||
"Invoiced: 12,000.00\xa0€; Not Yet Invoiced: 0.00\xa0€"
|
||||
)
|
||||
|
||||
invoice.invoice_line_ids[0].price_unit = 1000
|
||||
# in the warning:
|
||||
# * invoiced amount decreases by 2000 (since we reduced the price_unit by 1000)
|
||||
# * not yet invoiced amount stays the same (all quantities still invoiced)
|
||||
self.assertEqual(
|
||||
invoice.l10n_it_edi_doi_warning,
|
||||
"Pay attention, the threshold of your Declaration of Intent test 2019-threshold 1000 of 1,000.00\xa0€ is exceeded by 9,000.00\xa0€, this document included.\n"
|
||||
"Invoiced: 10,000.00\xa0€; Not Yet Invoiced: 0.00\xa0€"
|
||||
)
|
||||
self.assertRecordValues(declaration, [{
|
||||
'invoiced': 0.0,
|
||||
'not_yet_invoiced': 12000.0,
|
||||
'remaining': -11000.0,
|
||||
}])
|
||||
|
||||
invoice.invoice_line_ids[1].quantity = 1
|
||||
# in the warning: 1 qty (2000 €) moves from invoiced to net yet invoiced
|
||||
self.assertEqual(
|
||||
invoice.l10n_it_edi_doi_warning,
|
||||
"Pay attention, the threshold of your Declaration of Intent test 2019-threshold 1000 of 1,000.00\xa0€ is exceeded by 9,000.00\xa0€, this document included.\n"
|
||||
"Invoiced: 8,000.00\xa0€; Not Yet Invoiced: 2,000.00\xa0€"
|
||||
)
|
||||
self.assertRecordValues(declaration, [{
|
||||
'invoiced': 0.0,
|
||||
'not_yet_invoiced': 12000.0,
|
||||
'remaining': -11000.0,
|
||||
}])
|
||||
|
||||
invoice.invoice_line_ids[2].quantity = 3
|
||||
# in the warning:
|
||||
# * invoiced amount increases by 2000 (since we increase the quantity by 1)
|
||||
# * not yet invoiced amount stays the same (all quantities still invoiced)
|
||||
self.assertEqual(
|
||||
invoice.l10n_it_edi_doi_warning,
|
||||
"Pay attention, the threshold of your Declaration of Intent test 2019-threshold 1000 of 1,000.00\xa0€ is exceeded by 11,000.00\xa0€, this document included.\n"
|
||||
"Invoiced: 10,000.00\xa0€; Not Yet Invoiced: 2,000.00\xa0€"
|
||||
)
|
||||
self.assertRecordValues(declaration, [{
|
||||
'invoiced': 0.0,
|
||||
'not_yet_invoiced': 12000.0,
|
||||
'remaining': -11000.0,
|
||||
}])
|
||||
|
||||
invoice.action_post()
|
||||
# Same values as in the last warning
|
||||
self.assertRecordValues(declaration, [{
|
||||
'invoiced': 10000.0,
|
||||
'not_yet_invoiced': 2000.0,
|
||||
'remaining': -11000.0,
|
||||
}])
|
||||
|
|
@ -0,0 +1,79 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
|
||||
<record id="view_account_invoice_filter" model="ir.ui.view">
|
||||
<field name="name">account.invoice.select</field>
|
||||
<field name="model">account.move</field>
|
||||
<field name="inherit_id" ref="account.view_account_invoice_filter"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//search/field[@name='journal_id']" position="after">
|
||||
<field name="l10n_it_edi_doi_id"/>
|
||||
</xpath>
|
||||
<xpath expr="//filter[@name='to_check']" position="after">
|
||||
<filter string="Exceeded Declaration of Intent"
|
||||
name="l10n_it_edi_doi_declaration_of_intent_exceeded"
|
||||
domain="[('l10n_it_edi_doi_id.remaining','<', 0)]"/>
|
||||
</xpath>
|
||||
<xpath expr="//group" position="inside">
|
||||
<filter string="Declaration of Intent"
|
||||
name="l10n_it_edi_doi_declaration_of_intent"
|
||||
context="{'group_by':'l10n_it_edi_doi_id'}"/>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="view_move_tree" model="ir.ui.view">
|
||||
<field name="name">account.move.tree</field>
|
||||
<field name="model">account.move</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Invoices" sample="1" decoration-info="state == 'draft'">
|
||||
<field name="made_sequence_hole" attrs="{'column_invisible': True}"/>
|
||||
<field name="name" decoration-bf="1" decoration-danger="made_sequence_hole"/>
|
||||
<field name="invoice_partner_display_name" string="Customer"/>
|
||||
<field name="invoice_date" string="Invoice Date"/>
|
||||
<field name="date" string="Accounting Date" optional="hidden"/>
|
||||
<field name="currency_id" attrs="{'column_invisible': True}"/>
|
||||
<field name="state" widget="badge" decoration-info="state == 'draft'" decoration-success="state == 'posted'"/>
|
||||
<field name="l10n_it_edi_doi_amount" decoration-bf="1" sum="Total" string="Tax excluded"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="view_move_form" model="ir.ui.view">
|
||||
<field name="name">account.move.form</field>
|
||||
<field name="model">account.move</field>
|
||||
<field name="inherit_id" ref="account.view_move_form"/>
|
||||
<field name="arch" type="xml">
|
||||
<div name="button_box" position="inside">
|
||||
<button groups="account.group_account_invoice"
|
||||
type="object"
|
||||
class="oe_stat_button"
|
||||
name="action_open_declaration_of_intent"
|
||||
icon="fa-list"
|
||||
attrs="{'invisible': [('l10n_it_edi_doi_id', '=', False)]}">
|
||||
<div class="o_field_widget o_stat_info">
|
||||
<span class="o_stat_text">Declaration of Intent</span>
|
||||
</div>
|
||||
</button>
|
||||
</div>
|
||||
<xpath expr="//header" position="after">
|
||||
<div class="alert alert-warning mb-0" role="alert"
|
||||
attrs="{'invisible': [('l10n_it_edi_doi_warning', '=', '')]}">
|
||||
<field name="l10n_it_edi_doi_warning"/>
|
||||
</div>
|
||||
</xpath>
|
||||
<xpath expr="//field[@name='fiscal_position_id']" position="before">
|
||||
<field name="l10n_it_edi_doi_use" invisible="True"/>
|
||||
<field name="l10n_it_edi_doi_id"
|
||||
attrs="{'invisible': [('l10n_it_edi_doi_use', '=', False)], 'readonly': [('state', '!=', 'draft')]}"
|
||||
options='{"no_quick_create": True}'
|
||||
domain="[
|
||||
('state', '!=', 'draft'),
|
||||
('company_id', '=', company_id),
|
||||
('currency_id', '=', currency_id),
|
||||
('partner_id', '=', commercial_partner_id)]"/>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
</odoo>
|
||||
|
|
@ -0,0 +1,135 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<odoo>
|
||||
|
||||
<record id="view_l10n_it_edi_doi_tree" model="ir.ui.view">
|
||||
<field name="name">l10n_it_edi_doi.declaration_of_intent.tree</field>
|
||||
<field name="model">l10n_it_edi_doi.declaration_of_intent</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree decoration-info="state == 'draft'"
|
||||
decoration-muted="state == 'terminated'"
|
||||
decoration-danger="state == 'revoked'">
|
||||
<control>
|
||||
<create name="add_line_control" string="Add a Declaration of Intent"/>
|
||||
</control>
|
||||
<field name="currency_id" attrs="{'column_invisible': True}"/>
|
||||
<field name="partner_id" attrs="{'readonly': [('state', '!=', 'draft')]}"/>
|
||||
<field name="company_id" groups="base.group_multi_company" optional="hidden"/>
|
||||
<field name="protocol_number_part1" attrs="{'readonly': [('state', '!=', 'draft')]}"/>
|
||||
<field name="protocol_number_part2" attrs="{'readonly': [('state', '!=', 'draft')]}"/>
|
||||
<field name="issue_date" attrs="{'readonly': [('state', '!=', 'draft')]}"/>
|
||||
<field name="start_date" attrs="{'readonly': [('state', '!=', 'draft')]}"/>
|
||||
<field name="end_date" attrs="{'readonly': [('state', '!=', 'draft')]}"/>
|
||||
<field name="threshold" attrs="{'readonly': [('state', '!=', 'draft')]}"/>
|
||||
<field name="not_yet_invoiced" optional="hidden"/>
|
||||
<field name="invoiced" optional="hidden"/>
|
||||
<field name="remaining"/>
|
||||
<field name="state"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="view_l10n_it_edi_doi_form" model="ir.ui.view">
|
||||
<field name="name">l10n_it_edi_doi.declaration_of_intent.form</field>
|
||||
<field name="model">l10n_it_edi_doi.declaration_of_intent</field>
|
||||
<field name="arch" type="xml">
|
||||
<form>
|
||||
<header>
|
||||
<field name="state" widget="statusbar" statusbar_visible="draft,active"/>
|
||||
<button string="Validate" attrs="{'invisible': [('state', '!=', 'draft')]}" class="btn-primary"
|
||||
type="object" name="action_validate"/>
|
||||
<button string="Terminate" attrs="{'invisible': [('state', '!=', 'active')]}" class="btn-primary"
|
||||
type="object" name="action_terminate"/>
|
||||
<button string="Reset to Draft" attrs="{'invisible': [('state', '!=', 'active')]}" class="btn-secondary"
|
||||
type="object" name="action_reset_to_draft"/>
|
||||
<button string="Reactivate" attrs="{'invisible': [('state', 'not in', ('terminated', 'revoked'))]}" class="btn-secondary"
|
||||
type="object" name="action_reactivate"/>
|
||||
<button string="Revoke" attrs="{'invisible': [('state', '!=', 'active')]}" class="btn-secondary"
|
||||
type="object" name="action_revoke"/>
|
||||
</header>
|
||||
<sheet>
|
||||
<div class="oe_button_box" name="button_box">
|
||||
<field name="invoice_ids" invisible="True"/>
|
||||
<field name="sale_order_ids" invisible="True"/>
|
||||
<button type="object"
|
||||
class="oe_stat_button"
|
||||
name="action_open_invoice_ids"
|
||||
icon="fa-pencil-square-o"
|
||||
attrs="{'invisible': [('invoice_ids', '=', False)]}">
|
||||
<div class="o_field_widget o_stat_info">
|
||||
<span class="o_stat_text">Invoices</span>
|
||||
</div>
|
||||
</button>
|
||||
<button type="object"
|
||||
class="oe_stat_button"
|
||||
name="action_open_sale_order_ids"
|
||||
icon="fa-pencil-square-o"
|
||||
attrs="{'invisible': [('sale_order_ids', '=', False)]}">
|
||||
<div class="o_field_widget o_stat_info">
|
||||
<span class="o_stat_text">Sale Orders</span>
|
||||
</div>
|
||||
</button>
|
||||
</div>
|
||||
<group name="main_group">
|
||||
<group name="left_column">
|
||||
<field name="partner_id" attrs="{'readonly': [('state', '!=', 'draft')]}"/>
|
||||
<field name="company_id" groups="base.group_multi_company" attrs="{'readonly': [('state', '!=', 'draft')]}"/>
|
||||
<label for="protocol_number_part1" string="Protocol Number"/>
|
||||
<div name="protocol_div" class="d-flex">
|
||||
<field name="protocol_number_part1" attrs="{'readonly': [('state', '!=', 'draft')]}"/>
|
||||
<span class="o_form_label mx-3">/</span>
|
||||
<field name="protocol_number_part2" attrs="{'readonly': [('state', '!=', 'draft')]}"/>
|
||||
</div>
|
||||
<field name="issue_date" attrs="{'readonly': [('state', '!=', 'draft')]}"/>
|
||||
<label string="Date Range" for="start_date"/>
|
||||
<div name="date_range_div" class="d-flex">
|
||||
<field name="start_date" attrs="{'readonly': [('state', '!=', 'draft')]}"/>
|
||||
<span class="o_form_label mx-3"> to </span>
|
||||
<field name="end_date" attrs="{'readonly': [('state', '!=', 'draft')]}"/>
|
||||
</div>
|
||||
</group>
|
||||
<group name="right_column">
|
||||
<div colspan="2" class="o_wrap_label">
|
||||
<span class="o_form_label">Amounts:</span>
|
||||
</div>
|
||||
<field name="currency_id" invisible="True"/>
|
||||
<field name="threshold" widget="monetary" attrs="{'readonly': [('state', '!=', 'draft')]}"/>
|
||||
<field name="not_yet_invoiced" widget="monetary"/>
|
||||
<field name="invoiced" widget="monetary"/>
|
||||
<field name="remaining" widget="monetary"/>
|
||||
</group>
|
||||
</group>
|
||||
</sheet>
|
||||
<div class="oe_chatter">
|
||||
<field name="message_follower_ids" groups="base.group_user"/>
|
||||
<field name="message_ids"/>
|
||||
<field name="activity_ids"/>
|
||||
</div>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="view_l10n_it_edi_doi_declaration_of_intent_search" model="ir.ui.view">
|
||||
<field name="name">l10n_it_edi_doi.declaration_of_intent.search</field>
|
||||
<field name="model">l10n_it_edi_doi.declaration_of_intent</field>
|
||||
<field name="type">search</field>
|
||||
<field name="arch" type="xml">
|
||||
<search>
|
||||
<field name="protocol_number_part1"/>
|
||||
<field name="protocol_number_part2"/>
|
||||
<filter name="l10n_it_edi_doi_declaration_of_intent_active_filter"
|
||||
string="Active"
|
||||
domain="[('state','=', 'active')]"
|
||||
help="Show active declarations of intent"/>
|
||||
<filter name="l10n_it_edi_doi_declaration_of_intent_draft_filter"
|
||||
string="Draft"
|
||||
domain="[('state','=', 'draft')]"
|
||||
help="Show draft declarations of intent"/>
|
||||
<filter name="l10n_it_edi_doi_declaration_of_intent_terminated_filter"
|
||||
string="Terminated / Revoked"
|
||||
domain="[('state','in', ['terminated', 'revoked'])]"
|
||||
help="Show terminated or revoked Declarations of Intent"/>
|
||||
</search>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
</odoo>
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<template id="report_invoice_document" inherit_id="account.report_invoice_document">
|
||||
<div name="comment" position="before">
|
||||
<div t-if="o.l10n_it_edi_doi_id">
|
||||
<span>Your Declaration of Intent number <span t-field="o.l10n_it_edi_doi_id"/> from <span t-field="o.l10n_it_edi_doi_id.issue_date"/>.</span>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</odoo>
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<odoo>
|
||||
|
||||
<record id="res_partner_view_search" model="ir.ui.view">
|
||||
<field name="name">res.partner.search.inherit</field>
|
||||
<field name="model">res.partner</field>
|
||||
<field name="inherit_id" ref="account.res_partner_view_search"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//filter[@name='supplier']" position="after">
|
||||
<filter string="Exceeded Declaration of Intent"
|
||||
name="l10n_it_edi_doi_declaration_of_intent_exceeded"
|
||||
domain="[('l10n_it_edi_doi_ids','any', [('remaining', '<', 0)])]"/>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="view_partner_l10n_form" model="ir.ui.view">
|
||||
<field name="name">view_partner_l10n_form</field>
|
||||
<field name="inherit_id" ref="base_vat.view_partner_base_vat_form"/>
|
||||
<field name="model">res.partner</field>
|
||||
<field name="priority">100</field>
|
||||
<field name="arch" type="xml">
|
||||
<div name="button_box" position="inside">
|
||||
<button groups="account.group_account_invoice"
|
||||
type="object"
|
||||
class="oe_stat_button"
|
||||
name="l10n_it_edi_doi_action_open_declarations"
|
||||
icon="fa-list"
|
||||
attrs="{'invisible': [('country_code', '!=', 'IT')]}">
|
||||
<div class="o_field_widget o_stat_info">
|
||||
<span class="o_stat_text">Declarations of Intent</span>
|
||||
</div>
|
||||
</button>
|
||||
</div>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
</odoo>
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<template id="report_saleorder_document" inherit_id="sale.report_saleorder_document">
|
||||
<p id="fiscal_position_remark" position="after">
|
||||
<div t-if="doc.l10n_it_edi_doi_id">
|
||||
<span>Your Declaration of Intent number <span t-field="doc.l10n_it_edi_doi_id"/> from <span t-field="doc.l10n_it_edi_doi_id.issue_date"/>.</span>
|
||||
</div>
|
||||
</p>
|
||||
</template>
|
||||
</odoo>
|
||||
|
|
@ -0,0 +1,81 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<record id="view_sales_order_filter" model="ir.ui.view">
|
||||
<field name="name">sale.order.list.select</field>
|
||||
<field name="model">sale.order</field>
|
||||
<field name="inherit_id" ref="sale.view_sales_order_filter"/>
|
||||
<field name="arch" type="xml">
|
||||
<filter name="my_sale_orders_filter" position="after">
|
||||
<filter string="Exceeded Declaration of Intent"
|
||||
name="l10n_it_edi_doi_declaration_of_intent_exceeded"
|
||||
domain="[('l10n_it_edi_doi_id.remaining','<', 0)]"/>
|
||||
</filter>
|
||||
<xpath expr="//search/group" position="inside">
|
||||
<filter string="Declaration of Intent"
|
||||
name="l10n_it_edi_doi_declaration_of_intent"
|
||||
domain="" context="{'group_by':'l10n_it_edi_doi_id'}"/>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="view_quotation_tree" model="ir.ui.view">
|
||||
<field name="name">sale.order.tree</field>
|
||||
<field name="model">sale.order</field>
|
||||
<field name="priority">1000</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree class="o_sale_order"
|
||||
string="Sales Orders"
|
||||
sample="1"
|
||||
decoration-muted="state == 'cancel'">
|
||||
<field name="name" string="Number"/>
|
||||
<field name="date_order" widget="date"/>
|
||||
<field name="partner_id"/>
|
||||
<field name="currency_id" attrs="{'column_invisible': True}"/>
|
||||
<field name="state"
|
||||
decoration-success="state == 'sale'"
|
||||
decoration-info="state == 'draft'"
|
||||
decoration-primary="state == 'sent'"
|
||||
widget="badge"/>
|
||||
<field name="l10n_it_edi_doi_not_yet_invoiced" decoration-bf="1" sum="Total" string="Not Yet Invoiced Amount"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="view_order_form" model="ir.ui.view">
|
||||
<field name="name">sale.order.form</field>
|
||||
<field name="model">sale.order</field>
|
||||
<field name="inherit_id" ref="sale.view_order_form"/>
|
||||
<field name="arch" type="xml">
|
||||
<div name="button_box" position="inside">
|
||||
<button groups="account.group_account_invoice"
|
||||
type="object"
|
||||
class="oe_stat_button"
|
||||
name="action_open_declaration_of_intent"
|
||||
icon="fa-list"
|
||||
attrs="{'invisible': [('l10n_it_edi_doi_id', '=', False)]}">
|
||||
<div class="o_field_widget o_stat_info">
|
||||
<span class="o_stat_text">Declaration of Intent</span>
|
||||
</div>
|
||||
</button>
|
||||
</div>
|
||||
<xpath expr="//header" position="after">
|
||||
<div class="alert alert-warning mb-0" role="alert"
|
||||
attrs="{'invisible': [('l10n_it_edi_doi_warning', '=', '')]}">
|
||||
<field name="l10n_it_edi_doi_warning"/>
|
||||
</div>
|
||||
</xpath>
|
||||
<xpath expr="//label[@for='fiscal_position_id']" position="before">
|
||||
<field name="l10n_it_edi_doi_use" invisible="True"/>
|
||||
<field name="l10n_it_edi_doi_id"
|
||||
attrs="{'invisible': [('l10n_it_edi_doi_use', '=', False)]}"
|
||||
options='{"no_quick_create": True}'
|
||||
domain="[
|
||||
('state', '!=', 'draft'),
|
||||
('company_id', '=', company_id),
|
||||
('currency_id', '=', currency_id),
|
||||
('partner_id', 'parent_of', partner_id)]"/>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
</odoo>
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from . import sale_make_invoice_advance
|
||||
|
|
@ -0,0 +1,93 @@
|
|||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from odoo import models
|
||||
from odoo.fields import Command
|
||||
|
||||
|
||||
class SaleAdvancePaymentInv(models.TransientModel):
|
||||
_inherit = 'sale.advance.payment.inv'
|
||||
|
||||
def _create_invoices(self, sale_orders):
|
||||
"""Extend to create a dedicated down payment line for the declaration of intent amount."""
|
||||
invoice = super()._create_invoices(sale_orders)
|
||||
|
||||
if self.advance_payment_method == 'delivered':
|
||||
return invoice
|
||||
|
||||
order = self.sale_order_ids # super calls ensure_one
|
||||
doi_tax = order.l10n_it_edi_doi_id.company_id.l10n_it_edi_doi_tax_id
|
||||
if not doi_tax:
|
||||
# Includes the case where there is no order.l10n_it_edi_doi_id
|
||||
return invoice
|
||||
|
||||
doi_total = 0
|
||||
for line in order.order_line:
|
||||
if line.tax_id.ids != doi_tax.ids:
|
||||
continue
|
||||
price_reduce = line.price_unit * (1 - (line.discount or 0.0) / 100.0)
|
||||
doi_total += price_reduce * line.product_uom_qty
|
||||
|
||||
# The tax on the down payment product was possibly mapped by the doi fiscal position
|
||||
# Here we do a custom mapping that does not map taxes that will be mapped to the special doi tax
|
||||
doi_fiscal_position = order.l10n_it_edi_doi_id.company_id.l10n_it_edi_doi_fiscal_position_id
|
||||
advance_product_taxes = self.product_id.taxes_id.filtered(lambda tax: tax.company_id == order.company_id)
|
||||
if advance_product_taxes and doi_fiscal_position and order.fiscal_position_id == doi_fiscal_position:
|
||||
custom_mapped_taxes = self.env['account.tax']
|
||||
for tax in advance_product_taxes:
|
||||
mapped_tax = doi_fiscal_position.map_tax(tax)
|
||||
custom_mapped_taxes |= tax if mapped_tax == doi_tax else mapped_tax
|
||||
advance_product_taxes = custom_mapped_taxes
|
||||
|
||||
for invoice_line in invoice.invoice_line_ids:
|
||||
if not invoice_line.is_downpayment:
|
||||
continue
|
||||
downpayment_line = invoice_line.sale_line_ids.filtered(lambda line: line.is_downpayment)
|
||||
if len(downpayment_line) != 1:
|
||||
continue
|
||||
|
||||
if advance_product_taxes:
|
||||
downpayment_line.tax_id = advance_product_taxes
|
||||
invoice_line.tax_ids = advance_product_taxes
|
||||
|
||||
if order.currency_id.is_zero(doi_total):
|
||||
# The order has no lines contributing to the declaration of intent
|
||||
continue
|
||||
|
||||
# Split the down payment amount into 2: doi amount and other amount
|
||||
down_total = downpayment_line.price_unit
|
||||
if all(advance_product_taxes.mapped('price_include')):
|
||||
amount_total = order.amount_total
|
||||
else:
|
||||
amount_total = order.amount_untaxed
|
||||
doi_down = order.currency_id.round(doi_total / amount_total * down_total)
|
||||
other_down = down_total - doi_down
|
||||
|
||||
if order.currency_id.is_zero(amount_total - doi_total):
|
||||
# The whole order amount is under doi_tax
|
||||
# We just have to add the tax information on the lines
|
||||
downpayment_line.tax_id = doi_tax
|
||||
invoice_line.tax_ids = doi_tax
|
||||
continue
|
||||
|
||||
# The order amount is partially not under doi_tax
|
||||
# Split the down payment line into 2: one for the doi amount and one for the other amount
|
||||
downpayment_line.price_unit = other_down
|
||||
doi_so_line_values = {
|
||||
**self._prepare_so_line_values(order),
|
||||
'price_unit': doi_down,
|
||||
'tax_id': [Command.set(doi_tax.ids)],
|
||||
}
|
||||
doi_down_payment_so_line = self.env['sale.order.line'].create(doi_so_line_values)
|
||||
|
||||
# Split the invoice line into 2: one for the doi amount and one for the other amount
|
||||
invoice.invoice_line_ids = [
|
||||
Command.create(doi_down_payment_so_line._prepare_invoice_line(
|
||||
name=self._get_down_payment_description(order),
|
||||
quantity=1.0,
|
||||
)),
|
||||
Command.update(invoice_line.id, {
|
||||
'price_unit': other_down,
|
||||
}),
|
||||
]
|
||||
|
||||
return invoice
|
||||
43
odoo-bringout-oca-ocb-l10n_it_edi_doi/pyproject.toml
Normal file
43
odoo-bringout-oca-ocb-l10n_it_edi_doi/pyproject.toml
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
[project]
|
||||
name = "odoo-bringout-oca-ocb-l10n_it_edi_doi"
|
||||
version = "16.0.0"
|
||||
description = "Italy - Declaration of Intent - Odoo addon"
|
||||
authors = [
|
||||
{ name = "Ernad Husremovic", email = "hernad@bring.out.ba" }
|
||||
]
|
||||
dependencies = [
|
||||
"odoo-bringout-oca-ocb-l10n_it_edi>=16.0.0",
|
||||
"odoo-bringout-oca-ocb-sale>=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 = ["l10n_it_edi_doi"]
|
||||
|
||||
[tool.rye]
|
||||
managed = true
|
||||
dev-dependencies = [
|
||||
"pytest>=8.4.1",
|
||||
]
|
||||
Loading…
Add table
Add a link
Reference in a new issue