get CLIN info from EDA XML
This commit is contained in:
parent
a05d226401
commit
6a03664b51
@ -5,6 +5,39 @@ import requests
|
|||||||
from requests.auth import HTTPBasicAuth
|
from requests.auth import HTTPBasicAuth
|
||||||
|
|
||||||
|
|
||||||
|
def parse_eda_xml(xml_string):
|
||||||
|
contract_et = ET.fromstring(xml_string)
|
||||||
|
handler = EDAXMLHandler(contract_et)
|
||||||
|
handler.parse()
|
||||||
|
return {
|
||||||
|
"clin_0001": handler.clins.get("0001"),
|
||||||
|
"clin_0003": handler.clins.get("0003"),
|
||||||
|
"clin_1001": handler.clins.get("1001"),
|
||||||
|
"clin_1003": handler.clins.get("1003"),
|
||||||
|
"clin_2001": handler.clins.get("2001"),
|
||||||
|
"clin_2003": handler.clins.get("2003"),
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class EDAXMLHandler:
|
||||||
|
def __init__(self, element_tree):
|
||||||
|
self.element_tree = element_tree
|
||||||
|
self.clins = {}
|
||||||
|
|
||||||
|
@property
|
||||||
|
def _line_items(self):
|
||||||
|
return self.element_tree.findall(".//LineItem[LineItemType='CLIN']/../../..")
|
||||||
|
|
||||||
|
def _parse_clin_data(self):
|
||||||
|
for line_item in self._line_items:
|
||||||
|
number = line_item.find(".//LineItemBase").text
|
||||||
|
amount_details = line_item.find(".//ItemOtherAmounts[AmountDescription='Not to Exceed Amount (Funding)']/Amount")
|
||||||
|
self.clins[number] = float(amount_details.text)
|
||||||
|
|
||||||
|
def parse(self):
|
||||||
|
self._parse_clin_data()
|
||||||
|
|
||||||
|
|
||||||
class EDAClientBase(object):
|
class EDAClientBase(object):
|
||||||
def list_contracts(
|
def list_contracts(
|
||||||
self,
|
self,
|
||||||
@ -80,9 +113,6 @@ class MockEDAClient(EDAClientBase):
|
|||||||
|
|
||||||
MOCK_CONTRACT_NUMBER = "DCA10096D0052"
|
MOCK_CONTRACT_NUMBER = "DCA10096D0052"
|
||||||
|
|
||||||
# TODO: It seems likely that this will have to supply CLIN data form the
|
|
||||||
# EDA returnclinXML API call, in addition to the basic task order data
|
|
||||||
# below. See the EDA docs.
|
|
||||||
def get_contract(self, contract_number, status):
|
def get_contract(self, contract_number, status):
|
||||||
if contract_number == self.MOCK_CONTRACT_NUMBER and status == "y":
|
if contract_number == self.MOCK_CONTRACT_NUMBER and status == "y":
|
||||||
return {
|
return {
|
||||||
|
239
tests/fixtures/eda_contract.xml
vendored
Normal file
239
tests/fixtures/eda_contract.xml
vendored
Normal file
@ -0,0 +1,239 @@
|
|||||||
|
<ProcurementDocument>
|
||||||
|
<SchemaVersionUsed>2.5</SchemaVersionUsed>
|
||||||
|
<ProcurementInstrumentForm>DD 1155</ProcurementInstrumentForm>
|
||||||
|
<OriginatorDetails>
|
||||||
|
<InternalDocumentNumber>3244871</InternalDocumentNumber>
|
||||||
|
<DoDSystem>
|
||||||
|
<DITPRNumber>00000431</DITPRNumber>
|
||||||
|
<SystemAdministratorDoDAAC>704331</SystemAdministratorDoDAAC>
|
||||||
|
</DoDSystem>
|
||||||
|
</OriginatorDetails>
|
||||||
|
<AwardInstrument>
|
||||||
|
<ProcurementInstrumentHeader>
|
||||||
|
<ProcurementInstrumentIdentifier>
|
||||||
|
<ProcurementInstrumentOrigin>Department of Defense</ProcurementInstrumentOrigin>
|
||||||
|
<ProcurementInstrumentVehicle>Delivery Order</ProcurementInstrumentVehicle>
|
||||||
|
<NonDoDNumber>70433119F2644</NonDoDNumber>
|
||||||
|
<ProcurementInstrumentDescription>Represented Contract</ProcurementInstrumentDescription>
|
||||||
|
</ProcurementInstrumentIdentifier>
|
||||||
|
<ProcurementInstrumentIdentifier>
|
||||||
|
<ProcurementInstrumentOrigin>Department of Defense</ProcurementInstrumentOrigin>
|
||||||
|
<ProcurementInstrumentVehicle>Basic Ordering Agreement</ProcurementInstrumentVehicle>
|
||||||
|
<NonDoDNumber>W81K0419G0001</NonDoDNumber>
|
||||||
|
<ProcurementInstrumentDescription>Ordering Instrument</ProcurementInstrumentDescription>
|
||||||
|
</ProcurementInstrumentIdentifier>
|
||||||
|
<BasicInformation>
|
||||||
|
<ContingencyContract>false</ContingencyContract>
|
||||||
|
<DocumentPurpose>Original</DocumentPurpose>
|
||||||
|
<EmergencyRequestContract>false</EmergencyRequestContract>
|
||||||
|
<PricingArrangement>
|
||||||
|
<PricingArrangementBase>Firm Fixed Price</PricingArrangementBase>
|
||||||
|
</PricingArrangement>
|
||||||
|
</BasicInformation>
|
||||||
|
<ClauseInformation>
|
||||||
|
<RegulationURL>
|
||||||
|
http://farsite.hill.af.mil/reghtml/regs/far2afmcfars/fardfars/far/52_220.htm#P810_149596
|
||||||
|
</RegulationURL>
|
||||||
|
<ClauseDetails>
|
||||||
|
<RegulationOrSupplement>FAR</RegulationOrSupplement>
|
||||||
|
<ClauseNumber>52.222-50</ClauseNumber>
|
||||||
|
<ClauseTitle>Combating Trafficking in Persons.</ClauseTitle>
|
||||||
|
<ClauseEffectiveDate>2015-05</ClauseEffectiveDate>
|
||||||
|
<ClauseText>
|
||||||
|
<ClauseFullText>
|
||||||
|
[ lots of text ]
|
||||||
|
</ClauseFullText>
|
||||||
|
</ClauseText>
|
||||||
|
<Section>I</Section>
|
||||||
|
</ClauseDetails>
|
||||||
|
<ClauseDetails>
|
||||||
|
<RegulationOrSupplement>FAR</RegulationOrSupplement>
|
||||||
|
<ClauseNumber>52.245-1</ClauseNumber>
|
||||||
|
<ClauseTitle>Government Property.</ClauseTitle>
|
||||||
|
<ClauseEffectiveDate>2012-04</ClauseEffectiveDate>
|
||||||
|
<ClauseText>
|
||||||
|
<ClauseFullText>
|
||||||
|
[ lots of text ]
|
||||||
|
</ClauseFullText>
|
||||||
|
</ClauseText>
|
||||||
|
<Section>I</Section>
|
||||||
|
</ClauseDetails>
|
||||||
|
</ClauseInformation>
|
||||||
|
<ProcurementInstrumentDates>
|
||||||
|
<ProcurementInstrumentEffectiveDate>2016-02-04</ProcurementInstrumentEffectiveDate>
|
||||||
|
<ContractingOfficer>
|
||||||
|
<SignatureDate>2016-01-25</SignatureDate>
|
||||||
|
<SigneeDetails>
|
||||||
|
<Name>DALE WOLFE</Name>
|
||||||
|
<ContactMethod>
|
||||||
|
<MethodDescription>Telephone</MethodDescription>
|
||||||
|
<MethodValue>520-533-9132</MethodValue>
|
||||||
|
</ContactMethod>
|
||||||
|
</SigneeDetails>
|
||||||
|
</ContractingOfficer>
|
||||||
|
</ProcurementInstrumentDates>
|
||||||
|
<ProcurementInstrumentAddresses>
|
||||||
|
<AddressDescription>Contractor</AddressDescription>
|
||||||
|
<Address>
|
||||||
|
<OrganizationID>
|
||||||
|
<Cage>0Z7K0</Cage>
|
||||||
|
<DunsNumber>808152482</DunsNumber>
|
||||||
|
</OrganizationID>
|
||||||
|
<OrganizationNameAddress>
|
||||||
|
<OrganizationName>CACI TECHNOLOGIES, INC</OrganizationName>
|
||||||
|
<OrganizationAddress>
|
||||||
|
<FreeFormAddress>
|
||||||
|
<AddressLine1>6933 Gateway Ct</AddressLine1>
|
||||||
|
<AddressLine2>Manassas VA, 20109</AddressLine2>
|
||||||
|
</FreeFormAddress>
|
||||||
|
</OrganizationAddress>
|
||||||
|
</OrganizationNameAddress>
|
||||||
|
</Address>
|
||||||
|
</ProcurementInstrumentAddresses>
|
||||||
|
<ProcurementInstrumentAddresses>
|
||||||
|
<AddressDescription>Contract Issuing Office</AddressDescription>
|
||||||
|
<Address>
|
||||||
|
<OrganizationID>
|
||||||
|
<DoDAAC>704331</DoDAAC>
|
||||||
|
</OrganizationID>
|
||||||
|
<OrganizationNameAddress>
|
||||||
|
<OrganizationName>FEMA DISTRIBUTION CENTER</OrganizationName>
|
||||||
|
<OrganizationAddress>
|
||||||
|
<FreeFormAddress>
|
||||||
|
<AddressLine1>3870 S. SIDE INDUSTRIAL CTR</AddressLine1>
|
||||||
|
<AddressLine2>ATLANTA GA, 30354</AddressLine2>
|
||||||
|
</FreeFormAddress>
|
||||||
|
</OrganizationAddress>
|
||||||
|
</OrganizationNameAddress>
|
||||||
|
</Address>
|
||||||
|
<Contact>
|
||||||
|
<Name>GENE BARBER</Name>
|
||||||
|
<ContactMethod>
|
||||||
|
<MethodDescription>Telephone</MethodDescription>
|
||||||
|
<MethodValue>(202) 646-2727</MethodValue>
|
||||||
|
</ContactMethod>
|
||||||
|
</Contact>
|
||||||
|
</ProcurementInstrumentAddresses>
|
||||||
|
<ProcurementInstrumentAddresses>
|
||||||
|
<AddressDescription>Contract Administrative Office</AddressDescription>
|
||||||
|
<Address>
|
||||||
|
<OrganizationID>
|
||||||
|
<DoDAAC>704331</DoDAAC>
|
||||||
|
</OrganizationID>
|
||||||
|
<OrganizationNameAddress>
|
||||||
|
<OrganizationName>FEMA DISTRIBUTION CENTER</OrganizationName>
|
||||||
|
<OrganizationAddress>
|
||||||
|
<FreeFormAddress>
|
||||||
|
<AddressLine1>3870 S. SIDE INDUSTRIAL CTR</AddressLine1>
|
||||||
|
<AddressLine2>ATLANTA GA, 30354</AddressLine2>
|
||||||
|
</FreeFormAddress>
|
||||||
|
</OrganizationAddress>
|
||||||
|
</OrganizationNameAddress>
|
||||||
|
</Address>
|
||||||
|
</ProcurementInstrumentAddresses>
|
||||||
|
<ProcurementInstrumentAddresses>
|
||||||
|
<AddressDescription>Paying Office</AddressDescription>
|
||||||
|
<Address>
|
||||||
|
<OrganizationID>
|
||||||
|
<DoDAAC>HQ0131</DoDAAC>
|
||||||
|
</OrganizationID>
|
||||||
|
<OrganizationNameAddress>
|
||||||
|
<OrganizationName>DEFENSE FINANCE AND ACCOUNTING SVC</OrganizationName>
|
||||||
|
<OrganizationAddress>
|
||||||
|
<FreeFormAddress>
|
||||||
|
<AddressLine1>P.O. BOX 369016</AddressLine1>
|
||||||
|
<AddressLine2>COLUMBUS OH, 43236</AddressLine2>
|
||||||
|
</FreeFormAddress>
|
||||||
|
</OrganizationAddress>
|
||||||
|
</OrganizationNameAddress>
|
||||||
|
</Address>
|
||||||
|
</ProcurementInstrumentAddresses>
|
||||||
|
<ProcurementInstrumentAddresses>
|
||||||
|
<AddressDescription>Ship To</AddressDescription>
|
||||||
|
<Address>
|
||||||
|
<OrganizationID>
|
||||||
|
<DoDAAC>S0302A</DoDAAC>
|
||||||
|
</OrganizationID>
|
||||||
|
<OrganizationNameAddress>
|
||||||
|
<OrganizationName>DCMA PHOENIX</OrganizationName>
|
||||||
|
<OrganizationAddress>
|
||||||
|
<FreeFormAddress>
|
||||||
|
<AddressLine1>40 NORTH CENTRAL AVE, STE 400</AddressLine1>
|
||||||
|
<AddressLine2>TWO RENAISSANCE SQUARE</AddressLine2>
|
||||||
|
<AddressLine3>PHOENIX AZ, 85004</AddressLine3>
|
||||||
|
</FreeFormAddress>
|
||||||
|
</OrganizationAddress>
|
||||||
|
</OrganizationNameAddress>
|
||||||
|
</Address>
|
||||||
|
</ProcurementInstrumentAddresses>
|
||||||
|
<ProcurementInstrumentAmounts>
|
||||||
|
<OtherAmounts>
|
||||||
|
<AmountDescription>Header Only - Total Contract Value</AmountDescription>
|
||||||
|
<Amount>192000.00</Amount>
|
||||||
|
</OtherAmounts>
|
||||||
|
</ProcurementInstrumentAmounts>
|
||||||
|
<DeliveryDetails>
|
||||||
|
<DeliveryDates>
|
||||||
|
<DeliveryDescription>Delivery Requested By</DeliveryDescription>
|
||||||
|
<DeliveryDate>
|
||||||
|
<DateElement>2016-01-16</DateElement>
|
||||||
|
</DeliveryDate>
|
||||||
|
</DeliveryDates>
|
||||||
|
</DeliveryDetails>
|
||||||
|
<ReferenceNumber>
|
||||||
|
<ReferenceDescription>
|
||||||
|
Defense Priorities Allocation System (DPAS) Priority Rating
|
||||||
|
</ReferenceDescription>
|
||||||
|
<ReferenceValue>DO-A7</ReferenceValue>
|
||||||
|
<Section>A</Section>
|
||||||
|
</ReferenceNumber>
|
||||||
|
<Shipping>
|
||||||
|
<FoBDetails>
|
||||||
|
<PaymentMethod>Contractor</PaymentMethod>
|
||||||
|
<FoBPoint>Origin (after Loading)</FoBPoint>
|
||||||
|
</FoBDetails>
|
||||||
|
</Shipping>
|
||||||
|
</ProcurementInstrumentHeader>
|
||||||
|
<ContractLineItems>
|
||||||
|
<LineItems>
|
||||||
|
<LineItemIdentifier>
|
||||||
|
<DFARS>
|
||||||
|
<LineItem>
|
||||||
|
<LineItemType>CLIN</LineItemType>
|
||||||
|
<LineItemBase>0001</LineItemBase>
|
||||||
|
</LineItem>
|
||||||
|
</DFARS>
|
||||||
|
</LineItemIdentifier>
|
||||||
|
<LineItemBasicInformation>
|
||||||
|
<OptionLineItem>false</OptionLineItem>
|
||||||
|
<PricingArrangement>
|
||||||
|
<PricingArrangementBase>Cost No Fee</PricingArrangementBase>
|
||||||
|
</PricingArrangement>
|
||||||
|
<ProductServicesOrdered>
|
||||||
|
<ProductOrService>Real Property</ProductOrService>
|
||||||
|
<ProductServiceDescription>Radio Dishes</ProductServiceDescription>
|
||||||
|
<Quantity>3</Quantity>
|
||||||
|
<ItemUIDRequired>false</ItemUIDRequired>
|
||||||
|
<PriceBasis>Estimated</PriceBasis>
|
||||||
|
<UnitOfMeasure>Each</UnitOfMeasure>
|
||||||
|
<UnitPrice>64000.00</UnitPrice>
|
||||||
|
<ProductServiceData>
|
||||||
|
<DataDescription>Manufacturer's Part Number</DataDescription>
|
||||||
|
<DataValue>5L33M7730291DX081</DataValue>
|
||||||
|
</ProductServiceData>
|
||||||
|
</ProductServicesOrdered>
|
||||||
|
</LineItemBasicInformation>
|
||||||
|
<LineItemAmounts>
|
||||||
|
<ItemOtherAmounts>
|
||||||
|
<AmountDescription>Estimated Cost</AmountDescription>
|
||||||
|
<Amount>192000.00</Amount>
|
||||||
|
</ItemOtherAmounts>
|
||||||
|
<ItemOtherAmounts>
|
||||||
|
<AmountDescription>Not to Exceed Amount (Funding)</AmountDescription>
|
||||||
|
<Amount>200000.00</Amount>
|
||||||
|
</ItemOtherAmounts>
|
||||||
|
</LineItemAmounts>
|
||||||
|
</LineItems>
|
||||||
|
</ContractLineItems>
|
||||||
|
</AwardInstrument>
|
||||||
|
</ProcurementDocument>
|
@ -1,20 +1,27 @@
|
|||||||
from atst.eda_client import MockEDAClient
|
from atst.eda_client import MockEDAClient, parse_eda_xml
|
||||||
|
|
||||||
|
|
||||||
client = MockEDAClient()
|
mock_client = MockEDAClient()
|
||||||
|
|
||||||
|
|
||||||
def test_list_contracts():
|
def test_list_contracts():
|
||||||
results = client.list_contracts()
|
results = mock_client.list_contracts()
|
||||||
assert len(results) == 3
|
assert len(results) == 3
|
||||||
|
|
||||||
|
|
||||||
def test_get_contract():
|
def test_get_contract():
|
||||||
result = client.get_contract("DCA10096D0052", "y")
|
result = mock_client.get_contract("DCA10096D0052", "y")
|
||||||
assert result["contract_no"] == "DCA10096D0052"
|
assert result["contract_no"] == "DCA10096D0052"
|
||||||
assert result["amount"] == 2_000_000
|
assert result["amount"] == 2_000_000
|
||||||
|
|
||||||
|
|
||||||
def test_contract_not_found():
|
def test_contract_not_found():
|
||||||
result = client.get_contract("abc", "y")
|
result = mock_client.get_contract("abc", "y")
|
||||||
assert result is None
|
assert result is None
|
||||||
|
|
||||||
|
|
||||||
|
def test_eda_xml_parser():
|
||||||
|
with open("tests/fixtures/eda_contract.xml") as contract:
|
||||||
|
eda_data = parse_eda_xml(contract.read())
|
||||||
|
assert eda_data["clin_0001"] == 200000.00
|
||||||
|
assert not eda_data["clin_0003"]
|
||||||
|
Loading…
x
Reference in New Issue
Block a user