<commit_before>/**
 * mSupply Mobile
 * Sustainable Solutions (NZ) Ltd. 2019
 */

import { UIDatabase } from '../../../database';
import { parsePositiveInteger, MODAL_KEYS } from '../../../utilities';
import { ACTIONS } from './constants';
import { openModal, closeModal } from './pageActions';

/**
 * Refreshes a row in the DataTable component.
 * Use case: editing a field of a realm object and ensuring the
 * UI is updated.
 *
 * @param {String} rowKey Key of the row to edit.
 */
export const refreshRow = rowKey => ({ type: ACTIONS.REFRESH_ROW, payload: { rowKey } });

/**
 * Edits a rows underlying `expiryDate` field.
 *
 * @param {Date}    newDate     The new date to set as the expiry.
 * @param {String}  rowKey      Key of the row to edit.
 * @param {String}  objectType  Type of object to edit i.e. 'TransactionBatch'
 */
export const editExpiryDate = (newDate, rowKey, objectType) => (dispatch, getState) => {
  const { data, keyExtractor } = getState();

  const objectToEdit = data.find(row => keyExtractor(row) === rowKey);

  UIDatabase.write(() => {
    objectToEdit.expiryDate = newDate;
    UIDatabase.save(objectType, objectToEdit);
  });

  dispatch(refreshRow(rowKey));
};

/**
 * Wrapper around editExpiryDate.
 */
export const editTransactionBatchExpiryDate = (newDate, rowKey) =>
  editExpiryDate(newDate, rowKey, 'TransactionBatch');

/**
 * Edits the field `totalQuantity` of a rows underlying data object.
 *
 * @param {String|Number} value      The new value to set (parsed as a positive integer)
 * @param {String}        rowKey     The key of the row to edit.
 */
export const editTotalQuantity = (value, rowKey) => (dispatch, getState) => {
  const { data, keyExtractor } = getState();

  const objectToEdit = data.find(row => keyExtractor(row) === rowKey);

  UIDatabase.write(() => {
    objectToEdit.setTotalQuantity(UIDatabase, parsePositiveInteger(value));
  });

  dispatch(refreshRow(rowKey));
};

/**
 * Edits a rows underlying `suggestedQuantity` field.
 *
 * @param {String|Number}   value       The new value to set as the required quantity.
 * @param {String}          rowKey      Key of the row to edit.
 * @param {String}          objectType  Type of object to edit i.e. 'RequisitionItem'
 */
export const editSuppliedQuantity = (value, rowKey) => (dispatch, getState) => {
  const { data, keyExtractor } = getState();

  const objectToEdit = data.find(row => keyExtractor(row) === rowKey);

  UIDatabase.write(() => objectToEdit.setSuppliedQuantity(UIDatabase, parsePositiveInteger(value)));

  dispatch(refreshRow(rowKey));
};

/**
 * Edits a rows underlying `requiredQuantity` field.
 *
 * @param {String|Number}   value       The new value to set as the required quantity.
 * @param {String}          rowKey      Key of the row to edit.
 * @param {String}          objectType  Type of object to edit i.e. 'RequisitionItem'
 */
export const editRequiredQuantity = (value, rowKey, objectType) => (dispatch, getState) => {
  const { data, keyExtractor } = getState();

  const objectToEdit = data.find(row => keyExtractor(row) === rowKey);

  UIDatabase.write(() => {
    objectToEdit.requiredQuantity = parsePositiveInteger(value);
    UIDatabase.save(objectType, objectToEdit);
  });

  dispatch(refreshRow(rowKey));
};

/**
 * Wrapper around editRequiredQuantity.
 */
export const editRequisitionItemRequiredQuantity = (value, rowKey) =>
  editRequiredQuantity(value, rowKey, 'RequisitionItem');

/**
 * Edits a rows underlying countedTotalQuantity field.
 *
 * @param {String|Number}   value   The new value to set as the ccounted total quantity.
 * @param {String}          rowKey  Key of the row to edit.
 */
export const editCountedQuantity = (value, rowKey) => (dispatch, getState) => {
  const { data, keyExtractor } = getState();

  const objectToEdit = data.find(row => keyExtractor(row) === rowKey);

  objectToEdit.setCountedTotalQuantity(UIDatabase, parsePositiveInteger(value));

  dispatch(refreshRow(rowKey));
};

/**
 * Removes a reason from a rows underlying data.
 *
 * @param {String} rowKey   Key for the row to edit.
 */
export const removeReason = rowKey => (dispatch, getState) => {
  const { data, keyExtractor } = getState();

  const objectToEdit = data.find(row => keyExtractor(row) === rowKey);

  objectToEdit.applyReason(UIDatabase);

  dispatch(refreshRow(rowKey));
};

