Skip to content

Commit c8bb021

Browse files
committed
[MERGE] forward port branch saas-11.3 up to 3cdcbce
2 parents 4e2733e + 3cdcbce commit c8bb021

File tree

130 files changed

+2766
-492
lines changed

Some content is hidden

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

130 files changed

+2766
-492
lines changed

.tx/config

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -362,6 +362,11 @@ file_filter = addons/im_livechat/i18n/<lang>.po
362362
source_file = addons/im_livechat/i18n/im_livechat.pot
363363
source_lang = en
364364

365+
[odoo-master.im_support]
366+
file_filter = addons/im_support/i18n/<lang>.po
367+
source_file = addons/im_support/i18n/im_support.pot
368+
source_lang = en
369+
365370
[odoo-master.link_tracker]
366371
file_filter = addons/link_tracker/i18n/<lang>.po
367372
source_file = addons/link_tracker/i18n/link_tracker.pot
@@ -407,6 +412,11 @@ file_filter = addons/mrp/i18n/<lang>.po
407412
source_file = addons/mrp/i18n/mrp.pot
408413
source_lang = en
409414

415+
[odoo-master.mrp_bom_cost]
416+
file_filter = addons/mrp_bom_cost/i18n/<lang>.po
417+
source_file = addons/mrp_bom_cost/i18n/mrp_bom_cost.pot
418+
source_lang = en
419+
410420
[odoo-master.mrp_byproduct]
411421
file_filter = addons/mrp_byproduct/i18n/<lang>.po
412422
source_file = addons/mrp_byproduct/i18n/mrp_byproduct.pot
@@ -552,11 +562,6 @@ file_filter = addons/product_expiry/i18n/<lang>.po
552562
source_file = addons/product_expiry/i18n/product_expiry.pot
553563
source_lang = en
554564

555-
[odoo-master.product_extended]
556-
file_filter = addons/product_extended/i18n/<lang>.po
557-
source_file = addons/product_extended/i18n/product_extended.pot
558-
source_lang = en
559-
560565
[odoo-master.product_margin]
561566
file_filter = addons/product_margin/i18n/<lang>.po
562567
source_file = addons/product_margin/i18n/product_margin.pot
@@ -722,6 +727,11 @@ file_filter = addons/transifex/i18n/<lang>.po
722727
source_file = addons/transifex/i18n/transifex.pot
723728
source_lang = en
724729

730+
[odoo-master.uom]
731+
file_filter = addons/uom/i18n/<lang>.po
732+
source_file = addons/uom/i18n/uom.pot
733+
source_lang = en
734+
725735
[odoo-master.utm]
726736
file_filter = addons/utm/i18n/<lang>.po
727737
source_file = addons/utm/i18n/utm.pot

addons/account/models/product.py

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -35,22 +35,6 @@ class ProductTemplate(models.Model):
3535
domain=[('deprecated', '=', False)],
3636
help="The expense is accounted for when a vendor bill is validated, except in anglo-saxon accounting with perpetual inventory valuation in which case the expense (Cost of Goods Sold account) is recognized at the customer invoice validation. If the field is empty, it uses the one defined in the product category.")
3737

