<commit_before>import React from 'react'
import { connect } from 'react-redux'
import { AUradio } from '@gov.au/control-input'
import AUselect from '@gov.au/select'
import AUtextInput from '@gov.au/text-inputs'
import { approveEvidence, rejectEvidence } from '../../redux/modules/evidence'
import format from 'date-fns/format'
import './EvidenceAssessment.css'

class EvidenceAssessment extends React.Component {
  constructor(props) {
    super(props)
    this.state = {
      wasApproved: false,
      wasRejected: false,
      vfm: undefined
    }

    const criteria = {}
    if (this.props.evidence) {
      Object.keys(this.props.evidence.data.evidence).map(criteriaId => {
        criteria[criteriaId] = {
          demonstrates: this.props.evidence.approvedCriteria.includes(criteriaId) ? true : undefined,
          reason: '',
          feedback: ''
        }
      })
      this.state.criteria = criteria
    }

    this.handleAssessmentApprove = this.handleAssessmentApprove.bind(this)
    this.handleAssessmentReject = this.handleAssessmentReject.bind(this)
    this.hasMetAllEssentialCriteria = this.hasMetAllEssentialCriteria.bind(this)
  }

  hasReviewedAllCriteria() {
    return Object.keys(this.state.criteria).every(id => {
      return this.state.criteria[id].demonstrates === true || (this.state.criteria[id].demonstrates === false && this.state.criteria[id].reason)
    })
  }

  hasReviewiedVFM() {
    return this.state.vfm !== undefined
  }

  hasMetAllEssentialCriteria = essentialCriteriaIds => {
    const demonstratedCriteriaIds = Object.keys(this.state.criteria)
      .filter(id => this.state.criteria[id].demonstrates === true)
      .map(id => parseInt(id))

    return essentialCriteriaIds.every(id => demonstratedCriteriaIds.includes(id))
  }

  hasMetEnoughCriteria() {
    return (
      this.props.evidence.criteriaNeeded > 0 &&
      Object.keys(this.state.criteria).filter(id => this.state.criteria[id].demonstrates === true).length >= this.props.evidence.criteriaNeeded
    )
  }

  getCriteriaName(criteriaId) {
    const match = this.props.evidence.domain_criteria.find(x => parseInt(x.id, 10) === parseInt(criteriaId, 10))
    return match.name ? match.name : ''
  }

  getReasonOptions() {
    const reasonsText = [
      'Not clear what the seller specifically did',
      'The evidence does not contain enough detail to assess',
      'The evidence does not relate to the criteria',
      'The evidence only partially demonstrates the criteria',
      'The situation cited does not reflect a common government need'
    ]
    const reasons = [
      {
        value: '',
        text: 'Select a reason...'
      }
    ]
    reasonsText.map(reason => reasons.push({ value: reason, text: reason }))
    return reasons
  }

  handleCriteriaReviewClick(e, criteriaId) {
    e.persist()
    this.setState(curState => {
      const value = e.target.value === "yes" ? true : false
      const newState = { ...curState }
      newState.criteria[criteriaId].demonstrates = value
      return newState
    })
  }

  handleVFMClick(vfm) {
    this.setState({
      vfm
    })
  }

  handleFeedbackChange(e, type, criteriaId) {
    e.persist()
    this.setState(curState => {
      const feedback = e.target.value
      const newState = { ...curState }
      newState.criteria[criteriaId][type] = feedback
      return newState
    })
  }

  handleAssessmentReject = essentialCriteriaIds => {
    const evidenceId = this.props.match.params.id
    const failed_criteria = {}
    Object.keys(this.state.criteria).map(criteriaId => {
      if (this.state.criteria[criteriaId].demonstrates === false && this.state.criteria[criteriaId].reason) {
        failed_criteria[criteriaId] = {
          reason: this.state.criteria[criteriaId].reason,
          feedback: this.state.criteria[criteriaId].feedback
        }
      }
    })

    // This resets the value of vfm if it's been rejected but the assessor has changed their mind and rejected criteria
    let vfm = this.state.vfm
    if (!this.hasMetAllEssentialCriteria(essentialCriteriaIds) || !this.hasMetEnoughCriteria()) {
      vfm = null
    }

    this.props.rejectEvidence(evidenceId, failed_criteria, vfm).then(res => {
      this.setState({
        wasApproved: false,
        wasRejected: true
      })
    })
  }

