
Programa de gestión desde 0 (Activo)
#1
Escrito 06 junio 2013 - 12:45
#2
Escrito 06 junio 2013 - 03:33

el programa se llama Ibeasy+ y lo podéis bajar de http://ibeasy.software.informer.com/.
Ahora que creo quede más claro mi idea de uso de las tablas modulares (no si sera correcto), paso a explicar un par de términos y su uso básico, para que luego al usarlos estén un pocos más claros.
Stock: Creo que es el más común y se refiere a la cantidad de mercancía que tenemos disponible
ADR: Se refiere al transporte de mercancía por carretera y una gran cantidad de países se han acogido al sistema, es obligatorio en los países de la comunidad europea y en todos los acogidos a este sistema. El llevar mercancías que necesitan ADR y no llevarlo conlleva severas multas al conductor y a la empresa, e incluso in movilización del vehículo y la mercancías. para más información
http://es.wikipedia....s_por_carretera
Trazabilidad: Este es el punto más peliagudo, la mayor parte de la gente cree, que sólo es obligatorio a los productos comestibles, pero realmente hay que aplicarla a otros muchos sectores, como todos los derivados de los químicos, manufacturados, alimentación, agricultura, residuales, Nucleares y un largo etc.
Hay que tener en cuenta que la trazabilidad es desde la creación del producto (inclusive anterior de los proveedores) hasta el consumidor final (quedando exento en este punto supermercados, tiendas y pocos más al no tener un control exacto de a quién se le ha vendido la mercancía) la trazabilidad viene controlada por lo que se llaman seriales, lotes, etc e implica que toda una producción hecha o creada (Artificial o naturalmente) tenga un mismo número de registro, asignando el número de registro (lote) la cantidad/formato de producto sacado, aunque el (lote) no varia hay que especificar cantidad lote, pongo un ejemplo:
Hacemos 1000 Litros de lavavajillas lote 130001 y sacamos en los siguientes formatos
Lote................Cantidad.............Formato...............Total Litros
--------------------------------------------------------------
130001............20.....................Garrafas 25 L.........500 L.
130001............80.....................Garrafas 5 L...........400 L.
130001............100...................Botellas 1 L............100 L.
Esto obliga a tener controlado las ordenes de producción y al control de la trazabilidad de los 1000 Litros del lote 130001, mediante partes de rotura, utilización interna, en fabricación uso como materias primas o re conversión y por supuesto ventas (albaranes, facturas, etc.)
Hay que usar el sistema de recursividad, con la trazabilidad, al igual que con el Stock, es decir si eliminamos una factura, cambiamos la cantidad a menos o nos devuelven una mercancía. eta debe ser controlada tanto en el stock como en su control de lotes.
La trazabilidad permite a los organismos públicos, en contacto con las empresas a tener controlado todo el proceso de una mercancía, aunque se hay trasformado en otra, desde su origen al consumidor final (hipotéticamente), el responsable del problema pagará una multa, pero si alguna de las partes no tiene la trazabilidad, la multa puede ser mucho mayor y si se produjesen muertes o lesiones graves, puede llevar incluso a prisión, en caso de tenerla controlada, esto muy difícilmente ocurriría, salvo que seamos los responsables.
Y por último, es muy frecuente que tengamos que controlar junto con la trazabilidad la caducidad, ya que muchos productos, alimentarios, químicos, etc, tiene caducidad.
Para más información podéis dirigiros a http://es.wikipedia....ki/Trazabilidad
Ley de Protección de Datos (LPD): Esta ley obliga a todas las empresas que controlen cual quier tipo de datos de clientes, proveedores, etc. a tener contratado una empresa gestora de dicha ley, esto obliga al texto que deben aparecer, en emails, facturas y demás documentos y aplicarla a nuestro programa es bastante simple, se trata de tener 2 o 3 memos, que su texto se pueda editar y guardar, para posibles cambios futuros y que aparezcan en nuestros documentos físicos como digitales. aparte de esto, obliga a que el cliente si así lo pide, no sea puesto en listados de ningún tipo, e incluso sea borrada su información, pero tener cuidado, por que hacienda esta por encima de esta Ley y si borráis, datos antes del cierre con hacienda y no aparecen los datos del cliente podéis tener un grabe problema. Las multas por no tener este sistema aplicado van desde los 6.000 euros a los 600.000 o el cierre de la empresa con posibilidad de prisión.
Para más información ir a http://noticias.juri.../lo15-1999.html
Lotes: Así es como voy a denominar el control identificativo de nuestra trazabilidad. Los lotes pueden tener derivados, pudiendo ser padres e hijos, o maestros y esclavos. Quiero decir que de un producto con un lote se puede vender en varios productos diferentes, si haber alteración, cada producto tendrá un lote pero tenemos que tener controlado de que lo te viene. Ejemplo:
Hacemos un Desengrasante base lote 130002 de este embotellamos una parte como limpia suelos desengrasante u otro artículo y a este último le asignarnos el lote 130003, quedando de la siguiente manera
Lote Padre <> Lote Hijo
130002...........130003 (este realmente es un derivado sin modificación del lote 130002 y cuando pidamos un informe del lote 130002 debe darnos la información del lote 130003, para tener la trazabilidad correcta e igualmente pero al revés si la solicitamos del 130003.
Ordenes de producción: Esto implica el proceso para la creación del lote con el producto fabricable (no confundir con el producto final), implica el operario, lote y formatos y cantidades.
Diferencias entre un producto fabricable y el producto final: El producto fabricable, es el producto que vamos a fabricar y el producto final es el producto ya en su formato. Ejemplo
Producto Fabricable: Lavavajillas producto finales , Lavavajillas 5L, Lavavajillas 25L, Lavavajillas 1L , Lavavajillas a granel, etc.
Estos conceptos deben quedar muy claros, ya que si no es fácil perderse más adelante, así que si tenéis dudas, preguntar ahora antes de seguir, y por supuesto, los que no sois de España, debéis informaros de las leyes en vuestro país. Pero la mayoría de programas no tiene estos conceptos que algunos de ellos son obligatorios hace más de una década.
#3
Escrito 07 junio 2013 - 03:17
Estructura de la base de datos
CREATE TABLE ARTICULOS (
ID INTEGER NOT NULL,
CODIGO T20 /* T20 = VARCHAR(20) */, //Código del artículo
PRODUCTO T80 /* T80 = VARCHAR(80) */, //Nombre del producto
COSTE POR /* POR = NUMERIC(15,4) */, //Coste del producto
CODIGOPROVEEDOR T20 /* T20 = VARCHAR(20) */, //Código del proveedor
PV1 POR /* POR = NUMERIC(15,4) */, //Precio de venta tarifa 1
PV2 POR /* POR = NUMERIC(15,4) */, //Precio de venta tarifa 2
PV3 POR /* POR = NUMERIC(15,4) */, //Precio de venta tarifa 3
PV4 POR /* POR = NUMERIC(15,4) */, //Precio de venta tarifa 4
PV5 POR /* POR = NUMERIC(15,4) */, //Precio de venta tarifa 5
DTO1 POR /* POR = NUMERIC(15,4) */, //Descuento de venta tarifa 1
DTO2 POR /* POR = NUMERIC(15,4) */, //Descuento de venta tarifa 2
DTO3 POR /* POR = NUMERIC(15,4) */, //Descuento de venta tarifa 3
DTO4 POR /* POR = NUMERIC(15,4) */, //Descuento de venta tarifa 4
DTO5 POR /* POR = NUMERIC(15,4) */, //Descuento de venta tarifa 5
FAMILIA T20 /* T20 = VARCHAR(20) */, //Familia del artículo
CODIGOBARRAS39 T20 /* T20 = VARCHAR(20) */, //Código de barras libre
CODIGOBARRASEAN13 T20 /* T20 = VARCHAR(20) */, //Códigos de barra estándar Ean 13
PESO POR /* POR = NUMERIC(15,4) */, //Peso del formato del producto
PROPIO LOG /* LOG = CHAR(1) */, //Si es un artículo de fabricación propia
TRAZABILIDAD LOG /* LOG = CHAR(1) */, //Si lleva trazabilidad
SERVICIO LOG /* LOG = CHAR(1) */, //Si es un servicio
CADUCO LOG /* LOG = CHAR(1) */, //Si el artículo es caduco (se lleva la caducidad con el lote
TIPOIMPUESTO INTEGER, //Tipo de aimpuesto aplicable (va con el nombre del impuesto en configuración)
COMISIONMAXIMA POR /* POR = NUMERIC(15,4) */, //Comisión máxima a pagar en este artículo, prevalece sobre la comisión en el agente
DTOMAXIMO POR /* POR = NUMERIC(15,4) */, //Descuento máximo del artículo (prevalece sobre los descuentos en clientes o aplicados en DTO1...DTO5)
RAPEL1 INTEGER, //Rapel de ventas en tarifa 1
RAPEL2 INTEGER, //Rapel de ventas en tarifa 2
RAPEL3 INTEGER, //Rapel de ventas en tarifa 3
RAPEL4 INTEGER, //Rapel de ventas en tarifa 4
RAPEL5 INTEGER, //Rapel de ventas en tarifa 5
ADR VARCHAR(150) CHARACTER SET NONE, //Descripción de la frase de adr
ADREXEPCION INTEGER, // formatos que estan exentos del adr según el propio ADR
ADRLIMITE INTEGER //Limite de mercancía a transportar por un conductor y vehículo sin el carnet y permiso de mercancías peligrosas
);
Rapel: Los clientes que se les hace descuento por rapel, deben hacerles albaranes, unificando a la hora de facturar, la mercancía por código, de manera que si el total de unidades vendidas es igual o superior al rapel de su tarifa se aplica el precio de esta tarifa, en caso contrario se aplica el PVP normal.
Escala de Rapel: Es cuando el cliente parte de un precio normal y según sus ventas finales a la hora de facturar se aplica la tarifa según el rapel alcanzado (no lo he usado nunca y nunca me lo han pedido)
Ahora la tabla NOTAS
CREATE TABLE NOTAS (
ID INTEGER NOT NULL,
NOMBREMODULO T20 /* T20 = VARCHAR(20) */, //Nombre del módulo
CODIGO T20 /* T20 = VARCHAR(20) */, //Código del módulo al que pertenece
DESCRIPCION T20 /* T20 = VARCHAR(20) */, //Descripción dentro del modulo, (Avisos, Notas, Alertas,etc.)
NOTAS MEMO /* MEMO = BLOB SUB_TYPE 1 SEGMENT SIZE 80 */ //Campo memo para notas
);
Y por último La tabla imágenes
CREATE TABLE IMAGENES (
ID INTEGER NOT NULL,
NOMBREMODULO T20 /* T20 = VARCHAR(20) */, //Nombre del módulo
CODIGO T20 /* T20 = VARCHAR(20) */, //Código del módulo al que pertenece
DESCRIPCION T20 /* T20 = VARCHAR(20) */, //Descripción dentro del modulo, (Foto, interior, exterior, detalle, etc.)
IMAGENES IMG /* IMG = BLOB SUB_TYPE 0 SEGMENT SIZE 80 */ //Imagen a mostrar
);
#4
Escrito 07 junio 2013 - 09:46
#5
Escrito 07 junio 2013 - 04:06
Primero veréis que hay datos tachados, por que lo que os muestro son con información real y hay que respetar la protección de datos, así que pido disculpas, aun así creo que queda bastante claro
Para empezar una imagen del tema de los lotes

Como podéis ver marco en rojo el lote del producto que buscamos, en verde sería el maestro (en este caso es el mismo que hemos introducido) y en naranja el lote derivado que vemos que es el 120402, se puede dar el caso que el lote 120401, tenga el derivado que tenga, pero también tenga un maestro que pueda ser por ejemplo el 120399.
Ya que hablo de mi antiguo programa, que por cierto este que empiezo nuevo es por hacerlo más sencillo y eficaz, os pongo una imagen de un proceso que más abajo os explico.
[img width=500 height=600]http://nsae01.casimages.net/img/2013/06/08/130608120642801849.jpg[/img]
como podéis ver se trata de la edición de Facturas, con datos reales, os pongo imagen del menú, del visor de documentos (presupuestos, pedidos, albaranes y facturas), del editor de documentos y por último el editor de artículos, que contiene aparte de la información habitual, contiene lotes disponible (La única condición será que 1º el stock disponibles sea igual o superior a 1 y 2º que la fecha de caducidad sea inferior a la actual), por supuesto esto lo veis en el apartado llamado lotes y vencimientos, después del Stringrid hay una última linea que nos permite introducir un lote de forma manual (Se da en más de una ocasión, de que aun no hemos dado la entrada de la mercancía y tengamos que facturarla))
Por otro lado en el apartado precios veréis algo que es muy poco común, por un lado 5 tarifas de precios (esto es normal) y por otro precio especial del cliente, esto si os dais cuenta no esta en la estructura ni de clientes, ni en la de artículos, si no que esta en una tabla independiente y para que se muestre debe darse las siguientes condiciones el código del cliente y el del artículo, pero ya lo veremos mucho más adelante.
Por cierto algo que es muy posible que en breve sea obligatorio en la facturación y demás documentos de ventas, es que deben tener el peso por artículos, el total de la factura y una hoja de ruta detallando la factura, peso total de la misma y peso total de mercancía transportada. Pero aún no es obligatorio.
#6
Escrito 08 junio 2013 - 03:03
debe quedar de la siguiente manera:
[DELPHI]procedure TFBancos.DSPrincipalDataChange(Sender: TObject; Field: TField);
//------------------------------------------------------------------------------
//******************************************************[ Datasorce change ]****
//------------------------------------------------------------------------------
begin
if (not (DsPrincipal.DataSet.State in [dsEdit,dsInsert])) and (FBancos.Active) then
begin
Label12.Caption :=ceros(DBEdit5.Text,4)+'/'+ ceros(DBEdit6.Text,4)+'/'+ceros(DBEdit7.Text,2)+'/'+ceros(DBEdit8.Text,10);
end;
end;[/DELPHI]
y
[DELPHI]procedure TFBancos.DBEdit5Change(Sender: TObject);
//------------------------------------------------------------------------------
//********************************************************[ Change Dbedit5 ]****
// Comprueba el digíto de control
//------------------------------------------------------------------------------
begin
TDBEdit(Sender).Text:=EditLogico(tedit(TDBEdit(Sender)), '0123456789');
if (DBEdit5.Text<>'') and (DBEdit6.Text<>'') and (DBEdit8.Text<>'') and (FBancos.Active) then
begin
DBEdit7.Field.Value:=StrToInt( IntToStr(CalculaDC(ceros(DBEdit5.Text,4)+ ceros(DBEdit6.Text,4),ceros(DBEdit8.Text,10))));
end;
Label12.Caption :=ceros(DBEdit5.Text,4)+'/'+ ceros(DBEdit6.Text,4)+'/'+ceros(DBEdit7.Text,2)+'/'+ceros(DBEdit8.Text,10);
if (Length(DBEdit5.Text)>=4) and (Sender=DBEdit5) then DBEdit6.SetFocus;
if (Length(DBEdit6.Text)>=4) and (Sender=DBEdit6) then DBEdit8.SetFocus;
end;[/DELPHI]
Como podéis comprobar me faltaba en ambos casos and (FBancos.Active) para evitar que cargue datos sin estar activo
#7
Escrito 09 junio 2013 - 07:16
Vamos ahora con artículos
Como siempre la imagen

