Nie możesz wybrać więcej, niż 25 tematów Tematy muszą się zaczynać od litery lub cyfry, mogą zawierać myślniki ('-') i mogą mieć do 35 znaków.

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