codigo latino 12

85

Upload: radicaled

Post on 09-Jun-2015

3.531 views

Category:

Documents


0 download

DESCRIPTION

Código Latino #12

TRANSCRIPT

Page 2: Codigo Latino 12

Hemos vuelto con entrevistas, con códigos y mucho ganas de enseñar; damos por terminada la sección de la Run Time Library de Eternal_Idol y veremos como poner a Windows a hacer lo que quiera de la mano de Cronodragon; esta edición se ha demorado por que he tenido un pequeño problema en la casa y es que se me inundo el fin de semana y hasta hoy se arreglo el chicharrón.

Espero disfruten leyendola tanto como yo hicé editandola!!!

Gracias a todos los lectores de Código Latino.

Page 3: Codigo Latino 12

● Crear nuestra propia RunTime Library III (C)● Autenticación en .NET I (VB.NET)● Manejador de procesos I – Fundamentos (Sistemas Operativos)● Entrevista a CHECMATED● ZTIC TAC TOE (ABAP)● Windows te ordeno que trabajes por mi (Autoit)● Incluir documentos HTML o datos complejos (Perl)● Entrevista a Daniel Bermudez● Software para captura de Inventarios (PHP)

Page 4: Codigo Latino 12

Crear nuestra propia RunTime Library (Tercera Parte)Por Eternal_Idol

En la MSDN encontré algo interesante sobre la opción /ENTRY del linker: 

"Type a function name in the Entry­Point Symbol text box (or in the function argument on the command line). The function must be defined with the __stdcall calling convention. The parameters and return value must be defined as documented in the Win32 API for WinMain (for an .EXE file) or DllEntryPoint (for a DLL). It is recommended that you let the linker set the entry point so that the C run­time library is initialized correctly, and C++ constructors for static objects are executed." 

Vamos a probar un poco de código con objetos estáticos: 

ESTATICOS.CPP #include <windows.h>void SayLong(int number){  char Data[10];  ltoa(number,Data,10);  MessageBox(0,Data,"El Numero",0);}

class Man{  public:  Man()  {     SayLong(66);  }

  ~Man()  {     SayLong(99);  }};

Man Jacinto;Man Pedrito;

void main(){

}

Compilando y linkeando este código con la Run Time Library por defecto conseguimos cuatro MessageBox, dos con 66 (el constructor) y dos con 99 (el destructor). Ahora tratamos de compilar y linkear con nuestra Run Time Library y nos encontramos con lo siguiente: estaticos.obj : error LNK2001: unresolved external symbol _atexit estaticos.exe : fatal error LNK1120: 1 unresolved externals 

Page 5: Codigo Latino 12

Si vamos a la MSDN podemos ver que lo que hace esta función es ejecutar la función que le es pasada como parámetro al final del programa. Usando una estructura de pila (LIFO). Entonces qué nos detiene? Qué nos imposibilita crear una función simple como esa? Nada, manos a la obra señores. 

C_ATEXIT.CPP #include <malloc.h>unsigned long *Funcs = 0;int n_funcs = 0;

extern "C" int atexit(void (__cdecl *func)(void)){  if (!Funcs) { Funcs = (unsigned long*)malloc(1); }  Funcs = (unsigned long*)realloc(Funcs,(n_funcs+1)*4);  Funcs[n_funcs] = (unsigned long)func;  n_funcs++;  return 0; }

extern "C" void destructores(){  for (int x = n_funcs­1;x >= 0;x­­)  {    void (__cdecl *calla)(void) = (void (__cdecl *)(void))Funcs[x];    calla();  }  free(Funcs);}

Hermoso el código verdad? Cada vez que se llama a la función atexit() se comprueba si ya tiene valor la estructura donde vamos a guardar los punteros a las funciones. Se realloca la memoria necesaria y se le asigna al elemento actual el parámetro func. Siempre devolvemos cero que indica que no hubo ningún error. 

Pero este código hermoso que hace exactamente hasta ahora? Ir llenando una lista de punteros a funciones, perfecto pero nos falta algo muy importante, recordemos que atexit() crea una lista de funciones que van a ser llamadas al final del programa. El principio del programa es la función de ENTRADA (solo nos interesan main, WinMain y DllMain ya que si fuera otra no usaría la Run Time Library, ni la nuestra ni la de VC++) que sabemos como se ejecuta, la llamamos nosotros desde nuestra Run Time Library por lo tanto sabemos perfectamente cuando termina de ejecutarse; en la siguiente instrucción a la llamada a main() el programa debe ejecutar la lista de funciones de atexit() y limpiar el buffer utilizado. Estas dos cosas las hace la función destructores() que está también en C_ATEXIT.CPP. 

Ahora mismo podríamos compilar el programa ESTATICOS.CPP pero no pasaría nada, la compilación y el linkeo serían satisfactorios pero nuestro programa no haría absolutamente nada. La pregunta del millón, quién llama a la función atexit(): la propia Run Time Library la llama. Acertaron? No me mientan eh. Y cuando y porqué la llama? Porque el compilador le pasa el puntero del destructor al ejecutar el constructor, por lo tanto, al no tener implementado nuestro código para manejar los constructores estáticos no recibimos 

Page 6: Codigo Latino 12

ninguna llamada a atexit() y destructores() se ejecuta sin ningún puntero al que llamar. 

Qué hace el compilador para decirnos que existen constructores de objetos estáticos? El compilador crea un función diferente para cada uno de los objetos estáticos (esto lo podemos comprobar viendo las direcciones que le pasa por cada objeto a atexit) y nos pasa dentro del ejecutable las 'etiquetas' (posición en el archivo) de esas funciones a ejecutarse. 

data_seg #pragma data_seg( ["section­name"[, "section­class"] ] ) 

Specifies the default section for data. For example: 

#pragma data_seg( "MY_DATA" ) 

causes data allocated following the #pragma statement to be placed in a section called MY_DATA. 

Data allocated using the data_seg pragma does not retain any information about its location. 

Estas secciones que se definen con #pragma data_seg son escritas por el linker dentro del ejecutable y tienen punteros,  a  inicializadores de C, constructores de C++, pre­terminadores de C y  terminadores de C que forman tablas, estas se guardan en variables que tienen el comienzo y el fin de la tabla y son pasadas a una función llamada _initterm() que se encarga de llamar a todos esos punteros ejecutando su código. Esta es la forma en la que se llama a al constructor de un objeto estático. 

Nuestro nuevo C_MAIN.CPP: #include <malloc.h>#include <string.h>extern "C" int __argc = 1;extern "C" char** __argv = 0;extern "C" void __stdcall ExitProcess(unsigned long uExitCode);extern "C" char* __stdcall GetCommandLineA(void);extern int main(int argc, char *argv[],char *env[]);extern "C" int __stdcall MessageBoxA(int a,char *b,char *c,unsigned int p);typedef void (__cdecl *_PVFV)(void);

#pragma data_seg(".CRT$XIA")_PVFV __xi_a[] = { 0 };

#pragma data_seg(".CRT$XIZ")_PVFV __xi_z[] = { 0 };

#pragma data_seg(".CRT$XCA")_PVFV __xc_a[] = { 0 };

#pragma data_seg(".CRT$XCZ")_PVFV __xc_z[] = { 0 };typedef void (* PFV)(void);

Page 7: Codigo Latino 12

#pragma data_seg(".CRT$XPA")PFV __xp_a = 0; /* C pre­terminators */

#pragma data_seg(".CRT$XPZ")PFV __xp_z = 0;

#pragma data_seg(".CRT$XTA")PFV __xt_a = 0; /* C terminators */

#pragma data_seg(".CRT$XTZ")PFV __xt_z = 0;

extern "C" void __cdecl _initterm(_PVFV *, _PVFV *);//__xi_a[], __xi_z[]; /* C initializers *///__xc_a[], __xc_z[]; /* C++ initializers *///__xp_a[], __xp_z[]; /* C pre­terminators *///__xt_a[], __xt_z[]; /* C terminators */extern "C" void destructores();

#define FALSE 0#define TRUE 1

extern "C" void mainCRTStartup(){  char *parámetros = GetCommandLineA();  char *temp = (char*)malloc(2048);  memset(temp,0,2048);  __argc = 0;  __argv = (char**)malloc(4);  char Except = FALSE;  while(*parámetros)  {    if (*parámetros == 34)    {      if (Except == FALSE)      {        Except = TRUE;      }      else      {        Except = FALSE;        if (strlen(temp) > 0)        {           __argv = (char**)realloc(__argv,4 * (__argc+1));           __argv[__argc] = (char*)malloc(strlen(temp) + 1);           memset(__argv[__argc],0,strlen(temp) + 1);           strcpy(__argv[__argc],temp);           strcpy(temp,"");           __argc++;         }      }      parámetros++;      continue;

Page 8: Codigo Latino 12

   }

   if ( (*parámetros == 32) && (Except == FALSE) )   {      if (strlen(temp) > 0)     {       __argv = (char**)realloc(__argv,4 * (__argc+1));       __argv[__argc] = (char*)malloc(strlen(temp) + 1);       memset(__argv[__argc],0,strlen(temp) + 1);       strcpy(__argv[__argc],temp);       strcpy(temp,"");       __argc++;      }   }    else   {     unsigned long pos = strlen(temp);     temp[pos] = *parámetros;     temp[pos+1] = 0;   }   parámetros++;  }  if (strlen(temp) > 0)  {    __argv = (char**)realloc(__argv,4 * (__argc+1));    __argv[__argc] = (char*)malloc(strlen(temp) + 1);    memset(__argv[__argc],0,strlen(temp) + 1);    strcpy(__argv[__argc],temp);    strcpy(temp,"");    __argc++;  }   free(temp);  _initterm(__xi_a,__xi_z);  _initterm(__xc_a,__xc_z);  main(__argc,__argv,0);  _initterm(&__xp_a,&__xp_z);  _initterm(&__xt_a,&__xt_z);  destructores();

  for (int y = 0;y < __argc;y++) { free(__argv[y]); }  free(__argv);  ExitProcess(0);}

static void __cdecl _initterm(_PVFV *pfbegin,_PVFV *pfend){  while (pfbegin < pfend)  {    if (*pfbegin) { (**pfbegin)(); }    ++pfbegin;  }}

Page 9: Codigo Latino 12

Este nuevo main define las diferentes secciones donde se encontrarán las benditas tablas, llama a las tablas de inicio justo antes que a main() y a las de terminaciones justo después, además de llamar a nuestra función destructores().   Las   tablas   son   procesadas   por   la   función   initterm()   que   recorre   la   tabla   de   punteros   a funciones, ejecutando cada uno de ellas, hasta encontrar un puntero nulo. 

Creamos nuestra libreria y ESTATICOS.EXE: 

cl /c *.cpp lib *.obj /out:clib.lib cl /c ESTATICOS.CPP link ESTATICOS.OBJ /NODEFAULTLIB USER32.LIB KERNEL32.LIB \CLIB\CLIB.LIB Ahora   si,   tenemos  el  mismo comportamiento  que  con   la  Run  Time Library  de  VC++ para   los  objetos estáticos. 

Un regalito en esta parte, vamos a ver como manejar las variables de entorno: 

C_MAIN.CPP #include <malloc.h>#include <string.h>

//entornoextern "C" int vars = 0;extern "C" char** _environ = 0;extern "C" char* __stdcall GetEnvironmentStrings(void);extern "C" bool __stdcall FreeEnvironmentStringsA(char *block);void __cdecl _envinit(void);//parámetrosextern "C" int __argc = 1;extern "C" char** __argv = 0;extern "C" void __stdcall ExitProcess(unsigned long uExitCode);extern "C" char* __stdcall GetCommandLineA(void);extern int main(int argc, char *argv[],char *env[]);extern "C" int __stdcall MessageBoxA(int a,char *b,char *c,unsigned int p);typedef void (__cdecl *_PVFV)(void);

#pragma data_seg(".CRT$XIA")_PVFV __xi_a[] = { 0 };#pragma data_seg(".CRT$XIZ")_PVFV __xi_z[] = { 0 };#pragma data_seg(".CRT$XCA")_PVFV __xc_a[] = { 0 };#pragma data_seg(".CRT$XCZ")_PVFV __xc_z[] = { 0 };typedef void (* PFV)(void);#pragma data_seg(".CRT$XPA")PFV __xp_a = 0; /* C pre­terminators */#pragma data_seg(".CRT$XPZ")PFV __xp_z = 0;#pragma data_seg(".CRT$XTA")PFV __xt_a = 0; /* C terminators */

Page 10: Codigo Latino 12

#pragma data_seg(".CRT$XTZ")PFV __xt_z = 0;extern "C" void __cdecl _initterm(_PVFV *, _PVFV *);//__xi_a[], __xi_z[]; /* C initializers *///__xc_a[], __xc_z[]; /* C++ initializers *///__xp_a[], __xp_z[]; /* C pre­terminators *///__xt_a[], __xt_z[]; /* C terminators */extern "C" void destructores();

#define FALSE 0#define TRUE 1

extern "C" void mainCRTStartup(){  char *parámetros = GetCommandLineA();  char *temp = (char*)malloc(2048);  memset(temp,0,2048);  __argc = 0;  __argv = (char**)malloc(4);  char Except = FALSE;  while(*parámetros)  {    if (*parámetros == 34)    {      if (Except == FALSE)      {        Except = TRUE;      }      else      {        Except = FALSE;        if (strlen(temp) > 0)        {          __argv = (char**)realloc(__argv,4 * (__argc+1));          __argv[__argc] = (char*)malloc(strlen(temp) + 1);          memset(__argv[__argc],0,strlen(temp) + 1);          strcpy(__argv[__argc],temp);          strcpy(temp,"");          __argc++;          }       }       parámetros++;       continue;    }

     if ( (*parámetros == 32) && (Except == FALSE) )     {         if (strlen(temp) > 0)       {          __argv = (char**)realloc(__argv,4 * (__argc+1));          __argv[__argc] = (char*)malloc(strlen(temp) + 1);          memset(__argv[__argc],0,strlen(temp) + 1);          strcpy(__argv[__argc],temp);

Page 11: Codigo Latino 12

          strcpy(temp,"");          __argc++;         }      }       else      {         unsigned long pos = strlen(temp);         temp[pos] = *parámetros;         temp[pos+1] = 0;      }      parámetros++;    }    if (strlen(temp) > 0)    {       __argv = (char**)realloc(__argv,4 * (__argc+1));       __argv[__argc] = (char*)malloc(strlen(temp) + 1);       memset(__argv[__argc],0,strlen(temp) + 1);       strcpy(__argv[__argc],temp);       strcpy(temp,"");       __argc++;    }     free(temp);    _initterm(__xi_a,__xi_z);    _initterm(__xc_a,__xc_z);    _envinit();     main(__argc,__argv,_environ);    _initterm(&__xp_a,&__xp_z);    _initterm(&__xt_a,&__xt_z);    destructores();

    for (int y = 0;y < __argc;y++) { free(__argv[y]); }    free(__argv);    for (int z = 0;z < vars;z++)     {       if (_environ[z]) { free(_environ[z]); }    }     free(_environ);    ExitProcess(0);}

static void __cdecl _initterm(_PVFV *pfbegin,_PVFV *pfend){while (pfbegin < pfend){ if (*pfbegin) { (**pfbegin)(); } ++pfbegin;}}

void __cdecl _envinit(void){char *var = GetEnvironmentStrings();_environ = (char**)malloc(4);

Page 12: Codigo Latino 12

while(*var){ _environ = (char**)realloc(_environ,(vars + 1) * 4); _environ[vars] = (char*)malloc(strlen(var) + 1); memset(_environ[vars],0,strlen(var) + 1); strcpy(_environ[vars],var);  (char*)var += strlen((char*)var); (char*)var +=1; vars++;}FreeEnvironmentStringsA(var);}

Esta nueva versión del C_MAIN.CPP incorpora la función _envinit, que cre la lista de variables de entorno y le pasa la variable _environ a la función main() de nuestro programa. 

Ahora vamos a implementar getenv y putenv: 

C_PUTENV.CPP #include <malloc.h>#include <string.h>

extern "C" int vars;extern "C" char** _environ;

bool compararPut(char *s1,const char *s2){while(*s2){ if (*s1 != *s2) { return false; } s1++; s2++;} return true;}

extern "C" int putenv(const char *envstring){for (int x = 0;x < vars;x++){ if (!_environ[x]) { continue; } if (compararPut(_environ[x],envstring) == true) { char *ptr = (char*)envstring; while(*envstring) { if ( (*ptr == '=') && (*++ptr == 0) ) { free(_environ[x]);

Page 13: Codigo Latino 12

 _environ[x] = 0; return 0; }  ptr++;  }  strcpy(_environ[x],envstring);  return 0; }}_environ = (char**)realloc(_environ,(vars + 1) * 4);_environ[vars] = (char*)malloc(strlen(envstring) + 1);memset(_environ[vars],0,strlen(envstring) + 1);strcpy(_environ[vars],envstring); vars++;return 0;}

C_GETENV.CPP #include <string.h>

extern "C" int vars;extern "C" char** _environ;

bool compararGet(char *s1,const char *s2){while(*s2){ if (*s1 != *s2) { return false; } s1++; s2++;} if (*s1 == '=') { return true; }return false;}

extern "C" char *getenv(const char *varname){for (int x = 0;x < vars;x++){ if (!_environ[x]) { continue; } if (compararGet(_environ[x],varname) == true) { return (_environ[x]+strlen(varname)+1); }}return 0;}

Podemos   probar   su   correcto   funcionamiento   con   cualquier   programa   que   use   el   parámetro   envp   o 

Page 14: Codigo Latino 12

simplemente cambiando variables del entorno como TMP (el path de los archivos temporales). 

En la cuarta parte veremos como implementar las funciones de entrada y salida por consola. 

Saludos, Mariano. 

Page 15: Codigo Latino 12

Autenticación en .NET (Primera Parte)Por Piyey http://piyeycorp.wordpress.com/

¿Cuántos métodos de encriptación has probado para tus aplicaciones?Hoy en  día  sabemos  que   la   seguridad  en  nuestras   aplicaciones   es  un   factor  muy  importante.  Debemos brindarle   a   nuestros   clientes   o   a   la   empresa   donde   trabajemos   seguridad   en   las   aplicaciones   que desarrollamos. En este punto, hablaré sobre la seguridad ejemplificando el login de usuarios.Existen muchos métodos de encriptación, en lo personal he probado un par de ellos. Cuando trabajé con php lo hacía con MD5, el cual php ya incluye una función para hacer un hash con este método. En otra ocasión utilicé  un método de encriptación el  cual  se   tiene una “semilla” o “clave” con  la  cual  encriptas  y  para desencriptar debes conocerla. También utilicé un algoritmo que te generaba una matriz aleatoria y te incluida la “semilla” dentro de la cadena encriptada, y el método de desencriptación la buscaba en la cadena y con ella lo desencriptaba.Ahora, con .NET, en la ayuda que brinda pude ver que ellos ofrecen un método en el cual utilizan una “salt” el cual es el complemento de la contraseña. En uno de los métodos que utilizaba antes sería la semilla, pero en esos algoritmos la semilla iba en código duro, a diferencia del método que implementaré en este ejemplo, el cual se almacena en la BD.Como ejemplo tomaremos un requerimiento inicial como el siguiente:“Se necesita crear un módulo de seguridad en el que los usuarios tengan acceso con su nombre de usuario y  contraseña. La seguridad deberá ser muy importante en este módulo. Los usuarios tendrán roles, un usuario  podrá   tener uno o más roles. Existirán permisos a las distintas funciones que se establecerán por rol o exclusivamente por usuario, esto es, un usuario podrá tener acceso a funciones heredadas desde sus roles o a funciones específicas asignadas a su cuenta exclusivamente.”Acá mostraré un ejemplo de cómo implementar seguridad en la autenticación y autorización utilizando las Interfaces IIdentity & IPrincipal suplantando la identidad por defecto de la aplicación que es la identidad de Windows estableciendo My.User.CurrentPrincipal, el cual es una clase implementando la interface IPrincipal, en la cual crearemos una clase utilice dicha interface.

Creando una IdentidadA como se mencionó anteriormente, .NET utiliza las interfaces  IIdentity  y  IPrincipal  como base para la autenticación   y   autorización,   para   este   ejemplo   utilizaremos   la   autenticación   de   usuario   personalizada, haciendo uso de estas interfaces.

