diff --git a/addons/auth_reset_password/__openerp__.py b/addons/auth_reset_password/__openerp__.py index e620d515fa1..2c5b61bf378 100644 --- a/addons/auth_reset_password/__openerp__.py +++ b/addons/auth_reset_password/__openerp__.py @@ -22,8 +22,11 @@ { 'name': 'Reset Password', 'description': """ +Reset Password +============== + Allow users to reset their password from the login page. -======================================================== +Allow administrator to click a button to send a "Reset Password" request to a user. """, 'author': 'OpenERP SA', 'version': '1.0', diff --git a/addons/crm/board_crm_view.xml b/addons/crm/board_crm_view.xml index d80183b80c9..19baa5a5709 100644 --- a/addons/crm/board_crm_view.xml +++ b/addons/crm/board_crm_view.xml @@ -43,7 +43,7 @@ form graph,tree,form - [('state','!=','cancel'),('opening_date','>',datetime.date.today().strftime("%Y-%m-%d"))] + [('state','!=','cancel'),('opening_date','>',context_today().strftime("%Y-%m-%d"))] {'search_default_Stage':1} diff --git a/addons/crm/crm_lead.py b/addons/crm/crm_lead.py index 4bc01047b73..80ac2fa16d3 100644 --- a/addons/crm/crm_lead.py +++ b/addons/crm/crm_lead.py @@ -272,6 +272,10 @@ class crm_lead(base_stage, format_address, osv.osv): 'color': 0, } + _sql_constraints = [ + ('check_probability', 'check(probability >= 0 and probability <= 100)', 'The probability of closing the deal should be between 0% and 100%!') + ] + def create(self, cr, uid, vals, context=None): obj_id = super(crm_lead, self).create(cr, uid, vals, context) section_id = self.browse(cr, uid, obj_id, context=context).section_id diff --git a/addons/delivery/delivery_view.xml b/addons/delivery/delivery_view.xml index 9b67d6b01b9..d6ec48e7601 100644 --- a/addons/delivery/delivery_view.xml +++ b/addons/delivery/delivery_view.xml @@ -264,9 +264,9 @@ stock.picking_withweight.internal.move.form.view stock.move - + - + diff --git a/addons/fleet/fleet.py b/addons/fleet/fleet.py index be0e8b34351..e74ac4839f4 100644 --- a/addons/fleet/fleet.py +++ b/addons/fleet/fleet.py @@ -625,7 +625,7 @@ class fleet_vehicle_log_contract(osv.Model): startdate = datetime.datetime.strptime(last_cost_date, tools.DEFAULT_SERVER_DATE_FORMAT).date() if found: startdate += deltas.get(contract.cost_frequency) - while (startdate < d) & (startdate < datetime.datetime.strptime(contract.expiration_date, tools.DEFAULT_SERVER_DATE_FORMAT).date()): + while (startdate <= d) & (startdate <= datetime.datetime.strptime(contract.expiration_date, tools.DEFAULT_SERVER_DATE_FORMAT).date()): data = { 'amount': contract.cost_generated, 'date': startdate.strftime(tools.DEFAULT_SERVER_DATE_FORMAT), diff --git a/addons/mrp/security/ir.model.access.csv b/addons/mrp/security/ir.model.access.csv index 6ca9cb3d705..7a94b1a660c 100644 --- a/addons/mrp/security/ir.model.access.csv +++ b/addons/mrp/security/ir.model.access.csv @@ -53,7 +53,7 @@ access_stock_move_mrp_manager,stock.move mrp_manager,stock.model_stock_move,mrp. access_mrp_production_product_line_manager,mrp.production.product.line manager,model_mrp_production_product_line,mrp.group_mrp_manager,1,0,0,0 access_account_sequence_fiscalyear_system,account.sequence.fiscalyear.system,account.model_account_sequence_fiscalyear,mrp.group_mrp_manager,1,0,0,0 access_stock_production_lot_user,stock.production.lot,stock.model_stock_production_lot,mrp.group_mrp_user,1,1,1,1 -access_stock_warehouse_orderpoint_manager,stock.warehouse.orderpoint,procurement.model_stock_warehouse_orderpoint,mrp.group_mrp_manager,1,0,0,0 +access_stock_warehouse_orderpoint_user,stock.warehouse.orderpoint,procurement.model_stock_warehouse_orderpoint,mrp.group_mrp_user,1,0,0,0 access_stock_picking_mrp_manager,stock.picking mrp_manager,stock.model_stock_picking,mrp.group_mrp_manager,1,0,0,0 access_report_mrp_inout_user,report.mrp.inout user,model_report_mrp_inout,mrp.group_mrp_user,1,0,0,0 access_report_workcenter_load_user,report.workcenter.load.user,model_report_workcenter_load,mrp.group_mrp_user,1,0,0,0 diff --git a/addons/project/project.py b/addons/project/project.py index b7c88f3532b..12d7cada034 100644 --- a/addons/project/project.py +++ b/addons/project/project.py @@ -538,7 +538,7 @@ def Project(): # Prevent double project creation when 'use_tasks' is checked! context = dict(context, project_creation_in_progress=True) mail_alias = self.pool.get('mail.alias') - if not vals.get('alias_id'): + if not vals.get('alias_id') and vals.get('name', False): vals.pop('alias_name', None) # prevent errors during copy() alias_id = mail_alias.create_unique_alias(cr, uid, # Using '+' allows using subaddressing for those who don't diff --git a/addons/project_timesheet/project_timesheet_view.xml b/addons/project_timesheet/project_timesheet_view.xml index b8f5675891c..0f6c8f3340b 100644 --- a/addons/project_timesheet/project_timesheet_view.xml +++ b/addons/project_timesheet/project_timesheet_view.xml @@ -98,7 +98,8 @@ sequence="5" groups="base.group_hr_attendance" /> + parent="base.menu_main_pm" sequence="5" + groups="project.group_project_manager"/> diff --git a/addons/sale/sale.py b/addons/sale/sale.py index 18947d5d7b4..3a072ab1a48 100644 --- a/addons/sale/sale.py +++ b/addons/sale/sale.py @@ -530,55 +530,17 @@ class sale_order(osv.osv): return res def action_invoice_cancel(self, cr, uid, ids, context=None): - if context is None: - context = {} - for sale in self.browse(cr, uid, ids, context=context): - for line in sale.order_line: - # - # Check if the line is invoiced (has asociated invoice - # lines from non-cancelled invoices). - # - invoiced = False - for iline in line.invoice_lines: - if iline.invoice_id and iline.invoice_id.state != 'cancel': - invoiced = True - break - # Update the line (only when needed) - if line.invoiced != invoiced: - self.pool.get('sale.order.line').write(cr, uid, [line.id], {'invoiced': invoiced}, context=context) - self.write(cr, uid, ids, {'state': 'invoice_except', 'invoice_ids': False}, context=context) + self.write(cr, uid, ids, {'state': 'invoice_except'}, context=context) return True def action_invoice_end(self, cr, uid, ids, context=None): - for order in self.browse(cr, uid, ids, context=context): - # - # Update the sale order lines state (and invoiced flag). - # - for line in order.order_line: - vals = {} - # - # Check if the line is invoiced (has asociated invoice - # lines from non-cancelled invoices). - # - invoiced = False - for iline in line.invoice_lines: - if iline.invoice_id and iline.invoice_id.state != 'cancel': - invoiced = True - break - if line.invoiced != invoiced: - vals['invoiced'] = invoiced - # If the line was in exception state, now it gets confirmed. + for this in self.browse(cr, uid, ids, context=context): + for line in this.order_line: if line.state == 'exception': - vals['state'] = 'confirmed' - # Update the line (only when needed). - if vals: - self.pool.get('sale.order.line').write(cr, uid, [line.id], vals, context=context) - # - # Update the sales order state. - # - if order.state == 'invoice_except': - self.write(cr, uid, [order.id], {'state': 'progress'}, context=context) - self.invoice_paid_send_note(cr, uid, [order.id], context=context) + line.write({'state': 'confirmed'}) + if this.state == 'invoice_except': + this.write({'state': 'progress'}) + this.invoice_paid_send_note() return True def action_cancel(self, cr, uid, ids, context=None): @@ -732,6 +694,20 @@ class sale_order_line(osv.osv): except Exception, ex: return False + def _fnct_line_invoiced(self, cr, uid, ids, field_name, args, context=None): + res = dict.fromkeys(ids, False) + for this in self.browse(cr, uid, ids, context=context): + res[this.id] = this.invoice_lines and \ + all(iline.invoice_id.state != 'cancel' for iline in this.invoice_lines) + return res + + def _order_lines_from_invoice(self, cr, uid, ids, context=None): + # direct access to the m2m table is the less convoluted way to achieve this (and is ok ACL-wise) + cr.execute("""SELECT DISTINCT sol.id FROM sale_order_invoice_rel rel JOIN + sale_order_line sol ON (sol.order_id = rel.order_id) + WHERE rel.invoice_id = ANY(%s)""", (list(ids),)) + return [i[0] for i in cr.fetchall()] + _name = 'sale.order.line' _description = 'Sales Order Line' _columns = { @@ -740,7 +716,8 @@ class sale_order_line(osv.osv): 'sequence': fields.integer('Sequence', help="Gives the sequence order when displaying a list of sales order lines."), 'product_id': fields.many2one('product.product', 'Product', domain=[('sale_ok', '=', True)], change_default=True), 'invoice_lines': fields.many2many('account.invoice.line', 'sale_order_line_invoice_rel', 'order_line_id', 'invoice_id', 'Invoice Lines', readonly=True), - 'invoiced': fields.boolean('Invoiced', readonly=True), + 'invoiced': fields.function(_fnct_line_invoiced, string='Invoiced', type='boolean', + store={'account.invoice': (_order_lines_from_invoice, ['state'], 10)}), 'price_unit': fields.float('Unit Price', required=True, digits_compute= dp.get_precision('Product Price'), readonly=True, states={'draft': [('readonly', False)]}), 'type': fields.selection([('make_to_stock', 'from stock'), ('make_to_order', 'on order')], 'Procurement Method', required=True, readonly=True, states={'draft': [('readonly', False)]}, help="From stock: When needed, the product is taken from the stock or we wait for replenishment.\nOn order: When needed, the product is purchased or produced."), @@ -770,7 +747,6 @@ class sale_order_line(osv.osv): 'product_uom_qty': 1, 'product_uos_qty': 1, 'sequence': 10, - 'invoiced': 0, 'state': 'draft', 'type': 'make_to_stock', 'price_unit': 0.0, @@ -853,7 +829,6 @@ class sale_order_line(osv.osv): if vals: inv_id = self.pool.get('account.invoice.line').create(cr, uid, vals, context=context) cr.execute('insert into sale_order_line_invoice_rel (order_line_id,invoice_id) values (%s,%s)', (line.id, inv_id)) - self.write(cr, uid, [line.id], {'invoiced': True}) sales.add(line.order_id.id) create_ids.append(inv_id) # Trigger workflow events @@ -901,7 +876,7 @@ class sale_order_line(osv.osv): def copy_data(self, cr, uid, id, default=None, context=None): if not default: default = {} - default.update({'state': 'draft', 'invoiced': False, 'invoice_lines': []}) + default.update({'state': 'draft', 'invoice_lines': []}) return super(sale_order_line, self).copy_data(cr, uid, id, default, context=context) def product_id_change(self, cr, uid, ids, pricelist, product, qty=0, diff --git a/addons/sale/test/cancel_order.yml b/addons/sale/test/cancel_order.yml index 6145964224a..cde3a5b34f2 100644 --- a/addons/sale/test/cancel_order.yml +++ b/addons/sale/test/cancel_order.yml @@ -75,5 +75,5 @@ for invoice in sale_order.invoice_ids: if invoice.state != 'cancel': total_order_line += len(invoice.invoice_line) - assert total_order_line == 2, "wrong number of invoice lines" + assert total_order_line == 2, "wrong number of invoice lines, got %s" % total_order_line diff --git a/addons/sale/wizard/sale_line_invoice.py b/addons/sale/wizard/sale_line_invoice.py index 360c42ceb51..54001f645c8 100644 --- a/addons/sale/wizard/sale_line_invoice.py +++ b/addons/sale/wizard/sale_line_invoice.py @@ -88,8 +88,6 @@ class sale_order_line_make_invoice(osv.osv_memory): [line.id]) for lid in line_id: invoices[line.order_id.id].append((line, lid)) - sales_order_line_obj.write(cr, uid, [line.id], - {'invoiced': True}) for result in invoices.values(): order = result[0][0].order_id il = map(lambda x: x[1], result) diff --git a/addons/sale_stock/stock.py b/addons/sale_stock/stock.py index 6fc5c061dda..e621d63fede 100644 --- a/addons/sale_stock/stock.py +++ b/addons/sale_stock/stock.py @@ -100,14 +100,8 @@ class stock_picking(osv.osv): return super(stock_picking, self)._get_account_analytic_invoice(cursor, user, picking, move_line) def _invoice_line_hook(self, cursor, user, move_line, invoice_line_id): - sale_line_obj = self.pool.get('sale.order.line') - invoice_line_obj = self.pool.get('account.invoice.line') if move_line.sale_line_id: - sale_line_obj.write(cursor, user, [move_line.sale_line_id.id], - { - 'invoiced': True, - 'invoice_lines': [(4, invoice_line_id)], - }) + move_line.sale_line_id.write({'invoice_lines': [(4, invoice_line_id)]}) return super(stock_picking, self)._invoice_line_hook(cursor, user, move_line, invoice_line_id) def _invoice_hook(self, cursor, user, picking, invoice_id): @@ -180,10 +174,7 @@ class stock_picking(osv.osv): vals['account_analytic_id'] = self._get_account_analytic_invoice(cursor, user, picking, sale_line) vals['invoice_id'] = invoices[result[picking.id]].id invoice_line_id = invoice_line_obj.create(cursor, user, vals, context=context) - order_line_obj.write(cursor, user, [sale_line.id], { - 'invoiced': True, - 'invoice_lines': [(6, 0, [invoice_line_id])], - }) + sale_line.write({'invoice_lines': [(4, invoice_line_id)]}) return result # Redefinition of the new field in order to update the model stock.picking.out in the orm diff --git a/addons/stock/board_warehouse_view.xml b/addons/stock/board_warehouse_view.xml index 839a99c1fa7..801fa8ea156 100644 --- a/addons/stock/board_warehouse_view.xml +++ b/addons/stock/board_warehouse_view.xml @@ -19,7 +19,7 @@ report.stock.move form graph,tree - [('type','=','in'),('day','<=', time.strftime('%Y-%m-%d')),('day','>',(datetime.date.today()-datetime.timedelta(days=15)).strftime('%Y-%m-%d'))] + [('type','=','in'),('day','<=', time.strftime('%Y-%m-%d')),('day','>',(context_today().today()-datetime.timedelta(days=15)).strftime('%Y-%m-%d'))] {'search_default_in':1} @@ -28,7 +28,7 @@ report.stock.move form graph,tree - [('type','=','out'),('day','<=', time.strftime('%Y-%m-%d')),('day','>',(datetime.date.today()-datetime.timedelta(days=15)).strftime('%Y-%m-%d'))] + [('type','=','out'),('day','<=', time.strftime('%Y-%m-%d')),('day','>',(context_today().today()-datetime.timedelta(days=15)).strftime('%Y-%m-%d'))] {'search_default_out':1} diff --git a/addons/stock/stock.py b/addons/stock/stock.py index 9040c678778..defe2805c37 100644 --- a/addons/stock/stock.py +++ b/addons/stock/stock.py @@ -1845,7 +1845,7 @@ class stock_move(osv.osv): if move.state == 'done': if frozen_fields.intersection(vals): raise osv.except_osv(_('Operation forbidden !'), - _('Quantities, Unit of Measures, Products and Locations cannot be modified on stock moves that have already been processed (except by the Administrator).')) + _('Quantities, Units of Measure, Products and Locations cannot be modified on stock moves that have already been processed (except by the Administrator).')) return super(stock_move, self).write(cr, uid, ids, vals, context=context) def copy(self, cr, uid, id, default=None, context=None): diff --git a/addons/stock/stock_view.xml b/addons/stock/stock_view.xml index ad28fce8686..168a1c85233 100644 --- a/addons/stock/stock_view.xml +++ b/addons/stock/stock_view.xml @@ -1151,7 +1151,7 @@ -