diff --git a/lv/lv3100.cpp b/lv/lv3100.cpp
index b89554450..d9dbcdcef 100755
--- a/lv/lv3100.cpp
+++ b/lv/lv3100.cpp
@@ -2,6 +2,7 @@
 #include "../ve/veini.h"
 #include "../ve/veuml.h"
 #include "../ve/verig.h"
+#include "../ve/vepriv.h"
 
 #include "lv0.h"
 #include "lvlib.h"
@@ -12,62 +13,125 @@
 class TGestione_bolle_msk : public TDocumento_mask
 {
 protected:
+  static void arrotonda(const TMask& msk, real& quantita);
   static bool lv_bolla_handler(TMask_field& f, KEY k);
-  static bool lv_qta_handler(TMask_field& f, KEY k);
+  static bool lv_ritirato_handler(TMask_field& f, KEY k);
+  static bool lv_consegnato_handler(TMask_field& f, KEY k);
+  static bool lv_codart_handler(TMask_field& f, KEY k);
 public:
   virtual void user_set_handler( short fieldid, int index);
   virtual void user_set_row_handler(TMask& rm, short field, int index);
   TGestione_bolle_msk(const char* tipodoc) : TDocumento_mask(tipodoc) {}
 };
 
-bool TGestione_bolle_msk::lv_qta_handler(TMask_field& f, KEY k)
+void TGestione_bolle_msk::arrotonda(const TMask& msk, real& quantita)
+{
+  const TString& codart = msk.get(FR_CODART);
+  //instanzio una cache sulla tabella del magazzino
+  const TRectype& anamag = cache().get(LF_ANAMAG,codart);
+  //recupero i dati di interesse dall'anagrafica di magazzino
+  const long ppconf = anamag.get_long(ANAMAG_PPCONF);
+  if (ppconf > 0)
+  {
+    TDocumento_mask& dmsk = (TDocumento_mask&) msk.get_sheet()->mask();
+    
+    //recupero dal documento i dati di interesse per recuperare...
+    //...i dati dalla riga contratto
+    const long codcf = dmsk.get_long(F_CODCF);
+    const int indsped = dmsk.get_int(F_CODINDSP);
+    TDate datadoc = dmsk.get_date(F_DATADOC);
+    if (!datadoc.ok())
+      datadoc = TODAY;
+
+    const TLaundry_contract cont(codcf, indsped, datadoc);
+    //leggo la riga del contratto per l'articolo corrente
+    const TRectype& rcont = cont.row(codart);
+    //recupero i dati di interesse dalla riga del contratto
+    if (rcont.get_bool(LVRCONDV_ARROT))
+    {
+      //calcolo di quanti pezzi sforo
+      const long arr = quantita.integer() % ppconf;
+      //se sforo (arr > 0) allora calcolo quanti pezzi in pi� gli devo dare e aggiorno la quantit�
+      if (arr > 0)
+        quantita += ppconf - arr;
+    }
+  }
+}
+
+bool TGestione_bolle_msk::lv_ritirato_handler(TMask_field& f, KEY k)
 {
   if (f.to_check(k, false) && !f.empty())
   {
     TMask& msk = f.mask();
     if (msk.field(FR_QTA).empty())
     {
-      const int r = msk.get_sheet()->selected()+1;
-      TDocumento_mask& dmsk = (TDocumento_mask&) f.mask().get_sheet()->mask();
-      const TRiga_documento& rdoc = dmsk.doc()[r];
-      const TDocumento doc = rdoc.doc();
-
-      //recupero dal documento i dati di interesse per recuperare...
-      //...i dati dalla riga contratto
-      const long codcf = doc.get_long(DOC_CODCF);
-      const int indsped = doc.get_int(DOC_CODINDSP);
-      TDate datadoc = doc.get_date(DOC_DATADOC);
-      if (!datadoc.ok())
-        datadoc = TODAY;
-
-      const TLaundry_contract cont(codcf, indsped, datadoc);
-      //leggo la riga del contratto per l'articolo corrente
-      const TRectype& rcont = cont.row(msk.get(FR_CODART));
-      //recupero i dati di interesse dalla riga del contratto
-      const bool arrot = rcont.get_bool(LVRCONDV_ARROT);
-
       real ritirato = f.get();
-      if (arrot)
-      {
-        //instanzio una cache sulla tabella del magazzino
-        const TRectype& anamag = cache().get(LF_ANAMAG,msk.get(FR_CODART));
-        //recupero i dati di interesse dall'anagrafica di magazzino
-        const long ppconf = anamag.get_long(ANAMAG_PPCONF);
-        if (ppconf > 0)
-        {
-          //calcolo di quanti pezzi sforo
-          const long arr = ritirato.integer() % ppconf;
-          //se sforo (arr > 0) allora calcolo quanti pezzi in pi� gli devo dare e aggiorno la quantit�
-          if (arr > 0)
-            ritirato += ppconf - arr;
-        }
-      }
+      arrotonda(msk,ritirato);
       msk.set(FR_QTA,ritirato);
     }
   }
   return true;
 }
 
