[FIX] website_forum: post edition working again
[odoo/odoo.git] / addons / sale_stock / stock.py
1 # -*- coding: utf-8 -*-
2 ##############################################################################
3 #
4 #    OpenERP, Open Source Management Solution
5 #    Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
6 #
7 #    This program is free software: you can redistribute it and/or modify
8 #    it under the terms of the GNU Affero General Public License as
9 #    published by the Free Software Foundation, either version 3 of the
10 #    License, or (at your option) any later version.
11 #
12 #    This program is distributed in the hope that it will be useful,
13 #    but WITHOUT ANY WARRANTY; without even the implied warranty of
14 #    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 #    GNU Affero General Public License for more details.
16 #
17 #    You should have received a copy of the GNU Affero General Public License
18 #    along with this program.  If not, see <http://www.gnu.org/licenses/>.
19 #
20 ##############################################################################
21
22 from openerp.osv import fields, osv
23 from openerp.tools.translate import _
24
25 class stock_move(osv.osv):
26     _inherit = 'stock.move'
27     _columns = {
28         'sale_line_id': fields.many2one('sale.order.line', 'Sales Order Line', ondelete='set null', select=True, readonly=True),
29     }
30
31     def _prepare_chained_picking(self, cr, uid, picking_name, picking, picking_type, moves_todo, context=None):
32         values = super(stock_move, self)._prepare_chained_picking(cr, uid, picking_name, picking, picking_type, moves_todo, context=context)
33         if picking.sale_id:
34             values['sale_id'] = picking.sale_id.id
35         return values
36
37 class stock_picking(osv.osv):
38     _inherit = 'stock.picking'
39     _columns = {
40         'sale_id': fields.many2one('sale.order', 'Sales Order', ondelete='set null', select=True),
41     }
42     _defaults = {
43         'sale_id': False
44     }
45
46     def get_currency_id(self, cursor, user, picking):
47         if picking.sale_id:
48             return picking.sale_id.pricelist_id.currency_id.id
49         else:
50             return super(stock_picking, self).get_currency_id(cursor, user, picking)
51
52     def _get_partner_to_invoice(self, cr, uid, picking, context=None):
53         """ Inherit the original function of the 'stock' module
54             We select the partner of the sales order as the partner of the customer invoice
55         """
56         if picking.sale_id:
57             return picking.sale_id.partner_invoice_id
58         return super(stock_picking, self)._get_partner_to_invoice(cr, uid, picking, context=context)
59
60     def _get_comment_invoice(self, cursor, user, picking):
61         if picking.note or (picking.sale_id and picking.sale_id.note):
62             return picking.note or picking.sale_id.note
63         return super(stock_picking, self)._get_comment_invoice(cursor, user, picking)
64
65     def _prepare_invoice_group(self, cr, uid, picking, partner, invoice, context=None):
66         """ Inherit the original function of the 'stock' module in order to override name field
67             to pass the customer reference form the sales order
68         """
69         invoice_vals = super(stock_picking, self)._prepare_invoice_group(cr, uid, picking, partner, invoice, context)
70         if picking.sale_id:
71             invoice_vals['name'] = (invoice.name or '') + ', ' + (picking.sale_id.client_order_ref or '')
72         return invoice_vals
73
74     def _prepare_invoice(self, cr, uid, picking, partner, inv_type, journal_id, context=None):
75         """ Inherit the original function of the 'stock' module in order to override some
76             values if the picking has been generated by a sales order
77         """
78         invoice_vals = super(stock_picking, self)._prepare_invoice(cr, uid, picking, partner, inv_type, journal_id, context=context)
79         if picking.sale_id:
80             invoice_vals['fiscal_position'] = picking.sale_id.fiscal_position.id
81             invoice_vals['payment_term'] = picking.sale_id.payment_term.id
82             invoice_vals['user_id'] = picking.sale_id.user_id.id
83             invoice_vals['name'] = picking.sale_id.client_order_ref or ''
84         return invoice_vals
85
86     def _prepare_invoice_line(self, cr, uid, group, picking, move_line, invoice_id, invoice_vals, context=None):
87         invoice_vals = super(stock_picking, self)._prepare_invoice_line(cr, uid, group, picking, move_line, invoice_id, invoice_vals, context=context)
88         if picking.sale_id:
89             if move_line.sale_line_id:
90                 invoice_vals['account_analytic_id'] = self._get_account_analytic_invoice(cr, uid, picking, move_line)
91         return invoice_vals
92
93     def _get_price_unit_invoice(self, cursor, user, move_line, type):
94         if move_line.sale_line_id and move_line.sale_line_id.product_id.id == move_line.product_id.id:
95             uom_id = move_line.product_id.uom_id.id
96             uos_id = move_line.product_id.uos_id and move_line.product_id.uos_id.id or False
97             price = move_line.sale_line_id.price_unit
98             coeff = move_line.product_id.uos_coeff
99             if uom_id != uos_id  and coeff != 0:
100                 price_unit = price / coeff
101                 return price_unit
102             return move_line.sale_line_id.price_unit
103         return super(stock_picking, self)._get_price_unit_invoice(cursor, user, move_line, type)
104
105     def _get_discount_invoice(self, cursor, user, move_line):
106         if move_line.sale_line_id:
107             return move_line.sale_line_id.discount
108         return super(stock_picking, self)._get_discount_invoice(cursor, user, move_line)
109
110     def _get_taxes_invoice(self, cursor, user, move_line, type):
111         if move_line.sale_line_id and move_line.sale_line_id.product_id.id == move_line.product_id.id:
112             return [x.id for x in move_line.sale_line_id.tax_id]
113         return super(stock_picking, self)._get_taxes_invoice(cursor, user, move_line, type)
114
115     def _get_account_analytic_invoice(self, cursor, user, picking, move_line):
116         if picking.sale_id:
117             return picking.sale_id.project_id.id
118         return super(stock_picking, self)._get_account_analytic_invoice(cursor, user, picking, move_line)
119
120     def _invoice_line_hook(self, cursor, user, move_line, invoice_line_id):
121         if move_line.sale_line_id:
122             move_line.sale_line_id.write({'invoice_lines': [(4, invoice_line_id)]})
123         return super(stock_picking, self)._invoice_line_hook(cursor, user, move_line, invoice_line_id)
124
125     def _invoice_hook(self, cursor, user, picking, invoice_id):
126         sale_obj = self.pool.get('sale.order')
127         order_line_obj = self.pool.get('sale.order.line')
128         invoice_obj = self.pool.get('account.invoice')
129         invoice_line_obj = self.pool.get('account.invoice.line')
130         if picking.sale_id:
131             sale_obj.write(cursor, user, [picking.sale_id.id], {
132                 'invoice_ids': [(4, invoice_id)],
133             })
134             for sale_line in picking.sale_id.order_line:
135                 if sale_line.product_id.type == 'service' and not sale_line.invoiced:
136                     vals = order_line_obj._prepare_order_line_invoice_line(cursor, user, sale_line, False)
137                     vals['invoice_id'] = invoice_id
138                     invoice_line_id = invoice_line_obj.create(cursor, user, vals)
139                     order_line_obj.write(cursor, user, [sale_line.id], {
140                         'invoice_lines': [(6, 0, [invoice_line_id])],
141                     })
142                     invoice_obj.button_compute(cursor, user, [invoice_id])
143         return super(stock_picking, self)._invoice_hook(cursor, user, picking, invoice_id)
144     
145     def action_done(self, cr, uid, ids, context=None):
146         """ Changes picking state to done. This method is called at the end of
147             the workflow by the activity "done".
148         """
149         for record in self.browse(cr, uid, ids, context):
150             if record.type == "out" and record.sale_id:
151                 self.pool.get('sale.order').message_post(cr, uid, [record.sale_id.id], body=_("Products delivered"), context=context)
152         return super(stock_picking, self).action_done(cr, uid, ids, context=context)
153
154 # Redefinition of the new field in order to update the model stock.picking.out in the orm
155 # FIXME: this is a temporary workaround because of a framework bug (ref: lp996816). It should be removed as soon as
156 #        the bug is fixed
157 class stock_picking_out(osv.osv):
158     _inherit = 'stock.picking.out'
159     _columns = {
160         'sale_id': fields.many2one('sale.order', 'Sale Order',
161             ondelete='set null', select=True),
162     }
163 # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: