diff --git a/addons/mail/mail_thread.py b/addons/mail/mail_thread.py index 61f8195d319..c87df08eed4 100644 --- a/addons/mail/mail_thread.py +++ b/addons/mail/mail_thread.py @@ -1064,11 +1064,23 @@ class mail_thread(osv.AbstractModel): alternative = True if part.get_content_maintype() == 'multipart': continue # skip container - filename = part.get_filename() # None if normal part + # part.get_filename returns decoded value if able to decode, coded otherwise. + # original get_filename is not able to decode iso-8859-1 (for instance). + # therefore, iso encoded attachements are not able to be decoded properly with get_filename + # code here partially copy the original get_filename method, but handle more encoding + filename=part.get_param('filename', None, 'content-disposition') + if not filename: + filename=part.get_param('name', None) + if filename: + if isinstance(filename, tuple): + # RFC2231 + filename=email.utils.collapse_rfc2231_value(filename).strip() + else: + filename=decode(filename) encoding = part.get_content_charset() # None if attachment # 1) Explicit Attachments -> attachments if filename or part.get('content-disposition', '').strip().startswith('attachment'): - attachments.append((decode(filename) or 'attachment', part.get_payload(decode=True))) + attachments.append((filename or 'attachment', part.get_payload(decode=True))) continue # 2) text/plain ->
                 if part.get_content_type() == 'text/plain' and (not alternative or not body):
diff --git a/addons/sale_stock/stock.py b/addons/sale_stock/stock.py
index ccece846390..cfc8a8e634c 100644
--- a/addons/sale_stock/stock.py
+++ b/addons/sale_stock/stock.py
@@ -124,10 +124,22 @@ class stock_picking(osv.osv):
 
     def _invoice_hook(self, cursor, user, picking, invoice_id):
         sale_obj = self.pool.get('sale.order')
+        order_line_obj = self.pool.get('sale.order.line')
+        invoice_obj = self.pool.get('account.invoice')
+        invoice_line_obj = self.pool.get('account.invoice.line')
         if picking.sale_id:
             sale_obj.write(cursor, user, [picking.sale_id.id], {
                 'invoice_ids': [(4, invoice_id)],
-                })
+            })
+            for sale_line in picking.sale_id.order_line:
+                if sale_line.product_id.type == 'service' and not sale_line.invoiced:
+                    vals = order_line_obj._prepare_order_line_invoice_line(cursor, user, sale_line, False)
+                    vals['invoice_id'] = invoice_id
+                    invoice_line_id = invoice_line_obj.create(cursor, user, vals)
+                    order_line_obj.write(cursor, user, [sale_line.id], {
+                        'invoice_lines': [(6, 0, [invoice_line_id])],
+                    })
+                    invoice_obj.button_compute(cursor, user, [invoice_id])
         return super(stock_picking, self)._invoice_hook(cursor, user, picking, invoice_id)
     
     def action_done(self, cr, uid, ids, context=None):
diff --git a/addons/sale_stock/test/picking_order_policy.yml b/addons/sale_stock/test/picking_order_policy.yml
index 609cd405bad..83610bdd043 100644
--- a/addons/sale_stock/test/picking_order_policy.yml
+++ b/addons/sale_stock/test/picking_order_policy.yml
@@ -3,6 +3,16 @@
 -
   !context
     uid: 'res_sale_stock_salesman'
+-
+  Add SO line with service type product in SO to check flow which contain service type product in SO(BUG#1167330).
+-
+  !record {model: sale.order.line, id: sale_order_1}:
+    name: 'On Site Assistance'
+    product_id: product.product_product_2
+    product_uom_qty: 1.0
+    product_uom: 1
+    price_unit: 150.0
+    order_id: sale.sale_order_6
 -
   First I check the total amount of the Quotation before Approved.
 -
@@ -75,7 +85,7 @@
       assert picking.partner_id.id == sale_order.partner_shipping_id.id,"Shipping Address is not correspond with sale order."
       assert picking.note == sale_order.note,"Note is not correspond with sale order."
       assert picking.invoice_state == (sale_order.order_policy=='picking' and '2binvoiced') or 'none',"Invoice policy is not correspond with sale order."
-      assert len(picking.move_lines) == len(sale_order.order_line), "Total move of delivery order are not corresposning with total sale order lines."
+      assert len(picking.move_lines) == len(sale_order.order_line) - 1, "Total move of delivery order are not corresposning with total sale order lines."
       location_id = sale_order.warehouse_id.lot_stock_id.id
       output_id = sale_order.warehouse_id.lot_output_id.id
       for move in picking.move_lines: