Vamos lá, seguindo em frente Tem um problema aqui Se você começar a reparar O governo, ele muda o tempo todo essas regras, né? Por exemplo, você tem regime de competência Para determinados segmentos de empresa Que reconhecem descontos Sobre todo o período de prestação de serviço. Aí você tem alguns tipos de segmentos de empresas que reconhecem a partir do momento que ele foi aplicado, mas não para trás, só para frente. Nossa, mas toda hora muda essas regras ou, sei lá, você tem um cliente que tem um tipo de contabilização diferente e a tendência é que isso aqui aumente hoje você tem isso, amanhã você tem aquilo depois você tem mais uma, mais uma, mais uma e é assim que você chega no fim do dia de regra acumulada vou voltar para onde a gente estava por isso que você chega lá muitas vezes vou adicionar aqui pronto com essas regras todas acumuladas até está de novo, com essas regras todas acumuladas e existem padrões que vão resolver um problema lá do solid é o tal do OCP que se chama Vamos resolver um problema lá do Solid. É o tal do OCP. Que se chama Open Closed Principle. O que isso quer dizer? Fechado para modificação. E aberto para extensão. Vou traduzir isso para você. Vou traduzir isso para você. Vou traduzir melhor. Crie pontos de extensão evitando mexer o que já está funcionando e introduzindo para... evitando, na verdade, fragilizar o código. Essa é a tradução disso. Esse nome fechado para modificação é muito vago. Muito vago. O que a gente quer dizer aqui na prática? É que assim, o mesh está funcionando, o anchor está funcionando, esse algoritmo tem coisas funcionando. Não mexe aqui, estende Cria um ponto de extensão E na prática o que é um ponto de extensão? É entender o seguinte Olha Eu vou precisar de um contrato aqui E aí a gente vai ter que pensar num Num nome talvez E eu poderia chamar o que? De, olha, invoice Generate E eu poderia chamar o quê? De invoice generate ou generation strategy Olha surgindo um padrão aí Então agora a gente vai falar do padrão strategy O que o padrão strategy propõe? Vou abrir aqui. Se é aqui, vai rolar. Vou fechar aqui porque não rolou. vamos lá pronto deixa eu pegar aqui eu vou pegar o link direto strategy não é manual do padrão, vamos lá strategy é um padrão de projeto de comportamento que permite que você defina famílias de algoritmos certo? separadas por classes fazendo com que eles sejam intercambiáveis então olha aqui no diagrama você vai ter algum tipo de estratégia e aqui você tem o que? A estratégia rodoviária, por transporte público, a pé, e aí você tem o navigator, o navegador usando uma das estratégias, não sabe qual que ele vai usar. E aí, permite esse intercâmbio. Bom, o repository não deixa de ser isso eu poderia pegar esse o repository esse é o princípio do polimorfismo isso é aplicado em quase tudo no orientação a objetos o repository segue esse princípio o adapter por sua vez também segue, porque se eu tivesse uma outra conexão com outra biblioteca, seria intercambiável também. E aí, quando eu venho aqui para essa estratégia, o que eu vou ter aqui? Olha, invoice generation strategy. O que eu vou ter aqui? É uma interface, né? Eu vou ter aqui um método chamado generate. Estou entendendo que isso é intercambiável. Ele vai receber um contract e eu vou retornar desse contract o que? para a rede invoices isso eu passo um eu passo um contrato eu vou ter que passar mais coisas também É isso, né? Passo um... Eu passo um contrato. Eu vou ter que passar mais coisas também. Além do contrato, eu tenho que passar ex, ano e tipo. Acho que é isso. Vamos ver como é que fica. É que tem uma peculiaridade aí que a gente tem que entender. Que faz com que eu não precise passar isso aqui. Aí está a beleza da coisa. Segura aí. Vamos tocar sem isso que você vai entender por que dá para fazer sem. Quando eu venho aqui para o contract, pessoal, num regime contábil, de certa forma você não deveria você define isso de antemão então é factível dizer que o seu contrato ele deveria saber como ele deve ser gerado é relativamente factível dizer isso então a ele deveria saber como ele deve ser gerado. É relativamente factível dizer isso. Então, a gente deveria conseguir fazer. Então, é factível dizer que essa estratégia, a invoice generation strategy, ela deva acompanhar o contrato. É obrigatório fazer assim? não, pode fazer de outras formas também agora quais são os tipos de invoice generation strategy? vamos lá eu vou ter o cash generation seria o termo até mais interessante talvez seria Cache Basis. Strategy, que é o regime de caixa. Que isso? Aí é interessante, né? Explore the full class Cache Basis Strategy. Implement. Como é o nome? Regeneration Strategy. O que ele tem que é o nome? by generation strategy o que ele tem que me entregar? aqui como eu faço isso? ah, não, faltou o mês e ano sim porque o contrato não está implícito saber qual o mês e ano o tipo sim, o mês e ano faltou. Então, não precisava do tipo. Deixa eu só vir aqui e eu tenho que dizer... Pudimos de uma, o outro não dá mas here agora vamos lá vamos pegar um pedaço aqui, que é esse ó, bem simples, tá eu até vou fazer assim, ó, eu vou pegar tudo e depois eu corto quando eu precisar não preciso disso vou até aproveitar vou até vou fazer assim, eu vou pegar tudo e depois eu corto quando eu precisar não preciso disso vou até aproveitar, vou até fazer isso aqui vou fazer isso aqui de tipo para aqui eu tiro isso o type está implícito na classe. Fechou. Aqui. Get payments. E retorna. Fechou, fechou. Aqui. Tiro o cache. Tiro o type. Aqui. Aqui. Contracts. Contracts. aqui, import moment from moments, fechou, tá lindo? Fechou, fechou. O que eu posso fazer aqui então? Você quer que eu gere? Posso tirar isso aqui. E dizer o seguinte. Return this. GenerationStrategy. Que eu não sei qual é. Generate. No próprio contrato. qual é. Generate. No próprio contrato. OfYear. E assim a gente vai definir. Vamos para o teste para a gente ver como é que fica isso. Esse contrato aqui fica fácil, né? Porque esse aqui é Acron. Então aqui eu vou dizer... é Acron. Então aqui eu vou dizer eu posso rodar e vai funcionar. Aqui eu não teria mais esse type. Não preciso mais do type. Agora eu tenho instância para passar. Aqui vai quebrar. Porque provavelmente todos eles vão ficar, não todos, porque vai quebrar aqui também. Agora quando eu remontar isso aqui, eu vou precisar definir qual é. Então vamos supor que eu venha aqui e diga, isso aqui agora é Acron, quando eu vou dar o teste, aquele teste de caixa vai quebrar. Esse quebrou, os outros passaram. Então tem essa diferença aí. O que a gente pode fazer agora para resolver essa questão da seleção da estratégia? Isso é importante. Ah, mas com base no contrato, na tipagem do contrato, eu quero definir. Bom, nada impede você de definir na hora da geração também. Não tem problema. Você poderia, na hora da geração, decidir. Você poderia, sei lá, já fixar que o contrato tem aquela característica. Então, vamos explorar de outra forma para a gente pensar. Tirei do contrato, se tirei daqui, trouxe para cá. Voltaria a ter o type aqui. Bom, tem o type, vou ter que criar a estratégia. Para criar a estratégia, vou ter que ter algum tipo de fábrica. Então, é muito comum que a gente tenha... Eu vou abrindo threads aqui e a gente vai voltando. Então, a strategy permite o quê? Criar comportamento intercambiável. Existe um padrão que não é um abstract factory, um factory method, que a gente pode chamar de dynamic factory, que a gente chama de simple factory também, que basicamente é criar uma instância com base em um string. E isso pode ser útil tanto para você trazer do banco de dados, quanto também se você estiver passando pouco parâmetro no input, por exemplo, como é o nosso caso. Então, nesse caso, o que a gente vai fazer aqui? Poderia dizer, olha, eu vou ter aqui o... deixa eu ver qual o nome... InvoiceGenerationFactory for the full class envolve generationFactory, for default class generationFactory, poderia ter um método estático chamado create, aqui eu tenho typeString, if type igual a cache, return new cache-strategy if type igual a acro return new se chegou aqui embaixo e não deu nada, true new error invalid type. É fácil. Então, agora eu posso dizer, olha, if a generation strategy é igual a if a generation factory .create type. E aí eu não fico travado num só. Eu já vi casos que você quer gerar das duas formas, e analisar, enfim. São possibilidades. Voltamos para cá então. E aí, volta para cá. Não preciso mais desse tipo aqui. Volta para cá, não preciso mais desse tipo aqui, fechou? Volta para cá, não preciso mais desse tipo aqui, pago ele de volta para cá. Mas não tem regra, tá? Você pode passar no consultor, você pode usar uma fábrica, você pode fazer de várias maneiras. E está aí passando então colocamos aqui também uma strategy associada com uma factory e isso permite que a gente respeite mais o open close do OCP que é um princípio super importante para que eu não acumule código demais no mesmo lugar. Então a gente entendeu, olha, não é papel do contract ficar decidindo qual é a regra de criação de fatura. Ele vai se preocupar com outras coisas. De repente eu poderia me preocupar aqui em dizer o seguinte, olha, características de contract, né? Deve calcular o saldo do contrato o saldo porque é um contrato de 3 mil reais eu poderia dizer head payments tem um pagamento aí tem um pagamento em new date 0101, 10, 0000, de 2000, tá? Qual é o saldo do contrato? Contrato get balance subir 4000, falta pagar 4000. Está pendente em 4000. O que a gente faz aqui? Poder se ter um get balance? O que é o Get Balance? O Balance começa com a Mouth e aí para cada Payments of this Payments eu vou descontando. Balance menos ou igual, Payments, Mouth, Return Balance. balance menos igual payments amount return balance isso é responsabilidade de contract agora gerar faturas poderia ser, agora são várias são 10 tipos, são 3 tipos, são 4 tipos considere mover isso para algum lugar específico criando um ponto de extensão tornando o código menos bem menos frágil sem dúvida nenhuma agora, repara o seguinte imagina que aqui eu queira ter uma coisa que é assim olha para mim é interessante exportar isso aqui muitas vezes como um CSV. Porque eu acho interessante, de repente, pegar essa nota fiscal aqui, vou pegar essa aqui, vou pegar essa primeira do Acro. Porque eu poderia ter um JSON voltando para PI e um CSV. Por CSV. Isso faz com que meu output na zero. Agora sim, na zero. Ele seja isso aqui. CSV. É o teste. Quebrou, porque obviamente não veio. Volt né o objeto todo e aí como é que eu poderia dizer pra cá assim olha bem cá com licença eu queria voltar um csv não queria voltar esse dia e aí que muita gente começa a fazer umas coisas que é o seguinte ó a vamos passar um format para cá. Vamos fazer um string. E aí eu posso fazer um if, que if input type igual a JSON, volta isso aqui, if input type igual a csv vamos voltar a outra coisa, mas antes eu vou só fazer uma coisa que é o seguinte padrão aqui é disso padrão aqui gente vou botar aqui então ele vai quebrar lá na frente deixa você como opcional dá um input type ou input type JSON para cá como é que eu voltaria com o CSV? só vamos pensar o que é um CSV na essência? O CSV é um conjunto de linhas um headstring que vai fazer assim para cada fatura invoice of invoices para cada fatura então está lá invoice of invoices eu até posso pegar eu até posso pegar elementos da fault put dá, tá? a gente vai fazer uma jogada aqui porque eu já tenho lá date e amount então vai dar boa aí eu vou ter aqui uma linha que também é um array de string. Eu vou fazer o seguinte, olha. Para cada property of elements em elements, imagem aí, vai em ponto push elements a property. Então eu estou, de de certa forma adicionando deixa eu só ver o que ele reclamou aqui string index peraí line está aqui para cada linha eu peguei um elements daqui deixa eu fazer uma coisa Eu peguei um elements daqui. Vou fazer uma coisa aqui só para ver se ele se acalma. Espera aí. cada um desse aqui é um invoice então para cada aqui em uma invoice se eu pegar essa line, que é um array de strings, fizer um push, de invoice vai dar erro, se eu fizer isso aqui funciona. E se eu fizer invoice aqui? Ah, que não necessariamente a string entendi não necessariamente a string vamos fazer isso aqui então deixa eu ver o que está acontecendo aqui espera aí os founding output tá, esse output tem uma rede ah tá, porque ele tem date e tem a month tá, eu vou fazer um por um então tá, tá bom find.push date e esse amalfi aqui eu vou converter pronto, mais fácil peguei os dois para cá, beleza agora para cada linha eu vou fazer push. De join. E aqui no final, eu vou dar return de lines.join. Agora ele vai reclamar que não é exatamente o que você imaginava Vamos ter que fazer o seguinte Vamos tirar o output por enquanto Depois eu vou desfazer esse código Segura aqui por enquanto Segura aqui por enquanto A gente tem um formato CSV retornando aqui. Porcaria, mas tudo bem. E aqui, neste input, eu vou botar lá. Format CSV. Vamos ver quantas taxas a gente quebra agora. quantos testes a gente quebra agora quebrou o at aqui deixa eu só ver uma coisa peraí Branas eu acho que ali você colocou o type o if ah é isso acho que ali você colocou o type, o if, você colocou o type. Ah, tá, é isso. Tá faltando um pair programming aqui, é isso. Aí ele não deve ter voltado nada, tá certo. Agora só um quebrou. Perfeito, é isso aí. Então ele recebeu dois, tá, porque ele quebrou demais aqui agora, vamos ver uma coisa aqui. Deixa eu ver o que saiu agora nesse CSV, vamos lá. Isso aí, quanto mais bagunçado tá o código, pior. Ó, saiu certo gente. É porque não é na ets, né? É ele inteiro. Ele todo. Agora vai. Então agora a gente tem o formato eu tentei jogar o código, mas no fim não adianta, fica feio