Skip to content

Commit 68326b1

Browse files
committed
[MERGE] forward port branch 11.0 up to c5ed372
2 parents 512dab4 + c5ed372 commit 68326b1

File tree

46 files changed

+985
-346
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

46 files changed

+985
-346
lines changed

addons/account/report/account_aged_partner_balance.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -194,7 +194,7 @@ def _get_partner_move_lines(self, account_type, date_from, target_move, period_l
194194
values['name'] = _('Unknown Partner')
195195
values['trust'] = False
196196

197-
if at_least_one_amount or self._context.get('include_nullified_amount'):
197+
if at_least_one_amount or (self._context.get('include_nullified_amount') and lines[partner['partner_id']]):
198198
res.append(values)
199199

200200
return res, total, lines

addons/account/report/account_general_ledger.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ def _get_account_move_entry(self, accounts, init_balance, sortby, display_accoun
3838
init_wheres.append(init_where_clause.strip())
3939
init_filters = " AND ".join(init_wheres)
4040
filters = init_filters.replace('account_move_line__move_id', 'm').replace('account_move_line', 'l')
41-
sql = ("""SELECT 0 AS lid, l.account_id AS account_id, '' AS ldate, '' AS lcode, NULL AS amount_currency, '' AS lref, 'Initial Balance' AS lname, COALESCE(SUM(l.debit),0.0) AS debit, COALESCE(SUM(l.credit),0.0) AS credit, COALESCE(SUM(l.debit),0) - COALESCE(SUM(l.credit), 0) as balance, '' AS lpartner_id,\
41+
sql = ("""SELECT 0 AS lid, l.account_id AS account_id, '' AS ldate, '' AS lcode, 0.0 AS amount_currency, '' AS lref, 'Initial Balance' AS lname, COALESCE(SUM(l.debit),0.0) AS debit, COALESCE(SUM(l.credit),0.0) AS credit, COALESCE(SUM(l.debit),0) - COALESCE(SUM(l.credit), 0) as balance, '' AS lpartner_id,\
4242
'' AS move_name, '' AS mmove_id, '' AS currency_code,\
4343
NULL AS currency_id,\
4444
'' AS invoice_id, '' AS invoice_type, '' AS invoice_number,\

addons/account/tests/test_reconciliation.py

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -758,6 +758,63 @@ def test_revert_payment_and_reconcile(self):
758758
self.assertEqual(reversed_bank_line.full_reconcile_id.id, bank_line.full_reconcile_id.id)
759759
self.assertEqual(reversed_customer_line.full_reconcile_id.id, customer_line.full_reconcile_id.id)
760760

761+
def create_invoice_partner(self, type='out_invoice', invoice_amount=50, currency_id=None, partner_id=False):
762+
#we create an invoice in given currency
763+
invoice = self.account_invoice_model.create({'partner_id': partner_id,
764+
'reference_type': 'none',
765+
'currency_id': currency_id,
766+
'name': type == 'out_invoice' and 'invoice to client' or 'invoice to vendor',
767+
'account_id': self.account_rcv.id,
768+
'type': type,
769+
'date_invoice': time.strftime('%Y') + '-07-01',
770+
})
771+
self.account_invoice_line_model.create({'product_id': self.product.id,
772+
'quantity': 1,
773+
'price_unit': invoice_amount,
774+
'invoice_id': invoice.id,
775+
'name': 'product that cost ' + str(invoice_amount),
776+
'account_id': self.env['account.account'].search([('user_type_id', '=', self.env.ref('account.data_account_type_revenue').id)], limit=1).id,
777+
})
778+
779+
#validate invoice
780+
invoice.action_invoice_open()
781+
return invoice
782+
783+
def test_aged_report(self):
784+
AgedReport = self.env['report.account.report_agedpartnerbalance'].with_context(include_nullified_amount=True)
785+
account_type = ['receivable']
786+
report_date_to = time.strftime('%Y') + '-07-15'
787+
partner = self.env['res.partner'].create({'name': 'AgedPartner'})
788+
currency = self.env.user.company_id.currency_id
789+
790+
invoice = self.create_invoice_partner(currency_id=currency.id, partner_id=partner.id)
791+
journal = self.env['account.journal'].create({'name': 'Bank', 'type': 'bank', 'code': 'THE', 'currency_id': currency.id})
792+
793+
statement = self.make_payment(invoice, journal, 50)
794+
795+
# Case 1: The invoice and payment are reconciled: Nothing should appear
796+
report_lines, total, amls = AgedReport._get_partner_move_lines(account_type, report_date_to, 'posted', 30)
797+
798+
partner_lines = [line for line in report_lines if line['partner_id'] == partner.id]
799+
self.assertEqual(partner_lines, [], 'The aged receivable shouldn\'t have lines at this point')
800+
self.assertFalse(partner.id in amls, 'The aged receivable should not have amls either')
801+
802+
# Case 2: The invoice and payment are not reconciled: we should have one line on the report
803+
# and 2 amls
804+
invoice.move_id.line_ids.with_context(invoice_id=invoice.id).remove_move_reconcile()
805+
report_lines, total, amls = AgedReport._get_partner_move_lines(account_type, report_date_to, 'posted', 30)
806+
807+
partner_lines = [line for line in report_lines if line['partner_id'] == partner.id]
808+
self.assertEqual(partner_lines, [{'trust': 'normal', '1': 0.0, '0': 0.0, 'direction': 0.0, 'partner_id': partner.id, '3': 0.0, 'total': 0.0, 'name': 'AgedPartner', '4': 0.0, '2': 0.0}],
809+
'We should have a line in the report for the partner')
810+
self.assertEqual(len(amls[partner.id]), 2, 'We should have 2 account move lines for the partner')
811+
812+
positive_line = [line for line in amls[partner.id] if line['line'].balance > 0]
813+
negative_line = [line for line in amls[partner.id] if line['line'].balance < 0]
814+
815+
self.assertEqual(positive_line[0]['amount'], 50.0, 'The amount of the amls should be 50')
816+
self.assertEqual(negative_line[0]['amount'], -50.0, 'The amount of the amls should be -50')
817+
761818
def test_partial_reconcile_currencies_02(self):
762819
####
763820
# Day 1: Invoice Cust/001 to customer (expressed in USD)

addons/account_payment/controllers/payment.py

Lines changed: 7 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ def invoice_pay_form(self, acquirer_id, invoice_id, save_token=False, access_tok
1717
:return html: form containing all values related to the acquirer to
1818
redirect customers to the acquirer website """
1919
success_url = kwargs.get('success_url', '/my')
20-
callback_method = kwargs.get('callback_method', '')
2120

2221
invoice_sudo = request.env['account.invoice'].sudo().browse(invoice_id)
2322
if not invoice_sudo:
@@ -28,17 +27,16 @@ def invoice_pay_form(self, acquirer_id, invoice_id, save_token=False, access_tok
2827
except:
2928
return False
3029

30+
if request.env.user == request.env.ref('base.public_user'):
31+
save_token = False # we avoid to create a token for the public user
32+
3133
token = request.env['payment.token'].sudo() # currently no support of payment tokens
3234
tx = request.env['payment.transaction'].sudo()._check_or_create_invoice_tx(
3335
invoice_sudo,
3436
acquirer,
3537
payment_token=token,
3638
tx_type='form_save' if save_token else 'form',
37-
add_tx_values={
38-
'callback_model_id': request.env['ir.model'].sudo().search([('model', '=', invoice_sudo._name)], limit=1).id,
39-
'callback_res_id': invoice_sudo.id,
40-
'callback_method': callback_method,
41-
})
39+
)
4240

4341
# set the transaction id into the session
4442
request.session['portal_invoice_%s_transaction_id' % invoice_sudo.id] = tx.id
@@ -58,7 +56,6 @@ def invoice_pay_token(self, invoice_id, pm_id=None, **kwargs):
5856
""" Use a token to perform a s2s transaction """
5957
error_url = kwargs.get('error_url', '/my')
6058
success_url = kwargs.get('success_url', '/my')
61-
callback_method = kwargs.get('callback_method', '')
6259
access_token = kwargs.get('access_token')
6360
params = {}
6461
if access_token:
@@ -73,7 +70,8 @@ def invoice_pay_token(self, invoice_id, pm_id=None, **kwargs):
7370
token = request.env['payment.token'].sudo().browse(int(pm_id))
7471
except (ValueError, TypeError):
7572
token = False
76-
if not token:
73+
token_owner = invoice_sudo.partner_id if request.env.user == request.env.ref('base.public_user') else request.env.user.partner_id
74+
if not token or token.partner_id != token_owner:
7775
params['error'] = 'pay_invoice_invalid_token'
7876
return request.redirect(_build_url_w_params(error_url, params))
7977

@@ -83,11 +81,7 @@ def invoice_pay_token(self, invoice_id, pm_id=None, **kwargs):
8381
token.acquirer_id,
8482
payment_token=token,
8583
tx_type='server2server',
86-
add_tx_values={
87-
'callback_model_id': request.env['ir.model'].sudo().search([('model', '=', invoice_sudo._name)], limit=1).id,
88-
'callback_res_id': invoice_sudo.id,
89-
'callback_method': callback_method,
90-
})
84+
)
9185

9286
# set the transaction id into the session
9387
request.session['portal_invoice_%s_transaction_id' % invoice_sudo.id] = tx.id

addons/account_payment/controllers/portal.py

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,5 +9,18 @@ class PortalAccount(PortalAccount):
99

1010
def _invoice_get_page_view_values(self, invoice, access_token, **kwargs):
1111
values = super(PortalAccount, self)._invoice_get_page_view_values(invoice, access_token, **kwargs)
12-
values.update(request.env['payment.acquirer']._get_available_payment_input(invoice.partner_id, invoice.company_id))
12+
payment_inputs = request.env['payment.acquirer']._get_available_payment_input(company=invoice.company_id)
13+
# if not connected (using public user), the method _get_available_payment_input will return public user tokens
14+
is_public_user = request.env.ref('base.public_user') == request.env.user
15+
if is_public_user:
16+
# we should not display payment tokens owned by the public user
17+
payment_inputs.pop('pms', None)
18+
token_count = request.env['payment.token'].sudo().search_count([('acquirer_id.company_id', '=', invoice.company_id.id),
19+
('partner_id', '=', invoice.partner_id.id),
20+
])
21+
values['existing_token'] = token_count > 0
22+
values.update(payment_inputs)
23+
# if the current user is connected we set partner_id to his partner otherwise we set it as the invoice partner
24+
# we do this to force the creation of payment tokens to the correct partner and avoid token linked to the public user
25+
values['partner_id'] = invoice.partner_id if is_public_user else request.env.user.partner_id,
1326
return values

addons/account_payment/views/account_portal_templates.xml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,11 @@
8383
</t>
8484
</div>
8585
</div>
86+
<div class="panel-body" t-if="existing_token">
87+
<div class="col-md-offset-3 col-md-6">
88+
<i class="fa fa-info"></i> You have credits card registered, you can log-in to be able to use them.
89+
</div>
90+
</div>
8691
</xpath>
8792
</template>
8893

addons/barcodes/static/src/js/barcode_parser.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@ var BarcodeParser = Class.extend({
1818
// only when those data have been loaded
1919
load: function(){
2020
var self = this;
21+
if (!this.nomenclature_id) {
22+
return;
23+
}
2124
var id = this.nomenclature_id[0];
2225
rpc.query({
2326
model: 'barcode.nomenclature',

addons/base_address_extended/__manifest__.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@
1616
with the street name, the house number, and room number.
1717
""",
1818
'data': [
19-
'views/base_address_extended.xml'
19+
'views/base_address_extended.xml',
20+
'data/base_address_extended_data.xml',
2021
],
2122
'depends': ['base'],
2223
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<odoo>
3+
<data noupdate="1">
4+
<record id="base.nl" model="res.country">
5+
<field eval="'%(street_name)s %(street_number)s/%(street_number2)s'" name="street_format" />
6+
</record>
7+
</data>
8+
</odoo>

addons/calendar/models/calendar.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
import babel.dates
66
import collections
7-
from datetime import datetime, timedelta
7+
from datetime import datetime, timedelta, MAXYEAR
88
from dateutil import parser
99
from dateutil import rrule
1010
from dateutil.relativedelta import relativedelta
@@ -632,7 +632,7 @@ def todate(date):
632632
recurring_date = todate(meeting.recurrent_id_date)
633633
rset1.exdate(recurring_date)
634634
invalidate = True
635-
return [d.astimezone(pytz.UTC) if d.tzinfo else d for d in rset1]
635+
return [d.astimezone(pytz.UTC) if d.tzinfo else d for d in rset1 if d.year < MAXYEAR]
636636

637637
@api.multi
638638
def _get_recurrency_end_date(self):
@@ -902,8 +902,8 @@ def _inverse_dates(self):
902902
startdate = startdate.astimezone(pytz.utc) # Convert to UTC
903903
meeting.start = fields.Datetime.to_string(startdate)
904904
else:
905-
meeting.start = meeting.start_datetime
906-
meeting.stop = meeting.stop_datetime
905+
meeting.write({'start': meeting.start_datetime,
906+
'stop': meeting.stop_datetime})
907907

908908
@api.depends('byday', 'recurrency', 'final_date', 'rrule_type', 'month_by', 'interval', 'count', 'end_type', 'mo', 'tu', 'we', 'th', 'fr', 'sa', 'su', 'day', 'week_list')
909909
def _compute_rrule(self):

0 commit comments

Comments
 (0)