[PATCH] Upstream patch - 13072022

This commit is contained in:
Parthiv Patel
2022-07-13 08:34:28 +00:00
parent 001f15af95
commit 932cee07db
12 changed files with 174 additions and 45 deletions

View File

@@ -14,15 +14,29 @@ from flectra.tools.translate import _
from flectra.addons.google_account.models.google_service import GOOGLE_TOKEN_ENDPOINT, TIMEOUT
from datetime import date
_logger = logging.getLogger(__name__)
# Google is depreciating their OOB Auth Flow on 3rd October 2022, the Google Drive
# integration thus become irrelevant after that date.
# https://developers.googleblog.com/2022/02/making-oauth-flows-safer.html#disallowed-oob
GOOGLE_AUTH_DEPRECATION_DATE = date(2022, 10, 3)
class GoogleDrive(models.Model):
_name = 'google.drive.config'
_description = "Google Drive templates config"
def _module_deprecated(self):
return GOOGLE_AUTH_DEPRECATION_DATE > fields.Date.today()
def get_google_drive_url(self, res_id, template_id):
if self._module_deprecated():
return
self.ensure_one()
self = self.sudo()
@@ -49,6 +63,9 @@ class GoogleDrive(models.Model):
@api.model
def get_access_token(self, scope=None):
if self._module_deprecated():
return
Config = self.env['ir.config_parameter'].sudo()
google_drive_refresh_token = Config.get_param('google_drive_refresh_token')
user_is_admin = self.env.is_admin()
@@ -84,6 +101,9 @@ class GoogleDrive(models.Model):
@api.model
def copy_doc(self, res_id, template_id, name_gdocs, res_model):
if self._module_deprecated():
return
google_web_base_url = self.env['ir.config_parameter'].sudo().get_param('web.base.url')
access_token = self.get_access_token()
# Copy template in to drive with help of new access token

View File

