Este proyecto es una aplicación para trabajar con un base de datos Postgresql por el ramo de base de datos. https://cromer.cl/sernatur
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

315 lines
8.7KB

  1. /*
  2. * Copyright 2018-2019 Chris Cromer
  3. *
  4. * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
  5. *
  6. * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
  7. *
  8. * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
  9. *
  10. * 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
  11. *
  12. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  13. */
  14. namespace LibSernatur {
  15. /**
  16. * The misc name space
  17. */
  18. namespace Misc {
  19. /**
  20. * The errors that can be thrown by the Rut class
  21. */
  22. public errordomain InvalidRut {
  23. /**
  24. * The RUT is invalid
  25. */
  26. INVALID,
  27. /**
  28. * The RUT is too large, larger than 100.000.000
  29. */
  30. TOOLARGE,
  31. /**
  32. * The verifier is incorrect
  33. */
  34. INVALIDVERIFIER
  35. }
  36. /**
  37. * This class converts a float or double into a percentage string
  38. */
  39. public class Percentage : Object {
  40. /**
  41. * Format a float into a percentage string
  42. * @param value The value to convert
  43. * @return Returns a string of the percentage
  44. */
  45. public static string format_float (float value) {
  46. return (value * 100).to_string () + "%";
  47. }
  48. /**
  49. * Format a double into a percentage string
  50. * @param value The value to convert
  51. * @return Returns a string of the percentage
  52. */
  53. public static string format_double (double value) {
  54. // Remove the double precision by converting to float
  55. return ((float) (value * (double) 100)).to_string () + "%";
  56. }
  57. }
  58. /**
  59. * This class handles making money look pretty
  60. */
  61. public class Money : Object {
  62. /**
  63. * Format an int to look pretty
  64. * @param value The value to format
  65. * @return Returns a pretty string
  66. */
  67. public static string format_int (int value) {
  68. string money = "";
  69. string temp_money = value.to_string ().reverse ();
  70. int money_length = temp_money.length;
  71. for (int i = 0; i < money_length; i++) {
  72. money = money + temp_money.get_char(i).to_string ();
  73. if ((i + 1) % 3 == 0) {
  74. if (i != money_length - 1) {
  75. money = money + ".";
  76. }
  77. }
  78. }
  79. money = money.reverse ();
  80. return "$" + money;
  81. }
  82. /**
  83. * Format a uint to look pretty
  84. * @param value The value to format
  85. * @return Returns a pretty string
  86. */
  87. public static string format_uint (uint value) {
  88. string money = "";
  89. string temp_money = value.to_string ().reverse ();
  90. int money_length = temp_money.length;
  91. for (int i = 0; i < money_length; i++) {
  92. money = money + temp_money.get_char(i).to_string ();
  93. if ((i + 1) % 3 == 0) {
  94. if (i != money_length - 1) {
  95. money = money + ".";
  96. }
  97. }
  98. }
  99. money = money.reverse ();
  100. return "$" + money;
  101. }
  102. /**
  103. * Format a string to look pretty
  104. * @param value The value to format
  105. * @return Returns a pretty string
  106. */
  107. public static string format_string (string value) {
  108. string money = "";
  109. string temp_money = value.reverse ();
  110. int money_length = temp_money.length;
  111. for (int i = 0; i < money_length; i++) {
  112. money = money + temp_money.get_char(i).to_string ();
  113. if ((i + 1) % 3 == 0) {
  114. if (i != money_length - 1) {
  115. money = money + ".";
  116. }
  117. }
  118. }
  119. money = money.reverse ();
  120. return "$" + money;
  121. }
  122. }
  123. /**
  124. * This class handles parsing and validation of RUTs
  125. */
  126. public class Rut : Object {
  127. /**
  128. * The cleaned RUT
  129. */
  130. private string clean_rut;
  131. /**
  132. * The pretty RUT, e.g. with periods and dash
  133. */
  134. private string pretty_rut;
  135. /**
  136. * The verifier
  137. */
  138. private unichar verifier;
  139. /**
  140. * The type of identifier
  141. */
  142. public enum Type {
  143. /**
  144. * Person
  145. */
  146. RUN,
  147. /**
  148. * Company
  149. */
  150. RUT
  151. }
  152. /**
  153. * Initialize the Rut class
  154. * @param rut The RUT to parse
  155. * @throws InvalidRut Thrown if the RUT is invalid in any way
  156. */
  157. public Rut (string rut) throws InvalidRut {
  158. parse (rut);
  159. }
  160. /**
  161. * Parse the rut that was passed to the constructor
  162. * @param rut The RUT to parse
  163. * @throws InvalidRut Thrown if the RUT is invalid in any way
  164. */
  165. private void parse (string rut) throws InvalidRut {
  166. try {
  167. var regex = new Regex ("^[ ]*([0-9.]{0,11}[\\-]?[0-9kK])?[ ]*$");
  168. if (!regex.match (rut)) {
  169. throw new InvalidRut.INVALID (_ ("The RUT %s has an invalid character!"), rut);
  170. }
  171. }
  172. catch (Error e) {
  173. #if DEBUG
  174. error (e.message);
  175. #else
  176. warning (e.message);
  177. #endif
  178. }
  179. try {
  180. var regex = new Regex ("([.-])");
  181. string new_rut = rut.up ();
  182. new_rut = new_rut.strip ();
  183. rut = regex.replace (new_rut, new_rut.length, 0, "");
  184. if (int.parse (rut.substring (0, rut.length - 1)) > 100000000) {
  185. throw new InvalidRut.TOOLARGE (_ ("The RUT %s is too big!"), rut);
  186. }
  187. this.verifier = rut.get_char (rut.length - 1);
  188. this.clean_rut = rut.substring (0, rut.length - 1);
  189. if (generate_verfifier (this.clean_rut) != this.verifier) {
  190. throw new InvalidRut.INVALIDVERIFIER (_ ("The verifier %C is invalid!"), this.verifier);
  191. }
  192. pretty();
  193. }
  194. catch (Error e) {
  195. #if DEBUG
  196. error (e.message);
  197. #else
  198. warning (e.message);
  199. #endif
  200. }
  201. }
  202. /**
  203. * Add periods and dash to the RUT to make it look pretty
  204. */
  205. private void pretty () {
  206. string new_rut = "";
  207. string temp_rut = this.clean_rut.reverse ();
  208. int rut_length = this.clean_rut.length;
  209. for (int i = 0; i < rut_length; i++) {
  210. new_rut = new_rut + temp_rut.get_char(i).to_string ();
  211. if ((i + 1) % 3 == 0) {
  212. if (i != rut_length - 1) {
  213. new_rut = new_rut + ".";
  214. }
  215. }
  216. }
  217. new_rut = new_rut.reverse ();
  218. this.pretty_rut = new_rut + "-" + this.verifier.to_string ();
  219. }
  220. /**
  221. * Generate a verifier based off the RUT
  222. * @param rut The RUT used to generate the verifier
  223. * @return Returns the verifier
  224. */
  225. private unichar generate_verfifier (string rut) {
  226. /**
  227. * 1. Multiply each digit of the RUT by 2, 3, ..., 7, 2, 3, ... from the end of the RUT moving forward.
  228. * 2. Add the partial multiplications.
  229. * 3. Calculate the remainder of the division by 11.
  230. * 4. The verifier is 11 minus the previous result. If the result is 10, change it to K.
  231. */
  232. int multiplier = 2;
  233. int sum = 0;
  234. int remainder;
  235. int division;
  236. int rut_length = rut.length;
  237. // Steps 1 and 2
  238. for (int i = rut_length - 1; i >= 0; i--) {
  239. sum = sum + (int.parse (rut.substring(i, 1)) * multiplier);
  240. multiplier++;
  241. if (multiplier == 8) {
  242. multiplier = 2;
  243. }
  244. }
  245. // Step 3
  246. division = sum / 11;
  247. division = division * 11;
  248. remainder = sum - division;
  249. // Step 4
  250. if (remainder != 0) {
  251. remainder = 11 - remainder;
  252. }
  253. // Let's return their verifier
  254. if (remainder == 10) {
  255. // Their verifier is 10 so let's return K.
  256. return 'K';
  257. }
  258. else {
  259. // Add the '0' to convert from int to unichar
  260. return (unichar) remainder + '0';
  261. }
  262. }
  263. /**
  264. * Get the clean RUT
  265. * @return Returns the cleaned up RUT
  266. */
  267. public string get_clean_rut () {
  268. return this.clean_rut + this.verifier.to_string ();
  269. }
  270. /**
  271. * Get the RUT
  272. * @return Returns the RUT with periods and dash
  273. */
  274. public string get_rut () {
  275. return this.pretty_rut;
  276. }
  277. /**
  278. * Check the type of identifier
  279. * @return Returns the type of identifier, Type.RUT if it's a company or Type.RUN if it's a person
  280. */
  281. public Type type () {
  282. uint rut = int.parse (this.clean_rut);
  283. if (rut > 50000000 && rut < 100000000) {
  284. // Company
  285. return Type.RUT;
  286. }
  287. else {
  288. // Person
  289. return Type.RUN;
  290. }
  291. }
  292. }
  293. }
  294. }