Account.js 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  1. import EncryptionHandler from "../EncryptionHandler.js";
  2. import Notifier from "../Notifier.js";
  3. import Format from "../Format.js";
  4. import Transaction from "./Transaction.js";
  5. export default class Account{
  6. constructor(id, iv, data){
  7. this._id = id;
  8. this._iv = iv;
  9. this._name = data.name;
  10. this._balance = data.balance;
  11. this._income = data.income;
  12. this._bills = data.bills;
  13. this._allowances = data.allowances;
  14. this._transactions = [];
  15. this._populated = false;
  16. }
  17. get balance(){
  18. return this.toDollars(this._balance);
  19. }
  20. incomeTotal(){
  21. let income = 0;
  22. for(let i = 0; i < this._income.length; i++){
  23. income += this._income[i].amount;
  24. }
  25. return this.toDollars(income);
  26. }
  27. billsTotal(){
  28. let bills = 0;
  29. for(let i = 0; i < this._bills.length; i++){
  30. bills += this._bills[i].amount;
  31. }
  32. return this.toDollars(bills);
  33. }
  34. static async create(name, balance){
  35. const data = {
  36. name: name,
  37. balance: Account.toCents(balance),
  38. income: [],
  39. bills: [],
  40. allowances: []
  41. };
  42. const iv = encryptionHandler.generateIv();
  43. const encryptedData = await encryptionHandler.encrypt(data, iv);
  44. let response;
  45. try{
  46. response = await fetch("/api/account", {
  47. method: "POST",
  48. headers: {"Content-Type": "application/json"},
  49. body: JSON.stringify({data: encryptedData, iv})
  50. });
  51. }catch(e){
  52. new Notifier("error", "Something went wrong, try refreshing the page");
  53. }
  54. if(response.error) new Notifier("error", response.error.message);
  55. return new Account(response.id, iv, data);
  56. }
  57. async addIncome(name, amount){
  58. this._income.push({
  59. id: crypto.randomUUID(),
  60. name: name,
  61. amount: this.toCents(amount)
  62. });
  63. await this.save();
  64. }
  65. async addBill(name, amount){
  66. this._bills.push({
  67. id: crypto.randomUUID(),
  68. name: name,
  69. amount: this.toCents(amount)
  70. });
  71. await this.save();
  72. }
  73. async addAllowance(name, amount, isPercent){
  74. if(isPercent){
  75. amount = Number(amount);
  76. }else{
  77. amount = this.toCents(amount);
  78. }
  79. this._allowances.push({
  80. id: crypto.randomUUID(),
  81. name: name,
  82. amount: amount,
  83. isPercent: isPercent
  84. });
  85. await this.save();
  86. }
  87. toCents(num){
  88. if(typeof num === "string") num = Number(num);
  89. return Math.round(num * 100);
  90. }
  91. static toCents(num){
  92. if(typeof num === "string") num = Number(num);
  93. return Math.round(num * 100);
  94. }
  95. toDollars(num){
  96. return num / 100;
  97. }
  98. async populateTransactions(){
  99. if(this._populated) return;
  100. let from = new Date();
  101. from.setDate(1);
  102. const to = new Date();
  103. let response;
  104. try{
  105. response = await fetch("/api/transaction/search", {
  106. method: "POST",
  107. headers: {"Content-Type": "application/json"},
  108. body: JSON.stringify({
  109. account: this._id,
  110. from: Format.transactionDate(from),
  111. to: Format.transactionDate(to)
  112. })
  113. });
  114. }catch(e){
  115. new Notifier("error", "Something went wrong, try refreshing the page");
  116. }
  117. if(response.error){
  118. new Notifier("error", response.error.message);
  119. }else{
  120. for(let i = 0; i < response.length; i++){
  121. this._transactions = Transaction.decrypt(response[i]);
  122. }
  123. this._populated = true;
  124. }
  125. }
  126. async save(){
  127. const data = {
  128. name: this._name,
  129. balance: this._balance,
  130. income: this._income,
  131. bills: this._bills,
  132. allowances: this._allowances
  133. };
  134. const encryptedData = await encryptionHandler.encrypt(data, this._iv);
  135. let response;
  136. try{
  137. response = await fetch("/api/account", {
  138. method: "PUT",
  139. headers: {"Content-Type": "application/json"},
  140. body: JSON.stringify({
  141. id: this._id,
  142. data: encryptedData
  143. })
  144. });
  145. }catch(e){
  146. new Notifier("error", "Something went wrong, try refreshing the page");
  147. }
  148. if(response.error) new Notifier("error", response.error.message);
  149. }
  150. }