View Javadoc
1   /*
2    * (c) Copyright 2006-2020 by rapiddweller GmbH & Volker Bergmann. All rights reserved.
3    *
4    * Redistribution and use in source and binary forms, with or without
5    * modification, is permitted under the terms of the
6    * GNU General Public License.
7    *
8    * For redistributing this software or a derivative work under a license other
9    * than the GPL-compatible Free Software License as defined by the Free
10   * Software Foundation or approved by OSI, you must first obtain a commercial
11   * license to this software product from rapiddweller GmbH & Volker Bergmann.
12   *
13   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
14   * WITHOUT A WARRANTY OF ANY KIND. ALL EXPRESS OR IMPLIED CONDITIONS,
15   * REPRESENTATIONS AND WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF
16   * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE
17   * HEREBY EXCLUDED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
18   * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
19   * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
20   * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
21   * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
22   * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
23   * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
24   * POSSIBILITY OF SUCH DAMAGE.
25   */
26  
27  package com.rapiddweller.domain.br;
28  
29  import com.rapiddweller.benerator.NonNullGenerator;
30  import com.rapiddweller.benerator.sample.WeightedCSVSampleGenerator;
31  import com.rapiddweller.benerator.wrapper.ProductWrapper;
32  import com.rapiddweller.common.Encodings;
33  
34  import java.util.ArrayList;
35  import java.util.Random;
36  
37  /**
38   * Generates Brazilian CNPJ numbers.
39   * CNPJ stands for <i>Cadastro Nacional da Pessoa Jurídica</i>
40   * and is a tax payer number assigned to a
41   * legal person (Pessoa Jurídica).
42   *
43   * @author Eric Chaves
44   * @see "http://en.wikipedia.org/wiki/Cadastro_de_Pessoas_F%C3%ADsicas"
45   */
46  public class CNPJGenerator extends WeightedCSVSampleGenerator<String>
47      implements NonNullGenerator<String> {
48  
49    private static final String LOCAL =
50        "/com/rapiddweller/domain/br/cnpj_sufix.csv";
51  
52    /**
53     * flag indicating should return CPF in numeric or formatted form. Defaults to true
54     */
55    private final boolean formatted;
56  
57    private final Random random;
58  
59    /**
60     * Instantiates a new Cnpj generator.
61     */
62    public CNPJGenerator() {
63      this(false);
64    }
65  
66    /**
67     * Instantiates a new Cnpj generator.
68     *
69     * @param formatted the formatted
70     */
71    public CNPJGenerator(boolean formatted) {
72      super(LOCAL, Encodings.UTF_8);
73      this.random = new Random();
74      this.formatted = formatted;
75    }
76  
77    // Generator interface implementation ------------------------------------------------------------------------------
78  
79    private static void addDigits(ArrayList<Integer> digits) {
80      int sum = 0;
81      sum = (5 * digits.get(0)) + (4 * digits.get(1)) + (3 * digits.get(2)) +
82          (2 * digits.get(3))
83          + (9 * digits.get(4)) + (8 * digits.get(5)) +
84          (7 * digits.get(6)) + (6 * digits.get(7))
85          + (5 * digits.get(8)) + (4 * digits.get(9)) +
86          (3 * digits.get(10)) + (2 * digits.get(11));
87      digits.add((sum % 11 < 2) ? 0 : 11 - (sum % 11));
88  
89      sum = (6 * digits.get(0)) + (5 * digits.get(1)) + (4 * digits.get(2)) +
90          (3 * digits.get(3))
91          + (2 * digits.get(4)) + (9 * digits.get(5)) +
92          (8 * digits.get(6)) + (7 * digits.get(7))
93          + (6 * digits.get(8)) + (5 * digits.get(9)) +
94          (4 * digits.get(10)) + (3 * digits.get(11))
95          + (2 * digits.get(12));
96      digits.add((sum % 11 < 2) ? 0 : 11 - (sum % 11));
97    }
98  
99    @Override
100   public String generate() {
101     return generate(getResultWrapper()).unwrap();
102   }
103 
104   // private helpers -------------------------------------------------------------------------------------------------
105 
106   @Override
107   public ProductWrapper<String> generate(ProductWrapper<String> wrapper) {
108     String suffix = super.generate(wrapper).unwrap();
109     if (suffix == null) {
110       suffix = "0000";
111     }
112     return wrapper.wrap(generateCNPJ(suffix));
113   }
114 
115   private String generateCNPJ(String sufix) {
116 
117     StringBuilder buf = new StringBuilder();
118     ArrayList<Integer> digits = new ArrayList<>();
119     for (int i = 0; i < 8; i++) {
120       digits.add(random.nextInt(9));
121     }
122     for (int i = 0; i < 4; i++) {
123       digits.add(Integer.parseInt(sufix.substring(i, i + 1)));
124     }
125     addDigits(digits);
126 
127     for (Integer digit : digits) {
128       buf.append(digit);
129     }
130     if (this.formatted) {
131       buf.insert(2, '.');
132       buf.insert(6, '.');
133       buf.insert(10, '/');
134       buf.insert(15, '-');
135     }
136     return buf.toString();
137   }
138 
139 }