def __get_new_due_date(self, days=None, date=None): assert days is not None or date is not None if days is None: new_due_date = process_due_date(local_to_utc(date, self.__tz_name)) else: new_due_date = get_due_date( utc_to_local(self.request.due_date, self.__tz_name), days, self.__tz_name) return new_due_date
def test_extend_days(self): days = 20 reason = "Reasonable reasoning for the rational reasoner." due_date = get_due_date( utc_to_local( self.request.due_date, self.tz_name ), days, self.tz_name ) response = self.request.extend(reason=reason, days=days) self.__test_extension(response, determination_type.EXTENSION, reason, due_date)
def test_acknowledge_days(self): days = 30 info = "Informative information that will inform you." due_date = get_due_date( utc_to_local( self.request.due_date, self.tz_name ), days, self.tz_name ) response = self.request.acknowledge(info=info, days=days) self.__test_extension(response, determination_type.ACKNOWLEDGMENT, info, due_date)
def create_requests_search_set(requester, other_requester): """ Generate 216 unique requests. Every combination of title content, description content, agency description content, title privacy, agency description privacy, and requester is guaranteed to be unique. """ agency_eins = [ ein[0] for ein in Agencies.query.with_entities(Agencies.ein).all() ] for title_private, agency_request_summary_private, is_requester in product( range(2), repeat=3): for title, description, agency_request_summary in product( ("foo", "bar", "qux"), repeat=3): agency_ein = random.choice(agency_eins) date_created = get_random_date(datetime(2015, 1, 1), datetime(2016, 1, 1)) date_submitted = get_following_date(date_created) # TODO: use rf = RequestsFactory() request = Requests(generate_request_id(agency_ein), title=title, description=description, agency_ein=agency_ein, date_created=date_created, date_submitted=date_submitted, due_date=get_due_date(date_submitted, ACKNOWLEDGMENT_DAYS_DUE, 'US/Eastern'), submission=submission_methods.DIRECT_INPUT, status=random.choice( (request_status.OPEN, request_status.CLOSED, request_status.OVERDUE, request_status.IN_PROGRESS, request_status.DUE_SOON)), privacy={ 'title': bool(title_private), 'agency_request_summary': bool(agency_request_summary_private) }) request.agency_request_summary = agency_request_summary create_object(request) user_request = UserRequests( user_guid=(requester.guid if is_requester else other_requester.guid), auth_user_type=(requester.auth_user_type if is_requester else other_requester.auth_user_type), request_id=request.id, request_user_type=user_type_request.REQUESTER, permissions=11) create_object(user_request)
def __init__(self, request_id=None, clean=True): """ :param request_id: request FOIL id :param clean: reset data? """ self.clean = clean date_created = datetime.utcnow() date_submitted = get_following_date(date_created) agency_ein = '0860' self.request = Requests( request_id or generate_request_id(agency_ein), title="I would like my vital essence.", description="Someone has taken my vital essence " "and I would like it back.", agency_ein=agency_ein, date_created=date_created, date_submitted=date_submitted, due_date=get_due_date(date_submitted, ACKNOWLEDGMENT_DAYS_DUE), submission=submission_methods.DIRECT_INPUT, status=request_status.OPEN) create_object(self.request) self.requester = Users( guid=generate_user_guid(user_type_auth.PUBLIC_USER_NYC_ID), auth_user_type=user_type_auth.PUBLIC_USER_NYC_ID, agency_ein=agency_ein, first_name='Jane', last_name='Doe', email='*****@*****.**', email_validated=True, terms_of_use_accepted=True, title='The Janest') create_object(self.requester) self.user_request = UserRequests( user_guid=self.requester.guid, auth_user_type=self.requester.auth_user_type, request_id=self.request.id, request_user_type=user_type_request.REQUESTER, permissions=Roles.query.filter_by( name=PUBLIC_REQUESTER).first().permissions) create_object(self.user_request)
def create_request(title, description, category, tz_name, agency_ein=None, first_name=None, last_name=None, submission=DIRECT_INPUT, agency_date_submitted_local=None, email=None, user_title=None, organization=None, phone=None, fax=None, address=None, upload_path=None, custom_metadata=None): """ Creates a new FOIL Request and associated Users, UserRequests, and Events. :param title: request title :param description: detailed description of the request :param tz_name: client's timezone name :param agency_ein: agency_ein selected for the request :param first_name: first name of the requester :param last_name: last name of the requester :param submission: request submission method :param agency_date_submitted_local: submission date chosen by agency :param email: requester's email address :param user_title: requester's organizational title :param organization: requester's organization :param phone: requester's phone number :param fax: requester's fax number :param address: requester's mailing address :param upload_path: file path of the validated upload :param custom_metadata: JSON containing all data from custom request forms """ # 1. Generate the request id request_id = generate_request_id(agency_ein) # 2a. Generate Email Notification Text for Agency # agency_email = generate_email_template('agency_acknowledgment.html', request_id=request_id) # 2b. Generate Email Notification Text for Requester # 3a. Send Email Notification Text for Agency # 3b. Send Email Notification Text for Requester # 4a. Calculate Request Submitted Date (Round to next business day) date_created_local = utc_to_local(datetime.utcnow(), tz_name) if current_user.is_agency: date_submitted_local = agency_date_submitted_local else: date_submitted_local = date_created_local # 4b. Calculate Request Due Date (month day year but time is always 5PM, 5 Days after submitted date) due_date = get_due_date(date_submitted_local, ACKNOWLEDGMENT_PERIOD_LENGTH, tz_name) date_created = local_to_utc(date_created_local, tz_name) date_submitted = local_to_utc(date_submitted_local, tz_name) # 5. Create Request request = Requests(id=request_id, title=title, agency_ein=agency_ein, category=category, description=description, date_created=date_created, date_submitted=date_submitted, due_date=due_date, submission=submission, custom_metadata=custom_metadata) create_object(request) guid_for_event = current_user.guid if not current_user.is_anonymous else None # 6. Get or Create User if current_user.is_public: user = current_user else: user = Users(guid=generate_guid(), email=email, first_name=first_name, last_name=last_name, title=user_title or None, organization=organization or None, email_validated=False, terms_of_use_accepted=False, phone_number=phone, fax_number=fax, mailing_address=address, is_anonymous_requester=True) create_object(user) # user created event create_object( Events(request_id, guid_for_event, event_type.USER_CREATED, previous_value=None, new_value=user.val_for_events, response_id=None, timestamp=datetime.utcnow())) if upload_path is not None: # 7. Move file to upload directory upload_path = _move_validated_upload(request_id, upload_path) # 8. Create response object filename = os.path.basename(upload_path) response = Files(request_id, RELEASE_AND_PRIVATE, filename, filename, fu.get_mime_type(upload_path), fu.getsize(upload_path), fu.get_hash(upload_path), is_editable=False) create_object(obj=response) # 8. Create upload Event upload_event = Events(user_guid=user.guid, response_id=response.id, request_id=request_id, type_=event_type.FILE_ADDED, timestamp=datetime.utcnow(), new_value=response.val_for_events) create_object(upload_event) # Create response token if requester is anonymous if current_user.is_anonymous or current_user.is_agency: create_object(ResponseTokens(response.id)) role_to_user = { role.PUBLIC_REQUESTER: user.is_public, role.ANONYMOUS: user.is_anonymous_requester, } role_name = [k for (k, v) in role_to_user.items() if v][0] # (key for "truthy" value) # 9. Create Event timestamp = datetime.utcnow() event = Events(user_guid=user.guid if current_user.is_anonymous else current_user.guid, request_id=request_id, type_=event_type.REQ_CREATED, timestamp=timestamp, new_value=request.val_for_events) create_object(event) if current_user.is_agency: agency_event = Events(user_guid=current_user.guid, request_id=request.id, type_=event_type.AGENCY_REQ_CREATED, timestamp=timestamp) create_object(agency_event) # 10. Create UserRequest for requester user_request = UserRequests( user_guid=user.guid, request_user_type=user_type_request.REQUESTER, request_id=request_id, permissions=Roles.query.filter_by(name=role_name).first().permissions) create_object(user_request) create_object( Events(request_id, guid_for_event, event_type.USER_ADDED, previous_value=None, new_value=user_request.val_for_events, response_id=None, timestamp=datetime.utcnow())) # 11. Create the elasticsearch request doc only if agency has been onboarded agency = Agencies.query.filter_by(ein=agency_ein).one() # 12. Add all agency administrators to the request. if agency.administrators: # b. Store all agency users objects in the UserRequests table as Agency users with Agency Administrator # privileges _create_agency_user_requests(request_id=request_id, agency_admins=agency.administrators, guid_for_event=guid_for_event) # 13. Add all parent agency administrators to the request. if agency != agency.parent: if (agency.parent.agency_features is not None and agency_ein in agency.parent.agency_features.get( 'monitor_agency_requests', []) and agency.parent.is_active and agency.parent.administrators): _create_agency_user_requests( request_id=request_id, agency_admins=agency.parent.administrators, guid_for_event=guid_for_event) # (Now that we can associate the request with its requester AND agency users.) if current_app.config['ELASTICSEARCH_ENABLED'] and agency.is_active: request.es_create() return request_id
def __assert_request_data_correct(self, user, request, agency_parent_ein, default=False, title=None, description=None, agency_request_summary=None, agency_ein=None, date_created=None, due_date=None, category='All', title_privacy=True, agency_request_summary_privacy=True, submission=None, status=request_status.OPEN): request = Requests.query.get(request.id) privacy = {"title": title_privacy, "agency_request_summary": agency_request_summary_privacy} agency_ein = agency_ein or user.agency_ein or request.agency_ein date_created_local = utc_to_local(date_created or request.date_created, self.tz_name) date_submitted_local = get_following_date(date_created_local) if default: self.assertTrue(request.submission in submission_methods.ALL) request_list = [ type(request.title), type(request.description), ] check_list = [ str, str, ] else: request_list = [ request.title, request.description, request.agency_request_summary, request.date_created, request.submission, ] check_list = [ title, description, agency_request_summary, date_created, submission, ] request_list += [ request.id, request.category, request.privacy, request.agency_ein, request.status, request.date_submitted, request.due_date, ] check_list += [ "FOIL-{}-{}-00001".format(datetime.today().year, agency_parent_ein), category, privacy, agency_ein, status, local_to_utc(date_submitted_local, self.tz_name), due_date or get_due_date(date_submitted_local, ACKNOWLEDGMENT_DAYS_DUE, self.tz_name) ] self.assertEqual(request_list, check_list) # check associated events event_req_created = Events.query.filter_by(type=event_type.REQ_CREATED).one() self.assertEqual( [ event_req_created.user_guid, event_req_created.auth_user_type, event_req_created.request_id, event_req_created.response_id, event_req_created.previous_value, event_req_created.new_value, ], [ user.guid, user.auth_user_type, request.id, None, # response_id None, # previous_value request.val_for_events # new_value ] ) if user.is_agency: event_agency_req_created = Events.query.filter_by(type=event_type.AGENCY_REQ_CREATED).one() self.assertEqual( [ event_agency_req_created.user_guid, event_agency_req_created.auth_user_type, event_agency_req_created.request_id, event_agency_req_created.response_id, event_agency_req_created.previous_value, event_agency_req_created.new_value, ], [ user.guid, user.auth_user_type, request.id, None, # response_id None, # previous_value None, # new_value ] )
def create_request( self, user, title=None, description=None, agency_request_summary=None, # TODO: agency_request_summary_release_date agency_ein=None, date_created=None, date_submitted=None, due_date=None, category=None, title_privacy=True, agency_request_summary_privacy=True, submission=None, status=request_status.OPEN, tz_name=current_app.config["APP_TIMEZONE"]): """ Create a request as the supplied user. An anonymous requester will be created if the supplied user is an agency user. :rtype: RequestWrapper """ # check due date if (date_created is not None or date_submitted is not None) and due_date is not None: def assert_date(date, date_var_str): assert ( due_date - date ).days >= 1, "due_date must be at least 1 day after " + date_var_str if date_created is not None: assert_date(date_created, "date_created") if date_submitted is not None: assert_date(date_submitted, "date_submitted") # check agency_ein if (agency_ein is not None or self.agency_ein is not None) \ and user.auth_user_type == user_type_auth.AGENCY_USER: assert (agency_ein or self.agency_ein) == user.agency_ein, \ "user's agency ein must match supplied agency ein" agency_ein = agency_ein or self.agency_ein or user.agency_ein or get_random_agency( ).ein # create dates date_created_local = utc_to_local(date_created or datetime.utcnow(), tz_name) date_submitted_local = date_submitted or get_following_date( date_created_local) due_date = due_date or get_due_date(date_submitted_local, ACKNOWLEDGMENT_DAYS_DUE, tz_name) date_created = date_created or local_to_utc(date_created_local, tz_name) date_submitted = date_submitted or local_to_utc( date_submitted_local, tz_name) # create request request = Requests( generate_request_id(agency_ein), title or fake.title(), description or fake.description(), agency_ein=agency_ein, date_created=date_created or datetime.utcnow(), date_submitted=date_submitted, due_date=due_date, category=category, privacy={ "title": title_privacy, "agency_request_summary": agency_request_summary_privacy }, submission=submission or random.choice(submission_methods.ALL), status=status, ) if agency_request_summary is not None: request.agency_request_summary = agency_request_summary if agency_request_summary_privacy is not None: request.agency_request_summary_release_date = calendar.addbusdays( datetime.utcnow(), RELEASE_PUBLIC_DAYS ) if not agency_request_summary_privacy else None create_object(request) request = RequestWrapper(request, self.agency_user) # create events timestamp = datetime.utcnow() create_object( Events(user_guid=user.guid, auth_user_type=user.auth_user_type, request_id=request.id, type_=event_type.REQ_CREATED, timestamp=timestamp, new_value=request.val_for_events)) if user.is_agency: create_object( Events(user_guid=user.guid, auth_user_type=user.auth_user_type, request_id=request.id, type_=event_type.AGENCY_REQ_CREATED, timestamp=timestamp)) # add users if user.is_public or user.is_anonymous_requester: request.add_user(user) if user.is_agency: # then create and add anonymous requester request.add_user(self.__uf.create_anonymous_user()) for admin in Agencies.query.filter_by( ein=agency_ein).one().administrators: request.add_user(admin) # create request doc now that requester is set request.es_create() return request
def create_request(title, description, category, tz_name, agency_ein=None, first_name=None, last_name=None, submission=DIRECT_INPUT, agency_date_submitted_local=None, email=None, user_title=None, organization=None, phone=None, fax=None, address=None, upload_path=None, custom_metadata=None): """ Creates a new FOIL Request and associated Users, UserRequests, and Events. :param title: request title :param description: detailed description of the request :param tz_name: client's timezone name :param agency_ein: agency_ein selected for the request :param first_name: first name of the requester :param last_name: last name of the requester :param submission: request submission method :param agency_date_submitted_local: submission date chosen by agency :param email: requester's email address :param user_title: requester's organizational title :param organization: requester's organization :param phone: requester's phone number :param fax: requester's fax number :param address: requester's mailing address :param upload_path: file path of the validated upload :param custom_metadata: JSON containing all data from custom request forms """ # 1. Generate the request id request_id = generate_request_id(agency_ein) # 2a. Generate Email Notification Text for Agency # agency_email = generate_email_template('agency_acknowledgment.html', request_id=request_id) # 2b. Generate Email Notification Text for Requester # 3a. Send Email Notification Text for Agency # 3b. Send Email Notification Text for Requester # 4a. Calculate Request Submitted Date (Round to next business day) date_created_local = utc_to_local(datetime.utcnow(), tz_name) if current_user.is_agency: date_submitted_local = agency_date_submitted_local else: date_submitted_local = date_created_local # 4b. Calculate Request Due Date (month day year but time is always 5PM, 5 Days after submitted date) due_date = get_due_date( date_submitted_local, ACKNOWLEDGMENT_PERIOD_LENGTH, tz_name) date_created = local_to_utc(date_created_local, tz_name) date_submitted = local_to_utc(date_submitted_local, tz_name) # 5. Create Request request = Requests( id=request_id, title=title, agency_ein=agency_ein, category=category, description=description, date_created=date_created, date_submitted=date_submitted, due_date=due_date, submission=submission, custom_metadata=custom_metadata ) create_object(request) guid_for_event = current_user.guid if not current_user.is_anonymous else None # 6. Get or Create User if current_user.is_public: user = current_user else: user = Users( guid=generate_guid(), email=email, first_name=first_name, last_name=last_name, title=user_title or None, organization=organization or None, email_validated=False, terms_of_use_accepted=False, phone_number=phone, fax_number=fax, mailing_address=address, is_anonymous_requester=True ) create_object(user) # user created event create_object(Events( request_id, guid_for_event, event_type.USER_CREATED, previous_value=None, new_value=user.val_for_events, response_id=None, timestamp=datetime.utcnow() )) if upload_path is not None: # 7. Move file to upload directory upload_path = _move_validated_upload(request_id, upload_path) # 8. Create response object filename = os.path.basename(upload_path) response = Files(request_id, RELEASE_AND_PRIVATE, filename, filename, fu.get_mime_type(upload_path), fu.getsize(upload_path), fu.get_hash(upload_path), is_editable=False) create_object(obj=response) # 8. Create upload Event upload_event = Events(user_guid=user.guid, response_id=response.id, request_id=request_id, type_=event_type.FILE_ADDED, timestamp=datetime.utcnow(), new_value=response.val_for_events) create_object(upload_event) # Create response token if requester is anonymous if current_user.is_anonymous or current_user.is_agency: create_object(ResponseTokens(response.id)) role_to_user = { role.PUBLIC_REQUESTER: user.is_public, role.ANONYMOUS: user.is_anonymous_requester, } role_name = [k for (k, v) in role_to_user.items() if v][0] # (key for "truthy" value) # 9. Create Event timestamp = datetime.utcnow() event = Events(user_guid=user.guid if current_user.is_anonymous else current_user.guid, request_id=request_id, type_=event_type.REQ_CREATED, timestamp=timestamp, new_value=request.val_for_events) create_object(event) if current_user.is_agency: agency_event = Events(user_guid=current_user.guid, request_id=request.id, type_=event_type.AGENCY_REQ_CREATED, timestamp=timestamp) create_object(agency_event) # 10. Create UserRequest for requester user_request = UserRequests(user_guid=user.guid, request_user_type=user_type_request.REQUESTER, request_id=request_id, permissions=Roles.query.filter_by( name=role_name).first().permissions) create_object(user_request) create_object(Events( request_id, guid_for_event, event_type.USER_ADDED, previous_value=None, new_value=user_request.val_for_events, response_id=None, timestamp=datetime.utcnow() )) # 11. Create the elasticsearch request doc only if agency has been onboarded agency = Agencies.query.filter_by(ein=agency_ein).one() # 12. Add all agency administrators to the request. if agency.administrators: # b. Store all agency users objects in the UserRequests table as Agency users with Agency Administrator # privileges _create_agency_user_requests(request_id=request_id, agency_admins=agency.administrators, guid_for_event=guid_for_event) # 13. Add all parent agency administrators to the request. if agency != agency.parent: if ( agency.parent.agency_features is not None and agency_ein in agency.parent.agency_features.get('monitor_agency_requests', []) and agency.parent.is_active and agency.parent.administrators ): _create_agency_user_requests(request_id=request_id, agency_admins=agency.parent.administrators, guid_for_event=guid_for_event) # (Now that we can associate the request with its requester AND agency users.) if current_app.config['ELASTICSEARCH_ENABLED'] and agency.is_active: request.es_create() return request_id