1 # -*- coding: utf-8 -*-
2 ##############################################################################
4 # OpenERP, Open Source Management Solution
5 # Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
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.
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.
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/>.
20 ##############################################################################
22 from report.render import render
23 from report.interface import report_int
25 from mx.DateTime import *
27 from datetime import datetime
28 from dateutil.relativedelta import relativedelta
30 from report.misc import choice_colors
40 # TODO: Bad code, seems buggy, TO CHECK !
43 class external_pdf(render):
44 def __init__(self, pdf):
47 self.output_type='pdf'
52 class report_custom(report_int):
53 def _compute_dates(self, time_unit, start, stop):
56 if time_unit == 'month':
58 a = Date(*map(int, start.split("-"))).year*12+Date(*map(int, start.split("-"))).month
59 z = Date(*map(int, stop.split("-"))).year*12+Date(*map(int, stop.split("-"))).month+1
66 months = {1:"January",2:"February",3:"March",4:"April",5:"May",6:"June",7:"July",8:"August",9:"September",10:"October",11:"November",12:"December"}
68 'name' :months[month],
69 'start':(datetime.date(year, month, 2) + relativedelta(day=1)).strftime('%Y-%m-%d'),
70 'stop' :(datetime.date(year, month, 2) + relativedelta(day=-1)).strftime('%Y-%m-%d'),
73 elif time_unit == 'week':
75 a = Date(*map(int, start.split("-"))).iso_week[0]*52+Date(*map(int, start.split("-"))).iso_week[1]
76 z = Date(*map(int, stop.split("-"))).iso_week[0]*52+Date(*map(int, stop.split("-"))).iso_week[1]
77 for i in range(a,z+1):
81 'name' :"Week #%d" % week,
82 'start':ISO.WeekTime(year, week, 1).strftime('%Y-%m-%d'),
83 'stop' :ISO.WeekTime(year, week, 7).strftime('%Y-%m-%d'),
86 else: # time_unit = day
88 a = Date(*map(int, start.split("-")))
89 z = Date(*map(int, stop.split("-")))
92 dates[map(int,i.strftime('%Y%m%d').split())[0]] = {
93 'name' :i.strftime('%Y-%m-%d'),
94 'start':i.strftime('%Y-%m-%d'),
95 'stop' :i.strftime('%Y-%m-%d'),
97 i = i + relativedelta(days=+1)
101 def create(self, cr, uid, ids, datas, context={}):
102 assert len(ids), 'You should provide some ids!'
103 colors = choice_colors(len(ids))
105 "SELECT MAX(mrp_production.date_planned) AS stop,MIN(mrp_production.date_planned) AS start "\
106 "FROM mrp_workcenter, mrp_production, mrp_production_workcenter_line "\
107 "WHERE mrp_production_workcenter_line.production_id=mrp_production.id "\
108 "AND mrp_production_workcenter_line.workcenter_id=mrp_workcenter.id "\
109 "AND mrp_production.state NOT IN ('cancel','done') "\
110 "AND mrp_workcenter.id IN %s",(tuple(ids),))
111 res = cr.dictfetchone()
113 res['stop'] = time.strftime('%Y-%m-%d %H:%M:%S')
115 res['start'] = time.strftime('%Y-%m-%d %H:%M:%S')
116 dates = self._compute_dates(datas['form']['time_unit'], res['start'][:10], res['stop'][:10])
117 dates_list = dates.keys()
120 for date in dates_list:
121 x_index.append((dates[date]['name'], date))
122 pdf_string = StringIO.StringIO()
123 can = canvas.init(fname=pdf_string, format='pdf')
124 chart_object.set_defaults(line_plot.T, line_style=None)
125 if datas['form']['measure_unit'] == 'cycles':
126 y_label = "Load (Cycles)"
128 y_label = "Load (Hours)"
129 ar = area.T(legend = legend.T(),
130 x_grid_style = line_style.gray70_dash1,
131 x_axis = axis.X(label="Periods", format="/a90/hC%s"),
132 x_coord = category_coord.T(x_index, 0),
133 y_axis = axis.Y(label=y_label),
136 bar_plot.fill_styles.reset();
140 "SELECT mw.id, rs.name FROM mrp_workcenter mw, resource_resource rs " \
141 "WHERE mw.id IN %s and mw.resource_id=rs.id " \
142 "ORDER BY mw.id" ,(tuple(ids),))
143 workcenters = cr.dictfetchall()
146 for date in dates_list:
148 for workcenter in workcenters:
149 cr.execute("SELECT SUM(mrp_production_workcenter_line.hour) AS hours, SUM(mrp_production_workcenter_line.cycle) AS cycles, \
150 resource_resource.name AS name, mrp_workcenter.id AS id \
151 FROM mrp_production_workcenter_line, mrp_production, mrp_workcenter, resource_resource \
152 WHERE (mrp_production_workcenter_line.production_id=mrp_production.id) \
153 AND (mrp_production_workcenter_line.workcenter_id=mrp_workcenter.id) \
154 AND (mrp_workcenter.resource_id=resource_resource.id) \
155 AND (mrp_workcenter.id=%s) \
156 AND (mrp_production.date_planned BETWEEN %s AND %s) \
157 GROUP BY mrp_production_workcenter_line.workcenter_id, resource_resource.name, mrp_workcenter.id \
158 ORDER BY mrp_workcenter.id", (workcenter['id'], dates[date]['start'] + ' 00:00:00', dates[date]['stop'] + ' 23:59:59'))
159 res = cr.dictfetchall()
163 if datas['form']['measure_unit'] == 'cycles':
164 vals.append(res[0]['cycles'] or 0.0)
166 vals.append(res[0]['hours'] or 0.0)
168 toto = [dates[date]['name']]
174 for workcenter in workcenters:
175 f = fill_style.Plain()
176 f.bgcolor = colors[workcenter_num]
177 ar.add_plot(bar_plot.T(label=workcenter['name'], data=data, fill_style=f, hcol=workcenter_num+1, cluster=(workcenter_num, len(res))))
180 if (not data) or (len(data[0]) <= 1):
181 ar = self._empty_graph(time.strftime('%Y-%m-%d'))
183 # close canvas so that the file is written to "disk"
185 self.obj = external_pdf(pdf_string.getvalue())
188 return (self.obj.pdf, 'pdf')
190 def _empty_graph(self, date):
192 ar = area.T(x_coord = category_coord.T(data, 0), y_range = (0, None),
193 x_axis = axis.X(label="Periods"),
194 y_axis = axis.Y(label="Load"))
195 ar.add_plot(bar_plot.T(data = data, label="No production order"))
198 report_custom('report.mrp.workcenter.load')
201 # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: