mirror of
https://gitlab.com/flectra-hq/flectra.git
synced 2025-02-25 18:55:21 -06:00
[PATCH] Upstream patch - 14072023
This commit is contained in:
@@ -73,8 +73,7 @@ def update_taxes_from_templates(cr, chart_template_xmlid):
|
||||
_avoid_name_conflict(company, template)
|
||||
templates_to_create += template
|
||||
new_template2tax_company = templates_to_create._generate_tax(company, accounts_exist=True)['tax_template_to_tax']
|
||||
return [(env['account.tax.template'].browse(template_id), env['account.tax'].browse(tax_id))
|
||||
for template_id, tax_id in new_template2tax_company.items()]
|
||||
return new_template2tax_company.items()
|
||||
|
||||
def _update_taxes_from_template(template2tax_mapping):
|
||||
""" Update the taxes' tags (and only tags!) based on their corresponding template values.
|
||||
|
||||
@@ -32,6 +32,8 @@ class Partner(models.Model):
|
||||
@api.model
|
||||
def _fields_view_get_address(self, arch):
|
||||
arch = super(Partner, self)._fields_view_get_address(arch)
|
||||
if self.env.context.get('no_address_format'):
|
||||
return arch
|
||||
# render the partner address accordingly to address_view_id
|
||||
doc = etree.fromstring(arch)
|
||||
if doc.xpath("//field[@name='city_id']"):
|
||||
|
||||
@@ -179,7 +179,7 @@ class Contract(models.Model):
|
||||
for contract in contract_ids:
|
||||
next_contract = self.search([
|
||||
('employee_id', '=', contract.employee_id.id),
|
||||
('state', 'not in', ['cancel', 'new']),
|
||||
('state', 'not in', ['cancel', 'draft']),
|
||||
('date_start', '>', contract.date_start)
|
||||
], order="date_start asc", limit=1)
|
||||
if next_contract:
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
# Part of Odoo, Flectra. See LICENSE file for full copyright and licensing details.
|
||||
import re
|
||||
from lxml import etree
|
||||
|
||||
from flectra.tools.float_utils import float_compare
|
||||
from flectra import models, fields, api, _
|
||||
from flectra.exceptions import UserError, ValidationError, RedirectWarning
|
||||
|
||||
@@ -143,7 +143,7 @@ class Task(models.Model):
|
||||
if (task.planned_hours > 0.0):
|
||||
task_total_hours = task.effective_hours + task.subtask_effective_hours
|
||||
task.overtime = max(task_total_hours - task.planned_hours, 0)
|
||||
if task_total_hours > task.planned_hours:
|
||||
if float_compare(task_total_hours, task.planned_hours, precision_digits=2) >= 0:
|
||||
task.progress = 100
|
||||
else:
|
||||
task.progress = round(100.0 * task_total_hours / task.planned_hours, 2)
|
||||
|
||||
@@ -256,6 +256,15 @@
|
||||
<field name="sequence">15</field>
|
||||
</record>
|
||||
|
||||
<record id="tax_report_F9" model="account.tax.report.line">
|
||||
<field name="name">F9 - Opérations internes réalisées entre membres d'un assujetti unique</field>
|
||||
<field name="tag_name">F9</field>
|
||||
<field name="code">box_F9</field>
|
||||
<field name="parent_id" ref="tax_report_op_non_imposables"/>
|
||||
<field name="report_id" ref="tax_report"/>
|
||||
<field name="sequence">16</field>
|
||||
</record>
|
||||
|
||||
<!-- DÉCOMPTE DE LA TVA À PAYER -->
|
||||
<record id="tax_report_decompte_tva" model="account.tax.report.line">
|
||||
<field name="name">B. Décompte de la TVA à payer</field>
|
||||
@@ -385,13 +394,126 @@
|
||||
<field name="formula">None</field>
|
||||
</record>
|
||||
|
||||
<record id="tax_report_T1_base" model="account.tax.report.line">
|
||||
<field name="name">T1 - Opérations réalisées dans les DOM et imposables au taux de 1,75% (base)</field>
|
||||
<field name="tag_name">T1_base</field>
|
||||
<field name="code">box_T1_base</field>
|
||||
<field name="parent_id" ref="tax_report_tva_brute_autre"/>
|
||||
<field name="report_id" ref="tax_report"/>
|
||||
<field name="sequence">1</field>
|
||||
</record>
|
||||
<record id="tax_report_T1_taxe" model="account.tax.report.line">
|
||||
<field name="name">T1 - Opérations réalisées dans les DOM et imposables au taux de 1,75% (taxe)</field>
|
||||
<field name="tag_name">T1_taxe</field>
|
||||
<field name="code">box_T1_taxe</field>
|
||||
<field name="parent_id" ref="tax_report_tva_brute_autre"/>
|
||||
<field name="report_id" ref="tax_report"/>
|
||||
<field name="sequence">2</field>
|
||||
</record>
|
||||
<record id="tax_report_T2_base" model="account.tax.report.line">
|
||||
<field name="name">T2 - Opérations réalisées dans les DOM et imposables au taux de 1,05% (base)</field>
|
||||
<field name="tag_name">T2_base</field>
|
||||
<field name="code">box_T2_base</field>
|
||||
<field name="parent_id" ref="tax_report_tva_brute_autre"/>
|
||||
<field name="report_id" ref="tax_report"/>
|
||||
<field name="sequence">3</field>
|
||||
</record>
|
||||
<record id="tax_report_T2_taxe" model="account.tax.report.line">
|
||||
<field name="name">T2 - Opérations réalisées dans les DOM et imposables au taux de 1,05% (taxe)</field>
|
||||
<field name="tag_name">T2_taxe</field>
|
||||
<field name="code">box_T2_taxe</field>
|
||||
<field name="parent_id" ref="tax_report_tva_brute_autre"/>
|
||||
<field name="report_id" ref="tax_report"/>
|
||||
<field name="sequence">4</field>
|
||||
</record>
|
||||
<record id="tax_report_T3_base" model="account.tax.report.line">
|
||||
<field name="name">T3 - Opérations réalisées en Corse et imposables au taux de 10% (base)</field>
|
||||
<field name="tag_name">T3_base</field>
|
||||
<field name="code">box_T3_base</field>
|
||||
<field name="parent_id" ref="tax_report_tva_brute_autre"/>
|
||||
<field name="report_id" ref="tax_report"/>
|
||||
<field name="sequence">5</field>
|
||||
</record>
|
||||
<record id="tax_report_T3_taxe" model="account.tax.report.line">
|
||||
<field name="name">T3 - Opérations réalisées en Corse et imposables au taux de 10% (taxe)</field>
|
||||
<field name="tag_name">T3_taxe</field>
|
||||
<field name="code">box_T3_taxe</field>
|
||||
<field name="parent_id" ref="tax_report_tva_brute_autre"/>
|
||||
<field name="report_id" ref="tax_report"/>
|
||||
<field name="sequence">6</field>
|
||||
</record>
|
||||
<record id="tax_report_T4_base" model="account.tax.report.line">
|
||||
<field name="name">T4 - Opérations réalisées en Corse et imposables au taux de 2,1% (base)</field>
|
||||
<field name="tag_name">T4_base</field>
|
||||
<field name="code">box_T4_base</field>
|
||||
<field name="parent_id" ref="tax_report_tva_brute_autre"/>
|
||||
<field name="report_id" ref="tax_report"/>
|
||||
<field name="sequence">7</field>
|
||||
</record>
|
||||
<record id="tax_report_T4_taxe" model="account.tax.report.line">
|
||||
<field name="name">T4 - Opérations réalisées en Corse et imposables au taux de 2,1% (taxe)</field>
|
||||
<field name="tag_name">T4_taxe</field>
|
||||
<field name="code">box_T4_taxe</field>
|
||||
<field name="parent_id" ref="tax_report_tva_brute_autre"/>
|
||||
<field name="report_id" ref="tax_report"/>
|
||||
<field name="sequence">8</field>
|
||||
</record>
|
||||
<record id="tax_report_T5_base" model="account.tax.report.line">
|
||||
<field name="name">T5 - Opérations réalisées en Corse et imposables au taux de 0,9% (base)</field>
|
||||
<field name="tag_name">T5_base</field>
|
||||
<field name="code">box_T5_base</field>
|
||||
<field name="parent_id" ref="tax_report_tva_brute_autre"/>
|
||||
<field name="report_id" ref="tax_report"/>
|
||||
<field name="sequence">9</field>
|
||||
</record>
|
||||
<record id="tax_report_T5_taxe" model="account.tax.report.line">
|
||||
<field name="name">T5 - Opérations réalisées en Corse et imposables au taux de 0,9% (taxe)</field>
|
||||
<field name="tag_name">T5_taxe</field>
|
||||
<field name="code">box_T5_taxe</field>
|
||||
<field name="parent_id" ref="tax_report_tva_brute_autre"/>
|
||||
<field name="report_id" ref="tax_report"/>
|
||||
<field name="sequence">10</field>
|
||||
</record>
|
||||
<record id="tax_report_T6_base" model="account.tax.report.line">
|
||||
<field name="name">T6 - Opérations réalisées en France continentale au taux de 2,1% (base)</field>
|
||||
<field name="tag_name">T6_base</field>
|
||||
<field name="code">box_T6_base</field>
|
||||
<field name="parent_id" ref="tax_report_tva_brute_autre"/>
|
||||
<field name="report_id" ref="tax_report"/>
|
||||
<field name="sequence">11</field>
|
||||
</record>
|
||||
<record id="tax_report_T6_taxe" model="account.tax.report.line">
|
||||
<field name="name">T6 - Opérations réalisées en France continentale au taux de 2,1% (taxe)</field>
|
||||
<field name="tag_name">T6_taxe</field>
|
||||
<field name="code">box_T6_taxe</field>
|
||||
<field name="parent_id" ref="tax_report_tva_brute_autre"/>
|
||||
<field name="report_id" ref="tax_report"/>
|
||||
<field name="sequence">12</field>
|
||||
</record>
|
||||
<record id="tax_report_T7_base" model="account.tax.report.line">
|
||||
<field name="name">T7 - Retenue de TVA sur droits d'auteur (base)</field>
|
||||
<field name="tag_name">T7_base</field>
|
||||
<field name="code">box_T7_base</field>
|
||||
<field name="parent_id" ref="tax_report_tva_brute_autre"/>
|
||||
<field name="report_id" ref="tax_report"/>
|
||||
<field name="sequence">13</field>
|
||||
</record>
|
||||
<record id="tax_report_T7_taxe" model="account.tax.report.line">
|
||||
<field name="name">T7 - Retenue de TVA sur droits d'auteur (taxe)</field>
|
||||
<field name="tag_name">T7_taxe</field>
|
||||
<field name="code">box_T7_taxe</field>
|
||||
<field name="parent_id" ref="tax_report_tva_brute_autre"/>
|
||||
<field name="report_id" ref="tax_report"/>
|
||||
<field name="sequence">14</field>
|
||||
</record>
|
||||
|
||||
<record id="tax_report_13_base" model="account.tax.report.line">
|
||||
<field name="name">13 - Anciens taux (base)</field>
|
||||
<field name="tag_name">13_base</field>
|
||||
<field name="code">box_13_base</field>
|
||||
<field name="parent_id" ref="tax_report_tva_brute_autre"/>
|
||||
<field name="report_id" ref="tax_report"/>
|
||||
<field name="sequence">11</field>
|
||||
<field name="sequence">15</field>
|
||||
</record>
|
||||
<record id="tax_report_13_taxe" model="account.tax.report.line">
|
||||
<field name="name">13 - Anciens taux (taxe)</field>
|
||||
@@ -399,7 +521,7 @@
|
||||
<field name="code">box_13_taxe</field>
|
||||
<field name="parent_id" ref="tax_report_tva_brute_autre"/>
|
||||
<field name="report_id" ref="tax_report"/>
|
||||
<field name="sequence">12</field>
|
||||
<field name="sequence">16</field>
|
||||
</record>
|
||||
|
||||
<record id="tax_report_14_base" model="account.tax.report.line">
|
||||
@@ -408,7 +530,7 @@
|
||||
<field name="code">box_14_base</field>
|
||||
<field name="parent_id" ref="tax_report_tva_brute_autre"/>
|
||||
<field name="report_id" ref="tax_report"/>
|
||||
<field name="sequence">13</field>
|
||||
<field name="sequence">17</field>
|
||||
</record>
|
||||
<record id="tax_report_14_taxe" model="account.tax.report.line">
|
||||
<field name="name">14 - Opérations imposables à un taux particulier (taxe)</field>
|
||||
@@ -416,7 +538,7 @@
|
||||
<field name="code">box_14_taxe</field>
|
||||
<field name="parent_id" ref="tax_report_tva_brute_autre"/>
|
||||
<field name="report_id" ref="tax_report"/>
|
||||
<field name="sequence">14</field>
|
||||
<field name="sequence">18</field>
|
||||
</record>
|
||||
|
||||
<!-- Produits pétroliers -->
|
||||
@@ -614,7 +736,7 @@
|
||||
<field name="report_id" ref="tax_report"/>
|
||||
<field name="sequence">33</field>
|
||||
<field name="formula">
|
||||
box_08_taxe + box_09_taxe + box_9B_taxe + box_10_taxe + box_11_taxe + box_13_taxe + box_14_taxe + box_P1_taxe + box_P2_taxe + box_I1_taxe + box_I2_taxe + box_I3_taxe + box_I4_taxe + box_I5_taxe + box_I6_taxe + box_15 + box_5B
|
||||
box_08_taxe + box_09_taxe + box_9B_taxe + box_10_taxe + box_11_taxe + box_13_taxe + box_14_taxe + box_T1_taxe + box_T2_taxe + box_T3_taxe + box_T4_taxe + box_T5_taxe + box_T6_taxe + box_T7_taxe + box_P1_taxe + box_P2_taxe + box_I1_taxe + box_I2_taxe + box_I3_taxe + box_I4_taxe + box_I5_taxe + box_I6_taxe + box_15 + box_5B
|
||||
</field>
|
||||
</record>
|
||||
|
||||
@@ -717,14 +839,14 @@
|
||||
<field name="sequence">9</field>
|
||||
</record>
|
||||
|
||||
<!-- TVA due ou crédit de TVA -->
|
||||
<record id="tax_report_credit" model="account.tax.report.line">
|
||||
<field name="name">Crédit</field>
|
||||
<field name="name">TVA due ou crédit de TVA</field>
|
||||
<field name="report_id" ref="tax_report"/>
|
||||
<field name="sequence">3</field>
|
||||
<field name="formula">None</field>
|
||||
</record>
|
||||
|
||||
<!-- CREDIT -->
|
||||
<record id="tax_report_25" model="account.tax.report.line">
|
||||
<field name="name">25 - Crédit de TVA</field>
|
||||
<field name="code">box_25</field>
|
||||
@@ -734,11 +856,198 @@
|
||||
<field name="formula">box_23 - box_16 if box_23 - box_16 > 0 else 0</field>
|
||||
</record>
|
||||
|
||||
<record id="tax_report_TD" model="account.tax.report.line">
|
||||
<field name="name">TD - TVA Due</field>
|
||||
<field name="code">box_TD</field>
|
||||
<field name="parent_id" ref="tax_report_credit"/>
|
||||
<field name="report_id" ref="tax_report"/>
|
||||
<field name="sequence">1</field>
|
||||
<field name="formula">box_16 - box_23 if box_16 - box_23 > 0 else 0</field>
|
||||
</record>
|
||||
|
||||
<!-- Régularisation des taxes intérieures de consommation (TIC) -->
|
||||
<record id="tax_report_regularisation" model="account.tax.report.line">
|
||||
<field name="name">Régularisation des taxes intérieures de consommation (TIC)</field>
|
||||
<field name="report_id" ref="tax_report"/>
|
||||
<field name="sequence">4</field>
|
||||
</record>
|
||||
|
||||
<!-- Crédit constaté -->
|
||||
<record id="tax_report_credit_constate" model="account.tax.report.line">
|
||||
<field name="name">Crédit constaté</field>
|
||||
<field name="parent_id" ref="tax_report_regularisation"/>
|
||||
<field name="report_id" ref="tax_report"/>
|
||||
<field name="sequence">1</field>
|
||||
</record>
|
||||
|
||||
<record id="tax_report_TICFE" model="account.tax.report.line">
|
||||
<field name="name">TICFE</field>
|
||||
<field name="code">box_TICFE</field>
|
||||
<field name="tag_name">TICFE_constate</field>
|
||||
<field name="parent_id" ref="tax_report_credit_constate"/>
|
||||
<field name="report_id" ref="tax_report"/>
|
||||
<field name="sequence">1</field>
|
||||
</record>
|
||||
<record id="tax_report_TICGN" model="account.tax.report.line">
|
||||
<field name="name">TICGN</field>
|
||||
<field name="code">box_TICGN</field>
|
||||
<field name="tag_name">TICGN_constate</field>
|
||||
<field name="parent_id" ref="tax_report_credit_constate"/>
|
||||
<field name="report_id" ref="tax_report"/>
|
||||
<field name="sequence">2</field>
|
||||
</record>
|
||||
<record id="tax_report_TICC" model="account.tax.report.line">
|
||||
<field name="name">TICC</field>
|
||||
<field name="code">box_TICC</field>
|
||||
<field name="tag_name">TICC_constate</field>
|
||||
<field name="parent_id" ref="tax_report_credit_constate"/>
|
||||
<field name="report_id" ref="tax_report"/>
|
||||
<field name="sequence">3</field>
|
||||
</record>
|
||||
<record id="tax_report_TIC_total" model="account.tax.report.line">
|
||||
<field name="name">Total</field>
|
||||
<field name="code">box_TIC_total</field>
|
||||
<field name="parent_id" ref="tax_report_credit_constate"/>
|
||||
<field name="report_id" ref="tax_report"/>
|
||||
<field name="sequence">4</field>
|
||||
<field name="formula">box_TICFE + box_TICGN + box_TICC</field>
|
||||
</record>
|
||||
|
||||
<!-- Crédit imputé -->
|
||||
<record id="tax_report_credit_impute" model="account.tax.report.line">
|
||||
<field name="name">Crédit imputé</field>
|
||||
<field name="parent_id" ref="tax_report_regularisation"/>
|
||||
<field name="report_id" ref="tax_report"/>
|
||||
<field name="sequence">2</field>
|
||||
</record>
|
||||
|
||||
<record id="tax_report_X1" model="account.tax.report.line">
|
||||
<field name="name">X1</field>
|
||||
<field name="tag_name">X1</field>
|
||||
<field name="code">box_X1</field>
|
||||
<field name="parent_id" ref="tax_report_credit_impute"/>
|
||||
<field name="report_id" ref="tax_report"/>
|
||||
<field name="sequence">1</field>
|
||||
</record>
|
||||
<record id="tax_report_X2" model="account.tax.report.line">
|
||||
<field name="name">X2</field>
|
||||
<field name="tag_name">X2</field>
|
||||
<field name="code">box_X2</field>
|
||||
<field name="parent_id" ref="tax_report_credit_impute"/>
|
||||
<field name="report_id" ref="tax_report"/>
|
||||
<field name="sequence">2</field>
|
||||
</record>
|
||||
<record id="tax_report_X3" model="account.tax.report.line">
|
||||
<field name="name">X3</field>
|
||||
<field name="tag_name">X3</field>
|
||||
<field name="code">box_X3</field>
|
||||
<field name="parent_id" ref="tax_report_credit_impute"/>
|
||||
<field name="report_id" ref="tax_report"/>
|
||||
<field name="sequence">3</field>
|
||||
</record>
|
||||
<record id="tax_report_X4" model="account.tax.report.line">
|
||||
<field name="name">X4</field>
|
||||
<field name="code">box_X4</field>
|
||||
<field name="parent_id" ref="tax_report_credit_impute"/>
|
||||
<field name="report_id" ref="tax_report"/>
|
||||
<field name="sequence">4</field>
|
||||
<field name="formula">box_X1 + box_X2 + box_X3</field>
|
||||
</record>
|
||||
|
||||
<!-- Reliquat de crédit à rembourser -->
|
||||
<record id="tax_report_reliquat" model="account.tax.report.line">
|
||||
<field name="name">Reliquat de crédit à rembourser</field>
|
||||
<field name="parent_id" ref="tax_report_regularisation"/>
|
||||
<field name="report_id" ref="tax_report"/>
|
||||
<field name="sequence">3</field>
|
||||
</record>
|
||||
|
||||
<record id="tax_report_Y1" model="account.tax.report.line">
|
||||
<field name="name">Y1</field>
|
||||
<field name="code">box_Y1</field>
|
||||
<field name="parent_id" ref="tax_report_reliquat"/>
|
||||
<field name="report_id" ref="tax_report"/>
|
||||
<field name="sequence">1</field>
|
||||
<field name="formula">box_TICFE - box_X1</field>
|
||||
</record>
|
||||
<record id="tax_report_Y2" model="account.tax.report.line">
|
||||
<field name="name">Y2</field>
|
||||
<field name="code">box_Y2</field>
|
||||
<field name="parent_id" ref="tax_report_reliquat"/>
|
||||
<field name="report_id" ref="tax_report"/>
|
||||
<field name="sequence">2</field>
|
||||
<field name="formula">box_TICGN - box_X2</field>
|
||||
</record>
|
||||
<record id="tax_report_Y3" model="account.tax.report.line">
|
||||
<field name="name">Y3</field>
|
||||
<field name="code">box_Y3</field>
|
||||
<field name="parent_id" ref="tax_report_reliquat"/>
|
||||
<field name="report_id" ref="tax_report"/>
|
||||
<field name="sequence">3</field>
|
||||
<field name="formula">box_TICC - box_X3</field>
|
||||
</record>
|
||||
<record id="tax_report_Y4" model="account.tax.report.line">
|
||||
<field name="name">Y4</field>
|
||||
<field name="code">box_Y4</field>
|
||||
<field name="parent_id" ref="tax_report_reliquat"/>
|
||||
<field name="report_id" ref="tax_report"/>
|
||||
<field name="sequence">4</field>
|
||||
<field name="formula">box_Y1 + box_Y2 + box_Y3</field>
|
||||
</record>
|
||||
|
||||
<!-- Taxe due -->
|
||||
<record id="tax_report_tic_tax" model="account.tax.report.line">
|
||||
<field name="name">Taxe due</field>
|
||||
<field name="parent_id" ref="tax_report_regularisation"/>
|
||||
<field name="report_id" ref="tax_report"/>
|
||||
<field name="sequence">4</field>
|
||||
</record>
|
||||
|
||||
<record id="tax_report_Z1" model="account.tax.report.line">
|
||||
<field name="name">Z1</field>
|
||||
<field name="tag_name">Z1</field>
|
||||
<field name="code">box_Z1</field>
|
||||
<field name="parent_id" ref="tax_report_tic_tax"/>
|
||||
<field name="report_id" ref="tax_report"/>
|
||||
<field name="sequence">1</field>
|
||||
</record>
|
||||
<record id="tax_report_Z2" model="account.tax.report.line">
|
||||
<field name="name">Z2</field>
|
||||
<field name="tag_name">Z2</field>
|
||||
<field name="code">box_Z2</field>
|
||||
<field name="parent_id" ref="tax_report_tic_tax"/>
|
||||
<field name="report_id" ref="tax_report"/>
|
||||
<field name="sequence">2</field>
|
||||
</record>
|
||||
<record id="tax_report_Z3" model="account.tax.report.line">
|
||||
<field name="name">Z3</field>
|
||||
<field name="tag_name">Z3</field>
|
||||
<field name="code">box_Z3</field>
|
||||
<field name="parent_id" ref="tax_report_tic_tax"/>
|
||||
<field name="report_id" ref="tax_report"/>
|
||||
<field name="sequence">3</field>
|
||||
</record>
|
||||
<record id="tax_report_Z4" model="account.tax.report.line">
|
||||
<field name="name">Z4</field>
|
||||
<field name="code">box_Z4</field>
|
||||
<field name="parent_id" ref="tax_report_tic_tax"/>
|
||||
<field name="report_id" ref="tax_report"/>
|
||||
<field name="sequence">4</field>
|
||||
<field name="formula">box_Z1 + box_Z2 + box_Z3</field>
|
||||
</record>
|
||||
|
||||
<!-- Détermination du montant à payer et/ou des crédits de TVA et/ou de TIC-->
|
||||
<record id="tax_report_determination" model="account.tax.report.line">
|
||||
<field name="name">Détermination du montant à payer et/ou des crédits de TVA et/ou de TIC</field>
|
||||
<field name="report_id" ref="tax_report"/>
|
||||
<field name="sequence">5</field>
|
||||
</record>
|
||||
|
||||
<record id="tax_report_26" model="account.tax.report.line">
|
||||
<field name="name">26 - Remboursement de crédit demandé sur formulaire n°3519 joint</field>
|
||||
<field name="tag_name">26</field>
|
||||
<field name="code">box_26</field>
|
||||
<field name="parent_id" ref="tax_report_credit"/>
|
||||
<field name="parent_id" ref="tax_report_determination"/>
|
||||
<field name="report_id" ref="tax_report"/>
|
||||
<field name="sequence">2</field>
|
||||
</record>
|
||||
@@ -749,7 +1058,7 @@
|
||||
</field>
|
||||
<field name="tag_name">AA</field>
|
||||
<field name="code">box_AA</field>
|
||||
<field name="parent_id" ref="tax_report_credit"/>
|
||||
<field name="parent_id" ref="tax_report_determination"/>
|
||||
<field name="report_id" ref="tax_report"/>
|
||||
<field name="sequence">3</field>
|
||||
</record>
|
||||
@@ -757,36 +1066,64 @@
|
||||
<record id="tax_report_27" model="account.tax.report.line">
|
||||
<field name="name">27 - Crédit à reporter</field>
|
||||
<field name="code">box_27</field>
|
||||
<field name="parent_id" ref="tax_report_credit"/>
|
||||
<field name="parent_id" ref="tax_report_determination"/>
|
||||
<field name="report_id" ref="tax_report"/>
|
||||
<field name="sequence">4</field>
|
||||
<field name="formula">box_25 - box_26 - box_AA if box_25 - box_26 - box_AA > 0 else 0</field>
|
||||
</record>
|
||||
|
||||
<record id="tax_report_taxes_a_payer" model="account.tax.report.line">
|
||||
<field name="name">Taxe à Payer</field>
|
||||
<record id="tax_report_Y5" model="account.tax.report.line">
|
||||
<field name="name">Y5 - Remboursement de reliquat de TIC demandé (report de la ligne Y4)</field>
|
||||
<field name="code">box_Y5</field>
|
||||
<field name="parent_id" ref="tax_report_determination"/>
|
||||
<field name="report_id" ref="tax_report"/>
|
||||
<field name="sequence">4</field>
|
||||
<field name="formula">None</field>
|
||||
<field name="sequence">5</field>
|
||||
<field name="formula">box_Y4</field>
|
||||
</record>
|
||||
|
||||
<record id="tax_report_Y6" model="account.tax.report.line">
|
||||
<field name="name">Y6 - Crédit de TIC transféré à la société tête de groupe sur la déclaration récapitulative
|
||||
3310-CA3G (report de la ligne Y4)</field>
|
||||
<field name="code">box_Y6</field>
|
||||
<field name="parent_id" ref="tax_report_determination"/>
|
||||
<field name="report_id" ref="tax_report"/>
|
||||
<field name="sequence">5</field>
|
||||
</record>
|
||||
|
||||
<record id="tax_report_X5" model="account.tax.report.line">
|
||||
<field name="name">X5 - Crédit de TIC imputé sur la TVA (report de la ligne X4)</field>
|
||||
<field name="code">box_X5</field>
|
||||
<field name="parent_id" ref="tax_report_determination"/>
|
||||
<field name="report_id" ref="tax_report"/>
|
||||
<field name="sequence">6</field>
|
||||
<field name="formula">box_X4</field>
|
||||
</record>
|
||||
|
||||
<!-- TAXE A PAYER -->
|
||||
<record id="tax_report_28" model="account.tax.report.line">
|
||||
<field name="name">28 - TVA nette due</field>
|
||||
<field name="code">box_28</field>
|
||||
<field name="parent_id" ref="tax_report_taxes_a_payer"/>
|
||||
<field name="parent_id" ref="tax_report_determination"/>
|
||||
<field name="report_id" ref="tax_report"/>
|
||||
<field name="sequence">1</field>
|
||||
<field name="formula">box_16 - box_23 if box_16 - box_23 > 0 else 0</field>
|
||||
<field name="sequence">7</field>
|
||||
<field name="formula">box_TD - box_X5 if box_TD - box_X5 > 0 else 0</field>
|
||||
</record>
|
||||
|
||||
<record id="tax_report_29" model="account.tax.report.line">
|
||||
<field name="name">29 - Taxes assimilées calculées sur annexe n°3310-A-SD</field>
|
||||
<field name="tag_name">29</field>
|
||||
<field name="code">box_29</field>
|
||||
<field name="parent_id" ref="tax_report_taxes_a_payer"/>
|
||||
<field name="parent_id" ref="tax_report_determination"/>
|
||||
<field name="report_id" ref="tax_report"/>
|
||||
<field name="sequence">2</field>
|
||||
<field name="sequence">8</field>
|
||||
</record>
|
||||
|
||||
<record id="tax_report_Z5" model="account.tax.report.line">
|
||||
<field name="name">Z5 - Total des taxes intérieures de consommation dues (report de la ligne Z4)</field>
|
||||
<field name="code">box_Z5</field>
|
||||
<field name="parent_id" ref="tax_report_determination"/>
|
||||
<field name="report_id" ref="tax_report"/>
|
||||
<field name="sequence">9</field>
|
||||
<field name="formula">box_Z4</field>
|
||||
</record>
|
||||
|
||||
<record id="tax_report_AB" model="account.tax.report.line">
|
||||
@@ -794,9 +1131,9 @@
|
||||
3310-CA3G
|
||||
</field>
|
||||
<field name="code">box_AB</field>
|
||||
<field name="parent_id" ref="tax_report_taxes_a_payer"/>
|
||||
<field name="parent_id" ref="tax_report_determination"/>
|
||||
<field name="report_id" ref="tax_report"/>
|
||||
<field name="sequence">3</field>
|
||||
<field name="sequence">10</field>
|
||||
<!--According to the trustee, it's very rare that a company fill this box-->
|
||||
<field name="formula">None</field>
|
||||
</record>
|
||||
@@ -804,11 +1141,11 @@
|
||||
<record id="tax_report_32" model="account.tax.report.line">
|
||||
<field name="name">32 - Total à payer</field>
|
||||
<field name="code">box_32</field>
|
||||
<field name="parent_id" ref="tax_report_taxes_a_payer"/>
|
||||
<field name="parent_id" ref="tax_report_determination"/>
|
||||
<field name="report_id" ref="tax_report"/>
|
||||
<field name="sequence">4</field>
|
||||
<!--The real formula is "box_28 + box_29 - box_AB" but box_AB not zero is a rare edge case -->
|
||||
<field name="formula">box_28 + box_29</field>
|
||||
<field name="sequence">11</field>
|
||||
<!--Omit "... - box_AB" in the formula because box_AB not zero is a rare edge case -->
|
||||
<field name="formula">box_28 + box_29 + box_Z5</field>
|
||||
</record>
|
||||
|
||||
</flectra>
|
||||
@@ -5,6 +5,11 @@ from flectra.tests import common
|
||||
|
||||
|
||||
class TestMailRenderMixin(common.TransactionCase):
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
r = self.patch_requests()
|
||||
r.side_effect=NotImplementedError
|
||||
|
||||
def test_shorten_links(self):
|
||||
test_links = [
|
||||
'<a href="https://gitlab.com" title="title" fake="fake">test_label</a>',
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo, Flectra. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from flectra import api, models
|
||||
from flectra import api, models, _
|
||||
from flectra.exceptions import ValidationError
|
||||
|
||||
|
||||
class IrConfigParameter(models.Model):
|
||||
@@ -12,10 +13,24 @@ class IrConfigParameter(models.Model):
|
||||
for vals in vals_list:
|
||||
if vals.get('key') in ['mail.bounce.alias', 'mail.catchall.alias']:
|
||||
vals['value'] = self.env['mail.alias']._clean_and_check_unique(vals.get('value'))
|
||||
elif vals.get('key') == 'mail.catchall.domain.allowed':
|
||||
vals['value'] = vals.get('value') and self._clean_and_check_mail_catchall_allowed_domains(vals['value'])
|
||||
return super().create(vals_list)
|
||||
|
||||
def write(self, vals):
|
||||
for parameter in self:
|
||||
if 'value' in vals and parameter.key in ['mail.bounce.alias', 'mail.catchall.alias'] and vals['value'] != parameter.value:
|
||||
vals['value'] = self.env['mail.alias']._clean_and_check_unique(vals.get('value'))
|
||||
elif 'value' in vals and parameter.key == 'mail.catchall.domain.allowed' and vals['value'] != parameter.value:
|
||||
vals['value'] = vals['value'] and self._clean_and_check_mail_catchall_allowed_domains(vals['value'])
|
||||
return super().write(vals)
|
||||
|
||||
def _clean_and_check_mail_catchall_allowed_domains(self, value):
|
||||
""" The purpose of this system parameter is to avoid the creation
|
||||
of records from incoming emails with a domain != alias_domain
|
||||
but that have a pattern matching an internal mail.alias . """
|
||||
value = [domain.strip().lower() for domain in value.split(',') if domain.strip()]
|
||||
if not value:
|
||||
raise ValidationError(_("Value for `mail.catchall.domain.allowed` cannot be validated.\n"
|
||||
"It should be a comma separated list of domains e.g. example.com,example.org."))
|
||||
return ",".join(value)
|
||||
|
||||
@@ -851,9 +851,16 @@ class Channel(models.Model):
|
||||
if channel_partner.fetched_message_id.id == last_message_id:
|
||||
# last message fetched by user is already up-to-date
|
||||
return
|
||||
channel_partner.write({
|
||||
'fetched_message_id': last_message_id,
|
||||
})
|
||||
# Avoid serialization error when multiple tabs are opened.
|
||||
query = """
|
||||
UPDATE mail_channel_partner
|
||||
SET fetched_message_id = %s
|
||||
WHERE id IN (
|
||||
SELECT id FROM mail_channel_partner WHERE id = %s
|
||||
FOR NO KEY UPDATE SKIP LOCKED
|
||||
)
|
||||
"""
|
||||
self.env.cr.execute(query, (last_message_id, channel_partner.id))
|
||||
data = {
|
||||
'id': channel_partner.id,
|
||||
'info': 'channel_fetched',
|
||||
|
||||
@@ -888,6 +888,10 @@ class MailThread(models.AbstractModel):
|
||||
if not isinstance(message, EmailMessage):
|
||||
raise TypeError('message must be an email.message.EmailMessage at this point')
|
||||
catchall_alias = self.env['ir.config_parameter'].sudo().get_param("mail.catchall.alias")
|
||||
catchall_domain_lowered = self.env["ir.config_parameter"].sudo().get_param("mail.catchall.domain", "").strip().lower()
|
||||
catchall_domains_allowed = self.env["ir.config_parameter"].sudo().get_param("mail.catchall.domain.allowed")
|
||||
if catchall_domain_lowered and catchall_domains_allowed:
|
||||
catchall_domains_allowed = catchall_domains_allowed.split(',') + [catchall_domain_lowered]
|
||||
bounce_alias = self.env['ir.config_parameter'].sudo().get_param("mail.bounce.alias")
|
||||
bounce_alias_static = tools.str2bool(self.env['ir.config_parameter'].sudo().get_param("mail.bounce.alias.static", "False"))
|
||||
fallback_model = model
|
||||
@@ -917,10 +921,11 @@ class MailThread(models.AbstractModel):
|
||||
]
|
||||
# Delivered-To is a safe bet in most modern MTAs, but we have to fallback on To + Cc values
|
||||
# for all the odd MTAs out there, as there is no standard header for the envelope's `rcpt_to` value.
|
||||
rcpt_tos_localparts = [
|
||||
e.split('@')[0].lower()
|
||||
for e in tools.email_split(message_dict['recipients'])
|
||||
]
|
||||
rcpt_tos_localparts = []
|
||||
for recipient in tools.email_split(message_dict['recipients']):
|
||||
to_local, to_domain = recipient.split('@', maxsplit=1)
|
||||
if not catchall_domains_allowed or to_domain.lower() in catchall_domains_allowed:
|
||||
rcpt_tos_localparts.append(to_local.lower())
|
||||
rcpt_tos_valid_localparts = [to for to in rcpt_tos_localparts]
|
||||
|
||||
# 0. Handle bounce: verify whether this is a bounced email and use it to collect bounce data and update notifications for customers
|
||||
|
||||
@@ -15,6 +15,7 @@ Bridge module adding UX requirements to ease SMS marketing o, event attendees.
|
||||
'depends': [
|
||||
'event',
|
||||
'mass_mailing',
|
||||
'mass_mailing_event',
|
||||
'mass_mailing_sms',
|
||||
'sms',
|
||||
],
|
||||
|
||||
@@ -393,7 +393,7 @@ class MrpWorkorder(models.Model):
|
||||
|
||||
@api.onchange('date_planned_finished')
|
||||
def _onchange_date_planned_finished(self):
|
||||
if self.date_planned_start and self.date_planned_finished:
|
||||
if self.date_planned_start and self.date_planned_finished and self.workcenter_id:
|
||||
self.duration_expected = self._calculate_duration_expected()
|
||||
|
||||
def _calculate_duration_expected(self, date_planned_start=False, date_planned_finished=False):
|
||||
@@ -728,7 +728,7 @@ class MrpWorkorder(models.Model):
|
||||
@api.depends('qty_production', 'qty_produced')
|
||||
def _compute_qty_remaining(self):
|
||||
for wo in self:
|
||||
wo.qty_remaining = float_round(wo.qty_production - wo.qty_produced, precision_rounding=wo.production_id.product_uom_id.rounding)
|
||||
wo.qty_remaining = max(float_round(wo.qty_production - wo.qty_produced, precision_rounding=wo.production_id.product_uom_id.rounding), 0)
|
||||
|
||||
def _get_duration_expected(self, alternative_workcenter=False, ratio=1):
|
||||
self.ensure_one()
|
||||
|
||||
@@ -201,7 +201,7 @@ class CustomerPortal(CustomerPortal):
|
||||
elif groupby == 'stage':
|
||||
grouped_tasks = [request.env['project.task'].concat(*g) for k, g in groupbyelem(tasks, itemgetter('stage_id'))]
|
||||
else:
|
||||
grouped_tasks = [tasks]
|
||||
grouped_tasks = [tasks] if tasks else []
|
||||
|
||||
values.update({
|
||||
'date': date_begin,
|
||||
|
||||
@@ -1139,8 +1139,10 @@ class Task(models.Model):
|
||||
recurrence = self.env['project.task.recurrence'].create(rec_values)
|
||||
task.recurrence_id = recurrence.id
|
||||
|
||||
if 'recurring_task' in vals and not vals.get('recurring_task'):
|
||||
if not vals.get('recurring_task', True) and self.recurrence_id:
|
||||
tasks_in_recurrence = self.recurrence_id.task_ids
|
||||
self.recurrence_id.unlink()
|
||||
tasks_in_recurrence.write({'recurring_task': False})
|
||||
|
||||
tasks = self
|
||||
recurrence_update = vals.pop('recurrence_update', 'this')
|
||||
|
||||
@@ -554,3 +554,33 @@ class TestProjectrecurrence(SavepointCase):
|
||||
|
||||
self.env.user.lang = None
|
||||
task._compute_recurrence_message()
|
||||
|
||||
def test_disabling_recurrence(self):
|
||||
"""
|
||||
Disabling the recurrence of one task in a recurrence suite should disable *all*
|
||||
recurrences option on the tasks linked to that recurrence
|
||||
"""
|
||||
with freeze_time("2020-01-01"):
|
||||
self.env['project.task'].create({
|
||||
'name': 'test recurring task',
|
||||
'project_id': self.project_recurring.id,
|
||||
'recurring_task': True,
|
||||
'repeat_interval': 1,
|
||||
'repeat_unit': 'week',
|
||||
'repeat_type': 'after',
|
||||
'repeat_number': 2,
|
||||
'mon': True,
|
||||
})
|
||||
|
||||
with freeze_time("2020-01-06"):
|
||||
self.env['project.task.recurrence']._cron_create_recurring_tasks()
|
||||
|
||||
with freeze_time("2020-01-13"):
|
||||
self.env['project.task.recurrence']._cron_create_recurring_tasks()
|
||||
|
||||
task_c, task_b, task_a = self.env['project.task'].search([('project_id', '=', self.project_recurring.id)])
|
||||
|
||||
task_b.recurring_task = False
|
||||
|
||||
self.assertFalse(any((task_a + task_b + task_c).mapped('recurring_task')),
|
||||
"All tasks in the recurrence should have their recurrence disabled")
|
||||
|
||||
@@ -13,13 +13,15 @@ class ResPartner(models.Model):
|
||||
purchase_line_ids = fields.One2many('purchase.order.line', 'partner_id', string="Purchase Lines")
|
||||
on_time_rate = fields.Float(
|
||||
"On-Time Delivery Rate", compute='_compute_on_time_rate',
|
||||
help="Over the past 12 months; the number of products received on time divided by the number of ordered products.")
|
||||
help="Over the past x days; the number of products received on time divided by the number of ordered products."\
|
||||
"x is either the System Parameter purchase_stock.on_time_delivery_days or the default 365")
|
||||
|
||||
@api.depends('purchase_line_ids')
|
||||
def _compute_on_time_rate(self):
|
||||
date_order_days_delta = int(self.env['ir.config_parameter'].sudo().get_param('purchase_stock.on_time_delivery_days', default='365'))
|
||||
order_lines = self.env['purchase.order.line'].search([
|
||||
('partner_id', 'in', self.ids),
|
||||
('date_order', '>', fields.Date.today() - timedelta(365)),
|
||||
('date_order', '>', fields.Date.today() - timedelta(date_order_days_delta)),
|
||||
('qty_received', '!=', 0),
|
||||
('order_id.state', 'in', ['done', 'purchase']),
|
||||
('product_id', 'in', self.env['product.product'].sudo()._search([('type', '!=', 'service')]))
|
||||
|
||||
@@ -234,7 +234,7 @@ class Orderpoint(models.Model):
|
||||
'product.supplierinfo', string='Vendor', check_company=True,
|
||||
domain="['|', ('product_id', '=', product_id), '&', ('product_id', '=', False), ('product_tmpl_id', '=', product_tmpl_id)]")
|
||||
|
||||
@api.depends('product_id.purchase_order_line_ids', 'product_id.purchase_order_line_ids.state')
|
||||
@api.depends('product_id.purchase_order_line_ids.product_qty', 'product_id.purchase_order_line_ids.state')
|
||||
def _compute_qty(self):
|
||||
""" Extend to add more depends values """
|
||||
return super()._compute_qty()
|
||||
|
||||
@@ -276,6 +276,64 @@ class TestReorderingRule(SavepointCase):
|
||||
move = move.move_dest_ids
|
||||
self.assertFalse(move)
|
||||
|
||||
def test_reordering_rule_5(self):
|
||||
"""
|
||||
A product P wth RR 0-0-1.
|
||||
Confirm a delivery with 1 x P -> PO created for it.
|
||||
Confirm a second delivery, with 1 x P again:
|
||||
- The PO should be updated
|
||||
- The qty to order of the RR should be zero
|
||||
"""
|
||||
warehouse = self.env['stock.warehouse'].search([('company_id', '=', self.env.user.id)], limit=1)
|
||||
stock_location = warehouse.lot_stock_id
|
||||
out_type = warehouse.out_type_id
|
||||
customer_location = self.env.ref('stock.stock_location_customers')
|
||||
|
||||
rr = self.env['stock.warehouse.orderpoint'].create({
|
||||
'location_id': stock_location.id,
|
||||
'product_id': self.product_01.id,
|
||||
'product_min_qty': 0,
|
||||
'product_max_qty': 0,
|
||||
'qty_multiple': 1,
|
||||
})
|
||||
|
||||
delivery = self.env['stock.picking'].create({
|
||||
'picking_type_id': out_type.id,
|
||||
'location_id': stock_location.id,
|
||||
'location_dest_id': customer_location.id,
|
||||
'move_lines': [(0, 0, {
|
||||
'name': self.product_01.name,
|
||||
'product_id': self.product_01.id,
|
||||
'product_uom_qty': 1,
|
||||
'product_uom': self.product_01.uom_id.id,
|
||||
'location_id': stock_location.id,
|
||||
'location_dest_id': customer_location.id,
|
||||
})]
|
||||
})
|
||||
delivery.action_confirm()
|
||||
|
||||
pol = self.env['purchase.order.line'].search([('product_id', '=', self.product_01.id)])
|
||||
self.assertEqual(pol.product_qty, 1.0)
|
||||
self.assertEqual(rr.qty_to_order, 0.0)
|
||||
|
||||
delivery = self.env['stock.picking'].create({
|
||||
'picking_type_id': out_type.id,
|
||||
'location_id': stock_location.id,
|
||||
'location_dest_id': customer_location.id,
|
||||
'move_lines': [(0, 0, {
|
||||
'name': self.product_01.name,
|
||||
'product_id': self.product_01.id,
|
||||
'product_uom_qty': 1,
|
||||
'product_uom': self.product_01.uom_id.id,
|
||||
'location_id': stock_location.id,
|
||||
'location_dest_id': customer_location.id,
|
||||
})]
|
||||
})
|
||||
delivery.action_confirm()
|
||||
|
||||
self.assertEqual(pol.product_qty, 2.0)
|
||||
self.assertEqual(rr.qty_to_order, 0.0)
|
||||
|
||||
def test_replenish_report_1(self):
|
||||
"""Tests the auto generation of manual orderpoints.
|
||||
|
||||
|
||||
@@ -171,6 +171,23 @@ class TestMailAlias(TestMailCommon):
|
||||
with self.assertRaises(exceptions.ValidationError):
|
||||
record.write({'alias_defaults': "{'custom_field': brokendict"})
|
||||
|
||||
def test_alias_domain_allowed_validation(self):
|
||||
""" Check the validation of `mail.catchall.domain.allowed` system parameter"""
|
||||
for value in [',', ',,', ', ,']:
|
||||
with self.assertRaises(exceptions.ValidationError,
|
||||
msg="The value '%s' should not be allowed" % value):
|
||||
self.env['ir.config_parameter'].set_param('mail.catchall.domain.allowed', value)
|
||||
|
||||
for value, expected in [
|
||||
('', False),
|
||||
('hello.com', 'hello.com'),
|
||||
('hello.com,,', 'hello.com'),
|
||||
('hello.com,bonjour.com', 'hello.com,bonjour.com'),
|
||||
('hello.COM, BONJOUR.com', 'hello.com,bonjour.com'),
|
||||
]:
|
||||
self.env['ir.config_parameter'].set_param('mail.catchall.domain.allowed', value)
|
||||
self.assertEqual(self.env['ir.config_parameter'].get_param('mail.catchall.domain.allowed'), expected)
|
||||
|
||||
def test_alias_setup(self):
|
||||
alias = self.env['mail.alias'].create({
|
||||
'alias_model_id': self.env['ir.model']._get('mail.test.container').id,
|
||||
@@ -801,6 +818,66 @@ class TestMailgateway(TestMailCommon):
|
||||
new_simple = self.env['mail.test.gateway'].search([('name', '=', 'Test Subject')])
|
||||
self.assertEqual(len(new_simple), 1, 'message_process: a new mail.test should have been created')
|
||||
|
||||
@mute_logger('flectra.addons.mail.models.mail_thread', 'flectra.models')
|
||||
def test_message_route_alias_with_allowed_domains(self):
|
||||
""" Incoming email: check that if domains are set in the
|
||||
optional system parameter `mail.catchall.domain.allowed`,
|
||||
only incoming emails from these domains will generate records."""
|
||||
|
||||
MailTestGatewayModel = self.env['mail.test.gateway']
|
||||
MailTestContainerModel = self.env['mail.test.container']
|
||||
|
||||
allowed_domain = 'hello.com'
|
||||
not_allowed_domain = 'bonjour.com'
|
||||
|
||||
# test@.. will cause the creation of new mail.test
|
||||
new_alias_2 = self.env['mail.alias'].create({
|
||||
'alias_name': 'test',
|
||||
'alias_user_id': False,
|
||||
'alias_model_id': self.env['ir.model']._get('mail.test.container').id,
|
||||
'alias_contact': 'everyone',
|
||||
})
|
||||
|
||||
for subject, gateway_created, container_created, alias2_domain, sys_param in [
|
||||
# Test with 'mail.catchall.domain.allowed' not set in system parameters
|
||||
# and with a domain not allowed
|
||||
('Test Subject 1', True, True, not_allowed_domain, ""),
|
||||
# Test with 'mail.catchall.domain.allowed' set in system parameters
|
||||
# and with a domain not allowed
|
||||
('Test Subject 2', True, False, not_allowed_domain, allowed_domain),
|
||||
# Test with 'mail.catchall.domain.allowed' set in system parameters
|
||||
# and with a domain allowed
|
||||
('Test Subject 3', True, True, allowed_domain, allowed_domain),
|
||||
]:
|
||||
with self.subTest(subject=subject, gateway_created=gateway_created,
|
||||
container_created=container_created, alias2_domain=alias2_domain,
|
||||
sys_param=sys_param):
|
||||
self.env['ir.config_parameter'].set_param('mail.catchall.domain.allowed', sys_param)
|
||||
|
||||
email_to = '%s@%s, %s@%s' % (
|
||||
self.alias.alias_name, self.alias_domain,
|
||||
new_alias_2.alias_name, alias2_domain,
|
||||
)
|
||||
|
||||
self.format_and_process(
|
||||
MAIL_TEMPLATE, self.partner_1.email_formatted, email_to,
|
||||
subject=subject,
|
||||
target_model=self.alias.alias_model_id.model
|
||||
)
|
||||
|
||||
res_alias_1 = MailTestGatewayModel.search([('name', '=', subject)])
|
||||
res_alias_2 = MailTestContainerModel.search([('name', '=', subject)])
|
||||
self.assertEqual(
|
||||
bool(res_alias_1), gateway_created,
|
||||
'message_process (%s): a new mail.test.gateway %s have been created' %
|
||||
(subject, 'should' if gateway_created else "should not")
|
||||
)
|
||||
self.assertEqual(
|
||||
bool(res_alias_2), container_created,
|
||||
'message_process (%s): a new mail.test.container %s have been created' %
|
||||
(subject, 'should' if container_created else "should not")
|
||||
)
|
||||
|
||||
# --------------------------------------------------
|
||||
# Email Management
|
||||
# --------------------------------------------------
|
||||
|
||||
@@ -2,6 +2,7 @@ flectra.define('wysiwyg.widgets.media', function (require) {
|
||||
'use strict';
|
||||
|
||||
var concurrency = require('web.concurrency');
|
||||
const config = require('web.config');
|
||||
var core = require('web.core');
|
||||
var Dialog = require('web.Dialog');
|
||||
var dom = require('web.dom');
|
||||
@@ -872,6 +873,38 @@ var ImageWidget = FileWidget.extend({
|
||||
.addClass("o_we_attachment_selected");
|
||||
});
|
||||
},
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
_getAttachmentsDomain(needle) {
|
||||
const domain = this._super(...arguments);
|
||||
|
||||
// Optimized images (meaning they are related to an `original_id`) can
|
||||
// only be shown in debug mode as the toggler to make those images
|
||||
// appear is hidden when not in debug mode.
|
||||
// There is thus no point to fetch those optimized images outside debug
|
||||
// mode. Worst, it leads to bugs: it might fetch only optimized images
|
||||
// when clicking on "load more" which will look like it's bugged as no
|
||||
// images will appear on screen (they all will be hidden).
|
||||
if (!config.isDebug()) {
|
||||
const subDomain = [false];
|
||||
|
||||
// Particular exception: if the edited image is an optimized
|
||||
// image, we need to fetch it too so it's displayed as the
|
||||
// selected image when opening the media dialog.
|
||||
// We might get a few more optimized image than necessary if the
|
||||
// original image has multiple optimized images but it's not a
|
||||
// big deal.
|
||||
const originalId = this.$media.length && this.$media[0].dataset.originalId;
|
||||
if (originalId) {
|
||||
subDomain.push(originalId);
|
||||
}
|
||||
|
||||
domain.push(['original_id', 'in', subDomain]);
|
||||
}
|
||||
|
||||
return domain;
|
||||
},
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Handlers
|
||||
|
||||
@@ -65,7 +65,16 @@ flectra.define('website_form.s_website_form', function (require) {
|
||||
// Because, using t-att- inside form make it non-editable
|
||||
var $values = $('[data-for=' + this.$target.attr('id') + ']');
|
||||
if ($values.length) {
|
||||
var values = JSON.parse($values.data('values').replace('False', '""').replace('None', '""').replace(/'/g, '"'));
|
||||
const values = JSON.parse($values.data('values')
|
||||
// replaces `True` by `true` if they are after `,` or `:` or `[`
|
||||
.replace(/([,:\[]\s*)True/g, '$1true')
|
||||
// replaces `False` and `None` by `""` if they are after `,` or `:` or `[`
|
||||
.replace(/([,:\[]\s*)(False|None)/g, '$1""')
|
||||
// replaces the `'` by `"` if they are before `,` or `:` or `]` or `}`
|
||||
.replace(/'(\s*[,:\]}])/g, '"$1')
|
||||
// replaces the `'` by `"` if they are after `{` or `[` or `,` or `:`
|
||||
.replace(/([{\[:,]\s*)'/g, '$1"')
|
||||
);
|
||||
var fields = _.pluck(this.$target.serializeArray(), 'name');
|
||||
_.each(fields, function (field) {
|
||||
if (_.has(values, field)) {
|
||||
|
||||
@@ -35,7 +35,5 @@ class ResCountry(models.Model):
|
||||
states = res
|
||||
break
|
||||
states |= carrier.state_ids
|
||||
if not states:
|
||||
states = states.search([('country_id', '=', self.id)])
|
||||
res = res & states
|
||||
return res
|
||||
|
||||
@@ -2,3 +2,4 @@
|
||||
# Part of Odoo, Flectra. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from . import test_ui
|
||||
from . import test_delivery
|
||||
|
||||
27
addons/website_sale_delivery/tests/test_delivery.py
Normal file
27
addons/website_sale_delivery/tests/test_delivery.py
Normal file
@@ -0,0 +1,27 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from flectra.addons.website_sale.controllers.main import WebsiteSale
|
||||
from flectra.tests import tagged, HttpCase
|
||||
|
||||
@tagged('post_install', '-at_install')
|
||||
class TestDelivery(HttpCase):
|
||||
def test_address_states(self):
|
||||
US = self.env.ref('base.us')
|
||||
MX = self.env.ref('base.mx')
|
||||
|
||||
# Set all carriers to mexico
|
||||
self.env['delivery.carrier'].sudo().search([('website_published', '=', True)]).country_ids = [(6, 0, [MX.id])]
|
||||
|
||||
# Create a new carrier to only one state in mexico
|
||||
self.env['delivery.carrier'].create({
|
||||
'name': "One_state",
|
||||
'product_id': self.env['product.product'].create({'name': "delivery product"}).id,
|
||||
'website_published': True,
|
||||
'country_ids': [(6, 0, [MX.id])],
|
||||
'state_ids': [(6, 0, [MX.state_ids.ids[0]])]
|
||||
})
|
||||
|
||||
country_info = WebsiteSale().country_infos(country=MX, mode="shipping")
|
||||
self.assertEqual(len(country_info['states']), len(MX.state_ids))
|
||||
|
||||
country_info = WebsiteSale().country_infos(country=US, mode="shipping")
|
||||
self.assertEqual(len(country_info['states']), 0)
|
||||
@@ -1125,6 +1125,8 @@ class WebsiteSlides(WebsiteProfile):
|
||||
# try accessing slide, and display to corresponding template
|
||||
try:
|
||||
slide = request.env['slide.slide'].browse(slide_id)
|
||||
if not slide.active:
|
||||
raise werkzeug.exceptions.NotFound()
|
||||
if is_embedded:
|
||||
request.env['slide.embed'].sudo()._add_embed_url(slide.id, referrer_url)
|
||||
values = self._get_slide_detail(slide)
|
||||
|
||||
Reference in New Issue
Block a user