Como podéis ver no pongo la pestaña facturado, ya que aún no tenemos preparado la facturación y como en todos el código que llevo puesto, no pondré el código de impresión, por que al tener múltiples operadores a la hora de imprimir, que cada uno use y diseñe el que le gusta.
El código https://gist.github....onymous/5743472
Funciones usada de mi archivo fun_dbgrid.pas
[DELPHI]
function GridImagen(Grid:TDBGrid; Campo:TField; Rect:TRect; Column:TColumn; State:TGridDrawState):Boolean;
begin
if Column.Field = Campo then
begin
if not (gdSelected in State) then // se não for a célula selecionada
Grid.Canvas.FillRect(Rect); // limpa a célula
with TPicture.Create do
begin
Assign(Campo);
Grid.Canvas.StretchDraw(Rect,Bitmap); // desenha imagem
Free;
end;
Result:=True;
end else Result:=False;
end;
function MemoGridB(Grid:TDBGrid; Campo:TField; Rect:TRect; Column:TColumn; State:TGridDrawState):Boolean;
var FixRect:TRect;
begin
fixRect:=Rect; // declara uma variável local fixRect : TRect
Dec(fixRect.Bottom,2);
if Column.Field=Campo then
begin
if not (gdSelected in State) then
Grid.Canvas.FillRect(Rect);
DrawText(Grid.Canvas.Handle,pchar(Campo.AsString), length(campo.AsString),fixRect,DT_WORDBREAK);
Result:=True;
end else Result:=False;
end;
[/DELPHI]
#8
Escrito 09 junio 2013 - 07:21

