CAP/cap_gestion/tickets.cpp
2021-09-01 18:53:06 +02:00

610 lines
20 KiB
C++

//---------------------------------------------------------------------------
#include <inifiles.hpp>
#include <vcl\Clipbrd.hpp>
#include <vcl.h>
#pragma hdrstop
#include "tickets.h"
#include "crd_ctrl.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma link "DigitNum"
#pragma resource "*.dfm"
TfTickets *fTickets;
//---------------------------------------------------------------------------
__fastcall TfTickets::TfTickets(TComponent* Owner)
: TForm(Owner)
{
ticketE = new TStringList;
ticketS = new TStringList;
Height = 290;
TbTickets->Active = false;
TbVentas->Active = true;
TbPrecios->Active = true;
// Cargar la configuración de LMs
AnsiString E, S;
TIniFile *ini;
ini = new TIniFile( ExtractFileDir( Application->ExeName ) + "\\CAP.INI" );
// General
E = ini->ReadString( "CAP_c", "IDsLegoE", "1;" );
S = ini->ReadString( "CAP_c", "IDsLegoS", "2;" );
precioInicial=ini->ReadFloat( "CAP_g", "precioInicial", 0.0 );
precioMinuto= ini->ReadFloat( "CAP_g", "precioMinuto", 0.0 );
// Ticket de entrada
int i;
AnsiString cab,key;
ticketE->Clear();
i=1;
while(1){
key=AnsiString("cab")+AnsiString(i);
cab=ini->ReadString("ticketE",key,"<<EOF>>");
if ( cab!="<<EOF>>" )
ticketE->Add(cab);
else
break;
i++;
}
// Ticket de salida
ticketS->Clear();
i=1;
while(1){
cab=ini->ReadString("ticketS",AnsiString("cab")+AnsiString(i),"<<EOF>>");
if ( cab!="<<EOF>>" )
ticketS->Add(cab);
else
break;
i++;
}
delete ini;
int *ID, nL;
ObtenDirLEGOS( E, nL, &ID );
for ( i=0; i<nL; i++ ) ComboBox1->Items->Add( "Entrada ;O"+AnsiString( ID[i] ) );
ObtenDirLEGOS( S, nL, &ID );
for ( i=0; i<nL; i++ ) ComboBox1->Items->Add( "Salida ;O"+AnsiString( ID[i] ) );
}
//---------------------------------------------------------------------------
void __fastcall TfTickets::ObtenDirLEGOS(AnsiString cadena, int &nLEGOS, int **ID)
{
char *pDir, buff[80], *pbuff;
nLEGOS = 0; int i = 1, j=0;
while ( i <= cadena.Length() )
{
if ( cadena[i] == ';' ) nLEGOS++;
i++;
}
(*ID) = new int[nLEGOS];
i = 1; pbuff = buff;
while ( i <= cadena.Length() )
{
if ( cadena[i] == ';' )
{
*pbuff = '\0';
try {
(*ID)[j++] = AnsiString( buff ).ToInt();
} catch(...) {
nLEGOS--;
ShowMessage( "La configuración de direcciones LEGO'S es incorrecta" );
}
pbuff = buff; i++;
}else{
*(pbuff++) = cadena[i];
i++;
}
}
}
//---------------------------------------------------------------------------
int __fastcall TfTickets::NDias( TDateTime E, TDateTime S )
{
int dS, dE;
dE = E;
dS = S;
return ( S-E );
}
//---------------------------------------------------------------------------
int __fastcall TfTickets::NMinutos( TDateTime hE, TDateTime hS )
{
unsigned short HH, MM, SS, MS;
int RetroDias = 1, MinutosDentro = 0;
TDateTime TD;
if ( hS < hE )
{
TDateTime S(00,00,00,00);
RetroDias = -1;
TD = (S - hE) + hS;
} else {
TD =(hS - hE);
}
TD.DecodeTime( &HH, &MM, &SS, &MS );
MinutosDentro = HH*60 + MM;
return (MinutosDentro * RetroDias);
}
//---------------------------------------------------------------------------
int __fastcall TfTickets::obtenerTicket(void)
{
int pref, upref, cont;
upref=0;
sql->SQL->Clear();
sql->SQL->Add("SELECT Prefijo,Contador FROM 'datos\\contadores' WHERE Id=1");
sql->Active=true;
cont = sql->FieldByName("Contador")->AsInteger;
if ( cont>1000 ) upref=1;
pref = sql->FieldByName("Prefijo")->AsInteger+upref;
sql->SQL->Clear();
sql->SQL->Add("UPDATE 'datos\\contadores' SET Prefijo="+AnsiString(pref)+",Contador="+AnsiString(cont+1)+" WHERE Id=1" );
sql->ExecSQL();
return ( pref*1000 + cont );
}
//---------------------------------------------------------------------------
void __fastcall TfTickets::BitBtn1Click(TObject *Sender)
{
TbTickets->Active = true;
int NTicket;
if ( Edit1->Text.IsEmpty() )
{
TDateTime fE = fE.CurrentDate();
TDateTime hE = hE.CurrentTime();
TbTickets->Insert();
TbTickets->FieldByName("fechaE")->AsDateTime = fE;
TbTickets->FieldByName("horaE")->AsDateTime = hE;
TbTickets->FieldByName("puedeSalir")->AsBoolean = false;
TbTickets->Post();
if ( RadioGroup1->ItemIndex==0 )
{
NTicket = TbTickets->FieldByName("id")->AsInteger;
NTicket = (NTicket<<1)+1;
TbTickets->Edit();
TbTickets->FieldByName("Ticket")->AsInteger = 0;
TbTickets->FieldByName("idCard")->AsInteger = NTicket;
TbTickets->Post();
if ( !GrabaTarjeta(NTicket) )
TbTickets->Delete();
else
ShowMessage( "Nº de Ticket: "+AnsiString( NTicket ) );
} else {
NTicket = obtenerTicket();
TbTickets->Edit();
TbTickets->FieldByName("Ticket")->AsInteger = NTicket;
TbTickets->FieldByName("idCard")->AsInteger = 0;
TbTickets->Post();
//Currency pvp,int mm,TDateTime fechaE,TDateTime fechaS
//
ticket_Imprimir(NTicket,'E', 0, 0,
TbTickets->FieldByName("fechaE")->AsDateTime+TbTickets->FieldByName("horaE")->AsDateTime,
0 );
}
// #############
Height = 290;
} else {
// Buscar ticket y mostrar sus datos...
try {
// CAMBIADO 30/ABRL/2002
// NTicket = ( Edit1->Text.ToInt() ) >> 1;
// if ( TbTickets->Locate( "id", NTicket, TLocateOptions() << loCaseInsensitive << loPartialKey ) )
AnsiString fieldKey;
NTicket = Edit1->Text.ToInt();
if ( RadioGroup1->ItemIndex==0 ) fieldKey = "idCard"; else fieldKey = "Ticket";
if ( TbTickets->Locate( fieldKey, NTicket, TLocateOptions() << loCaseInsensitive ) )
{
TDateTime TD; Currency Coste;
int DiasDentro, MinutosDentro;
DiasDentro = NDias( TbTickets->FieldByName("fechaE")->AsDateTime, TDateTime::CurrentDate() );
MinutosDentro = NMinutos( TbTickets->FieldByName("horaE")->AsDateTime, TDateTime::CurrentTime() );
if ( MinutosDentro < 0 )
{
MinutosDentro = MinutosDentro*(-1);
DiasDentro--;
}
Coste = CalculaCoste( MinutosDentro, DiasDentro );
int VDig = Coste*100;
DigitNum1->Value = VDig / 100;
DigitNum2->Value = VDig - ( (VDig / 100)*100 );
Label4->Caption = TDateTime::CurrentTime();
Label5->Caption = TDateTime::CurrentDate();
Label3->Caption = AnsiString( DiasDentro ) + " Dias y " + AnsiString( MinutosDentro ) + " minutos.";
Label6->Caption = TbTickets->FieldByName("fechaE")->AsDateTime;
Label7->Caption = TbTickets->FieldByName("horaE")->AsDateTime;
Height = 370;
}
} catch(...) {
ShowMessage( "El formato del Ticket, es incorrecto" );
}
}
TbTickets->Active = false;
}
//---------------------------------------------------------------------------
Currency __fastcall TfTickets::CalculaCoste( int Minutos, int Dias )
{
Minutos = Minutos+(24*60*Dias);
return precioMinuto*Minutos+precioInicial;
Currency MM = 0, DD = 0;
TbPrecios->First();
while ( ! TbPrecios->Eof )
{
if ( Minutos <= TbPrecios->FieldByName("Tiempo")->AsInteger )
{
MM = TbPrecios->FieldByName("Precio")->AsCurrency;
break;
}
TbPrecios->Next();
}
if ( Dias > 0 )
{
Dias += 9000;
TbPrecios->First();
while ( ! TbPrecios->Eof )
{
if ( Dias <= TbPrecios->FieldByName("Tiempo")->AsInteger )
{
DD = TbPrecios->FieldByName("Precio")->AsCurrency;
break;
}
TbPrecios->Next();
}
}
return ( DD + MM );
}
//---------------------------------------------------------------------------
void __fastcall TfTickets::BitBtn2Click(TObject *Sender)
{
bool emitir=true;
if ( Edit1->Text.IsEmpty() ) return;
TbTickets->Active = true;
AnsiString fieldKey;
if ( RadioGroup1->ItemIndex==0 ) fieldKey = "idCard"; else fieldKey = "Ticket";
if ( TbTickets->Locate( fieldKey, Edit1->Text, TLocateOptions() << loCaseInsensitive << loPartialKey ) )
{
emitir = !TbTickets->FieldByName("PuedeSalir")->AsBoolean;
if ( !emitir )
{
// emitir = ( MessageDlg("El ticket "+Edit1->Text+" ya ha sido cobrado. \n ¿Volver a cobrar ahora?",mtInformation, TMsgDlgButtons() << mbYes << mbNo, 0)==mrYes);
ShowMessage("Este ticket ya ha sido cobrado!");
}
if ( emitir )
{
// Imprimimos ¿Ticket PAGADAO?
//ShowMessage( "Aqui debería imprimirse el comprobante de pago" );
TbTickets->Edit();
TbTickets->FieldByName("PuedeSalir")->AsBoolean = true;
TbTickets->Post();
// Insertamos la venta...
Currency Importe;
Importe = (Currency)(DigitNum1->Value * 100 + DigitNum2->Value ) / 100;
TbVentas->Insert();
TbVentas->FieldByName("idc")->AsInteger = -1; // Cliente ocacional
TbVentas->FieldByName("fechaE")->AsDateTime = TbTickets->FieldByName("fechaE")->AsDateTime;
TbVentas->FieldByName("horaE")->AsDateTime = TbTickets->FieldByName("horaE")->AsDateTime;
TbVentas->FieldByName("fechaS")->AsDateTime = TDateTime::CurrentDate();
TbVentas->FieldByName("fechaP")->AsDateTime = TDateTime::CurrentDate();
TbVentas->FieldByName("horaS")->AsDateTime = TDateTime::CurrentTime();
TbVentas->FieldByName("importe")->AsCurrency = Importe;
TbVentas->FieldByName("pagado")->AsBoolean = true;
TbVentas->Post();
//Currency pvp,int mm,TDateTime fechaE,TDateTime fechaS
//
int DiasDentro, MinutosDentro;
DiasDentro = NDias( TbVentas->FieldByName("fechaE")->AsDateTime, TbVentas->FieldByName("fechaS")->AsDateTime );
MinutosDentro = NMinutos( TbVentas->FieldByName("horaE")->AsDateTime, TbVentas->FieldByName("horaS")->AsDateTime );
if ( MinutosDentro < 0 )
{
MinutosDentro = MinutosDentro*(-1);
DiasDentro--;
}
if ( MessageDlg("¿Imprimir Ticket?",mtInformation, TMsgDlgButtons() << mbYes << mbNo, 0)==mrYes)
ticket_Imprimir(TbTickets->FieldByName("idCard")->AsInteger,'S', Importe, DiasDentro*1000+MinutosDentro,
TbVentas->FieldByName("fechaE")->AsDateTime+TbVentas->FieldByName("horaE")->AsDateTime,
TbVentas->FieldByName("fechaS")->AsDateTime+TbVentas->FieldByName("horaS")->AsDateTime );
// TbTickets->Delete();
}
} else ShowMessage( "Ticket no encontrado" );
TbTickets->Active = false;
// Cobrar
Edit1->Text = "";
DigitNum1->Value = 0;
DigitNum2->Value = 0;
Height = 290;
}
//---------------------------------------------------------------------------
void __fastcall TfTickets::ComboBox1Change(TObject *Sender)
{
// Mandamos el mensaje de selección al PortaPapeles...
AnsiString Bra = ComboBox1->Items->Strings[ComboBox1->ItemIndex];
Bra = "JDsoft:" + Bra.SubString( Bra.Length()-4, Bra.Length() );
Clipboard()->SetTextBuf( Bra.c_str() );
}
//---------------------------------------------------------------------------
void __fastcall TfTickets::Edit1KeyPress(TObject *Sender, char &Key)
{
if ( !Edit1->Text.IsEmpty() && Key == VK_RETURN )
BitBtn1Click( 0 );
}
//---------------------------------------------------------------------------
bool __fastcall TfTickets::GrabaTarjeta(int ID)
{
bool dev = false;
TCardCtrl *CCard;
CCard = new TCardCtrl(this);
char buf[80];
CCard->IDcard = ID;
CCard->GrabaTarjeraClick(0);
dev = CCard->statusOK;
if ( !dev )
{
ShowMessage( "ERROR DE GRABACION" );
}
/*
CCard->LeeTarjeta(buf);
ShowMessage( AnsiString(buf) );
*/
if ( CCard->LM_opened ) CCard->CierraPuerto();
delete CCard;
return dev;
}
//---------------------------------------------------------------------------
//###########################################################################
void __fastcall TfTickets::ticket_Imprimir(int idt,char tipo,Currency pvp,int mm,TDateTime fechaE,TDateTime fechaS)
{
//ShowMessage( "Nº de Ticket: "+AnsiString( idt ) );return;//BORRAME CUANDO ESTE LISTO
Currency Importe;
Importe = (DigitNum1->Value * 100 + DigitNum2->Value ) / 100;
TStringList *ticket;
ticket = (tipo=='E'?ticketE:ticketS);
hCom = ticket_AbrirPuerto("LPT1");
int i;
double sump=0;
// Nothing
// Generamos la cabecera
ticket_writeCOM( "\n" );
for ( i=0; i<ticket->Count; i++ )
{
ticket_writeCOM( ticket_parsearLinea(ticket->Strings[i],idt,pvp,mm,fechaE,fechaS) );
ticket_writeCOM( "\n" );
}
ticket_CerrarPuerto();
}
//---------------------------------------------------------------------------
AnsiString __fastcall TfTickets::ticket_parsearLinea(AnsiString linea, int idt, Currency pvp,int mm, TDateTime fechaE, TDateTime fechaS)
{
AnsiString dev;
// Esto será un "simple", buscar y reemplazar...
// dev = SearchAndReplace( linea, "[fecha]", DateTimePicker1->Date.DateString() );
dev = ticket_SearchAndReplace( linea, "{idt}", AnsiString(idt) );
dev = ticket_SearchAndReplace( dev, "{pvp}", FormatCurr( "##,###,##0.#0",pvp) );
dev = ticket_SearchAndReplace( dev, "{mm}", mm );
dev = ticket_SearchAndReplace( dev, "{fechaE}", fechaE.DateTimeString() );
dev = ticket_SearchAndReplace( dev, "{fechaS}", fechaS.DateTimeString() );
return dev;
}
//---------------------------------------------------------------------------
AnsiString __fastcall TfTickets::ticket_SearchAndReplace(AnsiString l, AnsiString s, AnsiString r )
{
AnsiString dev;
int i;
// Buscamos s en l
i = l.Pos(s);
if ( i>0 )
dev = l.SubString(1,i-1) + r + l.SubString(i+s.Length(),l.Length());
else
dev = l;
return dev;
}
//---------------------------------------------------------------------------
bool __fastcall TfTickets::ticket_writeCOM(AnsiString output)
{
char string[255], *p;
string[0]='\0';
if ( output.data() != NULL )
{
// Esto debería estar en el parser
strcpy( string, (char *)output.data() );
do {
p = StrPos(string,"{r}");
if ( p!=NULL )
{ p[0]=(char)0x1B; p[1]='r'; p[2]='1'; } else break;
} while( p!=NULL );
do {
p = StrPos(string,"{n}");
if ( p!=NULL )
{ p[0]=(char)0x1B; p[1]='r'; p[2]='0'; } else break;
} while( p!=NULL );
do {
p = StrPos(string,"{fc}");
if ( p!=NULL )
{ p[0]=(char)0x1D; p[1]='V'; p[2]=66; p[3]='0'; } else break;
} while( p!=NULL );
do {
p = StrPos(string,"{F1}");
if ( p!=NULL )
{ p[0]=(char)0x1B; p[1]='!'; p[2]=16+1+32; } else break;
} while( p!=NULL );
do {
p = StrPos(string,"{F}");
if ( p!=NULL )
{ p[0]=(char)0x1B; p[1]='!'; p[2]=17; } else break;
} while( p!=NULL );
do {
p = StrPos(string,"{f}");
if ( p!=NULL )
{ p[0]=(char)0x1B; p[1]='!'; p[2]=0x01; } else break;
} while( p!=NULL );
do {
p = StrPos(string,"{B}");
if ( p!=NULL )
{ p[0]=(char)0x1B; p[1]='E'; p[2]=1; } else break;
} while( p!=NULL );
do {
p = StrPos(string,"{b}");
if ( p!=NULL )
{ p[0]=(char)0x1B; p[1]='E'; p[2]='0'; } else break;
} while( p!=NULL );
do {
p = StrPos(string,"{E}");
if ( p!=NULL )
{ p[0]=(char)0x1B; p[1]='E'; p[2]=1; } else break;
} while( p!=NULL );
do {
p = StrPos(string,"{e}");
if ( p!=NULL )
{ p[0]=(char)0x1B; p[1]='E'; p[2]='0'; } else break;
} while( p!=NULL );
do {
p = StrPos(string,"{fA}");
if ( p!=NULL )
{ p[0]=(char)0x1B; p[1]='M'; p[2]='0'; } else break;
} while( p!=NULL );
do {
p = StrPos(string,"{fB}");
if ( p!=NULL )
{ p[0]=(char)0x1B; p[1]='M'; p[2]=1; } else break;
} while( p!=NULL );
do {
p = StrPos(string,"{fC}");
if ( p!=NULL )
{ p[0]=(char)0x1B; p[1]='M'; p[2]=2; } else break;
} while( p!=NULL );
do {
p = StrPos(string,"{L}");
if ( p!=NULL )
{ p[0]=(char)0x1B; p[1]='a'; p[2]='0'; } else break;
} while( p!=NULL );
do {
p = StrPos(string,"{C}");
if ( p!=NULL )
{ p[0]=(char)0x1B; p[1]='a'; p[2]=1; } else break;
} while( p!=NULL );
do {
p = StrPos(string,"{R}");
if ( p!=NULL )
{ p[0]=(char)0x1B; p[1]='a'; p[2]=2; } else break;
} while( p!=NULL );
/*
do {
p = StrPos(string,"[P]");
if ( p!=NULL )
{ p[0]=(char)0x1B; p[1]='a'; p[2]=2; } else break;
} while( p!=NULL );
*/
for ( p=string; *p!='\0'; p++ )
if ( *p == (char)0xFF ) *p='\0';
}
unsigned long int wt;
// return WriteFile( hCom,output.c_str(),output.Length(),&wt,NULL);
//ShowMessage( string );
return WriteFile( hCom,string,output.Length(),&wt,NULL);
}
//---------------------------------------------------------------------------
HANDLE __fastcall TfTickets::ticket_AbrirPuerto(char *puerto)
{
HANDLE hCom;
hCom = CreateFile( puerto,
GENERIC_READ | GENERIC_WRITE,
0, // comm devices must be opened w/exclusive-access
NULL, // no security attributes
OPEN_EXISTING, // comm devices must use OPEN_EXISTING
0, // not overlapped I/O
NULL // hTemplate must be NULL for comm devices
);
if ( puerto[0]!='L' )
if (hCom != INVALID_HANDLE_VALUE)
{
DCB dcb;
// We will build on the current configuration, and skip setting the size
// of the input and output buffers with SetupComm.
if ( GetCommState(hCom, &dcb) )
{
// Fill in the DCB: baud=57,600 bps, 8 data bits, no parity, and 1 stop bit.
dcb.BaudRate = CBR_9600; // set the baud rate
dcb.ByteSize = 8; // data size, xmit, and rcv
dcb.Parity = NOPARITY; // no parity bit
dcb.StopBits = ONESTOPBIT; // one stop bit
if ( !SetCommState(hCom, &dcb) )
CloseHandle( hCom );
}
}
return hCom;
}
//---------------------------------------------------------------------------
void __fastcall TfTickets::ticket_CerrarPuerto(void)
{
CloseHandle( hCom );
}
//---------------------------------------------------------------------------
//###########################################################################
void __fastcall TfTickets::FormDestroy(TObject *Sender)
{
delete ticketE;
delete ticketS;
}
//---------------------------------------------------------------------------