mirror of
https://gitlab.com/flectra-hq/flectra.git
synced 2026-10-25 07:27:39 -05:00
[PATCH] Upstream patch - 06102022
This commit is contained in:
1 parent
ea43861c99
commit
508ace56d6
15 files changed
+255
-57
No files matched your search
@@ -25,48 +25,27 @@ class BarcodeNomenclature(models.Model):
|
||||
|
||||
# returns the checksum of the ean13, or -1 if the ean has not the correct length, ean must be a string
|
||||
def ean_checksum(self, ean):
|
||||
code = list(ean)
|
||||
if len(code) != 13:
|
||||
if len(ean) != 13:
|
||||
return -1
|
||||
|
||||
oddsum = evensum = total = 0
|
||||
code = code[:-1] # Remove checksum
|
||||
for i in range(len(code)):
|
||||
if i % 2 == 0:
|
||||
evensum += int(code[i])
|
||||
else:
|
||||
oddsum += int(code[i])
|
||||
total = oddsum * 3 + evensum
|
||||
return int((10 - total % 10) % 10)
|
||||
return self.env['ir.actions.report'].get_barcode_check_digit(ean)
|
||||
|
||||
# returns the checksum of the ean8, or -1 if the ean has not the correct length, ean must be a string
|
||||
def ean8_checksum(self,ean):
|
||||
code = list(ean)
|
||||
if len(code) != 8:
|
||||
if len(ean) != 8:
|
||||
return -1
|
||||
|
||||
sum1 = int(ean[1]) + int(ean[3]) + int(ean[5])
|
||||
sum2 = int(ean[0]) + int(ean[2]) + int(ean[4]) + int(ean[6])
|
||||
total = sum1 + 3 * sum2
|
||||
return int((10 - total % 10) % 10)
|
||||
return self.env['ir.actions.report'].get_barcode_check_digit(ean)
|
||||
|
||||
# returns true if the barcode is a valid EAN barcode
|
||||
def check_ean(self, ean):
|
||||
return re.match("^\d+$", ean) and self.ean_checksum(ean) == int(ean[-1])
|
||||
if len(ean) == 13:
|
||||
return self.env['ir.actions.report'].check_barcode_encoding(ean, 'ean13')
|
||||
elif len(ean) == 8:
|
||||
return self.env['ir.actions.report'].check_barcode_encoding(ean, 'ean8')
|
||||
return False
|
||||
|
||||
# returns true if the barcode string is encoded with the provided encoding.
|
||||
def check_encoding(self, barcode, encoding):
|
||||
if encoding == 'ean13':
|
||||
return len(barcode) == 13 and re.match("^\d+$", barcode) and self.ean_checksum(barcode) == int(barcode[-1])
|
||||
elif encoding == 'ean8':
|
||||
return len(barcode) == 8 and re.match("^\d+$", barcode) and self.ean8_checksum(barcode) == int(barcode[-1])
|
||||
elif encoding == 'upca':
|
||||
return len(barcode) == 12 and re.match("^\d+$", barcode) and self.ean_checksum("0"+barcode) == int(barcode[-1])
|
||||
elif encoding == 'any':
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
return self.env['ir.actions.report'].check_barcode_encoding(barcode, encoding)
|
||||
|
||||
# Returns a valid zero padded ean13 from an ean prefix. the ean prefix must be a string.
|
||||
def sanitize_ean(self, ean):
|
||||
|
||||
@@ -99,15 +99,15 @@ l10n_ar.base_productos_terminados,l10n_ar.l10nar_base_chart_template,1.1.6.01.03
|
||||
l10n_ar.base_mercaderia_reventa,l10n_ar.l10nar_base_chart_template,1.1.6.01.040,account.data_account_type_current_assets,Mercaderia de reventa,False
|
||||
l10n_ar.base_anticipo_proveedores,l10n_ar.l10nar_base_chart_template,1.1.6.01.050,account.data_account_type_current_assets,Anticipo a Proveedores,False
|
||||
l10n_ar.base_instalaciones,l10n_ar.l10nar_base_chart_template,1.2.1.01.010,account.data_account_type_fixed_assets,Instalaciones,False
|
||||
l10n_ar.base_amortizacion_acumulada_instalaciones,l10n_ar.l10nar_base_chart_template,1.2.1.01.020,account.data_account_type_depreciation,Amortización acumulada instalaciones,False
|
||||
l10n_ar.base_amortizacion_acumulada_instalaciones,l10n_ar.l10nar_base_chart_template,1.2.1.01.020,account.data_account_type_fixed_assets,Amortización acumulada instalaciones,False
|
||||
l10n_ar.base_maq_y_equipos,l10n_ar.l10nar_base_chart_template,1.2.1.02.010,account.data_account_type_fixed_assets,Maquinarias y equipos,False
|
||||
l10n_ar.base_amortizacion_acumulada_maq_y_equipos,l10n_ar.l10nar_base_chart_template,1.2.1.02.020,account.data_account_type_depreciation,Amortización acumulada maquinarias y equipos,False
|
||||
l10n_ar.base_amortizacion_acumulada_maq_y_equipos,l10n_ar.l10nar_base_chart_template,1.2.1.02.020,account.data_account_type_fixed_assets,Amortización acumulada maquinarias y equipos,False
|
||||
l10n_ar.base_muebles_y_utiles,l10n_ar.l10nar_base_chart_template,1.2.1.03.010,account.data_account_type_fixed_assets,Muebles y útiles,False
|
||||
l10n_ar.base_amortizacion_acumulada_muebles_utiles,l10n_ar.l10nar_base_chart_template,1.2.1.03.020,account.data_account_type_depreciation,Amortización acumulada muebles y útiles,False
|
||||
l10n_ar.base_amortizacion_acumulada_muebles_utiles,l10n_ar.l10nar_base_chart_template,1.2.1.03.020,account.data_account_type_fixed_assets,Amortización acumulada muebles y útiles,False
|
||||
l10n_ar.base_rodados,l10n_ar.l10nar_base_chart_template,1.2.1.04.010,account.data_account_type_fixed_assets,Rodados,False
|
||||
l10n_ar.base_amortizacion_acumulada_rodados,l10n_ar.l10nar_base_chart_template,1.2.1.04.020,account.data_account_type_depreciation,Amortización acumulada rodados,False
|
||||
l10n_ar.base_amortizacion_acumulada_rodados,l10n_ar.l10nar_base_chart_template,1.2.1.04.020,account.data_account_type_fixed_assets,Amortización acumulada rodados,False
|
||||
l10n_ar.base_derechos_de_marca,l10n_ar.l10nar_base_chart_template,1.2.2.01.010,account.data_account_type_fixed_assets,Derechos de marca,False
|
||||
l10n_ar.base_amortizacion_acumulada_derechos_de_marca,l10n_ar.l10nar_base_chart_template,1.2.2.01.020,account.data_account_type_depreciation,Amortización acumulada Derechos de marca,False
|
||||
l10n_ar.base_amortizacion_acumulada_derechos_de_marca,l10n_ar.l10nar_base_chart_template,1.2.2.01.020,account.data_account_type_fixed_assets,Amortización acumulada Derechos de marca,False
|
||||
l10n_ar.base_proveedores,l10n_ar.l10nar_base_chart_template,2.1.1.01.010,account.data_account_type_payable,Proveedores,True
|
||||
l10n_ar.base_cheques_diferidos,l10n_ar.l10nar_base_chart_template,2.1.1.01.020,account.data_account_type_current_liabilities,Cheques diferidos a pagar,True
|
||||
l10n_ar.base_cheques_rechazados,l10n_ar.l10nar_base_chart_template,2.1.1.01.030,account.data_account_type_current_liabilities,Cheques Rechazados,False
|
||||
@@ -288,4 +288,9 @@ l10n_ar.base_intereses_por_venta_de_valores,l10n_ar.l10nar_base_chart_template,5
|
||||
l10n_ar.base_intereses_fiscales,l10n_ar.l10nar_base_chart_template,5.6.1.01.050,account.data_account_type_expenses,Intereses fiscales,False
|
||||
l10n_ar.base_gastos_bancarios,l10n_ar.l10nar_base_chart_template,5.6.1.01.060,account.data_account_type_expenses,Gastos Bancarios,False
|
||||
l10n_ar.base_r_e_c_p_a_m,l10n_ar.l10nar_base_chart_template,5.6.1.01.070,account.data_account_type_expenses,R.E.C.P.A.M.,False
|
||||
l10n_ar.base_amortizacion_instalaciones,l10n_ar.l10nar_base_chart_template,5.7.1.01.010,account.data_account_type_depreciation,Amortización instalaciones,False
|
||||
l10n_ar.base_amortizacion_maq_y_equipos,l10n_ar.l10nar_base_chart_template,5.7.1.01.020,account.data_account_type_depreciation,Amortización maquinarias y equipos,False
|
||||
l10n_ar.base_amortizacion_muebles_utiles,l10n_ar.l10nar_base_chart_template,5.7.1.01.030,account.data_account_type_depreciation,Amortización muebles y útiles,False
|
||||
l10n_ar.base_amortizacion_rodados,l10n_ar.l10nar_base_chart_template,5.7.1.01.040,account.data_account_type_depreciation,Amortización rodados,False
|
||||
l10n_ar.base_amortizacion_derechos_de_marca,l10n_ar.l10nar_base_chart_template,5.7.1.01.050,account.data_account_type_depreciation,Amortización Derechos de marca,False
|
||||
l10n_ar.base_contrapartida_auxiliar,l10n_ar.l10nar_base_chart_template,6.0.0.00.010,account.data_account_type_current_assets,Contrapartida Auxiliar,False
|
||||
|
@@ -3574,7 +3574,7 @@
|
||||
<record id="fptt_ispn_p_iva4_bi" model="account.fiscal.position.tax.template">
|
||||
<field name="position_id" ref="fp_ispn"/>
|
||||
<field name="tax_src_id" ref="account_tax_template_p_iva4_bi"/>
|
||||
<field name="tax_dest_id" ref="account_tax_template_p_iva4_isp"/>
|
||||
<field name="tax_dest_id" ref="account_tax_template_p_iva4_isp_bi"/>
|
||||
</record>
|
||||
<record id="fptt_ispn_p_iva10_bc" model="account.fiscal.position.tax.template">
|
||||
<field name="position_id" ref="fp_ispn"/>
|
||||
@@ -3589,7 +3589,7 @@
|
||||
<record id="fptt_ispn_p_iva10_bi" model="account.fiscal.position.tax.template">
|
||||
<field name="position_id" ref="fp_ispn"/>
|
||||
<field name="tax_src_id" ref="account_tax_template_p_iva10_bi"/>
|
||||
<field name="tax_dest_id" ref="account_tax_template_p_iva10_isp"/>
|
||||
<field name="tax_dest_id" ref="account_tax_template_p_iva10_isp_bi"/>
|
||||
</record>
|
||||
<record id="fptt_ispn_p_iva21_bc" model="account.fiscal.position.tax.template">
|
||||
<field name="position_id" ref="fp_ispn"/>
|
||||
@@ -3604,7 +3604,7 @@
|
||||
<record id="fptt_ispn_p_iva21_bi" model="account.fiscal.position.tax.template">
|
||||
<field name="position_id" ref="fp_ispn"/>
|
||||
<field name="tax_src_id" ref="account_tax_template_p_iva21_bi"/>
|
||||
<field name="tax_dest_id" ref="account_tax_template_p_iva21_isp"/>
|
||||
<field name="tax_dest_id" ref="account_tax_template_p_iva21_isp_bi"/>
|
||||
</record>
|
||||
<record id="fptt_ispn_s_iva4b" model="account.fiscal.position.tax.template">
|
||||
<field name="position_id" ref="fp_ispn"/>
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
© 2015 Vicent Cubells
|
||||
© 2013-2020 Pedro M. Baeza
|
||||
© 2020 Harald Panten - Sygel Technology
|
||||
© 2022 Omar Castiñeira - Comunitea
|
||||
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). -->
|
||||
<flectra>
|
||||
|
||||
@@ -3943,6 +3944,156 @@
|
||||
}),
|
||||
]"/>
|
||||
</record>
|
||||
<record id="account_tax_template_p_iva4_isp_bi" model="account.tax.template">
|
||||
<field name="name">IVA 4% ISP (bienes de inversión)</field>
|
||||
<field name="type_tax_use">purchase</field>
|
||||
<field name="amount_type">percent</field>
|
||||
<field name="amount" eval="4"/>
|
||||
<field name="chart_template_id" ref="l10n_es.account_chart_template_common"/>
|
||||
<field name="tax_group_id" ref="tax_group_iva_4"/>
|
||||
<field name="invoice_repartition_line_ids" eval="[(5, 0, 0),
|
||||
(0,0, {
|
||||
'factor_percent': 100,
|
||||
'repartition_type': 'base',
|
||||
'tag_ids': [ref('mod_303_30'), ref('mod_303_12')],
|
||||
}),
|
||||
|
||||
(0,0, {
|
||||
'factor_percent': 100,
|
||||
'repartition_type': 'tax',
|
||||
'account_id': ref('l10n_es.account_common_472'),
|
||||
'tag_ids': [ref('mod_303_31')],
|
||||
}),
|
||||
|
||||
(0,0, {
|
||||
'factor_percent': -100,
|
||||
'repartition_type': 'tax',
|
||||
'account_id': ref('l10n_es.account_common_477'),
|
||||
'tag_ids': [ref('mod_303_13')],
|
||||
}),
|
||||
]"/>
|
||||
<field name="refund_repartition_line_ids" eval="[(5, 0, 0),
|
||||
(0,0, {
|
||||
'factor_percent': 100,
|
||||
'repartition_type': 'base',
|
||||
'tag_ids': [ref('mod_303_40'), ref('mod_303_14_purchase')],
|
||||
}),
|
||||
|
||||
(0,0, {
|
||||
'factor_percent': 100,
|
||||
'repartition_type': 'tax',
|
||||
'account_id': ref('l10n_es.account_common_472'),
|
||||
'tag_ids': [ref('mod_303_41')],
|
||||
}),
|
||||
|
||||
(0,0, {
|
||||
'factor_percent': -100,
|
||||
'repartition_type': 'tax',
|
||||
'account_id': ref('l10n_es.account_common_477'),
|
||||
'tag_ids': [ref('mod_303_15')],
|
||||
}),
|
||||
]"/>
|
||||
</record>
|
||||
<record id="account_tax_template_p_iva10_isp_bi" model="account.tax.template">
|
||||
<field name="name">IVA 10% ISP (bienes de inversión)</field>
|
||||
<field name="type_tax_use">purchase</field>
|
||||
<field name="amount_type">percent</field>
|
||||
<field name="amount" eval="10"/>
|
||||
<field name="chart_template_id" ref="l10n_es.account_chart_template_common"/>
|
||||
<field name="tax_group_id" ref="tax_group_iva_10"/>
|
||||
<field name="invoice_repartition_line_ids" eval="[(5, 0, 0),
|
||||
(0,0, {
|
||||
'factor_percent': 100,
|
||||
'repartition_type': 'base',
|
||||
'tag_ids': [ref('mod_303_30'), ref('mod_303_12')],
|
||||
}),
|
||||
|
||||
(0,0, {
|
||||
'factor_percent': 100,
|
||||
'repartition_type': 'tax',
|
||||
'account_id': ref('l10n_es.account_common_472'),
|
||||
'tag_ids': [ref('mod_303_31')],
|
||||
}),
|
||||
|
||||
(0,0, {
|
||||
'factor_percent': -100,
|
||||
'repartition_type': 'tax',
|
||||
'account_id': ref('l10n_es.account_common_477'),
|
||||
'tag_ids': [ref('mod_303_13')],
|
||||
}),
|
||||
]"/>
|
||||
<field name="refund_repartition_line_ids" eval="[(5, 0, 0),
|
||||
(0,0, {
|
||||
'factor_percent': 100,
|
||||
'repartition_type': 'base',
|
||||
'tag_ids': [ref('mod_303_40'), ref('mod_303_14_purchase')],
|
||||
}),
|
||||
|
||||
(0,0, {
|
||||
'factor_percent': 100,
|
||||
'repartition_type': 'tax',
|
||||
'account_id': ref('l10n_es.account_common_472'),
|
||||
'tag_ids': [ref('mod_303_41')],
|
||||
}),
|
||||
|
||||
(0,0, {
|
||||
'factor_percent': -100,
|
||||
'repartition_type': 'tax',
|
||||
'account_id': ref('l10n_es.account_common_477'),
|
||||
'tag_ids': [ref('mod_303_15')],
|
||||
}),
|
||||
]"/>
|
||||
</record>
|
||||
<record id="account_tax_template_p_iva21_isp_bi" model="account.tax.template">
|
||||
<field name="name">IVA 21% ISP (bienes de inversión)</field>
|
||||
<field name="type_tax_use">purchase</field>
|
||||
<field name="amount_type">percent</field>
|
||||
<field name="amount" eval="21"/>
|
||||
<field name="chart_template_id" ref="l10n_es.account_chart_template_common"/>
|
||||
<field name="tax_group_id" ref="tax_group_iva_21"/>
|
||||
<field name="invoice_repartition_line_ids" eval="[(5, 0, 0),
|
||||
(0,0, {
|
||||
'factor_percent': 100,
|
||||
'repartition_type': 'base',
|
||||
'tag_ids': [ref('mod_303_30'), ref('mod_303_12')],
|
||||
}),
|
||||
|
||||
(0,0, {
|
||||
'factor_percent': 100,
|
||||
'repartition_type': 'tax',
|
||||
'account_id': ref('l10n_es.account_common_472'),
|
||||
'tag_ids': [ref('mod_303_31')],
|
||||
}),
|
||||
|
||||
(0,0, {
|
||||
'factor_percent': -100,
|
||||
'repartition_type': 'tax',
|
||||
'account_id': ref('l10n_es.account_common_477'),
|
||||
'tag_ids': [ref('mod_303_13')],
|
||||
}),
|
||||
]"/>
|
||||
<field name="refund_repartition_line_ids" eval="[(5, 0, 0),
|
||||
(0,0, {
|
||||
'factor_percent': 100,
|
||||
'repartition_type': 'base',
|
||||
'tag_ids': [ref('mod_303_40'), ref('mod_303_14_purchase')],
|
||||
}),
|
||||
|
||||
(0,0, {
|
||||
'factor_percent': 100,
|
||||
'repartition_type': 'tax',
|
||||
'account_id': ref('l10n_es.account_common_472'),
|
||||
'tag_ids': [ref('mod_303_41')],
|
||||
}),
|
||||
|
||||
(0,0, {
|
||||
'factor_percent': -100,
|
||||
'repartition_type': 'tax',
|
||||
'account_id': ref('l10n_es.account_common_477'),
|
||||
'tag_ids': [ref('mod_303_15')],
|
||||
}),
|
||||
]"/>
|
||||
</record>
|
||||
<record id="account_tax_template_p_rp19" model="account.tax.template">
|
||||
<field name="type_tax_use">purchase</field>
|
||||
<field name="description"/> <!-- for resetting the value on existing DBs -->
|
||||
|
||||
@@ -286,6 +286,7 @@
|
||||
'factor_percent': 100,
|
||||
'repartition_type': 'tax',
|
||||
'account_id': ref('nz_21330'),
|
||||
'plus_report_line_ids': [ref('tax_report_box11')],
|
||||
}),
|
||||
]"/>
|
||||
<field name="refund_repartition_line_ids" eval="[(5, 0, 0),
|
||||
@@ -298,6 +299,7 @@
|
||||
'factor_percent': 100,
|
||||
'repartition_type': 'tax',
|
||||
'account_id': ref('nz_21330'),
|
||||
'minus_report_line_ids': [ref('tax_report_box11')],
|
||||
}),
|
||||
]"/>
|
||||
</record>
|
||||
|
||||
@@ -54,6 +54,12 @@
|
||||
// may impact the bullet point (at least it does on Safari).
|
||||
max-width: 100%;
|
||||
overflow-x: auto;
|
||||
|
||||
// overflow: auto can break rendering of next element of a frequent broken Outlook 365
|
||||
// warning table. If detected, we prevent the issue by removing flotation.
|
||||
&table[align="left"][width="100%"] {
|
||||
float: none;
|
||||
}
|
||||
}
|
||||
|
||||
img {
|
||||
|
||||
@@ -99,7 +99,7 @@ class PosConfig(models.Model):
|
||||
|
||||
def _compute_customer_html(self):
|
||||
for config in self:
|
||||
config.customer_facing_display_html = self.env['ir.qweb']._render('point_of_sale.customer_facing_display_html')
|
||||
config.customer_facing_display_html = self.env['ir.qweb']._render('point_of_sale.customer_facing_display_html', {'company': self.company_id})
|
||||
|
||||
name = fields.Char(string='Point of Sale', index=True, required=True, help="An internal identification of the point of sale.")
|
||||
is_installed_account_accountant = fields.Boolean(string="Is the Full Accounting Installed",
|
||||
|
||||
@@ -42,7 +42,7 @@
|
||||
</div>
|
||||
|
||||
<div class="pos-payment_info">
|
||||
<div class="pos-company_logo"/>
|
||||
<div class="pos-company_logo" t-attf-style="background-image:url(/logo?company=#{company.id})"/>
|
||||
|
||||
<div class="pos-payment_info_details">
|
||||
<div class="pos-total">
|
||||
|
||||
@@ -7,6 +7,7 @@ from unittest.mock import patch
|
||||
|
||||
from flectra import http
|
||||
from flectra.tests import common, tagged
|
||||
from flectra.tools.misc import get_lang
|
||||
from flectra.addons.web.controllers.main import ExportXlsxWriter
|
||||
from flectra.addons.mail.tests.common import mail_new_test_user
|
||||
|
||||
@@ -382,6 +383,23 @@ class TestGroupedExport(XlsxCreatorCase):
|
||||
['3','1000.00'],
|
||||
])
|
||||
|
||||
def test_decimal_separator(self):
|
||||
""" The decimal separator of the language used shouldn't impact the float representation in the exported xlsx """
|
||||
get_lang(self.env).decimal_point = ','
|
||||
get_lang(self.env).thousands_sep = '.'
|
||||
|
||||
values = [
|
||||
{'int_sum': 1, 'float_min': 86420.864},
|
||||
]
|
||||
export = self.export(values, fields=['int_sum', 'float_min'], params={'groupby': ['int_sum', 'float_min']})
|
||||
|
||||
self.assertExportEqual(export, [
|
||||
['Int Sum' ,'Float Min'],
|
||||
['1 (1)' ,'86420.86'],
|
||||
[' 86420.864 (1)','86420.86'],
|
||||
['1' ,'86420.86'],
|
||||
])
|
||||
|
||||
@tagged('-at_install', 'post_install')
|
||||
class TestComputedBinaryExport(XlsxCreatorCase):
|
||||
model_name = 'export.computed.binary'
|
||||
|
||||
@@ -37,7 +37,7 @@ from flectra.modules import get_module_path, get_resource_path
|
||||
from flectra.tools import image_process, topological_sort, html_escape, pycompat, ustr, apply_inheritance_specs, lazy_property
|
||||
from flectra.tools.mimetypes import guess_mimetype
|
||||
from flectra.tools.translate import _
|
||||
from flectra.tools.misc import str2bool, xlsxwriter, file_open, get_lang
|
||||
from flectra.tools.misc import str2bool, xlsxwriter, file_open
|
||||
from flectra.tools.safe_eval import safe_eval, time
|
||||
from flectra import http, tools
|
||||
from flectra.http import content_disposition, dispatch_rpc, request, serialize_exception as _serialize_exception, Response
|
||||
@@ -777,10 +777,9 @@ class ExportXlsxWriter:
|
||||
self.datetime_style = self.workbook.add_format({'text_wrap': True, 'num_format': 'yyyy-mm-dd hh:mm:ss'})
|
||||
self.worksheet = self.workbook.add_worksheet()
|
||||
self.value = False
|
||||
decimal_separator = get_lang(request.env).decimal_point
|
||||
self.float_format = f'0{decimal_separator}00'
|
||||
self.float_format = '#,##0.00'
|
||||
decimal_places = [res['decimal_places'] for res in request.env['res.currency'].search_read([], ['decimal_places'])]
|
||||
self.monetary_format = f'0{decimal_separator}{max(decimal_places or [2]) * "0"}'
|
||||
self.monetary_format = f'#,##0.{max(decimal_places or [2]) * "0"}'
|
||||
|
||||
if row_count > self.worksheet.xls_rowmax:
|
||||
raise UserError(_('There are too many rows (%s rows, limit: %s) to export as Excel 2007-2013 (.xlsx) format. Consider splitting the export.') % (row_count, self.worksheet.xls_rowmax))
|
||||
|
||||
@@ -2157,8 +2157,6 @@ var FieldMany2ManyBinaryMultiFiles = AbstractField.extend({
|
||||
fieldsToFetch: {
|
||||
name: {type: 'char'},
|
||||
mimetype: {type: 'char'},
|
||||
res_id: {type: 'number'},
|
||||
access_token: {type: 'char'},
|
||||
},
|
||||
events: {
|
||||
'click .o_attach': '_onAttach',
|
||||
|
||||
@@ -1548,7 +1548,7 @@
|
||||
<t t-name="FieldBinaryFileUploader.attachment_preview">
|
||||
<t t-set="url" t-value="widget.metadata[file.id] ? widget.metadata[file.id].url : false"/>
|
||||
<t t-if="file.data" t-set="file" t-value="file.data"/>
|
||||
<t t-set="editable" t-value="widget.mode === 'edit' and !(file.res_id === 0 and file.access_token)"/>
|
||||
<t t-set="editable" t-value="widget.mode === 'edit'"/>
|
||||
<t t-if="file.mimetype" t-set="mimetype" t-value="file.mimetype"/>
|
||||
<div t-attf-class="o_attachment o_attachment_many2many #{ editable ? 'o_attachment_editable' : '' } #{upload ? 'o_attachment_uploading' : ''}" t-att-title="file.name">
|
||||
<div class="o_attachment_wrap">
|
||||
|
||||
@@ -2536,14 +2536,11 @@ QUnit.module('relational_fields', {
|
||||
fields: {
|
||||
name: {string:"Name", type: "char"},
|
||||
mimetype: {string: "Mimetype", type: "char"},
|
||||
res_id: {type: "number"},
|
||||
access_token: {type: "char"},
|
||||
},
|
||||
records: [{
|
||||
id: 17,
|
||||
name: 'Marley&Me.jpg',
|
||||
mimetype: 'jpg',
|
||||
res_id: 1,
|
||||
}],
|
||||
};
|
||||
this.data.turtle.fields.picture_ids = {
|
||||
@@ -2567,7 +2564,7 @@ QUnit.module('relational_fields', {
|
||||
mockRPC: function (route, args) {
|
||||
assert.step(route);
|
||||
if (route === '/web/dataset/call_kw/ir.attachment/read') {
|
||||
assert.deepEqual(args.args[1], ['name', 'mimetype', 'res_id', 'access_token']);
|
||||
assert.deepEqual(args.args[1], ['name', 'mimetype']);
|
||||
}
|
||||
return this._super.apply(this, arguments);
|
||||
},
|
||||
|
||||
@@ -246,7 +246,8 @@ var FieldHtml = basic_fields.DebouncedField.extend(TranslatableFieldMixin, {
|
||||
* @param {Object} event the event containing attachment data
|
||||
*/
|
||||
_onAttachmentChange: function (event) {
|
||||
if (!this.fieldNameAttachment) {
|
||||
// This only needs to happen for the composer for now
|
||||
if (!this.fieldNameAttachment || this.model !== 'mail.compose.message') {
|
||||
return;
|
||||
}
|
||||
this.trigger_up('field_changed', {
|
||||
|
||||
@@ -9,6 +9,7 @@ var core = require('web.core');
|
||||
var Wysiwyg = require('web_editor.wysiwyg');
|
||||
var MediaDialog = require('wysiwyg.widgets.MediaDialog');
|
||||
var FieldHtml = require('web_editor.field.html');
|
||||
var FieldManagerMixin = require('web.FieldManagerMixin');
|
||||
|
||||
var _t = core._t;
|
||||
|
||||
@@ -58,6 +59,29 @@ QUnit.module('web_editor', {}, function () {
|
||||
</div>`,
|
||||
}],
|
||||
},
|
||||
'mail.compose.message': {
|
||||
fields: {
|
||||
display_name: {
|
||||
string: "Displayed name",
|
||||
type: "char"
|
||||
},
|
||||
body: {
|
||||
string: "Message Body inline (to send)",
|
||||
type: "html"
|
||||
},
|
||||
attachment_ids: {
|
||||
string: "Attachments",
|
||||
type: "many2many",
|
||||
relation: "ir.attachment",
|
||||
}
|
||||
},
|
||||
records: [{
|
||||
id: 1,
|
||||
display_name: "Some Composer",
|
||||
body: "Hello",
|
||||
attachment_ids: [],
|
||||
}],
|
||||
},
|
||||
'mass.mailing': {
|
||||
fields: {
|
||||
display_name: {
|
||||
@@ -286,21 +310,33 @@ QUnit.module('web_editor', {}, function () {
|
||||
QUnit.test('media dialog: upload', async function (assert) {
|
||||
/**
|
||||
* Ensures _onAttachmentChange from FieldHTML is called on file upload
|
||||
* as well as _onFieldChanged when that model is a mail composer
|
||||
*/
|
||||
assert.expect(1);
|
||||
assert.expect(2);
|
||||
const onAttachmentChangeTriggered = testUtils.makeTestPromise();
|
||||
testUtils.mock.patch(FieldHtml, {
|
||||
'_onAttachmentChange': function (event) {
|
||||
'_onAttachmentChange': function (ev) {
|
||||
this._super(ev);
|
||||
onAttachmentChangeTriggered.resolve(true);
|
||||
}
|
||||
});
|
||||
|
||||
const onRecordChange = testUtils.makeTestPromise();
|
||||
testUtils.mock.patch(FieldManagerMixin, {
|
||||
'_applyChanges': function (dataPointID, changes, event) {
|
||||
const res = this._super(dataPointID, changes, event);
|
||||
onRecordChange.resolve(true);
|
||||
return res;
|
||||
},
|
||||
})
|
||||
|
||||
const form = await testUtils.createView({
|
||||
View: FormView,
|
||||
model: 'note.note',
|
||||
model: 'mail.compose.message',
|
||||
data: this.data,
|
||||
arch: '<form>' +
|
||||
'<field name="body" widget="html" style="height: 100px"/>' +
|
||||
'<field name="attachment_ids" widget="many2many_binary"/>' +
|
||||
'</form>',
|
||||
res_id: 1,
|
||||
mockRPC: function (route, args) {
|
||||
@@ -361,8 +397,14 @@ QUnit.module('web_editor', {}, function () {
|
||||
assert.ok(await Promise.race([onAttachmentChangeTriggered, new Promise((res, _) => setTimeout(() => res(false), 400))]),
|
||||
"_onAttachmentChange was not called with the new attachment, necessary for unsused upload cleanup on backend");
|
||||
|
||||
await onRecordChange;
|
||||
// wait to check that dom is properly updated
|
||||
await new Promise((res, _) => setTimeout(() => res(false), 400));
|
||||
assert.ok(form.$('.o_attachment[title="test.jpg"]')[0])
|
||||
|
||||
testUtils.mock.unpatch(MediaDialog);
|
||||
testUtils.mock.unpatch(FieldHtml)
|
||||
testUtils.mock.unpatch(FieldHtml);
|
||||
testUtils.mock.unpatch(FieldManagerMixin);
|
||||
form.destroy();
|
||||
|
||||
});
|
||||
|
||||
Reference in new issue
Block a user