Implementando IIdentity.Primeramente   crearemos   una   nueva   clase   (Menú   Proyecto­>Agregar   clase)   y   le   pondremos   el   nombre AplicationIIdentity.vb. Una vez creada se nos abrirá la ventana de código de dicha clase con el siguiente código:Public Class ApplicationIIdentityEnd Classen la linea siguiente de public class ApplicationIIdentity escribiremos la siguiente linea:Implements System.Security.Principal.IIdentityy al   final  presionamos  enter,  el  editor  de  código crea   las  propiedades  que  se deben  implementar  de   la interface utilizada, quedando de la siguiente manera:

Page 16: Codigo Latino 12

Public Class AplicationIIdentity  Implements System.Security.Principal.IIdentity  Public ReadOnly Property AuthenticationType() As String Implements System.Security.Principal.IIdentity.AuthenticationType    Get    End Get  End Property  Public ReadOnly Property IsAuthenticated() As Boolean Implements System.Security.Principal.IIdentity.IsAuthenticated    Get    End Get  End Property  Public ReadOnly Property Name() As String Implements System.Security.Principal.IIdentity.Name    Get    End Get  End PropertyEnd Class

luego añadimos unos atributos privados para almacenar el nombre de usuario y un valor que indicará si el usuario está autenticado o no:Private nameValue As StringPrivate authenticatedValue As BooleanPrivate roleValue As ApplicationServices.BuiltInRoleen la propiedad AuthenticationType añadimos el siguiente código:Return “Autenticación personalizada”esto   indica   que   el   tipo   de   autenticación   es   personalizada   por   el   usuario   y   no   por   windows.En la propiedad IsAuthenticated escribimos el siguiente código:Return authenticatedValueesta   propiedad   indica   si   el   usuario   está   autenticado   o   no   en   el   sistema.Ahora escribimos el código para la propiedad Name, la cual retorna el nombre del usuario autenticado:Return nameValueEn  nuestro   ejemplo,   los  usuarios   trabajarán  con   los  distintos   roles   asignados  a   su  cuenta,  por   lo   tanto crearemos una propiedad que retorne los roles del usuario:Public ReadOnly Property Role() As ApplicationServices.BuiltInRole Get   Return roleValue End GetEnd PropertyCabe mencionar que en este ejemplo estamos tomando los roles de la enumeración BuiltInRole que viene en el espacio de nombres (namespace) ApplicationServices, puede quedar como proyecto del lector (pa que no boludee y lo deje todo al autor jejeje) escribir el código para trabajar con distintos roles que se implementen en su aplicación.Bien,  hasta  acá  hemos  terminado con  las  propiedades  que  deben  implementarse  por   ley  de   la   interface utilizada, añadiendo una propiedad extra para controlar los roles del usuario.Ahora crearemos el constructor de la clase, el cual inicializará la clase mediante la autenticación del usuario, brindandole el nombre de usuario y la contraseña. El código es el siguiente:Public Sub New(ByVal name As String, ByVal password As String) If IsValidNameAndPassword(name, password) Then   nameValue = name   authenticatedValue = True   roleValue = ApplicationServices.BuiltInRole.Administrator

Page 17: Codigo Latino 12

 Else   nameValue = ""   authenticatedValue = False   roleValue = ApplicationServices.BuiltInRole.Guest End IfEnd SubEn el constructor hacemos uso de un método denominado IsValidNameAndPassword el cual lo definimos a continuación:Nota: como método didáctico en este ejemplo obtendremos los datos del usuario desde código duro. En una  segunda entrega se hará desde la base de datos.

Private Function IsValidNameAndPassword( _ ByVal username As String, _ ByVal password As String) _ As Boolean

 ' Obtenemos la contraseña encriptada y la salt. Dim storedHashedPW As String = GetHashedPassword(username) Dim salt As String = GetSalt(username)

 'Creamos el hash con la salt leida y la contraseña brindada. Dim rawSalted As String = salt & Trim(password) Dim saltedPwBytes() As Byte = _ System.Text.Encoding.Unicode.GetBytes(rawSalted) Dim sha1 As New _ System.Security.Cryptography.SHA1CryptoServiceProvider Dim hashedPwBytes() As Byte = sha1.ComputeHash(saltedPwBytes) Dim hashedPw As String = Convert.ToBase64String(hashedPwBytes)

 ' Comparamos la contraseña con el hash contra la contraseña almacenada. Return hashedPw = storedHashedPWEnd FunctionAhora   creamos   las   funciones   utilizadas   en   el   método   anterior   (GetHashedPassword   y   GetSalt):Nota: a como se dijo anteriormente, en esta entrega trabajaremos desde código duro la salt y la contraseña,  en la próxima entrega lo trataremos desde la base de datos.Private Function GetHashedPassword(ByVal username As String) As String ' Aca va el código que obtiene la contraseña con hash del usuario desde la BD. ' En este ejemplo usaremos código duro para obtenerla. ' Por buena práctica, la contraseña hash debe ser almacenada fuera ' del código de la aplicación. If Trim(username).ToLower = "testuser" Then   Return "ZFFzgfsGjgtmExzWBRmZI5S4w6o=" Else   Return "" End IfEnd Function

Private Function GetSalt(ByVal username As String) As String ' El código que obtiene la sal del usuario va acá. ' En este ejemplo usaremos código duro para obtener la salt. ' Por buena práctica, la salt debe ser almacenada fuera ' del código de la aplicación.

Page 18: Codigo Latino 12

 If Trim(username).ToLower = "testuser" Then   Return "Debe ser un valor aleatorio diferente para cada usuario" Else   Return "" End IfEnd FunctionHasta acá está el código de la clase ApplicationIIdentity. El código completo de la clase debe quedar como el siguiente:Public Class ApplicationIIdentity  Implements System.Security.Principal.IIdentity  Private nameValue As String  Private authenticatedValue As Boolean  Private roleValue As ApplicationServices.BuiltInRole  Public ReadOnly Property AuthenticationType() As String Implements System.Security.Principal.IIdentity.AuthenticationType    Get      Return “Autenticación personalizada”    End Get  End Property  Public ReadOnly Property IsAuthenticated() As Boolean Implements System.Security.Principal.IIdentity.IsAuthenticated    Get     Return authenticatedValue    End Get  End Property  Public ReadOnly Property Name() As String Implements System.Security.Principal.IIdentity.Name    Get      Return nameValue    End Get  End Property  Public ReadOnly Property Role() As ApplicationServices.BuiltInRole    Get      Return roleValue    End Get  End Property  Public Sub New(ByVal name As String, ByVal password As String)    If IsValidNameAndPassword(name, password) Then      nameValue = name      authenticatedValue = True      roleValue = ApplicationServices.BuiltInRole.Administrator    Else      nameValue = “”      authenticatedValue = False      roleValue = ApplicationServices.BuiltInRole.Guest    End If  End Sub  Private Function IsValidNameAndPassword( _    ByVal username As String, _    ByVal password As String) _    As Boolean    ‘ Obtenemos la contraseña encriptada y la salt.    Dim storedHashedPW As String = GetHashedPassword(username)    Dim salt As String = GetSalt(username)    ‘Creamos el hash con la salt leida y la contraseña brindada.    Dim rawSalted As String = salt & Trim(password)

Page 19: Codigo Latino 12

    Dim saltedPwBytes() As Byte = _    System.Text.Encoding.Unicode.GetBytes(rawSalted)    Dim sha1 As New _    System.Security.Cryptography.SHA1CryptoServiceProvider()    Dim hashedPwBytes() As Byte = sha1.ComputeHash(saltedPwBytes)    Dim hashedPw As String = Convert.ToBase64String(hashedPwBytes)    ‘ Comparamos la contraseña con el hash contra la contraseña almacenada.    Return hashedPw = storedHashedPW  End Function  Private Function GetHashedPassword(ByVal username As String) As String    ‘ Aca va el código que obtiene la contraseña con hash del usuario desde la BD.    ‘ En este ejemplo usaremos código duro para obtenerla.    ‘ Por buena práctica, la contraseña hash debe ser almacenada fuera    ‘ del código de la aplicación.    If Trim(username).ToLower = “testuser” Then      Return “ZFFzgfsGjgtmExzWBRmZI5S4w6o=”    Else      Return “”    End If  End Function  Private Function GetSalt(ByVal username As String) As String    ‘ El código que obtiene la sal del usuario va acá.    ‘ En este ejemplo usaremos código duro para obtener la salt.    ‘ Por buena práctica, la salt debe ser almacenada fuera    ‘ del código de la aplicación.    If Trim(username).ToLower = “testuser” Then      Return “Debe ser un valor aleatorio diferente para cada usuario“    Else      Return “”    End If  End FunctionEnd Class

Bien, ya tenemos la identidad, ahora trabajaremos con la clase ApplicationIPrincipal.

Crear una clase Principal.En   este   punto   debemos   crear   una   nueva   clase   que   implemente   la   interface  IPrincipal.Creamos una nueva clase (Proyecto­>Agregar clase) y le pondremos el nombre  ApplicationIPrincipal. Una vez creada la clase, en el código ponemos lo siguiente justo despues de la lineaPublic Class ApplicationIPrincipal:Implements System.Security.Principal.IPrincipalal presionar enter al final de esta línea, el editor de código agregará una propiedad y un método que deben implementarse en nuestra clase. Luego agregamos un atributo privado que almacenará la identidad asociada a nuestro objeto principal:Private identityValue As ApplicationIIdentityLuego, en la propiedad Identity agregamos el siguiente código:Return identityValuey en el método IsInRole agregamos el siguiente código:Return role = identityValue.Role.ToStringAhora   crearemos   el   constructor   de   la   clase,   el   cual   inicializa   la   clase   con   una   instancia   de 

Page 20: Codigo Latino 12

ApplicationIIdentity, brindando el nombre de usuario y la contraseña:Public Sub New(ByVal name As String, ByVal password As String)  identityValue = New SampleIIdentity(name, password)End Subaca establecemos la identidad del usuario haciendo uso de la clase ApplicationIIdentity.El código de la claseApplicationIPrincipal debe quedar de la siguiente manera:Public Class ApplicationIPrincipal  Implements System.Security.Principal.IPrincipal  Private identityValue As ApplicationIIdentity  Public ReadOnly Property Identity() As System.Security.Principal.IIdentity Implements System.Security.Principal.IPrincipal.Identity    Get      Return identityValue    End Get  End Property  Public Function IsInRole(ByVal role As String) As Boolean Implements System.Security.Principal.IPrincipal.IsInRole    Return role = identityValue.Role.ToString  End Function  Public Sub New(ByVal name As String, ByVal password As String)     identityValue = New ApplicationIIdentity(name, password)  End SubEnd Class

Probando nuestra clase de autenticación.Para probar nuestra clase de autenticación de usuarios personalizada, haremos uso del formulario de inicio de sesión que nos brinda Visual Basic .NET. Nos vamos a la opción  proyecto­>Agregar Windows Forms… y seleccionamos Formulario de inicio de sesión y le ponemos el nombre frmLogin.vb.Luego que lo creamos nos aparece el formulario en diseño, damos doble clic en el botón Aceptar y nos aparecerá el código para el evento Click del botón. Nos aparecerá un código autogenerado por el IDE, el cual reemplazaremos con el siguiente código:Private Sub OK_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdAceptar.Click  Dim samplePrincipal As New ApplicationIPrincipal( _  Me.UsernameTextBox.Text, Me.PasswordTextBox.Text)  Me.PasswordTextBox.Text = “”  If (Not samplePrincipal.Identity.IsAuthenticated) Then    ‘ The user is still not validated.    MsgBox(“The username and password pair is incorrect”)  Else    ‘ Update the current principal.    My.User.CurrentPrincipal = samplePrincipal    Me.Close()  End IfEnd Sub

LISTO!!!!

Ahora solo queda hacer la llamada de nuestro formulario de login para terminar de probarlo. Añadiremos un formulario a nuestro proyecto y le agregaremos 2 etiquetas (Label) y un botón (Button) dejándolos todos con el nombre por defecto (Label1, Label2 y Button1), luego borramos el texto de las etiquetas dejándolo vacío. 

Page 21: Codigo Latino 12

Al botón le pondremos en la propiedad text a Autenticar. Luego hacemos doble clic sobre el botón y en el evento clic añadimos el siguiente código:

My.Forms.frmLogin.ShowDialog()' Verificamos si el usuario está autenticado.If My.User.IsAuthenticated Then Me.Label1.Text = "Autenticado como " & My.User.NameElse Me.Label1.Text = "User not authenticated"End If

If My.User.IsInRole(ApplicationServices.BuiltInRole.Administrator) Then Me.Label2.Text = "El usuario es un Administrador"Else Me.Label2.Text = "El usuario no es Administrador"End If

Este pequeño código lo que haces es: llama al formulario de login, el cual se encarga de verificar si el usuario introduce usuario y contraseña correcta, luego que se cierre el formulario de login, verifica en la instancia de aplicación My.User, la cual la sustituimos por nuestra instancia creada en nuestra clase.My.User es una instancia de la aplicación que contiene la información del usuario, la cual implementa la interface IPrincipal… en este caso, nosotros hemos creado una clase que implementa de esta misma interface para sustituir el contenido de My.User por el nuestro.En la próxima entrega trataremos el punto sobre la seguridad en el almacenamiento de la contraseña y la salt en nuestra base de datos. Haremos el diseño de nuestra BD para poder acceder a ella y mejorar nuestro código.Espero les haya servido este “breve”  tutorial sobre seguridad en .NET en la implementación de usuarios y contraseñas xD jejeje…

Saludos,Ing. Paúl Somarriba

Page 22: Codigo Latino 12

Sistemas OperativosManejador de Procesos (Primera parte) ­ FundamentosPor JuanK http://juank.black­byte.com

Esta es una serie de 2 o 3 post introductorios acerca de lo que es el manejador de procesos, la idea es tener un concepto muy general de lo que hace esta parte de todo sistema operativo, sin embargo es un tema muy extenso y que puede  llegar  a  ser  bastante  complejo,  por   lo  cual  cabe  aclarar  que por  el  momento solo trataremos los conceptos de manera muy superficial.

El   manejador   de   procesos   (también   llamado   planificador,   scheduler,   calendarizador   etc.)   es   la   parte fundamental de todo sistema operativo, de hecho se puede decir que para crear un sistema operativo básico basta con crear cuatro componentes fundamentales:

• Planificador de procesos • Administrador de memoria • Manejador de E/S (como mínimo con controladores para video, teclado y disco) • Sistema de archivos 

El  manejador  de  procesos  es  el   encargado,  como su  nombre   lo   indica,  de  permitir   le   ejecución  de   los diferentes procesos en una o varias CPU. A simple vista esta tarea es sencilla, pero esta lejos de serlo.

El procesador es un dispositivo que ejecuta un conjunto de instrucciones y devuelve un resultado, así que desde el punto de vista del procesador el concepto de proceso no existe más allá de ejecutar una instrucción en cada ciclo de procesamiento; es el sistema operativo quien determina que es un proceso en si: un conjunto de instrucciones agrupadas con un(os) objetivo(s) especifico(s). 

Cuando estamos utilizando un sistema operativo como Windows siempre tenemos la percepción de que hay múltiples   programas   ejecutándose   al   mismo   tiempo,   podemos   ver   varias   ventanas   abiertas   mientras escuchamos música, navegamos por internet y diligenciamos una hoja de cálculo de excel, pero esto no es más que una ilusión. 

Para simplificar un poco el trabajo examinaremos la situación cuando solo hay presente un procesador de un único núcleo.

funcionamiento básico de una CPULa CPU, como ya lo mencionamos, solo puede ejecutar una instrucción a la vez, pero como es esto?

Bueno la forma mas sencilla de explicarlo es con un ejemplo: digamos que queremos sumar los valores 2+3 utilizando la CPU, la CPU tiene una especie de ‘ranuras’ llamadas registros algunas de estas ranuras reciben los nombres de Ax, Bx, Cx (pero hay varias más.) y son utilizados por la CPU como fuente de entrada y salida de información.

Lo que se hace entonces para la suma es colocar los valores a sumar en los registros, esto es un mini ejemplo en lenguaje ensamblador:

Page 23: Codigo Latino 12

mov AX, 2 ; poner el número 2 en el registro AXadd AX, 3 ;sumar al contenido de AX el valor 3, la respuesta queda en AXveamos estos dos pasos en el siguiente gráfico (lo he expandido a 4 pasos para mayor claridad)

El procesador posee un registro que es un apuntador que le permite saber en que instrucción del programa se encuentra  de tal  manera que cada vez que ejecuta una instrucción el  mueve al  apuntador  a  la  siguiente instrucción a ser ejecutada.

Cualquier instrucción ejecutada por la CPU funciona de manera similar, utilizando los registros como ranuras de intercambio de datos.

Cómo se ejecutan varios procesos?De acuerdo al tema tratado anteriormente pudimos ver que una CPU solo puede ejecutar una instrucción a la vez, y como es de suponerse dicha instrucción pertenece a un proceso determinado. Hay varias maneras de llevar a cabo la ejecución de procesosSistemas Operativos MonotareaLa CPU por si sola no puede iniciar la ejecución de otro proceso, es el sistema operativo es quien le dice a la CPU cuando comenzar a ejecutar un conjunto de instrucciones determinado, sin embargo la CPU ejecutaría todas las instrucciones de un proceso hasta finalizar y en ese momento continuaría la ejecución del sistema operativo (que en si es otro proceso) el cual seleccionaría el siguiente proceso a ejecutar suspendiéndose a si mismo  hasta  que  el   proceso   finalice,   luego  nuevamente  volvería  a   seleccionar   un  nuevo  proceso  y   así sucesivamente hasta que no hubiesen procesos por ejecutar.

Algunos dirán y como es que se vuelve a ejecutar el sistema operativo cuando acaba de terminar un proceso?, 

Page 24: Codigo Latino 12

bueno el truco es sencillo, devolvámonos a algunos sistemas mono tarea tipo DOS en sus primeras versiones, si  hacíamos  un  programa en  C este   al   final  del  main  siempre   tenia   la   instrucción   return,  pues  bien  el compilador al compilar código convertía esa expresión return en instrucciones de maquina que hacían que la siguiente ‘línea’ de código a ejecutar fuera… el sistema operativo, así que básicamente todo programa hecho finaliza con una instrucción para devolver el control al sistema operativo.

Este tipo de comportamiento es el habitual en sistemas operativos mono­proceso , es decir que solo pueden ejecutar un proceso a la vez de tal forma que todos los procesos deben esperar su turno en una larga fila de procesos pendientes: esto también es conocido como: planificación por lotes.

Si Windows funcionara de esta manera no podríamos hacer nada con el pues no podríamos tener sino un programa a la vez y esto excluye de manea inevitable los propios servicios que el sistema operativo corre en segundo plano, incluso si mandaras un trabajo de impresión no podrías hacer absolutamente nada más hasta que el trabajo de impresión finalice.

Esto esta muy lejos de ser el comportamiento que estamos habituados a ver, es decir un sistema con decenas de procesos ejecutándose ‘al tiempo’, entonces como funciona esto? bueno todo se resuelve con un truco que realiza el sistema operativo.

Sistemas Operativos MultitareaComo su nombre lo indica ‘multitarea’ se refiere a que puede realizar varias tareas a la vez, al menos eso es lo que parece.

Realmente lo que sucede es que el sistema operativo esta hecho para tomar la sabia decisión de no permitirle a un programa ejecutarse sino por una fracción de tiempo (muy pequeña),  de  tal  forma que en un solo segundo   muchos   programas   han   tenido   tiempo   de   procesamiento,   es   decir   muchos   programas   se   han ejecutado en lapsos de pequeñas fracciones de tiempo. En esencia el concepto es sencillo, implementarlo suele ser más complicado pues hay muchos más aspectos involucrados, estudiaremos algunos.

Interrupción de la Ejecución de un ProcesoAl   ejecutarse   un   proceso   en   un   sistema   multitarea,   este   tiene   la   oportunidad   de   realizar   un   conjunto indeterminado de instrucciones, lo que alcance a hacer en un tiempo limitado, una vez ese tiempo se ha cumplido el sistema operativo debe decidir que proceso debe continuar su ejecución ( bien sean procesos de usuario o procesos de sistema ), esto lo hace teniendo en cuenta una lista de procesos y unas listas por prioridades de procesos, donde algunos procesos tienen más tiempo de ejecución que otros y tienen una 

Page 25: Codigo Latino 12

prioridad mayor que les permite ‘avanzar más rápido en la fila’.

El sistema operativo sabe que se ha cumplido el tiempo de ejecución de un proceso cuando recibe una señal de interrupción por parte del procesador, esta señal se activa solo cada determinado tiempo (este lapso de tiempo es   llamado Quantum),  básicamente  existe  un microprograma que en  ese  momento  le  permite  al procesador suspender la ejecución y enviar el control (es decir ejecutar) al sistema operativo para que lleve a cabo la planificación necesaria .

Sin embargo hay otros mecanismos que pueden generar interrupciones como por ejemplo:• Una Señal enviada desde un dispositivo de hardware • Un proceso puede optar por suspenderse a si mismo 

Hay muchas situaciones donde las dos condiciones anteriores puede ocurrir, este es un ejemplo típico:

El proceso P1 se encuentra en ejecución y en un momento determinado espera respuesta desde un dispositivo de E/S(por ejemplo una tarjeta de red), pero no sabe en que momento se recibirá dicha respuesta, así que el proceso  se  encuentra  en  espera  y  suspende su ejecución.  El   sistema operativo  coloca  al  proceso  P2 en ejecución y este comienza a ejecutarse durante su Quantum, seguidamente termina su tiempo de ejecución y siguen en ejecución otros procesos P3…Pn.

En un momento determinado el proceso P5 se encontraba en ejecución cuando el dispositivo de red envió la respuesta que estaba esperando P1, el procesador conoce de esa respuesta y genera una nueva interrupción (es decir   devuelve   el   control   otra   vez   al   sistema   operativo)   suspendiendo   inmediatamente   el   proceso   en ejecución. El sistema operativo revisa los buffer de los dispositivos de entrada, encuentra la respuesta que esperaba P1 y activa inmediatamente P1 para que este continúe con su ejecución por un nuevo Quantum de tiempo o en tanto no se genere una nueva interrupción cualquiera que sea su origen.

Tenemos  entonces   tres  maneras  que  permiten  que  un  proceso   suspenda  su  ejecución  para  que  otros   se ejecuten:

1. Interrupción por el reloj del procesador (Quantum de tiempo) 2. Interrupción por dispositivos de E/S 3. Auto suspensión del proceso o finalización del proceso. 

Estado De La Ejecución De Un ProcesoYa hemos visto como es que el sistema operativo alterna entre varios procesos para dar la impresión de que esta haciendo varias cosas a la vez, pero puede que alguno de ustedes ya les haya surgido la pregunta: ¿Cómo sabe el sistema en que iba mi proceso justo antes de suspenderlo? veamos el caso anterior (el de 2 +3) en un entorno multitarea:

Page 26: Codigo Latino 12

En  la  gráfica  vemos  al  proceso  P1  justo   terminando de   finalizar   su  primera   instrucción,   así   que  como respuesta a esta instrucción el procesador dejó el valor 2 en el registro AX, luego viene los demás procesos cada uno utilizando los registros según sus necesidades como se ve en la gráfica:

hasta  que por alguna razón  le  vuelve a   tocar  el   turno de ejecución al  proceso P1 y ooops!!!  P1 estaba esperando que en AX estuviera el valor 2 para que así su suma sea 2+3, pero en este momento ya el proceso P1 no tendría en los registros los mismos valores que tenia justo antes de suspenderse!!!Por otro lado el sistema operativo también necesita saber en que instrucción estaba la ejecución de P1 para continuar justo donde estaba antes de suspender su ejecución, y algunos otros datos más, entonces como hace para que todo pueda continuar normal?

Como lo dije anteriormente cuando un proceso se suspende básicamente se devuelve la ejecución al sistema operativo, allí el sistema lleva a acabo la planificación de procesos y otras tareas, pero que hace realmente?

El sistema lo primero que hace es guardar el estado del proceso en algún sitio, el estado del proceso es una estructura   en  memoria  que  guarda   los   valores  de  TODOS  los   registros   y  banderas   del  procesador   (las banderas   son   un   registro   utilizado   por   el   procesador   para   indicar   situaciones   como   división   por   cero, overflow, signo negativo etc.) es decir esto incluye el registro IP(Instruction Pointer) que es un registro que contiene un apuntador que indica al procesador en que instrucción de código va la ejecución, y los registros 

Page 27: Codigo Latino 12

Ax, Bx, Cx, etc.

Una vez ese dato queda guardado el sistema verifica cual es el siguiente proceso que debe tener un Quantum de ejecución, digamos el proceso P2, así que el sistema operativo lee el estado del proceso P2 y comienza a dejar   las   cosas  en   su   lugar,  es  decir   lee   los  valores  que  deberían  tener   cada  uno de   los   registros   ,   las banderas,etc.  y establece esos valores en el  procesador,  una vez  todos  los valores están establecidos  los últimos valores  que establece  el  sistema son  los  de   los   registros  de  segmento  y  el   registro   IP,  una  vez realizada esta  labor   inicia   la  ejecución de P2 hasta  que sea interrumpido y se continúe con  la   labor  de planificación una y otra vez.Si desean más información acerca de los registros los invito a consultar este Tutorial de Assembler.Esto es todo por el momento, los más conocedores me perdonaran por todas las cosas que he podido pasar por alto pero recuerden que esto es solo un post introductorio y no pretendo detallar las cosas más allá de los conocimientos generales, de igual forma cualquier duda o corrección que tengan es bienvenida.

Saludos.

Page 28: Codigo Latino 12

CHECMATED es un excelente programador del foro code­makers maneja muy bien Python y es uno de los moderadores más queridos del foro; acá les dejo la entrevista que nos concedió.

1) ¿De dónde eres?Soy de Venezuela, para ser mas especifico, de turen, un pequeño pueblo del estado portuguesa.

2) ¿Hace cuánto que comenzaste a programar?Llevo aproximadamente 2 años con la programación, pero   mi   "aprendizaje"   fue   muy   interrumpido   por distintos motivos.

3)   ¿Cuáles   son   tus   lenguajes   de   programación favoritos?No lo llamaria favoritismo pero prefiero trabajar con python por su facilidad, ademas de que es un lenguaje muy   flexible   con   el   cual   puedes   tener   buenos resultados con cualquier proyecto. Aparte de python, uso Visual Basic, y porsupuesto, C/C++.

4) ¿Cuáles son tus programas favoritos de Diseño?Aunque debo admitir  que nunca se me a dado muy bien   el   diseño,   es   un   pasatiempo   que   tengo.   Por Windows uso Adobe Photo Shop, pero por el lado de Linux no tengo ningun programa predilecto

5) ¿Qué te inspiró a ser programador?Diria que fue por simple curiosidad que me inicie en este   mundo.   Dicha   curiosidad   comenzo   cuando   un primo (ahora ingeniero en informatica) instala VB en mi PC para hacer unas practicas. Luego de varios dias, comenze   a   leerme   el  manual   que  venia   con   este   y pues, por hay comenze jaja

6) ¿Cuéntanos un poco acerca de tu compañía?Sin comentarios jaja

7) ¿Qué opinas de la escena de programadores en Latinoamérica?Creo que es bastante  desarollada y prometedora.  En latinoamérica hay mucho, talento, por así llamarlo

8) ¿Cuáles son tus nuevos proyectos?Ya   que   me   apasiona   la   programacion   de   juegos, 

planeo   dedicarme   a   esta   por   unos   años   mas. Actualmente   estoy   en   la  programacion  de  un   juego llamado "The CM Incident" el cual, se prevee estara listo alrededor de julio ­ septiembre de este año

9) ¿Que te gustaría ver en los próximos años en el mundo de la programación?Pues,   el   progreso   en   el   area   de   programacion   en latinoamérica   en   los   ultimos   años   a   sido   realmente bueno,  dejemos que  todo "fluya" y ya veremos que pasa, es decir, no espero nada en especifico :P

10) ¿Cuál es tu mensaje final para la comunidad?Un saludo a código latino, gracias por la oportunidad

Page 29: Codigo Latino 12

ZTIC_TAC_TOE (Juego en ABAP)Por Blag http://atejada.blogspot.com

El otro día estaba aburrido en la oficina, esperando una orden de transporte y que una tabla me devolviera algunos resultados...Entonces, me puse a pensar acerca de mi nuevo blog... Como ya he escrito tantas cosas, me es un poco dificil crear algo nuevo y extraño ­;) Felizmente me acordé que hace algún tiempo hice un Tic­Tac­Toe (Michi o Gato) en Ruby, así que pensé que hacerlo en ABAP no sería muy díficil...Y no lo fué ­;) Me tomó solamente 20 minutos hacer esto...

El   juego   tiene  una  pobre  y   limitada   Inteligencia  Artificial...Debemos   ingresar  un  número del  1   al  9  y presionar Play! para que la computadora haga su jugada debemos presionar Play! nuevamente...

Ahora, el código fuente...*&­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­**& Report ZTIC_TAC_TOE                   **&­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­*REPORT ZTIC_TAC_TOE NO STANDARD PAGE HEADING.TYPES: BEGIN OF TY_PLAYS,   PLAY TYPE C,   END OF TY_PLAYS.

Page 30: Codigo Latino 12

DATA: T_PLAYS TYPE STANDARD TABLE OF TY_PLAYS.FIELD­SYMBOLS: <FS_PLAYS> LIKE LINE OF T_PLAYS.DATA: RANDOM TYPE REF TO CL_ABAP_RANDOM.DATA: SEED TYPE I,   WIN_FLAG TYPE C,   FLAG_OK TYPE C,   W_LINES TYPE I,   FLAG TYPE C,   PLAYER_ONE TYPE C,   PLAYER_TWO TYPE C,   ONE TYPE C,   TWO TYPE C,   THREE TYPE C,   FOUR TYPE C,   FIVE TYPE C,   SIX TYPE C,   SEVEN TYPE C,   EIGHT TYPE C,   NINE TYPE C.*­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­**    START­OF­SELECTION                 **­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­*START­OF­SELECTION. FLAG = '1'. SET PF­STATUS 'BAR'. PERFORM BOARD USING '' '' ''. PERFORM PLAYER_ONE.*­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­**    FORM PLAYER_ONE                   **­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­*FORM PLAYER_ONE. IF WIN_FLAG EQ SPACE.  WRITE:/ 'Player one: '.  FORMAT INPUT ON.  WRITE: PLAYER_ONE.  FORMAT INPUT OFF. ENDIF.ENDFORM.          "player_one*­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­**    FORM PLAYER_TWO                   **­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­*FORM PLAYER_TWO. IF WIN_FLAG EQ SPACE.  WRITE:/ 'Player two: '.  FORMAT INPUT ON.  WRITE: PLAYER_TWO.  FORMAT INPUT OFF. ENDIF.ENDFORM.          "player_two*­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­**    FORM BOARD                     **­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­*FORM BOARD USING P_PLAYER P_NUMBER FLAG_OK.

Page 31: Codigo Latino 12

 IF P_PLAYER NE SPACE AND P_NUMBER NE SPACE.  READ TABLE T_PLAYS WITH KEY PLAY = P_NUMBER  ASSIGNING <FS_PLAYS>.  IF NOT <FS_PLAYS> IS ASSIGNED OR SY­SUBRC NE 0.   APPEND INITIAL LINE TO T_PLAYS   ASSIGNING <FS_PLAYS>.   <FS_PLAYS>­PLAY = P_NUMBER.   UNASSIGN <FS_PLAYS>.   FLAG_OK = 'X'.  ELSE.   WRITE:/ 'Please select another number!'.   CLEAR: P_NUMBER,FLAG_OK.  ENDIF. ENDIF. CASE P_NUMBER.  WHEN '1'.   IF P_PLAYER EQ '1'.    ONE = 'X'.   ELSE.    ONE = 'O'.   ENDIF.  WHEN '2'.   IF P_PLAYER EQ '1'.    TWO = 'X'.   ELSE.    TWO = 'O'.   ENDIF.  WHEN '3'.   IF P_PLAYER EQ '1'.    THREE = 'X'.   ELSE.    THREE = 'O'.   ENDIF.  WHEN '4'.   IF P_PLAYER EQ '1'.    FOUR = 'X'.   ELSE.    FOUR = 'O'.   ENDIF.  WHEN '5'.   IF P_PLAYER EQ '1'.    FIVE = 'X'.   ELSE.    FIVE = 'O'.   ENDIF.  WHEN '6'.   IF P_PLAYER EQ '1'.    SIX = 'X'.   ELSE.    SIX = 'O'.   ENDIF.  WHEN '7'.   IF P_PLAYER EQ '1'.

Page 32: Codigo Latino 12

    SEVEN = 'X'.   ELSE.    SEVEN = 'O'.   ENDIF.  WHEN '8'.   IF P_PLAYER EQ '1'.    EIGHT = 'X'.   ELSE.    EIGHT = 'O'.   ENDIF.  WHEN '9'.   IF P_PLAYER EQ '1'.    NINE = 'X'.   ELSE.    NINE = 'O'.   ENDIF. ENDCASE. PERFORM CHECK_WHO_WINS. DESCRIBE TABLE T_PLAYS LINES W_LINES. IF WIN_FLAG EQ SPACE AND W_LINES EQ 9.  WIN_FLAG = 'X'.  WRITE: 'It''s a tie!'. ENDIF. WRITE:/ ONE,'|',TWO,'|',THREE. WRITE:/ '­­+­­­+­­­'. WRITE:/ FOUR,'|',FIVE,'|',SIX. WRITE:/ '­­+­­­+­­­'. WRITE:/ SEVEN,'|',EIGHT,'|',NINE. IF P_PLAYER EQ '2'.  PERFORM PLAYER_ONE. ELSEIF P_PLAYER EQ '1'.  PERFORM PLAYER_TWO. ENDIF.ENDFORM.          "board*­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­**    FORM check_who_wins                 **­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­*FORM CHECK_WHO_WINS. IF ONE EQ TWO AND TWO EQ THREE.  IF THREE EQ 'X'.   WRITE:/ 'Player 1 Wins!'.   WIN_FLAG = 'X'.   SKIP 2.  ELSEIF THREE EQ 'O'.   WRITE:/ 'Player 2 Wins!'.   WIN_FLAG = 'X'.   SKIP 2.  ENDIF. ENDIF. IF FOUR EQ FIVE AND FIVE EQ SIX.  IF SIX EQ 'X'.   WRITE:/ 'Player 1 Wins!'.   WIN_FLAG = 'X'.

Page 33: Codigo Latino 12

   SKIP 2.  ELSEIF SIX EQ 'O'.   WRITE:/ 'Player 2 Wins!'.   WIN_FLAG = 'X'.   SKIP 2.  ENDIF. ENDIF. IF SEVEN EQ EIGHT AND EIGHT EQ NINE.  IF NINE EQ 'X'.   WRITE:/ 'Player 1 Wins!'.   WIN_FLAG = 'X'.   SKIP 2.  ELSEIF NINE EQ 'O'.   WRITE:/ 'Player 2 Wins!'.   WIN_FLAG = 'X'.   SKIP 2.  ENDIF. ENDIF. IF ONE EQ FOUR AND FOUR EQ SEVEN.  IF SEVEN EQ 'X'.   WRITE:/ 'Player 1 Wins!'.   WIN_FLAG = 'X'.   SKIP 2.  ELSEIF SEVEN EQ 'O'.   WRITE:/ 'Player 2 Wins!'.   WIN_FLAG = 'X'.   SKIP 2.  ENDIF. ENDIF. IF TWO EQ FIVE AND FIVE EQ EIGHT.  IF EIGHT EQ 'X'.   WRITE:/ 'Player 1 Wins!'.   WIN_FLAG = 'X'.   SKIP 2.  ELSEIF EIGHT EQ 'O'.   WRITE:/ 'Player 2 Wins!'.   WIN_FLAG = 'X'.   SKIP 2.  ENDIF. ENDIF. IF THREE EQ SIX AND SIX EQ NINE.  IF NINE EQ 'X'.   WRITE:/ 'Player 1 Wins!'.   WIN_FLAG = 'X'.   SKIP 2.  ELSEIF NINE EQ 'O'.   WRITE:/ 'Player 2 Wins!'.   WIN_FLAG = 'X'.   SKIP 2.  ENDIF. ENDIF. IF ONE EQ FIVE AND FIVE EQ NINE.  IF NINE EQ 'X'.

Page 34: Codigo Latino 12

   WRITE:/ 'Player 1 Wins!'.   WIN_FLAG = 'X'.   SKIP 2.  ELSEIF NINE EQ 'O'.   WRITE:/ 'Player 2 Wins!'.   WIN_FLAG = 'X'.   SKIP 2.  ENDIF. ENDIF. IF SEVEN EQ FIVE AND FIVE EQ THREE.  IF THREE EQ 'X'.   WRITE:/ 'Player 1 Wins!'.   WIN_FLAG = 'X'.   SKIP 2.  ELSEIF THREE EQ 'O'.   WRITE:/ 'Player 2 Wins!'.   WIN_FLAG = 'X'.   SKIP 2.  ENDIF. ENDIF. IF FOUR EQ FIVE AND FIVE EQ SIX.  IF SIX EQ 'X'.   WRITE:/ 'Player 1 Wins!'.   WIN_FLAG = 'X'.   SKIP 2.  ELSEIF SIX EQ 'O'.   WRITE:/ 'Player 2 Wins!'.   WIN_FLAG = 'X'.   SKIP 2.  ENDIF. ENDIF.ENDFORM.          "check_who_wins*­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­**    AT USER­COMMAND                   **­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­*AT USER­COMMAND. IF SY­UCOMM EQ 'BACK'.  SET SCREEN 0.  LEAVE PROGRAM. ELSE.  IF WIN_FLAG EQ SPACE.   IF FLAG = '1'.    PLAYER_ONE = SY­LISEL+12(1).    PERFORM BOARD USING FLAG PLAYER_ONE FLAG_OK.    IF FLAG_OK = 'X'.     FLAG = '2'.    ENDIF.   ELSE.    SEED = CL_ABAP_RANDOM=>SEED( ).    RANDOM = CL_ABAP_RANDOM=>CREATE( SEED ).    PLAYER_TWO = RANDOM­>INTINRANGE( LOW = 1 HIGH = 9 ).    PERFORM BOARD USING FLAG PLAYER_TWO FLAG_OK.    IF FLAG_OK = 'X'.

Page 35: Codigo Latino 12

     FLAG = '1'.    ENDIF.   ENDIF.  ENDIF. ENDIF.

Espero que les guste y si pueden, mejorenlo ­:)

Saludos,

Blag.

Page 36: Codigo Latino 12

Windows te ordeno que trabajes por Mi!!!Por Cronodragon

Este artículo trata sobre como convertir a Windows en un robot que hace lo que se le pida. Puede usarse para el mal o para bien, queda a conciencia del programador, pero mejor que sea algo útil y divertido.

Les presento AutoIt v3, una sencilla pero poderosa herramienta de automatización que es gratuita. Con esta podemos   lograr   que  Windows  haga   cualquier   cosa   que   le   pidamos,   aparte   de   levantarse   y   preparar   el desayuno, aunque talvez un día... un día de estos. Esta es realmente el arma perfecta para acabar con esas tareas largas y rutinarias.

Para comenzar programaremos un Hola Mundo. así que creamos un nuevo archivo de texto con extensión .au3 . Ahora abrimos el archivo con el editor que trae AutoIt, o con su editor de texto favorito, e insertamos las siguientes líneas:

Run("notepad.exe")Sleep(1000)Send("Hola Mundo!{ENTER}")

Guardamos el cambio, y ejecutamos el archivo... fuera manos!! El script abrira automaticamente el notepad y escribira por si solo. Es importante no intervenir mientras se ejecuta el script, o podria terminar escribiendo en otra aplicación. Hagase la salvedad que podemos intervenir para pausar el script presionando en el icono del tray bar, esto es útil por si el script se desboca. AutoIt es un amigo fiel y bien entrenado, aun así se debe tener cuidado para manipularlo.

La mejor forma de aprender a usar AutoIt es consultando la ayuda que trae. Entre las funciones mas útiles estan   las  de  manipulación del   teclado y  el   ratón,  que convierten  a  Windows en  un  automata  a  nuestro servicio.

La única desventaja que he encontrado es que es díficil hacer portables los scripts de un sistema a otro. Si abren el ejemplo de notepad que viene incluido con AutoIt, veran las siguientes lineas:

; Wait for the Notepad become active ­ it is titled "Untitled ­ Notepad" on English systemsWinWaitActive("Untitled ­ Notepad")

En vez de esperar una cantidad de tiempo como en nuestro Hola Mundo, usando Sleep(1000), este ejemplo espera que se abra la ventana de notepad, pero solo funciona para Windows en ingles. Como ven es un metodo mas seguro, pero pierde portabilidad, así  que se debe tomar en cuenta la configuración del sistema, su velocidad,  etc. Además posiblemente se deben preconfigurar y abrir  los programas que el script va a utilzar, para que encuentre las cosas tal y como las necesita.

