[MERGE]: Merge with lp:openobject-addons
[odoo/odoo.git] / addons / purchase / 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 osv import osv, fields
23
24 class stock_move(osv.osv):
25     _inherit = 'stock.move'
26     _columns = {
27         'purchase_line_id': fields.many2one('purchase.order.line',
28             'Purchase Order Line', ondelete='set null', select=True,
29             readonly=True),
30     }
31
32     def _get_reference_accounting_values_for_valuation(self, cr, uid, move, context=None):
33         """
34         Overrides the default stock valuation to take into account the currency that was specified
35         on the purchase order in case the valuation data was not directly specified during picking
36         confirmation.
37         """
38         reference_amount, reference_currency_id = super(stock_move, self)._get_reference_accounting_values_for_valuation(cr, uid, move, context=context)
39         if move.product_id.cost_method != 'average' or not move.price_unit:
40             # no average price costing or cost not specified during picking validation, we will
41             # plug the purchase line values if they are found.
42             if move.purchase_line_id and move.picking_id.purchase_id.pricelist_id:
43                 reference_amount, reference_currency_id = move.purchase_line_id.price_unit, move.picking_id.purchase_id.pricelist_id.currency_id.id
44         return reference_amount, reference_currency_id
45
46 stock_move()
47
48 #
49 # Inherit of picking to add the link to the PO
50 #
51 class stock_picking(osv.osv):
52     _inherit = 'stock.picking'
53     _columns = {
54         'purchase_id': fields.many2one('purchase.order', 'Purchase Order',
55             ondelete='set null', select=True),
56     }
57     _defaults = {
58         'purchase_id': False,
59     }
60
61     def get_currency_id(self, cursor, user, picking):
62         if picking.purchase_id:
63             return picking.purchase_id.pricelist_id.currency_id.id
64         else:
65             return super(stock_picking, self).get_currency_id(cursor, user, picking)
66
67     def _get_comment_invoice(self, cursor, user, picking):
68         if picking.purchase_id and picking.purchase_id.notes:
69             if picking.note:
70                 return picking.note + '\n' + picking.purchase_id.notes
71             else:
72                 return picking.purchase_id.notes
73         return super(stock_picking, self)._get_comment_invoice(cursor, user, picking)
74
75     def _get_price_unit_invoice(self, cursor, user, move_line, type):
76         if move_line.purchase_line_id:
77             return move_line.purchase_line_id.price_unit
78         return super(stock_picking, self)._get_price_unit_invoice(cursor, user, move_line, type)
79
80     def _get_discount_invoice(self, cursor, user, move_line):
81         if move_line.purchase_line_id:
82             return 0.0
83         return super(stock_picking, self)._get_discount_invoice(cursor, user, move_line)
84
85     def _get_taxes_invoice(self, cursor, user, move_line, type):
86         if move_line.purchase_line_id:
87             return [x.id for x in move_line.purchase_line_id.taxes_id]
88         return super(stock_picking, self)._get_taxes_invoice(cursor, user, move_line, type)
89
90     def _get_account_analytic_invoice(self, cursor, user, picking, move_line):
91         if move_line.purchase_line_id:
92             return move_line.purchase_line_id.account_analytic_id.id
93         return super(stock_picking, self)._get_account_analytic_invoice(cursor, user, picking, move_line)
94
95     def _invoice_line_hook(self, cursor, user, move_line, invoice_line_id):
96         if move_line.purchase_line_id:
97             invoice_line_obj = self.pool.get('account.invoice.line')
98             invoice_line_obj.write(cursor, user, [invoice_line_id], {'note':  move_line.purchase_line_id.notes,})
99         return super(stock_picking, self)._invoice_line_hook(cursor, user, move_line, invoice_line_id)
100
101     def _invoice_hook(self, cursor, user, picking, invoice_id):
102         purchase_obj = self.pool.get('purchase.order')
103         if picking.purchase_id:
104             purchase_obj.write(cursor, user, [picking.purchase_id.id], {'invoice_id': invoice_id,})
105         return super(stock_picking, self)._invoice_hook(cursor, user, picking, invoice_id)
106
107 stock_picking()
108
109 class stock_partial_picking(osv.osv_memory):
110     _inherit = 'stock.partial.picking'
111
112     def default_get(self, cr, uid, fields, context=None):
113         """ To get default values for the object.
114         @param self: The object pointer.
115         @param cr: A database cursor
116         @param uid: ID of the user currently logged in
117         @param fields: List of fields for which we want default values
118         @param context: A standard dictionary
119         @return: A dictionary which of fields with values.
120         """
121         if context is None:
122             context = {}
123         pick_obj = self.pool.get('stock.picking')
124         res = super(stock_partial_picking, self).default_get(cr, uid, fields, context=context)
125         for pick in pick_obj.browse(cr, uid, context.get('active_ids', []), context=context):
126             has_product_cost = (pick.type == 'in' and pick.purchase_id)
127             for m in pick.move_lines:
128                 if m.state in ('done','cancel') :
129                     continue
130                 if has_product_cost and m.product_id.cost_method == 'average' and m.purchase_line_id:
131                     # We use the original PO unit purchase price as the basis for the cost, expressed
132                     # in the currency of the PO (i.e the PO's pricelist currency)
133                     res['move%s_product_price'%(m.id)] =  m.purchase_line_id.price_unit
134                     res['move%s_product_currency'%(m.id)] = pick.purchase_id.pricelist_id.currency_id.id
135         return res
136 stock_partial_picking()
137
138 class stock_partial_move(osv.osv_memory):
139     _inherit = "stock.partial.move"
140     def default_get(self, cr, uid, fields, context=None):
141         """ To get default values for the object.
142         @param self: The object pointer.
143         @param cr: A database cursor
144         @param uid: ID of the user currently logged in
145         @param fields: List of fields for which we want default values
146         @param context: A standard dictionary
147         @return: A dictionary which of fields with values.
148         """
149         if context is None:
150             context = {}
151         res = super(stock_partial_move, self).default_get(cr, uid, fields, context=context)
152         move_obj = self.pool.get('stock.move')
153         for m in move_obj.browse(cr, uid, context.get('active_ids', []), context=context):
154             if m.picking_id.type == 'in' and m.product_id.cost_method == 'average' \
155                 and m.purchase_line_id and m.picking_id.purchase_id:
156                     # We use the original PO unit purchase price as the basis for the cost, expressed
157                     # in the currency of the PO (i.e the PO's pricelist currency)
158                     res['move%s_product_price'%(m.id)] = m.purchase_line_id.price_unit
159                     res['move%s_product_currency'%(m.id)] = m.picking_id.purchase_id.pricelist_id.currency_id.id
160         return res
161 stock_partial_move()
162 # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
163