tengo un pequeño error en este módulo que aún no he encontrado, que es que no muestra las imágenes de los botones y no se si tendré que rehacerlo, pero la ida esta hay y los botones son los de siempre y el código no varia.
el código https://gist.github....onymous/5743504
y de este apartado nada más
#9
Escrito 09 junio 2013 - 07:33

el código https://gist.github....onymous/5743525
Aquí si hay un cambio importante en el botón de cargar imagen, yo ya he hecho el cambio en el resto de los módulos, el código queda de la siguiente manera
[DELPHI]procedure TFImagenes.SpeedButtonBC1Click(Sender: TObject);
//------------------------------------------------------------------------------
//*********************************************************[ Cargar imagen ]****
//------------------------------------------------------------------------------
begin
CargaIimagenADBImagen(OpenPictureDialog1,DBImage1);
end;[/DELPHI]
y la función es
[DELPHI]//------------------------------------------------------------------------------
//*************************************************[ CargaIimagenADBImagen ]****
// Parte de la idea original de ??? 09/06/2013
// bajada de http://www.planetade...a-um-campo-blob
//------------------------------------------------------------------------------
// Pequeñas modificaciones y convertido a unción por mi permitiendo cargar varios
// tipos de imágenes diferentes
//------------------------------------------------------------------------------
// [Dialog] TOpenPictureDialog Dialogo de cargad de la imagen
// [Dbimage] TDBImage El nº de cuenta de 10 digitos usar la funcion ceros
//------------------------------------------------------------------------------
//---EJEMPLO--------------------------------------------------------------------
// CargaIimagenADBImagen:(OpenPictureDialog1,Dbimage1);
//------------------------------------------------------------------------------
function CargaIimagenADBImagen(Dialog:TOpenPictureDialog;Dbimage:TDBImage):Boolean;
var imagem : TPicture;
begin
if Dialog.Execute then
begin
try
imagem:=TPicture.Create;
imagem.LoadFromFile(Dialog.FileName);
Clipboard.Assign(imagem);
Dbimage.PasteFromClipboard;
imagem.Free;
Result:=True;
except on E: Exception do
Result:=False;
end;
end;
end;[/DELPHI]
También se realizaron cambios en mi módulo de datos (DM.pas) el código añadido es el siguiente
[DELPHI]
uses Fun;
....
procedure TDM.DataModuleDestroy(Sender: TObject);
//------------------------------------------------------------------------------
//*********************************************************[ Al destruirlo ]****
// Nos aseguramos de que no se nos queden Querys abiertos //Añadir el archivo Fun.Pas
//------------------------------------------------------------------------------
begin
QuerryOC(IBQIMAGENES);
QuerryOC(IBQNOTAS);
end;[/DELPHI]
y una imagen de como va quedando
[img width=800 height=421]http://nsae01.casimages.net/img/2013/06/09/130609033219499667.jpg[/img]
Como ya comente, el código y uno va evolucionando, así que seguirá habiendo cambios.
De momento que tal os va pareciendo, es muy pesado, esta claro?, es que como hay tan pocos comentarios, no se si estoy aburriendo al personal.
#10
Escrito 09 junio 2013 - 08:33
A pesar de que por cuestiones de tiempo no puedo mirar en detalle tu trabajo, por el poco código que veo en los post de este hilo, me permito hacerte una respetuosa sugerencia: Utiliza algún tipo de nomenclatura (cualquiera que sea un poco más legible) para tus controles, métodos y clases, esto te lo digo porque después será casi imposible hacer mantenimiento a la aplicación. Por ejemplo si el DBEdit1 va a almacenar el valor del campo Apellidos entonces ponle el nombre dbeApellidos, o si el procedimiento DBEdit5Change lo que hace es validar algo entonces llámalo "procedure ValidarAlgo" y le agregas un comentario que dicho procedimiento se dispara al cambiar tal o cual control; puedes usar el estilo de nomenclatura que más te guste y sin duda tu código se hará mucho mas legible.
Un cordial saludo, y una vez más, muchas gracias por compartir tu trabajo.
#11
Escrito 10 junio 2013 - 02:11
#12
Escrito 10 junio 2013 - 02:12
Vamos con la estructura de las siguientes 6 tablas
Proveedores
CREATE TABLE PROVEEDORES (
ID INTEGER NOT NULL,
CODIGO T20 /* T20 = VARCHAR(20) */, //Código del proveedor
EMPRESA T80 /* T80 = VARCHAR(80) */, //Nombre de la empresa
LIBRE T80 /* T80 = VARCHAR(80) */, //Campo libre sin uso inicialmente
CIF T20 /* T20 = VARCHAR(20) */, //Número del CIF o documento identificativo
FECHAALTA DATE, //Fecha de alta
FORMAPAGO T40 /* T40 = VARCHAR(40) */, //Forma de pago
DIASPAGO T20 /* T20 = VARCHAR(20) */ //Los días de pago
);
Empleados incluye a los agentes
CREATE TABLE EMPLEADOS (
ID INTEGER NOT NULL,
CODIGO T20 /* T20 = VARCHAR(20) */, /Código del empleado
AGENTE LOG /* LOG = CHAR(1) */, //Es un agente/comercial
MEDIACOMISION NUMERIC(15,2), /Media de su comisión, se puede poner la más alta y el programa regulara sobre la comisión por producto
FECHAALTA DATE, //Fecha de alta
FECHABAJA DATE, //Fecha de su baja (Los datos de los empleados en ciertos sectores no se pueden borrar nunca, como en todas las empresas del sector químico
NUMEROSEGURIDADSOCIAL T40 /* T40 = VARCHAR(40) */, //Número de la seguridad social
NUMERODOCUMENTO T40 /* T40 = VARCHAR(40) */, //Número de documento identificativo, Nif, Dni, pasaporte, etc
COMISIONDTO1 NUMERIC(15,2), //Descuento a aplicar en la comisión si se aplica el Dto 1
COMISIONDTORAPEL2 NUMERIC(15,2), //Descuento a aplicar en la comisión si se aplica el Dto o rapel 2
COMISIONDTORAPEL3 NUMERIC(15,2), //Descuento a aplicar en la comisión si se aplica el Dto o rapel 2
COMISIONDTORAPEL4 NUMERIC(15,2), //Descuento a aplicar en la comisión si se aplica el Dto o rapel 3
COMISIONDTORAPEL5 NUMERIC(15,2), //Descuento a aplicar en la comisión si se aplica el Dto o rapel 5
PUESTO T20 /* T20 = VARCHAR(20) */, //Puesto que ocupa dentro de la empresa
NOMBRE T80 /* T80 = VARCHAR(80) */, //Nombre de la persona
SALARIO NUMERIC(15,2)// //Sueldo de la persona (este campo sólo lo dejaremos ver a los empleados de mayor nivel
);
Como podéis ver se aplica un descuento en las comisiones según el rapel o descuento que aplicamos entre el 2 y el 5 (rapel), pero no en el 1 ya que es el precio base, este descuento de la comisión se aplica si el descuento dentro del producto es diferente de 0, ó si se ha aplicado el rapel.
Fabricables
CREATE TABLE FABRICABLES (
ID INTEGER NOT NULL,
CODIGO T20 /* T20 = VARCHAR(20) */, //Código del fabricable
PRODUCTO T80 /* T80 = VARCHAR(80) */ //Nombre base del producto a fabricar
);
Formas de pago
CREATE TABLE FPAGOS (
ID INTEGER NOT NULL,
CODIGO T20 /* T20 = VARCHAR(20) */, //Código de la forma de pago (este campo es único)
FORMAPAGO T40 /* T40 = VARCHAR(40) */, //Formas de pago a establecer
DIASPRESENTACION T20 /* T20 = VARCHAR(20) */, //Días de presentación
DIASCOBRO T20 /* T20 = VARCHAR(20) */, //Dias de cobros
NUMERODEPAGOS INTEGER// Si tiene pago aplazado el numero de plazos
);
Pagos plazos
CREATE TABLE PAGOSPLAZOS (
ID INTEGER NOT NULL,
CODIGOFORMADEPAGO T20 /* T20 = VARCHAR(20) */, //Código de forma de pago a la que esta unida
NUMERODEDIAS INTEGER, //Número de días desde la emisión de la factura, dejar en blanco si no se quiere especificar
PORCENTAJEPAGO NUMERIC(15,2) //Porcentaje del total de la factura a cobrar en este plazo
);
Bueno en primer lugar decir que estas son las primeras tabla que están enlazada ( FPAGOS es el maestro y PAGOSPLAZOS el detalle), después sobre la tabla PAGOSPLAZOS
deciros que mi modo de uso es el siguiente pongo dos ejemplos
1º) Cliente pago a 30(40%),60(30%),90(30%) días factura 1000, fecha 30/06/2013 y días de pago del 20 al 25, quedarían los pagos de la siguiente manera
25/07/2013..Importe 400.00 euros [Pago lógico 30/07/2013] (como podemos ver no llega a los 30 días, pero hemos cogido el dato de sus fechas de pago, en caso contrario se iría a casi dos meses)
25/08/2013..Importe 300.00 euros [Pago lógico 29/08/2013]
25/09/2013..Importe 300.00 euros [Pago lógico 28/09/2013]
2º) Cliente paga a 50% y 50%, factura de 1000 euros, fecha 30/06/2013 y días de pago del 20 al 25, lo pagos serían
25/ (mes a designar entre el cliente y la empresa)/2013..Importe 500.00 euros
25/ (mes a designar entre el cliente y la empresa)/2013..Importe 500.00 euros
Al no poner el número de días sólo tenemos en cuenta el día de pago y no el número de días a transcurrir para cada uno de los plazos.
La tabla Lotes
CREATE TABLE LOTES (
ID INTEGER NOT NULL,
CODIGOPRODUCTOFABRICABLE T20 /* T20 = VARCHAR(20) */, //Código del producto Fabricable
CODIGOEMPLEADO T20 /* T20 = VARCHAR(20) */, //Código del empleado responsable
FECHA DATE, //Fecha en que se fabrico
LOTE T20 /* T20 = VARCHAR(20) */, //Lote asignado
CADUCIDAD DATE, //Si es caduco su fecha de caducidad
CANTIDAD NUMERIC(15,2), //Cantidad total fabricada (litros, kilos unidades)
ACTIVO LOG /* LOG = CHAR(1) */ //Si el producto esta activo
);
Sobre el campo ACTIVO, lo usamos para saber si es un lote que se puede vender (S) o no se puede vender (N), por que sea para trasformación, o sea un lote retirado del mercado.
Aunque nadie me ha preguntado, si os dais cuenta, en mi tabla artículos, no he puesto campos para tallas, colores, tamaños o si esta dividido en partes, si lo necesitáis sabéis que son campos que tienen que usarse con tablas auxiliares. yo en esta demo no las voy a poner, pero no esta demás comentarlo.
#13
Escrito 10 junio 2013 - 06:10
#14
Escrito 10 junio 2013 - 08:00