/**
 * Checks if a rows enforceReason field is true, if so, transforms
 * the action to open a fullScreen reasons modal, otherwise, remove
 * any reasons applied.
 *
 * @param {String} rowKey Key of the row to enforce a reason on
 */
export const enforceReasonChoice = rowKey => (dispatch, getState) => {
  const { data, keyExtractor } = getState();

  const objectToEdit = data.find(row => keyExtractor(row) === rowKey);

  const { enforceReason } = objectToEdit;

  if (enforceReason) {
    dispatch(openModal(MODAL_KEYS.ENFORCE_STOCKTAKE_REASON, rowKey));
  } else {
    dispatch(removeReason(rowKey));
  }
};

/**
 * Applys a passed reason to the underlying row data. Can be a StocktakeItem
 * or StocktakeBatch.
 *
 * @param {Realm.Option} value Reason to apply to the underlying rorw.
 */
export const applyReason = value => (dispatch, getState) => {
  const { modalValue, keyExtractor } = getState();

  modalValue.applyReason(UIDatabase, value);

  const rowKey = keyExtractor(modalValue);

  dispatch(closeModal());
  dispatch(refreshRow(rowKey));
};

export const CellActionsLookup = {
  refreshRow,
  editExpiryDate,
  editTransactionBatchExpiryDate,
  editTotalQuantity,
  editSuppliedQuantity,
  editRequiredQuantity,
  editRequisitionItemRequiredQuantity,
  editCountedQuantity,
  removeReason,
  enforceReasonChoice,
  applyReason,
};

/**
 * =====================================================================
 *
 *                             Overrides
 *
 * Below are actions which are overrides of base actions.<commit_msg>Add editBatchName and editStocktakeBatchExpiryDate action creators<commit_after>/**
 * mSupply Mobile
 * Sustainable Solutions (NZ) Ltd. 2019
 */

import { UIDatabase } from '../../../database';
import { parsePositiveInteger, MODAL_KEYS } from '../../../utilities';
import { ACTIONS } from './constants';
import { openModal, closeModal } from './pageActions';

/**
 * Refreshes a row in the DataTable component.
 * Use case: editing a field of a realm object and ensuring the
 * UI is updated.
 *
 * @param {String} rowKey Key of the row to edit.
 */
export const refreshRow = rowKey => ({ type: ACTIONS.REFRESH_ROW, payload: { rowKey } });

/**
 * Edits a rows underlying `batch` field.
 *
 * @param {Date}    value       The new batch name value.
 * @param {String}  rowKey      Key of the row to edit.
 * @param {String}  objectType  Type of object to edit i.e. 'TransactionBatch'
 */
export const editBatchName = (value, rowKey, objectType) => (dispatch, getState) => {
  const { data, keyExtractor } = getState();

  const objectToEdit = data.find(row => keyExtractor(row) === rowKey);

  const { batch } = objectToEdit;

  if (value !== batch) {
    UIDatabase.write(() => UIDatabase.update(objectType, { ...objectToEdit, batch: value }));

    dispatch(refreshRow(rowKey));
  }
};

/**
 * Wrapper around editBatchName for StocktakeBatches
 */
export const editStocktakeBatchName = (value, rowKey) =>
  editBatchName(value, rowKey, 'StocktakeBatch');

/**
 * Edits a rows underlying `expiryDate` field.
 *
 * @param {Date}    newDate     The new date to set as the expiry.
 * @param {String}  rowKey      Key of the row to edit.
 * @param {String}  objectType  Type of object to edit i.e. 'TransactionBatch'
 */
export const editExpiryDate = (newDate, rowKey, objectType) => (dispatch, getState) => {
  const { data, keyExtractor } = getState();

  const objectToEdit = data.find(row => keyExtractor(row) === rowKey);

  UIDatabase.write(() => {
    objectToEdit.expiryDate = newDate;
    UIDatabase.save(objectType, objectToEdit);
  });

  dispatch(refreshRow(rowKey));
};

/**
 * Wrapper around editExpiryDate.
 */
export const editTransactionBatchExpiryDate = (newDate, rowKey) =>
  editExpiryDate(newDate, rowKey, 'TransactionBatch');

export const editStocktakeBatchExpiryDate = (newDate, rowKey) =>
  editExpiryDate(newDate, rowKey, 'StocktakeBatch');

/**
 * Edits the field `totalQuantity` of a rows underlying data object.
 *
 * @param {String|Number} value      The new value to set (parsed as a positive integer)
 * @param {String}        rowKey     The key of the row to edit.
 */
export const editTotalQuantity = (value, rowKey) => (dispatch, getState) => {
  const { data, keyExtractor } = getState();

  const objectToEdit = data.find(row => keyExtractor(row) === rowKey);

  UIDatabase.write(() => {
    objectToEdit.setTotalQuantity(UIDatabase, parsePositiveInteger(value));
  });

  dispatch(refreshRow(rowKey));
};

