Hola amigos de yii, despues de un tiempo fuera del foro por problemas de conectividad con internet, les traigo una duda que espewro me ayuden a resolver, el problema es que tengo un sistema (facturacion) que necesito generar los numeros de facturas automáticos, para ello tengo dos tablas en mi BD, una tabla facturas con los datos de las facturas incluyendo un campo Idn autonumerico y otra tabla detallesfacturas donde se llenan los datos de los productos a facturar con un campo Id_sal entero relacionado con el campo Idn de la tabla factura uno a muchos, o sea, si tengo una factura con el Idn = 1 entonces puedo tener varios ptoductos en esa factura con Id_sal = 1, de esta lleno las tablas, el problema es que si en el navegador la conexion es lenta al dar clic, demora al hacer la factura, entonces cuando la persona que esta haciendo la operacion le da clic mas de una vez al botón submit de crear la factura, entonces me crea la operacion mas de una vez, generando errores, ya que como todo es automatico, entonces me rebaja los saldos mas de una vez de la tabla submayor, que es donde se guardan los saldos de los productos.
Si alguien tiene una validacion para eso y me la puede dar a traves de este post, se lo agradeceria, en conclusion, lo que quiero es que al hacer clic en el botón submit de crear la factura, entonces me la cree y si le hago clic otra vez entonces ya este inabilitado para que no la vuelva a crear.
Deberías tener una acción en tu FacturasController (nombre de ejemplo) que capture la creación de la factura. Desde tu formulario deberías llamar a esta acción mediante AJAX y cuando lo haces cambiar el atributo del botón a "disabled". Una vez que tengas éxito (success), vuelves a habilitar el botón o redireccionas al usuario.
por favor, necesito un ejemplo de esto, es muy importante, ya que hoy lo tengo poniendo en número consecutivo en en campo numerico entero, no autoincrementable y luego genera el numero de factura con ese consecutivo al final, pero necesito hacerlo automatico, creo debe ser con ese consecutivo autonumerico, pero si lo pongo asi, entonces al dar mas de un clic en el botón submit me genera mas de una factura
No se como haces las facturas, para mi una factura es un encabezado (que va en una tabla), y una serie de conceptos (que van en 1 u otras tablas). Si no hay conceptos la factura esta vacia.
En tu caso, creo que detalles facturas es la tabla que tiene los conceptos, si una factura esta vacia aqui no hay ninguna linea enlazada con tu factura.
Si enlazas conceptos automaticamente al crear la factura, esto no valdría. (Quiza habría otra forma de verlo.)
El tema del ajax esta bien, pero esto se controla en el cliente (debes tenerlo en cuenta para futuros cambios).
Ok, mi factura la hago en dos tablas, una tabla de facturas y otra de detalles de facturas, en la tabla factura pongo los detalles preliminares de los clientes, conceptos de facturas, etc. y en la tabla detalles pongo los productos con precios, cantidades de productos, importes, almacenes donde estan los productos, etc., por productos todos por codigos, entre la tabla facturas y detalles estan relacionadas por el consecutivo de la factura, la que genera el numero de factura con la tabla detalles, ejemplo:
Tabla facturas:
Idn (integer no autoincrementable) es el consecutivo, entonces se genera el numero de factura nfactura (varchar 20), aqui este numero se forma segun algunas condiciones que le pongo, entonces en la tabla detalles tengo un campo Id_sal (varchar 20), donde lo toma del numero de factura (nfactura), estos campos esta relacionados uno a muchos, ya que una factura puede tener muchos productos, lo que quiero es que este campo (Idn) sea autoincrementable, por supuesto, entonces usted me sugiere que ponga en la tabla facturas una factura vacia para cada cliente, donde debe llevar un valor Idny en el campo codigo_cliente el numero de cliente, le pongo de antemano que tengo una tabla cliente con todos los clientes (mas de 2500) con todas las generalidades de estos, con campo codigo_cliente de llave que se relaciona con la tabla factura por ese campo uno a muchos, o sea un cliente puede tener muchas facturas, asi las facturas tiene otros campors tambien relacionados con otras tablas, pero le pongo el de clientes que es el que importa en cuestion, le digo esto porque si tengo que agregar una factura si pongo una factura vacia para cada cliente, entonces voy a utilizar por adelantado mas de 2500 numeros.
Disculpe si no entendi lo de poner una factura vacia.
Un programa de facturación es complejo, pero puede ser que te estés ahogando en un vaso de agua?
Tienes dos tablas, una de resumen facturas y otra de lineas factura, eso está bien.
Relaciona las líneas factura con su factura a través del id autoincrementable de toda la vida de la tabla facturas
Y no uses este id como el número de factura. El número de factura calcúlalo de otra forma: lees el valor MAX(numfactura) y le sumas 1 a la factura que se va a crear, así de sencillo.
Cómo evitar números duplicados? al validar los datos debes comprobar que ese número de factura no existe.
Cómo evitar reenvíos del formulario? Revisa la anterior respuesta. Creo que no se pueden evitar porque es cosa del navegador. Simplemente si el número de factura ya existe no cumplirá las reglas de validación, avisas al usuario y no la guardas, como es lógico.
Otra cosa que puedes hacer es usar una variable de sesión para controlar si la factura ya ha sido creada o no, por ejemplo guardando su número en esa variable, o usar ajax o pasar los datos a otra página por json… Hay diversas maneras de controlar eso.
Una cosa respecto a los clientes: los datos del cliente pueden cambiar, pero los datos del cliente en una factura ya hecha no. Con esto quiero decirte que los datos del cliente deberías guardarlos en la tabla facturas, en lugar de la referencia a su id de cliente.
El post anterior de Fher es todo ok. Respecto del mio anterior creo que te he liado totalmente.
Lo de los clientes que te comenta es super importante, una factura debe tener todos las datos como texto porque es un documento final y tal como se ha calculado debe quedar sin modificar.
Yo en mi caso suelo crear un campo lineas en la tabla facturas y cada vez que agrego productos a la factura incremento el numero (si elimino resto), esto me obliga a hacer un update de la factura cada vez que se agregan o eliminan articulos pero me permite controlar que no se creen varias facturas al enviar un formulario o por otras razones.
hola de nuevo he trabajado en lo que me dice dicen, pero no logro evitar lo de hacer varias facturas cada vez que se hace clic, eso lo necesito resolver, ya que cada vez que se hace una factura en cada clic, me rebaja los saldos aunque se haga con numeros diferentes.
Es de suponer que en el formulario tienes un input con el número de factura, si ese número no lo cambias las reglas de validación deben dar el error de que ese número ya existe y la factura no se debe guardar.
¿Por qué cambia el número de factura?
En el modo "normal", el usuario puede reenviar el formulario y eso es cosa del navegador y del usuario, eso pasa con todos los formularios. Lo que nosotros debemos hacer con php es validar que esos datos sean correctos antes de guardarlos.
Si lo haces con ajax una vez guardada la nueva factura inicializas los datos del formulario y problema resuelto. Pero vamos que se puede hacer de las dos formas.
Si sigues sin solucionarlo pon un ejemplo más claro.
Hola Fher gracias por responder te explico, el numero de factura cambia, porque yo tengo un campo Id [color="#0000FF"]autoincrementable [/color]y un campo Idn numerico pero [color="#FF0000"]no autoincrementable[/color], este campo lo formo de la siguiente forma: Busco en la tabla factura el mayor numero Idn MAX(Idn) y le adiciono uno. o sea, Idn=MAX(Idn)+1, y este numero obtenido es con el formo el [color="#800080"]número de factura[/color] (con otros elementos en varias cadenas), lo que pasa es que cada vez que se hace clic en el botón submit para crear la factura, hace la misma operacion y me crea tantos Idn y facturas como veces de clic en este botón, esto es lo que quiero resolver, pongo la validacion en la accion crear factura del controlador:
if ($id) {
$model = $this->loadModel($id);
} else {
$model = new Facturas;
//verificar si el consecutivo ya existe
$fact = Facturas::model()->find('Idn = :fa', array(':fa' => $_POST['idn']));
if ($fact) {
echo "fail";
yii::app()->end();
}
}
y en el form cuando formo los datos pongo esto:
success: function(data) {
if (data === 'fail')
alert('Ya existe un registro con ese número consecutivo');
else
window.location.href = 'index.php?r=facturas/admin';
}
pero esto no funciona, ya que siempre forma un nuevo Idn.
Hola rahif, lo que necesito implementar es lo que dice migue, o s ea, cuando se envie el primer clic desabilitar el boton submit para que no se repita, pero no se como hacerlo.
1.- En la acción crearFactura calculas el número de factura a crear, tal como dices con consulta max()+1, y muestras e inicializas el form con ese número.
2.- En la acción guardarFactura validas todos los datos y la guardas.
3.- Al volver a crearFactura se genera un nuevo número y se inicializa el form.
4.- Si el usuario reenvía el formulario ese número de factura ya existe > error de validación.
El próximo número de factura debe calcularse siempre al inicializar el form, en la acción crearFactura y consultando la base de datos, no al hacer clic en el botón enviar.
Gracias por responder, he probado varias veces y se me ha hecho dificil, esto, aqui voy a poner mi accion donde creo la factura en el controlador (salvaFactura) y el form (vista), para ver si me pueden ayudar mas claro:
No se si he entendido bien tu post, pero lo que entiendo es que deseas que un usuario o pueda enviar una factura hasta que la anterior haya sido procesada.
Lo más fácil en mi opinión sería sustituir tu botón submit por el siguiente botón:
Cuando se haga click el botón se desactiva y se envía el formulario. Una vez el formulario es procesado, la página se vuelve a recargar, con lo que el botón vuelve a activarse. De esta forma no puedes enviar el formulario mientras se esté procesando un envío anterior.
Además, no tienes que tocar para nada la base de datos y puedes dejar tu campo en autonumérico.
De todas formas, a mi me gusta (y lo veo muy útil) que las facturas siguan expresiones regulares y no están formadas sólo por números correlativos. De esta forma simplemente viendo el número de factura puedes saber más datos del pedido sin tener que consultar nada más.
Hola lagogz, buenos dias aca, alla buenas tardes, mira cambie el botón submit que tenia por el que me indicaste, pero, al hacer clic sobre él, me lo desabilita, pero no ejecuta la acción crear factura.
En cuanto al post, es realmante lo que quiero, que tengo el Idn como autonumerico y al hacer clic me cre la factura y no permita hacer mas facturas si diera mas clic.