#15
Escrito 19 junio 2013 - 01:22
1º) se ha añadido un IBQuerry y su datasource el ModuleData (UDM en mi caso), para facilitar los datos a todos los modulos que lo llaman,, eliminando parte del código de control en cada uno de estos, el aspecto actual de mi UDM es el siguiente

Los cambios en su código son los siguientes:
[DELPHI]
procedure TDM.conectar;
//------------------------------------------------------------------------------
//**************************************************************[ Conectar ]****
//Nos permite conectar las tablas, querrys + IBDatabase + IBTransaction
//------------------------------------------------------------------------------
begin
IBDatabase1.Connected:=True; //La base de datos
IBTransaction1.Active:=True; //Las Tansacciones
IBDCLIEN.Active:=True; //La tabla Clientes
IBDirecciones.Active:=True; //La tabla Direcciones
IBDPC.Active:=True; //La tabla Personas de Contacto
IBDContacto.Active:=True; //La Tabla de datos de contacto
IBDBcos.Active:=True; //La tabla de Bancos
IBDCONFI.Active:=True; //La tabla de Configuración
IBDUSUA.Active:=True; //La tabla de usuarios (permisos de acceso)
IBDNOTAS.Active:=True; //La tabla de notas
IBDIMAGENES.Active:=True; //La tabla de Imagenes
IBDPROVEEDORES.Active:=True; //La tabla de Proveedores
IBDLOTES.Active:=True; //La tabla de Lotes
IBDARTICULOS.Active:=True; //La tabla de Artículos
IBDFAMILIAS.Active:=True; //La tabla de Familias
IBDFABRICABLES.Active:=True; //La tabla de Fabricables
IBDSTOCK.Active:=True; //La tabla de Stock
end;
procedure TDM.DataModuleDestroy(Sender: TObject);
//------------------------------------------------------------------------------
//*********************************************************[ Al destruirlo ]****
// Nos aseguramos de que no se nos queden Querys abiertos //Añadir el archivo Fun.Pas
//------------------------------------------------------------------------------
begin
QuerryOC(IBQIMAGENES);
QuerryOC(IBQNOTAS);
QuerryOC(IBQDirecciones);
QuerryOC(IBQPersonasContacto);
QuerryOC(IBQContactos);
QuerryOC(IBQBancos);
end;[/code]
2º) en el FormClose de cada módulo auxiliar ponemos el siguiente código
//////////He editado nuevamente este post cambiando lo que había puesto por lo siguiente y explico lo que he eliminado///////////
[DELPHI]
//Cambiar donde aparece XXX por lo que proceda (Nombre del MODULO, de la Tabla, de el IBDataSet, del IBQuerry, del módulo de llamada o del SpeedButtonBC)
procedure TFNotas.FXXXClose(Sender: TObject; var Action: TCloseAction);
//------------------------------------------------------------------------------
//*************************************************[ Al Cerrarse El Form ]******
// Cerramos todos los procesos para que no consuman memoria y posibles errores
//------------------------------------------------------------------------------
begin
if Timer1.Enabled=true then Timer1.Enabled:=False;
ActIbdataset(DM.IBDXXX,'select * from XXX');
//Retornos al modulo de llamada
if VarSNomMod='XXX' then FArticulos.SpeedButtonBCXXXClick(sender);
end;[/code]
he eliminado el siguiente código
[DELPHI]
if DM.IBQXXX.Active then //Nos aseguramos de refrescar los datos del querry, con los nuevos introducidos si los ha habido
begin //No uso refresh, ya que muchas veces no funciona y de esta manera es más efectivo el refresco de datos
DM.IBQXXX.Active:=False;
DM.IBQXXX.Active:=True;
end;
[/code]
, al ya esta controlado en la lineas
[DELPHI]
if VarSNomMod='XXX' then FArticulos.SpeedButtonBCXXXClick(sender);
[/code]
Que no había actualizado, con lo que el código anterior era redundante.
#16
Escrito 19 junio 2013 - 05:32
Una pequeña sugerencia, en vez de utilizar Active para los descendientes del TDataSet usa mejor los métodos Open y Close. Que al final hacen la misma asignación que estas realizando, pero a mi modo de ver es más legible con los métodos.
#17
Escrito 19 junio 2013 - 12:07
#18
Escrito 19 junio 2013 - 12:21
LA imagen

