Ajout d'un attribut couleur pour chaque groupe d'article pour les graphiques
[bilio:bilio.git] / src / stat_articles.rb
1 # coding: utf-8
2
3 class Stat_articles_box < Gtk::VBox
4
5         def initialize window
6         
7                 super(false, 3)
8                 
9                 set_border_width 10
10                                 
11                 @window = window
12                 @login = window.login
13                 
14                 @style = 1
15                 @activer_combo = false
16                 
17                 @image_chargement = Gdk::Pixbuf.new "resources/icons/chargement.png"
18                 @image_nograph = Gdk::Pixbuf.new "resources/icons/nograph.png"
19                 
20                 agencement
21                 
22         end
23         
24         def agencement
25         
26                 @frame = Gtk::Frame.new
27                 @frame.label = "Statistiques"
28                 
29                 @vbox_corps = Gtk::VBox.new false, 3
30                 @frame.add @vbox_corps
31                 @vbox_corps.pack_start( en_tete, false, false, 3 )              
32                 @vbox_corps.pack_start( corps, true, true, 3 )          
33         
34                 self.add @frame
35         
36         end
37         
38         def en_tete
39         
40                 vbox = Gtk::VBox.new false, 3
41                 hbox1 = Gtk::HBox.new false, 3
42                 hbox2 = Gtk::HBox.new false, 3
43                 
44                 @annee = Gtk::ComboBox.new
45                 remplir_annee
46                 @annee.active = 0
47                 
48                 @recette = Gtk::ComboBox.new
49                 @recette.append_text "Recettes"
50                 @recette.append_text "Dépenses"
51                 @recette.active = 0
52                 
53                 @qtite = Gtk::ComboBox.new
54                 @qtite.append_text "Quantité"
55                 @qtite.append_text "CA"
56                 @qtite.active = 0
57                 
58                 @groupe_model = Gtk::TreeStore.new(Integer, String)
59                 @groupe = Gtk::ComboBox.new @groupe_model
60                 renderer_left = Gtk::CellRendererText.new
61                 @groupe.pack_start renderer_left, true
62                 @groupe.add_attribute renderer_left, "text", 1
63                 remplir_groupe
64                 
65                 @refresh = Gtk::Button.new
66                 @refresh.image = Gtk::Image.new "resources/icons/refresh.png"
67                 
68                 @graph_style_1 = Gtk::ToggleButton.new
69                 @graph_style_1.image = Gtk::Image.new "resources/icons/pie_1.png"
70                 @graph_style_1.tooltip_text = "Graphique plat"
71                 @graph_style_2 = Gtk::ToggleButton.new
72                 @graph_style_2.image = Gtk::Image.new "resources/icons/pie_2.png"
73                 @graph_style_2.tooltip_text = "Graphique 3D"
74                 @graph_style_3 = Gtk::ToggleButton.new
75                 @graph_style_3.image = Gtk::Image.new "resources/icons/pie_3.png"
76                 @graph_style_3.tooltip_text = "Graphique éclaté"
77                 case @style
78                         when 1
79                                 @graph_style_1.active = true
80                         when 2
81                                 @graph_style_2.active = true
82                         when 3
83                                 @graph_style_3.active = true
84                 end
85                 
86                 @annee.signal_connect('changed') {
87                         changement_filtre if @activer_combo
88                 }
89                 
90                 @recette.signal_connect('changed') {
91                         changement_filtre if @activer_combo
92                 }
93                 
94                 @qtite.signal_connect('changed') {
95                         changement_filtre if @activer_combo
96                 }
97                 
98                 @groupe.signal_connect('changed') {
99                         changement_filtre if @activer_combo
100                 }
101                 
102                 @refresh.signal_connect('clicked') {
103                         changement_filtre if @activer_combo
104                 }
105                 
106                 @graph_style_1.signal_connect('toggled') {
107                         if @graph_style_1.active?
108                                 @style = 1
109                                 @graph_style_2.active = false
110                                 @graph_style_3.active = false
111                                 changement_filtre if @activer_combo
112                         end
113                 }
114                 
115                 @graph_style_2.signal_connect('toggled') {
116                         if @graph_style_2.active?
117                                 @style = 2
118                                 @graph_style_1.active = false
119                                 @graph_style_3.active = false
120                                 changement_filtre if @activer_combo
121                         end
122                 }
123                 
124                 @graph_style_3.signal_connect('toggled') {
125                         if @graph_style_3.active?
126                                 @style = 3
127                                 @graph_style_2.active = false
128                                 @graph_style_1.active = false
129                                 changement_filtre if @activer_combo
130                         end
131                 }
132                 
133                 combo_sensitive false
134                 
135                 hbox1.pack_start( Gtk::Label.new("Année :"), false, false, 3)
136                 hbox1.pack_start( @annee, true, true, 3 ) 
137                 hbox1.pack_start( Gtk::Label.new("Recettes ou dépenses :"), false, false, 3)
138                 hbox1.pack_start( @recette, true, true, 3 ) 
139                 hbox1.pack_start( Gtk::Label.new("Qtité ou CA :"), false, false, 3)
140                 hbox1.pack_start( @qtite, true, true, 3 ) 
141                 hbox1.pack_start( Gtk::Label.new("Groupe :"), false, false, 3)
142                 hbox1.pack_start( @groupe, true, true, 3 ) 
143                 hbox1.pack_start( @refresh, false, false, 3)
144                 
145                 hbox2.add @graph_style_1
146                 hbox2.add @graph_style_3
147                 hbox2.add @graph_style_2
148                 
149                 align = Gtk::Alignment.new 1, 0, 0, 0
150                 align.add hbox2
151         
152                 vbox.add hbox1
153                 vbox.add align
154                 
155                 vbox
156         
157         end
158         
159         def corps
160                 
161                 @graph = Gtk::Image.new
162                 scroll = Gtk::ScrolledWindow.new
163                 scroll.set_policy(Gtk::POLICY_AUTOMATIC,Gtk::POLICY_AUTOMATIC)
164                 scroll.add_with_viewport @graph
165                 
166                 scroll
167         
168         end
169         
170         def refresh style=nil, groupe=0, annee=nil, recette=true, qtite=true
171                 
172                 combo_sensitive false
173                 @graph.pixbuf = @image_chargement
174                 @style=style unless style.nil?
175                 
176                 Thread.new {
177                 
178                         serie1 = []
179                         serie2 = []
180                         couleurs = []
181                 
182                         if groupe.eql?(0)
183                                 select_groupe = "(CASE WHEN T2.parent_id=0 THEN T2.id ELSE T2.parent_id END)"
184                                 where_groupe = "2>1"
185                         else
186                                 select_groupe = "T2.id"
187                                 where_groupe = "T2.parent_id=#{groupe}"
188                         end
189                         
190                         select_total = (qtite ? "SUM(T0.qtite*T0.colisage)" : "SUM(T0.total_ligne)")
191                 
192                         where_type = (recette ? "T3.documenttype_id=4" : "T3.documenttype_id=8")
193                 
194                         where_annee = (annee.nil? ? "EXTRACT(YEAR FROM T3.date_document)=#{@annee.active_text}" : "EXTRACT(YEAR FROM T3.date_document)=#{annee}")
195                 
196                         req =   "       
197                                                                 SELECT #{select_groupe} AS groupe, #{select_total} AS total
198                                                                 FROM documentlignes T0
199                                                                 INNER JOIN documents T3
200                                                                 ON T0.document_id=T3.id
201                                                                 INNER JOIN articles T1
202                                                                 ON T0.article_id=T1.id
203                                                                 LEFT JOIN articlegroupes T2
204                                                                 ON T1.articlegroupe_id=T2.id
205                                                                 WHERE #{where_type} AND #{where_groupe} AND #{where_annee}
206                                                                 GROUP BY groupe
207                                                                 ORDER BY groupe
208                                                         "
209                 
210                         res = Documentligne.find_by_sql(req)
211                 
212                         if res then
213                 
214                                         res.each {|row| 
215                                                 serie1 << row["total"].to_f
216                                                 if row["groupe"].nil? then
217                                                         serie2 << "Sans groupe"
218                                                 else
219                                                         g = Articlegroupe.find(row["groupe"].to_i)
220                                                         serie2 << g.designation
221                                                         if g.couleur.to_s.empty?
222                                                                 couleurs << [rand(0..255), rand(0..255), rand(0..255)]
223                                                         else
224                                                                 const = 0.003891051
225                                                                 c = g.couleur.to_s.match /#(....)(....)(....)/
226                                                                 couleurs << [(c[1].hex*const).ceil, (c[2].hex*const).ceil, (c[3].hex*const).ceil] 
227                                                         end
228                                                 end
229                                         }
230                                 
231                                         unless serie1.count<2
232                                                 x = @window.size[0]-40
233                                                 y = @window.size[1]-170
234                                                 gr = Graphique.new x, y, [{:titre => "total", :serie => serie1}, {:titre => "groupes", :serie => serie2}], @style, type=1, titre=nil, couleurs
235                                                 chemin = gr.graph
236                                                 @graph.file = chemin if File.exist?(chemin)
237                                         else
238                                                 @graph.pixbuf = @image_nograph
239                                         end
240                                 
241                         else
242                                 @graph.pixbuf = @image_nograph
243                         end
244                 
245                         combo_sensitive true
246                         @activer_combo = true
247                 
248                 }
249         
250         end
251                 
252         def remplir_groupe nom=nil
253                 
254                 @groupe.model.clear
255                 
256                 iter = @groupe_model.append nil
257                 iter[0] = 0
258                 iter[1] = "Tous"
259                 active_iter = iter
260                 
261                 groupesp = Articlegroupe.where(:parent_id => 0).order(:designation)
262                 
263                 if groupesp then
264                         groupesp.each do |gr|
265                                 gr_enfant = Articlegroupe.where(:parent_id => gr.id)
266                                 if gr_enfant.count>1
267                                         iter = @groupe_model.append nil
268                                         iter[0] = gr.id
269                                         iter[1] = gr.designation        
270                                         if !nom.nil?
271                                                 active_iter = iter if nom.eql?(gr.id)           
272                                         end
273                                 end
274                         end
275                 
276                         @groupe.active_iter = active_iter
277                 else
278                         @window.message_erreur groupesp.error
279                 end
280                 
281         end
282         
283         def changement_filtre
284                 annee = (@annee.active.eql?(-1) ? DateTime.now.strftime("%Y") : @annee.active_text)
285                 recette = (@recette.active.eql?(0) or @recette.active.eql?(-1))
286                 groupe = (@groupe.active_iter ? @groupe.model.get_value(@groupe.active_iter, 0) : 0)
287                 qtite = (@qtite.active.eql?(0) or @qtite.active.eql?(-1))
288                 
289                 refresh @style, groupe, annee, recette, qtite
290         end
291         
292         def combo_sensitive status
293                 @annee.sensitive = status
294                 @recette.sensitive = status
295                 @groupe.sensitive = status
296                 @refresh.sensitive = status
297                 @qtite.sensitive = status
298                 @graph_style_1.sensitive = status unless (status and @graph_style_1.active?)
299                 @graph_style_2.sensitive = status unless (status and @graph_style_2.active?)
300                 @graph_style_3.sensitive = status unless (status and @graph_style_3.active?)
301         end
302         
303         def remplir_annee
304                 
305                 doc = Document.find_by_sql("SELECT MIN(date_document) AS min, MAX(date_document) AS max FROM documents").first
306                 min = Date.parse(doc.min).year
307                 max = Date.parse(doc.max).year
308                 (min..max).to_a.reverse.each do |a|
309                         @annee.append_text a.to_s
310                 end
311                 
312         end
313         
314 end