Esempio n. 1
0
export default AbstractModel.extend(CanEditRequested, DateFormat, ResultValidation, {
  charges: DS.hasMany('proc-charge', {
    async: false
  }),
  imagingDate: DS.attr('date'),
  imagingType: DS.belongsTo('pricing', {
    async: false
  }),
  notes: DS.attr('string'),
  patient: DS.belongsTo('patient', {
    async: false
  }),
  radiologist: DS.attr('string'),
  requestedBy: DS.attr('string'),
  requestedDate: DS.attr('date'),
  result: DS.attr('string'),
  status: DS.attr('string'),
  visit: DS.belongsTo('visit', {
    async: false
  }),

  imagingDateAsTime: function() {
    return this.dateToTime(this.get('imagingDate'));
  }.property('imagingDate'),

  requestedDateAsTime: function() {
    return this.dateToTime(this.get('requestedDate'));
  }.property('requestedDate'),

  validations: {
    imagingTypeName: {
      presence: {
        'if'(object) {
          if (object.get('isNew')) {
            return true;
          }
        },
        message: 'Please select an imaging type'
      }
    },
    patientTypeAhead: PatientValidation.patientTypeAhead,
    patient: {
      presence: true
    }
  }
});
import AbstractModel from 'hospitalrun/models/abstract';
import DS from 'ember-data';

export default AbstractModel.extend({
  // Attributes
  name: DS.attr('string'),
  capabilities: DS.attr(),
  navRoute: DS.attr()
});
let InventoryPurchaseItem = AbstractModel.extend(LocationName, NumberFormat, {
  purchaseCost: DS.attr('number'),
  lotNumber: DS.attr('string'),
  dateReceived: DS.attr('date'),
  originalQuantity: DS.attr('number'),
  currentQuantity: DS.attr('number'),
  expirationDate: DS.attr('date'),
  expired: DS.attr('boolean'),
  location: DS.attr('string'),
  aisleLocation: DS.attr('string'),
  giftInKind: DS.attr('boolean'),
  inventoryItem: DS.attr('string'), // Currently just storing id instead of DS.belongsTo('inventory', { async: true }),
  vendor: DS.attr('string'),
  vendorItemNo: DS.attr('string'),
  distributionUnit: DS.attr('string'),
  invoiceNo: DS.attr('string'),
  quantityGroups: DS.attr({ defaultValue: defaultQuantityGroups }),

  costPerUnit: computed('purchaseCost', 'originalQuantity', function() {
    let purchaseCost = this.get('purchaseCost');
    let quantity = parseInt(this.get('originalQuantity'));
    if (Ember.isEmpty(purchaseCost) || Ember.isEmpty(quantity) || purchaseCost === 0 || quantity === 0) {
      return 0;
    }
    return this._numberFormat(purchaseCost / quantity, true);
  }),

  validations: {
    purchaseCost: {
      numericality: true
    },
    originalQuantity: {
      numericality: {
        greaterThanOrEqualTo: 0
      }
    },
    vendor: {
      presence: true
    }
  }
});
export default AbstractModel.extend({
  // Attributes
  allDay: DS.attr(),
  provider: DS.attr('string'),
  location: DS.attr('string'),
  appointmentType: DS.attr('string'),
  startDate: DS.attr('date'),
  endDate: DS.attr('date'),
  notes: DS.attr('string'),
  status: DS.attr('string', { defaultValue: 'Scheduled' }),

  // Associations
  patient: DS.belongsTo('patient', { async: false }),
  visits: DS.hasMany('visit'),

  // Formats
  longDateFormat: 'l h:mm A',
  shortDateFormat: 'l',
  timeFormat: 'h:mm A',

  _getDateSpan(startDate, endDate, format) {
    let formattedStart = startDate.format(format);
    let formattedEnd = endDate.format(format);
    return `${formattedStart} - ${formattedEnd}`;
  },

  appointmentDate: computed('startDate', function() {
    let startDate = this.get('startDate');
    return startDate;
  }),

  displayStatus: computed('status', function() {
    let status = this.get('status');
    if (isEmpty(status)) {
      status = 'Scheduled';
    }
    return status;
  }),

  formattedAppointmentDate: computed('startDate', 'endDate', function() {
    let allDay = this.get('allDay');
    let endDate = moment(this.get('endDate'));
    let dateFormat = '';
    let formattedDate = '';
    let startDate = moment(this.get('startDate'));

    if (startDate.isSame(endDate, 'day')) {
      formattedDate = startDate.format(this.get('shortDateFormat'));
      if (!allDay) {
        formattedDate += ' ';
        formattedDate += this._getDateSpan(startDate, endDate, this.get('timeFormat'));
      }
    } else {
      if (allDay) {
        dateFormat = this.get('shortDateFormat');
      } else {
        dateFormat = this.get('longDateFormat');
      }
      formattedDate = this._getDateSpan(startDate, endDate, dateFormat);
    }
    return formattedDate;
  }),

  validations: {
    appointmentDate: {
      presence: {
        if(object) {
          let appointmentType = object.get('appointmentType');
          return appointmentType !== 'Admission';
        }
      }
    },

    patientTypeAhead: PatientValidation.patientTypeAhead,

    patient: {
      presence: true
    },
    appointmentType: {
      presence: true
    },
    startDate: {
      presence: true
    },
    endDate: {
      acceptance: {
        accept: true,
        if(object) {
          if (!object.get('hasDirtyAttributes')) {
            return false;
          }
          let allDay = object.get('allDay');
          let startDate = object.get('startDate');
          let endDate = object.get('endDate');
          if (isEmpty(endDate) || isEmpty(startDate)) {
            // force validation to fail
            return true;
          } else {
            if (allDay) {
              if (endDate.getTime() < startDate.getTime()) {
                return true;
              }
            } else {
              if (endDate.getTime() <= startDate.getTime()) {
                return true;
              }
            }
          }
          // patient is properly selected; don't do any further validation
          return false;

        },
        message: 'Please select an end date later than the start date'
      }
    }
  }
});
Esempio n. 5
0
import AbstractModel from 'hospitalrun/models/abstract';

export default AbstractModel.extend({
    
    //part of ministy models information
    leadershipEvent: DS.belongsTo('leadership-event'),
    
    //Main information
    organization: DS.attr('string'),
    participantName: DS.attr('string'),
    gender: DS.attr('string'),
    
});
export default AbstractModel.extend(MedicationDetails, {
  medication: DS.belongsTo('inventory', {
    async: false
  }),
  pricingItem: DS.belongsTo('pricing', {
    async: false
  }),
  quantity: DS.attr('number'),
  dateCharged: DS.attr('date'),

  medicationCharge: function() {
    let medication = this.get('medication');
    let newMedicationCharge = this.get('newMedicationCharge');
    return (!Ember.isEmpty(medication) || !Ember.isEmpty(newMedicationCharge));
  }.property('medication', 'newMedicationCharge'),

  medicationName: function() {
    return this.get('medication.name');
  }.property('medication'),

  medicationPrice: function() {
    return this.get('medication.price');
  }.property('medication'),

  validations: {
    itemName: {
      presence: true,
      acceptance: {
        accept: true,
        if(object) {
          let medicationCharge = object.get('medicationCharge');
          if (!medicationCharge || !object.get('hasDirtyAttributes')) {
            return false;
          }
          let itemName = object.get('inventoryItem.name');
          let itemTypeAhead = object.get('itemName');
          if (Ember.isEmpty(itemName) || Ember.isEmpty(itemTypeAhead)) {
            // force validation to fail
            return true;
          } else {
            let typeAheadName = itemTypeAhead.substr(0, itemName.length);
            if (itemName !== typeAheadName) {
              return true;
            }
          }
          // Inventory item is properly selected; don't do any further validation
          return false;
        },
        message: 'Please select a valid medication'
      }

    },

    quantity: {
      numericality: {
        greaterThan: 0,
        messages: {
          greaterThan: 'must be greater than 0'
        }
      }
    }
  }
});
import AbstractModel from 'hospitalrun/models/abstract';
import DS from 'ember-data';
import NumberFormat from 'hospitalrun/mixins/number-format';

export default AbstractModel.extend(NumberFormat, {
  department: DS.attr('string'),
  expenseAccount: DS.attr('string'),
  name: DS.attr('string'),
  price: DS.attr('number'),
  pricingItem: DS.belongsTo('pricing', {
    async: false
  }),
  quantity: DS.attr('number'),
  total: DS.attr('number'),

  amountOwed: function() {
    let price = this.get('price');
    let quantity = this.get('quantity');
    let total = 0;
    if (this._validNumber(price) && this._validNumber(quantity)) {
      total = this._numberFormat((price * quantity), true);
    }
    return total;
  }.property('price', 'quantity')

});
let InventoryLocation = AbstractModel.extend(LocationName, {
  quantity: DS.attr('number'),
  location: DS.attr('string'),
  aisleLocation: DS.attr('string'),

  locationNameWithQuantity: function() {
    let quantity = this.get('quantity');
    let locationName = this.get('locationName');
    return `${locationName} (${quantity} available)`;
  }.property('locationName', 'quantity'),

  validations: {
    adjustmentQuantity: {
      numericality: {
        greaterThan: 0,
        messages: {
          greaterThan: 'must be greater than 0'
        }
      },
      acceptance: {
        /**
         * Validate that the adjustment quantity is a number and that if a deduction there are enough items to deduct
         */
        accept: true,
        if(object) {
          let adjustmentQuantity = object.get('adjustmentQuantity');
          let transactionType = object.get('transactionType');
          let locationQuantity = object.get('quantity');
          if (Ember.isEmpty(adjustmentQuantity) || isNaN(adjustmentQuantity)) {
            return true;
          }
          if (transactionType !== 'Adjustment (Add)' && adjustmentQuantity > locationQuantity) {
            return true;
          }
          return false;
        },
        message: 'Invalid quantity'
      }
    },

    dateCompleted: {
      presence: {
        message: 'Please provide a date'
      }
    },

    transferLocation: {
      acceptance: {
        accept: true,
        if(object) {
          let transferLocation = object.get('transferLocation');
          let transferItem = object.get('transferItem');
          // If we don't have a transfer item, then a transfer is not occurring.
          if (!Ember.isEmpty(transferItem) && Ember.isEmpty(transferLocation)) {
            return true;
          }
          return false;
        },
        message: 'Please select a location to transfer to'
      }
    }
  }
});
Esempio n. 9
0
import AbstractModel from "hospitalrun/models/abstract";

