2
# -*- coding: utf-8 -*-
3
##############################################################################
5
# OpenERP, Open Source Management Solution
6
# Copyright (C) 2012 TeMPO Consulting, MSF. All Rights Reserved
7
# Developer: Olivier DOSSMANN
9
# This program is free software: you can redistribute it and/or modify
10
# it under the terms of the GNU Affero General Public License as
11
# published by the Free Software Foundation, either version 3 of the
12
# License, or (at your option) any later version.
14
# This program is distributed in the hope that it will be useful,
15
# but WITHOUT ANY WARRANTY; without even the implied warranty of
16
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17
# GNU Affero General Public License for more details.
19
# You should have received a copy of the GNU Affero General Public License
20
# along with this program. If not, see <http://www.gnu.org/licenses/>.
22
##############################################################################
26
from tools.translate import _
28
class stock_picking(osv.osv):
29
_name = 'stock.picking'
30
_inherit = 'stock.picking'
32
def _invoice_line_hook(self, cr, uid, move_line, invoice_line_id):
34
BE CAREFUL : For FO with PICK/PACK/SHIP, the invoice is not created on picking but on shipment
36
res = super(stock_picking, self)._invoice_line_hook(cr, uid, move_line, invoice_line_id)
38
# Modify the product UoM and the quantity of line according to move attributes
39
values = {'uos_id': move_line.product_uom.id,
40
'quantity': move_line.product_qty}
43
if move_line.price_unit:
44
price_unit = move_line.price_unit
46
# UTP-220: As now the price can be changed when making the reception, the system still needs to keep the PO price in the invoice!
47
# UF-2211: The price unit needs to be adapted to the UoM: so it needs to be retrieved from the move line, and not the po_line in another UoM
48
# Finance may decide to change later, but for instance, this is not agreed by Finance. Check UTP-220 for further info
49
if move_line.picking_id:
50
inv_type = self._get_invoice_type(move_line.picking_id)
51
price_unit = self._get_price_unit_invoice(cr, uid, move_line, inv_type)
54
values.update({'price_unit': price_unit})
56
self.pool.get('account.invoice.line').write(cr, uid, [invoice_line_id], values)
58
if move_line.picking_id and move_line.picking_id.purchase_id and move_line.picking_id.purchase_id.order_type == 'in_kind':
59
order_line = move_line.purchase_line_id or False
60
account_id = (order_line.product_id and order_line.product_id.donation_expense_account and order_line.product_id.donation_expense_account.id) \
61
or (order_line.product_id.categ_id and order_line.product_id.categ_id.donation_expense_account and order_line.product_id.categ_id.donation_expense_account.id) \
64
raise osv.except_osv(_('Error'), _('No donation expense account defined for this PO Line: %s') % (order_line.name or '',))
65
self.pool.get('account.invoice.line').write(cr, uid, [invoice_line_id], {'account_id': account_id,})
66
# Delete invoice lines that come from a picking from scratch that have an intermission/section partner and which reason type is different from deliver partner
67
# first fetch some values
69
rt_id = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'reason_types_moves', 'reason_type_deliver_partner')[1]
73
if move_line.picking_id and move_line.picking_id.type == 'out' and move_line.reason_type_id.id != rt_id:
74
if move_line.picking_id and not move_line.picking_id.purchase_id and not move_line.picking_id.sale_id and move_line.picking_id.partner_id.partner_type in ['intermission', 'section']:
75
self.pool.get('account.invoice.line').unlink(cr, uid, [invoice_line_id])
78
def _hook_invoice_vals_before_invoice_creation(self, cr, uid, ids, invoice_vals, picking):
80
Update journal by an inkind journal if we come from an inkind donation PO.
81
Update partner account
82
BE CAREFUL : For FO with PICK/PACK/SHIP, the invoice is not created on picking but on shipment
84
super(stock_picking, self)._hook_invoice_vals_before_invoice_creation(cr, uid, ids, invoice_vals, picking)
85
if not invoice_vals.get('date_invoice',False):
86
invoice_vals['date_invoice'] = time.strftime('%Y-%m-%d',time.localtime())
87
journal_ids = self.pool.get('account.journal').search(cr, uid, [('type', '=', 'inkind'),
88
('is_current_instance', '=', True)])
89
if picking and picking.purchase_id and picking.purchase_id.order_type == "in_kind":
91
raise osv.except_osv(_('Error'), _('No In-kind donation journal found!'))
92
account_id = picking.partner_id and picking.partner_id.donation_payable_account and picking.partner_id.donation_payable_account.id or False
94
raise osv.except_osv(_('Error'), _('No Donation Payable account for this partner: %s') % (picking.partner_id.name or '',))
95
invoice_vals.update({'journal_id': journal_ids[0], 'account_id': account_id, 'is_inkind_donation': True,})
96
if picking and picking.partner_id and picking.partner_id.partner_type == 'intermission':
97
invoice_vals.update({'is_intermission': True})
99
if picking and picking.type == 'in' and picking.partner_id and (not picking.partner_id.property_account_payable or not picking.partner_id.property_account_receivable):
100
raise osv.except_osv(_('Error'), _('Partner of this incoming shipment has no account set. Please set appropriate accounts (receivable and payable) in order to process this IN'))
104
def action_invoice_create(self, cr, uid, ids, journal_id=False, group=False, type='out_invoice', context=None):
106
Add a link between stock picking and invoice
108
res = super(stock_picking, self).action_invoice_create(cr, uid, ids, journal_id, group, type, context)
109
for pick in self.browse(cr, uid, [x for x in res]):
110
inv_id = res[pick.id]
112
self.pool.get('account.invoice').write(cr, uid, [inv_id], {'picking_id': pick.id})
116
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: