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 @@
-
+
@@ -1458,7 +1458,7 @@
states="assigned" class="oe_highlight"/>
+ class="oe_highlight" help="Done"/>