+bool TGestione_bolle_msk::lv_consegnato_handler(TMask_field& f, KEY k)
+{
+  bool ok = true;
+  switch(f.dlg())
+  {
+  case FR_QTA: ok = qta_handler( f, k ); break;
+  default: break;
+  }
+    
+  if (ok && f.to_check(k) && !f.empty())
+  {
+    TMask& msk = f.mask();
+    real ritirato = msk.get_real(FR_QTAGG1);
+    real consegnato = f.get();
+    arrotonda(msk, consegnato);
+    arrotonda(msk, ritirato);
+    if (consegnato.integer() != ritirato.integer() && 
+        !yesno_box(TR("Si desidera consegnare una quantita' di merce diversa da quella ritirata?")))
+      f.set(ritirato.string());
+    else
+      f.set(consegnato.string());
+  }
+  return ok;
+}
+
+bool TGestione_bolle_msk::lv_codart_handler(TMask_field& f, KEY k)
+{
+  bool ok = true;
+  switch(f.dlg())
+  {
+  case FR_CODART: ok = codart_handler( f, k ); break;
+  default: break;
+  }
+
+  if (ok && f.to_check(k))
+  {
+    TMask& msk = f.mask();
+    const TString& codart = msk.get(FR_CODART);
+
+    TDocumento_mask& dmsk = (TDocumento_mask&) msk.get_sheet()->mask();
+    
+    //recupero dal documento i dati di interesse per recuperare...
+    //...i dati dalla riga contratto
+    const long codcf = dmsk.get_long(F_CODCF);
+    const int indsped = dmsk.get_int(F_CODINDSP);
+    TDate datadoc = dmsk.get_date(F_DATADOC);
+    if (!datadoc.ok())
+      datadoc = TODAY;
+
+    const TLaundry_contract cont(codcf, indsped, datadoc);
+    
+    if (cont.row(codart).empty() && 
+        yesno_box(TR("L'articolo in esame non fa parte della dotazione standard di questo cliente."
+                     "Si desidera aggiungerla ai contratti?")))
+      cont.edit();
+  }
+  return ok;
+}
+
 bool TGestione_bolle_msk::lv_bolla_handler(TMask_field& f, KEY k)
 {
   bool ok = true;
@@ -179,7 +243,9 @@ void TGestione_bolle_msk::user_set_row_handler(TMask& rm, short field, int index
 {
   switch(index)
   {
-  case 4101: rm.set_handler(field, lv_qta_handler); break;
+  case 4101: rm.set_handler(field, lv_ritirato_handler); break;
+  case 4102: rm.set_handler(field, lv_consegnato_handler); break;
+  case 4103: rm.set_handler(field, lv_codart_handler); break;
   default  : TDocumento_mask::user_set_row_handler(rm, field, index); break;
   }
 }
diff --git a/lv/lvmenu.men b/lv/lvmenu.men
index 9f7587046..a0165227d 100755
--- a/lv/lvmenu.men
+++ b/lv/lvmenu.men
@@ -89,7 +89,7 @@ Caption = "Documenti"
 Picture = <ve01>
 Module  = 41
 Flags   = ""
-Item_01 = "Documenti di Trasporto", "ve0 -1 -filtI1=1 -defNUM_GEN,TIPODOC_GEN,lv", "F"
+Item_01 = "Documenti di Trasporto", "lv3 -0 -filtI1=1 -defNUM_GEN,TIPODOC_GEN,lv", "F"
 Item_02 = "Fatture", "ve0 -1 -filtI1=2 -defNUM_FAT,TIPODOC_FAT,lv", "F"
 Item_03 = "Ordini Fornitori", "ve0 -1 -filtI1=3 -defNUM_ORF,TIPODOC_ORF,lv", "F"
 Item_04 = "Ordini Clienti", "ve0 -1 -filtI1=3 -defNUM_ORC,TIPODOC_ORC,lv", "F"
diff --git a/lv/verig21.ini b/lv/verig21.ini
index 629a8069c..822433cc6 100755
--- a/lv/verig21.ini
+++ b/lv/verig21.ini
@@ -5,6 +5,8 @@ CAMPICALC=
 IMPONIBILE=IMPNS
 
 [HANDLERS]
-NHANDLER = 1
+NHANDLER = 3
 1 = 133|4101
+2 = 112|4102
+3 = 105|4103