[REF] Delivery : Weight calculation Optimized
[odoo/odoo.git] / addons / delivery / stock.py
1 # -*- encoding: utf-8 -*-
2 ##############################################################################
3 #
4 #    OpenERP, Open Source Management Solution
5 #    Copyright (C) 2004-2009 Tiny SPRL (<http://tiny.be>). All Rights Reserved
6 #    $Id$
7 #
8 #    This program is free software: you can redistribute it and/or modify
9 #    it under the terms of the GNU General Public License as published by
10 #    the Free Software Foundation, either version 3 of the License, or
11 #    (at your option) any later version.
12 #
13 #    This program is distributed in the hope that it will be useful,
14 #    but WITHOUT ANY WARRANTY; without even the implied warranty of
15 #    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 #    GNU General Public License for more details.
17 #
18 #    You should have received a copy of the GNU General Public License
19 #    along with this program.  If not, see <http://www.gnu.org/licenses/>.
20 #
21 ##############################################################################
22
23 import netsvc
24 from osv import fields,osv
25 from tools.translate import _
26 import tools
27
28 # Overloaded stock_picking to manage carriers :
29 class stock_picking(osv.osv):
30     _name = "stock.picking"
31     _description = "Picking list"
32     _inherit = 'stock.picking'
33
34     def _cal_weight(self, cr, uid, ids, name, args, context=None):
35         res = {}
36         uom_obj = self.pool.get('product.uom')
37         for picking in self.browse(cr, uid, ids, context):
38             total_weight = 0.00
39             for move in picking.move_lines:
40                 weight = 0.00
41                 if move.product_id.weight > 0.00:
42                     converted_qty = move.product_qty
43 #                    from_uom = move.product_uom.id
44 #                    pass_qty = move.product_qty
45 #                    to_uom = move.product_id.uom_id.id
46 #                    if picking.type == 'out':
47 #                        if move.product_uos:
48 #                            converted_qty = move.product_uos_qty
49 #                            if move.product_uos.id <> move.product_uom.id:
50 #                                converted_qty = (move.product_uos_qty/move.product_id.uos_coeff)
51 #                            pass_qty = converted_qty
52                     if move.product_uom.id <> move.product_id.uom_id.id:
53                         converted_qty = uom_obj._compute_qty(cr, uid, move.product_uom.id, move.product_qty, move.product_id.uom_id.id)
54
55                     weight = (converted_qty * move.product_id.weight)
56                     total_weight += weight
57             res[picking.id] = total_weight
58         return res
59
60     def _get_picking_line(self, cr, uid, ids, context=None):
61         result = {}
62         for line in self.pool.get('stock.move').browse(cr, uid, ids, context=context):
63             result[line.picking_id.id] = True
64         return result.keys()
65     
66     _columns = {
67         'carrier_id':fields.many2one("delivery.carrier","Carrier"),
68         'volume': fields.float('Volume'),
69         'weight': fields.function(_cal_weight, method=True, type='float', string='Weight',digits=(16, 6),
70                   store={
71                  'stock.picking': (lambda self, cr, uid, ids, c={}: ids, ['move_lines'], 20),
72                  'stock.move': (_get_picking_line, ['product_id','product_uos_qty'], 20),
73                  }),
74         }
75
76     def action_invoice_create(self, cursor, user, ids, journal_id=False,
77             group=False, type='out_invoice', context=None):
78         invoice_obj = self.pool.get('account.invoice')
79         picking_obj = self.pool.get('stock.picking')
80         carrier_obj = self.pool.get('delivery.carrier')
81         grid_obj = self.pool.get('delivery.grid')
82         invoice_line_obj = self.pool.get('account.invoice.line')
83
84         result = super(stock_picking, self).action_invoice_create(cursor, user,
85                 ids, journal_id=journal_id, group=group, type=type,
86                 context=context)
87
88         picking_ids = result.keys()
89         invoice_ids = result.values()
90
91         invoices = {}
92         for invoice in invoice_obj.browse(cursor, user, invoice_ids,
93                 context=context):
94             invoices[invoice.id] = invoice
95
96         for picking in picking_obj.browse(cursor, user, picking_ids,
97                 context=context):
98             if not picking.carrier_id:
99                 continue
100             grid_id = carrier_obj.grid_get(cursor, user, [picking.carrier_id.id],
101                     picking.address_id.id, context=context)
102             if not grid_id:
103                 raise osv.except_osv(_('Warning'),
104                         _('The carrier %s (id: %d) has no delivery grid!') \
105                                 % (picking.carrier_id.name,
106                                     picking.carrier_id.id))
107             invoice = invoices[result[picking.id]]
108             price = grid_obj.get_price_from_picking(cursor, user, grid_id,
109                     invoice.amount_untaxed, picking.weight, picking.volume,
110                     context=context)
111             account_id = picking.carrier_id.product_id.product_tmpl_id\
112                     .property_account_income.id
113             if not account_id:
114                 account_id = picking.carrier_id.product_id.categ_id\
115                         .property_account_income_categ.id
116
117             taxes = picking.carrier_id.product_id.taxes_id
118
119             partner_id=picking.address_id.partner_id and picking.address_id.partner_id.id or False
120             taxes_ids = [x.id for x in picking.carrier_id.product_id.taxes_id]
121             if partner_id:
122                 partner = picking.address_id.partner_id
123                 account_id = self.pool.get('account.fiscal.position').map_account(cursor, user, partner.property_account_position, account_id)
124                 taxes_ids = self.pool.get('account.fiscal.position').map_tax(cursor, user, partner.property_account_position, taxes)
125
126             invoice_line_obj.create(cursor, user, {
127                 'name': picking.carrier_id.name,
128                 'invoice_id': invoice.id,
129                 'uos_id': picking.carrier_id.product_id.uos_id.id,
130                 'product_id': picking.carrier_id.product_id.id,
131                 'account_id': account_id,
132                 'price_unit': price,
133                 'quantity': 1,
134                 'invoice_line_tax_id': [(6, 0,taxes_ids)],
135             })
136         return result
137
138 stock_picking()
139
140 # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
141