@@ -36,6 +36,9 @@ class ResConfigSettings(models.TransientModel):
def action_setup_token(self):
self.ensure_one()
if self.env['google.drive.config']._module_deprecated():
return
template = self.env.ref('google_drive.google_drive_auth_code_wizard')
return {
'name': _('Set up refresh token'),

View File

@@ -9,6 +9,10 @@
<div id="msg_module_google_drive" position="replace">
<div class="content-group"
attrs="{'invisible': [('module_google_drive','=',False)]}">
<div class="mt8 mb8 text-warning font-weight-bold">
This module will stop working after the 3rd October 2022 due to
<a href="https://developers.googleblog.com/2022/02/making-oauth-flows-safer.html#disallowed-oob">changes in Google Authentication API</a>.
</div>
<div class="mt8 row">
<div class="col-sm">
<field name="is_google_drive_token_generated" invisible="1"/>

View File

@@ -161,7 +161,7 @@ class AccountMove(models.Model):
# To solve this there is a <Arrotondamento> or 'rounding' field, such that:
# taxable base = sum(taxable base for each unit) + Arrotondamento
tax_details = self._prepare_edi_tax_details(
filter_to_apply=lambda l: l['tax_repartition_line_id'].factor_percent > 0
filter_to_apply=lambda l: l['tax_repartition_line_id'].factor_percent >= 0
)
for _tax_name, tax_dict in tax_details['tax_details'].items():
base_amount = tax_dict['base_amount_currency']

View File

@@ -5,7 +5,7 @@
<IdPaese>IT</IdPaese>
<IdCodice>01234560157</IdCodice>
</IdTrasmittente>
<ProgressivoInvio>2022030008</ProgressivoInvio>
<ProgressivoInvio>___ignore___</ProgressivoInvio>
<FormatoTrasmissione>FPR12</FormatoTrasmissione>
<CodiceDestinatario>XXXXXXX</CodiceDestinatario>
<ContattiTrasmittente>
@@ -54,7 +54,7 @@
<TipoDocumento>TD01</TipoDocumento>
<Divisa>EUR</Divisa>
<Data>2022-03-24</Data>
<Numero>INV/2022/03/0008</Numero>
<Numero>___ignore___</Numero>
<ImportoTotaleDocumento>1600.80</ImportoTotaleDocumento>
</DatiGeneraliDocumento>
</DatiGenerali>
@@ -92,7 +92,7 @@
<ModalitaPagamento>MP05</ModalitaPagamento>
<DataScadenzaPagamento>2022-03-24</DataScadenzaPagamento>
<ImportoPagamento>1600.80</ImportoPagamento>
<CodicePagamento>INV/2022/03/0008</CodicePagamento>
<CodicePagamento>___ignore___</CodicePagamento>
</DettaglioPagamento>
</DatiPagamento>
<Allegati></Allegati>

View File

@@ -171,7 +171,7 @@ class TestItEdiReverseCharge(TestItEdi):
def _test_invoice_with_sample_file(self, invoice, filename, xpaths_file=None, xpaths_result=None):
result = self._cleanup_etree(invoice._export_as_xml(), xpaths_result)
expected = self._cleanup_etree(self._get_test_file_content(filename), xpaths_file)
self.assertXmlTreeEqual(expected, result)
self.assertXmlTreeEqual(result, expected)
def test_reverse_charge_invoice(self):
self._test_invoice_with_sample_file(self.reverse_charge_invoice, "reverse_charge_invoice.xml")

View File

@@ -47,6 +47,36 @@ class TestItEdi(AccountEdiTestCommon):
'company_id': cls.company.id,
})
cls.tax_zero_percent_hundred_percent_repartition = cls.env['account.tax'].create({
'name': 'all of nothing',
'amount': 0,
'amount_type': 'percent',
'company_id': cls.company.id,
'invoice_repartition_line_ids': [
(0, 0, {'factor_percent': 100, 'repartition_type': 'base'}),
(0, 0, {'factor_percent': 100, 'repartition_type': 'tax'}),
],
'refund_repartition_line_ids': [
(0, 0, {'factor_percent': 100, 'repartition_type': 'base'}),
(0, 0, {'factor_percent': 100, 'repartition_type': 'tax'}),
],
})
cls.tax_zero_percent_zero_percent_repartition = cls.env['account.tax'].create({
'name': 'none of nothing',
'amount': 0,
'amount_type': 'percent',
'company_id': cls.company.id,
'invoice_repartition_line_ids': [
(0, 0, {'factor_percent': 100, 'repartition_type': 'base'}),
(0, 0, {'factor_percent': 0, 'repartition_type': 'tax'}),
],
'refund_repartition_line_ids': [
(0, 0, {'factor_percent': 100, 'repartition_type': 'base'}),
(0, 0, {'factor_percent': 0, 'repartition_type': 'tax'}),
],
})
cls.italian_partner_a = cls.env['res.partner'].create({
'name': 'Alessi',
'vat': 'IT00465840031',
@@ -261,6 +291,24 @@ class TestItEdi(AccountEdiTestCommon):
'private_key': 'l10n_it_edi_sdicoop_test',
})
cls.zero_tax_invoice = cls.env['account.move'].with_company(cls.company).create({
'move_type': 'out_invoice',
'invoice_date': datetime.date(2022, 3, 24),
'partner_id': cls.italian_partner_a.id,
'invoice_line_ids': [
(0, 0, {
**cls.standard_line,
'name': 'line with tax of 0% with repartition line of 100% ',
'tax_ids': [(6, 0, [cls.tax_zero_percent_hundred_percent_repartition.id])],
}),
(0, 0, {
**cls.standard_line,
'name': 'line with tax of 0% with repartition line of 0% ',
'tax_ids': [(6, 0, [cls.tax_zero_percent_zero_percent_repartition.id])],
}),
],
})
# post the invoices
cls.price_included_invoice._post()
cls.partial_discount_invoice._post()
@@ -269,6 +317,7 @@ class TestItEdi(AccountEdiTestCommon):
cls.below_400_codice_simplified_invoice._post()
cls.total_400_VAT_simplified_invoice._post()
cls.pa_partner_invoice._post()
cls.zero_tax_invoice._post()
cls.edi_basis_xml = cls._get_test_file_content('IT00470550013_basis.xml')
cls.edi_simplified_basis_xml = cls._get_test_file_content('IT00470550013_simpl.xml')
@@ -571,3 +620,51 @@ class TestItEdi(AccountEdiTestCommon):
def test_send_pa_partner(self):
res = self.edi_format._l10n_it_post_invoices_step_1(self.pa_partner_invoice)
self.assertEqual(res[self.pa_partner_invoice], {'attachment': self.pa_partner_invoice.l10n_it_edi_attachment_id, 'success': True})
def test_zero_percent_taxes(self):
invoice_etree = etree.fromstring(self.zero_tax_invoice._export_as_xml())
expected_etree = self.with_applied_xpath(
etree.fromstring(self.edi_basis_xml),
'''
<xpath expr="//FatturaElettronicaBody//DatiBeniServizi" position="replace">
<DatiBeniServizi>
<DettaglioLinee>
<NumeroLinea>1</NumeroLinea>
<Descrizione>line with tax of 0% with repartition line of 100%</Descrizione>
<Quantita>1.00</Quantita>
<PrezzoUnitario>800.400000</PrezzoUnitario>
<PrezzoTotale>800.40</PrezzoTotale>
<AliquotaIVA>0.00</AliquotaIVA>
</DettaglioLinee>
<DettaglioLinee>
<NumeroLinea>2</NumeroLinea>
<Descrizione>line with tax of 0% with repartition line of 0%</Descrizione>
<Quantita>1.00</Quantita>
<PrezzoUnitario>800.400000</PrezzoUnitario>
<PrezzoTotale>800.40</PrezzoTotale>
<AliquotaIVA>0.00</AliquotaIVA>
</DettaglioLinee>
<DatiRiepilogo>
<AliquotaIVA>0.00</AliquotaIVA>
<ImponibileImporto>800.40</ImponibileImporto>
<Imposta>0.00</Imposta>
<EsigibilitaIVA>I</EsigibilitaIVA>
</DatiRiepilogo>
<DatiRiepilogo>
<AliquotaIVA>0.00</AliquotaIVA>
<ImponibileImporto>800.40</ImponibileImporto>
<Imposta>0.00</Imposta>
<EsigibilitaIVA>I</EsigibilitaIVA>
</DatiRiepilogo>
</DatiBeniServizi>
</xpath>
<xpath expr="//DettaglioPagamento//ImportoPagamento" position="inside">
1600.80
</xpath>
<xpath expr="//DatiGeneraliDocumento//ImportoTotaleDocumento" position="inside">
1600.80
</xpath>
'''
)
invoice_etree = self.with_applied_xpath(invoice_etree, "<xpath expr='.//Allegati' position='replace'/>")
self.assertXmlTreeEqual(invoice_etree, expected_etree)