export default AbstractModel.extend({
    amount: DS.attr('number'),
    charityPatient: DS.attr('boolean'), //Is patient a charity case
    expenseAccount: DS.attr('string'),
    invoice: DS.belongsTo('invoice'),    
    datePaid: DS.attr('date'),
    type: DS.attr('string'),
    notes: DS.attr('string'),
    
     validations: {
        amount: {
            numericality: true
        },
        datePaid: {
            presence: true
        }
    }
});
export default AbstractModel.extend({
  // Attributes
  /*
   * if the note was written by one person but dictated or
   * given on behalf of another, otherwise, this and createdBy are the same.
   */
  attribution: DS.attr('string'),

  content: DS.attr('string'),
  createdBy: DS.attr('string'),
  date: DS.attr('date'),
  /* custom list of noteTypes of mixins/patient-note-types */
  noteType: DS.attr(),
  /* who is this note about? */
  patient: DS.belongsTo('patient', { async: false }),
  /* if this note is related to a visit, make sure it's noted. */
  visit: DS.belongsTo('visit', { async: false }),

  authoredBy: computed('attribution', 'createdBy', function() {
    if (!isEmpty(this.get('attribution'))) {
      let intl = this.get('intl');
      return `${this.get('createdBy')} ${intl.t('patients.notes.onBehalfOfCopy')} ${this.get('attribution')}`;
    } else {
      return this.get('createdBy');
    }
  }),

  validations: {
    patient: {
      presence: true
    },
    visit: {
      presence: true
    },
    content: {
      presence: true
    }
  }
});
Esempio n. 11
0
var InventoryLocation = AbstractModel.extend(LocationName, {
    quantity: DS.attr('number'),
    location: DS.attr('string'),
    aisleLocation: DS.attr('string'),

    locationNameWithQuantity: function() {
        var quantity = this.get('quantity'),
            locationName = this.get('locationName');
        return '%@ (%@ available)'.fmt(locationName, quantity);
    }.property('locationName'),
    
    validations: {
        adjustmentQuantity: {
            numericality: {
                greaterThan: 0
            },            
            acceptance: {
                /***
                 * Validate that the adjustment quantity is a number and that if a deduction there are enough items to deduct
                 */
                accept: true,
                if: function(object) {
                    var adjustmentQuantity = object.get('adjustmentQuantity'),
                        transactionType = object.get('transactionType'),
                        locationQuantity = object.get('quantity');
                    if (Ember.isEmpty(adjustmentQuantity)|| isNaN(adjustmentQuantity)) { 
                        return true;
                    }
                    if (transactionType !== 'Adjustment (Add)' && adjustmentQuantity > locationQuantity) {
                        return true;            
                    }
                    return false;
                },
                message: 'Invalid quantity'         
            }
        },        
        
        transferLocation: {
            acceptance: {
                /***
                * Validate that a procedure has been specified and that it
                * is a valid procedure.
                */
                accept: true,
                if: function(object) {
                    var transferLocation = object.get('transferLocation'),
                    transferItem = object.get('transferItem');
                    //If we don't have a transfer item, then a transfer is not occurring.
                    if (!Ember.isEmpty(transferItem) && Ember.isEmpty(transferLocation)) {
                        return true;
                    }
                    return false;
                },
                message: 'Please select a location to transfer to'         
            }
        }
    }
});
export default AbstractModel.extend({
  // Attributes
  additionalNotes: DS.attr('string'),
  caseComplexity: DS.attr('number'),
  customForms: DS.attr('custom-forms'),
  procedures: DS.attr('operative-procedures', { defaultValue: defaultProcedures }),
  operationDescription: DS.attr('string'),
  surgeon: DS.attr('string'),
  surgeryDate: DS.attr('date'),

  // Associations
  preOpDiagnoses: DS.hasMany('diagnosis'),
  diagnoses: DS.hasMany('diagnosis'), // Post op diagnosis
  operativePlan: DS.belongsTo('operative-plan', { async: true }),
  patient: DS.belongsTo('patient', { async: false }),

  validations: {
    caseComplexity: {
      numericality: {
        allowBlank: true,
        onlyInteger: true
      }
    },
    procedureDescription: {
      presence: {
        if(object) {
          return isEmpty(get(object, 'procedures'));
        }
      }
    }
  }
});
Esempio n. 13
0
export default AbstractModel.extend(DateFormat, ResultValidation, {
    charges: DS.hasMany('proc-charge'),
    imagingDate: DS.attr('date'),
    imagingType: DS.belongsTo('pricing'),
    notes: DS.attr('string'),
    patient: DS.belongsTo('patient'),
    requestedBy: DS.attr('string'),
    requestedDate: DS.attr('date'),
    result: DS.attr('string'),
    status: DS.attr('string'),
    visit: DS.belongsTo('visit'),
    
    imagingDateAsTime: function() {        
        return this.dateToTime(this.get('imagingDate'));
    }.property('imagingDate'),
    
    requestedDateAsTime: function() {
        return this.dateToTime(this.get('requestedDate'));
    }.property('requestedDate'),
    
    validations: {
        imagingTypeName: {
            presence: {
                'if': function(object) {
                    if (object.get('isNew')) {
                        return true;
                    }
                }
            }
        },        
        patientTypeAhead: PatientValidation.patientTypeAhead,
        patient: {
            presence: true
        },
    }
});
export default AbstractModel.extend(NumberFormat, {
  amountOwed: DS.attr('number'),
  category: DS.attr('string'),
  description: DS.attr('string'),
  details: DS.hasMany('line-item-detail', {
    async: false
  }), /* The individual objects that make up this line item. */
  discount: DS.attr('number'),
  name: DS.attr('string'),
  nationalInsurance: DS.attr('number'),
  privateInsurance: DS.attr('number'),

  amountOwedChanged: function() {
    Ember.run.debounce(this, function() {
      var discount = this._getValidNumber(this.get('discount')),
        nationalInsurance = this._getValidNumber(this.get('nationalInsurance')),
        privateInsurance = this._getValidNumber(this.get('privateInsurance')),
        amountOwed = this._getValidNumber(this.get('total'));
      amountOwed = amountOwed - discount - nationalInsurance - privateInsurance;
      if (amountOwed < 0) {
        amountOwed = 0;
      }
      if (!this.get('isDestroyed')) {
        this.set('amountOwed', this._numberFormat(amountOwed, true));
      }
    }, 500);
  }.observes('discount', 'nationalInsurance', 'privateInsurance', 'total'),

  detailTotals: Ember.computed.mapBy('details', 'amountOwed'),
  total: Ember.computed.sum('detailTotals'),

  validations: {
    category: {
      presence: true
    },
    discount: {
      numericality: {
        allowBlank: true
      }
    },
    nationalInsurance: {
      numericality: {
        allowBlank: true
      }
    },
    name: {
      presence: true
    },
    privateInsurance: {
      numericality: {
        allowBlank: true
      }
    },
    total: {
      numericality: {
        allowBlank: true
      }
    }
  }
});
import AbstractModel from 'hospitalrun/models/abstract';
import DS from 'ember-data';
import Ember from 'ember';
import NumberFormat from 'hospitalrun/mixins/number-format';

