timeline.service.ts 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. import { Injectable } from '@angular/core';
  2. import { Observable } from 'rxjs';
  3. import { HttpClient } from '@angular/common/http';
  4. import * as moment from 'moment';
  5. import { CurrencyPipe } from '@angular/common';
  6. export class Transaction {
  7. header: { value: string, icon: string }[] = [];
  8. itens: { name: string, value: string }[] = [];
  9. time: moment.Moment;
  10. };
  11. @Injectable({
  12. providedIn: 'root'
  13. })
  14. export class ApiEventsService {
  15. // Registro de todos os tratadores de eventos
  16. protected eventHandler = new Map<string, (trans, event) => void>([
  17. ['comprou-produto', (trans, event) => this.comprouProdutoHandler(trans, event)],
  18. ['comprou', (trans, event) => this.comprouHandler(trans, event)],
  19. ]);
  20. // public apiURL = 'https://storage.googleapis.com/dito-questions/events.json';
  21. public apiURL = 'https://dito-questions.storage.googleapis.com/events.json';
  22. public _events: any;
  23. protected currencyPipe = new CurrencyPipe('pt-BR');
  24. constructor(
  25. protected $http: HttpClient
  26. ) {
  27. this._events = [
  28. {
  29. "event": "comprou-produto", "timestamp": "2016-09-22T13:57:33.2311892-03:00", "custom_data": [{ "key": "product_price", "value": 150 }, { "key": "transaction_id", "value": "3029384" }, { "key": "product_name", "value": "Calça Rosa" }]
  30. },
  31. {
  32. "event": "comprou-produto", "timestamp": "2016-10-02T11:37:35.2300892-03:00", "custom_data": [{ "key": "transaction_id", "value": "3409340" }, { "key": "product_name", "value": "Tenis Preto" }, { "key": "product_price", "value": 120 }]
  33. },
  34. {
  35. "event": "comprou", "timestamp": "2016-10-02T11:37:31.2300892-03:00", "revenue": 120, "custom_data": [{ "key": "transaction_id", "value": "3409340" }, { "key": "store_name", "value": "BH Shopping" }]
  36. },
  37. {
  38. "event": "comprou-produto", "timestamp": "2016-09-22T13:57:32.2311892-03:00", "custom_data": [{ "key": "product_name", "value": "Camisa Azul" }, { "key": "transaction_id", "value": "3029384" }, { "key": "product_price", "value": 100 }]
  39. },
  40. {
  41. "event": "comprou", "timestamp": "2016-09-22T13:57:31.2311892-03:00", "revenue": 250, "custom_data": [{ "key": "store_name", "value": "Patio Savassi" }, { "key": "transaction_id", "value": "3029384" }]
  42. }
  43. ]
  44. }
  45. public transactions() {
  46. return new Observable<any>(ob => {
  47. // Realiza uma requisição para o endpoint determinado
  48. // this.$http.get(this.apiURL).subscribe(results => {
  49. // ob.next(this.parseEventResults(results))
  50. // })
  51. // Simula a requisição ajax
  52. setTimeout(() => {
  53. ob.next(this.parseEventResults(this._events))
  54. })
  55. })
  56. }
  57. // Retona o id da transação do evento
  58. protected findTransactionId(event): string {
  59. let id;
  60. event && event.custom_data.find(data => {
  61. if (data.key === 'transaction_id') {
  62. id = data.value;
  63. return true;
  64. }
  65. })
  66. return id;
  67. }
  68. // Converte a lista de eventos em um lista de transações
  69. protected parseEventResults(events): Transaction[] {
  70. let transactions = []
  71. , transactionsMap = new Map<string, Transaction>();
  72. // Percorre a lista de eventos e realiza os agrupamentos
  73. events.map(event => {
  74. // Busca o id da transação contido no evento
  75. let id = this.findTransactionId(event);
  76. if (!id) {
  77. // Não tratado por falta de definição
  78. return;
  79. }
  80. // Cria uma nova instancia para o id caso ainda não exista
  81. if (!transactionsMap.has(id)) {
  82. transactionsMap.set(id, new Transaction());
  83. }
  84. // Recupera a instancia da transação correspondente ao id
  85. let trans = transactionsMap.get(id);
  86. // Verifica o tipo de evento para tratamento
  87. this.eventHandler.get(event.event)(trans, event)
  88. })
  89. // Converte o map em lista
  90. transactionsMap.forEach(t => transactions.push(t))
  91. // Ordena as transações pela data
  92. transactions.sort((t1, t2) => {
  93. return (t2.time - t1.time);
  94. });
  95. return transactions;
  96. }
  97. // Realiza o tratamento do evento comprou
  98. // * Extra os dados do cabeçalho
  99. // * Seta o atributo header da transação
  100. protected comprouHandler(trans, event) {
  101. let place = "";
  102. // Converte o timestamp para um moment object
  103. trans.time = moment(event.timestamp);
  104. // Busca o nome do estabelecimento
  105. event.custom_data.find(item => {
  106. if (item.key === "store_name") {
  107. place = item.value;
  108. return true;
  109. }
  110. })
  111. // Cria um array contendo os elementos do header de cada evento
  112. // Cada elemento é mapeado para um item do array
  113. trans.header = [
  114. { icon: "icon-calendar", value: trans.time.format("DD/MM/YYYY") },
  115. { icon: "icon-clock", value: trans.time.format("HH:mm") },
  116. { icon: "icon-place", value: place },
  117. { icon: "icon-money", value: this.currencyPipe.transform(event.revenue, 'BRL', true, '1.2-2') },
  118. ];
  119. }
  120. // Realiza o tratamento do evento comprou-produto
  121. // * Extra os nomes e os preços dos itens comprados
  122. // * Adiciona o novo item na lista de itens da transação
  123. protected comprouProdutoHandler(trans, event) {
  124. let add = { name: "", value: "" }, control = 0;
  125. // Atribui os valores do nome do produto e o preço para o objeto da listagem
  126. event.custom_data.find(item => {
  127. if (item.key === "product_name") {
  128. add.name = item.value;
  129. control++;
  130. } else if (item.key === "product_price") {
  131. // Formata o valor com a moeda brasileira
  132. add.value = this.currencyPipe.transform(item.value, 'BRL', true, '1.2-2');
  133. control++;
  134. }
  135. // Se ja encontrou os dois dados evita de percorrer o array todo.
  136. if (control > 1) {
  137. return true;
  138. }
  139. })
  140. trans.itens.push(add)
  141. }
  142. }