/src/lei/li3/g50/modulos/compras/Compras.java

https://gitlab.com/andrerfcsantos/GesthiperJava · Java · 432 lines · 325 code · 88 blank · 19 comment · 51 complexity · 9900ae1b3ae58b91c3b6bbb842ad5733 MD5 · raw file

  1. package lei.li3.g50.modulos.compras;
  2. import java.io.Serializable;
  3. import java.util.ArrayList;
  4. import java.util.Arrays;
  5. import java.util.HashMap;
  6. import java.util.List;
  7. import java.util.Map;
  8. import java.util.Objects;
  9. import java.util.TreeMap;
  10. import java.util.TreeSet;
  11. import lei.li3.g50.excepcoes.ClienteNaoComprouProdutoException;
  12. import lei.li3.g50.excepcoes.ClienteNaoExisteException;
  13. import lei.li3.g50.excepcoes.ProdutoNaoExisteException;
  14. import lei.li3.g50.modulos.dados.Cliente;
  15. import lei.li3.g50.modulos.dados.Compra;
  16. import lei.li3.g50.modulos.dados.Mes;
  17. import lei.li3.g50.modulos.dados.Produto;
  18. import lei.li3.g50.modulos.dados.TipoCompra;
  19. import lei.li3.g50.utilitarios.ComparatorParClienteProdutosDiferentes;
  20. import lei.li3.g50.utilitarios.ComparatorTriploClienteQtdCompradaDinheiro;
  21. import lei.li3.g50.utilitarios.Matriz_Double_12x2;
  22. import lei.li3.g50.utilitarios.Matriz_Int_12x2;
  23. import lei.li3.g50.utilitarios.ParClienteProdutosDiferentes;
  24. import lei.li3.g50.utilitarios.ParProdutoQuantidadeComprada;
  25. import lei.li3.g50.utilitarios.TriploClienteQtdCompradaDinheiro;
  26. public class Compras implements Serializable {
  27. private static final long serialVersionUID = 7175792608614138915L;
  28. private int numeroComprasValorZero;
  29. private int numeroClientesDistintosPorMes[];
  30. private int numeroTotalClientesDistintos;
  31. private TreeMap<Cliente, FichaClienteCompras> arvoreClientes;
  32. private HashMap<Produto, ParProdutoNClientes> arvoreParesProdutoNClientes;
  33. /*
  34. CONSTRUCTORES
  35. */
  36. public Compras() {
  37. this.numeroComprasValorZero = 0;
  38. numeroTotalClientesDistintos = 0;
  39. numeroClientesDistintosPorMes = new int[12];
  40. arvoreClientes = new TreeMap<>();
  41. arvoreParesProdutoNClientes = new HashMap<>();
  42. }
  43. public Compras(Compras compras) {
  44. numeroTotalClientesDistintos = compras.getTotalClientesDistintos();
  45. this.numeroComprasValorZero = compras.getNumeroComprasValorZero();
  46. for (int i = 0; i < 12; i++) {
  47. this.numeroClientesDistintosPorMes[i] = compras.numeroClientesDistintosPorMes[i];
  48. }
  49. for (Map.Entry<Cliente, FichaClienteCompras> entrada : compras.arvoreClientes.entrySet()) {
  50. this.arvoreClientes.put(entrada.getKey().clone(), entrada.getValue().clone());
  51. }
  52. for (Map.Entry<Produto, ParProdutoNClientes> entrada : compras.arvoreParesProdutoNClientes.entrySet()) {
  53. this.arvoreParesProdutoNClientes.put(entrada.getKey().clone(), entrada.getValue().clone());
  54. }
  55. }
  56. /*
  57. REGISTOS
  58. */
  59. public void registaCliente(Cliente cliente) {
  60. this.arvoreClientes.put(cliente.clone(), new FichaClienteCompras());
  61. }
  62. public void registaProduto(Produto produto) {
  63. this.arvoreParesProdutoNClientes.put(produto.clone(), new ParProdutoNClientes());
  64. }
  65. public void registaCompra(Compra compra) {
  66. Mes mes = compra.getMes();
  67. Produto produto = compra.getProduto();
  68. FichaClienteCompras ficha_cliente;
  69. try {
  70. ficha_cliente = getFichaClienteNoClone(compra.getCliente());
  71. } catch (ClienteNaoExisteException ex) {
  72. ficha_cliente = new FichaClienteCompras();
  73. this.arvoreClientes.put(compra.getCliente().clone(), ficha_cliente);
  74. }
  75. if (ficha_cliente.getNumComprasMes(mes, TipoCompra.AMBOS) == 0) {
  76. numeroClientesDistintosPorMes[mes.getIndiceArray()]++;
  77. }
  78. if (ficha_cliente.getTotalCompras() == 0) {
  79. numeroTotalClientesDistintos++;
  80. }
  81. ParProdutoNClientes par_prod_nclis;
  82. try {
  83. par_prod_nclis = this.getParProdutoNClientesNoClone(produto);
  84. } catch (ProdutoNaoExisteException ex) {
  85. par_prod_nclis = new ParProdutoNClientes();
  86. this.arvoreParesProdutoNClientes.put(compra.getProduto().clone(), par_prod_nclis);
  87. }
  88. try {
  89. Matriz_Int_12x2 comprasMeses = ficha_cliente.getNumComprasProdutoMeses(produto);
  90. if (comprasMeses.getValorMesTipoCompra(mes, TipoCompra.AMBOS) == 0) {
  91. par_prod_nclis.addNumeroClientesMes(mes, 1);
  92. }
  93. if (comprasMeses.getSomaTotal() == 0) {
  94. par_prod_nclis.addNumeroTotalClientesDistintos(1);
  95. }
  96. } catch (ClienteNaoComprouProdutoException ex) {
  97. par_prod_nclis.addNumeroClientesMes(mes, 1);
  98. par_prod_nclis.addNumeroTotalClientesDistintos(1);
  99. }
  100. if (compra.getPreco() == 0) {
  101. this.numeroComprasValorZero++;
  102. }
  103. ficha_cliente.regista_compra(compra);
  104. }
  105. /*
  106. GETTERS ESPECIFICOS CLASSE
  107. */
  108. /*COMPRAS*/
  109. public int getNumeroComprasValorZero() {
  110. return numeroComprasValorZero;
  111. }
  112. /*CLIENTES DISTINTOS*/
  113. public int getTotalClientesDistintos() {
  114. return this.numeroTotalClientesDistintos;
  115. }
  116. public int getNumeroClientesDistintosMes(Mes mes) {
  117. return this.numeroClientesDistintosPorMes[mes.getIndiceArray()];
  118. }
  119. public int[] getNumeroClientesDistintosMesesAsArray() {
  120. int resultado[] = new int[12];
  121. for (int i = 0; i < 12; i++) {
  122. resultado[i] = this.numeroClientesDistintosPorMes[i];
  123. }
  124. return resultado;
  125. }
  126. public Map<Mes, Integer> getNumeroClientesDistintosMeses() {
  127. Mes mes;
  128. TreeMap<Mes, Integer> resultado = new TreeMap<>();
  129. for (int i = 0; i < 12; i++) {
  130. mes = Mes.numero_to_mes(i + 1);
  131. resultado.put(mes, this.numeroClientesDistintosPorMes[i]);
  132. }
  133. return resultado;
  134. }
  135. /*GETTERS CLASSES INFERIORES*/
  136. /*CLASSE FICHA CLIENTE*/
  137. private FichaClienteCompras getFichaClienteNoClone(Cliente cliente) throws ClienteNaoExisteException {
  138. FichaClienteCompras ficha;
  139. if (this.arvoreClientes.containsKey(cliente)) {
  140. ficha = this.arvoreClientes.get(cliente);
  141. } else {
  142. throw new ClienteNaoExisteException();
  143. }
  144. return ficha;
  145. }
  146. public int getNumeroProdutosDistintosCliente(Cliente cliente) throws ClienteNaoExisteException {
  147. return this.getFichaClienteNoClone(cliente).getNumeroProdutosDistintos();
  148. }
  149. public Matriz_Int_12x2 getNumeroUnidadesCompradasClienteMeses(Cliente cliente) throws ClienteNaoExisteException {
  150. return this.getFichaClienteNoClone(cliente).getNumUnidadesCompradasClientePorMes();
  151. }
  152. public Matriz_Int_12x2 getNumeroComprasClienteMeses(Cliente cliente) throws ClienteNaoExisteException {
  153. return this.getFichaClienteNoClone(cliente).getNumComprasClientePorMes();
  154. }
  155. public Matriz_Double_12x2 getDinheiroGastoClienteMeses(Cliente cliente) throws ClienteNaoExisteException {
  156. return this.getFichaClienteNoClone(cliente).getDinheiroGastoClientePorMes();
  157. }
  158. public int getNumeroUnidadesCompradasClienteMes(Cliente cliente, Mes mes) throws ClienteNaoExisteException {
  159. return this.getFichaClienteNoClone(cliente).getNumUnidadesCompradasMes(mes, TipoCompra.AMBOS);
  160. }
  161. public int getNumeroComprasClienteMes(Cliente cliente, Mes mes) throws ClienteNaoExisteException {
  162. return this.getFichaClienteNoClone(cliente).getNumComprasMes(mes, TipoCompra.AMBOS);
  163. }
  164. public double getDinheiroGastoClienteMes(Cliente cliente, Mes mes) throws ClienteNaoExisteException {
  165. return this.getFichaClienteNoClone(cliente).getDinheiroGastoClientePorMes(mes, TipoCompra.AMBOS);
  166. }
  167. public int getTotalUnidadesCompradasCliente(Cliente cliente) throws ClienteNaoExisteException {
  168. return this.getFichaClienteNoClone(cliente).getTotalUnidadesCompradas();
  169. }
  170. public int getTotalComprasCliente(Cliente cliente) throws ClienteNaoExisteException {
  171. return this.getFichaClienteNoClone(cliente).getTotalCompras();
  172. }
  173. public double getTotalDinheiroGasto(Cliente cliente) throws ClienteNaoExisteException {
  174. return this.getFichaClienteNoClone(cliente).getTotalDinheiroGasto();
  175. }
  176. /*CLASSE ParProdutoNClientes*/
  177. private ParProdutoNClientes getParProdutoNClientesNoClone(Produto produto) throws ProdutoNaoExisteException {
  178. ParProdutoNClientes resultado;
  179. if (this.arvoreParesProdutoNClientes.containsKey(produto)) {
  180. resultado = this.arvoreParesProdutoNClientes.get(produto);
  181. } else {
  182. throw new ProdutoNaoExisteException();
  183. }
  184. return resultado;
  185. }
  186. public int getTotalClientesDistintosProduto(Produto produto) throws ProdutoNaoExisteException {
  187. return this.getParProdutoNClientesNoClone(produto).getNumeroTotalClientesDisntintos();
  188. }
  189. public Map<Mes, Integer> getClientesDistintosProdutoMeses(Produto produto) throws ProdutoNaoExisteException {
  190. return this.getParProdutoNClientesNoClone(produto).getNumeroClientesDistintosPorMes();
  191. }
  192. public int getClientesDistintosProdutoMes(Produto produto, Mes mes) throws ProdutoNaoExisteException {
  193. return this.getParProdutoNClientesNoClone(produto).getNumeroClientesDisntintosMes(mes);
  194. }
  195. /*CLASSE FichaProdutoDeClienteCompras (ASSOCIACAO PRODUTO-CLIENTE)*/
  196. public Matriz_Int_12x2 getComprasProdutoClienteMeses(Produto produto, Cliente cliente) throws ClienteNaoExisteException, ClienteNaoComprouProdutoException {
  197. return this.getFichaClienteNoClone(cliente).getNumComprasProdutoMeses(produto);
  198. }
  199. public Matriz_Int_12x2 getUnidadesCompradasProdutoClienteMeses(Produto produto, Cliente cliente) throws ClienteNaoExisteException, ClienteNaoComprouProdutoException {
  200. return this.getFichaClienteNoClone(cliente).getNumUnidadesCompradasProdutoMeses(produto);
  201. }
  202. public int getTotalComprasProdutoCliente(Produto produto, Cliente cliente) throws ClienteNaoExisteException, ClienteNaoComprouProdutoException {
  203. return this.getFichaClienteNoClone(cliente).getNumTotalUnidadesCompradasProduto(produto);
  204. }
  205. public int getTotalUnidadesCompradasProdutoCliente(Produto produto, Cliente cliente) throws ClienteNaoExisteException, ClienteNaoComprouProdutoException {
  206. return this.getFichaClienteNoClone(cliente).getNumTotalUnidadesCompradasProduto(produto);
  207. }
  208. public double getTotalDinheiroGastoProdutoCliente(Produto produto, Cliente cliente) throws ClienteNaoExisteException, ClienteNaoComprouProdutoException {
  209. return this.getFichaClienteNoClone(cliente).getDinheiroGastoProduto(produto);
  210. }
  211. /*RESULTADOS QUERIES*/
  212. public int getTotalClientesSemCompras() {
  213. int resultado = 0;
  214. for (Map.Entry<Cliente, FichaClienteCompras> entrada : this.arvoreClientes.entrySet()) {
  215. if (entrada.getValue().getTotalCompras() == 0) {
  216. resultado++;
  217. }
  218. }
  219. return resultado;
  220. }
  221. public int getTotalProdutosNaoComprados() {
  222. int resultado = 0;
  223. for (Map.Entry<Produto, ParProdutoNClientes> entrada : this.arvoreParesProdutoNClientes.entrySet()) {
  224. if (entrada.getValue().getNumeroTotalClientesDisntintos() == 0) {
  225. resultado++;
  226. }
  227. }
  228. return resultado;
  229. }
  230. public Map<Mes, Integer> getNumeroProdutosDisntintosPorMesCliente(Cliente cliente) throws ClienteNaoExisteException {
  231. return this.getFichaClienteNoClone(cliente).getNumeroProdutosDistintosPorMes();
  232. }
  233. public List<Produto> getProdutosNaoComprados() {
  234. ArrayList<Produto> lista_produtos = new ArrayList<>();
  235. for (Map.Entry<Produto, ParProdutoNClientes> entrada : this.arvoreParesProdutoNClientes.entrySet()) {
  236. if (entrada.getValue().getNumeroTotalClientesDisntintos() == 0) {
  237. lista_produtos.add(entrada.getKey().clone());
  238. }
  239. }
  240. return lista_produtos;
  241. }
  242. public List<TriploClienteQtdCompradaDinheiro> getTriplosClienteQtdCompradaDinheiro(Produto produto, int topN) {
  243. int unidadesCompradas;
  244. double dinheiroGasto;
  245. TreeSet<TriploClienteQtdCompradaDinheiro> triplos = new TreeSet<>(new ComparatorTriploClienteQtdCompradaDinheiro());
  246. ArrayList<TriploClienteQtdCompradaDinheiro> lista_triplos = new ArrayList<>();
  247. TriploClienteQtdCompradaDinheiro novo_triplo;
  248. for (Map.Entry<Cliente, FichaClienteCompras> entrada : this.arvoreClientes.entrySet()) {
  249. try {
  250. unidadesCompradas = this.getTotalComprasProdutoCliente(produto, entrada.getKey());
  251. dinheiroGasto = this.getTotalDinheiroGastoProdutoCliente(produto, entrada.getKey());
  252. novo_triplo = new TriploClienteQtdCompradaDinheiro(entrada.getKey().clone(),
  253. unidadesCompradas,
  254. dinheiroGasto);
  255. triplos.add(novo_triplo);
  256. } catch (ClienteNaoComprouProdutoException | ClienteNaoExisteException ex) {
  257. }
  258. }
  259. for (TriploClienteQtdCompradaDinheiro triplo : triplos) {
  260. lista_triplos.add(triplo);
  261. }
  262. return lista_triplos.subList(0, (topN > lista_triplos.size()) ? lista_triplos.size() : topN);
  263. }
  264. public List<ParClienteProdutosDiferentes> getParesClienteProdutosDiferentes(int n) {
  265. TreeSet<ParClienteProdutosDiferentes> pares = new TreeSet<>(new ComparatorParClienteProdutosDiferentes());
  266. ArrayList<ParClienteProdutosDiferentes> lista = new ArrayList<>();
  267. ParClienteProdutosDiferentes novo_par;
  268. for (Map.Entry<Cliente, FichaClienteCompras> entrada : this.arvoreClientes.entrySet()) {
  269. novo_par = new ParClienteProdutosDiferentes(entrada.getKey().clone(), entrada.getValue().getNumeroProdutosDistintos());
  270. pares.add(novo_par);
  271. }
  272. for (ParClienteProdutosDiferentes par : pares) {
  273. lista.add(par);
  274. }
  275. if (n > arvoreClientes.size()) {
  276. n = arvoreClientes.size();
  277. }
  278. return lista.subList(0, n);
  279. }
  280. public List<ParProdutoQuantidadeComprada> getParesProdutoNumComprasCliente(Cliente cliente) throws ClienteNaoExisteException {
  281. return this.getFichaClienteNoClone(cliente).getParesProdutoQuantidadeComprada();
  282. }
  283. public List<Cliente> getClientesSemCompras() {
  284. ArrayList<Cliente> lista_clientes = new ArrayList<>(this.arvoreClientes.size() / 10);
  285. for (Map.Entry<Cliente, FichaClienteCompras> entrada : this.arvoreClientes.entrySet()) {
  286. if (entrada.getValue().getTotalCompras() == 0) {
  287. lista_clientes.add(entrada.getKey().clone());
  288. }
  289. }
  290. return (List<Cliente>) lista_clientes;
  291. }
  292. public List<Produto> getProdutosSemCompras() {
  293. ArrayList<Produto> lista_produtos = new ArrayList<>(this.arvoreClientes.size() / 10);
  294. for (Map.Entry<Produto, ParProdutoNClientes> entrada : this.arvoreParesProdutoNClientes.entrySet()) {
  295. if (entrada.getValue().getNumeroTotalClientesDisntintos() == 0) {
  296. lista_produtos.add(entrada.getKey().clone());
  297. }
  298. }
  299. return (List<Produto>) lista_produtos;
  300. }
  301. /*
  302. METODOS STANDARD
  303. */
  304. @Override
  305. public int hashCode() {
  306. int hash = 3;
  307. hash = 11 * hash + this.numeroComprasValorZero;
  308. hash = 11 * hash + Objects.hashCode(this.numeroClientesDistintosPorMes);
  309. hash = 11 * hash + Objects.hashCode(this.arvoreClientes);
  310. hash = 11 * hash + Objects.hashCode(this.arvoreParesProdutoNClientes);
  311. return hash;
  312. }
  313. @Override
  314. public boolean equals(Object obj) {
  315. if (this == obj) {
  316. return true;
  317. }
  318. if (obj == null) {
  319. return false;
  320. }
  321. if (getClass() != obj.getClass()) {
  322. return false;
  323. }
  324. final Compras other = (Compras) obj;
  325. return this.arvoreClientes.keySet().containsAll(other.arvoreClientes.keySet())
  326. && this.arvoreClientes.values().containsAll(other.arvoreClientes.values())
  327. && this.arvoreParesProdutoNClientes.keySet().containsAll(other.arvoreParesProdutoNClientes.keySet())
  328. && this.arvoreParesProdutoNClientes.values().containsAll(other.arvoreParesProdutoNClientes.values())
  329. && Arrays.equals(this.numeroClientesDistintosPorMes, other.numeroClientesDistintosPorMes)
  330. && this.numeroComprasValorZero == other.numeroComprasValorZero;
  331. }
  332. @Override
  333. public String toString() {
  334. StringBuilder sb = new StringBuilder();
  335. sb.append("Compras{");
  336. sb.append("Compras valor zero=").append(numeroComprasValorZero);
  337. sb.append(" Nº Clientes distintos=").append(arvoreClientes.size());
  338. sb.append('}');
  339. return sb.toString();
  340. }
  341. public Compras clone() {
  342. return new Compras(this);
  343. }
  344. }