38-
@api.multi
39-
def write(self, vals):
40-
#TODO: really? i don't see the reason we'd need that constraint..
41-
check = self.ids and 'uom_po_id' in vals
42-
if check:
43-
self._cr.execute("SELECT id, uom_po_id FROM product_template WHERE id IN %s", [tuple(self.ids)])
44-
uoms = dict(self._cr.fetchall())
45-
res = super(ProductTemplate, self).write(vals)
46-
if check:
47-
self._cr.execute("SELECT id, uom_po_id FROM product_template WHERE id IN %s", [tuple(self.ids)])
48-
if dict(self._cr.fetchall()) != uoms:
49-
products = self.env['product.product'].search([('product_tmpl_id', 'in', self.ids)])
50-
if self.env['account.move.line'].search_count([('product_id', 'in', products.ids)]):
51-
raise UserError(_('You can not change the unit of measure of a product that has been already used in an account journal item. If you need to change the unit of measure, you should archive this product and create a new one.'))
52-
return res
53-
5438
@api.multi
5539
def _get_product_accounts(self):
5640
return {

addons/account/report/account_aged_partner_balance.py

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

206-
if at_least_one_amount or self._context.get('include_nullified_amount'):
206+
if at_least_one_amount or (self._context.get('include_nullified_amount') and lines[partner['partner_id']]):
207207
res.append(values)
208208

209209
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
@@ -760,6 +760,63 @@ def test_revert_payment_and_reconcile(self):
760760
self.assertEqual(reversed_bank_line.full_reconcile_id.id, bank_line.full_reconcile_id.id)
761761
self.assertEqual(reversed_customer_line.full_reconcile_id.id, customer_line.full_reconcile_id.id)
762762

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

addons/account_check_printing/models/account_payment.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -162,12 +162,12 @@ def _check_make_stub_pages(self):
162162

163163
# Prepare the stub lines
164164
if not credits:
165-
stub_lines = [self.make_stub_line(inv) for inv in invoices]
165+
stub_lines = [self._check_make_stub_line(inv) for inv in invoices]
166166
else:
167167
stub_lines = [{'header': True, 'name': "Bills"}]
168-
stub_lines += [self.make_stub_line(inv) for inv in debits]
168+
stub_lines += [self._check_make_stub_line(inv) for inv in debits]
169169
stub_lines += [{'header': True, 'name': "Refunds"}]
170-
stub_lines += [self.make_stub_line(inv) for inv in credits]
170+
stub_lines += [self._check_make_stub_line(inv) for inv in credits]
171171

172172
# Crop the stub lines or split them on multiple pages
173173
if not multi_stub:

addons/account_payment/controllers/payment.py

Lines changed: 7 additions & 11 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,11 +27,10 @@ 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
3132
vals = {
3233
'acquirer_id': acquirer_id,
33-
'callback_model_id': request.env['ir.model'].sudo().search([('model', '=', invoice_sudo._name)], limit=1).id,
34-
'callback_res_id': invoice_sudo.id,
35-
'callback_method': callback_method,
3634
}
3735

3836
if save_token:
@@ -55,7 +53,6 @@ def invoice_pay_token(self, invoice_id, pm_id=None, **kwargs):
5553
""" Use a token to perform a s2s transaction """
5654
error_url = kwargs.get('error_url', '/my')
5755
success_url = kwargs.get('success_url', '/my')
58-
callback_method = kwargs.get('callback_method', '')
5956
access_token = kwargs.get('access_token')
6057
params = {}
6158
if access_token:
@@ -67,18 +64,17 @@ def invoice_pay_token(self, invoice_id, pm_id=None, **kwargs):
6764
return request.redirect(_build_url_w_params(error_url, params))
6865

6966
try:
70-
pm_id = int(pm_id)
67+
token = request.env['payment.token'].sudo().browse(int(pm_id))
7168
except (ValueError, TypeError):
69+
token = False
70+
token_owner = invoice_sudo.partner_id if request.env.user == request.env.ref('base.public_user') else request.env.user.partner_id
71+
if not token or token.partner_id != token_owner:
7272
params['error'] = 'pay_invoice_invalid_token'
7373
return request.redirect(_build_url_w_params(error_url, params))
7474

7575
vals = {
76-
'payment_token_id': pm_id,
76+
'payment_token_id': token.id,
7777
'type': 'server2server',
78-
'callback_model_id': request.env['ir.model'].sudo().search([('model', '=', invoice_sudo._name)],
79-
limit=1).id,
80-
'callback_res_id': invoice_sudo.id,
81-
'callback_method': callback_method,
8278
}
8379

8480
invoice_sudo._create_payment_transaction(vals)

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
@@ -53,6 +53,11 @@
5353
</t>
5454
</div>
5555
</div>
56+
<div class="panel-body" t-if="existing_token">
57+
<div class="col-md-offset-3 col-md-6">
58+
<i class="fa fa-info"></i> You have credits card registered, you can log-in to be able to use them.
59+
</div>
60+
</div>
5661
</xpath>
5762
</template>
5863

addons/auth_signup/models/res_users.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -196,5 +196,5 @@ def copy(self, default=None):
196196
sup = super(ResUsers, self)
197197
if not default or not default.get('email'):
198198
# avoid sending email to the user we are duplicating
199-
sup = super(ResUsers, self.with_context(reset_password=False))
199+
sup = super(ResUsers, self.with_context(no_reset_password=True))
200200
return sup.copy(default=default)

0 commit comments

Comments
 (0)