summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristophe Simonis <chs@odoo.com>2018-06-15 11:30:27 +0200
committerChristophe Simonis <chs@odoo.com>2018-06-15 11:30:27 +0200
commit50860317ccd2c1b44f873598858a3cff87fa7ea6 (patch)
tree2b752e71a34a062112c2e28acf4a2993336ec3e6
parent42ba1298d8d908c6d34b64f25be4e5c71e7888a3 (diff)
parentb170a753e18c96f59e8c99a4e1750a4b85628338 (diff)
[MERGE] forward port branch saas-11.2 up to b170a753e18
-rw-r--r--addons/account/i18n/ru.po7
-rw-r--r--addons/account/models/account_invoice.py13
-rw-r--r--addons/account/models/res_config_settings.py2
-rw-r--r--addons/account/views/account_journal_dashboard_view.xml12
-rw-r--r--addons/account/views/report_journal.xml2
-rw-r--r--addons/account_bank_statement_import/account_bank_statement_import.py6
-rw-r--r--addons/account_check_printing/i18n/tr.po5
-rw-r--r--addons/base_address_city/models/res_partner.py2
-rw-r--r--addons/board/static/src/js/favorite_menu.js5
-rw-r--r--addons/crm/models/crm_lead.py2
-rw-r--r--addons/event/i18n/tr.po2
-rw-r--r--addons/event/models/event.py7
-rw-r--r--addons/event/models/res_partner.py2
-rw-r--r--addons/event/report/event_event_templates.xml2
-rw-r--r--addons/event/views/res_partner_views.xml1
-rw-r--r--addons/event_sale/i18n/tr.po2
-rw-r--r--addons/fleet/i18n/tr.po2
-rw-r--r--addons/fleet/views/fleet_vehicle_views.xml11
-rw-r--r--addons/google_calendar/i18n/tr.po2
-rw-r--r--addons/hr_holidays/models/hr_leave.py2
-rw-r--r--addons/hr_recruitment/i18n/pt_BR.po29
-rw-r--r--addons/hr_recruitment/views/hr_job_views.xml2
-rw-r--r--addons/hr_recruitment_survey/i18n/pt_BR.po23
-rw-r--r--addons/hr_timesheet_attendance/i18n/tr.po2
-rw-r--r--addons/iap/i18n/tr.po2
-rw-r--r--addons/im_livechat/i18n/tr.po5
-rw-r--r--addons/l10n_nl/data/account_tax_template.xml4
-rw-r--r--addons/link_tracker/i18n/tr.po8
-rw-r--r--addons/lunch/i18n/tr.po2
-rw-r--r--addons/mail/i18n/tr.po67
-rw-r--r--addons/mail/static/src/js/services/chat_manager.js2
-rw-r--r--addons/mail/static/src/js/systray.js8
-rw-r--r--addons/maintenance/i18n/tr.po2
-rw-r--r--addons/mass_mailing/i18n/tr.po6
-rw-r--r--addons/mass_mailing/static/src/js/mass_mailing.js2
-rw-r--r--addons/mass_mailing_event_track/models/event.py2
-rw-r--r--addons/mrp/models/mrp_bom.py2
-rw-r--r--addons/mrp/models/mrp_workorder.py1
-rw-r--r--addons/mrp/models/stock_move.py7
-rw-r--r--addons/mrp/views/mrp_workorder_views.xml6
-rw-r--r--addons/payment_authorize/models/payment.py13
-rw-r--r--addons/payment_ogone/controllers/main.py2
-rw-r--r--addons/payment_stripe/static/src/js/stripe.js82
-rw-r--r--addons/phone_validation/i18n/tr.po2
-rw-r--r--addons/point_of_sale/i18n/tr.po3
-rw-r--r--addons/point_of_sale/models/pos_session.py4
-rw-r--r--addons/point_of_sale/models/product.py12
-rw-r--r--addons/point_of_sale/static/src/js/models.js3
-rw-r--r--addons/portal/controllers/mail.py2
-rw-r--r--addons/portal/i18n/tr.po2
-rw-r--r--addons/portal/wizard/portal_wizard.py2
-rw-r--r--addons/pos_cache/i18n/tr.po2
-rw-r--r--addons/pos_restaurant/i18n/tr.po6
-rw-r--r--addons/product/models/product.py2
-rw-r--r--addons/product/models/product_attribute.py3
-rw-r--r--addons/product/tests/__init__.py2
-rw-r--r--addons/product/tests/test_seller.py28
-rw-r--r--addons/product_expiry/i18n/tr.po2
-rw-r--r--addons/project/controllers/portal.py2
-rw-r--r--addons/project/i18n/tr.po2
-rw-r--r--addons/project/models/project.py2
-rw-r--r--addons/purchase/models/purchase.py2
-rw-r--r--addons/purchase/views/purchase_template.xml2
-rw-r--r--addons/repair/i18n/tr.po2
-rw-r--r--addons/repair/models/repair.py17
-rw-r--r--addons/repair/report/repair_templates_repair_order.xml3
-rw-r--r--addons/sale/report/report_all_channels_sales_views.xml2
-rw-r--r--addons/sale_payment/i18n/tr.po2
-rw-r--r--addons/sale_timesheet/__init__.py11
-rw-r--r--addons/sale_timesheet/__manifest__.py1
-rw-r--r--addons/stock/i18n/tr.po6
-rw-r--r--addons/stock/models/product.py6
-rw-r--r--addons/stock/models/stock_move.py26
-rw-r--r--addons/stock/report/report_stockpicking_operations.xml7
-rw-r--r--addons/stock/tests/test_move.py74
-rw-r--r--addons/stock_account/models/product.py63
-rw-r--r--addons/stock_account/models/stock.py3
-rw-r--r--addons/stock_account/tests/test_stockvaluation.py152
-rw-r--r--addons/web/static/lib/qweb/qweb-test-widgets.xml26
-rw-r--r--addons/web/static/src/js/chrome/abstract_web_client.js2
-rw-r--r--addons/web/static/src/js/chrome/loading.js6
-rw-r--r--addons/web/static/src/js/core/ajax.js51
-rw-r--r--addons/web/static/src/js/core/session.js50
-rw-r--r--addons/web/static/src/js/fields/basic_fields.js8
-rw-r--r--addons/web_editor/static/lib/summernote/src/js/module/Editor.js4
-rw-r--r--addons/web_editor/static/src/js/editor/rte.summernote.js2
-rw-r--r--addons/web_editor/static/src/js/widgets/widgets.js2
-rw-r--r--addons/website/models/ir_http.py5
-rw-r--r--addons/website/models/ir_model.py4
-rw-r--r--addons/website_event/controllers/main.py2
-rw-r--r--addons/website_event/static/src/js/website_event.js4
-rw-r--r--addons/website_event_track/views/event_track_templates.xml4
-rw-r--r--addons/website_forum/models/forum.py5
-rw-r--r--addons/website_livechat/controllers/main.py10
-rw-r--r--addons/website_mass_mailing/controllers/main.py2
-rw-r--r--addons/website_sale_stock/models/product_product.py2
-rw-r--r--addons/website_sale_wishlist/models/product_wishlist.py7
-rw-r--r--doc/cla/corporate/adhoc.md1
-rw-r--r--doc/cla/corporate/eficent.md1
-rw-r--r--doc/cla/corporate/modoolar.md19
-rw-r--r--doc/cla/corporate/shine-it.md17
-rw-r--r--doc/cla/corporate/tvtmarine-automation.md4
-rw-r--r--doc/cla/individual/Zelwak.md11
-rw-r--r--doc/cla/individual/mduvergey.md11
-rw-r--r--doc/cla/individual/schout-it.md11
-rw-r--r--doc/howtos/themes.rst2
-rw-r--r--doc/reference/cmdline.rst39
-rw-r--r--doc/reference/javascript_reference.rst18
-rw-r--r--doc/setup/enterprise.rst2
-rw-r--r--odoo/addons/base/data/res.country.state.csv2
-rw-r--r--odoo/addons/base/data/res_country_data.xml5
-rw-r--r--odoo/addons/base/i18n/tr.po545
-rw-r--r--odoo/addons/base/models/ir_mail_server.py6
-rw-r--r--odoo/addons/base/models/ir_model.py2
-rw-r--r--odoo/addons/base/models/qweb.py7
-rw-r--r--odoo/addons/base/models/res_users.py5
-rw-r--r--odoo/addons/base/rng/tree_view.rng2
-rw-r--r--odoo/addons/base/security/base_security.xml2
-rw-r--r--odoo/addons/base/tests/test_qweb.py21
-rw-r--r--odoo/addons/test_new_api/tests/test_new_fields.py13
-rw-r--r--odoo/addons/test_pylint/tests/test_pylint.py8
-rw-r--r--odoo/http.py8
-rw-r--r--odoo/models.py4
-rw-r--r--odoo/modules/registry.py4
-rw-r--r--odoo/service/db.py1
-rw-r--r--odoo/service/security.py20
-rw-r--r--odoo/service/server.py6
-rw-r--r--odoo/tests/common.py2
-rw-r--r--odoo/tools/misc.py12
-rw-r--r--setup.py1
130 files changed, 1279 insertions, 557 deletions
diff --git a/addons/account/i18n/ru.po b/addons/account/i18n/ru.po
index a3f724f574f..71955ffdde2 100644
--- a/addons/account/i18n/ru.po
+++ b/addons/account/i18n/ru.po
@@ -35,13 +35,14 @@
# Yuriy Ney <k_wizard@mail.ru>, 2017
# Yuriy Ney <kwizardn@gmail.com>, 2018
# sergeiruzkiicode <sergei.ruzki@icode.by>, 2018
+# Илья Пономарев <horochiy92@gmail.com>, 2018
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server saas~11.2\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2018-03-22 14:10+0000\n"
"PO-Revision-Date: 2018-03-22 14:10+0000\n"
-"Last-Translator: sergeiruzkiicode <sergei.ruzki@icode.by>, 2018\n"
+"Last-Translator: Илья Пономарев <horochiy92@gmail.com>, 2018\n"
"Language-Team: Russian (https://www.transifex.com/odoo/teams/41243/ru/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
@@ -4790,12 +4791,12 @@ msgstr ""
#. module: account
#: model:ir.ui.view,arch_db:account.res_config_settings_view_form
msgid "Import your bank statements in CAMT.053"
-msgstr ""
+msgstr "Импорт банковской выписки в формате CAMT.053"
#. module: account
#: model:ir.ui.view,arch_db:account.res_config_settings_view_form
msgid "Import your bank statements in CSV"
-msgstr ""
+msgstr "Импорт Банковской Выписки в формате CSV"
#. module: account
#: model:ir.ui.view,arch_db:account.res_config_settings_view_form
diff --git a/addons/account/models/account_invoice.py b/addons/account/models/account_invoice.py
index 020d725e3ca..786832d1bb0 100644
--- a/addons/account/models/account_invoice.py
+++ b/addons/account/models/account_invoice.py
@@ -396,7 +396,7 @@ class AccountInvoice(models.Model):
""" computes the prefix of the number that will be assigned to the first invoice/bill/refund of a journal, in order to
let the user manually change it.
"""
- if not self.env.user._is_admin():
+ if not self.env.user._is_system():
for invoice in self:
invoice.sequence_number_next_prefix = False
invoice.sequence_number_next = ''
@@ -1523,6 +1523,13 @@ class AccountInvoiceLine(models.Model):
return accounts['income']
return accounts['expense']
+ def _set_currency(self):
+ company = self.invoice_id.company_id
+ currency = self.invoice_id.currency_id
+ if company and currency:
+ if company.currency_id != currency:
+ self.price_unit = self.price_unit * currency.with_context(dict(self._context or {}, date=self.invoice_id.date_invoice)).rate
+
def _set_taxes(self):
""" Used in on_change to set taxes and price."""
if self.invoice_id.type in ('out_invoice', 'out_refund'):
@@ -1541,8 +1548,10 @@ class AccountInvoiceLine(models.Model):
prec = self.env['decimal.precision'].precision_get('Product Price')
if not self.price_unit or float_compare(self.price_unit, self.product_id.standard_price, precision_digits=prec) == 0:
self.price_unit = fix_price(self.product_id.standard_price, taxes, fp_taxes)
+ self._set_currency()
else:
self.price_unit = fix_price(self.product_id.lst_price, taxes, fp_taxes)
+ self._set_currency()
@api.onchange('product_id')
def _onchange_product_id(self):
@@ -1591,8 +1600,6 @@ class AccountInvoiceLine(models.Model):
domain['uom_id'] = [('category_id', '=', product.uom_id.category_id.id)]
if company and currency:
- if company.currency_id != currency:
- self.price_unit = self.price_unit * currency.with_context(dict(self._context or {}, date=self.invoice_id.date_invoice)).rate
if self.uom_id and self.uom_id.id != product.uom_id.id:
self.price_unit = product.uom_id._compute_price(self.price_unit, self.uom_id)
diff --git a/addons/account/models/res_config_settings.py b/addons/account/models/res_config_settings.py
index d4593130d2c..231bae4b54b 100644
--- a/addons/account/models/res_config_settings.py
+++ b/addons/account/models/res_config_settings.py
@@ -14,7 +14,7 @@ class ResConfigSettings(models.TransientModel):
'account.journal',
related='company_id.currency_exchange_journal_id',
string="Exchange Gain or Loss Journal",
- domain=[('type', '=', 'general')],
+ domain="[('company_id', '=', company_id), ('type', '=', 'general')]",
help='The accounting journal where automatic exchange differences will be registered')
has_chart_of_accounts = fields.Boolean(compute='_compute_has_chart_of_accounts', string='Company has a chart of accounts')
chart_template_id = fields.Many2one('account.chart.template', string='Template',
diff --git a/addons/account/views/account_journal_dashboard_view.xml b/addons/account/views/account_journal_dashboard_view.xml
index 9c7f1aca551..27f879b8018 100644
--- a/addons/account/views/account_journal_dashboard_view.xml
+++ b/addons/account/views/account_journal_dashboard_view.xml
@@ -248,14 +248,16 @@
<span><t t-esc="dashboard.account_balance"/></span>
</div>
</div>
- <div class="row" name="latest_statement" t-if="dashboard.last_balance != dashboard.account_balance">
- <div class="col-xs-7">
+ <t t-if="dashboard.last_balance != dashboard.account_balance">
+ <div class="row" name="latest_statement">
+ <div class="col-xs-7">
<span title="Latest Statement">Latest Statement</span>
- </div>
- <div class="col-xs-5 text-right">
+ </div>
+ <div class="col-xs-5 text-right">
<span><t t-esc="dashboard.last_balance"/></span>
+ </div>
</div>
- </div>
+ </t>
</div>
</t>
<t t-name="JournalBodySalePurchase" id="account.JournalBodySalePurchase">
diff --git a/addons/account/views/report_journal.xml b/addons/account/views/report_journal.xml
index 06dbab99ae4..c642b89347a 100644
--- a/addons/account/views/report_journal.xml
+++ b/addons/account/views/report_journal.xml
@@ -50,7 +50,7 @@
<td><span t-field="aml.date"/></td>
<td><span t-field="aml.account_id.code"/></td>
<td><span t-esc="aml.sudo().partner_id and aml.sudo().partner_id.name and aml.sudo().partner_id.name[:23] or ''"/></td>
- <td><span t-esc="aml.name[:35]"/></td>
+ <td><span t-esc="aml.name and aml.name[:35]"/></td>
<td><span t-esc="aml.debit" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/></td>
<td><span t-esc="aml.credit" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/></td>
<td t-if="data['form']['amount_currency'] and aml.amount_currency">
diff --git a/addons/account_bank_statement_import/account_bank_statement_import.py b/addons/account_bank_statement_import/account_bank_statement_import.py
index b2862a9c5cb..753b38ff299 100644
--- a/addons/account_bank_statement_import/account_bank_statement_import.py
+++ b/addons/account_bank_statement_import/account_bank_statement_import.py
@@ -50,7 +50,11 @@ class AccountBankStatementImport(models.TransientModel):
# Create the bank statements
statement_ids, notifications = self._create_bank_statements(stmts_vals)
# Now that the import worked out, set it as the bank_statements_source of the journal
- journal.bank_statements_source = 'file_import'
+ if journal.bank_statements_source != 'file_import':
+ # Use sudo() because only 'account.group_account_manager'
+ # has write access on 'account.journal', but 'account.group_account_user'
+ # must be able to import bank statement files
+ journal.sudo().bank_statements_source = 'file_import'
# Finally dispatch to reconciliation interface
action = self.env.ref('account.action_bank_reconcile_bank_statements')
return {
diff --git a/addons/account_check_printing/i18n/tr.po b/addons/account_check_printing/i18n/tr.po
index a57d2d5029c..f22ebc6235d 100644
--- a/addons/account_check_printing/i18n/tr.po
+++ b/addons/account_check_printing/i18n/tr.po
@@ -8,13 +8,14 @@
# Ayhan KIZILTAN <akiziltan76@hotmail.com>, 2018
# Martin Trigaux, 2018
# Alexander B. <road2monstercat@gmail.com>, 2018
+# Umur Akın <umura@projetgrup.com>, 2018
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server saas~11.2\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2018-03-22 14:10+0000\n"
"PO-Revision-Date: 2018-03-22 14:10+0000\n"
-"Last-Translator: Alexander B. <road2monstercat@gmail.com>, 2018\n"
+"Last-Translator: Umur Akın <umura@projetgrup.com>, 2018\n"
"Language-Team: Turkish (https://www.transifex.com/odoo/teams/41243/tr/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
@@ -333,6 +334,8 @@ msgid ""
"The ISO country code in two chars. \n"
"You can use this field for quick search."
msgstr ""
+"İki karakterde ISO ülke kodu.\n"
+"Hızlı arama için bu alanı kullanabilirsiniz."
#. module: account_check_printing
#: code:addons/account_check_printing/models/account_journal.py:26
diff --git a/addons/base_address_city/models/res_partner.py b/addons/base_address_city/models/res_partner.py
index c35430d1f92..07c42694ef1 100644
--- a/addons/base_address_city/models/res_partner.py
+++ b/addons/base_address_city/models/res_partner.py
@@ -10,7 +10,7 @@ from odoo.tools.translate import _
class Partner(models.Model):
_inherit = 'res.partner'
- country_enforce_cities = fields.Boolean(related='country_id.enforce_cities')
+ country_enforce_cities = fields.Boolean(related='country_id.enforce_cities', readonly=True)
city_id = fields.Many2one('res.city', string='City of Address')
@api.onchange('city_id')
diff --git a/addons/board/static/src/js/favorite_menu.js b/addons/board/static/src/js/favorite_menu.js
index 701ebef2801..112b4d634fa 100644
--- a/addons/board/static/src/js/favorite_menu.js
+++ b/addons/board/static/src/js/favorite_menu.js
@@ -99,7 +99,10 @@ FavoriteMenu.include({
})
.then(function (r) {
if (r) {
- self.do_notify(_.str.sprintf(_t("'%s' added to dashboard"), name), '');
+ self.do_notify(
+ _.str.sprintf(_t("'%s' added to dashboard"), name),
+ _t('Please refresh your browser for the changes to take effect.')
+ );
} else {
self.do_warn(_t("Could not add filter to dashboard"));
}
diff --git a/addons/crm/models/crm_lead.py b/addons/crm/models/crm_lead.py
index e7427f36e75..fe739029705 100644
--- a/addons/crm/models/crm_lead.py
+++ b/addons/crm/models/crm_lead.py
@@ -237,6 +237,8 @@ class Lead(models.Model):
@api.model
def _onchange_user_values(self, user_id):
""" returns new values when user_id has changed """
+ if not user_id:
+ return {}
if user_id and self._context.get('team_id'):
team = self.env['crm.team'].browse(self._context['team_id'])
if user_id in team.member_ids.ids:
diff --git a/addons/event/i18n/tr.po b/addons/event/i18n/tr.po
index 67b6aeb2e6f..90c8084cbdc 100644
--- a/addons/event/i18n/tr.po
+++ b/addons/event/i18n/tr.po
@@ -1551,7 +1551,7 @@ msgstr ""
#. module: event
#: model:ir.model,name:event.model_event_confirm
msgid "event.confirm"
-msgstr ""
+msgstr "event.confirm"
#. module: event
#: code:addons/event/models/event.py:503
diff --git a/addons/event/models/event.py b/addons/event/models/event.py
index 1dc2ccb60d6..66292407b99 100644
--- a/addons/event/models/event.py
+++ b/addons/event/models/event.py
@@ -444,9 +444,14 @@ class EventRegistration(models.Model):
@api.multi
def message_get_suggested_recipients(self):
recipients = super(EventRegistration, self).message_get_suggested_recipients()
+ public_users = self.env['res.users'].sudo()
+ public_groups = self.env.ref("base.group_public", raise_if_not_found=False)
+ if public_groups:
+ public_users = public_groups.sudo().with_context(active_test=False).mapped("users")
try:
for attendee in self:
- if attendee.partner_id:
+ is_public = attendee.sudo().with_context(active_test=False).partner_id.user_ids in public_users if public_users else False
+ if attendee.partner_id and not is_public:
attendee._message_add_suggested_recipient(recipients, partner=attendee.partner_id, reason=_('Customer'))
elif attendee.email:
attendee._message_add_suggested_recipient(recipients, email=attendee.email, reason=_('Customer Email'))
diff --git a/addons/event/models/res_partner.py b/addons/event/models/res_partner.py
index d534f3749f2..009b182c1ae 100644
--- a/addons/event/models/res_partner.py
+++ b/addons/event/models/res_partner.py
@@ -9,6 +9,8 @@ class ResPartner(models.Model):
event_count = fields.Integer("Events", compute='_compute_event_count', help="Number of events the partner has participated.")
def _compute_event_count(self):
+ if not self.user_has_groups('event.group_event_user'):
+ return
for partner in self:
partner.event_count = self.env['event.event'].search_count([('registration_ids.partner_id', 'child_of', partner.ids)])
diff --git a/addons/event/report/event_event_templates.xml b/addons/event/report/event_event_templates.xml
index 76b64138f44..8490dc4aaca 100644
--- a/addons/event/report/event_event_templates.xml
+++ b/addons/event/report/event_event_templates.xml
@@ -18,7 +18,7 @@
<img t-att-src="'data:image/png;base64,%s' % to_text(o.event_id.organizer_id.company_id.logo_web)" style="max-height:1cm; max-width:4cm;"/>
</span>
<h5 t-field="o.event_id.name"/>
- <h5>( <i class="fa fa-clock-o"></i> <span itemprop="startDate" t-field="o.event_id.date_begin" t-options='{"hide_seconds": True}'> </span> <i>to</i> <span itemprop="endDate" t-field="o.event_id.date_end" t-options='{"hide_seconds": True}'> </span> )</h5>
+ <h5>( <i class="fa fa-clock-o"></i> <span itemprop="startDate" t-field="o.event_id.with_context(tz=o.event_id.date_tz).date_begin" t-options='{"hide_seconds": True}'> </span> <i>to</i> <span itemprop="endDate" t-field="o.event_id.with_context(tz=o.event_id.date_tz).date_end" t-options='{"hide_seconds": True}'> </span> )</h5>
</div>
<div class="row">
<div class="col-xs-12 text-center" id="o_event_name">
diff --git a/addons/event/views/res_partner_views.xml b/addons/event/views/res_partner_views.xml
index 59d096efcd1..22aeba8686a 100644
--- a/addons/event/views/res_partner_views.xml
+++ b/addons/event/views/res_partner_views.xml
@@ -11,6 +11,7 @@
<button class="oe_stat_button"
type="object"
icon="fa-ticket"
+ groups="event.group_event_user"
name="action_event_view" attrs="{'invisible': [('event_count','=', 0)]}">
<field string="Events" name="event_count" widget="statinfo"/>
</button>
diff --git a/addons/event_sale/i18n/tr.po b/addons/event_sale/i18n/tr.po
index 1cf54f0f8c6..ab1b8afb73f 100644
--- a/addons/event_sale/i18n/tr.po
+++ b/addons/event_sale/i18n/tr.po
@@ -455,7 +455,7 @@ msgstr "Lütfen kayıtlarla ilgili ayrıntıları veriniz."
#. module: event_sale
#: model:ir.model,name:event_sale.model_registration_editor
msgid "registration.editor"
-msgstr ""
+msgstr "registration.editor"
#. module: event_sale
#: model:ir.model,name:event_sale.model_registration_editor_line
diff --git a/addons/fleet/i18n/tr.po b/addons/fleet/i18n/tr.po
index 6986a11fd02..d707676ed82 100644
--- a/addons/fleet/i18n/tr.po
+++ b/addons/fleet/i18n/tr.po
@@ -158,6 +158,8 @@ msgstr "Sözleşmenin hala geçerli olup olmadığını seçin"
msgid ""
"Choose whether the service refer to contracts, vehicle services or both"
msgstr ""
+"Hizmetin sözleşmelerle mi, araç hizmetleriyle mi ya da her ikisiyle de mi "
+"ilgili olduğunu seçin"
#. module: fleet
#: model:ir.ui.view,arch_db:fleet.fleet_vehicle_log_contract_view_form
diff --git a/addons/fleet/views/fleet_vehicle_views.xml b/addons/fleet/views/fleet_vehicle_views.xml
index 0dc0463c778..58e9f868df9 100644
--- a/addons/fleet/views/fleet_vehicle_views.xml
+++ b/addons/fleet/views/fleet_vehicle_views.xml
@@ -150,6 +150,15 @@
<filter name="alert_true" domain="['|',('contract_renewal_due_soon','=',True),('contract_renewal_overdue','=',True)]" string="Has Alert(s)"/>
<separator/>
<filter string="Archived" name="inactive" domain="[('active','=',False)]"/>
+ <separator/>
+ <filter string="Late Activities" name="activities_overdue"
+ domain="[('activity_ids.date_deadline', '&lt;', context_today().strftime('%Y-%m-%d'))]"
+ help="Show all records which has next action date is before today"/>
+ <filter string="Today Activities" name="activities_today"
+ domain="[('activity_ids.date_deadline', '=', context_today().strftime('%Y-%m-%d'))]"/>
+ <filter string="Future Activities" name="activities_upcoming_all"
+ domain="[('activity_ids.date_deadline', '&gt;', context_today().strftime('%Y-%m-%d'))
+ ]"/>
<group expand="1" string="Group By">
<filter name="groupby_status" context="{'group_by' : 'state_id'}" string="Status"/>
<filter name="groupby_model" context="{'group_by' : 'model_id'}" string="Model"/>
@@ -163,7 +172,7 @@
<field name="name">fleet.vehicle.kanban</field>
<field name="model">fleet.vehicle</field>
<field name="arch" type="xml">
- <kanban>
+ <kanban default_group_by="state_id">
<field name="license_plate" />
<field name="model_id" />
<field name="driver_id" />
diff --git a/addons/google_calendar/i18n/tr.po b/addons/google_calendar/i18n/tr.po
index 13557b095b7..ebf3cda9fcf 100644
--- a/addons/google_calendar/i18n/tr.po
+++ b/addons/google_calendar/i18n/tr.po
@@ -292,7 +292,7 @@ msgstr "Tokenınız geçersiz ya da iptal edilmiş!"
#. module: google_calendar
#: model:ir.model,name:google_calendar.model_google_calendar
msgid "google.calendar"
-msgstr ""
+msgstr "google.calendar"
#. module: google_calendar
#: model:ir.model,name:google_calendar.model_res_config_settings
diff --git a/addons/hr_holidays/models/hr_leave.py b/addons/hr_holidays/models/hr_leave.py
index 2bfbd27ed1f..d34427e352b 100644
--- a/addons/hr_holidays/models/hr_leave.py
+++ b/addons/hr_holidays/models/hr_leave.py
@@ -87,7 +87,7 @@ class HolidaysRequest(models.Model):
number_of_days = fields.Float('Number of Days', compute='_compute_number_of_days', store=True, track_visibility='onchange')
meeting_id = fields.Many2one('calendar.event', string='Meeting')
- parent_id = fields.Many2one('hr.leave', string='Parent')
+ parent_id = fields.Many2one('hr.leave', string='Parent', copy=False)
linked_request_ids = fields.One2many('hr.leave', 'parent_id', string='Linked Requests')
department_id = fields.Many2one('hr.department', string='Department', readonly=True, states={'draft': [('readonly', False)], 'confirm': [('readonly', False)]})
category_id = fields.Many2one('hr.employee.category', string='Employee Tag', readonly=True,
diff --git a/addons/hr_recruitment/i18n/pt_BR.po b/addons/hr_recruitment/i18n/pt_BR.po
index f313ca3b50e..1e3d3e4a631 100644
--- a/addons/hr_recruitment/i18n/pt_BR.po
+++ b/addons/hr_recruitment/i18n/pt_BR.po
@@ -12,13 +12,14 @@
# danimaribeiro <danimaribeiro@gmail.com>, 2016
# Adriel Kotviski <kotviski@gmail.com>, 2016
# Silmar <pinheirosilmar@gmail.com>, 2017
+# Thiago Alves Cavalcante <tkramer.tk@gmail.com>, 2018
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server saas~11.2\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2018-03-22 14:10+0000\n"
"PO-Revision-Date: 2018-03-22 14:10+0000\n"
-"Last-Translator: Silmar <pinheirosilmar@gmail.com>, 2017\n"
+"Last-Translator: Thiago Alves Cavalcante <tkramer.tk@gmail.com>, 2018\n"
"Language-Team: Portuguese (Brazil) (https://www.transifex.com/odoo/teams/41243/pt_BR/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
@@ -414,7 +415,7 @@ msgstr "<span class=\"o_stat_text\">Rastreadores</span>"
#. module: hr_recruitment
#: model:ir.ui.view,arch_db:hr_recruitment.view_hr_recruitment_stage_kanban
msgid "<span>Folded in Recruitment Pipe: </span>"
-msgstr ""
+msgstr "Dobrado na Lista de Recrutamento"
#. module: hr_recruitment
#: model:ir.model.fields,help:hr_recruitment.field_hr_job__alias_defaults
@@ -484,7 +485,7 @@ msgstr "Modelo Apelidado"
#. module: hr_recruitment
#: model:ir.ui.menu,name:hr_recruitment.menu_crm_case_categ_all_app
msgid "All Applications"
-msgstr ""
+msgstr "Todas as aplicações"
#. module: hr_recruitment
#: model:ir.model,name:hr_recruitment.model_hr_applicant
@@ -608,7 +609,7 @@ msgstr "Anexos"
#. module: hr_recruitment
#: model:ir.model.fields,field_description:hr_recruitment.field_hr_recruitment_stage__template_id
msgid "Automated Email"
-msgstr ""
+msgstr "E-mail Automatizado"
#. module: hr_recruitment
#: model:ir.model.fields,field_description:hr_recruitment.field_hr_applicant__availability
@@ -650,7 +651,7 @@ msgstr "Categoria de candidato"
#: code:addons/hr_recruitment/static/src/js/tour.js:16
#, python-format
msgid "Click here to create a new job position."
-msgstr ""
+msgstr "Clique aqui para criar um novo cargo."
#. module: hr_recruitment
#: model:ir.model.fields,field_description:hr_recruitment.field_hr_applicant__date_closed
@@ -722,7 +723,7 @@ msgstr "Criar Funcionário"
#: model:ir.actions.act_window,name:hr_recruitment.create_job_simple
#: model:ir.ui.view,arch_db:hr_recruitment.hr_job_simple_form
msgid "Create a Job Position"
-msgstr ""
+msgstr "Criar um Cargo"
#. module: hr_recruitment
#: model:ir.ui.view,arch_db:hr_recruitment.hr_recruitment_source_tree
@@ -915,7 +916,7 @@ msgstr "Apelido de E-mail"
#. module: hr_recruitment
#: model:ir.ui.view,arch_db:hr_recruitment.hr_job_survey
msgid "Email alias"
-msgstr ""
+msgstr "Apelido de email"
#. module: hr_recruitment
#: model:ir.model.fields,help:hr_recruitment.field_hr_job__alias_id
@@ -1039,7 +1040,7 @@ msgstr "Departamento de RH"
#. module: hr_recruitment
#: model:ir.model.fields,field_description:hr_recruitment.field_hr_job__hr_responsible_id
msgid "HR Responsible"
-msgstr ""
+msgstr "Responsável do RH"
#. module: hr_recruitment
#: model:ir.ui.view,arch_db:hr_recruitment.view_hr_job_kanban
@@ -1091,7 +1092,7 @@ msgstr "Qualificação Inicial"
#: model:ir.model.fields,field_description:hr_recruitment.field_res_config_settings__module_hr_recruitment_survey
#: model:ir.ui.view,arch_db:hr_recruitment.res_config_settings_view_form
msgid "Interview Forms"
-msgstr ""
+msgstr "Formulários de Entrevista"
#. module: hr_recruitment
#: code:addons/hr_recruitment/models/hr_job.py:94
@@ -1104,12 +1105,12 @@ msgstr "Trabalho"
#. module: hr_recruitment
#: model:mail.template,subject:hr_recruitment.email_template_data_applicant_congratulations
msgid "Job Application Confirmation: ${object.job_id.name | safe}"
-msgstr ""
+msgstr "Confirmação de pedido de emprego: ${object.job_id.name | safe}"
#. module: hr_recruitment
#: model:ir.ui.view,arch_db:hr_recruitment.crm_case_pivot_view_job
msgid "Job Applications"
-msgstr ""
+msgstr "Solicitações de emprego"
#. module: hr_recruitment
#: model:utm.campaign,name:hr_recruitment.utm_campaign_job
@@ -1152,12 +1153,12 @@ msgstr "Cargos"
#. module: hr_recruitment
#: model:ir.ui.view,arch_db:hr_recruitment.res_config_settings_view_form
msgid "Job Posting"
-msgstr ""
+msgstr "Anúncio de emprego"
#. module: hr_recruitment
#: model:ir.model.fields,field_description:hr_recruitment.field_hr_recruitment_stage__job_id
msgid "Job Specific"
-msgstr ""
+msgstr "Especificação de trabalho"
#. module: hr_recruitment
#: model:ir.ui.view,arch_db:hr_recruitment.hr_applicant_view_search
@@ -1228,7 +1229,7 @@ msgstr ""
#, python-format
msgid ""
"Let's have a look at the <b>applications pipeline</b> for this job position."
-msgstr ""
+msgstr "Vamos dar uma olhada na <b>lista de exigências</b> para este cargo. "
#. module: hr_recruitment
#: model:res.groups,name:hr_recruitment.group_hr_recruitment_manager
diff --git a/addons/hr_recruitment/views/hr_job_views.xml b/addons/hr_recruitment/views/hr_job_views.xml
index 60971806e89..3868fd739ea 100644
--- a/addons/hr_recruitment/views/hr_job_views.xml
+++ b/addons/hr_recruitment/views/hr_job_views.xml
@@ -23,7 +23,6 @@
<field name="manager_id"/>
<field name="state"/>
<field name="user_id"/>
- <field name="documents_count"/>
<templates>
<t t-name="kanban-box">
<div t-attf-class="#{kanban_color(record.color.raw_value)}">
@@ -49,7 +48,6 @@
<div class="o_recruitment_kanban_box o_kanban_primary_bottom bottom_block">
<a name="action_get_attachment_tree_view" type="object">
<span title='Documents'><i class='fa fa-book'/>
- <t t-esc="record.documents_count.raw_value"/>
</span>
</a>
</div>
diff --git a/addons/hr_recruitment_survey/i18n/pt_BR.po b/addons/hr_recruitment_survey/i18n/pt_BR.po
index 270f1dc87bf..f12f2ac4c2b 100644
--- a/addons/hr_recruitment_survey/i18n/pt_BR.po
+++ b/addons/hr_recruitment_survey/i18n/pt_BR.po
@@ -5,17 +5,18 @@
# Translators:
# grazziano <gra.negocia@gmail.com>, 2016
# Clemilton Clementino <clemylton@hotmail.com>, 2016
-# Martin Trigaux <mat@odoo.com>, 2016
+# Martin Trigaux, 2016
# Mateus Lopes <mateus1@gmail.com>, 2016
# danimaribeiro <danimaribeiro@gmail.com>, 2016
# Rodrigo de Almeida Sottomaior Macedo <rmsolucoeseminformatic4@gmail.com>, 2016
+# Thiago Alves Cavalcante <tkramer.tk@gmail.com>, 2018
msgid ""
msgstr ""
-"Project-Id-Version: Odoo Server 10.saas~18\n"
+"Project-Id-Version: Odoo Server saas~11.2\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2017-09-20 09:53+0000\n"
-"PO-Revision-Date: 2017-09-20 09:53+0000\n"
-"Last-Translator: Rodrigo de Almeida Sottomaior Macedo <rmsolucoeseminformatic4@gmail.com>, 2016\n"
+"POT-Creation-Date: 2018-03-22 14:10+0000\n"
+"PO-Revision-Date: 2018-03-22 14:10+0000\n"
+"Last-Translator: Thiago Alves Cavalcante <tkramer.tk@gmail.com>, 2018\n"
"Language-Team: Portuguese (Brazil) (https://www.transifex.com/odoo/teams/41243/pt_BR/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
@@ -102,8 +103,8 @@ msgid "Basic information"
msgstr "Informações básicas"
#. module: hr_recruitment_survey
-#: model:ir.model.fields,help:hr_recruitment_survey.field_hr_applicant_survey_id
-#: model:ir.model.fields,help:hr_recruitment_survey.field_hr_job_survey_id
+#: model:ir.model.fields,help:hr_recruitment_survey.field_hr_applicant__survey_id
+#: model:ir.model.fields,help:hr_recruitment_survey.field_hr_job__survey_id
msgid ""
"Choose an interview form for this job position and you will be able to "
"print/answer this interview from all applicants who apply for this job"
@@ -201,7 +202,7 @@ msgid "Important"
msgstr "Importante"
#. module: hr_recruitment_survey
-#: model:ir.model.fields,field_description:hr_recruitment_survey.field_hr_job_survey_id
+#: model:ir.model.fields,field_description:hr_recruitment_survey.field_hr_job__survey_id
#: model:ir.ui.view,arch_db:hr_recruitment_survey.view_hr_job_kanban_inherit
msgid "Interview Form"
msgstr "Formulário de Entrevista"
@@ -209,7 +210,7 @@ msgstr "Formulário de Entrevista"
#. module: hr_recruitment_survey
#: model:ir.ui.view,arch_db:hr_recruitment_survey.res_config_settings_view_form
msgid "Interview Forms"
-msgstr ""
+msgstr "Formulários de Entrevista"
#. module: hr_recruitment_survey
#: model:ir.model,name:hr_recruitment_survey.model_hr_job
@@ -282,7 +283,7 @@ msgid "Regular meetings"
msgstr "Reuniões regulares"
#. module: hr_recruitment_survey
-#: model:ir.model.fields,field_description:hr_recruitment_survey.field_hr_applicant_response_id
+#: model:ir.model.fields,field_description:hr_recruitment_survey.field_hr_applicant__response_id
msgid "Response"
msgstr "Resposta"
@@ -297,7 +298,7 @@ msgid "State of the art technology"
msgstr "Estado da Arte da Tecnologia"
#. module: hr_recruitment_survey
-#: model:ir.model.fields,field_description:hr_recruitment_survey.field_hr_applicant_survey_id
+#: model:ir.model.fields,field_description:hr_recruitment_survey.field_hr_applicant__survey_id
msgid "Survey"
msgstr "Pesquisa"
diff --git a/addons/hr_timesheet_attendance/i18n/tr.po b/addons/hr_timesheet_attendance/i18n/tr.po
index 5588db3e311..8865465e6d4 100644
--- a/addons/hr_timesheet_attendance/i18n/tr.po
+++ b/addons/hr_timesheet_attendance/i18n/tr.po
@@ -86,7 +86,7 @@ msgstr "Kullanıcı"
#. module: hr_timesheet_attendance
#: model:ir.model,name:hr_timesheet_attendance.model_hr_timesheet_attendance_report
msgid "hr.timesheet.attendance.report"
-msgstr ""
+msgstr "hr.timesheet.attendance.report"
#. module: hr_timesheet_attendance
#: model:ir.ui.view,arch_db:hr_timesheet_attendance.view_hr_timesheet_attendance_report_pivot
diff --git a/addons/iap/i18n/tr.po b/addons/iap/i18n/tr.po
index 0a841f08079..7a9b5661000 100644
--- a/addons/iap/i18n/tr.po
+++ b/addons/iap/i18n/tr.po
@@ -130,4 +130,4 @@ msgstr "Hizmet Adı"
#. module: iap
#: model:ir.model,name:iap.model_iap_account
msgid "iap.account"
-msgstr ""
+msgstr "iap.account"
diff --git a/addons/im_livechat/i18n/tr.po b/addons/im_livechat/i18n/tr.po
index 996f2a4e8a3..7b440f587db 100644
--- a/addons/im_livechat/i18n/tr.po
+++ b/addons/im_livechat/i18n/tr.po
@@ -64,6 +64,11 @@ msgid ""
"country, GeoIP must be installed on your server, otherwise, the countries of"
" the rule will not be taken into account.</span>"
msgstr ""
+"<span>Canlı destek kanalınız için kuralları tanımlayın. Belirtilen URL ve "
+"ülke için aksiyon tanımlayabilir (desteği gizle, desteği otomatik aç, veya "
+"sadece butonu göster)<br/>Ülkeyi tanımlayabilmek için, GeoIP'nin sunucuda "
+"yüklenmiş olması gerekmektedir, aksi durumda ülke ile ilgili kurallar "
+"geçersiz olacaktır.</span>"
#. module: im_livechat
#: model:ir.model.fields,field_description:im_livechat.field_im_livechat_channel_rule__action
diff --git a/addons/l10n_nl/data/account_tax_template.xml b/addons/l10n_nl/data/account_tax_template.xml
index c26dc9a8345..e9b937b98f5 100644
--- a/addons/l10n_nl/data/account_tax_template.xml
+++ b/addons/l10n_nl/data/account_tax_template.xml
@@ -593,7 +593,7 @@
<field name="refund_account_id" ref="vat_refund_h_non_eu"/>
<field name="account_id" ref="vat_refund_h_non_eu"/>
<field name="type_tax_use">none</field>
- <field name="tag_ids" eval="[(6,0,[ref('tag_nl_34')])]"/>
+ <field name="tag_ids" eval="[(6,0,[ref('tag_nl_33')])]"/>
<field name="tax_group_id" ref="tax_group_21_niet_eu"/>
</record>
<record id="btw_E2" model="account.tax.template">
@@ -735,7 +735,7 @@
<field name="refund_account_id" ref="vat_refund_h_d_non_eu"/>
<field name="account_id" ref="vat_refund_h_d_non_eu"/>
<field name="type_tax_use">none</field>
- <field name="tag_ids" eval="[(6,0,[ref('tag_nl_34')])]"/>
+ <field name="tag_ids" eval="[(6,0,[ref('tag_nl_33')])]"/>
<field name="tax_group_id" ref="tax_group_21_niet_eu"/>
</record>
<record id="btw_E2_d" model="account.tax.template">
diff --git a/addons/link_tracker/i18n/tr.po b/addons/link_tracker/i18n/tr.po
index 21f4defb143..325781ee040 100644
--- a/addons/link_tracker/i18n/tr.po
+++ b/addons/link_tracker/i18n/tr.po
@@ -228,19 +228,19 @@ msgstr "Website Link Tıklamaları"
#. module: link_tracker
#: model:ir.model,name:link_tracker.model_link_tracker
msgid "link.tracker"
-msgstr ""
+msgstr "link.tracker"
#. module: link_tracker
#: model:ir.model,name:link_tracker.model_link_tracker_click
msgid "link.tracker.click"
-msgstr ""
+msgstr "link.tracker.click"
#. module: link_tracker
#: model:ir.model,name:link_tracker.model_link_tracker_code
msgid "link.tracker.code"
-msgstr ""
+msgstr "link.tracker.code"
#. module: link_tracker
#: model:ir.actions.act_window,name:link_tracker.action_link_tracker_stats
msgid "link.tracker.form.graph.action"
-msgstr ""
+msgstr "link.tracker.form.graph.action"
diff --git a/addons/lunch/i18n/tr.po b/addons/lunch/i18n/tr.po
index 6fd066e863d..4bb623040f0 100644
--- a/addons/lunch/i18n/tr.po
+++ b/addons/lunch/i18n/tr.po
@@ -986,4 +986,4 @@ msgstr "öğle yemeği ürün kategorisi"
#. module: lunch
#: model:ir.model,name:lunch.model_lunch_order_line_lucky
msgid "lunch.order.line.lucky"
-msgstr ""
+msgstr "lunch.order.line.lucky"
diff --git a/addons/mail/i18n/tr.po b/addons/mail/i18n/tr.po
index 10f755b2fec..1aabb67b1ff 100644
--- a/addons/mail/i18n/tr.po
+++ b/addons/mail/i18n/tr.po
@@ -329,6 +329,8 @@ msgid ""
"A shortcode is a keyboard shortcut. For instance, you type #gm and it will "
"be transformed into \"Good Morning\"."
msgstr ""
+"Bir kısa kod, bir klavye kısayoludır. Örneğin, # gm yazarsınız ve "
+"\"Günaydın\" a dönüşür."
#. module: mail
#: model:ir.model,name:mail.model_res_groups
@@ -1518,6 +1520,8 @@ msgid ""
"Email address of the sender. This field is set when no matching partner is "
"found and replaces the author_id field in the chatter."
msgstr ""
+"Gönderenin e-posta adresi. Eşleşen bir ortak bulunmadığında ve sohbetteki "
+"author_id alanının yerini aldığında bu alan ayarlanır."
#. module: mail
#: model:ir.ui.view,arch_db:mail.email_compose_message_wizard_form
@@ -3123,7 +3127,7 @@ msgstr ""
#. module: mail
#: model:ir.model.fields,field_description:mail.field_mail_tracking_value__new_value_char
msgid "New Value Char"
-msgstr ""
+msgstr "Yeni Karakter Değeri"
#. module: mail
#: model:ir.model.fields,field_description:mail.field_mail_tracking_value__new_value_datetime
@@ -3143,12 +3147,12 @@ msgstr "Yeni Tam Sayı Değeri"
#. module: mail
#: model:ir.model.fields,field_description:mail.field_mail_tracking_value__new_value_monetary
msgid "New Value Monetary"
-msgstr ""
+msgstr "Yeni Parasal Değer"
#. module: mail
#: model:ir.model.fields,field_description:mail.field_mail_tracking_value__new_value_text
msgid "New Value Text"
-msgstr ""
+msgstr "Yeni Metin Değeri"
#. module: mail
#. openerp-web
@@ -3275,7 +3279,7 @@ msgstr ""
#: code:addons/mail/static/src/xml/web_kanban_activity.xml:22
#, python-format
msgid "No activities planned."
-msgstr ""
+msgstr "Hiçbir etkinlik planlanmadı."
#. module: mail
#. openerp-web
@@ -3591,7 +3595,7 @@ msgstr "Odoo"
#, python-format
msgid ""
"Odoo has now the permission to send you native notifications on this device."
-msgstr ""
+msgstr "Odoo, artık bu cihazda yerel bildirimler göndermek için izin aldı."
#. module: mail
#. openerp-web
@@ -3607,7 +3611,7 @@ msgstr "Odoo için izniniz gerekiyor"
msgid ""
"Odoo will not have the permission to send native notifications on this "
"device."
-msgstr ""
+msgstr "Odoo, bu cihazda yerel bildirimler gönderme iznine sahip olmayacak."
#. module: mail
#. openerp-web
@@ -3619,32 +3623,32 @@ msgstr "Çevrimdışı"
#. module: mail
#: model:ir.model.fields,field_description:mail.field_mail_tracking_value__old_value_char
msgid "Old Value Char"
-msgstr ""
+msgstr "Eski Karakter Değeri"
#. module: mail
#: model:ir.model.fields,field_description:mail.field_mail_tracking_value__old_value_datetime
msgid "Old Value DateTime"
-msgstr ""
+msgstr "Eski Tarih Saat Değeri"
#. module: mail
#: model:ir.model.fields,field_description:mail.field_mail_tracking_value__old_value_float
msgid "Old Value Float"
-msgstr ""
+msgstr "Eski Sayısal Değer"
#. module: mail
#: model:ir.model.fields,field_description:mail.field_mail_tracking_value__old_value_integer
msgid "Old Value Integer"
-msgstr ""
+msgstr "Eski Tam Sayı Değeri"
#. module: mail
#: model:ir.model.fields,field_description:mail.field_mail_tracking_value__old_value_monetary
msgid "Old Value Monetary"
-msgstr ""
+msgstr "Eski Parasal Değer"
#. module: mail
#: model:ir.model.fields,field_description:mail.field_mail_tracking_value__old_value_text
msgid "Old Value Text"
-msgstr ""
+msgstr "Eski Metin Değeri"
#. module: mail
#: selection:ir.model.fields,track_visibility:0
@@ -3701,21 +3705,21 @@ msgstr "Üst Belgeyi Aç"
#: code:addons/mail/static/src/xml/discuss.xml:139
#, python-format
msgid "Open channel settings"
-msgstr ""
+msgstr "Açık kanal ayarları"
#. module: mail
#. openerp-web
#: code:addons/mail/static/src/xml/discuss.xml:187
#, python-format
msgid "Open chat"
-msgstr ""
+msgstr "Konuşmayı aç"
#. module: mail
#. openerp-web
#: code:addons/mail/static/src/xml/extended_chat_window.xml:15
#, python-format
msgid "Open in Discuss"
-msgstr ""
+msgstr "Tartışmayı Aç"
#. module: mail
#: model:ir.model.fields,field_description:mail.field_res_partner__opt_out
@@ -3881,6 +3885,9 @@ msgid ""
" named. For example on a project, the parent_id of project subtypes refers "
"to task-related subtypes."
msgstr ""
+"Otomatik abonelik için kullanılan alt alt türü. Bu alan doğru bir şekilde "
+"adlandırılmamış. Örneğin, bir projede, proje alt türlerinin parent_id'i, "
+"görevle ilgili alt türlere başvurur."
#. module: mail
#: model:ir.actions.act_window,name:mail.action_partner_mass_mail
@@ -3905,7 +3912,7 @@ msgstr ""
#: model:ir.model.fields,field_description:mail.field_mail_message__needaction_partner_ids
#: model:ir.model.fields,field_description:mail.field_survey_mail_compose_message__needaction_partner_ids
msgid "Partners with Need Action"
-msgstr ""
+msgstr "Eylem İhtiyacı Olan İş Ortakları"
#. module: mail
#: model:ir.model.fields,help:mail.field_email_template_preview__auto_delete
@@ -4312,7 +4319,7 @@ msgstr "Yeni Şablon olarak kaydet"
#: code:addons/mail/static/src/js/chat_window.js:40
#, python-format
msgid "Say something"
-msgstr ""
+msgstr "Bir şey söyle"
#. module: mail
#: model:ir.ui.view,arch_db:mail.mail_activity_view_form_popup
@@ -4436,7 +4443,7 @@ msgstr ""
#: code:addons/mail/static/src/js/thread_field.js:92
#, python-format
msgid "Sending Error"
-msgstr ""
+msgstr "Hata Gönderiliyor"
#. module: mail
#. openerp-web
@@ -4483,7 +4490,7 @@ msgstr ""
#: model:ir.ui.view,arch_db:mail.mail_shortcode_view_form
#: model:ir.ui.view,arch_db:mail.mail_shortcode_view_tree
msgid "Shortcodes"
-msgstr ""
+msgstr "Kısa kodlar"
#. module: mail
#: model:ir.model.fields,field_description:mail.field_mail_shortcode__source
@@ -4500,7 +4507,7 @@ msgstr "Bir sonraki eylem tarihi bugünden önce olan tüm kayıtları göster"
#: code:addons/mail/models/mail_channel.py:673
#, python-format
msgid "Show an helper message"
-msgstr ""
+msgstr "Bir yardımcı mesajı göster"
#. module: mail
#: model:ir.model.fields,field_description:mail.field_email_template_preview__ref_ir_act_window
@@ -4557,6 +4564,8 @@ msgid ""
"Specify a model if the activity should be specific to a model and not "
"available when managing activities for other models."
msgstr ""
+"Etkinliğin bir modele özgü olması ve diğer modellerin etkinliklerini "
+"yönetirken kullanılamaması durumunda bir model belirtin."
#. module: mail
#. openerp-web
@@ -4821,6 +4830,8 @@ msgid ""
"This group is visible by non members. Invisible groups can add members "
"through the invite button."
msgstr ""
+"Bu grup üye olmayanlar tarafından görülebilir. Görünmez gruplar, davet "
+"butonuyla üye ekleyebilir."
#. module: mail
#: model:ir.ui.view,arch_db:mail.view_mail_search
@@ -4924,13 +4935,13 @@ msgstr "İzleme"
#: model:ir.ui.view,arch_db:mail.view_mail_tracking_value_form
#: model:ir.ui.view,arch_db:mail.view_mail_tracking_value_tree
msgid "Tracking Value"
-msgstr ""
+msgstr "İzleme Değeri"
#. module: mail
#: model:ir.actions.act_window,name:mail.action_view_mail_tracking_value
#: model:ir.ui.menu,name:mail.menu_mail_tracking_value
msgid "Tracking Values"
-msgstr ""
+msgstr "İzleme Değerleri"
#. module: mail
#: model:ir.model.fields,field_description:mail.field_mail_compose_message__tracking_value_ids
@@ -4938,7 +4949,7 @@ msgstr ""
#: model:ir.model.fields,field_description:mail.field_mail_message__tracking_value_ids
#: model:ir.model.fields,field_description:mail.field_survey_mail_compose_message__tracking_value_ids
msgid "Tracking values"
-msgstr ""
+msgstr "İzleme Değerleri"
#. module: mail
#: model:ir.model.fields,field_description:mail.field_mail_compose_message__message_type
@@ -5191,7 +5202,7 @@ msgstr "Şablonu Kullan"
#. module: mail
#: model:ir.ui.view,arch_db:mail.res_config_settings_view_form
msgid "Use your own email servers"
-msgstr ""
+msgstr "Kendi e-mail sunucusunu kullanın"
#. module: mail
#: model:ir.model.fields,help:mail.field_mail_message_subtype__sequence
@@ -5299,7 +5310,7 @@ msgstr "Bu modelin ileti ve bildirimleri destekleyip desteklemediğidir."
#. module: mail
#: model:ir.ui.view,arch_db:mail.mail_channel_view_form
msgid "Who can follow the group's activities?"
-msgstr ""
+msgstr "Grubun faaliyetlerini kim takip edebilir?"
#. module: mail
#. openerp-web
@@ -5433,13 +5444,13 @@ msgstr ""
#: code:addons/mail/static/src/js/thread_field.js:92
#, python-format
msgid "Your message has not been sent."
-msgstr ""
+msgstr "Mesajınız gönderilemedi."
#. module: mail
#: code:addons/mail/models/ir_actions.py:30
#, python-format
msgid "Your template should define email_from"
-msgstr ""
+msgstr "Şablonunuz email_from tanımlanabilir"
#. module: mail
#: code:addons/mail/models/mail_thread.py:948
@@ -5533,7 +5544,7 @@ msgstr ""
#: code:addons/mail/models/mail_alias.py:267
#, python-format
msgid "incorrectly configured alias (unknown reference record)"
-msgstr ""
+msgstr "yanlış yapılandırılmış takma ad (bilinmeyen referans kaydı)"
#. module: mail
#: model:ir.model,name:mail.model_ir_actions_server
diff --git a/addons/mail/static/src/js/services/chat_manager.js b/addons/mail/static/src/js/services/chat_manager.js
index 073365d2b7a..4bb6e9be6aa 100644
--- a/addons/mail/static/src/js/services/chat_manager.js
+++ b/addons/mail/static/src/js/services/chat_manager.js
@@ -1620,7 +1620,7 @@ var ChatManager = AbstractService.extend({
}
this._removeChannel(channel);
this.chatBus.trigger("unsubscribe_from_channel", data.id);
- web_client.do_notify(_("Unsubscribed"), msg);
+ web_client.do_notify(_t("Unsubscribed"), msg);
}
} else if (data.type === 'toggle_star') {
this._manageToggleStarNotification(data);
diff --git a/addons/mail/static/src/js/systray.js b/addons/mail/static/src/js/systray.js
index 1c320515fa9..fbfb250a91e 100644
--- a/addons/mail/static/src/js/systray.js
+++ b/addons/mail/static/src/js/systray.js
@@ -128,7 +128,7 @@ var MessagingMenu = Widget.extend({
if (channelID === 'channel_inbox') {
var resID = $(event.currentTarget).data('res_id');
var resModel = $(event.currentTarget).data('res_model');
- if (resModel && resID) {
+ if (resModel && resModel !== 'mail.channel' && resID) {
this.do_action({
type: 'ir.actions.act_window',
res_model: resModel,
@@ -136,7 +136,11 @@ var MessagingMenu = Widget.extend({
res_id: resID
});
} else {
- this.do_action('mail.mail_channel_action_client_chat', {clear_breadcrumbs: true})
+ var clientChatOptions = {clear_breadcrumbs: true};
+ if (resModel && resModel === 'mail.channel' && resID) {
+ clientChatOptions.active_id = resID;
+ }
+ this.do_action('mail.mail_channel_action_client_chat', clientChatOptions)
.then(function () {
self.trigger_up('hide_home_menu'); // we cannot 'go back to previous page' otherwise
core.bus.trigger('change_menu_section', self.call('chat_manager', 'getDiscussMenuID'));
diff --git a/addons/maintenance/i18n/tr.po b/addons/maintenance/i18n/tr.po
index bbac3f16eee..fe2712e0e13 100644
--- a/addons/maintenance/i18n/tr.po
+++ b/addons/maintenance/i18n/tr.po
@@ -982,7 +982,7 @@ msgstr "Durumu değişti"
#. module: maintenance
#: model:ir.model.fields,field_description:maintenance.field_maintenance_request__name
msgid "Subjects"
-msgstr ""
+msgstr "Konular"
#. module: maintenance
#: model:ir.model.fields,field_description:maintenance.field_maintenance_request__maintenance_team_id
diff --git a/addons/mass_mailing/i18n/tr.po b/addons/mass_mailing/i18n/tr.po
index 03ea4cd2a45..88b89e36056 100644
--- a/addons/mass_mailing/i18n/tr.po
+++ b/addons/mass_mailing/i18n/tr.po
@@ -1911,7 +1911,7 @@ msgstr "Ve bir sonraki siparişinizde20 TL tasarruf edin!"
#. module: mass_mailing
#: model:ir.model.fields,field_description:mass_mailing.field_mail_mass_mailing_campaign__campaign_id
msgid "campaign_id"
-msgstr ""
+msgstr "campaign_id"
#. module: mass_mailing
#: model:ir.ui.view,arch_db:mass_mailing.view_mail_mass_mailing_list_form
@@ -1937,12 +1937,12 @@ msgstr ""
#. module: mass_mailing
#: model:ir.model,name:mass_mailing.model_link_tracker
msgid "link.tracker"
-msgstr ""
+msgstr "link.tracker"
#. module: mass_mailing
#: model:ir.model,name:mass_mailing.model_link_tracker_click
msgid "link.tracker.click"
-msgstr ""
+msgstr "link.tracker.click"
#. module: mass_mailing
#: model:ir.model,name:mass_mailing.model_res_config_settings
diff --git a/addons/mass_mailing/static/src/js/mass_mailing.js b/addons/mass_mailing/static/src/js/mass_mailing.js
index e611d9dbe26..e1689b69e5b 100644
--- a/addons/mass_mailing/static/src/js/mass_mailing.js
+++ b/addons/mass_mailing/static/src/js/mass_mailing.js
@@ -41,7 +41,7 @@ FieldTextHtml.include({
var datarecord = this._super();
if (this.model === 'mail.mass_mailing') {
// these fields can potentially get very long, let's remove them
- datarecord = _.omit(datarecord, ['mailing_domain', 'contact_list_ids', 'body_html']);
+ datarecord = _.omit(datarecord, ['mailing_domain', 'contact_list_ids', 'body_html', 'attachment_ids']);
}
return datarecord;
},
diff --git a/addons/mass_mailing_event_track/models/event.py b/addons/mass_mailing_event_track/models/event.py
index 156625391c0..e5747875f21 100644
--- a/addons/mass_mailing_event_track/models/event.py
+++ b/addons/mass_mailing_event_track/models/event.py
@@ -16,7 +16,7 @@ class Event(models.Model):
view_mode='form',
target='current',
context=dict(
- default_mailing_model=self.env.ref('website_event_track.model_event_track').id,
+ default_mailing_model_id=self.env.ref('website_event_track.model_event_track').id,
default_mailing_domain="[('event_id', 'in', %s), ('stage_id.is_cancel', '!=', True)]" % self.ids,
),
)
diff --git a/addons/mrp/models/mrp_bom.py b/addons/mrp/models/mrp_bom.py
index b1892c4db2a..922802f9659 100644
--- a/addons/mrp/models/mrp_bom.py
+++ b/addons/mrp/models/mrp_bom.py
@@ -80,6 +80,8 @@ class MrpBom(models.Model):
def onchange_product_tmpl_id(self):
if self.product_tmpl_id:
self.product_uom_id = self.product_tmpl_id.uom_id.id
+ if self.product_id.product_tmpl_id != self.product_tmpl_id:
+ self.product_id = False
@api.onchange('routing_id')
def onchange_routing_id(self):
diff --git a/addons/mrp/models/mrp_workorder.py b/addons/mrp/models/mrp_workorder.py
index 0c0ddf37ead..ce3d87688ee 100644
--- a/addons/mrp/models/mrp_workorder.py
+++ b/addons/mrp/models/mrp_workorder.py
@@ -364,6 +364,7 @@ class MrpWorkorder(models.Model):
move_line = production_move.move_line_ids.filtered(lambda x: x.lot_id.id == self.final_lot_id.id)
if move_line:
move_line.product_uom_qty += self.qty_producing
+ move_line.qty_done += self.qty_producing
else:
move_line.create({'move_id': production_move.id,
'product_id': production_move.product_id.id,
diff --git a/addons/mrp/models/stock_move.py b/addons/mrp/models/stock_move.py
index 1099d8b549e..befe9ceb9d1 100644
--- a/addons/mrp/models/stock_move.py
+++ b/addons/mrp/models/stock_move.py
@@ -73,6 +73,13 @@ class StockMove(models.Model):
order_finished_lot_ids = fields.Many2many('stock.production.lot', compute='_compute_order_finished_lot_ids')
finished_lots_exist = fields.Boolean('Finished Lots Exist', compute='_compute_order_finished_lot_ids')
+ def _unreserve_initial_demand(self, new_move):
+ # If you were already putting stock.move.lots on the next one in the work order, transfer those to the new move
+ self.filtered(lambda m: m.production_id or m.raw_material_production_id)\
+ .mapped('move_line_ids')\
+ .filtered(lambda ml: ml.qty_done == 0.0)\
+ .write({'move_id': new_move, 'product_uom_qty': 0})
+
@api.depends('active_move_line_ids.qty_done', 'active_move_line_ids.product_uom_id')
def _compute_done_quantity(self):
super(StockMove, self)._compute_done_quantity()
diff --git a/addons/mrp/views/mrp_workorder_views.xml b/addons/mrp/views/mrp_workorder_views.xml
index 15561dc1ddd..3fbb2ab111a 100644
--- a/addons/mrp/views/mrp_workorder_views.xml
+++ b/addons/mrp/views/mrp_workorder_views.xml
@@ -196,18 +196,19 @@
<label for="duration"/>
<div>
<button style="pointer-events: none;" class="oe_inline label label-default">
- <field name="duration" widget="mrp_time_counter"/>
+ <field name="duration" widget="mrp_time_counter" help="Time the currently logged user spent on this workorder."/>
</button>
</div>
</group>
</group>
<group>
- <field name="time_ids" nolabel="1">
+ <field name="time_ids" nolabel="1" context="{'default_workcenter_id': workcenter_id}">
<tree>
<field name="date_start"/>
<field name="date_end"/>
<field name="duration" widget="float_time" sum="Total duration"/>
<field name="user_id"/>
+ <field name="workcenter_id" invisible="1"/>
<field name="loss_id" string="Efficiency"/>
</tree>
<form>
@@ -219,6 +220,7 @@
</group>
<group>
<field name="user_id"/>
+ <field name="workcenter_id"/>
<field name="loss_id"/>
</group>
</group>
diff --git a/addons/payment_authorize/models/payment.py b/addons/payment_authorize/models/payment.py
index fe17ee4add9..89aa33aa249 100644
--- a/addons/payment_authorize/models/payment.py
+++ b/addons/payment_authorize/models/payment.py
@@ -59,6 +59,15 @@ class PaymentAcquirerAuthorize(models.Model):
@api.multi
def authorize_form_generate_values(self, values):
self.ensure_one()
+ # State code is only supported in US, use state name by default
+ # See https://developer.authorize.net/api/reference/
+ state = values['partner_state'].name if values.get('partner_state') else ''
+ if values.get('partner_country') and values.get('partner_country') == self.env.ref('base.us', False):
+ state = values['partner_state'].code if values.get('partner_state') else ''
+ billing_state = values['billing_partner_state'].name if values.get('billing_partner_state') else ''
+ if values.get('billing_partner_country') and values.get('billing_partner_country') == self.env.ref('base.us', False):
+ billing_state = values['billing_partner_state'].code if values.get('billing_partner_state') else ''
+
base_url = self.env['ir.config_parameter'].get_param('web.base.url')
authorize_tx_values = dict(values)
temp_authorize_tx_values = {
@@ -83,7 +92,7 @@ class PaymentAcquirerAuthorize(models.Model):
'first_name': values.get('partner_first_name'),
'last_name': values.get('partner_last_name'),
'phone': values.get('partner_phone'),
- 'state': values.get('partner_state') and values['partner_state'].code or '',
+ 'state': state,
'billing_address': values.get('billing_partner_address'),
'billing_city': values.get('billing_partner_city'),
'billing_country': values.get('billing_partner_country') and values.get('billing_partner_country').name or '',
@@ -92,7 +101,7 @@ class PaymentAcquirerAuthorize(models.Model):
'billing_first_name': values.get('billing_partner_first_name'),
'billing_last_name': values.get('billing_partner_last_name'),
'billing_phone': values.get('billing_partner_phone'),
- 'billing_state': values.get('billing_partner_state') and values['billing_partner_state'].code or '',
+ 'billing_state': billing_state,
}
temp_authorize_tx_values['returndata'] = authorize_tx_values.pop('return_url', '')
temp_authorize_tx_values['x_fp_hash'] = self._authorize_generate_hashing(temp_authorize_tx_values)
diff --git a/addons/payment_ogone/controllers/main.py b/addons/payment_ogone/controllers/main.py
index 1d03a688630..409e09b8a9e 100644
--- a/addons/payment_ogone/controllers/main.py
+++ b/addons/payment_ogone/controllers/main.py
@@ -110,7 +110,7 @@ class OgoneController(http.Controller):
def feedback(self, **kwargs):
try:
tx = request.env['payment.transaction'].sudo()._ogone_form_get_tx_from_data(kwargs)
- tx._ogone_s2s_validate()
+ tx._ogone_s2s_validate_tree(kwargs)
except ValidationError:
return 'ko'
return 'ok'
diff --git a/addons/payment_stripe/static/src/js/stripe.js b/addons/payment_stripe/static/src/js/stripe.js
index e4474fe72ce..956765e8042 100644
--- a/addons/payment_stripe/static/src/js/stripe.js
+++ b/addons/payment_stripe/static/src/js/stripe.js
@@ -87,74 +87,30 @@ odoo.define('payment_stripe.stripe', function(require) {
payment_form.append('<i class="fa fa-spinner fa-spin"/>');
payment_form.attr('disabled','disabled');
- var acquirer_id = payment_form.find('input[type="radio"][data-provider="stripe"]:checked').data('acquirer-id');
- if (! acquirer_id) {
- return false;
- }
-
+ var payment_tx_url = payment_form.find('input[name="prepare_tx_url"]').val();
var access_token = $("input[name='access_token']").val() || $("input[name='token']").val() || '';
- var so_id = $("input[name='return_url']").val().match(/quote\/([0-9]+)/) || undefined;
- if (so_id) {
- so_id = parseInt(so_id[1]);
- }
- var invoice_id = $("input[name='return_url']").val().match(/invoices\/([0-9]+)/) || undefined;
- if (invoice_id) {
- invoice_id = parseInt(invoice_id[1]);
- }
-
- var currency = $("input[name='currency']").val();
- var currency_id = $("input[name='currency_id']").val();
- var amount = parseFloat($("input[name='amount']").val() || '0.0');
+ var get_input_value = function(name) {
+ return provider_form.find('input[name="' + name + '"]').val();
+ }
- if ($('.o_website_payment').length !== 0) {
- var invoice_num = $("input[name='invoice_num']").val();
- var url = _.str.sprintf("/website_payment/transaction/v2/%f/%s/%s",
- amount, currency_id, invoice_num);
+ var acquirer_id = parseInt(provider_form.find('#acquirer_stripe').val());
+ var amount = parseFloat(get_input_value("amount") || '0.0');
+ var currency = get_input_value("currency");
+ var email = get_input_value("email");
+ var invoice_num = get_input_value("invoice_num");
+ var merchant = get_input_value("merchant");
- var create_tx = ajax.jsonRpc(url, 'call', {
- acquirer_id: acquirer_id
- }).then(function (data) {
- try { provider_form[0].innerHTML = data; } catch (e) {}
- });
- }
- else if ($('.o_website_quote').length !== 0) {
- var url = _.str.sprintf("/quote/%s/transaction/", so_id);
- var create_tx = ajax.jsonRpc(url, 'call', {
- access_token: access_token,
- acquirer_id: acquirer_id
- }).then(function (data) {
- try { provider_form[0].innerHTML = data; } catch (e) {};
- });
- } else if (window.location.href.includes("/my/orders/")) {
- var create_tx = ajax.jsonRpc('/pay/sale/' + so_id + '/form_tx/', 'call', {
- access_token: access_token,
- acquirer_id: acquirer_id
- }).then(function (data) {
- try { provider_form.innerHTML = data; } catch (e) {};
- });
- } else if (window.location.href.includes("/my/invoices/")) {
- var create_tx = ajax.jsonRpc('/invoice/pay/' + invoice_id + '/form_tx/', 'call', {
- access_token: access_token,
- acquirer_id: acquirer_id
- }).then(function (data) {
- try { provider_form.innerHTML = data; } catch (e) {};
- });
- }
- else {
- var create_tx = ajax.jsonRpc('/shop/payment/transaction/' + acquirer_id, 'call', {
- so_id: so_id,
- access_token: access_token,
- acquirer_id: acquirer_id
- }).then(function (data) {
- try { provider_form.innerHTML = data; } catch (e) {};
- });
- }
- create_tx.done(function () {
+ ajax.jsonRpc(payment_tx_url, 'call', {
+ acquirer_id: acquirer_id,
+ access_token: access_token,
+ }).then(function(data) {
+ try { provider_form[0].innerHTML = data; } catch (e) {};
+ }).done(function () {
getStripeHandler().open({
- name: $("input[name='merchant']").val(),
- description: $("input[name='invoice_num']").val(),
- email: $("input[name='email']").val(),
+ name: merchant,
+ description: invoice_num,
+ email: email,
currency: currency,
amount: _.contains(int_currencies, currency) ? amount : amount * 100,
});
diff --git a/addons/phone_validation/i18n/tr.po b/addons/phone_validation/i18n/tr.po
index d154d793e22..b86582c48e2 100644
--- a/addons/phone_validation/i18n/tr.po
+++ b/addons/phone_validation/i18n/tr.po
@@ -95,4 +95,4 @@ msgstr ""
#. module: phone_validation
#: model:ir.model,name:phone_validation.model_phone_validation_mixin
msgid "phone.validation.mixin"
-msgstr ""
+msgstr "phone.validation.mixin"
diff --git a/addons/point_of_sale/i18n/tr.po b/addons/point_of_sale/i18n/tr.po
index 4b4e51b656a..fd552931a40 100644
--- a/addons/point_of_sale/i18n/tr.po
+++ b/addons/point_of_sale/i18n/tr.po
@@ -4132,6 +4132,9 @@ msgid ""
"You cannot confirm all orders of this session, because they have not the 'paid' status.\n"
"{reference} is in state {state}, total amount: {total}, paid: {paid}"
msgstr ""
+"Bu oturumun tüm siparişlerini onaylayamazsınız, çünkü \"ödendi\" durumları "
+"yoktur. {Reference} durum {state} durumundadır, toplam tutar: {total}, "
+"ödendi: {paid}"
#. module: point_of_sale
#: code:addons/point_of_sale/models/pos_session.py:151
diff --git a/addons/point_of_sale/models/pos_session.py b/addons/point_of_sale/models/pos_session.py
index d9f38720fd4..f219847c8d7 100644
--- a/addons/point_of_sale/models/pos_session.py
+++ b/addons/point_of_sale/models/pos_session.py
@@ -38,8 +38,8 @@ class PosSession(models.Model):
paid=order.amount_paid,
))
order.action_pos_order_done()
- orders = session.order_ids.filtered(lambda order: order.state in ['invoiced', 'done'])
- orders.sudo()._reconcile_payments()
+ orders_to_reconcile = session.order_ids.filtered(lambda order: order.state in ['invoiced', 'done'] and order.partner_id)
+ orders_to_reconcile.sudo()._reconcile_payments()
config_id = fields.Many2one(
'pos.config', string='Point of Sale',
diff --git a/addons/point_of_sale/models/product.py b/addons/point_of_sale/models/product.py
index 43a959bcfa4..ed9f2dce8cd 100644
--- a/addons/point_of_sale/models/product.py
+++ b/addons/point_of_sale/models/product.py
@@ -27,6 +27,18 @@ class ProductTemplate(models.Model):
self.available_in_pos = False
+class ProductProduct(models.Model):
+ _inherit = 'product.product'
+
+ @api.multi
+ def unlink(self):
+ product_ctx = dict(self.env.context or {}, active_test=False)
+ if self.env['pos.session'].search_count([('state', '!=', 'closed')]):
+ if self.with_context(product_ctx).search_count([('id', 'in', self.ids), ('product_tmpl_id.available_in_pos', '=', True)]):
+ raise UserError(_('You cannot delete a product saleable in point of sale while a session is still opened.'))
+ return super(ProductProduct, self).unlink()
+
+
class UomCateg(models.Model):
_inherit = 'uom.category'
diff --git a/addons/point_of_sale/static/src/js/models.js b/addons/point_of_sale/static/src/js/models.js
index 63c9e1c0cb0..c73c7f75165 100644
--- a/addons/point_of_sale/static/src/js/models.js
+++ b/addons/point_of_sale/static/src/js/models.js
@@ -1406,6 +1406,7 @@ exports.Orderline = Backbone.Model.extend({
this.set_unit_price(this.product.get_price(this.order.pricelist, this.get_quantity()));
this.order.fix_tax_included_price(this);
}
+ this.trigger('change', this);
},
// return the quantity of product
get_quantity: function(){
@@ -2124,7 +2125,7 @@ exports.Order = Backbone.Model.extend({
company_registry: company.company_registry,
contact_address: company.partner_id[1],
vat: company.vat,
- vat_label: company.country.vat_label,
+ vat_label: company.country && company.country.vat_label || '',
name: company.name,
phone: company.phone,
logo: this.pos.company_logo_base64,
diff --git a/addons/portal/controllers/mail.py b/addons/portal/controllers/mail.py
index 9fb2c6b94ac..89dbded3676 100644
--- a/addons/portal/controllers/mail.py
+++ b/addons/portal/controllers/mail.py
@@ -100,7 +100,7 @@ class PortalChatter(http.Controller):
raise Forbidden()
# Non-employee see only messages with not internal subtype (aka, no internal logs)
if not request.env['res.users'].has_group('base.group_user'):
- domain = expression.AND([['&', '&', ('subtype_id', '!=', False), ('subtype_id.internal', '=', False)], domain])
+ domain = expression.AND([['&', ('subtype_id', '!=', False), ('subtype_id.internal', '=', False)], domain])
Message = request.env['mail.message'].sudo()
return {
'messages': Message.search(domain, limit=limit, offset=offset).portal_message_format(),
diff --git a/addons/portal/i18n/tr.po b/addons/portal/i18n/tr.po
index 6ea7eb0fe95..2aac19a95f8 100644
--- a/addons/portal/i18n/tr.po
+++ b/addons/portal/i18n/tr.po
@@ -626,7 +626,7 @@ msgstr "oturum açıldı"
#. module: portal
#: model:ir.model,name:portal.model_portal_mixin
msgid "portal.mixin"
-msgstr ""
+msgstr "portal.mixin"
#. module: portal
#: model:ir.ui.view,arch_db:portal.portal_my_details
diff --git a/addons/portal/wizard/portal_wizard.py b/addons/portal/wizard/portal_wizard.py
index 22d6765aac7..44eb1637619 100644
--- a/addons/portal/wizard/portal_wizard.py
+++ b/addons/portal/wizard/portal_wizard.py
@@ -134,7 +134,7 @@ class PortalWizardUser(models.TransientModel):
if wizard_user.partner_id.company_id:
company_id = wizard_user.partner_id.company_id.id
else:
- company_id = self.env['res.company']._company_default_get('res.users')
+ company_id = self.env['res.company']._company_default_get('res.users').id
user_portal = wizard_user.sudo().with_context(company_id=company_id)._create_user()
else:
user_portal = user
diff --git a/addons/pos_cache/i18n/tr.po b/addons/pos_cache/i18n/tr.po
index 85565d72609..22c95880db7 100644
--- a/addons/pos_cache/i18n/tr.po
+++ b/addons/pos_cache/i18n/tr.po
@@ -110,7 +110,7 @@ msgstr "Ürün Alanı"
#. module: pos_cache
#: model:ir.model,name:pos_cache.model_pos_cache
msgid "pos.cache"
-msgstr ""
+msgstr "pos.cache"
#. module: pos_cache
#: model:ir.model,name:pos_cache.model_pos_config
diff --git a/addons/pos_restaurant/i18n/tr.po b/addons/pos_restaurant/i18n/tr.po
index f403a4cc836..fef517cdeba 100644
--- a/addons/pos_restaurant/i18n/tr.po
+++ b/addons/pos_restaurant/i18n/tr.po
@@ -752,14 +752,14 @@ msgstr "pos.config"
#. module: pos_restaurant
#: model:ir.model,name:pos_restaurant.model_restaurant_floor
msgid "restaurant.floor"
-msgstr ""
+msgstr "restaurant.floor"
#. module: pos_restaurant
#: model:ir.model,name:pos_restaurant.model_restaurant_printer
msgid "restaurant.printer"
-msgstr ""
+msgstr "restaurant.printer"
#. module: pos_restaurant
#: model:ir.model,name:pos_restaurant.model_restaurant_table
msgid "restaurant.table"
-msgstr ""
+msgstr "restaurant.table"
diff --git a/addons/product/models/product.py b/addons/product/models/product.py
index dd0f2a4817a..18cba4a61be 100644
--- a/addons/product/models/product.py
+++ b/addons/product/models/product.py
@@ -220,6 +220,7 @@ class ProductProduct(models.Model):
for supplier_info in self.seller_ids:
if supplier_info.name.id == self._context.get('partner_id'):
self.code = supplier_info.product_code or self.default_code
+ break
else:
self.code = self.default_code
@@ -229,6 +230,7 @@ class ProductProduct(models.Model):
if supplier_info.name.id == self._context.get('partner_id'):
product_name = supplier_info.product_name or self.default_code
self.partner_ref = '%s%s' % (self.code and '[%s] ' % self.code or '', product_name)
+ break
else:
self.partner_ref = self.name_get()[0][1]
diff --git a/addons/product/models/product_attribute.py b/addons/product/models/product_attribute.py
index e47297da52f..0b319b6d8ce 100644
--- a/addons/product/models/product_attribute.py
+++ b/addons/product/models/product_attribute.py
@@ -4,6 +4,7 @@
from odoo import api, fields, models, _
from odoo.addons import decimal_precision as dp
from odoo.exceptions import UserError, ValidationError
+from odoo.osv import expression
class ProductAttribute(models.Model):
@@ -107,6 +108,6 @@ class ProductAttributeLine(models.Model):
# search on a m2o and one on a m2m, probably this will quickly become
# difficult to compute - check if performance optimization is required
if name and operator in ('=', 'ilike', '=ilike', 'like', '=like'):
- args = ['|', ('attribute_id', operator, name), ('value_ids', operator, name)]
+ args = expression.AND([['|', ('attribute_id', operator, name), ('value_ids', operator, name)], args])
return self.search(args, limit=limit).name_get()
return super(ProductAttributeLine, self).name_search(name=name, args=args, operator=operator, limit=limit)
diff --git a/addons/product/tests/__init__.py b/addons/product/tests/__init__.py
index b0122192ff8..96caad34928 100644
--- a/addons/product/tests/__init__.py
+++ b/addons/product/tests/__init__.py
@@ -1,4 +1,4 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
-from . import test_variants, test_pricelist, test_product_pricelist
+from . import test_variants, test_pricelist, test_product_pricelist, test_seller
diff --git a/addons/product/tests/test_seller.py b/addons/product/tests/test_seller.py
new file mode 100644
index 00000000000..36693317c34
--- /dev/null
+++ b/addons/product/tests/test_seller.py
@@ -0,0 +1,28 @@
+# -*- coding: utf-8 -*-
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
+
+from odoo.tests.common import TransactionCase
+
+
+class TestSeller(TransactionCase):
+
+ def setUp(self):
+ super(TestSeller, self).setUp()
+ self.product_service = self.env.ref('product.product_product_2')
+ self.product_service.default_code = 'DEFCODE'
+ self.asustec = self.env.ref('base.res_partner_1')
+ self.camptocamp = self.env.ref('base.res_partner_12')
+
+ def test_10_sellers(self):
+ self.product_service.write({'seller_ids': [
+ (0, 0, {'name': self.asustec.id, 'product_code': 'ASUCODE'}),
+ (0, 0, {'name': self.camptocamp.id, 'product_code': 'C2CCODE'}),
+ ]})
+
+ default_code = self.product_service.code
+ self.assertEqual("DEFCODE", default_code, "Default code not used in product name")
+
+ context_code = self.product_service\
+ .with_context(partner_id=self.camptocamp.id)\
+ .code
+ self.assertEqual('C2CCODE', context_code, "Partner's code not used in product name with context set")
diff --git a/addons/product_expiry/i18n/tr.po b/addons/product_expiry/i18n/tr.po
index 450843980a7..af48243a9f9 100644
--- a/addons/product_expiry/i18n/tr.po
+++ b/addons/product_expiry/i18n/tr.po
@@ -107,6 +107,8 @@ msgid ""
"Number of days before the goods should be removed from the stock. It will be"
" computed on the lot/serial number."
msgstr ""
+"Malların stoktan çıkarılmadan önce gereken gün sayısı. Bu lot / seri "
+"numarası üzerinde hesaplanacaktır.."
#. module: product_expiry
#: model:ir.model.fields,help:product_expiry.field_product_product__use_time
diff --git a/addons/project/controllers/portal.py b/addons/project/controllers/portal.py
index 105e90e9fba..1e94b2e2a04 100644
--- a/addons/project/controllers/portal.py
+++ b/addons/project/controllers/portal.py
@@ -143,7 +143,7 @@ class CustomerPortal(CustomerPortal):
# pager
pager = portal_pager(
url="/my/tasks",
- url_args={'date_begin': date_begin, 'date_end': date_end, 'sortby': sortby, 'filterby': filterby},
+ url_args={'date_begin': date_begin, 'date_end': date_end, 'sortby': sortby, 'filterby': filterby, 'search_in': search_in, 'search': search},
total=task_count,
page=page,
step=self._items_per_page
diff --git a/addons/project/i18n/tr.po b/addons/project/i18n/tr.po
index 4e4795b6648..aa60fd117ae 100644
--- a/addons/project/i18n/tr.po
+++ b/addons/project/i18n/tr.po
@@ -1523,6 +1523,8 @@ msgid ""
"Lets the company customize which Pad installation should be used to link to "
"new pads (for example: http://etherpad.com/)."
msgstr ""
+"Şirketin yeni pedlere bağlantı kurmak için hangi Pad kurulumunun "
+"kullanılması gerektiğini özelleştirir (örneğin: http://etherpad.com/)."
#. module: project
#: model:ir.model.fields,help:project.field_project_project__analytic_account_id
diff --git a/addons/project/models/project.py b/addons/project/models/project.py
index 36eb3d323be..f2758b1e9e3 100644
--- a/addons/project/models/project.py
+++ b/addons/project/models/project.py
@@ -868,7 +868,7 @@ class Task(models.Model):
groups = [new_group] + groups
for group_name, group_method, group_data in groups:
- if group_name in ('customer'):
+ if group_name == 'customer':
continue
group_data['has_button_access'] = True
diff --git a/addons/purchase/models/purchase.py b/addons/purchase/models/purchase.py
index 72c1cedab76..d25ff51881b 100644
--- a/addons/purchase/models/purchase.py
+++ b/addons/purchase/models/purchase.py
@@ -537,7 +537,7 @@ class PurchaseOrder(models.Model):
result['context'] = {}
pick_ids = self.mapped('picking_ids')
#choose the view_mode accordingly
- if len(pick_ids) > 1:
+ if not pick_ids or len(pick_ids) > 1:
result['domain'] = "[('id','in',%s)]" % (pick_ids.ids)
elif len(pick_ids) == 1:
res = self.env.ref('stock.view_picking_form', False)
diff --git a/addons/purchase/views/purchase_template.xml b/addons/purchase/views/purchase_template.xml
index 71d77830d6c..4c5c01f4ee7 100644
--- a/addons/purchase/views/purchase_template.xml
+++ b/addons/purchase/views/purchase_template.xml
@@ -5,7 +5,7 @@
<div>
<strong>The ordered quantity has been updated.</strong>
<ul>
- <li><t t-esc="line.order_id.product_id.display_name"/>:</li>
+ <li><t t-esc="line.product_id.display_name"/>:</li>
Ordered Quantity: <t t-esc="line.product_qty" /> -&gt; <t t-esc="float(product_qty)"/><br/>
<t t-if='line.order_id.product_id.type in ("consu", "product")'>
Received Quantity: <t t-esc="line.qty_received" /><br/>
diff --git a/addons/repair/i18n/tr.po b/addons/repair/i18n/tr.po
index 88357d2a8f6..d93d5460fb6 100644
--- a/addons/repair/i18n/tr.po
+++ b/addons/repair/i18n/tr.po
@@ -990,4 +990,4 @@ msgstr "stock.traceability.report"
#. module: repair
#: model:ir.model,name:repair.model_stock_warn_insufficient_qty_repair
msgid "stock.warn.insufficient.qty.repair"
-msgstr ""
+msgstr "stock.warn.insufficient.qty.repair"
diff --git a/addons/repair/models/repair.py b/addons/repair/models/repair.py
index 807f2b91117..c3b6ce4a36d 100644
--- a/addons/repair/models/repair.py
+++ b/addons/repair/models/repair.py
@@ -200,9 +200,11 @@ class Repair(models.Model):
def action_validate(self):
self.ensure_one()
precision = self.env['decimal.precision'].precision_get('Product Unit of Measure')
- available_qty = self.env['stock.quant']._get_available_quantity(self.product_id, self.location_id, self.lot_id, strict=True)
- if float_compare(available_qty, self.product_qty, precision_digits=precision) >= 0:
- return self.action_repair_confirm()
+ available_qty_owner = self.env['stock.quant']._get_available_quantity(self.product_id, self.location_id, self.lot_id, owner_id=self.partner_id, strict=True)
+ available_qty_noown = self.env['stock.quant']._get_available_quantity(self.product_id, self.location_id, self.lot_id, strict=True)
+ for available_qty in [available_qty_owner, available_qty_noown]:
+ if float_compare(available_qty, self.product_qty, precision_digits=precision) >= 0:
+ return self.action_repair_confirm()
else:
return {
'name': _('Insufficient Quantity'),
@@ -428,8 +430,15 @@ class Repair(models.Model):
if self.filtered(lambda repair: not repair.repaired):
raise UserError(_("Repair must be repaired in order to make the product moves."))
res = {}
+ precision = self.env['decimal.precision'].precision_get('Product Unit of Measure')
Move = self.env['stock.move']
for repair in self:
+ # Try to create move with the appropriate owner
+ owner_id = False
+ available_qty_owner = self.env['stock.quant']._get_available_quantity(repair.product_id, repair.location_id, repair.lot_id, owner_id=repair.partner_id, strict=True)
+ if float_compare(available_qty_owner, repair.product_qty, precision_digits=precision) >= 0:
+ owner_id = repair.partner_id.id
+
moves = self.env['stock.move']
for operation in repair.operations:
move = Move.create({
@@ -447,6 +456,7 @@ class Repair(models.Model):
'qty_done': operation.product_uom_qty,
'package_id': False,
'result_package_id': False,
+ 'owner_id': owner_id,
'location_id': operation.location_id.id, #TODO: owner stuff
'location_dest_id': operation.location_dest_id.id,})],
'repair_id': repair.id,
@@ -469,6 +479,7 @@ class Repair(models.Model):
'qty_done': repair.product_qty,
'package_id': False,
'result_package_id': False,
+ 'owner_id': owner_id,
'location_id': repair.location_id.id, #TODO: owner stuff
'location_dest_id': repair.location_id.id,})],
'repair_id': repair.id,
diff --git a/addons/repair/report/repair_templates_repair_order.xml b/addons/repair/report/repair_templates_repair_order.xml
index 0e255cbc69d..ccd7dcfa53c 100644
--- a/addons/repair/report/repair_templates_repair_order.xml
+++ b/addons/repair/report/repair_templates_repair_order.xml
@@ -2,7 +2,7 @@
<odoo>
<data>
<template id="report_repairorder">
- <t t-foreach="docs" t-as="o">
+ <t t-set="o" t-value="doc"/>
<t t-call="web.external_layout">
<t t-set="o" t-value="o.with_context({'lang': o.partner_id.lang})" />
<div class="page">
@@ -155,7 +155,6 @@
<div class="oe_structure"/>
</div>
</t>
- </t>
</template>
<template id="report_repairorder2">
diff --git a/addons/sale/report/report_all_channels_sales_views.xml b/addons/sale/report/report_all_channels_sales_views.xml
index 793b568528e..201e229a186 100644
--- a/addons/sale/report/report_all_channels_sales_views.xml
+++ b/addons/sale/report/report_all_channels_sales_views.xml
@@ -4,7 +4,7 @@
<field name="name">report.all.channels.sales.pivot</field>
<field name="model">report.all.channels.sales</field>
<field name="arch" type="xml">
- <pivot string="Sales by Channel Analysis">
+ <pivot string="Sales by Channel Analysis" disable_linking="True">
<field name="name" type="row"/>
<field name="price_total" string="Total Price" type="measure"/>
</pivot>
diff --git a/addons/sale_payment/i18n/tr.po b/addons/sale_payment/i18n/tr.po
index e5930a93beb..8a6ddb72af1 100644
--- a/addons/sale_payment/i18n/tr.po
+++ b/addons/sale_payment/i18n/tr.po
@@ -176,7 +176,7 @@ msgstr "Ödeme İşlemi"
#. module: sale_payment
#: model:ir.ui.view,arch_db:sale_payment.crm_team_salesteams_view_kanban_inherit_website_portal_sale
msgid "Payment to Capture"
-msgstr ""
+msgstr "Yakalanan Ödeme"
#. module: sale_payment
#: model:ir.ui.view,arch_db:sale_payment.crm_team_salesteams_view_kanban_inherit_website_portal_sale
diff --git a/addons/sale_timesheet/__init__.py b/addons/sale_timesheet/__init__.py
index 4480f53802e..eca4161450d 100644
--- a/addons/sale_timesheet/__init__.py
+++ b/addons/sale_timesheet/__init__.py
@@ -1,7 +1,18 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
+from odoo import api, SUPERUSER_ID
+
from . import models
from . import wizard
from . import controllers
from . import report
+
+def uninstall_hook(cr, registry):
+ env = api.Environment(cr, SUPERUSER_ID, {})
+ env['product.template'].search([
+ ('service_type', '=', 'timesheet')
+ ]).write({'service_type': 'manual'})
+ env['product.product'].search([
+ ('service_type', '=', 'timesheet')
+ ]).write({'service_type': 'manual'})
diff --git a/addons/sale_timesheet/__manifest__.py b/addons/sale_timesheet/__manifest__.py
index ba22b0818f2..924f12fd15a 100644
--- a/addons/sale_timesheet/__manifest__.py
+++ b/addons/sale_timesheet/__manifest__.py
@@ -33,4 +33,5 @@ have real delivered quantities in sales orders.
'data/sale_service_demo.xml',
],
'auto_install': True,
+ 'uninstall_hook': 'uninstall_hook',
}
diff --git a/addons/stock/i18n/tr.po b/addons/stock/i18n/tr.po
index 5eb3786cd5d..cd3c1a68696 100644
--- a/addons/stock/i18n/tr.po
+++ b/addons/stock/i18n/tr.po
@@ -6851,7 +6851,7 @@ msgstr "stock.fixed.putaway.strat"
#. module: stock
#: model:ir.model,name:stock.model_stock_overprocessed_transfer
msgid "stock.overprocessed.transfer"
-msgstr ""
+msgstr "stock.overprocessed.transfer"
#. module: stock
#: model:ir.model,name:stock.model_stock_return_picking_line
@@ -6871,12 +6871,12 @@ msgstr "stock.traceability.report"
#. module: stock
#: model:ir.model,name:stock.model_stock_warn_insufficient_qty
msgid "stock.warn.insufficient.qty"
-msgstr ""
+msgstr "stock.warn.insufficient.qty"
#. module: stock
#: model:ir.model,name:stock.model_stock_warn_insufficient_qty_scrap
msgid "stock.warn.insufficient.qty.scrap"
-msgstr ""
+msgstr "stock.warn.insufficient.qty.scrap"
#. module: stock
#: model:ir.ui.view,arch_db:stock.view_inventory_form
diff --git a/addons/stock/models/product.py b/addons/stock/models/product.py
index 75223abea24..ae8cc4d98fd 100644
--- a/addons/stock/models/product.py
+++ b/addons/stock/models/product.py
@@ -98,13 +98,13 @@ class Product(models.Model):
domain_move_in = [('product_id', 'in', self.ids)] + domain_move_in_loc
domain_move_out = [('product_id', 'in', self.ids)] + domain_move_out_loc
- if lot_id:
+ if lot_id is not None:
domain_quant += [('lot_id', '=', lot_id)]
- if owner_id:
+ if owner_id is not None:
domain_quant += [('owner_id', '=', owner_id)]
domain_move_in += [('restrict_partner_id', '=', owner_id)]
domain_move_out += [('restrict_partner_id', '=', owner_id)]
- if package_id:
+ if package_id is not None:
domain_quant += [('package_id', '=', package_id)]
if dates_in_the_past:
domain_move_in_done = list(domain_move_in)
diff --git a/addons/stock/models/stock_move.py b/addons/stock/models/stock_move.py
index 28a0055b5a4..6a596fed2c2 100644
--- a/addons/stock/models/stock_move.py
+++ b/addons/stock/models/stock_move.py
@@ -661,7 +661,7 @@ class StockMove(models.Model):
self.product_uom = product.uom_id.id
return {'domain': {'product_uom': [('category_id', '=', product.uom_id.category_id.id)]}}
- @api.onchange('date')
+ @api.onchange('date_expected')
def onchange_date(self):
if self.date_expected:
self.date = self.date_expected
@@ -877,11 +877,6 @@ class StockMove(models.Model):
package_id=package_id, owner_id=owner_id, strict=strict
)
except UserError:
- # If it raises here, it means that the `available_quantity` brought by a done move line
- # is not available on the quants itself. This could be the result of an inventory
- # adjustment that removed totally of partially `available_quantity`. When this happens, we
- # chose to do nothing. This situation could not happen on MTS move, because in this case
- # `available_quantity` is directly the quantity on the quants themselves.
taken_quantity = 0
# Find a candidate move line to update or create a new one.
@@ -997,7 +992,17 @@ class StockMove(models.Model):
available_move_lines[(move_line.location_id, move_line.lot_id, move_line.result_package_id, move_line.owner_id)] -= move_line.product_qty
for (location_id, lot_id, package_id, owner_id), quantity in available_move_lines.items():
need = move.product_qty - sum(move.move_line_ids.mapped('product_qty'))
- taken_quantity = move._update_reserved_quantity(need, quantity, location_id, lot_id, package_id, owner_id)
+ # `quantity` is what is brought by chained done move lines. We double check
+ # here this quantity is available on the quants themselves. If not, this
+ # could be the result of an inventory adjustment that removed totally of
+ # partially `quantity`. When this happens, we chose to reserve the maximum
+ # still available. This situation could not happen on MTS move, because in
+ # this case `quantity` is directly the quantity on the quants themselves.
+ available_quantity = self.env['stock.quant']._get_available_quantity(
+ move.product_id, location_id, lot_id=lot_id, package_id=package_id, owner_id=owner_id, strict=True)
+ if float_is_zero(available_quantity, precision_rounding=move.product_id.uom_id.rounding):
+ continue
+ taken_quantity = move._update_reserved_quantity(need, min(quantity, available_quantity), location_id, lot_id, package_id, owner_id)
if float_is_zero(taken_quantity, precision_rounding=move.product_id.uom_id.rounding):
continue
if need - taken_quantity == 0.0:
@@ -1079,6 +1084,9 @@ class StockMove(models.Model):
break
return extra_move
+ def _unreserve_initial_demand(self, new_move):
+ pass
+
def _action_done(self):
self.filtered(lambda move: move.state == 'draft')._action_confirm() # MRP allows scrapping draft moves
@@ -1119,9 +1127,7 @@ class StockMove(models.Model):
move_line.write({'product_uom_qty': move_line.qty_done})
except UserError:
pass
-
- # If you were already putting stock.move.lots on the next one in the work order, transfer those to the new move
- move.move_line_ids.filtered(lambda x: x.qty_done == 0.0).write({'move_id': new_move, 'product_uom_qty': 0})
+ move._unreserve_initial_demand(new_move)
move.move_line_ids._action_done()
# Check the consistency of the result packages; there should be an unique location across
# the contained quants.
diff --git a/addons/stock/report/report_stockpicking_operations.xml b/addons/stock/report/report_stockpicking_operations.xml
index b92d95738e3..537746a201d 100644
--- a/addons/stock/report/report_stockpicking_operations.xml
+++ b/addons/stock/report/report_stockpicking_operations.xml
@@ -99,6 +99,7 @@
<span t-if="o.state != 'done'" t-field="ml.product_uom_qty"/>
<span t-if="o.state == 'done'" t-field="ml.qty_done"/>
<span t-field="ml.product_uom_id" groups="uom.group_uom"/>
+
</td>
<td width="20%" t-if="o.picking_type_id.code != 'incoming'">
<span t-esc="ml.location_id.display_name"/>
@@ -116,11 +117,15 @@
</td>
<td width="15%" class=" text-center h6" t-if="has_serial_number">
<img t-if="has_serial_number and (ml.lot_id or ml.lot_name)" t-att-src="'/report/barcode/?type=%s&amp;value=%s&amp;width=%s&amp;height=%s&amp;humanreadable=1' % ('Code128', ml.lot_id.name, 600, 100)" style="width:100%;height:35px;"/>
+
</td>
<td width="15%" class="text-center" t-if="has_barcode">
<t t-if="product_barcode != move.product_id.barcode">
<span t-if="move.product_id and move.product_id.barcode">
- <img t-att-src="'/report/barcode/?type=%s&amp;value=%s&amp;width=%s&amp;height=%s' % ('Code128', move.product_id.barcode, 600, 100)" style="width:100%;height:35px"/>
+ <img t-if="len(move.product_id.barcode) == 13" t-att-src="'/report/barcode/?type=%s&amp;value=%s&amp;width=%s&amp;height=%s' % ('EAN13', move.product_id.barcode, 600, 100)" style="width:100%;height:35px"/>
+ <img t-elif="len(move.product_id.barcode) == 8" t-att-src="'/report/barcode/?type=%s&amp;value=%s&amp;width=%s&amp;height=%s' % ('EAN8', move.product_id.barcode, 600, 100)" style="width:100%;height:35px"/>
+ <img t-else="" t-att-src="'/report/barcode/?type=%s&amp;value=%s&amp;width=%s&amp;height=%s' % ('Code128', move.product_id.barcode, 600, 100)" style="width:100%;height:35px"/>
+
</span>
<t t-set="product_barcode" t-value="move.product_id.barcode"/>
</t>
diff --git a/addons/stock/tests/test_move.py b/addons/stock/tests/test_move.py
index 9b5de71473c..32129bde80a 100644
--- a/addons/stock/tests/test_move.py
+++ b/addons/stock/tests/test_move.py
@@ -1901,18 +1901,29 @@ class StockMove(TransactionCase):
ml.qty_done = 1
res_dict_for_back_order = picking_pack_cust.button_validate()
backorder_wizard = self.env[(res_dict_for_back_order.get('res_model'))].browse(res_dict_for_back_order.get('res_id'))
- backorder_wizard.with_context(debug=True).process()
+ backorder_wizard.process()
backorder = self.env['stock.picking'].search([('backorder_id', '=', picking_pack_cust.id)])
- backordered_ml = backorder.move_line_ids
- quant_lot3 = self.env['stock.quant'].search([('lot_id', '=', backordered_ml.lot_id.id)])
+ backordered_move = backorder.move_lines
# due to the rounding, the backordered quantity is 0.999 ; we shoudln't be able to reserve
# 0.999 on a tracked by serial number quant
- self.assertEqual(backordered_ml.product_uom_qty, 0)
- self.assertTrue(backordered_ml.lot_id)
+ backordered_move._action_assign()
+ self.assertEqual(backordered_move.reserved_availability, 0)
# force the serial number and validate
- backordered_ml.qty_done = 1
+ lot3 = self.env['stock.production.lot'].search([('name', '=', "lot3")])
+ backorder.write({'move_line_ids': [(0, 0, {
+ 'product_id': self.product2.id,
+ 'product_uom_id': self.uom_unit.id,
+ 'qty_done': 1,
+ 'product_uom_qty': 0,
+ 'lot_id': lot3.id,
+ 'package_id': False,
+ 'result_package_id': False,
+ 'location_id': backordered_move.location_id.id,
+ 'location_dest_id': backordered_move.location_dest_id.id,
+ 'move_id': backordered_move.id,
+ })]})
overprocessed_wizard = backorder.button_validate()
overprocessed_wizard = self.env['stock.overprocessed.transfer'].browse(overprocessed_wizard['res_id'])
@@ -1921,6 +1932,57 @@ class StockMove(TransactionCase):
self.assertEqual(self.env['stock.quant']._get_available_quantity(self.product2, self.customer_location), 3)
self.assertEqual(self.env['stock.quant']._get_available_quantity(self.product2, self.pack_location), 0)
+ def test_link_assign_10(self):
+ """ Test the assignment mechanism with partial availability.
+ """
+ # make some stock:
+ # stock location: 2.0
+ # pack location: -1.0
+ self.env['stock.quant']._update_available_quantity(self.product1, self.stock_location, 2.0)
+ self.assertEqual(len(self.env['stock.quant']._gather(self.product1, self.stock_location)), 1.0)
+
+ move_out = self.env['stock.move'].create({
+ 'name': 'test_link_assign_out',
+ 'location_id': self.pack_location.id,
+ 'location_dest_id': self.customer_location.id,
+ 'product_id': self.product1.id,
+ 'product_uom': self.uom_unit.id,
+ 'product_uom_qty': 1.0,
+ })
+ move_out._action_confirm()
+ move_out._action_assign()
+ move_out.quantity_done = 1.0
+ move_out._action_done()
+ self.assertEqual(len(self.env['stock.quant']._gather(self.product1, self.pack_location)), 1.0)
+
+ move_stock_pack = self.env['stock.move'].create({
+ 'name': 'test_link_assign_1_1',
+ 'location_id': self.stock_location.id,
+ 'location_dest_id': self.pack_location.id,
+ 'product_id': self.product1.id,
+ 'product_uom': self.uom_unit.id,
+ 'product_uom_qty': 2.0,
+ })
+ move_pack_cust = self.env['stock.move'].create({
+ 'name': 'test_link_assign_1_2',
+ 'location_id': self.pack_location.id,
+ 'location_dest_id': self.customer_location.id,
+ 'product_id': self.product1.id,
+ 'product_uom': self.uom_unit.id,
+ 'product_uom_qty': 2.0,
+ })
+ move_stock_pack.write({'move_dest_ids': [(4, move_pack_cust.id, 0)]})
+ move_pack_cust.write({'move_orig_ids': [(4, move_stock_pack.id, 0)]})
+
+ (move_stock_pack + move_pack_cust)._action_confirm()
+ move_stock_pack._action_assign()
+ move_stock_pack.quantity_done = 2.0
+ move_stock_pack._action_done()
+ self.assertEqual(len(move_pack_cust.move_line_ids), 1)
+
+ self.assertAlmostEqual(move_pack_cust.reserved_availability, 1.0)
+ self.assertEqual(move_pack_cust.state, 'partially_available')
+
def test_use_unreserved_move_line_1(self):
""" Test that validating a stock move linked to an untracked product reserved by another one
correctly unreserves the other one.
diff --git a/addons/stock_account/models/product.py b/addons/stock_account/models/product.py
index ae4cf425b6d..88823b67b96 100644
--- a/addons/stock_account/models/product.py
+++ b/addons/stock_account/models/product.py
@@ -201,39 +201,45 @@ class ProductProduct(models.Model):
fifo_automated_values[(row[0], row[1])] = (row[2], row[3], list(row[4]))
for product in self:
- if product.cost_method in ['standard', 'average']:
- qty_available = product.with_context(company_owned=True).qty_available
- price_used = product.standard_price
- if to_date:
- price_used = product.get_history_price(
- self.env.user.company_id.id,
- date=to_date,
- )
- product.stock_value = price_used * qty_available
- product.qty_at_date = qty_available
- elif product.cost_method == 'fifo':
- if to_date:
- if product.product_tmpl_id.valuation == 'manual_periodic':
- domain = [('product_id', '=', product.id), ('date', '<=', to_date)] + StockMove._get_all_base_domain()
- moves = StockMove.search(domain)
+ if to_date:
+ price_used = product.get_history_price(
+ self.env.user.company_id.id,
+ date=to_date,
+ ) if product.cost_method in ['standard', 'average'] else 0.0
+ if product.product_tmpl_id.valuation == 'manual_periodic':
+ domain = [('product_id', '=', product.id), ('date', '<=', to_date)] + StockMove._get_all_base_domain()
+ moves = StockMove.search(domain)
+ product.qty_at_date = product.with_context(company_owned=True, owner_id=False).qty_available
+ if product.cost_method == 'fifo':
product.stock_value = sum(moves.mapped('value'))
- product.qty_at_date = product.with_context(company_owned=True).qty_available
product.stock_fifo_manual_move_ids = StockMove.browse(moves.ids)
- elif product.product_tmpl_id.valuation == 'real_time':
- valuation_account_id = product.categ_id.property_stock_valuation_account_id.id
- value, quantity, aml_ids = fifo_automated_values.get((product.id, valuation_account_id)) or (0, 0, [])
+ elif product.cost_method in ['standard', 'average']:
+ product.stock_value = product.qty_at_date * price_used
+ elif product.product_tmpl_id.valuation == 'real_time':
+ valuation_account_id = product.categ_id.property_stock_valuation_account_id.id
+ value, quantity, aml_ids = fifo_automated_values.get((product.id, valuation_account_id)) or (0, 0, [])
+ product.qty_at_date = quantity
+ if product.cost_method == 'fifo':
product.stock_value = value
- product.qty_at_date = quantity
product.stock_fifo_real_time_aml_ids = self.env['account.move.line'].browse(aml_ids)
- else:
- product.stock_value, moves = product._sum_remaining_values()
- product.qty_at_date = product.with_context(company_owned=True).qty_available
- if product.product_tmpl_id.valuation == 'manual_periodic':
- product.stock_fifo_manual_move_ids = moves
- elif product.product_tmpl_id.valuation == 'real_time':
- valuation_account_id = product.categ_id.property_stock_valuation_account_id.id
- value, quantity, aml_ids = fifo_automated_values.get((product.id, valuation_account_id)) or (0, 0, [])
+ elif product.cost_method in ['standard', 'average']:
+ product.stock_value = quantity * price_used
+ else:
+ if product.product_tmpl_id.valuation == 'manual_periodic':
+ product.qty_at_date = product.with_context(company_owned=True, owner_id=False).qty_available
+ if product.cost_method == 'fifo':
+ product.stock_value, product.stock_fifo_manual_move_ids = product._sum_remaining_values()
+ elif product.cost_method in ['standard', 'average']:
+ product.stock_value = product.qty_at_date * product.standard_price
+ elif product.product_tmpl_id.valuation == 'real_time':
+ valuation_account_id = product.categ_id.property_stock_valuation_account_id.id
+ value, quantity, aml_ids = fifo_automated_values.get((product.id, valuation_account_id)) or (0, 0, [])
+ product.qty_at_date = quantity
+ if product.cost_method == 'fifo':
+ product.stock_value = value
product.stock_fifo_real_time_aml_ids = self.env['account.move.line'].browse(aml_ids)
+ elif product.cost_method in ['standard', 'average']:
+ product.stock_value = quantity * product.standard_price
def action_valuation_at_date_details(self):
""" Returns an action with either a list view of all the valued stock moves of `self` if the
@@ -404,4 +410,3 @@ class ProductCategory(models.Model):
'message': _("Changing your cost method is an important change that will impact your inventory valuation. Are you sure you want to make that change?"),
}
}
-
diff --git a/addons/stock_account/models/stock.py b/addons/stock_account/models/stock.py
index a0764069865..0d480f0410c 100644
--- a/addons/stock_account/models/stock.py
+++ b/addons/stock_account/models/stock.py
@@ -596,7 +596,8 @@ class StockMove(models.Model):
def _create_account_move_line(self, credit_account_id, debit_account_id, journal_id):
self.ensure_one()
AccountMove = self.env['account.move']
- quantity = self.env.context.get('forced_quantity', self.product_qty if self._is_in() else -1 * self.product_qty)
+ quantity = self.env.context.get('forced_quantity', self.product_qty)
+ quantity = quantity if self._is_in() else -1 * quantity
# Make an informative `ref` on the created account move to differentiate between classic
# movements, vacuum and edition of past moves.
diff --git a/addons/stock_account/tests/test_stockvaluation.py b/addons/stock_account/tests/test_stockvaluation.py
index 1679ba51368..ada1b155a93 100644
--- a/addons/stock_account/tests/test_stockvaluation.py
+++ b/addons/stock_account/tests/test_stockvaluation.py
@@ -2079,6 +2079,8 @@ class TestStockValuation(TransactionCase):
self.assertEqual(len(move1.account_move_ids), 1)
+ self.assertAlmostEqual(self.product1.qty_available, 10.0)
+ self.assertAlmostEqual(self.product1.qty_at_date, 10.0)
self.assertEqual(self.product1.stock_value, 100)
# ---------------------------------------------------------------------
@@ -2121,6 +2123,8 @@ class TestStockValuation(TransactionCase):
self.assertEqual(len(move2.account_move_ids), 1)
+ self.assertAlmostEqual(self.product1.qty_available, 20.0)
+ self.assertAlmostEqual(self.product1.qty_at_date, 20.0)
self.assertEqual(self.product1.stock_value, 220)
# ---------------------------------------------------------------------
@@ -2165,6 +2169,8 @@ class TestStockValuation(TransactionCase):
self.assertEqual(len(move3.account_move_ids), 1)
+ self.assertAlmostEqual(self.product1.qty_available, 12.0)
+ self.assertAlmostEqual(self.product1.qty_at_date, 12.0)
self.assertEqual(self.product1.stock_value, 140)
# ---------------------------------------------------------------------
@@ -2198,6 +2204,7 @@ class TestStockValuation(TransactionCase):
# Ending
# ---------------------------------------------------------------------
self.assertEqual(self.product1.qty_available, 6)
+ self.assertAlmostEqual(self.product1.qty_at_date, 6.0)
self.assertEqual(self.product1.stock_value, 72)
self.assertEqual(sum(self._get_stock_input_move_lines().mapped('debit')), 0)
self.assertEqual(sum(self._get_stock_input_move_lines().mapped('credit')), 220)
@@ -2553,8 +2560,33 @@ class TestStockValuation(TransactionCase):
move2.move_line_ids.qty_done = 1.0
move2._action_done()
+ self.assertAlmostEqual(self.product1.qty_available, 2.0)
+ self.assertAlmostEqual(self.product1.qty_at_date, 2.0)
self.assertAlmostEqual(self.product1.standard_price, 7.5)
+ def test_average_perpetual_5(self):
+ ''' Set owner on incoming move => no valuation '''
+ self.product1.product_tmpl_id.cost_method = 'average'
+
+ move1 = self.env['stock.move'].create({
+ 'name': 'Receive 1 unit at 10',
+ 'location_id': self.supplier_location.id,
+ 'location_dest_id': self.stock_location.id,
+ 'product_id': self.product1.id,
+ 'product_uom': self.uom_unit.id,
+ 'product_uom_qty': 1.0,
+ 'price_unit': 10,
+ })
+ move1._action_confirm()
+ move1._action_assign()
+ move1.move_line_ids.qty_done = 1.0
+ move1.move_line_ids.owner_id = self.owner1.id
+ move1._action_done()
+
+ self.assertAlmostEqual(self.product1.qty_available, 1.0)
+ self.assertAlmostEqual(self.product1.qty_at_date, 0.0)
+ self.assertAlmostEqual(self.product1.stock_value, 0.0)
+
def test_average_negative_1(self):
""" Test edit in the past. Receive 10, send 20, edit the second move to only send 10.
"""
@@ -2843,6 +2875,77 @@ class TestStockValuation(TransactionCase):
self.assertEqual(move7.value, 100.0)
self.assertEqual(self.product1.standard_price, 10)
+ def test_average_manual_1(self):
+ ''' Set owner on incoming move => no valuation '''
+ self.product1.product_tmpl_id.cost_method = 'average'
+ self.product1.product_tmpl_id.valuation = 'manual_periodic'
+
+ move1 = self.env['stock.move'].create({
+ 'name': 'Receive 1 unit at 10',
+ 'location_id': self.supplier_location.id,
+ 'location_dest_id': self.stock_location.id,
+ 'product_id': self.product1.id,
+ 'product_uom': self.uom_unit.id,
+ 'product_uom_qty': 1.0,
+ 'price_unit': 10,
+ })
+ move1._action_confirm()
+ move1._action_assign()
+ move1.move_line_ids.qty_done = 1.0
+ move1.move_line_ids.owner_id = self.owner1.id
+ move1._action_done()
+
+ self.assertAlmostEqual(self.product1.qty_available, 1.0)
+ self.assertAlmostEqual(self.product1.qty_at_date, 0.0)
+ self.assertAlmostEqual(self.product1.stock_value, 0.0)
+
+ def test_standard_perpetual_1(self):
+ ''' Set owner on incoming move => no valuation '''
+ self.product1.product_tmpl_id.cost_method = 'standard'
+
+ move1 = self.env['stock.move'].create({
+ 'name': 'Receive 1 unit at 10',
+ 'location_id': self.supplier_location.id,
+ 'location_dest_id': self.stock_location.id,
+ 'product_id': self.product1.id,
+ 'product_uom': self.uom_unit.id,
+ 'product_uom_qty': 1.0,
+ 'price_unit': 10,
+ })
+ move1._action_confirm()
+ move1._action_assign()
+ move1.move_line_ids.qty_done = 1.0
+ move1.move_line_ids.owner_id = self.owner1.id
+ move1._action_done()
+
+ self.assertAlmostEqual(self.product1.qty_available, 1.0)
+ self.assertAlmostEqual(self.product1.qty_at_date, 0.0)
+ self.assertAlmostEqual(self.product1.stock_value, 0.0)
+
+ def test_standard_manual_1(self):
+ ''' Set owner on incoming move => no valuation '''
+ self.product1.product_tmpl_id.cost_method = 'standard'
+ self.product1.product_tmpl_id.valuation = 'manual_periodic'
+
+ move1 = self.env['stock.move'].create({
+ 'name': 'Receive 1 unit at 10',
+ 'location_id': self.supplier_location.id,
+ 'location_dest_id': self.stock_location.id,
+ 'product_id': self.product1.id,
+ 'product_uom': self.uom_unit.id,
+ 'product_uom_qty': 1.0,
+ 'price_unit': 10,
+ })
+ move1._action_confirm()
+ move1._action_assign()
+ move1.move_line_ids.qty_done = 1.0
+ move1.move_line_ids.owner_id = self.owner1.id
+ move1._action_done()
+
+ self.assertAlmostEqual(self.product1.qty_available, 1.0)
+ self.assertAlmostEqual(self.product1.qty_at_date, 0.0)
+ self.assertAlmostEqual(self.product1.stock_value, 0.0)
+
def test_change_cost_method_1(self):
""" Change the cost method from FIFO to AVCO.
"""
@@ -2895,6 +2998,8 @@ class TestStockValuation(TransactionCase):
move3.move_line_ids.qty_done = 1.0
move3._action_done()
+ self.assertAlmostEqual(self.product1.qty_available, 19)
+ self.assertAlmostEqual(self.product1.qty_at_date, 19)
self.assertEqual(self.product1.stock_value, 240)
# ---------------------------------------------------------------------
@@ -2963,6 +3068,8 @@ class TestStockValuation(TransactionCase):
move3.move_line_ids.qty_done = 1.0
move3._action_done()
+ self.assertAlmostEqual(self.product1.qty_available, 19)
+ self.assertAlmostEqual(self.product1.qty_at_date, 19)
self.assertEqual(self.product1.stock_value, 240)
# ---------------------------------------------------------------------
@@ -3036,6 +3143,8 @@ class TestStockValuation(TransactionCase):
self.assertEqual(move1.value, 10)
self.assertEqual(move1.remaining_value, 10)
self.assertEqual(move1.remaining_qty, 1)
+ self.assertAlmostEqual(self.product1.qty_available, 0.0)
+ self.assertAlmostEqual(self.product1.qty_at_date, 2.0)
self.assertEqual(self.product1.stock_value, 10)
self.assertTrue(len(move1.account_move_ids), 1)
@@ -3185,8 +3294,10 @@ class TestStockValuation(TransactionCase):
move1.move_line_ids.qty_done = 10
move1._action_done()
move1.date = date2
+ move1.account_move_ids.write({'date': date2})
self.assertEqual(self.product1.qty_available, 10)
+ self.assertAlmostEqual(self.product1.qty_at_date, 10.0)
self.assertEqual(self.product1.stock_value, 100)
# receive 20
@@ -3203,8 +3314,10 @@ class TestStockValuation(TransactionCase):
move2.move_line_ids.qty_done = 20
move2._action_done()
move2.date = date3
+ move2.account_move_ids.write({'date': date3})
self.assertEqual(self.product1.qty_available, 30)
+ self.assertAlmostEqual(self.product1.qty_at_date, 30.0)
self.assertEqual(self.product1.stock_value, 300)
# send 15
@@ -3221,8 +3334,10 @@ class TestStockValuation(TransactionCase):
move3.move_line_ids.qty_done = 15
move3._action_done()
move3.date = date4
+ move3.account_move_ids.write({'date': date4})
self.assertEqual(self.product1.qty_available, 15)
+ self.assertAlmostEqual(self.product1.qty_at_date, 15.0)
self.assertEqual(self.product1.stock_value, 150)
# set the standard price to 5
@@ -3230,6 +3345,7 @@ class TestStockValuation(TransactionCase):
self.env['product.price.history'].search([('product_id', '=', self.product1.id)], order='datetime desc, id DESC', limit=1).datetime = date5
self.assertEqual(self.product1.qty_available, 15)
+ self.assertAlmostEqual(self.product1.qty_at_date, 15.0)
self.assertEqual(self.product1.stock_value, 75)
# send 20
@@ -3246,8 +3362,10 @@ class TestStockValuation(TransactionCase):
move4.move_line_ids.qty_done = 20
move4._action_done()
move4.date = date6
+ move4.account_move_ids.write({'date': date6})
self.assertEqual(self.product1.qty_available, -5)
+ self.assertAlmostEqual(self.product1.qty_at_date, -5.0)
self.assertEqual(self.product1.stock_value, -25)
# set the standard price to 7.5
@@ -3268,11 +3386,13 @@ class TestStockValuation(TransactionCase):
move5.move_line_ids.qty_done = 100
move5._action_done()
move5.date = date8
+ move5.account_move_ids.write({'date': date8})
self.assertEqual(self.product1.qty_available, 95)
+ self.assertAlmostEqual(self.product1.qty_at_date, 95.0)
self.assertEqual(self.product1.stock_value, 712.5)
- # Quantity at date
+ # Quantity available at date
self.assertEqual(self.product1.with_context(to_date=Date.to_string(date1)).qty_available, 0)
self.assertEqual(self.product1.with_context(to_date=Date.to_string(date2)).qty_available, 10)
self.assertEqual(self.product1.with_context(to_date=Date.to_string(date3)).qty_available, 30)
@@ -3290,12 +3410,25 @@ class TestStockValuation(TransactionCase):
self.assertEqual(self.product1.with_context(to_date=Date.to_string(date6)).stock_value, -25)
self.assertEqual(self.product1.with_context(to_date=Date.to_string(date8)).stock_value, 712.5)
+ # Quantity at date
+ self.assertAlmostEqual(self.product1.with_context(to_date=Date.to_string(date1)).qty_at_date, 0.0)
+ self.assertAlmostEqual(self.product1.with_context(to_date=Date.to_string(date2)).qty_at_date, 10.0)
+ self.assertAlmostEqual(self.product1.with_context(to_date=Date.to_string(date3)).qty_at_date, 30.0)
+ self.assertAlmostEqual(self.product1.with_context(to_date=Date.to_string(date4)).qty_at_date, 15.0)
+ self.assertAlmostEqual(self.product1.with_context(to_date=Date.to_string(date5)).qty_at_date, 15.0)
+ self.assertAlmostEqual(self.product1.with_context(to_date=Date.to_string(date6)).qty_at_date, -5.0)
+ self.assertAlmostEqual(self.product1.with_context(to_date=Date.to_string(date7)).qty_at_date, -5.0)
+ self.assertAlmostEqual(self.product1.with_context(to_date=Date.to_string(date8)).qty_at_date, 95.0)
+
# edit the done quantity of move1, decrease it
self.assertEqual(self.product1.with_context(to_date=Date.to_string(date2)).qty_available, 10)
+ self.assertAlmostEqual(self.product1.with_context(to_date=Date.to_string(date2)).qty_at_date, 10.0)
move1.quantity_done = 5
+ move1.account_move_ids.write({'date': date2})
# the quantity at date will reflect the change directly
self.assertEqual(self.product1.with_context(to_date=Date.to_string(date2)).qty_available, 5)
+ self.assertAlmostEqual(self.product1.with_context(to_date=Date.to_string(date2)).qty_at_date, 5.0)
# as when we decrease a quantity on a recreipt, we consider it as a out move with the price
# of today, the value will be decrease of 100 - (5*7.5)
@@ -3307,12 +3440,17 @@ class TestStockValuation(TransactionCase):
# edit move 4, send 15 instead of 20
# we now have +5 + 20 - 15 -20 = -10 * a standard price of 5
+ self.assertAlmostEqual(self.product1.with_context(to_date=Date.to_string(date6)).qty_available, -10.0)
+ self.assertAlmostEqual(self.product1.with_context(to_date=Date.to_string(date6)).qty_at_date, -10.0)
self.assertEqual(self.product1.with_context(to_date=Date.to_string(date6)).stock_value, -50)
move4.quantity_done = 15
+ move4.account_move_ids.write({'date': date6})
# -(20*5) + (5*7.5)
self.assertEqual(move4.value, -62.5)
# we now have +5 + 20 - 15 -15 = -5 * a standard price of 5
+ self.assertAlmostEqual(self.product1.with_context(to_date=Date.to_string(date6)).qty_available, -5.0)
+ self.assertAlmostEqual(self.product1.with_context(to_date=Date.to_string(date6)).qty_at_date, -5.0)
self.assertEqual(self.product1.with_context(to_date=Date.to_string(date6)).stock_value, -25)
def test_at_date_fifo_1(self):
@@ -3348,6 +3486,7 @@ class TestStockValuation(TransactionCase):
move1.account_move_ids.write({'date': date1})
self.assertEqual(self.product1.qty_available, 10)
+ self.assertAlmostEqual(self.product1.qty_at_date, 10.0)
self.assertEqual(self.product1.stock_value, 100)
# receive 10@12
@@ -3368,6 +3507,7 @@ class TestStockValuation(TransactionCase):
move2.account_move_ids.write({'date': date2})
self.assertEqual(self.product1.qty_available, 20)
+ self.assertAlmostEqual(self.product1.qty_at_date, 20)
self.assertEqual(self.product1.stock_value, 220)
# send 15
@@ -3387,6 +3527,7 @@ class TestStockValuation(TransactionCase):
move3.account_move_ids.write({'date': date3})
self.assertEqual(self.product1.qty_available, 5)
+ self.assertAlmostEqual(self.product1.qty_at_date, 5.0)
self.assertEqual(self.product1.stock_value, 60)
# send 20
@@ -3406,6 +3547,7 @@ class TestStockValuation(TransactionCase):
move4.account_move_ids.write({'date': date4})
self.assertEqual(self.product1.qty_available, -15)
+ self.assertAlmostEqual(self.product1.qty_at_date, -15.0)
self.assertEqual(self.product1.stock_value, -180)
# receive 100@15
@@ -3426,6 +3568,7 @@ class TestStockValuation(TransactionCase):
move5.account_move_ids.write({'date': date5})
self.assertEqual(self.product1.qty_available, 85)
+ self.assertAlmostEqual(self.product1.qty_at_date, 85.0)
self.assertEqual(self.product1.stock_value, 1320)
# run the vacuum to compensate the negative stock move
@@ -3433,6 +3576,7 @@ class TestStockValuation(TransactionCase):
move4.account_move_ids[0].write({'date': date6})
self.assertEqual(self.product1.qty_available, 85)
+ self.assertAlmostEqual(self.product1.qty_at_date, 85.0)
self.assertEqual(self.product1.stock_value, 1275)
# Edit the quantity done of move1, increase it.
@@ -3505,6 +3649,7 @@ class TestStockValuation(TransactionCase):
move1.account_move_ids.write({'date': date1})
self.assertEqual(self.product1.qty_available, 10)
+ self.assertAlmostEqual(self.product1.qty_at_date, 10.0)
self.assertEqual(self.product1.stock_value, 100)
# receive 10@15
@@ -3525,6 +3670,7 @@ class TestStockValuation(TransactionCase):
move2.account_move_ids.write({'date': date2})
self.assertEqual(self.product1.qty_available, 20)
+ self.assertAlmostEqual(self.product1.qty_at_date, 20.0)
self.assertEqual(self.product1.stock_value, 250)
# send 30
@@ -3544,6 +3690,7 @@ class TestStockValuation(TransactionCase):
move3.account_move_ids.write({'date': date3})
self.assertEqual(self.product1.qty_available, -10)
+ self.assertAlmostEqual(self.product1.qty_at_date, -10.0)
self.assertEqual(self.product1.stock_value, -150)
# receive 10@20
@@ -3564,6 +3711,7 @@ class TestStockValuation(TransactionCase):
move4.account_move_ids.write({'date': date4})
self.assertEqual(self.product1.qty_available, 0)
+ self.assertAlmostEqual(self.product1.qty_at_date, 0.0)
self.assertEqual(self.product1.stock_value, 50)
# receive 10@10
@@ -3584,6 +3732,7 @@ class TestStockValuation(TransactionCase):
move5.account_move_ids.write({'date': date5})
self.assertEqual(self.product1.qty_available, 10)
+ self.assertAlmostEqual(self.product1.qty_at_date, 10.0)
self.assertEqual(self.product1.stock_value, 150)
# run the vacuum to compensate the negative stock move
@@ -3591,6 +3740,7 @@ class TestStockValuation(TransactionCase):
move3.account_move_ids[0].write({'date': date6})
self.assertEqual(self.product1.qty_available, 10)
+ self.assertAlmostEqual(self.product1.qty_at_date, 10.0)
self.assertEqual(self.product1.stock_value, 100)
# ---------------------------------------------------------------------
diff --git a/addons/web/static/lib/qweb/qweb-test-widgets.xml b/addons/web/static/lib/qweb/qweb-test-widgets.xml
new file mode 100644
index 00000000000..503880bcc34
--- /dev/null
+++ b/addons/web/static/lib/qweb/qweb-test-widgets.xml
@@ -0,0 +1,26 @@
+<templates>
+ <t t-name="date-simple"><t t-esc='value' /></t>
+ <params id="date-simple">{"value": "1988-09-16"}</params>
+ <result id="date-simple">1988-09-16</result>
+
+ <t t-name="datetime-simple"><t t-esc='value' /></t>
+ <params id="datetime-simple">{"value": "1988-09-16 14:00:00"}</params>
+ <result id="datetime-simple">1988-09-16 14:00:00</result>
+
+ <t t-name="datetime-widget-datetime"><t t-esc='value' t-options="{'widget': 'datetime'}" /></t>
+ <params id="datetime-widget-datetime">{"value": "1988-09-16 14:00:00"}</params>
+ <result id="datetime-widget-datetime">09/16/1988 16:00:00</result>
+
+ <t t-name="datetime-widget-date"><t t-esc='value' t-options="{'widget': 'date'}" /></t>
+ <params id="datetime-widget-date">{"value": "1988-09-16 14:00:00"}</params>
+ <result id="datetime-widget-date">09/16/1988</result>
+
+ <t t-name="datetime-widget-date-tz2"><t t-esc='value' t-options="{'widget': 'date'}" /></t>
+ <params id="datetime-widget-date-tz2">{"value": "1988-09-16 01:00:00"}</params>
+ <result id="datetime-widget-date-tz2">09/16/1988</result>
+
+ <t t-name="datetime-widget-date-tz"><t t-esc='value' t-options="{'widget': 'date'}" /></t>
+ <params id="datetime-widget-date-tz">{"value": "1988-09-16 23:00:00"}</params>
+ <result id="datetime-widget-date-tz">09/17/1988</result>
+
+</templates>
diff --git a/addons/web/static/src/js/chrome/abstract_web_client.js b/addons/web/static/src/js/chrome/abstract_web_client.js
index 3492af748f5..f502f37be94 100644
--- a/addons/web/static/src/js/chrome/abstract_web_client.js
+++ b/addons/web/static/src/js/chrome/abstract_web_client.js
@@ -178,7 +178,7 @@ var AbstractWebClient = Widget.extend(ServiceProviderMixin, KeyboardNavigationMi
core.bus.on('connection_restored', this, this.on_connection_restored);
// crash manager integration
- session.on('error', crash_manager, crash_manager.rpc_error);
+ core.bus.on('rpc_error', crash_manager, crash_manager.rpc_error);
window.onerror = function (message, file, line, col, error) {
// Scripts injected in DOM (eg: google API's js files) won't return a clean error on window.onerror.
// The browser will just give you a 'Script error.' as message and nothing else for security issue.
diff --git a/addons/web/static/src/js/chrome/loading.js b/addons/web/static/src/js/chrome/loading.js
index 0c1b5e5025f..6c7f102231b 100644
--- a/addons/web/static/src/js/chrome/loading.js
+++ b/addons/web/static/src/js/chrome/loading.js
@@ -26,9 +26,9 @@ var Loading = Widget.extend({
this._super(parent);
this.count = 0;
this.blocked_ui = false;
- session.on("request", this, this.request_call);
- session.on("response", this, this.response_call);
- session.on("response_failed", this, this.response_call);
+ core.bus.on('rpc_request', this, this.request_call);
+ core.bus.on("rpc_response", this, this.response_call);
+ core.bus.on("rpc_response_failed", this, this.response_call);
},
destroy: function() {
this.on_rpc_event(-this.count);
diff --git a/addons/web/static/src/js/core/ajax.js b/addons/web/static/src/js/core/ajax.js
index d6c67eacaec..f1f73bb5a28 100644
--- a/addons/web/static/src/js/core/ajax.js
+++ b/addons/web/static/src/js/core/ajax.js
@@ -5,7 +5,12 @@ var core = require('web.core');
var utils = require('web.utils');
var time = require('web.time');
-function genericJsonRpc (fct_name, params, fct) {
+function genericJsonRpc (fct_name, params, settings, fct) {
+ var shadow = settings.shadow || false;
+ delete settings.shadow;
+ if (! shadow)
+ core.bus.trigger('rpc_request');
+
var data = {
jsonrpc: "2.0",
method: fct_name,
@@ -30,11 +35,49 @@ function genericJsonRpc (fct_name, params, fct) {
});
// FIXME: jsonp?
result.abort = function () { if (xhr.abort) xhr.abort(); };
- return result;
+
+ var p = result.then(function (result) {
+ if (!shadow) {
+ core.bus.trigger('rpc_response');
+ }
+ return result;
+ }, function (type, error, textStatus, errorThrown) {
+ if (type === "server") {
+ if (!shadow) {
+ core.bus.trigger('rpc_response');
+ }
+ if (error.code === 100) {
+ core.bus.trigger('invalidate_session');
+ }
+ return $.Deferred().reject(error, $.Event());
+ } else {
+ if (!shadow) {
+ core.bus.trigger('rpc_response_failed');
+ }
+ var nerror = {
+ code: -32098,
+ message: "XmlHttpRequestError " + errorThrown,
+ data: {
+ type: "xhr"+textStatus,
+ debug: error.responseText,
+ objects: [error, errorThrown]
+ },
+ };
+ return $.Deferred().reject(nerror, $.Event());
+ }
+ });
+ return p.fail(function () { // Allow deferred user to disable rpc_error call in fail
+ p.fail(function (error, event) {
+ if (!event.isDefaultPrevented()) {
+ core.bus.trigger('rpc_error', error, event);
+ }
+ });
+ });
}
function jsonRpc(url, fct_name, params, settings) {
- return genericJsonRpc(fct_name, params, function(data) {
+ settings = settings || {};
+ return genericJsonRpc(fct_name, params, settings, function(data) {
return $.ajax(url, _.extend({}, settings, {
url: url,
dataType: 'json',
@@ -47,7 +90,7 @@ function jsonRpc(url, fct_name, params, settings) {
function jsonpRpc(url, fct_name, params, settings) {
settings = settings || {};
- return genericJsonRpc(fct_name, params, function(data) {
+ return genericJsonRpc(fct_name, params, settings, function(data) {
var payload_str = JSON.stringify(data, time.date_to_utc);
var payload_url = $.param({r:payload_str});
var force2step = settings.force2step || false;
diff --git a/addons/web/static/src/js/core/session.js b/addons/web/static/src/js/core/session.js
index 4760867e99f..cc372877e6d 100644
--- a/addons/web/static/src/js/core/session.js
+++ b/addons/web/static/src/js/core/session.js
@@ -49,6 +49,7 @@ var Session = core.Class.extend(mixins.EventDispatcherMixin, {
this.qweb_mutex = new concurrency.Mutex();
this.currencies = {};
this._groups_def = {};
+ core.bus.on('invalidate_session', this, this._onInvalidateSession);
},
setup: function (origin, options) {
// must be able to customize server
@@ -327,23 +328,17 @@ var Session = core.Class.extend(mixins.EventDispatcherMixin, {
rpc: function (url, params, options) {
var self = this;
options = _.clone(options || {});
- var shadow = options.shadow || false;
options.headers = _.extend({}, options.headers);
if (odoo.debug) {
options.headers["X-Debug-Mode"] = $.deparam($.param.querystring()).debug;
}
- delete options.shadow;
-
return self.check_session_id().then(function () {
// TODO: remove
if (! _.isString(url)) {
_.extend(options, url);
url = url.url;
}
- // TODO correct handling of timeouts
- if (! shadow)
- self.trigger('request');
var fct;
if (self.origin_server) {
fct = ajax.jsonRpc;
@@ -362,37 +357,7 @@ var Session = core.Class.extend(mixins.EventDispatcherMixin, {
url = self.url(url, null);
options.session_id = self.session_id || '';
}
- var p = fct(url, "call", params, options);
- p = p.then(function (result) {
- if (! shadow)
- self.trigger('response');
- return result;
- }, function (type, error, textStatus, errorThrown) {
- if (type === "server") {
- if (! shadow)
- self.trigger('response');
- if (error.code === 100) {
- self.uid = false;
- }
- return $.Deferred().reject(error, $.Event());
- } else {
- if (! shadow)
- self.trigger('response_failed');
- var nerror = {
- code: -32098,
- message: "XmlHttpRequestError " + errorThrown,
- data: {type: "xhr"+textStatus, debug: error.responseText, objects: [error, errorThrown] }
- };
- return $.Deferred().reject(nerror, $.Event());
- }
- });
- return p.fail(function () { // Allow deferred user to disable rpc_error call in fail
- p.fail(function (error, event) {
- if (!event.isDefaultPrevented()) {
- self.trigger('error', error, event);
- }
- });
- });
+ return fct(url, "call", params, options);
});
},
url: function (path, params) {
@@ -418,6 +383,17 @@ var Session = core.Class.extend(mixins.EventDispatcherMixin, {
getTZOffset: function (date) {
return -new Date(date).getTimezoneOffset();
},
+
+ //--------------------------------------------------------------------------
+ // Handlers
+ //--------------------------------------------------------------------------
+
+ /**
+ * @private
+ */
+ _onInvalidateSession: function () {
+ this.uid = false;
+ },
});
return Session;
diff --git a/addons/web/static/src/js/fields/basic_fields.js b/addons/web/static/src/js/fields/basic_fields.js
index b2b7f20f1df..974615f2b5c 100644
--- a/addons/web/static/src/js/fields/basic_fields.js
+++ b/addons/web/static/src/js/fields/basic_fields.js
@@ -491,7 +491,13 @@ var FieldDate = InputField.extend({
* @private
*/
_makeDatePicker: function () {
- return new datepicker.DateWidget(this, {defaultDate: this.value});
+ return new datepicker.DateWidget(
+ this,
+ _.defaults(
+ this.nodeOptions.datepicker || {},
+ {defaultDate: this.value}
+ )
+ );
},
/**
diff --git a/addons/web_editor/static/lib/summernote/src/js/module/Editor.js b/addons/web_editor/static/lib/summernote/src/js/module/Editor.js
index b7ba30bfcd1..99947c346cf 100644
--- a/addons/web_editor/static/lib/summernote/src/js/module/Editor.js
+++ b/addons/web_editor/static/lib/summernote/src/js/module/Editor.js
@@ -628,9 +628,9 @@ define([
}
var anchors = [];
- // ODOO: adding this branch to modify existing anchor
+ // ODOO: adding this branch to modify existing anchor if it fully contains the range
var ancestor_anchor = dom.ancestor(rng.sc, dom.isAnchor);
- if(ancestor_anchor) {
+ if(ancestor_anchor && ancestor_anchor === dom.ancestor(rng.ec, dom.isAnchor)) {
anchors.push($(ancestor_anchor).html(linkText).get(0));
} else if (isTextChanged) {
// Create a new link when text changed.
diff --git a/addons/web_editor/static/src/js/editor/rte.summernote.js b/addons/web_editor/static/src/js/editor/rte.summernote.js
index 3de70e5fcda..614ab4bfcf0 100644
--- a/addons/web_editor/static/src/js/editor/rte.summernote.js
+++ b/addons/web_editor/static/src/js/editor/rte.summernote.js
@@ -474,7 +474,7 @@ function prettify_html(html) {
while (i--) space += ' ';
return space;
},
- reg = /^<\/?(a|span|font|strong|u|i|strong|b)(\s|>)/i,
+ reg = /^<\/?(a|span|font|u|em|i|strong|b)(\s|>)/i,
inline_level = Infinity,
tokens = _.compact(_.flatten(_.map(html.split(/</), function (value) {
value = value.replace(/\s+/g, ' ').split(/>/);
diff --git a/addons/web_editor/static/src/js/widgets/widgets.js b/addons/web_editor/static/src/js/widgets/widgets.js
index 51ff585d200..7aa300b5bbb 100644
--- a/addons/web_editor/static/src/js/widgets/widgets.js
+++ b/addons/web_editor/static/src/js/widgets/widgets.js
@@ -1398,6 +1398,8 @@ var LinkDialog = Dialog.extend({
if (dom.ancestor(nodes[i], dom.isImg)) {
this.data.images.push(dom.ancestor(nodes[i], dom.isImg));
text += '[IMG]';
+ } else if (!is_link && nodes[i].nodeType === 1) {
+ // just use text nodes from listBetween
} else if (!is_link && i===0) {
text += nodes[i].textContent.slice(so, Infinity);
} else if (!is_link && i===nodes.length-1) {
diff --git a/addons/website/models/ir_http.py b/addons/website/models/ir_http.py
index 0e5443ad79e..aa703071d9b 100644
--- a/addons/website/models/ir_http.py
+++ b/addons/website/models/ir_http.py
@@ -6,6 +6,7 @@ import traceback
import os
import unittest
+import pytz
import werkzeug
import werkzeug.routing
import werkzeug.utils
@@ -74,6 +75,10 @@ class Http(models.AbstractModel):
context = {}
if not request.context.get('tz'):
context['tz'] = request.session.get('geoip', {}).get('time_zone')
+ try:
+ pytz.timezone(context['tz'] or '')
+ except pytz.UnknownTimeZoneError:
+ context.pop('tz')
request.website = request.env['website'].get_current_website() # can use `request.env` since auth methods are called
context['website_id'] = request.website.id
diff --git a/addons/website/models/ir_model.py b/addons/website/models/ir_model.py
index 6d254374c38..84c6a0b1836 100644
--- a/addons/website/models/ir_model.py
+++ b/addons/website/models/ir_model.py
@@ -10,6 +10,6 @@ class IrModel(models.Model):
@api.multi
def unlink(self):
- self.env.cr.execute(
- "DELETE FROM ir_model_fields WHERE name='website_id'")
+ self.env.cr.execute("DELETE FROM ir_model_fields WHERE name='website_id'")
+ self.env.cr.execute("DELETE FROM res_config_settings WHERE website_id IS NOT NULL")
return super(IrModel, self).unlink()
diff --git a/addons/website_event/controllers/main.py b/addons/website_event/controllers/main.py
index 38bd5b0ce7f..f3a8041d54e 100644
--- a/addons/website_event/controllers/main.py
+++ b/addons/website_event/controllers/main.py
@@ -261,6 +261,6 @@ class WebsiteEventController(http.Controller):
Attendees._prepare_attendee_values(registration))
return request.render("website_event.registration_complete", {
- 'attendees': Attendees,
+ 'attendees': Attendees.sudo(),
'event': event,
})
diff --git a/addons/website_event/static/src/js/website_event.js b/addons/website_event/static/src/js/website_event.js
index ebe38118559..53a304c707e 100644
--- a/addons/website_event/static/src/js/website_event.js
+++ b/addons/website_event/static/src/js/website_event.js
@@ -59,12 +59,16 @@ var EventRegistrationForm = Widget.extend({
$button.attr('disabled', true);
return ajax.jsonRpc($form.attr('action'), 'call', post).then(function (modal) {
var $modal = $(modal);
+ $modal.modal({backdrop: 'static', keyboard: false});
$modal.find('.modal-body > div').removeClass('container'); // retrocompatibility - REMOVE ME in master / saas-19
$modal.insertAfter($form).modal();
$modal.on('click', '.js_goto_event', function () {
$modal.modal('hide');
$button.prop('disabled', false);
});
+ $modal.on('click', '.close', function () {
+ $button.prop('disabled', false);
+ });
});
}
},
diff --git a/addons/website_event_track/views/event_track_templates.xml b/addons/website_event_track/views/event_track_templates.xml
index 70ed14e680a..dbfceeb8ca6 100644
--- a/addons/website_event_track/views/event_track_templates.xml
+++ b/addons/website_event_track/views/event_track_templates.xml
@@ -50,8 +50,8 @@
<input type="text" class="form-control" placeholder="Filter Tracks..." id="event_track_search"/>
</div>
</section>
- <t t-set="dayslist" t-value="days.keys()"/>
- <t t-set="dayslist2" t-value="list(dayslist).sort()"/> <!-- display days in the right order -->
+ <t t-set="dayslist" t-value="list(days.keys())"/>
+ <t t-set="dayslist2" t-value="dayslist.sort()"/> <!-- display days in the right order -->
<section class="container" t-foreach="dayslist" t-as="day">
<t t-set="locations" t-value="days[day]['locations']"/>
<t t-set="dates" t-value="days[day]['dates']"/>
diff --git a/addons/website_forum/models/forum.py b/addons/website_forum/models/forum.py
index 073eb69e219..afc154597d2 100644
--- a/addons/website_forum/models/forum.py
+++ b/addons/website_forum/models/forum.py
@@ -422,6 +422,11 @@ class Post(models.Model):
raise KarmaError('User karma not sufficient to post an image or link.')
return content
+ @api.constrains('parent_id')
+ def _check_parent_id(self):
+ if not self._check_recursion():
+ raise ValidationError(_('You cannot create recursive forum posts.'))
+
@api.model
def create(self, vals):
if 'content' in vals and vals.get('forum_id'):
diff --git a/addons/website_livechat/controllers/main.py b/addons/website_livechat/controllers/main.py
index 753e4eef1ae..31af89c2e63 100644
--- a/addons/website_livechat/controllers/main.py
+++ b/addons/website_livechat/controllers/main.py
@@ -20,13 +20,17 @@ class WebsiteLivechat(http.Controller):
@http.route('/livechat/channel/<model("im_livechat.channel"):channel>', type='http', auth='public', website=True)
def channel_rating(self, channel, **kw):
# get the last 100 ratings and the repartition per grade
- ratings = request.env['rating.rating'].search([('res_model', '=', 'mail.channel'), ('res_id', 'in', channel.sudo().channel_ids.ids)], order='create_date desc', limit=100)
- repartition = channel.sudo().channel_ids.rating_get_grades()
+ domain = [
+ ('res_model', '=', 'mail.channel'), ('res_id', 'in', channel.sudo().channel_ids.ids),
+ ('consumed', '=', True), ('rating', '>=', 1),
+ ]
+ ratings = request.env['rating.rating'].search(domain, order='create_date desc', limit=100)
+ repartition = channel.sudo().channel_ids.rating_get_grades(domain=domain)
# compute percentage
percentage = dict.fromkeys(['great', 'okay', 'bad'], 0)
for grade in repartition:
- percentage[grade] = repartition[grade] * 100 / sum(repartition.values()) if sum(repartition.values()) else 0
+ percentage[grade] = round(repartition[grade] * 100.0 / sum(repartition.values()), 1) if sum(repartition.values()) else 0
# the value dict to render the template
values = {
diff --git a/addons/website_mass_mailing/controllers/main.py b/addons/website_mass_mailing/controllers/main.py
index d1aa21f5cd4..455ab1bdae0 100644
--- a/addons/website_mass_mailing/controllers/main.py
+++ b/addons/website_mass_mailing/controllers/main.py
@@ -11,7 +11,7 @@ class MassMailController(MassMailController):
def mailing(self, mailing_id, email=None, res_id=None, **post):
mailing = request.env['mail.mass_mailing'].sudo().browse(mailing_id)
if mailing.exists():
- if mailing.mailing_model_name == 'mail.mass_mailing.contact':
+ if mailing.mailing_model_real == 'mail.mass_mailing.contact':
contacts = request.env['mail.mass_mailing.contact'].sudo().search([('email', '=', email)])
return request.render('website_mass_mailing.page_unsubscribe', {
'contacts': contacts,
diff --git a/addons/website_sale_stock/models/product_product.py b/addons/website_sale_stock/models/product_product.py
index 829efd3f2dc..cfab171bb32 100644
--- a/addons/website_sale_stock/models/product_product.py
+++ b/addons/website_sale_stock/models/product_product.py
@@ -11,7 +11,7 @@ class ProductProduct(models.Model):
cart_qty = fields.Integer(compute='_compute_cart_qty')
def _compute_cart_qty(self):
- website = getattr(request, 'website', None)
+ website = request and getattr(request, 'website', None)
if not website:
return
cart = website.sale_get_order()
diff --git a/addons/website_sale_wishlist/models/product_wishlist.py b/addons/website_sale_wishlist/models/product_wishlist.py
index 6c73cf50608..381d5eceb45 100644
--- a/addons/website_sale_wishlist/models/product_wishlist.py
+++ b/addons/website_sale_wishlist/models/product_wishlist.py
@@ -36,14 +36,15 @@ class ProductWishlist(models.Model):
@api.model
def current(self):
- """Get all wishlist items that belong to current user or session."""
- return self.search([
+ """Get all wishlist items that belong to current user or session,
+ filter products that are unpublished."""
+ return self.sudo().search([
"|",
("partner_id", "=", self.env.user.partner_id.id),
"&",
("partner_id", "=", False),
("session", "=", self.env.user.current_session),
- ])
+ ]).filtered('product_id.product_tmpl_id.website_published')
@api.model
def _add_to_wishlist(self, pricelist_id, currency_id, website_id, price, product_id, partner_id=False, session=False):
diff --git a/doc/cla/corporate/adhoc.md b/doc/cla/corporate/adhoc.md
index 627065bafab..428f46b0056 100644
--- a/doc/cla/corporate/adhoc.md
+++ b/doc/cla/corporate/adhoc.md
@@ -13,3 +13,4 @@ List of contributors:
Damián Soriano ds@adhoc.com.ar https://github.com/damiansoriano
Juan José Scarafía jjs@adhoc.com.ar https://github.com/jjscarafia
Nicolás Mac Rouillon nmr@adhoc.com.ar https://github.com/nicomacr
+Katherine Zaoral kz@adhoc.com.ar https://github.com/zaoral
diff --git a/doc/cla/corporate/eficent.md b/doc/cla/corporate/eficent.md
index 284e2b7b691..70184f115c8 100644
--- a/doc/cla/corporate/eficent.md
+++ b/doc/cla/corporate/eficent.md
@@ -14,7 +14,6 @@ List of contributors:
Aarón Henríquez ahenriquez@eficent.com https://github.com/aheficent
Lois Rilo lois.rilo@eficent.com https://github.com/lreficent
-Roser Garcia roser.garcia@eficent.com https://github.com/rgarnau
Miquel Raich miquel.raich@eficent.com https://github.com/mreficent
Jordi Ballester jordi.ballester@eficent.com https://github.com/jbeficent
Hector Villarreal hector.villarreal@eficent.com https://github.com/hveficent
diff --git a/doc/cla/corporate/modoolar.md b/doc/cla/corporate/modoolar.md
new file mode 100644
index 00000000000..a3ee461fab4
--- /dev/null
+++ b/doc/cla/corporate/modoolar.md
@@ -0,0 +1,19 @@
+Serbia, 2018-06-11
+
+Modoolar agrees to the terms of the Odoo Corporate Contributor License
+Agreement v1.0.
+
+I declare that I am authorized and able to make this agreement and sign this
+declaration.
+
+Signed,
+
+Petar Najman petar.najman@modoolar.com https://github.com/pnajman-modoolar
+
+List of contributors:
+
+- Aleksandar Gajić aleksandar.gajic@modoolar.com https://github.com/agajic-modoolar
+- Igor Jovanović igor.jovanovic@modoolar.com https://github.com/ijovanovic-modoolar
+- Mladen Meseldžija mladen.meseldzija@modoolar.com https://github.com/mmeseldzija-modoolar
+- Petar Najman petar.najman@modoolar.com https://github.com/pnajman-modoolar
+- Slađan Kantar sladjan.kantar@modoolar.com https://github.com/skantar
diff --git a/doc/cla/corporate/shine-it.md b/doc/cla/corporate/shine-it.md
new file mode 100644
index 00000000000..975f9d885f4
--- /dev/null
+++ b/doc/cla/corporate/shine-it.md
@@ -0,0 +1,17 @@
+China, 2018-04-28
+
+Shine IT agrees to the terms of the Odoo Corporate Contributor License
+Agreement v1.0.
+
+I declare that I am authorized and able to make this agreement and sign this
+declaration.
+
+Signed,
+
+Tony Gu tony@openerp.cn https://github.com/digitalsatori
+
+List of contributors:
+Tony Gu tony@openerp.cn https://github.com/digitalsatori
+Joshua Jan joshua@openerp.cn https://github.com/joshuajan
+Xiao Guo xerxes@openerp.cn https://github.com/xerxesnoPT
+
diff --git a/doc/cla/corporate/tvtmarine-automation.md b/doc/cla/corporate/tvtmarine-automation.md
index de0906f0331..59e3c250ab3 100644
--- a/doc/cla/corporate/tvtmarine-automation.md
+++ b/doc/cla/corporate/tvtmarine-automation.md
@@ -13,7 +13,7 @@ David Tran david.tran@tvtmarine.com https://github.com/tvtma/
List of contributors:
David Tran david.tran@tvtmarine.com https://github.com/davidtranhp
-Long Do dhlong.1209@gmail.com https://github.com/hoanglong87
+Long Do long.do@tvtmarine.com https://github.com/hoanglong87
Hao Hoang hao.hoang@ma.tvtmarine.com https://github.com/hoanghao2001
Tommy Tran tu.tran@tvtmarine.com https://github.com/tutran81
-Emily Ha emily.ha@tvtmarine.com https://github.com/emilyha \ No newline at end of file
+Emily Ha emily.ha@tvtmarine.com https://github.com/emilyha
diff --git a/doc/cla/individual/Zelwak.md b/doc/cla/individual/Zelwak.md
new file mode 100644
index 00000000000..40c8f303d42
--- /dev/null
+++ b/doc/cla/individual/Zelwak.md
@@ -0,0 +1,11 @@
+
+
+France, 2018-06-07
+
+I here by 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,
+
+Flavien CHÊNE me@flavienchene.fr https://github.com/Zelwak
diff --git a/doc/cla/individual/mduvergey.md b/doc/cla/individual/mduvergey.md
new file mode 100644
index 00000000000..3b9422711ec
--- /dev/null
+++ b/doc/cla/individual/mduvergey.md
@@ -0,0 +1,11 @@
+France, 2018-05-24
+
+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,
+
+Martin Duvergey martin.duvergey@gpsante.fr https://github.com/mduvergey
diff --git a/doc/cla/individual/schout-it.md b/doc/cla/individual/schout-it.md
new file mode 100644
index 00000000000..35451db875d
--- /dev/null
+++ b/doc/cla/individual/schout-it.md
@@ -0,0 +1,11 @@
+Belgium, 2018-05-17
+
+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,
+
+Rod Schouteden rod@schout-it.be https://github.com/schout-it
diff --git a/doc/howtos/themes.rst b/doc/howtos/themes.rst
index 5252ed5b776..f9158631282 100644
--- a/doc/howtos/themes.rst
+++ b/doc/howtos/themes.rst
@@ -686,7 +686,7 @@ The previous code will create the snippet’s content, but we still need to plac
.. code-block:: xml
<template id="place_into_bar" inherit_id="website.snippets" name="Place into bar">
- <xpath expr="//div[@id='snippet_content']/div[@class='o_panel_body']" position="inside">
+ <xpath expr="//div[@id='snippet_structure']/div[@class='o_panel_body']" position="inside">
<t t-snippet="theme_tutorial.snippet_testimonial"
t-thumbnail="/theme_tutorial/static/src/img/ui/snippet_thumb.jpg"/>
</xpath>
diff --git a/doc/reference/cmdline.rst b/doc/reference/cmdline.rst
index 4171f12c5e1..12cd5f7a9d8 100644
--- a/doc/reference/cmdline.rst
+++ b/doc/reference/cmdline.rst
@@ -221,6 +221,45 @@ database
'verify-ca' or 'verify-full'
Default value is 'prefer'
+.. _reference/cmdline/server/internationalisation:
+
+Internationalisation
+--------------------
+
+Use these options to translate Odoo to another language. See i18n section of
+the user manual. Option '-d' is mandatory. Option '-l' is mandatory in case
+of importation
+
+.. option:: --load-language <languages>
+
+ specifies the languages (separated by commas) for the translations you
+ want to be loaded
+
+.. option:: -l, --language <language>
+
+ specify the language of the translation file. Use it with --i18n-export
+ or --i18n-import
+
+.. option:: --i18n-export <filename>
+
+ export all sentences to be translated to a CSV file, a PO file or a TGZ
+ archive and exit.
+
+.. option:: --i18n-import <filename>
+
+ import a CSV or a PO file with translations and exit. The '-l' option is
+ required.
+
+.. option:: --i18n-overwrite
+
+ overwrites existing translation terms on updating a module or importing
+ a CSV or a PO file.
+
+.. option:: --modules
+
+ specify modules to export. Use in combination with --i18n-export
+
+
built-in HTTP
-------------
diff --git a/doc/reference/javascript_reference.rst b/doc/reference/javascript_reference.rst
index d13b2b86412..e6bfeba0726 100644
--- a/doc/reference/javascript_reference.rst
+++ b/doc/reference/javascript_reference.rst
@@ -1329,11 +1329,27 @@ order.
- Supported field types: *date*, *datetime*
+ Options:
+
+ - datepicker: extra settings for the datepicker_ widget.
+
+ .. code-block:: xml
+
+ <field name="datefield" options='{"datepicker": {"daysOfWeekDisabled": [0, 6]}}'/>
+
- datetime (FieldDateTime)
This is the default field type for fields of type *datetime*.
- Supported field types: *date*, *datetime*
+ Options:
+
+ - datepicker: extra settings for the datepicker_ widget.
+
+ .. code-block:: xml
+
+ <field name="datefield" options='{"datepicker": {"daysOfWeekDisabled": [0, 6]}}'/>
+
- monetary (FieldMonetary)
This is the default field type for fields of type 'monetary'. It is used to
display a currency. If there is a currency fields given in option, it will
@@ -1822,4 +1838,6 @@ Relational fields
.. _event delegation:
http://api.jquery.com/delegate/
+.. _datepicker: https://github.com/Eonasdan/bootstrap-datetimepicker
+
.. _deferred: http://api.jquery.com/category/deferred-object/
diff --git a/doc/setup/enterprise.rst b/doc/setup/enterprise.rst
index 49ba8af4c84..66f8fe82671 100644
--- a/doc/setup/enterprise.rst
+++ b/doc/setup/enterprise.rst
@@ -46,7 +46,7 @@ On Linux, using an installer
.. code-block:: console
- $ python3 /usr/bin/odoo.py -d <database_name> -i web_enterprise --stop-after-init
+ $ python3 /usr/bin/odoo-bin -d <database_name> -i web_enterprise --stop-after-init
* You should be able to connect to your Odoo Enterprise instance using your usual mean of identification.
You can then link your database with your Odoo Enterprise Subscription by entering the code you received
diff --git a/odoo/addons/base/data/res.country.state.csv b/odoo/addons/base/data/res.country.state.csv
index 4b445f52cf9..b64c8f78f12 100644
--- a/odoo/addons/base/data/res.country.state.csv
+++ b/odoo/addons/base/data/res.country.state.csv
@@ -450,7 +450,7 @@ state_es_m,es,"Madrid","M"
state_es_ma,es,"Málaga","MA"
state_es_ml,es,"Melilla","ME"
state_es_mu,es,"Murcia","MU"
-state_es_na,es,"Nafarroa (Navarra)","NA"
+state_es_na,es,"Navarra (Nafarroa)","NA"
state_es_or,es,"Ourense (Orense)","OR"
state_es_p,es,"Palencia","P"
state_es_po,es,"Pontevedra","PO"
diff --git a/odoo/addons/base/data/res_country_data.xml b/odoo/addons/base/data/res_country_data.xml
index 0e865be0fdf..1648d24430c 100644
--- a/odoo/addons/base/data/res_country_data.xml
+++ b/odoo/addons/base/data/res_country_data.xml
@@ -271,6 +271,7 @@
<field eval="'%(street)s\n%(street2)s\n%(city)s %(state_code)s %(zip)s\n%(country_name)s'" name="address_format" />
<field name="currency_id" ref="CAD" />
<field eval="1" name="phone_code" />
+ <field name="vat_label">HST</field>
</record>
<record id="cc" model="res.country">
<field name="name">Cocos (Keeling) Islands</field>
@@ -440,8 +441,10 @@
<field name="name">Dominican Republic</field>
<field name="code">do</field>
<field file="base/static/img/country_flags/do.png" name="image" type="base64" />
+ <field eval="'%(street)s\n%(street2)s\n%(city)s %(state_name)s %(zip)s\n%(country_name)s'" name="address_format" />
<field name="currency_id" ref="DOP" />
- <field eval="0" name="phone_code" />
+ <field eval="1" name="phone_code" />
+ <field name="vat_label">RNC</field>
</record>
<record id="dz" model="res.country">
<field name="name">Algeria</field>
diff --git a/odoo/addons/base/i18n/tr.po b/odoo/addons/base/i18n/tr.po
index ff3637e92d3..5d994c17db8 100644
--- a/odoo/addons/base/i18n/tr.po
+++ b/odoo/addons/base/i18n/tr.po
@@ -16788,6 +16788,39 @@ msgid ""
"\n"
"You can activate a blog for each event allowing you to communicate on specific events. Visitors can subscribe to news to get informed."
msgstr ""
+"Etkinlikleri, Çalışmaları & Webinarları Organize Edin\n"
+"\n"
+"Planlayın, Tanıtın, Satın, Organize Edin\n"
+"\n"
+"Etkinlik başına ekstra özellik elde edin; birden çok sayfa, sponsorlar, çoklu konuşma, teklif formunu konuşun, ajanda, etkinlikle ilgili haberleri, belgeleri (sunum slaytları), etkinlik özel menüleri.\n"
+"\n"
+"Takiplerinizi Organize Edin\n"
+"\n"
+"Konuşma teklifinden yayına\n"
+"\n"
+"Ziyaretçilerin konuşmaları ve konuşmacıları göndermesine izin vermek için etkinliklerinize bir konuşma teklifi formu ekleyin. Her konuşmanın onaylama sürecini düzenleyin ve kolayca programlayın.\n"
+"\n"
+"Odoo'nun benzersiz ön ve arka uç entegrasyonu organizasyon yapmayı ve yayınlamayı çok kolaylaştırıyor. Güzel konuşmacı biyografilerini kolayca tasarlayın ve açıklamaları açıklayın.\n"
+"\n"
+"Ajanda ve Konuşma Listesi\n"
+"\n"
+"Güçlü bir kullanıcı arayüzü\n"
+"\n"
+"Web sitenizde otomatik olarak yayınlanan her etkinlik için güzel bir ajanda yapın. Ziyaretçilerin görüşmeleri kolayca aramasına ve göz atmasına izin verin, etiketlere, yerlere veya konuşmacılara göre filtreleyin.\n"
+"\n"
+"Sponsorları Yönetin\n"
+"\n"
+"Sponsorluk satın, sponsorlarınızı tanıtın\n"
+"\n"
+"Etkinliğinize sponsorlar ekleyin ve etkinliğin her sayfasının altındaki seviyeye (örneğin bronz, gümüş, altın) sponsorlar yayınlayın.\n"
+"\n"
+"Tam bir satış döngüsü entegrasyonu için Odoo eCommerce üzerinden sponsorluk paketlerini online olarak satın.\n"
+"\n"
+"Verimli Bir Şekilde İletişim Kurun\n"
+"\n"
+"Bazı etkinlikler için bir blog etkinleştirin\n"
+"\n"
+"Belirli etkinlikler hakkında iletişim kurmanızı sağlayan her etkinlik için bir blogu etkinleştirebilirsiniz. Ziyaretçiler bilgi almak için haberlere abone olabilirler."
#. module: base
#: model:ir.module.module,description:base.module_website_event
@@ -16950,7 +16983,7 @@ msgstr "Diğer Sahiplik"
#. module: base
#: model:res.partner.industry,name:base.res_partner_industry_S
msgid "Other Services"
-msgstr ""
+msgstr "Diğer Hizmetler"
#. module: base
#: selection:res.partner,type:0
@@ -17005,7 +17038,7 @@ msgstr "Sahibi"
#. module: base
#: model:res.partner.industry,full_name:base.res_partner_industry_P
msgid "P EDUCATION"
-msgstr ""
+msgstr "P EĞİTİM"
#. module: base
#: selection:ir.actions.report,report_type:0
@@ -17221,12 +17254,12 @@ msgstr "Yol"
#. module: base
#: model:ir.module.module,shortdesc:base.module_account_payment
msgid "Payment - Account"
-msgstr ""
+msgstr "Ödeme - Hesap"
#. module: base
#: model:ir.module.module,shortdesc:base.module_sale_payment
msgid "Payment - Sale"
-msgstr ""
+msgstr "Ödeme - İnidirim"
#. module: base
#: model:ir.module.category,name:base.module_category_payment_acquirer
@@ -17268,12 +17301,12 @@ msgstr "Ödeme Alıcısı: Paypal Uygulaması"
#. module: base
#: model:ir.module.module,summary:base.module_payment_payumoney
msgid "Payment Acquirer: PayuMoney Implementation"
-msgstr ""
+msgstr "Ödeme Alıcısı: PayuMoney Uygulaması"
#. module: base
#: model:ir.module.module,summary:base.module_payment_stripe
msgid "Payment Acquirer: Stripe Implementation"
-msgstr ""
+msgstr "Ödeme Alıcısı: Stripe Uygulaması"
#. module: base
#: model:ir.module.module,summary:base.module_payment_transfer
@@ -17311,7 +17344,7 @@ msgstr "Bordro Muhasebesi"
#. module: base
#: model:ir.module.module,shortdesc:base.module_payment_payumoney
msgid "PayuMoney Payment Acquirer"
-msgstr ""
+msgstr "PayuMoney Ödeme Alıcısı"
#. module: base
#: model:ir.module.module,summary:base.module_hr_appraisal
@@ -17354,7 +17387,7 @@ msgstr "Telefon"
#. module: base
#: model:ir.module.module,shortdesc:base.module_phone_validation
msgid "Phone Numbers Validation"
-msgstr ""
+msgstr "Telefon Numarası Doğrulama"
#. module: base
#: model:ir.ui.view,arch_db:base.view_partner_form
@@ -17364,7 +17397,7 @@ msgstr "Telefon:"
#. module: base
#: model:res.country,name:base.pn
msgid "Pitcairn Islands"
-msgstr ""
+msgstr "Pitcairn Adaları"
#. module: base
#: selection:ir.actions.act_window.view,view_mode:0
@@ -17392,11 +17425,13 @@ msgid ""
"Please define at least one SMTP server, or provide the SMTP parameters "
"explicitly."
msgstr ""
+"En az birtane SMTP sunucusu tanımlayın yada SMTP parametrelerini açıkça "
+"belirtin."
#. module: base
#: model:ir.ui.view,arch_db:base.view_server_action_form
msgid "Please set the Model to Create before choosing values"
-msgstr ""
+msgstr "Lütfen değerleri seçmeden önce Modeli Oluştur'a ayarlayın."
#. module: base
#: code:addons/base/models/res_users.py:251
@@ -17417,7 +17452,7 @@ msgstr "Satış Noktası"
#. module: base
#: model:ir.module.module,shortdesc:base.module_pos_data_drinks
msgid "Point of Sale Common Data Drinks"
-msgstr ""
+msgstr "Satış Noktası Ortak Veri İçkileri"
#. module: base
#: model:ir.module.module,shortdesc:base.module_pos_discount
@@ -17427,7 +17462,7 @@ msgstr "Satış Noktası İndirimleri"
#. module: base
#: model:ir.module.module,shortdesc:base.module_pos_reprint
msgid "Point of Sale Receipt Reprinting"
-msgstr ""
+msgstr "Satış Noktası Makbuzunu Yeniden Yazdırma"
#. module: base
#: model:res.country,name:base.pl
@@ -17442,7 +17477,7 @@ msgstr "Polonya - Muhasebe"
#. module: base
#: model:ir.module.module,shortdesc:base.module_l10n_pl_reports
msgid "Poland - Accounting Reports"
-msgstr ""
+msgstr "Polonya - Muhasebe Raporları"
#. module: base
#: model:res.groups,name:base.group_portal
@@ -17471,7 +17506,7 @@ msgstr "Portekiz"
#. module: base
#: model:ir.module.module,shortdesc:base.module_l10n_pt
msgid "Portugal - Accounting"
-msgstr ""
+msgstr "Portekiz - Muhasebe"
#. module: base
#: model:ir.module.module,shortdesc:base.module_hw_posbox_homepage
@@ -17486,7 +17521,7 @@ msgstr "PosBox Yazılım Güncelleyicisi"
#. module: base
#: model:ir.model.fields,help:base.field_ir_model_constraint__definition
msgid "PostgreSQL constraint definition"
-msgstr ""
+msgstr "PostgreSQL kısıt tanımı"
#. module: base
#: model:ir.model.fields,help:base.field_ir_model_constraint__name
@@ -17536,32 +17571,32 @@ msgstr "Faturayı Yazdır"
#. module: base
#: model:ir.module.module,shortdesc:base.module_print_docsaway
msgid "Print Provider : DocsAway"
-msgstr ""
+msgstr "Yazdırma Sağlayıcısı : DocsAway"
#. module: base
#: model:ir.module.module,shortdesc:base.module_print_sale
msgid "Print Sale"
-msgstr ""
+msgstr "Satış Yazdırma"
#. module: base
#: model:ir.module.module,summary:base.module_l10n_us_check_printing
msgid "Print US Checks"
-msgstr ""
+msgstr "Birleşik Devletler Çeklerini Yazdırma"
#. module: base
#: model:ir.module.module,summary:base.module_hr_expense_check
msgid "Print amount in words on checks issued for expenses"
-msgstr ""
+msgstr "Masraflar için verilen çeklerde yazılı tutar"
#. module: base
#: model:ir.module.module,summary:base.module_print_docsaway
msgid "Print and Send Invoices with DocsAway.com"
-msgstr ""
+msgstr "DocsAway.com adresi ile birlikte Faturaları Yazdırın ve Gönderin"
#. module: base
#: model:ir.module.module,summary:base.module_print
msgid "Print and Send Provider Base Module"
-msgstr ""
+msgstr "Yazdırma ve Gönderme Sağlayıcı Temel Modül"
#. module: base
#: model:ir.module.module,description:base.module_print
@@ -17569,16 +17604,19 @@ msgid ""
"Print and Send Provider Base Module. Print and send your invoice with a "
"Postal Provider. This required to install a module implementing a provider."
msgstr ""
+"Yazdırma ve Gönderme Sağlayıcı Temel Modül. Faturanızı bir Posta Sağlayıcısı"
+" ile yazdırın ve gönderin. Bu bir sağlayıcıyı uygulayan bir modülü kurmak "
+"için gerekli."
#. module: base
#: model:ir.module.module,summary:base.module_print_sale
msgid "Print and Send Sales Orders"
-msgstr ""
+msgstr "Satış Siparişlerini Yazdır ve Gönder"
#. module: base
#: model:ir.module.module,description:base.module_print_sale
msgid "Print and Send your Sales Order by Post"
-msgstr ""
+msgstr "Posta ile Satış Siparişlerinizi Gönderin ve Yazdırın"
#. module: base
#: model:ir.model.fields,field_description:base.field_ir_actions_report__print_report_name
@@ -17600,12 +17638,12 @@ msgstr ""
#. module: base
#: model:ir.module.module,shortdesc:base.module_website_sale_comparison
msgid "Product Comparison And Product Attribute Category"
-msgstr ""
+msgstr "Ürün Kıyaslama ve Ürün Özellikleri Kategorisi"
#. module: base
#: model:ir.module.module,description:base.module_website_sale_comparison
msgid "Product Comparison, Product Attribute Category and specification table"
-msgstr ""
+msgstr "Ürün Kıyaslaması, Ürün Özellikleri Kategorisi ve özelleştirme masası"
#. module: base
#: model:ir.module.module,shortdesc:base.module_product_email_template
@@ -17737,12 +17775,12 @@ msgstr ""
#. module: base
#: model:ir.module.module,summary:base.module_helpdesk_sale_timesheet
msgid "Project, Helpdesk, Timesheet and Sale Orders"
-msgstr ""
+msgstr "Proje, Yardım Masası, Zaman Çizelgesi ve Satış Siparişleri"
#. module: base
#: model:ir.module.module,summary:base.module_helpdesk_timesheet
msgid "Project, Tasks, Timesheet"
-msgstr ""
+msgstr "Projeler, Görevler, Zaman Çizelgesi"
#. module: base
#: model:ir.module.module,summary:base.module_project
@@ -17768,7 +17806,7 @@ msgstr ""
#. module: base
#: model:ir.module.module,description:base.module_website_theme_install
msgid "Propose to install a theme on website installation"
-msgstr ""
+msgstr "Web sitesi kurulumuna bir tema yüklemeyi önerin"
#. module: base
#: model:ir.model.fields,help:base.field_ir_actions_server__link_field_id
@@ -17781,7 +17819,7 @@ msgstr ""
#. module: base
#: model:ir.module.module,summary:base.module_hw_screen
msgid "Provides support for customer facing displays"
-msgstr ""
+msgstr "Müşterinin karşısındaki ekranlar için destek sağlar"
#. module: base
#: model:res.groups,name:base.group_public
@@ -17791,7 +17829,7 @@ msgstr "Genel"
#. module: base
#: model:res.partner.industry,name:base.res_partner_industry_O
msgid "Public Administration"
-msgstr ""
+msgstr "Kamu Yönetimi"
#. module: base
#: model:res.groups,comment:base.group_public
@@ -17810,7 +17848,7 @@ msgstr "Birlikleri, Gruplar ve Üyelikleri Yayınla"
#. module: base
#: model:ir.module.module,summary:base.module_website_event
msgid "Publish Events and Manage Online Registrations on your Website"
-msgstr ""
+msgstr "Web sitenizde Etkinlikler Yayınlayın ve Çevrimiçi Kayıtları Yönetin"
#. module: base
#: model:ir.module.module,summary:base.module_website_crm_partner_assign
@@ -17866,7 +17904,7 @@ msgstr "Satınalımlar"
#. module: base
#: model:ir.module.module,summary:base.module_mail_push
msgid "Push notification for mobile app"
-msgstr ""
+msgstr "Mobil uygulama için bildirimleri aktarın"
#. module: base
#: model:ir.model.fields,field_description:base.field_ir_actions_server__code
@@ -17883,7 +17921,7 @@ msgstr "Python Expression"
#. module: base
#: model:res.partner.industry,full_name:base.res_partner_industry_Q
msgid "Q HUMAN HEALTH AND SOCIAL WORK ACTIVITIES"
-msgstr ""
+msgstr "Q İNSAN SAĞLIĞI VE SOSYAL ÇALIŞMA FAALİYETLERİ"
#. module: base
#: model:ir.ui.view,arch_db:base.view_view_search selection:ir.ui.view,type:0
@@ -17919,7 +17957,7 @@ msgstr "Kalite Kontrol"
#: model:ir.module.module,summary:base.module_quality_mrp
#: model:ir.module.module,summary:base.module_quality_mrp_workorder
msgid "Quality Management with MRP"
-msgstr ""
+msgstr "MRP ile Kalite Yönetimi"
#. module: base
#: model:ir.module.module,description:base.module_website_event_questions
@@ -17936,7 +17974,7 @@ msgstr ""
#: model:ir.module.module,summary:base.module_sale_expense
#: model:ir.module.module,summary:base.module_sale_stock
msgid "Quotation, Sales Orders, Delivery & Invoicing Control"
-msgstr ""
+msgstr "Teklif, Satış Siparişi, Teslimat & Faturalama Kontrolü"
#. module: base
#: model:ir.module.module,summary:base.module_sale_management
@@ -17950,11 +17988,13 @@ msgid ""
"Qweb view cannot have 'Groups' define on the record. Use 'groups' attributes"
" inside the view definition"
msgstr ""
+"Qweb görünümü, kayıtta 'Gruplar' tanımlayamaz. Görünüm tanımındaki 'gruplar'"
+" özelliklerini kullan"
#. module: base
#: model:res.partner.industry,full_name:base.res_partner_industry_R
msgid "R ARTS, ENTERTAINMENT AND RECREATION"
-msgstr ""
+msgstr "R SANAT, EĞLENCE VE REKREASYON"
#. module: base
#: model:ir.model.fields,field_description:base.field_res_currency_rate__rate
@@ -17987,7 +18027,7 @@ msgstr "Salt Okunur"
#. module: base
#: model:res.partner.industry,name:base.res_partner_industry_L
msgid "Real Estate"
-msgstr ""
+msgstr "Emlak"
#. module: base
#: model:ir.ui.view,arch_db:base.view_model_data_form
@@ -18024,6 +18064,8 @@ msgid ""
"Record cannot be modified right now: This cron task is currently being "
"executed and may not be modified Please try again in a few minutes"
msgstr ""
+"Kayıt şu anda değiştirilemiyor: Bu cron görevi şu anda yürütülüyor ve "
+"değiştirilemiyor Lütfen birkaç dakika içinde tekrar deneyin."
#. module: base
#: code:addons/base/models/ir_actions.py:238 code:addons/models.py:3915
@@ -18045,7 +18087,7 @@ msgstr "İşe Alım"
#. module: base
#: model:ir.module.module,summary:base.module_sale_subscription
msgid "Recurring invoicing, renewals"
-msgstr ""
+msgstr "Tekrarlanan faturalar, yinelemeler"
#. module: base
#: code:addons/base/models/ir_module.py:352
@@ -18116,7 +18158,7 @@ msgstr "İlişki Adı"
#. module: base
#: model:ir.model.fields,field_description:base.field_ir_model_fields__relation_table
msgid "Relation Table"
-msgstr ""
+msgstr "İlişki Tablosu"
#. module: base
#: model:ir.model.fields,field_description:base.field_ir_actions_report__attachment_use
@@ -18126,22 +18168,22 @@ msgstr "Ekten yeniden yükle"
#. module: base
#: model:ir.ui.view,arch_db:base.view_server_action_form
msgid "Remove 'More' top-menu contextual action related to this action"
-msgstr ""
+msgstr "Bu eyleme ilişkin 'Diğer' üst menü bağlamsal eylemini kaldırın"
#. module: base
#: model:ir.ui.view,arch_db:base.view_server_action_form
msgid "Remove Contextual Action"
-msgstr ""
+msgstr "Bağlamsal Eylemi Kaldır"
#. module: base
#: model:ir.ui.view,arch_db:base.act_report_xml_view
msgid "Remove from the 'Print' menu"
-msgstr ""
+msgstr "'Yazdır' menüsünden kaldır"
#. module: base
#: model:ir.ui.view,arch_db:base.act_report_xml_view
msgid "Remove the contextual action related this report"
-msgstr ""
+msgstr "Bu raporla ilgili bağlamsal aksiyonu kaldır"
#. module: base
#: model:ir.module.module,summary:base.module_repair
@@ -18273,7 +18315,7 @@ msgstr "Kaynak Adı"
#. module: base
#: model:ir.module.module,summary:base.module_project_forecast
msgid "Resource management for Project"
-msgstr ""
+msgstr "Proje için kaynak yönetimi"
#. module: base
#: model:ir.module.module,shortdesc:base.module_pos_restaurant
@@ -18298,7 +18340,7 @@ msgstr "Listelerine sınırla"
#. module: base
#: model:ir.module.module,summary:base.module_hr_timesheet
msgid "Review and approve employees time reports"
-msgstr ""
+msgstr "Çalışanların zaman raporlarını gözden geçirin ve onaylayın"
#. module: base
#: model:ir.model.fields,field_description:base.field_report_paperformat__margin_right
@@ -18328,7 +18370,7 @@ msgstr "Romanya - Muhasebe"
#. module: base
#: model:ir.module.module,shortdesc:base.module_l10n_ro_reports
msgid "Romania - Accounting Reports"
-msgstr ""
+msgstr "Romanya - Muhasebe Raporları"
#. module: base
#: model:ir.model.fields,field_description:base.field_res_currency__rounding
@@ -18380,12 +18422,12 @@ msgstr "Ruanda"
#. module: base
#: model:res.country,name:base.re
msgid "Réunion"
-msgstr ""
+msgstr "Birleşme"
#. module: base
#: model:res.partner.industry,full_name:base.res_partner_industry_S
msgid "S OTHER SERVICE ACTIVITIES"
-msgstr ""
+msgstr "S DİĞER HİZMET ETKİNLİKLERİ"
#. module: base
#: model:ir.module.module,shortdesc:base.module_account_sepa
@@ -18395,22 +18437,22 @@ msgstr "SEPA Alacak Transferi"
#. module: base
#: model:ir.module.module,shortdesc:base.module_hr_expense_sepa
msgid "SEPA Credit Transfer in Expenses"
-msgstr ""
+msgstr "Giderlerde SEPA Kredi Transferi"
#. module: base
#: model:ir.module.module,shortdesc:base.module_account_sepa_direct_debit
msgid "SEPA Direct Debit"
-msgstr ""
+msgstr "SEPA Doğrudan Ödeme"
#. module: base
#: model:ir.module.module,summary:base.module_sms
msgid "SMS Text Messaging"
-msgstr ""
+msgstr "SMS Metin Mesajı"
#. module: base
#: model:ir.module.module,shortdesc:base.module_sms
msgid "SMS gateway"
-msgstr ""
+msgstr "SMS Ağ Geçidi"
#. module: base
#: model:ir.model.fields,field_description:base.field_ir_mail_server__smtp_port
@@ -18447,12 +18489,12 @@ msgstr "Saint Barthélémy"
#. module: base
#: model:res.country,name:base.sh
msgid "Saint Helena, Ascension and Tristan da Cunha"
-msgstr ""
+msgstr "Saint Helena, Ascension ve Tristan da Cunha"
#. module: base
#: model:res.country,name:base.kn
msgid "Saint Kitts and Nevis"
-msgstr ""
+msgstr "Saint Kitts ve Nevis"
#. module: base
#: model:res.country,name:base.lc
@@ -18472,12 +18514,12 @@ msgstr "Sen Piyer ve Miquelon"
#. module: base
#: model:res.country,name:base.vc
msgid "Saint Vincent and the Grenadines"
-msgstr ""
+msgstr "Saint Vincent ve the Grenadines"
#. module: base
#: model:ir.module.module,summary:base.module_hr_contract_salary
msgid "Salary Package Configurator"
-msgstr ""
+msgstr "Maaş Paketi Yapılandıcı"
#. module: base
#: model:ir.ui.view,arch_db:base.view_partner_form
@@ -18492,12 +18534,12 @@ msgstr "Satış ve Satınalma Fişleri"
#. module: base
#: model:ir.module.module,shortdesc:base.module_sale_coupon
msgid "Sale Coupon"
-msgstr ""
+msgstr "Satış Kuponu"
#. module: base
#: model:ir.module.module,shortdesc:base.module_sale_coupon_delivery
msgid "Sale Coupon Delivery"
-msgstr ""
+msgstr "Satış Kuponu Teslimatı"
#. module: base
#: model:ir.module.module,shortdesc:base.module_sale_subscription_dashboard
@@ -18541,7 +18583,7 @@ msgstr "Satış Zaman Çizelgesi"
#. module: base
#: model:ir.module.module,shortdesc:base.module_timesheet_grid_sale
msgid "Sales Timesheet: Grid Support"
-msgstr ""
+msgstr "Satış Zaman Çizelgesi : Grid Desteği"
#. module: base
#: model:ir.module.module,shortdesc:base.module_sale_mrp
@@ -18556,7 +18598,7 @@ msgstr "Satış ve Depo Yönetimi"
#. module: base
#: model:ir.module.module,summary:base.module_sale
msgid "Sales internal machinery"
-msgstr ""
+msgstr "İç satış düzeneği"
#. module: base
#: model:ir.model.fields,field_description:base.field_res_partner__user_id
@@ -18605,7 +18647,7 @@ msgstr "Kaydet"
#. module: base
#: model:ir.ui.view,arch_db:base.view_company_report_form_with_print
msgid "Save and Print"
-msgstr ""
+msgstr "Kaydet ve Yazdır"
#. module: base
#: model:ir.model.fields,field_description:base.field_ir_actions_report__attachment
@@ -18615,17 +18657,17 @@ msgstr "Eki Önek Olarak Kaydet"
#. module: base
#: model:ir.module.module,summary:base.module_website_calendar
msgid "Schedule Appointments with Clients"
-msgstr ""
+msgstr "Müşteri Randevularını Planla"
#. module: base
#: model:ir.module.module,summary:base.module_mrp_maintenance
msgid "Schedule and manage maintenance on machine and tools."
-msgstr ""
+msgstr "Makine ve araç bakımını yönet ve planla"
#. module: base
#: model:ir.module.module,summary:base.module_project_timesheet_holidays
msgid "Schedule timesheet when on leaves"
-msgstr ""
+msgstr "İzin zaman çizelgesini planla"
#. module: base
#: selection:ir.actions.server,usage:0
@@ -18646,17 +18688,17 @@ msgstr "Planlanmış İşlemler"
#. module: base
#: model:ir.model.fields,field_description:base.field_ir_cron__user_id
msgid "Scheduler User"
-msgstr ""
+msgstr "Kullanıcı Planlayıcısı"
#. module: base
#: model:res.partner.industry,name:base.res_partner_industry_M
msgid "Scientific"
-msgstr ""
+msgstr "Bilimsel"
#. module: base
#: model:ir.module.module,shortdesc:base.module_hw_screen
msgid "Screen Driver"
-msgstr ""
+msgstr "Ekran Sürücüsü"
#. module: base
#: model:ir.ui.view,arch_db:base.view_view_search selection:ir.ui.view,type:0
@@ -18793,7 +18835,7 @@ msgstr "Kendin"
#. module: base
#: model:ir.module.module,shortdesc:base.module_helpdesk_sale_timesheet
msgid "Sell Helpdesk Timesheet"
-msgstr ""
+msgstr "Yardım Masası Zaman Çizelgesi Sat"
#. module: base
#: model:ir.module.module,summary:base.module_website_sale
@@ -18803,7 +18845,7 @@ msgstr "Ürünlerin Çevrimiçi Satışı"
#. module: base
#: model:ir.module.module,summary:base.module_sale_timesheet
msgid "Sell based on timesheets"
-msgstr ""
+msgstr "Zaman çizelgesini baz alarak sat"
#. module: base
#: model:ir.module.module,summary:base.module_account
@@ -18836,38 +18878,58 @@ msgid ""
"\n"
"Have clear pricing strategies.\n"
msgstr ""
+"Teklifleri Online Gönderin\n"
+"\n"
+"Dakikalar içinde profesyonel, parlak teklifler hazırlayın\n"
+"\n"
+"\n"
+"Dakikalar içinde profesyonel, parlak teklifler hazırlamak için şablonlar kullanın. Bu teklifleri e-postayla gönderin ve müşterinizin online olarak oturum açmasına izin verin. Satışlarınızı artırmak için çapraz satış ve indirimleri kullanın.\n"
+"\n"
+"Elektronik İmza\n"
+"\n"
+"Emaillerde daha fazla faks ve tarama yok\n"
+"\n"
+"Müşterilerinizin teklifleri çevrimiçi olarak imzalamasına izin verin. Bazı seçenekler önermek için satış teknikleri kullanın.\n"
+"\n"
+"Verileri kaydetmeye değil, satış yapmaya odaklanan ek süreyi harcayın.\n"
+"\n"
+"Verimli İletişim\n"
+"\n"
+"Net fiyatlandırma stratejiniz olsun.\n"
#. module: base
#: model:ir.module.module,summary:base.module_website_sign
msgid ""
"Send documents to sign online, receive and archive filled copies (esign)"
msgstr ""
+"Çevrimiçi olarak imzalamak, dolu kopyaları almak ve arşivlemek için "
+"belgeleri gönderin (e-imza)"
#. module: base
#: model:ir.module.module,description:base.module_calendar_sms
#: model:ir.module.module,summary:base.module_calendar_sms
msgid "Send text messages as event reminders"
-msgstr ""
+msgstr "Etkinlik hatırlatıcı olarak metin mesajı gönder"
#. module: base
#: model:ir.module.module,description:base.module_delivery_dhl
msgid "Send your shippings through DHL and track them online"
-msgstr ""
+msgstr "Gönderilerinizi DHL yoluyla gönderin ve çevrimiçi takip edin"
#. module: base
#: model:ir.module.module,description:base.module_delivery_fedex
msgid "Send your shippings through Fedex and track them online"
-msgstr ""
+msgstr "Gönderilerinizi Fedex yoluyla gönderin ve çevrimiçi takip edin"
#. module: base
#: model:ir.module.module,description:base.module_delivery_ups
msgid "Send your shippings through UPS and track them online"
-msgstr ""
+msgstr "Gönderilerinizi UPS yoluyla gönderin ve çevrimiçi takip edin"
#. module: base
#: model:ir.module.module,description:base.module_delivery_usps
msgid "Send your shippings through USPS and track them online"
-msgstr ""
+msgstr "Gönderilerinizi USPS yoluyla gönderin ve çevrimiçi takip edin"
#. module: base
#: model:res.country,name:base.sn
@@ -18953,7 +19015,7 @@ msgstr "Sunucu İşlemleri"
#. module: base
#: model:ir.model.fields,field_description:base.field_ir_cron__ir_actions_server_id
msgid "Server action"
-msgstr ""
+msgstr "Sunucu eylemi"
#. module: base
#: selection:ir.model.fields,on_delete:0
@@ -19025,7 +19087,7 @@ msgstr "Paylaşım Kullanıcısı"
#. module: base
#: model:ir.module.module,summary:base.module_website_slides
msgid "Share and Publish Videos, Presentations and Documents"
-msgstr ""
+msgstr "Videoları, Sunumları, Belgeleri Paylaşın ve Yayınlayın"
#. module: base
#: model:ir.ui.view,arch_db:base.ir_filters_view_search
@@ -19040,22 +19102,22 @@ msgstr "Sevkiyat Adresi"
#. module: base
#: model:ir.model.fields,field_description:base.field_base_module_uninstall__show_all
msgid "Show All"
-msgstr ""
+msgstr "Tümünü Göster"
#. module: base
#: model:ir.ui.view,arch_db:base.view_currency_search
msgid "Show active currencies"
-msgstr ""
+msgstr "Etkin para birimlerini göster"
#. module: base
#: model:ir.ui.view,arch_db:base.view_currency_search
msgid "Show inactive currencies"
-msgstr ""
+msgstr "Etkin olmayan para birimlerini göster"
#. module: base
#: model:ir.ui.view,arch_db:base.view_base_module_uninstall
msgid "Show technical modules"
-msgstr ""
+msgstr "Teknik modülleri göster"
#. module: base
#: model:res.country,name:base.sl
@@ -19095,7 +19157,7 @@ msgstr "Singapur - Muhasebesi"
#. module: base
#: model:ir.module.module,shortdesc:base.module_l10n_sg_reports
msgid "Singapore - Accounting Reports"
-msgstr ""
+msgstr "Singapur - Muhasebe Raporları"
#. module: base
#: model:res.country,name:base.sx
@@ -19110,7 +19172,7 @@ msgstr "Boyut"
#. module: base
#: sql_constraint:ir.model.fields:0
msgid "Size of the field cannot be negative."
-msgstr ""
+msgstr "Alan büyüklüğü negatif olamaz"
#. module: base
#: model:ir.ui.view,arch_db:base.res_config_installer
@@ -19145,7 +19207,7 @@ msgstr "Slovenya - Hesapplananı"
#. module: base
#: model:ir.module.module,shortdesc:base.module_l10n_si_reports
msgid "Slovenian - Accounting Reports"
-msgstr ""
+msgstr "Slovenya - Muhasebe Raporları"
#. module: base
#: model:ir.model.fields,field_description:base.field_res_partner__image_small
@@ -19245,7 +19307,7 @@ msgstr "Güney Afrika"
#. module: base
#: model:res.country.group,name:base.south_america
msgid "South America"
-msgstr ""
+msgstr "Güney Amerika"
#. module: base
#: model:res.country,name:base.gs
@@ -19270,17 +19332,17 @@ msgstr "İspanya"
#. module: base
#: model:ir.module.module,shortdesc:base.module_l10n_es
msgid "Spain - Accounting (PGCE 2008)"
-msgstr ""
+msgstr "İspanya - Muhasebe (PGCE 2008)"
#. module: base
#: model:ir.module.module,shortdesc:base.module_l10n_es_reports
msgid "Spain - Accounting (PGCE 2008) Reports"
-msgstr ""
+msgstr "İspanya - Muhasebe (PGCE 2008) Raporları"
#. module: base
#: model:ir.module.module,shortdesc:base.module_base_sparse_field
msgid "Sparse Fields"
-msgstr ""
+msgstr "Aralıklı Alanlar"
#. module: base
#: model:ir.module.category,name:base.module_category_specific_industry_applications
@@ -19294,12 +19356,17 @@ msgid ""
"password, otherwise leave empty. After a change of password, the user has to"
" login again."
msgstr ""
+"Sadece bir kullanıcı oluşturuyor veya kullanıcının şifresini "
+"değiştiriyorsanız bir değer belirtin, aksi halde boş bırakın. Şifre "
+"değişikliği yapıldıktan sonra, kullanıcı tekrar giriş yapmalıdır."
#. module: base
#: model:ir.model.fields,help:base.field_ir_cron__doall
msgid ""
"Specify if missed occurrences should be executed when the server restarts."
msgstr ""
+"Sunucu yeniden başlatıldığında kaçırılan olayların yürütülmesi gerekip "
+"gerekmediğini belirtin."
#. module: base
#: model:ir.module.module,summary:base.module_website_event_track
@@ -19350,7 +19417,7 @@ msgstr "İl/Eyalet Adı"
#. module: base
#: model:res.country,name:base.ps
msgid "State of Palestine"
-msgstr ""
+msgstr "Filistin Devleti"
#. module: base
#: model:ir.model.fields,field_description:base.field_res_country__state_ids
@@ -19378,7 +19445,7 @@ msgstr "Adım"
#: code:addons/base/models/ir_sequence.py:32
#, python-format
msgid "Step must not be zero."
-msgstr ""
+msgstr "Adım sıfırdan farklı olmak zorundadır"
#. module: base
#: model:ir.module.module,summary:base.module_note_pad
@@ -19398,12 +19465,12 @@ msgstr "Stok"
#. module: base
#: model:ir.module.module,shortdesc:base.module_stock_barcode_mobile
msgid "Stock Barcode in Mobile"
-msgstr ""
+msgstr "Mobilde Stok Barkodu"
#. module: base
#: model:ir.module.module,summary:base.module_stock_barcode_mobile
msgid "Stock Barcode scan in Mobile"
-msgstr ""
+msgstr "Mobilde Stok Barkod Taraması"
#. module: base
#: model:ir.model.fields,field_description:base.field_ir_model_fields__store
@@ -19453,7 +19520,7 @@ msgstr "Adres2"
#: model:ir.module.module,description:base.module_payment_stripe
#: model:ir.module.module,shortdesc:base.module_payment_stripe
msgid "Stripe Payment Acquirer"
-msgstr ""
+msgstr "Çizgili Ödeme Alıcısı"
#. module: base
#: model:ir.module.module,shortdesc:base.module_web_studio
@@ -19473,7 +19540,7 @@ msgstr "Abonelik Yönetimi"
#. module: base
#: model:ir.model.fields,field_description:base.field_ir_sequence__date_range_ids
msgid "Subsequences"
-msgstr ""
+msgstr "Alt Diziler"
#. module: base
#: model:res.country,name:base.sd
@@ -19534,7 +19601,7 @@ msgstr "Anketler"
#. module: base
#: model:res.country,name:base.sj
msgid "Svalbard and Jan Mayen"
-msgstr ""
+msgstr "Svalbard ve Jan Mayen"
#. module: base
#: model:res.country,name:base.sz
@@ -19559,7 +19626,7 @@ msgstr "İsviçre - Muhasebe"
#. module: base
#: model:ir.module.module,shortdesc:base.module_l10n_ch_reports
msgid "Switzerland - Accounting Reports"
-msgstr ""
+msgstr "İsviçre - Muhasebe Raporları"
#. module: base
#: model:ir.model.fields,field_description:base.field_res_currency__symbol
@@ -19574,7 +19641,7 @@ msgstr "Sembol Pozisyonu"
#. module: base
#: model:ir.module.module,shortdesc:base.module_project_timesheet_synchro
msgid "Synchronization with the external timesheet application"
-msgstr ""
+msgstr "Harici zaman çizelgesi uygulaması ile senkronizasyon."
#. module: base
#: model:res.country,name:base.sy
@@ -19602,7 +19669,7 @@ msgstr "Sistem Güncellemesi"
#. module: base
#: model:res.country,name:base.st
msgid "São Tomé and Príncipe"
-msgstr ""
+msgstr "São Tomé ve Príncipe"
#. module: base
#: model:res.partner.industry,full_name:base.res_partner_industry_T
@@ -19610,6 +19677,8 @@ msgid ""
"T ACTIVITIES OF HOUSEHOLDS AS EMPLOYERS;UNDIFFERENTIATED GOODS- AND "
"SERVICES-PRODUCING ACTIVITIES OF HOUSEHOLDS FOR OWN USE"
msgstr ""
+"T İŞVEREN HİZMETLERİNİN FAALİYET ALANLARI VE BUNLARIN KULLANIMINA YÖNELİK "
+"HİSSEDARLIK HİZMETLERİ VE HİZMET ÜRETİM FAALİYETLERİ"
#. module: base
#: selection:base.language.export,format:0
@@ -19622,6 +19691,8 @@ msgid ""
"TGZ format: this is a compressed archive containing a PO file, directly suitable\n"
" for uploading to Odoo's translation platform,"
msgstr ""
+"TGZ formatı: Bu, Odoo'nun çeviri platformuna yüklenmek için doğrudan uygun "
+"bir satın alma sipariş dosyası içeren sıkıştırılmış bir arşivdir."
#. module: base
#: model:ir.model.fields,field_description:base.field_res_company__vat
@@ -19696,7 +19767,7 @@ msgstr ""
#. module: base
#: model:ir.module.module,summary:base.module_account_taxcloud
msgid "TaxCloud make it easy for business to comply with sales tax law"
-msgstr ""
+msgstr "TaxCloud, işin satış vergisi kanunuyla uyumlu olmasını kolaylaştırır"
#. module: base
#: model:ir.module.module,shortdesc:base.module_website_hr
@@ -19759,12 +19830,12 @@ msgstr "Bağlantıyı Sına"
#. module: base
#: model:ir.module.module,shortdesc:base.module_test_main_flows
msgid "Test Main Flow"
-msgstr ""
+msgstr "Ana Akışı Test Et"
#. module: base
#: model:ir.module.module,shortdesc:base.module_test_performance
msgid "Test Performance"
-msgstr ""
+msgstr "Performansı Test Et"
#. module: base
#: model:ir.module.module,summary:base.module_test_marketing_automation
@@ -19790,7 +19861,7 @@ msgstr "Testler"
#. module: base
#: model:ir.module.module,description:base.module_test_read_group
msgid "Tests for read_group"
-msgstr ""
+msgstr "read_group için test yap"
#. module: base
#: model:ir.module.module,description:base.module_test_converter
@@ -19815,13 +19886,13 @@ msgstr "Tayland - Muhasebe"
#. module: base
#: model:ir.module.module,shortdesc:base.module_l10n_th_reports
msgid "Thailand - Accounting Reports"
-msgstr ""
+msgstr "Tayland - Muhasebe Raporları"
#. module: base
#: code:addons/base/models/res_users.py:291
#, python-format
msgid "The \"App Switcher\" action cannot be selected as home action."
-msgstr ""
+msgstr "App Switcher eylemi ana eylem olarak seçilemez."
#. module: base
#: model:ir.model.fields,help:base.field_res_country__code
@@ -19829,6 +19900,8 @@ msgid ""
"The ISO country code in two chars. \n"
"You can use this field for quick search."
msgstr ""
+"İki karakterde ISO ülke kodu.\n"
+"Hızlı arama için bu alanı kullanabilirsiniz."
#. module: base
#: code:addons/base/models/ir_model.py:367
@@ -19837,6 +19910,8 @@ msgid ""
"The Selection Options expression is not a valid Pythonic expression. Please "
"provide an expression in the [('key','Label'), ...] format."
msgstr ""
+"Seçim tercihleri ifadesi geçerli bir Pythonic ifade değil. Lütfen "
+"[('anahtar','etiket'), ...] biçiminde bir ifade girin."
#. module: base
#: model:ir.model.fields,help:base.field_res_lang__grouping
@@ -19895,7 +19970,7 @@ msgstr "Dil kodu tekil olmak zorunda !"
#. module: base
#: sql_constraint:res.country.state:0
msgid "The code of the state must be unique by country !"
-msgstr ""
+msgstr "Devletin kodu ülkeye göre eşsiz olmalı!"
#. module: base
#: sql_constraint:res.company:0
@@ -19924,6 +19999,8 @@ msgid ""
"The corresponding related field, if any. This must be a dot-separated list "
"of field names."
msgstr ""
+"Varsa uygun, ilgili alan. Bu, nokta isimleriyle ayrılmış bir alan adları "
+"listesi olmalıdır."
#. module: base
#: sql_constraint:res.currency:0
@@ -19987,12 +20064,12 @@ msgstr ""
#. module: base
#: model:ir.ui.view,arch_db:base.view_base_module_uninstall
msgid "The following apps will be uninstalled"
-msgstr ""
+msgstr "Aşağıdaki uygulamalar kaldırılacaktır"
#. module: base
#: model:ir.ui.view,arch_db:base.view_base_module_uninstall
msgid "The following documents will be permanently lost"
-msgstr ""
+msgstr "Aşağıdaki belgeler kalıcı olarak kaybolacaktır."
#. module: base
#: code:addons/base/wizard/base_module_upgrade.py:69
@@ -20016,7 +20093,7 @@ msgstr "Eğer varsa, bu kişi ile iletişime görevlendirilmiş iç kullanıcı.
#. module: base
#: model:ir.model.fields,help:base.field_ir_model__inherited_model_ids
msgid "The list of models that extends the current model."
-msgstr ""
+msgstr "Mevcut modeli genişleten modellerin listesi."
#. module: base
#: model:ir.model.fields,help:base.field_ir_filters__action_id
@@ -20024,6 +20101,8 @@ msgid ""
"The menu action this filter applies to. When left empty the filter applies "
"to all menus for this model."
msgstr ""
+"Bu filtrenin menü eylemi için geçerlidir. Boş bırakıldığında, filtre bu "
+"model için tüm menülere uygulanır."
#. module: base
#: code:addons/base/models/ir_model.py:136
@@ -20031,13 +20110,13 @@ msgstr ""
msgid ""
"The model name can only contain lowercase characters, digits, underscores "
"and dots."
-msgstr ""
+msgstr "Model adı yalnızca küçük harf, rakam, alt çizgi ve nokta içerebilir."
#. module: base
#: code:addons/base/models/ir_model.py:134
#, python-format
msgid "The model name must start with 'x_'."
-msgstr ""
+msgstr "Model adı 'x_' ile başlamalıdır."
#. module: base
#: model:ir.model.fields,help:base.field_ir_model_fields__model_id
@@ -20084,7 +20163,7 @@ msgstr "Sonraki adım dosya biçimine bağlıdır:"
#: model:ir.ui.view,arch_db:base.view_model_fields_form
#: model:ir.ui.view,arch_db:base.view_model_form
msgid "The only predefined variables are"
-msgstr ""
+msgstr "Sadece önceden tanımlanmış değişkenler"
#. module: base
#: code:addons/model.py:121
@@ -20118,6 +20197,10 @@ msgid ""
"use the same timezone that is otherwise used to pick and render date and "
"time values: your computer's timezone."
msgstr ""
+"Basılı raporlar içinde uygun tarih ve saat değerlerini yayınlamak için "
+"kullanılan eşin zaman dilimi. Bu alan için bir değer belirlemek önemlidir. "
+"Tarih ve saat değerlerini almak ve işlemek için kullanılan aynı saat "
+"dilimini kullanmalısınız: bilgisayarınızın saat dilimi."
#. module: base
#: model:ir.model.fields,help:base.field_ir_actions_report__report_file
@@ -20125,6 +20208,8 @@ msgid ""
"The path to the main report file (depending on Report Type) or empty if the "
"content is in another field"
msgstr ""
+"Ana rapor dosyasına giden yol (Rapor Türü'ne bağlı olarak) veya içerik başka"
+" bir alanda ise boş"
#. module: base
#: model:ir.model.fields,help:base.field_ir_cron__priority
@@ -20132,6 +20217,8 @@ msgid ""
"The priority of the job, as an integer: 0 means higher priority, 10 means "
"lower priority."
msgstr ""
+"Sayı olarak işin önceliği,: 0, daha yüksek öncelik anlamına gelir, 10, daha "
+"düşük öncelik anlamına gelir."
#. module: base
#: model:ir.model.fields,help:base.field_res_currency_rate__rate
@@ -20172,7 +20259,7 @@ msgstr ""
#. module: base
#: sql_constraint:res.currency:0
msgid "The rounding factor must be greater than 0!"
-msgstr ""
+msgstr "Yuvarlama faktörü 0'dan büyük olmalıdır !"
#. module: base
#: model:ir.ui.view,arch_db:base.view_base_language_install
@@ -20180,6 +20267,8 @@ msgid ""
"The selected language has been successfully installed. You must change the "
"preferences of the user to view the changes."
msgstr ""
+"Seçilen dil başarıyla kuruldu. Değişiklikleri görüntülemek için kullanıcının"
+" tercihlerini değiştirmeniz gerekir."
#. module: base
#: model:ir.ui.view,arch_db:base.view_base_module_upgrade_install
@@ -20189,7 +20278,7 @@ msgstr "Seçtiğiniz modüller güncellendi / yüklendi !"
#. module: base
#: model:ir.model.fields,help:base.field_res_country_state__code
msgid "The state code."
-msgstr ""
+msgstr "İl kodu."
#. module: base
#: code:addons/base/models/ir_model.py:492
@@ -20210,6 +20299,10 @@ msgid ""
"browserPDF means the report will be rendered using Wkhtmltopdf and "
"downloaded by the user."
msgstr ""
+"İşlenecek raporun türü, her birinin kendi oluşturma yöntemi vardır.HTML, "
+"raporun doğrudan tarayıcınızda açılacağı anlamına gelir. Pdf raporun "
+"Wkhtmltopdf kullanılarak oluşturulacağı ve kullanıcı tarafından indirileceği"
+" anlamına gelir."
#. module: base
#: model:ir.model.fields,help:base.field_ir_filters__user_id
@@ -20217,6 +20310,8 @@ msgid ""
"The user this filter is private to. When left empty the filter is public and"
" available to all users."
msgstr ""
+"Bu filtrenin kullanıcısı özeldir. Boş bırakıldığında, filtre herkese açıktır"
+" ve tüm kullanıcılar tarafından kullanılabilir."
#. module: base
#: code:addons/models.py:5208
@@ -20300,6 +20395,10 @@ msgid ""
" and reference view. The result is returned as an ordered list of pairs "
"(view_id,view_mode)."
msgstr ""
+"Bu işlev alanı, bir eylemin sonucunu görüntülerken, görüntüleme modunu, "
+"görünümleri ve referans görünümünü birleştirirken etkinleştirilmesi gereken "
+"sıralı görünüm listesini hesaplar. Sonuç, bir çiftler listesi (view_id, "
+"view_mode) olarak döndürülür."
#. module: base
#: model:ir.model.fields,help:base.field_ir_actions_report__attachment
@@ -20327,6 +20426,9 @@ msgid ""
"\n"
"Updated for Odoo 9 by Bringsvor Consulting AS <www.bringsvor.com>\n"
msgstr ""
+"Bu, Odoo'da Norveç için muhasebe çizelgesini yöneten modüldür.\n"
+"\n"
+" Bringsvor Consulting AS tarafından Odoo 9 için güncellenmiştir <www.bringsvor.com>\n"
#. module: base
#: model:ir.module.module,description:base.module_test_mail
@@ -20347,6 +20449,8 @@ msgid ""
"This theme module is exclusively for master to keep the support of "
"Bootswatch themes which were previously part of the website module in 8.0."
msgstr ""
+"Bu tema modülü, master'ın daha önce 8.0'da bulunan web sitesi modülünün bir "
+"parçası olan Bootswatch temalarını desteklemesini sağlamak içindir."
#. module: base
#: model:ir.model.fields,field_description:base.field_res_lang__thousands_sep
@@ -20361,17 +20465,17 @@ msgstr "Perşembe"
#. module: base
#: model:ir.module.module,summary:base.module_helpdesk
msgid "Ticketing, Support, Issues"
-msgstr ""
+msgstr "Talep, Destek, Sorunlar"
#. module: base
#: model:ir.module.module,summary:base.module_website_helpdesk_livechat
msgid "Ticketing, Support, Livechat"
-msgstr ""
+msgstr "Talep, Destek, Canlı Sohbet"
#. module: base
#: model:ir.module.module,summary:base.module_website_helpdesk_slides
msgid "Ticketing, Support, Slides"
-msgstr ""
+msgstr "Talep, Destek, Slaytlar"
#. module: base
#: model:ir.model.fields,field_description:base.field_res_lang__time_format
@@ -20381,12 +20485,12 @@ msgstr "Saat Biçimi"
#. module: base
#: model:ir.module.module,summary:base.module_timesheet_grid
msgid "Timesheet Validation and Grid View"
-msgstr ""
+msgstr "Zaman Çizelgesi Onayı ve Grid Görünümü"
#. module: base
#: model:ir.module.module,shortdesc:base.module_project_timesheet_holidays
msgid "Timesheet when on Leaves"
-msgstr ""
+msgstr "İzinlerde Zaman Çizelgesi"
#. module: base
#: model:ir.module.category,name:base.module_category_hr_timesheet
@@ -20397,12 +20501,12 @@ msgstr "Zaman Çizelgeleri"
#. module: base
#: model:ir.module.module,shortdesc:base.module_timesheet_grid
msgid "Timesheets Validation"
-msgstr ""
+msgstr "Zaman Çizelgesi Doğrulama"
#. module: base
#: model:ir.module.module,shortdesc:base.module_hr_timesheet_attendance
msgid "Timesheets/attendances reporting"
-msgstr ""
+msgstr "Zaman çizelgesi/Katılım raporları"
#. module: base
#: model:ir.model.fields,field_description:base.field_res_partner__tz
@@ -20419,7 +20523,7 @@ msgstr "Saat dilimi ofseti"
#. module: base
#: model:res.country,name:base.tl
msgid "Timor-Leste"
-msgstr ""
+msgstr "Doğu Timor"
#. module: base
#: model:ir.model.fields,field_description:base.field_res_partner__title
@@ -20471,6 +20575,8 @@ msgstr "Yükseltilecek"
msgid ""
"To enable it, make sure this directory exists and is writable on the server:"
msgstr ""
+"Bunu etkinleştirmek için, bu dizinin var olduğundan ve sunucuda yazılabilir "
+"olduğundan emin olun:"
#. module: base
#: model:ir.ui.view,arch_db:base.view_server_action_form
@@ -20510,7 +20616,7 @@ msgstr "Üst Marj (mm)"
#. module: base
#: model:ir.model.fields,help:base.field_ir_model__count
msgid "Total number of records in this model"
-msgstr ""
+msgstr "Bu modeldeki toplam kayıt sayısı"
#. module: base
#: model:ir.module.module,summary:base.module_point_of_sale
@@ -20546,17 +20652,17 @@ msgstr "Geçici Model"
#. module: base
#: model:ir.ui.view,arch_db:base.report_irmodeloverview
msgid "Transient: False"
-msgstr ""
+msgstr "Geçici : Yanlış"
#. module: base
#: model:ir.ui.view,arch_db:base.report_irmodeloverview
msgid "Transient: True"
-msgstr ""
+msgstr "Geçici : Doğru"
#. module: base
#: model:ir.module.module,shortdesc:base.module_transifex
msgid "Transifex integration"
-msgstr ""
+msgstr "Transifex Entegrasyonu"
#. module: base
#: model:ir.model.fields,field_description:base.field_res_groups__trans_implied_ids
@@ -20640,7 +20746,7 @@ msgstr "Çeviriler"
#. module: base
#: model:res.partner.industry,name:base.res_partner_industry_H
msgid "Transportation"
-msgstr ""
+msgstr "Ulaştırma"
#. module: base
#: selection:ir.actions.act_window,view_type:0
@@ -20753,7 +20859,7 @@ msgstr "Türü:"
#. module: base
#: model:res.partner.industry,full_name:base.res_partner_industry_U
msgid "U ACTIVITIES OF EXTRA TERRITORIAL ORGANISATIONS AND BODIES"
-msgstr ""
+msgstr "U SINIR ÖTESİ ORGANİZASYON ETKİNLİKLERİ VE BEDENLER"
#. module: base
#: model:ir.module.module,shortdesc:base.module_l10n_ae
@@ -20768,7 +20874,7 @@ msgstr "UK - Accounting"
#. module: base
#: model:ir.module.module,shortdesc:base.module_l10n_uk_reports
msgid "UK - Accounting Reports"
-msgstr ""
+msgstr "Birleşik Krallık - Muhasebe Raporları"
#. module: base
#: model:ir.module.module,shortdesc:base.module_website_delivery_ups
@@ -20778,7 +20884,7 @@ msgstr "UPS Fatura Hesabım"
#. module: base
#: model:ir.module.module,shortdesc:base.module_delivery_ups
msgid "UPS Shipping"
-msgstr ""
+msgstr "UPS Sevkıyatı"
#. module: base
#: selection:ir.attachment,type:0
@@ -20790,7 +20896,7 @@ msgstr "URL"
#. module: base
#: model:ir.module.module,shortdesc:base.module_l10n_us_reports
msgid "US - Accounting Reports"
-msgstr ""
+msgstr "Birleşik Devlerler - Muhasebe Raporları"
#. module: base
#: model:ir.module.module,shortdesc:base.module_l10n_us_check_printing
@@ -20805,7 +20911,7 @@ msgstr "ABD Çevresi Adaları"
#. module: base
#: model:ir.module.module,shortdesc:base.module_utm
msgid "UTM Trackers"
-msgstr ""
+msgstr "UTM İzleyici"
#. module: base
#: model:res.country,name:base.ug
@@ -20833,7 +20939,7 @@ msgstr "Döküman öntamımlı bir özellik olarak kullanıldığı için siline
#: code:addons/base/models/ir_actions_report.py:622
#, python-format
msgid "Unable to find Wkhtmltopdf on this system. The PDF can not be created."
-msgstr ""
+msgstr "Wkhtmltopdf bu sistemde bulunamadı. PDF oluşturulamıyor."
#. module: base
#: code:addons/base/models/ir_module.py:342
@@ -20876,7 +20982,7 @@ msgstr "Kaldır"
#: model:ir.ui.view,arch_db:base.view_base_module_uninstall
#, python-format
msgid "Uninstall module"
-msgstr ""
+msgstr "Modülü kaldır"
#. module: base
#: selection:ir.module.module,state:0
@@ -20908,7 +21014,7 @@ msgstr "USA - Muhasebe Hesapları"
#. module: base
#: model:ir.module.module,shortdesc:base.module_delivery_usps
msgid "United States Postal Service (USPS) Shipping"
-msgstr ""
+msgstr "Birleşik Devletler Posta Servisi (USPS) Teslimatı"
#. module: base
#: selection:ir.module.module.dependency,state:0
@@ -21011,7 +21117,7 @@ msgstr "Güncelleştirme Şartları"
#. module: base
#: selection:ir.actions.server,state:0
msgid "Update the Record"
-msgstr ""
+msgstr "Kaydı Güncelle"
#. module: base
#: model:ir.ui.view,arch_db:base.view_company_report_form
@@ -21019,6 +21125,8 @@ msgid ""
"Update your company details and upload your logo to get a beautiful "
"document."
msgstr ""
+"Şirket bilgilerinizi güncelleyin ve güzel bir doküman almak için logonuzu "
+"yükleyin."
#. module: base
#: model:ir.actions.client,name:base.modules_updates_act_cl
@@ -21044,7 +21152,7 @@ msgstr "Uruguay"
#. module: base
#: model:ir.module.module,shortdesc:base.module_l10n_uy_reports
msgid "Uruguay - Accounts Reports"
-msgstr ""
+msgstr "Uruguay - Hesap Raporları"
#. module: base
#: model:ir.module.module,shortdesc:base.module_l10n_uy
@@ -21067,7 +21175,7 @@ msgstr "Use '1' for yes and '0' for no"
#. module: base
#: model:ir.model.fields,field_description:base.field_ir_sequence__use_date_range
msgid "Use subsequences per date_range"
-msgstr ""
+msgstr "date_range başına aşağıdakileri kullanın"
#. module: base
#: model:ir.module.module,description:base.module_hr_gamification
@@ -21078,6 +21186,11 @@ msgid ""
"This allow the user to send badges to employees instead of simple users.\n"
"Badge received are displayed on the user profile.\n"
msgstr ""
+"Oyunlaştırma işlemleri için İK kaynaklarını kullanın.\n"
+"\n"
+"İK sorumlusu artık mücadeleleri ve rozetleri yönetebilir.\n"
+"Bu, kullanıcının basit kullanıcılar yerine çalışanlara rozet göndermesine izin verir. \n"
+"Alınan rozet kullanıcı profilinde görüntülenir.\n"
#. module: base
#: code:addons/base/models/ir_fields.py:209
@@ -21089,7 +21202,7 @@ msgstr "Biçimini kullanın '%s'"
#. module: base
#: model:ir.model.fields,help:base.field_res_country__vat_label
msgid "Use this field if you want to change vat label."
-msgstr ""
+msgstr "Vergi etiketini değiştirmek istiyorsanız bu alanı kullanın."
#. module: base
#: model:ir.model.fields,help:base.field_res_country__address_view_id
@@ -21099,12 +21212,18 @@ msgid ""
"display addresses (in reports for example), while this field is used to "
"modify the input form for addresses."
msgstr ""
+"Tam adresi kodlamak için genel yolunu değiştirmek istiyorsanız, bu alanı "
+"kullanın. Address_format alanının adresleri görüntüleme şeklini değiştirmek "
+"için (örneğin raporlarda), bu alanın adresler için giriş formunu değiştirmek"
+" için kullanıldığını unutmayın."
#. module: base
#: model:ir.model.fields,help:base.field_ir_model_fields__relation_table
msgid ""
"Used for custom many2many fields to define a custom relation table name"
msgstr ""
+"Özel bir ilişki tablosu adı tanımlamak için özel many2many alanları için "
+"kullanılır"
#. module: base
#: model:ir.model.fields,help:base.field_ir_actions_act_window__usage
@@ -21156,7 +21275,7 @@ msgstr "Kullanıcı Girişi"
#. module: base
#: model:ir.model.fields,field_description:base.field_res_users__log_ids
msgid "User log entries"
-msgstr ""
+msgstr "Kullanıcı log girişleri"
#. module: base
#: model:ir.actions.act_window,name:base.ir_default_menu_action
@@ -21239,7 +21358,7 @@ msgstr "Vergi No"
#. module: base
#: model:ir.module.module,shortdesc:base.module_base_vat_autocomplete
msgid "VAT Number Autocomplete"
-msgstr ""
+msgstr "Otomatik Vergi Numarası Tamamlayıcı"
#. module: base
#: model:ir.module.module,shortdesc:base.module_base_vat
@@ -21249,27 +21368,29 @@ msgstr "KDV Numara Doğrulaması"
#. module: base
#: model:ir.module.module,shortdesc:base.module_voip
msgid "VOIP"
-msgstr ""
+msgstr "VOIP"
#. module: base
#: model:ir.module.module,shortdesc:base.module_voip_onsip
msgid "VOIP OnSIP"
-msgstr ""
+msgstr "VOIP OnSIP"
#. module: base
#: model:ir.module.module,summary:base.module_website_crm_phone_validation
msgid "Validate and format contact form numbers"
-msgstr ""
+msgstr "İletişim formu numaralarını doğrulayın ve biçimlendirin"
#. module: base
#: model:ir.module.module,summary:base.module_phone_validation
msgid "Validate and format phone numbers"
-msgstr ""
+msgstr "Telefon numaralarını doğrula ve biçimlendir."
#. module: base
#: model:ir.module.module,summary:base.module_crm_phone_validation
msgid "Validate and format phone numbers for leads and contacts"
msgstr ""
+"Bağlantılar ve potansiyel müşteriler için telefon numaralarını biçimlendir "
+"ve doğrula"
#. module: base
#: model:ir.model.fields,field_description:base.field_ir_config_parameter__value
@@ -21288,22 +21409,22 @@ msgstr "'%%(field)s' seçmeli alanında '%s' değeri bulunamadı"
#. module: base
#: model:ir.model.fields,field_description:base.field_ir_property__value_binary
msgid "Value Binary"
-msgstr ""
+msgstr "Değer İkili"
#. module: base
#: model:ir.model.fields,field_description:base.field_ir_property__value_datetime
msgid "Value Datetime"
-msgstr ""
+msgstr "Tarih-Saat Değeri"
#. module: base
#: model:ir.model.fields,field_description:base.field_ir_property__value_float
msgid "Value Float"
-msgstr ""
+msgstr "Sayısal Değer"
#. module: base
#: model:ir.model.fields,field_description:base.field_ir_property__value_integer
msgid "Value Integer"
-msgstr ""
+msgstr "Tam Sayı Değeri"
#. module: base
#: model:ir.model.fields,field_description:base.field_ir_actions_server__fields_lines
@@ -21314,12 +21435,12 @@ msgstr "Değer Eşleme"
#. module: base
#: model:ir.model.fields,field_description:base.field_ir_property__value_reference
msgid "Value Reference"
-msgstr ""
+msgstr "Referans Değeri"
#. module: base
#: model:ir.model.fields,field_description:base.field_ir_property__value_text
msgid "Value Text"
-msgstr ""
+msgstr "Metin Değeri"
#. module: base
#: model:res.country,name:base.vu
@@ -21338,7 +21459,7 @@ msgstr ""
#. module: base
#: model:ir.model.fields,field_description:base.field_res_country__vat_label
msgid "Vat Label"
-msgstr ""
+msgstr "Vergi Etiketi"
#. module: base
#: model:ir.module.module,summary:base.module_fleet
@@ -21348,7 +21469,7 @@ msgstr "Araç, finansal kiralama, sigorta, maliyetleri"
#. module: base
#: model:ir.module.module,shortdesc:base.module_account_3way_match
msgid "Vendor Bill: Release to Pay"
-msgstr ""
+msgstr "Tedarikçi Faturaları: Ödeme Yap"
#. module: base
#: model:ir.actions.act_window,name:base.action_partner_supplier_form
@@ -21384,7 +21505,7 @@ msgstr "Vietnam Hesap Planı"
#. module: base
#: model:ir.module.module,shortdesc:base.module_l10n_vn_reports
msgid "Vietnam - Accounting Reports"
-msgstr ""
+msgstr "Vietnam - Muhasebe Raporları"
#. module: base
#: model:ir.model.fields,field_description:base.field_ir_actions_act_window_view__view_id
@@ -21433,7 +21554,7 @@ msgstr "Görünüm Türü"
#. module: base
#: model:ir.module.module,summary:base.module_account_reports
msgid "View and create reports"
-msgstr ""
+msgstr "Raporları oluştur ve görüntüle"
#. module: base
#: model:ir.model.fields,field_description:base.field_ir_ui_view__mode
@@ -21453,7 +21574,7 @@ msgstr ""
#: code:addons/base/models/ir_model.py:571
#, python-format
msgid "View: %s"
-msgstr ""
+msgstr "Görünüm:%s"
#. module: base
#: model:ir.actions.act_window,name:base.action_ui_view
@@ -21514,7 +21635,7 @@ msgstr "Maliyet Yüklemeleri"
#. module: base
#: model:res.country,name:base.wf
msgid "Wallis and Futuna"
-msgstr ""
+msgstr "Wallis ve Futuna"
#. module: base
#: model:ir.module.category,name:base.module_category_warehouse
@@ -21524,12 +21645,12 @@ msgstr "Depo"
#. module: base
#: model:ir.module.module,shortdesc:base.module_stock_barcode
msgid "Warehouse Management Barcode Scanning"
-msgstr ""
+msgstr "Depo Yönetimi Barkod Taraması"
#. module: base
#: model:ir.module.module,shortdesc:base.module_stock_picking_batch
msgid "Warehouse Management: Batch Picking"
-msgstr ""
+msgstr "Depo Yönetimi: Toplu Transfer"
#. module: base
#: code:addons/base/models/ir_mail_server.py:476
@@ -21555,7 +21676,7 @@ msgstr "Uyarılar"
#. module: base
#: model:res.partner.industry,name:base.res_partner_industry_E
msgid "Water supply"
-msgstr ""
+msgstr "Su temini"
#. module: base
#: model:ir.ui.view,arch_db:base.view_base_module_upgrade_install
@@ -21574,7 +21695,7 @@ msgstr "Web"
#. module: base
#: model:ir.module.module,shortdesc:base.module_web_clearbit
msgid "Web Clearbit"
-msgstr ""
+msgstr "Web Clearbit"
#. module: base
#: model:ir.module.module,shortdesc:base.module_web_editor
@@ -21584,7 +21705,7 @@ msgstr "Web Editörü"
#. module: base
#: model:ir.module.module,shortdesc:base.module_web_enterprise
msgid "Web Enterprise"
-msgstr ""
+msgstr "Web Kurumsal"
#. module: base
#: model:ir.module.module,shortdesc:base.module_web_gantt
@@ -21605,7 +21726,7 @@ msgstr "Web İkon Resmi"
#: model:ir.module.module,shortdesc:base.module_http_routing
#: model:ir.module.module,summary:base.module_http_routing
msgid "Web Routing"
-msgstr ""
+msgstr "Web Rotası"
#. module: base
#: model:ir.ui.view,arch_db:base.view_translation_search
@@ -21629,22 +21750,22 @@ msgstr "Web Sitesi Oluşturucusu"
#. module: base
#: model:ir.module.module,shortdesc:base.module_website_enterprise
msgid "Website Enterprise"
-msgstr ""
+msgstr "Website Kurumsal"
#. module: base
#: model:ir.module.module,shortdesc:base.module_website_form_project
msgid "Website Form - Project"
-msgstr ""
+msgstr "Website Formu - Proje"
#. module: base
#: model:ir.module.module,shortdesc:base.module_website_form_editor
msgid "Website Form Builder"
-msgstr ""
+msgstr "Website Form Oluşturucu"
#. module: base
#: model:ir.module.module,shortdesc:base.module_website_helpdesk_form
msgid "Website Form Helpdesk"
-msgstr ""
+msgstr "Website Yardım Masası Formu"
#. module: base
#: model:ir.module.module,shortdesc:base.module_website_gengo
@@ -21659,12 +21780,12 @@ msgstr "Web Sitesi Google Haritalar"
#. module: base
#: model:ir.module.module,shortdesc:base.module_website_helpdesk
msgid "Website Helpdesk"
-msgstr ""
+msgstr "Website Yardım Masası"
#. module: base
#: model:ir.module.module,shortdesc:base.module_website_helpdesk_livechat
msgid "Website IM Livechat Helpdesk"
-msgstr ""
+msgstr "Website IM Canlı Destek Masası"
#. module: base
#: model:ir.module.module,shortdesc:base.module_website_links
@@ -21709,32 +21830,32 @@ msgstr "Web Sitesi Satış - Satış Yönetimi"
#. module: base
#: model:ir.module.module,shortdesc:base.module_website_sale_coupon
msgid "Website Sale Coupon"
-msgstr ""
+msgstr "Website İndirim Kuponu"
#. module: base
#: model:ir.module.module,shortdesc:base.module_website_sale_digital
msgid "Website Sale Digital - Sell digital products"
-msgstr ""
+msgstr "Website Dijital Satış - Dijital Ürünleri Satın"
#. module: base
#: model:ir.module.module,shortdesc:base.module_website_sale_stock
msgid "Website Sale Stock - Website Delivery Information"
-msgstr ""
+msgstr "Web Sitesi Satış Stoku - Web Sitesi Teslimat Bilgileri"
#. module: base
#: model:ir.module.module,shortdesc:base.module_website_sale_stock_options
msgid "Website Sale Stock&Options"
-msgstr ""
+msgstr "Web Sitesi Satış Stok ve Seçenekleri"
#. module: base
#: model:ir.module.module,shortdesc:base.module_website_helpdesk_slides
msgid "Website Slides Helpdesk"
-msgstr ""
+msgstr "Web Sitesi Slaytları Yardım Masası"
#. module: base
#: model:ir.module.module,shortdesc:base.module_website_studio
msgid "Website Studio"
-msgstr ""
+msgstr "Website Stüdyo"
#. module: base
#: model:ir.module.module,shortdesc:base.module_website_theme_install
@@ -21744,12 +21865,12 @@ msgstr "Web Sitesi Tema Yükleme"
#. module: base
#: model:ir.module.module,shortdesc:base.module_website_version
msgid "Website Versioning"
-msgstr ""
+msgstr "Website Versiyonlama"
#. module: base
#: model:ir.module.module,shortdesc:base.module_website_sale_wishlist
msgid "Website Wishlist"
-msgstr ""
+msgstr "Website Wishlisti"
#. module: base
#: model:ir.model.fields,help:base.field_res_company__website
@@ -21799,6 +21920,9 @@ msgid ""
"When no specific mail server is requested for a mail, the highest priority "
"one is used. Default priority is 10 (smaller number = higher priority)"
msgstr ""
+"Posta için belirli bir posta sunucusu talep edilmediğinde, en yüksek öncelik"
+" kullanılır. Varsayılan öncelik 10'dur (daha küçük sayı = daha yüksek "
+"öncelik)"
#. module: base
#: model:ir.ui.view,arch_db:base.sequence_view
@@ -21810,12 +21934,12 @@ msgstr ""
#. module: base
#: model:ir.model.fields,help:base.field_ir_model_fields__copy
msgid "Whether the value is copied when duplicating a record."
-msgstr ""
+msgstr "Bir kayıt çoğaltılırken değer kopyalanıp kopyalanmayacağı."
#. module: base
#: model:ir.model.fields,help:base.field_ir_model_fields__store
msgid "Whether the value is stored in the database."
-msgstr ""
+msgstr "Değerin veritabanında depolanıp depolanmadığı."
#. module: base
#: model:ir.model.fields,help:base.field_ir_model_fields__translate
@@ -21829,7 +21953,7 @@ msgstr ""
#. module: base
#: model:res.partner.industry,name:base.res_partner_industry_G
msgid "Wholesale/Retail"
-msgstr ""
+msgstr "Toptan/Perakende"
#. module: base
#: model:ir.actions.act_window,name:base.ir_action_window
@@ -21865,7 +21989,7 @@ msgstr "Wkhtmltopdf başarısız oldu (hata kodu: %s). Mesaj: %s"
#. module: base
#: model:ir.module.module,summary:base.module_mrp_workorder
msgid "Work Orders, Planing, Stock Reports."
-msgstr ""
+msgstr "İş Emri, Planlama, Stok Raporları"
#. module: base
#: model:ir.module.module,shortdesc:base.module_payment_sips
@@ -21906,7 +22030,7 @@ msgstr "Yodlee"
#. module: base
#: model:ir.module.module,summary:base.module_account_yodlee
msgid "Yodlee Finance"
-msgstr ""
+msgstr "Yodlee Finans"
#. module: base
#: model:ir.ui.view,arch_db:base.view_users_simple_form
@@ -21967,7 +22091,7 @@ msgstr "Özyinelemeli Partner hiyerarşileri oluşturamazsınız."
#: code:addons/base/models/ir_ui_view.py:357
#, python-format
msgid "You cannot create recursive inherited views."
-msgstr ""
+msgstr "Yinelenen miras görünümler oluşturamazsınız."
#. module: base
#: code:addons/base/models/res_users.py:344
@@ -22075,6 +22199,9 @@ msgid ""
"instead. If SSL is needed, an upgrade to Python 2.6 on the server-side "
"should do the trick."
msgstr ""
+"Odoo Sunucusu SMTP üzerinden SSL desteklemez. STARTTLS yerine "
+"kullanabilirsiniz. Python 2.6 sürümüne yükseltmeyi sunucu tarafında SSL "
+"kullanılmıyorsa, işimizi görür."
#. module: base
#: code:addons/base/models/ir_mail_server.py:477
@@ -22176,17 +22303,17 @@ msgstr "base.update.translations"
#. module: base
#: selection:ir.model.fields,ttype:0
msgid "binary"
-msgstr ""
+msgstr "ikili"
#. module: base
#: selection:ir.model.fields,ttype:0
msgid "boolean"
-msgstr ""
+msgstr "mantıksal"
#. module: base
#: model:ir.module.module,shortdesc:base.module_delivery_bpost
msgid "bpost Shipping"
-msgstr ""
+msgstr "bpost Sevkıyat"
#. module: base
#: selection:ir.model.fields,ttype:0
@@ -22201,7 +22328,7 @@ msgstr "seç"
#. module: base
#: model:ir.module.category,name:base.module_category_crm
msgid "crm"
-msgstr ""
+msgstr "crm"
#. module: base
#: code:addons/base/models/ir_fields.py:314
@@ -22212,12 +22339,12 @@ msgstr "veritabanı id"
#. module: base
#: selection:ir.model.fields,ttype:0
msgid "date"
-msgstr ""
+msgstr "tarih"
#. module: base
#: selection:ir.model.fields,ttype:0
msgid "datetime"
-msgstr ""
+msgstr "tarih saat"
#. module: base
#: model:ir.ui.view,arch_db:base.wizard_lang_export
@@ -22249,7 +22376,7 @@ msgstr "örn. Global İş Çözümleri"
#. module: base
#: model:ir.ui.view,arch_db:base.view_partner_form
msgid "e.g. Mr."
-msgstr ""
+msgstr "örn. Bay"
#. module: base
#: model:ir.ui.view,arch_db:base.view_partner_form
@@ -22261,12 +22388,12 @@ msgstr "örn. Satış Yöneticisi"
#. module: base
#: model:ir.ui.view,arch_db:base.view_server_action_form
msgid "e.g. Update order quantity"
-msgstr ""
+msgstr "örn. Sipariş miktarını güncelle"
#. module: base
#: model:ir.ui.view,arch_db:base.view_company_form
msgid "e.g. Your Bank Accounts, one per line"
-msgstr ""
+msgstr "örn. Banka Hesaplarınız, satır başına"
#. module: base
#: model:ir.ui.view,arch_db:base.view_base_import_language
@@ -22283,7 +22410,7 @@ msgstr "örn. www.odoo.com"
#. module: base
#: model:ir.module.module,shortdesc:base.module_sale_ebay
msgid "eBay Connector"
-msgstr ""
+msgstr "eBay Bağlayıcı"
#. module: base
#: model:ir.module.module,shortdesc:base.module_website_sale
@@ -22325,7 +22452,7 @@ msgstr "yanlış"
#. module: base
#: selection:ir.model.fields,ttype:0
msgid "float"
-msgstr ""
+msgstr "sayısal"
#. module: base
#: model:ir.ui.view,arch_db:base.view_model_fields_form
@@ -22334,6 +22461,8 @@ msgid ""
"for record in self:\n"
" record['size'] = len(record.name)"
msgstr ""
+"kendi kaydı için:\n"
+"record['size'] = len(record.name)"
#. module: base
#: code:addons/base/models/res_lang.py:255
@@ -22344,7 +22473,7 @@ msgstr ""
#. module: base
#: model:ir.model,name:base.model_format_address_mixin
msgid "format.address.mixin"
-msgstr ""
+msgstr "format.address.mixin"
#. module: base
#: selection:base.language.export,state:0
@@ -22354,7 +22483,7 @@ msgstr "alma"
#. module: base
#: selection:ir.model.fields,ttype:0
msgid "html"
-msgstr ""
+msgstr "html"
#. module: base
#: selection:base.language.install,state:0
@@ -22365,7 +22494,7 @@ msgstr "başlatma"
#. module: base
#: selection:ir.model.fields,ttype:0
msgid "integer"
-msgstr ""
+msgstr "tamsayı"
#. module: base
#: model:ir.ui.view,arch_db:base.view_partner_form
@@ -22435,7 +22564,7 @@ msgstr "ir.config_parameter"
#. module: base
#: model:ir.model,name:base.model_ir_default
msgid "ir.default"
-msgstr ""
+msgstr "ir.default"
#. module: base
#: model:ir.model,name:base.model_ir_exports
@@ -22530,7 +22659,7 @@ msgstr "ir.qweb.field.float"
#. module: base
#: model:ir.model,name:base.model_ir_qweb_field_float_time
msgid "ir.qweb.field.float_time"
-msgstr ""
+msgstr "ir.qweb.field.float_time"
#. module: base
#: model:ir.model,name:base.model_ir_qweb_field_html
@@ -22615,17 +22744,17 @@ msgstr "ir.ui.view.custom"
#. module: base
#: selection:ir.model.fields,ttype:0
msgid "many2many"
-msgstr ""
+msgstr "many2many"
#. module: base
#: selection:ir.model.fields,ttype:0
msgid "many2one"
-msgstr ""
+msgstr "many2one"
#. module: base
#: selection:ir.model.fields,ttype:0
msgid "monetary"
-msgstr ""
+msgstr "monetary"
#. module: base
#: code:addons/base/models/ir_ui_view.py:488
@@ -22653,22 +22782,22 @@ msgstr "açık"
#. module: base
#: selection:ir.model.fields,ttype:0
msgid "one2many"
-msgstr ""
+msgstr "ne2many"
#. module: base
#: model:ir.module.module,shortdesc:base.module_pos_cache
msgid "pos_cache"
-msgstr ""
+msgstr "pos_cache"
#. module: base
#: model:ir.module.module,shortdesc:base.module_pos_sale
msgid "pos_sale"
-msgstr ""
+msgstr "pos_sale"
#. module: base
#: selection:ir.model.fields,ttype:0
msgid "reference"
-msgstr ""
+msgstr "referans"
#. module: base
#: model:ir.model,name:base.model_report_base_report_irmodulereference
@@ -22703,7 +22832,7 @@ msgstr "res.users.log"
#. module: base
#: selection:ir.model.fields,ttype:0
msgid "selection"
-msgstr ""
+msgstr "seçim"
#. module: base
#: model:ir.module.module,shortdesc:base.module_social_media
@@ -22728,12 +22857,12 @@ msgstr ""
#. module: base
#: model:ir.module.module,shortdesc:base.module_test_assetsbundle
msgid "test-assetsbundle"
-msgstr ""
+msgstr "test-assetsbundle"
#. module: base
#: model:ir.module.module,shortdesc:base.module_test_pylint
msgid "test-eval"
-msgstr ""
+msgstr "test - deneme sürümü"
#. module: base
#: model:ir.module.module,shortdesc:base.module_test_exceptions
@@ -22778,7 +22907,7 @@ msgstr "test_convert"
#. module: base
#: selection:ir.model.fields,ttype:0
msgid "text"
-msgstr ""
+msgstr "metin"
#. module: base
#: model:ir.ui.view,arch_db:base.res_config_installer
diff --git a/odoo/addons/base/models/ir_mail_server.py b/odoo/addons/base/models/ir_mail_server.py
index 97f100fb94b..9cf939dcf05 100644
--- a/odoo/addons/base/models/ir_mail_server.py
+++ b/odoo/addons/base/models/ir_mail_server.py
@@ -22,6 +22,8 @@ from odoo.tools import ustr, pycompat
_logger = logging.getLogger(__name__)
_test_logger = logging.getLogger('odoo.tests')
+SMTP_TIMEOUT = 60
+
class MailDeliveryException(except_orm):
"""Specific exception subclass for mail delivery errors"""
@@ -246,9 +248,9 @@ class IrMailServer(models.Model):
"You could use STARTTLS instead. "
"If SSL is needed, an upgrade to Python 2.6 on the server-side "
"should do the trick."))
- connection = smtplib.SMTP_SSL(smtp_server, smtp_port)
+ connection = smtplib.SMTP_SSL(smtp_server, smtp_port, timeout=SMTP_TIMEOUT)
else:
- connection = smtplib.SMTP(smtp_server, smtp_port)
+ connection = smtplib.SMTP(smtp_server, smtp_port, timeout=SMTP_TIMEOUT)
connection.set_debuglevel(smtp_debug)
if smtp_encryption == 'starttls':
# starttls() will perform ehlo() if needed first
diff --git a/odoo/addons/base/models/ir_model.py b/odoo/addons/base/models/ir_model.py
index 8981618590e..77efe9daba2 100644
--- a/odoo/addons/base/models/ir_model.py
+++ b/odoo/addons/base/models/ir_model.py
@@ -28,7 +28,7 @@ SAFE_EVAL_BASE = {
def make_compute(text, deps):
""" Return a compute function from its code body and dependencies. """
func = lambda self: safe_eval(text, SAFE_EVAL_BASE, {'self': self}, mode="exec")
- deps = [arg.strip() for arg in (deps or "").split(",")]
+ deps = [arg.strip() for arg in deps.split(",")] if deps else []
return api.depends(*deps)(func)
diff --git a/odoo/addons/base/models/qweb.py b/odoo/addons/base/models/qweb.py
index 98697b87738..692db1bf0f3 100644
--- a/odoo/addons/base/models/qweb.py
+++ b/odoo/addons/base/models/qweb.py
@@ -308,8 +308,9 @@ class QWeb(object):
raise e
except Exception as e:
path = _options['last_path_node']
- node = element.getroottree().xpath(path)
- raise QWebException("Error when compiling AST", e, path, etree.tostring(node[0], encoding='unicode'), name)
+ element, document = self.get_template(template, options)
+ node = element.getroottree().xpath(path) if ':' not in path else None
+ raise QWebException("Error when compiling AST", e, path, node and etree.tostring(node[0], encoding='unicode'), name)
astmod.body.extend(_options['ast_calls'])
if 'profile' in options:
@@ -344,7 +345,7 @@ class QWeb(object):
except Exception as e:
path = log['last_path_node']
element, document = self.get_template(template, options)
- node = element.getroottree().xpath(path)
+ node = element.getroottree().xpath(path) if ':' not in path else None
raise QWebException("Error to render compiling AST", e, path, node and etree.tostring(node[0], encoding='unicode'), name)
return _compiled_fn
diff --git a/odoo/addons/base/models/res_users.py b/odoo/addons/base/models/res_users.py
index 02f9d90562c..204d4751eb6 100644
--- a/odoo/addons/base/models/res_users.py
+++ b/odoo/addons/base/models/res_users.py
@@ -789,6 +789,11 @@ class GroupsView(models.Model):
xml = E.field(E.group(*(xml1), col="2"), E.group(*(xml2), col="4"), name="groups_id", position="replace")
xml.addprevious(etree.Comment("GENERATED AUTOMATICALLY BY GROUPS"))
xml_content = etree.tostring(xml, pretty_print=True, encoding="unicode")
+ if not view.check_access_rights('write', raise_exception=False):
+ # erp manager has the rights to update groups/users but not
+ # to modify ir.ui.view
+ if self.env.user.has_group('base.group_erp_manager'):
+ view = view.sudo()
new_context = dict(view._context)
new_context.pop('install_mode_data', None) # don't set arch_fs for this computed view
diff --git a/odoo/addons/base/rng/tree_view.rng b/odoo/addons/base/rng/tree_view.rng
index 1dec8e9ab11..dc41ee5005c 100644
--- a/odoo/addons/base/rng/tree_view.rng
+++ b/odoo/addons/base/rng/tree_view.rng
@@ -17,6 +17,8 @@
<rng:optional><rng:attribute name="duplicate"/></rng:optional>
<rng:optional><rng:attribute name="import"/></rng:optional>
<rng:optional><rng:attribute name="class"/></rng:optional>
+ <!-- Allows to take a custom View widget for handling. Defined in view_manager. -->
+ <rng:optional><rng:attribute name="js_class"/></rng:optional>
<rng:optional><rng:attribute name="colors"/></rng:optional>
<rng:optional><rng:attribute name="fonts"/></rng:optional>
<rng:optional><rng:attribute name="default_order"/></rng:optional>
diff --git a/odoo/addons/base/security/base_security.xml b/odoo/addons/base/security/base_security.xml
index f3bf2f908dd..21401d88b47 100644
--- a/odoo/addons/base/security/base_security.xml
+++ b/odoo/addons/base/security/base_security.xml
@@ -78,7 +78,7 @@
<field name="name">res.partner.rule.private.employee</field>
<field name="model_id" ref="base.model_res_partner"/>
<field name="domain_force">
- [('type', '!=', 'private')]
+ ['|', ('type', '!=', 'private'), ('type', '=', False)]
</field>
<field name="groups" eval="[
(4, ref('base.group_user')),
diff --git a/odoo/addons/base/tests/test_qweb.py b/odoo/addons/base/tests/test_qweb.py
index bea0c74cabe..310c5220897 100644
--- a/odoo/addons/base/tests/test_qweb.py
+++ b/odoo/addons/base/tests/test_qweb.py
@@ -5,6 +5,7 @@ import collections
import json
import os.path
import re
+import sys
from lxml import etree
@@ -465,6 +466,26 @@ class TestQWebNS(TransactionCase):
expected_result
)
+ def test_render_dynamic_xml_with_code_error(self):
+ """ Test that, when rendering a template containing a namespaced node
+ that evaluates code with errors, the proper exception is raised
+ """
+ view1 = self.env['ir.ui.view'].create({
+ 'name': "dummy",
+ 'type': 'qweb',
+ 'arch': u"""
+ <t t-name="base.dummy">
+ <Invoice xmlns:od="http://odoo.com/od">
+ <od:name t-att-test="'a' + 1"/>
+ </Invoice>
+ </t>
+ """
+ })
+ error_msg = "Can't convert 'int' object to str implicitly"
+ if sys.version_info >= (3, 6):
+ error_msg = "must be str, not int"
+ with self.assertRaisesRegexp(QWebException, error_msg):
+ view1.render()
from copy import deepcopy
class FileSystemLoader(object):
diff --git a/odoo/addons/test_new_api/tests/test_new_fields.py b/odoo/addons/test_new_api/tests/test_new_fields.py
index a7d0f977968..1ce7d1a75e2 100644
--- a/odoo/addons/test_new_api/tests/test_new_fields.py
+++ b/odoo/addons/test_new_api/tests/test_new_fields.py
@@ -61,6 +61,19 @@ class TestFields(common.TransactionCase):
self.assertTrue(field.store)
self.assertTrue(field.readonly)
+ def test_10_computed_custom(self):
+ """ check definition of custom computed fields """
+ self.env['ir.model.fields'].create({
+ 'name': 'x_bool_false_computed',
+ 'model_id': self.env.ref('test_new_api.model_test_new_api_message').id,
+ 'field_description': 'A boolean computed to false',
+ 'compute': "for r in self: r['x_bool_false_computed'] = False",
+ 'store': False,
+ 'ttype': 'boolean'
+ })
+ field = self.env['test_new_api.message']._fields['x_bool_false_computed']
+ self.assertFalse(field.depends)
+
def test_10_non_stored(self):
""" test non-stored fields """
# a field declared with store=False should not have a column
diff --git a/odoo/addons/test_pylint/tests/test_pylint.py b/odoo/addons/test_pylint/tests/test_pylint.py
index 5681e013d38..e067c87a5fe 100644
--- a/odoo/addons/test_pylint/tests/test_pylint.py
+++ b/odoo/addons/test_pylint/tests/test_pylint.py
@@ -10,6 +10,7 @@ import subprocess
from distutils.version import LooseVersion
import os
from os.path import join
+import sys
from odoo.tests.common import TransactionCase
from odoo import tools
@@ -114,8 +115,11 @@ class TestPyLint(TransactionCase):
def test_pylint(self):
if pylint is None:
self._skip_test('please install pylint')
- if LooseVersion(getattr(pylint, '__version__', '0.0.1')) < LooseVersion('1.6.4'):
- self._skip_test('please upgrade pylint to >= 1.6.4')
+ required_pylint_version = LooseVersion('1.6.4')
+ if sys.version_info >= (3, 6):
+ required_pylint_version = LooseVersion('1.7.0')
+ if LooseVersion(getattr(pylint, '__version__', '0.0.1')) < required_pylint_version:
+ self._skip_test('please upgrade pylint to >= %s' % required_pylint_version)
paths = [tools.config['root_path']]
for module in get_modules():
diff --git a/odoo/http.py b/odoo/http.py
index f984bcb44df..09999066941 100644
--- a/odoo/http.py
+++ b/odoo/http.py
@@ -1038,7 +1038,7 @@ class OpenERPSession(werkzeug.contrib.sessions.Session):
self.db = db
self.uid = uid
self.login = login
- self.session_token = uid and security.compute_session_token(self)
+ self.session_token = uid and security.compute_session_token(self, request.env)
request.uid = uid
request.disable_db = False
@@ -1053,9 +1053,11 @@ class OpenERPSession(werkzeug.contrib.sessions.Session):
"""
if not self.db or not self.uid:
raise SessionExpiredException("Session expired")
-
+ # We create our own environment instead of the request's one.
+ # to avoid creating it without the uid since request.uid isn't set yet
+ env = odoo.api.Environment(request.cr, self.uid, self.context)
# here we check if the session is still valid
- if not security.check_session(self):
+ if not security.check_session(self, env):
raise SessionExpiredException("Session expired")
def logout(self, keep_db=False):
diff --git a/odoo/models.py b/odoo/models.py
index f1de9a5c4bb..2d46e7e5d60 100644
--- a/odoo/models.py
+++ b/odoo/models.py
@@ -2047,7 +2047,7 @@ class BaseModel(MetaModel('DummyModel', (object,), {'_register': False})):
for field in many2onefields:
ids_set = {d[field] for d in data if d[field]}
m2o_records = self.env[self._fields[field].comodel_name].browse(ids_set)
- data_dict = dict(m2o_records.name_get())
+ data_dict = dict(m2o_records.sudo().name_get())
for d in data:
d[field] = (d[field], data_dict[d[field]]) if d[field] else False
@@ -3900,7 +3900,7 @@ class BaseModel(MetaModel('DummyModel', (object,), {'_register': False})):
vals = self.copy_data(default)[0]
# To avoid to create a translation in the lang of the user, copy_translation will do it
new = self.with_context(lang=None).create(vals)
- self.copy_translations(new)
+ self.with_context(from_copy_translation=True).copy_translations(new)
return new
@api.multi
diff --git a/odoo/modules/registry.py b/odoo/modules/registry.py
index 9e180138a21..7dfead33210 100644
--- a/odoo/modules/registry.py
+++ b/odoo/modules/registry.py
@@ -149,9 +149,7 @@ class Registry(Mapping):
""" Delete the registry linked to a given database. """
with cls._lock:
if db_name in cls.registries:
- registry = cls.registries.pop(db_name)
- registry.clear_caches()
- registry.registry_invalidated = True
+ cls.registries.pop(db_name)
@classmethod
def delete_all(cls):
diff --git a/odoo/service/db.py b/odoo/service/db.py
index ce868f693dd..8f3c24d7d8a 100644
--- a/odoo/service/db.py
+++ b/odoo/service/db.py
@@ -394,6 +394,7 @@ def list_db_incompatible(databases):
incompatible_databases.append(database_name)
else:
incompatible_databases.append(database_name)
+ for database_name in incompatible_databases:
# release connection
odoo.sql_db.close_db(database_name)
return incompatible_databases
diff --git a/odoo/service/security.py b/odoo/service/security.py
index 229e4b84077..54d108fb4b1 100644
--- a/odoo/service/security.py
+++ b/odoo/service/security.py
@@ -12,15 +12,13 @@ def check(db, uid, passwd):
res_users = odoo.registry(db)['res.users']
return res_users.check(db, uid, passwd)
-def compute_session_token(session):
- with odoo.registry(session.db).cursor() as cr:
- self = odoo.api.Environment(cr, session.uid, {})['res.users'].browse(session.uid)
- return self._compute_session_token(session.sid)
+def compute_session_token(session, env):
+ self = env['res.users'].browse(session.uid)
+ return self._compute_session_token(session.sid)
-def check_session(session):
- with odoo.registry(session.db).cursor() as cr:
- self = odoo.api.Environment(cr, session.uid, {})['res.users'].browse(session.uid)
- if odoo.tools.misc.consteq(self._compute_session_token(session.sid), session.session_token):
- return True
- self._invalidate_session_cache()
- return False
+def check_session(session, env):
+ self = env['res.users'].browse(session.uid)
+ if odoo.tools.misc.consteq(self._compute_session_token(session.sid), session.session_token):
+ return True
+ self._invalidate_session_cache()
+ return False
diff --git a/odoo/service/server.py b/odoo/service/server.py
index d246a3d80f1..8899760ce91 100644
--- a/odoo/service/server.py
+++ b/odoo/service/server.py
@@ -364,7 +364,10 @@ class GeventServer(CommonServer):
def start(self):
import gevent
- from gevent.wsgi import WSGIServer
+ try:
+ from gevent.pywsgi import WSGIServer
+ except ImportError:
+ from gevent.wsgi import WSGIServer
if os.name == 'posix':
@@ -829,7 +832,6 @@ class WorkerCron(Worker):
from odoo.addons import base
base.models.ir_cron.ir_cron._acquire_job(db_name)
- odoo.modules.registry.Registry.delete(db_name)
# dont keep cursors in multi database mode
if len(db_names) > 1:
diff --git a/odoo/tests/common.py b/odoo/tests/common.py
index e2fe271c5a1..9f176e332ea 100644
--- a/odoo/tests/common.py
+++ b/odoo/tests/common.py
@@ -367,7 +367,7 @@ class HttpCase(TransactionCase):
session.db = db
session.uid = uid
session.login = user
- session.session_token = uid and security.compute_session_token(session)
+ session.session_token = uid and security.compute_session_token(session, env)
session.context = env['res.users'].context_get() or {}
session.context['uid'] = uid
session._fix_lang(session.context)
diff --git a/odoo/tools/misc.py b/odoo/tools/misc.py
index 09ad85d278b..725971e0143 100644
--- a/odoo/tools/misc.py
+++ b/odoo/tools/misc.py
@@ -1177,13 +1177,15 @@ def format_date(env, value, lang_code=False, date_format=False):
'''
if not value:
return ''
- if isinstance(value, datetime.datetime):
- value = value.date()
- elif isinstance(value, pycompat.string_types):
+ if isinstance(value, pycompat.string_types):
if len(value) < DATE_LENGTH:
return ''
- value = value[:DATE_LENGTH]
- value = datetime.datetime.strptime(value, DEFAULT_SERVER_DATE_FORMAT).date()
+ if len(value) > DATE_LENGTH:
+ # a datetime, convert to correct timezone
+ value = odoo.fields.Datetime.from_string(value)
+ value = odoo.fields.Datetime.context_timestamp(env['res.lang'], value)
+ else:
+ value = odoo.fields.Datetime.from_string(value)
lang = env['res.lang']._lang_get(lang_code or env.context.get('lang') or 'en_US')
locale = babel.Locale.parse(lang.code)
diff --git a/setup.py b/setup.py
index a85c9e3fcdb..86920fccbc9 100644
--- a/setup.py
+++ b/setup.py
@@ -70,6 +70,7 @@ def py2exe_options():
'dist_dir': 'dist',
'packages': [
'asynchat', 'asyncore',
+ 'BeautifulSoup',
'commands',
'dateutil',
'decimal',