def test_year_period_to_dates(): """ Test successful conversions from quarter to dates """ # Test year/period that has dates in the same year start, end = year_period_to_dates(2017, 4) assert start == '01/01/2017' assert end == '01/31/2017' # Test year/period that has dates in the previous year start, end = year_period_to_dates(2017, 2) assert start == '11/01/2016' assert end == '11/30/2016'
def test_year_period_to_dates_year_failure(): error_text = 'Year must be in YYYY format.' # Test null year with pytest.raises(ResponseException) as resp_except: year_period_to_dates(None, 2) assert resp_except.value.status == 400 assert str(resp_except.value) == error_text # Test invalid year with pytest.raises(ResponseException) as resp_except: year_period_to_dates(999, 2) assert resp_except.value.status == 400 assert str(resp_except.value) == error_text
def test_year_period_to_dates_period_failure(): """ Test invalid quarter formats """ error_text = 'Period must be an integer 2-12.' # Test period that's too high with pytest.raises(ResponseException) as resp_except: year_period_to_dates(2017, 13) assert resp_except.value.status == 400 assert str(resp_except.value) == error_text # Test period that's too low with pytest.raises(ResponseException) as resp_except: year_period_to_dates(2017, 1) assert resp_except.value.status == 400 assert str(resp_except.value) == error_text # Test null period with pytest.raises(ResponseException) as resp_except: year_period_to_dates(2017, None) assert resp_except.value.status == 400 assert str(resp_except.value) == error_text
def generate_detached_file(file_type, cgac_code, frec_code, start_date, end_date, year, period, agency_type, file_format): """ Start a file generation job for the specified file type not connected to a submission Args: file_type: type of file to be generated cgac_code: the code of a CGAC agency if generating for a CGAC agency frec_code: the code of a FREC agency if generating for a FREC agency start_date: start date in a string, formatted MM/DD/YYYY end_date: end date in a string, formatted MM/DD/YYYY year: year to generate for, integer 4 digits period: period to generate for, integer (2-12) agency_type: The type of agency (awarding or funding) to generate the file for file_format: determines if the file generated is a txt or a csv (only used for D file generation) Returns: JSONResponse object with keys job_id, status, file_type, url, message, start_date, and end_date. Raises: ResponseException: if the start_date and end_date Strings cannot be parsed into dates """ # Make sure it's a valid request if not cgac_code and not frec_code: return JsonResponse.error( ValueError( "Detached file generation requires CGAC or FR Entity Code"), StatusCode.CLIENT_ERROR) if file_type in ['D1', 'D2']: # Make sure we have a start and end date for D1/D2 generation if not start_date or not end_date: return JsonResponse.error( ValueError( 'Must have a start and end date for D file generation.'), StatusCode.CLIENT_ERROR) # Check if date format is MM/DD/YYYY if not (StringCleaner.is_date(start_date) and StringCleaner.is_date(end_date)): raise ResponseException( 'Start or end date cannot be parsed into a date', StatusCode.CLIENT_ERROR) if agency_type not in ['awarding', 'funding']: return JsonResponse.error( ValueError('agency_type must be either awarding or funding.'), StatusCode.CLIENT_ERROR) if file_format not in ['csv', 'txt']: return JsonResponse.error( ValueError('file_format must be either csv or txt.'), StatusCode.CLIENT_ERROR) else: # Make sure both year and period are provided if not (year and period): return JsonResponse.error( ValueError( "Must have a year and period for A file generation."), StatusCode.CLIENT_ERROR) try: # Convert to real start and end dates start_date, end_date = generic_helper.year_period_to_dates( year, period) except ResponseException as e: return JsonResponse.error(e, StatusCode.CLIENT_ERROR) # Add job info file_type_name = lookups.FILE_TYPE_DICT_LETTER_NAME[file_type] new_job = generation_helper.create_generation_job(file_type_name, start_date, end_date) agency_code = frec_code if frec_code else cgac_code logger.info({ 'message': 'Starting detached {} file generation'.format(file_type), 'message_type': 'BrokerInfo', 'job_id': new_job.job_id, 'file_type': file_type, 'agency_code': agency_code, 'start_date': start_date, 'end_date': end_date }) try: if file_type in ['D1', 'D2']: generation_helper.start_d_generation(new_job, start_date, end_date, agency_type, agency_code=agency_code, file_format=file_format) else: generation_helper.start_a_generation(new_job, start_date, end_date, agency_code) except Exception as e: mark_job_status(new_job.job_id, 'failed') new_job.error_message = str(e) GlobalDB.db().session.commit() return JsonResponse.error(e, StatusCode.INTERNAL_ERROR) # Return same response as check generation route return check_detached_generation(new_job.job_id)
def generate_detached_file(file_type, cgac_code, frec_code, start_date, end_date, year, period, agency_type): """ Start a file generation job for the specified file type not connected to a submission Args: file_type: type of file to be generated cgac_code: the code of a CGAC agency if generating for a CGAC agency frec_code: the code of a FREC agency if generating for a FREC agency start_date: start date in a string, formatted MM/DD/YYYY end_date: end date in a string, formatted MM/DD/YYYY year: year to generate for, integer 4 digits period: period to generate for, integer (2-12) agency_type: The type of agency (awarding or funding) to generate the file for Returns: JSONResponse object with keys job_id, status, file_type, url, message, start_date, and end_date. Raises: ResponseException: if the start_date and end_date Strings cannot be parsed into dates """ # Make sure it's a valid request if not cgac_code and not frec_code: return JsonResponse.error(ValueError("Detached file generation requires CGAC or FR Entity Code"), StatusCode.CLIENT_ERROR) if file_type in ['D1', 'D2']: # Make sure we have a start and end date for D1/D2 generation if not start_date or not end_date: return JsonResponse.error(ValueError("Must have a start and end date for D file generation."), StatusCode.CLIENT_ERROR) # Check if date format is MM/DD/YYYY if not (StringCleaner.is_date(start_date) and StringCleaner.is_date(end_date)): raise ResponseException('Start or end date cannot be parsed into a date', StatusCode.CLIENT_ERROR) if agency_type not in ('awarding', 'funding'): return JsonResponse.error(ValueError("agency_type must be either awarding or funding."), StatusCode.CLIENT_ERROR) else: # Make sure both year and period are provided if not (year and period): return JsonResponse.error(ValueError("Must have a year and period for A file generation."), StatusCode.CLIENT_ERROR) try: # Convert to real start and end dates start_date, end_date = generic_helper.year_period_to_dates(year, period) except ResponseException as e: return JsonResponse.error(e, StatusCode.CLIENT_ERROR) # Add job info file_type_name = lookups.FILE_TYPE_DICT_LETTER_NAME[file_type] new_job = generation_helper.create_generation_job(file_type_name, start_date, end_date) agency_code = frec_code if frec_code else cgac_code logger.info({'message': 'Starting detached {} file generation'.format(file_type), 'message_type': 'BrokerInfo', 'job_id': new_job.job_id, 'file_type': file_type, 'agency_code': agency_code, 'start_date': start_date, 'end_date': end_date}) try: if file_type in ['D1', 'D2']: generation_helper.start_d_generation(new_job, start_date, end_date, agency_type, agency_code=agency_code) else: generation_helper.start_a_generation(new_job, start_date, end_date, agency_code) except Exception as e: mark_job_status(new_job.job_id, 'failed') new_job.error_message = str(e) GlobalDB.db().session.commit() return JsonResponse.error(e, StatusCode.INTERNAL_ERROR) # Return same response as check generation route return check_detached_generation(new_job.job_id)