TPVwin/TpvProductos.cpp
2021-09-12 22:19:30 +02:00

1113 lines
37 KiB
C++

//---------------------------------------------------------------------------
#include <vcl.h>
#include <stdio.h>
#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;
}
//---------------------------------------------------------------------------