const { computed, get } = Ember;

export default AbstractModel.extend(NumberFormat, {
  // Attributes
  department: DS.attr('string'),
  expenseAccount: DS.attr('string'),
  name: DS.attr('string'),
  price: DS.attr('number'),
  quantity: DS.attr('number'),
  total: DS.attr('number'),

  // Associations
  pricingItem: DS.belongsTo('pricing', { async: false }),

  amountOwed: computed('price', 'quantity', function() {
    let price = get(this, 'price');
    let quantity = get(this, 'quantity');
    let total = 0;
    if (this._validNumber(price) && this._validNumber(quantity)) {
      total = this._numberFormat((price * quantity), true);
    }
    return total;
  })
});
Esempio n. 16
0
import { get, computed } from '@ember/object';
import AbstractModel from 'hospitalrun/models/abstract';
import DS from 'ember-data';

export default AbstractModel.extend({
  // Attributes
  amount: DS.attr('number'),
  /* Is patient a charity case */
  charityPatient: DS.attr('boolean'),
  datePaid: DS.attr('date'),
  expenseAccount: DS.attr('string'),
  notes: DS.attr('string'),
  paymentType: DS.attr('string'),

  // Associations
  invoice: DS.belongsTo('invoice', { async: false }),

  canRemovePayment: computed('paymentType', function() {
    return get(this, 'paymentType') === 'Deposit';
  }),

  validations: {
    amount: {
      numericality: true
    },
    datePaid: {
      presence: true
    }
  }
});
Esempio n. 17
0
export default AbstractModel.extend(CanEditRequested, DateFormat, ResultValidation, {
  // Attributes
  customForms: DS.attr('custom-forms'),
  labDate: DS.attr('date'),
  notes: DS.attr('string'),
  requestedBy: DS.attr('string'),
  requestedDate: DS.attr('date'),
  result: DS.attr('string'),
  status: DS.attr('string'),

  // Associations
  charges: DS.hasMany('proc-charge', { async: false }),
  labType: DS.belongsTo('pricing', { async: false }),
  patient: DS.belongsTo('patient', { async: false }),
  visit: DS.belongsTo('visit', { async: false }),

  labDateAsTime: computed('labDate', function() {
    return this.dateToTime(get(this, 'labDate'));
  }),

  requestedDateAsTime: computed('requestedDate', function() {
    return this.dateToTime(get(this, 'requestedDate'));
  }),

  validations: {
    labTypeName: {
      presence: {
        'if'(object) {
          if (object.get('isNew')) {
            return true;
          }
        },
        message: 'Please select a lab type'
      }
    },
    patientTypeAhead: PatientValidation.patientTypeAhead,
    patient: {
      presence: true
    }
  }
});
export default AbstractModel.extend(CanEditRequested, DateFormat, MedicationDetails, {
  // Attributes
  notes: DS.attr('string'),
  prescription: DS.attr('string'),
  prescriptionDate: DS.attr('date'),
  quantity: DS.attr('number'),
  refills: DS.attr('number'),
  requestedDate: DS.attr('date'),
  requestedBy: DS.attr('string'),
  status: DS.attr('string'),

  // Associations
  inventoryItem: DS.belongsTo('inventory', { async: true }),
  patient: DS.belongsTo('patient', { async: false }),
  visit: DS.belongsTo('visit', { async: false }),

  isRequested: computed('status', function() {
    return get(this, 'status') === 'Requested';
  }),

  medicationName: computed('medicationTitle', 'inventoryItem', function() {
    return this.getMedicationName('inventoryItem');
  }),

  medicationPrice: computed('priceOfMedication', 'inventoryItem', function() {
    return this.getMedicationPrice('inventoryItem');
  }),

  prescriptionDateAsTime: computed('prescriptionDate', function() {
    return this.dateToTime(get(this, 'prescriptionDate'));
  }),

  requestedDateAsTime: computed('requestedDate', function() {
    return this.dateToTime(get(this, 'requestedDate'));
  }),

  validations: {
    prescription: {
      acceptance: {
        accept: true,
        if(object) {
          if (!get(object, 'hasDirtyAttributes') || get(object, 'isFulfilling')) {
            return false;
          }
          let prescription = get(object, 'prescription');
          let quantity = get(object, 'quantity');
          return Ember.isEmpty(prescription) && Ember.isEmpty(quantity);
        },
        message: 'Please enter a prescription or a quantity'
      }
    },

    inventoryItemTypeAhead: {
      acceptance: {
        accept: true,
        if(object) {
          if (!get(object, 'hasDirtyAttributes') || !get(object, 'isNew')) {
            return false;
          }
          let itemName = get(object, 'inventoryItem.name');
          let itemTypeAhead = get(object, 'inventoryItemTypeAhead');
          if (Ember.isEmpty(itemName) || Ember.isEmpty(itemTypeAhead)) {
            // force validation to fail
            return true;
          } else {
            let typeAheadName = itemTypeAhead.substr(0, itemName.length);
            if (itemName !== typeAheadName) {
              return true;
            }
          }
          // Inventory item is properly selected; don't do any further validation
          return false;
        },
        message: 'Please select a valid medication'
      }
    },

    patientTypeAhead: {
      presence: {
        if(object) {
          return get(object, 'selectPatient');
        }
      }
    },

    quantity: {
      numericality: {
        allowBlank: true,
        greaterThan: 0,
        messages: {
          greaterThan: 'must be greater than 0'
        }
      },
      presence: {
        if(object) {
          return get(object, 'isFulfilling');
        }
      },
      acceptance: {
        accept: true,
        if(object) {
          let isFulfilling = get(object, 'isFulfilling');
          let requestQuantity = parseInt(get(object, 'quantity'));
          let quantityToCompare = null;

          if (!isFulfilling) {
            // no validation needed when not fulfilling
            return false;
          } else {
            quantityToCompare = object.get('inventoryItem.quantity');
          }

          if (requestQuantity > quantityToCompare) {
            // force validation to fail
            return true;
          } else {
            // There is enough quantity on hand
            return false;
          }
        },
        message: 'The quantity must be less than or equal to the number of available medication.'
      }
    },

    refills: {
      numericality: {
        allowBlank: true
      }
    }
  }
});
Esempio n. 19
0
export default AbstractModel.extend(NumberFormat,{
    amountOwed: DS.attr('number'),
    department: DS.attr('string'),
    discount: DS.attr('number'),
    discountPercentage: DS.attr('number'),
    expenseAccount: DS.attr('string'),
    name: DS.attr('string'),
    price: DS.attr('number'),
    pricingItem: DS.belongsTo('pricing'),
    quantity: DS.attr('number'),
    total: DS.attr('number'),
    
    _calculateAmountOwed: function() {
        var amountOwed,
            discount = this.get('discount'),
            total = this.get('total');
        if (this._validNumber(total)) {
            if (this._validNumber(discount)) {            
                amountOwed = this._numberFormat((total - discount), true);
            } else {
                amountOwed = this._numberFormat(total, true);
            }            
        }
        this.set('amountOwed', amountOwed);
    },
    
    _calculateTotal: function() {
        var discountPercentage = this.get('discountPercentage'),
            price = this.get('price'),
            quantity = this.get('quantity'),
            total;
        if (this._validNumber(price) && this._validNumber(quantity)) {
            total = this._numberFormat((price * quantity), true);
            if (!Ember.isEmpty(discountPercentage)) {
                var discount = this._numberFormat((discountPercentage * total), true);
                this.set('discount', discount);
            }
        }
        this.set('total', total);
    },
    
    amountOwedChanged: function() {
        Ember.run.debounce(this, this._calculateAmountOwed,150);
    }.observes('discount', 'total'),
   
    totalChanged: function() {
        Ember.run.debounce(this, this._calculateTotal,300);
    }.observes('price','quantity')

});
Esempio n. 20
0
export default AbstractModel.extend(DOBDays, PatientName, {
  admitted: DS.attr('boolean', { defaultValue: false }),
  additionalContacts: DS.attr(),
  address: DS.attr('string'),
  address2: DS.attr('string'),
  address3: DS.attr('string'),
  address4: DS.attr('string'),
  bloodType: DS.attr('string'),
  clinic: DS.attr('string'),
  country: DS.attr('string'),
  dateOfBirth: DS.attr('date'),
  economicClassification: DS.attr('string'),
  email: DS.attr('string'),
  expenses: DS.attr(),
  externalPatientId: DS.attr('string'),
  familySupport1: DS.attr('string'),
  familySupport2: DS.attr('string'),
  familySupport3: DS.attr('string'),
  familySupport4: DS.attr('string'),
  familySupport5: DS.attr('string'),
  friendlyId: DS.attr('string'),
  familyInfo: DS.attr(),
  firstName: DS.attr('string'),
  sex: DS.attr('string'),
  occupation: DS.attr('string'),
  history: DS.attr('string'),
  insurance: DS.attr('string'),
  lastName: DS.attr('string'),
  livingArrangement: DS.attr('string'),
  middleName: DS.attr('string'),
  notes: DS.attr('string'),
  otherIncome: DS.attr('string'),
  payments: DS.hasMany('payment', {
    async: true
  }),
  patientType: DS.attr('string'),
  parent: DS.attr('string'),
  paymentProfile: DS.belongsTo('price-profile', {
    async: false
  }),
  phone: DS.attr('string'),
  placeOfBirth: DS.attr('string'),
  referredDate: DS.attr('date'),
  referredBy: DS.attr('string'),
  religion: DS.attr('string'),
  socialActionTaken: DS.attr('string'),
  socialRecommendation: DS.attr('string'),
  status: DS.attr('string'),

  age: function() {
    let dob = this.get('dateOfBirth');
    return this.convertDOBToText(dob);
  }.property('dateOfBirth'),

  displayAddress: function() {
    let addressFields = this.getProperties('address', 'address2', 'address3', 'address4');
    let displayAddress = '';
    for (let prop in addressFields) {
      if (!Ember.isEmpty(addressFields[prop])) {
        if (!Ember.isEmpty(displayAddress)) {
          displayAddress += ', ';
        }
        displayAddress += addressFields[prop];
      }
    }
    return displayAddress;
  }.property('address', 'address2', 'address3', 'address4'),

  displayName: function() {
    return this.getPatientDisplayName(this);
  }.property('firstName', 'lastName', 'middleName'),

  displayPatientId: function() {
    return this.getPatientDisplayId(this);
  }.property('id', 'externalPatientId', 'friendlyId'),

  validations: {
    email: {
      format: {
        with: EmailValidation.emailRegex,
        allowBlank: true,
        message: 'please enter a valid email address'
      }
    },
    friendlyId: {
      presence: true
    },
    firstName: {
      presence: true
    },
    lastName: {
      presence: true
    }
  }

});
export default AbstractModel.extend({
  // Attributes
  additionalNotes: DS.attr('string'),
  admissionInstructions: DS.attr('string'),
  caseComplexity: DS.attr('number'),
  customForms: DS.attr('custom-forms'),
  operationDescription: DS.attr('string'),
  procedures: DS.attr('operative-procedures', { defaultValue: defaultProcedures }),
  status: DS.attr('string', { defaultValue: PLANNED_STATUS }),
  surgeon: DS.attr('string'),

  // Associations
  diagnoses: DS.hasMany('diagnosis'),
  patient: DS.belongsTo('patient', { async: false }),

  isPlanned: computed('status', {
    get() {
      let status = get(this, 'status');
      return status === PLANNED_STATUS;
    }
  }),

  validations: {
    caseComplexity: {
      numericality: {
        allowBlank: true,
        onlyInteger: true
      }
    },

    procedureDescription: {
      presence: {
        if(object) {
          return isEmpty(get(object, 'procedures'));
        }
      }
    }
  }
});
Esempio n. 22
0
import AbstractModel from 'hospitalrun/models/abstract';

