[MERGE] forward port branch saas-15 up to 788684a5dd

This commit is contained in:
Christophe Simonis
2019-01-29 11:57:06 +01:00
7 changed files with 131 additions and 20 deletions
+20 -1
View File
@@ -1266,6 +1266,20 @@ class AccountInvoice(models.Model):
return result
@api.model
def _refund_tax_lines_account_change(self, lines, taxes_to_change):
# Let's change the account on tax lines when
# @param {list} lines: a list of orm commands
# @param {dict} taxes_to_change
# key: tax ID, value: refund account
if not taxes_to_change:
return lines
for line in lines:
if isinstance(line[2], dict) and line[2]['tax_id'] in taxes_to_change:
line[2]['account_id'] = taxes_to_change[line[2]['tax_id']]
return lines
def _get_refund_common_fields(self):
return ['partner_id', 'payment_term_id', 'account_id', 'currency_id', 'journal_id']
@@ -1311,7 +1325,12 @@ class AccountInvoice(models.Model):
values['invoice_line_ids'] = self._refund_cleanup_lines(invoice.invoice_line_ids)
tax_lines = invoice.tax_line_ids
values['tax_line_ids'] = self._refund_cleanup_lines(tax_lines)
taxes_to_change = {
line.tax_id.id: line.tax_id.refund_account_id.id
for line in tax_lines.filtered(lambda l: l.tax_id.refund_account_id != l.tax_id.account_id)
}
cleaned_tax_lines = self._refund_cleanup_lines(tax_lines)
values['tax_line_ids'] = self._refund_tax_lines_account_change(cleaned_tax_lines, taxes_to_change)
if journal_id:
journal = self.env['account.journal'].browse(journal_id)
@@ -164,3 +164,59 @@ class TestAccountCustomerInvoice(AccountTestUsers):
))
self.assertEquals(invoice.amount_untaxed, sum([x.base for x in invoice.tax_line_ids]))
def test_customer_invoice_tax_refund(self):
company = self.env.user.company_id
tax_account = self.env['account.account'].create({
'name': 'TAX',
'code': 'TAX',
'user_type_id': self.env.ref('account.data_account_type_current_assets').id,
'company_id': company.id,
})
tax_refund_account = self.env['account.account'].create({
'name': 'TAX_REFUND',
'code': 'TAX_R',
'user_type_id': self.env.ref('account.data_account_type_current_assets').id,
'company_id': company.id,
})
journalrec = self.env['account.journal'].search([('type', '=', 'sale')])[0]
partner3 = self.env.ref('base.res_partner_3')
account_id = self.env['account.account'].search([('user_type_id', '=', self.env.ref('account.data_account_type_revenue').id)], limit=1).id
tax = self.env['account.tax'].create({
'name': 'Tax 15.0',
'amount': 15.0,
'amount_type': 'percent',
'type_tax_use': 'sale',
'account_id': tax_account.id,
'refund_account_id': tax_refund_account.id
})
invoice_line_data = [
(0, 0,
{
'product_id': self.env.ref('product.product_product_1').id,
'quantity': 40.0,
'account_id': account_id,
'name': 'product test 1',
'discount': 10.00,
'price_unit': 2.27,
'invoice_line_tax_ids': [(6, 0, [tax.id])],
}
)]
invoice = self.env['account.invoice'].create(dict(
name="Test Customer Invoice",
reference_type="none",
journal_id=journalrec.id,
partner_id=partner3.id,
invoice_line_ids=invoice_line_data
))
invoice.action_invoice_open()
refund = invoice.refund()
self.assertEqual(invoice.tax_line_ids.mapped('account_id'), tax_account)
self.assertEqual(refund.tax_line_ids.mapped('account_id'), tax_refund_account)
+14 -6
View File
@@ -892,12 +892,20 @@ exports.PosModel = Backbone.Model.extend({
transfer.pipe(function(order_server_id){
// generate the pdf and download it
self.chrome.do_action('point_of_sale.pos_invoice_report',{additional_context:{
active_ids:order_server_id,
}}).done(function () {
invoiced.resolve();
done.resolve();
});
if (order_server_id.length) {
self.chrome.do_action('point_of_sale.pos_invoice_report',{additional_context:{
active_ids:order_server_id,
}}).done(function () {
invoiced.resolve();
done.resolve();
});
} else {
// The order has been pushed separately in batch when
// the connection came back.
// The user has to go to the backend to print the invoice
invoiced.reject({code:401, message:'Backend Invoice', data:{order: order}});
done.reject();
}
});
return done;
@@ -2078,6 +2078,17 @@ var PaymentScreenWidget = ScreenWidget.extend({
self.gui.show_screen('clientlist');
},
});
} else if (error.message === 'Backend Invoice') {
self.gui.show_popup('confirm',{
'title': _t('Please print the invoice from the backend'),
'body': _t('The order has been synchronized earlier. Please make the invoice from the backend for the order: ') + error.data.order.name,
confirm: function () {
this.gui.show_screen('receipt');
},
cancel: function () {
this.gui.show_screen('receipt');
},
});
} else if (error.code < 0) { // XmlHttpRequest Errors
self.gui.show_popup('error',{
'title': _t('The order could not be sent'),
@@ -22,6 +22,7 @@ var map_title ={
var CrashManager = core.Class.extend({
init: function() {
this.active = true;
this.isConnected = true;
},
enable: function () {
this.active = true;
@@ -29,8 +30,29 @@ var CrashManager = core.Class.extend({
disable: function () {
this.active = false;
},
rpc_error: function(error) {
handleLostConnection: function () {
var self = this;
if (!this.isConnected) {
// already handled, nothing to do. This can happen when several
// rpcs are done in parallel and fail because of a lost connection.
return;
}
this.isConnected = false;
var delay = 2000;
core.bus.trigger('connection_lost');
setTimeout(function checkConnection() {
ajax.jsonRpc('/web/webclient/version_info', 'call', {}, {shadow:true}).then(function () {
core.bus.trigger('connection_restored');
self.isConnected = true;
}).fail(function () {
// exponential backoff, with some jitter
delay = (delay * 1.5) + 500*Math.random();
setTimeout(checkConnection, delay);
});
}, delay);
},
rpc_error: function(error) {
if (!this.active) {
return;
}
@@ -38,16 +60,7 @@ var CrashManager = core.Class.extend({
return;
}
if (error.code === -32098) {
core.bus.trigger('connection_lost');
this.connection_lost = true;
var timeinterval = setInterval(function() {
var options = {shadow: true};
ajax.jsonRpc('/web/webclient/version_info', 'call', {}, options).then(function () {
clearInterval(timeinterval);
core.bus.trigger('connection_restored');
self.connection_lost = false;
});
}, 2000);
this.handleLostConnection();
return;
}
var handler = core.crash_registry.get(error.data.name, true);
+5 -1
View File
@@ -155,7 +155,6 @@
position: relative;
height: @odoo-navbar-height;
overflow: hidden;
> ul {
> li {
@@ -171,6 +170,7 @@
&.o_menu_sections {
width: 100%;
display: none;
> li.open .dropdown-menu {
position: static;
@@ -219,6 +219,10 @@
.o_main_navbar {
height: 100%;
overflow: auto;
.o_menu_sections {
display: block;
}
}
}
}
+1 -1
View File
@@ -182,7 +182,7 @@ class WebsiteSlides(http.Controller):
@http.route('''/slides/slide/<model("slide.slide"):slide>/download''', type='http', auth="public", website=True, sitemap=False)
def slide_download(self, slide, **kw):
slide = slide.sudo()
if slide.download_security == 'public' or (slide.download_security == 'user' and request.session.uid):
if slide.download_security == 'public' or (slide.download_security == 'user' and request.env.user and request.env.user != request.website.user_id):
filecontent = base64.b64decode(slide.datas)
disposition = 'attachment; filename=%s.pdf' % werkzeug.urls.url_quote(slide.name)
return request.make_response(