<commit_before>from api.base_api import UpdatableApi
from api_util import PTC, PTC_AND_HEALTHPRO, VIBRENT_BARCODE_URL
from app_util import auth_required, ObjDict
from dao.dv_order_dao import DvOrderDao
from fhir_utils import SimpleFhirR4Reader
from flask import request
from model.utils import from_client_participant_id
from participant_enums import OrderShipmentTrackingStatus
from werkzeug.exceptions import BadRequest, MethodNotAllowed
import dateutil


class DvOrderApi(UpdatableApi):

  def __init__(self):
    super(DvOrderApi, self).__init__(DvOrderDao())

  @staticmethod
  def _lookup_resource_type_method(resource_type_method_map, raw_resource):
    try:
      resource_type = raw_resource['resourceType']
    except KeyError:
      raise BadRequest("payload is missing resourceType")
    try:
      return resource_type_method_map[resource_type]
    except KeyError:
      raise MethodNotAllowed("Method not allowed for resource type {}".format(resource_type))

  @auth_required(PTC)
  def post(self):
    resource = request.get_json(force=True)
    method = self._lookup_resource_type_method(
      {'SupplyRequest': self._post_supply_request},
      resource
    )
    return method(resource)

  def _post_supply_request(self, resource):
    fhir_resource = SimpleFhirR4Reader(resource)
    patient = fhir_resource.contained.get(resourceType='Patient')
    p_id = from_client_participant_id(patient.identifier.get(
      system='http://joinallofus.org/fhir/participantId').value)
    response = super(DvOrderApi, self).post(participant_id=p_id)
    order_id = fhir_resource.identifier.get(system='orderId').value
    response[2]['Location'] = '/rdr/v1/SupplyRequest/{}'.format(order_id)
    # @todo: return a 201
    return response

  @auth_required(PTC_AND_HEALTHPRO)
  def get(self, p_id, order_id):  # pylint: disable=unused-argument
    if order_id:
      pk = {'participant_id': p_id, 'order_id': order_id}
      obj = ObjDict(pk)
      id_ = self.dao.get_id(obj)[0]
    else:
      raise BadRequest('Must include order ID to retrieve DV orders.')
    return super(DvOrderApi, self).get(id_=id_, participant_id=p_id)

  @auth_required(PTC)
  def put(self, bo_id):  # pylint: disable=unused-argument
    resource = request.get_json(force=True)
    method = self._lookup_resource_type_method(
      {
        'SupplyRequest': self._put_supply_request,
        'SupplyDelivery': self._put_supply_delivery
      },
      resource
    )
    return method(resource, bo_id)

  def _put_supply_request(self, resource, bo_id):
    barcode_url = resource.get('extension')[0].get('url', "No barcode url")
    # @todo: add a cancel request
    fhir_resource = SimpleFhirR4Reader(resource)
    p_id = from_client_participant_id(fhir_resource.contained.get(
      resourceType='Patient').identifier.get(system='http://joinallofus.org/fhir/participantId'))
    merged_resource = None
    if not p_id:
      raise BadRequest('Request must include participant id and must be of type int')
    if barcode_url == VIBRENT_BARCODE_URL:
      _id = self.dao.get_id(ObjDict({'participantId': p_id, 'order_id': int(bo_id)}))
      ex_obj = self.dao.get(_id)
      if not ex_obj.barcode:
        # Send to mayolink and create internal biobank order
        response = self.dao.send_order(resource, p_id)
        merged_resource = merge_dicts(response, resource)
        merged_resource['id'] = _id
        self.dao.insert_biobank_order(p_id, merged_resource)

    if merged_resource:
      response = super(DvOrderApi, self).put(bo_id, participant_id=p_id, skip_etag=True,
                                             resource=merged_resource)
    else:
      response = super(DvOrderApi, self).put(bo_id, participant_id=p_id, skip_etag=True)

    return response<commit_msg>DA-992 rebase master and refactor how we get participant id (#992)<commit_after>from api.base_api import UpdatableApi
from api_util import PTC, PTC_AND_HEALTHPRO, VIBRENT_BARCODE_URL
from app_util import auth_required, ObjDict
from dao.dv_order_dao import DvOrderDao
from fhir_utils import SimpleFhirR4Reader
from flask import request
from model.utils import from_client_participant_id
from participant_enums import OrderShipmentTrackingStatus
from werkzeug.exceptions import BadRequest, MethodNotAllowed
import dateutil


class DvOrderApi(UpdatableApi):

  def __init__(self):
    super(DvOrderApi, self).__init__(DvOrderDao())

  @staticmethod
  def _lookup_resource_type_method(resource_type_method_map, raw_resource):
    try:
      resource_type = raw_resource['resourceType']
    except KeyError:
      raise BadRequest("payload is missing resourceType")
    try:
      return resource_type_method_map[resource_type]
    except KeyError:
      raise MethodNotAllowed("Method not allowed for resource type {}".format(resource_type))

  @auth_required(PTC)
  def post(self):
    resource = request.get_json(force=True)
    method = self._lookup_resource_type_method(
      {'SupplyRequest': self._post_supply_request},
      resource
    )
    return method(resource)

  def _post_supply_request(self, resource):
    fhir_resource = SimpleFhirR4Reader(resource)
    patient = fhir_resource.contained.get(resourceType='Patient')
    pid = from_client_participant_id(patient.identifier.get(
      system='http://joinallofus.org/fhir/participantId').value)
    p_id = from_client_participant_id(pid.value)
    response = super(DvOrderApi, self).post(participant_id=p_id)
    order_id = fhir_resource.identifier.get(system='orderId').value
    response[2]['Location'] = '/rdr/v1/SupplyRequest/{}'.format(order_id)
    # @todo: return a 201
    return response

  @auth_required(PTC_AND_HEALTHPRO)
  def get(self, p_id, order_id):  # pylint: disable=unused-argument
    if order_id:
      pk = {'participant_id': p_id, 'order_id': order_id}
      obj = ObjDict(pk)
      id_ = self.dao.get_id(obj)[0]
    else:
      raise BadRequest('Must include order ID to retrieve DV orders.')
    return super(DvOrderApi, self).get(id_=id_, participant_id=p_id)

  @auth_required(PTC)
  def put(self, bo_id):  # pylint: disable=unused-argument
    resource = request.get_json(force=True)
    method = self._lookup_resource_type_method(
      {
        'SupplyRequest': self._put_supply_request,
        'SupplyDelivery': self._put_supply_delivery
      },
      resource
    )
    return method(resource, bo_id)

  def _put_supply_request(self, resource, bo_id):
    barcode_url = resource.get('extension')[0].get('url', "No barcode url")
    # @todo: add a cancel request
    fhir_resource = SimpleFhirR4Reader(resource)
    pid = fhir_resource.contained.get(
      resourceType='Patient').identifier.get(system='http://joinallofus.org/fhir/participantId')
    p_id = from_client_participant_id(pid.value)
    merged_resource = None
    if not p_id:
      raise BadRequest('Request must include participant id and must be of type int')
    if barcode_url == VIBRENT_BARCODE_URL:
      _id = self.dao.get_id(ObjDict({'participantId': p_id, 'order_id': int(bo_id)}))
      ex_obj = self.dao.get(_id)
      if not ex_obj.barcode:
        # Send to mayolink and create internal biobank order
        response = self.dao.send_order(resource, p_id)
        merged_resource = merge_dicts(response, resource)
        merged_resource['id'] = _id
        self.dao.insert_biobank_order(p_id, merged_resource)

    if merged_resource:
      response = super(DvOrderApi, self).put(bo_id, participant_id=p_id, skip_etag=True,
                                             resource=merged_resource)
    else:
      response = super(DvOrderApi, self).put(bo_id, participant_id=p_id, skip_etag=True)

    return response
{'fraction_non_alphanumeric': 0.09580994648218248, 'fraction_numerical': 0.003393812818169952, 'mean_word_length': 4.114819759679572, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4110757', 'n_tokens_mistral': 2534, 'n_tokens_neox': 2484, 'n_words': 499}