View File

@@ -13,7 +13,7 @@ echo "addons/point_of_sale/tools/posbox/overwrite_after_init/home/pi/odoo" >> .g
git fetch "${localremote}" "${localbranch}" --depth=1
git reset "${localremote}"/"${localbranch}" --hard
git clean -df
git clean -dfx
cp -a /home/pi/odoo/addons/point_of_sale/tools/posbox/overwrite_after_init/home/pi/odoo/* /home/pi/odoo/
rm -r /home/pi/odoo/addons/point_of_sale/tools/posbox/overwrite_after_init

View File

@@ -315,21 +315,10 @@ publicWidget.registry.WebsiteSale = publicWidget.Widget.extend(VariantMixin, {
if (!data.cart_quantity) {
return window.location = '/shop/cart';
}
wSaleUtils.updateCartNavBar(data);
$input.val(data.quantity);
$('.js_quantity[data-line-id='+line_id+']').val(data.quantity).html(data.quantity);
if (data.warning) {
var cart_alert = $('.oe_cart').parent().find('#data_warning');
if (cart_alert.length === 0) {
$('.oe_cart').prepend('<div class="alert alert-danger alert-dismissable" role="alert" id="data_warning">'+
'<button type="button" class="close" data-dismiss="alert" aria-hidden="true">&times;</button> ' + data.warning + '</div>');
}
else {
cart_alert.html('<button type="button" class="close" data-dismiss="alert" aria-hidden="true">&times;</button> ' + data.warning);
}
$input.val(data.quantity);
}
wSaleUtils.updateCartNavBar(data);
wSaleUtils.showWarning(data.warning);
});
},
/**

View File

@@ -45,18 +45,43 @@ function animateClone($cart, $elem, offsetTop, offsetLeft) {
* @param {Object} data
*/
function updateCartNavBar(data) {
var $qtyNavBar = $(".my_cart_quantity");
_.each($qtyNavBar, function (qty) {
var $qty = $(qty);
$qty.parents('li:first').removeClass('d-none');
$qty.html(data.cart_quantity).hide().fadeIn(600);
});
$(".my_cart_quantity")
.parents('li.o_wsale_my_cart').removeClass('d-none').end()
.toggleClass('fa fa-warning', !data.cart_quantity)
.attr('title', data.warning)
.text(data.cart_quantity || '')
.hide()
.fadeIn(600);
$(".js_cart_lines").first().before(data['website_sale.cart_lines']).end().remove();
$(".js_cart_summary").first().before(data['website_sale.short_cart_summary']).end().remove();
}
/**
* Displays `message` in an alert box at the top of the page if it's a
* non-empty string.
*
* @param {string | null} message
*/
function showWarning(message) {
if (!message) {
return;
}
var $page = $('.oe_website_sale');
var cart_alert = $page.children('#data_warning');
if (!cart_alert.length) {
cart_alert = $(
'<div class="alert alert-danger alert-dismissible" role="alert" id="data_warning">' +
'<button type="button" class="close" data-dismiss="alert">&times;</button> ' +
'<span></span>' +
'</div>').prependTo($page);
}
cart_alert.children('span:last-child').text(message);
}
return {
animateClone: animateClone,
updateCartNavBar: updateCartNavBar,
showWarning: showWarning,
};
});

