diff --git a/addons/account/account_invoice.py b/addons/account/account_invoice.py index 9e8bcd330c2..215a9eccec0 100644 --- a/addons/account/account_invoice.py +++ b/addons/account/account_invoice.py @@ -1326,9 +1326,9 @@ class account_invoice_line(models.Model): raise UserError(_("You must first select a partner!")) if not product: if type in ('in_invoice', 'in_refund'): - return {'value': {}, 'domain': {'product_uom': []}} + return {'value': {}, 'domain': {'uos_id': []}} else: - return {'value': {'price_unit': 0.0}, 'domain': {'product_uom': []}} + return {'value': {'price_unit': 0.0}, 'domain': {'uos_id': []}} values = {} diff --git a/addons/account/views/report_vat.xml b/addons/account/views/report_vat.xml index 1f9a240099f..d29c3038b33 100644 --- a/addons/account/views/report_vat.xml +++ b/addons/account/views/report_vat.xml @@ -39,7 +39,7 @@ - + diff --git a/addons/auth_signup/controllers/main.py b/addons/auth_signup/controllers/main.py index 09d5b324370..849293ce1e9 100644 --- a/addons/auth_signup/controllers/main.py +++ b/addons/auth_signup/controllers/main.py @@ -114,6 +114,7 @@ class AuthSignupHome(openerp.addons.web.controllers.main.Home): values = dict((key, qcontext.get(key)) for key in ('login', 'name', 'password')) assert any([k for k in values.values()]), "The form was not properly filled in." assert values.get('password') == qcontext.get('confirm_password'), "Passwords do not match; please retype them." + values['lang'] = request.lang self._signup_with_values(qcontext.get('token'), values) request.cr.commit() diff --git a/addons/calendar/calendar.py b/addons/calendar/calendar.py index 4bcd2e58905..e8b56ef7f0c 100644 --- a/addons/calendar/calendar.py +++ b/addons/calendar/calendar.py @@ -657,18 +657,18 @@ class ir_model(osv.Model): original_exp_report = openerp.service.report.exp_report -def exp_report(db, uid, object, ids, data=None, context=None): +def exp_report(db, uid, object, ids, datas=None, context=None): """ Export Report """ if object == 'printscreen.list': - original_exp_report(db, uid, object, ids, data, context) + original_exp_report(db, uid, object, ids, datas, context) new_ids = [] for id in ids: new_ids.append(calendar_id2real_id(id)) - if data.get('id', False): - data['id'] = calendar_id2real_id(data['id']) - return original_exp_report(db, uid, object, new_ids, data, context) + if datas.get('id', False): + datas['id'] = calendar_id2real_id(datas['id']) + return original_exp_report(db, uid, object, new_ids, datas, context) openerp.service.report.exp_report = exp_report diff --git a/addons/l10n_be/l10n_be_sequence.xml b/addons/l10n_be/l10n_be_sequence.xml index f6a9bcec651..8ce7eef4239 100644 --- a/addons/l10n_be/l10n_be_sequence.xml +++ b/addons/l10n_be/l10n_be_sequence.xml @@ -8,6 +8,7 @@ Declarantnum declarantnum 5 + diff --git a/addons/mail/mail_thread.py b/addons/mail/mail_thread.py index 2a7529759ea..48cf100e578 100644 --- a/addons/mail/mail_thread.py +++ b/addons/mail/mail_thread.py @@ -388,13 +388,6 @@ class mail_thread(osv.AbstractModel): name = ir_model_pool.read(cr, uid, ids, ['name'], context=context)[0]['name'] self.message_post(cr, uid, thread_id, body=_('%s created') % name, context=context) - # auto_subscribe: take values and defaults into account - create_values = dict(values) - for key, val in context.iteritems(): - if key.startswith('default_') and key[8:] not in create_values: - create_values[key[8:]] = val - self.message_auto_subscribe(cr, uid, [thread_id], create_values.keys(), context=context, values=create_values) - # track values track_ctx = dict(context) if 'lang' not in track_ctx: @@ -404,6 +397,14 @@ class mail_thread(osv.AbstractModel): if tracked_fields: initial_values = {thread_id: dict.fromkeys(tracked_fields, False)} self.message_track(cr, uid, [thread_id], tracked_fields, initial_values, context=track_ctx) + + # auto_subscribe: take values and defaults into account + create_values = dict(values) + for key, val in context.iteritems(): + if key.startswith('default_') and key[8:] not in create_values: + create_values[key[8:]] = val + self.message_auto_subscribe(cr, uid, [thread_id], create_values.keys(), context=context, values=create_values) + return thread_id def write(self, cr, uid, ids, values, context=None): @@ -428,14 +429,16 @@ class mail_thread(osv.AbstractModel): initial_values = dict((record.id, dict((key, getattr(record, key)) for key in tracked_fields)) for record in records) - # Perform write, update followers + # Perform write result = super(mail_thread, self).write(cr, uid, ids, values, context=context) - self.message_auto_subscribe(cr, uid, ids, values.keys(), context=context, values=values) # Perform the tracking if tracked_fields: self.message_track(cr, uid, ids, tracked_fields, initial_values, context=track_ctx) + # update followers + self.message_auto_subscribe(cr, uid, ids, values.keys(), context=context, values=values) + return result def unlink(self, cr, uid, ids, context=None): diff --git a/addons/membership/membership_view.xml b/addons/membership/membership_view.xml index 0267ae88cb3..0a1949fa12c 100644 --- a/addons/membership/membership_view.xml +++ b/addons/membership/membership_view.xml @@ -157,7 +157,8 @@ 50 - + diff --git a/addons/mrp/mrp.py b/addons/mrp/mrp.py index 851f7368497..8145f0f1542 100644 --- a/addons/mrp/mrp.py +++ b/addons/mrp/mrp.py @@ -975,7 +975,7 @@ class mrp_production(osv.osv): location_id=produce_product.location_id.id, restrict_lot_id=lot_id, context=context) stock_mov_obj.write(cr, uid, new_moves, {'production_id': production_id}, context=context) remaining_qty = subproduct_factor * production_qty_uom - qty - if not float_is_zero(remaining_qty, precision_rounding=precision): + if not float_is_zero(remaining_qty, precision_digits=precision): # In case you need to make more than planned #consumed more in wizard than previously planned extra_move_id = stock_mov_obj.copy(cr, uid, produce_product.id, default={'product_uom_qty': remaining_qty, @@ -1006,7 +1006,7 @@ class mrp_production(osv.osv): stock_mov_obj.action_consume(cr, uid, [raw_material_line.id], consumed_qty, raw_material_line.location_id.id, restrict_lot_id=consume['lot_id'], consumed_for=main_production_move, context=context) remaining_qty -= consumed_qty - if not float_is_zero(remaining_qty, precision_rounding=precision): + if not float_is_zero(remaining_qty, precision_digits=precision): #consumed more in wizard than previously planned product = self.pool.get('product.product').browse(cr, uid, consume['product_id'], context=context) extra_move_id = self._make_consume_line_from_data(cr, uid, production, product, product.uom_id.id, remaining_qty, False, 0, context=context) diff --git a/addons/point_of_sale/point_of_sale.py b/addons/point_of_sale/point_of_sale.py index a84b12a70f3..09ca3903d96 100644 --- a/addons/point_of_sale/point_of_sale.py +++ b/addons/point_of_sale/point_of_sale.py @@ -576,6 +576,16 @@ class pos_order(osv.osv): _description = "Point of Sale" _order = "id desc" + def _amount_line_tax(self, cr, uid, line, context=None): + account_tax_obj = self.pool['account.tax'] + taxes_ids = [tax for tax in line.product_id.taxes_id if tax.company_id.id == line.order_id.company_id.id] + price = line.price_unit * (1 - (line.discount or 0.0) / 100.0) + taxes = account_tax_obj.compute_all(cr, uid, taxes_ids, price, line.qty, product=line.product_id, partner=line.order_id.partner_id or False)['taxes'] + val = 0.0 + for c in taxes: + val += c.get('amount', 0.0) + return val + def _order_fields(self, cr, uid, ui_order, context=None): process_line = partial(self.pool['pos.order.line']._order_line_fields, cr, uid, context=context) return { @@ -695,10 +705,10 @@ class pos_order(osv.osv): res[order.id]['amount_paid'] += payment.amount res[order.id]['amount_return'] += (payment.amount < 0 and payment.amount or 0) for line in order.lines: - val1 += line.price_subtotal_incl + val1 += self._amount_line_tax(cr, uid, line, context=context) val2 += line.price_subtotal - res[order.id]['amount_tax'] = cur_obj.round(cr, uid, cur, val1-val2) - res[order.id]['amount_total'] = cur_obj.round(cr, uid, cur, val1) + res[order.id]['amount_tax'] = cur_obj.round(cr, uid, cur, val1) + res[order.id]['amount_total'] = cur_obj.round(cr, uid, cur, val1+val2) return res _columns = { @@ -1321,8 +1331,8 @@ class pos_order_line(osv.osv): taxes = account_tax_obj.compute_all(cr, uid, taxes_ids, price, line.qty, product=line.product_id, partner=line.order_id.partner_id or False) cur = line.order_id.pricelist_id.currency_id - res[line.id]['price_subtotal'] = cur_obj.round(cr, uid, cur, taxes['total']) - res[line.id]['price_subtotal_incl'] = cur_obj.round(cr, uid, cur, taxes['total_included']) + res[line.id]['price_subtotal'] = taxes['total'] + res[line.id]['price_subtotal_incl'] = taxes['total_included'] return res def onchange_product_id(self, cr, uid, ids, pricelist, product_id, qty=0, partner_id=False, context=None): diff --git a/addons/point_of_sale/point_of_sale_demo.xml b/addons/point_of_sale/point_of_sale_demo.xml index d176c9ff060..32a02f48357 100644 --- a/addons/point_of_sale/point_of_sale_demo.xml +++ b/addons/point_of_sale/point_of_sale_demo.xml @@ -65,6 +65,10 @@ Food + + Partner Services + + Fresh Fruits @@ -1085,6 +1089,114 @@ + + + True + 850.00 + Odoo Start Workshop + service + + + + + + True + 999.99 + Odoo Consulting + service + + + + + + True + 999.99 + Eezee-It + service + + + + + + True + 999.99 + Ekomurz.nl + service + + + + + + True + 999.99 + Acsone.eu + + + + + + True + 999.99 + Vauxoo.com + service + + + + + + True + 999.99 + Datalp.com + service + + + + + + True + 999.99 + camptocamp.com + service + + + + + + True + 999.99 + EGGS-solutions.fr + service + + + + + + True + 3500.00 + Odoo primary scoping & analysis package (£900, £450, £30) + service + + + + + + True + 900.00 + 3rd party system analysis + service + + + + + + True + 30.00 + Odoo enterprise agreement + service + + + + diff --git a/addons/point_of_sale/static/img/partners/acsone.png b/addons/point_of_sale/static/img/partners/acsone.png new file mode 100644 index 00000000000..f6ec989338e Binary files /dev/null and b/addons/point_of_sale/static/img/partners/acsone.png differ diff --git a/addons/point_of_sale/static/img/partners/bhc.jpg b/addons/point_of_sale/static/img/partners/bhc.jpg new file mode 100644 index 00000000000..30005451d2a Binary files /dev/null and b/addons/point_of_sale/static/img/partners/bhc.jpg differ diff --git a/addons/point_of_sale/static/img/partners/camptocamp.png b/addons/point_of_sale/static/img/partners/camptocamp.png new file mode 100644 index 00000000000..0cb138e1ceb Binary files /dev/null and b/addons/point_of_sale/static/img/partners/camptocamp.png differ diff --git a/addons/point_of_sale/static/img/partners/datalp.jpg b/addons/point_of_sale/static/img/partners/datalp.jpg new file mode 100644 index 00000000000..9ef1f913c9a Binary files /dev/null and b/addons/point_of_sale/static/img/partners/datalp.jpg differ diff --git a/addons/point_of_sale/static/img/partners/eezee-it.png b/addons/point_of_sale/static/img/partners/eezee-it.png new file mode 100644 index 00000000000..2e975e5a9b6 Binary files /dev/null and b/addons/point_of_sale/static/img/partners/eezee-it.png differ diff --git a/addons/point_of_sale/static/img/partners/eggs-solutions.jpg b/addons/point_of_sale/static/img/partners/eggs-solutions.jpg new file mode 100644 index 00000000000..b15656b0578 Binary files /dev/null and b/addons/point_of_sale/static/img/partners/eggs-solutions.jpg differ diff --git a/addons/point_of_sale/static/img/partners/ekomurz.gif b/addons/point_of_sale/static/img/partners/ekomurz.gif new file mode 100644 index 00000000000..73905684838 Binary files /dev/null and b/addons/point_of_sale/static/img/partners/ekomurz.gif differ diff --git a/addons/point_of_sale/static/img/partners/openbig.jpg b/addons/point_of_sale/static/img/partners/openbig.jpg new file mode 100644 index 00000000000..88be89bfbbd Binary files /dev/null and b/addons/point_of_sale/static/img/partners/openbig.jpg differ diff --git a/addons/point_of_sale/static/img/partners/opusvl.png b/addons/point_of_sale/static/img/partners/opusvl.png new file mode 100644 index 00000000000..7d7ab158331 Binary files /dev/null and b/addons/point_of_sale/static/img/partners/opusvl.png differ diff --git a/addons/point_of_sale/static/img/partners/services.jpg b/addons/point_of_sale/static/img/partners/services.jpg new file mode 100644 index 00000000000..915f21fc0c4 Binary files /dev/null and b/addons/point_of_sale/static/img/partners/services.jpg differ diff --git a/addons/point_of_sale/static/img/partners/vauxoo.png b/addons/point_of_sale/static/img/partners/vauxoo.png new file mode 100644 index 00000000000..be52bd1f444 Binary files /dev/null and b/addons/point_of_sale/static/img/partners/vauxoo.png differ diff --git a/addons/product/product.py b/addons/product/product.py index d8af26f83a3..6e28ab26c0b 100644 --- a/addons/product/product.py +++ b/addons/product/product.py @@ -25,8 +25,7 @@ import time from _common import ceiling -from openerp import SUPERUSER_ID -from openerp import tools +from openerp import api, tools, SUPERUSER_ID from openerp.osv import osv, fields, expression from openerp.tools.translate import _ from openerp.tools import DEFAULT_SERVER_DATETIME_FORMAT @@ -225,19 +224,17 @@ class product_ul(osv.osv): #---------------------------------------------------------- class product_category(osv.osv): - def name_get(self, cr, uid, ids, context=None): - if isinstance(ids, (list, tuple)) and not len(ids): - return [] - if isinstance(ids, (long, int)): - ids = [ids] - reads = self.read(cr, uid, ids, ['name','parent_id'], context=context) - res = [] - for record in reads: - name = record['name'] - if record['parent_id']: - name = record['parent_id'][1]+' / '+name - res.append((record['id'], name)) - return res + @api.multi + def name_get(self): + def get_names(cat): + """ Return the list [cat.name, cat.parent_id.name, ...] """ + res = [] + while cat: + res.append(cat.name) + cat = cat.parent_id + return res + + return [(cat.id, " / ".join(reversed(get_names(cat)))) for cat in self] def name_search(self, cr, uid, name, args=None, operator='ilike', context=None, limit=100): if not args: diff --git a/addons/purchase/purchase.py b/addons/purchase/purchase.py index 465b54a297f..aa6816c6b13 100644 --- a/addons/purchase/purchase.py +++ b/addons/purchase/purchase.py @@ -1259,8 +1259,12 @@ class procurement_order(osv.osv): return super(procurement_order, self).run(cr, uid, list(set_others), context=context) def _check(self, cr, uid, procurement, context=None): - if procurement.purchase_line_id and procurement.purchase_line_id.order_id.shipped: # TOCHECK: does it work for several deliveries? - return True + if procurement.purchase_line_id: + if procurement.purchase_line_id.order_id.shipped: + return True + elif procurement.move_ids: + moves = self.pool.get('stock.move').browse(cr, uid, [x.id for x in procurement.move_ids], context=context) + return all(move.state == 'done' for move in moves) return super(procurement_order, self)._check(cr, uid, procurement, context=context) def _check_supplier_info(self, cr, uid, ids, context=None): diff --git a/addons/sale/sale.py b/addons/sale/sale.py index b7ca0e79a6b..1515e2cd02b 100644 --- a/addons/sale/sale.py +++ b/addons/sale/sale.py @@ -295,12 +295,11 @@ class sale_order(osv.osv): def onchange_delivery_id(self, cr, uid, ids, company_id, partner_id, delivery_id, fiscal_position, context=None): r = {'value': {}} - if not fiscal_position: - if not company_id: - company_id = self._get_default_company(cr, uid, context=context) - fiscal_position = self.pool['account.fiscal.position'].get_fiscal_position(cr, uid, company_id, partner_id, delivery_id, context=context) - if fiscal_position: - r['value']['fiscal_position'] = fiscal_position + if not company_id: + company_id = self._get_default_company(cr, uid, context=context) + fiscal_position = self.pool['account.fiscal.position'].get_fiscal_position(cr, uid, company_id, partner_id, delivery_id, context=context) + if fiscal_position: + r['value']['fiscal_position'] = fiscal_position return r def onchange_partner_id(self, cr, uid, ids, part, context=None): diff --git a/addons/stock/stock.py b/addons/stock/stock.py index a4a03af3822..f5e10c45d0d 100644 --- a/addons/stock/stock.py +++ b/addons/stock/stock.py @@ -1952,7 +1952,7 @@ class stock_move(osv.osv): self.write(cr, uid, [move.id], {'state': 'confirmed'}, context=context) def _prepare_procurement_from_move(self, cr, uid, move, context=None): - origin = (move.group_id and (move.group_id.name + ":") or "") + (move.rule_id and move.rule_id.name or move.origin or "/") + origin = (move.group_id and (move.group_id.name + ":") or "") + (move.rule_id and move.rule_id.name or move.origin or move.picking_id.name or "/") group_id = move.group_id and move.group_id.id or False if move.rule_id: if move.rule_id.group_propagation_option == 'fixed' and move.rule_id.group_id: @@ -2155,6 +2155,19 @@ class stock_move(osv.osv): result['location_dest_id'] = loc_dest_id return {'value': result} + def _prepare_picking_assign(self, cr, uid, move, context=None): + """ Prepares a new picking for this move as it could not be assigned to + another picking. This method is designed to be inherited. + """ + values = { + 'origin': move.origin, + 'company_id': move.company_id and move.company_id.id or False, + 'move_type': move.group_id and move.group_id.move_type or 'direct', + 'partner_id': move.partner_id.id or False, + 'picking_type_id': move.picking_type_id and move.picking_type_id.id or False, + } + return values + @api.cr_uid_ids_context def _picking_assign(self, cr, uid, move_ids, procurement_group, location_from, location_to, context=None): """Assign a picking on the given move_ids, which is a list of move supposed to share the same procurement_group, location_from and location_to @@ -2170,13 +2183,7 @@ class stock_move(osv.osv): pick = picks[0] else: move = self.browse(cr, uid, move_ids, context=context)[0] - values = { - 'origin': move.origin, - 'company_id': move.company_id and move.company_id.id or False, - 'move_type': move.group_id and move.group_id.move_type or 'direct', - 'partner_id': move.partner_id.id or False, - 'picking_type_id': move.picking_type_id and move.picking_type_id.id or False, - } + values = self._prepare_picking_assign(cr, uid, move, context=context) pick = pick_obj.create(cr, uid, values, context=context) return self.write(cr, uid, move_ids, {'picking_id': pick}, context=context) diff --git a/addons/stock_account/wizard/stock_valuation_history.py b/addons/stock_account/wizard/stock_valuation_history.py index a6223b443e4..e1ae51c79eb 100644 --- a/addons/stock_account/wizard/stock_valuation_history.py +++ b/addons/stock_account/wizard/stock_valuation_history.py @@ -46,21 +46,39 @@ class stock_history(osv.osv): if context is None: context = {} date = context.get('history_date') - prod_dict = {} if 'inventory_value' in fields: + group_lines = {} + for line in res: + domain = line.get('__domain', []) + group_lines.setdefault(str(domain), self.search(cr, uid, domain, context=context)) + line_ids = set() + for ids in group_lines.values(): + for product_id in ids: + line_ids.add(product_id) + line_ids = list(line_ids) + cr.execute('SELECT id, product_id, price_unit_on_quant, company_id, quantity FROM stock_history WHERE id in %s', (tuple(line_ids),)) + lines_rec = cr.dictfetchall() + lines_dict = dict((line['id'], line) for line in lines_rec) + product_ids = list(set(line_rec['product_id'] for line_rec in lines_rec)) + products_rec = self.pool['product.product'].read(cr, uid, product_ids, ['cost_method', 'product_tmpl_id'], context=context) + products_dict = dict((product['id'], product) for product in products_rec) + cost_method_product_tmpl_ids = list(set(product['product_tmpl_id'][0] for product in products_rec if product['cost_method'] != 'real')) + cr.execute('SELECT DISTINCT ON (product_template_id, company_id) product_template_id, company_id, cost FROM product_price_history WHERE product_template_id in %s AND datetime <= %s ORDER BY product_template_id, company_id, datetime DESC', (tuple(cost_method_product_tmpl_ids), date)) + histories = cr.dictfetchall() + histories_dict = {} + for history in histories: + histories_dict[(history['product_template_id'], history['company_id'])] = history['cost'] for line in res: - lines = self.search(cr, uid, line.get('__domain', []), context=context) inv_value = 0.0 - product_tmpl_obj = self.pool.get("product.template") - lines_rec = self.browse(cr, uid, lines, context=context) - for line_rec in lines_rec: - if line_rec.product_id.cost_method == 'real': - price = line_rec.price_unit_on_quant + lines = group_lines.get(str(line.get('__domain', []))) + for line_id in lines: + line_rec = lines_dict[line_id] + product = products_dict[line_rec['product_id']] + if product['cost_method'] == 'real': + price = line_rec['price_unit_on_quant'] else: - if not line_rec.product_id.id in prod_dict: - prod_dict[line_rec.product_id.id] = product_tmpl_obj.get_history_price(cr, uid, line_rec.product_id.product_tmpl_id.id, line_rec.company_id.id, date=date, context=context) - price = prod_dict[line_rec.product_id.id] - inv_value += price * line_rec.quantity + price = histories_dict.get((product['product_tmpl_id'][0], line_rec['company_id']), 0.0) + inv_value += price * line_rec['quantity'] line['inventory_value'] = inv_value return res diff --git a/addons/web/controllers/main.py b/addons/web/controllers/main.py index d72404e4314..894faec7e51 100644 --- a/addons/web/controllers/main.py +++ b/addons/web/controllers/main.py @@ -312,12 +312,12 @@ def set_cookie_and_redirect(redirect_url): def login_redirect(): url = '/web/login?' - if request.debug: - url += 'debug&' + # built the redirect url, keeping all the query parameters of the url + redirect_url = '%s?%s' % (request.httprequest.base_url, werkzeug.urls.url_encode(request.params)) return """ - """ % (url,) + """ % (url, redirect_url) def load_actions_from_ir_values(key, key2, models, meta): Values = request.session.model('ir.values') diff --git a/addons/web/static/src/css/base.css b/addons/web/static/src/css/base.css index d9c17ea6465..14edf1cf14d 100644 --- a/addons/web/static/src/css/base.css +++ b/addons/web/static/src/css/base.css @@ -577,6 +577,7 @@ border-radius: 3px; background: #f0f0fa; color: #4C4C4C; + word-break: break-word; } .openerp .oe_tag_dark { background: #7C7BAD; @@ -620,7 +621,8 @@ width: 100% !important; } .openerp .oe_tags .text-core { - min-height: 22px; + height: initial !important; + word-break: break-word; } .openerp .oe_tags .text-core .text-wrap .text-dropdown .text-list .text-suggestion em { font-style: italic; diff --git a/addons/web/static/src/css/base.sass b/addons/web/static/src/css/base.sass index ac4742f2598..30ff7e83c0e 100644 --- a/addons/web/static/src/css/base.sass +++ b/addons/web/static/src/css/base.sass @@ -514,6 +514,7 @@ $sheet-padding: 16px @include radius(3px) background: $tag-bg-light color: #4C4C4C + word-break: break-word .oe_tag_dark background: $tag-bg-dark color: #eee @@ -547,7 +548,8 @@ $sheet-padding: 16px textarea width: 100% !important .text-core - min-height: 22px + height: initial !important + word-break: break-word .text-wrap .text-dropdown .text-list .text-suggestion em font-style: italic text-decoration: none diff --git a/addons/website_forum/controllers/main.py b/addons/website_forum/controllers/main.py index f1ef56be907..2438767e075 100644 --- a/addons/website_forum/controllers/main.py +++ b/addons/website_forum/controllers/main.py @@ -308,7 +308,7 @@ class WebsiteForum(http.Controller): }) return werkzeug.utils.redirect("/forum/%s/question/%s" % (slug(forum), post_parent and slug(post_parent) or new_question.id)) - @http.route('/forum//post//comment', type='http', auth="public", methods=['POST'], website=True) + @http.route('/forum//post//comment', type='http', auth="public", website=True) def post_comment(self, forum, post, **kwargs): if not request.session.uid: return login_redirect() diff --git a/addons/website_sale/controllers/main.py b/addons/website_sale/controllers/main.py index e5232cedff2..54061771cf6 100644 --- a/addons/website_sale/controllers/main.py +++ b/addons/website_sale/controllers/main.py @@ -280,7 +280,7 @@ class website_sale(http.Controller): } return request.website.render("website_sale.product", values) - @http.route(['/shop/product/comment/'], type='http', auth="public", methods=['POST'], website=True) + @http.route(['/shop/product/comment/'], type='http', auth="public", website=True) def product_comment(self, product_template_id, **post): if not request.session.uid: return login_redirect() @@ -292,7 +292,7 @@ class website_sale(http.Controller): type='comment', subtype='mt_comment', context=dict(context, mail_create_nosubscribe=True)) - return werkzeug.utils.redirect(request.httprequest.referrer + "#comments") + return werkzeug.utils.redirect('/shop/product/%s#comments' % product_template_id) @http.route(['/shop/pricelist'], type='http', auth="public", website=True) def pricelist(self, promo, **post): @@ -716,6 +716,7 @@ class website_sale(http.Controller): if tx.state == 'draft': # button cliked but no more info -> rewrite on tx or create a new one ? tx.write({ 'acquirer_id': acquirer_id, + 'amount': order.amount_total, }) tx_id = tx.id else: diff --git a/addons/website_sale/models/sale_order.py b/addons/website_sale/models/sale_order.py index 0b2b4b9e16d..608e50a787b 100644 --- a/addons/website_sale/models/sale_order.py +++ b/addons/website_sale/models/sale_order.py @@ -197,7 +197,8 @@ class website(orm.Model): values.update(sale_order.onchange_pricelist_id(pricelist_id, None)['value']) sale_order.write(values) for line in sale_order.order_line: - sale_order._cart_update(product_id=line.product_id.id, line_id=line.id, add_qty=0) + if line.exists(): + sale_order._cart_update(product_id=line.product_id.id, line_id=line.id, add_qty=0) # update browse record if (code and code != sale_order.pricelist_id.code) or sale_order.partner_id.id != partner.id: diff --git a/addons/website_sale_delivery/models/sale_order.py b/addons/website_sale_delivery/models/sale_order.py index d9821d1391c..7c8ea80edc2 100644 --- a/addons/website_sale_delivery/models/sale_order.py +++ b/addons/website_sale_delivery/models/sale_order.py @@ -124,3 +124,15 @@ class SaleOrder(orm.Model): values['deliveries'] = DeliveryCarrier.browse(cr, SUPERUSER_ID, delivery_ids, context=delivery_ctx) return values + + def _cart_update(self, cr, uid, ids, product_id=None, line_id=None, add_qty=0, set_qty=0, context=None, **kwargs): + """ Override to update carrier quotation if quantity changed """ + + values = super(SaleOrder, self)._cart_update( + cr, uid, ids, product_id, line_id, add_qty, set_qty, context, **kwargs) + + if add_qty or set_qty is not None: + for sale_order in self.browse(cr, uid, ids, context=context): + self._check_carrier_quotation(cr, uid, sale_order, context=context) + + return values diff --git a/doc/cla/individual/antespi.md b/doc/cla/individual/antespi.md new file mode 100644 index 00000000000..9e6d55fe2ff --- /dev/null +++ b/doc/cla/individual/antespi.md @@ -0,0 +1,11 @@ +Spain, 2015-04-20 + +I hereby agree to the terms of the Odoo Individual Contributor License +Agreement v1.0. + +I declare that I am authorized and able to make this agreement and sign this +declaration. + +Signed, + +Antonio Espinosa antespi@gmail.com https://github.com/antespi \ No newline at end of file diff --git a/doc/cla/individual/bartekwojcicki.md b/doc/cla/individual/bartekwojcicki.md new file mode 100644 index 00000000000..ad34d046ad9 --- /dev/null +++ b/doc/cla/individual/bartekwojcicki.md @@ -0,0 +1,11 @@ +Poland, 2015-06-18 + +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, + +Bartłomiej Wójcicki bartwojcicki@gmail.com https://github.com/bartekwojcicki diff --git a/doc/cla/individual/palankai.md b/doc/cla/individual/palankai.md new file mode 100644 index 00000000000..839044a6f28 --- /dev/null +++ b/doc/cla/individual/palankai.md @@ -0,0 +1,11 @@ +United Kingdom, 15.06.2015 + +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, + +Csaba Palankai csaba.palankai@gmail.com https://github.com/palankai diff --git a/doc/cla/individual/wearp.md b/doc/cla/individual/wearp.md new file mode 100644 index 00000000000..9689b2550d4 --- /dev/null +++ b/doc/cla/individual/wearp.md @@ -0,0 +1,11 @@ +United Kingdom, 2015-06-18 + +I hereby agree to the terms of the Individual Contributor License +Agreement v1.0. + +I declare that I am authorized and able to make this agreement and +sign this declaration. + +Signed, + +Will Earp will.earp@icloud.com https://github.com/wearp diff --git a/doc/howtos/backend.rst b/doc/howtos/backend.rst index 00c5b103462..56acc81e9c3 100644 --- a/doc/howtos/backend.rst +++ b/doc/howtos/backend.rst @@ -621,7 +621,7 @@ instead of a single view its ``arch`` field is composed of any number of id.category.list2 - ir.ui.view + idea.category/field>