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