Documentos de Académico
Documentos de Profesional
Documentos de Cultura
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.
● 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)
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 EntryPoint 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 runtime 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
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_funcs1;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
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( ["sectionname"[, "sectionclass"] ] )
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++, preterminadores 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);
#pragma data_seg(".CRT$XPA")
PFV __xp_a = 0; /* C preterminators */
#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 preterminators */
//__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);
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;
}
}
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>
//entorno
extern "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ámetros
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);
#pragma data_seg(".CRT$XPA")
PFV __xp_a = 0; /* C preterminators */
#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 preterminators */
//__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);
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);
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]);
_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
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.
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 Identidad
A 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 ApplicationIIdentity
End Class
en la linea siguiente de public class ApplicationIIdentity escribiremos la siguiente linea:
Implements System.Security.Principal.IIdentity
y 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:
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 Property
End 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 String
Private authenticatedValue As Boolean
Private roleValue As ApplicationServices.BuiltInRole
en 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 authenticatedValue
esta 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 nameValue
En 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 Get
End Property
Cabe 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
Else
nameValue = ""
authenticatedValue = False
roleValue = ApplicationServices.BuiltInRole.Guest
End If
End Sub
En 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 = storedHashedPW
End Function
Ahora 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 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 Function
Hasta 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)
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 Function
End 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 linea
Public Class ApplicationIPrincipal:
Implements System.Security.Principal.IPrincipal
al 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 ApplicationIIdentity
Luego, en la propiedad Identity agregamos el siguiente código:
Return identityValue
y en el método IsInRole agregamos el siguiente código:
Return role = identityValue.Role.ToString
Ahora crearemos el constructor de la clase, el cual inicializa la clase con una instancia de
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 Sub
aca establecemos la identidad del usuario haciendo uso de la clase ApplicationIIdentity.
El código de la clase
ApplicationIPrincipal 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 Sub
End 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 If
End 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.
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.Name
Else
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
Sistemas Operativos
Manejador de Procesos (Primera parte) Fundamentos
Por JuanK http://juank.blackbyte.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.
• Planificador de procesos
• Administrador de memoria
• Manejador de E/S (como mínimo con controladores para video, teclado y disco)
• Sistema de archivos
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 CPU
La 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:
mov AX, 2 ; poner el número 2 en el registro AX
add AX, 3 ;sumar al contenido de AX el valor 3, la respuesta queda en AX
veamos 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 procesos
Sistemas Operativos Monotarea
La 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?,
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 monoproceso , 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 Multitarea
Como 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 Proceso
Al 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
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 Proceso
Ya 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:
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:
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
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.
CHECMATED es un excelente programador del foro codemakers maneja muy bien Python y es uno de los
moderadores más queridos del foro; acá les dejo la entrevista que nos concedió.
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,
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
TacToe (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.
DATA: T_PLAYS TYPE STANDARD TABLE OF TY_PLAYS.
FIELDSYMBOLS: <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.
**
* STARTOFSELECTION *
**
STARTOFSELECTION.
FLAG = '1'.
SET PFSTATUS '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.
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 SYSUBRC 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'.
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'.
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'.
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 USERCOMMAND *
**
AT USERCOMMAND.
IF SYUCOMM EQ 'BACK'.
SET SCREEN 0.
LEAVE PROGRAM.
ELSE.
IF WIN_FLAG EQ SPACE.
IF FLAG = '1'.
PLAYER_ONE = SYLISEL+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'.
FLAG = '1'.
ENDIF.
ENDIF.
ENDIF.
ENDIF.
Espero que les guste y si pueden, mejorenlo :)
Saludos,
Blag.
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 systems
WinWaitActive("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.
Estoy creando un diccionario inglesespanol 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 prueba
Send("{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")
Exit
EndIf
While 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")
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!
Incluir documentos HTML o datos Complejos
Por 100% Telch
Vamos a aprender a incluir documentos HTML o datos complejos, con el HtmlTemplate 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 HTMLTemplate, 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>
Mi archivo de Perl:
#!c:/perl/bin/perl
use 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>
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 enviado
my $buffer = $ENV{'QUERY_STRING'};
my @pairs = split(/&/, $buffer);
foreach my $pair (@pairs) {
my ($name, $value) = split(/=/, $pair);
$name =~ tr/+/ /;
$name =~ s/%([afAF09][afAF09])/pack("C", hex($1))/eg;
$value =~ tr/+/ /;
$value =~ s/%([afAF09][afAF09])/pack("C", hex($1))/eg;
$dato{$name} = $value;
};
# función para desplegar un f ichero html
sub 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 plantilla
my $template = HTML::Template>new(filename => $plantilla);
$template>param(contenido => $include );
$template>param(menu => \@menu );
print "ContentType: text/html\n\n", $template>output;
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 HTMLTemplate.
Con las siguientes líneas decodificamos el Query envíado
my(%dato); #Iniciamos el hash
#Leemos el query enviado
my $buffer = $ENV{'QUERY_STRING'};
my @pairs = split(/&/, $buffer);
foreach my $pair (@pairs) {
my ($name, $value) = split(/=/, $pair);
$name =~ tr/+/ /;
$name =~ s/%([afAF09][afAF09])/pack("C", hex($1))/eg;
$value =~ tr/+/ /;
$value =~ s/%([afAF09][afAF09])/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 html
sub 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
{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
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 plantilla
my $template = HTML::Template>new(filename => $plantilla);
$template>param(contenido => $include );
$template>param(menu => \@menu );
print "ContentType: 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.
Daniel Bermudez es un Colombiano igual que yo y administrador del espectacular foro aprenderpython,
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 9) ¿Que te gustaría ver en los próximos años en el
mundo de la programación?
2) ¿Hace cuánto que comenzaste a programar? Un lenguaje de programacion totalmente en Español.
Hace 2 años aproximadamente.
10) ¿Cuál es tu mensaje final para la comunidad?
3) ¿Cuáles son tus lenguajes de programación Como lo dijo alguien: Ignorante no es el que no sabe
favoritos? leer, sino el que sabiendo leer no lee.
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.
Software para captura de inventarios
Por 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.
Esta obra está bajo Licencia AtribuciónNo 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`)
);
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`)
);
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 httpequiv="ContentType" content="text/html; charset=iso88591">
<! PARA REFRESCAR LA PÁGINA CON UN INTERVALO DE 60 SEGUNDOS !>
<meta httpequiv="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];
}
?>
<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ó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ó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; ?
>','','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ó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 '.
$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))
{
$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">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta httpequiv="ContentType" content="text/html; charset=iso88591" />
<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ÓN</b></td>
</tr>
<tr>
<td class="letratd" align="center"><input type="text" name="posicion" style="textalign: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 || $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ÓN</b></td>
</tr>
<tr>
<td class="letratd" align="center"><input type="text" name="posicion" style="textalign: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ÓN</b></td>
</tr>
<tr>
<td class="letratd" align="center"><input type="text" name="posicion" style="textalign: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="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
transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta httpequiv="ContentType" content="text/html; charset=iso88591" />
<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Ó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Ó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ÓDIGO BARRAS</b></td> <? } ?>
<td class="letratd" align="center"><b>POSICIÓ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="textalign:center;" size="12" maxlength="10" <? if ($numrows==0){ echo
'disabled';} ?>></td>
<td class="letratd" align="center"><input type="text" name="cantidad" style="textalign: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="textalign:center;" size="12" maxlength="28" <? if
($numrows==0){ echo 'disabled';} ?>></td><? } ?>
<td class="letratd" align="center"><input type="text" name="posicion" style="textalign: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ÓN <? echo $posicion; ?></b></td>
</tr>
<tr>
<td class="letratd" align="center"><b>CÓ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; ?
>","","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Ó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ÓDIGO BARRAS</b></td> <? } ?>
<td class="letratd" align="center"><b>POSICIÓ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="textalign:center;" size="12" maxlength="10"></td>
<td class="letratd" align="center"><input type="text" name="cantidad" style="textalign:center;" size="5"
maxlength="5"></td>
<?php } elseif ($conteo==5){ ?>
<td class="letratd" align="center"><input type="text" name="cantidad" style="textalign:center;" size="5"
maxlength="5"></td>
<td class="letratd" align="center"><input type="text" name="item" style="textalign:center;" size="12"
maxlength="28"></td><? } ?>
<td class="letratd" align="center"><input type="text" name="posicion" style="textalign: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ÓN <? echo $posicion; ?></b></td>
</tr>
<tr>
<td class="letratd" align="center"><b>CÓ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; ?
>","","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Ó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>
<td class="letratd" align="center"><b>CÓDIGO BARRAS</b></td> <? } ?>
<td class="letratd" align="center"><b>POSICIÓ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="textalign:center;" size="12" maxlength="10"></td>
<td class="letratd" align="center"><input type="text" name="cantidad" style="textalign:center;" size="5"
maxlength="5"></td>
<?php } elseif ($conteo==6){ ?>
<td class="letratd" align="center"><input type="text" name="cantidad" style="textalign:center;" size="5"
maxlength="5"></td>
<td class="letratd" align="center"><input type="text" name="item" style="textalign:center;" size="12"
maxlength="28"></td><? } ?>
<td class="letratd" align="center"><input type="text" name="posicion" style="textalign: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ÓN <? echo $posicion; ?></b></td>
</tr>
<tr>
<td class="letratd" align="center"><b>CÓ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; ?
>","","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."'
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É POR QUÉ :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."', '".
$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());
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());
}
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."'";
$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 httpequiv="ContentType" content="text/html; charset=iso88591" />
<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ÓN</b></td>
</tr>
<tr>
<td class="letratd" align="center"><input type="text" name="posicion" style="textalign: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ÓN</b></td>
</tr>
<tr>
<td class="letratd" align="center"><input type="text" name="posicion" style="textalign: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ÓN</b></td>
</tr>
<tr>
<td class="letratd" align="center"><input type="text" name="posicion" style="textalign: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="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 httpequiv="ContentType" content="text/html; charset=iso88591" />
<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)
{
?>
<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ÓDIGO ITEM</b></td>
<td class="letratd" align="center"><b>CANTIDAD</b></td>
<?php } elseif ($conteo==4){ ?><td class="letratd" align="center"><b>CÓDIGO BARRAS</b></td> <? } ?>
<td class="letratd" align="center"><b>POSICIÓ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="textalign:center;" size="12" maxlength="10" readonly="readonly"></td>
<td class="letratd" align="center"><input type="text" id="cantidad" name="cantidad" value="<? echo $cantidad1conteo; ?>"
style="textalign: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="textalign: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ÓN <? echo $posicion; ?></b></td>
</tr>
<tr>
<td class="letratd" align="center"><b>CÓ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());
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ÓDIGO ITEM</b></td>
<td class="letratd" align="center"><b>CANTIDAD</b></td>
<?php } elseif ($conteo==4){ ?><td class="letratd" align="center"><b>CÓDIGO BARRAS</b></td> <? } ?>
<td class="letratd" align="center"><b>POSICIÓ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="textalign:center;" size="12" maxlength="10" readonly="readonly"></td>
<td class="letratd" align="center"><input type="text" id="cantidad" name="cantidad" value="<? echo $cantidad2conteo; ?>"
style="textalign: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="textalign: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>
</tr>
</table>
</form>
<table border="1" cellspacing="1" cellpadding="1">
<tr>
<td class="letratd" align="center" colspan="4"><b>POSICIÓN <? echo $posicion; ?></b></td>
</tr>
<tr>
<td class="letratd" align="center"><b>CÓ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
{
?>
<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ÓDIGO ITEM</b></td>
<td class="letratd" align="center"><b>CANTIDAD</b></td>
<?php } elseif ($conteo==4){ ?><td class="letratd" align="center"><b>CÓDIGO BARRAS</b></td> <? } ?>
<td class="letratd" align="center"><b>POSICIÓ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="textalign:center;" size="12" maxlength="10" readonly="readonly"></td>
<td class="letratd" align="center"><input type="text" id="cantidad" name="cantidad" value="<? echo $cantidad3conteo; ?>"
style="textalign: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="textalign: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ÓN <? echo $posicion; ?></b></td>
</tr>
<tr>
<td class="letratd" align="center"><b>CÓ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];
$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É POR QUÉ :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'];
$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 httpequiv="ContentType" content="text/html; charset=iso88591">
<! PARA REFRESCAR LA PAGINA CON UN INTERVALO DE 5 SEGUNDOS !>
<meta httpequiv="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());
?>
<div align="center">
<table border="1" cellspacing="1" cellpadding="1">
<tr>
<td class="letratd" align="center"><b>CÓDIGO</b></td>
<td class="letratd" align="center"><b>DESCRIPCIÓN</b></td>
<td class="letratd" align="center"><b>PRECIO</b></td>
<td class="letratd" align="center"><b>POSICIÓ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Ó</b></td><? } ?>
<td class="letratd" align="center"><b>CONTEO 2</b></td>
<?php if($tipo==69){?><td class="letratd" align="center"><b>CONTÓ</b></td><? } ?>
<!<td class="letratd" align="center"><b>CONTEO 3</b></td>
<?php if($tipo==69){?><td class="letratd" align="center"><b>CONTÓ</b></td><? } ?>!>
<td class="letratd" align="center"><b>SISTUNO</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;
}
}
//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);
$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Ú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.' </td>
<td class="letratd" align="center">'.$segundo.' </td>
<td class="letratd" align="center">'.$conto_segundo.' </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É EN VARIOS RAK's
//Y COMPARARLO CON LO QUE HAY EN EL SISTEMA UNO
if($row1=mysql_fetch_array($result))
{
$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Ó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>
</body>
</html>
items.php
<?php
include 'configuration.php';
$TOTAL = 0;
$show = $_GET['show'];
$forma = $_GET['forma'];
//ESTOS DOS CAMPOS ES CUANDO SE HACEN BÚ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 httpequiv="ContentType" content="text/html; charset=iso88591" />
<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úsqueda ITEMS
</a>
<?php
//SI SE ESCOGE $forma=2 SIRVE PARA HACER BÚ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> </b></td>
</tr>
<tr>
<td class="letratd" align="center"><b>ID</b></td>
<td class="letratd" align="center"><b>CÓ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."%'";
}
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> </b></td>
</tr>
<tr>
<td class="letratd" align="center"><b>ID</b></td>
<td class="letratd" align="center"><b>CÓ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";
$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=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 httpequiv="ContentType" content="text/html; charset=iso88591" />
<title>Bú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ÚSQUEDA DE ITEMS</b></td>
</tr>
<tr>
<td class="letratd" align="center">
<select name="opc">
<option value="1">Có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'>
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á
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 willian.radicaled@gmail.com
Unetenos con Google Group http://groups.google.com/group/codigolatino
Visita nuestro Blog para más información: http://revistacodigolatino.blogspot.com
Hasta una próxima entrega.
Chao