[MERGE] forward port branch saas-12 up to b1b700a
This commit is contained in:
@@ -1062,11 +1062,15 @@ class AccountInvoice(models.Model):
|
|||||||
if payment_method not in journal_payment_methods:
|
if payment_method not in journal_payment_methods:
|
||||||
raise UserError(_('No appropriate payment method enabled on journal %s') % pay_journal.name)
|
raise UserError(_('No appropriate payment method enabled on journal %s') % pay_journal.name)
|
||||||
|
|
||||||
|
communication = self.type in ('in_invoice', 'in_refund') and self.reference or self.number
|
||||||
|
if self.origin:
|
||||||
|
communication = '%s (%s)' % (communication, self.origin)
|
||||||
|
|
||||||
payment = self.env['account.payment'].create({
|
payment = self.env['account.payment'].create({
|
||||||
'invoice_ids': [(6, 0, self.ids)],
|
'invoice_ids': [(6, 0, self.ids)],
|
||||||
'amount': pay_amount or self.residual,
|
'amount': pay_amount or self.residual,
|
||||||
'payment_date': date or fields.Date.context_today(self),
|
'payment_date': date or fields.Date.context_today(self),
|
||||||
'communication': self.type in ('in_invoice', 'in_refund') and self.reference or self.number,
|
'communication': communication,
|
||||||
'partner_id': self.partner_id.id,
|
'partner_id': self.partner_id.id,
|
||||||
'partner_type': self.type in ('out_invoice', 'out_refund') and 'customer' or 'supplier',
|
'partner_type': self.type in ('out_invoice', 'out_refund') and 'customer' or 'supplier',
|
||||||
'journal_id': pay_journal.id,
|
'journal_id': pay_journal.id,
|
||||||
|
|||||||
@@ -50,14 +50,17 @@ class IrModelFieldsAnonymizeWizard(models.TransientModel):
|
|||||||
summary = u''
|
summary = u''
|
||||||
for anon_field in self.env['ir.model.fields.anonymization'].search([('state', '!=', 'not_existing')]):
|
for anon_field in self.env['ir.model.fields.anonymization'].search([('state', '!=', 'not_existing')]):
|
||||||
field = anon_field.field_id
|
field = anon_field.field_id
|
||||||
values = {
|
if field:
|
||||||
'model_name': field.model_id.name,
|
values = {
|
||||||
'model_code': field.model_id.model,
|
'model_name': field.model_id.name,
|
||||||
'field_code': field.name,
|
'model_code': field.model_id.model,
|
||||||
'field_name': field.field_description,
|
'field_code': field.name,
|
||||||
'state': anon_field.state,
|
'field_name': field.field_description,
|
||||||
}
|
'state': anon_field.state,
|
||||||
summary += u" * %(model_name)s (%(model_code)s) -> %(field_name)s (%(field_code)s): state: (%(state)s)\n" % values
|
}
|
||||||
|
summary += u" * %(model_name)s (%(model_code)s) -> %(field_name)s (%(field_code)s): state: (%(state)s)\n" % values
|
||||||
|
else:
|
||||||
|
summary += u"* Missing local model (%s) and field (%s): state: (%s) \n" % (anon_field.model_name, anon_field.field_name, anon_field.state)
|
||||||
return summary
|
return summary
|
||||||
|
|
||||||
@api.model
|
@api.model
|
||||||
|
|||||||
@@ -673,8 +673,8 @@ class Lead(FormatAddress, models.Model):
|
|||||||
'partner_id': customer.id if customer else False,
|
'partner_id': customer.id if customer else False,
|
||||||
'type': 'opportunity',
|
'type': 'opportunity',
|
||||||
'date_open': fields.Datetime.now(),
|
'date_open': fields.Datetime.now(),
|
||||||
'email_from': customer.email if customer else self.email_from,
|
'email_from': customer and customer.email or self.email_from,
|
||||||
'phone': customer.phone if customer else self.phone,
|
'phone': customer and customer.phone or self.phone,
|
||||||
'date_conversion': fields.Datetime.now(),
|
'date_conversion': fields.Datetime.now(),
|
||||||
}
|
}
|
||||||
if not self.stage_id:
|
if not self.stage_id:
|
||||||
|
|||||||
@@ -568,7 +568,7 @@
|
|||||||
<field name="name">Departments</field>
|
<field name="name">Departments</field>
|
||||||
<field name="res_model">hr.department</field>
|
<field name="res_model">hr.department</field>
|
||||||
<field name="view_type">form</field>
|
<field name="view_type">form</field>
|
||||||
<field name="view_mode">kanban,form</field>
|
<field name="view_mode">kanban,tree,form</field>
|
||||||
<field name="search_view_id" ref="view_department_filter"/>
|
<field name="search_view_id" ref="view_department_filter"/>
|
||||||
<field name="help" type="html">
|
<field name="help" type="html">
|
||||||
<p class="oe_view_nocontent_create">
|
<p class="oe_view_nocontent_create">
|
||||||
|
|||||||
@@ -7,13 +7,13 @@ msgstr ""
|
|||||||
"Project-Id-Version: Odoo Server 9.0\n"
|
"Project-Id-Version: Odoo Server 9.0\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2015-09-18 16:56+0200\n"
|
"POT-Creation-Date: 2015-09-18 16:56+0200\n"
|
||||||
"PO-Revision-Date: 2015-09-18 17:09+0200\n"
|
"PO-Revision-Date: 2016-09-19 16:51+0200\n"
|
||||||
"Language-Team: \n"
|
"Language-Team: \n"
|
||||||
"MIME-Version: 1.0\n"
|
"MIME-Version: 1.0\n"
|
||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
"Content-Transfer-Encoding: 8bit\n"
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||||
"X-Generator: Poedit 1.8.4\n"
|
"X-Generator: Poedit 1.8.9\n"
|
||||||
"Last-Translator: \n"
|
"Last-Translator: \n"
|
||||||
"Language: nl_BE\n"
|
"Language: nl_BE\n"
|
||||||
|
|
||||||
@@ -495,17 +495,17 @@ msgstr "Resultaten uit de omrekening van vreemde valuta"
|
|||||||
#. module: l10n_be
|
#. module: l10n_be
|
||||||
#: model:account.account.template,name:l10n_be.a175111
|
#: model:account.account.template,name:l10n_be.a175111
|
||||||
msgid "Effets à payer \\ Fournisseurs C.E.E."
|
msgid "Effets à payer \\ Fournisseurs C.E.E."
|
||||||
msgstr ""
|
msgstr "Te betalen wissels: Leveranciers van de EEG"
|
||||||
|
|
||||||
#. module: l10n_be
|
#. module: l10n_be
|
||||||
#: model:account.account.template,name:l10n_be.a175110
|
#: model:account.account.template,name:l10n_be.a175110
|
||||||
msgid "Effets à payer \\ Fournisseurs belges"
|
msgid "Effets à payer \\ Fournisseurs belges"
|
||||||
msgstr ""
|
msgstr "Te betalen wissels: Belgische leveranciers"
|
||||||
|
|
||||||
#. module: l10n_be
|
#. module: l10n_be
|
||||||
#: model:account.account.template,name:l10n_be.a175112
|
#: model:account.account.template,name:l10n_be.a175112
|
||||||
msgid "Effets à payer \\ Fournisseurs importation"
|
msgid "Effets à payer \\ Fournisseurs importation"
|
||||||
msgstr ""
|
msgstr "Te betalen wissels: Import leveranciers"
|
||||||
|
|
||||||
#. module: l10n_be
|
#. module: l10n_be
|
||||||
#: model:account.account.template,name:l10n_be.a4166
|
#: model:account.account.template,name:l10n_be.a4166
|
||||||
@@ -521,7 +521,7 @@ msgstr "Bedienden"
|
|||||||
#. module: l10n_be
|
#. module: l10n_be
|
||||||
#: model:account.account.template,name:l10n_be.a3200
|
#: model:account.account.template,name:l10n_be.a3200
|
||||||
msgid "En cours de fabrication"
|
msgid "En cours de fabrication"
|
||||||
msgstr ""
|
msgstr "Goederen in bewerking"
|
||||||
|
|
||||||
#. module: l10n_be
|
#. module: l10n_be
|
||||||
#: model:account.account.template,name:l10n_be.a440
|
#: model:account.account.template,name:l10n_be.a440
|
||||||
@@ -571,7 +571,7 @@ msgstr "Leveranciers"
|
|||||||
#. module: l10n_be
|
#. module: l10n_be
|
||||||
#: model:account.account.template,name:l10n_be.a612
|
#: model:account.account.template,name:l10n_be.a612
|
||||||
msgid "Fournitures"
|
msgid "Fournitures"
|
||||||
msgstr ""
|
msgstr "Diverse leveringen"
|
||||||
|
|
||||||
#. module: l10n_be
|
#. module: l10n_be
|
||||||
#: model:account.account.template,name:l10n_be.a260
|
#: model:account.account.template,name:l10n_be.a260
|
||||||
@@ -596,22 +596,22 @@ msgstr "Kosten van onderzoek en ontwikkeling"
|
|||||||
#. module: l10n_be
|
#. module: l10n_be
|
||||||
#: model:account.tax.template,name:l10n_be.attn_VAT-IN-V82-CAR-EXC-C2
|
#: model:account.tax.template,name:l10n_be.attn_VAT-IN-V82-CAR-EXC-C2
|
||||||
msgid "Frais de voiture - TVA 50% Deductible (Prix Excl.)"
|
msgid "Frais de voiture - TVA 50% Deductible (Prix Excl.)"
|
||||||
msgstr ""
|
msgstr "Auto kosten - BTW 50% aftrekbaar (exl. prijs)"
|
||||||
|
|
||||||
#. module: l10n_be
|
#. module: l10n_be
|
||||||
#: model:account.tax.template,name:l10n_be.attn_VAT-IN-V82-CAR-EXC-C1
|
#: model:account.tax.template,name:l10n_be.attn_VAT-IN-V82-CAR-EXC-C1
|
||||||
msgid "Frais de voiture - TVA 50% Non Deductible"
|
msgid "Frais de voiture - TVA 50% Non Deductible"
|
||||||
msgstr ""
|
msgstr "Auto kosten - BTW 50% niet aftrekbaar"
|
||||||
|
|
||||||
#. module: l10n_be
|
#. module: l10n_be
|
||||||
#: model:account.account.template,name:l10n_be.a3500
|
#: model:account.account.template,name:l10n_be.a3500
|
||||||
msgid "Immeubles destinés à la vente"
|
msgid "Immeubles destinés à la vente"
|
||||||
msgstr ""
|
msgstr "Onroerende goederen bestemd voor verkoop"
|
||||||
|
|
||||||
#. module: l10n_be
|
#. module: l10n_be
|
||||||
#: model:account.account.template,name:l10n_be.a2800
|
#: model:account.account.template,name:l10n_be.a2800
|
||||||
msgid "Immobilisations Financières"
|
msgid "Immobilisations Financières"
|
||||||
msgstr ""
|
msgstr "Financiële vaste activa"
|
||||||
|
|
||||||
#. module: l10n_be
|
#. module: l10n_be
|
||||||
#: model:account.account.template,name:l10n_be.a4120
|
#: model:account.account.template,name:l10n_be.a4120
|
||||||
@@ -641,17 +641,17 @@ msgstr "Goederen"
|
|||||||
#. module: l10n_be
|
#. module: l10n_be
|
||||||
#: model:account.account.template,name:l10n_be.a300
|
#: model:account.account.template,name:l10n_be.a300
|
||||||
msgid "Matières premières"
|
msgid "Matières premières"
|
||||||
msgstr ""
|
msgstr "Grondstoffen"
|
||||||
|
|
||||||
#. module: l10n_be
|
#. module: l10n_be
|
||||||
#: model:account.account.template,name:l10n_be.a24011
|
#: model:account.account.template,name:l10n_be.a24011
|
||||||
msgid "Matériel de bureau de bâtiments administratifs et commerciaux"
|
msgid "Matériel de bureau de bâtiments administratifs et commerciaux"
|
||||||
msgstr ""
|
msgstr "Kantooruitrusting voor gebouwen met adminestratieve en commerciële functie"
|
||||||
|
|
||||||
#. module: l10n_be
|
#. module: l10n_be
|
||||||
#: model:account.account.template,name:l10n_be.a24010
|
#: model:account.account.template,name:l10n_be.a24010
|
||||||
msgid "Matériel de bureau de bâtiments industriels"
|
msgid "Matériel de bureau de bâtiments industriels"
|
||||||
msgstr ""
|
msgstr "Kantooruitrusting voor gebouwen met industriële functie"
|
||||||
|
|
||||||
#. module: l10n_be
|
#. module: l10n_be
|
||||||
#: model:account.account.template,name:l10n_be.a2521
|
#: model:account.account.template,name:l10n_be.a2521
|
||||||
@@ -681,22 +681,22 @@ msgstr "Bedragen komende van het resultaat"
|
|||||||
#. module: l10n_be
|
#. module: l10n_be
|
||||||
#: model:account.account.template,name:l10n_be.a4541
|
#: model:account.account.template,name:l10n_be.a4541
|
||||||
msgid "ONSS. 1er trimestre"
|
msgid "ONSS. 1er trimestre"
|
||||||
msgstr ""
|
msgstr "R.S.Z. 1ste kwartaal"
|
||||||
|
|
||||||
#. module: l10n_be
|
#. module: l10n_be
|
||||||
#: model:account.account.template,name:l10n_be.a4542
|
#: model:account.account.template,name:l10n_be.a4542
|
||||||
msgid "ONSS. 2ème trimestre"
|
msgid "ONSS. 2ème trimestre"
|
||||||
msgstr ""
|
msgstr "R.S.Z. 2de kwartaal"
|
||||||
|
|
||||||
#. module: l10n_be
|
#. module: l10n_be
|
||||||
#: model:account.account.template,name:l10n_be.a4543
|
#: model:account.account.template,name:l10n_be.a4543
|
||||||
msgid "ONSS. 3ème trimestre"
|
msgid "ONSS. 3ème trimestre"
|
||||||
msgstr ""
|
msgstr "R.S.Z. 3de kwartaal"
|
||||||
|
|
||||||
#. module: l10n_be
|
#. module: l10n_be
|
||||||
#: model:account.account.template,name:l10n_be.a4544
|
#: model:account.account.template,name:l10n_be.a4544
|
||||||
msgid "ONSS. 4ème trimestre"
|
msgid "ONSS. 4ème trimestre"
|
||||||
msgstr ""
|
msgstr "R.S.Z. 4de kwartaal"
|
||||||
|
|
||||||
#. module: l10n_be
|
#. module: l10n_be
|
||||||
#: model:account.account.template,name:l10n_be.a4540
|
#: model:account.account.template,name:l10n_be.a4540
|
||||||
@@ -762,7 +762,7 @@ msgstr "Dienstverlening buiten de E.E.G. (export)"
|
|||||||
#. module: l10n_be
|
#. module: l10n_be
|
||||||
#: model:account.account.template,name:l10n_be.a11
|
#: model:account.account.template,name:l10n_be.a11
|
||||||
msgid "Primes d'émission"
|
msgid "Primes d'émission"
|
||||||
msgstr ""
|
msgstr "Uitgifte premies"
|
||||||
|
|
||||||
#. module: l10n_be
|
#. module: l10n_be
|
||||||
#: model:account.account.template,name:l10n_be.a4930
|
#: model:account.account.template,name:l10n_be.a4930
|
||||||
@@ -782,12 +782,12 @@ msgstr "Diverse financiële opbrengsten"
|
|||||||
#. module: l10n_be
|
#. module: l10n_be
|
||||||
#: model:account.account.template,name:l10n_be.a7600
|
#: model:account.account.template,name:l10n_be.a7600
|
||||||
msgid "Produits exceptionnels"
|
msgid "Produits exceptionnels"
|
||||||
msgstr ""
|
msgstr "Uitzonderlijke opbrengsten"
|
||||||
|
|
||||||
#. module: l10n_be
|
#. module: l10n_be
|
||||||
#: model:account.account.template,name:l10n_be.a3300
|
#: model:account.account.template,name:l10n_be.a3300
|
||||||
msgid "Produits finis"
|
msgid "Produits finis"
|
||||||
msgstr ""
|
msgstr "Gereed product"
|
||||||
|
|
||||||
#. module: l10n_be
|
#. module: l10n_be
|
||||||
#: model:account.account.template,name:l10n_be.a404
|
#: model:account.account.template,name:l10n_be.a404
|
||||||
@@ -803,7 +803,7 @@ msgstr "Voorziening voor eindejaarspremie"
|
|||||||
#. module: l10n_be
|
#. module: l10n_be
|
||||||
#: model:account.account.template,name:l10n_be.a1600
|
#: model:account.account.template,name:l10n_be.a1600
|
||||||
msgid "Provisions pour risques et charges"
|
msgid "Provisions pour risques et charges"
|
||||||
msgstr ""
|
msgstr "Voorzieningen voor risico's en kosten"
|
||||||
|
|
||||||
#. module: l10n_be
|
#. module: l10n_be
|
||||||
#: model:account.account.template,name:l10n_be.a4533
|
#: model:account.account.template,name:l10n_be.a4533
|
||||||
@@ -823,12 +823,12 @@ msgstr "Onttrekking aan het kapitaal en aan de uitgiftepremies"
|
|||||||
#. module: l10n_be
|
#. module: l10n_be
|
||||||
#: model:account.account.template,name:l10n_be.a780
|
#: model:account.account.template,name:l10n_be.a780
|
||||||
msgid "Prélèvements sur les impôts différés"
|
msgid "Prélèvements sur les impôts différés"
|
||||||
msgstr ""
|
msgstr "Onttrekking aan de uitgestelde belastingen"
|
||||||
|
|
||||||
#. module: l10n_be
|
#. module: l10n_be
|
||||||
#: model:account.account.template,name:l10n_be.a789
|
#: model:account.account.template,name:l10n_be.a789
|
||||||
msgid "Prélèvements sur les réserves immunisées"
|
msgid "Prélèvements sur les réserves immunisées"
|
||||||
msgstr ""
|
msgstr "Onttrekking aan de reserves"
|
||||||
|
|
||||||
#. module: l10n_be
|
#. module: l10n_be
|
||||||
#: model:account.account.template,name:l10n_be.a706
|
#: model:account.account.template,name:l10n_be.a706
|
||||||
@@ -909,27 +909,27 @@ msgstr "Regularisering van geraamde belastingen"
|
|||||||
#. module: l10n_be
|
#. module: l10n_be
|
||||||
#: model:account.account.template,name:l10n_be.a6200
|
#: model:account.account.template,name:l10n_be.a6200
|
||||||
msgid "Rémunérations: Administrateurs ou gérants"
|
msgid "Rémunérations: Administrateurs ou gérants"
|
||||||
msgstr ""
|
msgstr "Bezoldigingen: Bestuurders of zaakvoerders"
|
||||||
|
|
||||||
#. module: l10n_be
|
#. module: l10n_be
|
||||||
#: model:account.account.template,name:l10n_be.a6204
|
#: model:account.account.template,name:l10n_be.a6204
|
||||||
msgid "Rémunérations: Autres membres du personnel"
|
msgid "Rémunérations: Autres membres du personnel"
|
||||||
msgstr ""
|
msgstr "Bezoldigingen: Andere personeelsleden, verbonden met een arbeidsovereenkomst"
|
||||||
|
|
||||||
#. module: l10n_be
|
#. module: l10n_be
|
||||||
#: model:account.account.template,name:l10n_be.a6202
|
#: model:account.account.template,name:l10n_be.a6202
|
||||||
msgid "Rémunérations: Employés"
|
msgid "Rémunérations: Employés"
|
||||||
msgstr ""
|
msgstr "Bezoldigingen: Arbeiders"
|
||||||
|
|
||||||
#. module: l10n_be
|
#. module: l10n_be
|
||||||
#: model:account.account.template,name:l10n_be.a6203
|
#: model:account.account.template,name:l10n_be.a6203
|
||||||
msgid "Rémunérations: Ouvriers"
|
msgid "Rémunérations: Ouvriers"
|
||||||
msgstr ""
|
msgstr "Bezoldigingen: Bedienden"
|
||||||
|
|
||||||
#. module: l10n_be
|
#. module: l10n_be
|
||||||
#: model:account.account.template,name:l10n_be.a6201
|
#: model:account.account.template,name:l10n_be.a6201
|
||||||
msgid "Rémunérations: Personnel de direction"
|
msgid "Rémunérations: Personnel de direction"
|
||||||
msgstr ""
|
msgstr "Bezoldigingen: Directiepersoneel"
|
||||||
|
|
||||||
#. module: l10n_be
|
#. module: l10n_be
|
||||||
#: model:account.account.template,name:l10n_be.a130
|
#: model:account.account.template,name:l10n_be.a130
|
||||||
@@ -959,7 +959,7 @@ msgstr "Kapitaal- en interestsubsidies"
|
|||||||
#. module: l10n_be
|
#. module: l10n_be
|
||||||
#: model:account.account.template,name:l10n_be.a150
|
#: model:account.account.template,name:l10n_be.a150
|
||||||
msgid "Subsides obtenus"
|
msgid "Subsides obtenus"
|
||||||
msgstr ""
|
msgstr "Verkregen subsidies"
|
||||||
|
|
||||||
#. module: l10n_be
|
#. module: l10n_be
|
||||||
#: model:account.account.template,name:l10n_be.a41670
|
#: model:account.account.template,name:l10n_be.a41670
|
||||||
@@ -1204,7 +1204,7 @@ msgstr "Terreinen"
|
|||||||
#. module: l10n_be
|
#. module: l10n_be
|
||||||
#: model:account.account.template,name:l10n_be.trans
|
#: model:account.account.template,name:l10n_be.trans
|
||||||
msgid "Transferts"
|
msgid "Transferts"
|
||||||
msgstr ""
|
msgstr "Transferten"
|
||||||
|
|
||||||
#. module: l10n_be
|
#. module: l10n_be
|
||||||
#: model:account.tax.template,name:l10n_be.attn_VAT-IN-V81-06-CC-C1
|
#: model:account.tax.template,name:l10n_be.attn_VAT-IN-V81-06-CC-C1
|
||||||
@@ -1509,32 +1509,32 @@ msgstr "VAT-IN-V83-21-ROW-CC-C2"
|
|||||||
#. module: l10n_be
|
#. module: l10n_be
|
||||||
#: model:account.account.template,name:l10n_be.a7001
|
#: model:account.account.template,name:l10n_be.a7001
|
||||||
msgid "Ventes dans les pays membres de la C.E.E. (marchandises)"
|
msgid "Ventes dans les pays membres de la C.E.E. (marchandises)"
|
||||||
msgstr ""
|
msgstr "Verkopen: leden van de Europese gemeenschap (handelsgoederen)"
|
||||||
|
|
||||||
#. module: l10n_be
|
#. module: l10n_be
|
||||||
#: model:account.account.template,name:l10n_be.a7011
|
#: model:account.account.template,name:l10n_be.a7011
|
||||||
msgid "Ventes dans les pays membres de la C.E.E. (produits finis)"
|
msgid "Ventes dans les pays membres de la C.E.E. (produits finis)"
|
||||||
msgstr ""
|
msgstr "Verkopen: leden van de Europese gemeenschap (gereed product)"
|
||||||
|
|
||||||
#. module: l10n_be
|
#. module: l10n_be
|
||||||
#: model:account.account.template,name:l10n_be.a7000
|
#: model:account.account.template,name:l10n_be.a7000
|
||||||
msgid "Ventes en Belgique (marchandises)"
|
msgid "Ventes en Belgique (marchandises)"
|
||||||
msgstr ""
|
msgstr "Verkopen: België (handelsgoederen)"
|
||||||
|
|
||||||
#. module: l10n_be
|
#. module: l10n_be
|
||||||
#: model:account.account.template,name:l10n_be.a7010
|
#: model:account.account.template,name:l10n_be.a7010
|
||||||
msgid "Ventes en Belgique (produits finis)"
|
msgid "Ventes en Belgique (produits finis)"
|
||||||
msgstr ""
|
msgstr "Verkopen: België (gereed product)"
|
||||||
|
|
||||||
#. module: l10n_be
|
#. module: l10n_be
|
||||||
#: model:account.account.template,name:l10n_be.a7002
|
#: model:account.account.template,name:l10n_be.a7002
|
||||||
msgid "Ventes à l'exportation (marchandises)"
|
msgid "Ventes à l'exportation (marchandises)"
|
||||||
msgstr ""
|
msgstr "Verkopen: export (handelsgoederen)"
|
||||||
|
|
||||||
#. module: l10n_be
|
#. module: l10n_be
|
||||||
#: model:account.account.template,name:l10n_be.a7012
|
#: model:account.account.template,name:l10n_be.a7012
|
||||||
msgid "Ventes à l'exportation (produits finis)"
|
msgid "Ventes à l'exportation (produits finis)"
|
||||||
msgstr ""
|
msgstr "Verkopen: export (gereed product)"
|
||||||
|
|
||||||
#. module: l10n_be
|
#. module: l10n_be
|
||||||
#: model:account.account.template,name:l10n_be.a24100
|
#: model:account.account.template,name:l10n_be.a24100
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -98,7 +98,20 @@ class PadCommon(models.AbstractModel):
|
|||||||
@api.model
|
@api.model
|
||||||
def create(self, vals):
|
def create(self, vals):
|
||||||
self._set_pad_value(vals)
|
self._set_pad_value(vals)
|
||||||
return super(PadCommon, self).create(vals)
|
pad = super(PadCommon, self).create(vals)
|
||||||
|
|
||||||
|
# In case the pad is created programmatically, the content is not filled in yet since it is
|
||||||
|
# normally initialized by the JS layer
|
||||||
|
for k, field in self._fields.iteritems():
|
||||||
|
if hasattr(field, 'pad_content_field') and k not in vals:
|
||||||
|
ctx = {
|
||||||
|
'model': self._name,
|
||||||
|
'field_name': k,
|
||||||
|
'object_id': pad.id,
|
||||||
|
}
|
||||||
|
pad_info = self.with_context(**ctx).pad_generate_url()
|
||||||
|
pad[k] = pad_info.get('url')
|
||||||
|
return pad
|
||||||
|
|
||||||
# Set the pad content in vals
|
# Set the pad content in vals
|
||||||
def _set_pad_value(self, vals):
|
def _set_pad_value(self, vals):
|
||||||
|
|||||||
@@ -571,7 +571,7 @@ class PosOrder(models.Model):
|
|||||||
Move += Move.create({
|
Move += Move.create({
|
||||||
'name': line.name,
|
'name': line.name,
|
||||||
'product_uom': line.product_id.uom_id.id,
|
'product_uom': line.product_id.uom_id.id,
|
||||||
'picking_id': picking_id.id,
|
'picking_id': picking_id and picking_id.id or False,
|
||||||
'picking_type_id': picking_type.id,
|
'picking_type_id': picking_type.id,
|
||||||
'product_id': line.product_id.id,
|
'product_id': line.product_id.id,
|
||||||
'product_uom_qty': abs(line.qty),
|
'product_uom_qty': abs(line.qty),
|
||||||
|
|||||||
@@ -1081,9 +1081,9 @@ class MailComposeMessage(models.TransientModel):
|
|||||||
|
|
||||||
@api.multi
|
@api.multi
|
||||||
def send_mail(self, auto_commit=False):
|
def send_mail(self, auto_commit=False):
|
||||||
compose_internal = self.filtered('subtype_id.internal')
|
if self._context.get('default_model') == 'purchase.order' and self._context.get('default_res_id'):
|
||||||
if self._context.get('default_model') == 'purchase.order' and self._context.get('default_res_id') and not compose_internal:
|
if not self.filtered('subtype_id.internal'):
|
||||||
order = self.env['purchase.order'].browse([self._context['default_res_id']])
|
order = self.env['purchase.order'].browse([self._context['default_res_id']])
|
||||||
if order.state == 'draft':
|
if order.state == 'draft':
|
||||||
order.state = 'sent'
|
order.state = 'sent'
|
||||||
return super(MailComposeMessage, self.with_context(mail_post_autofollow=True)).send_mail(auto_commit=auto_commit)
|
return super(MailComposeMessage, self.with_context(mail_post_autofollow=True)).send_mail(auto_commit=auto_commit)
|
||||||
|
|||||||
@@ -136,8 +136,7 @@ class Report(models.Model):
|
|||||||
'doc_model': report.model,
|
'doc_model': report.model,
|
||||||
'docs': docs,
|
'docs': docs,
|
||||||
}
|
}
|
||||||
return self.render(report.report_name, docargs).encode('utf-8')
|
return self.render(report.report_name, docargs)
|
||||||
|
|
||||||
@api.model
|
@api.model
|
||||||
def get_pdf(self, docids, report_name, html=None, data=None):
|
def get_pdf(self, docids, report_name, html=None, data=None):
|
||||||
"""This method generates and returns pdf version of a report.
|
"""This method generates and returns pdf version of a report.
|
||||||
@@ -172,6 +171,8 @@ class Report(models.Model):
|
|||||||
if isinstance(self.env.cr, TestCursor):
|
if isinstance(self.env.cr, TestCursor):
|
||||||
return html
|
return html
|
||||||
|
|
||||||
|
html = html.decode('utf-8') # Ensure the current document is utf-8 encoded.
|
||||||
|
|
||||||
# Get the ir.actions.report.xml record we are working on.
|
# Get the ir.actions.report.xml record we are working on.
|
||||||
report = self._get_report_from_name(report_name)
|
report = self._get_report_from_name(report_name)
|
||||||
# Check if we have to save the report or if we have to get one from the db.
|
# Check if we have to save the report or if we have to get one from the db.
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import json
|
|||||||
|
|
||||||
from odoo import http
|
from odoo import http
|
||||||
from odoo.http import request
|
from odoo.http import request
|
||||||
|
from odoo.tools import ustr
|
||||||
from odoo.tools.misc import xlwt
|
from odoo.tools.misc import xlwt
|
||||||
|
|
||||||
|
|
||||||
@@ -69,7 +70,7 @@ class TableExporter(http.Controller):
|
|||||||
# Step 3: writing data
|
# Step 3: writing data
|
||||||
x = 0
|
x = 0
|
||||||
for row in jdata['rows']:
|
for row in jdata['rows']:
|
||||||
worksheet.write(y, x, row['indent'] * ' ' + row['title'], header_plain)
|
worksheet.write(y, x, row['indent'] * ' ' + ustr(row['title']), header_plain)
|
||||||
for cell in row['values']:
|
for cell in row['values']:
|
||||||
x = x + 1
|
x = x + 1
|
||||||
if cell.get('is_bold', False):
|
if cell.get('is_bold', False):
|
||||||
|
|||||||
@@ -129,7 +129,7 @@ ExtendedSearchProposition.Field = Widget.extend({
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
show_inputs: function ($operator) {
|
show_inputs: function ($operator) {
|
||||||
var $value = this.$('.o_searchview_extended_prop_value');
|
var $value = this.$el.parent();
|
||||||
switch ($operator.val()) {
|
switch ($operator.val()) {
|
||||||
case '∃':
|
case '∃':
|
||||||
case '∄':
|
case '∄':
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
<!-- These templates are accessible in backend and frontend -->
|
<!-- These templates are accessible in backend and frontend -->
|
||||||
|
|
||||||
<div t-name="Dialog" class="modal" tabindex="-1" data-backdrop="static" role="dialog" aria-hidden="true">
|
<div t-name="Dialog" class="modal" tabindex="-1" data-backdrop="static" role="dialog" aria-hidden="true" t-att-id="_.uniqueId('modal_')">
|
||||||
<div class="modal-dialog">
|
<div class="modal-dialog">
|
||||||
<div class="modal-content">
|
<div class="modal-content">
|
||||||
<div class="modal-header">
|
<div class="modal-header">
|
||||||
|
|||||||
@@ -616,7 +616,6 @@ define([
|
|||||||
var linkUrl = linkInfo.url;
|
var linkUrl = linkInfo.url;
|
||||||
var linkText = linkInfo.text;
|
var linkText = linkInfo.text;
|
||||||
var isNewWindow = linkInfo.isNewWindow;
|
var isNewWindow = linkInfo.isNewWindow;
|
||||||
var className = linkInfo.className || null; // ODOO: addition
|
|
||||||
var rng = linkInfo.range || this.createRange($editable);
|
var rng = linkInfo.range || this.createRange($editable);
|
||||||
var isTextChanged = rng.toString() !== linkText;
|
var isTextChanged = rng.toString() !== linkText;
|
||||||
|
|
||||||
@@ -647,7 +646,8 @@ define([
|
|||||||
|
|
||||||
$.each(anchors, function (idx, anchor) {
|
$.each(anchors, function (idx, anchor) {
|
||||||
$(anchor).attr('href', linkUrl);
|
$(anchor).attr('href', linkUrl);
|
||||||
$(anchor).attr('class', className); // ODOO: addition
|
$(anchor).attr('class', linkInfo.className || null); // ODOO: addition
|
||||||
|
$(anchor).css(linkInfo.style || {}); // ODOO: addition
|
||||||
if (isNewWindow) {
|
if (isNewWindow) {
|
||||||
$(anchor).attr('target', '_blank');
|
$(anchor).attr('target', '_blank');
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -509,7 +509,7 @@ var RTE = Widget.extend({
|
|||||||
*/
|
*/
|
||||||
$target.attr('contenteditable', true);
|
$target.attr('contenteditable', true);
|
||||||
_.defer(function () {
|
_.defer(function () {
|
||||||
$editable.attr('contenteditable', false);
|
$editable.not($target).attr('contenteditable', false);
|
||||||
$target.focus();
|
$target.focus();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -1001,10 +1001,12 @@ data.Editor = Class.extend({
|
|||||||
},
|
},
|
||||||
|
|
||||||
on_remove: function (event) {
|
on_remove: function (event) {
|
||||||
event.preventDefault();
|
if (event !== undefined) {
|
||||||
this.on_blur();
|
event.preventDefault();
|
||||||
|
this.buildingBlock.getParent().rte.historyRecordUndo(this.$target);
|
||||||
|
}
|
||||||
|
|
||||||
this.buildingBlock.getParent().rte.historyRecordUndo(this.$target);
|
this.on_blur();
|
||||||
|
|
||||||
var index = _.indexOf(this.buildingBlock.snippets, this.$target.get(0));
|
var index = _.indexOf(this.buildingBlock.snippets, this.$target.get(0));
|
||||||
this.buildingBlock.call_for_all_snippets(this.$target, function (editor, $snippet) {
|
this.buildingBlock.call_for_all_snippets(this.$target, function (editor, $snippet) {
|
||||||
@@ -1037,7 +1039,7 @@ data.Editor = Class.extend({
|
|||||||
}
|
}
|
||||||
if ($parent.children().length === 0 && $parent.text().trim() === "") {
|
if ($parent.children().length === 0 && $parent.text().trim() === "") {
|
||||||
_.defer(function () {
|
_.defer(function () {
|
||||||
$parent.data("snippet-editor").on_remove(event);
|
$parent.data("snippet-editor").on_remove();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -767,7 +767,9 @@ var fontIconsDialog = Widget.extend({
|
|||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
function createVideoNode(url) {
|
function createVideoNode(url, options) {
|
||||||
|
options = options || {};
|
||||||
|
|
||||||
// video url patterns(youtube, instagram, vimeo, dailymotion, youku)
|
// video url patterns(youtube, instagram, vimeo, dailymotion, youku)
|
||||||
var ytRegExp = /^(?:(?:https?:)?\/\/)?(?:www\.)?(?:youtu\.be\/|youtube\.com\/(?:embed\/|v\/|watch\?v=|watch\?.+&v=))((\w|-){11})(?:\S+)?$/;
|
var ytRegExp = /^(?:(?:https?:)?\/\/)?(?:www\.)?(?:youtu\.be\/|youtube\.com\/(?:embed\/|v\/|watch\?v=|watch\?.+&v=))((\w|-){11})(?:\S+)?$/;
|
||||||
var ytMatch = url.match(ytRegExp);
|
var ytMatch = url.match(ytRegExp);
|
||||||
@@ -837,6 +839,10 @@ function createVideoNode(url) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (options.autoplay) {
|
||||||
|
$video.attr("src", $video.attr("src") + "?autoplay=1");
|
||||||
|
}
|
||||||
|
|
||||||
$video.attr('frameborder', 0);
|
$video.attr('frameborder', 0);
|
||||||
|
|
||||||
return $video;
|
return $video;
|
||||||
@@ -851,6 +857,7 @@ var VideoDialog = Widget.extend({
|
|||||||
events : _.extend({}, Dialog.prototype.events, {
|
events : _.extend({}, Dialog.prototype.events, {
|
||||||
'click input#urlvideo ~ button': 'get_video',
|
'click input#urlvideo ~ button': 'get_video',
|
||||||
'click input#embedvideo ~ button': 'get_embed_video',
|
'click input#embedvideo ~ button': 'get_embed_video',
|
||||||
|
'change input#autoplay': 'get_video',
|
||||||
'change input#urlvideo': 'change_input',
|
'change input#urlvideo': 'change_input',
|
||||||
'keyup input#urlvideo': 'change_input',
|
'keyup input#urlvideo': 'change_input',
|
||||||
'change input#embedvideo': 'change_input',
|
'change input#embedvideo': 'change_input',
|
||||||
@@ -869,6 +876,7 @@ var VideoDialog = Widget.extend({
|
|||||||
if ($media.hasClass("media_iframe_video")) {
|
if ($media.hasClass("media_iframe_video")) {
|
||||||
var src = $media.data('src');
|
var src = $media.data('src');
|
||||||
this.$("input#urlvideo").val(src);
|
this.$("input#urlvideo").val(src);
|
||||||
|
this.$("input#autoplay").prop("checked", (src || "").indexOf("autoplay") >= 0);
|
||||||
this.get_video();
|
this.get_video();
|
||||||
}
|
}
|
||||||
return this._super.apply(this, arguments);
|
return this._super.apply(this, arguments);
|
||||||
@@ -893,7 +901,7 @@ var VideoDialog = Widget.extend({
|
|||||||
},
|
},
|
||||||
get_video: function (event) {
|
get_video: function (event) {
|
||||||
if (event) event.preventDefault();
|
if (event) event.preventDefault();
|
||||||
var $video = createVideoNode(this.$("input#urlvideo").val());
|
var $video = createVideoNode(this.$("input#urlvideo").val(), {autoplay: this.$("input#autoplay").is(":checked")});
|
||||||
this.$iframe.replaceWith($video);
|
this.$iframe.replaceWith($video);
|
||||||
this.$iframe = $video;
|
this.$iframe = $video;
|
||||||
return false;
|
return false;
|
||||||
@@ -1084,7 +1092,9 @@ var LinkDialog = Dialog.extend({
|
|||||||
self.data.isNewWindow = new_window;
|
self.data.isNewWindow = new_window;
|
||||||
self.data.text = label;
|
self.data.text = label;
|
||||||
self.data.className = classes.replace(/\s+/gi, ' ').replace(/^\s+|\s+$/gi, '');
|
self.data.className = classes.replace(/\s+/gi, ' ').replace(/^\s+|\s+$/gi, '');
|
||||||
|
if (classes.replace(/(^|[ ])(btn-default|btn-success|btn-primary|btn-info|btn-warning|btn-danger)([ ]|$)/gi, ' ')) {
|
||||||
|
self.data.style = {'background-color': '', 'color': ''};
|
||||||
|
}
|
||||||
self.trigger("save", self.data);
|
self.trigger("save", self.data);
|
||||||
}).then(_super);
|
}).then(_super);
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -210,7 +210,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="text-center mt32">
|
<div class="text-center mt32">
|
||||||
<div class="checkbox">
|
<div class="checkbox">
|
||||||
<label>
|
<label title="The feature might not be supported for every video type">
|
||||||
<input id="autoplay" type="checkbox"/>Autoplay</label>
|
<input id="autoplay" type="checkbox"/>Autoplay</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -122,7 +122,7 @@ class WebsiteBlog(http.Controller):
|
|||||||
|
|
||||||
blog_posts = BlogPost.search(domain, order="post_date desc")
|
blog_posts = BlogPost.search(domain, order="post_date desc")
|
||||||
pager = request.website.pager(
|
pager = request.website.pager(
|
||||||
url=request.httprequest.path,
|
url=request.httprequest.path.partition('/page/')[0],
|
||||||
total=len(blog_posts),
|
total=len(blog_posts),
|
||||||
page=page,
|
page=page,
|
||||||
step=self._blog_post_per_page,
|
step=self._blog_post_per_page,
|
||||||
|
|||||||
@@ -4,7 +4,6 @@
|
|||||||
<xpath expr="//div[@name='mail_button']" position="replace">
|
<xpath expr="//div[@name='mail_button']" position="replace">
|
||||||
<div>
|
<div>
|
||||||
<form action="/website_form/" method="post" data-model_name="crm.lead" data-success_page="/page/website_crm.contactus_thanks" class="s_website_form form-horizontal container-fluid mt32" enctype="multipart/form-data">
|
<form action="/website_form/" method="post" data-model_name="crm.lead" data-success_page="/page/website_crm.contactus_thanks" class="s_website_form form-horizontal container-fluid mt32" enctype="multipart/form-data">
|
||||||
<input type="hidden" name="csrf_token" t-att-value="request.csrf_token()"/>
|
|
||||||
<div class="form-group form-field o_website_form_required_custom">
|
<div class="form-group form-field o_website_form_required_custom">
|
||||||
<label class="col-md-3 col-sm-4 control-label" for="contact_name">Your Name</label>
|
<label class="col-md-3 col-sm-4 control-label" for="contact_name">Your Name</label>
|
||||||
<div class="col-md-7 col-sm-8">
|
<div class="col-md-7 col-sm-8">
|
||||||
|
|||||||
@@ -204,8 +204,8 @@ class CrmLead(models.Model):
|
|||||||
else:
|
else:
|
||||||
message = _('<p>I am not interested by this lead. I have not contacted the lead.</p>')
|
message = _('<p>I am not interested by this lead. I have not contacted the lead.</p>')
|
||||||
partner_ids = self.env['res.partner'].search(
|
partner_ids = self.env['res.partner'].search(
|
||||||
[('id', 'child_of', self.env.uid.partner_id.commercial_partner_id.id)])
|
[('id', 'child_of', self.env.user.partner_id.commercial_partner_id.id)])
|
||||||
self.sudo().message_unsubscribe(partner_ids)
|
self.sudo().message_unsubscribe(partner_ids=partner_ids.ids)
|
||||||
if comment:
|
if comment:
|
||||||
message += '<p>%s</p>' % comment
|
message += '<p>%s</p>' % comment
|
||||||
self.message_post(body=message, subtype="mail.mt_note")
|
self.message_post(body=message, subtype="mail.mt_note")
|
||||||
@@ -213,8 +213,8 @@ class CrmLead(models.Model):
|
|||||||
'partner_assigned_id': False
|
'partner_assigned_id': False
|
||||||
}
|
}
|
||||||
if partner_ids:
|
if partner_ids:
|
||||||
values['partner_declined_ids'] = map(lambda p: (4, p, 0), partner_ids)
|
values['partner_declined_ids'] = map(lambda p: (4, p, 0), partner_ids.ids)
|
||||||
self.write(values)
|
self.sudo().write(values)
|
||||||
|
|
||||||
@api.multi
|
@api.multi
|
||||||
def update_lead_portal(self, values):
|
def update_lead_portal(self, values):
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ $('.interested_partner_assign_confirm').on('click',function(e){
|
|||||||
$('.desinterested_partner_assign_confirm').on('click',function(e){
|
$('.desinterested_partner_assign_confirm').on('click',function(e){
|
||||||
new Model('crm.lead')
|
new Model('crm.lead')
|
||||||
.call("partner_desinterested",
|
.call("partner_desinterested",
|
||||||
[[$('.desinterested_partner_assign_form .assign_lead_id').val()],
|
[[parseInt($('.desinterested_partner_assign_form .assign_lead_id').val())],
|
||||||
$('.desinterested_partner_assign_form .comment_desinterested').val(),
|
$('.desinterested_partner_assign_form .comment_desinterested').val(),
|
||||||
$('.desinterested_partner_assign_form .contacted_desinterested').prop('checked')])
|
$('.desinterested_partner_assign_form .contacted_desinterested').prop('checked')])
|
||||||
.then(function(){
|
.then(function(){
|
||||||
|
|||||||
@@ -132,7 +132,6 @@
|
|||||||
<div class="row">
|
<div class="row">
|
||||||
<section id="forms">
|
<section id="forms">
|
||||||
<form action="/website_form/" method="post" class="s_website_form form-horizontal container-fluid mt32" enctype="multipart/form-data" data-model_name="hr.applicant" data-success_page="/page/website_hr_recruitment.thankyou" t-att-data-form_field_department_id="job and job.department_id.id or False" t-att-data-form_field_job_id="job and job.id or False">
|
<form action="/website_form/" method="post" class="s_website_form form-horizontal container-fluid mt32" enctype="multipart/form-data" data-model_name="hr.applicant" data-success_page="/page/website_hr_recruitment.thankyou" t-att-data-form_field_department_id="job and job.department_id.id or False" t-att-data-form_field_job_id="job and job.id or False">
|
||||||
<input type="hidden" name="csrf_token" t-att-value="request.csrf_token()"/>
|
|
||||||
<div class="form-group form-field o_website_form_required_custom">
|
<div class="form-group form-field o_website_form_required_custom">
|
||||||
<div class="col-md-3 col-sm-4 text-right">
|
<div class="col-md-3 col-sm-4 text-right">
|
||||||
<label class="control-label" for="partner_name">Your Name</label>
|
<label class="control-label" for="partner_name">Your Name</label>
|
||||||
|
|||||||
@@ -130,6 +130,10 @@ preserve order.
|
|||||||
* ``record in set`` returns whether ``record`` (which must be a 1-element
|
* ``record in set`` returns whether ``record`` (which must be a 1-element
|
||||||
recordset) is present in ``set``. ``record not in set`` is the inverse
|
recordset) is present in ``set``. ``record not in set`` is the inverse
|
||||||
operation
|
operation
|
||||||
|
* ``set1 <= set2`` and ``set1 < set2`` return whether ``set1`` is a subset
|
||||||
|
of ``set2`` (resp. strict)
|
||||||
|
* ``set1 >= set2`` and ``set1 > set2`` return whether ``set1`` is a superset
|
||||||
|
of ``set2`` (resp. strict)
|
||||||
* ``set1 | set2`` returns the union of the two recordsets, a new recordset
|
* ``set1 | set2`` returns the union of the two recordsets, a new recordset
|
||||||
containing all records present in either source
|
containing all records present in either source
|
||||||
* ``set1 & set2`` returns the intersection of two recordsets, a new recordset
|
* ``set1 & set2`` returns the intersection of two recordsets, a new recordset
|
||||||
|
|||||||
@@ -341,7 +341,7 @@ The ``request_sftp_access`` method returns a JSON dictionary containing the foll
|
|||||||
SSH_KEYS=/path/to/your/authorized_keys
|
SSH_KEYS=/path/to/your/authorized_keys
|
||||||
KEY="Aw7pItGVKFuZ_FOR3U8VFQ=="
|
KEY="Aw7pItGVKFuZ_FOR3U8VFQ=="
|
||||||
REQUEST_ID="10534"
|
REQUEST_ID="10534"
|
||||||
URL_PARAMS="key=${KEY}&request=${REQUEST}"
|
URL_PARAMS="key=${KEY}&request=${REQUEST_ID}"
|
||||||
|
|
||||||
curl -sS "${REQUEST_SFTP_ACCESS_URL}?${URL_PARAMS}" -F ssh_keys=@${SSH_KEYS} > request_sftp_result.json
|
curl -sS "${REQUEST_SFTP_ACCESS_URL}?${URL_PARAMS}" -F ssh_keys=@${SSH_KEYS} > request_sftp_result.json
|
||||||
|
|
||||||
|
|||||||
@@ -8826,7 +8826,7 @@ msgstr ""
|
|||||||
#. module: base
|
#. module: base
|
||||||
#: code:addons/base/res/res_users.py:316
|
#: code:addons/base/res/res_users.py:316
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "Invalid group by"
|
msgid "Invalid 'group by' parameter"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#. module: base
|
#. module: base
|
||||||
|
|||||||
@@ -414,6 +414,7 @@ class IrModelFields(models.Model):
|
|||||||
any(field.state != 'manual' for field in self):
|
any(field.state != 'manual' for field in self):
|
||||||
raise UserError(_("This column contains module data and cannot be removed!"))
|
raise UserError(_("This column contains module data and cannot be removed!"))
|
||||||
|
|
||||||
|
model_names = self.mapped('model')
|
||||||
self._drop_column()
|
self._drop_column()
|
||||||
res = super(IrModelFields, self).unlink()
|
res = super(IrModelFields, self).unlink()
|
||||||
|
|
||||||
@@ -423,6 +424,8 @@ class IrModelFields(models.Model):
|
|||||||
self._cr.commit()
|
self._cr.commit()
|
||||||
api.Environment.reset()
|
api.Environment.reset()
|
||||||
registry = Registry.new(self._cr.dbname)
|
registry = Registry.new(self._cr.dbname)
|
||||||
|
models = registry.descendants(model_names, '_inherits')
|
||||||
|
registry.init_models(self._cr, models, dict(self._context, update_custom_fields=True))
|
||||||
registry.signal_registry_change()
|
registry.signal_registry_change()
|
||||||
|
|
||||||
return res
|
return res
|
||||||
@@ -455,8 +458,9 @@ class IrModelFields(models.Model):
|
|||||||
if vals['model'] in self.pool:
|
if vals['model'] in self.pool:
|
||||||
# setup models; this re-initializes model in registry
|
# setup models; this re-initializes model in registry
|
||||||
self.pool.setup_models(self._cr, partial=(not self.pool.ready))
|
self.pool.setup_models(self._cr, partial=(not self.pool.ready))
|
||||||
# update database schema
|
# update database schema of model and its descendant models
|
||||||
self.pool.init_models(self._cr, [vals['model']], dict(self._context, update_custom_fields=True))
|
models = self.pool.descendants([vals['model']], '_inherits')
|
||||||
|
self.pool.init_models(self._cr, models, dict(self._context, update_custom_fields=True))
|
||||||
self.pool.signal_registry_change()
|
self.pool.signal_registry_change()
|
||||||
|
|
||||||
return res
|
return res
|
||||||
@@ -538,7 +542,8 @@ class IrModelFields(models.Model):
|
|||||||
|
|
||||||
if patched_models:
|
if patched_models:
|
||||||
# update the database schema of the models to patch
|
# update the database schema of the models to patch
|
||||||
self.pool.init_models(self._cr, patched_models, dict(self._context, update_custom_fields=True))
|
models = self.pool.descendants(patched_models, '_inherits')
|
||||||
|
self.pool.init_models(self._cr, models, dict(self._context, update_custom_fields=True))
|
||||||
|
|
||||||
if column_rename or patched_models:
|
if column_rename or patched_models:
|
||||||
self.pool.signal_registry_change()
|
self.pool.signal_registry_change()
|
||||||
|
|||||||
@@ -246,7 +246,7 @@ class QWeb(object):
|
|||||||
"""
|
"""
|
||||||
body = []
|
body = []
|
||||||
self.compile(template, options)(self, body.append, values or {})
|
self.compile(template, options)(self, body.append, values or {})
|
||||||
return u''.join(body)
|
return u''.join(body).encode('utf8')
|
||||||
|
|
||||||
def compile(self, template, options):
|
def compile(self, template, options):
|
||||||
""" Compile the given template into a rendering function::
|
""" Compile the given template into a rendering function::
|
||||||
|
|||||||
@@ -313,7 +313,7 @@ class Users(models.Model):
|
|||||||
if self._uid != SUPERUSER_ID:
|
if self._uid != SUPERUSER_ID:
|
||||||
groupby_fields = set([groupby] if isinstance(groupby, basestring) else groupby)
|
groupby_fields = set([groupby] if isinstance(groupby, basestring) else groupby)
|
||||||
if groupby_fields.intersection(USER_PRIVATE_FIELDS):
|
if groupby_fields.intersection(USER_PRIVATE_FIELDS):
|
||||||
raise AccessError(_('Invalid group by'))
|
raise AccessError(_("Invalid 'group by' parameter"))
|
||||||
return super(Users, self).read_group(domain, fields, groupby, offset=offset, limit=limit, orderby=orderby, lazy=lazy)
|
return super(Users, self).read_group(domain, fields, groupby, offset=offset, limit=limit, orderby=orderby, lazy=lazy)
|
||||||
|
|
||||||
@api.model
|
@api.model
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ class TestQWebTField(TransactionCase):
|
|||||||
field = etree.Element('span', {'t-field': u'company.name'})
|
field = etree.Element('span', {'t-field': u'company.name'})
|
||||||
company = self.env['res.company'].create({'name': "My Test Company"})
|
company = self.env['res.company'].create({'name': "My Test Company"})
|
||||||
|
|
||||||
result = self.engine.render(field, {'company': company}).encode('utf-8')
|
result = self.engine.render(field, {'company': company})
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
result,
|
result,
|
||||||
'<span data-oe-model="res.company" data-oe-id="%d" '
|
'<span data-oe-model="res.company" data-oe-id="%d" '
|
||||||
@@ -41,7 +41,7 @@ class TestQWebTField(TransactionCase):
|
|||||||
s = u"Testing «ταБЬℓσ»: 1<2 & 4+1>3, now 20% off!"
|
s = u"Testing «ταБЬℓσ»: 1<2 & 4+1>3, now 20% off!"
|
||||||
company = self.env['res.company'].create({'name': s})
|
company = self.env['res.company'].create({'name': s})
|
||||||
|
|
||||||
result = self.engine.render(field, {'company': company}).encode('utf-8')
|
result = self.engine.render(field, {'company': company})
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
result,
|
result,
|
||||||
'<span data-oe-model="res.company" data-oe-id="%d" '
|
'<span data-oe-model="res.company" data-oe-id="%d" '
|
||||||
@@ -56,13 +56,13 @@ class TestQWebTField(TransactionCase):
|
|||||||
field = etree.Element('td', {'t-field': u'company.name'})
|
field = etree.Element('td', {'t-field': u'company.name'})
|
||||||
|
|
||||||
with self.assertRaisesRegexp(QWebException, r'^RTE widgets do not work correctly'):
|
with self.assertRaisesRegexp(QWebException, r'^RTE widgets do not work correctly'):
|
||||||
self.engine.render(field, {'company': None}).encode('utf-8')
|
self.engine.render(field, {'company': None})
|
||||||
|
|
||||||
def test_reject_t_tag(self):
|
def test_reject_t_tag(self):
|
||||||
field = etree.Element('t', {'t-field': u'company.name'})
|
field = etree.Element('t', {'t-field': u'company.name'})
|
||||||
|
|
||||||
with self.assertRaisesRegexp(QWebException, r'^t-field can not be used on a t element'):
|
with self.assertRaisesRegexp(QWebException, r'^t-field can not be used on a t element'):
|
||||||
self.engine.render(field, {'company': None}).encode('utf-8')
|
self.engine.render(field, {'company': None})
|
||||||
|
|
||||||
|
|
||||||
from copy import deepcopy
|
from copy import deepcopy
|
||||||
@@ -128,7 +128,7 @@ class TestQWeb(TransactionCase):
|
|||||||
|
|
||||||
result = doc.find('result[@id="{}"]'.format(template)).text
|
result = doc.find('result[@id="{}"]'.format(template)).text
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
qweb.render(template, values=params, load=loader).strip().encode('utf-8'),
|
qweb.render(template, values=params, load=loader).strip(),
|
||||||
(result or u'').strip().encode('utf-8'),
|
(result or u'').strip().encode('utf-8'),
|
||||||
template
|
template
|
||||||
)
|
)
|
||||||
|
|||||||
+9
-3
@@ -377,6 +377,7 @@ class BaseModel(object):
|
|||||||
cr.execute(query, vals)
|
cr.execute(query, vals)
|
||||||
self.invalidate_cache()
|
self.invalidate_cache()
|
||||||
|
|
||||||
|
|
||||||
@api.model
|
@api.model
|
||||||
def _add_field(self, name, field):
|
def _add_field(self, name, field):
|
||||||
""" Add the given ``field`` under the given ``name`` in the class """
|
""" Add the given ``field`` under the given ``name`` in the class """
|
||||||
@@ -536,6 +537,7 @@ class BaseModel(object):
|
|||||||
'_register': False,
|
'_register': False,
|
||||||
'_original_module': cls._module,
|
'_original_module': cls._module,
|
||||||
'_inherit_children': OrderedSet(), # names of children models
|
'_inherit_children': OrderedSet(), # names of children models
|
||||||
|
'_inherits_children': set(), # names of children models
|
||||||
'_fields': {}, # populated in _setup_base()
|
'_fields': {}, # populated in _setup_base()
|
||||||
})
|
})
|
||||||
check_parent = cls._build_model_check_parent
|
check_parent = cls._build_model_check_parent
|
||||||
@@ -633,7 +635,11 @@ class BaseModel(object):
|
|||||||
cls._sequence = cls._sequence or (cls._table + '_id_seq')
|
cls._sequence = cls._sequence or (cls._table + '_id_seq')
|
||||||
cls._constraints = cls._constraints.values()
|
cls._constraints = cls._constraints.values()
|
||||||
|
|
||||||
# recompute attributes of children models
|
# update _inherits_children of parent models
|
||||||
|
for parent_name in cls._inherits:
|
||||||
|
pool[parent_name]._inherits_children.add(cls._name)
|
||||||
|
|
||||||
|
# recompute attributes of _inherit_children models
|
||||||
for child_name in cls._inherit_children:
|
for child_name in cls._inherit_children:
|
||||||
child_class = pool[child_name]
|
child_class = pool[child_name]
|
||||||
child_class._build_model_attributes(pool)
|
child_class._build_model_attributes(pool)
|
||||||
@@ -1933,7 +1939,7 @@ class BaseModel(object):
|
|||||||
"""
|
"""
|
||||||
result = self._read_group_raw(domain, fields, groupby, offset=offset, limit=limit, orderby=orderby, lazy=lazy)
|
result = self._read_group_raw(domain, fields, groupby, offset=offset, limit=limit, orderby=orderby, lazy=lazy)
|
||||||
|
|
||||||
groupby = [groupby] if isinstance(groupby, basestring) else groupby
|
groupby = [groupby] if isinstance(groupby, basestring) else list(OrderedSet(groupby))
|
||||||
dt = [
|
dt = [
|
||||||
f for f in groupby
|
f for f in groupby
|
||||||
if self._fields[f.split(':')[0]].type in ('date', 'datetime')
|
if self._fields[f.split(':')[0]].type in ('date', 'datetime')
|
||||||
@@ -1957,7 +1963,7 @@ class BaseModel(object):
|
|||||||
query = self._where_calc(domain)
|
query = self._where_calc(domain)
|
||||||
fields = fields or [f.name for f in self._fields.itervalues() if f.store]
|
fields = fields or [f.name for f in self._fields.itervalues() if f.store]
|
||||||
|
|
||||||
groupby = [groupby] if isinstance(groupby, basestring) else groupby
|
groupby = [groupby] if isinstance(groupby, basestring) else list(OrderedSet(groupby))
|
||||||
groupby_list = groupby[:1] if lazy else groupby
|
groupby_list = groupby[:1] if lazy else groupby
|
||||||
annotated_groupbys = [self._read_group_process_groupby(gb, query) for gb in groupby_list]
|
annotated_groupbys = [self._read_group_process_groupby(gb, query) for gb in groupby_list]
|
||||||
groupby_fields = [g['field'] for g in annotated_groupbys]
|
groupby_fields = [g['field'] for g in annotated_groupbys]
|
||||||
|
|||||||
+23
-12
@@ -4,16 +4,17 @@
|
|||||||
""" Models registries.
|
""" Models registries.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
from collections import Mapping, defaultdict
|
from collections import Mapping, defaultdict, deque
|
||||||
from contextlib import closing
|
from contextlib import closing
|
||||||
|
from operator import attrgetter
|
||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
import threading
|
import threading
|
||||||
|
|
||||||
import odoo
|
import odoo
|
||||||
from .. import SUPERUSER_ID
|
from .. import SUPERUSER_ID
|
||||||
from odoo.tools import assertion_report, lazy_classproperty, config, \
|
from odoo.tools import (assertion_report, lazy_classproperty, config,
|
||||||
lazy_property, topological_sort, OrderedSet
|
lazy_property, topological_sort, OrderedSet)
|
||||||
from odoo.tools.lru import LRU
|
from odoo.tools.lru import LRU
|
||||||
|
|
||||||
_logger = logging.getLogger(__name__)
|
_logger = logging.getLogger(__name__)
|
||||||
@@ -222,6 +223,22 @@ class Registry(Mapping):
|
|||||||
env[model_name]._parent_store_compute()
|
env[model_name]._parent_store_compute()
|
||||||
self._init = False
|
self._init = False
|
||||||
|
|
||||||
|
def descendants(self, model_names, *kinds):
|
||||||
|
""" Return the models corresponding to ``model_names`` and all those
|
||||||
|
that inherit/inherits from them.
|
||||||
|
"""
|
||||||
|
assert all(kind in ('_inherit', '_inherits') for kind in kinds)
|
||||||
|
funcs = [attrgetter(kind + '_children') for kind in kinds]
|
||||||
|
|
||||||
|
models = OrderedSet()
|
||||||
|
queue = deque(model_names)
|
||||||
|
while queue:
|
||||||
|
model = self[queue.popleft()]
|
||||||
|
models.add(model)
|
||||||
|
for func in funcs:
|
||||||
|
queue.extend(func(model))
|
||||||
|
return models
|
||||||
|
|
||||||
def load(self, cr, module):
|
def load(self, cr, module):
|
||||||
""" Load a given module in the registry, and return the names of the
|
""" Load a given module in the registry, and return the names of the
|
||||||
modified models.
|
modified models.
|
||||||
@@ -234,23 +251,17 @@ class Registry(Mapping):
|
|||||||
"""
|
"""
|
||||||
from .. import models
|
from .. import models
|
||||||
|
|
||||||
loaded_models = OrderedSet()
|
|
||||||
def mark_loaded(model):
|
|
||||||
# recursively mark model and its children
|
|
||||||
loaded_models.add(model._name)
|
|
||||||
for child_name in model._inherit_children:
|
|
||||||
mark_loaded(self[child_name])
|
|
||||||
|
|
||||||
lazy_property.reset_all(self)
|
lazy_property.reset_all(self)
|
||||||
|
|
||||||
# Instantiate registered classes (via the MetaModel automatic discovery
|
# Instantiate registered classes (via the MetaModel automatic discovery
|
||||||
# or via explicit constructor call), and add them to the pool.
|
# or via explicit constructor call), and add them to the pool.
|
||||||
|
model_names = []
|
||||||
for cls in models.MetaModel.module_to_models.get(module.name, []):
|
for cls in models.MetaModel.module_to_models.get(module.name, []):
|
||||||
# models register themselves in self.models
|
# models register themselves in self.models
|
||||||
model = cls._build_model(self, cr)
|
model = cls._build_model(self, cr)
|
||||||
mark_loaded(model)
|
model_names.append(model._name)
|
||||||
|
|
||||||
return list(loaded_models)
|
return self.descendants(model_names, '_inherit')
|
||||||
|
|
||||||
def setup_models(self, cr, partial=False):
|
def setup_models(self, cr, partial=False):
|
||||||
""" Complete the setup of models.
|
""" Complete the setup of models.
|
||||||
|
|||||||
Reference in New Issue
Block a user