Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
211 changes: 161 additions & 50 deletions pyvet/benefits/claims/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
Benefits Intake API: https://developer.va.gov/explore/benefits/docs/claims?version=v1
Note: V1 is for external users, V2 is for internal users.
"""

import base64
import logging

import requests
Expand All @@ -13,6 +15,16 @@
get_bearer_token,
)
from pyvet.creds import API_URL
from pyvet.file_submission_schemas import (
Address,
Claimant,
Phone,
POAForm,
ServiceOrganization,
Signature,
Signatures,
Veteran,
)
from pyvet.json_alias import Json

BENEFITS_INTAKE_URL = API_URL + "claims/v1/"
Expand Down Expand Up @@ -233,30 +245,56 @@ def submit_526(
# pass


# def submit_intent_to_file(
# is_representative: bool = False,
# ssn: str = "",
# first_name: str = "",
# last_name: str = "",
# birth_date: str = "",
# ) -> Json:
# """Submit an intent to file for disability compensation, burial, or pension claims.
# is_representative : bool
# If the consumer is a representative on behalf of a veteran.
# ssn : str
# The veteran's SSN.
# first_name : str
# The veteran's first name.
# last_name : str
# The veteran's last name.
# birth_date : str
# The veteran's birth date in iso8601 format.
# Returns
# -------
# r : json
# Response in json format.
# """
# pass
def submit_intent_to_file(
is_representative: bool = False,
ssn: str = "",
first_name: str = "",
last_name: str = "",
birth_date: str = "",
) -> Json:
"""Submit an intent to file for disability compensation or pension claims (burial not allowed).
is_representative : bool
If the consumer is a representative on behalf of a veteran.
ssn : str
The veteran's SSN.
first_name : str
The veteran's first name.
last_name : str
The veteran's last name.
birth_date : str
The veteran's birth date in iso8601 format.
Returns
-------
r : json
Response in json format.
"""
submission_url = BENEFITS_INTAKE_URL + "forms/0966"
authorization = session.headers.get("Authorization")
if authorization is None:
logging.error("No token set.")
session.headers[
"Authorization"
] = f"""Bearer {get_bearer_token(scope=CLAIM_SCOPE)}"""
if session.headers.get("Authorization") is None:
logging.error("Fetcing token failed.")
return None

if is_representative:
session.headers["X-VA-SSN"] = ssn
session.headers["X-VA-First-Name"] = first_name
session.headers["X-VA-Last-Name"] = last_name
session.headers["X-VA-Birth-Date"] = birth_date

try:
r = session.post(
submission_url,
headers=session.headers,
data={"type": "form/0966", "attributes": {"type": "compensation"}},
)
r.raise_for_status()
return r.json()
except requests.exceptions.RequestException as e:
logging.error(e)


