diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..e3d32c8
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,149 @@
+# Compiled class file
+*.class
+
+# Log file
+*.log
+
+# BlueJ files
+*.ctxt
+
+# Mobile Tools for Java (J2ME)
+.mtj.tmp/
+
+# Package Files #
+*.jar
+*.war
+*.ear
+*.zip
+*.tar.gz
+*.rar
+
+# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
+hs_err_pid*
+
+## Netbeans Stuff
+nbproject/private/
+build/
+nbbuild/
+dist/
+nbdist/
+.nb-gradle/
+
+## Eclipse Stuff
+.metadata
+bin/
+tmp/
+*.tmp
+*.bak
+*.swp
+*~.nib
+local.properties
+.settings/
+.loadpath
+.recommenders
+
+# External tool builders
+.externalToolBuilders/
+
+# Locally stored "Eclipse launch configurations"
+*.launch
+
+# PyDev specific (Python IDE for Eclipse)
+*.pydevproject
+
+# CDT-specific (C/C++ Development Tooling)
+.cproject
+
+# Java annotation processor (APT)
+.factorypath
+
+# PDT-specific (PHP Development Tools)
+.buildpath
+
+# sbteclipse plugin
+.target
+
+# Tern plugin
+.tern-project
+
+# TeXlipse plugin
+.texlipse
+
+# STS (Spring Tool Suite)
+.springBeans
+
+# Code Recommenders
+.recommenders/
+
+# Scala IDE specific (Scala & Java development for Eclipse)
+.cache-main
+.scala_dependencies
+.worksheet
+
+##------------------------ IntelliJ
+# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and WebStorm
+# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
+
+# User-specific stuff
+.idea/**/workspace.xml
+.idea/**/tasks.xml
+.idea/**/usage.statistics.xml
+.idea/**/dictionaries
+.idea/**/shelf
+
+# Generated files
+.idea/**/contentModel.xml
+
+# Sensitive or high-churn files
+.idea/**/dataSources/
+.idea/**/dataSources.ids
+.idea/**/dataSources.local.xml
+.idea/**/sqlDataSources.xml
+.idea/**/dynamic.xml
+.idea/**/uiDesigner.xml
+.idea/**/dbnavigator.xml
+
+# Gradle
+.idea/**/gradle.xml
+.idea/**/libraries
+
+# Gradle and Maven with auto-import
+# When using Gradle or Maven with auto-import, you should exclude module files,
+# since they will be recreated, and may cause churn. Uncomment if using
+# auto-import.
+# .idea/modules.xml
+# .idea/*.iml
+# .idea/modules
+
+# CMake
+cmake-build-*/
+
+# Mongo Explorer plugin
+.idea/**/mongoSettings.xml
+
+# File-based project format
+*.iws
+
+# IntelliJ
+out/
+
+# mpeltonen/sbt-idea plugin
+.idea_modules/
+
+# JIRA plugin
+atlassian-ide-plugin.xml
+
+# Cursive Clojure plugin
+.idea/replstate.xml
+
+# Crashlytics plugin (for Android Studio and IntelliJ)
+com_crashlytics_export_strings.xml
+crashlytics.properties
+crashlytics-build.properties
+fabric.properties
+
+# Editor-based Rest Client
+.idea/httpRequests
+
+# Android studio 3.1+ serialized cache file
+.idea/caches/build_file_checksums.ser
\ No newline at end of file
diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml
new file mode 100644
index 0000000..6d799a0
--- /dev/null
+++ b/.idea/codeStyles/Project.xml
@@ -0,0 +1,52 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/compiler.xml b/.idea/compiler.xml
new file mode 100644
index 0000000..217af47
--- /dev/null
+++ b/.idea/compiler.xml
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/.idea/description.html b/.idea/description.html
new file mode 100644
index 0000000..cc10d56
--- /dev/null
+++ b/.idea/description.html
@@ -0,0 +1,2 @@
+Simple JavaFX 2.0 application that includes simple .fxml file with attached controller and Main class to quick start. Artifact to build JavaFX application is provided.
+
\ No newline at end of file
diff --git a/.idea/encodings.xml b/.idea/encodings.xml
new file mode 100644
index 0000000..97626ba
--- /dev/null
+++ b/.idea/encodings.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
new file mode 100644
index 0000000..f991ccd
--- /dev/null
+++ b/.idea/misc.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/modules.xml b/.idea/modules.xml
new file mode 100644
index 0000000..b85e6f9
--- /dev/null
+++ b/.idea/modules.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
new file mode 100644
index 0000000..94a25f7
--- /dev/null
+++ b/.idea/vcs.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..8b4a7aa
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2017 Manuel
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..25e4fd5
--- /dev/null
+++ b/README.md
@@ -0,0 +1,17 @@
+# Factura-Ventas
+Es una aplicación moderna escrita en Java, para facturar
+artículos vendidos por una organización. La aplicación provee
+registro de artículos y clientes, necesarios para la facturación.
+
+![Imgur](https://i.imgur.com/xiFsapK.png)
+
+## Características
++ Registro y consulta de clientes.
++ Registro y consulta de articulos.
++ Facturación de artículos.
++ Consulta de facturas.
+
+## Software de terceros
++ JavaFX 11
++ JFoenix 9 ([Apache License 2.0](http://www.jfoenix.com/documentation.html#license))
++ PostgreSQL y pgJDBC ([PostgreSQL License](https://www.postgresql.org/about/licence))
diff --git a/db/README.txt b/db/README.txt
new file mode 100644
index 0000000..77f0344
--- /dev/null
+++ b/db/README.txt
@@ -0,0 +1,7 @@
+El gestor usado para la creacion de la base de datos es PostgreSQL: https://www.postgresql.org/download/
+
+INSTRUCCIONES PARA GENERAR BASE DE DATOS.
+
+1. Ejecutar el script DROP DATABASE y CREATE DATABASE ubicado en el archivo "script.sql", el cual puede ser abierto con cualquier editor de texto;
+
+2. Ejecutar los queries restantes en la base de datos creada.
diff --git a/db/venta.sql b/db/venta.sql
new file mode 100644
index 0000000..ade1596
--- /dev/null
+++ b/db/venta.sql
@@ -0,0 +1,1260 @@
+--
+-- PostgreSQL database dump
+--
+
+-- Dumped from database version 10.7
+-- Dumped by pg_dump version 10.7
+
+-- Started on 2019-04-24 11:56:12
+
+SET statement_timeout = 0;
+SET lock_timeout = 0;
+SET idle_in_transaction_session_timeout = 0;
+SET client_encoding = 'UTF8';
+SET standard_conforming_strings = on;
+SELECT pg_catalog.set_config('search_path', '', false);
+SET check_function_bodies = false;
+SET client_min_messages = warning;
+SET row_security = off;
+
+DO
+$do$
+BEGIN
+ IF NOT EXISTS (
+ SELECT -- SELECT list can stay empty for this
+ FROM pg_catalog.pg_roles
+ WHERE rolname = 'usuario') THEN
+
+ CREATE ROLE usuario LOGIN;
+ END IF;
+ ALTER USER usuario PASSWORD '1234';
+END
+$do$;
+--
+-- TOC entry 1 (class 3079 OID 12924)
+-- Name: plpgsql; Type: EXTENSION; Schema: -; Owner:
+--
+
+CREATE EXTENSION IF NOT EXISTS plpgsql WITH SCHEMA pg_catalog;
+
+
+--
+-- TOC entry 2931 (class 0 OID 0)
+-- Dependencies: 1
+-- Name: EXTENSION plpgsql; Type: COMMENT; Schema: -; Owner:
+--
+
+COMMENT ON EXTENSION plpgsql IS 'PL/pgSQL procedural language';
+
+
+--
+-- TOC entry 227 (class 1255 OID 26049)
+-- Name: Articulo_HISTORICO(); Type: FUNCTION; Schema: public; Owner: postgres
+--
+
+CREATE FUNCTION public."Articulo_HISTORICO"() RETURNS trigger
+ LANGUAGE plpgsql
+ AS $$ BEGIN
+INSERT INTO articuloHis(articuloId,
+articuloCodigo, articuloNombre, articuloDescripcion,
+articuloPrecio, articuloUnidadesStock, articuloEstatus)
+VALUES (OLD.articuloId, OLD.articuloCodigo,
+OLD.articuloNombre, OLD.articuloDescripcion,
+OLD.articuloPrecio, OLD.articuloUnidadesStock, OLD.articuloEstatus);
+END;$$;
+
+
+ALTER FUNCTION public."Articulo_HISTORICO"() OWNER TO postgres;
+
+--
+-- TOC entry 228 (class 1255 OID 26051)
+-- Name: Articulo_LOG(); Type: FUNCTION; Schema: public; Owner: postgres
+--
+
+CREATE FUNCTION public."Articulo_LOG"() RETURNS trigger
+ LANGUAGE plpgsql
+ AS $$ BEGIN
+INSERT INTO articuloLog(articuloId, articuloCodigo, articuloNombre, articuloDescripcion,
+ articuloPrecio, articuloUnidadesStock, articuloEstatus, articuloLogUsuario)
+VALUES (NEW.articuloId, NEW.articuloCodigo, NEW.articuloNombre, NEW.articuloDescripcion, NEW.articuloPrecio, NEW.articuloUnidadesStock, NEW.articuloEstatus, current_user);
+RETURN NEW;
+END;$$;
+
+
+ALTER FUNCTION public."Articulo_LOG"() OWNER TO postgres;
+
+--
+-- TOC entry 233 (class 1255 OID 26123)
+-- Name: Calcular_factura_TOTAL(); Type: FUNCTION; Schema: public; Owner: postgres
+--
+
+CREATE FUNCTION public."Calcular_factura_TOTAL"() RETURNS trigger
+ LANGUAGE plpgsql
+ AS $$ BEGIN
+
+UPDATE factura
+SET facturaTotalBruto =
+facturaTotalBruto + NEW.facturaPrecio * NEW.facturaCantidad,
+facturaTotalImpuesto =
+facturaTotalImpuesto + NEW.facturaImpuesto * NEW.facturaCantidad,
+facturaTotalDescto =
+facturaTotalDescto + NEW.facturaDescuento * NEW.facturaCantidad,
+facturaTotalNeto =
+facturaTotalNeto + NEW.facturaNeto * NEW.facturaCantidad
+WHERE factura.facturaId = NEW.facturaId;
+
+UPDATE ONLY articulo
+SET articuloUnidadesStock =
+articuloUnidadesStock - NEW.facturaCantidad
+WHERE articuloId = NEW.articuloId;
+RETURN NEW;
+END;$$;
+
+
+ALTER FUNCTION public."Calcular_factura_TOTAL"() OWNER TO postgres;
+
+--
+-- TOC entry 232 (class 1255 OID 26125)
+-- Name: Cliente_ACCESO(); Type: FUNCTION; Schema: public; Owner: postgres
+--
+
+CREATE FUNCTION public."Cliente_ACCESO"() RETURNS trigger
+ LANGUAGE plpgsql
+ AS $$ BEGIN
+UPDATE Cliente
+SET clienteultimatransaccion = CURRENT_TIMESTAMP
+WHERE ClienteId = NEW.ClienteId;
+RETURN NEW;
+END;$$;
+
+
+ALTER FUNCTION public."Cliente_ACCESO"() OWNER TO postgres;
+
+--
+-- TOC entry 208 (class 1255 OID 26022)
+-- Name: Cliente_HISTORICO(); Type: FUNCTION; Schema: public; Owner: postgres
+--
+
+CREATE FUNCTION public."Cliente_HISTORICO"() RETURNS trigger
+ LANGUAGE plpgsql
+ AS $$ BEGIN
+INSERT INTO clienteHis(clienteId,
+clienteNombre, clienteDireccion,
+clienteCiudad,
+clienteEmail,
+clienteTelefono,
+clienteCodigoPostal,
+clientePais, clienteEstatus)
+
+VALUES (OLD.clienteId,
+OLD.clienteNombre, OLD.clienteDireccion, OLD.clienteCiudad, OLD.clienteEmail, OLD.clienteTelefono,
+OLD.clienteCodigoPostal, OLD.clientePais, OLD.clienteEstatus);
+RETURN OLD;
+END;$$;
+
+
+ALTER FUNCTION public."Cliente_HISTORICO"() OWNER TO postgres;
+
+--
+-- TOC entry 209 (class 1255 OID 26024)
+-- Name: Cliente_LOG(); Type: FUNCTION; Schema: public; Owner: postgres
+--
+
+CREATE FUNCTION public."Cliente_LOG"() RETURNS trigger
+ LANGUAGE plpgsql
+ AS $$ BEGIN
+
+INSERT INTO clienteLog(clienteId,
+clienteNombre, clienteDireccion,
+clienteCiudad,
+clienteEmail,
+clienteTelefono,
+clienteCodigoPostal,
+clientePais, clienteEstatus, clienteLogUsuario)
+
+VALUES (NEW.clienteId,
+NEW.clienteNombre, NEW.clienteDireccion, NEW.clienteCiudad, NEW.clienteEmail, NEW.clienteTelefono,
+NEW.clienteCodigoPostal, NEW.clientePais, NEW.clienteEstatus, current_user);
+RETURN NEW;
+END;$$;
+
+
+ALTER FUNCTION public."Cliente_LOG"() OWNER TO postgres;
+
+--
+-- TOC entry 210 (class 1255 OID 26026)
+-- Name: Cliente_PURGAR(); Type: FUNCTION; Schema: public; Owner: postgres
+--
+
+CREATE FUNCTION public."Cliente_PURGAR"() RETURNS trigger
+ LANGUAGE plpgsql
+ AS $$ BEGIN
+DELETE FROM ONLY Cliente
+WHERE clienteultimatransaccion < CURRENT_TIMESTAMP - INTERVAL '5 years';
+RETURN NULL;
+END;$$;
+
+
+ALTER FUNCTION public."Cliente_PURGAR"() OWNER TO postgres;
+
+--
+-- TOC entry 234 (class 1255 OID 26136)
+-- Name: Sumar_Cargo(); Type: FUNCTION; Schema: public; Owner: postgres
+--
+
+CREATE FUNCTION public."Sumar_Cargo"() RETURNS trigger
+ LANGUAGE plpgsql
+ AS $$BEGIN
+UPDATE Factura
+SET FacturaTotalNeto = FacturaTotalCargo
+WHERE FacturaId = NEW.FacturaId;
+RETURN NEW;
+END;$$;
+
+
+ALTER FUNCTION public."Sumar_Cargo"() OWNER TO postgres;
+
+--
+-- TOC entry 229 (class 1255 OID 26077)
+-- Name: articulo_buscar(character varying); Type: FUNCTION; Schema: public; Owner: postgres
+--
+
+CREATE FUNCTION public.articulo_buscar(nom character varying) RETURNS TABLE(id integer, codigo character, nombre character varying, descripcion character varying, unidades_stock integer, precio numeric, estatus character)
+ LANGUAGE plpgsql
+ AS $$BEGIN
+RETURN QUERY
+SELECT articuloId ID,
+articuloCodigo Codigo,
+articuloNombre Nombre,
+articuloDescripcion Descripcion,
+articuloUnidadesStock Unidades_Stock,
+articuloPrecio Precio,
+articuloEstatus Estatus
+FROM ONLY articulo
+WHERE articuloNombre LIKE CONCAT(nom, '%')
+ORDER BY articuloid DESC;
+END;$$;
+
+
+ALTER FUNCTION public.articulo_buscar(nom character varying) OWNER TO postgres;
+
+--
+-- TOC entry 230 (class 1255 OID 26078)
+-- Name: articulo_mostrar(); Type: FUNCTION; Schema: public; Owner: postgres
+--
+
+CREATE FUNCTION public.articulo_mostrar() RETURNS TABLE(id integer, codigo character, nombre character varying, descripcion character varying, unidades_stock integer, precio numeric, estatus character)
+ LANGUAGE plpgsql
+ AS $$ BEGIN
+RETURN QUERY
+SELECT articuloId,
+articuloCodigo,
+articuloNombre,
+articuloDescripcion,
+articuloUnidadesStock,
+articuloPrecio,
+articuloEstatus
+FROM ONLY articulo
+ORDER BY articuloId
+LIMIT 200;
+END;$$;
+
+
+ALTER FUNCTION public.articulo_mostrar() OWNER TO postgres;
+
+--
+-- TOC entry 231 (class 1255 OID 26079)
+-- Name: articulo_mostraractivos(); Type: FUNCTION; Schema: public; Owner: postgres
+--
+
+CREATE FUNCTION public.articulo_mostraractivos() RETURNS TABLE(id integer, codigo character, nombre character varying, descripcion character varying, unidades_stock integer, precio numeric, estatus character)
+ LANGUAGE plpgsql
+ AS $$ BEGIN
+RETURN QUERY
+SELECT articuloId ID,
+articuloCodigo Codigo,
+articuloNombre Nombre,
+articuloDescripcion Descripcion,
+articuloUnidadesStock Unidades_Stock,
+articuloPrecio Precio,
+articuloEstatus Estatus
+FROM ONLY articulo
+WHERE articuloEstatus = 'A'
+ORDER BY articuloId
+LIMIT 200;
+END;$$;
+
+
+ALTER FUNCTION public.articulo_mostraractivos() OWNER TO postgres;
+
+--
+-- TOC entry 211 (class 1255 OID 26030)
+-- Name: cliente_buscar(character varying); Type: FUNCTION; Schema: public; Owner: postgres
+--
+
+CREATE FUNCTION public.cliente_buscar(nom character varying) RETURNS TABLE(id integer, nombre character varying, email character varying, telefono character varying, direccion character varying, codigopostal character varying, ciudad character varying, pais character varying, estatus character)
+ LANGUAGE plpgsql
+ AS $$ BEGIN
+RETURN QUERY
+SELECT clienteid id,
+clientenombre nombre,
+clienteemail email,
+clientetelefono telefono,
+clientedireccion direccion,
+clientecodigopostal codigopostal,
+clienteciudad ciudad,
+clientepais pais,
+clienteestatus estatus
+FROM ONLY cliente
+WHERE clienteNombre LIKE CONCAT(nom, '%')
+ORDER BY clienteid DESC
+LIMIT 200;
+END;$$;
+
+
+ALTER FUNCTION public.cliente_buscar(nom character varying) OWNER TO postgres;
+
+--
+-- TOC entry 224 (class 1255 OID 26031)
+-- Name: cliente_buscaractivos(character varying); Type: FUNCTION; Schema: public; Owner: postgres
+--
+
+CREATE FUNCTION public.cliente_buscaractivos(nom character varying) RETURNS TABLE(id integer, nombre character varying, email character varying, telefono character varying, direccion character varying, codigopostal character varying, ciudad character varying, pais character varying, estatus character)
+ LANGUAGE plpgsql
+ AS $$BEGIN
+RETURN QUERY
+SELECT clienteId AS Id,
+clienteNombre AS Nombre,
+clienteEmail AS Email,
+clienteTelefono AS Telefono,
+clienteDireccion AS Direccion,
+clienteCodigoPostal AS CodigoPostal,
+clienteCiudad AS Ciudad,
+clientePais AS Pais,
+clienteEstatus AS Estatus
+FROM ONLY cliente
+WHERE clienteNombre LIKE CONCAT(nombre, '%')
+AND clienteEstatus = 'A'
+ORDER BY clienteultimatransaccion DESC, clienteid;
+END;$$;
+
+
+ALTER FUNCTION public.cliente_buscaractivos(nom character varying) OWNER TO postgres;
+
+--
+-- TOC entry 225 (class 1255 OID 26032)
+-- Name: cliente_mostrar(); Type: FUNCTION; Schema: public; Owner: postgres
+--
+
+CREATE FUNCTION public.cliente_mostrar() RETURNS TABLE(id integer, nombre character varying, email character varying, telefono character varying, direccion character varying, codigopostal character varying, ciudad character varying, pais character varying, estatus character)
+ LANGUAGE plpgsql
+ AS $$ BEGIN
+RETURN QUERY
+SELECT clienteid,
+clientenombre,
+clienteemail,
+clientetelefono,
+clientedireccion,
+clientecodigopostal,
+clienteciudad,
+clientepais,
+clienteestatus
+FROM ONLY cliente
+ORDER BY clienteid
+LIMIT 200;
+END;$$;
+
+
+ALTER FUNCTION public.cliente_mostrar() OWNER TO postgres;
+
+--
+-- TOC entry 226 (class 1255 OID 26033)
+-- Name: cliente_mostraractivos(); Type: FUNCTION; Schema: public; Owner: postgres
+--
+
+CREATE FUNCTION public.cliente_mostraractivos() RETURNS TABLE(id integer, nombre character varying, email character varying, telefono character varying, direccion character varying, codigopostal character varying, ciudad character varying, pais character varying, estatus character)
+ LANGUAGE plpgsql
+ AS $$ BEGIN
+RETURN QUERY
+SELECT clienteid,
+clientenombre,
+clienteemail,
+clientetelefono,
+clientedireccion,
+clientecodigopostal,
+clienteciudad,
+clientepais,
+clienteestatus
+FROM ONLY cliente
+WHERE clienteEstatus = 'A'
+ORDER BY clienteultimatransaccion DESC, clienteid
+LIMIT 200;
+END;$$;
+
+
+ALTER FUNCTION public.cliente_mostraractivos() OWNER TO postgres;
+
+--
+-- TOC entry 236 (class 1255 OID 26133)
+-- Name: factura_mostrar(); Type: FUNCTION; Schema: public; Owner: postgres
+--
+
+CREATE FUNCTION public.factura_mostrar() RETURNS TABLE(no integer, nombre character varying, id integer, numero integer, fecha date, hora time without time zone, total_bruto numeric, total_descuento numeric, total_impuesto numeric, total_cargo numeric, total_neto numeric)
+ LANGUAGE plpgsql
+ AS $$BEGIN
+RETURN QUERY
+SELECT s.clienteId N,
+s.clienteNombre Nombre,
+facturaId Id, facturaNumero Numero,
+cast(facturaFecha AS DATE) AS Fecha, cast(facturaFecha AS TIME) AS Hora,
+facturaTotalBruto AS Total_Bruto,
+facturaTotalDescto AS Total_Descuento,
+facturaTotalImpuesto AS Total_Impuesto,
+facturaTotalCargo AS Total_Cargo,
+facturaTotalNeto AS Total_Neto
+FROM factura o
+INNER JOIN ONLY cliente s
+ON o.clienteId = s.clienteId
+WHERE facturaEstatus = 'P'
+ORDER BY facturaId DESC
+LIMIT 200;
+END;$$;
+
+
+ALTER FUNCTION public.factura_mostrar() OWNER TO postgres;
+
+--
+-- TOC entry 237 (class 1255 OID 26129)
+-- Name: factura_mostrar(integer); Type: FUNCTION; Schema: public; Owner: postgres
+--
+
+CREATE FUNCTION public.factura_mostrar(numero integer) RETURNS TABLE(linea smallint, codigo_articulo character, articulo character varying, descripcion character varying, cantidad integer, precio numeric, descuento numeric, impuesto numeric, neto numeric)
+ LANGUAGE plpgsql
+ AS $$ BEGIN
+RETURN QUERY
+SELECT facturaLinea AS Linea,
+articuloCodigo AS Codigo_articulo,
+articuloNombre AS articulo,
+articuloDescripcion AS Descripcion,
+facturaCantidad AS Cantidad,
+facturaPrecio AS Precio,
+facturaDescuento AS Descuento,
+facturaImpuesto AS Impuesto,
+facturaNeto AS Neto
+FROM facturaDetalle d
+INNER JOIN ONLY articulo p
+ON d.articuloId = p.articuloId
+INNER JOIN factura o
+ON o.facturaId = d.facturaId
+WHERE o.facturaNumero = numero
+ORDER BY facturaLinea ASC
+LIMIT 15;
+END;$$;
+
+
+ALTER FUNCTION public.factura_mostrar(numero integer) OWNER TO postgres;
+
+--
+-- TOC entry 235 (class 1255 OID 26132)
+-- Name: facturadetalle_insertar(integer, integer, numeric, integer, numeric, numeric); Type: FUNCTION; Schema: public; Owner: postgres
+--
+
+CREATE FUNCTION public.facturadetalle_insertar(id integer, articuloid integer, precio numeric, cantidad integer, descuento numeric, impuesto numeric) RETURNS void
+ LANGUAGE plpgsql
+ AS $$
+DECLARE rprecio NUMERIC;
+BEGIN
+SELECT articuloprecio INTO rprecio FROM articulo;
+INSERT INTO facturadetalle(facturaid, articuloid,
+ facturaPrecio, facturaCantidad, facturaDescuento,
+ facturaImpuesto, facturaNeto)
+ VALUES
+ (
+ id, articuloid, rprecio, cantidad, descuento, impuesto ,
+ rprecio + impuesto - descuento);
+END; $$;
+
+
+ALTER FUNCTION public.facturadetalle_insertar(id integer, articuloid integer, precio numeric, cantidad integer, descuento numeric, impuesto numeric) OWNER TO postgres;
+
+--
+-- TOC entry 200 (class 1259 OID 26028)
+-- Name: articulo_articuloid_seq; Type: SEQUENCE; Schema: public; Owner: postgres
+--
+
+CREATE SEQUENCE public.articulo_articuloid_seq
+ START WITH 1
+ INCREMENT BY 1
+ NO MINVALUE
+ NO MAXVALUE
+ CACHE 1;
+
+
+ALTER TABLE public.articulo_articuloid_seq OWNER TO postgres;
+
+SET default_tablespace = '';
+
+SET default_with_oids = false;
+
+--
+-- TOC entry 201 (class 1259 OID 26034)
+-- Name: articulo; Type: TABLE; Schema: public; Owner: postgres
+--
+
+CREATE TABLE public.articulo (
+ articuloid integer DEFAULT nextval('public.articulo_articuloid_seq'::regclass) NOT NULL,
+ articulocodigo character(24),
+ articulonombre character varying(40) NOT NULL,
+ articulodescripcion character varying(512),
+ articulounidadesstock integer,
+ articuloprecio numeric(10,2),
+ articuloestatus character(1) DEFAULT 'A'::bpchar,
+ CONSTRAINT articulo_articulonombre_check CHECK (((articulonombre)::text <> ''::text)),
+ CONSTRAINT natural_unidadesstock CHECK ((articulounidadesstock >= 0)),
+ CONSTRAINT positivo_precio CHECK ((articuloprecio > (0)::numeric))
+);
+
+
+ALTER TABLE public.articulo OWNER TO postgres;
+
+--
+-- TOC entry 203 (class 1259 OID 26065)
+-- Name: articulohis; Type: TABLE; Schema: public; Owner: postgres
+--
+
+CREATE TABLE public.articulohis (
+ articulohisfecha timestamp with time zone DEFAULT CURRENT_TIMESTAMP(0)
+)
+INHERITS (public.articulo);
+
+
+ALTER TABLE public.articulohis OWNER TO postgres;
+
+--
+-- TOC entry 2952 (class 0 OID 0)
+-- Dependencies: 203
+-- Name: TABLE articulohis; Type: COMMENT; Schema: public; Owner: postgres
+--
+
+COMMENT ON TABLE public.articulohis IS 'Registra las purgaciones hechas en la tabla articulo.';
+
+
+--
+-- TOC entry 202 (class 1259 OID 26053)
+-- Name: articulolog; Type: TABLE; Schema: public; Owner: postgres
+--
+
+CREATE TABLE public.articulolog (
+ articulologusuario character varying(45),
+ articulologfecha timestamp with time zone DEFAULT CURRENT_TIMESTAMP(0)
+)
+INHERITS (public.articulo);
+
+
+ALTER TABLE public.articulolog OWNER TO postgres;
+
+--
+-- TOC entry 2954 (class 0 OID 0)
+-- Dependencies: 202
+-- Name: TABLE articulolog; Type: COMMENT; Schema: public; Owner: postgres
+--
+
+COMMENT ON TABLE public.articulolog IS 'Registra las inserciones hechas en la tabla articulo.';
+
+
+--
+-- TOC entry 196 (class 1259 OID 25980)
+-- Name: cliente_clienteid_seq; Type: SEQUENCE; Schema: public; Owner: postgres
+--
+
+CREATE SEQUENCE public.cliente_clienteid_seq
+ START WITH 1
+ INCREMENT BY 1
+ NO MINVALUE
+ NO MAXVALUE
+ CACHE 1;
+
+
+ALTER TABLE public.cliente_clienteid_seq OWNER TO postgres;
+
+--
+-- TOC entry 197 (class 1259 OID 25982)
+-- Name: cliente; Type: TABLE; Schema: public; Owner: postgres
+--
+
+CREATE TABLE public.cliente (
+ clienteid integer DEFAULT nextval('public.cliente_clienteid_seq'::regclass) NOT NULL,
+ clientenombre character varying(100) NOT NULL,
+ clienteemail character varying(254),
+ clientetelefono character varying(15),
+ clientedireccion character varying(95),
+ clientecodigopostal character varying(10),
+ clienteciudad character varying(35),
+ clientepais character varying(70),
+ clienteultimatransaccion timestamp with time zone DEFAULT CURRENT_TIMESTAMP(0),
+ clienteestatus character(1) DEFAULT 'A'::bpchar,
+ CONSTRAINT cliente_clientenombre_check CHECK (((clientenombre)::text <> ''::text))
+);
+
+
+ALTER TABLE public.cliente OWNER TO postgres;
+
+--
+-- TOC entry 198 (class 1259 OID 26000)
+-- Name: clientehis; Type: TABLE; Schema: public; Owner: postgres
+--
+
+CREATE TABLE public.clientehis (
+ clientehisfecha timestamp with time zone DEFAULT CURRENT_TIMESTAMP(0)
+)
+INHERITS (public.cliente);
+
+
+ALTER TABLE public.clientehis OWNER TO postgres;
+
+--
+-- TOC entry 2958 (class 0 OID 0)
+-- Dependencies: 198
+-- Name: TABLE clientehis; Type: COMMENT; Schema: public; Owner: postgres
+--
+
+COMMENT ON TABLE public.clientehis IS 'Registra las purgaciones hechas en la tabla cliente.';
+
+
+--
+-- TOC entry 199 (class 1259 OID 26011)
+-- Name: clientelog; Type: TABLE; Schema: public; Owner: postgres
+--
+
+CREATE TABLE public.clientelog (
+ clientelogusuario character varying(45),
+ clientelogfecha timestamp with time zone DEFAULT CURRENT_TIMESTAMP(0)
+)
+INHERITS (public.cliente);
+
+
+ALTER TABLE public.clientelog OWNER TO postgres;
+
+--
+-- TOC entry 2960 (class 0 OID 0)
+-- Dependencies: 199
+-- Name: TABLE clientelog; Type: COMMENT; Schema: public; Owner: postgres
+--
+
+COMMENT ON TABLE public.clientelog IS 'Registra las inserciones hechas en la tabla cliente.';
+
+
+--
+-- TOC entry 204 (class 1259 OID 26080)
+-- Name: factura_facturaid_seq; Type: SEQUENCE; Schema: public; Owner: postgres
+--
+
+CREATE SEQUENCE public.factura_facturaid_seq
+ START WITH 1
+ INCREMENT BY 1
+ NO MINVALUE
+ NO MAXVALUE
+ CACHE 1;
+
+
+ALTER TABLE public.factura_facturaid_seq OWNER TO postgres;
+
+--
+-- TOC entry 205 (class 1259 OID 26082)
+-- Name: factura; Type: TABLE; Schema: public; Owner: postgres
+--
+
+CREATE TABLE public.factura (
+ facturaid integer DEFAULT nextval('public.factura_facturaid_seq'::regclass) NOT NULL,
+ facturanumero integer DEFAULT currval('public.factura_facturaid_seq'::regclass) NOT NULL,
+ clienteid integer,
+ facturafecha timestamp with time zone DEFAULT CURRENT_TIMESTAMP(0) NOT NULL,
+ facturaestatus character(1) DEFAULT 'P'::bpchar,
+ facturatotalbruto numeric(12,2) DEFAULT 0.00,
+ facturatotaldescto numeric(8,2) DEFAULT 0.00,
+ facturatotalimpuesto numeric(8,2) DEFAULT 0.00,
+ facturatotalcargo numeric(8,2) DEFAULT 200.00,
+ facturatotalneto numeric(12,2) DEFAULT 0.00
+);
+
+
+ALTER TABLE public.factura OWNER TO postgres;
+
+--
+-- TOC entry 206 (class 1259 OID 26101)
+-- Name: facturadetalle_facturalinea_seq; Type: SEQUENCE; Schema: public; Owner: postgres
+--
+
+CREATE SEQUENCE public.facturadetalle_facturalinea_seq
+ START WITH 1
+ INCREMENT BY 1
+ NO MINVALUE
+ NO MAXVALUE
+ CACHE 1;
+
+
+ALTER TABLE public.facturadetalle_facturalinea_seq OWNER TO postgres;
+
+--
+-- TOC entry 207 (class 1259 OID 26103)
+-- Name: facturadetalle; Type: TABLE; Schema: public; Owner: postgres
+--
+
+CREATE TABLE public.facturadetalle (
+ facturalinea smallint DEFAULT nextval('public.facturadetalle_facturalinea_seq'::regclass) NOT NULL,
+ facturaid integer NOT NULL,
+ articuloid integer,
+ facturacantidad integer,
+ facturaprecio numeric(10,2),
+ facturadescuento numeric(8,2) DEFAULT 0.00,
+ facturaimpuesto numeric(8,2) DEFAULT 0.00,
+ facturaneto numeric(10,2) DEFAULT 0.00,
+ CONSTRAINT natural_cantidad CHECK ((facturacantidad > 0))
+);
+
+
+ALTER TABLE public.facturadetalle OWNER TO postgres;
+
+--
+-- TOC entry 2756 (class 2604 OID 26068)
+-- Name: articulohis articuloid; Type: DEFAULT; Schema: public; Owner: postgres
+--
+
+ALTER TABLE ONLY public.articulohis ALTER COLUMN articuloid SET DEFAULT nextval('public.articulo_articuloid_seq'::regclass);
+
+
+--
+-- TOC entry 2757 (class 2604 OID 26069)
+-- Name: articulohis articuloestatus; Type: DEFAULT; Schema: public; Owner: postgres
+--
+
+ALTER TABLE ONLY public.articulohis ALTER COLUMN articuloestatus SET DEFAULT 'A'::bpchar;
+
+
+--
+-- TOC entry 2750 (class 2604 OID 26056)
+-- Name: articulolog articuloid; Type: DEFAULT; Schema: public; Owner: postgres
+--
+
+ALTER TABLE ONLY public.articulolog ALTER COLUMN articuloid SET DEFAULT nextval('public.articulo_articuloid_seq'::regclass);
+
+
+--
+-- TOC entry 2751 (class 2604 OID 26057)
+-- Name: articulolog articuloestatus; Type: DEFAULT; Schema: public; Owner: postgres
+--
+
+ALTER TABLE ONLY public.articulolog ALTER COLUMN articuloestatus SET DEFAULT 'A'::bpchar;
+
+
+--
+-- TOC entry 2735 (class 2604 OID 26003)
+-- Name: clientehis clienteid; Type: DEFAULT; Schema: public; Owner: postgres
+--
+
+ALTER TABLE ONLY public.clientehis ALTER COLUMN clienteid SET DEFAULT nextval('public.cliente_clienteid_seq'::regclass);
+
+
+--
+-- TOC entry 2736 (class 2604 OID 26004)
+-- Name: clientehis clienteultimatransaccion; Type: DEFAULT; Schema: public; Owner: postgres
+--
+
+ALTER TABLE ONLY public.clientehis ALTER COLUMN clienteultimatransaccion SET DEFAULT CURRENT_TIMESTAMP(0);
+
+
+--
+-- TOC entry 2737 (class 2604 OID 26005)
+-- Name: clientehis clienteestatus; Type: DEFAULT; Schema: public; Owner: postgres
+--
+
+ALTER TABLE ONLY public.clientehis ALTER COLUMN clienteestatus SET DEFAULT 'A'::bpchar;
+
+
+--
+-- TOC entry 2740 (class 2604 OID 26014)
+-- Name: clientelog clienteid; Type: DEFAULT; Schema: public; Owner: postgres
+--
+
+ALTER TABLE ONLY public.clientelog ALTER COLUMN clienteid SET DEFAULT nextval('public.cliente_clienteid_seq'::regclass);
+
+
+--
+-- TOC entry 2741 (class 2604 OID 26015)
+-- Name: clientelog clienteultimatransaccion; Type: DEFAULT; Schema: public; Owner: postgres
+--
+
+ALTER TABLE ONLY public.clientelog ALTER COLUMN clienteultimatransaccion SET DEFAULT CURRENT_TIMESTAMP(0);
+
+
+--
+-- TOC entry 2742 (class 2604 OID 26016)
+-- Name: clientelog clienteestatus; Type: DEFAULT; Schema: public; Owner: postgres
+--
+
+ALTER TABLE ONLY public.clientelog ALTER COLUMN clienteestatus SET DEFAULT 'A'::bpchar;
+
+
+--
+-- TOC entry 2785 (class 2606 OID 26046)
+-- Name: articulo pk_articulo; Type: CONSTRAINT; Schema: public; Owner: postgres
+--
+
+ALTER TABLE ONLY public.articulo
+ ADD CONSTRAINT pk_articulo PRIMARY KEY (articuloid);
+
+
+--
+-- TOC entry 2777 (class 2606 OID 25993)
+-- Name: cliente pk_cliente; Type: CONSTRAINT; Schema: public; Owner: postgres
+--
+
+ALTER TABLE ONLY public.cliente
+ ADD CONSTRAINT pk_cliente PRIMARY KEY (clienteid);
+
+
+--
+-- TOC entry 2789 (class 2606 OID 26095)
+-- Name: factura pk_factura; Type: CONSTRAINT; Schema: public; Owner: postgres
+--
+
+ALTER TABLE ONLY public.factura
+ ADD CONSTRAINT pk_factura PRIMARY KEY (facturaid);
+
+
+--
+-- TOC entry 2791 (class 2606 OID 26112)
+-- Name: facturadetalle pk_facturadetalle; Type: CONSTRAINT; Schema: public; Owner: postgres
+--
+
+ALTER TABLE ONLY public.facturadetalle
+ ADD CONSTRAINT pk_facturadetalle PRIMARY KEY (facturalinea, facturaid);
+
+
+--
+-- TOC entry 2787 (class 2606 OID 26048)
+-- Name: articulo un_articulocodigo; Type: CONSTRAINT; Schema: public; Owner: postgres
+--
+
+ALTER TABLE ONLY public.articulo
+ ADD CONSTRAINT un_articulocodigo UNIQUE (articulocodigo);
+
+
+--
+-- TOC entry 2779 (class 2606 OID 25995)
+-- Name: cliente un_clientedireccion; Type: CONSTRAINT; Schema: public; Owner: postgres
+--
+
+ALTER TABLE ONLY public.cliente
+ ADD CONSTRAINT un_clientedireccion UNIQUE (clientedireccion);
+
+
+--
+-- TOC entry 2781 (class 2606 OID 25997)
+-- Name: cliente un_clienteemail; Type: CONSTRAINT; Schema: public; Owner: postgres
+--
+
+ALTER TABLE ONLY public.cliente
+ ADD CONSTRAINT un_clienteemail UNIQUE (clienteemail);
+
+
+--
+-- TOC entry 2783 (class 2606 OID 25999)
+-- Name: cliente un_clientetelefono; Type: CONSTRAINT; Schema: public; Owner: postgres
+--
+
+ALTER TABLE ONLY public.cliente
+ ADD CONSTRAINT un_clientetelefono UNIQUE (clientetelefono);
+
+
+--
+-- TOC entry 2802 (class 2620 OID 26124)
+-- Name: facturadetalle Factura_TOTAL; Type: TRIGGER; Schema: public; Owner: postgres
+--
+
+CREATE TRIGGER "Factura_TOTAL" AFTER INSERT ON public.facturadetalle FOR EACH ROW EXECUTE PROCEDURE public."Calcular_factura_TOTAL"();
+
+
+--
+-- TOC entry 2795 (class 2620 OID 26023)
+-- Name: cliente HISTORICO; Type: TRIGGER; Schema: public; Owner: postgres
+--
+
+CREATE TRIGGER "HISTORICO" AFTER DELETE ON public.cliente FOR EACH ROW EXECUTE PROCEDURE public."Cliente_HISTORICO"();
+
+
+--
+-- TOC entry 2798 (class 2620 OID 26050)
+-- Name: articulo HISTORICO; Type: TRIGGER; Schema: public; Owner: postgres
+--
+
+CREATE TRIGGER "HISTORICO" AFTER DELETE ON public.articulo FOR EACH ROW EXECUTE PROCEDURE public."Articulo_HISTORICO"();
+
+
+--
+-- TOC entry 2796 (class 2620 OID 26025)
+-- Name: cliente LOG; Type: TRIGGER; Schema: public; Owner: postgres
+--
+
+CREATE TRIGGER "LOG" AFTER INSERT OR UPDATE ON public.cliente FOR EACH ROW EXECUTE PROCEDURE public."Cliente_LOG"();
+
+
+--
+-- TOC entry 2799 (class 2620 OID 26052)
+-- Name: articulo LOG; Type: TRIGGER; Schema: public; Owner: postgres
+--
+
+CREATE TRIGGER "LOG" AFTER INSERT OR UPDATE ON public.articulo FOR EACH ROW EXECUTE PROCEDURE public."Articulo_LOG"();
+
+
+--
+-- TOC entry 2797 (class 2620 OID 26027)
+-- Name: cliente PURGACION; Type: TRIGGER; Schema: public; Owner: postgres
+--
+
+CREATE TRIGGER "PURGACION" AFTER INSERT OR UPDATE ON public.cliente FOR EACH ROW EXECUTE PROCEDURE public."Cliente_PURGAR"();
+
+
+--
+-- TOC entry 2800 (class 2620 OID 26137)
+-- Name: factura SUMACARGO; Type: TRIGGER; Schema: public; Owner: postgres
+--
+
+CREATE TRIGGER "SUMACARGO" AFTER INSERT ON public.factura FOR EACH ROW EXECUTE PROCEDURE public."Sumar_Cargo"();
+
+
+--
+-- TOC entry 2801 (class 2620 OID 26126)
+-- Name: factura ULTIMO_ACCESO; Type: TRIGGER; Schema: public; Owner: postgres
+--
+
+CREATE TRIGGER "ULTIMO_ACCESO" AFTER INSERT ON public.factura FOR EACH ROW EXECUTE PROCEDURE public."Cliente_ACCESO"();
+
+
+--
+-- TOC entry 2792 (class 2606 OID 26096)
+-- Name: factura FK_clienteId; Type: FK CONSTRAINT; Schema: public; Owner: postgres
+--
+
+ALTER TABLE ONLY public.factura
+ ADD CONSTRAINT "FK_clienteId" FOREIGN KEY (clienteid) REFERENCES public.cliente(clienteid);
+
+
+--
+-- TOC entry 2794 (class 2606 OID 26118)
+-- Name: facturadetalle fk_articuloid; Type: FK CONSTRAINT; Schema: public; Owner: postgres
+--
+
+ALTER TABLE ONLY public.facturadetalle
+ ADD CONSTRAINT fk_articuloid FOREIGN KEY (articuloid) REFERENCES public.articulo(articuloid);
+
+
+--
+-- TOC entry 2793 (class 2606 OID 26113)
+-- Name: facturadetalle fk_facturaid; Type: FK CONSTRAINT; Schema: public; Owner: postgres
+--
+
+ALTER TABLE ONLY public.facturadetalle
+ ADD CONSTRAINT fk_facturaid FOREIGN KEY (facturaid) REFERENCES public.factura(facturaid) ON UPDATE CASCADE ON DELETE CASCADE;
+
+
+--
+-- TOC entry 2932 (class 0 OID 0)
+-- Dependencies: 227
+-- Name: FUNCTION "Articulo_HISTORICO"(); Type: ACL; Schema: public; Owner: postgres
+--
+
+GRANT ALL ON FUNCTION public."Articulo_HISTORICO"() TO usuario;
+
+
+--
+-- TOC entry 2933 (class 0 OID 0)
+-- Dependencies: 228
+-- Name: FUNCTION "Articulo_LOG"(); Type: ACL; Schema: public; Owner: postgres
+--
+
+GRANT ALL ON FUNCTION public."Articulo_LOG"() TO usuario;
+
+
+--
+-- TOC entry 2934 (class 0 OID 0)
+-- Dependencies: 233
+-- Name: FUNCTION "Calcular_factura_TOTAL"(); Type: ACL; Schema: public; Owner: postgres
+--
+
+GRANT ALL ON FUNCTION public."Calcular_factura_TOTAL"() TO usuario;
+
+
+--
+-- TOC entry 2935 (class 0 OID 0)
+-- Dependencies: 232
+-- Name: FUNCTION "Cliente_ACCESO"(); Type: ACL; Schema: public; Owner: postgres
+--
+
+GRANT ALL ON FUNCTION public."Cliente_ACCESO"() TO usuario;
+
+
+--
+-- TOC entry 2936 (class 0 OID 0)
+-- Dependencies: 208
+-- Name: FUNCTION "Cliente_HISTORICO"(); Type: ACL; Schema: public; Owner: postgres
+--
+
+GRANT ALL ON FUNCTION public."Cliente_HISTORICO"() TO usuario;
+
+
+--
+-- TOC entry 2937 (class 0 OID 0)
+-- Dependencies: 209
+-- Name: FUNCTION "Cliente_LOG"(); Type: ACL; Schema: public; Owner: postgres
+--
+
+GRANT ALL ON FUNCTION public."Cliente_LOG"() TO usuario;
+
+
+--
+-- TOC entry 2938 (class 0 OID 0)
+-- Dependencies: 210
+-- Name: FUNCTION "Cliente_PURGAR"(); Type: ACL; Schema: public; Owner: postgres
+--
+
+GRANT ALL ON FUNCTION public."Cliente_PURGAR"() TO usuario;
+
+
+--
+-- TOC entry 2939 (class 0 OID 0)
+-- Dependencies: 234
+-- Name: FUNCTION "Sumar_Cargo"(); Type: ACL; Schema: public; Owner: postgres
+--
+
+GRANT ALL ON FUNCTION public."Sumar_Cargo"() TO usuario;
+
+
+--
+-- TOC entry 2940 (class 0 OID 0)
+-- Dependencies: 229
+-- Name: FUNCTION articulo_buscar(nom character varying); Type: ACL; Schema: public; Owner: postgres
+--
+
+GRANT ALL ON FUNCTION public.articulo_buscar(nom character varying) TO usuario;
+
+
+--
+-- TOC entry 2941 (class 0 OID 0)
+-- Dependencies: 230
+-- Name: FUNCTION articulo_mostrar(); Type: ACL; Schema: public; Owner: postgres
+--
+
+GRANT ALL ON FUNCTION public.articulo_mostrar() TO usuario;
+
+
+--
+-- TOC entry 2942 (class 0 OID 0)
+-- Dependencies: 231
+-- Name: FUNCTION articulo_mostraractivos(); Type: ACL; Schema: public; Owner: postgres
+--
+
+GRANT ALL ON FUNCTION public.articulo_mostraractivos() TO usuario;
+
+
+--
+-- TOC entry 2943 (class 0 OID 0)
+-- Dependencies: 211
+-- Name: FUNCTION cliente_buscar(nom character varying); Type: ACL; Schema: public; Owner: postgres
+--
+
+GRANT ALL ON FUNCTION public.cliente_buscar(nom character varying) TO usuario;
+
+
+--
+-- TOC entry 2944 (class 0 OID 0)
+-- Dependencies: 224
+-- Name: FUNCTION cliente_buscaractivos(nom character varying); Type: ACL; Schema: public; Owner: postgres
+--
+
+GRANT ALL ON FUNCTION public.cliente_buscaractivos(nom character varying) TO usuario;
+
+
+--
+-- TOC entry 2945 (class 0 OID 0)
+-- Dependencies: 225
+-- Name: FUNCTION cliente_mostrar(); Type: ACL; Schema: public; Owner: postgres
+--
+
+GRANT ALL ON FUNCTION public.cliente_mostrar() TO usuario;
+
+
+--
+-- TOC entry 2946 (class 0 OID 0)
+-- Dependencies: 226
+-- Name: FUNCTION cliente_mostraractivos(); Type: ACL; Schema: public; Owner: postgres
+--
+
+GRANT ALL ON FUNCTION public.cliente_mostraractivos() TO usuario;
+
+
+--
+-- TOC entry 2947 (class 0 OID 0)
+-- Dependencies: 236
+-- Name: FUNCTION factura_mostrar(); Type: ACL; Schema: public; Owner: postgres
+--
+
+GRANT ALL ON FUNCTION public.factura_mostrar() TO usuario;
+
+
+--
+-- TOC entry 2948 (class 0 OID 0)
+-- Dependencies: 237
+-- Name: FUNCTION factura_mostrar(numero integer); Type: ACL; Schema: public; Owner: postgres
+--
+
+GRANT ALL ON FUNCTION public.factura_mostrar(numero integer) TO usuario;
+
+
+--
+-- TOC entry 2949 (class 0 OID 0)
+-- Dependencies: 235
+-- Name: FUNCTION facturadetalle_insertar(id integer, articuloid integer, precio numeric, cantidad integer, descuento numeric, impuesto numeric); Type: ACL; Schema: public; Owner: postgres
+--
+
+GRANT ALL ON FUNCTION public.facturadetalle_insertar(id integer, articuloid integer, precio numeric, cantidad integer, descuento numeric, impuesto numeric) TO usuario;
+
+
+--
+-- TOC entry 2950 (class 0 OID 0)
+-- Dependencies: 200
+-- Name: SEQUENCE articulo_articuloid_seq; Type: ACL; Schema: public; Owner: postgres
+--
+
+GRANT SELECT,USAGE ON SEQUENCE public.articulo_articuloid_seq TO usuario;
+
+
+--
+-- TOC entry 2951 (class 0 OID 0)
+-- Dependencies: 201
+-- Name: TABLE articulo; Type: ACL; Schema: public; Owner: postgres
+--
+
+GRANT ALL ON TABLE public.articulo TO usuario;
+
+
+--
+-- TOC entry 2953 (class 0 OID 0)
+-- Dependencies: 203
+-- Name: TABLE articulohis; Type: ACL; Schema: public; Owner: postgres
+--
+
+GRANT ALL ON TABLE public.articulohis TO usuario;
+
+
+--
+-- TOC entry 2955 (class 0 OID 0)
+-- Dependencies: 202
+-- Name: TABLE articulolog; Type: ACL; Schema: public; Owner: postgres
+--
+
+GRANT ALL ON TABLE public.articulolog TO usuario;
+
+
+--
+-- TOC entry 2956 (class 0 OID 0)
+-- Dependencies: 196
+-- Name: SEQUENCE cliente_clienteid_seq; Type: ACL; Schema: public; Owner: postgres
+--
+
+GRANT SELECT,USAGE ON SEQUENCE public.cliente_clienteid_seq TO usuario;
+
+
+--
+-- TOC entry 2957 (class 0 OID 0)
+-- Dependencies: 197
+-- Name: TABLE cliente; Type: ACL; Schema: public; Owner: postgres
+--
+
+GRANT ALL ON TABLE public.cliente TO usuario;
+
+
+--
+-- TOC entry 2959 (class 0 OID 0)
+-- Dependencies: 198
+-- Name: TABLE clientehis; Type: ACL; Schema: public; Owner: postgres
+--
+
+GRANT ALL ON TABLE public.clientehis TO usuario;
+
+
+--
+-- TOC entry 2961 (class 0 OID 0)
+-- Dependencies: 199
+-- Name: TABLE clientelog; Type: ACL; Schema: public; Owner: postgres
+--
+
+GRANT ALL ON TABLE public.clientelog TO usuario;
+
+
+--
+-- TOC entry 2962 (class 0 OID 0)
+-- Dependencies: 204
+-- Name: SEQUENCE factura_facturaid_seq; Type: ACL; Schema: public; Owner: postgres
+--
+
+GRANT SELECT,USAGE ON SEQUENCE public.factura_facturaid_seq TO usuario;
+
+
+--
+-- TOC entry 2963 (class 0 OID 0)
+-- Dependencies: 205
+-- Name: TABLE factura; Type: ACL; Schema: public; Owner: postgres
+--
+
+GRANT ALL ON TABLE public.factura TO usuario;
+
+
+--
+-- TOC entry 2964 (class 0 OID 0)
+-- Dependencies: 206
+-- Name: SEQUENCE facturadetalle_facturalinea_seq; Type: ACL; Schema: public; Owner: postgres
+--
+
+GRANT SELECT,USAGE ON SEQUENCE public.facturadetalle_facturalinea_seq TO usuario;
+
+
+--
+-- TOC entry 2965 (class 0 OID 0)
+-- Dependencies: 207
+-- Name: TABLE facturadetalle; Type: ACL; Schema: public; Owner: postgres
+--
+
+GRANT ALL ON TABLE public.facturadetalle TO usuario;
+
+
+--
+-- TOC entry 1728 (class 826 OID 25978)
+-- Name: DEFAULT PRIVILEGES FOR SEQUENCES; Type: DEFAULT ACL; Schema: -; Owner: postgres
+--
+
+ALTER DEFAULT PRIVILEGES FOR ROLE postgres GRANT SELECT,USAGE ON SEQUENCES TO usuario;
+
+
+--
+-- TOC entry 1729 (class 826 OID 25979)
+-- Name: DEFAULT PRIVILEGES FOR FUNCTIONS; Type: DEFAULT ACL; Schema: -; Owner: postgres
+--
+
+ALTER DEFAULT PRIVILEGES FOR ROLE postgres GRANT ALL ON FUNCTIONS TO usuario;
+
+
+--
+-- TOC entry 1727 (class 826 OID 25977)
+-- Name: DEFAULT PRIVILEGES FOR TABLES; Type: DEFAULT ACL; Schema: -; Owner: postgres
+--
+
+ALTER DEFAULT PRIVILEGES FOR ROLE postgres GRANT ALL ON TABLES TO usuario;
+
+
+-- Completed on 2019-04-24 11:56:12
+
+--
+-- PostgreSQL database dump complete
+--
+
diff --git a/factura-ventas.iml b/factura-ventas.iml
new file mode 100644
index 0000000..ec07972
--- /dev/null
+++ b/factura-ventas.iml
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/META-INF/MANIFEST.MF b/src/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..4f412c9
--- /dev/null
+++ b/src/META-INF/MANIFEST.MF
@@ -0,0 +1,3 @@
+Manifest-Version: 1.0
+Main-Class: view.Main
+
diff --git a/src/business/Articulo.java b/src/business/Articulo.java
new file mode 100644
index 0000000..9eaa16b
--- /dev/null
+++ b/src/business/Articulo.java
@@ -0,0 +1,39 @@
+package business;
+
+import data.Estatus;
+import javafx.collections.ObservableList;
+
+import java.math.BigDecimal;
+
+public class Articulo {
+
+ private Articulo() {
+
+ }
+
+ public static String insertar(String codigo, String nombre, String descripcion, BigDecimal precio,
+ int unidadesStock) {
+ data.Articulo articulo = new data.Articulo(codigo, nombre, descripcion, precio, unidadesStock);
+ return articulo.insertar(articulo);
+ }
+
+ public static String actualizar(int id, String codigo, String nombre, String descripcion, BigDecimal precio,
+ int unidadesStock, Estatus estatus) {
+ data.Articulo articulo = new data.Articulo(id, codigo, nombre, descripcion, precio, unidadesStock, estatus);
+ return articulo.actualizar(articulo);
+ }
+
+ public static ObservableList buscar(String textoABuscar) {
+ data.Articulo articulo = new data.Articulo(textoABuscar);
+ return articulo.buscar(articulo);
+ }
+
+ public static ObservableList mostrar() {
+ return new data.Articulo().mostrar();
+ }
+
+ public static ObservableList mostrarActivos() {
+ return new data.Articulo().mostrarActivos();
+ }
+
+}
diff --git a/src/business/Cliente.java b/src/business/Cliente.java
new file mode 100644
index 0000000..98ec067
--- /dev/null
+++ b/src/business/Cliente.java
@@ -0,0 +1,45 @@
+package business;
+
+import data.Estatus;
+import javafx.collections.ObservableList;
+
+public class Cliente {
+
+ private Cliente(){
+
+ }
+
+ public static String insertar(String nombre, String direccion, String ciudad, String email,
+ String telefono, String codigoPostal, String pais) {
+ data.Cliente cliente = new data.Cliente(nombre, direccion, ciudad, email,
+ telefono, codigoPostal, pais);
+
+ return new data.Cliente().insertar(cliente);
+ }
+
+ public static String actualizar(int id, String nombre, String direccion, String ciudad, String email,
+ String telefono, String codigoPostal, String pais, Estatus estatus) {
+ data.Cliente cliente = new data.Cliente(id, nombre, direccion, ciudad, email,
+ telefono, codigoPostal, pais, estatus);
+ return new data.Cliente().actualizar(cliente);
+ }
+
+ public static ObservableList buscar(String textoABuscar) {
+ //data.Cliente cliente = new data.Cliente(textoABuscar);
+ return new data.Cliente().buscar(textoABuscar);
+ }
+
+ public static ObservableList buscarActivos(String textoABuscar) {
+ //data.Cliente cliente = new data.Cliente(textoABuscar);
+ return new data.Cliente().buscarActivos(textoABuscar);
+ }
+
+ public static ObservableList mostrar() {
+ return new data.Cliente().mostrar();
+ }
+
+ public static ObservableList mostrarActivos() {
+ return new data.Cliente().mostrarActivos();
+ }
+
+}
diff --git a/src/business/Factura.java b/src/business/Factura.java
new file mode 100644
index 0000000..b1fcc6b
--- /dev/null
+++ b/src/business/Factura.java
@@ -0,0 +1,30 @@
+package business;
+
+import data.FacturaDetalle;
+import javafx.collections.ObservableList;
+
+public class Factura {
+
+ private Factura() {
+
+ }
+
+
+ // Listo.
+ public static String eliminar(int id) {
+ data.Factura factura = new data.Factura(id);
+ return new data.Factura().eliminar(factura);
+ }
+
+ // Listo.
+ public static ObservableList mostrar() {
+ return new data.Factura().mostrar();
+ }
+
+ // Listo.
+ public static ObservableList mostrarDetalles(int numero) {
+ data.Factura factura = new data.Factura();
+ return factura.mostrarDetalles(numero);
+ }
+
+}
\ No newline at end of file
diff --git a/src/data/Articulo.java b/src/data/Articulo.java
new file mode 100644
index 0000000..43c3f5a
--- /dev/null
+++ b/src/data/Articulo.java
@@ -0,0 +1,276 @@
+package data;
+
+import javafx.collections.FXCollections;
+import javafx.collections.ObservableList;
+
+import java.math.BigDecimal;
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.text.DecimalFormat;
+import java.util.HashMap;
+import java.util.Objects;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+public class Articulo {
+
+ private int id_;
+ private String nombre_;
+ private String descripcion_;
+ private BigDecimal precio_;
+ private int unidadesStock_;
+ private String codigo_;
+ private Estatus estatus_;
+
+ private String textoABuscar_;
+
+ // Para realizar consultas a la base de datos.
+ public Articulo() {
+
+ }
+
+ // Para actualizar.
+ public Articulo(int id, String codigo, String nombre, String descripcion,
+ BigDecimal precio, int unidadesStock, Estatus estatus) {
+ this(codigo, nombre, descripcion, precio, unidadesStock);
+ setEstatus(estatus);
+ setId(id);
+ }
+
+ // Para insertar
+ public Articulo(String codigo, String nombre, String descripcion,
+ BigDecimal precio, int unidadesStock) {
+ setCodigo(codigo);
+ setNombre(nombre);
+ setDescripcion(descripcion);
+ setPrecio(precio);
+ setUnidadesStock(unidadesStock);
+ }
+
+ // Para buscar
+ public Articulo(String textoABuscar) {
+ setTextoABuscar(textoABuscar);
+ }
+
+ // Para eliminar
+ public Articulo(int id){
+ setId(id);
+ }
+
+ public String insertar(Articulo articulo) {
+ String mensaje;
+ try (Connection conn = Conexion.conectar()) {
+ try (PreparedStatement query = conn.prepareStatement("INSERT INTO Articulo(ArticuloCodigo, ArticuloNombre, "
+ + "ArticuloDescripcion, ArticuloPrecio, ArticuloUnidadesStock) VALUES (?, ?, ?, ?, ?);")) {
+ query.setString(1, articulo.codigo_);
+ query.setString(2, articulo.nombre_);
+ query.setString(3, articulo.descripcion_);
+ query.setBigDecimal(4, articulo.precio_);
+ query.setInt(5, articulo.unidadesStock_);
+
+ boolean esEjecutado = (query.executeUpdate() > 0);
+ if (esEjecutado) {
+ mensaje = "El registro ha sido agregado exitosamente.";
+ } else {
+ throw new SQLException("El registro no pudo ser agregado correctamente.");
+ }
+ } catch (SQLException ex) {
+ mensaje = ex.getMessage();
+ Logger.getLogger(Articulo.class.getName()).log(Level.SEVERE, null, ex);
+ }
+
+ } catch (SQLException ex) {
+ mensaje = "La conexion a la base de datos no pudo ser realizada exitosamente.";
+ Logger.getLogger(Articulo.class.getName()).log(Level.SEVERE, null, ex);
+ }
+
+ return mensaje;
+ }
+
+ public String actualizar(Articulo articulo) {
+ String mensaje;
+ try (Connection conn = Conexion.conectar()) {
+ try (PreparedStatement query = conn.prepareStatement("UPDATE ONLY Articulo SET ArticuloCodigo = ?, " +
+ "ArticuloNombre = ?, ArticuloDescripcion = ?, ArticuloPrecio = ?, ArticuloUnidadesStock = ?,"
+ + "ArticuloEstatus = ? WHERE ArticuloId = ?;")) {
+ query.setString(1, articulo.codigo_);
+ query.setString(2, articulo.nombre_);
+ query.setString(3, articulo.descripcion_);
+ query.setBigDecimal(4, articulo.precio_);
+ query.setInt(5, articulo.unidadesStock_);
+ query.setString(6, articulo.getEstatus().getChar());
+ query.setInt(7, articulo.id_); // Modificar
+
+ boolean esEjecutado = (query.executeUpdate() > 0);
+ if (esEjecutado) {
+ mensaje = "El registro ha sido actualizado exitosamente.";
+ } else {
+ throw new SQLException("El registro no pudo ser actualizado correctamente.");
+ }
+ } catch (SQLException ex) {
+ mensaje = ex.getMessage();
+ Logger.getLogger(Articulo.class.getName()).log(Level.SEVERE, null, ex);
+
+ }
+ } catch (SQLException ex) {
+ mensaje = "La conexion a la base de datos no pudo ser realizada exitosamente.";
+ Logger.getLogger(Articulo.class.getName()).log(Level.SEVERE, null, ex);
+ }
+
+ return mensaje;
+
+ }
+
+ public ObservableList buscar(Articulo articulo) {
+ ObservableList data = FXCollections.observableArrayList();
+ try (Connection conn = Conexion.conectar()) {
+ PreparedStatement query = conn.prepareStatement("SELECT * from articulo_buscar(?)");
+ query.setString(1, articulo.textoABuscar_);
+ data = leer(query.executeQuery());
+ } catch (SQLException ex) {
+ Logger.getLogger(Articulo.class.getName()).log(Level.SEVERE, null, ex);
+ }
+
+ return data;
+ }
+
+ public ObservableList mostrar() {
+ ObservableList data = FXCollections.observableArrayList();
+ try (Connection conn = Conexion.conectar()) {
+ PreparedStatement query = conn.prepareStatement("SELECT * from articulo_mostrar()");
+ data = leer(query.executeQuery());
+ } catch (SQLException ex) {
+ Logger.getLogger(Articulo.class.getName()).log(Level.SEVERE, null, ex);
+ }
+
+ return data;
+ }
+
+ public ObservableList mostrarActivos() {
+ ObservableList data = FXCollections.observableArrayList();
+ try (Connection conn = Conexion.conectar()) {
+ PreparedStatement query = conn.prepareStatement("SELECT * from articulo_mostraractivos()");
+ data = leer(query.executeQuery());
+ } catch (SQLException ex) {
+ Logger.getLogger(Articulo.class.getName()).log(Level.SEVERE, null, ex);
+ }
+ return data;
+ }
+
+ private ObservableList leer(ResultSet resultSet) throws SQLException {
+ ObservableList data = FXCollections.observableArrayList();
+ while (resultSet.next()) {
+ data.add(crear(resultSet));
+ }
+ return data;
+ }
+
+ private Articulo crear(ResultSet resultSet) throws SQLException {
+ int no = resultSet.getInt("Id");
+ final String nombre = resultSet.getString("Nombre");
+ final String descripcion = resultSet.getString("Descripcion");
+ final BigDecimal precio = resultSet.getBigDecimal("Precio");
+ final int unidadesStock = resultSet.getInt("Unidades_Stock");
+ final String codigo = resultSet.getString("Codigo");
+ Articulo articulo = new Articulo(codigo, nombre, descripcion, precio, unidadesStock);
+ articulo.setId(no);
+
+ // Set Estatus.
+ HashMap opciones = new HashMap<>();
+ opciones.put(Estatus.ACTIVO.getChar(), Estatus.ACTIVO);
+ opciones.put(Estatus.INACTIVO.getChar(), Estatus.INACTIVO);
+ final Estatus estatus = opciones.get(resultSet.getString("Estatus"));
+ articulo.setEstatus(estatus);
+
+ return articulo;
+ }
+
+ public int getId() {
+ return id_;
+ }
+
+ public String getNombre() {
+ return nombre_;
+ }
+
+ public String getDescripcion() {
+ return descripcion_;
+ }
+
+ public BigDecimal getPrecio() {
+ return precio_;
+ }
+
+ public int getUnidadesStock() {
+ return unidadesStock_;
+ }
+
+ public String getCodigo() {
+ return codigo_;
+ }
+
+ public Estatus getEstatus() {
+ return estatus_;
+ }
+
+ private void setId(int id) {
+ id_ = id;
+ }
+
+ public void setNombre(String nombre) {
+ nombre_ = nombre;
+ }
+
+ public void setDescripcion(String descripcion) {
+ descripcion_ = descripcion;
+ }
+
+ public void setPrecio(BigDecimal precio) {
+ precio_ = precio;
+ }
+
+ public void setUnidadesStock(int unidadesStock) {
+ unidadesStock_ = unidadesStock;
+ }
+
+ public void setCodigo(String codigo) {
+ codigo_ = codigo;
+ }
+
+ public void setEstatus(Estatus estatus) {
+ estatus_ = estatus;
+ }
+
+ private void setTextoABuscar(String textoABuscar) {
+ textoABuscar_ = textoABuscar;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (!(o instanceof Articulo)) return false;
+ Articulo articulo = (Articulo) o;
+ return Objects.equals(codigo_, articulo.codigo_);
+ }
+
+ @Override
+ public int hashCode() {
+
+ return Objects.hash(codigo_);
+ }
+
+ @Override
+ public String toString() {
+ DecimalFormat f = new DecimalFormat("###,##0.00");
+ return "Articulo{" +
+ "id_=" + id_ +
+ ", codigo_='" + codigo_ + '\'' +
+ ", nombre_='" + nombre_ + '\'' +
+ ", descripcion_='" + descripcion_ + '\'' +
+ ", unidadesStock_=" + unidadesStock_ +
+ ", precio_=" + f.format(precio_) +
+ ", estatus_=" + estatus_ + '}';
+ }
+}
diff --git a/src/data/Cliente.java b/src/data/Cliente.java
new file mode 100644
index 0000000..9cb2cbd
--- /dev/null
+++ b/src/data/Cliente.java
@@ -0,0 +1,302 @@
+package data;
+
+import javafx.collections.FXCollections;
+import javafx.collections.ObservableList;
+
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.HashMap;
+import java.util.Objects;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+public class Cliente {
+
+ private int id_;
+ private String nombre_;
+ private String direccion_;
+ private String ciudad_;
+ private String email_;
+ private String telefono_;
+ private String codigoPostal_;
+ private String pais_;
+ private Estatus estatus_;
+
+ public Cliente() {
+ }
+
+ public Cliente(int id) {
+ setId(id);
+ }
+
+ // Para actualizar
+ public Cliente(int id, String nombre, String direccion, String ciudad, String email,
+ String telefono, String codigoPostal, String pais, Estatus estatus) {
+ this(nombre, direccion, ciudad, email, telefono, codigoPostal, pais); // Constructor de insertar
+ setEstatus(estatus);
+ setId(id);
+ }
+
+ // Para insertar
+ public Cliente(String nombre, String direccion, String ciudad, String email,
+ String telefono, String codigoPostal, String pais) {
+ setNombre(nombre);
+ setDireccion(direccion);
+ setCiudad(ciudad);
+ setEmail(email);
+ setTelefono(telefono);
+ setCodigoPostal(codigoPostal);
+ setPais(pais);
+ }
+
+ public String insertar(Cliente cliente) {
+ String mensaje;
+ try (Connection conn = Conexion.conectar()) {
+ try (PreparedStatement query = conn.prepareStatement("INSERT INTO cliente(ClienteNombre, " +
+ "ClienteDireccion, ClienteCiudad, ClienteEmail, ClienteTelefono, ClienteCodigoPostal, " +
+ "ClientePais) VALUES (?, ?, ?, ?, ?, ?, ?);")) {
+ query.setString(1, cliente.nombre_);
+ query.setString(2, cliente.direccion_);
+ query.setString(3, cliente.ciudad_);
+ query.setString(4, cliente.email_);
+ query.setString(5, cliente.telefono_);
+ query.setString(6, cliente.codigoPostal_);
+ query.setString(7, cliente.pais_);
+
+ int tuplas = query.executeUpdate();
+ if (tuplas > 0) {
+ mensaje = "El registro ha sido agregado exitosamente.";
+ } else {
+ throw new SQLException("El registro no pudo ser agregado correctamente.\n");
+ }
+
+ } catch (SQLException ex) {
+ mensaje = ex.getMessage();
+ Logger.getLogger(Cliente.class.getName()).log(Level.SEVERE, null, ex);
+
+ }
+
+ } catch (SQLException ex) {
+ mensaje = "La conexion a la base de datos no pudo ser realizada exitosamente.";
+ Logger.getLogger(Cliente.class.getName()).log(Level.SEVERE, null, ex);
+ }
+
+ return mensaje;
+ }
+
+ public String actualizar(Cliente cliente) {
+ String mensaje;
+ try (Connection conn = Conexion.conectar()) {
+ try (PreparedStatement query = conn.prepareStatement("UPDATE Cliente SET ClienteNombre = ?," +
+ "ClienteDireccion = ?, ClienteCiudad = ?, ClienteEmail = ?, ClienteTelefono = ?," +
+ "ClienteCodigoPostal = ?, ClientePais = ?, ClienteEstatus = ? WHERE ClienteId = ? ;\n")) {
+ query.setString(1, cliente.nombre_);
+ query.setString(2, cliente.direccion_);
+ query.setString(3, cliente.ciudad_);
+ query.setString(4, cliente.email_);
+ query.setString(5, cliente.telefono_);
+ query.setString(6, cliente.codigoPostal_);
+ query.setString(7, cliente.pais_);
+ query.setString(8, cliente.estatus_.getChar());
+ query.setInt(9, cliente.id_); // Modificar
+
+ boolean esEjecutado = (query.executeUpdate() > 0);
+ if (esEjecutado) {
+ mensaje = "El registro ha sido actualizado exitosamente.";
+ } else {
+ throw new SQLException("El registro no pudo ser actualizado correctamente.");
+ }
+
+ } catch (SQLException ex) {
+ mensaje = ex.getMessage();
+ Logger.getLogger(Cliente.class.getName()).log(Level.SEVERE, null, ex);
+ }
+
+ } catch (SQLException ex) {
+ mensaje = "La conexion a la base de datos no pudo ser realizada exitosamente.";
+ Logger.getLogger(Cliente.class.getName()).log(Level.SEVERE, null, ex);
+ }
+
+ return mensaje;
+
+ }
+
+ public ObservableList buscar(String textoABuscar) {
+ ObservableList data = FXCollections.observableArrayList();
+ try (Connection conn = Conexion.conectar()) {
+ PreparedStatement query = conn.prepareStatement("SELECT * from cliente_buscar(?)");
+ query.setString(1, textoABuscar);
+ data = leer(query.executeQuery());
+ } catch (SQLException ex) {
+ Logger.getLogger(Cliente.class.getName()).log(Level.SEVERE, null, ex);
+ }
+
+ return data;
+ }
+
+ public ObservableList buscarActivos(String textoABuscar) {
+ ObservableList data = FXCollections.observableArrayList();
+ try (Connection conn = Conexion.conectar()) {
+ PreparedStatement query = conn.prepareStatement("SELECT * from cliente_buscaractivos(?)");
+ query.setString(1, textoABuscar);
+ data = leer(query.executeQuery());
+ } catch (SQLException ex) {
+ Logger.getLogger(Cliente.class.getName()).log(Level.SEVERE, null, ex);
+ }
+
+ return data;
+ }
+
+ public ObservableList mostrar() {
+ ObservableList data = FXCollections.observableArrayList();
+ try (Connection conn = Conexion.conectar()) {
+ PreparedStatement query = conn.prepareStatement("SELECT * from cliente_mostrar()");
+ data = leer(query.executeQuery());
+ } catch (SQLException ex) {
+ Logger.getLogger(Cliente.class.getName()).log(Level.SEVERE, null, ex);
+ }
+ return data;
+ }
+
+ public ObservableList mostrarActivos() {
+ ObservableList data = FXCollections.observableArrayList();
+ try (Connection conn = Conexion.conectar()) {
+ PreparedStatement query = conn.prepareStatement("SELECT * from cliente_mostraractivos()");
+ data = leer(query.executeQuery());
+ } catch (SQLException ex) {
+ Logger.getLogger(Cliente.class.getName()).log(Level.SEVERE, null, ex);
+ }
+ return data;
+ }
+
+ private ObservableList leer(ResultSet resultSet) throws SQLException {
+ ObservableList data = FXCollections.observableArrayList();
+ while (resultSet.next()) {
+ data.add(crear(resultSet));
+ }
+ return data;
+ }
+
+ private Cliente crear(ResultSet resultSet) throws SQLException {
+ int no = resultSet.getInt("Id");
+ final String nombre = resultSet.getString("Nombre");
+ final String email = resultSet.getString("Email");
+ final String telefono = resultSet.getString("Telefono");
+ final String direccion = resultSet.getString("Direccion");
+ final String pais = resultSet.getString("Pais");
+ final String ciudad = resultSet.getString("Ciudad");
+ final String codigoPostal = resultSet.getString("CodigoPostal");
+ Cliente cliente = new Cliente(nombre, direccion, ciudad, email, telefono, codigoPostal, pais);
+ cliente.setId(no);
+
+ HashMap opciones = new HashMap<>();
+ opciones.put("A", Estatus.ACTIVO);
+ opciones.put("I", Estatus.INACTIVO);
+ final String estatus = resultSet.getString("Estatus");
+ cliente.setEstatus(opciones.get(estatus));
+
+ return cliente;
+ }
+
+ public int getId() {
+ return id_;
+ }
+
+ public String getNombre() {
+ return nombre_;
+ }
+
+ public String getDireccion() {
+ return direccion_;
+ }
+
+ public String getCiudad() {
+ return ciudad_;
+ }
+
+ public String getEmail() {
+ return email_;
+ }
+
+ public String getTelefono() {
+ return telefono_;
+ }
+
+ public String getCodigoPostal() {
+ return codigoPostal_;
+ }
+
+ public String getPais() {
+ return pais_;
+ }
+
+ public Estatus getEstatus() {
+ return estatus_;
+ }
+
+ public void setId(int id) {
+ id_ = id;
+ }
+
+ public void setNombre(String nombre) {
+ nombre_ = nombre;
+ }
+
+ public void setDireccion(String direccion) {
+ direccion_ = direccion;
+ }
+
+ public void setCiudad(String ciudad) {
+ ciudad_ = ciudad;
+ }
+
+ public void setEmail(String email) {
+ email_ = email;
+ }
+
+ public void setTelefono(String telefono) {
+ telefono_ = telefono;
+ }
+
+ public void setCodigoPostal(String codigoPostal) {
+ codigoPostal_ = codigoPostal;
+ }
+
+ public void setPais(String pais) {
+ pais_ = pais;
+ }
+
+ public void setEstatus(Estatus estatus) {
+ estatus_ = estatus;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ Cliente cliente = (Cliente) o;
+ return id_ == cliente.id_;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(id_);
+ }
+
+ @Override
+ public String toString() {
+ return "Cliente{" +
+ "id_=" + id_ +
+ ", nombre_='" + nombre_ + '\'' +
+ ", direccion_='" + direccion_ + '\'' +
+ ", ciudad_='" + ciudad_ + '\'' +
+ ", email_='" + email_ + '\'' +
+ ", telefono_='" + telefono_ + '\'' +
+ ", codigoPostal_='" + codigoPostal_ + '\'' +
+ ", pais_='" + pais_ + '\'' +
+ ", estatus_=" + estatus_ +
+ '}';
+ }
+}
diff --git a/src/data/Conexion.java b/src/data/Conexion.java
new file mode 100644
index 0000000..34035a3
--- /dev/null
+++ b/src/data/Conexion.java
@@ -0,0 +1,20 @@
+package data;
+
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.SQLException;
+
+class Conexion {
+
+ private Conexion(){
+
+ }
+
+ static Connection conectar() throws SQLException {
+ final String dbUrl = "jdbc:postgresql://localhost/venta";
+ final String user = "usuario";
+ final String password = "1234";
+ return DriverManager.getConnection(dbUrl, user, password);
+ }
+
+}
diff --git a/src/data/Estatus.java b/src/data/Estatus.java
new file mode 100644
index 0000000..c6d9ee3
--- /dev/null
+++ b/src/data/Estatus.java
@@ -0,0 +1,18 @@
+package data;
+
+public enum Estatus {
+ ACTIVO('A'), INACTIVO('I');
+
+ private final char estatus_;
+ Estatus(char estatus){
+ estatus_ = estatus;
+ }
+ public String getChar(){
+ return String.valueOf(estatus_);
+ }
+
+ @Override
+ public String toString() {
+ return super.toString().toUpperCase().charAt(0) + super.toString().substring(1).toLowerCase();
+ }
+}
diff --git a/src/data/Factura.java b/src/data/Factura.java
new file mode 100644
index 0000000..ac8cdab
--- /dev/null
+++ b/src/data/Factura.java
@@ -0,0 +1,350 @@
+package data;
+
+import javafx.collections.FXCollections;
+import javafx.collections.ObservableList;
+
+import java.math.BigDecimal;
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.text.DecimalFormat;
+import java.time.LocalDate;
+import java.time.LocalTime;
+import java.util.HashSet;
+import java.util.Objects;
+import java.util.Set;
+import java.util.concurrent.atomic.AtomicReference;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+public class Factura {
+
+ private int id_;
+ private int numero_;
+
+ private Cliente cliente_ = new Cliente();
+ private LocalDate fecha_;
+ private LocalTime hora_;
+ private BigDecimal totalBruto_;
+ private BigDecimal totalDescuento_;
+ private BigDecimal totalImpuesto_;
+ private BigDecimal totalCargo_;
+ private BigDecimal totalNeto_;
+ private Set detalles_ = new HashSet<>();
+
+ // Para realizar consultas a la base de datos.
+ public Factura() {
+
+ }
+
+ // Para insertar
+ public Factura(Cliente cliente) {
+ cliente_ = cliente;
+ }
+
+ // Para Mostrar
+ private Factura(Cliente cliente, int id, int numero, LocalDate fecha, LocalTime hora,
+ BigDecimal totalBruto, BigDecimal totalDescuento, BigDecimal totalImpuesto, BigDecimal totalCargo,
+ BigDecimal totalNeto){
+ cliente_ = cliente;
+ setId(id);
+ setNumero(numero);
+ setFecha(fecha);
+ setHora(hora);
+ setTotalBruto(totalBruto);
+ setTotalDescuento(totalDescuento);
+ setTotalImpuesto(totalImpuesto);
+ setTotalCargo(totalCargo);
+ setTotalNeto(totalNeto);
+
+ }
+
+ // Para eliminar.
+ public Factura(int id) {
+ setId(id);
+ }
+
+ private void insertarDetalles(Connection conn)
+ throws SQLException {
+
+ for (FacturaDetalle detalle : getDetalles()) {
+ PreparedStatement statement = new AtomicReference<>(conn.prepareStatement(
+ "SELECT * FROM FacturaDetalle_Insertar(" +
+ "id := ?, articuloid := ?, precio := ?, cantidad := ?, descuento := ?, impuesto := ?)")).get();
+ statement.setInt(1, getId());
+ statement.setInt(2, detalle.getArticuloId());
+ statement.setBigDecimal(3, detalle.getPrecio());
+ statement.setInt(4, detalle.getCantidad());
+ statement.setBigDecimal(5, detalle.getDescuento());
+ statement.setBigDecimal(6, detalle.getImpuesto());
+
+ boolean esEjecutado = statement.execute();
+ if (!esEjecutado) {
+ throw new SQLException();
+ }
+ }
+ }
+
+ // Listo.
+ public String insertar() {
+ String mensaje;
+ try (Connection conn = Conexion.conectar()) {
+ try {
+ // Deshabilita auto transaccion.
+ conn.setAutoCommit(false);
+ PreparedStatement query = new AtomicReference<>(conn.prepareStatement("INSERT INTO "
+ + "Factura(ClienteId, FacturaTotalCargo) "
+ + "VALUES ( ?, ?) RETURNING facturaid;")).get();
+ query.setInt(1, getClienteId());
+ query.setObject(2, getTotalCargo());
+ boolean esEjecutado = query.execute();
+ if (esEjecutado) {
+ ResultSet rs = query.getResultSet();
+ rs.next();
+ setId(rs.getInt(1));
+ insertarDetalles(conn);
+ conn.commit(); // Confirma la transaccion.
+ mensaje = "El registro ha sido agregado exitosamente.";
+
+ } else {
+ throw new SQLException();
+ }
+
+ } catch (SQLException ex) {
+ conn.rollback(); // Cancela la transaccion
+ mensaje = "El registro no pudo ser agregado correctamente.";
+ Logger.getLogger(Articulo.class.getName()).log(Level.SEVERE, null, ex);
+ }
+
+ } catch (SQLException ex) {
+ mensaje = "La conexion a la base de datos no pudo ser realizada exitosamente.";
+ Logger.getLogger(Articulo.class.getName()).log(Level.SEVERE, null, ex);
+ }
+
+ return mensaje;
+ }
+
+ public String eliminar(Factura factura) {
+ String mensaje;
+ try (Connection conn = Conexion.conectar()) {
+ try (PreparedStatement query = conn.prepareStatement("UPDATE Factura SET FacturaEstatus = 'C'"
+ + " WHERE FacturaId = ?;")) {
+
+ query.setInt(1, factura.id_);
+ boolean esEjecutado = (query.executeUpdate() > 0);
+ if (esEjecutado) {
+ mensaje = "La factura ha sido cancelada exitosamente.";
+ } else {
+ throw new SQLException( "La factura no pudo ser cancelada.");
+ }
+ } catch (SQLException ex) {
+ mensaje = ex.getMessage();
+ Logger.getLogger(Articulo.class.getName()).log(Level.SEVERE, null, ex);
+ }
+ } catch (SQLException ex) {
+ mensaje = "La conexion a la base de datos no pudo ser realizada exitosamente.";
+ Logger.getLogger(Articulo.class.getName()).log(Level.SEVERE, null, ex);
+ }
+
+ return mensaje;
+
+ }
+
+ // Listo
+ public ObservableList mostrar() {
+ ObservableList data = FXCollections.observableArrayList();
+ try (Connection conn = Conexion.conectar();
+ PreparedStatement query = conn.prepareStatement("SELECT * FROM Factura_mostrar()")) {
+ ResultSet resultSet = query.executeQuery();
+ while (resultSet.next()) {
+
+ Cliente cliente = new Cliente();
+ int clienteId = resultSet.getInt("No");
+ String clienteNombre = resultSet.getString("Nombre");
+ cliente.setNombre(clienteNombre);
+ cliente.setId(clienteId);
+
+ final int id = resultSet.getInt("Id");
+ final int numero = resultSet.getInt("Numero");
+ final LocalDate fecha = resultSet.getDate("Fecha").toLocalDate();
+ final LocalTime hora = resultSet.getTime("Hora").toLocalTime();
+ BigDecimal totalBruto = resultSet.getBigDecimal("Total_Bruto");
+ BigDecimal totalDescuento = resultSet.getBigDecimal("Total_Descuento");
+ BigDecimal totalImpuesto = resultSet.getBigDecimal("Total_Impuesto");
+ BigDecimal totalCargo = resultSet.getBigDecimal("Total_Cargo");
+ BigDecimal totalNeto = resultSet.getBigDecimal("Total_Neto");
+ Factura obj = new Factura(cliente, id, numero, fecha, hora,
+ totalBruto, totalDescuento, totalImpuesto, totalCargo, totalNeto);
+
+ data.add(obj);
+ }
+
+
+ } catch (SQLException ex) {
+ Logger.getLogger(Articulo.class.getName()).log(Level.SEVERE, null, ex);
+ }
+
+ return data;
+ }
+
+ // Listo
+ public ObservableList mostrarDetalles(int numero) {
+ // Texto
+ ObservableList detalles_ = FXCollections.observableArrayList();
+ try (Connection conn = Conexion.conectar()) {
+ PreparedStatement query = conn.prepareStatement("SELECT * FROM Factura_Mostrar(?)");
+ query.setInt(1, numero);
+ ResultSet resultSet = query.executeQuery();
+ while (resultSet.next()) {
+
+ final short linea = resultSet.getShort("Linea");
+
+ Articulo articulo = new Articulo();
+ final String articuloCodigo = resultSet.getString("Codigo_Articulo");
+ articulo.setCodigo(articuloCodigo);
+ final String articuloNombre = resultSet.getString("articulo");
+ articulo.setNombre(articuloNombre);
+ final String articuloDescripcion = resultSet.getString("descripcion");
+ articulo.setDescripcion(articuloDescripcion);
+ BigDecimal precio = resultSet.getBigDecimal("Precio");
+ articulo.setPrecio(precio);
+
+ final int cantidad = resultSet.getInt("cantidad");
+ BigDecimal descuento = resultSet.getBigDecimal("Descuento");
+ BigDecimal impuesto = resultSet.getBigDecimal("Impuesto");
+ BigDecimal neto = resultSet.getBigDecimal("Neto");
+ FacturaDetalle obj = new FacturaDetalle(id_, articulo, cantidad,
+ descuento, impuesto, neto);
+ obj.setLinea(linea);
+ detalles_.add(obj);
+ }
+
+ } catch (SQLException ex) {
+ Logger.getLogger(Factura.class.getName()).log(Level.SEVERE, null, ex);
+ }
+
+ return detalles_;
+
+ }
+
+ public int getId() {
+ return id_;
+ }
+
+ public int getNumero() {
+ return numero_;
+ }
+
+ public Cliente getCliente() {
+ return cliente_;
+ }
+
+ public int getClienteId() {
+ return cliente_.getId();
+ }
+
+ public String getClienteNombre(){
+ return cliente_.getNombre();
+ }
+
+ public LocalDate getFecha() {
+ return fecha_;
+ }
+
+ public LocalTime getHora(){
+ return hora_;
+ }
+
+ public Set getDetalles() {
+ return detalles_;
+ }
+
+ public BigDecimal getTotalBruto() {
+ return totalBruto_;
+ }
+
+ public BigDecimal getTotalDescuento() {
+ return totalDescuento_;
+ }
+
+ public BigDecimal getTotalImpuesto() {
+ return totalImpuesto_;
+ }
+
+ public BigDecimal getTotalCargo() {
+ return totalCargo_;
+ }
+
+ public BigDecimal getTotalNeto() {
+ return totalNeto_;
+ }
+
+ private void setId(int id) {
+ id_ = id;
+ }
+
+ private void setNumero(int numero) {
+ numero_ = numero;
+ }
+
+ public void setCliente(Cliente cliente) {
+ cliente_ = cliente;
+ }
+
+ private void setFecha(LocalDate fecha) {
+ fecha_ = fecha;
+ }
+
+ private void setHora(LocalTime hora) {
+ hora_ = hora;
+ }
+
+ public void setDetalles(Set detalles) {
+ detalles_ = detalles;
+ }
+
+ public void setTotalBruto(BigDecimal totalBruto) {
+ totalBruto_ = totalBruto;
+ }
+
+ public void setTotalDescuento(BigDecimal totalDescuento) {
+ totalDescuento_ = totalDescuento;
+ }
+
+ public void setTotalImpuesto(BigDecimal totalImpuesto) {
+ totalImpuesto_ = totalImpuesto;
+ }
+
+ public void setTotalCargo(BigDecimal totalCargo) {
+ totalCargo_ = totalCargo;
+ }
+
+ public void setTotalNeto(BigDecimal totalNeto) {
+ totalNeto_ = totalNeto;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ Factura factura = (Factura) o;
+ return id_ == factura.id_;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(id_);
+ }
+
+ @Override
+ public String toString(){
+ DecimalFormat f = new DecimalFormat("###,##0.00");
+
+ return "Factura[No = " + getClienteId() + ", cliente = " + getClienteNombre()
+ + ", numero de factura = " + getNumero() + ", fecha = " + getFecha()
+ + ", totalBruto = " + f.format(getTotalBruto()) + ", totalImpuesto = " + f.format(getTotalImpuesto())
+ + ", totalCargo = " + f.format(getTotalCargo()) + ", totalDescuento = " + f.format(getTotalDescuento())
+ + ", totalNeto = " + f.format(getTotalNeto()) + "]\n";
+ }
+}
diff --git a/src/data/FacturaDetalle.java b/src/data/FacturaDetalle.java
new file mode 100644
index 0000000..195b58f
--- /dev/null
+++ b/src/data/FacturaDetalle.java
@@ -0,0 +1,140 @@
+package data;
+
+import java.math.BigDecimal;
+import java.text.DecimalFormat;
+import java.util.Objects;
+
+public class FacturaDetalle {
+
+ private int idFactura_; // Factura
+ private short linea;
+
+ private Articulo articulo_;
+
+ static {
+ new Articulo();
+ }
+
+ private int cantidad_;
+ private BigDecimal descuento_;
+ private BigDecimal impuesto_;
+ private BigDecimal neto_;
+
+ // Para insertar.
+
+ public FacturaDetalle(int idFactura, Articulo articulo, int cantidad) {
+ idFactura_ = idFactura;
+ articulo_ = articulo;
+ setPrecio(articulo.getPrecio());
+ setCantidad(cantidad);
+ }
+
+ // Para mostrar.
+ FacturaDetalle(int idFactura, Articulo articulo, int cantidad,
+ BigDecimal descuento, BigDecimal impuesto, BigDecimal neto) {
+ idFactura_ = idFactura;
+ articulo_ = articulo;
+ setCantidad(cantidad);
+ setDescuento(descuento);
+ setImpuesto(impuesto);
+ setNeto(neto);
+ }
+
+
+ int getIdFactura() {
+ return idFactura_;
+ }
+
+ int getArticuloId(){
+ return articulo_.getId();
+ }
+
+ public String getArticuloCodigo(){
+ return articulo_.getCodigo();
+ }
+
+ public String getArticuloNombre(){
+ return articulo_.getNombre();
+ }
+
+ public String getArticuloDescripcion(){
+ return articulo_.getDescripcion();
+ }
+
+ public BigDecimal getPrecio() {
+ return articulo_.getPrecio();
+ }
+
+ public int getCantidad() {
+ return cantidad_;
+ }
+
+ public BigDecimal getDescuento() {
+ return descuento_;
+ }
+
+ public BigDecimal getImpuesto() {
+ return impuesto_;
+ }
+
+ public BigDecimal getNeto() {
+ return neto_;
+ }
+
+ void setIdFactura(int idFactura) {
+ idFactura_ = idFactura;
+ }
+
+ public void setLinea(short linea) {
+ this.linea = linea;
+ }
+
+ private void setPrecio(BigDecimal precio) {
+ articulo_.setPrecio(precio);
+ }
+
+ public void setCantidad(int cantidad) {
+ cantidad_ = cantidad;
+ }
+
+ public void setDescuento(BigDecimal descuento) {
+ descuento_ = descuento;
+ }
+
+ public void setImpuesto(BigDecimal impuesto) {
+ impuesto_ = impuesto;
+ }
+
+ public void setNeto(BigDecimal neto) {
+ neto_ = neto;
+ }
+
+ public short getLinea() {
+ return linea;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ FacturaDetalle that = (FacturaDetalle) o;
+ return idFactura_ == that.idFactura_ &&
+ linea == that.linea;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(idFactura_, linea);
+ }
+
+ @Override
+ public String toString(){
+ DecimalFormat f = new DecimalFormat("###,##0.00");
+
+ return "FacturaDetalle[línea = " + getLinea() + ", código = " + getArticuloCodigo()
+ + ", artículo = " + getArticuloNombre() + ", descripción = " + getArticuloDescripcion()
+ + ", cantidad = " + getCantidad() + ", precio = " + f.format(getPrecio())
+ + ", impuesto = " + f.format(getImpuesto()) + ", descuento = " + f.format(getDescuento())
+ + ", neto = " + f.format(getNeto()) + "]\n";
+ }
+}
diff --git a/src/view/Main.java b/src/view/Main.java
new file mode 100644
index 0000000..a763083
--- /dev/null
+++ b/src/view/Main.java
@@ -0,0 +1,105 @@
+package view;
+
+import javafx.application.Application;
+import javafx.scene.control.TreeItem;
+import javafx.scene.image.Image;
+import javafx.scene.image.ImageView;
+import javafx.stage.Stage;
+import javafx.stage.WindowEvent;
+import view.articulo.ArticuloController;
+import view.cliente.ClienteActivoController;
+import view.cliente.ClienteController;
+import view.factura.FacturaController;
+
+import java.io.IOException;
+
+import static javafx.application.Platform.exit;
+
+
+public class Main extends Application {
+
+
+ public static void main(String[] args) {
+ launch(args);
+ }
+
+ @Override
+ public void start(Stage primaryStage) throws IOException {
+ primaryStage.getIcons().add(new Image("view/resources/main.png"));
+ primaryStage.setOnCloseRequest((WindowEvent e) ->
+ exit()
+ );
+ ClienteController.start(primaryStage);
+ primaryStage.show();
+ }
+
+ public static TreeItem iniciarItems() {
+ ImageView iconCliente = new ImageView(
+ new Image(Main.class.getResourceAsStream("/view/resources/clientes.png"))
+ );
+ iconCliente.setFitWidth(15);
+ iconCliente.setFitHeight(12);
+ TreeItem nodoClientes = new TreeItem<>("Ver clientes", iconCliente);
+ TreeItem rootCliente = new TreeItem<>("Cliente");
+ rootCliente.getChildren().add(nodoClientes);
+
+ ImageView iconArticulo = new ImageView(
+ new Image(Main.class.getResourceAsStream("/view/resources/articulos.png"))
+ );
+ iconArticulo.setFitWidth(15);
+ iconArticulo.setFitHeight(12);
+ TreeItem nodoArticulos = new TreeItem<>("Ver articulos", iconArticulo);
+ TreeItem rootArticulo = new TreeItem<>("Articulo");
+ rootArticulo.getChildren().add(nodoArticulos);
+
+
+ ImageView iconFactura = new ImageView(
+ new Image(Main.class.getResourceAsStream("/view/resources/facturas.png"))
+ );
+ iconFactura.setFitWidth(15);
+ iconFactura.setFitHeight(12);
+ TreeItem nodoFacturas = new TreeItem<>("Ver facturas", iconFactura);
+ ImageView iconComprar = new ImageView(
+ new Image(Main.class.getResourceAsStream("/view/resources/comprar.png"))
+ );
+ iconComprar.setFitWidth(15);
+ iconComprar.setFitHeight(12);
+ TreeItem nodoCompras = new TreeItem<>("Efectuar una compra", iconComprar);
+ TreeItem rootFactura = new TreeItem<>("Factura");
+ rootFactura.getChildren().add(nodoFacturas);
+ rootFactura.getChildren().add(nodoCompras);
+
+
+ TreeItem root = new TreeItem<>("NULL");
+ root.getChildren().addAll(rootCliente, rootArticulo, rootFactura);
+
+ return root;
+
+ }
+
+ public static void cambiarScene(Stage primaryStage, TreeItem item) {
+ if (item == null)
+ return;
+ try {
+ switch (item.getValue()) {
+ case "Ver clientes":
+ ClienteController.start(primaryStage);
+ break;
+ case "Ver facturas":
+ FacturaController.start(primaryStage);
+ break;
+ case "Ver articulos":
+ ArticuloController.start(primaryStage);
+ break;
+ case "Efectuar una compra":
+ ClienteActivoController.start(primaryStage);
+ break;
+ }
+
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+
+ }
+
+}
\ No newline at end of file
diff --git a/src/view/RadioButtonCell.java b/src/view/RadioButtonCell.java
new file mode 100644
index 0000000..d4583dc
--- /dev/null
+++ b/src/view/RadioButtonCell.java
@@ -0,0 +1,54 @@
+package view;
+
+import com.jfoenix.controls.JFXRadioButton;
+import javafx.beans.value.ObservableValue;
+import javafx.geometry.Pos;
+import javafx.scene.control.TableCell;
+import javafx.scene.control.Toggle;
+import javafx.scene.control.ToggleGroup;
+import javafx.scene.layout.HBox;
+
+import java.util.EnumSet;
+
+public class RadioButtonCell> extends TableCell {
+
+ private final EnumSet enumeration;
+
+ public RadioButtonCell(EnumSet enumeration) {
+ this.enumeration = enumeration;
+ }
+
+ @Override
+ protected void updateItem(T item, boolean empty)
+ {
+ super.updateItem(item, empty);
+ setGraphic(null);
+ if (!empty)
+ {
+ // gui setup
+ HBox hb = new HBox(7);
+ hb.setAlignment(Pos.CENTER);
+ final ToggleGroup group = new ToggleGroup();
+
+ // create a radio button for each 'element' of the enumeration
+ for (Enum enumElement : enumeration) {
+ JFXRadioButton radioButton = new JFXRadioButton(enumElement.toString());
+ radioButton.setUserData(enumElement);
+ radioButton.setToggleGroup(group);
+ hb.getChildren().add(radioButton);
+ if (enumElement.equals(item)) {
+ radioButton.setSelected(true);
+ }
+ }
+
+ // issue events on change of the selected radio button
+ group.selectedToggleProperty().addListener((ObservableValue extends Toggle> observable, Toggle oldValue,
+ Toggle newValue) -> {
+ getTableView().edit(getIndex(), getTableColumn());
+ //noinspection unchecked
+ RadioButtonCell.this.commitEdit((T) newValue.getUserData());
+ });
+ setGraphic(hb);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/view/articulo/Articulo.fxml b/src/view/articulo/Articulo.fxml
new file mode 100644
index 0000000..f482f1d
--- /dev/null
+++ b/src/view/articulo/Articulo.fxml
@@ -0,0 +1,44 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/view/articulo/ArticuloActivo.fxml b/src/view/articulo/ArticuloActivo.fxml
new file mode 100644
index 0000000..5380082
--- /dev/null
+++ b/src/view/articulo/ArticuloActivo.fxml
@@ -0,0 +1,107 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/view/articulo/ArticuloActivoController.java b/src/view/articulo/ArticuloActivoController.java
new file mode 100644
index 0000000..2112867
--- /dev/null
+++ b/src/view/articulo/ArticuloActivoController.java
@@ -0,0 +1,149 @@
+package view.articulo;
+
+import com.jfoenix.controls.JFXButton;
+import com.jfoenix.controls.JFXTextField;
+import data.Articulo;
+import data.Cliente;
+import javafx.fxml.FXML;
+import javafx.fxml.FXMLLoader;
+import javafx.fxml.Initializable;
+import javafx.scene.Parent;
+import javafx.scene.Scene;
+import javafx.scene.control.*;
+import javafx.scene.control.cell.PropertyValueFactory;
+import javafx.stage.Stage;
+import view.Main;
+import view.cliente.ClienteActivoController;
+import view.factura.FacturaActivaController;
+
+import java.io.IOException;
+import java.net.URL;
+import java.util.HashMap;
+import java.util.ResourceBundle;
+
+public class ArticuloActivoController implements Initializable {
+ @FXML
+ private Label id_;
+ @FXML
+ private Label nombre_;
+ @FXML
+ private Label email_;
+
+ private static Stage primaryStage;
+ private static Cliente cliente_;
+
+ public static void start(Stage stage, Cliente cliente) throws IOException {
+ primaryStage = stage;
+ cliente_ = cliente;
+ Parent root = FXMLLoader.load(ArticuloActivoController.class.getResource("ArticuloActivo.fxml"));
+ Scene scene = new Scene(root);
+ primaryStage.setScene(scene);
+ primaryStage.setTitle("Seleccione articulos");
+
+ }
+
+ @FXML
+ private TableView tableView;
+ @FXML
+ private TableColumn, ?> columnaNo;
+ @FXML
+ private TableColumn, ?> columnaNombre;
+ @FXML
+ private TableColumn, ?> columnaDescripcion;
+ @FXML
+ private TableColumn, ?> columnaPrecio;
+ @FXML
+ private TableColumn, ?> columnaUnidadesStock;
+ @FXML
+ private TableColumn, ?> columnaCodigo;
+
+ private void initTabla() {
+ columnaNo.setCellValueFactory(new PropertyValueFactory<>("id"));
+ columnaNombre.setCellValueFactory(new PropertyValueFactory<>("nombre"));
+ columnaDescripcion.setCellValueFactory(new PropertyValueFactory<>("descripcion"));
+ columnaPrecio.setCellValueFactory(new PropertyValueFactory<>("precio"));
+ columnaUnidadesStock.setCellValueFactory(new PropertyValueFactory<>("unidadesStock"));
+ columnaCodigo.setCellValueFactory(new PropertyValueFactory<>("codigo"));
+ }
+
+
+ @FXML
+ private TreeView treeView;
+
+ private final HashMap articulos = new HashMap<>();
+ private Articulo articulo = new Articulo();
+
+ @Override
+ public void initialize(URL location, ResourceBundle resources) {
+ // Inicializa labels
+ id_.setText(String.valueOf(cliente_.getId()));
+ nombre_.setText(cliente_.getNombre());
+ email_.setText(cliente_.getEmail());
+ //---------------------
+
+ initTabla();
+ tableView.getSelectionModel().selectedItemProperty().addListener(
+ (v, oldValue, newValue) -> {
+ if (newValue == null)
+ return;
+ articulo = newValue;
+ cantidad.setDisable(false);
+ botonAgregar.setDisable(false);
+ }
+ );
+ tableView.getSelectionModel().selectedItemProperty().removeListener(
+ (v, oldValue, newValue) -> {
+ cantidad.setDisable(true);
+ botonAgregar.setDisable(true);
+ }
+ );
+ tableView.setItems(business.Articulo.mostrarActivos());
+ treeView.setRoot(Main.iniciarItems());
+ treeView.getSelectionModel().selectedItemProperty().addListener((v, oldValue, newValue) ->
+ Main.cambiarScene(primaryStage, newValue));
+ }
+
+ @FXML
+ private void volver() throws IOException {
+ ClienteActivoController.start(primaryStage);
+ }
+
+ @FXML
+ private void continuar() throws IOException {
+
+ FacturaActivaController.start(primaryStage, cliente_, articulos);
+ }
+
+
+ @FXML
+ private void seleccionar() {
+ tableView.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE);
+ }
+
+
+ @FXML
+ private JFXButton botonContinuar;
+ @FXML
+ private JFXButton botonAgregar;
+ @FXML
+ private JFXButton botonRemover;
+ @FXML
+ private JFXTextField cantidad;
+
+ @FXML
+ private void agregar() {
+ articulos.put(articulo, Integer.parseUnsignedInt(cantidad.getText()));
+ botonRemover.setDisable(false);
+ botonContinuar.setDisable(false);
+ }
+
+ @FXML
+ private void remover() {
+ articulos.remove(articulo);
+ articulos.remove(articulo);
+ if (articulos.isEmpty()) {
+ botonRemover.setDisable(true);
+ botonContinuar.setDisable(true);
+ }
+ }
+}
diff --git a/src/view/articulo/ArticuloController.java b/src/view/articulo/ArticuloController.java
new file mode 100644
index 0000000..4f16c22
--- /dev/null
+++ b/src/view/articulo/ArticuloController.java
@@ -0,0 +1,202 @@
+package view.articulo;
+
+import com.jfoenix.controls.JFXTextArea;
+import com.jfoenix.controls.JFXTextField;
+import com.jfoenix.validation.DoubleValidator;
+import com.jfoenix.validation.IntegerValidator;
+import data.Articulo;
+import data.Estatus;
+import javafx.fxml.FXML;
+import javafx.fxml.Initializable;
+import javafx.scene.Parent;
+import javafx.scene.Scene;
+import javafx.scene.control.Alert;
+import javafx.scene.control.TableColumn;
+import javafx.scene.control.TableView;
+import javafx.scene.control.TreeView;
+import javafx.scene.control.cell.PropertyValueFactory;
+import javafx.scene.control.cell.TextFieldTableCell;
+import javafx.stage.Stage;
+import javafx.util.converter.BigDecimalStringConverter;
+import javafx.util.converter.IntegerStringConverter;
+import view.Main;
+import view.RadioButtonCell;
+
+import java.io.IOException;
+import java.math.BigDecimal;
+import java.net.URL;
+import java.util.EnumSet;
+import java.util.ResourceBundle;
+
+import static javafx.fxml.FXMLLoader.load;
+
+public class ArticuloController implements Initializable {
+
+ private static Stage primaryStage;
+
+ public static void start(Stage stage) throws IOException {
+ primaryStage = stage;
+ Parent root = load(ArticuloController.class.getResource("Articulo.fxml"));
+ Scene scene = new Scene(root);
+ primaryStage.setScene(scene);
+ primaryStage.setTitle("Ver Articulos");
+ }
+
+ @FXML
+ private TableView tableView;
+ @FXML
+ private TableColumn columnaNo;
+ @FXML
+ private TableColumn columnaNombre;
+ @FXML
+ private TableColumn columnaDescripcion;
+ @FXML
+ private TableColumn columnaPrecio;
+ @FXML
+ private TableColumn columnaUnidadesStock;
+ @FXML
+ private TableColumn columnaCodigo;
+ @FXML
+ private TableColumn columnaEstatus;
+
+ private void initTabla() {
+ columnaNo.setCellValueFactory(new PropertyValueFactory<>("id"));
+ columnaNombre.setCellValueFactory(new PropertyValueFactory<>("nombre"));
+ columnaDescripcion.setCellValueFactory(new PropertyValueFactory<>("descripcion"));
+ columnaPrecio.setCellValueFactory(new PropertyValueFactory<>("precio"));
+ columnaUnidadesStock.setCellValueFactory(new PropertyValueFactory<>("unidadesStock"));
+ columnaCodigo.setCellValueFactory(new PropertyValueFactory<>("codigo"));
+ columnaEstatus.setCellValueFactory(new PropertyValueFactory<>("estatus"));
+
+ columnaCodigo.setCellFactory(TextFieldTableCell.forTableColumn());
+ columnaNombre.setCellFactory(TextFieldTableCell.forTableColumn());
+ columnaDescripcion.setCellFactory(TextFieldTableCell.forTableColumn());
+ columnaUnidadesStock.setCellFactory(TextFieldTableCell.forTableColumn(
+ new IntegerStringConverter()
+ ));
+ columnaPrecio.setCellFactory(TextFieldTableCell.forTableColumn(
+ new BigDecimalStringConverter()
+ ));
+
+ columnaEstatus.setCellFactory((param) -> new RadioButtonCell<>(EnumSet.allOf(Estatus.class)));
+ }
+
+ @FXML
+ private TreeView treeView;
+
+ @FXML
+ private JFXTextField nombre;
+ @FXML
+ private JFXTextArea descripcion;
+ @FXML
+ private JFXTextField unidadesStock;
+ @FXML
+ private JFXTextField precio;
+ @FXML
+ private JFXTextField codigo;
+
+ @Override
+ public void initialize(URL location, ResourceBundle resources) {
+ initTabla();
+ tableView.setItems(business.Articulo.mostrar());
+
+ treeView.setRoot(Main.iniciarItems());
+ treeView.getSelectionModel().selectedItemProperty().addListener((v, oldValue, newValue) ->
+ Main.cambiarScene(primaryStage, newValue));
+ tableView.getSelectionModel().selectedItemProperty().addListener( (v, oldValue, newValue) ->
+ articulo = newValue
+ );
+
+ unidadesStock.getValidators().add(new IntegerValidator("Solo numeros naturales"));
+ unidadesStock.focusedProperty().addListener((o, oldValue, newValue) -> {
+ if (!newValue)
+ unidadesStock.validate();
+ });
+
+ precio.getValidators().add(new DoubleValidator("Solo numeros reales no negativos"));
+
+ precio.focusedProperty().addListener((o, oldValue, newValue) -> {
+ if (!newValue)
+ precio.validate();
+ });
+ }
+
+ @FXML
+ private void buscar() {
+ tableView.setItems(business.Articulo.buscar(nombre.getText()));
+ }
+
+
+ private boolean haConfirmado() {
+ String mensaje = ("Codigo: " + codigo.getText() + "\n") +
+ "Nombre: " + nombre.getText() + "\n" +
+ "Descripcion: " + descripcion.getText() + "\n" +
+ "Unidades en Stock: " + unidadesStock.getText() + "\n" +
+ "Precio: " + precio.getText() + "\n";
+
+ Alert alerta = new Alert(Alert.AlertType.CONFIRMATION);
+ alerta.setTitle("\"¿Desea continuar?\"");
+ alerta.setHeaderText(mensaje);
+ return alerta.showAndWait().isPresent();
+ }
+
+ private void clear() {
+ codigo.setText("");
+ nombre.setText("");
+ descripcion.setText("");
+ unidadesStock.setText("");
+ precio.setText("");
+ }
+
+ @FXML
+ private void agregar() {
+ if (haConfirmado()) {
+ String context = business.Articulo.insertar(codigo.getText(), nombre.getText(), descripcion.getText(),
+ new BigDecimal(precio.getText()), Integer.parseInt(unidadesStock.getText()));
+ Alert insercion = new Alert(Alert.AlertType.INFORMATION, context);
+ insercion.show();
+ tableView.setItems(business.Articulo.mostrar());
+ clear();
+ }
+ }
+
+ private Articulo articulo = new Articulo();
+
+ @FXML
+ private void actualizar(TableColumn.CellEditEvent newValue){
+
+ Articulo articulo = (Articulo) newValue.getTableView().getItems().get(
+ newValue.getTablePosition().getRow()
+ );
+ if (articulo == null)
+ return;
+ if (newValue.getNewValue().equals(newValue.getOldValue()))
+ return;
+
+ TableColumn col = newValue.getTableColumn();
+ String value = newValue.getNewValue().toString();
+ if(col.equals(columnaNombre)){
+ articulo.setNombre(value);
+ } else if (col.equals(columnaCodigo)){
+ articulo.setCodigo(value);
+ } else if (col.equals(columnaDescripcion)){
+ articulo.setDescripcion(value);
+ } else if(col.equals(columnaPrecio)){
+ articulo.setPrecio(new BigDecimal(value));
+ } else if (col.equals(columnaEstatus)){
+ articulo.setEstatus(Estatus.valueOf(newValue.getNewValue().toString().toUpperCase()));
+ } else if (col.equals(columnaUnidadesStock)){
+ articulo.setUnidadesStock(Integer.parseInt(value));
+ }
+
+ String context = business.Articulo.actualizar(articulo.getId(), articulo.getCodigo(),
+ articulo.getNombre(), articulo.getDescripcion(), articulo.getPrecio(),
+ articulo.getUnidadesStock(), articulo.getEstatus());
+ Alert insercion = new Alert(Alert.AlertType.INFORMATION, context);
+ insercion.show();
+ tableView.setItems(business.Articulo.mostrar());
+
+ }
+
+
+}
diff --git a/src/view/cliente/Cliente.fxml b/src/view/cliente/Cliente.fxml
new file mode 100644
index 0000000..70fb4a3
--- /dev/null
+++ b/src/view/cliente/Cliente.fxml
@@ -0,0 +1,48 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/view/cliente/ClienteActivo.fxml b/src/view/cliente/ClienteActivo.fxml
new file mode 100644
index 0000000..7c3e00b
--- /dev/null
+++ b/src/view/cliente/ClienteActivo.fxml
@@ -0,0 +1,43 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/view/cliente/ClienteActivoController.java b/src/view/cliente/ClienteActivoController.java
new file mode 100644
index 0000000..832f969
--- /dev/null
+++ b/src/view/cliente/ClienteActivoController.java
@@ -0,0 +1,105 @@
+package view.cliente;
+
+import com.jfoenix.controls.JFXButton;
+import com.jfoenix.controls.JFXTextField;
+import data.Cliente;
+import javafx.fxml.FXML;
+import javafx.fxml.FXMLLoader;
+import javafx.fxml.Initializable;
+import javafx.scene.Parent;
+import javafx.scene.Scene;
+import javafx.scene.control.TableColumn;
+import javafx.scene.control.TableView;
+import javafx.scene.control.TreeView;
+import javafx.scene.control.cell.PropertyValueFactory;
+import javafx.stage.Stage;
+import view.Main;
+import view.articulo.ArticuloActivoController;
+
+import java.io.IOException;
+import java.net.URL;
+import java.util.ResourceBundle;
+
+public class ClienteActivoController implements Initializable {
+
+ private static Stage primaryStage;
+
+ public static void start(Stage stage) throws IOException {
+ primaryStage = stage;
+ Parent root = FXMLLoader.load(ClienteActivoController.class.getResource("ClienteActivo.fxml"));
+ Scene scene = new Scene(root);
+ primaryStage.setScene(scene);
+ primaryStage.setTitle("Seleccione cliente");
+
+ }
+
+ @FXML
+ private TreeView treeView;
+
+ @FXML
+ private TableView tableView;
+ @FXML
+ private TableColumn, ?> columnaNo;
+ @FXML
+ private TableColumn, ?> columnaNombre;
+ @FXML
+ private TableColumn, ?> columnaEmail;
+ @FXML
+ private TableColumn, ?> columnaTelefono;
+ @FXML
+ private TableColumn, ?> columnaDireccion;
+ @FXML
+ private TableColumn, ?> columnaPais;
+ @FXML
+ private TableColumn, ?> columnaCiudad;
+ @FXML
+ private TableColumn, ?> columnaCodigoPostal;
+
+ private void initTabla() {
+ columnaNo.setCellValueFactory(new PropertyValueFactory<>("id"));
+ columnaNombre.setCellValueFactory(new PropertyValueFactory<>("nombre"));
+ columnaEmail.setCellValueFactory(new PropertyValueFactory<>("email"));
+ columnaTelefono.setCellValueFactory(new PropertyValueFactory<>("telefono"));
+ columnaDireccion.setCellValueFactory(new PropertyValueFactory<>("direccion"));
+ columnaPais.setCellValueFactory(new PropertyValueFactory<>("pais"));
+ columnaCiudad.setCellValueFactory(new PropertyValueFactory<>("ciudad"));
+ columnaCodigoPostal.setCellValueFactory(new PropertyValueFactory<>("codigoPostal"));
+ }
+
+ @FXML
+ private JFXTextField nombre;
+ @FXML
+ private JFXButton botonSiguiente;
+
+
+ @Override
+ public void initialize(URL location, ResourceBundle resources) {
+ initTabla();
+ tableView.setItems(business.Cliente.mostrarActivos());
+ tableView.getSelectionModel().selectedItemProperty().addListener((v, oldValue, newValue) ->
+ {
+ cliente = newValue;
+ botonSiguiente.setDisable(cliente == null);
+ }
+ );
+ treeView.setRoot(Main.iniciarItems());
+ treeView.getSelectionModel().selectedItemProperty().addListener((v, oldValue, newValue) ->
+ Main.cambiarScene(primaryStage, newValue));
+
+ }
+
+ @FXML
+ private void completarNombre() {
+ tableView.setItems(business.Cliente.buscarActivos(nombre.getText()));
+ }
+
+ private Cliente cliente;
+
+ @FXML
+ private void continuar() throws IOException {
+ if (cliente == null)
+ return;
+ ArticuloActivoController.start(primaryStage, cliente);
+ }
+
+}
diff --git a/src/view/cliente/ClienteController.java b/src/view/cliente/ClienteController.java
new file mode 100644
index 0000000..88e4e10
--- /dev/null
+++ b/src/view/cliente/ClienteController.java
@@ -0,0 +1,224 @@
+package view.cliente;
+
+import com.jfoenix.controls.JFXComboBox;
+import com.jfoenix.controls.JFXTextField;
+import data.Cliente;
+import data.Estatus;
+import javafx.collections.FXCollections;
+import javafx.collections.ObservableList;
+import javafx.fxml.FXML;
+import javafx.fxml.FXMLLoader;
+import javafx.fxml.Initializable;
+import javafx.scene.Parent;
+import javafx.scene.Scene;
+import javafx.scene.control.Alert;
+import javafx.scene.control.TableColumn;
+import javafx.scene.control.TableView;
+import javafx.scene.control.TreeView;
+import javafx.scene.control.cell.ChoiceBoxTableCell;
+import javafx.scene.control.cell.PropertyValueFactory;
+import javafx.scene.control.cell.TextFieldTableCell;
+import javafx.stage.Stage;
+import view.Main;
+import view.RadioButtonCell;
+
+import java.io.IOException;
+import java.net.URL;
+import java.util.Collections;
+import java.util.EnumSet;
+import java.util.Locale;
+import java.util.ResourceBundle;
+
+public class ClienteController implements Initializable {
+
+ private static Stage primaryStage;
+
+ public static void start(Stage stage) throws IOException {
+ primaryStage = stage;
+ Parent root = FXMLLoader.load(ClienteController.class.getResource("Cliente.fxml"));
+ Scene scene = new Scene(root);
+ primaryStage.setScene(scene);
+ primaryStage.setTitle("Ver Clientes");
+ }
+
+ @FXML
+ private JFXTextField nombre;
+ @FXML
+ private JFXTextField email;
+ @FXML
+ private JFXTextField telefono;
+ @FXML
+ private JFXTextField direccion;
+ @FXML
+ private JFXTextField ciudad;
+ @FXML
+ private JFXTextField codigoPostal;
+
+ @FXML
+ private JFXComboBox paises;
+
+ @FXML
+ private TableView tableView;
+ @FXML
+ private TableColumn columnaNo;
+ @FXML
+ private TableColumn columnaNombre;
+ @FXML
+ private TableColumn columnaEmail;
+ @FXML
+ private TableColumn columnaTelefono;
+ @FXML
+ private TableColumn columnaDireccion;
+ @FXML
+ private TableColumn columnaPais;
+ @FXML
+ private TableColumn columnaCiudad;
+ @FXML
+ private TableColumn columnaCodigoPostal;
+ @FXML
+ private TableColumn columnaEstatus;
+
+ @FXML
+ private TreeView treeView;
+
+
+ private void initTabla() {
+ columnaNo.setCellValueFactory(new PropertyValueFactory<>("id"));
+ columnaNombre.setCellValueFactory(new PropertyValueFactory<>("nombre"));
+ columnaEmail.setCellValueFactory(new PropertyValueFactory<>("email"));
+ columnaTelefono.setCellValueFactory(new PropertyValueFactory<>("telefono"));
+ columnaDireccion.setCellValueFactory(new PropertyValueFactory<>("direccion"));
+ columnaPais.setCellValueFactory(new PropertyValueFactory<>("pais"));
+ columnaCiudad.setCellValueFactory(new PropertyValueFactory<>("ciudad"));
+ columnaCodigoPostal.setCellValueFactory(new PropertyValueFactory<>("codigoPostal"));
+ columnaEstatus.setCellValueFactory(new PropertyValueFactory<>("estatus"));
+
+ columnaNombre.setCellFactory(TextFieldTableCell.forTableColumn());
+ columnaEmail.setCellFactory(TextFieldTableCell.forTableColumn());
+ columnaTelefono.setCellFactory(TextFieldTableCell.forTableColumn());
+ columnaDireccion.setCellFactory(TextFieldTableCell.forTableColumn());
+ columnaPais.setCellFactory(ChoiceBoxTableCell.forTableColumn(data));
+ columnaCiudad.setCellFactory(TextFieldTableCell.forTableColumn());
+ columnaCodigoPostal.setCellFactory(TextFieldTableCell.forTableColumn());
+ columnaEstatus.setCellFactory((param) -> new RadioButtonCell<>(EnumSet.allOf(Estatus.class)));
+ }
+
+
+ @Override
+ public void initialize(URL location, ResourceBundle resources) {
+ llenarPaises();
+ initTabla();
+ tableView.setItems(business.Cliente.mostrar());
+ tableView.getSelectionModel().selectedItemProperty().addListener((v, oldValue, newValue) ->
+ cliente = newValue
+ );
+ treeView.setRoot(Main.iniciarItems());
+ treeView.getSelectionModel().selectedItemProperty().addListener((v, oldValue, newValue) ->
+ Main.cambiarScene(primaryStage, newValue));
+ }
+
+ private final ObservableList data = FXCollections.observableArrayList();
+ private void llenarPaises() {
+ data.add("");
+ for (String countrylist : Locale.getISOCountries()) {
+ Locale pais = new Locale("", countrylist);
+ data.add(pais.getDisplayCountry());
+ }
+ Collections.sort(data);
+ paises.setItems(data);
+ }
+
+ private void clear() {
+ nombre.setText("");
+ email.setText("");
+ telefono.setText("");
+ direccion.setText("");
+ codigoPostal.setText("");
+ ciudad.setText("");
+ paises.getSelectionModel().select(null);
+ }
+
+ @FXML
+ private void buscar() {
+ tableView.setItems(business.Cliente.buscar(nombre.getText()));
+ }
+
+ private boolean haConfirmado() {
+ String mensaje = ("Nombre: " + nombre.getText() + "\n") +
+ "Email: " + email.getText() + "\n" +
+ "Telefono: " + telefono.getText() + "\n" +
+ "Direccion: " + direccion.getText() + "\n" +
+ "Pais: " + paises.getSelectionModel().getSelectedItem() + "\n" +
+ "Ciudad: " + ciudad.getText() + "\n" +
+ "Codigo Postal: " + codigoPostal.getText() + "\n";
+
+ Alert alerta = new Alert(Alert.AlertType.CONFIRMATION);
+ alerta.setTitle("\"¿Desea continuar?\"");
+ alerta.setHeaderText(mensaje);
+ return alerta.showAndWait().isPresent();
+ }
+
+
+ @FXML
+ private void agregar() {
+ if (haConfirmado()) {
+ String context = business.Cliente.insertar(
+ nombre.getText(), direccion.getText(), ciudad.getText(), email.getText(), telefono.getText(),
+ codigoPostal.getText(), paises.getValue());
+ Alert insercion = new Alert(Alert.AlertType.INFORMATION, context);
+ insercion.show();
+ tableView.setItems(business.Cliente.mostrar());
+ clear();
+ }
+
+ }
+
+ private Cliente cliente = new Cliente();
+
+ @FXML
+ private void actualizar(TableColumn.CellEditEvent newValue) {
+ Cliente cliente = (Cliente) newValue.getTableView().getItems().get(
+ newValue.getTablePosition().getRow()
+ );
+ if (cliente == null)
+ return;
+ if (newValue.getNewValue().equals(newValue.getOldValue()))
+ return;
+
+ TableColumn col = newValue.getTableColumn();
+ String value = newValue.getNewValue().toString();
+
+ if (col.equals(columnaNombre)){
+ cliente.setNombre(value);
+ } else if(col.equals(columnaEmail)){
+ if (value.toLowerCase().equals(newValue.getOldValue())) {
+ cliente.setEmail(newValue.getOldValue().toString());
+ initTabla();
+ return;
+ } else{
+ cliente.setEmail(value.toLowerCase());
+ }
+ } else if (col.equals(columnaTelefono)){
+ cliente.setTelefono(value);
+ } else if (col.equals(columnaDireccion)){
+ cliente.setDireccion(value);
+ } else if (col.equals(columnaCodigoPostal)){
+ cliente.setCodigoPostal(value);
+ } else if (col.equals(columnaCiudad)){
+ cliente.setCiudad(value);
+ } else if (col.equals(columnaPais)){
+ cliente.setPais(value);
+ } else {
+ cliente.setEstatus(Estatus.valueOf(newValue.getNewValue().toString().toUpperCase()));
+ }
+
+ String context = business.Cliente.actualizar(
+ cliente.getId(), cliente.getNombre(), cliente.getDireccion(), cliente.getCiudad(), cliente.getEmail(),
+ cliente.getTelefono(), cliente.getCodigoPostal(), cliente.getPais(), cliente.getEstatus()
+ );
+ Alert insercion = new Alert(Alert.AlertType.INFORMATION, context);
+ insercion.show();
+ tableView.setItems(business.Cliente.mostrar());
+
+ }
+}
diff --git a/src/view/factura/Factura.fxml b/src/view/factura/Factura.fxml
new file mode 100644
index 0000000..f0549fe
--- /dev/null
+++ b/src/view/factura/Factura.fxml
@@ -0,0 +1,43 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/view/factura/FacturaActiva.fxml b/src/view/factura/FacturaActiva.fxml
new file mode 100644
index 0000000..06cd7fa
--- /dev/null
+++ b/src/view/factura/FacturaActiva.fxml
@@ -0,0 +1,99 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/view/factura/FacturaActivaController.java b/src/view/factura/FacturaActivaController.java
new file mode 100644
index 0000000..ecc4865
--- /dev/null
+++ b/src/view/factura/FacturaActivaController.java
@@ -0,0 +1,200 @@
+package view.factura;
+
+import data.Articulo;
+import data.Cliente;
+import data.FacturaDetalle;
+import javafx.collections.FXCollections;
+import javafx.collections.ObservableList;
+import javafx.fxml.FXML;
+import javafx.fxml.Initializable;
+import javafx.scene.Parent;
+import javafx.scene.Scene;
+import javafx.scene.control.*;
+import javafx.scene.control.cell.PropertyValueFactory;
+import javafx.scene.control.cell.TextFieldTableCell;
+import javafx.stage.Stage;
+import javafx.util.converter.IntegerStringConverter;
+import view.Main;
+import view.articulo.ArticuloActivoController;
+
+import java.io.IOException;
+import java.math.BigDecimal;
+import java.math.RoundingMode;
+import java.net.URL;
+import java.text.DecimalFormat;
+import java.time.LocalDate;
+import java.time.LocalTime;
+import java.time.format.DateTimeFormatter;
+import java.util.Map;
+import java.util.ResourceBundle;
+
+import static javafx.fxml.FXMLLoader.load;
+
+public class FacturaActivaController implements Initializable {
+
+ private static data.Factura factura_ = new data.Factura();
+ private static Stage primaryStage = new Stage();
+ private static final ObservableList detalles_ = FXCollections.observableArrayList();
+
+ public static void start(Stage stage, Cliente cliente,
+ Map articulos) throws IOException {
+ primaryStage = stage;
+ factura_ = new data.Factura(cliente);
+ cargarDetalles(articulos);
+ Parent root = load(FacturaActivaController.class.getResource("FacturaActiva.fxml"));
+ Scene scene = new Scene(root);
+ primaryStage.setScene(scene);
+ primaryStage.setTitle("Confirmar factura");
+ }
+
+
+ @FXML
+ private Label id;
+ @FXML
+ private Label nombre;
+ @FXML
+ private Label fecha;
+ @FXML
+ private Label hora;
+ @FXML
+ private Label totalBruto;
+ @FXML
+ private Label totalDescuento;
+ @FXML
+ private Label totalImpuesto;
+ @FXML
+ private Label totalCargo;
+ @FXML
+ private Label totalNeto;
+
+
+ @FXML
+ private TableView tableView;
+ @FXML
+ private TableColumn, ?> columnaNo;
+ @FXML
+ private TableColumn, ?> columnaCodigo;
+ @FXML
+ private TableColumn, ?> columnaNombre;
+ @FXML
+ private TableColumn, ?> columnaDescripcion;
+ @FXML
+ private TableColumn, Integer> columnaCantidad;
+ @FXML
+ private TableColumn, ?> columnaPrecio;
+ @FXML
+ private TableColumn, ?> columnaDescuento;
+ @FXML
+ private TableColumn, ?> columnaImpuesto;
+ @FXML
+ private TableColumn, ?> columnaNeto;
+
+ private void initTabla() {
+ columnaNo.setCellValueFactory(new PropertyValueFactory<>("linea"));
+ columnaCodigo.setCellValueFactory(new PropertyValueFactory<>("articuloCodigo"));
+ columnaNombre.setCellValueFactory(new PropertyValueFactory<>("articuloNombre"));
+ columnaDescripcion.setCellValueFactory(new PropertyValueFactory<>("articuloDescripcion"));
+ columnaCantidad.setCellValueFactory(new PropertyValueFactory<>("cantidad"));
+ columnaPrecio.setCellValueFactory(new PropertyValueFactory<>("precio"));
+ columnaDescuento.setCellValueFactory(new PropertyValueFactory<>("descuento"));
+ columnaImpuesto.setCellValueFactory(new PropertyValueFactory<>("impuesto"));
+ columnaNeto.setCellValueFactory(new PropertyValueFactory<>("neto"));
+ columnaCantidad.setCellFactory(TextFieldTableCell.forTableColumn(new IntegerStringConverter()));
+ calcularTotal();
+ }
+
+ private void calcularTotal() {
+
+ BigDecimal bruto = new BigDecimal("0.00");
+ BigDecimal descuento = new BigDecimal("0.00");
+ BigDecimal impuesto = new BigDecimal("0.00");
+ BigDecimal cargo = new BigDecimal(Math.random() * 300);
+ BigDecimal neto = new BigDecimal(cargo.doubleValue());
+ for (FacturaDetalle detalle : detalles_) {
+ bruto = bruto.add(detalle.getPrecio().multiply(BigDecimal.valueOf(detalle.getCantidad())));
+ descuento = descuento.add(detalle.getDescuento().multiply(BigDecimal.valueOf(detalle.getCantidad())));
+ impuesto = impuesto.add(detalle.getImpuesto().multiply(BigDecimal.valueOf(detalle.getCantidad())));
+ neto = neto.add(detalle.getNeto().multiply(BigDecimal.valueOf(detalle.getCantidad())));
+ }
+ DecimalFormat format = new DecimalFormat("###,##0.00");
+ factura_.setTotalBruto(bruto);
+ factura_.setTotalImpuesto(impuesto);
+ factura_.setTotalCargo(cargo);
+ factura_.setTotalDescuento(descuento);
+ factura_.setTotalNeto(neto);
+
+ totalBruto.setText(format.format(factura_.getTotalBruto()));
+ totalDescuento.setText(format.format(factura_.getTotalDescuento()));
+ totalImpuesto.setText(format.format(factura_.getTotalImpuesto() ));
+ totalCargo.setText(format.format(factura_.getTotalCargo()));
+ totalNeto.setText(format.format(factura_.getTotalNeto()));
+ }
+
+ @FXML
+ private TreeView treeView;
+
+ @Override
+ public void initialize(URL location, ResourceBundle resources) {
+ initTabla();
+ tableView.setItems(detalles_);
+ id.setText(String.valueOf(factura_.getClienteId()));
+ nombre.setText(factura_.getClienteNombre());
+ fecha.setText(LocalDate.now().toString());
+ hora.setText(LocalTime.now().format(DateTimeFormatter.ofPattern("HH:mm:ss")));
+ treeView.setRoot(Main.iniciarItems());
+ treeView.getSelectionModel().selectedItemProperty().addListener((v, oldValue, newValue) ->
+ Main.cambiarScene(primaryStage, newValue));
+ }
+
+ private static void cargarDetalles(Map articulos) {
+ factura_.getDetalles().clear();
+ short linea = 0;
+ final double ITBIS = 0.18;
+ for (Map.Entry entry : articulos.entrySet()) {
+ FacturaDetalle detalle = new FacturaDetalle(factura_.getId(), entry.getKey(), entry.getValue());
+ detalle.setLinea(++linea);
+ detalle.setImpuesto(new BigDecimal(ITBIS * detalle.getPrecio().doubleValue())
+ .setScale(2, RoundingMode.CEILING));
+ final double DESCT = 0.08 * Math.random();
+ detalle.setDescuento(new BigDecimal( DESCT * detalle.getPrecio().doubleValue())
+ .setScale(2, RoundingMode.CEILING));
+ detalle.setNeto(detalle.getPrecio().add(detalle.getImpuesto()).subtract(detalle.getDescuento()));
+ factura_.getDetalles().add(detalle);
+ detalles_.add(detalle);
+ }
+
+ }
+
+
+ @FXML
+ private void cambiarCantidad(TableColumn.CellEditEvent newValue){
+ FacturaDetalle detalle = tableView.getSelectionModel().getSelectedItem();
+
+ if (detalle == null || newValue == null)
+ return;
+ if (newValue.getNewValue().equals(newValue.getOldValue()))
+ return;
+
+ detalle.setCantidad((int)newValue.getNewValue());
+ }
+
+ @FXML
+ private void confirmar() throws IOException {
+ Alert alerta = new Alert(Alert.AlertType.CONFIRMATION);
+ alerta.setTitle("¿Desea continuar?");
+ alerta.setHeaderText("Presione ok para confirmar la factura");
+ if (alerta.showAndWait().isPresent()) {
+ Alert insercion = new Alert(Alert.AlertType.INFORMATION,
+ factura_.insertar());
+ insercion.show();
+ FacturaController.start(primaryStage);
+ }
+ }
+
+ @FXML
+ private void cancelar() throws IOException {
+ detalles_.clear();
+ ArticuloActivoController.start(primaryStage, factura_.getCliente());
+ }
+
+}
diff --git a/src/view/factura/FacturaController.java b/src/view/factura/FacturaController.java
new file mode 100644
index 0000000..6ce9493
--- /dev/null
+++ b/src/view/factura/FacturaController.java
@@ -0,0 +1,109 @@
+package view.factura;
+
+import com.jfoenix.controls.JFXTextField;
+import data.Factura;
+import javafx.fxml.FXML;
+import javafx.fxml.FXMLLoader;
+import javafx.fxml.Initializable;
+import javafx.scene.Parent;
+import javafx.scene.Scene;
+import javafx.scene.control.Button;
+import javafx.scene.control.TableColumn;
+import javafx.scene.control.TableView;
+import javafx.scene.control.TreeView;
+import javafx.scene.control.cell.PropertyValueFactory;
+import javafx.stage.Stage;
+import view.Main;
+
+import java.io.IOException;
+import java.net.URL;
+import java.util.ResourceBundle;
+
+public class FacturaController implements Initializable {
+
+ private static Stage primaryStage;
+
+ public static void start(Stage stage) throws IOException {
+ primaryStage = stage;
+ Parent root = FXMLLoader.load(FacturaController.class.getResource("Factura.fxml"));
+ Scene scene = new Scene(root);
+ primaryStage.setScene(scene);
+ primaryStage.setTitle("Ver Facturas");
+ }
+
+ @FXML
+ TableView tableView;
+ @FXML
+ private TableColumn, ?> columnaClienteNo;
+ @FXML
+ private TableColumn, ?> columnaClienteNombre;
+ @FXML
+ private TableColumn, ?> columnaNo;
+ @FXML
+ private TableColumn, ?> columnaFecha;
+ @FXML
+ private TableColumn, ?> columnaHora;
+ @FXML
+ private TableColumn, ?> columnaTotalBruto;
+ @FXML
+ private TableColumn, ?> columnaTotalDescuento;
+ @FXML
+ private TableColumn, ?> columnaTotalImpuesto;
+ @FXML
+ private TableColumn, ?> columnaTotalCargo;
+ @FXML
+ private TableColumn, ?> columnaTotalNeto;
+
+ private void initTabla() {
+ columnaClienteNo.setCellValueFactory(new PropertyValueFactory<>("clienteId"));
+ columnaClienteNombre.setCellValueFactory(new PropertyValueFactory<>("clienteNombre"));
+ columnaNo.setCellValueFactory(new PropertyValueFactory<>("numero"));
+ columnaFecha.setCellValueFactory(new PropertyValueFactory<>("fecha"));
+ columnaHora.setCellValueFactory(new PropertyValueFactory<>("hora"));
+ columnaTotalBruto.setCellValueFactory(new PropertyValueFactory<>("totalBruto"));
+ columnaTotalDescuento.setCellValueFactory(new PropertyValueFactory<>("totalDescuento"));
+ columnaTotalImpuesto.setCellValueFactory(new PropertyValueFactory<>("totalImpuesto"));
+ columnaTotalCargo.setCellValueFactory(new PropertyValueFactory<>("totalCargo"));
+ columnaTotalNeto.setCellValueFactory(new PropertyValueFactory<>("totalNeto"));
+ }
+
+ @FXML
+ private TreeView treeView;
+
+ @Override
+ public void initialize(URL location, ResourceBundle resources) {
+ initTabla();
+ tableView.setItems(business.Factura.mostrar());
+ tableView.getSelectionModel().selectedItemProperty().addListener(
+ (v, oldValue, newValue) -> {
+ if (newValue == null)
+ return;
+ factura = newValue;
+ numero.setText(String.valueOf(factura.getNumero()));
+ botonVerDetalles.setDisable(false);
+ }
+ );
+ treeView.setRoot(Main.iniciarItems());
+ treeView.getSelectionModel().selectedItemProperty().addListener((v, oldValue, newValue) ->
+ Main.cambiarScene(primaryStage, newValue));
+ }
+
+
+ @FXML
+ private JFXTextField numero;
+ @FXML
+ private Button botonVerDetalles;
+ private Factura factura = new Factura();
+
+ @FXML
+ private void verDetalles() throws IOException {
+ // Cargame un stage con los detalles, envia cliente No y ClienteNombre
+ numero.clear();
+ botonVerDetalles.setDisable(true);
+ Stage primaryStage = new Stage();
+ FacturaDetallesController.start(primaryStage, factura);
+ tableView.setItems(business.Factura.mostrar());
+ }
+
+
+}
diff --git a/src/view/factura/FacturaDetalles.fxml b/src/view/factura/FacturaDetalles.fxml
new file mode 100644
index 0000000..6b3d655
--- /dev/null
+++ b/src/view/factura/FacturaDetalles.fxml
@@ -0,0 +1,145 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/view/factura/FacturaDetallesController.java b/src/view/factura/FacturaDetallesController.java
new file mode 100644
index 0000000..d0389a3
--- /dev/null
+++ b/src/view/factura/FacturaDetallesController.java
@@ -0,0 +1,127 @@
+package view.factura;
+
+import data.Factura;
+import data.FacturaDetalle;
+import javafx.fxml.FXML;
+import javafx.fxml.FXMLLoader;
+import javafx.fxml.Initializable;
+import javafx.scene.Parent;
+import javafx.scene.Scene;
+import javafx.scene.control.Alert;
+import javafx.scene.control.Label;
+import javafx.scene.control.TableColumn;
+import javafx.scene.control.TableView;
+import javafx.scene.control.cell.PropertyValueFactory;
+import javafx.stage.Stage;
+
+import java.io.IOException;
+import java.net.URL;
+import java.text.DecimalFormat;
+import java.time.format.DateTimeFormatter;
+import java.util.ResourceBundle;
+
+public class FacturaDetallesController implements Initializable {
+ private static Stage primaryStage;
+ private static Factura factura_;
+
+ static void start(Stage stage, Factura factura) throws IOException {
+ primaryStage = stage;
+ factura_ = factura;
+ Parent root = FXMLLoader.load(FacturaDetallesController.class.getResource("FacturaDetalles.fxml"));
+ Scene scene = new Scene(root);
+ primaryStage.setScene(scene);
+ primaryStage.setTitle("Ver Facturas");
+ primaryStage.showAndWait();
+ }
+
+
+ @FXML
+ private TableView tableView;
+ @FXML
+ private TableColumn, ?> columnaNo;
+ @FXML
+ private TableColumn, ?> columnaCodigo;
+ @FXML
+ private TableColumn, ?> columnaNombre;
+ @FXML
+ private TableColumn, ?> columnaDescripcion;
+ @FXML
+ private TableColumn, ?> columnaCantidad;
+ @FXML
+ private TableColumn, ?> columnaPrecio;
+ @FXML
+ private TableColumn, ?> columnaDescuento;
+ @FXML
+ private TableColumn, ?> columnaImpuesto;
+ @FXML
+ private TableColumn, ?> columnaNeto;
+
+ private void initTabla() {
+ columnaNo.setCellValueFactory(new PropertyValueFactory<>("linea"));
+ columnaCodigo.setCellValueFactory(new PropertyValueFactory<>("articuloCodigo"));
+ columnaNombre.setCellValueFactory(new PropertyValueFactory<>("articuloNombre"));
+ columnaDescripcion.setCellValueFactory(new PropertyValueFactory<>("articuloDescripcion"));
+ columnaCantidad.setCellValueFactory(new PropertyValueFactory<>("cantidad"));
+ columnaPrecio.setCellValueFactory(new PropertyValueFactory<>("precio"));
+ columnaDescuento.setCellValueFactory(new PropertyValueFactory<>("descuento"));
+ columnaImpuesto.setCellValueFactory(new PropertyValueFactory<>("impuesto"));
+ columnaNeto.setCellValueFactory(new PropertyValueFactory<>("neto"));
+ }
+
+ @FXML
+ private Label id;
+ @FXML
+ private Label nombre;
+ @FXML
+ private Label numero;
+ @FXML
+ private Label fecha;
+ @FXML
+ private Label hora;
+ @FXML
+ private Label totalBruto;
+ @FXML
+ private Label totalDescuento;
+ @FXML
+ private Label totalImpuesto;
+ @FXML
+ private Label totalCargo;
+ @FXML
+ private Label totalNeto;
+
+ @Override
+ public void initialize(URL location, ResourceBundle resources) {
+ initTabla();
+ initLabels();
+ tableView.setItems(business.Factura.mostrarDetalles(factura_.getId()));
+ }
+
+ private void initLabels() {
+ id.setText(String.valueOf(factura_.getClienteId()));
+ nombre.setText(factura_.getClienteNombre());
+ numero.setText(String.valueOf(factura_.getNumero()));
+ fecha.setText(factura_.getFecha().toString());
+ hora.setText(factura_.getHora().format(DateTimeFormatter.ofPattern("HH:mm:ss")));
+ DecimalFormat f = new DecimalFormat("###,##0.00");
+ totalBruto.setText(f.format(factura_.getTotalBruto()));//.setScale(2, RoundingMode.CEILING).toPlainString()
+ totalDescuento.setText(f.format(factura_.getTotalDescuento()));
+ totalImpuesto.setText(f.format(factura_.getTotalImpuesto()));
+ totalCargo.setText(f.format(factura_.getTotalCargo()));
+ totalNeto.setText(f.format(factura_.getTotalNeto()));
+ }
+
+ @FXML
+ private void cancelarOrden() {
+ Alert alerta = new Alert(Alert.AlertType.CONFIRMATION);
+ alerta.setTitle("¿Desea cancelar la factura?");
+ alerta.setHeaderText("La factura va a ser cancelada.");
+ if (alerta.showAndWait().isPresent()) {
+ Alert insercion = new Alert(Alert.AlertType.INFORMATION,
+ business.Factura.eliminar(factura_.getId()));
+ insercion.show();
+ primaryStage.close();
+ }
+
+ }
+
+}
diff --git a/src/view/resources/aceptar.png b/src/view/resources/aceptar.png
new file mode 100644
index 0000000..2024f1d
Binary files /dev/null and b/src/view/resources/aceptar.png differ
diff --git a/src/view/resources/agregarCarrito.png b/src/view/resources/agregarCarrito.png
new file mode 100644
index 0000000..8c34a6f
Binary files /dev/null and b/src/view/resources/agregarCarrito.png differ
diff --git a/src/view/resources/articulos.png b/src/view/resources/articulos.png
new file mode 100644
index 0000000..12e96fc
Binary files /dev/null and b/src/view/resources/articulos.png differ
diff --git a/src/view/resources/articulosTabla.png b/src/view/resources/articulosTabla.png
new file mode 100644
index 0000000..65545eb
Binary files /dev/null and b/src/view/resources/articulosTabla.png differ
diff --git a/src/view/resources/botonAgregar.png b/src/view/resources/botonAgregar.png
new file mode 100644
index 0000000..ce6a40d
Binary files /dev/null and b/src/view/resources/botonAgregar.png differ
diff --git a/src/view/resources/botonBuscar.png b/src/view/resources/botonBuscar.png
new file mode 100644
index 0000000..e69f297
Binary files /dev/null and b/src/view/resources/botonBuscar.png differ
diff --git a/src/view/resources/botonEliminar.png b/src/view/resources/botonEliminar.png
new file mode 100644
index 0000000..1bcf2e9
Binary files /dev/null and b/src/view/resources/botonEliminar.png differ
diff --git a/src/view/resources/botonSiguiente.png b/src/view/resources/botonSiguiente.png
new file mode 100644
index 0000000..49f8d22
Binary files /dev/null and b/src/view/resources/botonSiguiente.png differ
diff --git a/src/view/resources/buscarTexto.png b/src/view/resources/buscarTexto.png
new file mode 100644
index 0000000..2253a52
Binary files /dev/null and b/src/view/resources/buscarTexto.png differ
diff --git a/src/view/resources/clientes.png b/src/view/resources/clientes.png
new file mode 100644
index 0000000..2ec5ab9
Binary files /dev/null and b/src/view/resources/clientes.png differ
diff --git a/src/view/resources/clientesTabla.png b/src/view/resources/clientesTabla.png
new file mode 100644
index 0000000..245a1c9
Binary files /dev/null and b/src/view/resources/clientesTabla.png differ
diff --git a/src/view/resources/comprar.png b/src/view/resources/comprar.png
new file mode 100644
index 0000000..2c91bb3
Binary files /dev/null and b/src/view/resources/comprar.png differ
diff --git a/src/view/resources/facturas.png b/src/view/resources/facturas.png
new file mode 100644
index 0000000..ccdd35f
Binary files /dev/null and b/src/view/resources/facturas.png differ
diff --git a/src/view/resources/facturasTabla.png b/src/view/resources/facturasTabla.png
new file mode 100644
index 0000000..9f93dab
Binary files /dev/null and b/src/view/resources/facturasTabla.png differ
diff --git a/src/view/resources/main.png b/src/view/resources/main.png
new file mode 100644
index 0000000..9020595
Binary files /dev/null and b/src/view/resources/main.png differ
diff --git a/src/view/resources/removerCarrito.png b/src/view/resources/removerCarrito.png
new file mode 100644
index 0000000..a21ab1d
Binary files /dev/null and b/src/view/resources/removerCarrito.png differ
diff --git a/src/view/resources/root.png b/src/view/resources/root.png
new file mode 100644
index 0000000..de2e631
Binary files /dev/null and b/src/view/resources/root.png differ