Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Principal > Varios
Registrarse FAQ Miembros Calendario Guía de estilo Buscar Temas de Hoy Marcar Foros Como Leídos

Grupo de Teaming del ClubDelphi

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 01-01-2014
Avatar de José Luis Garcí
[José Luis Garcí] José Luis Garcí is offline
Miembro Premium
 
Registrado: may 2003
Ubicación: Las Palmas de G.C.
Posts: 1.372
Poder: 23
José Luis Garcí Va camino a la fama
El ticket y su contenido

Esto que parece un chorrada, es algo que se pasa por alto muchas veces, coger bolígrafos de publicidad, tickets, etc y leerlos con atención, pongamos el siguiente ejemplo

Químicas XXX, S.L.
Teléfono 999-999-999

A que se dedica esta empresa, puede ser un fabricante de productos de limpieza, de piscina, farmacéutico, etc o simplemente un distribuidor, no no los etc indicando, por eso debemos especificar bien y muy detalladamente algunos de nuestros datos ya que estos nos pueden representar y ser nuestra publicidad, también en el ticket.

Nuestra ticket debe estar dividido en varias partes y este es más o menos el estándar:

LA CABECERA (1)

Logo (opcional)
Nombre
A que nos dedicamos
Calle
Provincia
Código postal y población
Teléfono y fax
CIF o NIF
Email
Web

DATOS DEL TICKET (1)

Número del ticket
Fecha y hora
Terminal o persona que le atendió
Elemento (mesa, taburete, etc)

DATOS DEL DETALLE

Unidades, descripción, precio ud., descuento y subtotal (2)

TOTAL

Total
impuestos
entregado (el importe únicamente)
Devuelto (el importe únicamente)

CIERRE

Una frase de cierre como "gracias por su compra" (3)


Claro esta, debemos tener en cuenta el ancho y la capacidad de caracteres de nuestro ticket yo en el mio uso 42 caracteres por linea, por lo que debemos limitar el ancho y es aveces preferible que no aparezca un dato como el email o la web si no va a poder leerse entero , esto deberemos decidir si hay campos del ticket que su lengt es mayor que el ancho disponible no salgan, así de simple.


(1) Si alguno de los datos esta en blanco, simplemente no pasa por el ticket, evitando de esta manera un linea en blanco, salvo que en esa misma linea exista otro dato
claro esta

(2) en una linea mejor que en 2

(3) Esta frase debe poder ser preseleccionada, incluso en mi proceso de desarrollo previo pensé en poner dos frases una que pusiese según la hora del día más o menos la
siguiente frase

que pase (un buen día) o (una buena tarde) o (buena noche)

Y otra para ofertas tipo

café + sándwich 2'80 €

(opcional) pues eso que el cliente pueda elegir si quiere que le aparezca en el ticket
__________________
Un saludo desde Canarias, "El abuelo Cebolleta"
Responder Con Cita
  #2  
Antiguo 01-01-2014
Avatar de José Luis Garcí
[José Luis Garcí] José Luis Garcí is offline
Miembro Premium
 
Registrado: may 2003
Ubicación: Las Palmas de G.C.
Posts: 1.372
Poder: 23
José Luis Garcí Va camino a la fama
Por último queda el método a usar, existen varios que conozca, a través de un report, tipo memo y por código de impresora, yo he usado los dos últimos, pero no descarto otros métodos más, hablo de los que he leído y de aquí en adelante de los que yo uso, para ello os pongo el código de las funciones que uso que suelo usar para ambos casos ya que más adelante aparecerá y sin esta parte será más compliacado entenderlo

Código Delphi [-]
unit uimpticket;

interface

uses printers, WinSpool,  Windows, Sysutils, Dialogs, StrUtils;

function WriteRawDataToPrinter(PrinterName: String; Str: String): Boolean;

Function GetImpresora(Impre:String):Integer;

function MyTextReplace(Texto:String):String;

function CenterString(aStr: String; Len: Integer): String;

implementation

function WriteRawDataToPrinter(PrinterName: String; Str: String): Boolean;
var
  PrinterHandle: THandle;
  DocInfo: TDocInfo1;
  i: Integer;
  B: Byte;
  Escritos: DWORD;
begin
  Result:= FALSE;
  if OpenPrinter(PChar(PrinterName), PrinterHandle, nil) then
  try
    FillChar(DocInfo,Sizeof(DocInfo),#0);
    with DocInfo do
    begin
      pDocName:= PChar('Printer Test');
      pOutputFile:= nil;
      pDataType:= 'RAW';
    end;
    if StartDocPrinter(PrinterHandle, 1, @DocInfo) <> 0 then
    try
      if StartPagePrinter(PrinterHandle) then
      try
        while Length(Str) > 0 do
        begin
          if Copy(Str, 1, 1) = '\' then
          begin
            if Uppercase(Copy(Str, 2, 1)) = 'X' then
              Str[2]:= '$';
            if not TryStrToInt(Copy(Str, 2, 3),i) then
              Exit;
            B:= Byte(i);
            Delete(Str, 1, 3);
          end else B:= Byte(Str[1]);
          Delete(Str,1,1);
          WritePrinter(PrinterHandle, @B, 1, Escritos);
        end;
        Result:= TRUE;
      finally
        EndPagePrinter(PrinterHandle);
      end;
    finally
      EndDocPrinter(PrinterHandle);
    end;
  finally
    ClosePrinter(PrinterHandle);
  end;
end;

Function GetImpresora(Impre:String):Integer;
//------------------------------------------------------------------------------
//**********************************************************[ GetImpresora ]****
// de Marcos Zorilla bajada de http://www.clubdelphi.com/foros/showthread.php?t=68519
//------------------------------------------------------------------------------
Var
nCont:Integer;
lSearch:Boolean;
cNewLIne:String;
begin
  lSearch:=False;
  cNewLine:=Chr(10)+Chr(13);
  For nCont:=0 to Printer.Printers.Count - 1 do   //buscamos la impresora en la lista del sistema
  begin
      if Pos(impre, Printer.Printers[nCont]) <> 0 then
      begin
      lSearch:=True;
      Result:=nCont;
      Break;
      end;
  end;
  if lSearch = False then
  begin
  ShowMessage('Impresora no encontrada.'+impre+cNewLine+'Se utilizará la predeterminda.');
  Result:=-1
  end;
end;

function MyTextReplace(Texto:String):String;
begin
    if Texto<>'' then begin
    Texto:= AnsiReplaceStr(Texto,'Ñ', #165);
    Texto:= AnsiReplaceStr(Texto,'ñ', #164);
    Texto:= AnsiReplaceStr(Texto,'á', #160);
    Texto:= AnsiReplaceStr(Texto,'é', #101);//#130);
    Texto:= AnsiReplaceStr(Texto,'í', #161);
    Texto:= AnsiReplaceStr(Texto,'ó', #162);
    Texto:= AnsiReplaceStr(Texto,'ú', #163);
    Texto:= AnsiReplaceStr(Texto,'Á', #65);
    Texto:= AnsiReplaceStr(Texto,'É', #144);
    Texto:= AnsiReplaceStr(Texto,'Í', #73);
    Texto:= AnsiReplaceStr(Texto,'Ó', #79);
    Texto:= AnsiReplaceStr(Texto,'Ú', #85);
    Texto:= AnsiReplaceStr(Texto,'Ü', #85);
    Texto:= AnsiReplaceStr(Texto,'Ü', #129);
    Result:=Texto;
  end;
end;

function CenterString(aStr: String; Len: Integer): String;
var
  posStr : integer;
begin
  if Length(aStr)>Len then
    Result := Copy(aStr, 1, Len)
  else
  begin
    posStr := (len - Length(aStr)) div 2;
    Result := Format('%*s', [len, aStr + Format('%-*s', [posStr, ''])]);
  end;
end;

end.

el WriteRawDataToPrinte es del maestro SEONE

el GetImpresora es del maestro Marcos Zorrilla

el MyTextReplace es bajado de Planetadelphi.com

Y CenterString no estoy seguro si es mía o la baje de algún lado

Yo personalmente uso ambos sistemas y dejo que el cliente decida si quiere imprimir por código o ticket simple, esto lo hace en configuración mediante el campo método de impresión con dos valores posibles 1 o 2.

Pongo una imagen de mi visor de tickets



en esta me queda varias cosas que corregir, detalles como nº de artículos, ya que hace referencia al número de lineas y no de artículos, etc, pero os vale de ejemplo.

El método por código es un poco más trabajoso y debemos tener en cuenta que en cualquier momento el cliente puede cambiar de impresora, resultando que los códigos ya no son válidos, el método de usar un memo, es 100% fiable ya que imprimimos nada más que un texto plano y podemos salvar que nuestra impresora admita acentos o no ya que los sustituiremos gracias a la función MyTextReplace, permitiendo imprimir en cualquier impresora que admita los códigos ASCII, por la tanto en todas, salvo especificas para otros países que no tengan la posibilidad de cambiar el idioma /(ejemplo caracteres, chino, cirilicos o árabes)

Pongo el código de unos de mis primeros tickets por código y memo con selección de impresora normal o no (ya digo mi antiguo método

Código Delphi [-]
//------------------------------------------------------------------------------
//**************************************************************[ Imprimir ]****
//------------------------------------------------------------------------------
var
  r: TRect;
  i,p: Integer;
begin
  if DM.DsConfi.DataSet.FieldByName('USARTICKETNORMAL').Value='S' then
  begin  //Si vamos a usar impresión por código
     if not DsTicket.DataSet.IsEmpty then
     begin
       WriteRawDataToPrinter(DM.DsConfi.DataSet.FieldByName('IMPRESORATICKET').Value,DM.DsConfi.DataSet.Fie  ldByName('TEXTINICIAR').Value);
       WriteRawDataToPrinter(DM.DsConfi.DataSet.FieldByName('IMPRESORATICKET').Value,DM.DsConfi.DataSet.Fie  ldByName('RETROCEDER').Value);
       WriteRawDataToPrinter(DM.DsConfi.DataSet.FieldByName('IMPRESORATICKET').Value,DM.DsConfi.DataSet.Fie  ldByName('RETROCEDER').Value);
       WriteRawDataToPrinter(DM.DsConfi.DataSet.FieldByName('IMPRESORATICKET').Value,DM.DsConfi.DataSet.Fie  ldByName('TEXGRANDE').Value);
       WriteRawDataToPrinter(DM.DsConfi.DataSet.FieldByName('IMPRESORATICKET').Value,CenterString(DM.DsConf  i.DataSet.FieldByName('EMPRESA').Value,35));
       WriteRawDataToPrinter(DM.DsConfi.DataSet.FieldByName('IMPRESORATICKET').Value,DM.DsConfi.DataSet.Fie  ldByName('TEXCOMPRIMIDO').Value);
       WriteRawDataToPrinter(DM.DsConfi.DataSet.FieldByName('IMPRESORATICKET').Value,espacios(MyTextReplace  ('Calle:'+DM.DsConfi.DataSet.FieldByName('DIRECCION').Value),42,0));
       WriteRawDataToPrinter(DM.DsConfi.DataSet.FieldByName('IMPRESORATICKET').Value,espacios(MyTextReplace  ('Población:'+DM.DsConfi.DataSet.FieldByName('POBLACION').Value),42,0));
       WriteRawDataToPrinter(DM.DsConfi.DataSet.FieldByName('IMPRESORATICKET').Value,espacios(MyTextReplace  ('C.P.:'+DM.DsConfi.DataSet.FieldByName('CODIGOPOSTAL').Value+'  Provincia:'+DM.DsConfi.DataSet.FieldByName('PROVINCIA').Value),42,0));
       WriteRawDataToPrinter(DM.DsConfi.DataSet.FieldByName('IMPRESORATICKET').Value,espacios(MyTextReplace  ('Tf.:'+DM.DsConfi.DataSet.FieldByName('TELEFONO').Value+'   CIF:'+DM.DsConfi.DataSet.FieldByName('CIF').Value),42,0));
       WriteRawDataToPrinter(DM.DsConfi.DataSet.FieldByName('IMPRESORATICKET').Value,espacios(MyTextReplace  ('Email:'+DM.DsConfi.DataSet.FieldByName('EMAIL').Value),42,0));
       WriteRawDataToPrinter(DM.DsConfi.DataSet.FieldByName('IMPRESORATICKET').Value,espacios(MyTextReplace  ('Web:'+DM.DsConfi.DataSet.FieldByName('WEB').Value),42,0));
       WriteRawDataToPrinter(DM.DsConfi.DataSet.FieldByName('IMPRESORATICKET').Value,espacios(' ',42,0));
       WriteRawDataToPrinter(DM.DsConfi.DataSet.FieldByName('IMPRESORATICKET').Value,Espacios(MyTextReplace  ('Número: ')+DsTicket.DataSet.FieldByName('NUMERO').AsString+
                                                                                             '       '+DsTicket.DataSet.FieldByName('FECHA').AsString+
                                                                                             '    '+DsTicket.DataSet.FieldByName('HORA').AsString,42,0));
       WriteRawDataToPrinter(DM.DsConfi.DataSet.FieldByName('IMPRESORATICKET').Value,espacios(' ',42,0));
       WriteRawDataToPrinter(DM.DsConfi.DataSet.FieldByName('IMPRESORATICKET').Value,Espacios('Cant.',6,0)+  espacios('Producto',20,0)+espacios('Dto.',6,0)+espacios('Sub-total',10,0));
       WriteRawDataToPrinter(DM.DsConfi.DataSet.FieldByName('IMPRESORATICKET').Value,espacios('--------------------------------------------',42,0));
       //----------------------------------------------------------------------------
       with DsDetalle.DataSet do
       begin
          First;
          while not Eof do
          begin
            WriteRawDataToPrinter(DM.DsConfi.DataSet.FieldByName('IMPRESORATICKET').Value,espacios(DsDetalle.Dat  aSet.FieldByName('UNIDADES').AsString,5,1)+' '+
                            espacios(Copy(MyTextReplace(DsDetalle.DataSet.FieldByName('DESCRIPCION').AsString),1,19),19,0)+' '+
                            espacios(FormatFloat('#,##0.00',DsDetalle.DataSet.FieldByName('DESCUENTO').Value),5,1)+' '+
                            espacios(FormatFloat('#,##0.00',DsDetalle.DataSet.FieldByName('SUBTOTAL').value),10,1));
            Next;
          end;
        end;
       WriteRawDataToPrinter(DM.DsConfi.DataSet.FieldByName('IMPRESORATICKET').Value,espacios('--------------------------------------------',42,0));
       WriteRawDataToPrinter(DM.DsConfi.DataSet.FieldByName('IMPRESORATICKET').Value,DM.DsConfi.DataSet.Fie  ldByName('TEXTCOMPRIMIDANEGRITA').Value);
       if not DsTicket.DataSet.FieldByName('TOTAL').IsNull then WriteRawDataToPrinter(DM.DsConfi.DataSet.FieldByName('IMPRESORATICKET').Value,espacios('Total: ',32,1)+Espacios(FormatFloat('#,##0.00',DsTicket.DataSet.FieldByName('TOTAL').Value),10,1))
                                                           else WriteRawDataToPrinter(DM.DsConfi.DataSet.FieldByName('IMPRESORATICKET').Value,espacios('Total: ',32,1)+Espacios(FormatFloat('#,##0.00',0),10,1));
       WriteRawDataToPrinter(DM.DsConfi.DataSet.FieldByName('IMPRESORATICKET').Value,DM.DsConfi.DataSet.Fie  ldByName('TEXCOMPRIMIDO').Value);
       if not DsTicket.DataSet.FieldByName('ENTREGADO').IsNull then WriteRawDataToPrinter(DM.DsConfi.DataSet.FieldByName('IMPRESORATICKET').Value,espacios('Entregado: ',32,1)+Espacios(FormatFloat('#,##0.00',DsTicket.DataSet.FieldByName('ENTREGADO').Value),10,1))
                                                               else WriteRawDataToPrinter(DM.DsConfi.DataSet.FieldByName('IMPRESORATICKET').Value,espacios('Entregado: ',32,1)+Espacios(FormatFloat('#,##0.00',0),10,1));
       if DsTicket.DataSet.FieldByName('SINPAGAR').AsString='N' then
       begin
          if not DsTicket.DataSet.FieldByName('DEVUELTO').IsNull then WriteRawDataToPrinter(DM.DsConfi.DataSet.FieldByName('IMPRESORATICKET').Value,espacios('Devuelto: ',32,1)+Espacios(FormatFloat('#,##0.00',DsTicket.DataSet.FieldByName('DEVUELTO').Value),10,1))
                                                                 else WriteRawDataToPrinter(DM.DsConfi.DataSet.FieldByName('IMPRESORATICKET').Value,espacios('Devuelto: ',32,1)+Espacios(FormatFloat('#,##0.00',0),10,1));
       end else
       begin
         if not DsTicket.DataSet.FieldByName('DEVUELTO').IsNull then WriteRawDataToPrinter(DM.DsConfi.DataSet.FieldByName('IMPRESORATICKET').Value,Espacios('SinP.[x]',10,0)+espacios('Devuelto: ',22,1)+Espacios(FormatFloat('#,##0.00',DsTicket.DataSet.FieldByName('DEVUELTO').Value),10,1))
                                                                else WriteRawDataToPrinter(DM.DsConfi.DataSet.FieldByName('IMPRESORATICKET').Value,Espacios('SinP.[x]',10,0)+espacios('Devuelto: ',22,1)+Espacios(FormatFloat('#,##0.00',0),10,1));
       end;
       WriteRawDataToPrinter(DM.DsConfi.DataSet.FieldByName('IMPRESORATICKET').Value,espacios(' ',44,0));
       //CAMBIAR POR DATOS EN CONFIGURACION------------------------------------------
       WriteRawDataToPrinter(DM.DsConfi.DataSet.FieldByName('IMPRESORATICKET').Value,CenterString(MyTextRep  lace(DM.DsConfi.DataSet.FieldByName('FRASECIERRE').Value),44));
       //----------------------------------------------------------------------------
//       WriteRawDataToPrinter(DM.DsConfi.DataSet.FieldByName('IMPRESORATICKET').Value,espacios(' ',44,0));
       for i := 1 to 7 do  WriteRawDataToPrinter(DM.DsConfi.DataSet.FieldByName('IMPRESORATICKET').Value,DM.DsConfi.DataSet.Fie  ldByName('TEXTAVANZAR').Value);
     end;
  end else
  begin
    with Printer do
    begin
        PrinterIndex:=GetImpresora(DM.DsConfi.DataSet.FieldByName('IMPRESORATICKET').Value);
        r := Rect(100,100,(Pagewidth - 100),(PageHeight - 100));
        BeginDoc;
        Canvas.Brush.Style := bsClear;
        for i := 0 to Memo1.Lines.Count do
           Canvas.TextOut(100,180 + (i * Canvas.TextHeight(Memo1.Lines.Strings[i])),
        Memo1.Lines.Strings[i]);
        Canvas.Brush.Color := clBlack;
        Canvas.FrameRect(r);
        EndDoc;
    end;
  end;
  //Cortar papel
  WriteRawDataToPrinter(DM.DsConfi.DataSet.FieldByName('IMPRESORATICKET').Value,DM.DsConfi.DataSet.Fie  ldByName('TEXTCORTE').Value);
  //aBrirCajon
  WriteRawDataToPrinter(DM.DsConfi.DataSet.FieldByName('IMPRESORATICKET').Value,DM.DsConfi.DataSet.Fie  ldByName('CODIGOAPERTURACAJA').Value);
  //Inicializa la impresora
  WriteRawDataToPrinter(DM.DsConfi.DataSet.FieldByName('IMPRESORATICKET').Value,DM.DsConfi.DataSet.Fie  ldByName('TEXTINICIAR').Value);
end;

Como veis lo que hago es diversas llamadas a la tabla de configuración donde tengo definidos los campos con su código tipo TEXTCORTE, TEXTINICIAR, etc.
__________________
Un saludo desde Canarias, "El abuelo Cebolleta"
Responder Con Cita
  #3  
Antiguo 01-01-2014
Avatar de José Luis Garcí
[José Luis Garcí] José Luis Garcí is offline
Miembro Premium
 
Registrado: may 2003
Ubicación: Las Palmas de G.C.
Posts: 1.372
Poder: 23
José Luis Garcí Va camino a la fama
No se si os valdrá pero qui pongo alguno de los códigos usados en mis viejas EPDON TM 210 de las que no tengo drivers para mi windows 7, os advierto que puedo poner el texto a rojo, pero luego debo reiniciar mi impresora para que vuelva a salir a negro, no se por que es pero aquí os pongo casí todos, pero me reservo unos pocos para mi

Cita:

Iniciar la impresora \027\064 o \x1B
Cambiar a rojo \027\114\049
Cambiar a negro \027\114\048
Saltar x lineas \027\074\N (donde n es el número de lineas)
Algunos de los tamaños y tipos \027\033\X (donde x es alguno de los siguientes)
0 retorna a normal
1 Comprimida
8 Negrita
16 Grande
128 subrayada
Existen combinaciones como 9, 41 o 153 que combinan los diferentes formatos, pero así tenéis algo de trabajo vaguetes
Avanzar papel \027\100\N ( N= 0 a 255)
Cortar el papel \x1B@\x0A\x0D\x1Bi\x0A\x0D
Retroceder micras la impresora \027\075\n (n= 0 a 48)
Espero sea de utilidad, pero estos códigos podéis encontrarlos en los manuales de las impresoras.
__________________
Un saludo desde Canarias, "El abuelo Cebolleta"
Responder Con Cita
  #4  
Antiguo 01-01-2014
Avatar de José Luis Garcí
[José Luis Garcí] José Luis Garcí is offline
Miembro Premium
 
Registrado: may 2003
Ubicación: Las Palmas de G.C.
Posts: 1.372
Poder: 23
José Luis Garcí Va camino a la fama
Bueno ya no sigo por hoy con el monologo y espero no estar haciendo el ridículo, se que lo que he puesto debería estar bien ya que lo he probado, pero no me gustaría estar dando mal la información por que yo este equivocado, de hecho os hablo por que he estado al otro lado de la barra y se que era lo que me hacia falta, pero eso no quiere decir que mi verdad pueda ser la única.

Sigo diciendo que no soy la persona más adecuada, para enseñar, ya que me queda mucho por aprender, pero estoy seguro y muy seguro de que muchas de las cosas de las que hablo están en la red o debieran estar, lo único que hago es unificarlas y darles un punto de vista determinado, claro esta el mio.

Me considero bueno analizando problemas en los programas y a veces logro dar soluciones buenas, pero como me enseño mi amigo Jesús en programación normalmente a problema puede abordarse de varias maneras, que sean más o menos efectivas ya depende del programador, su experiencia y lo que quiera arriesgar.

Como ya dije no pienso poner esta vez el programa ni módulos completos, sólo es la teoría de como debe funcionar un TPV.

Que tengáis buen día.
__________________
Un saludo desde Canarias, "El abuelo Cebolleta"
Responder Con Cita
  #5  
Antiguo 01-01-2014
Avatar de fjcg02
[fjcg02] fjcg02 is offline
Miembro Premium
 
Registrado: dic 2003
Ubicación: Zamudio
Posts: 1.410
Poder: 22
fjcg02 Va camino a la fama
Gracias por la clase, magistral y cercana, como siempre.

Un saludo
__________________
Cuando los grillos cantan, es que es de noche - viejo proverbio chino -
Responder Con Cita
  #6  
Antiguo 02-01-2014
Avatar de Neftali [Germán.Estévez]
Neftali [Germán.Estévez] Neftali [Germán.Estévez] is offline
[becario]
 
Registrado: jul 2004
Ubicación: Barcelona - España
Posts: 18.293
Poder: 10
Neftali [Germán.Estévez] Es un diamante en brutoNeftali [Germán.Estévez] Es un diamante en brutoNeftali [Germán.Estévez] Es un diamante en bruto
Fantástica explicación.



Gracias.
__________________
Germán Estévez => Web/Blog
Guía de estilo, Guía alternativa
Utiliza TAG's en tus mensajes.
Contactar con el Clubdelphi

P.D: Más tiempo dedicado a la pregunta=Mejores respuestas.
Responder Con Cita
  #7  
Antiguo 03-01-2014
Avatar de José Luis Garcí
[José Luis Garcí] José Luis Garcí is offline
Miembro Premium
 
Registrado: may 2003
Ubicación: Las Palmas de G.C.
Posts: 1.372
Poder: 23
José Luis Garcí Va camino a la fama
Vamos con las rejillas y el stock



se pueden hacer con bastante trabajo mediante abundante código, las he visto incluso con un dbgrid normal y uno vertical, incluso de manera más común en un Stringrid, pero según mi modesta opinión lo mejor es usar un componente para ello, de hecho en el programa que estoy realizando es el único componente al que no le he metido mano y no es mio, lo llevo recomendando mucho tiempo es gratuito y lo podeis descargar junto con otros componente interesantes desde http://componentes.clubdelphi.com/, en este conjunto de componentes cedidos por algunos maestros del clubdelphi, así como un par de ellos míos y de otros compañeros, lo bueno de esta idea era que podi participar cualquiera independiente de su nivel y conocimientos, mientras el componente fuese suyo y lo cediera libremente, el componente si no recuerdo mal es CCDdBimagenGrid, la verdad que esta muy completo, sólo echo en falta el hint por casilla y que me da algunos problemas si los controles avanzar y retroceder páginas los inserto dentro de la rejilla, por ese motivo he optado por ponerlos en un panel aparte.

Lo bueno es que visualmente es atractivo, no he querido meterle mano y mirarlo con detenimiento, pero si lo hago le pediré permiso al compañero Luis Bataller, autor del componente, he intentaría añadirles propiedades como un auto hint con el teto del campo asociado y que la imagen pueda ser proporcional, para que no se deforme, el resto es muy muy bueno, seguro que hay componentes de pago que lograrán lo mismo, pero tampoco los he buscado.

Después de todo este monologo, paso a detallar lo que yo considero debemos tener en nuestra rejilla, es muy simple, principalmente su imagen descriptiva, recordar que vale más una imagen que mil palabras y mas en entornos de este tipo ya que nuestro cerebro asocia rápidamente la imagen a lo que deseamos mientras que el proceso de leer lleva muchísimo más tiempo, es recomendable que aparezca el texto descriptivo, he incluso su precio, pero con los dos primeros debemos darnos por contento.

Si os fijáis en la banda negra que pone artículos, es un panel que a su derecha tiene otro panel, donde pongo el artículo seleccionado, al no disponer del un autohint, debajo de esta tengo un panel con los botones para retroceder y avanzar página (flecha arriba y abajo), debajo de la primera flecha puse un estatic tex que relleno con los diferentes precios (*), y debajo de esta la palabra stock y un display donde nos mostrará el stock disponible de este producto, pero hablamos de productos como bocadillos, cafés etc, con esto quiero decir que no podemos poner un sistema de stock cerrado, simplemente regula ra el stock de los productos que nosotros deseamos al crear el artículo, dejando el uso de los otros libres, os pongo un ejemplo más claro.

Nosotros tenemos 10 cajas de cerveza de 250 c.c. a 18 botellas por caja nos da un total de 180 botella s de cerveza, de este artículo podemos hacer en su creación que tengamos el stock cerrado o no, realmente importa poco, la principal diferencia es que nos descuente o no del stock.

También tenemos 50 panes para bocadillos, pero no podemos darle entrada por e stock, salvo que sean ya preparados, ya que un bocadillo puede ser de tortilla, de lomo, etc

Esto no quiera decir que perdemos el control sobre las ventas, sólo lo perdemos sobre el stock, nosotros podemos saber cuantos bocadillos, cafés, cervezas, etc, hemos vendido, mediante una consulta SQL a nuestra tabla de tickets detalle.

Lo correcto para la entrada de productos es tener un form distinto, donde nos permita buscar el artículo, darle la cantidad de entrada, asegurarnos de que entra al mismo precio y si no es así si debemos cambiar el precio de nuestros productos.
__________________
Un saludo desde Canarias, "El abuelo Cebolleta"
Responder Con Cita
Respuesta


Herramientas Buscar en Tema
Buscar en Tema:

Búsqueda Avanzada
Desplegado

Normas de Publicación
no Puedes crear nuevos temas
no Puedes responder a temas
no Puedes adjuntar archivos
no Puedes editar tus mensajes

El código vB está habilitado
Las caritas están habilitado
Código [IMG] está habilitado
Código HTML está deshabilitado
Saltar a Foro

Temas Similares
Tema Autor Foro Respuestas Último mensaje
Teoría del Infierno fidel Humor 5 28-10-2016 01:00:14
Teoria y Practica jcarteagaf Humor 0 18-08-2008 16:32:34
Teoría sobre Archivos de Recursos MaMu OOP 3 15-04-2008 12:36:31
Frameworks, Persistencia: ¿Teoria? Delphius OOP 8 12-04-2008 23:27:24
Teoría del Salario obiwuan Humor 0 06-05-2003 22:00:43


La franja horaria es GMT +2. Ahora son las 00:04:26.


Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi
Copyright 1996-2007 Club Delphi