<commit_before>import { Feature } from 'toolkit/core/feature';
import * as toolkitHelper from 'toolkit/helpers/toolkit';

export class BudgetBalanceToZero extends Feature {
  attachedObserver = false
  budgetView = null

  shouldInvoke = () => {
    return toolkitHelper.getCurrentRouteName().indexOf('budget') !== -1;
  }

  invoke = () => {
    if (!this.attachedObserver) {
      this.addBudgetVersionIdObserver();
      this.attachedObserver = true;
    }

    const categories = this.getCategories();
    const categoryName = this.getInspectorName();
    const masterCategoryViewId = $('ul.is-checked').prevAll('ul.is-master-category').attr('id');

    if (masterCategoryViewId) {
      const masterCategory = ynabToolKit.shared.getEmberView(masterCategoryViewId).get('data');
      const masterCategoryId = masterCategory.get('categoryId');

      categories.forEach(category => {
        if (category.name === categoryName && category.masterCategoryId === masterCategoryId) {
          this.updateInspectorButton(category);

          return false;
        }
      });
    }
  }

  observe = (changedNodes) => {
    if (this.shouldInvoke() &&
      (
        changedNodes.has('inspector-quick-budget') ||
        changedNodes.has('budget-inspector-default')
      )) {
      this.invoke();
    }
  }

  addBudgetVersionIdObserver = () => {
    const resetBudgetView = () => {
      this.budgetView = null;
    };

    let applicationController = ynabToolKit.shared.containerLookup('controller:application');
    applicationController.addObserver('budgetVersionId', function () {
      Ember.run.scheduleOnce('afterRender', this, resetBudgetView);
    });
  }

  getCategories = () => {
    // After using Budget Quick Switch, budgetView needs to be reset to the new budget. The try catch construct is necessary
    // because this function can be called several times during the budget switch process.
    if (this.budgetView === null) {
      try {
        this.budgetView = ynab.YNABSharedLib.getBudgetViewModel_AllBudgetMonthsViewModel()._result;
      } catch (e) {
        return;
      }
    }

    const categories = [];
    const masterCats = this.budgetView.categoriesViewModel.masterCategoriesCollection._internalDataArray;
    const masterCategories = masterCats.filter(category => category.internalName === null);

    masterCategories.forEach((category) => {
      let accounts = this.budgetView
        .categoriesViewModel.subCategoriesCollection
        .findItemsByMasterCategoryId(category.entityId);

      Array.prototype.push.apply(categories, accounts);
    });

    return categories;
  }

  updateInspectorButton = (f) => {
    const amount = this.getBudgetAmount(f);
    const fAmount = ynabToolKit.shared.formatCurrency(amount);
    const existingButton = $('.toolkit-balance-to-zero');

    /* check for positive amounts */
    const positive = ynab.unformat(amount) > 0 ? '+' : '';<commit_msg>Budget Balance to Zero Fix<commit_after>import { Feature } from 'toolkit/core/feature';
import * as toolkitHelper from 'toolkit/helpers/toolkit';

export class BudgetBalanceToZero extends Feature {
  attachedObserver = false
  budgetView = null

  shouldInvoke = () => {
    return toolkitHelper.getCurrentRouteName().indexOf('budget') !== -1;
  }

  invoke = () => {
    if (!this.attachedObserver) {
      this.addBudgetVersionIdObserver();
      this.attachedObserver = true;
    }

    const categories = this.getCategories();
    const categoryName = this.getInspectorName();
    const masterCategoryViewId = $('ul.is-checked').prevAll('ul.is-master-category').attr('id');

    if (masterCategoryViewId) {
      const masterCategory = ynabToolKit.shared.getEmberView(masterCategoryViewId).get('data');
      const masterCategoryId = masterCategory.get('categoryId');

      categories.forEach(category => {
        if (category.name === categoryName && category.masterCategoryId === masterCategoryId) {
          this.updateInspectorButton(category);

          return false;
        }
      });
    }
  }

  observe = (changedNodes) => {
    if (this.shouldInvoke() &&
      (
        changedNodes.has('inspector-quick-budget') ||
        changedNodes.has('budget-inspector-default')
      )) {
      this.invoke();
    }
  }

  addBudgetVersionIdObserver = () => {
    const resetBudgetView = () => {
      this.budgetView = null;
    };

    let applicationController = ynabToolKit.shared.containerLookup('controller:application');
    applicationController.addObserver('budgetVersionId', function () {
      Ember.run.scheduleOnce('afterRender', this, resetBudgetView);
    });
  }

  getCategories = () => {
    // After using Budget Quick Switch, budgetView needs to be reset to the new budget. The try catch construct is necessary
    // because this function can be called several times during the budget switch process.
    if (this.budgetView === null) {
      try {
        this.budgetView = ynab.YNABSharedLib.getBudgetViewModel_AllBudgetMonthsViewModel()._result;
      } catch (e) {
        return;
      }
    }

    if (this.budgetView.categoriesViewModel === null) {
      return;
    }

    const categories = [];
    const masterCats = this.budgetView.categoriesViewModel.masterCategoriesCollection._internalDataArray;
    const masterCategories = masterCats.filter(category => category.internalName === null);

    masterCategories.forEach((category) => {
      let accounts = this.budgetView
        .categoriesViewModel.subCategoriesCollection
        .findItemsByMasterCategoryId(category.entityId);

      Array.prototype.push.apply(categories, accounts);
    });

    return categories;
  }

  updateInspectorButton = (f) => {
    const amount = this.getBudgetAmount(f);
    const fAmount = ynabToolKit.shared.formatCurrency(amount);
    const existingButton = $('.toolkit-balance-to-zero');

    /* check for positive amounts */
    const positive = ynab.unformat(amount) > 0 ? '+' : '';
{'fraction_non_alphanumeric': 0.12108980827447023, 'fraction_numerical': 0.0006727211570803902, 'mean_word_length': 3.318809005083515, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 25, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5995976', 'n_tokens_mistral': 1695, 'n_tokens_neox': 1638, 'n_words': 320}