he marcado algún olvido y lo que hacen algunos botones, ahora las pestañas
0º) Es la de los datos, vemos que realmente en la tabla proveedores tenemos que introducir pocos datos, pero que el conjunto de datos con las auxiliares la completa bastante
1º) Contactos. Recordar que esta tabla sera luego nuestra agenda, permitiendo, separarlo, por Clientes, proveedores, etc, ademas de todos, buscar por el nombre/empresa/etc y ponderemos un indice que nos permitirá ver clasificado por su inicio.
2º) Notas, como podemos ver en este caso tenemos dos notas y las hemos clasificado (campo descripción) como avisos y recordatorio, pero podríamos tener muchos más solo para este proveedor, aquí es donde se ve la potencia de este modo de programar, que aunque un poco más lioso nos da mucha más potencia.
3º) Las Imágenes, Como podemos ver también hemos puesto 2 la del logo y productos.
4º) Personas de contactos, , al tenerla en una tabla auxiliar, nos permite tener multitud de personas de contacto dentro del mismo registro
5º) Direcciones, al igual que la anterior tabla podríamos tener multitud de direcciones (Almacenes, oficinas, tiendas, etc).
6º) Bancos, sería más correcto decir cuentas, pero un cliente/proveedor/etc, puede trabajar con más de un banco o más de una cuenta corriente.
7º) Aquí ira nuestro modulo de compras a este proveedor, que aún no desarrollaremos.
No voy a entrar en algo que ya se ha hablado ampliamente en los foros, sobre las notas y las imágenes si guardarlas dentro de las tablas o sólo guardar su referencia en la tabla y guardarla físicamente en archivos en el disco duro.
También quiero explicar que poner en las pestañas los campos nombre del módulo y código de las tablas auxiliares, es para que quede más claro en el tutorial, normalmente, serían campos no visibles.
y el código podéis bajarlo de https://gist.github....onymous/5812746
#19
Escrito 19 junio 2013 - 12:25

En este módulo hay cosas que cambian, al tratarse de usar una tabla maestro y otra detalle, como podemos ver tenemos 2 panales con botonera y debemos controlar ambas y aunque en la imagen no se ve tenemos un sólo juego de botenes de confirmación y cancelación, para que quede más claro hay que estudiar el código
podemos ver que hemos hecho la relación maestro detalle en el módulo UDM

Aquí el código https://gist.github....onymous/5812904
#20
Escrito 19 junio 2013 - 12:30

como podemos ver un módulo sencillo de tan sólo 160 lineas actualmente, que ira creciendo según avancemos el proyecto, sólo tendremos que añadir el control de los módulos de llamada y su retorno, ya que este módulo sera llamado por varios módulos.
No usamos la función de coloración del grid, ya que al ser este variable, en número de campos nos daría un error, más adelante lo modificare y añadiré el código, para que se ajuste al resto del diseño.
El código aquí https://gist.github....onymous/5812974