Petites correction et affichage du status payé/impayé dans l'entete des factures
[bilio:bilio.git] / document.rb
1 # coding: utf-8
2
3 class Document_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                 @id = 0
15                 @type = 0
16                 
17                 @ligne_modif_id = []
18                 @ligne_supp_id = []
19                 
20                 @imprimer = Gtk::Button.new
21                 hbox_imprimer = Gtk::HBox.new false, 2
22                 hbox_imprimer.add Gtk::Image.new( "./resources/icons/print.png" )
23                 hbox_imprimer.add Gtk::Label.new "Imprimer"
24                 @imprimer.add hbox_imprimer
25                 @valider = Gtk::Button.new
26                 hbox_valider = Gtk::HBox.new false, 2
27                 hbox_valider.add Gtk::Image.new( "./resources/icons/ok.png" )
28                 hbox_valider.add Gtk::Label.new "Valider"
29                 @valider.add hbox_valider
30                 @annuler = Gtk::Button.new
31                 hbox_annuler = Gtk::HBox.new false, 2
32                 hbox_annuler.add Gtk::Image.new( "./resources/icons/cancel.png" )
33                 hbox_annuler.add Gtk::Label.new "Annuler"
34                 @annuler.add hbox_annuler
35                 @transfert = Gtk::Button.new
36                 hbox_transfert = Gtk::HBox.new false, 2
37                 hbox_transfert.add Gtk::Image.new( "./resources/icons/transfert.png" )
38                 hbox_transfert.add Gtk::Label.new "Transférer"
39                 @transfert.add hbox_transfert
40                 
41                 agencement
42                 
43                 @valider.signal_connect( "clicked" ) { validate }
44                 @annuler.signal_connect( "clicked" ) { quit }
45                 @imprimer.signal_connect( "clicked" ) { imprimer }
46                 @transfert.signal_connect("clicked") { transfert }
47         
48         end
49         
50         def agencement
51         
52                 vbox = Gtk::VBox.new false, 3
53                 @frame = Gtk::Frame.new
54                 @frame.label = "Nouveau document"
55                 vbox.pack_start( @frame, true, true, 3 )
56                 
57                 vbox_corps = Gtk::VBox.new false, 3
58                 @frame.add vbox_corps
59                 vbox_corps.pack_start( en_tete, false, false, 3 )
60                 vbox_corps.pack_start( lignes, true, true, 3 )
61                 vbox_corps.pack_start( pieds, false, false, 3 )
62                 
63                 hbox_button = Gtk::HBox.new false, 2
64                 hbox2 = Gtk::HBox.new false, 2
65                 hbox2.pack_start( @imprimer, true, true, 3 )
66                 hbox2.pack_start( @transfert, true, true, 3 )
67                 hbox3 = Gtk::HBox.new false, 2
68                 align0 = Gtk::Alignment.new 0, 0, 0, 0
69                 align0.add hbox2
70                 align1 = Gtk::Alignment.new 1, 1, 0, 0
71                 hbox3.pack_start( @annuler, true, true, 3 )
72                 hbox3.pack_start( @valider, true, true, 3 )
73                 align1.add hbox3
74                 hbox_button.add align0
75                 hbox_button.add align1
76                 
77                 vbox.pack_start( hbox_button, false, false, 3 )
78                 
79                 self.add vbox
80         
81         end
82
83         def en_tete
84         
85                 # Objets
86                 @ref = ""
87                 @provenance = ""
88                 @id_client = 0
89                 @client = Gtk::Entry.new
90                 @id_tarif = 0
91                 @date_document = Gtk::Entry.new
92                 @date_livraison = Gtk::Entry.new
93                 @date_echeance = Gtk::Entry.new
94                 @label_livraison = Gtk::Label.new "Date de livraison :"
95                 @note = Gtk::TextView.new       
96                 @note_priv = Gtk::TextView.new          
97                 @tranfere = false
98                 @status = Gtk::Image.new "resources/icons/empty.png"
99                 @status.tooltip_text = ""
100                 
101                 # Propriétés
102                 @note.wrap_mode = Gtk::TextTag::WRAP_WORD
103                 @note.set_size_request(10, 60)
104                 @note_priv.wrap_mode = Gtk::TextTag::WRAP_WORD
105                 @note_priv.set_size_request(10, 60)
106                 @client.primary_icon_stock = Gtk::Stock::FIND
107                 @client.secondary_icon_stock = Gtk::Stock::CLEAR
108                 
109                 # Agencement            
110                 table = Gtk::Table.new 6, 3, false
111                 
112                 table.attach( Gtk::Label.new("Client :"), 0, 1, 0, 1, Gtk::FILL, Gtk::FILL, 5, 5 )
113                 table.attach( @client, 1, 4, 0, 1, Gtk::EXPAND|Gtk::FILL, Gtk::FILL, 5, 5 )
114                 
115                 table.attach( Gtk::Label.new("Date du document :"), 4, 5, 0, 1, Gtk::FILL, Gtk::FILL, 5, 5 )
116                 table.attach( @date_document, 5, 6, 0, 1, Gtk::FILL, Gtk::FILL, 5, 5 )
117                 
118                 table.attach( @label_livraison, 6, 7, 0, 1, Gtk::FILL, Gtk::FILL, 5, 5 )
119                 table.attach( @date_livraison, 7, 8, 0, 1, Gtk::FILL, Gtk::FILL, 5, 5 )
120                 
121                 table.attach( Gtk::Label.new("Date d'échéance :"), 8, 9, 0, 1, Gtk::FILL, Gtk::FILL, 5, 5 )
122                 table.attach( @date_echeance, 9, 10, 0, 1, Gtk::FILL, Gtk::FILL, 5, 5 )
123                 
124                 table.attach( @status, 10, 11, 0, 1, Gtk::FILL, Gtk::FILL, 5, 5 )
125                 
126                 @client.signal_connect('activate') { 
127                         if !@client.text.empty? then
128                                 vente = @window.type_doc[@type][:vente] ? 0 : 1
129                                 search = SearchTiers.new @window, @client.text, vente
130                                 search.run { |response| 
131                                         if ( !search.liste.view.selection.selected.nil? ) then
132                                                 @client.sensitive = false
133                                                 @client.text = search.liste.view.model.get_value( search.liste.view.selection.selected, 1 )
134                                                 @id_client = search.liste.view.model.get_value( search.liste.view.selection.selected, 0 )
135                                                 @id_tarif = search.liste.view.model.get_value( search.liste.view.selection.selected, 8 )
136                                         else
137                                                 @client.text = ""
138                                         end
139                                         search.destroy
140                                         focus_dernière_ligne unless @client.sensitive?
141                                 }
142                         end
143                 }
144                 
145                 #@date_document.signal_connect ("insert_text") { |entry, text| changement_condition_paiement }
146                 
147                 table
148         
149         end
150         
151         def lignes
152                 
153                 # list_store (id, id_document, id_article, code, designation, qtite, id_tva, colisage, pu, remise, total_ligne, tva, tva_taux, tva_np, commentaire, lot, qtite_orig)
154                 @list_store = Gtk::ListStore.new(Integer, Integer, Integer, String, String, Integer, Integer, Integer, String, Integer, String, String, Float, Integer, String, String, Integer)
155                 @view = Gtk::TreeView.new(@list_store)
156                 
157                 # Gestion du clic droit sur une ligne
158                 @view.signal_connect ("button-release-event") { |tree,event|
159                         if event.button.eql?(3)
160                                 npath = @view.get_path_at_pos(@view.pointer[0], @view.pointer[1]-30)
161                                 if !npath.nil? 
162                                         @view.set_cursor(npath[0], nil, false)
163                                         menu_modifie_article
164                                 end
165                         end
166                 }
167                 
168                 # Create a renderer with the background property set
169                 renderer_center = Gtk::CellRendererText.new
170                 renderer_center.background = "white"
171                 renderer_center.xalign = 0.5
172                 renderer_center.yalign = 0
173                 renderer_center.mode = Gtk::CellRendererText::MODE_EDITABLE
174                 
175                 # Create a renderer with the background property set
176                 renderer_left = Gtk::CellRendererText.new
177                 renderer_left.xalign = 0
178                 renderer_left.yalign = 0
179                 renderer_left.mode = Gtk::CellRendererText::MODE_EDITABLE
180                 
181                 # Create a renderer with the background property set
182                 renderer_right = Gtk::CellRendererText.new
183                 renderer_right.xalign = 1
184                 renderer_right.yalign = 0
185                 renderer_right.mode = Gtk::CellRendererText::MODE_EDITABLE
186                 
187                 # Create a renderer with the background property set
188                 renderer_right_bold = Gtk::CellRendererText.new
189                 renderer_right_bold.xalign = 1
190                 renderer_right_bold.yalign = 0
191                 renderer_right_bold.mode = Gtk::CellRendererText::MODE_EDITABLE
192                 renderer_right_bold.background = "#eee"
193                 
194                 # Colonne pour le code article :
195                 renderer_code = Gtk::CellRendererText.new
196                 renderer_code.xalign = 0
197                 renderer_code.yalign = 0
198                 renderer_code.mode = Gtk::CellRendererText::MODE_EDITABLE
199                 renderer_code.editable = true
200                 renderer_code.signal_connect('edited') { |combo, data, text|
201                         edit_cell(data, text, 3) 
202                 }  
203                 col = Gtk::TreeViewColumn.new("Code article", renderer_code, :text => 3)
204                 col.resizable = true
205                 @view.append_column(col)
206                 
207                 # Colonne pour la quantité :
208                 renderer_designation = Gtk::CellRendererText.new
209                 renderer_designation.xalign = 0
210                 renderer_designation.mode = Gtk::CellRendererText::MODE_EDITABLE
211                 renderer_designation.editable = true
212                 renderer_designation.signal_connect('edited') { |combo, data, text|
213                         if !text.empty? then
214                                 search = SearchArticles_box.new @window, text
215                                 search.run { |response| 
216                                         code = nil
217                                         if ( !search.liste.view.selection.selected.nil? and response.eql?(-5) )
218                                                 code = search.liste.view.model.get_value( search.liste.view.selection.selected, 1 )
219                                         end
220                                         search.destroy
221                                         add_article code, true unless code.nil?
222                                 }
223                         end
224                 }  
225                 col = Gtk::TreeViewColumn.new("Désignation", renderer_designation, :text => 4)
226                 col.resizable = true
227                 col.expand = true
228                 @view.append_column(col)
229                 
230                 renderer_commentaires = Gtk::CellRendererText.new
231                 renderer_commentaires.xalign = 0
232                 renderer_commentaires.mode = Gtk::CellRendererText::MODE_EDITABLE
233                 renderer_commentaires.editable = true
234                 renderer_commentaires.signal_connect('edited') { |combo, data, text|
235                         edit_cell(data, text, 14)
236                 }  
237                 col = Gtk::TreeViewColumn.new("Commentaires", renderer_commentaires, :text => 14)
238                 col.resizable = true
239                 col.expand = true
240                 @view.append_column(col)
241                 
242                 col = Gtk::TreeViewColumn.new("Lot / Série", renderer_left, :text => 15)
243                 col.resizable = true
244                 col.expand = true
245                 @view.append_column(col)
246                 
247                 # Colonne pour la quantité :
248                 renderer_qtite = Gtk::CellRendererSpin.new
249                 renderer_qtite.adjustment = Gtk::Adjustment.new(0, 0, 999999, 1, 10, 0)
250                 renderer_qtite.xalign = 1
251                 renderer_qtite.yalign = 0
252                 renderer_qtite.mode = Gtk::CellRendererText::MODE_EDITABLE
253                 renderer_qtite.editable = true
254                 renderer_qtite.signal_connect('edited') { |combo, data, text|
255                         edit_cell(data, text, 5)
256                 } 
257                 col = Gtk::TreeViewColumn.new("Quantité", renderer_qtite, :text => 5)
258                 #col.sort_column_id = 5
259                 col.resizable = true
260                 @view.append_column(col)
261                 
262                 # Colonne pour le colisage :
263                 renderer_colisage = Gtk::CellRendererSpin.new
264                 renderer_colisage.adjustment = Gtk::Adjustment.new(0, 0, 999999, 1, 10, 0)
265                 renderer_colisage.xalign = 1
266                 renderer_colisage.yalign = 0
267                 renderer_colisage.mode = Gtk::CellRendererText::MODE_EDITABLE
268                 renderer_colisage.editable = true
269                 renderer_colisage.signal_connect('edited') { |combo, data, text|
270                         edit_cell(data, text, 7)
271                 } 
272                 col = Gtk::TreeViewColumn.new("Colisage", renderer_colisage, :text => 7)
273                 col.resizable = true
274                 @view.append_column(col)
275                 
276                 # Colonne pour le PU :
277                 renderer_pu = Gtk::CellRendererSpin.new
278                 renderer_pu.adjustment = Gtk::Adjustment.new(0, 0, 999999, 1, 10, 0)
279                 renderer_pu.digits = 2
280                 renderer_pu.xalign = 1
281                 renderer_pu.yalign = 0
282                 renderer_pu.mode = Gtk::CellRendererText::MODE_EDITABLE
283                 renderer_pu.editable = true
284                 renderer_pu.signal_connect('edited') { |combo, data, text|
285                         edit_cell(data, text, 8)
286                 } 
287                 col = Gtk::TreeViewColumn.new("Prix unitaire", renderer_pu, :text => 8)
288                 #col.sort_column_id = 8
289                 col.resizable = true
290                 @view.append_column(col)
291                 
292                 # Colonne pour la remise :
293                 renderer_remise = Gtk::CellRendererSpin.new
294                 renderer_remise.adjustment = Gtk::Adjustment.new(0, 0, 100, 1, 10, 0)
295                 renderer_remise.xalign = 1
296                 renderer_remise.yalign = 0
297                 renderer_remise.mode = Gtk::CellRendererText::MODE_EDITABLE
298                 renderer_remise.editable = true
299                 renderer_remise.signal_connect('edited') { |combo, data, text|
300                         edit_cell(data, text, 9)
301                 } 
302                 col = Gtk::TreeViewColumn.new("Remise %", renderer_remise, :text => 9)
303                 col.resizable = true
304                 @view.append_column(col)
305                 
306                 col = Gtk::TreeViewColumn.new("Total ligne", renderer_right_bold, :text => 10)
307                 col.resizable = true
308                 @view.append_column(col)
309                 
310                 col = Gtk::TreeViewColumn.new("id TVA", renderer_center, :text => 6)
311                 col.resizable = true
312                 #@view.append_column(col)
313                 
314                 renderer_tva = Gtk::CellRendererCombo.new
315                 renderer_tva.xalign = 1
316                 renderer_tva.yalign = 0
317                 renderer_tva.editable = true            
318                 renderer_tva.model = modele_tva
319                 renderer_tva.text_column = 1
320                 renderer_tva.signal_connect('edited') { |combo, data, text|
321                         edit_cell(data, text, 11)
322                 } 
323                 col = Gtk::TreeViewColumn.new("TVA", renderer_tva, :text => 11)
324                 col.resizable = true
325                 @view.append_column(col)
326                 
327                 col = Gtk::TreeViewColumn.new("TVA taux", renderer_center, :text => 12)
328                 col.resizable = true
329                 #@view.append_column(col)
330                 
331                 col = Gtk::TreeViewColumn.new("TVA np ?", renderer_center, :text => 13)
332                 col.resizable = true
333                 #@view.append_column(col)
334                 
335                 col = Gtk::TreeViewColumn.new("Qtite orig", renderer_center, :text => 16)
336                 col.resizable = true
337                 #@view.append_column(col)
338                 
339                 scroll = Gtk::ScrolledWindow.new
340         scroll.set_policy(Gtk::POLICY_AUTOMATIC,Gtk::POLICY_AUTOMATIC)
341         scroll.add @view
342         
343         scroll
344         
345         end
346         
347         def modele_tva
348                 tvas = Tva.order(:id)
349                 tva_model = Gtk::ListStore.new(Integer, String, Float)
350                 tvas.each { |tva|
351                         iter = tva_model.append
352                         iter[0] = tva.id
353                         iter[1] = tva.designation
354                         iter[2] = tva.taux
355                 }       
356                 tva_model       
357         end
358         
359         def pieds
360         
361                 @ht = Gtk::Entry.new
362                 @tva = Gtk::Entry.new
363                 @ttc = Gtk::Entry.new
364                 @a_payer = Gtk::Entry.new
365                 
366                 @ht.editable = @tva.editable = @ttc.editable = @a_payer.editable = false
367                 @ht.width_chars = @tva.width_chars = @ttc.width_chars = @a_payer.width_chars = 8
368                 @ht.xalign = @tva.xalign = @ttc.xalign = @a_payer.xalign = 1
369                 
370                 @regler = Gtk::Button.new
371                 hbox_regler = Gtk::HBox.new false, 2
372                 hbox_regler.add Gtk::Image.new( "./resources/icons/document-send.png" )
373                 hbox_regler.add Gtk::Label.new "Régler"
374                 @regler.add hbox_regler
375                 @regler.signal_connect("clicked") { regler }
376                 
377                 @scan = Gtk::Button.new
378                 hbox_scan = Gtk::HBox.new false, 2
379                 hbox_scan.add Gtk::Image.new( "./resources/icons/scanner.png" )
380                 hbox_scan.add Gtk::Label.new "Scanner"
381                 @scan.add hbox_scan
382                 @scan.signal_connect("clicked") { scanner }
383                 
384                 @suppr_ged = Gtk::Button.new
385                 hbox_suppr_ged = Gtk::HBox.new false, 2
386                 hbox_suppr_ged.add Gtk::Image.new( "./resources/icons/trash-full.png" )
387                 hbox_suppr_ged.add Gtk::Label.new "Supprimer"
388                 @suppr_ged.add hbox_suppr_ged
389                 @suppr_ged.signal_connect("clicked") { supprime_ged }
390                 
391                 @nouveau_ged = Gtk::Button.new
392                 hbox_nouveau_ged = Gtk::HBox.new false, 2
393                 hbox_nouveau_ged.add Gtk::Image.new( "./resources/icons/document-new.png" )
394                 hbox_nouveau_ged.add Gtk::Label.new "Nouveau"
395                 @nouveau_ged.add hbox_nouveau_ged
396                 @nouveau_ged.signal_connect("clicked") {  }
397                 
398                 # Les réglements et le montants du pieds de page :
399                 table_montants = Gtk::Table.new 3, 2, false
400                 table_montants.attach( notebook, 0, 1, 0, 4, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 2, 2 )
401                 table_montants.attach( Gtk::Label.new("Réglements:"), 1, 2, 0, 1, Gtk::FILL, Gtk::FILL, 2, 2 )
402                 table_montants.attach( @regler, 1, 2, 1, 2, Gtk::FILL, Gtk::FILL, 2, 2 )
403                 table_montants.attach( table_reglements, 2, 3, 0, 4, Gtk::FILL, Gtk::FILL, 2, 2 )
404                 table_montants.attach( Gtk::Label.new("HT :"), 3, 4, 0, 1, Gtk::FILL, Gtk::FILL, 2, 2 )
405                 table_montants.attach( @ht, 4, 5, 0, 1, Gtk::FILL, Gtk::FILL, 2, 2 )
406                 table_montants.attach( Gtk::Label.new("TVA :"), 3, 4, 1, 2, Gtk::FILL, Gtk::FILL, 2, 2 )
407                 table_montants.attach( @tva, 4, 5, 1, 2, Gtk::FILL, Gtk::FILL, 2, 2 )
408                 table_montants.attach( Gtk::Label.new("TTC :"), 3, 4, 2, 3, Gtk::FILL, Gtk::FILL, 2, 2 )
409                 table_montants.attach( @ttc, 4, 5, 2, 3, Gtk::FILL, Gtk::FILL, 2, 2 )
410                 table_montants.attach( Gtk::Label.new("A PAYER :"), 3, 4, 3, 4, Gtk::FILL, Gtk::FILL, 2, 2 )
411                 table_montants.attach( @a_payer, 4, 5, 3, 4, Gtk::FILL, Gtk::FILL, 2, 2 )
412                 
413                 table_montants.set_column_spacing(0, 30)
414                 table_montants.set_column_spacing(2, 30)
415                 
416                 table_montants
417         
418         end
419         
420         def regler
421                 if validate(quit=false)
422                         popup = Saisie_reglement.new @window, @type, @id_client
423                         popup.run
424                         refresh @id, @type
425                 end
426         end 
427         
428         def table_reglements
429                                                                                         # id     date    type   montant         
430                 @list_paiement = Gtk::ListStore.new(Integer, String, String, String)
431                 table_paiement = Gtk::TreeView.new(@list_paiement)
432                 
433                 # Create a renderer with the background property set
434                 renderer_center = Gtk::CellRendererText.new
435                 renderer_right = Gtk::CellRendererText.new
436                 renderer_right.background = renderer_center.background = "white"
437                 renderer_center.xalign = 0.5
438                 renderer_right.xalign = 1
439                 renderer_right.yalign = renderer_center.yalign = 0
440                 
441                 col = Gtk::TreeViewColumn.new("ID", renderer_center, :text => 0)
442                 #table_paiement.append_column(col)
443                 
444                 col = Gtk::TreeViewColumn.new("Date", renderer_center, :text => 1)
445                 table_paiement.append_column(col)
446                 
447                 col = Gtk::TreeViewColumn.new("Type", renderer_center, :text => 2)
448                 table_paiement.append_column(col)
449                 
450                 col = Gtk::TreeViewColumn.new("Montant", renderer_right, :text => 3)
451                 table_paiement.append_column(col)
452                 
453                 scroll = Gtk::ScrolledWindow.new
454         scroll.set_policy(Gtk::POLICY_NEVER,Gtk::POLICY_AUTOMATIC)
455         scroll.add table_paiement
456                 
457                 scroll
458         end
459         
460         def ged
461                                                                                 # ID     Fichier  Miniature    Size
462                 @liste_ged = Gtk::ListStore.new(Integer, String, Gdk::Pixbuf, String)
463                 @table_ged = Gtk::TreeView.new(@liste_ged)
464                 
465                 @table_ged.signal_connect ("row-activated") { |view, path, column|
466                         if !@research then
467                                  fichier = @liste_ged.get_value(@table_ged.selection.selected, 1)
468                                  chemin = "#{@window.config_db.conf["chemin_documents"]}/documents/#{@id}/#{fichier}"
469                                  system "xdg-open", chemin
470                         end
471                 }
472                 
473                 # Create a renderer with the background property set
474                 renderer_left = Gtk::CellRendererText.new
475                 renderer_right = Gtk::CellRendererText.new
476                 renderer_left.background = renderer_right.background = "white"
477                 renderer_left.yalign = renderer_right.yalign = 0.5
478                 renderer_left.xalign = 0
479                 renderer_right.xalign = 1
480                 
481                 col = Gtk::TreeViewColumn.new("ID", renderer_left, :text => 0)
482                 #@table_ged.append_column(col)
483                 
484                 col = Gtk::TreeViewColumn.new("Fichier", renderer_left, :text => 1)
485                 col.expand = true
486                 @table_ged.append_column(col)   
487                 
488                 renderer_pix = Gtk::CellRendererPixbuf.new
489                 col = Gtk::TreeViewColumn.new
490                 col.title = "Aperçu"
491                 col.pack_start(renderer_pix, true)
492                 col.add_attribute(renderer_pix, 'pixbuf', 2)
493                 @table_ged.append_column(col)   
494                 
495                 col = Gtk::TreeViewColumn.new("Taille", renderer_right, :text => 3)
496                 @table_ged.append_column(col)
497                 
498                 scroll = Gtk::ScrolledWindow.new
499         scroll.set_policy(Gtk::POLICY_NEVER,Gtk::POLICY_AUTOMATIC)
500         scroll.add @table_ged
501                 
502                 scroll
503         end
504         
505         def scanner
506                 if validate(quitter=false)
507                         dial_scan = DialScan.new @window
508                         dial_scan.nom.text = @doc.ref2
509                         dial_scan.run { |response| 
510                                 if response.eql?(-5)
511                                         nom = (dial_scan.nom.text.empty? ? "scan" : dial_scan.nom.text.gsub(" ","_") )
512                                         mode = dial_scan.mode.active_text
513                                         @window.scan.acquisition nom, id=@doc.id, tiers=false, ext=".pdf", mode
514                                         refresh_ged
515                                 end
516                                 dial_scan.destroy                       
517                         }
518                 end
519         end
520         
521         # Suppression d'un fichier de la GED
522         def supprime_ged
523                 if @table_ged.selection.selected
524                         dialog = Gtk::MessageDialog.new(@window, 
525                                 Gtk::Dialog::DESTROY_WITH_PARENT,
526                                 Gtk::MessageDialog::QUESTION,
527                                 Gtk::MessageDialog::BUTTONS_YES_NO,
528                                 "Voulez-vous réellement supprimer ce fichier de la GED ?")
529                         response = dialog.run
530                         case response
531                           when Gtk::Dialog::RESPONSE_YES
532                                 id = @liste_ged.get_value(@table_ged.selection.selected, 0)
533                                 res = Geddocument.delete(id)
534                                 if res
535                                         fichier = @liste_ged.get_value(@table_ged.selection.selected, 1)
536                                         chemin = "#{@window.config_db.conf["chemin_documents"]}/documents/#{@id}/#{fichier}"
537                                         File.delete(chemin)
538                                         refresh_ged
539                                 end
540                         end 
541                         dialog.destroy
542                         
543                 end
544         end
545         
546         def remplir_liste_paiements
547                 reglements = Paiementdocument.where(:document_id => @id).order(:id)
548                 montant_regle = 0
549                 reglements.each { |r|
550                         iter = @list_paiement.append
551                         iter[0] = r.id
552                         iter[1] = r.paiement.date_paiement.strftime("%d/%m/%Y")
553                         iter[2] = r.paiement.paiementtype.designation
554                         iter[3] = "%.2f €" % r.montant
555                         montant_regle += r.montant
556                 }
557                 @a_payer.text = "%.2f €" % (@ttc.text.to_f-montant_regle)
558         end
559         
560         def notebook
561                 
562                 # Conteneurs
563                 notebook = Gtk::Notebook.new
564                 scroll_note1 = Gtk::ScrolledWindow.new
565                 scroll_note2 = Gtk::ScrolledWindow.new
566                 scroll_info = Gtk::ScrolledWindow.new
567                 table_ged = Gtk::Table.new 3, 2, false
568                 table_info = Gtk::Table.new 3, 2, false
569                 
570                 # Les objets
571                 @prov = Gtk::Entry.new
572                 conditionpaiement_model = Gtk::ListStore.new(Integer, String, String, Integer, Integer)
573                 @conditionpaiement = Gtk::ComboBox.new conditionpaiement_model
574                 @ref2 = Gtk::Entry.new
575                 label_provenance = Gtk::Alignment.new 0, 0.5, 0, 0
576                 label_provenance.add Gtk::Label.new("Provenance:")
577                 label_conditionpaiement = Gtk::Alignment.new 0, 0.5, 0, 0
578                 label_conditionpaiement.add Gtk::Label.new("Condition de paiement:")
579                 label_ref2 = Gtk::Alignment.new 0, 0.5, 0, 0
580                 label_ref2.add Gtk::Label.new("Référence secondaire:")
581
582                 # Propriétés des objets
583                 scroll_note1.set_policy Gtk::POLICY_NEVER, Gtk::POLICY_AUTOMATIC
584                 scroll_note1.shadow_type = Gtk::SHADOW_NONE
585                 scroll_note2.set_policy Gtk::POLICY_NEVER, Gtk::POLICY_AUTOMATIC
586                 scroll_note2.shadow_type = Gtk::SHADOW_NONE
587                 scroll_info.set_policy Gtk::POLICY_NEVER, Gtk::POLICY_AUTOMATIC
588                 scroll_info.shadow_type = Gtk::SHADOW_NONE
589                 @prov.editable = false
590                 renderer_conditionpaiement = Gtk::CellRendererText.new 
591                 @conditionpaiement.pack_start(renderer_conditionpaiement, true)
592                 @conditionpaiement.set_attributes(renderer_conditionpaiement, :text => 2)
593                 @conditionpaiement.signal_connect("changed") { changement_condition_paiement } 
594                 
595                 # Agencement des conteneurs Note
596                 scroll_note1.add @note
597                 scroll_note2.add @note_priv
598                 table_ged.attach( @scan, 0, 1, 0, 1, Gtk::FILL, Gtk::FILL, 2, 2 )
599                 table_ged.attach( @nouveau_ged, 0, 1, 1, 2, Gtk::FILL, Gtk::FILL, 2, 2 )
600                 table_ged.attach( @suppr_ged, 0, 1, 2, 3, Gtk::FILL, Gtk::FILL, 2, 2 )
601                 table_ged.attach( ged, 1, 2, 0, 3, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 2, 2 )
602                 
603                 # Agencement du conteneur Informations
604                 table_info.attach( label_ref2, 0, 1, 0, 1, Gtk::FILL, Gtk::FILL, 2, 2 )
605                 table_info.attach( @ref2, 1, 2, 0, 1, Gtk::FILL, Gtk::FILL, 2, 2 )
606                 table_info.attach( label_provenance, 2, 3, 0, 1, Gtk::FILL, Gtk::FILL, 2, 2 )
607                 table_info.attach( @prov, 3, 4, 0, 1, Gtk::FILL, Gtk::FILL, 2, 2 )
608                 table_info.attach( label_conditionpaiement, 0, 1, 1, 2, Gtk::FILL, Gtk::FILL, 2, 2 )
609                 table_info.attach( @conditionpaiement, 1, 2, 1, 2, Gtk::FILL, Gtk::FILL, 2, 2 )
610                 scroll_info.add_with_viewport table_info
611                 
612                 # Agencement du notebook
613                 notebook.append_page scroll_info, Gtk::Label.new("Informations")
614                 notebook.append_page table_ged, Gtk::Label.new("GED")
615                 notebook.append_page scroll_note1, Gtk::Label.new("Note publique")
616                 notebook.append_page scroll_note2, Gtk::Label.new("Note privée")
617
618                 # Renvoie
619                 notebook
620                 
621         end
622         
623         def changement_condition_paiement
624                 date_valide = false
625                 date_document = nil
626                 begin
627                         date_document = Date.parse(@date_document.text)
628                 rescue
629                         date_valide = false
630                 else
631                         date_valide = true
632                 end
633                 if date_valide
634                         begin
635                                 nb_jours = @conditionpaiement.model.get_value(@conditionpaiement.active_iter, 3) if @conditionpaiement.active_iter
636                                 fin_de_mois = @conditionpaiement.model.get_value(@conditionpaiement.active_iter, 4).eql?(1) if @conditionpaiement.active_iter
637                                 date = Date.parse(@date_document.text) + nb_jours
638                                 date = Date.new(date.year, date.month, -1) if fin_de_mois
639                                 @date_echeance.text = date.strftime("%d/%m/%Y")
640                         rescue
641                         end
642                 end
643         end
644         
645         def refresh id, type
646         
647                 @doc = nil
648                 @id = id        
649                 @type = type    
650                 @ligne_modif_id = []
651                 @ligne_supp_id = []             
652                 @date_livraison.sensitive = type.eql?(3)
653                 @list_paiement.clear
654                 
655                 if id>0 then
656                         
657                         @doc = Document.includes(:documenttype, :tiers).where(:id => id).first
658                         if @doc then
659                                 remplir_en_tete @doc
660                         end
661                         
662                         doclignes = Documentligne.where(:document_id => id).includes(:tva).order(:id)
663                         if doclignes then
664                                 remplir_lignes doclignes
665                         end
666                         
667                         remplir_pieds
668                 else
669                         @doc = Document.new
670                         @frame.label = nouveau_nouvelle type            
671                         @frame.label += @window.type_doc[type][:nom].downcase 
672                         empty_component
673                         @list_store.append
674                         @doc.montant_ttc = 0.0
675                         @doc.montant_regle = 0.0
676                 end
677                 
678                 refresh_ged
679                 @regler.sensitive = ([4,8].include?(@type) and (@doc.montant_regle<@doc.montant_ttc))
680                 remplir_conditionpaiement
681         
682         end
683         
684         def refresh_ged
685                 @liste_ged.clear
686                 ged = Geddocument.where(:document_id => @id).order(:fichier)
687                 ged.each { |g|
688                         iter = @liste_ged.append
689                         iter[0] = g.id
690                         iter[1] = g.fichier
691                         miniature = "#{File.basename(g.fichier, File.extname(g.fichier))}_miniature.jpg"
692                         chemin = "#{@window.config_db.conf["chemin_documents"]}/documents/#{@id}/#{miniature}"
693                         iter[2] = Gdk::Pixbuf.new(chemin, 25, 40) if File.exist?(chemin)
694                         chemin = "#{@window.config_db.conf["chemin_documents"]}/documents/#{@id}/#{g.fichier}"
695                         iter[3] = ("%.1f ko" % (File.size(chemin)/1000) ) if File.exist?(chemin)
696                 }
697         end
698         
699         def nouveau_nouvelle num
700                 texte = ""
701                 case num
702                         when 1, 3
703                                 texte = "Nouveau "
704                         when 5
705                                 texte = "Nouvel "
706                         else
707                                 texte = "Nouvelle "
708                 end
709                 texte
710         end
711         
712         def remplir_conditionpaiement
713                 @conditionpaiement.model.clear
714                 cond = Conditionpaiement.where(:actif => true).order(:id)
715                 active_iter = nil
716                 cond.each { |c|
717                         iter = @conditionpaiement.model.append
718                         iter[0] = c.id
719                         iter[1] = c.code
720                         iter[2] = c.designation
721                         iter[3] = c.nb_jours
722                         iter[4] = (c.fin_mois ? 1 : 0)
723                         active_iter = iter if @doc.conditionpaiement_id.eql?(c.id)
724                 }
725                 if active_iter
726                         @conditionpaiement.active_iter = active_iter
727                 else
728                         @conditionpaiement.active = 0
729                 end
730         end
731         
732         def remplir_en_tete doc
733         
734                 date_document = ""
735                 date_livraison = ""
736                 @id_client = doc.tiers_id
737                 @client.text = doc.tiers.nom
738                 @client.sensitive = false
739                 @id_tarif = doc.tarif_id
740                 date_document = doc.date_document.to_s
741                 date_livraison = doc.date_livraison.to_s
742                 date_echeance = doc.date_echeance.to_s
743                 @note.buffer.text = doc.note
744                 @note_priv.buffer.text = doc.note_priv
745                 @ref = doc.ref
746                 @transfere = doc.transfere
747                 @frame.label = @window.type_doc[@type][:nom] + " #{@ref}" 
748                 begin
749                         @date_document.text = Date.parse(date_document).strftime("%d/%m/%Y")
750                         @date_livraison.text = Date.parse(date_livraison).strftime("%d/%m/%Y")
751                         @date_echeance.text = Date.parse(date_echeance).strftime("%d/%m/%Y")
752                 rescue
753                 end
754                 @transfert.sensitive = (!@transfere and !@type.eql?(5) and !@type.eql?(8))
755                 remplir_liste_paiements 
756                 @provenance = @doc.provenance_ref
757                 @prov.text = @provenance ? @provenance : ""
758                 @ref2.text = @doc.ref2 ? @doc.ref2 : ""
759         end
760         
761         def remplir_lignes doclignes
762         
763                 @list_store.clear
764                 
765                 doclignes.each { |h| 
766                         
767                         iter = @list_store.append
768                         iter[0] = h.id
769                         iter[1] = h.document_id
770                         iter[2] = h.article_id
771                         iter[3] = h.code
772                         iter[4] = h.designation
773                         iter[5] = h.qtite
774                         iter[6] = h.tva_id
775                         iter[7] = h.colisage
776                         iter[8] = "%.2f" % h.pu
777                         iter[9] = h.remise
778                         iter[10] = "%.2f €" % h.total_ligne
779                         iter[11] = h.tva.designation.to_s
780                         iter[12] = h.tva.taux
781                         iter[13] = (h.tva.np ? 1 : 0)
782                         iter[14] = h.commentaires
783                         iter[15] = h.lot
784                         iter[16] = h.qtite
785                 }
786                 
787                 @list_store.append
788
789         end
790         
791         def remplir_pieds
792                 
793                 ht = 0.0
794                 tva = 0.0
795         
796                 @list_store.each { |model, path, iter|
797                         ligne = @view.model.get_iter(path)
798                         ht += ligne[10].to_f unless ligne[10].nil?
799                         tva += ligne[10].to_f*(ligne[12].to_f/100) unless ligne[10].nil? or ligne[12].nil? or ligne[13].eql?(1)
800                 }
801                 
802                 ht = ht.round(2)
803                 tva = tva.round(2)
804                 
805                 @ht.text = "%.2f €" % ht
806                 @tva.text = "%.2f €" % tva
807                 @ttc.text = "%.2f €" % (ht+tva).round(2)
808                 
809                 @a_payer.text = "%.2f €" % (@ttc.text.to_f-@doc.montant_regle)
810                 @regler.sensitive = true if @a_payer.text.to_f>0.0
811                 
812                 if @type.eql?(4) or @type.eql?(8)
813                         if (@a_payer.text.to_f.eql?(@ttc.text.to_f) and !@a_payer.text.to_f.eql?(0.0))
814                                 @status.set "resources/icons/impaye.png"
815                                 @status.tooltip_text = "Impayée"
816                         elsif @a_payer.text.to_f<@ttc.text.to_f
817                                 @status.set "resources/icons/partiel.png"
818                                 @status.tooltip_text = "Payée partiellement"
819                         else
820                                 @status.set "resources/icons/paye.png"
821                                 @status.tooltip_text = "Payée"
822                         end
823                 else
824                         @status.set "resources/icons/empty.png"
825                         @status.tooltip_text = ""
826                 end
827                 
828         end
829         
830         def empty_component entierement=true
831         
832                 @ref = ""
833                 @ref2.text = ""
834                 @provenance = "" if entierement
835                 @prov.text = "" if entierement
836                 @client.text = "" if entierement
837                 @client.sensitive = true if entierement
838                 @id_client = 0 if entierement
839                 if entierement
840                         t = Tarif.where(:vente => true, :default => true).first
841                         @id_tarif = t.id
842                 end
843                 date = DateTime.now
844                 @date_document.text = date.strftime("%d/%m/%Y")
845                 date += 1
846                 @date_livraison.text = ""
847                 @date_echeance.text = date.strftime("%d/%m/%Y")
848                 @note.buffer.text = "" if entierement
849                 @note_priv.buffer.text = "" if entierement
850                 @transfert.sensitive = (!@type.eql?(5) and !@type.eql?(8))
851                 
852                 @list_store.clear if entierement
853                 
854                 @ht.text = "0 €" if entierement
855                 @tva.text = "0 €" if entierement
856                 @ttc.text = "0 €" if entierement
857                 
858                 if !entierement #Si on est dans un transfert on vide la qtité initiale pour chaque article
859                         @list_store.each { |model, path, iter|
860                                 @view.model.get_iter(path)[16]=0
861                         }
862                 end
863                 
864                 @status.set "resources/icons/empty.png"
865                 @status.tooltip_text = ""
866         
867         end
868         
869         def edit_cell data, text, col
870         
871                 if (@doc.montant_regle<@doc.montant_ttc or @doc.montant_ttc.eql?(0.0))
872                         ligne = @view.model.get_iter(data)      
873                         if !text.empty? then
874                         
875                                 case col
876                         
877                                         when 3
878                                                 # Changement du code article
879                                                 add_article text                                        
880                                         when 4
881                                                 ligne[col] = text
882                                         when 5
883                                                 # Changement de quantité
884                                                 ligne[col] = text.to_i
885                                                 # On indique quel est la ligne qui a été modifiée
886                                                 @ligne_modif_id << ligne[0] unless @ligne_modif_id.include?(ligne[0])
887                                         when 7
888                                                 # Changement de colisage
889                                                 ligne[col] = text.to_i
890                                                 # On indique quel est la ligne qui a été modifiée
891                                                 @ligne_modif_id << ligne[0] unless @ligne_modif_id.include?(ligne[0])
892                                         when 8
893                                                 ligne[col] = text if text.to_f>=0.0
894                                                 # On indique quel est la ligne qui a été modifiée
895                                                 @ligne_modif_id << ligne[0] unless @ligne_modif_id.include?(ligne[0])
896                                         when 9
897                                                 ligne[col] = text.to_i if (text.to_i>=0 and text.to_i<=100)
898                                                 # On indique quel est la ligne qui a été modifiée
899                                                 @ligne_modif_id << ligne[0] unless @ligne_modif_id.include?(ligne[0])
900                                         when 11
901                                                 tva = Tva.where(:designation => text).first
902                                                 ligne[6] = tva.id
903                                                 ligne[11] = tva.designation.to_s
904                                                 ligne[12] = tva.taux
905                                                 ligne[13] = (tva.np ? 1 : 0)
906                                                 @ligne_modif_id << ligne[0] unless @ligne_modif_id.include?(ligne[0])
907                                         when 14
908                                                 # Ajout d'un commentaire
909                                                 ligne[col] = text
910                                                 @ligne_modif_id << ligne[0] unless @ligne_modif_id.include?(ligne[0])
911                                                 # On détermine le nombre de lignes
912                                                 i = -1
913                                                 @list_store.each { i += 1 }
914                                                 n = @view.selection.selected.path.to_s.to_i
915                                                 # Nouvelle ligne si on est sur une ligne de commentaire seul
916                                                 @list_store.append if ligne[2].eql?(0) and i.eql?(n)
917                                                 ligne[6] = 1 if ligne[6].eql?(0) # taux de tva à 0%
918                         
919                                 end             
920                                 calcule_total_ligne ligne
921                         else
922                                 # Suppresion de la ligne si le code article est vide
923                                 suppr_article ligne if col.eql?(3)
924                                 if col.eql?(14) then
925                                         ligne[col] = ""
926                                         @ligne_modif_id << ligne[0] unless @ligne_modif_id.include?(ligne[0])
927                                         # Si on est sur une ligne de commentaire libre, on supprime la ligne
928                                         suppr_article ligne if ligne[2].eql?(0)
929                                 end
930                                 remplir_pieds
931                         end
932                 else
933                         dialog = Gtk::MessageDialog.new(@window, 
934                                 Gtk::Dialog::DESTROY_WITH_PARENT,
935                                 Gtk::MessageDialog::ERROR,
936                                 Gtk::MessageDialog::BUTTONS_OK,
937                                 "Le document a déjà été réglé intégralement.\nAucune modification possible")
938                         dialog.run
939                         dialog.destroy
940                 end     
941                 
942         end
943         
944         def add_article code, recalcule=false
945                 
946                 ligne = @view.selection.selected
947                 
948                 # on vérifie si on prends un tarif d'achat ou de vente
949                 tarif = (@type.eql?(8) ? 3 : @id_tarif)
950                 
951                 ajout = true
952                 
953                 article = Article.includes(:tva).where("code=? OR gencode=? OR gencode2=?", code, code, code).first
954                         
955                 if article then         
956                         @list_store.append if ligne[3].nil?
957                         ligne[2] = article.id
958                         ligne[3] = article.code
959                         ligne[4] = article.description.to_s.empty? ? article.designation : "#{article.designation}\n#{article.description}"
960                         ligne[6] = article.tva_id
961                         ligne[7] = article.colisage
962                         at = Articletarif.where(:article_id =>  article.id, :tarif_id => tarif).first
963                         ligne[8] = "%.2f" % at.pu
964                         ligne[5] = 1 if ligne[5].eql?(0)
965                         ligne[11] = article.tva.designation
966                         ligne[12] = article.tva.taux
967                         ligne[13] = (article.tva.np ? 1 : 0)
968                         
969                         # Si l'article est géré par lot, on le demande tout de suite si on est sur un certain type de document
970                         ajout = verif_lot(article.id, ligne) if article.lot 
971                 
972                         if ajout then
973                                 calcule_total_ligne ligne if recalcule
974                 
975                                 # On indique quels sont les lignes qui ont été modifiées ou ajoutées
976                                 id_ligne = @view.selection.selected[0]
977                                 @ligne_modif_id << id_ligne unless @ligne_modif_id.include?(id_ligne)
978                                 
979                                 # on passe à la ligne
980                                 focus_dernière_ligne
981                         end
982
983                 end
984
985         end
986         
987         def focus_dernière_ligne
988                 # on trouve la dernière ligne du tableau
989                 npath = nil
990                 @view.model.each {|model, path, iter| 
991                         npath = path
992                 }
993                 # et on met le focus sur la première colonne.
994                 @view.set_cursor(npath, @view.get_column(0), true)
995         end
996         
997         def verif_lot article_id, ligne
998                 ajout = true
999         
1000                 if [4, 5].include?(@type)
1001                         search = SearchLots.new @window, article_id
1002                         search.run { |response| 
1003                                 if ( !search.liste.view.selection.selected.nil? and response.eql?(-5)) then
1004                                         ligne[15] = search.liste.view.model.get_value( search.liste.view.selection.selected, 1 )
1005                                 else
1006                                         suppr_article ligne
1007                                         ajout = false
1008                                 end
1009                                 search.destroy                  
1010                         }
1011                 elsif @type.eql?(8)
1012                         search = SaisieLot.new @window, article_id
1013                         search.run { |response| 
1014                                 if (!search.lot.text.empty? and response.eql?(-5))
1015                                         ligne[15] = search.lot.text
1016                                 else
1017                                         suppr_article ligne
1018                                         ajout = false
1019                                 end     
1020                                 search.destroy  
1021                         }
1022                 end
1023
1024                 return ajout
1025         end
1026         
1027         def suppr_article ligne
1028         
1029                 # Si la ligne était déjà enregistrée dans la base, on la marque à supprimer
1030                 @ligne_supp_id << ligne[0].to_i if ligne[0].to_i>0              
1031
1032                 # On réinitialise les valeurs des champs
1033                 ligne[0] = ligne[1] = ligne[2] = ligne[5] = ligne[16] = 0
1034                 ligne[3] = nil
1035                 ligne[4] = nil
1036                 ligne[6] = 1
1037                 ligne[8] = nil
1038                 ligne[14] = nil
1039                 ligne[7] = 1
1040                 
1041                 # On détermine le nombre de lignes
1042                 i = -1
1043                 @list_store.each { i += 1 }
1044                 n = @view.selection.selected.path.to_s.to_i
1045                 
1046                 # Puis on retire la ligne du tableau sauf si il s'agit de la dernière ligne
1047                 @list_store.remove @view.selection.selected unless i.eql?(n)
1048         
1049         end
1050         
1051         def calcule_total_ligne ligne
1052                 ligne[10] = "%.2f €" % ( ligne[5]*ligne[8].to_f*ligne[7]*( 1-ligne[9].to_f/100 ) ).round(2)
1053                 remplir_pieds
1054         end
1055         
1056         def imprimer
1057                 validate
1058                 Edition.new @doc.id
1059         end
1060         
1061         def validate quitter=true
1062         
1063                 date_document = Date.parse(@date_document.text).strftime("%Y-%m-%d")
1064                 date_livraison = @date_livraison.text.empty? ? "" : Date.parse(@date_livraison.text).strftime("%Y-%m-%d")
1065                 date_echeance =  Date.parse(@date_echeance.text).strftime("%Y-%m-%d")
1066                 tarif = @id_tarif
1067                 
1068                 res = !@id_client.eql?(0)  # Il faut qu'un client soit sélectionné pour pouvoir enregistrer le document !
1069                         
1070                 if res then
1071                         @ref = reference if @ref.empty?
1072                         @doc.tiers_id = @id_client
1073                         @doc.date_document = date_document
1074                         @doc.note = @note.buffer.text
1075                         @doc.note_priv = @note_priv.buffer.text
1076                         @doc.documenttype_id = @type
1077                         @doc.date_livraison = date_livraison
1078                         @doc.date_echeance = date_echeance
1079                         @doc.tarif_id = tarif
1080                         @doc.utilisateur_id = @login.user.id
1081                         @doc.montant_ht = @ht.text
1082                         @doc.montant_ttc = @ttc.text
1083                         @doc.ref = @ref
1084                         @doc.ref2 = @ref2.text
1085                         @doc.transfere = @tranfere
1086                         @doc.provenance_ref = @provenance
1087                         @doc.conditionpaiement_id = @conditionpaiement.model.get_value(@conditionpaiement.active_iter,0)
1088                         
1089                         res = @doc.save
1090                 else
1091                         erreur = "Vous devez sélectionner un client valide !"
1092                         dialog = Gtk::MessageDialog.new @window, Gtk::Dialog::MODAL, Gtk::MessageDialog::ERROR, Gtk::MessageDialog::BUTTONS_CLOSE, erreur
1093                         dialog.title = "Erreur"
1094                         dialog.signal_connect('response') { dialog.destroy }
1095                 dialog.run                               
1096                 end
1097                 
1098                 if res and !@ligne_modif_id.empty? then
1099                         
1100                         @list_store.each { |model, path, iter|
1101                                 
1102                                 if !@view.model.get_iter(path)[3].nil? or !@view.model.get_iter(path)[14].nil? then
1103                                         id_ligne = @view.model.get_iter(path)[0]
1104                                         id_article = @view.model.get_iter(path)[2]
1105                                         code = @view.model.get_iter(path)[3].to_s.gsub("'", "''")
1106                                         designation = @view.model.get_iter(path)[4].to_s.gsub("'", "''")
1107                                         qtite = @view.model.get_iter(path)[5]
1108                                         id_tva = @view.model.get_iter(path)[6].nil? ? "1" :  @view.model.get_iter(path)[6]
1109                                         colisage = @view.model.get_iter(path)[7]
1110                                         pu = @view.model.get_iter(path)[8].nil? ? 0 : @view.model.get_iter(path)[8]
1111                                         remise = @view.model.get_iter(path)[9]
1112                                         total_ligne = @view.model.get_iter(path)[10]
1113                                         commentaires = @view.model.get_iter(path)[14].to_s.gsub("'", "''")
1114                                         lot = @view.model.get_iter(path)[15].to_s.gsub("'", "''")
1115                                                 
1116                                         dl = nil
1117                                         if id_ligne>0 then
1118                                                 dl = Documentligne.find(id_ligne)
1119                                         else
1120                                                 dl = Documentligne.new
1121                                         end
1122                                         
1123                                         dl.document_id = @doc.id
1124                                         dl.article_id = id_article
1125                                         dl.qtite = qtite
1126                                         dl.tva_id = id_tva
1127                                         dl.colisage = colisage
1128                                         dl.pu = pu
1129                                         dl.remise = remise
1130                                         dl.code = code
1131                                         dl.designation = designation
1132                                         dl.total_ligne = total_ligne
1133                                         dl.commentaires = commentaires
1134                                         dl.lot = lot
1135                                         
1136                                         res = dl.save
1137                                         
1138                                         if res then
1139                                                 # Gestion des stocks
1140                                                 stock qtite, @view.model.get_iter(path)[16], id_article, lot
1141                                         end
1142                                 
1143                                 end
1144                                 
1145                         }
1146                         
1147                 end
1148                 
1149                 if res then 
1150                         # suppression en base des lignes supprimées dans le tableau
1151                         @ligne_supp_id.each { |l|                                                               
1152                                 dl = Documentligne.find(l)                              
1153                                 if dl then
1154                                         stock 0, dl.qtite, dl.article_id, dl.lot
1155                                         res = dl.destroy
1156                                         p "Suppresion de ligne : #{l}" if res
1157                                 end                             
1158                         }
1159                 end
1160                 
1161                 if res
1162                         if quitter
1163                                 quit @type
1164                         else
1165                                 refresh @doc.id, @type
1166                         end
1167                 end
1168                 return res      
1169         end
1170         
1171         def reference
1172                 num = Documenttype.find(@type)
1173                 if num then
1174                         d = num.dernier_num + 1
1175                         n = "%04d" % d
1176                         date_document = Date.parse(@date_document.text).strftime("%y%m")                        
1177                         ref = "#{num.code}#{date_document}-#{n}"
1178                         
1179                         res = num.increment!(:dernier_num)
1180                         
1181                         if res then
1182                                 return ref
1183                         else
1184                                 return ""
1185                         end
1186                 else
1187                         return ""
1188                 end
1189         end
1190         
1191         def stock qtite, qtite_orig, id_article, lot
1192                         
1193                 if [4,5,8].include?(@type) # Si on est sur une Facture ou un Avoir alors on modifie le stock
1194                         ajoute = [5,8].include?(@type) # Si on est sur un avoir ou une facture fournisseur, on ajoute, sinon on enlève 
1195                         change_stock qtite, qtite_orig, id_article, lot, ajoute
1196                 end     
1197                 
1198         end
1199         
1200         def change_stock qtite, qtite_orig, id_article, lot, ajoute
1201         
1202                 qtite_delta = qtite-qtite_orig
1203                 
1204                 stock = Articlestock.where(:article_id => id_article, :lot => lot).first
1205                 if stock then 
1206                         id_stock = stock.id
1207                         qtite_finale = ajoute ? stock.qtite+qtite_delta : stock.qtite-qtite_delta
1208                 else
1209                         stock = Articlestock.new
1210                         qtite_finale = ajoute ? qtite_delta : -qtite_delta 
1211                 end
1212         
1213                 stock.stock_id = 1
1214                 stock.lot = lot
1215                 stock.qtite = qtite_finale
1216                 stock.article_id = id_article
1217                 
1218                 p "nouveau stock = #{qtite_finale}"
1219                 
1220                 res = stock.save
1221         
1222         end
1223         
1224         def transfert
1225         
1226                 dialog = Gtk::MessageDialog.new(@window, 
1227                                 Gtk::Dialog::DESTROY_WITH_PARENT,
1228                                 Gtk::MessageDialog::QUESTION,
1229                                 Gtk::MessageDialog::BUTTONS_YES_NO,
1230                                 "Voulez-vous réellement transférer votre document en #{@window.type_doc[@type+1][:nom].downcase} ?")
1231                 response = dialog.run
1232                 case response
1233                         when Gtk::Dialog::RESPONSE_YES
1234                                 @tranfere = true
1235                                 validate quitter=false
1236                                 if validate(false) then
1237                                         @doc = Document.new
1238                                         @tranfere = false
1239                                         @provenance = @ref
1240                                         @prov.text = "Provenance : #{@provenance}" unless @provenance.empty?
1241                                         empty_component entierement=false
1242                                         @id=0
1243                                         @type = @type+1
1244                                         @frame.label = nouveau_nouvelle @type
1245                                         @frame.label += @window.type_doc[@type][:nom].downcase 
1246                         
1247                                         @list_store.each { |model, path, iter|
1248                                                 ligne = @view.model.get_iter(path)
1249                                                 ligne[0] = 0
1250                                                 @ligne_modif_id << ligne[0] unless @ligne_modif_id.include?(ligne[0])
1251                                         }
1252                                         
1253                                         @transfert.sensitive = (!@type.eql?(5) and !@type.eql?(8))
1254                                 end                     
1255                 end 
1256                 dialog.destroy  
1257         
1258         end
1259         
1260         def focus
1261                 @client.grab_focus
1262         end
1263         
1264         def menu_modifie_article
1265                 id = @view.model.get_value( @view.selection.selected, 2 )
1266                 code = @view.model.get_value( @view.selection.selected, 3 )
1267                 if id>0
1268                         modif_tb = Gtk::MenuItem.new "Modifier article #{code}"
1269                         modif_tb.signal_connect( "activate" ) { 
1270                                 dial_article = DialNewArticle.new @window, id
1271                                 dial_article.run { |response| 
1272                                         if response.eql?(-5)
1273                                                 dial_article.article_window.validate
1274                                         end
1275                                         dial_article.destroy
1276                                 }
1277                         }
1278                         menu = Gtk::Menu.new
1279                         menu.append modif_tb
1280                         menu.show_all
1281                         menu.popup(nil, nil, 0, 0)
1282                 end
1283         end
1284         
1285         def quit statut=nil
1286                 
1287                 @window.liste_documents.refresh statut unless statut.nil?       
1288                 @window.affiche @window.liste_documents
1289         
1290         end
1291         
1292 end