export default AbstractModel.extend({
    
    //part of ministy models information
    ministry: DS.belongsTo('ministry'),
    
    //Main information
    description: DS.attr('string'),
    eventName: DS.attr('string'),
    date: DS.attr('string'),
    location: DS.attr('string'),
    
    //for adding multiple participants per leadership event
    participants: DS.hasMany('leadership-participant'),//what will need to work
});
Esempio n. 23
0
import AbstractModel from 'hospitalrun/models/abstract';

export default AbstractModel.extend({    
    name: DS.attr('string'),
    discountAmount: DS.attr('number'),
    discountPercentage: DS.attr('number'),
    
    validations: {
        name: {
            presence: true
        },        
        discountAmount: {
            numericality: {
                allowBlank: true
            }
        },        
        discountPercentage: {
            numericality: {
                allowBlank: true
            }
        }
    }
});
Esempio n. 24
0
export default AbstractModel.extend(DateFormat, NumberFormat, {
  externalInvoiceNumber: DS.attr('string'),
  patient: DS.belongsTo('patient', {
    async: false
  }),
  patientInfo: DS.attr('string'), // Needed for searching
  visit: DS.belongsTo('visit', {
    async: false
  }),
  status: DS.attr('string'),
  remarks: DS.attr('string'),
  billDate: DS.attr('date'),
  paidTotal: DS.attr('number'),
  paymentProfile: DS.belongsTo('price-profile', {
    async: false
  }),
  // payments track the number of payment events attached to an invoice.
  payments: DS.hasMany('payment', {
    async: false
  }),
  // the individual line items of the invoice
  lineItems: DS.hasMany('billing-line-item', {
    async: false
  }),

  addPayment: function(payment) {
    let payments = this.get('payments');
    payments.addObject(payment);
    this.paymentAmountChanged();
  },

  billDateAsTime: function() {
    return this.dateToTime(this.get('billDate'));
  }.property('billDate'),

  discountTotals: Ember.computed.mapBy('lineItemsByCategory', 'discount'),
  discount: Ember.computed.sum('discountTotals'),

  nationalInsuranceTotals: Ember.computed.mapBy('lineItemsByCategory', 'nationalInsurance'),
  nationalInsurance: Ember.computed.sum('nationalInsuranceTotals'),

  paidFlag: function() {
    return (this.get('status') === 'Paid');
  }.property('status'),

  remainingBalance: function() {
    let patientResponsibility = this.get('patientResponsibility');
    let paidTotal = this.get('paidTotal');
    return this._numberFormat((patientResponsibility - paidTotal), true);
  }.property('patientResponsibility', 'paidTotal'),

  privateInsuranceTotals: Ember.computed.mapBy('lineItemsByCategory', 'privateInsurance'),
  privateInsurance: Ember.computed.sum('privateInsuranceTotals'),

  lineTotals: Ember.computed.mapBy('lineItems', 'total'),
  total: Ember.computed.sum('lineTotals'),

  displayInvoiceNumber: function() {
    let externalInvoiceNumber = this.get('externalInvoiceNumber');
    let id = this.get('id');
    if (Ember.isEmpty(externalInvoiceNumber)) {
      return id;
    } else {
      return externalInvoiceNumber;
    }
  }.property('externalInvoiceNumber', 'id'),

  lineItemsByCategory: function() {
    let lineItems = this.get('lineItems');
    let byCategory = [];
    lineItems.forEach(function(lineItem) {
      let category = lineItem.get('category');
      let categoryList = byCategory.findBy('category', category);
      if (Ember.isEmpty(categoryList)) {
        categoryList = {
          category: category,
          items: []
        };
        byCategory.push(categoryList);
      }
      categoryList.items.push(lineItem);
    }.bind(this));
    byCategory.forEach(function(categoryList) {
      categoryList.amountOwed = this._calculateTotal(categoryList.items, 'amountOwed');
      categoryList.discount = this._calculateTotal(categoryList.items, 'discount');
      categoryList.nationalInsurance = this._calculateTotal(categoryList.items, 'nationalInsurance');
      categoryList.privateInsurance = this._calculateTotal(categoryList.items, 'privateInsurance');
      categoryList.total = this._calculateTotal(categoryList.items, 'total');
    }.bind(this));
    return byCategory;
  }.property('*****@*****.**'),
  patientIdChanged: function() {
    if (!Ember.isEmpty(this.get('patient'))) {
      let patientDisplayName = this.get('patient.displayName');
      let patientDisplayId = this.get('patient.displayPatientId');
      this.set('patientInfo', `${patientDisplayName} - ${patientDisplayId}`);
    }
  }.observes('patient.displayName', 'patient.id', 'patient.displayPatientId'),

  patientResponsibilityTotals: Ember.computed.mapBy('lineItems', 'amountOwed'),
  patientResponsibility: Ember.computed.sum('patientResponsibilityTotals'),

  paymentAmountChanged: function() {
    let payments = this.get('payments').filter(function(payment) {
      return !payment.get('isNew');
    });
    if (payments.length === 0) {
      return;
    }
    let paidTotal = payments.reduce(function(previousValue, payment) {
        return previousValue += this._getValidNumber(payment.get('amount'));
      }.bind(this), 0);
    this.set('paidTotal', this._numberFormat(paidTotal, true));
    let remainingBalance = this.get('remainingBalance');
    if (remainingBalance <= 0) {
      this.set('status', 'Paid');
    }
  }.observes('payments.[]', '*****@*****.**'),

  validations: {
    patientTypeAhead: PatientValidation.patientTypeAhead,

    patient: {
      presence: true
    },

    visit: {
      presence: true
    }
  }
});
export default AbstractModel.extend({
  // Attributes
  anesthesiaType: DS.attr('string'),
  anesthesiologist: DS.attr('string'),
  assistant: DS.attr('string'),
  description: DS.attr('string'),
  cptCode: DS.attr('string'),
  location: DS.attr('string'),
  notes: DS.attr('string'),
  physician: DS.attr('string'),
  procedureDate: DS.attr('date'),
  timeStarted: DS.attr('string'),
  timeEnded: DS.attr('string'),

  // Associations
  charges: DS.hasMany('proc-charge', { async: false }),
  visit: DS.belongsTo('visit', { async: false }),

  validations: {
    description: {
      presence: true
    },

    oxygenHours: {
      numericality: {
        allowBlank: true
      }
    },
    pacuHours: {
      numericality: {
        allowBlank: true
      }
    },
    physician: {
      presence: true
    },
    procedureDate: {
      presence: true
    },
    display_procedureDate: {
      presence: {
        message: 'Please select a valid date'
      }
    }
  }
});
Esempio n. 26
0
export default AbstractModel.extend(LocationName, {
  purchases: DS.hasMany('inv-purchase', {
    async: false
  }),
  locations: DS.hasMany('inv-location', {
    async: false
  }),
  description: DS.attr('string'),
  friendlyId: DS.attr('string'),
  keywords: DS.attr(),
  name: DS.attr('string'),
  quantity: DS.attr('number'),
  crossReference: DS.attr('string'),
  inventoryType: DS.attr('string'),
  price: DS.attr('number'),
  reorderPoint: DS.attr('number'),
  distributionUnit: DS.attr('string'),
  rank: DS.attr('string'),

  // TODO: this value should be server calcuated property on model!
  estimatedDaysOfStock: 14,

  availableLocations: computed('*****@*****.**', function() {
    let locations = this.get('locations').filter((location) => {
      return location.get('quantity') > 0;
    });
    return locations;
  }),

  displayLocations: computed('availableLocations', function() {
    let locations = this.get('availableLocations');
    let returnLocations = [];

    locations.forEach((currentLocation) => {
      let aisleLocationName = currentLocation.get('aisleLocation');
      let locationName = currentLocation.get('location');
      let displayLocationName = this.formatLocationName(locationName, aisleLocationName);
      if (!Ember.isEmpty(displayLocationName)) {
        returnLocations.push(displayLocationName);
      }
    });

    return returnLocations.toString();
  }),

  condition: computed('rank', 'estimatedDaysOfStock', function() {
    let estimatedDaysOfStock = this.get('estimatedDaysOfStock');
    let multiplier = rankToMultiplier(this.get('rank'));

    return getCondition(estimatedDaysOfStock, multiplier);
  }),

  validations: {
    distributionUnit: {
      presence: true
    },
    purchaseCost: {
      numericality: validateIfNewItem
    },
    name: {
      presence: true
    },
    quantity: {
      numericality: {
        validateIfNewItem,
        greaterThanOrEqualTo: 0
      }
    },
    price: {
      numericality: {
        allowBlank: true
      }
    },
    originalQuantity: {
      presence: validateIfNewItem
    },
    reorderPoint: {
      numericality: {
        allowBlank: true
      }
    },
    inventoryType: {
      presence: true
    },
    vendor: {
      presence: validateIfNewItem
    }
  },

  updateQuantity() {
    let purchases = this.get('purchases');
    let newQuantity = purchases.reduce((previousItem, currentItem) => {
      let currentQuantity = 0;
      if (!currentItem.get('expired')) {
        currentQuantity = currentItem.get('currentQuantity');
      }
      return previousItem + currentQuantity;
    }, 0);
    this.set('quantity', newQuantity);
  }
});
Esempio n. 27
0
import Ember from 'ember';

