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.

164 lines
3.7 KiB

  1. var bodyParser = require('body-parser')
  2. var express = require('express')
  3. const got = require('got')
  4. var MIXMAX_API_KEY
  5. var app = express()
  6. var input
  7. app.use(function (req, res, next) {
  8. res.header('Access-Control-Allow-Origin', '*')
  9. res.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept')
  10. next()
  11. })
  12. app.use(bodyParser.json({
  13. limit: '100mb',
  14. type: 'application/json'
  15. }))
  16. app.get('/help', function (req, res) {
  17. res.send('https://github.com/binhonglee/Breakups')
  18. })
  19. app.post('/total', function (req, res) {
  20. input = req.body
  21. var toReturn = { 'total': 0 }
  22. toReturn.total = total(input.users)
  23. res.json(toReturn)
  24. })
  25. app.post('/perPerson', function (req, res) {
  26. input = req.body
  27. var toReturn = { 'perPerson': 0 }
  28. toReturn.perPerson = (total(input.users)) / input.users.length
  29. res.json(toReturn)
  30. })
  31. app.post('/oweChart', function (req, res) {
  32. input = req.body
  33. input.users = oweChart(input.users)
  34. res.send(input)
  35. })
  36. app.post('/sortedOweChart', function (req, res) {
  37. input = req.body
  38. input.users = mergeSort(oweChart(input.users))
  39. res.send(input)
  40. })
  41. app.post('/paymentChain', function (req, res) {
  42. input = req.body
  43. res.json(paymentChain(mergeSort(oweChart(input.users))))
  44. })
  45. app.post('/emailPaymentChain', function (req, res) {
  46. input = req.body
  47. MIXMAX_API_KEY = input['mixmax-api']
  48. var sorted = mergeSort(oweChart(input.users))
  49. var chain = paymentChain(sorted)
  50. var emails = []
  51. for (var i = 0; i < chain.length; i++) {
  52. var message = messageCreation(sorted[i], sorted[i + 1], chain[i].amount)
  53. send(message)
  54. emails.push('Email sent to ' + sorted[i].email)
  55. }
  56. res.json(emails)
  57. })
  58. // app.listen(5000)
  59. app.listen(process.env.PORT)
  60. function total (input) {
  61. var total = 0
  62. for (var i = 0; i < input.length; i++) {
  63. total += input[i].amount
  64. }
  65. return total
  66. }
  67. function oweChart (users) {
  68. var perPerson = total(users) / users.length
  69. for (var i = 0; i < users.length; i++) {
  70. users[i].amount -= perPerson
  71. }
  72. return users
  73. }
  74. function mergeSort (users) {
  75. if (users.length < 2) {
  76. return users
  77. }
  78. var middle = Math.floor(users.length / 2)
  79. var left = users.slice(0, middle)
  80. var right = users.slice(middle)
  81. return merge(mergeSort(left), mergeSort(right))
  82. }
  83. function merge (left, right) {
  84. var result = []
  85. var il = 0
  86. var ir = 0
  87. while (il < left.length && ir < right.length) {
  88. if (left[il].amount < 0 && right[ir].amount < 0) {
  89. if (left[il].amount > right[ir].amount) {
  90. result.push(left[il++])
  91. } else {
  92. result.push(right[ir++])
  93. }
  94. } else {
  95. if (left[il].amount < right[ir].amount) {
  96. result.push(left[il++])
  97. } else {
  98. result.push(right[ir++])
  99. }
  100. }
  101. }
  102. return result.concat(left.slice(il)).concat(right.slice(ir))
  103. }
  104. function paymentChain (users) {
  105. var chain = []
  106. var stack = 0
  107. for (var i = 0; i < users.length - 1; i++) {
  108. var item = {'from': '', 'to': '', 'amount': 0}
  109. item['from'] = users[i].name
  110. item['to'] = users[i + 1].name
  111. var amount = users[i].amount * -1
  112. stack += amount
  113. item['amount'] = stack
  114. chain.push(item)
  115. }
  116. return chain
  117. }
  118. function messageCreation (user1, user2, amount) {
  119. var signature = '<br><br><p>Sincerely,<br><a href="https://github.com/binhonglee/Breakups">BreakupBills</a></p>'
  120. var message = {}
  121. message.to = user1.email
  122. message.subject = 'Pay ' + user2.name + ' $' + amount
  123. message.html = '<p>Please pay ' + user2.name + ' $' + amount + '</p>' + signature
  124. return message
  125. }
  126. function send (message) {
  127. got.post('https://api.mixmax.com/v1/send', {
  128. body: JSON.stringify({
  129. message
  130. }),
  131. headers: {
  132. 'Content-Type': 'application/json',
  133. 'X-API-Token': MIXMAX_API_KEY
  134. }
  135. })
  136. }