/**
 * Edits a rows underlying `suggestedQuantity` field.
 *
 * @param {String|Number}   value       The new value to set as the required quantity.
 * @param {String}          rowKey      Key of the row to edit.
 * @param {String}          objectType  Type of object to edit i.e. 'RequisitionItem'
 */
export const editSuppliedQuantity = (value, rowKey) => (dispatch, getState) => {
  const { data, keyExtractor } = getState();

  const objectToEdit = data.find(row => keyExtractor(row) === rowKey);

  UIDatabase.write(() => objectToEdit.setSuppliedQuantity(UIDatabase, parsePositiveInteger(value)));

  dispatch(refreshRow(rowKey));
};

/**
 * Edits a rows underlying `requiredQuantity` field.
 *
 * @param {String|Number}   value       The new value to set as the required quantity.
 * @param {String}          rowKey      Key of the row to edit.
 * @param {String}          objectType  Type of object to edit i.e. 'RequisitionItem'
 */
export const editRequiredQuantity = (value, rowKey, objectType) => (dispatch, getState) => {
  const { data, keyExtractor } = getState();

  const objectToEdit = data.find(row => keyExtractor(row) === rowKey);

  UIDatabase.write(() => {
    objectToEdit.requiredQuantity = parsePositiveInteger(value);
    UIDatabase.save(objectType, objectToEdit);
  });

  dispatch(refreshRow(rowKey));
};

/**
 * Wrapper around editRequiredQuantity.
 */
export const editRequisitionItemRequiredQuantity = (value, rowKey) =>
  editRequiredQuantity(value, rowKey, 'RequisitionItem');

/**
 * Edits a rows underlying countedTotalQuantity field.
 *
 * @param {String|Number}   value   The new value to set as the ccounted total quantity.
 * @param {String}          rowKey  Key of the row to edit.
 */
export const editCountedQuantity = (value, rowKey) => (dispatch, getState) => {
  const { data, keyExtractor } = getState();

  const objectToEdit = data.find(row => keyExtractor(row) === rowKey);

  objectToEdit.setCountedTotalQuantity(UIDatabase, parsePositiveInteger(value));

  dispatch(refreshRow(rowKey));
};

/**
 * Removes a reason from a rows underlying data.
 *
 * @param {String} rowKey   Key for the row to edit.
 */
export const removeReason = rowKey => (dispatch, getState) => {
  const { data, keyExtractor } = getState();

  const objectToEdit = data.find(row => keyExtractor(row) === rowKey);

  objectToEdit.applyReason(UIDatabase);

  dispatch(refreshRow(rowKey));
};

/**
 * Checks if a rows enforceReason field is true, if so, transforms
 * the action to open a fullScreen reasons modal, otherwise, remove
 * any reasons applied.
 *
 * @param {String} rowKey Key of the row to enforce a reason on
 */
export const enforceReasonChoice = rowKey => (dispatch, getState) => {
  const { data, keyExtractor } = getState();

  const objectToEdit = data.find(row => keyExtractor(row) === rowKey);

  const { enforceReason } = objectToEdit;

  if (enforceReason) {
    dispatch(openModal(MODAL_KEYS.ENFORCE_STOCKTAKE_REASON, rowKey));
  } else {
    dispatch(removeReason(rowKey));
  }
};

/**
 * Applys a passed reason to the underlying row data. Can be a StocktakeItem
 * or StocktakeBatch.
 *
 * @param {Realm.Option} value Reason to apply to the underlying rorw.
 */
export const applyReason = value => (dispatch, getState) => {
  const { modalValue, keyExtractor } = getState();

  modalValue.applyReason(UIDatabase, value);

  const rowKey = keyExtractor(modalValue);

  dispatch(closeModal());
  dispatch(refreshRow(rowKey));
};

export const CellActionsLookup = {
  refreshRow,
  editExpiryDate,
  editTransactionBatchExpiryDate,
  editStocktakeBatchExpiryDate,
  editTotalQuantity,
  editSuppliedQuantity,
  editRequiredQuantity,
  editRequisitionItemRequiredQuantity,
  editCountedQuantity,
  removeReason,
  enforceReasonChoice,
  applyReason,
  editBatchName,
  editStocktakeBatchName,
};

/**
 * =====================================================================
 *
 *                             Overrides
 *
 * Below are actions which are overrides of base actions.
{'fraction_non_alphanumeric': 0.13329185784275605, 'fraction_numerical': 0.0006221323586593048, 'mean_word_length': 3.9710088906068806, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 69, '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': '5006814', 'n_tokens_mistral': 3968, 'n_tokens_neox': 3816, 'n_words': 1136}