Debido a este problema de portabilidad no puedo simplemente pasarles un script que resuelva un problema de la vida real, sino que deben adaptarlo a sus necesidades y a su sistema. Por eso voy a explicarles un problema que tengo que resolver, para que vean un flujo de trabajo para crear los scripts. 

Page 37: Codigo Latino 12

Estoy creando un diccionario ingles­espanol de 1500 palabras en Excel, y quiero insertarle a cada palabra el sonido de su pronunciación. Me va a llevar demasiado tiempo ponerle todos los sonidos, así que voy a crear un script para acelerar el trabajo. Por supuesto Excel tiene sus propios macros para automatizar estas tareas, pero veran lo fácil que se programa con AutoIt, y ademas funciona en cualquier software, de hecho funciona sobre todo el sistema operativo.

Lo primero que hago es probar a mano con que combinaciones del teclado puedo activar las funciones de Excel para insertar un objeto de archivo .wav . Me doy cuenta que presionando [alt]+[i] > [o] > [w] > [enter] se abre la grabadora de sonidos, y luego con [alt]+[e] > [i] se abre el dialogo para insertar el archivo. Escribo el nombre del archivo, cierro con [alt]+[f] > [x]. Luego paso a la siguiente celda presionando [esc] > [enter]. Con esto puedo crear la primera version del script como sigue:

Sleep(5000)Send("!iow{ENTER}")Sleep("500")Send("!ei")Sleep("500")Send("able0001.wav")    ; archivo de pruebaSend("{ENTER}")Sleep("500")Send("!fx")Sleep("500")Send("{ESC}{ENTER}")

El primer Sleep() me da 5 segundos de tiempo para darle foco a la ventana de Excel y colocarme en la primera celda. Ahora solo necesito hacer ese mismo paso para cada uno de los 1500 archivos de sonido que tengo almacenados. Para esto voy a usar la función FileFindFirstFile() y sus amigas. En la ayuda viene un ejemplo que convenientemente voy a copiar para no reinventar el agua tibia, así mi código quedaría de la siguiente manera:

Sleep(5000)$search = FileFindFirstFile("C:\PROYECTOS\Dictionary\*.*") 

If $search = ­1 Then  MsgBox(0, "Error", "No files/directories matched the search pattern")  ExitEndIfWhile 1  $file = FileFindNextFile($search)   If @error Then ExitLoop

        Sleep(1000)        Send("!iow{ENTER}")        Sleep("500")        Send("!ei")        Sleep("500")       MsgBox(4096, "File:", $file)       ; para depuracion        Send($file)        Send("{ENTER}")        Sleep("500")

Page 38: Codigo Latino 12

        Send("!fx")        Sleep("500")        Send("{ESC}{ENTER}")WEnd

FileClose($search)

Y con esto me ahorre varios días de aburrido trabajo! Espero que este tutorial sea de su entero provecho. Hasta pronto!

Page 39: Codigo Latino 12

Incluir documentos HTML o datos ComplejosPor 100% Telch

Vamos a aprender a incluir documentos HTML o datos complejos, con el Html­Template a tú archivo.tmpl

Introducción.

Una vez me vi en el gran problema de incluir un documento HTML completo dentro de una plantilla o un template; y quiero compartir con ustedes una forma con la cual solucioné este problema, que para muchos quizás no lo sea.

En un lenguaje como PHP me fue muy fácil hacer algo como esto:

If ($do == "articulos") {        Include ("articulos.html");}elseif ($do == "noticias") {        Include ("noticias.html");Elseif.. N... etc...}

Bueno pero me vi en el gran problema de necesitar incluir no solo documentos HTML, si no también un flash, un jpg, un despliegue de un DBI etc…, También se presento en inconveniente de que la pobre plantilla se me iba llenando de código y mas código a medida que ingresaba secciones.Si necesita crear a un menú nuevo, tenia que hacer toda la conexión a la base de datos y el desplegué de html dentro de la misma plantilla, y no que pereza la verdad eso parece mas una sopa y no un template, se también que se podría solucionar este problema en otros lenguajes.

Bueno, aun así la idea general era solucionar este problema usando Perl y sé que en PHP o ASP no lo podría solucionar como en Perl.

Desarrollo:Imagino que ya conocerás en HTML­Template,  si no estudiate uno des los tutoriales que andan por ahí, aunque no es tan complicada la cosa, con este ejemplo puedes ver como funciona

Resulta que tenemos esto que me devuelve un dato a una plantilla, Plantilla “template1.tmpl”<html>   <head>     <title>Template</title>   </head> <body>   Today is <tmpl_var name=dia>   </body> </html>

Page 40: Codigo Latino 12

Mi archivo de Perl:#!c:/perl/bin/perluse CGI qw(:all); use HTML::Template; use POSIX; print header; my $template = HTML::Template­>new(filename => 'template1.tmpl'); $template­>param(dia => strftime('%A', localtime()) ); print $template­>output();

Acá sencillamente tenemos una plantilla que me muestra la fecha en pantalla, pero lo que queremos devolver no solo un dato en variable si no un documento HTML completo, una imagen, un DHTML, un componente Active X, manteniendo el código Perl COMPLETAMENTE separado de la plantilla o template.Bueno veamos un ejemplo de un template que tiene sus vínculos que no solo desplegaran datos de variable, si no un documento HTML completo, un jpg, una consulta de una BD etc... Esta plantilla es un poco mas compleja, tiene una barra de navegación superior, un menú  izquierdo y su cuerpo; también tiene tres variables de template el <tmpl_loop name="menu"> ­ <tmpl_var name=vinculo> para el menú izquierdo y el <tmpl_var name=contenido> donde se desplegara el contenido de tus secciones.

Plantilla “template.tmpl”<html>   <head>     <title>Template</title>   </head> <body>   <table width="41%" border="0" cellspacing="0" cellpadding="0">   <tr>       <td></td>      <td>   <a    href="config.pl?go=home">Home</a></td>      <td>   <a    href="config.pl?go=contactos">Contactos</a></td>   </tr>   <tr>       <td>        <table>           <tmpl_loop name="menu">            <tr>              <td><tmpl_var name="vinculo"></td>            </tr>            </tmpl_loop>       </table>     </td>     <td colspan="2">       <tmpl_var name=contenido>     </td>   </tr>  </table></body> </html>

Page 41: Codigo Latino 12

Mi archivo de Perl “config.pl”:#!c:/perl/bin/perl   use CGI qw(:all);   use HTML::Template;my(%dato); #Iniciamos el hash#Leemos el query enviadomy $buffer = $ENV{'QUERY_STRING'};my @pairs = split(/&/, $buffer);foreach my $pair (@pairs) {    my ($name, $value) = split(/=/, $pair);    $name =~ tr/+/ /;    $name =~ s/%([a­fA­F0­9][a­fA­F0­9])/pack("C", hex($1))/eg;    $value =~ tr/+/ /;    $value =~ s/%([a­fA­F0­9][a­fA­F0­9])/pack("C", hex($1))/eg;    $dato{$name} = $value;};# función para desplegar un f ichero htmlsub desplegar{  open(ARCHIVO, $file) || die "No se pudo abrir archivo";     while(!eof(ARCHIVO)){        $clave=<ARCHIVO>;        # se guarda en include el documento html completo        $include = $include.$clave;        }  close(ARCHIVO);};#creamos un menu de las secciones de nuestra pagina web ej. my @menu = (   {vinculo => 'Perl'},   {vinculo => 'PHP5'},   {vinculo => 'ASP'}, );

if ($dato{'go'} eq "home") {  $include = "<img src='imagen.jpg'>"; # El contenido de la pagina principal es una imagen}elsif ($dato{'go'} eq "contactos") {   $file = "contactos.html";   #llamamos el procedimiento que desplega el fichero HTML en el include   &desplegar}elsif ($dato{'go'} eq "") { $include = "<img src='imagen.jpg'>";}else{   # en caso de lo contrario abre un documento con el nombre guardado en $dato{'go'} .html   $file = $dato{'go'}."html";   &desplegar};#indicamos como se llama la plantilla a utilizar$plantilla = "template.tmpl";# Salida de la plantillamy $template = HTML::Template­>new(filename => $plantilla); $template­>param(contenido => $include ); $template­>param(menu => \@menu  ); print "Content­Type: text/html\n\n", $template­>output;

Page 42: Codigo Latino 12

EXPLICACION Estas primeras líneas :

#!c:/perl/bin/perl   use CGI qw(:all);   use HTML::Template;

Es donde definimos el módulo CGI y el poderoso módulo HTML­Template.Con las siguientes líneas decodificamos el Query envíado

my(%dato); #Iniciamos el hash#Leemos el query enviadomy $buffer = $ENV{'QUERY_STRING'};my @pairs = split(/&/, $buffer);foreach my $pair (@pairs) {    my ($name, $value) = split(/=/, $pair);    $name =~ tr/+/ /;    $name =~ s/%([a­fA­F0­9][a­fA­F0­9])/pack("C", hex($1))/eg;    $value =~ tr/+/ /;    $value =~ s/%([a­fA­F0­9][a­fA­F0­9])/pack("C", hex($1))/eg;    $dato{$name} = $value;};

Este siguiente bloque nos hace es desplegar todo el contenido de un fichero HTML dentro del contenedor $include   el   cual   es   el   que   se   usa   para   desplegar   dentro   de   la   variable   $contenido   en   la   plantilla “template.tmpl”; como es una función, solo hará su trabajo cuando la llamemos

# función para desplegar un f ichero htmlsub desplegar{  open(ARCHIVO, $file) || die "No se pudo abrir archivo";     while(!eof(ARCHIVO)){        $clave=<ARCHIVO>;        # se guarda en include el documento html completo        $include = $include.$clave;        }  close(ARCHIVO);};

Nuestras siguientes líneas son sencillas:

#creamos un menu de las secciones de nuestra pagina web ej. my @menu = (   {vinculo => 'Perl'},   {vinculo => 'PHP5'},   {vinculo => 'ASP'}, );

Acá lo que hacemos es crear un array de hash para crear el menú, como puedes ver esta es la forma donde decides  que  secciones   incluir,   puedes  definir  de  una  vez  desde  aquí   los  vínculos   es  decir   remplazando 

Page 43: Codigo Latino 12

{vinculo => ‘perl’} por {vinculo => ‘ <a ref.=’config.pl?go=perl’>Perl</a> ’} con esto ya tienes para que el menú  del template en vez de dejarte solo texto, te cree ya un vínculo activo para ser manipulado por el config.pl;   también   si   deseas   puedes   remplazar   las   etiquetas   de   tu   template.tmpl   para   que   te   ponga directamente las etiquetas de hipervínculos “<a ref.> y</a>” y así te ahorras de ensuciar un poco tu código perl pero si la plantilla ej:

Código de Plantilla actual:<tmpl_loop name="menu"> <tr>  <td><tmpl_var name="vinculo"></td>  </tr> </tmpl_loop>

Código de Plantilla propuesta<tmpl_loop name="menu"> <tr>  <td>   <a    href="config.pl?go=<tmpl_var name="vinculo">" <tmpl_var name="vinculo"> </a></td>  </tr> </tmpl_loop>

Con esta propuesta listo solamente si tus archivos son extensión html te será útil y creo que es así, ya te evitastes ensuciar tu código perl, el automáticamente te hace los vínculos tomando como referencia el valor de la variable en el hash y suponiendo que el nombre del archivo html a incluir es el mismo valor del valor de la llave actual del hash y su extensión es html.

Ahora ustedes quieren saber como puedo incluir otra cosa que no sea un simple dato de una variable y un documento html completo; bueno acá les indicare como pueden hacerlo estoy seguro que con esto ya se hacen idea de cómo pueden hacerlo 

if ($dato{'go'} eq "home") {  $include = "<img src='imagen.jpg'>";}elsif ($dato{'go'} eq "contactos") {   $file = "contactos.html";   #llamamos el procedimiento que desplega el fichero HTML en el include   &desplegar}elsif ($dato{'go'} eq "") { $include = "<img src='imagen.jpg'>";}else{   # en caso de lo contrario abre un documento con el nombre guardado en $dato{'go'} .html   $file = $dato{'go'}."html";   &desplegar};

Si el valor de la llave dato{‘go’} es equivalente a home entonces la variable $include toma el valor de una etiqueta html que me dice que lo que quiero  es una imagen $include = "<img src='imagen.jpg'>"

Explicando también como es que se hace para desplegar quizas un vínculo que es un documento HTML que 

Page 44: Codigo Latino 12

no este en nuetro menú, usamos el siguiente elsif

}elsif ($dato{'go'} eq "contactos") {   $file = "contactos.html";   #llamamos el procedimiento que desplega el fichero HTML en el include   &desplegar}

Esto  nos  despliega  el   fichero   llamado contactos.html;  es  acá  donde  llamamos   la   función  desplegar  que sencillamente el archivo a desplegar es el que contenga la variable $file, en este caso es contactos, pero en el caso del menú es otro que ya lo explicaremos

elsif ($dato{'go'} eq "") { $include = "<img src='imagen.jpg'>";}

Sencillamente si no toma ningún valor en este caso queremos que nos regrese al home, o en otras palabras que nos incluya la misma imagen para cuando la llave es equivalente a “home”

Si no se cumple ninguno de los casos , entonces ahora es donde juega lo que hicimos en el menú.

else{   #en caso de lo contrario abre un documento con el nombre guardado en $dato{'go'} .html   $file = $dato{'go'}."html";   &desplegar};

El $file que se utilizara en el procedimiento o función como lo llamo yo será el mismo valor de la llave actual mas la extensión “html” así nos evitamos tener que crear como me toco hacer en php menús en una base de datos y después hacer esa conexión a BD y etc… me imagino que en este nivel ya sabrán a lo que me refiero.

#indicamos como se llama la plantilla a utilizar$plantilla = "template.tmpl";# Salida de la plantillamy $template = HTML::Template­>new(filename => $plantilla); $template­>param(contenido => $include ); $template­>param(menu => \@menu  ); print "Content­Type: text/html\n\n", $template­>output;

y ya este ultimo bloque (y no me refiero a bloques en términos de programación si no a bloques en términos de textos) tenemos definido cual es la plantilla que queremos utilizar  $plantilla = "template.tmpl" y el resto ya lo saben lo que contendrá la variable de template sera lo que tenga contenido “$include” y bueno ahí vemos como desplegamos el menú también  $template­>param(menu => \@menu    );

Si ustedes me preguntan si lo que quieren es una conexión a una base de datos un gif un flash,, bueno lo mismo colocan las etiquetas necesarias para llamar el flash el script, active x, o lo que deseen,  claro que en el caso de una conexión a base de datos lo mejor es crear un procedimiento y guardar todo el despliegue HTML  dentro de una variable contenedor.

Page 45: Codigo Latino 12

Daniel Bermudez es un Colombiano igual que yo y administrador del espectacular foro  aprender­python, promueve la enseñanza de este lenguaje de programación tan emocionante y pues hace poco promovió un curso en el foro para aprender Python, del cual soy asiduo lector, acá dejo esta entrevista que nos ha regalado.

1) ¿De dónde eres?Colombia, Bogota

2) ¿Hace cuánto que comenzaste a programar?Hace 2 años aproximadamente.

3)   ¿Cuáles   son   tus   lenguajes   de   programación favoritos?Primeroque nada Python, PHP, y pues los demas no losconozco mucho.

4) ¿Cuáles son tus programas favoritos de Diseño?Flash   es   mi   favorito,   Firework   meparece   excelente para   la   edicion   de   imagenes,   claroque   sin menospreciar   los   otros   programascomo   Photoshop, Corel Draw e Illustrater.

5) ¿Qué te inspiró a ser programador?Bueno  la  verdad Python ver   su  sintaxis   la   facilidad deaprendizaje  el  ver el  potencialque  tenia,   todos   los modulos que tiene, ademas libre, ysepresta desarrollar cualquier aplicacion.

6) ¿Cuéntanos un poco acerca de tu compañía?Actualmente no tengo compañia, pero a futuros tengo planeado crear una dedicada al software libre.

7) ¿Qué opinas de la escena de programadores en Latinoamérica?Bueno creo que no somos los mejores pero tampoco los mas malos, creo que aun falta mucho para llegar a ser los mejores.

8) ¿Cuáles son tus nuevos proyectos?Continuarcon el proyecto de Aprender Python, trabajar para   difundir  Python  y  que   todo  mundose   anime   a aprenderlo   y   vean   lo   facil   y   podero   que   puedeser, tambien crear un futuro proyecto ya con bases de datos que es otra de mispasiones.

9) ¿Que te gustaría ver en los próximos años en el mundo de la programación?Un lenguaje de programacion totalmente en Español.

10) ¿Cuál es tu mensaje final para la comunidad?Como lo dijo alguien: Ignorante no es el que no sabe leer, sino el que sabiendo leer no lee.

Page 46: Codigo Latino 12

Software para captura de inventariosPor RadicalEd http://radicalpython.blogspot.com

Como no todo es Python en esta vida :'( , hace rato pusé en el blog que iba a compartir un software para captura de inventarios, primero lo probé en el trabajo y ya puedo soltar esta pequeña casí belleza, no tiene módulos grandes, tampoco POO (no manejo POO en PHP) pero es funcional y nos ha hecho quedar bien; colocaré cada módulo y pues como están comentados no necesitan mucha explicación.

Lo voy a dejar  con los  datos  de ejemplo para que se pueda obtener   información de este  y  practicar,  el software se maneja a la perfección con códigos de barras, tanto en los productos como en las ubicaciones de la bodega, ya verán ustedes como lo modificaran a sus gustos.

Esta obra está bajo Licencia Atribución­No Comercial 2.5 Colombia License de Creative Commons.

Empecemos por el script SQL que se necesita para que funcióne el programa:

SET SQL_MODE="NO_AUTO_VALUE_ON_ZERO";

CREATE TABLE IF NOT EXISTS `tbinventario_bodega` ( `id` int(2) NOT NULL AUTO_INCREMENT, `ubicacion` varchar(25) NOT NULL, `nombre` varchar(50) NOT NULL, `código` varchar(15) NOT NULL, `conteo` varchar(1) NOT NULL DEFAULT '0', `cerrado` varchar(1) NOT NULL DEFAULT '0', `asig_planilla` varchar(1) NOT NULL DEFAULT '0', `num_planilla` varchar(5) NOT NULL DEFAULT '0', PRIMARY KEY (`id`), KEY `código` (`código`));

CREATE TABLE IF NOT EXISTS `tbinventario_conteos` ( `id` int(2) NOT NULL AUTO_INCREMENT, `item_código` varchar(10) NOT NULL, `posicion` varchar(8) NOT NULL, `primer` varchar(5) NOT NULL, `segundo` varchar(5) NOT NULL, `tercer` varchar(5) NOT NULL, `conto_primero` varchar(3) NOT NULL, `conto_segundo` varchar(3) NOT NULL, `conto_tercero` varchar(3) NOT NULL, PRIMARY KEY (`id`));

Page 47: Codigo Latino 12

CREATE TABLE IF NOT EXISTS `tbinventario_errores` ( `id` int(2) NOT NULL AUTO_INCREMENT, `id_user` varchar(2) NOT NULL, `posicion` varchar(8) NOT NULL, `item` varchar(10) NOT NULL, `conteo` varchar(1) NOT NULL, PRIMARY KEY (`id`));

CREATE TABLE IF NOT EXISTS `tbinventario_items` ( `id` int(5) NOT NULL AUTO_INCREMENT, `código` varchar(10) NOT NULL, `nombre` varchar(45) NOT NULL, `conteo` varchar(1) NOT NULL DEFAULT '0', `unidad` varchar(5) NOT NULL, `precio` varchar(11) NOT NULL, `cantidad` varchar(5) DEFAULT NULL, `cod_barra01` varchar(15) DEFAULT NULL, `cod_barra02` varchar(15) DEFAULT NULL, `cod_barra03` varchar(15) DEFAULT NULL, `cod_barra04` varchar(15) DEFAULT NULL, `cod_barra05` varchar(15) DEFAULT NULL, `cod_barra06` varchar(15) DEFAULT NULL, `cod_barra07` varchar(15) DEFAULT NULL, `cod_barra08` varchar(15) DEFAULT NULL, `cod_barra09` varchar(15) DEFAULT NULL, PRIMARY KEY (`id`));

CREATE TABLE IF NOT EXISTS `tbinventario_planilla` ( `id` int(2) NOT NULL AUTO_INCREMENT, `contado` varchar(20) DEFAULT NULL, PRIMARY KEY (`id`));

