Manual Reference Source Test

src/helpers/consent/ApproverGroup.js

import { deprecate } from 'core-decorators'; // eslint-disable-line
import ApproverAssignment from './ApproverAssignment';
import ApproverGroupAssignment from './ApproverGroupAssignment';
import ApproverGroupModel from '../../models/consent/ApproverGroup';
import Helper from '../Helper';
import { aggregate } from '../../utilities/ClassUtility';
import { serviceFactory } from '../../utilities/factories/ServiceFactory';

/**
 * Helper class representing an approver group.
 *
 * @extends {ApproverGroupModel}
 * @extends {Helper}
 *
 * @example
 * // To get a list of ApproverGroups use clinical6.get
 * import { clinical6, ApproverGroup } from 'clinical6';
 * clinical6.get(ApproverGroup).then(a => console.log(a));
 *
 * // To get a single approverGroup, you can also use clinical6
 * clinical6.get({ id: 5, type: 'consent__approver_groups'});
 *
 * // To save or insert, you can either use the .save() capability or clinical6
 * myApproverGroup.save(); // insert if no id, save if id
 * clinical6.insert(new ApproverGroup({...}));
 * clinical6.update(ApproverGroup);
 *
 * // To delete you can use the .delete() capability or clinical6
 * myApproverGroup.delete();
 * clinical6.delete(myApproverGroup);
 */
class ApproverGroup extends aggregate(ApproverGroupModel, Helper) {
  /**
   * Constructor for helper class representing an ApproverGroup
   *
   * @param {Object} json - json api response from server
   */
  constructor(json = {}) {
    super(json);

    // this._relationships = {};
    // this._relationships.approvers = [];
    // this._relationships.approver_assignments = [];
    // this._relationships.form_versions = [];
    this.deserializeRelationshipStubs(json);
    this.syncRelationships(json);
  }

  /** @type {String}  - The type */
  static get type() {
    return 'consent__approver_groups';
  }

  /** @type {ConsentFormVersion[]} */
  get formVersions() {
    return this._relationships.form_versions;
  }

  /** @type {ConsentFormVersion[]} */
  set formVersions(formVersions) {
    this._relationships.form_versions = formVersions;
  }

  /** @type {Object[]} */
  get approverAssignments() {
    return this._relationships.approver_assignments;
  }

  /** @type {Object[]} */
  set approverAssignments(assignments) {
    this._relationships.approver_assignments = assignments;
  }

  /** @type {ConsentApprover[]} */
  get approvers() {
    return this._relationships.approvers;
  }

  /** @type {ConsentApprover[]} */
  set approvers(approvers) {
    this._relationships.approvers = approvers;
  }

  /**
   * This will create a ApproverAssignment and save it to the server based on this current approver and the approver parameter
   *
   * @param  {ConsentApprover} approver   - The approver to be added to this approver
   * @return {Promise<ApproverAssignment} - Returns the approver assignment
   *
   * @example
   * import { clinical6, ConsentApprover, ApproverGroup } from 'clinical6';
   * const approverAssignments = await clinical6.get(ApproverGroup);
   * const approver = new ConsentApprover({...}); // some new approver
   * const assignment = await approverAssignments[0].addApprover(approver);
   */
  async addApprover(approver) {
    let assignment = new ApproverAssignment();
    assignment.approverGroup = this;
    assignment.approver = approver;
    this.approvers.push(approver);
    assignment = await assignment.save();
    this.approverAssignments.push(assignment);
    return assignment;
  }

  /**
   * This will create an ApproverGroupAssignment and save it to the server based on this current ApproverGroup and the Consent Form Version parameter
   *
   * @param {User} formVersion                   - The consent form version to be added to this Approver Group
   * @return {Promise<ApproverGroupAssignment}   - Returns the Approver Group Assignment
   *
   * @example
   * import { clinical6, ConsentFormVersion, ApproverGroup } from 'clinical6';
   * const approverGroups = await clinical6.get(ApproverGroup);
   * const consentFormVersion = new ConsentFormVersion({...}); // some new ConsentFormVersion
   * const assignment = await approverGroups[0].addFormVersion(consentFormVersion);
   */
  async addFormVersion(formVersion) {
    let assignment = new ApproverGroupAssignment();
    assignment.approverGroup = this;
    assignment.formVersion = formVersion;
    this.formVersions.push(formVersion);
    assignment = await assignment.save();
    this.approverAssignments.push(assignment);
    return assignment;
  }

  /**
   * Gets the approver group assignment associated to this approver group.
   *
   * @param  {Object} [params]            - Parameters used to get information from server
   * @param  {Number} [params.id]         - Id to get data from the server
   * @param  {String} [params.type]       - Type to be used for storage
   * @param  {Object} [params.filters]    - Filters to be used for get
   * @param  {String} [options]           - Modify the nature of the call and response
   * @param  {String} [options.url]       - Override the url for this call
   * @param  {String} [options.cacheMode] - Override the caching method for this call
   * @return {Promise}                    - Promise with data (array or object)
   *
   * @example
   * import { ApproverGroup, clinical6 } from 'clinical6';
   * const approverGroup = new ApproverGroup({ id: 23 });
   * approverGroup.getApproverAssignments({ id: 5 });
   *
   * // Combined with clinical6.get
   * clinical6.get(ApproverGroup).then(approverGroups => { approverGroups[0].getAssignments() });
   */
  async getApproverAssignments(params = {}, options = {}) {
    const service = serviceFactory.get(this.type);
    const assignment = { type: ApproverAssignment.type };
    if (params.id) {
      assignment.id = params.id;
    } else if (params.filters) {
      assignment.filters = params.filters;
    }
    const response = await service.getChildren(this, assignment, options);
    if (Array.isArray(response)) {
      this.approverAssignments = response;
      this.approvers = this.approverAssignments.map(a => a.approver);
    } else if (params.id) {
      // if the developer asks for one assignment given one id, return as just an object
      this.approverAssignments = response;
      this.approvers = response.approver;
    } else {
      // otherwise, there is just one response, make it an array
      this.approverAssignments = [response];
      this.approvers = [response.approver];
    }
    return this.approverAssignments;
  }

  /**
   * Gets the list of approvers after calling this.getApproverAssignments()
   * @return {Promise<ConsentApprover[]>} - Promise returning an array of approvers
   *
   * @example
   * import { clinical6, ApproverGroup } from 'clinical6';
   * const approverGroups = await clinical6.get(ApproverGroup);
   * const approvers = await approverGroups[0].getApprovers();
   * console.log(approvers);
   */
  async getApprovers() {
    return (await this.getApproverAssignments()).map(a => a.approver);
  }

  /**
   * Removes an assignment from a ApproverGroup.
   *
   * @param {ApproverAssignment|ConsentApprover} obj  - Object that is to be removed from current ApproverGroup.
   * @return {Promise}                                - Promise likely with an empty string or error
   *
   * @example
   * import { clinical6, ConsentApprover, ApproverGroup } from 'clinical6';
   * const approverGroups = await clinical6.get(ApproverGroup);
   * const approver = new ConsentApprover({...}); // some new approver
   * const assignment = await approverGroups[0].removeApprover(approver);
   */
  async removeApprover(obj) {
    let assignment;
    if (obj.type === 'consent__approvers') {
      assignment = (await this.getApproverAssignments()).find(a => (a.approver.id === obj.id));
    } else if (obj.type === 'consent__approver_assignments') {
      assignment = obj;
    } else {
      throw new Error('ApproverGroup.removeApprover cannot delete: obj is not an ApproverAssignment or a ConsentApprover');
    }
    return assignment.delete();
  }

  /**
   * Removes an assignment from an ApproverGroup.
   *
   * @param {ApproverGroupAssignment|ConsentFormVersion} obj  - Object that is to be removed from current ApproverGroup.
   * @return {Promise}                                        - Promise likely with an empty string or error
   *
   * @example
   * import { clinical6, ConsentFormVersion, ApproverGroup } from 'clinical6';
   * const approverGroups = await clinical6.get(ApproverGroup);
   * const formVersion = new ConsentFormVersion({...}); // some new formVersion
   * const assignment = await approverGroups[0].removeFormVersion(formVersion);
   */
  async removeFormVersion(obj) {
    let assignment;
    // Not able to retrieve ApproverGroupAssignments by ApproverGroup yet so only deleting when receiving an individual ApproverGroupAssignment
    if (obj.type === 'consent__approver_group_assignments') {
      assignment = obj;
    } else {
      throw new Error('ApproverGroup.removeFormVersion cannot delete: obj is not an ApproverGroupAssignment or ConsentFormVersion');
    }
    return assignment.delete();
  }

  /**
   * Saves an approverGroup (insert if id doesn't exist, update if it does)
   * @return {Promise<ApproverGroup>} - Returns a promise via ajax call.
   *
   * @example
   * import { ApproverGroup, clinical6 } from 'clinical6';
   *
   * // Inserts new approver group (no existing id)
   * const approverGroup = new ApproverGroup({
   *   "type": "consent__approver_groups",
   *   "attributes": {
   *       "name": "an approver group name"
   *   }
   * });
   * approverGroup.save();
   *
   * // Updates existing approverGroup(has existing id)
   * clinical6.get(ApproverGroup).then(capproverGroups => approverGroups[0].save());
   */
  async save() {
    const service = serviceFactory.get(this.type);
    return (this.id) ? service.update(this) : service.insert(this);
  }
}

export default ApproverGroup;