diff --git a/.bzrignore b/.bzrignore deleted file mode 100644 index 86a1881981f..00000000000 --- a/.bzrignore +++ /dev/null @@ -1,15 +0,0 @@ -.* -*.egg-info -*.orig -*.vim -build/ -RE:^bin/ -RE:^dist/ -RE:^include/ - -RE:^share/ -RE:^man/ -RE:^lib/ - -RE:^addons/\w+/doc/_build/ -RE:^.*?/node_modules diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000000..7828a605ef0 --- /dev/null +++ b/.gitignore @@ -0,0 +1,30 @@ +# sphinx build directories +_build/ + +# dotfiles +.* +!.gitignore +# compiled python files +*.py[co] +# setup.py egg_info +*.egg-info +# emacs backup files +*~ +# hg stuff +*.orig +status +# odoo filestore +openerp/filestore +# generated for windows installer? +install/win32/*.bat +install/win32/meta.py + +# various virtualenv +/bin/ +/build/ +/dist/ +/include/ +/lib/ +/man/ +/share/ +/src/ diff --git a/addons/delivery/sale.py b/addons/delivery/sale.py index c5d032ca8a8..93072b3d02d 100644 --- a/addons/delivery/sale.py +++ b/addons/delivery/sale.py @@ -74,7 +74,7 @@ class sale_order(osv.Model): if not grid_id: raise osv.except_osv(_('No Grid Available!'), _('No grid matching for this carrier!')) - if order.state != 'draft': + if order.state not in ('draft', 'sent'): raise osv.except_osv(_('Order not in Draft State!'), _('The order state have to be draft to add delivery lines.')) grid = grid_obj.browse(cr, uid, grid_id, context=context) diff --git a/addons/mail/mail_thread.py b/addons/mail/mail_thread.py index fe960292344..a264d58df7e 100644 --- a/addons/mail/mail_thread.py +++ b/addons/mail/mail_thread.py @@ -1132,7 +1132,14 @@ class mail_thread(osv.AbstractModel): body = u'' if save_original: attachments.append(('original_email.eml', message.as_string())) - if not message.is_multipart() or 'text/' in message.get('content-type', ''): + + # Be careful, content-type may contain tricky content like in the + # following example so test the MIME type with startswith() + # + # Content-Type: multipart/related; + # boundary="_004_3f1e4da175f349248b8d43cdeb9866f1AMSPR06MB343eurprd06pro_"; + # type="text/html" + if not message.is_multipart() or message.get('content-type', '').startswith("text/"): encoding = message.get_content_charset() body = message.get_payload(decode=True) body = tools.ustr(body, encoding, errors='replace') diff --git a/addons/purchase/purchase.py b/addons/purchase/purchase.py index 6497ec0045c..bf5a95d7abe 100644 --- a/addons/purchase/purchase.py +++ b/addons/purchase/purchase.py @@ -503,6 +503,8 @@ class purchase_order(osv.osv): if not len(ids): return False self.write(cr, uid, ids, {'state':'draft','shipped':0}) + for purchase in self.browse(cr, uid, ids, context=context): + self.pool['purchase.order.line'].write(cr, uid, [l.id for l in purchase.order_line], {'state': 'draft'}) for p_id in ids: # Deleting the existing instance of workflow for PO self.delete_workflow(cr, uid, [p_id]) # TODO is it necessary to interleave the calls? @@ -598,6 +600,8 @@ class purchase_order(osv.osv): _('You must first cancel all receptions related to this purchase order.')) self.pool.get('account.invoice') \ .signal_invoice_cancel(cr, uid, map(attrgetter('id'), purchase.invoice_ids)) + self.pool['purchase.order.line'].write(cr, uid, [l.id for l in purchase.order_line], + {'state': 'cancel'}) self.write(cr,uid,ids,{'state':'cancel'}) self.signal_purchase_cancel(cr, uid, ids) @@ -908,6 +912,8 @@ class purchase_order_line(osv.osv): def unlink(self, cr, uid, ids, context=None): procurement_ids_to_cancel = [] for line in self.browse(cr, uid, ids, context=context): + if line.state not in ['draft', 'cancel']: + raise osv.except_osv(_('Invalid Action!'), _('Cannot delete a purchase order line which is in state \'%s\'.') %(line.state,)) if line.move_dest_id: procurement_ids_to_cancel.extend(procurement.id for procurement in line.move_dest_id.procurements) if procurement_ids_to_cancel: diff --git a/addons/sale/sale.py b/addons/sale/sale.py index 0664b6521c1..8e895190295 100644 --- a/addons/sale/sale.py +++ b/addons/sale/sale.py @@ -515,14 +515,18 @@ class sale_order(osv.osv): if grouped: res = self._make_invoice(cr, uid, val[0][0], reduce(lambda x, y: x + y, [l for o, l in val], []), context=context) invoice_ref = '' + origin_ref = '' for o, l in val: - invoice_ref += o.name + '|' + invoice_ref += (o.client_order_ref or o.name) + '|' + origin_ref += (o.origin or o.name) + '|' self.write(cr, uid, [o.id], {'state': 'progress'}) cr.execute('insert into sale_order_invoice_rel (order_id,invoice_id) values (%s,%s)', (o.id, res)) #remove last '|' in invoice_ref - if len(invoice_ref) >= 1: + if len(invoice_ref) >= 1: invoice_ref = invoice_ref[:-1] - invoice.write(cr, uid, [res], {'origin': invoice_ref, 'name': invoice_ref}) + if len(origin_ref) >= 1: + origin_ref = origin_ref[:-1] + invoice.write(cr, uid, [res], {'origin': origin_ref, 'name': invoice_ref}) else: for order, il in val: res = self._make_invoice(cr, uid, order, il, context=context) diff --git a/addons/stock/stock.py b/addons/stock/stock.py index efb8582e9cb..c59fbc31da1 100644 --- a/addons/stock/stock.py +++ b/addons/stock/stock.py @@ -2395,7 +2395,7 @@ class stock_move(osv.osv): picking_ids.append(move.picking_id.id) if move.move_dest_id.id and (move.state != 'done'): # Downstream move should only be triggered if this move is the last pending upstream move - other_upstream_move_ids = self.search(cr, uid, [('id','!=',move.id),('state','not in',['done','cancel']), + other_upstream_move_ids = self.search(cr, uid, [('id','not in',move_ids),('state','not in',['done','cancel']), ('move_dest_id','=',move.move_dest_id.id)], context=context) if not other_upstream_move_ids: self.write(cr, uid, [move.id], {'move_history_ids': [(4, move.move_dest_id.id)]}) diff --git a/openerp/addons/base/security/ir.model.access.csv b/openerp/addons/base/security/ir.model.access.csv index 25df6e117d0..0fd8b548cb0 100644 --- a/openerp/addons/base/security/ir.model.access.csv +++ b/openerp/addons/base/security/ir.model.access.csv @@ -108,6 +108,7 @@ "access_multi_company_default manager","multi_company_default Manager","model_multi_company_default","group_erp_manager",1,1,1,1 "access_ir_filter all","ir_filters all","model_ir_filters",,1,1,1,1 "access_ir_config_parameter","ir_config_parameter","model_ir_config_parameter",,1,0,0,0 +"access_ir_config_parameter_system","ir_config_parameter_system","model_ir_config_parameter","group_system",1,1,1,1 "access_ir_mail_server","ir_mail_server","model_ir_mail_server","group_system",1,1,1,1 "access_ir_actions_client","ir_actions_client all","model_ir_actions_client",,1,0,0,0 "access_ir_needaction_mixin","ir_needaction_mixin","model_ir_needaction_mixin",,1,1,1,1