CREATE TABLE IF NOT EXISTS `tbinventario_subconteo` ( `id` int(2) NOT NULL AUTO_INCREMENT, `cod_item` varchar(10) NOT NULL, `cod_bodega` varchar(10) NOT NULL, `cantidad` varchar(4) NOT NULL, `indexado` varchar(1) NOT NULL, `indexado_por` varchar(3) NOT NULL, PRIMARY KEY (`id`));

Page 48: Codigo Latino 12

CREATE TABLE IF NOT EXISTS `tbinventario_ubicacion` ( `id` int(4) NOT NULL AUTO_INCREMENT, `rak` varchar(1) NOT NULL, `cara` varchar(1) NOT NULL, `piso` varchar(1) NOT NULL, `ubicacion` varchar(1) NOT NULL, `item` varchar(10) NOT NULL, `conteo1` varchar(4) NOT NULL, `conteo2` varchar(4) DEFAULT NULL, `conteo3` varchar(4) DEFAULT NULL, PRIMARY KEY (`id`));

CREATE TABLE IF NOT EXISTS `tbinventario_users` ( `id` int(11) NOT NULL AUTO_INCREMENT, `login` varchar(10) NOT NULL, `password` varchar(35) NOT NULL, `tipo` varchar(2) NOT NULL, `nombre` varchar(45) NOT NULL, `companero` varchar(45) NOT NULL, PRIMARY KEY (`id`));

Ahora trabajemos con los scripts; no voy a explicar ni el de conexión ni el de hacer el formulario de login ni nada de eso :P 

index2.php<?php    include 'configuration.php';  $id = $_GET['id'];  $tipo = $_GET['tipo'];?><!DOCTYPE HTML PUBLIC '­//W3C//DTD HTML 4.01 Transitional//EN'><html><head><title>Pantalla Inicial</title><meta http­equiv="Content­Type" content="text/html; charset=iso­8859­1"><!­­ PARA REFRESCAR LA P&#193;GINA CON UN INTERVALO DE 60 SEGUNDOS !­­><meta http­equiv="refresh" content="10"><LINK REL="StyleSheet" HREF="style.css" TYPE="text/css"></head><body><?php  //CON ESTA SE ACTIVARAN LOS CONTEOS  $query_conteos = "SELECT * FROM tbinventario_planilla";  $result_conteos = mysql_query($query_conteos) or die(mysql_error());

  if ($row_conteos=mysql_fetch_array($result_conteos))  {   $cual_conteo = $row_conteos[1];  }

Page 49: Codigo Latino 12

?><div align="center"><table border=1 cellpadding=1 cellspacing=1><?php  //PARA MOSTRAR LOS ENLACES A LOS CONTEOS  if ($cual_conteo==1 || $tipo==69)  {?><tr> <td>  <a href="javascript: window.open('conteo.php?conteo=1&id=<? echo $id; ?>','','resizable=yes,scrollbars=yes,width=400,height=400,menubar=no,status=yes,top=1,left=1').focus();">   Primer Conteo  </a>  </td> <td align='center'>­­></td> <td>  <a href="javascript: window.open('conteo.php?conteo=4&id=<? echo $id; ?>','','resizable=yes,scrollbars=yes,width=400,height=400,menubar=no,status=yes,top=1,left=1').focus();">   C&oacute;digo de Barras  </a> </td></tr><?php  }  //PARA MOSTRAR LOS ENLACES A LOS CONTEOS  if ($cual_conteo==2 || $tipo==69)  {?><tr> <td>  <a href="javascript: window.open('conteo.php?conteo=2&id=<? echo $id; ?>','','resizable=yes,scrollbars=yes,width=400,height=400,menubar=no,status=yes,top=1,left=1').focus();">   Segundo Conteo  </a> </td> <td align='center'>­­></td> <td>  <a href="javascript: window.open('conteo.php?conteo=5&id=<? echo $id; ?>','','resizable=yes,scrollbars=yes,width=400,height=400,menubar=no,status=yes,top=1,left=1').focus();">   C&oacute;digo de Barras  </a> </td></tr><?php  }  //PARA MOSTRAR LOS ENLACES A LOS CONTEOS  if ($cual_conteo==3 || $tipo==69)  {?><tr> <td>  <a href="javascript: window.open('conteo.php?conteo=3&id=<? echo $id; ?

Page 50: Codigo Latino 12

>','','resizable=yes,scrollbars=yes,width=400,height=400,menubar=no,status=yes,top=1,left=1').focus();">   Tercer Conteo  </a> </td> <td align='center'>­­></td> <td>  <a href="javascript: window.open('conteo.php?conteo=6&id=<? echo $id; ?>','','resizable=yes,scrollbars=yes,width=400,height=400,menubar=no,status=yes,top=1,left=1').focus();">   C&oacute;digo de Barras  </a> </td></tr><?php  }  if ($tipo==3 || $tipo==69)  {?><tr> <td>  <a href="javascript: window.open('consultar.php?conteo=<? echo $cual_conteo; ?>&id=<? echo $id; ?>','','resizable=yes,scrollbars=yes,width=400,height=400,menubar=no,status=yes,top=1,left=1').focus();">   Modificar Datos  </a> </td><?php  }?> <td>  <a href="./ver_items.php?show=0&forma=1&tipo=<? echo $tipo; ?>" target="_blank">   Conteos  </a> </td> <td><?php  //PARA MOSTRAR LOS ENLACES A LOS CONTEOS  if ($tipo==69)  {?> <a href="./items.php?show=0&forma=1" target="_blank">  Items </a><? } ?> </td></tr></table><?php  //PARA MOSTRAR LOS ENLACES A LOS CONTEOS  if ($tipo==69)  {?><br><form name='cuentaconteos' method="post" action="<? $_SERVER['PHP_SELF']; ?>"> <input type='hidden' name='contadito' value='<?php echo $cual_conteo; ?>' READONLY> <input type='submit' name='elconteo' value='<?php $cual_conteo += 1; if ($cual_conteo<=3) { echo 'Activar conteo '.

Page 51: Codigo Latino 12

$cual_conteo; }else{ echo 'Conteos terminados'; }?>'></form><?php  if ($_POST['elconteo'])  {   $contadito = $_POST['contadito'];   $contadito += 1;   $query_upd = "UPDATE tbinventario_planilla SET contado='".$contadito."'";   $result_upd = mysql_query($query_upd) or die(mysql_error());  }?><?php  //SABER CUANTOS HAN SIDO CONTADOS  $query_porcen = "SELECT * FROM tbinventario_bodega WHERE ubicacion LIKE 'Bodega 12 Punto Sur'";  $result_porcen = mysql_query($query_porcen) or die(mysql_error);

  $numrows = mysql_num_rows($result_porcen);

  while($row_porcen=mysql_fetch_array($result_porcen))  {    $sumatoria = $row_porcen[4];    if ($sumatoria==1)    {      $vale += 1;    }   }

  $por_conteos = round($vale/$numrows*100,2);?><table border=1 cellspacing=1 cellpadding=1> <tr>  <td class="letratd" align="center" colpan="4"><b>EL INVENTARIO LLEVA UN <? echo $por_conteos; ?>% DE CONTEO</b></td> </tr></table><table border=1 cellspacing=1 cellpadding=1> <tr>  <td class="letratd" align="center" colspan=4"><b>ESTOS GRUPOS HICIERON RECONTEO SOBRE POSICIONES YA CONTADAS</b></td> </tr> <tr>  <td class="letratd" align="center"><b>GRUPO</b></td>  <td class="letratd" align="center"><b>POSICION</b></td>  <td class="letratd" align="center"><b>ITEM</b></td>  <td class="letratd" align="center"><b>CONTEO</b></td> </tr>

 <?php  //PARA LISTAR A LOS INTELIGENTES QUE LA HAYAN EMBARRADO Y HAYAN VUELTO A CONTAR UN ITEM  $query = "SELECT * FROM tbinventario_errores";  $result = mysql_query($query) or die(mysql_error());

  while($row=mysql_fetch_array($result))

Page 52: Codigo Latino 12

  {   $id_user = $row[1];   $posicion = $row[2];   $item = $row[3];   $conteo = $row[4];

   //HACEMOS QUERY AL USUARIO   $query_user = "SELECT * FROM tbinventario_users WHERE id=".$id_user;   $result_user = mysql_query($query_user) or die(mysql_error());

   if($row_user=mysql_fetch_array($result_user))   {    $nombre1 = $row_user[4];    $nombre2 = $row_user[5];   }

   //HACEMOS QUERY A LA POSICION   $query_posi = "SELECT * FROM tbinventario_bodega WHERE código=".$posicion;   $result_posi = mysql_query($query_posi) or die(mysql_error());

   if($row_posi=mysql_fetch_array($result_posi))   {    $ubicacion = $row_posi[1];    $nombre = $row_posi[2];   }

   //HACEMOS QUERY A LA POSICION   $query_item = "SELECT * FROM tbinventario_items WHERE código LIKE '".$item."'";   $result_item = mysql_query($query_item) or die(mysql_error());

   if($row_item=mysql_fetch_array($result_item))   {    $nombre_item = $row_item[2];   }   echo '<tr><td class="letratd" align="center">'.$nombre1.'<br>'.$nombre2.'</td><td class="letratd" align="center">'.$ubicacion.'<br>'.$nombre.'</td><td class="letratd" align="center">'.$nombre_item.'</td><td class="letratd" align="center">'.$conteo.'</td></tr>';  }?></table><? } ?></div></body></html>

conteo.php<?php  include 'configuration.php';  $conteo = $_GET['conteo'];  $id_cuenta = $_GET['id'];?><!DOCTYPE html PUBLIC "­//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1­transitional.dtd">

Page 53: Codigo Latino 12

<html xmlns="http://www.w3.org/1999/xhtml"><head><meta http­equiv="Content­Type" content="text/html; charset=iso­8859­1" /><title>Ingreso Conteo ITEMS</title><LINK REL="StyleSheet" HREF="style.css" TYPE="text/css"><?php  echo '<script languaje="JavaScript"> function OpenPopup(texto1, texto2, texto3) {  window.open("captura.php?conteo=" + texto1 + "&id=" + texto2 + "&posicion=" + texto3, "_self", "width=400,height=400,toolbar=no,menubar=no,directories=yes,status=yes,resizable=no,location=yes,scrollbars=yes") } function cargar() {'; if ($conteo==1 || $conteo==4) {  echo 'f = document.frmconteo1;'; } elseif ($conteo==2 || $conteo==5) {  echo 'f = document.frmconteo2;'; } else {  echo 'f = document.frmconteo3;'; } echo 'if (f)        {   if (f.posicion.value == null || f.posicion.value == "")         {     f.posicion.focus();   }  }  }</script>';?></head><body onLoad="cargar()"><div align="center"><?php if($conteo==1 || $conteo==4) {?>  <form name="frmconteo1" method="post" action="<? $_SERVER['PHP_SELF']; ?>">   <table border="1" cellspacing="1" cellpadding="1">    <tr>     <td class="letratd" align="center"><b>POSICI&Oacute;N</b></td>    </tr>    <tr>     <td class="letratd" align="center"><input type="text" name="posicion" style="text­align:center;" size="10" maxlength="8"></td>    </tr>    <tr>

Page 54: Codigo Latino 12

     <td class="letratd" align="center" colspan="3">      <input type="hidden" name="conteo" value="<? echo $conteo; ?>">       <input type="hidden" name="id" value="<? echo $id_cuenta; ?>">       <!­­<input type="button" class="button" name="guardar1" value="Continuar" onClick="OpenPopup(frmconteo1.conteo.value, frmconteo1.id.value, frmconteo1.posicion.value)">!­­>      <input type="submit" class="button" name="guardar1" value="Continuar">     </td>    </tr>   </table>  </form><?php } elseif($conteo==2 || $conteo==5) {?>  <form name="frmconteo2" method="post" action="<? $_SERVER['PHP_SELF']; ?>">   <table border="1" cellspacing="1" cellpadding="1">    <tr>     <td class="letratd" align="center"><b>POSICI&Oacute;N</b></td>    </tr>    <tr>     <td class="letratd" align="center"><input type="text" name="posicion" style="text­align:center;" size="10" maxlength="8"></td>    </tr>    <tr>     <td class="letratd" align="center" colspan="3">       <input type="hidden" name="conteo" value="<? echo $conteo; ?>">        <input type="hidden" name="id" value="<? echo $id_cuenta; ?>">        <!­­<input type="button" class="button" name="guardar2" value="Continuar" onClick="OpenPopup(frmconteo2.conteo.value, frmconteo2.id.value, frmconteo2.posicion.value)">!­­>       <input type="submit" class="button" name="guardar2" value="Continuar">     </td>    </tr>   </table>  </form><?php } else {?>  <form name="frmconteo3" method="post" action="<? $_SERVER['PHP_SELF']; ?>">   <table border="1" cellspacing="1" cellpadding="1">    <tr>     <td class="letratd" align="center"><b>POSICI&Oacute;N</b></td>    </tr>    <tr>     <td class="letratd" align="center"><input type="text" name="posicion" style="text­align:center;" size="10" maxlength="8"></td>    </tr>    <tr>     <td class="letratd" align="center" colspan="3">       <input type="hidden" name="conteo" value="<? echo $conteo; ?>">

Page 55: Codigo Latino 12

       <input type="hidden" name="id" value="<? echo $id_cuenta; ?>">        <!­­<input type="button" class="button" name="guardar3" value="Continuar" onClick="OpenPopup(frmconteo3.conteo.value, frmconteo3.id.value, frmconteo3.posicion.value)">!­­>       <input type="submit" class="button" name="guardar3" value="Continuar">     </td>    </tr>   </table>  </form><? } ?></div></body></html><?php  if ($_POST['guardar1'])  {    echo $posicion = $_POST['posicion'];    echo $conteo = $_POST['conteo'];    echo $id = $_POST['id'];    echo '<script languaje="JavaScript">            OpenPopup('.$conteo.', '.$id.', '.$posicion.');          </script>';  }

  if ($_POST['guardar2'])  {    echo $posicion = $_POST['posicion'];    echo $conteo = $_POST['conteo'];    echo $id = $_POST['id'];    echo '<script languaje="JavaScript">            OpenPopup('.$conteo.', '.$id.', '.$posicion.');          </script>';  }

  if ($_POST['guardar3'])  {    echo $posicion = $_POST['posicion'];    echo $conteo = $_POST['conteo'];    echo $id = $_POST['id'];    echo '<script languaje="JavaScript">            OpenPopup('.$conteo.', '.$id.', '.$posicion.');          </script>';  }?>

captura.php<?php  include 'configuration.php';  $conteo = $_GET['conteo'];  $posicion = $_GET['posicion'];  $id_cuenta = $_GET['id'];?><!DOCTYPE html PUBLIC "­//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1­

Page 56: Codigo Latino 12

transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http­equiv="Content­Type" content="text/html; charset=iso­8859­1" /><title>Ingreso Conteo ITEMS</title><LINK REL="StyleSheet" HREF="style.css" TYPE="text/css"><script type="text/javascript" src="./ajax.js"></script></head><body><div align="center"><?php //VEMOS SI LA POSICION EXISTE  $query_posiexist = "SELECT * FROM tbinventario_bodega WHERE código LIKE '".$posicion."'"; $result_posiexist = mysql_query($query_posiexist) or die(mysql_error);

 $numrows = mysql_num_rows($result_posiexist);

 if ($numrows==0) {  echo "<blink class='letratd'><font color='#0000ff'>LA POSICI&Oacute;N ".$posicion." NO EXISTE</font></blink><br>     <a href='conteo.php?conteo=".$_GET['conteo']."&id=".$_GET['id'].">Volver</a>"; } else {   if ($row_posiexist=mysql_fetch_array($result_posiexist))  {   echo $row_posiexist[1]."<br>".$row_posiexist[2];  } } if($conteo==1 || $conteo==4) {?>  <div id="capaInfo" class="letratd"><b>Nombre del ITEM</b></div>        <form name="frmconteo1" method="post" action="<? $_SERVER['PHP_SELF']; ?>">   <table border="1" cellspacing="1" cellpadding="1">    <tr>     <?php if ($conteo==1){ ?><td class="letratd" align="center"><b>C&Oacute;DIGO ITEM</b></td>     <td class="letratd" align="center"><b>CANTIDAD</b></td>     <?php } elseif ($conteo==4){ ?><td class="letratd" align="center"><b>CANTIDAD</b></td>     <td class="letratd" align="center"><b>C&Oacute;DIGO BARRAS</b></td> <? } ?>     <td class="letratd" align="center"><b>POSICI&Oacute;N</b></td>    </tr>    <tr>     <?php if ($conteo==1){ ?><td class="letratd" align="center"><input type="text" name="items" onblur="traerDatos(frmconteo1.items.value)" style="text­align:center;" size="12" maxlength="10" <? if ($numrows==0){ echo 'disabled';} ?>></td>     <td class="letratd" align="center"><input type="text" name="cantidad" style="text­align:center;" size="5" maxlength="5" <? if ($numrows==0){ echo 'disabled';} ?>></td>     <?php } elseif ($conteo==4){ ?><td class="letratd" align="center"><input type="text" name="cantidad" style="text­align:center;" size="5" maxlength="5" <? if ($numrows==0){ echo 'disabled';} ?>></td>     <td class="letratd" align="center"><input type="text" name="item" style="text­align:center;" size="12" maxlength="28" <? if ($numrows==0){ echo 'disabled';} ?>></td><? } ?>

Page 57: Codigo Latino 12

     <td class="letratd" align="center"><input type="text" name="posicion" style="text­align:center;" size="10" maxlength="8" value="<? echo $posicion; ?>" readonly="readonly"></td>    </tr>    <tr>     <td class="letratd" align="center" colspan="3">      <input type="hidden" name="conteo" value="<? echo $conteo; ?>">       <input type="hidden" name="id_cuenta" value="<? echo $id_cuenta; ?>">       <input type="submit" class="button" name="save" value="Capturar">       <input type="submit" class="button" name="guardar1" value="Guardar">      </td>    </tr>   </table>  </form>   <table border="1" cellspacing="1" cellpadding="1">                <tr>                 <td class="letratd" align="center" colspan="4"><b>POSICI&Oacute;N <? echo $posicion; ?></b></td>    </tr>    <tr>     <td class="letratd" align="center"><b>C&Oacute;DIGO ITEM</b></td>     <td class="letratd" align="center"><b>DESC ITEM</b></td>     <td class="letratd" align="center"><b>CANTIDAD</b></td>     <td class="letratd" align="center"><b>ELIMINAR</b></td>    </tr>                <?php                  //SE VA A IMPRIMIR UNA TABLA CON LOS ITEMS QUE SE INDEXARAN DENTRO DE LA TABLA tbinventario_conteos                  $query_sacar = "SELECT * FROM tbinventario_subconteo WHERE cod_bodega LIKE '".$posicion."' AND indexado=0";                  $result_sacar = mysql_query($query_sacar) or die(mysql_error());

                  echo $numrows = mysql_num_rows($result_sacar);

                  while ($row_sacar=mysql_fetch_array($result_sacar))                  {                         $id_sub = $row_sacar[0];                   $cod_item = $row_sacar[1];

                         $query_item = "SELECT * FROM tbinventario_items WHERE código LIKE '".$cod_item."'";                         $result_item = mysql_query($query_item) or die(mysql_error());

                         if ($row_item=mysql_fetch_array($result_item))                         {                          $nombre_item = $row_item[2];                         }                         $cantidad = $row_sacar[3];                         echo "<tr>                             <td class='letratd' align='center'>".$cod_item."</td>                                         <td class='letratd' align='center'>".$nombre_item."</td>                                         <td class='letratd' align='center'>".$cantidad."</td>                                         <td class='letratd' align='center'>";                ?>                       <a href='javascript: window.open("edi_eli.php?conten=<? echo $id_sub; ?>&conteo=<? echo $conteo; ?>&id_cuenta=<? echo $conteo; ?>&posicion=<? echo $posicion; ?

Page 58: Codigo Latino 12

>","","resizable=yes,scrollbars=yes,width=250,height=80,menubar=no,status=yes,top=1,left=1").focus();'><img src='b_drop.png' border=0></a></td>                <?php                            echo "</tr>";                  }                ?>         </table><?php } elseif($conteo==2 || $conteo==5) {?>  <div id="capaInfo" class="letratd"><b>Nombre del ITEM</b></div>        <form name="frmconteo2" method="post" action="<? $_SERVER['PHP_SELF']; ?>">   <table border="1" cellspacing="1" cellpadding="1">    <tr>     <?php if ($conteo==2){ ?><td class="letratd" align="center"><b>C&Oacute;DIGO ITEM</b></td>     <td class="letratd" align="center"><b>CANTIDAD</b></td>     <?php } elseif ($conteo==5){ ?><td class="letratd" align="center"><b>CANTIDAD</b></td>     <td class="letratd" align="center"><b>C&Oacute;DIGO BARRAS</b></td> <? } ?>     <td class="letratd" align="center"><b>POSICI&Oacute;N</b></td>    </tr>    <tr>     <?php if ($conteo==2){ ?><td class="letratd" align="center"><input type="text" name="items" onblur="traerDatos(frmconteo2.items.value)" style="text­align:center;" size="12" maxlength="10"></td>     <td class="letratd" align="center"><input type="text" name="cantidad" style="text­align:center;" size="5" maxlength="5"></td>     <?php } elseif ($conteo==5){ ?>     <td class="letratd" align="center"><input type="text" name="cantidad" style="text­align:center;" size="5" maxlength="5"></td>     <td class="letratd" align="center"><input type="text" name="item" style="text­align:center;" size="12" maxlength="28"></td><? } ?>     <td class="letratd" align="center"><input type="text" name="posicion" style="text­align:center;" size="10" maxlength="8" value="<? echo $posicion; ?>" readonly="readonly"></td>    </tr>    <tr>     <td class="letratd" align="center" colspan="3">      <input type="hidden" name="conteo" value="<? echo $conteo; ?>">       <input type="hidden" name="id_cuenta" value="<? echo $id_cuenta; ?>">       <input type="submit" class="button" name="save" value="Capturar">      <input type="submit" class="button" name="guardar2" value="Guardar">      </td>    </tr>   </table>  </form>   <table border="1" cellspacing="1" cellpadding="1">                <tr>                 <td class="letratd" align="center" colspan="4"><b>POSICI&Oacute;N <? echo $posicion; ?></b></td>    </tr>    <tr>     <td class="letratd" align="center"><b>C&Oacute;DIGO ITEM</b></td>     <td class="letratd" align="center"><b>DESC ITEM</b></td>

Page 59: Codigo Latino 12

     <td class="letratd" align="center"><b>CANTIDAD</b></td>     <td class="letratd" align="center"><b>ELIMINAR</b></td>    </tr>                <?php                  //SE VA A IMPRIMIR UNA TABLA CON LOS ITEMS QUE SE INDEXARAN DENTRO DE LA TABLA tbinventario_conteos                  $query_sacar = "SELECT * FROM tbinventario_subconteo WHERE cod_bodega LIKE '".$posicion."' AND indexado=0";                  $result_sacar = mysql_query($query_sacar) or die(mysql_error());

                  echo $numrows = mysql_num_rows($result_sacar);

                  while ($row_sacar=mysql_fetch_array($result_sacar))                  {                         $id_sub = $row_sacar[0];                   $cod_item = $row_sacar[1];

                         $query_item = "SELECT * FROM tbinventario_items WHERE código LIKE '".$cod_item."'";                         $result_item = mysql_query($query_item) or die(mysql_error());

                         if ($row_item=mysql_fetch_array($result_item))                         {                          $nombre_item = $row_item[2];                         }                         $cantidad = $row_sacar[3];                         echo "<tr>                             <td class='letratd' align='center'>".$cod_item."</td>                                         <td class='letratd' align='center'>".$nombre_item."</td>                                         <td class='letratd' align='center'>".$cantidad."</td>                                         <td class='letratd' align='center'>";                ?>                     <a href='javascript: window.open("edi_eli.php?conten=<? echo $id_sub; ?>&conteo=<? echo $conteo; ?>&id_cuenta=<? echo $conteo; ?>&posicion=<? echo $posicion; ?>","","resizable=yes,scrollbars=yes,width=250,height=80,menubar=no,status=yes,top=1,left=1").focus();'><img src='b_drop.png' border=0></a></td>                <?php                            echo "</tr>";                  }                ?>         </table><?php } else {?>  <div id="capaInfo" class="letratd"><b>Nombre del ITEM</b></div>        <form name="frmconteo3" method="post" action="<? $_SERVER['PHP_SELF']; ?>">   <table border="1" cellspacing="1" cellpadding="1">    <tr>     <?php if ($conteo==3){ ?><td class="letratd" align="center"><b>C&Oacute;DIGO ITEM</b></td>     <td class="letratd" align="center"><b>CANTIDAD</b></td>     <?php } elseif ($conteo==6){ ?><td class="letratd" align="center"><b>CANTIDAD</b></td>

Page 60: Codigo Latino 12

     <td class="letratd" align="center"><b>C&Oacute;DIGO BARRAS</b></td> <? } ?>     <td class="letratd" align="center"><b>POSICI&Oacute;N</b></td>    </tr>    <tr>     <?php if ($conteo==3){ ?><td class="letratd" align="center"><input type="text" name="items" onblur="traerDatos(frmconteo3.items.value)" style="text­align:center;" size="12" maxlength="10"></td>     <td class="letratd" align="center"><input type="text" name="cantidad" style="text­align:center;" size="5" maxlength="5"></td>     <?php } elseif ($conteo==6){ ?>     <td class="letratd" align="center"><input type="text" name="cantidad" style="text­align:center;" size="5" maxlength="5"></td>     <td class="letratd" align="center"><input type="text" name="item" style="text­align:center;" size="12" maxlength="28"></td><? } ?>     <td class="letratd" align="center"><input type="text" name="posicion" style="text­align:center;" size="10" maxlength="8" value="<? echo $posicion; ?>" readonly="readonly"></td>    </tr>    <tr>     <td class="letratd" align="center" colspan="3">      <input type="hidden" name="conteo" value="<? echo $conteo; ?>">       <input type="hidden" name="id_cuenta" value="<? echo $id_cuenta; ?>">       <input type="submit" class="button" name="save" value="Capturar">       <input type="submit" class="button" name="guardar3" value="Guardar">      </td>    </tr>   </table>  </form>   <table border="1" cellspacing="1" cellpadding="1">                <tr>                 <td class="letratd" align="center" colspan="4"><b>POSICI&Oacute;N <? echo $posicion; ?></b></td>    </tr>    <tr>     <td class="letratd" align="center"><b>C&Oacute;DIGO ITEM</b></td>     <td class="letratd" align="center"><b>DESC ITEM</b></td>     <td class="letratd" align="center"><b>CANTIDAD</b></td>     <td class="letratd" align="center"><b>ELIMINAR</b></td>    </tr>                <?php                  //SE VA A IMPRIMIR UNA TABLA CON LOS ITEMS QUE SE INDEXARAN DENTRO DE LA TABLA tbinventario_conteos                  $query_sacar = "SELECT * FROM tbinventario_subconteo WHERE cod_bodega LIKE '".$posicion."' AND indexado=0";                  $result_sacar = mysql_query($query_sacar) or die(mysql_error());

                  echo $numrows = mysql_num_rows($result_sacar);

                  while ($row_sacar=mysql_fetch_array($result_sacar))                  {                         $id_sub = $row_sacar[0];                   $cod_item = $row_sacar[1];

                         $query_item = "SELECT * FROM tbinventario_items WHERE código LIKE '".$cod_item."'";                         $result_item = mysql_query($query_item) or die(mysql_error());

Page 61: Codigo Latino 12

                         if ($row_item=mysql_fetch_array($result_item))                         {                          $nombre_item = $row_item[2];                         }                         $cantidad = $row_sacar[3];                         echo "<tr>                             <td class='letratd' align='center'>".$cod_item."</td>                                         <td class='letratd' align='center'>".$nombre_item."</td>                                         <td class='letratd' align='center'>".$cantidad."</td>                                         <td class='letratd' align='center'>";                ?>                    <a href='javascript: window.open("edi_eli.php?conten=<? echo $id_sub; ?>&conteo=<? echo $conteo; ?>&id_cuenta=<? echo $conteo; ?>&posicion=<? echo $posicion; ?>","","resizable=yes,scrollbars=yes,width=250,height=80,menubar=no,status=yes,top=1,left=1").focus();'><img src='b_drop.png' border=0></a></td>                <?php                            echo "</tr>";                  }                ?>         </table><? } ?></div></body></html><?php  //SE SALVARAN LOS DATOS EN LA TABLA tbinventario_subconteo  if($_POST['save'])  {   $item = $_POST['item'];   $cantidad = $_POST['cantidad'];   $posicion = $_POST['posicion'];   $conteo = $_POST['conteo'];   $id_cuenta = $_POST['id_cuenta'];         $items = $_POST['items'];

         echo "El item es ".$item;   if ($conteo==4){ $contar=1; }   if ($conteo==5){ $contar=2; }   if ($conteo==6){ $contar=3; }

         if ($items)         {          echo $query_coditem = "SELECT * FROM tbinventario_items                     WHERE código LIKE '".$items."'";         }         else         {          echo $query_coditem = "SELECT * FROM tbinventario_items                     WHERE cod_barra01 LIKE '".$item."' OR cod_barra02 LIKE '".$item."'                     OR cod_barra03 LIKE '".$item."' OR cod_barra04 LIKE '".$item."'                     OR cod_barra05 LIKE '".$item."' OR cod_barra06 LIKE '".$item."'                     OR cod_barra07 LIKE '".$item."' OR cod_barra08 LIKE '".$item."'

Page 62: Codigo Latino 12

                     OR cod_barra09 LIKE '".$item."'";         }         $result_coditem = mysql_query($query_coditem) or die(mysql_error());

         if ($row_coditem=mysql_fetch_array($result_coditem));         {          $item = $row_coditem[1];         }

  $query_sub = "INSERT INTO tbinventario_subconteo VALUES (NULL, '".$item."', '".$posicion."', '".$cantidad."', '0', '".$id_cuenta."')";         $result_sub = mysql_query($query_sub) or die(mysql_error());

         echo "<script languaje='JavaScript'>             window.opener.location.href='captura.php?conteo=$conteo&id=$id_cuenta&posicion=$posicion';                  </script>";

  }  //UTILIZO EL METODO POST POR QUE EN MI UBUNTU NO ME funciona  //LA FORMA TRADICIONAL (NO S&#201; POR QU&#201; :S)  if($_POST['guardar1'])  {   $posicion = $_POST['posicion'];   $conteo = $_POST['conteo'];   $id_cuenta = $_POST['id_cuenta'];

         //COMO EL DESOCUPADO DE RENGIFO LO PUSO A HACER POR UN ARREGLO,         //'TONS AHORA TOCA DE ESTA FORMA         //PRIMERO SE LEE DE LA TABLA tbsdpel_subconteo, SE EXTRAEN LOS DATOS         //Y SE INGRESAN EN LA TABLA tbinventario_conteos         //echo $query_extraer = "SELECT * FROM tbinventario_subconteo WHERE cod_bodega LIKE '".$posicion."' AND indexado=0 AND indexado_por='".$id_cuenta."'";         echo $query_extraer = "SELECT * FROM tbinventario_subconteo WHERE cod_bodega LIKE '".$posicion."' AND indexado=0";         $result_extraer = mysql_query($query_extraer) or die(mysql_error());

         while ($row_extraer=mysql_fetch_array($result_extraer))         {          $cod_item = $row_extraer[1];          $cantidad = $row_extraer[3];

          //SABER SI YA SE HIZO ESE CONTEO Y SI NO ES así GUARDAR EL REGISTRO          $query_sabersi = "SELECT * FROM tbinventario_conteos WHERE item_código LIKE '".$cod_item."' AND posicion LIKE '".$posicion."'";          $result_sabersi = mysql_query($query_sabersi) or die(mysql_error());

          //LE AGREGO LA CANTIDAD DE REGISTROS ENTREGADOS POR LA CONSULTA A UNA VARIABLE          $numrows = mysql_num_rows($result_sabersi);

          if($numrows != 0)          {     echo "<div align='center'><b><font size=4>A ESTE ITEM YA SE LE HIZO PRIMER CONTEO</font></b></div>";     $query_error1 = "INSERT INTO tbinventario_errores VALUES(NULL, '".$id_cuenta."', '".$posicion."', '".$cod_item."', '".

Page 63: Codigo Latino 12

$conteo."')";     $result_error1 = mysql_query($query_error1) or die(mysql_error());    }    else    {     echo $query_conteo1 = "INSERT INTO tbinventario_conteos VALUES(NULL, '".$cod_item."', '".$posicion."', '".$cantidad."', '', '', '".$id_cuenta."', '', '')";     $result_conteo1 = mysql_query($query_conteo1) or die(mysql_error());     echo "<div align='center'><b><font size=4>EL ITEM HA SIDO INDEXADO SATISFACTORIAMENTE</font></b></div>";    }

    if($result_sabersi == 0)    {     echo "NO SE PUDO INDEXAR LA INFORMACION";    }

          //AHORA SE ACTUALIZA LA TABLA tbinventario_subconteo EN SU CAMPO INDEXADO          //PARA NO VOLVER A TOMAR ESOS ITEMS          $query_upd = "UPDATE tbinventario_subconteo SET indexado=1 WHERE cod_item LIKE '".$cod_item."' AND cod_bodega LIKE '".$posicion."'";          $result_upd = mysql_query($query_upd) or die(mysql_error());

         echo "<script languaje='JavaScript'>              window.close();                   </script>";

          //VAMOS DANDOLE AL ITEM EN QUE CONTEO VA          $query_itemcontado = "UPDATE tbinventario_items SET conteo=".$conteo." WHERE código LIKE '".$cod_item."'";          $result_itemcontado = mysql_query($query_itemcontado) or die(mysql_error());   }   //VAMOS A CERRAR LA POSICION DESPUES DE QUE SE INGRESEN LOS DATOS         //EN LA TABLA tbinventario_bodega         if ($conteo==4) { $conteo==1; }         if ($conteo==5) { $conteo==2; }         if ($conteo==6) { $conteo==3; }         $query_cerrar = "UPDATE tbinventario_bodega SET cerrado=1, conteo=".$conteo." WHERE código LIKE '".$posicion."'";         $result_cerrar = mysql_query($query_cerrar) or die(mysql_error());  }

  if($_POST['guardar2'])  {   $posicion = $_POST['posicion'];   $conteo = $_POST['conteo'];   $id_cuenta = $_POST['id_cuenta'];

         //COMO EL DESOCUPADO DE RENGIFO LO PUSO A HACER POR UN ARREGLO,         //'TONS AHORA TOCA DE ESTA FORMA         //PRIMERO SE LEE DE LA TABLA tbsdpel_subconteo, SE EXTRAEN LOS DATOS         //Y SE INGRESAN EN LA TABLA tbinventario_conteos         $query_extraer = "SELECT * FROM tbinventario_subconteo WHERE cod_bodega LIKE '".$posicion."' AND indexado=0 AND indexado_por='".$id_cuenta."'";         $result_extraer = mysql_query($query_extraer) or die(mysql_error());

Page 64: Codigo Latino 12

         while ($row_extraer=mysql_fetch_array($result_extraer))         {          $cod_item = $row_extraer[1];          $cantidad = $row_extraer[3];

          //SABER SI YA SE HIZO ESE CONTEO Y SI NO ES así GUARDAR EL REGISTRO          $query_sabersi = "SELECT * FROM tbinventario_conteos WHERE item_código LIKE '".$cod_item."' AND posicion=".$posicion." AND segundo!=0";      $result_sabersi = mysql_query($query_sabersi) or die(mysql_error());

     //LE AGREGO LA CANTIDAD DE REGISTROS ENTREGADOS POR LA CONSULTA A UNA VARIABLE     $numrows = mysql_num_rows($result_sabersi);

     if($numrows != 0)     {       echo "<div align='center'><b><font size=4>A ESTE ITEM YA SE LE HIZO SEGUNDO CONTEO</font></b></div>";       echo $query_error1 = "INSERT INTO tbinventario_errores VALUES(NULL, '".$id_cuenta."', '".$posicion."', '".$cod_item."', '".$conteo."')";     $result_error1 = mysql_query($query_error1) or die(mysql_error());    }    else    {     $query_conteo2 = "UPDATE tbinventario_conteos SET segundo='".$cantidad."', conto_segundo='".$id_cuenta."' WHERE item_código LIKE '".$cod_item."' AND posicion='".$posicion."'";     $result_conteo2 = mysql_query($query_conteo2) or die(mysql_error());     echo "<div align='center'><b><font size=4>EL ITEM HA SIDO INDEXADO SATISFACTORIAMENTE ".$cod_item."</font></b></div>";    }

    if($result_sabersi == 0)    {     echo "NO SE PUDO INDEXAR LA INFORMACION";    }

          //AHORA SE ACTUALIZA LA TABLA tbinventario_subconteo EN SU CAMPO INDEXADO          //PARA NO VOLVER A TOMAR ESOS ITEMS          $query_upd = "UPDATE tbinventario_subconteo SET indexado=1 WHERE cod_item LIKE '".$cod_item."' AND cod_bodega LIKE '".$posicion."'";          $result_upd = mysql_query($query_upd) or die(mysql_error());

         echo "<script languaje='JavaScript'>              window.close();                   </script>";

          //VAMOS DANDOLE AL ITEM EN QUE CONTEO VA          $query_itemcontado = "UPDATE tbinventario_items SET conteo=".$conteo." WHERE código LIKE '".$cod_item."'";          $result_itemcontado = mysql_query($query_itemcontado) or die(mysql_error());   }         //VAMOS A CERRAR LA POSICION DESPUES DE QUE SE INGRESEN LOS DATOS         //EN LA TABLA tbinventario_bodega         $query_cerrar = "UPDATE tbinventario_bodega SET cerrado=1, conteo=".$conteo." WHERE código LIKE '".$posicion."'";         $result_cerrar = mysql_query($query_cerrar) or die(mysql_error());  }

Page 65: Codigo Latino 12

  if($_POST['guardar3'])  {   $posicion = $_POST['posicion'];   $conteo = $_POST['conteo'];   $id_cuenta = $_POST['id_cuenta'];

         //COMO EL DESOCUPADO DE RENGIFO LO PUSO A HACER POR UN ARREGLO,         //'TONS AHORA TOCA DE ESTA FORMA         //PRIMERO SE LEE DE LA TABLA tbsdpel_subconteo, SE EXTRAEN LOS DATOS         //Y SE INGRESAN EN LA TABLA tbinventario_conteos         $query_extraer = "SELECT * FROM tbinventario_subconteo WHERE cod_bodega LIKE '".$posicion."' AND indexado=0 AND indexado_por='".$id_cuenta."'";         $result_extraer = mysql_query($query_extraer) or die(mysql_error());

         while ($row_extraer=mysql_fetch_array($result_extraer))         {          $cod_item = $row_extraer[1];          $cantidad = $row_extraer[3];

          //SABER SI YA SE HIZO ESE CONTEO Y SI NO ES así GUARDAR EL REGISTRO          $query_sabersi = "SELECT * FROM tbinventario_conteos WHERE item_código LIKE '".$cod_item."' AND posicion=".$posicion." AND tercer!=0";      $result_sabersi = mysql_query($query_sabersi) or die(mysql_error());

      //LE AGREGO LA CANTIDAD DE REGISTROS ENTREGADOS POR LA CONSULTA A UNA VARIABLE      $numrows = mysql_num_rows($result_sabersi);

     if($numrows != 0)    {       echo "<div align='center'><b><font size=4>A ESTE ITEM YA SE LE HIZO TERCER CONTEO</font></b></div>";       echo $query_error1 = "INSERT INTO tbinventario_errores VALUES(NULL, '".$id_cuenta."', '".$posicion."', '".$cod_item."', '".$conteo."')";     $result_error1 = mysql_query($query_error1) or die(mysql_error());    }    else    {     $query_conteo2 = "UPDATE tbinventario_conteos SET tercer='".$cantidad."', conto_tercero='".$id_cuenta."' WHERE item_código LIKE '".$cod_item."' AND posicion='".$posicion."'";     $result_conteo2 = mysql_query($query_conteo2) or die(mysql_error());     echo "<div align='center'><b><font size=4>EL ITEM HA SIDO INDEXADO SATISFACTORIAMENTE ".$cod_item."</font></b></div>";    }

    if($result_sabersi == 0)    {       echo "NO SE PUDO INDEXAR LA INFORMACION";    }

          //AHORA SE ACTUALIZA LA TABLA tbinventario_subconteo EN SU CAMPO INDEXADO          //PARA NO VOLVER A TOMAR ESOS ITEMS          $query_upd = "UPDATE tbinventario_subconteo SET indexado=1 WHERE cod_item LIKE '".$cod_item."' AND cod_bodega LIKE '".$posicion."'";

Page 66: Codigo Latino 12

          $result_upd = mysql_query($query_upd) or die(mysql_error());

         echo "<script languaje='JavaScript'>              window.close();                   </script>";

          //VAMOS DANDOLE AL ITEM EN QUE CONTEO VA          $query_itemcontado = "UPDATE tbinventario_items SET conteo=".$conteo." WHERE código LIKE '".$cod_item."'";          $result_itemcontado = mysql_query($query_itemcontado) or die(mysql_error());   }         //VAMOS A CERRAR LA POSICION DESPUES DE QUE SE INGRESEN LOS DATOS         //EN LA TABLA tbinventario_bodega         $query_cerrar = "UPDATE tbinventario_bodega SET cerrado=1, conteo=".$conteo." WHERE código LIKE '".$posicion."'";         $result_cerrar = mysql_query($query_cerrar) or die(mysql_error());  }?>

Los módulos de edición son muy similares a los de captura.

consultar.php<?php  include 'configuration.php';  $conteo = $_GET['conteo'];  $id_cuenta = $_GET['id'];?><!DOCTYPE html PUBLIC "­//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1­transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http­equiv="Content­Type" content="text/html; charset=iso­8859­1" /><title>Ingreso Conteo ITEMS</title><LINK REL="StyleSheet" HREF="style.css" TYPE="text/css"><script languaje="JavaScript"> function OpenPopup(texto1, texto2, texto3) {  window.open("editar.php?conteo=" + texto1 + "&id=" + texto2 + "&posicion=" + texto3, "_self", "width=400,height=400,toolbar=no,menubar=no,directories=yes,status=yes,resizable=no,location=yes,scrollbars=yes") }</script></head><body><div align="center"><?php if($conteo==1 || $conteo==4) {?>  <form name="frmconteo1" method="post" action="<? $_SERVER['PHP_SELF']; ?>">   <table border="1" cellspacing="1" cellpadding="1">    <tr>     <td class="letratd" align="center"><b>POSICI&Oacute;N</b></td>    </tr>    <tr>

Page 67: Codigo Latino 12

     <td class="letratd" align="center"><input type="text" name="posicion" style="text­align:center;" size="10" maxlength="8"></td>    </tr>    <tr>     <td class="letratd" align="center" colspan="3">      <input type="hidden" name="conteo" value="<? echo $conteo; ?>">       <input type="hidden" name="id" value="<? echo $id_cuenta; ?>">       <input type="button" class="button" name="guardar1" value="Continuar" onClick="OpenPopup(frmconteo1.conteo.value, frmconteo1.id.value, frmconteo1.posicion.value)">       <!­­<input type="submit" class="button" name="guardar1" value="Continuar">!­­>     </td>    </tr>   </table>  </form><?php } elseif($conteo==2) {?>  <form name="frmconteo2" method="post" action="<? $_SERVER['PHP_SELF']; ?>">   <table border="1" cellspacing="1" cellpadding="1">    <tr>     <td class="letratd" align="center"><b>POSICI&Oacute;N</b></td>    </tr>    <tr>     <td class="letratd" align="center"><input type="text" name="posicion" style="text­align:center;" size="10" maxlength="8"></td>    </tr>    <tr>     <td class="letratd" align="center" colspan="3">       <input type="hidden" name="conteo" value="<? echo $conteo; ?>">        <input type="hidden" name="id" value="<? echo $id_cuenta; ?>">        <input type="button" class="button" name="guardar2" value="Continuar" onClick="OpenPopup(frmconteo2.conteo.value, frmconteo2.id.value, frmconteo2.posicion.value)">     </td>    </tr>   </table>  </form><?php } else {?>  <form name="frmconteo3" method="post" action="<? $_SERVER['PHP_SELF']; ?>">   <table border="1" cellspacing="1" cellpadding="1">    <tr>     <td class="letratd" align="center"><b>POSICI&Oacute;N</b></td>    </tr>    <tr>     <td class="letratd" align="center"><input type="text" name="posicion" style="text­align:center;" size="10" maxlength="8"></td>    </tr>

Page 68: Codigo Latino 12

    <tr>     <td class="letratd" align="center" colspan="3">       <input type="hidden" name="conteo" value="<? echo $conteo; ?>">       <input type="hidden" name="id" value="<? echo $id_cuenta; ?>">        <input type="button" class="button" name="guardar3" value="Continuar" onClick="OpenPopup(frmconteo3.conteo.value, frmconteo3.id.value, frmconteo3.posicion.value)">     </td>    </tr>   </table>  </form><? } ?></div></body></html><?php  if ($_POST['guardar1'])  {   echo $posicion = $_GET['posicion'];         echo $conteo = $_GET['conteos'];         echo $id = $_GET['ids'];         echo '<script languaje="JavaScript">                         window.open("captura.php?conteo='.$conteo.'&id='.$id.'&posicion='.$posicion.', "_self", "width=400,height=400,toolbar=no,menubar=no,directories=yes,status=yes,resizable=no,location=yes,scrollbars=yes")                 </script>';  }?>

editar.php<?php  include 'configuration.php';  $conteo = $_GET['conteo'];  $posicion = $_GET['posicion'];  $id_cuenta = $_GET['id'];  $coditem = $_GET['coditem'];  $cantidad1conteo = $_GET['cantidad'];  $cantidad2conteo = $_GET['cantidad'];  $cantidad3conteo = $_GET['cantidad'];?><!DOCTYPE html PUBLIC "­//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1­transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http­equiv="Content­Type" content="text/html; charset=iso­8859­1" /><title>Ingreso Conteo ITEMS</title><LINK REL="StyleSheet" HREF="style.css" TYPE="text/css"><script type="text/javascript" src="./ajax.js"></script></head><body><div align="center"><?php if($conteo==1 || $conteo==4) {?>

Page 69: Codigo Latino 12

  <div id="capaInfo" class="letratd"><b>Nombre del ITEM</b></div>        <form name="frmconteo1" method="post" action="<? $_SERVER['PHP_SELF']; ?>">  <table border="1" cellspacing="1" cellpadding="1">    <tr>     <?php if ($conteo==1){ ?><td class="letratd" align="center"><b>C&Oacute;DIGO ITEM</b></td>     <td class="letratd" align="center"><b>CANTIDAD</b></td>     <?php } elseif ($conteo==4){ ?><td class="letratd" align="center"><b>C&Oacute;DIGO BARRAS</b></td> <? } ?>     <td class="letratd" align="center"><b>POSICI&Oacute;N</b></td>    </tr>    <tr>     <?php if ($conteo==1){ ?><td class="letratd" align="center"><input type="text" id="item" name="item" value="<? echo $coditem; ?>" style="text­align:center;" size="12" maxlength="10" readonly="readonly"></td>    <td class="letratd" align="center"><input type="text" id="cantidad" name="cantidad" value="<? echo $cantidad1conteo; ?>" style="text­align:center;" size="5" maxlength="5"></td>     <?php } elseif ($conteo==4){ ?><td class="letratd" align="center"><input type="text" name="cod_barra" style="text­align:center;" size="12" maxlength="28"></td><? } ?>     <td class="letratd" align="center"><input type="text" name="posicion" style="text­align:center;" size="10" maxlength="8" value="<? echo $posicion; ?>" readonly="readonly"></td>    </tr>    <tr>     <td class="letratd" align="center" colspan="3">      <input type="hidden" name="conteo" value="<? echo $conteo; ?>">       <input type="hidden" name="id_cuenta" value="<? echo $id_cuenta; ?>">       <input type="submit" class="button" name="guardar1" value="Guardar">      </td>    </tr>   </table>  </form>   <table border="1" cellspacing="1" cellpadding="1">                <tr>                 <td class="letratd" align="center" colspan="4"><b>POSICI&Oacute;N <? echo $posicion; ?></b></td>    </tr>    <tr>     <td class="letratd" align="center"><b>C&Oacute;DIGO ITEM</b></td>     <td class="letratd" align="center"><b>DESC ITEM</b></td>     <td class="letratd" align="center"><b>CANTIDAD</b></td>     <td class="letratd" align="center"><b>EDITAR</b></td>    </tr>      <?php         //SE VA A IMPRIMIR UNA TABLA CON LOS ITEMS QUE SE INDEXARAN DENTRO DE LA TABLA tbinventario_conteos         $query_sacar = "SELECT * FROM tbinventario_conteos WHERE posicion LIKE '".$posicion."'";// AND segundo != ''";         $result_sacar = mysql_query($query_sacar) or die(mysql_error());

         echo $numrows = mysql_num_rows($result_sacar);

         while ($row_sacar=mysql_fetch_array($result_sacar))         {           $id_sub = $row_sacar[0];           $cod_item = $row_sacar[1];

           $query_item = "SELECT * FROM tbinventario_items WHERE código LIKE '".$cod_item."'";           $result_item = mysql_query($query_item) or die(mysql_error());

Page 70: Codigo Latino 12

           if ($row_item=mysql_fetch_array($result_item))           {             $nombre_item = $row_item[2];           }

           $cantidad1conteo = $row_sacar[3];           echo "<tr>                   <td class='letratd' align='center'>".$cod_item."</td>                   <td class='letratd' align='center'>".$nombre_item."</td>                   <td class='letratd' align='center'>".$cantidad1conteo."</td>                   <td class='letratd' align='center'>";       ?>       <!­­<input type='button' name='editor' value='Editar' onclick="editarDatos('<? echo $cod_item; ?>', 2, frmconteo2.posicion.value)">!­­>        <a href='editar.php?conteo=<? echo $conteo; ?>&posicion=<? echo $posicion; ?>&id=<? echo $id_cuenta; ?>&coditem=<? echo $cod_item; ?>&cantidad=<? echo $cantidad1conteo; ?>'><img src='b_edit.png' border=0></a></td>       <?php              echo "</tr>";          }       ?>    </table><?php } elseif($conteo==2) {?>  <div id="capaInfos" class="letratd"><b>Nombre del ITEM</b></div>        <form name="frmconteo2" method="post" action="<? $_SERVER['PHP_SELF']; ?>">   <table border="1" cellspacing="1" cellpadding="1">    <tr>     <?php if ($conteo==2){ ?><td class="letratd" align="center"><b>C&Oacute;DIGO ITEM</b></td>     <td class="letratd" align="center"><b>CANTIDAD</b></td>     <?php } elseif ($conteo==4){ ?><td class="letratd" align="center"><b>C&Oacute;DIGO BARRAS</b></td> <? } ?>     <td class="letratd" align="center"><b>POSICI&Oacute;N</b></td>    </tr>    <tr>     <?php if ($conteo==2){ ?><td class="letratd" align="center"><input type="text" id="item" name="item" value="<? echo $coditem; ?>" style="text­align:center;" size="12" maxlength="10" readonly="readonly"></td>     <td class="letratd" align="center"><input type="text" id="cantidad" name="cantidad" value="<? echo $cantidad2conteo; ?>" style="text­align:center;" size="5" maxlength="5"></td>     <?php } elseif ($conteo==4){ ?><td class="letratd" align="center"><input type="text" name="cod_barra" style="text­align:center;" size="12" maxlength="28"></td><? } ?>     <td class="letratd" align="center"><input type="text" name="posicion" style="text­align:center;" size="10" maxlength="8" value="<? echo $posicion; ?>" readonly="readonly"></td>    </tr>    <tr>     <td class="letratd" align="center" colspan="3">      <input type="hidden" name="conteo" value="<? echo $conteo; ?>">       <input type="hidden" name="id_cuenta" value="<? echo $id_cuenta; ?>">       <input type="submit" class="button" name="guardar2" value="Guardar">      </td>

Page 71: Codigo Latino 12

    </tr>   </table>  </form>   <table border="1" cellspacing="1" cellpadding="1">     <tr>       <td class="letratd" align="center" colspan="4"><b>POSICI&Oacute;N <? echo $posicion; ?></b></td>    </tr>    <tr>     <td class="letratd" align="center"><b>C&Oacute;DIGO ITEM</b></td>     <td class="letratd" align="center"><b>DESC ITEM</b></td>     <td class="letratd" align="center"><b>CANTIDAD</b></td>     <td class="letratd" align="center"><b>EDITAR</b></td>    </tr>    <?php       //SE VA A IMPRIMIR UNA TABLA CON LOS ITEMS QUE SE INDEXARON DENTRO DE LA TABLA tbinventario_conteos      //PARA EDITARLOS EN EL PANEL SUPERIOR      $query_sacar = "SELECT * FROM tbinventario_conteos WHERE posicion LIKE '".$posicion."' AND segundo != ''";      $result_sacar = mysql_query($query_sacar) or die(mysql_error());

      echo $numrows = mysql_num_rows($result_sacar);      while ($row_sacar=mysql_fetch_array($result_sacar))      {        $id_sub = $row_sacar[0];         $cod_item = $row_sacar[1];         $query_item = "SELECT * FROM tbinventario_items WHERE código LIKE '".$cod_item."'";         $result_item = mysql_query($query_item) or die(mysql_error());

         if ($row_item=mysql_fetch_array($result_item))         {            $nombre_item = $row_item[2];         }

         $cantidad2conteo = $row_sacar[4];

         echo "<tr>                 <td class='letratd' align='center'>".$cod_item."</td>                 <td class='letratd' align='center'>".$nombre_item."</td>                 <td class='letratd' align='center'>".$cantidad2conteo."</td>                 <td class='letratd' align='center'>";     ?>       <!­­<input type='button' name='editor' value='Editar' onclick="editarDatos('<? echo $cod_item; ?>', 2, frmconteo2.posicion.value)">!­­>        <a href='editar.php?conteo=<? echo $conteo; ?>&posicion=<? echo $posicion; ?>&id=<? echo $id_cuenta; ?>&coditem=<? echo $cod_item; ?>&cantidad=<? echo $cantidad2conteo; ?>'><img src='b_edit.png' border=0></a></td>     <?php            echo "</tr>";       }     ?>     </table><?php } else {

Page 72: Codigo Latino 12

?>  <div id="capaInfo" class="letratd"><b>Nombre del ITEM</b></div>  <form name="frmconteo3" method="post" action="<? $_SERVER['PHP_SELF']; ?>">   <table border="1" cellspacing="1" cellpadding="1">    <tr>     <?php if ($conteo==3){ ?><td class="letratd" align="center"><b>C&Oacute;DIGO ITEM</b></td>     <td class="letratd" align="center"><b>CANTIDAD</b></td>     <?php } elseif ($conteo==4){ ?><td class="letratd" align="center"><b>C&Oacute;DIGO BARRAS</b></td> <? } ?>     <td class="letratd" align="center"><b>POSICI&Oacute;N</b></td>    </tr>    <tr>     <?php if ($conteo==2){ ?><td class="letratd" align="center"><input type="text" id="item" name="item" value="<? echo $coditem; ?>" style="text­align:center;" size="12" maxlength="10" readonly="readonly"></td>     <td class="letratd" align="center"><input type="text" id="cantidad" name="cantidad" value="<? echo $cantidad3conteo; ?>" style="text­align:center;" size="5" maxlength="5"></td>     <?php } elseif ($conteo==4){ ?><td class="letratd" align="center"><input type="text" name="cod_barra" style="text­align:center;" size="12" maxlength="28"></td><? } ?>     <td class="letratd" align="center"><input type="text" name="posicion" style="text­align:center;" size="10" maxlength="8" value="<? echo $posicion; ?>" readonly="readonly"></td>    </tr>    <tr>     <td class="letratd" align="center" colspan="3">      <input type="hidden" name="conteo" value="<? echo $conteo; ?>">       <input type="hidden" name="id_cuenta" value="<? echo $id_cuenta; ?>">       <input type="submit" class="button" name="guardar3" value="Guardar">      </td>    </tr>   </table>  </form>   <table border="1" cellspacing="1" cellpadding="1">     <tr>       <td class="letratd" align="center" colspan="4"><b>POSICI&Oacute;N <? echo $posicion; ?></b></td>    </tr>    <tr>     <td class="letratd" align="center"><b>C&Oacute;DIGO ITEM</b></td>     <td class="letratd" align="center"><b>DESC ITEM</b></td>     <td class="letratd" align="center"><b>CANTIDAD</b></td>     <td class="letratd" align="center"><b>EDITAR</b></td>    </tr>       <?php         //SE VA A IMPRIMIR UNA TABLA CON LOS ITEMS QUE SE INDEXARON DENTRO DE LA TABLA tbinventario_conteos        //PARA EDITARLOS EN EL PANEL SUPERIOR        $query_sacar = "SELECT * FROM tbinventario_conteos WHERE posicion LIKE '".$posicion."' AND tercer != ''";        $result_sacar = mysql_query($query_sacar) or die(mysql_error());

        echo $numrows = mysql_num_rows($result_sacar);

        while ($row_sacar=mysql_fetch_array($result_sacar))        {          $id_sub = $row_sacar[0];          $cod_item = $row_sacar[1];

Page 73: Codigo Latino 12

          $query_item = "SELECT * FROM tbinventario_items WHERE código LIKE '".$cod_item."'";          $result_item = mysql_query($query_item) or die(mysql_error());

          if ($row_item=mysql_fetch_array($result_item))          {            $nombre_item = $row_item[2];          }

          $cantidad3conteo = $row_sacar[4];          echo "<tr>                  <td class='letratd' align='center'>".$cod_item."</td>                  <td class='letratd' align='center'>".$nombre_item."</td>                  <td class='letratd' align='center'>".$cantidad3conteo."</td>                  <td class='letratd' align='center'>";       ?>        <!­­<input type='button' name='editor' value='Editar' onclick="editarDatos('<? echo $cod_item; ?>', 2, frmconteo2.posicion.value)">!­­>        <a href='editar.php?conteo=<? echo $conteo; ?>&posicion=<? echo $posicion; ?>&id=<? echo $id_cuenta; ?>&coditem=<? echo $cod_item; ?>&cantidad=<? echo $cantidad3conteo; ?>'><img src='b_edit.png' border=0></a></td>       <?php              echo "</tr>";         }       ?>       </table><? } ?></div></body></html><?php  //UTILIZO EL METODO POST POR QUE EN MI UBUNTU NO ME funciona  //LA FORMA TRADICIONAL (NO S&#201; POR QU&#201; :S)  //SE VA A ACTUALIZAR LOS DATOS POR EL JEFE DE MESA  if($_POST['guardar1'])  {   $posicion = $_POST['posicion'];   $conteo = $_POST['conteo'];   $id_cuenta = $_POST['id_cuenta'];   $item = $_POST['item'];   $cantidad = $_POST['cantidad'];

   $query_upd = "UPDATE tbinventario_conteos SET primer='".$cantidad."' WHERE item_código LIKE '".$item."' AND posicion LIKE '".$posicion."'";   $result_upd = mysql_query($query_upd) or die($query_upd);

   echo "<script languaje='javascript'>       document.location.href='editar.php?conteo=".$conteo."&posicion=".$posicion."&id=".$id_cuenta."';      </script>";  }

  //SE VA A ACTUALIZAR LOS DATOS POR EL JEFE DE MESA  if($_POST['guardar2'])  {   $posicion = $_POST['posicion'];

Page 74: Codigo Latino 12

   $conteo = $_POST['conteo'];   $id_cuenta = $_POST['id_cuenta'];   $item = $_POST['item'];   $cantidad = $_POST['cantidad'];

   $query_upd = "UPDATE tbinventario_conteos SET segundo='".$cantidad."' WHERE item_código LIKE '".$item."' AND posicion LIKE '".$posicion."'";   $result_upd = mysql_query($query_upd) or die($query_upd);

   echo "<script languaje='javascript'>       document.location.href='editar.php?conteo=".$conteo."&posicion=".$posicion."&id=".$id_cuenta."';      </script>";  }

  //SE VA A ACTUALIZAR LOS DATOS POR EL JEFE DE MESA  if($_POST['guardar3'])  {   $posicion = $_POST['posicion'];   $conteo = $_POST['conteo'];   $id_cuenta = $_POST['id_cuenta'];   $item = $_POST['item'];   $cantidad = $_POST['cantidad'];

   $query_upd = "UPDATE tbinventario_conteos SET tercer='".$cantidad."' WHERE item_código LIKE '".$item."' AND posicion LIKE '".$posicion."'";   $result_upd = mysql_query($query_upd) or die($query_upd);   echo "<script languaje='javascript'>       document.location.href='editar.php?conteo=".$conteo."&posicion=".$posicion."&id=".$id_cuenta."';      </script>";  }?>

ver_items.php<?php  include 'configuration.php';  $show = $_GET['show'];  $tipo = $_GET['tipo'];?><!DOCTYPE HTML PUBLIC '­//W3C//DTD HTML 4.01 Transitional//EN'><html><head><title>Items Contados</title><meta http­equiv="Content­Type" content="text/html; charset=iso­8859­1"><!­­ PARA REFRESCAR LA PAGINA CON UN INTERVALO DE 5 SEGUNDOS !­­><meta http­equiv="refresh" content="5"><LINK REL="StyleSheet" HREF="style.css" TYPE="text/css"></head><body><?php   $query = "SELECT * FROM tbinventario_conteos ORDER BY item_código LIMIT ".$show.", 25";   $result = mysql_query($query) or die(mysql_error());?>

Page 75: Codigo Latino 12

<div align="center"><table border="1" cellspacing="1" cellpadding="1"> <tr>  <td class="letratd" align="center"><b>C&Oacute;DIGO</b></td>  <td class="letratd" align="center"><b>DESCRIPCI&Oacute;N</b></td>  <td class="letratd" align="center"><b>PRECIO</b></td>  <td class="letratd" align="center"><b>POSICI&Oacute;N</b></td>  <td class="letratd" align="center"><b>CONTEO 1</b></td>  <!­­MOSTRARA A LOS ADMINISTRADORES QUIENES HAN CONTADO ESE ITEM !­­>  <?php if($tipo==69){?><td class="letratd" align="center"><b>CONT&Oacute;</b></td><? } ?>  <td class="letratd" align="center"><b>CONTEO 2</b></td>  <?php if($tipo==69){?><td class="letratd" align="center"><b>CONT&Oacute;</b></td><? } ?>  <!­­<td class="letratd" align="center"><b>CONTEO 3</b></td>  <?php if($tipo==69){?><td class="letratd" align="center"><b>CONT&Oacute;</b></td><? } ?>!­­>  <td class="letratd" align="center"><b>SIST­UNO</b></td>  <!­­<td class="letratd" align="center"><b>CONTEOS</b></td>!­­>  <td class="letratd" align="center"><b>DIFERENCIA</b></td>  <?php if($tipo==69){?><td class="letratd" align="center"><b>COSTO UNO</b></td>  <td class="letratd" align="center"><b>COSTO CONTEO</b></td>  <td class="letratd" align="center"><b>DIFERENCIA</b></td><? } ?> </tr><?php while($row=mysql_fetch_array($result)) {  $id = $row[0];  $cod = $row[1];  $conto_primero = $row[6];  $conto_segundo = $row[7];  $conto_tercero = $row[8];

  //ME ASEGURO DE QUE HAYA DATO SINO ME ARROJA UN ERROR DE SINTAXIS SQL  if($conto_segundo!="")  {   $query_segundo = "SELECT * FROM tbinventario_users WHERE id=".$conto_segundo;    $result_segundo = mysql_query($query_segundo) or die(mysql_error());   if($row_segundo=mysql_fetch_array($result_segundo))   {    $nom1segundo = $row_segundo[4];    $nom2segundo = $row_segundo[5];    $conto_segundo = $nom1segundo."<br>".$nom2segundo;   }  }  if($conto_tercero!="")  {   $query_tercero = "SELECT * FROM tbinventario_users WHERE id=".$conto_tercero;   $result_tercero = mysql_query($query_tercero) or die(mysql_error());   if($row_tercero=mysql_fetch_array($result_tercero))   {    $nom1tercero = $row_tercero[4];    $nom2tercero = $row_tercero[5];    $conto_tercero = $nom1tercero."<br>".$nom2tercero;   }

Page 76: Codigo Latino 12

  }  //ESTE QUERY ES PARA SABER QUIEN HIZO LOS CONTEOS  $query_primero = "SELECT * FROM tbinventario_users WHERE id=".$conto_primero;  $result_primero = mysql_query($query_primero) or die(mysql_error());

  if($row_primero=mysql_fetch_array($result_primero))  {   $nom1primero = $row_primero[4];   $nom2primero = $row_primero[5];   $contaron = $nom1primero."<br>".$nom2primero;  }

  //QUERY PARA SABER LA INFORMACION DEL ITEM  $query_item = "SELECT * FROM tbinventario_items WHERE código LIKE '".$cod."'";  $result_item = mysql_query($query_item) or die(mysql_error());

  if($result_item==0)  {   echo "La consulta no arrojo datos";  }

  if($row_item=mysql_fetch_array($result_item))  {   $descripcion = $row_item[2];   $precio = $row_item[5];   $cantidadinve = $row_item[6];

   //HAGO LA SUMA DE TODAS LAS BODEGAS   $suma_inventario = $cantidadinve;  }  $posicion = $row[2];

  //QUERY PARA SABER LA POSICION DONDE SE CONTO EL ITEM  $query_posicion = "SELECT * FROM tbinventario_bodega WHERE código LIKE '".$posicion."'";  $result_posicion = mysql_query($query_posicion) or die(mysql_error());

  if($result_posicion==0)  {   echo "La consulta no arrojo datos";  }

  if($row_posicion=mysql_fetch_array($result_posicion))  {   $nombre = $row_posicion[2];  }

  $primero = $row[3];  $segundo = $row[4];  $tercero = $row[5];

  //LE QUITO LA COMA PARA PODER HACER LA SUMA DE TODAS LAS BODEGAS Y LUEGO LO MULTIPLICO POR EL PRECIO  $precio = str_replace(",", "", $precio);

Page 77: Codigo Latino 12

  $suma_conteos = $primero + $segundo + $tercero;

  //$diferencia = $suma_conteos­$suma_inventario;  $diferencia = $primero­$suma_inventario;

  //PARA NO MULTIPLICAR EL PRECIO POR 0  //PARA MULTIPLICAR EL PRECIO POR LA CANTIDAD DE LOS ITEMS DEL UNO  //if ($suma_inventario==0){ $suma_inventario = 1; }  $total_uno = 1 * $precio;   //PARA NO MULTIPLICAR EL PRECIO POR 0   //PARA MULTIPLICAR EL PRECIO POR LA CANTIDAD DE LOS ITEMS CONTADOS   if ($primero==0){ $primero = 1; }   $total_cont = $primero * $precio;

   //DIFERENCIA EN PRECIOS ENTRE EL UNO Y LOS CONTEOS   $diferencia_pre = $total_cont ­ $total_uno;

  //PARA MOSTRAR DIFERENTES TABLAS SEG&#218;N EL TIPO DE USUARIO  if($tipo==69)  {   echo '<tr>          <td class="letratd" align="center">'.$cod.'</td>          <td class="letratd">'.$descripcion.'</td>          <td class="letratd" align="right">$ '.$precio.'</td>          <td class="letratd" align="center">'.$nombre.'</td>          <td class="letratd" align="center">'.$primero.'</td>          <td class="letratd" align="center">'.$contaron.'&nbsp;</td>          <td class="letratd" align="center">'.$segundo.'&nbsp;</td>          <td class="letratd" align="center">'.$conto_segundo.'&nbsp;</td>          <td class="letratd" align="center">'.$suma_inventario.'</td>          <td class="letratd" align="center">'.$diferencia.'</td>          <td class="letratd" align="center">'.$total_uno.'</td>          <td class="letratd" align="center">'.$total_cont.'</td>          <td class="letratd" align="center">'.$diferencia_pre.'</td>';  }  else  {   echo '<tr>          <td class="letratd" align="center">'.$cod.'</td>          <td class="letratd">'.$descripcion.'</td>          <td class="letratd" align="right">$ '.$precio.'</td>          <td class="letratd" align="center">'.$nombre.'</td>          <td class="letratd" align="center">'.$primero.'</td>          <td class="letratd" align="center">'.$suma_inventario.'</td>          <td class="letratd" align="center">'.$diferencia.'</td>';  }

  echo '</tr>'; }

  //PARA HACER LA SUMA TOTAL DE UN SOLO ITEM QUE EST&#201; EN VARIOS RAK's  //Y COMPARARLO CON LO QUE HAY EN EL SISTEMA UNO  if($row1=mysql_fetch_array($result))

Page 78: Codigo Latino 12

  {   $elcódigo = $row1[1];   $query_sumitems = "SELECT SUM(primer+segundo+tercero) AS SUMA FROM tbinventario_conteos WHERE item_código LIKE '".$elcódigo."'";   $result_sumitems = mysql_query($query_sumitems) or die(mysql_error());

   if($row_sumitems=mysql_fetch_array($result_sumitems))   {    $camposuma = $row_sumitems[0];   }  }

?> <!­­ <tr>  <td class="letratd" align="right" colspan="19"><b>TOTAL GENERAL</b></td>  <td class="letratd" align="right" colspan="19"><b><? echo $TOTAL; ?></b></td> </tr> !­­></table><?php //PAGINACI&#211;N DE LOS DATOS //ACA VIENE LO WENO; NO USE LA CONSULTA ANTERIOR, //POR QUE COMO DA LIMITE 'TONS NO ME DA LOS DATOS REALES $query_saber = "SELECT * FROM tbinventario_conteos"; $result_saber = mysql_query($query_saber) or die(mysql_error());

 //EN ESTA VARIABLE SE GUARDAN LA CANTIDAD DE REGISTROS GENERADOS $numrows = mysql_num_rows($result_saber);

 $variable = $numrows/25;

 //SI ME DA CON DECIMALES LO REDONDEO AL MENOR //CON LA función floor $variable = floor($variable); $n = 0;

 //EMPIEZO A IMPRIMIR LAS PAGINAS echo '<br>'; while($n<=$variable) {  $show = '25';  if ($tipo==69)  {    echo '<a href="'.$_SERVER['PHP_SELF'].'?show='.$show*$n.'&forma=1&tipo='.$tipo.'">'.$n.'</a> ';  }  else  {    echo '<a href="'.$_SERVER['PHP_SELF'].'?show='.$show*$n.'&forma=1">'.$n.'</a> ';  }

  $n++; }?></div>

