import java.util.*;
import java.text.NumberFormat;
import java.text.DateFormat;
//public class FacturaApp{
public class Main{
public static Factura factura = new Factura();
public static void main(String args[]){
System.out.println("Bienvenido a la aplicación de Facturación\n") ;
getItems();
displayFactura();
}
public static void getItems(){
Scanner sc = new Scanner(System.in);
String choice = "s";
while (choice.equalsIgnoreCase("s")){
String productoCodigo = Validator.getString(sc, "Ingrese el código del producto: ");
int cantidad = Validator.getInt(sc,"Ingrese cantidad: ", 0, 1000);
Producto producto = ProductoDB.getProducto(productoCodigo);
factura.addItem(new Item(producto, cantidad));
choice = Validator.getString(sc, "Otro producto? (s/n): ");
System.out.println() ;
}
}
public static void displayFactura() {
System.out.println("Código\tDescripción\t\t\t Precio\tCantidad Total");
System.out.println("------\t-----------\t\t\t-------\t-------- ------- ") ;
for (Item item : factura.getItems()){
Producto producto = item.getProducto();
String s = producto.getCodigo()
+ "\t" + producto.getDescripcion()
+ "\t" + producto.getFormattedPrecio()
+ "\t " + item.getCantidad()
+ " " + item.getFormattedTotal();
System.out.println(s);
}
System.out.println("\n\t\t\t\t\tTotal factura:\t " + factura.getFormattedTotal());
System.out.println("\t\t\t\t\tFecha :\t " + factura.getFormattedDate());
}
}
class Factura{
private ArrayList<Item> items;
private Date facturaDate;
public Factura(){
items = new ArrayList<>();
facturaDate = DateUtils.getCurrentDate(); // Date facturaDate = hoy con horas, min,.. = 0
}
public void addItem(Item item) {
this.items.add(item);
}
public ArrayList<Item> getItems(){
return items;
}
public double getFacturaTotal(){
double facturaTotal = 0;
for (Item item : this.items) facturaTotal += item.getTotal();
return facturaTotal;
}
public String getFormattedTotal(){
NumberFormat currency = NumberFormat.getCurrencyInstance();
return currency.format(this.getFacturaTotal());
}
// retorna String formateada
public String getFormattedDate(){ // retorna facturaDate formateada
DateFormat shortDate = DateFormat.getDateInstance(DateFormat.SHORT);
return shortDate.format(facturaDate);
}
}
class Item{
private Producto producto;
private int cantidad;
private double total;
public Item(){
this.producto = new Producto();
this.cantidad = 0 ;
this.total = 0 ;
}
public Item(Producto producto, int cantidad){
this.producto = producto;
this.cantidad = cantidad;
this.total = 0 ;
}
public void setProducto(Producto producto){this.producto = producto;}
public Producto getProducto(){return producto;}
public void setCantidad(int cantidad){this.cantidad = cantidad;}
public int getCantidad(){return cantidad;}
private void calcularTotal(){total = cantidad * producto.getPrecio();}
public double getTotal(){this.calcularTotal(); return total;}
public String getFormattedTotal(){
calcularTotal();
NumberFormat currency = NumberFormat.getCurrencyInstance();
return currency.format(total);
}
}
class Producto{
private String codigo;
private String descripcion;
private double precio;
public Producto(){ // un constructor de objetos: da valores a atributos no static
codigo = "";
descripcion = "";
precio = 0 ;
}
public void setCodigo(String codigo) {this.codigo = codigo;}
public String getCodigo(){return codigo;}
public void setDescripcion(String descripcion){ this.descripcion = descripcion;}
public String getDescripcion(){return descripcion;}
public void setPrecio(double precio){this.precio = precio;}
public double getPrecio(){return precio;}
public String getFormattedPrecio(){ // precio con formato
NumberFormat moneda = NumberFormat.getCurrencyInstance();
return moneda.format(precio);
}
}
class ProductoDB {
public static Producto getProducto(String productoCodigo){
Producto p = new Producto(); // crea un objeto
p.setCodigo(productoCodigo); // llena los atributos del objeto
if (productoCodigo.equalsIgnoreCase("java")){
p.setDescripcion("Java SE ");
p.setPrecio(49.50);
} else if (productoCodigo.equalsIgnoreCase("jssp")){
p.setDescripcion("Java Servlets y JSP ");
p.setPrecio(49.50);
} else if (productoCodigo.equalsIgnoreCase("fprg")){
p.setDescripcion("Fundamentos de Programación");
p.setPrecio(59.50);
} else p.setDescripcion("Desconocido ");
return p;
}
}
class Validator {
public static String getString(Scanner sc, String prompt){
System.out.print(prompt);
String s = sc.next();
sc.nextLine();
return s;
}
public static int getInt(Scanner sc, String prompt){
int i = 0 ;
boolean isValid = false;
while (isValid == false){
System.out.print(prompt);
if (sc.hasNextInt()){
i = sc.nextInt();
isValid = true;
} else System.out.println("Error! Valor entero no válido. Intente de nuevo.");
sc.nextLine();
}
return i;
}
public static int getInt(Scanner sc, String prompt, int min, int max){
int i = 0;
boolean isValid = false;
while (isValid == false){
i = getInt(sc, prompt);
if (i < min) System.out.println("Error! El número debe ser mayor o igual que " + min + ".");
else if (i > max) System.out.println("Error! El número debe ser menor o igual que " + max + ".");
else isValid = true;
}
return i ;
}
public static double getDouble(Scanner sc, String prompt){
double d = 0 ;
boolean isValid = false;
while (isValid == false){
System.out.print(prompt);
if (sc.hasNextDouble()){
d = sc.nextDouble();
isValid = true;
} else System.out.println("Error! Valor decimal no válido. Intente de nuevo.");
sc.nextLine();
}
return d;
}
public static double getDouble(Scanner sc, String prompt, double min, double max) {
double d = 0 ;
boolean isValid = false;
while (isValid == false){
d = getDouble(sc, prompt);
if (d < min) System.out.println("Error! El número debe ser mayor o igual que " + min + ".");
else if (d > max) System.out.println("Error! El número debe ser menor o igual que " + max + ".");
else isValid = true;
}
return d;
}
public static float getFloat(Scanner sc, String prompt){
float d = 0 ;
boolean isValid = false;
while (isValid == false){
System.out.print(prompt);
if (sc.hasNextFloat()){
d = sc.nextFloat();
isValid = true;
} else System.out.println("Error! Valor decimal no válido. Intente de nuevo.");
sc.nextLine();
}
return d;
}
public static float getFloat(Scanner sc, String prompt, float min, float max) {
float d = 0 ;
boolean isValid = false;
while (isValid == false){
d = getFloat(sc, prompt);
if (d < min) System.out.println("Error! El número debe ser mayor o igual que " + min + ".");
else if (d > max) System.out.println("Error! El número debe ser menor o igual que " + max + ".");
else isValid = true;
}
return d;
}
}
class DateUtils {
static final int MILLS_IN_DAY = 24 * 60 * 60 * 1000;
public static Date getCurrentDate() { // Retorna Date de hoy día a las 0 horas
GregorianCalendar hoy = new GregorianCalendar();
hoy.set(Calendar.HOUR, 0);
hoy.set(Calendar.MINUTE, 0);
hoy.set(Calendar.SECOND, 0);
return hoy.getTime(); // convierte a Date
}
public static Date createDate(int anno, int mes, int dia) { // Retorna Date a las 0 horas
GregorianCalendar fecha = new GregorianCalendar(anno, mes, dia);
return fecha.getTime(); // retorna un Date
}
public static Date stripTime(Date date) { // retorna Date con time = 0
GregorianCalendar fecha = new GregorianCalendar(); // fecha de hoy
fecha.setTime(date); // Cambia el valor de fecha al de date
fecha.set(Calendar.HOUR, 0);
fecha.set(Calendar.MINUTE, 0);
fecha.set(Calendar.SECOND, 0);
return fecha.getTime(); // retorna un Date
}
public static int daysDiff(Date date1, Date date2) { // retorna # días entre dos fechas
date1 = stripTime(date1);
date2 = stripTime(date2);
long longDate1 = date1.getTime();
long longDate2 = date2.getTime();
long longDiff = longDate2 - longDate1; // diferencia en milisegundos
return (int) (longDiff / MILLS_IN_DAY ) ;
}
}