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