import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
/**
* Esta clase nos ayuda a gestionar los productos de la tienda. Para invocar a
* esta clase se debe utilizar el método getInstance
* <code>GestionProductos.getInstance()</code> a partir de ahí se puede utilizar
* los métodos que contiene la clase
*
* @author billy.johnson
*/
public class GestionProductos {
LinkedList<Producto> productos;
Map<Integer, List<Producto>> productosMes;
private Producto productoMasCostoso;
private static GestionProductos gestion = null;
public static final Integer ENERO = 1;
public static final Integer FEBRERO = 2;
public static final Integer MARZO = 3;
public static final Integer ABRIL = 4;
public static final Integer MAYO = 5;
public static final Integer JUNIO = 6;
public static final Integer JULIO = 7;
public static final Integer AGOSTO = 8;
public static final Integer SEPTIEMBRE = 9;
public static final Integer OCTUBRE = 10;
public static final Integer NOVIEMBRE = 11;
public static final Integer DICIEMBRE = 12;
/**
* Constructor de la clase
*/
private GestionProductos() {
productos = new LinkedList();
productosMes = new HashMap();
}
/**
* Devuelve una instancia de la clase
*
* @return
*/
public static GestionProductos getInstance() {
if (gestion == null) {
gestion = new GestionProductos();
}
return gestion;
}
/**
* Registra un nuevo producto con la fecha actual como fecha de ingreso
*
* @param mes
* @param nombre
* @param codigo
* @param precio
* @param fechaVencimiento la fecha debe tener este formato yyyy/mmm/dd
* @return
*/
public Producto registrarProducto(Integer mes, String nombre, String codigo, Double precio, String fechaVencimiento) {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd");
return registrarProducto(mes, nombre, codigo, precio, fechaVencimiento, sdf.format(Calendar.getInstance().getTime()));
}
/**
* Registra un nuevo producto
*
* @param mes
* @param nombre
* @param codigo
* @param precio
* @param fechaVencimiento la fecha debe tener este formato yyyy/mmm/dd
* @param fechaIngreso la fecha debe tener este formato yyyy/mmm/dd
* @return
*/
public Producto registrarProducto(Integer mes, String nombre, String codigo, Double precio, String fechaVencimiento, String fechaIngreso) {
if (mes < 1 || mes > 12) {
return null;
} else {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd");
Producto p = new Producto();
try {
p.setNombre(nombre);
p.setCodigo(codigo);
p.setPrecio(precio);
p.setFechaIngreso(sdf.parse(fechaIngreso));
p.setFechaVencimiento(sdf.parse(fechaVencimiento));
productos.add(p);
if (productosMes.containsKey(mes)) {
productosMes.get(mes).add(p);
} else {
List<Producto> pp = new ArrayList();
pp.add(p);
productosMes.put(mes, pp);
}
if (productos.size() == 1) {
productoMasCostoso = p;
} else {
setProductoMasCostoso();
}
System.out.println("Producto agregado");
} catch (ParseException ex) {
System.out.println("ERROR: formato de fecha incorrecto");
return null;
}
return p;
}
}
/**
* Devuelve el primer producto de los ingresados
*
* @return
*/
public Producto getPrimerProducto() {
if (productos.isEmpty()) {
return null;
} else {
return productos.getFirst();
}
}
/**
* Devuelve el último producto de los ingresados
*
* @return
*/
public Producto getUltimoProducto() {
if (productos.isEmpty()) {
return null;
} else {
return productos.getLast();
}
}
/**
* @return the productoMasCostoso
*/
public Producto getProductoMasCostoso() {
return productoMasCostoso;
}
private void setProductoMasCostoso() {
// for(Producto p : productos){
// if(p.getPrecio() > productoMasCostoso.getPrecio()){
// productoMasCostoso = p;
// }
// }
productos.stream().filter((p) -> (p.getPrecio() > productoMasCostoso.getPrecio())).forEachOrdered((p) -> {
productoMasCostoso = p;
});
}
/**
* Devuelve la cantidad de productos ingresados
*
* @return
*/
public Integer getProductosCount() {
return productos.size();
}
/**
* Devuelve la sumatoria de precios los productos que no están vencidos
*
* @return
*/
public Double getCostoTotal() {
Double total = 0.0;
// for (Producto p : productos) {
// if (!p.isVencido()) {
// total += p.getPrecio();
// }
// }
total = productos.stream().filter((p) -> (!p.isVencido())).map((p) -> p.getPrecio()).reduce(total, (accumulator, _item) -> accumulator + _item);
return total;
}
/**
* Devuelve el promedio de precios de los productos que no estén vencidos
*
* @return
*/
public Double getPromedioPrecios() {
int count = 0;
// for (Producto p : productos) {
// if (!p.isVencido()) {
// count++;
// }
// }
count = productos.stream().filter((p) -> (!p.isVencido())).map((_item) -> 1).reduce(count, Integer::sum);
return getCostoTotal() / count;
}
/**
* Imprimir productos ingresados por mes
*/
public void imprimirProductosPorMes() {
SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");
String[] meses = {
"ENERO",
"FEBRERO",
"MARZO",
"MAYO",
"ABRIL",
"JUNIO",
"JULIO",
"AGOSTO",
"SEPTIEMBRE",
"OCTUBRE",
"NOVIEMBRE",
"DICIEMBRE"
};
for (int i = 1; i <= meses.length; i++) {
if (productosMes.containsKey(i)) {
System.out.println("Mes " + meses[i] + ":");
productosMes.get(i - 1).forEach(p -> {
System.out.println(
"Codigo: " + p.getCodigo()
+ "\nNombre: " + p.getNombre()
+ "\nPrecio: " + p.getPrecio()
+ "\nFecha de ingreso: " + sdf.format(p.getFechaIngreso())
+ "\nFecha de vencimiento: " + sdf.format(p.getFechaVencimiento())
+ "\nVencido: " + (p.isVencido() ? "Si" : "No") + "\n"
);
});
System.out.println("------------------------------------------\n");
}
}
}
}