Page 79: Codigo Latino 12

</body></html>

items.php<?php  include 'configuration.php';   $TOTAL = 0;  $show = $_GET['show'];  $forma = $_GET['forma'];  //ESTOS DOS CAMPOS ES CUANDO SE HACEN B&#218;SQUEDAS CON FILTRO  $buscar = $_GET['buscar'];  $opc = $_GET['opc'];?><!DOCTYPE html PUBLIC "­//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1­transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http­equiv="Content­Type" content="text/html; charset=iso­8859­1" /><title>Items</title><LINK REL="StyleSheet" HREF="style.css" TYPE="text/css"></head><body><div align="center"><a href="<? $_SERVER['PHP_SELF'] ?>?show=0&forma=1">Ver todos</a> | <a href="javascript: window.open('search.php','','resizable=yes,scrollbars=yes,width=300,height=170,menubar=no,status=yes,top=1,left=1').focus();">  B&uacute;squeda ITEMS </a>

<?php  //SI SE ESCOGE $forma=2 SIRVE PARA HACER B&#218;SQUEDAS, CON $forma=1 SE MUESTRAN TODOS LOS ITEMS  if ($forma==2)  {    $query = "SELECT * FROM tbinventario_items WHERE";    if ($opc==1)    {      $query = $query." código LIKE '%".$buscar."%'";    }    else    {      $query = $query." nombre LIKE '%".$buscar."%'";    }

    $query = $query." LIMIT ".$show.", 25";    $result = mysql_query($query) or die(mysql_error());?><table border="1" cellspacing="1" cellpadding="1"> <tr>  <td class="letratd" align="center" colspan="5"><b>ITEM</b></td>  <td class="letratd" align="center" colspan="14"><b>BODEGA</b></td>  <td class="letratd" align="center"><b>&nbsp;</b></td> </tr> <tr>

