1
# -*- coding: utf-8 -*-
2
##############################################################################
4
# wms module for OpenERP, Agro-Business Specific extensions
5
# Copyright (C) 2012 SYLEAM Info Services (<http://www.syleam.fr/>)
6
# Sebastien LANGE <sebastien.lange@syleam.fr>
8
# This file is a part of wms
10
# wms is free software: you can redistribute it and/or modify
11
# it under the terms of the GNU Affero General Public License as published by
12
# the Free Software Foundation, either version 3 of the License, or
13
# (at your option) any later version.
15
# wms is distributed in the hope that it will be useful,
16
# but WITHOUT ANY WARRANTY; without even the implied warranty of
17
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18
# GNU Affero General Public License for more details.
20
# You should have received a copy of the GNU Affero General Public License
21
# along with this program. If not, see <http://www.gnu.org/licenses/>.
23
##############################################################################
25
from openerp.osv import osv
26
from openerp.osv import fields
27
from openerp.addons.decimal_precision import decimal_precision as dp
29
from datetime import date
30
from dateutil.rrule import MO, FR
31
from dateutil.relativedelta import relativedelta
32
from openerp.tools.translate import _
35
class stock_to_date(osv.osv_memory):
36
_name = 'stock.to.date'
37
_description = 'Stock to date by product'
38
_rec_name = 'product_id'
40
def compute_stock_to_date(self, cr, uid, ids, context=None):
42
Compute total quantity on lines
44
product_obj = self.pool.get('product.product')
45
line_obj = self.pool.get('stock.to.date.line')
46
self.write(cr, uid, ids, {'stock_to_date_line_ids': [(5,)]}, context=context)
48
for wizard in self.browse(cr, uid, ids, context=context):
50
if not wizard.warehouse_id:
51
wids = self.pool.get('stock.warehouse').search(cr, uid, [], context=context)
52
user = self.pool.get('res.users').browse(cr, uid, uid, context=context)
53
for w in self.pool.get('stock.warehouse').browse(cr, uid, wids, context=context):
54
if w.partner_address_id and w.partner_address_id.partner_id and user.company_id.partner_id == w.partner_address_id.partner_id:
55
warehouse_ids.append(w.id)
57
warehouse_ids.append(wizard.warehouse_id.id)
59
raise osv.except_osv(_('Warning !'), _('Please contact your administrator to configure warehouse in your profile.'))
60
tuple_warehouse_ids = tuple(warehouse_ids)
64
SELECT distinct(date_move), product_id, warehouse_id
66
SELECT r.date::date AS date_move, r.product_id, %s AS warehouse_id
67
FROM stock_move r LEFT JOIN product_uom u ON (r.product_uom=u.id)
68
WHERE state IN ('confirmed','assigned','waiting','done','reserved')
71
WITH RECURSIVE location(id, parent_id) AS (
72
SELECT id, location_id FROM stock_location WHERE id IN (SELECT lot_stock_id FROM stock_warehouse WHERE id IN %s)
74
SELECT sl.id, sl.location_id FROM stock_location sl, location
75
WHERE sl.location_id = location.id)
76
SELECT id FROM location)
77
AND location_dest_id NOT IN (
78
WITH RECURSIVE location(id, parent_id) AS (
79
SELECT id, location_id FROM stock_location WHERE id IN (SELECT lot_stock_id FROM stock_warehouse WHERE id IN %s)
81
SELECT sl.id, sl.location_id FROM stock_location sl, location
82
WHERE sl.location_id = location.id)
83
SELECT id FROM location)
84
AND r.date::date >= %s AND r.date::date <= %s
85
GROUP BY r.date::date, product_id, warehouse_id
87
SELECT r.date::date as date_move, r.product_id, %s AS warehouse_id
88
FROM stock_move r LEFT JOIN product_uom u on (r.product_uom=u.id)
89
WHERE state IN ('confirmed','assigned','waiting','done','reserved')
91
AND location_dest_id IN (
92
WITH RECURSIVE location(id, parent_id) AS (
93
SELECT id, location_id FROM stock_location WHERE id IN (SELECT lot_stock_id FROM stock_warehouse WHERE id IN %s)
95
SELECT sl.id, sl.location_id FROM stock_location sl, location
96
WHERE sl.location_id = location.id)
97
SELECT id FROM location)
98
AND location_id NOT IN (
99
WITH RECURSIVE location(id, parent_id) AS (
100
SELECT id, location_id FROM stock_location WHERE id IN (SELECT lot_stock_id FROM stock_warehouse WHERE id IN %s)
102
SELECT sl.id, sl.location_id FROM stock_location sl, location
103
WHERE sl.location_id = location.id)
104
SELECT id FROM location)
105
AND r.date::date >= %s and r.date::date <= %s
106
GROUP BY r.date::date, product_id, warehouse_id
108
ORDER BY date_move ASC
112
wizard.product_id.id,
118
wizard.product_id.id,
126
results = cr.fetchall()
127
today = date.today().strftime('%Y-%m-%d')
129
for result in results:
134
results.append((today, wizard.product_id.id, warehouse_ids))
135
for date_move, product_id, warehouse_ids in sorted(results):
137
if isinstance(warehouse_ids, (int, long)):
139
'warehouse': warehouse_ids,
141
elif warehouse_ids and len(warehouse_ids) == 1:
143
'warehouse': warehouse_ids[0],
146
'to_date': date_move + ' 23:59:59',
147
'compute_child': True,
151
'from_date': date_move + ' 00:00:00',
153
product = product_obj.browse(cr, uid, product_id, context=ctx)
154
product2 = product_obj.browse(cr, uid, product_id, context=ctx2)
155
line_obj.create(cr, uid, {
156
'stock_to_date_id': wizard.id,
158
'virtual_available': product.virtual_available,
159
'incoming_qty': product2.incoming_qty,
160
'outgoing_qty': product2.outgoing_qty * -1,
161
'color': date_move == today and True or False,
165
def _get_orderpoint(self, cr, uid, ids, field_name, args, context=None):
167
Get orderpoint for this product
169
orderpoint_obj = self.pool.get('stock.warehouse.orderpoint')
171
for wizard in self.browse(cr, uid, ids, context=context):
172
result[wizard.id] = orderpoint_obj.search(cr, uid, [('product_id', '=', wizard.product_id.id)], context=context)
175
def _get_report_stock(self, cr, uid, ids, field_name, args, context=None):
177
Get stock avalaible by location for this product
179
report_obj = self.pool.get('wms.report.stock.available')
181
for wizard in self.browse(cr, uid, ids, context=context):
182
result[wizard.id] = report_obj.search(cr, uid, [('usage', '=', 'internal'), ('product_id', '=', wizard.product_id.id)], context=context)
186
'product_id': fields.many2one('product.product', 'Product', required=True),
187
'uom_id': fields.related('product_id', 'uom_id', type='many2one', relation='product.uom', string='Default UoM'),
188
'date_from': fields.date('Date start', required=True, help='Date start to compute stock'),
189
'date_to': fields.date('Date End', required=True, help='Date end to compute stock'),
190
'stock_to_date_line_ids': fields.one2many('stock.to.date.line', 'stock_to_date_id', 'Line of stock to date', readonly=True),
191
'warehouse_id': fields.many2one('stock.warehouse', 'Warehouse', required=False),
192
'orderpoint_ids': fields.function(_get_orderpoint, method=True, string='OrderPoint', type='one2many', relation='stock.warehouse.orderpoint', store=False),
193
'report_stock_ids': fields.function(_get_report_stock, method=True, string='Stock Available', type='one2many', relation='wms.report.stock.available', store=False),
196
def default_get(self, cr, uid, fields_list, context=None):
198
Automatically populate fields and lines when opening the wizard from the selected stock move
202
product_obj = self.pool.get('product.product')
204
# Call to super for standard behaviour
205
values = super(stock_to_date, self).default_get(cr, uid, fields_list, context=context)
207
# Retrieve current stock move from context
208
product_id = 'default_product_id' in context and context['default_product_id'] or 'active_id' in context and context['active_id'] or False
209
orderpoint_obj = self.pool.get('stock.warehouse.orderpoint')
210
report_obj = self.pool.get('wms.report.stock.available')
211
#user_obj = self.pool.get('res.users')
212
#user = user_obj.browse(cr, uid, uid, context=context)
214
product = product_obj.browse(cr, uid, product_id, context=context)
217
values['product_id'] = product.id
218
values['stock_to_date_line_ids'] = []
219
orderpoint_ids = orderpoint_obj.search(cr, uid, [('product_id', '=', product_id)], context=context)
220
values['orderpoint_ids'] = orderpoint_obj.read(cr, uid, orderpoint_ids, [], context=context)
221
report_stock_ids = report_obj.search(cr, uid, [('usage', '=', 'internal'), ('product_id', '=', product_id)], context=context)
222
values['report_stock_ids'] = report_obj.read(cr, uid, report_stock_ids, [], context=context)
223
#if user.context_stock2date_start:
224
# values['date_from'] = (date.today() + relativedelta(weekday=MO(user.context_stock2date_start))).strftime('%Y-%m-%d')
225
#if user.context_stock2date_end:
226
# values['date_to'] = 'default_date_to' in context and context['default_date_to'] or (date.today() + relativedelta(weekday=FR(user.context_stock2date_end))).strftime('%Y-%m-%d')
232
class stock_to_date_line(osv.osv_memory):
233
_name = 'stock.to.date.line'
234
_description = 'Lines of stock to date'
238
'stock_to_date_id': fields.many2one('stock.to.date', 'Stock To Date'),
239
'date': fields.date('Date'),
240
'virtual_available': fields.float('Virtual', digits_compute=dp.get_precision('Product UoM')),
241
'incoming_qty': fields.float('Incoming', digits_compute=dp.get_precision('Product UoM')),
242
'outgoing_qty': fields.float('Outgoing', digits_compute=dp.get_precision('Product UoM')),
243
'color': fields.boolean('Color', help='Just for show color in today'),
244
'empty': fields.char(' ', size=1),
254
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: