datacite/bracco

View on GitHub
app/models/provider.js

Summary

Maintainability
F
4 days
Test Coverage
import Model, { attr, belongsTo, hasMany } from '@ember-data/model';
import { computed } from '@ember/object';
import { reads } from '@ember/object/computed';
import { isPresent, isBlank } from '@ember/utils';
import { w } from '@ember/string';
// import ENV from 'bracco/config/environment';
import { validator, buildValidations } from 'ember-cp-validations';
import { fragment } from 'ember-data-model-fragments/attributes';
import addressFormatter from '@fragaria/address-formatter';
import ENV from 'bracco/config/environment';
import { inject as service } from '@ember/service';
import validatePwdInputs from 'bracco/utils/validate-pwd-inputs';

export const organizationTypeList = [
  'researchInstitution',
  'academicInstitution',
  'governmentAgency',
  'internationalOrganization',
  'nationalInstitution',
  'professionalSociety',
  'publisher',
  'serviceProvider',
  'other'
];
export const memberTypeList = [
  'consortium',
  'consortium_organization',
  'contractual_member',
  'direct_member',
  'member_only',
  'registration_agency'
];
export const focusAreaList = [
  'naturalSciences',
  'engineeringAndTechnology',
  'medicalAndHealthSciences',
  'agriculturalSciences',
  'socialSciences',
  'humanities',
  'general'
];
export const nonProfitStatusList = ['non-profit', 'for-profit'];

const Validations = buildValidations({
  symbol: [
    validator('presence', true),
    validator('unique-provider-id', {
      presence: true,
      disabled: computed('model', function () {
        return !this.model.get('isNew');
      })
    }),
    validator('format', {
      regex: /^[A-Z]+$/,
      message: 'The Member ID can contain only upper case letters'
    }),
    validator('length', {
      min: 2,
      max: 8
    })
  ],
  confirmSymbol: [
    validator('presence', {
      presence: true,
      disabled: computed('model', function () {
        return this.model.get('isNew');
      })
    }),
    validator('confirmation', {
      on: 'symbol',
      message: 'Member ID does not match',
      disabled: computed('model', function () {
        return this.model.get('isNew');
      })
    })
  ],
  globusUuid: [
    validator('uuid-format', {
      version: 4,
      allowBlank: true,
      message: 'Must be a valid UUID (version 4).'
    })
  ],
  twitterHandle: [
    validator('format', {
      regex: /^@[a-zA-Z0-9_]{0,15}$/,
      allowBlank: true,
      message: 'Must start with @ followed by up to 15 alphanumeric characters.'
    })
  ],
  name: validator('presence', true),
  displayName: validator('presence', true),
  systemEmail: [validator('presence', true), validator('email-format', true)],
  groupEmail: [
    validator('email-format', {
      allowBlank: true
    })
  ],
  passwordInput: [
    validator('presence', {
      presence: true,
      disabled: computed('model', 'model.router.currentRouteName', function () {
        return !validatePwdInputs(this.model.router.currentRouteName);
      })
    }),
    validator('length', {
      min: 8,
      disabled: computed('model', 'model.router.currentRouteName', function () {
        return !validatePwdInputs(this.model.router.currentRouteName);
      })
    })
  ],
  confirmPasswordInput: [
    validator('presence', {
      presence: true,
      disabled: computed('model', 'model.router.currentRouteName', function () {
        return !validatePwdInputs(this.model.router.currentRouteName);
      })
    }),
    validator('confirmation', {
      on: 'passwordInput',
      message: 'Password does not match',
      disabled: computed('model', 'model.router.currentRouteName', function () {
        return !validatePwdInputs(this.model.router.currentRouteName);
      })
    })
  ],
  website: [
    validator('url-format', {
      allowBlank: true,
      require_tld: false,
      message: 'Please enter a valid website URL.'
    })
  ],
  rorId: [
    validator('url-format', {
      allowBlank: true,
      message: 'Please enter a valid ROR ID expressed as URL.'
    })
  ],
  salesforceId: [
    validator('format', {
      regex: /[a-zA-Z0-9]{18}/,
      allowBlank: true,
      message: 'Please enter a valid 18 digit Salesforce ID.'
    })
  ],
  contacts: [
    validator('presence', {
      presence: true,
      disabled: computed('model', function () {
        return (
          this.model.get('disableValidations') ||
          this.model.get('isNew') ||
          this.model.get('mode') === 'change' ||
          this.model.get('memberType') === 'developer' ||
          !this.model.get('memberType') || // memberType is null for admin account
          !this.model.get('hasPassword') // Allows users with no contacts to set their password.
        );
      })
    })
  ],
  votingContact: [
    validator('presence', {
      presence: true,
      message: 'A voting representative is required.',
      disabled: computed('model', function () {
        return (
          this.model.get('contacts').length === 0 ||
          this.model.get('isNew') ||
          this.model.get('mode') === 'change' ||
          this.model.get('memberType') === 'consortium_organization' ||
          this.model.get('memberType') === 'developer' ||
          !this.model.get('memberType') // memberType is null for admin account
        );
      })
    })
  ],
  serviceContact: [
    validator('presence', {
      presence: true,
      message: 'A service contact is required.',
      disabled: computed('model', function () {
        return (
          this.model.get('contacts').length === 0 ||
          this.model.get('isNew') ||
          this.model.get('mode') === 'change' ||
          this.model.get('memberType') === 'consortium_organization' ||
          this.model.get('memberType') === 'developer' ||
          !this.model.get('memberType') // memberType is null for admin account
        );
      })
    })
  ],
  billingContact: [
    validator('presence', {
      presence: true,
      message: 'A billing contact is required.',
      disabled: computed('model', function () {
        return (
          this.model.get('contacts').length === 0 ||
          this.model.get('isNew') ||
          this.model.get('mode') === 'change' ||
          this.model.get('memberType') === 'consortium_organization' ||
          this.model.get('memberType') === 'developer' ||
          !this.model.get('memberType') // memberType is null for admin account
        );
      })
    })
  ],
  'billingInformation.state': [validator('billing-state')],
  doiEstimate: [
    validator('presence', {
      presence: true,
      ignoreBlank: true,
      message: 'A doi estimate is required.',

      disabled: computed('model', function () {
        return (
          this.model.get('memberType') !== 'consortium_organization' ||
          !this.model.get('memberType') || // memberType is null for admin account
          !ENV.featureFlags['enable-doi-estimate']
        );
      })
    }),
    validator('number', {
      allowString: true,
      integer: true,
      positive: true,

      disabled: computed('model', function () {
        return (
          this.model.get('memberType') !== 'consortium_organization' ||
          !this.model.get('memberType') || // memberType is null for admin account
          !ENV.featureFlags['enable-doi-estimate']
        );
      })
    })
  ]
});

export default Model.extend(Validations, {
  router: service(),

  consortium: belongsTo('provider', {
    inverse: 'consortiumOrganizations',
    async: true
  }),
  consortiumOrganizations: hasMany('provider', {
    inverse: 'consortium',
    async: true
  }),
  contacts: hasMany('contact', {
    inverse: 'provider',
    async: true
  }),

  meta: attr(),

  name: attr('string'),
  displayName: attr('string'),
  symbol: attr('string'),
  globusUuid: attr('string'),
  description: attr('string'),
  region: attr('string'),
  country: attr('country'),
  memberType: attr('string'),
  organizationType: attr('string'),
  focusArea: attr('string'),
  logoUrl: attr('string'),
  systemEmail: attr('string'),
  groupEmail: attr('string'),
  website: attr('string'),
  isActive: attr('boolean', { defaultValue: true }),
  passwordInput: attr('string'),
  nonProfitStatus: attr('string'),
  hasPassword: attr('boolean'),
  rorId: attr('string'),
  salesforceId: attr('string'),
  twitterHandle: attr('string'),
  logo: attr(),
  billingInformation: attr('billingInformation'),
  technicalContact: fragment('contact-fragment'),
  secondaryTechnicalContact: fragment('contact-fragment'),
  billingContact: fragment('contact-fragment'),
  secondaryBillingContact: fragment('contact-fragment'),
  secondaryServiceContact: fragment('contact-fragment'),
  serviceContact: fragment('contact-fragment'),
  votingContact: fragment('contact-fragment'),
  joined: attr('date'),
  created: attr('date'),
  updated: attr('date'),
  doiEstimate: attr('number'),

  uid: computed('id', function () {
    return this.id.toUpperCase();
  }),
  hasRequiredContacts: computed(
    'billingContact.email',
    'memberType',
    'serviceContact.email',
    'votingContact.email',
    function () {
      if (this.memberType === 'consortium_organization') {
        return isPresent(this.serviceContact.email);
      } else if (this.memberType !== 'developer') {
        return (
          isPresent(this.votingContact.email) &&
          isPresent(this.serviceContact.email) &&
          isPresent(this.billingContact.email)
        );
      }
    }
  ),
  filteredContacts: reads('contacts'),
  formattedBillingInformation: computed(
    'billingInformation',
    'billingInformation.{address,city,postCode,state.name,country,country.name,country.code}',
    function () {
      if (this.billingInformation) {
        return addressFormatter.format(
          {
            road: this.billingInformation.address,
            city: this.billingInformation.city,
            postcode: this.billingInformation.postCode
              ? this.billingInformation.postCode
              : null,
            state: this.billingInformation.state
              ? this.billingInformation.state.name
              : null,
            country: this.billingInformation.country
              ? this.billingInformation.country.name
              : null,
            countryCode: this.billingInformation.country
              ? this.billingInformation.country.code
              : null
          },
          {
            output: 'array'
          }
        );
      } else {
        return null;
      }
    }
  )
});