Page 80: Codigo Latino 12

  <td class="letratd" align="center"><b>ID</b></td>  <td class="letratd" align="center"><b>C&Oacute;DIGO</b></td>  <td class="letratd" align="center"><b>DESCRIPCION</b></td>  <td class="letratd" align="center"><b>UM</b></td>  <td class="letratd" align="center"><b>COSTO</b></td>  <td class="letratd" align="center"><b>CANTIDAD</b></td>  <td class="letratd" align="center"><b>TOTAL</b></td> </tr><?php while($row=mysql_fetch_array($result)) {  $id = $row[0];  $cod = $row[1];  $nombre = $row[2];  $um = $row[4];  $precio = $row[5];  $cantidad = $row[6];

  //LE QUITO LA COMA PARA PODER HACER LA SUMA DE TODAS LAS BODEGAS Y LUEGO LO MULTIPLICO POR EL PRECIO  $precio = str_replace(",", "", $precio);

  //PARA NO MULTIPLICAR EL PRECIO POR 0  if ($suma==0){ $suma = 1; }

  $total = $cantidad * $precio;

  //HAGO LA SUMA TOTAL DE TODOS LOS ITEMS PARA SABER CUANTO NAY EN INVENTARIO        $TOTAL += $total;  echo '<tr>          <td class="letratd" align="center">'.$id.'</td>          <td class="letratd" align="center">'.$cod.'</td>          <td class="letratd">'.$nombre.'</td>          <td class="letratd" align="center">'.$um.'</td>          <td class="letratd" align="right">$ '.$precio.'</td>          <td class="letratd" align="center">'.$cantidad.'</td>          <td class="letratd" align="right">$ '.$total.'</td>        </tr>'; }?> <!­­ <tr>  <td class="letratd" align="right" colspan="19"><b>TOTAL GENERAL</b></td>  <td class="letratd" align="right" colspan="19"><b><? echo $TOTAL; ?></b></td> </tr> !­­></table><?php //ACA VIENE LO WENO; NO USE LA CONSULTA ANTERIOR, //POR QUE COMO DA LIMITE 'TONS NO ME DA LOS DATOS REALES $query_saber = "SELECT * FROM tbinventario_items WHERE"; if ($opc==1) {   $query_saber = $query_saber." código LIKE '%".$buscar."%'"; }

Page 81: Codigo Latino 12

 else {   $query_saber = $query_saber." nombre LIKE '%".$buscar."%'"; }

 $result_saber = mysql_query($query_saber) or die(mysql_error());

 //EN ESTA VARIABLE SE GUARDAN LA CANTIDAD DE REGISTROS GENERADOS $numrows = mysql_num_rows($result_saber);

 $variable = $numrows/25;

 //SI ME DA CON DECIMALES LO REDONDEO AL MENOR //CON LA función floor $variable = floor($variable); $n = 0;

 //EMPIEZO A IMPRIMIR LAS PAGINAS //echo '<br><a href="paginacion.php?show=0">0</a> '; echo '<br>'; while($n<=$variable) {  $show = '25';  echo '<a href="'.$_SERVER['PHP_SELF'].'?show='.$show*$n.'&forma=2&buscar='.$buscar.'&opc='.$opc.'">'.$n.'</a> ';  //echo '<a href="?show=&forma=2&buscar=></a>';  $n++; } } //CIERRA LA DESICION forma  //ESTO DEL PRINCIPIO NO TIENE NADA EN PARTICULAR, //SOLAMENTE UNA CONSULTA Y UNA IMPRESION DE DATOS else {  $query = "SELECT * FROM tbinventario_items LIMIT ".$show.", 25";  $result = mysql_query($query) or die(mysql_error());?><table border="1" cellspacing="1" cellpadding="1"> <tr>  <td class="letratd" align="center" colspan="3"><b>ITEM</b></td>  <td class="letratd" align="center" colspan="3"><b>BODEGA</b></td>  <td class="letratd" align="center"><b>&nbsp;</b></td> </tr> <tr>  <td class="letratd" align="center"><b>ID</b></td>  <td class="letratd" align="center"><b>C&Oacute;DIGO</b></td>  <td class="letratd" align="center"><b>DESCRIPCION</b></td>  <td class="letratd" align="center"><b>UM</b></td>  <td class="letratd" align="center"><b>COSTO</b></td>  <td class="letratd" align="center"><b>CANTIDAD</b></td>  <td class="letratd" align="center"><b>TOTAL</b></td> </tr><?php while($row=mysql_fetch_array($result))

Page 82: Codigo Latino 12

 {  $id = $row[0];  $cod = $row[1];  $nombre = $row[2];  $um = $row[4];  $precio = $row[5];  $cantidad = $row[6];

  //LE QUITO LA COMA PARA PODER HACER LA SUMA DE TODAS LAS BODEGAS Y LUEGO LO MULTIPLICO POR EL PRECIO  $precio = str_replace(",", "", $precio);

  //PARA NO MULTIPLICAR EL PRECIO POR 0  if ($suma==0){ $suma = 1; }

  $total = $cantidad * $precio;  //HAGO LA SUMA TOTAL DE TODOS LOS ITEMS PARA SABER CUANTO NAY EN INVENTARIO  $TOTAL += $total;  echo '<tr>          <td class="letratd" align="center">'.$id.'</td>          <td class="letratd" align="center">'.$cod.'</td>          <td class="letratd">'.$nombre.'</td>          <td class="letratd" align="center">'.$um.'</td>          <td class="letratd" align="right">$ '.$precio.'</td>          <td class="letratd" align="center">'.$cantidad.'</td>          <td class="letratd" align="right">$ '.$total.'</td>        </tr>'; }?> <!­­ <tr>  <td class="letratd" align="right" colspan="19"><b>TOTAL GENERAL</b></td>  <td class="letratd" align="right" colspan="19"><b><? echo $TOTAL; ?></b></td> </tr> !­­></table><?php //ACA VIENE LO WENO; NO USE LA CONSULTA ANTERIOR, //POR QUE COMO DA LIMITE 'TONS NO ME DA LOS DATOS REALES $query_saber = "SELECT * FROM tbinventario_items"; $result_saber = mysql_query($query_saber) or die(mysql_error());

 //EN ESTA VARIABLE SE GUARDAN LA CANTIDAD DE REGISTROS GENERADOS $numrows = mysql_num_rows($result_saber);

 $variable = $numrows/25;

 //SI ME DA CON DECIMALES LO REDONDEO AL MENOR //CON LA función floor $variable = floor($variable); $n = 0;

 //EMPIEZO A IMPRIMIR LAS PAGINAS //echo '<br><a href="paginacion.php?show=0">0</a> ';

Page 83: Codigo Latino 12

 echo '<br>'; while($n<=$variable) {  $show = '25';  echo '<a href="'.$_SERVER['PHP_SELF'].'?show='.$show*$n.'&forma=1">'.$n.'</a> ';

   $n++; }}//CIERRA LA DECISION forma?> </div></body></html>

search.php<!DOCTYPE html PUBLIC "­//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1­transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http­equiv="Content­Type" content="text/html; charset=iso­8859­1" /><title>B&uacute;squeda de ITEMS</title><LINK REL="StyleSheet" HREF="style.css" TYPE="text/css"></head><body><form name="busqueda" action="<? $_SERVER['PHP_SELF'] ?>" method="post"><table border="1" cellspacing="1" cellpadding="1"> <tr>  <td class="letratd" align="center" colspan="2"><b>B&Uacute;SQUEDA DE ITEMS</b></td> </tr> <tr>  <td class="letratd" align="center">         <select name="opc">          <option value="1">C&oacute;digo</option>                <option value="2">Nombre</option>         </select>  </td>  <td class="letratd" align="center"><input type="text" name="buscar"></td> </tr> <tr>   <td class="letratd" align="center" colspan="2">   <input class="boton" type="submit" name="mostrar" value="Buscar"> </td> </tr></table></form></body></html><?php if ($_POST['mostrar']) {   $buscar = $_POST['buscar'];   $opc = $_POST['opc'];   echo "<script languaje='JavaScript'>

Page 84: Codigo Latino 12

                   window.close();                         window.opener.location.href='items.php?show=0&forma=2&buscar=".$buscar."&opc=".$opc."'                 </script>"; }?>

En mi blog dejo un video de cómo funciona la aplicación; recuerden que funciona al full con códigos de barras y un lector omnidireccional.

El   software  completo   lo  dejo  en  SoloCodigo  Código  Fuente  para  que  puedan  descargarlo   funcionando, revisen mi blog para cualquier duda.Descarga acá

Page 85: Codigo Latino 12

Código Latino es posible gracias a:

Sigan con el curso de Python que está realizando

Esperamos sus comentarios, códigos y artículos para la próxima entrega, esta es una revista de todos y para todos.Pueden escribirnos a [email protected] con Google Group http://groups.google.com/group/codigolatinoVisita nuestro Blog para más información: http://revistacodigolatino.blogspot.com

Hasta una próxima entrega.Chao