Limites pour les quantités et les remises
[bilio:bilio.git] / document.rb
1 # coding: utf-8
2
3 class Document < Gtk::VBox
4
5         def initialize window
6         
7                 super(false, 3)
8                 
9                 set_border_width 10
10                 
11                 @window = window
12                 @db = window.db
13                 @login = window.login
14                 
15                 @id = 0
16                 @type = 0
17                 
18                 @ligne_modif_id = []
19                 
20                 @imprimer = Gtk::Button.new Gtk::Stock::PRINT
21                 @valider = Gtk::Button.new Gtk::Stock::OK
22                 @annuler = Gtk::Button.new Gtk::Stock::CANCEL
23                 
24                 agencement
25                 
26                 @valider.signal_connect( "clicked" ) { validate }
27                 @annuler.signal_connect( "clicked" ) { quit }
28                 @imprimer.signal_connect( "clicked" ) { imprimer }
29         
30         end
31         
32         def agencement
33         
34                 vbox = Gtk::VBox.new false, 3
35                 @frame = Gtk::Frame.new
36                 @frame.label = "Nouveau document"
37                 vbox.pack_start( @frame, true, true, 3 )
38                 
39                 vbox_corps = Gtk::VBox.new false, 3
40                 @frame.add vbox_corps
41                 vbox_corps.pack_start( en_tete, false, false, 3 )
42                 vbox_corps.pack_start( lignes, true, true, 3 )
43                 vbox_corps.pack_start( pieds, false, false, 3 )
44                 
45                 hbox_button = Gtk::HBox.new false, 2
46                 hbox3 = Gtk::HBox.new false, 2
47                 align0 = Gtk::Alignment.new 0, 0, 0, 0
48                 align0.add @imprimer
49                 align1 = Gtk::Alignment.new 1, 1, 0, 0
50                 hbox3.pack_start( @annuler, true, true, 3 )
51                 hbox3.pack_start( @valider, true, true, 3 )
52                 align1.add hbox3
53                 hbox_button.add align0
54                 hbox_button.add align1
55                 
56                 vbox.pack_start( hbox_button, false, false, 3 )
57                 
58                 self.add vbox
59         
60         end
61
62         def en_tete
63         
64                 # Objets
65                 @client = Gtk::Entry.new
66                 @date_document = Gtk::Calendar.new
67                 @date_livraison = Gtk::Calendar.new
68                 @label_livraison = Gtk::Label.new "Date de livraison :"
69                 @note = Gtk::TextView.new
70                 
71                 # Propriétés
72                 @date_livraison.day = @date_livraison.day+1
73                 
74                 # Agencement            
75                 table = Gtk::Table.new 4, 3, false
76                 
77                 table.attach( Gtk::Label.new("Client :"), 0, 1, 0, 1, Gtk::FILL, Gtk::FILL, 5, 5 )
78                 table.attach( @client, 1, 2, 0, 1, Gtk::EXPAND|Gtk::FILL, Gtk::FILL, 5, 5 )
79                 
80                 table.attach( Gtk::Label.new("Date du document :"), 2, 3, 0, 1, Gtk::FILL, Gtk::FILL, 5, 5 )
81                 table.attach( @date_document, 2, 3, 1, 3, Gtk::FILL, Gtk::FILL, 5, 5 )
82                 
83                 table.attach( @label_livraison, 3, 4, 0, 1, Gtk::FILL, Gtk::FILL, 5, 5 )
84                 table.attach( @date_livraison, 3, 4, 1, 3, Gtk::FILL, Gtk::FILL, 5, 5 )
85                 
86                 scroll_note = Gtk::ScrolledWindow.new
87                 scroll_note.add @note
88                 scroll_note.set_policy Gtk::POLICY_NEVER, Gtk::POLICY_AUTOMATIC
89                 scroll_note.shadow_type = Gtk::SHADOW_IN
90                 
91                 align_note = Gtk::Alignment.new 0, 0, 0, 0
92                 align_note.add Gtk::Label.new( "Note :" )
93                 
94                 table.attach( align_note, 0, 1, 1, 2, Gtk::FILL, Gtk::FILL, 5, 5 )
95                 table.attach( scroll_note, 0, 2, 2, 3, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 5, 5 )
96                 
97                 table
98         
99         end
100         
101         def lignes
102         
103                 @article_store = Gtk::ListStore.new(String)
104                 refresh_code_article
105                 
106                 # list_store (id, id_document, id_article, code, designation, qtite, id_tva, colisage, pu, remise, total_ligne)
107                 @list_store = Gtk::ListStore.new(Integer, Integer, Integer, String, String, Integer, Float, Integer, Float, Integer, Float)
108                 @view = Gtk::TreeView.new(@list_store)
109                 @view.signal_connect ("row-activated") { |view, path, column|
110                          #p @view.model.get_value(@view.selection.selected, 0)
111                 }
112                 
113                 # Create a renderer with the background property set
114                 renderer_center = Gtk::CellRendererText.new
115                 renderer_center.background = "white"
116                 renderer_center.xalign = 0.5
117                 renderer_center.mode = Gtk::CellRendererText::MODE_EDITABLE
118                 
119                 # Create a renderer with the background property set
120                 renderer_left = Gtk::CellRendererText.new
121                 renderer_left.xalign = 0
122                 renderer_left.mode = Gtk::CellRendererText::MODE_EDITABLE
123                 
124                 # Create a renderer with the background property set
125                 renderer_right = Gtk::CellRendererText.new
126                 renderer_right.xalign = 1
127                 renderer_right.mode = Gtk::CellRendererText::MODE_EDITABLE
128                 
129                 # Colonne pour le code article :
130                 renderer_code = Gtk::CellRendererCombo.new
131                 renderer_code.background = "white"
132                 renderer_code.model = @article_store
133                 renderer_code.text_column = 0
134                 renderer_code.xalign = 0
135                 renderer_code.has_entry = true
136                 renderer_code.mode = Gtk::CellRendererText::MODE_EDITABLE
137                 renderer_code.editable = true
138                 renderer_code.signal_connect('edited') { |combo, data, text|
139                         edit_cell(combo, data, text, 3)
140                 }  
141                 col = Gtk::TreeViewColumn.new("Code article", renderer_code, :text => 3)
142                 #col.sort_column_id = 3
143                 col.resizable = true
144                 @view.append_column(col)
145                 
146                 col = Gtk::TreeViewColumn.new("Désignation", renderer_left, :text => 4)
147                 #col.sort_column_id = 4
148                 col.resizable = true
149                 col.expand = true
150                 @view.append_column(col)
151                 
152                 # Colonne pour la quantité :
153                 renderer_qtite = Gtk::CellRendererSpin.new
154                 renderer_qtite.adjustment = Gtk::Adjustment.new(0, 0, 999999, 1, 10, 0)
155                 renderer_qtite.xalign = 1
156                 renderer_qtite.mode = Gtk::CellRendererText::MODE_EDITABLE
157                 renderer_qtite.editable = true
158                 renderer_qtite.signal_connect('edited') { |combo, data, text|
159                         edit_cell(combo, data, text, 5)
160                 } 
161                 col = Gtk::TreeViewColumn.new("Quantité", renderer_qtite, :text => 5)
162                 #col.sort_column_id = 5
163                 col.resizable = true
164                 @view.append_column(col)
165                 
166                 col = Gtk::TreeViewColumn.new("Colisage", renderer_right, :text => 7)
167                 #col.sort_column_id = 7
168                 col.resizable = true
169                 @view.append_column(col)
170                 
171                 col = Gtk::TreeViewColumn.new("Prix unitaire", renderer_right, :text => 8)
172                 #col.sort_column_id = 8
173                 col.resizable = true
174                 @view.append_column(col)
175                 
176                 # Colonne pour la remise :
177                 renderer_remise = Gtk::CellRendererSpin.new
178                 renderer_remise.adjustment = Gtk::Adjustment.new(0, 0, 100, 1, 10, 0)
179                 renderer_remise.xalign = 1
180                 renderer_remise.mode = Gtk::CellRendererText::MODE_EDITABLE
181                 renderer_remise.editable = true
182                 renderer_remise.signal_connect('edited') { |combo, data, text|
183                         edit_cell(combo, data, text, 9)
184                 } 
185                 col = Gtk::TreeViewColumn.new("Remise %", renderer_remise, :text => 9)
186                 #col.sort_column_id = 9
187                 col.resizable = true
188                 @view.append_column(col)
189                 
190                 col = Gtk::TreeViewColumn.new("Total ligne", renderer_right, :text => 10)
191                 #col.sort_column_id = 10
192                 col.resizable = true
193                 @view.append_column(col)
194                 
195                 col = Gtk::TreeViewColumn.new("TVA", renderer_center, :text => 6)
196                 #col.sort_column_id = 6
197                 col.resizable = true
198                 @view.append_column(col)
199                 
200                 scroll = Gtk::ScrolledWindow.new
201         scroll.set_policy(Gtk::POLICY_AUTOMATIC,Gtk::POLICY_AUTOMATIC)
202         scroll.add @view
203         
204         scroll
205         
206         end
207         
208         def pieds
209         
210                 @ht = Gtk::Entry.new
211                 @tva = Gtk::Entry.new
212                 @ttc = Gtk::Entry.new
213                 
214                 @ht.editable = false
215                 @ht.width_chars = 8
216                 @tva.editable = false
217                 @tva.width_chars = 8
218                 @ttc.editable = false
219                 @ttc.width_chars = 8
220         
221                 align = Gtk::Alignment.new 1, 0, 0, 0
222                 
223                 table = Gtk::Table.new 3, 2, false
224                 align.add table
225                 
226                 table.attach( Gtk::Label.new("HT :"), 0, 1, 0, 1, Gtk::FILL, Gtk::FILL, 2, 2 )
227                 table.attach( @ht, 1, 2, 0, 1, Gtk::EXPAND, Gtk::FILL, 2, 2 )
228                 
229                 table.attach( Gtk::Label.new("TVA :"), 0, 1, 1, 2, Gtk::FILL, Gtk::FILL, 2, 2 )
230                 table.attach( @tva, 1, 2, 1, 2, Gtk::EXPAND, Gtk::FILL, 2, 2 )
231                 
232                 table.attach( Gtk::Label.new("TTC :"), 0, 1, 2, 3, Gtk::FILL, Gtk::FILL, 2, 2 )
233                 table.attach( @ttc, 1, 2, 2, 3, Gtk::EXPAND, Gtk::FILL, 2, 2 )
234                 
235                 align
236         
237         end
238         
239         def refresh id, type
240         
241                 @id = id
242                 @type = type
243                 
244                 @ligne_modif_id = []
245                 
246                 @date_livraison.sensitive = type.eql?(3)
247                 
248                 if id>0 then
249                         @frame.label = @window.type_doc[type] + " n° #{id}" 
250                         
251                         req = "SELECT * FROM documents WHERE id=#{id}"
252                         res = @db.requete req
253                         
254                         remplir_en_tete res
255                         
256                         req = "SELECT T0.id, T0.id_document, T0.id_article, T0.code, T0.designation, T0.qtite, T0.id_tva, T0.colisage, T0.pu, T0.remise, T0.total_ligne FROM documents_lignes T0 WHERE id_document=#{id} ORDER BY T0.id"
257                         res = @db.requete req
258                         
259                         remplir_lignes res
260                         
261                         remplir_pieds
262                 else
263                         case type
264                                 when 1, 3
265                                         @frame.label = "Nouveau "
266                                 when 5
267                                         @frame.label = "Nouvel "
268                                 else
269                                         @frame.label = "Nouvelle "
270                         end
271                 
272                         @frame.label += @window.type_doc[type].downcase 
273                         
274                         empty_component
275                         @list_store.append
276                 end
277         
278         end
279         
280         def refresh_code_article
281                 
282                 @article_store.clear
283                 
284                 res = @db.requete "SELECT * FROM articles"
285                 
286                 res.each { |h| 
287                         
288                         iter = @article_store.append
289                         iter[0] = h['code']
290                 }
291
292         
293         end
294         
295         def remplir_en_tete res
296         
297                 date_document = ""
298                 date_livraison = ""
299                 res.each { |doc|
300                         @client.text = doc['client']
301                         date_document = doc['date_document']
302                         date_livraison = doc['date_livraison']
303                         @note.buffer.text = doc['note']
304                 }
305                 @date_document.select_month date_document.split("-")[1].to_i, date_document.split("-")[0].to_i
306                 @date_document.select_day date_document.split("-")[2].to_i
307                 
308                 @date_livraison.select_month date_livraison.split("-")[1].to_i, date_livraison.split("-")[0].to_i
309                 @date_livraison.select_day date_livraison.split("-")[2].to_i
310         
311         end
312         
313         def remplir_lignes res
314         
315                 @list_store.clear
316                 
317                 res.each { |h| 
318                         
319                         iter = @list_store.append
320                         iter[0] = h['id'].to_i
321                         iter[1] = h['id_document'].to_i
322                         iter[2] = h['id_article'].to_i
323                         iter[3] = h['code']
324                         iter[4] = h['designation']
325                         iter[5] = h['qtite'].to_i
326                         iter[6] = h['id_tva'].to_f
327                         iter[7] = h['colisage'].to_i
328                         iter[8] = h['pu'].to_f
329                         iter[9] = h['remise'].to_i
330                         iter[10] = h['total_ligne'].to_f
331                         
332                 }
333                 
334                 @list_store.append
335
336         end
337         
338         def remplir_pieds
339                 
340                 ht = 0.0
341                 tva = 0.0
342         
343                 @list_store.each { |model, path, iter|
344                         ligne = @view.model.get_iter(path)
345                         ht += ligne[10] unless ligne[10].nil?
346                         tva += ligne[10]*(ligne[6].to_f/100) unless ligne[10].nil? or ligne[6].nil? 
347                 }
348                 
349                 ht = ht.round(2)
350                 tva = tva.round(2)
351                 
352                 @ht.text = ht.to_s
353                 @tva.text = tva.to_s
354                 @ttc.text = (ht+tva).to_s
355                 
356         end
357         
358         def empty_component
359         
360                 @client.text = ""
361                 @date_document.year = DateTime.now.year
362                 @date_document.month = DateTime.now.month-1
363                 @date_document.day = DateTime.now.day
364                 @date_livraison.year = DateTime.now.year
365                 @date_livraison.month = DateTime.now.month-1
366                 @date_livraison.day = DateTime.now.day+1
367                 @note.buffer.text = ""
368                 
369                 @list_store.clear
370                 
371                 @ht.text = "0"
372                 @tva.text = "0"
373                 @ttc.text = "0"
374         
375         end
376         
377         def edit_cell combo, data, text, col
378         
379                 p text
380                 ligne = @view.model.get_iter(data)
381                 
382                 if !text.empty? then
383                         
384                         case col
385                         
386                                 when 3
387                                         
388                                         req = "SELECT * FROM articles WHERE code='#{text}'"
389                                         res = @db.requete req
390                                         
391                                         if res.count>0 then
392                                                 article = res.first
393                                                 
394                                                 @list_store.append if ligne[col].nil?
395                                                 ligne[col] = text
396                                                 
397                                                 ligne[2] = article['id'].to_i
398                                                 ligne[4] = article['designation']
399                                                 ligne[6] = article['id_tva'].to_f
400                                                 ligne[7] = article['colisage'].to_i
401                                                 ligne[8] = article['pu'].to_f
402                                                 ligne[5] = 1 if ligne[5].eql?(0)
403                                         
404                                         end
405                                 when 5
406                                         ligne[col] = text.to_i if text.to_i>=0
407                                 when 9
408                                         ligne[col] = text.to_i if (text.to_i>=0 and text.to_i<=100)
409                         
410                         end             
411                         
412                         calcule_total_ligne ligne
413                         
414                 end
415                 
416                 id_ligne = @view.model.get_iter(data)[0]
417                 @ligne_modif_id << id_ligne unless @ligne_modif_id.include?(id_ligne)
418                 
419         end
420         
421         def calcule_total_ligne ligne
422                 ligne[10] = ( ligne[5]*ligne[8]*( 1-ligne[9].to_f/100 ) ).round(2)
423                 remplir_pieds
424         end
425         
426         def imprimer
427                 
428         end
429         
430         def validate
431                 
432                 date_document = @date_document.year.to_s + "-" + (@date_document.month+1).to_s + "-" + @date_document.day.to_s
433                 date_livraison = @date_livraison.year.to_s + "-" + (@date_livraison.month+1).to_s + "-" + @date_livraison.day.to_s
434                         
435                 if @id>0 then
436                         req = "UPDATE documents SET "
437                         req += " client='#{@client.text.gsub("'", "''")}', date_document='#{date_document}', note='#{@note.buffer.text}', id_type_document=#{@type}, date_livraison='#{date_livraison}' "
438                         req += " WHERE id=#{@id}"
439                         
440                         if !@ligne_modif_id.empty? then
441                                 p @ligne_modif_id
442                                 
443                                 @list_store.each { |model, path, iter|
444                                         
445                                         id_ligne = @view.model.get_iter(path)[0]
446                                         
447                                         if ( @ligne_modif_id.include?(id_ligne) and !@view.model.get_iter(path)[3].nil? ) then
448                                         
449                                                 id_article = @view.model.get_iter(path)[2]
450                                                 code = @view.model.get_iter(path)[3].gsub("'", "''")
451                                                 designation = @view.model.get_iter(path)[4].gsub("'", "''")
452                                                 qtite = @view.model.get_iter(path)[5]
453                                                 id_tva = @view.model.get_iter(path)[6]
454                                                 colisage = @view.model.get_iter(path)[7]
455                                                 pu = @view.model.get_iter(path)[8]
456                                                 remise = @view.model.get_iter(path)[9]
457                                                 total_ligne = @view.model.get_iter(path)[10]
458                                                                 
459                                                 if id_ligne.eql?(0) then
460                                                         p "Insertion de ligne"
461                                                         req_ligne = "INSERT INTO documents_lignes (id_document, id_article, qtite, id_tva, colisage, pu, remise, code, designation, total_ligne) "
462                                                         req_ligne += " VALUES (#{@id}, #{id_article}, #{qtite}, '#{id_tva}', #{colisage}, "
463                                                         req_ligne += " '#{pu}', #{remise}, '#{code}', '#{designation}', '#{total_ligne}') "
464                                                 else
465                                                         p "Modification de ligne"
466                                                         req_ligne = "UPDATE documents_lignes SET "
467                                                         req_ligne += " id_article=#{id_article}, code='#{code}', designation='#{designation}', "
468                                                         req_ligne += " qtite=#{qtite}, id_tva='#{id_tva}', colisage=#{colisage}, pu='#{pu}', remise=#{remise}, total_ligne='#{total_ligne}' "
469                                                         req_ligne += " WHERE id=#{id_ligne} "
470                                                 end                             
471                                                 
472                                                 res = @db.requete req_ligne
473                                         
474                                         end
475                                         
476                                 }                               
477                                                                 
478                         end
479                         
480                 else                    
481                         p "Nouveau document"
482                         
483                         req = "INSERT INTO documents (client, date_document, note, id_type_document, date_livraison, id_user)"
484                         req += " VALUES ('#{@client.text.gsub("'", "''")}', '#{date_document}', '#{@note.buffer.text}', #{@type}, '#{date_livraison}', '#{@login.user.id}')"
485                 end
486                 
487                 res = @db.requete req
488                 
489                 if (res.empty? and @id.eql?(0)) then
490                 
491                         req = "SELECT id FROM documents ORDER BY id DESC LIMIT 1"
492                         res = @db.requete req
493                         
494                         @id = res.first['id']
495                         
496                         @list_store.each { |model, path, iter|
497                                         
498                                 if !@view.model.get_iter(path)[3].nil? then
499                                         
500                                         id_ligne = @view.model.get_iter(path)[0]
501                                         id_article = @view.model.get_iter(path)[2]
502                                         code = @view.model.get_iter(path)[3].gsub("'", "''")
503                                         designation = @view.model.get_iter(path)[4].gsub("'", "''")
504                                         qtite = @view.model.get_iter(path)[5]
505                                         id_tva = @view.model.get_iter(path)[6]
506                                         colisage = @view.model.get_iter(path)[7]
507                                         pu = @view.model.get_iter(path)[8]
508                                         remise = @view.model.get_iter(path)[9]
509                                         total_ligne = @view.model.get_iter(path)[10]
510                                                         
511                                         p "Insertion de ligne"
512                                         req_ligne = "INSERT INTO documents_lignes (id_document, id_article, qtite, id_tva, colisage, pu, remise, code, designation, total_ligne) "
513                                         req_ligne += " VALUES (#{@id}, #{id_article}, #{qtite}, '#{id_tva}', #{colisage}, "
514                                         req_ligne += " '#{pu}', #{remise}, '#{code}', '#{designation}', '#{total_ligne}') "
515                                         res = @db.requete req_ligne
516                                         
517                                 end
518                         }
519                 
520                 end
521                 
522                 quit @type
523         
524         end
525         
526         def quit statut=nil
527                 
528                 @window.liste_documents.refresh statut unless statut.nil?       
529                 @window.affiche @window.liste_documents
530         
531         end
532         
533 end