diff options
20 files changed, 101 insertions, 22 deletions
diff --git a/addons/account/models/partner.py b/addons/account/models/partner.py index f34810b6bc6..ba6e8502efd 100644 --- a/addons/account/models/partner.py +++ b/addons/account/models/partner.py @@ -298,10 +298,16 @@ class ResPartner(models.Model): partner.total_invoiced = sum(price['total'] for price in price_totals if price['partner_id'] in child_ids) @api.multi - def _journal_item_count(self): + def _compute_journal_item_count(self): + AccountMoveLine = self.env['account.move.line'] for partner in self: - partner.journal_item_count = self.env['account.move.line'].search_count([('partner_id', '=', partner.id)]) - partner.contracts_count = self.env['account.analytic.account'].search_count([('partner_id', '=', partner.id)]) + partner.journal_item_count = AccountMoveLine.search_count([('partner_id', '=', partner.id)]) + + @api.multi + def _compute_contracts_count(self): + AccountAnalyticAccount = self.env['account.analytic.account'] + for partner in self: + partner.contracts_count = AccountAnalyticAccount.search_count([('partner_id', '=', partner.id)]) def get_followup_lines_domain(self, date, overdue_only=False, only_unblocked=False): domain = [('reconciled', '=', False), ('account_id.deprecated', '=', False), ('account_id.internal_type', '=', 'receivable'), '|', ('debit', '!=', 0), ('credit', '!=', 0), ('company_id', '=', self.env.user.company_id.id)] @@ -383,9 +389,8 @@ class ResPartner(models.Model): groups='account.group_account_invoice') currency_id = fields.Many2one('res.currency', compute='_get_company_currency', readonly=True, string="Currency", help='Utility field to express amount currency') - - contracts_count = fields.Integer(compute='_journal_item_count', string="Contracts", type='integer') - journal_item_count = fields.Integer(compute='_journal_item_count', string="Journal Items", type="integer") + contracts_count = fields.Integer(compute='_compute_contracts_count', string="Contracts", type='integer') + journal_item_count = fields.Integer(compute='_compute_journal_item_count', string="Journal Items", type="integer") issued_total = fields.Monetary(compute='_compute_issued_total', string="Journal Items") property_account_payable_id = fields.Many2one('account.account', company_dependent=True, string="Account Payable", oldname="property_account_payable", diff --git a/addons/mail/models/res_users.py b/addons/mail/models/res_users.py index 19630150a75..6aa3e307876 100644 --- a/addons/mail/models/res_users.py +++ b/addons/mail/models/res_users.py @@ -2,6 +2,7 @@ # Part of Odoo. See LICENSE file for full copyright and licensing details. from odoo import _, api, exceptions, fields, models +from odoo.addons.base.res.res_users import is_selection_groups class Users(models.Model): @@ -54,11 +55,14 @@ class Users(models.Model): @api.multi def write(self, vals): write_res = super(Users, self).write(vals) + sel_groups = [vals[k] for k in vals if is_selection_groups(k) and vals[k]] if vals.get('groups_id'): # form: {'group_ids': [(3, 10), (3, 3), (4, 10), (4, 3)]} or {'group_ids': [(6, 0, [ids]} user_group_ids = [command[1] for command in vals['groups_id'] if command[0] == 4] user_group_ids += [id for command in vals['groups_id'] if command[0] == 6 for id in command[2]] self.env['mail.channel'].search([('group_ids', 'in', user_group_ids)])._subscribe_users() + elif sel_groups: + self.env['mail.channel'].search([('group_ids', 'in', sel_groups)])._subscribe_users() return write_res def _create_welcome_message(self): diff --git a/addons/mail/security/ir.model.access.csv b/addons/mail/security/ir.model.access.csv index 95439743574..77eb51c7859 100644 --- a/addons/mail/security/ir.model.access.csv +++ b/addons/mail/security/ir.model.access.csv @@ -22,7 +22,7 @@ access_mail_alias_all,mail.alias.all,model_mail_alias,,1,0,0,0 access_mail_alias_user,mail.alias.user,model_mail_alias,base.group_user,1,1,1,1
access_mail_alias_system,mail.alias.system,model_mail_alias,base.group_system,1,1,1,1
access_mail_message_subtype_all,mail.message.subtype.all,model_mail_message_subtype,,1,0,0,0
-access_mail_message_subtype_user,mail.message.subtype.user,model_mail_message_subtype,,1,1,1,1
+access_mail_message_subtype_user,mail.message.subtype.user,model_mail_message_subtype,base.group_user,1,1,1,1
access_mail_tracking_value_all,mail.tracking.value.all,model_mail_tracking_value,,0,0,0,0
access_mail_tracking_value_portal,mail.tracking.value.portal,model_mail_tracking_value,base.group_portal,0,0,0,0
access_mail_tracking_value_user,mail.tracking.value.user,model_mail_tracking_value,base.group_user,0,0,0,0
diff --git a/addons/point_of_sale/static/src/js/models.js b/addons/point_of_sale/static/src/js/models.js index 19400b2fe93..c5cf1c77e5c 100644 --- a/addons/point_of_sale/static/src/js/models.js +++ b/addons/point_of_sale/static/src/js/models.js @@ -508,7 +508,7 @@ exports.PosModel = Backbone.Model.extend({ .then(function(){ load_model(index + 1); }, function(err){ loaded.reject(err); }); }catch(err){ - console.error(err.stack); + console.error(err.message, err.stack); loaded.reject(err); } },function(err){ diff --git a/addons/stock/wizard/stock_immediate_transfer.py b/addons/stock/wizard/stock_immediate_transfer.py index 365e9dbb382..2183e454023 100644 --- a/addons/stock/wizard/stock_immediate_transfer.py +++ b/addons/stock/wizard/stock_immediate_transfer.py @@ -33,4 +33,4 @@ class StockImmediateTransfer(models.TransientModel): pack.write({'qty_done': pack.product_qty}) else: pack.unlink() - self.pick_id.do_transfer() + return self.pick_id.do_transfer() diff --git a/addons/stock_account/models/stock.py b/addons/stock_account/models/stock.py index f66900de681..5bb399257c9 100644 --- a/addons/stock_account/models/stock.py +++ b/addons/stock_account/models/stock.py @@ -71,7 +71,10 @@ class StockQuant(models.Model): valuation_update = newprice - quant.cost # this is where we post accounting entries for adjustment, if needed # If neg quant period already closed (likely with manual valuation), skip update - if not quant.company_id.currency_id.is_zero(valuation_update) and move._check_lock_date(): + lock_date = max(move.company_id.period_lock_date, move.company_id.fiscalyear_lock_date) + if self.user_has_groups('account.group_account_manager'): + lock_date = move.company_id.fiscalyear_lock_date + if not quant.company_id.currency_id.is_zero(valuation_update) and lock_date and move.date[:10] > lock_date: quant.with_context(force_valuation_amount=valuation_update)._account_entry_move(move) # update the standard price of the product, only if we would have diff --git a/addons/website/controllers/main.py b/addons/website/controllers/main.py index dbf747c6832..fd68fa704dc 100644 --- a/addons/website/controllers/main.py +++ b/addons/website/controllers/main.py @@ -63,7 +63,7 @@ class Website(Home): @http.route('/', type='http', auth="public", website=True) def index(self, **kw): page = 'homepage' - main_menu = request.env.ref('website.main_menu', raise_if_not_found=False) + main_menu = request.website.menu_id or request.env.ref('website.main_menu', raise_if_not_found=False) if main_menu: first_menu = main_menu.child_id and main_menu.child_id[0] if first_menu: diff --git a/addons/website_blog/views/website_blog_templates.xml b/addons/website_blog/views/website_blog_templates.xml index f6f513668ac..bcaa3a4c2aa 100644 --- a/addons/website_blog/views/website_blog_templates.xml +++ b/addons/website_blog/views/website_blog_templates.xml @@ -102,6 +102,7 @@ <t t-set="head"> <link t-att-href="'/blog/%s/feed' % (blog.id)" type="application/atom+xml" rel="alternate" title="Atom Feed"/> </t> + <div class="oe_structure"/> <div class="container"> <t t-call="website.pager" > <t t-set="classname">pull-right</t> diff --git a/addons/website_event/controllers/main.py b/addons/website_event/controllers/main.py index fe260e997f3..d4be8fb5132 100644 --- a/addons/website_event/controllers/main.py +++ b/addons/website_event/controllers/main.py @@ -149,7 +149,7 @@ class WebsiteEventController(http.Controller): # page not found values['path'] = re.sub(r"^website_event\.", '', page) values['from_template'] = 'website_event.default_page' # .strip('website_event.') - page = 'website.page_404' + page = 'website.%s' % (request.website.is_publisher() and 'page_404' or '404') return request.render(page, values) diff --git a/addons/website_portal/views/website_portal_templates.xml b/addons/website_portal/views/website_portal_templates.xml index 012f4f59d35..68ac9cc876f 100644 --- a/addons/website_portal/views/website_portal_templates.xml +++ b/addons/website_portal/views/website_portal_templates.xml @@ -181,7 +181,8 @@ <div class="clearfix" /> <div t-attf-class="form-group #{error.get('company_name') and 'has-error' or ''} col-lg-6"> <label class="control-label label-optional" for="company_name">Company Name</label> - <input type="text" name="company_name" class="form-control" t-att-value="company_name or partner.company_name"/> + <p t-if="partner.commercial_partner_id.is_company" class="form-control" t-esc="partner.commercial_company_name"/> + <input t-else="" type="text" name="company_name" class="form-control" t-att-value="company_name or partner.company_name"/> </div> <div t-if="has_check_vat" t-attf-class="form-group #{error.get('vat') and 'has-error' or ''} col-lg-6"> <label class="control-label label-optional" for="vat">VAT Number</label> diff --git a/addons/website_sale/controllers/main.py b/addons/website_sale/controllers/main.py index 3cc5acb29ed..04a94de0e05 100644 --- a/addons/website_sale/controllers/main.py +++ b/addons/website_sale/controllers/main.py @@ -367,8 +367,8 @@ class WebsiteSale(http.Controller): def cart_update(self, product_id, add_qty=1, set_qty=0, **kw): request.website.sale_get_order(force_create=1)._cart_update( product_id=int(product_id), - add_qty=float(add_qty), - set_qty=float(set_qty), + add_qty=add_qty, + set_qty=set_qty, attributes=self._filter_attributes(**kw), ) return request.redirect("/shop/cart") @@ -382,7 +382,6 @@ class WebsiteSale(http.Controller): if order.state != 'draft': request.website.sale_reset() return {} - value = order._cart_update(product_id=product_id, line_id=line_id, add_qty=add_qty, set_qty=set_qty) if not order.cart_quantity: request.website.sale_reset() diff --git a/addons/website_sale/models/sale_order.py b/addons/website_sale/models/sale_order.py index a8d728396d2..95e1528756e 100644 --- a/addons/website_sale/models/sale_order.py +++ b/addons/website_sale/models/sale_order.py @@ -113,6 +113,17 @@ class SaleOrder(models.Model): """ Add or set product quantity, add_qty can be negative """ self.ensure_one() SaleOrderLineSudo = self.env['sale.order.line'].sudo() + + try: + if add_qty: + add_qty = float(add_qty) + except ValueError: + add_qty = 1 + try: + if set_qty: + set_qty = float(set_qty) + except ValueError: + set_qty = 0 quantity = 0 order_line = False if self.state != 'draft': diff --git a/addons/website_sale/static/src/js/website_sale.js b/addons/website_sale/static/src/js/website_sale.js index f7a8fa777bd..b2c6ca238e8 100644 --- a/addons/website_sale/static/src/js/website_sale.js +++ b/addons/website_sale/static/src/js/website_sale.js @@ -133,6 +133,9 @@ odoo.define('website_sale.website_sale', function (require) { return; } var value = parseInt($input.val() || 0, 10); + if (isNaN(value)) { + value = 1; + } var $dom = $(this).closest('tr'); //var default_price = parseFloat($dom.find('.text-danger > span.oe_currency_value').text()); var $dom_optional = $dom.nextUntil(':not(.optional_product.info)'); @@ -151,7 +154,11 @@ odoo.define('website_sale.website_sale', function (require) { 'set_qty': value }).then(function (data) { $input.data('update_change', false); - if (value !== parseInt($input.val() || 0, 10)) { + var check_value = parseInt($input.val() || 0, 10); + if (isNaN(check_value)) { + check_value = 1; + } + if (value !== check_value) { $input.trigger('change'); return; } diff --git a/addons/website_sale/static/src/js/website_sale_validate.js b/addons/website_sale/static/src/js/website_sale_validate.js index dce80543dc3..614e8901484 100644 --- a/addons/website_sale/static/src/js/website_sale_validate.js +++ b/addons/website_sale/static/src/js/website_sale_validate.js @@ -16,8 +16,13 @@ $(document).ready(function () { return ajax.jsonRpc('/shop/payment/get_status/' + order_id, 'call', { }).then(function (result) { _poll_nbr += 1; - if(result.recall && _poll_nbr <= 5){ - setTimeout(function () { payment_transaction_poll_status(); }, 1000); + if(result.recall) { + if (_poll_nbr < 20){ + setTimeout(function () { payment_transaction_poll_status(); }, Math.ceil(_poll_nbr / 3) * 1000); + } + else { + result.message = "<i class='fa fa-warning' />"; + } } $('div.oe_website_sale_tx_status').html(result.message); }); diff --git a/addons/website_sale/views/templates.xml b/addons/website_sale/views/templates.xml index 2dd70f71609..7aca313725d 100644 --- a/addons/website_sale/views/templates.xml +++ b/addons/website_sale/views/templates.xml @@ -1472,7 +1472,7 @@ <div class="container oe_website_sale"> <div class="row"> <div class="col-md-9"> - <h1 class="mb32">Order <em t-field="order.name" /> Confirmed</h1> + <h1 class="mb32">Order <em t-field="order.name" /></h1> <div class="thanks_msg"> <h2>Thank you for your order. <a class="btn btn-primary pull-right hidden-xs" href="/shop/print" target="_blank"><i class="fa fa-print"></i> Print diff --git a/addons/website_sale_options/controllers/main.py b/addons/website_sale_options/controllers/main.py index 4c9ba8e6502..1c84f9e460f 100644 --- a/addons/website_sale_options/controllers/main.py +++ b/addons/website_sale_options/controllers/main.py @@ -33,8 +33,8 @@ class WebsiteSaleOptions(WebsiteSale): if add_qty or set_qty: value = order._cart_update( product_id=int(product_id), - add_qty=int(add_qty), - set_qty=int(set_qty), + add_qty=add_qty, + set_qty=set_qty, attributes=attributes, optional_product_ids=optional_product_ids ) diff --git a/doc/cla/corporate/it-projects-llc.md b/doc/cla/corporate/it-projects-llc.md new file mode 100644 index 00000000000..038323173c3 --- /dev/null +++ b/doc/cla/corporate/it-projects-llc.md @@ -0,0 +1,20 @@ +Russia, 2017-11-25 + +IT-Projects LLC 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, + +Ivan Yelizariev https://github.com/yelizariev + +List of contributors: + +Ivan Yelizariev yelizariev@it-projects.info https://github.com/yelizariev +Ildar Nasyrov nasyrov@it-projects.info https://github.com/iledarn +Ilmir Karamov karamov@it-projects.info https://github.com/ilmir-k +Dinar Gabbasov gabbasov@it-projects.info https://github.com/GabbasovDinar +Artyom Losev losev@it-projects.info https://github.com/ArtyomLosev +Alexandr Kolushov kolushov@it-projects.info https://github.com/KolushovAlexandr diff --git a/doc/cla/individual/adekock11.md b/doc/cla/individual/adekock11.md new file mode 100644 index 00000000000..999190ef207 --- /dev/null +++ b/doc/cla/individual/adekock11.md @@ -0,0 +1,11 @@ +South Africa, 2017-11-25 + +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, + +Andre de Kock adekock11@gmail.com https://github.com/adekock11 diff --git a/doc/cla/individual/flyingL123.md b/doc/cla/individual/flyingL123.md new file mode 100644 index 00000000000..ba93055493d --- /dev/null +++ b/doc/cla/individual/flyingL123.md @@ -0,0 +1,11 @@ +USA, 2017-11-27 + +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, + +Michael Leff leff.michael@gmail.com https://github.com/flyingL123 diff --git a/odoo/addons/base/res/res_currency_data.xml b/odoo/addons/base/res/res_currency_data.xml index a39d049ffe1..8b108fa978d 100644 --- a/odoo/addons/base/res/res_currency_data.xml +++ b/odoo/addons/base/res/res_currency_data.xml @@ -266,6 +266,7 @@ <field name="name">ZAR</field> <field name="symbol">R</field> <field name="rounding">0.01</field> + <field name="position">before</field> <field name="active" eval="False"/> </record> |
