Account.js 4.6 KB

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