Add _get_partner_to_invoice() to purchase module.
[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.product_qty, 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_partner_to_invoice(self, cr, uid, picking, context=None):
62         if picking.purchase_id:
63             return picking.purchase_id.partner_id
64         return super(stock_picking, self)._get_partner_to_invoice(cr, uid, picking, context=context)
65
66     def _prepare_invoice(self, cr, uid, picking, partner, inv_type, journal_id, context=None):
67         """Inherit the original function of the 'stock' module in order to override some
68         values if the picking has been generated by a purchase order
69         """
70         invoice_vals = super(stock_picking, self)._prepare_invoice(cr, uid, picking, partner, inv_type, journal_id, context=context)
71         if picking.purchase_id:
72             invoice_vals['address_contact_id'], invoice_vals['address_invoice_id'] = \
73                     self.pool.get('res.partner').address_get(cr, uid, [partner.id],
74                             ['contact', 'invoice']).values()
75             if picking.purchase_id.fiscal_position:
76                 invoice_vals['fiscal_position'] = picking.purchase_id.fiscal_position.id
77         return invoice_vals
78
79     def get_currency_id(self, cursor, user, picking):
80         if picking.purchase_id:
81             return picking.purchase_id.pricelist_id.currency_id.id
82         else:
83             return super(stock_picking, self).get_currency_id(cursor, user, picking)
84
85     def _get_comment_invoice(self, cursor, user, picking):
86         if picking.purchase_id and picking.purchase_id.notes:
87             if picking.note:
88                 return picking.note + '\n' + picking.purchase_id.notes
89             else:
90                 return picking.purchase_id.notes
91         return super(stock_picking, self)._get_comment_invoice(cursor, user, picking)
92
93     def _get_price_unit_invoice(self, cursor, user, move_line, type):
94         if move_line.purchase_line_id:
95             if move_line.purchase_line_id.order_id.invoice_method == 'picking':
96                 return move_line.price_unit
97             else:
98                 return move_line.purchase_line_id.price_unit
99         return super(stock_picking, self)._get_price_unit_invoice(cursor, user, move_line, type)
100
101     def _get_discount_invoice(self, cursor, user, move_line):
102         if move_line.purchase_line_id:
103             return 0.0
104         return super(stock_picking, self)._get_discount_invoice(cursor, user, move_line)
105
106     def _get_taxes_invoice(self, cursor, user, move_line, type):
107         if move_line.purchase_line_id:
108             return [x.id for x in move_line.purchase_line_id.taxes_id]
109         return super(stock_picking, self)._get_taxes_invoice(cursor, user, move_line, type)
110
111     def _get_account_analytic_invoice(self, cursor, user, picking, move_line):
112         if picking.purchase_id and move_line.purchase_line_id:
113             return move_line.purchase_line_id.account_analytic_id.id
114         return super(stock_picking, self)._get_account_analytic_invoice(cursor, user, picking, move_line)
115
116     def _invoice_line_hook(self, cursor, user, move_line, invoice_line_id):
117         if move_line.purchase_line_id:
118             invoice_line_obj = self.pool.get('account.invoice.line')
119             invoice_line_obj.write(cursor, user, [invoice_line_id], {'note':  move_line.purchase_line_id.notes,})
120         return super(stock_picking, self)._invoice_line_hook(cursor, user, move_line, invoice_line_id)
121
122     def _invoice_hook(self, cursor, user, picking, invoice_id):
123         purchase_obj = self.pool.get('purchase.order')
124         if picking.purchase_id:
125             purchase_obj.write(cursor, user, [picking.purchase_id.id], {'invoice_ids': [(4, invoice_id)]})
126         return super(stock_picking, self)._invoice_hook(cursor, user, picking, invoice_id)
127
128 class stock_partial_picking(osv.osv_memory):
129     _inherit = 'stock.partial.picking'
130
131     # Overridden to inject the purchase price as true 'cost price' when processing
132     # incoming pickings.
133     def _product_cost_for_average_update(self, cr, uid, move):
134         if move.picking_id.purchase_id:
135             return {'cost': move.purchase_line_id.price_unit,
136                     'currency': move.picking_id.purchase_id.pricelist_id.currency_id.id}
137         return super(stock_partial_picking, self)._product_cost_for_average_update(cr, uid, move)
138
139 # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: