//--------------------------------------------------------------------------- #include #include #pragma hdrstop #include "TpvProductos.h" #include "TpvProductosPrint1.h" #include "TDlgBuscar.h" #ifdef EXIST_CFG #include "TpvCFG.h" #endif //--------------------------------------------------------------------------- #pragma link "Grids" #pragma link "ElastFrm" #pragma resource "*.dfm" TProductos *Productos; //--------------------------------------------------------------------------- __fastcall TProductos::TProductos(TComponent* Owner) : TForm(Owner) { // Cargamos la imagen OK! try { BtmOK = new Graphics::TBitmap(); BtmOK -> LoadFromFile( ExtractFilePath(Application->ExeName) + "Systm\\ok.bmp" ); } catch (...) { ShowMessage( "Error: La imagen OK! está corrupta" ); } AArbol = true; TbProductos -> Active = true; TbProductos->FieldByName("I.V.A")->OnSetText = TbProductosIVASetText; TbProductosC -> Active = true; TbProdInfC -> Active = true; TbSeguimiento -> Active = true; // Cargar el dialogo, buscar Productos DlgBuscar = new TDlgBuscar(this); DlgBuscar -> TbBusquedas -> TableName = TbProductos -> TableName; DlgBuscar -> TbBusquedas -> Active = true; } //--------------------------------------------------------------------------- void __fastcall TProductos::TProductosIVASetText(TField *Sender, const AnsiString Text) { long IVA; IVA = Text.ToInt(); if ( IVA >= 0 && IVA <= 100) { TbProductos -> FieldByName("I.V.A") -> AsInteger = IVA; } } //--------------------------------------------------------------------------- void __fastcall TProductos::DBEdit11KeyUp(TObject *Sender, WORD &Key, TShiftState Shift) { if ( Key == VK_RETURN ) { DBEdit16 -> SetFocus(); } } //--------------------------------------------------------------------------- void __fastcall TProductos::DBEdit12KeyUp(TObject *Sender, WORD &Key, TShiftState Shift) { if ( Key == VK_RETURN ) { DBEdit17 -> SetFocus(); } } //--------------------------------------------------------------------------- void __fastcall TProductos::DBEdit13KeyUp(TObject *Sender, WORD &Key, TShiftState Shift) { if ( Key == VK_RETURN ) { DBEdit18 -> SetFocus(); } } //--------------------------------------------------------------------------- void __fastcall TProductos::DBEdit14KeyUp(TObject *Sender, WORD &Key, TShiftState Shift) { if ( Key == VK_RETURN ) { DBEdit19 -> SetFocus(); } } //--------------------------------------------------------------------------- void TProductos::CambiaEstadoCombinados(void) { if ( TbProductosCOMBINADO -> AsBoolean ) DBGrid2 -> Color = clWindow; else DBGrid2 -> Color = clBtnFace; } //--------------------------------------------------------------------------- void __fastcall TProductos::InfoProductosDataChange(TObject *Sender, TField *Field) { char BarraEstado[80]; // Campo no MODIFICABLE manualmente... if ( TbProductosEsNodo -> Value == -1 ) { // CodigosAsociados -> Enabled = false; ListPrecios -> Enabled = false; DBEdit15 -> Enabled = false; } else { // CodigosAsociados -> Enabled = true; ListPrecios -> Enabled = true; DBEdit15 -> Enabled = true; } // Panel de combinados: Encendido / Apagado CambiaEstadoCombinados(); if ( PageControl1->ActivePage == TabSheet2 ) { AnsiString RutaImagen = TbProductos -> FieldByName( "PathImagen" ) -> AsString; if ( FileExists( ExtractFilePath(Application->ExeName) + RutaImagen ) ) Image1->Picture->LoadFromFile( ExtractFilePath(Application->ExeName)+RutaImagen ); else Image1->Picture->LoadFromFile( ExtractFilePath(Application->ExeName) + "systm\\iErro.bmp" ); Image1->Left = ImgRef->Left; Image1->Top = ImgRef->Top; // Vemos si es mayor que el recuadro que la contiene... if ( Image1->Picture->Height > ImgRef->Height || Image1->Picture->Width > ImgRef->Width ) { // Reescalamos en ese caso if ( Image1->Picture->Height > Image1->Picture->Width ) { Image1->Height = ImgRef->Height; Image1->Width = (Image1->Picture->Width * ImgRef->Height ) / Image1->Picture->Height; Image1->Left += ( ImgRef->Width - Image1->Width ) / 2; } else { Image1->Width = ImgRef->Width; Image1->Height = (Image1->Picture->Height * ImgRef->Width ) / Image1->Picture->Width; Image1->Top += ( ImgRef->Height - Image1->Height ) / 2; } } else { Image1->Left += ( ImgRef->Width - Image1->Picture->Width ) / 2; Image1->Top += ( ImgRef->Height - Image1->Picture->Height ) / 2; Image1->Height = Image1->Picture->Height; Image1->Width = Image1->Picture->Width; } } // Indicador de FichaActual / Num.Fichas if ( InfoProductos -> DataSet -> RecNo > 0 ) sprintf( BarraEstado, "%d / %d", InfoProductos -> DataSet -> RecNo, InfoProductos -> DataSet -> RecordCount ); else sprintf( BarraEstado, "¿Nuevo? / %d", InfoProductos -> DataSet -> RecordCount ); // Edit1 -> Text = AnsiString::IntToHex( TbProductosFamilia -> AsInteger, 18 ) + ":" + AnsiString( (int) TbProductosForcedIndex -> AsInteger ); StatusBar1->Panels->Items[1]->Text = BarraEstado; } //--------------------------------------------------------------------------- void __fastcall TProductos::DBGrid1DrawColumnCell(TObject *Sender, const TRect &Rect, int DataCol, TColumn *Column, TGridDrawState State) { // Linea Roja para productos "Especiales" if ( Column -> ID != 0 && ( TbProductosEsNodo -> Value == -1 || ( TbProductos -> FieldByName("I.V.A") -> AsInteger == 100 && TbProductos -> FieldByName("Precio Costo") -> AsFloat == 0 ) ) ) { DBGrid1 -> Canvas -> Brush -> Color = clRed; DBGrid1 -> DefaultDrawColumnCell( Rect, DataCol, Column, State ); } // Precisa seguimiento ¿? if ( Column -> ID == 0 ) if ( TbProductos -> FieldByName("Seguimiento") -> AsBoolean ) { DBGrid1 -> Canvas -> StretchDraw( Rect, BtmOK ); } else { DBGrid1 -> Canvas -> Brush -> Color = clWindow; DBGrid1 -> Canvas -> FillRect( Rect ); } } //--------------------------------------------------------------------------- void __fastcall TProductos::DBGrid1KeyPress(TObject *Sender, char &Key) { if ( TbProductosEsNodo -> Value == -1 && DBGrid1 -> EditorMode ) { // Abortamos la edicion Key = 0; return; } switch( Key ) { case VK_RETURN: if ( DBGrid1 -> EditorMode ) { Key = 0; if ( DBGrid1 -> Fields[DBGrid1 -> SelectedIndex + 1] == NULL ) { DBGrid1 -> SelectedField = DBGrid1 -> Fields[0]; TbProductos -> Next(); if ( TbProductos -> Eof ) { TbProductos -> Append(); } } else DBGrid1 -> SelectedIndex++; } break; case '.': Key = ','; break; } } //--------------------------------------------------------------------------- void __fastcall TProductos::SpeedButton2Click(TObject *Sender) { Close(); } //--------------------------------------------------------------------------- void __fastcall TProductos::SpeedButton1Click(TObject *Sender) { TbProductos -> Insert(); } //--------------------------------------------------------------------------- void __fastcall TProductos::SpeedButton3Click(TObject *Sender) { TbProductos -> Delete(); } //--------------------------------------------------------------------------- void __fastcall TProductos::BusqAntClick(TObject *Sender) { if ( DlgBuscar->Buscar( PRIOR, TbProductos ) ) BusqSig -> Enabled = true; else BusqAnt -> Enabled = false; } //--------------------------------------------------------------------------- void __fastcall TProductos::BuscarFichaClick(TObject *Sender) { Indices -> Selected = Indices -> Items -> GetFirstNode(); TbProductos->Filtered = false; if ( DlgBuscar->Buscar( NEW, TbProductos ) ) { BusqSig -> Enabled = true; BusqAnt -> Enabled = true; } } //--------------------------------------------------------------------------- void __fastcall TProductos::BusqSigClick(TObject *Sender) { if ( DlgBuscar->Buscar( NEXT, TbProductos ) ) BusqAnt -> Enabled = true; else BusqSig -> Enabled = false; } //--------------------------------------------------------------------------- void __fastcall TProductos::SpeedButton7Click(TObject *Sender) { TInformesProducto *InformesProducto; InformesProducto = new TInformesProducto(this); InformesProducto -> ShowModal(); delete InformesProducto; } //--------------------------------------------------------------------------- int __fastcall TProductos::NuevoHeredero( TTreeNode *Padre, bool EsHijo ) { union { int FamiliaC; unsigned char Fam[4]; } Long_Char, Dev; bool Occupado[256]; // Creamos e inicializamos el for ( unsigned char i = 0; i <255; i++ ) // el vector de posiciones libres. Occupado[i] = false; short int PLevel; // Nivel del padre, y anterior PLevel = Padre -> Level + // Valor a devolver ( EsHijo ? 1 : 0 ); if ( Padre -> Data == NULL ) Dev . FamiliaC = 0; else Dev . FamiliaC = ( (int *)Padre -> Data )[0]; if ( PLevel < 0 || PLevel > 3 ) // Nivel no tratable (máx. 4) return 0; int pHijo, uHijo; pHijo = 0; uHijo = 255; //////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// #define GetFirstChild( Sender ) Indices->Items->Item[Sender->AbsoluteIndex+(Sender->AbsoluteIndex!=(Indices->Items->Count - 1)?1:0)] //////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// //#define GetFirstChild( Sender ) ( Sender ->getFirstChild()) // AÑADIR HIJOS (nos preparamos para... añadir un hermano) if ( EsHijo ) { // En caso de que estemos añadiendo un EL PRIMER HIJO if ( Padre -> HasChildren ) Padre = Padre -> getFirstChild(); else { Dev . Fam[ 4 - (PLevel + 1) ] = 1; return Dev . FamiliaC; } } // AÑADIR HERMANOS bool Enc = false; int N; uHijo = (Padre->Parent==NULL)? (Indices->Items->Count-2) : (Padre->Parent)->Count; // Cuantos hermanos son? if ( uHijo >= 255 ) // Uff, son demasiados Enc = false; else { // Encontramos la primera entrada libre // Obtengo el primer hijo... TTreeNodes try { Padre = (Padre->Parent==NULL) ? (Indices->Items->Item[2]) : ( Padre -> Parent ) -> getFirstChild(); } catch(...) { Padre = NULL; } while ( Padre != NULL ) { Long_Char . FamiliaC = ((int *)Padre->Data)[0]; Occupado[ Long_Char . Fam[ 4 - (PLevel+1) ] ] = true; Padre = Padre -> getNextSibling(); } // Comprobamos que el nº de iguales a este nivel, es menor del máximo permitido for ( N = 1; N < 255 && !Enc ; N++ ) if ( ! Occupado[ N ] ) { Enc = true; break; } } if ( Enc ) Dev . Fam[ 4 - (PLevel + 1) ] = N; else Dev . FamiliaC = 0; return Dev . FamiliaC; } //--------------------------------------------------------------------------- void __fastcall TProductos::FamiliaClick(TObject *Sender) { TTreeNode * NuevoNodo; int Familia; if ( ( Familia = NuevoHeredero( Indices -> Selected, false ) ) == 0 ) { ShowMessage( "Sobrepasó el nivel maximo de descendencia o hijos." ); return; } // Añadimos un nuevo nodo al primer nivel NuevoNodo = Indices->Items->Add(Indices->Selected, "Nueva Familia"); NuevoNodo -> Data = new int [3]; // NuevoNodo -> Text = AnsiString::IntToHex(Familia, 18); ((int *)NuevoNodo -> Data)[0] = Familia; ((int *)NuevoNodo -> Data)[1] = 0; // Establecemos las imágenes (Por defecto es documento final) NuevoNodo->ImageIndex = 2; NuevoNodo->SelectedIndex = 2; // Seleccionando el nuevo nodo como actual Indices->Selected = NuevoNodo; // Creamos un nuevo registro, él sera su familia y como padre... TbProductos -> InsertRecord( OPENARRAY( TVarRec, ( NULL, NULL, NULL, Familia, 0, -1, "Nueva Familia" ) ) ); ((int *)NuevoNodo -> Data)[2] = TbProductosForcedIndex -> AsInteger; NuevoNodo->EditText(); // y editamos el texto } //--------------------------------------------------------------------------- void __fastcall TProductos::SubFamiliaClick(TObject *Sender) { // int N; TTreeNode * NuevoNodo; // Si no hay un nodo seleccionado actualmente if (Indices->Selected == NULL || Indices->Selected->Data==NULL) // no podemos saber a qué libro se desea añadir ShowMessage("Seleccione antes la familia a la que añadir la SubFamilia."); else { // Para abarcar la segunda familia --> Nivel 7 ( 8 Anidamientos ) if ( Indices -> Selected -> Level < 3 ) { int Familia; if ( ( Familia = NuevoHeredero( Indices -> Selected, true ) ) == 0 ) { ShowMessage( "Sobrepasó el nivel maximo de descendencia o hijos" ); return; } // Obtenemos el índice absoluto del nodo seleccionado // N = Indices->Selected->AbsoluteIndex; // Añadimos un nuevo nodo estableciendo // el título y sus imágenes NuevoNodo = Indices->Items->AddChild(Indices->/*Items->Item[N]*/Selected, "Nueva SubFamilia"); NuevoNodo -> Data = new int [3]; // NuevoNodo -> Text = AnsiString::IntToHex(Familia, 18); ((int *)NuevoNodo -> Data)[0] = Familia; ((int *)NuevoNodo -> Data)[1] = 0; NuevoNodo->ImageIndex = 2; NuevoNodo->SelectedIndex = 2; // Expandimos el nodo al que se acaba // de añadir el capítulo Indices->/*Items->Item[N]*/Selected->Expand(false); // Seleccionamos el nuevo nodo como el actual Indices->Selected = NuevoNodo; // Creamos un nuevo registro, él sera su familia y como padre... TbProductos -> InsertRecord( OPENARRAY( TVarRec, ( NULL, NULL, NULL, Familia, 0, -1, "Nueva Familia" ) ) ); ((int *)NuevoNodo -> Data)[2] = TbProductosForcedIndex -> AsInteger; NuevoNodo->EditText(); // y editamos el título } else { MessageBox( 0, "Ha sobrepasado el nivel máximo de anidamiento o descendencias.", "¡Alerta!", MB_OK ); } } } //--------------------------------------------------------------------------- void __fastcall TProductos::IndicesCollapsing(TObject *Sender, TTreeNode *Node, bool &AllowCollapse) { // Si el nodo es padre if ( Node -> HasChildren ) { // Restauramos las imágenes originales Node->ImageIndex = 0; Node->SelectedIndex = 0; } else { // Un nodo no padre NO puede ser CONTRAIDO // Usamos las imágenes de los documentos Node->ImageIndex = 2; Node->SelectedIndex = 2; } } //--------------------------------------------------------------------------- void __fastcall TProductos::IndicesExpanding(TObject *Sender, TTreeNode *Node, bool &AllowExpansion) { // Si el nodo es padre if ( Node -> HasChildren ) { // Usamos las imágenes de los libros abiertos Node->ImageIndex = 1; Node->SelectedIndex = 1; } else { // Usamos las imágenes de los documentos Node->ImageIndex = 2; Node->SelectedIndex = 2; } } //--------------------------------------------------------------------------- void __fastcall TProductos::EliminarClick(TObject *Sender) { // Si hay un nodo seleccionado if (Indices->Selected != NULL && !( Indices -> Selected -> AbsoluteIndex < 2 ) ) { if ( MessageDlg( "Al eliminar esta familia y sus\ndescendientes, transladara los productos a\n\"No Catalogados\".", mtWarning, TMsgDlgButtons() << mbNo << mbYes, 0 ) != mrNo ) { AnsiString NombreCampo, NCampoAnterior; // Aqui hay que iniciar un translado de todos los campos while ( TbProductos -> RecordCount ) { if ( TbProductosEsNodo -> Value == -1 ) { AArbol = false; TbProductos -> Delete(); AArbol = true; } else { TbProductos -> Edit(); TbProductos -> FieldByName( "Familia" ) -> AsInteger = 0; TbProductos -> FieldByName( "Familia2" ) -> AsInteger = 0; TbProductos -> Post(); } } // y eliminar la existencia de la familia... Indices->Items->Delete(Indices->Selected); // lo eliminamos } } } //--------------------------------------------------------------------------- void __fastcall TProductos::TbProductosBeforeDelete(TDataSet *DataSet) { if ( !AArbol ) return; if ( TbProductosEsNodo->Value == -1 ) { ShowMessage( "Las Sub/Familias, deben ser\neliminadas desde el arbol." ); Abort(); } switch( MessageDlg( "Atención, está apunto de\neliminar un producto.\n¿Realmente desea continuar?", mtWarning, TMsgDlgButtons() << mbNo << mbYes, 0 ) ) { case mrNo: Abort(); break; default: break; }; while ( ! TbProductosC -> Eof ) TbProductosC -> Delete(); AnsiString ImgOrg, ImgDst; ImgOrg = ExtractFilePath(Application->ExeName) + TbProductos -> FieldByName( "PathImagen" ) -> AsString; if ( FileExists( ImgOrg ) ) { if (!DirectoryExists(ExtractFilePath(Application->ExeName) + "datos\\deleted-backup" )) CreateDir(ExtractFilePath(Application->ExeName) + "datos\\deleted-backup"); // Mover el fichero de sitio... ImgDst = ExtractFilePath(Application->ExeName) + "datos\\deleted-backup\\" + ExtractFileName( TbProductos->FieldByName( "PathImagen" )->AsString ); CopyFile(ImgOrg.c_str(), ImgDst.c_str(), True); DeleteFile(ImgOrg); } } //--------------------------------------------------------------------------- void __fastcall TProductos::TbProductosCalcFields(TDataSet *DataSet) { /* TbProductosValorStock -> Value = TbProductosStockActual -> Value * ( TbProductosCantUnitaria -> Value ) * TbProductosPrecioCosto -> Value; TbProductosBeneficioStock -> Value = TbProductosStockActual -> Value * ( TbProductosCantUnitaria -> Value ) * TbProductosPrecioVenta1 -> Value - TbProductosValorStock -> Value; */ } //--------------------------------------------------------------------------- void __fastcall TProductos::TbProductosNewRecord(TDataSet *DataSet) { // Si no hay un nodo seleccionado actualmente o estamos sobre productos sin catalogar... if ( Indices->Selected == NULL || Indices->Selected->Data == NULL ) { TbProductos -> FieldByName( "Familia" ) -> AsInteger = 0; TbProductos -> FieldByName( "Familia2" ) -> AsInteger = 0; TbProductos -> FieldByName( "EsNodo" ) -> AsInteger = 0; // El anterior... } else { TbProductos -> FieldByName( "Familia" ) -> AsInteger = ((int *) Indices -> Selected -> Data )[0]; TbProductos -> FieldByName( "Familia2" ) -> AsInteger = ((int *) Indices -> Selected -> Data )[0]; TbProductos -> FieldByName( "EsNodo" ) -> AsInteger = 0; } TbProductos -> FieldByName( "CantUnitaria" ) -> AsFloat = 1.0; } //--------------------------------------------------------------------------- void __fastcall TProductos::IndicesChange(TObject *Sender, TTreeNode *Node) { union { long Familia; char Fam[4]; } FamL, FamH; // Reajustamos el filtro, acuerdo a la nueva familia switch ( Indices -> Selected -> AbsoluteIndex ) { case 0: // TbProductos -> Filtered = false; // return; if ( Indices -> Selected -> Text == "Ver Todos" ) { TbProductos -> Filtered = false; return; } else { FamL . Familia = 0x00000000; FamH . Familia = 0x01000000; } break; case 1: // El filtro es para la familia 0000 FamL . Familia = 0x00000000; FamH . Familia = 0x01000000; break; default: // Contruimos los limites del filtro ( >= AND < ) FamL . Familia = ( (int *) Indices -> Selected -> Data ) [0]; FamH . Familia = FamL . Familia; if ( !FamH . Fam[3-1] ) FamH . Fam[3-0] ++; else if ( !FamH . Fam[3-2] ) FamH . Fam[3-1] ++; else if ( !FamH . Fam[3-3] ) FamH . Fam[3-2] ++; else FamH . Fam[3-3] ++; break; }; Edit1 -> Text = AnsiString::IntToHex( FamL . Familia, 18 ) + ":" + AnsiString( (int) 0 ); if (DBGrid1->SelectedRows->Count > 0) { if ( MessageDlg( "¿Seguro que desea mover los elementos seleccionados de familia?", mtWarning, TMsgDlgButtons() << mbNo << mbYes, 0 ) != mrNo ) { AnsiString s = ""; TDataSet *pDS = DBGrid1->DataSource->DataSet; for (int i=0; i < DBGrid1->SelectedRows->Count; i++) { pDS->GotoBookmark((void *)DBGrid1->SelectedRows->Items[i].c_str()); if ( pDS->FieldByName("EsNodo")->AsInteger != -1 ) { pDS->Edit(); pDS->FieldByName("Familia")->AsInteger = FamL.Familia; pDS->FieldByName("Familia2")->AsInteger = FamL.Familia; pDS->Post(); } } } DBGrid1->SelectedRows->Clear(); } // Filtramos según los rangos construidos antes... TbProductos->FilterOptions = TbProductos->FilterOptions << foCaseInsensitive; TbProductos->Filter = "([Familia] >= '" + AnsiString( (int)( FamL . Familia ) ) + "' AND [Familia] < '" + AnsiString( (int)( FamH . Familia ) ) + "')"; TbProductos -> Filtered = true; } //--------------------------------------------------------------------------- void __fastcall TProductos::IndicesDeletion(TObject *Sender, TTreeNode *Node) { delete [] Node -> Data; } //--------------------------------------------------------------------------- void __fastcall TProductos::TbProductosAfterOpen(TDataSet *DataSet) { TTreeNode * NuevoNodo; union { int Familia; // 0x01020304 char Fam[4]; // 0 1 2 3 } FamC; int N, MascaraComp; // Deshabilitamos los controles... TbProductos -> DisableControls(); // Reconstrucción del arbol... TbProductos -> First(); while ( ! TbProductos -> Eof ) { // Si es parte del arbol... if ( TbProductosEsNodo -> Value == -1 ) { FamC . Familia = TbProductosFamilia -> AsInteger; // Si es raiz, lo creamos directamente if ( FamC . Fam[3-1] != 0 ) { // De lo contrario, buscamos su posición NATURAL dentro del arbol. ////////////////////////////////////////////////////////////////// // Contruimos la mascara de comparación... if ( FamC . Fam[3-2] == 0 ) MascaraComp = FamC . Familia & 0xFF000000; else if ( FamC . Fam[3-3] == 0 ) MascaraComp = FamC . Familia & 0xFFFF0000; else MascaraComp = FamC . Familia & 0xFFFFFF00; N = 2; while ( N < Indices -> Items -> Count ) { if ( ((int *)Indices -> Items -> Item[N] -> Data ) [0] == MascaraComp ) { // Añadimos un nuevo nodo al primer nivel en que nos quedamos NuevoNodo = Indices->Items->AddChild( Indices -> Items -> Item[N], TbProductosNombredelProducto -> Value ); NuevoNodo -> Data = new int [3]; ((int *)NuevoNodo -> Data)[0] = FamC . Familia; ((int *)NuevoNodo -> Data)[1] = 0; ((int *)NuevoNodo -> Data)[2] = TbProductosForcedIndex -> AsInteger; break; } else N++; } } else { // Añadimos un nuevo nodo al primer nivel en que nos quedamos NuevoNodo = Indices->Items->Add( Indices -> Items -> Item[0], TbProductosNombredelProducto -> Value ); NuevoNodo -> Data = new int [3]; ((int *)NuevoNodo -> Data)[0] = FamC . Familia; ((int *)NuevoNodo -> Data)[1] = 0; ((int *)NuevoNodo -> Data)[2] = TbProductosForcedIndex -> AsInteger; } } // Avanzamos al siguiente registro TbProductos -> Next(); } N = 2; while ( N < Indices -> Items -> Count ) { // Establecemos las imágenes (Por defecto es documento final) if ( Indices -> Items -> Item[N] -> HasChildren ) { Indices -> Items -> Item[N]->ImageIndex = 0; Indices -> Items -> Item[N]->SelectedIndex = 0; } else { Indices -> Items -> Item[N]->ImageIndex = 2; Indices -> Items -> Item[N]->SelectedIndex = 2; } N++; } ///////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////// // ATENCIÖN, LA SIGUIENTE LINEA ES POR UN BUG DETECTADO EN EL TREEVIEW // ///////////////////////////////////////////////////////////////////////// NuevoNodo = Indices->Items->AddChild( Indices -> Items -> Item[0], "Bug TTreeView 1.1 Fixed" ); Indices -> Items -> Delete( NuevoNodo ); ///////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////// Indices -> Selected = Indices -> Items -> Item[1]; // Indices -> Items -> Item[0] -> Selected = true; // Rehabilitamos los controles... TbProductos -> EnableControls(); } //--------------------------------------------------------------------------- void __fastcall TProductos::IndicesEdited(TObject *Sender, TTreeNode *Node, AnsiString &S) { if ( Node -> Data == NULL ) return; // Guardamos la posición actual... TBookmark CurrentPos; CurrentPos = TbProductos -> GetBookmark(); // Localizamos el registro que hemos de cambiar... TLocateOptions SearchOptions; if ( TbProductos -> Locate( "ForcedIndex", ((int *)Node -> Data)[2], SearchOptions ) ) { // Actualizamos el nuevo valor del campo TbProductos -> Edit(); TbProductosNombredelProducto -> AsString = S; TbProductos -> Post(); } // ...Regresamos a la posición en la que estabamos TbProductos -> GotoBookmark( CurrentPos ); TbProductos -> FreeBookmark( CurrentPos ); } //--------------------------------------------------------------------------- void __fastcall TProductos::DBEdit16KeyUp(TObject *Sender, WORD &Key, TShiftState Shift) { if ( Key == VK_RETURN ) { DBEdit12 -> SetFocus(); } } //--------------------------------------------------------------------------- void __fastcall TProductos::DBEdit17KeyUp(TObject *Sender, WORD &Key, TShiftState Shift) { if ( Key == VK_RETURN ) { DBEdit13 -> SetFocus(); } } //--------------------------------------------------------------------------- void __fastcall TProductos::DBEdit18KeyUp(TObject *Sender, WORD &Key, TShiftState Shift) { if ( Key == VK_RETURN ) { DBEdit14 -> SetFocus(); } } //--------------------------------------------------------------------------- void __fastcall TProductos::DBEdit19KeyUp(TObject *Sender, WORD &Key, TShiftState Shift) { if ( Key == VK_RETURN ) { DBEdit15 -> SetFocus(); } } //--------------------------------------------------------------------------- void __fastcall TProductos::FormClose(TObject *Sender, TCloseAction &Action) { // Destruimos el dialogo de busquedas... delete DlgBuscar; // Destruimos la imagen de OK! delete BtmOK; try { if ( TbProductos -> State == dsInsert || TbProductos -> State == dsEdit ) TbProductos -> Post(); } catch(...) { // Algun error con el BDE } } //--------------------------------------------------------------------------- void __fastcall TProductos::IndicesDragDrop(TObject *Sender, TObject *Source, int X, int Y) { /* TTreeNode* AnItem = new TTreeNode( Indices -> Items ); TNodeAttachMode AttachMode; THitTests HT; if( Indices->Selected == NULL || Indices -> Selected -> Text == "Ver Todos" || Indices -> Selected -> Text == "Sin Clasificar" ) return; HT = Indices->GetHitTestInfoAt(X, Y); AnItem = Indices->GetNodeAt(X, Y); if ( AnItem -> Text == "Ver Todos" || AnItem -> Text == "Sin Clasificar" ) return; if ( HT.Contains(htOnItem) || HT.Contains(htOnIcon) || HT.Contains(htOnIndent) || HT.Contains(htNowhere) ) { AttachMode << naAdd; if( HT.Contains(htOnItem) || HT.Contains(htOnIcon) ) { AttachMode << naAddChild; ShowMessage( AnsiString( "Hijo de " + AnItem -> Text ).c_str() ); } if( HT.Contains(htNowhere) ) { AttachMode << naAdd; ShowMessage( "Añadir" ); } if(HT.Contains(htOnIndent)) { AttachMode << naInsert; ShowMessage( "Insertar" ); } Indices->Selected->MoveTo(AnItem, AttachMode); } */ } //--------------------------------------------------------------------------- void __fastcall TProductos::IndicesDragOver(TObject *Sender, TObject *Source, int X, int Y, TDragState State, bool &Accept) { Accept = true; } //--------------------------------------------------------------------------- void __fastcall TProductos::DBGrid1CellClick(TColumn *Column) { if ( Column -> ID == 0 ) { if ( ( TbProductos -> FieldByName("Seguimiento") -> AsBoolean ) ) { if ( MessageDlg( "Atención, está apunto de desactivar el\nseguimiento estadístico del producto....\n¿Realmente desea continuar?", mtWarning, TMsgDlgButtons() << mbNo << mbYes, 0 ) == mrNo ) return; // Sincronizamos y eliminamos los informes estadísticos... TbSeguimiento->First(); while ( ! TbSeguimiento->Eof ) TbSeguimiento->Delete(); } TbProductos -> Edit(); TbProductos -> FieldByName("Seguimiento") -> AsBoolean = !(TbProductos -> FieldByName("Seguimiento") -> AsBoolean); TbProductos -> Post(); } } //--------------------------------------------------------------------------- void __fastcall TProductos::DBGrid2DblClick(TObject *Sender) { // Localiza producto a circular DlgBuscar -> ShowModal(); if ( DlgBuscar -> ModalResult == mrOk ) { // Indices -> Selected = Indices -> Items -> Item[0]; // BusqSig -> Enabled = true; // BusqAnt -> Enabled = true; // Introducimos sus datos... if ( ! TbProductosC -> Locate( "CodProdE", DlgBuscar -> TbBusquedas -> FieldByName("ForcedIndex") -> AsInteger, TLocateOptions() ) ) { if ( TbProductos -> FieldByName("ForcedIndex") -> AsInteger != DlgBuscar -> TbBusquedas -> FieldByName("ForcedIndex") -> AsInteger ) TbProductosC -> InsertRecord( ARRAYOFCONST( ( TbProductos -> FieldByName("ForcedIndex") -> AsInteger, // Código a circular DlgBuscar -> TbBusquedas -> FieldByName("ForcedIndex") -> AsInteger, // Código circular 1 ) ) ); } } } //--------------------------------------------------------------------------- void __fastcall TProductos::TbProductosCAfterDelete(TDataSet *DataSet) { TbProductos -> Edit(); TbProductosCOMBINADO -> Value = TbProductosC -> RecordCount <= 0 ? false : true; TbProductos -> Post(); #ifdef DEM001 ShowMessage( "Esta función ha sido deshabilitada para esta versión.\nPongase en contacto con el autor, si desea\nel módulo correspondiente: Jose-David.Guillen@cs.us.es" ); #endif } //--------------------------------------------------------------------------- void __fastcall TProductos::DBGrid1Exit(TObject *Sender) { DBGrid1->Options << dgRowSelect << dgAlwaysShowSelection; } //--------------------------------------------------------------------------- void __fastcall TProductos::DBGrid1Enter(TObject *Sender) { DBGrid1->Options >> dgRowSelect >> dgAlwaysShowSelection; } //--------------------------------------------------------------------------- void __fastcall TProductos::DBGrid2Enter(TObject *Sender) { #ifdef DEM001 ShowMessage( "Esta función ha sido deshabilitada para esta versión.\nPongase en contacto con el autor, si desea\nel módulo correspondiente: Jose-David.Guillen@cs.us.es" ); #endif if ( TbProductos -> State == dsInsert || TbProductos -> State == dsEdit ) TbProductos -> Post(); } //--------------------------------------------------------------------------- void __fastcall TProductos::TbProductosCantUnitariaChange(TField *Sender) { if ( TbProductosSeguimiento->AsBoolean ) ActualizaHistorico(); } //--------------------------------------------------------------------------- void __fastcall TProductos::TbProductosPrecioCostoChange(TField *Sender) { if ( TbProductosSeguimiento->AsBoolean ) ActualizaHistorico(); } //--------------------------------------------------------------------------- void __fastcall TProductos::TbProductosPrecioVenta1Change(TField *Sender) { if ( TbProductosSeguimiento->AsBoolean ) ActualizaHistorico(); } //--------------------------------------------------------------------------- void __fastcall TProductos::ActualizaHistorico(void) { TDateTime FechActual; FechActual = TDateTime::CurrentDate(); // Calculamos el precio de costo UNITARIO del producto Currency PrecioCosto = TbProductos->FieldByName("CantUnitaria")->AsCurrency; if ( PrecioCosto < 1 ) PrecioCosto = 1; PrecioCosto *= TbProductos->FieldByName("Precio Costo")->AsCurrency; TbSeguimiento->Last(); // Nos posicionamos en el ultimo seguimiento // Solo si el últ. seguimiento corresponde a este momento... if ( TbSeguimiento->FieldByName("Fecha")->AsDateTime == FechActual ) { // ...actualizamos TbSeguimiento->Edit(); TbSeguimiento->FieldByName("Precio Costo")->AsCurrency = PrecioCosto; TbSeguimiento->FieldByName("Precio Venta")->AsCurrency = TbProductos->FieldByName("Precio Venta 1")->AsCurrency; TbSeguimiento->Post(); } else { // Si hemos sobrepasado el maximo de seguimiento if ( TbSeguimiento->RecordCount > 24 ) { TbSeguimiento->First(); // Eliminamos el seguimiento mas antiguo TbSeguimiento->Delete(); } // Insertamos el seg. actual TbSeguimiento->InsertRecord( ARRAYOFCONST( ( TbProductosForcedIndex->AsInteger, Variant(FechActual), PrecioCosto, TbProductos->FieldByName("Precio Venta 1")->Value ))); } } //--------------------------------------------------------------------------- void __fastcall TProductos::TbProductosCAfterInsert(TDataSet *DataSet) { TbProductos -> Edit(); TbProductosCOMBINADO -> Value = TbProductosC -> RecordCount <= 0 ? false : true; TbProductos -> Post(); } //--------------------------------------------------------------------------- void __fastcall TProductos::TbProductosIVASetText(TField *Sender, const AnsiString Text) { int iva; if ( !Text.IsEmpty() ) { iva = Text.ToInt(); if ( iva == 4 || iva == 6 || iva == 16 ) Sender -> AsString = Text; else ShowMessage( "Por favor, solo I.V.A's de los tipos:\n\tTipo 1: 4%\n\tTipo 2: 6%\n\tTipo 3: 16%" ); } else { Sender -> AsString = Text; } } //--------------------------------------------------------------------------- void __fastcall TProductos::Image1DblClick(TObject *Sender) { if (OpenPictureDialog1->Execute()) { TbProductos -> Edit(); TbProductos -> FieldByName( "PathImagen" ) -> AsString = ExtractRelativePath( ExtractFilePath(Application->ExeName), OpenPictureDialog1->FileName ); TbProductos -> Post(); } } //--------------------------------------------------------------------------- void __fastcall TProductos::TabSheet2Show(TObject *Sender) { Image1->Picture->LoadFromFile( TbProductos -> FieldByName( "PathImagen" ) -> AsString ); } //--------------------------------------------------------------------------- void __fastcall TProductos::TbProductosPrecioCostoSetText(TField *Sender, const AnsiString Text) { /// CUIDADO QUE TAMBIEN ESTO ESTA LIGADO A TPVproductos.CPP y TPVcmp.CPP Currency Ganancia = 0, PC; #ifdef EXIST_CFG if ( CFG->RecalcularPrecioVentaAlCambiarCoste->ItemIndex > 0 ) { Ganancia = TbProductos->FieldByName("Precio Venta 1")->AsCurrency - Sender->AsCurrency; PC = Sender->AsCurrency; } #endif Sender->AsString = Text; #ifdef EXIST_CFG /// CUIDADO QUE TAMBIEN ESTO ESTA LIGADO A TPVproductos.CPP y TPVcmp.CPP if ( CFG->RecalcularPrecioVentaAlCambiarCoste->ItemIndex == 1 ) TbProductos->FieldByName("Precio Venta 1")->AsCurrency = Ganancia + Sender->AsCurrency; if ( CFG->RecalcularPrecioVentaAlCambiarCoste->ItemIndex == 2 ) TbProductos->FieldByName("Precio Venta 1")->AsCurrency = Sender->AsCurrency + ( (Ganancia * Sender->AsCurrency)/PC ); #endif /// FIN DEL CUIDADO } //--------------------------------------------------------------------------- void __fastcall TProductos::TbProductosPrecioVenta1SetText(TField *Sender, const AnsiString Text) { if ( !Text.IsEmpty() ) { if ( *(Text.AnsiLastChar()) == '+' ) { Sender->AsString = Text.SubString(1, Text.Length() -1 ); if ( ! TbProductosPrecioCosto->IsNull ) Sender->AsString = AnsiString( (Sender->AsString.ToDouble() + TbProductosPrecioCosto->AsFloat) ); } else { Sender->AsString = Text; } } else Sender->AsString = Text; } //---------------------------------------------------------------------------