def get_last_active_intent_to_file(
Expand Down Expand Up @@ -308,32 +346,105 @@ def get_last_active_intent_to_file(
logging.error(e)


# def submit_poa(
# is_representative: bool = False,
# ssn: str = "",
# first_name: str = "",
# last_name: str = "",
# birth_date: str = "",
# ) -> Json:
# """Submit a Power of Attorney form 2122.
# Parameters
# ----------
# is_representative : bool
# If the consumer is a representative on behalf of a veteran.
# ssn : str
# The veteran's SSN.
# first_name : str
# The veteran's first name.
# last_name : str
# The veteran's last name.
# birth_date : str
# The veteran's birth date in iso8601 format.
# Returns
# -------
# r : json
# Response in json format.
# """
# pass
def submit_poa(
is_representative: bool = False,
ssn: str = "",
first_name: str = "",
last_name: str = "",
birth_date: str = "",
) -> Json:
"""Submit a Power of Attorney form 2122.
Parameters
----------
is_representative : bool
If the consumer is a representative on behalf of a veteran.
ssn : str
The veteran's SSN.
first_name : str
The veteran's first name.
last_name : str
The veteran's last name.
birth_date : str
The veteran's birth date in iso8601 format.
Returns
-------
r : json
Response in json format.
"""
submission_url = BENEFITS_INTAKE_URL + "forms/2122"
authorization = session.headers.get("Authorization")
if authorization is None:
logging.error("No token set.")
session.headers[
"Authorization"
] = f"""Bearer {get_bearer_token(scope=CLAIM_SCOPE)}"""
if session.headers.get("Authorization") is None:
logging.error("Fetching token failed.")
return None

if is_representative:
session.headers["X-VA-SSN"] = ssn
session.headers["X-VA-First-Name"] = first_name
session.headers["X-VA-Last-Name"] = last_name
session.headers["X-VA-Birth-Date"] = birth_date

poa_form: POAForm = POAForm(
veteran=Veteran(
address=Address(
numberAndStreet="123 Main St",
city="Anytown",
country="USA",
zipFirstFive="12345",
),
phone=Phone(
areaCode="123",
phoneNumber="4567890",
),
emailAddress="[email protected]",
),
claimant=Claimant(
firstName="John",
lastName="Doe",
address=Address(
numberAndStreet="123 Main St",
city="Anytown",
country="USA",
zipFirstFive="12345",
),
phone=Phone(
areaCode="123",
phoneNumber="4567890",
),
email="[email protected]",
relationship="self",
),
serviceOrganization=ServiceOrganization(
poaCode="1",
),
recordConsent=True,
signatures=Signatures(
veteran=Signature(
title=base64.b64encode(b"John Doe"),
),
representative=Signature(
title=base64.b64encode(b"Jane Doe"),
),
),
)

try:
r = session.post(
submission_url,
headers=session.headers,
data={
"type": "form/21-22",
"attributes": poa_form,
},
)
r.raise_for_status()
return r.json()
except requests.exceptions.RequestException as e:
logging.error(e)


# def upload_signed_poa(
Expand Down
3 changes: 0 additions & 3 deletions pyvet/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
"""
import logging

# the below is an internal version, with some modifications.
import oidc_client as oidc
import requests
from requests.adapters import HTTPAdapter
Expand All @@ -26,8 +25,6 @@ def get_bearer_token(scope: str = DEFAULT_SCOPE) -> str | None:
"""Get a bearer token from the VA OIDC server.
Parameters
----------
va_api : str
The VA API to request a token for.
scope : str
A scope to request from the VA OIDC server (different per VA API).
Returns
Expand Down
99 changes: 99 additions & 0 deletions pyvet/file_submission_schemas.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
"""Dataclasses for Intent to File API"""
# pylint: skip-file
import base64
from dataclasses import dataclass
from datetime import datetime
from typing import Annotated

BytesBase64 = Annotated[bytes, bytes]


@dataclass
class Address:
"""Address dataclass for Intent to File API"""

numberAndStreet: str
city: str
country: str
zipFirstFive: str
aptUnitNumber: int | None = None
state: str | None = None
zipLastFour: str | None = None
additionalProperties: bool | None = None


@dataclass
class Phone:
"""Phone dataclass for Intent to File API"""

areaCode: str
phoneNumber: str
countryCode: str | None = None
phoneNumberExtstring: str | None = None


@dataclass
class Veteran:
"""Veteran dataclass for Intent to File API"""

address: Address
phone: Phone
emailAddress: str
serviceBranch: str | None = None
serviceBranchOtherstring: str | None = None


@dataclass
class Claimant:
"""Claimant dataclass for Intent to File API"""

firstName: str
lastName: str
address: Address
phone: Phone
email: str
relationship: str
middleInitial: str | None = None


@dataclass
class ServiceOrganization:
"""Service Organization dataclass for Intent to File API"""

poaCode: str
description: str | None = None
organizationNamestring: str | None = None
firstName: str | None = None
lastName: str | None = None
jobTitle: str | None = None
address: Address | None = None
email: str | None = None


@dataclass
class Signature:
"""Signature dataclass for Intent to File API"""

# Base64 encoded png image of the signature.
title: BytesBase64


@dataclass
class Signatures:
"""Signatures dataclass for Intent to File API"""

veteran: Signature
representative: Signature


@dataclass
class POAForm:
"""POA Form dataclass for Intent to File API"""

veteran: Veteran
claimant: Claimant
serviceOrganization: ServiceOrganization
recordConsent: bool
signatures: Signatures
consentLimits: str | None = None
consentAddressChangeboolean: bool | None = None
Loading