//--------------------------------------------------------------------------- #include #include #pragma hdrstop #include "TpvVntProd.h" #include "TpvCFG.h" #include "TpvVntProdQR.h" //--------------------------------------------------------------------------- #pragma link "Grids" #pragma link "ElastFrm" #pragma resource "*.dfm" TVntProd *VntProd; //--------------------------------------------------------------------------- __fastcall TVntProd::TVntProd(TComponent* Owner) : TForm(Owner) { CantidadTotal = new Currency [48]; BeneficioTotal = new Currency [48]; IamOpening = true; // Inicializamos la fecha de compra ( Y el filtro, en base a esta... ) unsigned short year, mes, dia; ( TDateTime::CurrentDate() ).DecodeDate( &year, &mes, &dia ); TbProdTmp -> TableName = "ProdTMP vnt" + AnsiString(".db"); #ifdef TB_DISCONTINUAS TbVentasC -> TableName = "Ventas (cabecera) '"+ AnsiString(year) +AnsiString(".db"); TbVentasD -> TableName = "Ventas (cuerpo) '"+ AnsiString(year) +AnsiString(".db"); #else TbVentasC -> TableName = "Ventas (cabecera).db"; TbVentasD -> TableName = "Ventas (cuerpo).db"; #endif MinFechaFact = TDateTime::CurrentDate(); MaxFechaFact = TDateTime::CurrentDate(); TbProductos -> Active = true; TbVentasC->Active = true; TbVentasD->Active = true; MinFecha -> Date = MinFechaFact; MaxFecha -> Date = MaxFechaFact; FiltrarFacturas(); } //--------------------------------------------------------------------------- void __fastcall TVntProd::CerrarAplicClick(TObject *Sender) { Close(); } //--------------------------------------------------------------------------- void __fastcall TVntProd::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 ( TbProductos -> FieldByName("EsNodo") -> Value == -1 ) { FamC . Familia = TbProductos -> FieldByName("Familia") -> 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], TbProductos -> FieldByName("Nombre del Producto") -> Value ); NuevoNodo -> Data = new int [3]; ((int *)NuevoNodo -> Data)[0] = FamC . Familia; ((int *)NuevoNodo -> Data)[1] = 0; ((int *)NuevoNodo -> Data)[2] = TbProductos -> FieldByName("ForcedIndex") -> 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], TbProductos -> FieldByName("Nombre del Producto") -> Value ); NuevoNodo -> Data = new int [3]; ((int *)NuevoNodo -> Data)[0] = FamC . Familia; ((int *)NuevoNodo -> Data)[1] = 0; ((int *)NuevoNodo -> Data)[2] = TbProductos -> FieldByName("ForcedIndex") -> 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 TVntProd::MinFechaChange(TObject *Sender) { MaxFechaFact = MaxFecha -> Date; // Reajustamos el filtro... MinFechaFact = MinFecha -> Date; FiltrarFacturas(); } //--------------------------------------------------------------------------- void __fastcall TVntProd::MaxFechaChange(TObject *Sender) { MinFechaFact = MinFecha -> Date; // Reajustamos el filtro... MaxFechaFact = MaxFecha -> Date; FiltrarFacturas(); } //--------------------------------------------------------------------------- void __fastcall TVntProd::FiltrarFacturas(void) { // Filtramos las facturas... TbProdTmp -> Active = false; TbProdTmp -> Filtered = false; TbVentasC->FilterOptions = TbVentasC->FilterOptions << foCaseInsensitive; TbVentasC->Filter = "([FechaFactura] >= '" + MinFechaFact + "' AND [FechaFactura] <= '" + MaxFechaFact +"')"; TbVentasC->Filtered = true; TbProdTmp -> Active = true; // Forzamos el recrear la base IndicesChange( 0, 0 ); } //--------------------------------------------------------------------------- void __fastcall TVntProd::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 TVntProd::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 TVntProd::IndicesDeletion(TObject *Sender, TTreeNode *Node) { delete [] Node -> Data; } //--------------------------------------------------------------------------- void __fastcall TVntProd::TbProdTmpBeforeOpen(TDataSet *DataSet) { AnsiString FileEmp, Cantidad; FileEmp = TbProdTmp -> TableName; // Establecemos la ruta TbProdTmp -> DatabaseName = "TpvWin"; // Facilitamos el nombre de la nueva tabla y su tipo TbProdTmp -> TableType = ttParadox; // Usamos la propiedad FielDefs para definir // las columnas que contendrá la tabla TbProdTmp -> FieldDefs -> Clear(); TbProdTmp -> FieldDefs -> Add("Familia0", ftInteger, 0, false ); TbProdTmp -> FieldDefs -> Add("Familia1", ftInteger, 0, false ); TbProdTmp -> FieldDefs -> Add("CodForced", ftInteger, 0, false ); TbProdTmp -> FieldDefs -> Add("CodProducto", ftString, 15, false ); TbProdTmp -> FieldDefs -> Add("NombreProducto", ftString, 30, false ); TbProdTmp -> FieldDefs -> Add("IVA", ftSmallint, 0, false ); TbProdTmp -> FieldDefs -> Add("PrecioC", ftCurrency, 0, false ); TbProdTmp -> FieldDefs -> Add("PrecioV", ftCurrency, 0, false ); for ( int hh=0; hh < 24; hh++ ) { Cantidad = "Cantidad " + AnsiString( hh ) + ":00+"; TbProdTmp -> FieldDefs -> Add(Cantidad, ftInteger, 0, false ); Cantidad = "Cantidad " + AnsiString( hh ) + ":30+"; TbProdTmp -> FieldDefs -> Add(Cantidad, ftInteger, 0, false ); } TbProdTmp -> IndexDefs-> Clear(); // TbProdTmp->IndexDefs->Add("Primary", "Familia0; Familia1; CodProducto", TIndexOptions() << ixPrimary ); // Creamos la base... TbProdTmp -> CreateTable(); } //--------------------------------------------------------------------------- void __fastcall TVntProd::TbProdTmpAfterOpen(TDataSet *DataSet) { /* SELECT CodProducto Código, NombreProducto Producto, SUM( Cantidad ) Cantidad, IVA, SUM( ( (PrecioC * (1 + (IVA / 100) ) ) * (1 - (Dto / 100) ) ) * Cantidad ) Ventas."PV Bruto" FROM "Ventas (cuerpo).db" Ventas GROUP BY CodProducto, NombreProducto, IVA, NombreProducto, CodProducto */ unsigned short hh, mm, ss, mss; int Familia0, Familia1; Currency PVP, PRECIO, COSTO; AnsiString Cantidad; int VntCodProductoAux; TbProdTmp->DisableControls(); for ( hh = 0; hh < 48; hh ++ ) { CantidadTotal[hh] = 0; BeneficioTotal[hh] = 0; } IamOpening = true; TbProdTmp->DisableControls(); TbVentasC -> First(); while ( ! TbVentasC -> Eof ) // Siguiente factura { TbVentasC->FieldByName("HoraFactura")->AsDateTime . DecodeTime( &hh, &mm, &ss, &mss ); Cantidad = "Cantidad " + AnsiString( hh ) + ":" + ( (mm<30) ? "00+" : "30+" ); TbVentasD -> First(); while( ! TbVentasD -> Eof ) // Siguiente linea de la factura { // Si el producto no esta ya en la lista VntCodProductoAux = TbVentasD->FieldByName("CodProductoAux")->AsInteger; if ( VntCodProductoAux == 0 || TbVentasD->FieldByName("CodProductoAux")->IsNull || ! ( TbProdTmp -> Locate( "CodForced", VntCodProductoAux, TLocateOptions() << loCaseInsensitive ) ) ) { if ( TbVentasD->FieldByName("CodProductoAux")->IsNull || VntCodProductoAux == 0 || ! ( TbProductos -> Locate( "ForcedIndex", VntCodProductoAux, TLocateOptions() << loCaseInsensitive ) ) ) { Familia0 = Familia1 = 0; COSTO = 0; } else { Familia0 = TbProductos -> FieldByName("Familia") -> AsInteger; COSTO = TbProductos->FieldByName("Precio Costo")->AsCurrency; } TbProdTmp -> InsertRecord( ARRAYOFCONST( ( Familia0, Familia1, VntCodProductoAux, TbVentasD->FieldByName("CodProducto")->AsString, TbVentasD->FieldByName("NombreProducto")->AsString, TbVentasD->FieldByName("IVA")->AsInteger, COSTO, 0 ) ) ); } // Actualizamos las cantidades según horas.... //////////// LOCALIZACION DEL REGISTRO CORRECTO PRECIO = (TbVentasD->FieldByName("PrecioC")->AsCurrency * TbVentasD->FieldByName("Cantidad")->AsFloat )* ( 1 - (TbVentasD->FieldByName("Dto")->AsInteger / 100) ); PVP = PRECIO * ( 1 + (TbVentasD->FieldByName("IVA")->AsCurrency / 100) ); TbProdTmp->Edit(); TbProdTmp->FieldByName( "PrecioV" )->AsCurrency = TbProdTmp->FieldByName( "PrecioV" )->AsCurrency +PVP; TbProdTmp->FieldByName( Cantidad )->AsFloat += TbVentasD->FieldByName("Cantidad")->AsFloat; TbProdTmp->Post(); CantidadTotal[hh*2+ ((mm<30)?0:1)] += TbVentasD->FieldByName("Cantidad")->AsFloat; BeneficioTotal[hh*2+ ((mm<30)?0:1)] += PRECIO - TbProdTmp->FieldByName("PrecioC")->AsCurrency * TbVentasD->FieldByName("Cantidad")->AsFloat; TbVentasD -> Next(); } TbVentasC -> Next(); } IamOpening = false; TbProdTmp->EnableControls(); RellenaGraficaTOTALES(); TbProdTmp->EnableControls(); } //--------------------------------------------------------------------------- void __fastcall TVntProd::RellenaGraficaTOTALES(void) { // Metemos los datos generales en la gráfica... Chart1 -> Series[0] -> Clear(); if ( mNumProductos -> Checked ) for ( int i = 0; i < 24; i++ ) { Chart1 -> Series[0] -> AddXY(i*2, CantidadTotal[i*2], i, clTeeColor); Chart1 -> Series[0] -> AddXY(i*2+1, CantidadTotal[i*2+1], "½", clTeeColor); } else for ( int i = 0; i < 24; i++ ) { Chart1 -> Series[0] -> AddXY(i*2, BeneficioTotal[i*2], i, clTeeColor); Chart1 -> Series[0] -> AddXY(i*2+1, BeneficioTotal[i*2+1], "½", clTeeColor); } } //--------------------------------------------------------------------------- void __fastcall TVntProd::DsProdTempDataChange(TObject *Sender, TField *Field) { AnsiString Cantidad; Currency Benef; StatusBar1->Panels->Items[0]->Text = "Creando gráfica..."; Chart1 -> Series[1] -> Clear(); Chart1 -> Series[2] -> Clear(); if ( mNumProductos -> Checked ) { // Metemos los datos en la gráfica... for ( int i = 0; i < 24; i++ ) { Cantidad = "Cantidad " + AnsiString( i ) + ":" + "00+"; Chart1 -> Series[1] -> AddXY(i*2, TbProdTmp->FieldByName( Cantidad )->AsInteger, i, clTeeColor); Cantidad = "Cantidad " + AnsiString( i ) + ":" + "30+"; Chart1 -> Series[1] -> AddXY(i*2+1, TbProdTmp->FieldByName( Cantidad )->AsInteger, "½", clTeeColor); } } else { Benef = TbProdTmp->FieldByName( "PrecioV" )->AsCurrency - TbProdTmp->FieldByName( "PrecioC" )->AsCurrency; // Metemos los datos en la gráfica... for ( int i = 0; i < 24; i++ ) { Cantidad = "Cantidad " + AnsiString( i ) + ":" + "00+"; Chart1 -> Series[1] -> AddXY(i*2, TbProdTmp->FieldByName( Cantidad )->AsInteger * TbProdTmp->FieldByName( "PrecioV" )->AsCurrency, i, clTeeColor); Chart1 -> Series[2] -> AddXY(i*2, TbProdTmp->FieldByName( Cantidad )->AsInteger * Benef, i, clTeeColor); Cantidad = "Cantidad " + AnsiString( i ) + ":" + "30+"; Chart1 -> Series[1] -> AddXY(i*2+1, TbProdTmp->FieldByName( Cantidad )->AsInteger * TbProdTmp->FieldByName( "PrecioV" )->AsCurrency, "½", clTeeColor); Chart1 -> Series[2] -> AddXY(i*2+1, TbProdTmp->FieldByName( Cantidad )->AsInteger * Benef, "½", clTeeColor); } } StatusBar1->Panels->Items[0]->Text = ""; } //--------------------------------------------------------------------------- void __fastcall TVntProd::MostrarTotalClick(TObject *Sender) { MostrarTotal->Checked = !MostrarTotal->Checked; // Ajustamos la grafica de totales... Chart1 -> Series[0] -> Active = MostrarTotal->Checked; } //--------------------------------------------------------------------------- void __fastcall TVntProd::VentaProductoClick(TObject *Sender) { VentaProducto->Checked = !VentaProducto->Checked; // Ajustamos la grafica de totales... Chart1 -> Series[1] -> Active = VentaProducto->Checked; } //--------------------------------------------------------------------------- void __fastcall TVntProd::BeneficioProductoClick(TObject *Sender) { BeneficioProducto->Checked = !BeneficioProducto->Checked; // Ajustamos la grafica de totales... Chart1 -> Series[2] -> Active = BeneficioProducto->Checked; } //--------------------------------------------------------------------------- void __fastcall TVntProd::mNumProductosClick(TObject *Sender) { mMostrarCifras -> Checked = false; mNumProductos -> Checked = true; BeneficioProducto->Enabled = false; Chart1 -> Series[2] -> Active = false; DsProdTempDataChange(0, 0); RellenaGraficaTOTALES(); } //--------------------------------------------------------------------------- void __fastcall TVntProd::mMostrarCifrasClick(TObject *Sender) { mMostrarCifras -> Checked = true; mNumProductos -> Checked = false; BeneficioProducto->Enabled = true; Chart1 -> Series[2] -> Active = BeneficioProducto->Checked; DsProdTempDataChange(0, 0); RellenaGraficaTOTALES(); } //--------------------------------------------------------------------------- void __fastcall TVntProd::FormDestroy(TObject *Sender) { delete [] CantidadTotal; delete [] BeneficioTotal; } //--------------------------------------------------------------------------- void __fastcall TVntProd::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" ) { TbProdTmp -> 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; }; // Filtramos según los rangos construidos antes... TbProdTmp->FilterOptions = TbProdTmp->FilterOptions << foCaseInsensitive; TbProdTmp->Filter = "([Familia0] >= '" + AnsiString( (int)( FamL . Familia ) ) + "' AND [Familia0] < '" + AnsiString( (int)( FamH . Familia ) ) + "')"; TbProdTmp -> Filtered = true; } //--------------------------------------------------------------------------- void __fastcall TVntProd::TbProdTmpCalcFields(TDataSet *DataSet) { if ( IamOpening ) return; int min, max; AnsiString Cantidad; float sCantidad; // Calculamos la cantidad según el rango especificado... unsigned short hh, mm, ss, mss; DateTimePicker1->DateTime . DecodeTime( &hh, &mm, &ss, &mss ); min = hh*2 + ( (mm<30) ? 0 : 1 ); DateTimePicker2->DateTime . DecodeTime( &hh, &mm, &ss, &mss ); max = hh*2 + ( (mm<30) ? 0 : 1 ); sCantidad = 0; for ( ; min <= max; min++ ) { Cantidad = "Cantidad " + AnsiString( min/2 ) + ":" + ((min%2) ? "30+" : "00+"); sCantidad += TbProdTmp->FieldByName( Cantidad ) -> AsFloat; } TbProdTmp->FieldByName( "Cantidad" ) -> Value = sCantidad; #ifdef EXIST_CFG if ( CFG->VntProdCosteBeneficio->Checked ) { #endif TbProdTmp->FieldByName( "CostoTotal" ) -> AsCurrency = TbProdTmp->FieldByName( "PrecioC" ) -> AsCurrency * sCantidad; TbProdTmp->FieldByName( "Beneficio" ) -> AsCurrency = TbProdTmp->FieldByName( "PrecioV" ) -> AsCurrency - TbProdTmp->FieldByName( "CostoTotal" ) -> AsCurrency; #ifdef EXIST_CFG } #endif } //--------------------------------------------------------------------------- void __fastcall TVntProd::bGraficasClick(TObject *Sender) { POINT MousePos; if ( GetCursorPos(&MousePos) ) { mGraficas->PopupComponent = bGraficas; // mGraficas->Popup(MousePos.x + bGraficas->Width, MousePos.y + bGraficas->Height); mGraficas->Popup( /*MousePos.x + bGraficas->Width + */bGraficas->Left + Left, /*MousePos.y + */bGraficas->Height * 2 + Top); mGraficas->PopupComponent = 0; } } //--------------------------------------------------------------------------- void __fastcall TVntProd::SpeedButton7Click(TObject *Sender) { TQRVntProd *QRVntProd; QRVntProd = new TQRVntProd(this); QRVntProd->QuickRep1->Preview(); delete QRVntProd; } //---------------------------------------------------------------------------