Space.eventSourcing.Projection.extend(Donations, 'AppealsProjection', {

  collections: {
    appeals: 'Donations.Appeals'
  },

  eventSubscriptions() {
    return [{
      'Donations.AppealDrafted': this._onAppealDrafted,
      'Donations.AppealDraftUpdated': this._onAppealDraftUpdated,
      'Donations.AppealMade': this._onAppealMade,
      'Donations.AppealUpdated': this._onAppealUpdated
    }];
  },

  _onAppealDrafted(event) {
    this.appeals.insert(_.extend({}, this._extractAppealDetails(event), {
      _id: event.sourceId.toString(),
      organizationId: event.organizationId.toString(),
      locationId: event.locationId.toString(),
      state: 'drafted'
    }));
  },

  _onAppealDraftUpdated(event) {
    this.appeals.update(event.sourceId.toString(), {
      $set: this._extractAppealDetails(event)
    });
  },

  _onAppealMade(event) {
    this.appeals.update(event.sourceId.toString(), { $set: { state: 'open' } });
  },

  _onAppealUpdated(event) {
    this.appeals.update(event.sourceId.toString(), {
      $set: { title: event.title, description: event.description }
    });
  },

  _extractAppealDetails(event) {
    return {
      title: event.title,
      requiredQuantity: event.requiredQuantity.value,
      description: event.description
    };
  }

});

Space.eventSourcing.Projection.extend(Donations, 'AppealsProjection', {

  collections: {
    appeals: 'Donations.Appeals'
  },

  eventSubscriptions() {
    return [{
      'Donations.AppealDrafted': this._onAppealDrafted,
      'Donations.AppealDraftUpdated': this._onAppealDraftUpdated,
      'Donations.AppealMade': this._onAppealMade,
      'Donations.AppealUpdated': this._onAppealUpdated
    }];
  },

  _onAppealDrafted(event) {
    this.appeals.insert(_.extend({}, this._extractAppealDetails(event), {
      _id: event.sourceId.toString(),
      organizationId: event.organizationId.toString(),
      locationId: event.locationId.toString(),
      state: 'draft'
    }));
  },

  _onAppealDraftUpdated(event) {
    this.appeals.update(event.sourceId.toString(), {
      $set: this._extractAppealDetails(event)
    });
  },

  _onAppealMade(event) {
    this.appeals.update(event.sourceId.toString(), { $set: { state: 'open' } });
  },

  _onAppealUpdated(event) {
    this.appeals.update(event.sourceId.toString(), {
      $set: { title: event.title, description: event.description }
    });
  },

  _extractAppealDetails(event) {
    return {
      title: event.title,
      requiredQuantity: event.requiredQuantity.value,
      description: event.description
    };
  }

});

Switch 'drafted' to 'draft' in projection
Switch 'drafted' to 'draft' in projection
