Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

membership.js 7.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215
  1. const Schmervice = require('@hapipal/schmervice')
  2. module.exports = class MembershipService extends Schmervice.Service {
  3. constructor(...args) {
  4. super(...args)
  5. }
  6. /**
  7. * Internal method to get list of grouping_ids for this user
  8. * @param {number} profileId
  9. * @returns {Array} List of all grouping_ids for user
  10. */
  11. async _getGroupIdsForProfileId(profileId, type) {
  12. const { Membership } = this.server.models()
  13. /** Grab every Membership associated with this id */
  14. let allMemberships
  15. console.log()
  16. if(type) {
  17. allMemberships = await Membership.query()
  18. .where({ profile_id: profileId })
  19. .where({ membership_type: type })
  20. .where({ is_active: true })
  21. } else {
  22. allMemberships = await Membership.query()
  23. .where({ profile_id: profileId })
  24. .where({ is_active: true })
  25. }
  26. /** Copy a list of the just the Groupings */
  27. const groupingIdsToGrab = allMemberships.map(
  28. membership => membership.grouping_id,
  29. )
  30. /** Uncomment to dedupe the list just in case */
  31. return [...new Set(groupingIdsToGrab)]
  32. }
  33. /**
  34. * Internal method to create a new grouping
  35. * @param {*} groupingToTry
  36. * @param {*} txn
  37. * @returns
  38. */
  39. async _createGrouping(groupingToTry, txn) {
  40. const { Grouping } = this.server.models()
  41. const groupingInfo = {
  42. grouping_name: groupingToTry.grouping_name,
  43. grouping_type: groupingToTry.grouping_type,
  44. }
  45. return await Grouping.query(txn).insert(groupingInfo)
  46. }
  47. async findOrCreateGrouping(groupingToTry) {
  48. let idToReturn = groupingToTry.grouping_id
  49. if (!idToReturn) {
  50. /** ?: For some reason this returns the key id */
  51. const grouping = await this._createGrouping(groupingToTry)
  52. idToReturn = grouping.id
  53. }
  54. return idToReturn
  55. }
  56. /**
  57. * Get a list of groupings for user
  58. * @param {number} profileId
  59. * @returns {Array}
  60. */
  61. async findGroupingsById(profileId, type) {
  62. const { Grouping } = this.server.models()
  63. const dedupedGroupings = await this._getGroupIdsForProfileId(profileId, type)
  64. /** Grab just the Groupings this id has a Membership for */
  65. return await Grouping.query()
  66. .throwIfNotFound()
  67. .whereIn('grouping_id', dedupedGroupings)
  68. }
  69. async _groupingIdsInCommon(profileId, targetId) {
  70. const dedupedUserGroupingIds = await this._getGroupIdsForProfileId(
  71. profileId,
  72. )
  73. const dedupedTargetGroupingIds = await this._getGroupIdsForProfileId(
  74. targetId,
  75. )
  76. /** Return true if both people have a group in common */
  77. return dedupedUserGroupingIds.filter(groupingId =>
  78. dedupedTargetGroupingIds.includes(groupingId),
  79. )
  80. }
  81. async _patchMembership(memberships, profileId, patch) {
  82. const { Membership } = this.server.models()
  83. /** Set membership as active only if the user initiates it */
  84. for (let membershipInfo of memberships) {
  85. await Membership.query()
  86. .where('membership_id', membershipInfo.membership_id)
  87. .where('user_id', profileId)
  88. .patch(patch)
  89. }
  90. }
  91. async attemptMatch(profileId, targetId) {
  92. const { Membership } = this.server.models()
  93. /** If both people have groups in common */
  94. const matchingGroupingIds = await this._groupingIdsInCommon(
  95. profileId,
  96. targetId,
  97. )
  98. if (matchingGroupingIds.length) {
  99. /** Grab all memberships associated with groupingIds */
  100. const memberships = await Membership.query().whereIn(
  101. 'grouping_id',
  102. matchingGroupingIds,
  103. )
  104. /** Set membership as active only if the user initiates it */
  105. await this._patchMembership(memberships, profileId, {
  106. is_active: true,
  107. })
  108. /** Make a new query to get updated information */
  109. return await Membership.query().whereIn(
  110. 'grouping_id',
  111. matchingGroupingIds,
  112. )
  113. }
  114. }
  115. /**
  116. * Check for grouping membership then add membership record and set to active
  117. * or create a new grouping and add membership record for user and membership record for target
  118. * @param {number} profileId
  119. * @param {number} targetId
  120. * @param {object} groupingToWrite
  121. * @param {string} role
  122. * @returns
  123. */
  124. async joinGrouping(profileId, targetId, groupingToWrite, role, txn) {
  125. const { Membership } = this.server.models()
  126. /** If both people have groups in common */
  127. const matchingGroupingIds = await this._groupingIdsInCommon(
  128. profileId,
  129. targetId,
  130. )
  131. if (matchingGroupingIds.length) {
  132. /** Grab all memberships associated with groupingIds */
  133. const memberships = await Membership.query().whereIn(
  134. 'grouping_id',
  135. matchingGroupingIds,
  136. )
  137. /** Set membership as active only if the user initiates it */
  138. await this._patchMembership(memberships, profileId, {
  139. is_active: true,
  140. })
  141. /** Make a new query to get updated information */
  142. return await Membership.query().whereIn(
  143. 'grouping_id',
  144. matchingGroupingIds,
  145. )
  146. } else {
  147. /**
  148. * If both have NO grouping in common create a membership
  149. * for both to new group but set membership as inactive for target
  150. * */
  151. /** Check if the grouping exists and if NOT creat it */
  152. const groupingId = await this.findOrCreateGrouping(groupingToWrite)
  153. const userMembership = await Membership.query(txn).insert({
  154. profile_id: profileId,
  155. grouping_id: groupingId,
  156. membership_type: role,
  157. can_edit: false,
  158. is_active: true,
  159. })
  160. const targetMembership = await Membership.query(txn).insert({
  161. profile_id: profileId,
  162. grouping_id: groupingId,
  163. membership_type: role,
  164. can_edit: false,
  165. is_active: false,
  166. })
  167. return [userMembership, targetMembership]
  168. }
  169. }
  170. /**
  171. * Remove membership record based on grouping_id
  172. * @param {number} profileId
  173. * @param {number} groupingId
  174. * @returns
  175. */
  176. async leaveGrouping(profileId, groupingId) {
  177. const { Membership } = this.server.models()
  178. const dedupedGroupings = await this._getGroupIdsForProfileId(profileId)
  179. /** Do NOTHING if NOT in Grouping */
  180. if (!dedupedGroupings.includes(groupingId)) return
  181. return await Membership.query()
  182. .delete()
  183. .where('grouping_id', groupingId)
  184. }
  185. }