diff options
| author | Christophe Simonis <chs@odoo.com> | 2018-03-21 18:20:22 +0100 |
|---|---|---|
| committer | Christophe Simonis <chs@odoo.com> | 2018-03-21 18:20:22 +0100 |
| commit | e8f630e44df6460a9027cc07fd79d2a4e11ce17c (patch) | |
| tree | 5462ac8d67c48fa524f7d4093371bcc565f538e5 | |
| parent | 3c468b0185077626ef2d2f220294f24923dd504f (diff) | |
| parent | 7a45296cf1a1643de6b2a114e535bc167364498e (diff) | |
[MERGE] forward port branch saas-15 up to 7a45296cf1a
| -rw-r--r-- | addons/account/models/account_move.py | 5 | ||||
| -rw-r--r-- | addons/account/tests/test_reconciliation.py | 36 | ||||
| -rw-r--r-- | addons/l10n_ch/i18n_extra/de_CH.po | 48 | ||||
| -rw-r--r-- | addons/mass_mailing/models/mass_mailing.py | 2 | ||||
| -rw-r--r-- | addons/portal/views/portal_templates.xml | 2 | ||||
| -rw-r--r-- | addons/product/models/product_pricelist.py | 2 | ||||
| -rw-r--r-- | addons/purchase/models/purchase.py | 3 | ||||
| -rw-r--r-- | addons/survey/security/survey_security.xml | 2 | ||||
| -rw-r--r-- | addons/web/controllers/main.py | 2 | ||||
| -rw-r--r-- | addons/website/views/website_templates.xml | 4 | ||||
| -rw-r--r-- | addons/website_sale/views/templates.xml | 3 | ||||
| -rw-r--r-- | addons/website_sale_delivery/models/sale_order.py | 5 | ||||
| -rw-r--r-- | doc/cla/individual/bigbear3001.md | 11 | ||||
| -rw-r--r-- | doc/cla/individual/highcooley.md | 11 | ||||
| -rw-r--r-- | doc/setup/install.rst | 2 |
15 files changed, 104 insertions, 34 deletions
diff --git a/addons/account/models/account_move.py b/addons/account/models/account_move.py index 5dde66d81de..796974adade 100644 --- a/addons/account/models/account_move.py +++ b/addons/account/models/account_move.py @@ -1173,6 +1173,11 @@ class AccountMoveLine(models.Model): account_move_line.payment_id.write({'invoice_ids': [(3, invoice.id, None)]}) rec_move_ids += account_move_line.matched_debit_ids rec_move_ids += account_move_line.matched_credit_ids + if self.env.context.get('invoice_id'): + current_invoice = self.env['account.invoice'].browse(self.env.context['invoice_id']) + rec_move_ids = rec_move_ids.filtered( + lambda r: (r.debit_move_id + r.credit_move_id) & current_invoice.move_id.line_ids + ) return rec_move_ids.unlink() #################################################### diff --git a/addons/account/tests/test_reconciliation.py b/addons/account/tests/test_reconciliation.py index bda31562874..84c8092234b 100644 --- a/addons/account/tests/test_reconciliation.py +++ b/addons/account/tests/test_reconciliation.py @@ -621,3 +621,39 @@ class TestReconciliation(AccountingTestCase): # Checking if the direction of the move is correct full_rec_payable = full_rec_move.line_ids.filtered(lambda l: l.account_id == self.account_rsa) self.assertEqual(full_rec_payable.balance, 18.75) + + def test_unreconcile(self): + # Use case: + # 2 invoices paid with a single payment. Unreconcile the payment with one invoice, the + # other invoice should remain reconciled. + inv1 = self.create_invoice(invoice_amount=10, currency_id=self.currency_usd_id) + inv2 = self.create_invoice(invoice_amount=20, currency_id=self.currency_usd_id) + payment = self.env['account.payment'].create({ + 'payment_type': 'inbound', + 'payment_method_id': self.env.ref('account.account_payment_method_manual_in').id, + 'partner_type': 'customer', + 'partner_id': self.partner_agrolait_id, + 'amount': 100, + 'currency_id': self.currency_usd_id, + 'journal_id': self.bank_journal_usd.id, + }) + payment.post() + credit_aml = payment.move_line_ids.filtered('credit') + + # Check residual before assignation + self.assertAlmostEquals(inv1.residual, 10) + self.assertAlmostEquals(inv2.residual, 20) + + # Assign credit and residual + inv1.assign_outstanding_credit(credit_aml.id) + inv2.assign_outstanding_credit(credit_aml.id) + self.assertAlmostEquals(inv1.residual, 0) + self.assertAlmostEquals(inv2.residual, 0) + + # Unreconcile one invoice at a time and check residual + credit_aml.with_context(invoice_id=inv1.id).remove_move_reconcile() + self.assertAlmostEquals(inv1.residual, 10) + self.assertAlmostEquals(inv2.residual, 0) + credit_aml.with_context(invoice_id=inv2.id).remove_move_reconcile() + self.assertAlmostEquals(inv1.residual, 10) + self.assertAlmostEquals(inv2.residual, 20) diff --git a/addons/l10n_ch/i18n_extra/de_CH.po b/addons/l10n_ch/i18n_extra/de_CH.po index 23e7511b472..0f9c0b78726 100644 --- a/addons/l10n_ch/i18n_extra/de_CH.po +++ b/addons/l10n_ch/i18n_extra/de_CH.po @@ -604,7 +604,7 @@ msgstr "Bankverbindlichkeiten" #: model:account.account,name:l10n_ch.1_ch_coa_2160 #: model:account.account.template,name:l10n_ch.ch_coa_2160 msgid "Dettes envers l'actionnaire" -msgstr "" +msgstr "Gesellschafterverbindlichkeiten" #. module: l10n_ch #: model:account.account,name:l10n_ch.1_ch_coa_3806 @@ -612,7 +612,7 @@ msgstr "" #: model:account.account.template,name:l10n_ch.ch_coa_3806 #: model:account.account.template,name:l10n_ch.ch_coa_4906 msgid "Différences de change" -msgstr "" +msgstr "Währungsdifferenzen" #. module: l10n_ch #: model:account.account,name:l10n_ch.1_ch_coa_2261 @@ -624,7 +624,7 @@ msgstr "Beschlossene Ausschüttungen" #: model:account.account,name:l10n_ch.1_ch_coa_4071 #: model:account.account.template,name:l10n_ch.ch_coa_4071 msgid "Droits de douanes à l'importation" -msgstr "" +msgstr "Einfuhrzölle" #. module: l10n_ch #: model:account.account,name:l10n_ch.1_ch_coa_1109 @@ -648,7 +648,7 @@ msgstr "Abrechnungskonto MWST" #: model:account.account,name:l10n_ch.1_ch_coa_4009 #: model:account.account.template,name:l10n_ch.ch_coa_4009 msgid "Déductions obtenues sur achats" -msgstr "" +msgstr "Einkaufsrabatte" #. module: l10n_ch #: model:account.account,name:l10n_ch.1_ch_coa_3009 @@ -714,7 +714,7 @@ msgstr "Unterhalt, Reparaturen, Ersatz mobile Sachanlagen" #: model:account.account,name:l10n_ch.1_ch_coa_1570 #: model:account.account.template,name:l10n_ch.ch_coa_1570 msgid "Equipements et Installations" -msgstr "" +msgstr "Feste Einrichtungen und Installationen" #. module: l10n_ch #: model:account.account,name:l10n_ch.1_ch_coa_3800 @@ -722,7 +722,7 @@ msgstr "" #: model:account.account.template,name:l10n_ch.ch_coa_3800 #: model:account.account.template,name:l10n_ch.ch_coa_4900 msgid "Escomptes" -msgstr "" +msgstr "Erlösminderungen" #. module: l10n_ch #: model:account.account,name:l10n_ch.1_ch_coa_4530 @@ -734,31 +734,31 @@ msgstr "Benzin" #: model:account.account,name:l10n_ch.1_ch_coa_3804 #: model:account.account.template,name:l10n_ch.ch_coa_3804 msgid "Frais d'encaissement" -msgstr "Frais d'encaissement" +msgstr "Inkassoaufwand" #. module: l10n_ch #: model:account.account,name:l10n_ch.1_ch_coa_3807 #: model:account.account.template,name:l10n_ch.ch_coa_3807 msgid "Frais d'expédition" -msgstr "Frais d'expédition" +msgstr "Versandkosten" #. module: l10n_ch #: model:account.account,name:l10n_ch.1_ch_coa_4072 #: model:account.account.template,name:l10n_ch.ch_coa_4072 msgid "Frais de transport à l'achat" -msgstr "Frais de transport à l'achat" +msgstr "Transportkosten" #. module: l10n_ch #: model:account.account,name:l10n_ch.1_ch_coa_4070 #: model:account.account.template,name:l10n_ch.ch_coa_4070 msgid "Frêts à l'achat" -msgstr "" +msgstr "Frachtkosten" #. module: l10n_ch #: model:account.account,name:l10n_ch.1_ch_coa_4510 #: model:account.account.template,name:l10n_ch.ch_coa_4510 msgid "Gaz" -msgstr "Gaz" +msgstr "Gas" #. module: l10n_ch #: model:account.account,name:l10n_ch.1_ch_coa_1770 @@ -992,7 +992,7 @@ msgstr "Beteiligungen" #: model:account.account,name:l10n_ch.1_ch_coa_4086 #: model:account.account.template,name:l10n_ch.ch_coa_4086 msgid "Pertes de matières" -msgstr "" +msgstr "Warenschwund" #. module: l10n_ch #: model:account.account,name:l10n_ch.1_ch_coa_3805 @@ -1125,13 +1125,13 @@ msgstr "Werbeaufwand" #: model:account.account,name:l10n_ch.1_ch_coa_3801 #: model:account.account.template,name:l10n_ch.ch_coa_3801 msgid "Rabais et réduction de prix" -msgstr "" +msgstr "Rabatte und Preisreduktionen" #. module: l10n_ch #: model:account.account,name:l10n_ch.1_ch_coa_4901 #: model:account.account.template,name:l10n_ch.ch_coa_4901 msgid "Rabais et réductions de prix" -msgstr "" +msgstr "Rabatte und Preisreduktionen" #. module: l10n_ch #: model:account.account,name:l10n_ch.1_ch_coa_3802 @@ -1139,7 +1139,7 @@ msgstr "" #: model:account.account.template,name:l10n_ch.ch_coa_3802 #: model:account.account.template,name:l10n_ch.ch_coa_4092 msgid "Ristournes" -msgstr "" +msgstr "Rückvergütungen" #. module: l10n_ch #: model:account.account,name:l10n_ch.1_ch_coa_2940 @@ -1473,13 +1473,13 @@ msgstr "Wertschriften" #: model:account.account,name:l10n_ch.1_transfer_account_id #: model:account.account.template,name:l10n_ch.transfer_account_id msgid "Transferts internes" -msgstr "" +msgstr "Interne Verrechnungen" #. module: l10n_ch #: model:account.account,name:l10n_ch.1_ch_coa_1280 #: model:account.account.template,name:l10n_ch.ch_coa_1280 msgid "Travaux en cours" -msgstr "Unfertige Erzeugnisse" +msgstr "Nicht fakturierte Dienstleistungen" #. module: l10n_ch #: model:account.account,name:l10n_ch.1_ch_coa_3940 @@ -1491,19 +1491,19 @@ msgstr "Bestandesänderungen nicht fakturierte Dienstleistungen" #: model:account.account,name:l10n_ch.1_ch_coa_1287 #: model:account.account.template,name:l10n_ch.ch_coa_1287 msgid "Variation de la valeur des travaux en cours" -msgstr "" +msgstr "Bestandesänderungen nicht fakturierte Dienstleistungen" #. module: l10n_ch #: model:account.account,name:l10n_ch.1_ch_coa_1277 #: model:account.account.template,name:l10n_ch.ch_coa_1277 msgid "Variation de stock produits semi-ouvrés" -msgstr "" +msgstr "Bestandesänderungen unfertige Erzeugnisse" #. module: l10n_ch #: model:account.account,name:l10n_ch.1_ch_coa_1267 #: model:account.account.template,name:l10n_ch.ch_coa_1267 msgid "Variation de stocks de produits finis" -msgstr "" +msgstr "Bestandesänderungen fertige Erzeugnisse" #. module: l10n_ch #: model:account.account,name:l10n_ch.1_ch_coa_1207 @@ -1511,13 +1511,13 @@ msgstr "" #: model:account.account.template,name:l10n_ch.ch_coa_1207 #: model:account.account.template,name:l10n_ch.ch_coa_4800 msgid "Variation des stocks de marchandises" -msgstr "" +msgstr "Bestandesänderungen Handelsware" #. module: l10n_ch #: model:account.account,name:l10n_ch.1_ch_coa_4801 #: model:account.account.template,name:l10n_ch.ch_coa_4801 msgid "Variation des stocks de matières premières" -msgstr "" +msgstr "Bestandesänderungen Rohstoffe" #. module: l10n_ch #: model:account.account,name:l10n_ch.1_ch_coa_3901 @@ -1535,7 +1535,7 @@ msgstr "Bestandesänderungen unfertige Erzeugnisse" #: model:account.account,name:l10n_ch.1_ch_coa_1217 #: model:account.account.template,name:l10n_ch.ch_coa_1217 msgid "Variation des stocks des matières premières" -msgstr "" +msgstr "Bestandesänderungen Rohstoffe" #. module: l10n_ch #: model:account.account,name:l10n_ch.1_ch_coa_4008 @@ -1543,7 +1543,7 @@ msgstr "" #: model:account.account.template,name:l10n_ch.ch_coa_4008 #: model:account.account.template,name:l10n_ch.ch_coa_4080 msgid "Variations de stocks" -msgstr "" +msgstr "Inventurdifferenzen" #. module: l10n_ch #: model:account.account,name:l10n_ch.1_ch_coa_3200 diff --git a/addons/mass_mailing/models/mass_mailing.py b/addons/mass_mailing/models/mass_mailing.py index 819f6ddf2d3..24f24216ba0 100644 --- a/addons/mass_mailing/models/mass_mailing.py +++ b/addons/mass_mailing/models/mass_mailing.py @@ -719,6 +719,8 @@ class MassMailing(models.Model): def _process_mass_mailing_queue(self): mass_mailings = self.search([('state', 'in', ('in_queue', 'sending')), '|', ('schedule_date', '<', fields.Datetime.now()), ('schedule_date', '=', False)]) for mass_mailing in mass_mailings: + user = mass_mailing.write_uid or self.env.user + mass_mailing = mass_mailing.with_context(**user.sudo(user=user).context_get()) if len(mass_mailing.get_remaining_recipients()) > 0: mass_mailing.state = 'sending' mass_mailing.send_mail() diff --git a/addons/portal/views/portal_templates.xml b/addons/portal/views/portal_templates.xml index 2052ed27ced..f18a5215c34 100644 --- a/addons/portal/views/portal_templates.xml +++ b/addons/portal/views/portal_templates.xml @@ -278,7 +278,7 @@ <select name="country_id" class="form-control"> <option value="">Country...</option> <t t-foreach="countries or []" t-as="country"> - <option t-att-value="country.id" t-att-selected="country.id == partner.country_id.id"> + <option t-att-value="country.id" t-att-selected="country.id == int(country_id) if country_id else country.id == partner.country_id.id"> <t t-esc="country.name" /> </option> </t> diff --git a/addons/product/models/product_pricelist.py b/addons/product/models/product_pricelist.py index 3df96254141..f38652785de 100644 --- a/addons/product/models/product_pricelist.py +++ b/addons/product/models/product_pricelist.py @@ -356,7 +356,7 @@ class PricelistItem(models.Model): 'product.category', 'Product Category', ondelete='cascade', help="Specify a product category if this rule only applies to products belonging to this category or its children categories. Keep empty otherwise.") min_quantity = fields.Integer( - 'Min. Quantity', default=1, + 'Min. Quantity', default=0, help="For the rule to apply, bought/sold quantity must be greater " "than or equal to the minimum quantity specified in this field.\n" "Expressed in the default unit of measure of the product.") diff --git a/addons/purchase/models/purchase.py b/addons/purchase/models/purchase.py index 89fcd975c60..42896ea6dd5 100644 --- a/addons/purchase/models/purchase.py +++ b/addons/purchase/models/purchase.py @@ -1124,5 +1124,6 @@ class MailComposeMessage(models.TransientModel): @api.multi def send_mail(self, auto_commit=False): if self._context.get('default_model') == 'purchase.order' and self._context.get('default_res_id'): + self = self.with_context(mail_post_autofollow=True) self.mail_purchase_order_on_send() - return super(MailComposeMessage, self.with_context(mail_post_autofollow=True)).send_mail(auto_commit=auto_commit) + return super(MailComposeMessage, self).send_mail(auto_commit=auto_commit) diff --git a/addons/survey/security/survey_security.xml b/addons/survey/security/survey_security.xml index 357e939525e..13412fd37a5 100644 --- a/addons/survey/security/survey_security.xml +++ b/addons/survey/security/survey_security.xml @@ -46,7 +46,7 @@ <field name="name">Public access to user_input</field> <field name="model_id" ref="survey.model_survey_user_input"/> <field name="domain_force">[('create_uid', '=', user.id)]</field> - <field name="groups" eval="[(4, ref('base.group_public'))]"/> + <field name="groups" eval="[(4, ref('base.group_user')), (4, ref('base.group_portal')), (4, ref('base.group_public'))]"/> <field eval="0" name="perm_unlink"/> <field eval="0" name="perm_write"/> <field eval="1" name="perm_read"/> diff --git a/addons/web/controllers/main.py b/addons/web/controllers/main.py index 913edc89932..578bc3420b8 100644 --- a/addons/web/controllers/main.py +++ b/addons/web/controllers/main.py @@ -993,7 +993,7 @@ class Binary(http.Controller): '/web/content/<string:model>/<int:id>/<string:field>/<string:filename>'], type='http', auth="public") def content_common(self, xmlid=None, model='ir.attachment', id=None, field='datas', filename=None, filename_field='datas_fname', unique=None, mimetype=None, - download=None, data=None, token=None, access_token=None): + download=None, data=None, token=None, access_token=None, **kw): status, headers, content = binary_content( xmlid=xmlid, model=model, id=id, field=field, unique=unique, filename=filename, filename_field=filename_field, download=download, mimetype=mimetype, diff --git a/addons/website/views/website_templates.xml b/addons/website/views/website_templates.xml index 69afcbbbd94..16fc3e33444 100644 --- a/addons/website/views/website_templates.xml +++ b/addons/website/views/website_templates.xml @@ -124,8 +124,8 @@ and main_object.website_meta_description or website_meta_description"/> <t t-set="meta_keywords" t-value="main_object and 'website_meta_keywords' in main_object and main_object.website_meta_keywords or website_meta_keywords"/> - <meta t-if="meta_description" name="description" t-att-content="meta_description"/> - <meta t-if="meta_keywords" name="keywords" t-att-content="meta_keywords"/> + <meta t-if="meta_description or editable" name="description" t-att-content="meta_description"/> + <meta t-if="meta_keywords or editable" name="keywords" t-att-content="meta_keywords"/> <!-- OpenGraph tags for Facebook sharing --> <meta property="og:title" t-att-content="additional_title" /> diff --git a/addons/website_sale/views/templates.xml b/addons/website_sale/views/templates.xml index 52708b1f1f5..f25d061c172 100644 --- a/addons/website_sale/views/templates.xml +++ b/addons/website_sale/views/templates.xml @@ -1298,7 +1298,8 @@ <div t-esc="int(line.product_uom_qty) == line.product_uom_qty and int(line.product_uom_qty) or line.product_uom_qty" /> </td> <td class="text-center td-price"> - <span t-field="line.price_unit" style="white-space: nowrap;" t-options="{'widget': 'monetary','from_currency': website_sale_order.pricelist_id.currency_id,'display_currency': website.currency_id}" /> + <span t-field="line.price_reduce_taxexcl" style="white-space: nowrap;" t-options="{'widget': 'monetary', 'from_currency': website_sale_order.pricelist_id.currency_id, 'display_currency': website.currency_id}" groups="sale.group_show_price_subtotal" /> + <span t-field="line.price_reduce_taxinc" style="white-space: nowrap;" t-options="{'widget': 'monetary', 'from_currency': website_sale_order.pricelist_id.currency_id, 'display_currency': website.currency_id}" groups="sale.group_show_price_total" /> </td> </tr> </tbody> diff --git a/addons/website_sale_delivery/models/sale_order.py b/addons/website_sale_delivery/models/sale_order.py index 8c746b05b21..027d3db904d 100644 --- a/addons/website_sale_delivery/models/sale_order.py +++ b/addons/website_sale_delivery/models/sale_order.py @@ -26,7 +26,10 @@ class SaleOrder(models.Model): @api.depends('order_line.price_unit', 'order_line.tax_id', 'order_line.discount', 'order_line.product_uom_qty') def _compute_amount_delivery(self): for order in self: - order.amount_delivery = sum(order.order_line.filtered('is_delivery').mapped('price_subtotal')) + if self.env.user.has_group('sale.group_show_price_subtotal'): + order.amount_delivery = sum(order.order_line.filtered('is_delivery').mapped('price_subtotal')) + else: + order.amount_delivery = sum(order.order_line.filtered('is_delivery').mapped('price_total')) @api.depends('order_line.is_delivery') def _compute_has_delivery(self): diff --git a/doc/cla/individual/bigbear3001.md b/doc/cla/individual/bigbear3001.md new file mode 100644 index 00000000000..9690403db37 --- /dev/null +++ b/doc/cla/individual/bigbear3001.md @@ -0,0 +1,11 @@ +Austria, 18th of March 2018 + +I hereby agree to the terms of the Odoo Individual Contributor License +Agreement v1.0. + +I declare that I am authorized and able to make this agreement and sign this +declaration. + +Signed, + +Andreas Perhab bigbear.ap@gmx.at https://github.com/bigbear3001 diff --git a/doc/cla/individual/highcooley.md b/doc/cla/individual/highcooley.md new file mode 100644 index 00000000000..c4e5bd37dbb --- /dev/null +++ b/doc/cla/individual/highcooley.md @@ -0,0 +1,11 @@ +Switzerland, 2018-03-20 + +I hereby agree to the terms of the Odoo Individual Contributor License +Agreement v1.0. + +I declare that I am authorized and able to make this agreement and sign this +declaration. + +Signed, + +Andreas Hochuli a.hochuli@hispeed.ch https://github.com/Highcooley diff --git a/doc/setup/install.rst b/doc/setup/install.rst index 99871bda78f..90e6e4ae089 100644 --- a/doc/setup/install.rst +++ b/doc/setup/install.rst @@ -406,7 +406,7 @@ Source installation requires manually installing dependencies: $ sudo npm install -g less - - on Windows, `install nodejs <http://nodejs.org/download/>`_, reboot (to + - on Windows, `install nodejs <https://nodejs.org/en/download/>`_, reboot (to update the :envvar:`PATH`) and install less: .. code-block:: doscon |