  handleAssessmentApprove() {
    const evidenceId = this.props.match.params.id
    const failedCriteria = {}
    Object.keys(this.state.criteria).map(criteriaId => {
      if (this.state.criteria[criteriaId].demonstrates === false && this.state.criteria[criteriaId].reason) {
        failedCriteria[criteriaId] = {
          reason: this.state.criteria[criteriaId].reason,
          feedback: this.state.criteria[criteriaId].feedback
        }
      }
    })
    this.props.approveEvidence(evidenceId, failedCriteria).then(res => {
      this.setState({
        wasApproved: true,
        wasRejected: false
      })
    })
  }

  priceIsOver() {
    return parseInt(this.props.evidence.maxDailyRate, 10) > parseInt(this.props.evidence.domain_price_maximum, 10)
  }

  getOverPercentage() {
    return Math.round(
      (parseInt(this.props.evidence.maxDailyRate, 10) / parseInt(this.props.evidence.domain_price_maximum, 10)
      * 100) - 100
    )
  }

  render() {
    const { evidence } = this.props
    const essentialCriteriaIds = evidence.domain_criteria.filter(
      criterion => criterion.essential
    ).map(criterion => criterion.id)

    if (!evidence) {
      return (
        <div>
          <h1 className="au-display-xl">Evidence submission not found</h1>
          <p>An evidence submission by this id either does not exist, or has already been reviewed.</p>
        </div>
      )
    }

    if (evidence && this.state.wasApproved) {
      return (
        <div>
          <h1 className="au-display-xl">Assessment approved</h1>
          <p>{evidence.domain_name} for <strong>{evidence.supplier_name} ({evidence.supplier_code})</strong> was approved.</p>
          <p><a href="/admin/evidence-assessments">Return to evidence assessment list</a></p>
        </div>
      )
    }<commit_msg>Investigate TypeError related to release of Platforms Integration category (#981)<commit_after>import React from 'react'
import { connect } from 'react-redux'
import { AUradio } from '@gov.au/control-input'
import AUselect from '@gov.au/select'
import AUtextInput from '@gov.au/text-inputs'
import { approveEvidence, rejectEvidence } from '../../redux/modules/evidence'
import format from 'date-fns/format'
import './EvidenceAssessment.css'

class EvidenceAssessment extends React.Component {
  constructor(props) {
    super(props)
    this.state = {
      wasApproved: false,
      wasRejected: false,
      vfm: undefined
    }

    const criteria = {}
    if (this.props.evidence) {
      Object.keys(this.props.evidence.data.evidence).map(criteriaId => {
        criteria[criteriaId] = {
          demonstrates: this.props.evidence.approvedCriteria.includes(criteriaId) ? true : undefined,
          reason: '',
          feedback: ''
        }
      })
      this.state.criteria = criteria
    }

    this.handleAssessmentApprove = this.handleAssessmentApprove.bind(this)
    this.handleAssessmentReject = this.handleAssessmentReject.bind(this)
    this.hasMetAllEssentialCriteria = this.hasMetAllEssentialCriteria.bind(this)
  }

  hasReviewedAllCriteria() {
    return Object.keys(this.state.criteria).every(id => {
      return this.state.criteria[id].demonstrates === true || (this.state.criteria[id].demonstrates === false && this.state.criteria[id].reason)
    })
  }

  hasReviewiedVFM() {
    return this.state.vfm !== undefined
  }

  hasMetAllEssentialCriteria = essentialCriteriaIds => {
    const demonstratedCriteriaIds = Object.keys(this.state.criteria)
      .filter(id => this.state.criteria[id].demonstrates === true)
      .map(id => parseInt(id))

    return essentialCriteriaIds.every(id => demonstratedCriteriaIds.includes(id))
  }

  hasMetEnoughCriteria() {
    return (
      this.props.evidence.criteriaNeeded > 0 &&
      Object.keys(this.state.criteria).filter(id => this.state.criteria[id].demonstrates === true).length >= this.props.evidence.criteriaNeeded
    )
  }

  getCriteriaName(criteriaId) {
    const match = this.props.evidence.domain_criteria.find(x => parseInt(x.id, 10) === parseInt(criteriaId, 10))
    return match.name ? match.name : ''
  }

  getReasonOptions() {
    const reasonsText = [
      'Not clear what the seller specifically did',
      'The evidence does not contain enough detail to assess',
      'The evidence does not relate to the criteria',
      'The evidence only partially demonstrates the criteria',
      'The situation cited does not reflect a common government need'
    ]
    const reasons = [
      {
        value: '',
        text: 'Select a reason...'
      }
    ]
    reasonsText.map(reason => reasons.push({ value: reason, text: reason }))
    return reasons
  }

  handleCriteriaReviewClick(e, criteriaId) {
    e.persist()
    this.setState(curState => {
      const value = e.target.value === "yes" ? true : false
      const newState = { ...curState }
      newState.criteria[criteriaId].demonstrates = value
      return newState
    })
  }

  handleVFMClick(vfm) {
    this.setState({
      vfm
    })
  }

  handleFeedbackChange(e, type, criteriaId) {
    e.persist()
    this.setState(curState => {
      const feedback = e.target.value
      const newState = { ...curState }
      newState.criteria[criteriaId][type] = feedback
      return newState
    })
  }

  handleAssessmentReject = essentialCriteriaIds => {
    const evidenceId = this.props.match.params.id
    const failed_criteria = {}
    Object.keys(this.state.criteria).map(criteriaId => {
      if (this.state.criteria[criteriaId].demonstrates === false && this.state.criteria[criteriaId].reason) {
        failed_criteria[criteriaId] = {
          reason: this.state.criteria[criteriaId].reason,
          feedback: this.state.criteria[criteriaId].feedback
        }
      }
    })

    // This resets the value of vfm if it's been rejected but the assessor has changed their mind and rejected criteria
    let vfm = this.state.vfm
    if (!this.hasMetAllEssentialCriteria(essentialCriteriaIds) || !this.hasMetEnoughCriteria()) {
      vfm = null
    }

    this.props.rejectEvidence(evidenceId, failed_criteria, vfm).then(res => {
      this.setState({
        wasApproved: false,
        wasRejected: true
      })
    })
  }

  handleAssessmentApprove() {
    const evidenceId = this.props.match.params.id
    const failedCriteria = {}
    Object.keys(this.state.criteria).map(criteriaId => {
      if (this.state.criteria[criteriaId].demonstrates === false && this.state.criteria[criteriaId].reason) {
        failedCriteria[criteriaId] = {
          reason: this.state.criteria[criteriaId].reason,
          feedback: this.state.criteria[criteriaId].feedback
        }
      }
    })
    this.props.approveEvidence(evidenceId, failedCriteria).then(res => {
      this.setState({
        wasApproved: true,
        wasRejected: false
      })
    })
  }

  priceIsOver() {
    return parseInt(this.props.evidence.maxDailyRate, 10) > parseInt(this.props.evidence.domain_price_maximum, 10)
  }

  getOverPercentage() {
    return Math.round(
      (parseInt(this.props.evidence.maxDailyRate, 10) / parseInt(this.props.evidence.domain_price_maximum, 10)
      * 100) - 100
    )
  }

  render() {
    const { evidence } = this.props
    let essentialCriteriaIds = [];
    if (evidence.domain_criteria) {
      essentialCriteriaIds = evidence.domain_criteria.filter(criterion => criterion.essential).map(criterion => criterion.id)
    }

    if (!evidence) {
      return (
        <div>
          <h1 className="au-display-xl">Evidence submission not found</h1>
          <p>An evidence submission by this id either does not exist, or has already been reviewed.</p>
        </div>
      )
    }

    if (evidence && this.state.wasApproved) {
      return (
        <div>
          <h1 className="au-display-xl">Assessment approved</h1>
          <p>{evidence.domain_name} for <strong>{evidence.supplier_name} ({evidence.supplier_code})</strong> was approved.</p>
          <p><a href="/admin/evidence-assessments">Return to evidence assessment list</a></p>
        </div>
      )
    }
{'fraction_non_alphanumeric': 0.12296739745975245, 'fraction_numerical': 0.003964080576005178, 'mean_word_length': 2.936942675159236, 'pattern_counts': {'":': 0, '<': 39, '<?xml version=': 0, '>': 81, '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': '4673511', 'n_tokens_mistral': 3864, 'n_tokens_neox': 3677, 'n_words': 712}