View File

@@ -177,15 +177,9 @@ publicWidget.registry.ProductWishlist = publicWidget.Widget.extend(VariantMixin,
add_qty: parseInt(qty_id, 10),
display: false,
},
}).then(function (resp) {
if (resp.warning) {
if (! $('#data_warning').length) {
$('.wishlist-section').prepend('<div class="mt16 alert alert-danger alert-dismissable" role="alert" id="data_warning"></div>');
}
var cart_alert = $('.wishlist-section').parent().find('#data_warning');
cart_alert.html('<button type="button" class="close" data-dismiss="alert" aria-hidden="true">&times;</button> ' + resp.warning);
}
$('.my_cart_quantity').html(resp.cart_quantity || '<i class="fa fa-warning" /> ');
}).then(function (data) {
wSaleUtils.updateCartNavBar(data);
wSaleUtils.showWarning(data.warning);
});
},
/**

View File

@@ -30,21 +30,18 @@
<blockquote class="small">
<h2>How to configure the Twitter API access</h2>
<ol>
<li>Create a new Twitter application on <a href="https://apps.twitter.com/app/new" target="new">https://apps.twitter.com/app/new</a>
with the following values:
<li>Log in or create an account on <a href="https://developer.twitter.com/" target="new"> https://developer.twitter.com/</a></li>
<li>Once connected, and if not already done, complete the Twitter portal access process on <a href="https://developer.twitter.com/portal/" target="new">https://developer.twitter.com/portal/</a></li>
<li>On the <a href="https://developer.twitter.com/portal/" target="new">Twitter Portal</a>, <strong>create a project</strong> with the following information:
<ul>
<li><strong>Name: </strong> Flectra Twitter Integration</li>
<li><strong>Description: </strong> Flectra Twitter Integration </li>
<li><strong>Website: </strong>
<b><field name="twitter_server_uri" /></b></li>
<li><strong>Callback URL: </strong>Leave blank</li>
<li>Accept terms of use and click on the Create your Twitter application button at the bottom</li>
<li><strong>Use Case: </strong> Embedding Tweets in a website</li>
<li><strong>Description: </strong> Flectra Twitter Integration</li>
<li><strong>App Name: </strong> choose a unique name</li>
</ul>
</li>
<li>Switch to the API Keys tab: <br/>
<img src='/website_twitter/static/src/img/api_key.png' alt="API Key"/>
</li><br/>
<li>Copy/Paste Consumer Key (API Key) and Consumer Secret (API Secret) keys below.</li>
<li>Copy/Paste the API Key and API Key Secret values into the above fields</li>
<li>Get Elevated access by going to <a href="https://developer.twitter.com/en/portal/products" target="new">https://developer.twitter.com/en/portal/products</a>, click on <strong>Elevated</strong> then on <strong>Apply</strong> and finally complete the form.</li>
</ol>
</blockquote>
</div>