export default AbstractModel.extend({
  _attachments: DS.attr(), // Temporarily store file as attachment until it gets uploaded to the server
  coverImage: DS.attr('boolean'),
  fileName: DS.attr('string'),
  localFile: DS.attr('boolean'),
  patient: DS.belongsTo('patient', {
    async: false
  }),
  caption: DS.attr('string'),
  url: DS.attr('string'),

  downloadImageFromServer(imageRecord) {
    let me = this;
    let url = imageRecord.get('url');
    let xhr = new XMLHttpRequest();
    if (!Ember.isEmpty(url)) {
      // Make sure directory exists or is created before downloading.
      this.getPatientDirectory(imageRecord.get('patientId'));
      xhr.open('GET', url, true);
      xhr.responseType = 'blob';
      xhr.onload = function() {
        let file = new Blob([xhr.response]);
        me.addImageToFileStore(file, null, imageRecord);
      };
      xhr.send();
    }
  }
});
Esempio n. 28
0
const { computed, get, isEmpty } = Ember;

export default AbstractModel.extend({
  // Attributes
  /* Temporarily store file as attachment until it gets uploaded to the server */
  caption: attr('string'),
  coverImage: attr('boolean'),
  files: attr('attachments', {
    defaultValue() {
      return [];
    }
  }),
  fileName: attr('string'),
  isImage: DS.attr('boolean', { defaultValue: false }),
  localFile: DS.attr('boolean', { defaultValue: false }),
  url: attr('string'),

  // Associations
  patient: belongsTo('patient', { async: false }),
  visit: belongsTo('visit', { async: false }),
  procedure: belongsTo('procedure', { async: false }),

  shortFileName: computed('fileName', function() {
    let fileName = get(this, 'fileName');
    if (!isEmpty(fileName)) {
      fileName = fileName.substr(fileName.lastIndexOf('/') + 1);
    }
    return fileName;
  })
});
Esempio n. 29
0
export default AbstractModel.extend({
    
    haveInvoiceItems: function() {
        var invoiceItems = this.get('invoiceItems');
        return (Ember.isEmpty(invoiceItems));
    },
    
    validations: {        
        dateReceived: {
            presence: true
        },
        inventoryItemTypeAhead: {
            presence: {
                if: function(object) {
                    return object.haveInvoiceItems();
                }
            }
        },
        purchaseCost: {
            numericality: {
                greaterThan: 0,
                if: function(object) {
                    return object.haveInvoiceItems();
                }
            }            
        },
        quantity: {
            numericality: {
                greaterThan: 0,
                if: function(object) {
                    return object.haveInvoiceItems();
                }
            }            
        }
    }
});