def create_contact_record(request, first_name, last_name, email, subject, message): """ Creates Users, Emails, and Events entries for a contact submission for a request. Sends email with message to all agency users associated with the request. :param request: request object :param first_name: sender's first name :param last_name: sender's last name :param email: sender's email :param subject: subject of email :param message: email body """ if current_user == request.requester: user = current_user else: user = Users(guid=generate_guid(), email=email, first_name=first_name, last_name=last_name, email_validated=False, terms_of_use_accepted=False, is_anonymous_requester=True) create_object(user) create_object( Events(request_id=request.id, user_guid=None, type_=event_type.USER_CREATED, new_value=user.val_for_events)) body = "Name: {} {}\n\nEmail: {}\n\nSubject: {}\n\nMessage:\n{}".format( first_name, last_name, email, subject, message) agency_emails = get_assigned_users_emails(request.id) email_obj = Emails(request.id, PRIVATE, to=','.join([ email.replace('{', '').replace('}', '') for email in agency_emails ]), cc=None, bcc=None, subject=subject, body=body) create_object(email_obj) create_object( Events(request_id=request.id, user_guid=user.guid, type_=event_type.CONTACT_EMAIL_SENT, response_id=email_obj.id, new_value=email_obj.val_for_events)) send_contact_email(subject, agency_emails, message, email)
def create(): """a route to handle creating an event""" event_details = request.get_json() check_details = validate_data(event_details) check_date = validate_date(event_details['event_date']) #check if the data was confirmed valid if check_details is not "valid": return jsonify({"message" : check_details}), 400 elif check_date is not "valid": return jsonify({"message" : check_date}), 400 else: name = event_details['name'] description = event_details['description'] category = event_details['category'] location = event_details['location'] event_date = event_details['event_date'] created_by = g.user #check if the user has an event with a similar name and location existing_event = [event for event in g.user.events if event.name == name \ and event.location == location] if not existing_event: #create the event if does not exist event = Events(name=name, description=description, category=category, \ location=location, event_date=event_date, created_by=created_by) event.save() res = event.to_json() return jsonify(res), 201 return jsonify({"message" : "you have a similar event in the same location"}), 302
def create_user_request_event_object(events_type, user_request, old_permissions=None, old_point_of_contact=None, user=current_user): """ Create an Event for the addition, removal, or updating of a UserRequest and insert into the database. Args: events_type (str): event type from the constants defined in constants.event_type. user_request (UserRequests): UserRequests object. old_permissions (int): Value of permissions for the request. user (Users): Users object that represents the user performing the user_request modification Returns: Events: The event object representing the change made to the user. """ previous_value = {'user_guid': user_request.user_guid} if old_permissions is not None: previous_value['permissions'] = old_permissions if old_point_of_contact is not None: previous_value['point_of_contact'] = old_point_of_contact return Events( user_request.request_id, user.guid, events_type, previous_value=previous_value, new_value=user_request.val_for_events, timestamp=datetime.utcnow(), )
def create_event(): form = EventForm() form.artistName.choices = [(artist1.id, artist1.name) for artist1 in Artist.query.all()] form.venueName.choices = [(venue.id, venue.location) for venue in Venues.query.all()] if form.validate_on_submit(): venue = Venues.query.filter_by(id=form.venueName.data).first() names = form.artistName.data flash('Venue = {}'.format(venue)) nameList = [] for i in range(len(names)): nameList.append(names[i]) flash(' Name List{}'.format(nameList[i])) event1 = Events(name=form.eventName.data, price='S400', venue_id=venue.id, event_date=form.eventDate.data) db.session.add(event1) db.session.commit() for a in range(len(nameList)): value = nameList[a] a2e = ArtistToEvent(Artist_id=value, Event_id=event1.id) db.session.add(a2e) db.session.commit() return render_template('create_event.html', form=form)
def update_status(suborder: Suborders, comment: str, new_status: str): """Updates the status of a row from the Suborders table. Args: suborder: A Suborders instance. comment: Any additional information about the updating of the status. new_status: The value of the status to be updated to. """ prev_event = Events.query.filter( Events.suborder_number == suborder.id, Events.new_value['status'].astext == suborder.status).order_by( Events.timestamp.desc()).first() previous_value = {} new_value = {} previous_value['status'] = suborder.status if prev_event is not None and 'comment' in prev_event.new_value: previous_value['comment'] = prev_event.new_value['comment'] update_object({'status': new_status}, Suborders, suborder.id) new_value['status'] = new_status if comment: new_value['comment'] = comment event = Events(suborder.id, event_type.UPDATE_STATUS, current_user.email, previous_value, new_value) create_object(event) suborder.es_update()
def create_document(uploader_id, file_title, file_name, document_type, file_type, file_path, division): """ Util function to create a Document object and 'document_uploaded' Event :param uploader_id: Id of the user who uploaded the file :param file_title: Human readable version of the file name :param file_name: Actual file name :param document_type: Category of document :param file_type: Extension of the file :param file_path: Full path of where the file is saved on the server :param division: Division that the file relates to """ # Create Document object document = Documents(uploader_id=uploader_id, file_title=file_title, file_name=file_name, document_type=document_type, file_type=file_type, file_path=file_path, division=division) create_object(document) # Create document_uploaded Event event = Events(document_id=document.id, user_id=uploader_id, type="document_uploaded", previous_value={}, new_value=document.val_for_events) create_object(event)
def _create_agency_user_requests(request_id, agency_admins, guid_for_event): """ Creates user_requests entries for agency administrators. :param request_id: Request being created :param agency_users: List of Users :param guid_for_event: guid used to create request events :return: """ for admin in agency_admins: user_request = UserRequests( user_guid=admin.guid, request_user_type=user_type_request.AGENCY, request_id=request_id, permissions=Roles.query.filter_by( name=role.AGENCY_ADMIN).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()))
def create(current_user, user_id, limit=4, page=1): """ Method to create event.""" event = request.get_json() name=event['name'].strip() category=event['category'] location=event['location'] date=event['date'] description=event['description'] new_event = validate_data(event) if new_event is not event: return jsonify({"message":new_event}), 400 existing=Events.query.filter_by(name=name).filter_by(category=category).filter_by\ (created_by=user_id).filter_by(location=location).first() if existing: response = {"message" : "A similar event already exists!"} return make_response(jsonify(response)), 302 try: created_event = Events(name=name, category=category, location=location, date=date, description=description, created_by = user_id) created_event.save() response = jsonify({ 'id': created_event.id, 'name' : created_event.name, 'category' : created_event.category, 'location' : created_event.location, 'date' : created_event.date, 'description' : created_event.description, 'created_by' : created_event.created_by, 'message': 'Event successfully created' }) except KeyError: response = {"message": "There was an error creating the event, please try again"} return make_response(jsonify(response)), 500 return make_response(response), 201
def remove_point_of_contact(request_id): """ Remove the current point of contact from a given request :param request_id: FOIL request ID """ point_of_contact = get_current_point_of_contact(request_id) set_point_of_contact(request_id, point_of_contact, False) create_object( Events( request_id, current_user.guid, current_user.auth_user_type, event_type.REQ_POINT_OF_CONTACT_REMOVED, previous_value={ "user_guid": point_of_contact.user_guid, "auth_user_type": point_of_contact.auth_user_type, "point_of_contact": "True" }, new_value={ "user_guid": point_of_contact.user_guid, "auth_user_type": point_of_contact.auth_user_type, "point_of_contact": "False" }, timestamp=datetime.utcnow(), ))
def create_event_post(event_date, event_location, event_leader, start_time, end_time, sponsor, author, title, content, tags): """ Util function for creating a EventPost object. Function will take parameters passed in from the form and create a event post along with the event object. """ event_post = EventPosts(event_date=event_date, event_location=event_location, event_leader=event_leader, start_time=start_time, end_time=end_time, sponsor=sponsor, author=author, title=title, content=content, tags=tags) create_object(event_post) # Create event_post_created Event event = Events(post_id=event_post.id, user_id=author, type="event_post_created", previous_value={}, new_value=event_post.val_for_events) create_object(event) return event_post.id
def setUp(self): self.user = Users self.password = self.user.hash_password('password') self.new_user = self.user('John', 'Doe', '*****@*****.**', self.password) self.new_event = Events("Barbecue party", "nairobi", "Food", "12/12/2017", 'frank')
def reset_db(): flash( "Resetting database: deleting old data and repopulating with dummy data" ) meta = db.metadata for table in reversed(meta.sorted_tables): print('Clear table {}'.format(table)) db.session.execute(table.delete()) db.session.commit() artist1 = Artist(name="Drake", description="Soon to be added") artist2 = Artist(name='Kendrick Lamar', description="Added after Drake") venue1 = Venues(location='Baltimore Soundstage, Maryland', date='01/24/2018') venue2 = Venues(location='The 20th Century Theater, Ohio', date='04/28/2018') venue3 = Venues(location='The New Parish, California', date='04/29/2018') event1 = Events(name='Aubrey & The Three Migos ', price='$350', venue_id=1, event_date=datetime.utcnow()) event2 = Events(name='Leeds Festival 2018', price='$170', venue_id=2, event_date=datetime.utcnow()) a2e = ArtistToEvent(Artist_id=1, Event_id=1) a2e1 = ArtistToEvent(Artist_id=2, Event_id=2) db.session.add(artist1) db.session.add(artist2) db.session.add(venue1) db.session.add(venue2) db.session.add(venue3) db.session.add(event1) db.session.add(event2) db.session.add(a2e) db.session.add(a2e1) db.session.commit() return redirect(url_for('index'))
def addEvent(): body = json.loads(request.data.decode()) try: if "type" in body: event = Events(subject=body['subject'], type=body.get('type'), message=body['message']) else: event = Events(subject=body['subject'], message=body['message']) db.session.add(event) db.session.commit() except Exception as e: print('DB Error: ', e) rsp = Response("Error on event registration", status=401, content_type="text/plain") return rsp print(event) rsp = Response("Event registered", status=200, content_type="text/plain") return rsp
def create_event(): """ Event create view """ form = CreateEventForm(request.form) if request.method == 'POST' and form.validate(): try: format_string = '%Y-%m-%dT%H:%M' name = str(request.form['name']) year = int(request.form['year']) semester = Semester(int(request.form['semester'])) specialslot = int(request.form['special_slots']) specialslotname = str(request.form['special_slots_name']) specialslotdescription = str( request.form['special_slots_description']) timestamp = datetime.now() opensignuptimestamp = datetime.strptime( str(request.form['open_signup_timestamp']), format_string) closesignuptimestamp = datetime.strptime( str(request.form['close_signup_timestamp']), format_string) place = str(request.form['place']) participationfee = str(request.form['participation_fee']) signup_open = False active = False except Exception as e: print(e) return render_template('error.html', message=str( request.form['opensignuptimestamp'])) try: event = Events(name=name, year=year, special_slots=specialslot, special_slots_name=specialslotname, special_slots_description=specialslotdescription, place=place, semester=semester, creation_timestamp=timestamp, signup_open=signup_open, active=active, participation_fee=participationfee, open_signup_timestamp=opensignuptimestamp, close_signup_timestamp=closesignuptimestamp) db.session.add(event) db.session.commit() except Exception as e: print(e) return render_template('error.html') return redirect(url_for('admin')) return render_template('create_event.html', form=form)
def create_request_info_event(request_id, type_, previous_value, new_value): """ Create and store events object for updating the request information into database. :param request_id: request ID :param type_: event type :param previous_value: previous value :param new_value: new value """ event = Events(request_id=request_id, user_guid=current_user.guid, type_=type_, previous_value=previous_value, new_value=new_value) create_object(event)
def addevent(): form = NewEventForm(request.form) if request.method == 'POST' and form.validate_on_submit(): #user = User(form.first_name.data, form.last_name.data, form.username.data, # form.username.data, form.email.data, form.enrollment.data, # form.college_name.data) event = Events(form.event_name.data, form.address.data, form.fees.data) event.start_date = form.start_date.data event.end_date = form.end_date.data db.session.add(event) db.session.commit() return render_template('addevent.html', isadded=True) return render_template('addevent.html', form=form, isadded=False)
def import_test_data(db): with open('./test_data.csv', newline='') as csvfile: spamreader = csv.reader(csvfile, delimiter=';') header = True for row in spamreader: if header: header = False continue new_event = Events(asin=row[0], brand=row[1], id=row[2], source=row[3], stars=int(row[4]), timestamp=datetime.datetime.fromtimestamp( int(row[5]))) db.session.add(new_event) db.session.commit()
def create_news(author, title, content, tags): """ Util function for creating a News object. Function will take parameters passed in from the form and create a News along with the event object. """ news = News(author=author, title=title, content=content, tags=tags) create_object(news) # Create news_created Event event = Events(post_id=news.id, user_id=author, type="news_created", previous_value={}, new_value=news.val_for_events) create_object(event) return news.id
def post(self, user_id): """Handle POST request for this view. Url ---> /api/events""" user = User.query.filter_by(id=user_id).first() # get user details if user.email_confirmed is not True: response = { "message": 'Your Must Confirm your Email Address in-order to create an event' } return make_response(jsonify(response)), 401 args = {} event_models = [ 'title', 'location', 'time', 'date', 'description', 'image_url', 'event_category' ] for event_res in event_models: var = str(request.data.get(event_res, '').capitalize()) var = var.strip(' \t\n\r') if not var: response = {"message": '{} missing'.format(event_res)} return make_response(jsonify(response)), 401 args.update({event_res: var}) if Events.query.filter_by(title=args['title']).first(): response = {"message": 'Event title exists. Choose another one'} return make_response(jsonify(response)), 401 event = Events(**args, created_by=user_id) event.save() response = jsonify({ 'id': event.id, 'title': event.title, 'location': event.location, 'time': event.time, 'date': event.date, 'description': event.description, 'image_url': event.image_url, 'created_by': user.name, 'event_category': event.event_category, }) return make_response(response), 201
def create_user_request_event(events_type, user_request, old_permissions=None): """ Create an Event for the addition, removal, or updating of a UserRequest """ if old_permissions is not None: previous_value = {"permissions": old_permissions} else: previous_value = None create_object( Events( user_request.request_id, current_user.guid, current_user.auth_user_type, events_type, previous_value=previous_value, new_value=user_request.val_for_events, timestamp=datetime.utcnow(), ))
def create_auth_event(auth_event_type: str, user_guid: str, new_value: dict): """ Create and store event object for given response. Args: auth_event_type (str): one of app.constants.event_type user_guid (Users): Users object performing the authentication event new_value (dict): Value to be stored in events table """ event = Events(request_id=None, user_guid=user_guid, type_=auth_event_type, timestamp=datetime.utcnow(), response_id=None, previous_value=None, new_value=new_value) # store event object create_object(event)
def post(self): current_user = get_jwt_identity() data = request.get_json() if not data: return invalid_data, 400 name = data["name"] desc = data["description"] location = data["location"] date = data["event_date"] event = Events.query.filter_by(name=name, user_id=current_user).first() if event: return {"error": "event exists"}, 409 post_event = Events(name=name, desc=desc, location=location, event_date=date, owner=current_user) db.session.add(post_event) db.session.commit() return {"message": "{} has been added".format(name)}, 201
def edit_events(): form = EventsForm() events = Events.query.all() if form.validate_on_submit(): event = Events(Events_title=form.Events_title.data, Events_time=form.Events_time.data, Events_city=form.Events_city.data, Events_country=form.Events_country.data, Events_intro=form.Events_intro.data) db.session.add(event) db.session.commit() flash(_('Added')) return redirect(url_for('main.edit_events')) if request.method == 'POST': del_form = request.form for ID in del_form.to_dict(): record_id = ID del_event = Events.query.filter_by(id=record_id).first() db.session.delete(del_event) db.session.commit() flash(_('Deleted')) return redirect(url_for('main.edit_events')) return render_template("edit_database/EditEvents.html", form=form, events=events)
def patch(agency_ein): """ Only accessible by Super Users Currently only changes: is_active """ if not current_user.is_anonymous and current_user.is_super: is_active = request.form.get('is_active') if is_active is not None and Agencies.query.filter_by( ein=agency_ein).first() is not None: update_object({'is_active': eval_request_bool(is_active)}, Agencies, agency_ein) create_object( Events(request_id=None, user_guid=current_user.guid, auth_user_type=current_user.auth_user_type, type_=AGENCY_ACTIVATED, new_value={"ein": agency_ein}, timestamp=datetime.utcnow())) return '', 200 return '', 400 return '', 403
def create_meeting_notes(meeting_date, meeting_location, meeting_leader, meeting_note_taker, start_time, end_time, attendees, next_meeting_date, next_meeting_leader, next_meeting_note_taker, meeting_type, division, author, title, content, tags): """ Util function for creating a MeetingNotes object. Function will take parameters passed in from the form and create a meeting notes along with the event object. """ meeting_notes = MeetingNotes( meeting_date=meeting_date, meeting_location=meeting_location, meeting_leader=meeting_leader, meeting_note_taker=meeting_note_taker, start_time=start_time, end_time=end_time, attendees=attendees, next_meeting_date=next_meeting_date or None, next_meeting_leader=next_meeting_leader or None, next_meeting_note_taker=next_meeting_note_taker or None, meeting_type=meeting_type, division=division, author=author, title=title, content=content, tags=tags) create_object(meeting_notes) # Create meeting_notes_created Event event = Events(post_id=meeting_notes.id, user_id=author, type="meeting_notes_created", previous_value={}, new_value=meeting_notes.val_for_events) create_object(event) return meeting_notes.id
def __set_due_soon_or_overdue(self, status, new_due_date, shift_dates): data = {"status": status} if shift_dates: shift = new_due_date - self.request.due_date data.update({ "due_date": new_due_date, "date_submitted": self.request.date_submitted + shift, "date_created": self.request.date_created + shift, "agency_request_summary_release_date": (self.request.agency_request_summary_release_date + shift if self.request.agency_request_summary_release_date else None) }) create_object( Events(self.request.id, user_guid=None, auth_user_type=None, type_=event_type.REQ_STATUS_CHANGED, previous_value={"status": self.request.status}, new_value={"status": status}, response_id=None)) self.__update(data)
def update_tax_photo(suborder_number: str, block_no: str, lot_no: str, roll_no: str) -> str: """ This function is used for the Tax Photo API POST method, will update these fields from JSON sent back :param suborder_number: :param block_no: :param lot_no: :param roll_no: :return: {} """ tax_photo = TaxPhoto.query.filter_by(suborder_number=suborder_number).one() message = 'No changes were made' new_value = {} previous_value = {} for name, value, col_value in [('block', block_no, tax_photo.block), ('lot', lot_no, tax_photo.lot), ('roll', roll_no, tax_photo.roll)]: if value and value != col_value: setattr(tax_photo, name, value) new_value[name] = value previous_value[name] = col_value if new_value: db.session.add(tax_photo) event = Events(suborder_number, event_type.UPDATE_TAX_PHOTO, current_user.email, previous_value, new_value) db.session.add(event) db.session.commit() message = 'Tax Photo Info Updated' return message
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 update_request_statuses(): """ Update statuses for all requests that are now Due Soon or Overdue and send a notification email to agency admins listing the requests. """ with scheduler.app.app_context(): now = datetime.utcnow() due_soon_date = calendar.addbusdays( now, current_app.config['DUE_SOON_DAYS_THRESHOLD']).replace( hour=23, minute=59, second=59) # the entire day requests_overdue = Requests.query.filter( Requests.due_date < now, Requests.status != request_status.CLOSED).order_by( Requests.due_date.asc()).all() requests_due_soon = Requests.query.filter( Requests.due_date > now, Requests.due_date <= due_soon_date, Requests.status != request_status.CLOSED).order_by( Requests.due_date.asc()).all() agencies_to_requests_overdue = {} agencies_to_acknowledgments_overdue = {} agencies_to_requests_due_soon = {} agencies_to_acknowledgments_due_soon = {} def add_to_agencies_to_request_dict(req, agencies_to_request_dict): if req.agency.ein not in agencies_to_request_dict: agencies_to_request_dict[req.agency.ein] = [req] else: agencies_to_request_dict[req.agency.ein].append(req) # OVERDUE for request in requests_overdue: if request.was_acknowledged: add_to_agencies_to_request_dict(request, agencies_to_requests_overdue) else: add_to_agencies_to_request_dict( request, agencies_to_acknowledgments_overdue) if request.status != request_status.OVERDUE: update_object({"status": request_status.OVERDUE}, Requests, request.id) # DUE SOON for request in requests_due_soon: if request.was_acknowledged: add_to_agencies_to_request_dict(request, agencies_to_requests_due_soon) else: add_to_agencies_to_request_dict( request, agencies_to_acknowledgments_due_soon) if request.status != request_status.DUE_SOON: update_object({"status": request_status.DUE_SOON}, Requests, request.id) # get all possible agencies to email agency_eins = set( list(agencies_to_requests_overdue) + list(agencies_to_acknowledgments_overdue) + list(agencies_to_requests_due_soon) + list(agencies_to_acknowledgments_due_soon)) # mail to agency admins for each agency for agency_ein in agency_eins: agency_requests_overdue = agencies_to_requests_overdue.get( agency_ein, []) agency_acknowledgments_overdue = agencies_to_acknowledgments_overdue.get( agency_ein, []) agency_requests_due_soon = agencies_to_requests_due_soon.get( agency_ein, []) agency_acknowledgments_due_soon = agencies_to_acknowledgments_due_soon.get( agency_ein, []) user_emails = list( set(admin.notification_email or admin.email for admin in Agencies.query.filter_by( ein=agency_ein).one().administrators)) send_email( STATUSES_EMAIL_SUBJECT, to=user_emails, template=STATUSES_EMAIL_TEMPLATE, requests_overdue=agency_requests_overdue, acknowledgments_overdue=agency_acknowledgments_overdue, requests_due_soon=agency_requests_due_soon, acknowledgments_due_soon=agency_acknowledgments_due_soon) email = Emails( request.id, PRIVATE, to=','.join(user_emails), cc=None, bcc=None, subject=STATUSES_EMAIL_SUBJECT, body=render_template( STATUSES_EMAIL_TEMPLATE + ".html", requests_overdue=agency_requests_overdue, acknowledgments_overdue=agency_acknowledgments_overdue, requests_due_soon=agency_requests_due_soon, acknowledgments_due_soon=agency_acknowledgments_due_soon)) create_object(email) create_object( Events(request.id, user_guid=None, auth_user_type=None, type_=EMAIL_NOTIFICATION_SENT, previous_value=None, new_value=email.val_for_events, response_id=None, timestamp=datetime.utcnow()))
def _update_request_statuses(): """ Update statuses for all requests that are now Due Soon or Overdue and send a notification email to agency admins listing the requests. """ now = datetime.utcnow() due_soon_date = calendar.addbusdays( now, current_app.config['DUE_SOON_DAYS_THRESHOLD']).replace( hour=23, minute=59, second=59) # the entire day agencies = Agencies.query.with_entities( Agencies.ein).filter_by(is_active=True).all() for agency_ein, in agencies: requests_overdue = Requests.query.filter( Requests.due_date < now, Requests.status != request_status.CLOSED, Requests.agency_ein == agency_ein).order_by( Requests.due_date.asc()).all() requests_due_soon = Requests.query.filter( Requests.due_date > now, Requests.due_date <= due_soon_date, Requests.status != request_status.CLOSED, Requests.agency_ein == agency_ein).order_by( Requests.due_date.asc()).all() if not requests_overdue and not requests_due_soon: continue agency_requests_overdue = [] agency_acknowledgments_overdue = [] agency_requests_due_soon = [] agency_acknowledgments_due_soon = [] # OVERDUE for request in requests_overdue: if request.was_acknowledged: agency_requests_overdue.append(request) else: agency_acknowledgments_overdue.append(request) if request.status != request_status.OVERDUE: create_object( Events( request.id, user_guid=None, auth_user_type=None, type_=REQ_STATUS_CHANGED, previous_value={"status": request.status}, new_value={"status": request_status.OVERDUE}, response_id=None, )) update_object({"status": request_status.OVERDUE}, Requests, request.id) # DUE SOON for request in requests_due_soon: if request.was_acknowledged: agency_requests_due_soon.append(request) else: agency_acknowledgments_due_soon.append(request) if request.status != request_status.DUE_SOON: create_object( Events( request.id, user_guid=None, auth_user_type=None, type_=REQ_STATUS_CHANGED, previous_value={"status": request.status}, new_value={"status": request_status.DUE_SOON}, response_id=None, )) update_object({"status": request_status.DUE_SOON}, Requests, request.id) # mail to agency admins for each agency user_emails = list( set(admin.notification_email or admin.email for admin in Agencies.query.filter_by( ein=agency_ein).one().administrators)) send_email(STATUSES_EMAIL_SUBJECT, to=user_emails, template=STATUSES_EMAIL_TEMPLATE, requests_overdue=agency_requests_overdue, acknowledgments_overdue=agency_acknowledgments_overdue, requests_due_soon=agency_requests_due_soon, acknowledgments_due_soon=agency_acknowledgments_due_soon) email = Emails( request.id, PRIVATE, to=','.join(user_emails), cc=None, bcc=None, subject=STATUSES_EMAIL_SUBJECT, body=render_template( STATUSES_EMAIL_TEMPLATE + ".html", requests_overdue=agency_requests_overdue, acknowledgments_overdue=agency_acknowledgments_overdue, requests_due_soon=agency_requests_due_soon, acknowledgments_due_soon=agency_acknowledgments_due_soon)) create_object(email) create_object( Events(request.id, user_guid=None, auth_user_type=None, type_=EMAIL_NOTIFICATION_SENT, previous_value=None, new_value=email.val_for_events, response_id=None, timestamp=datetime.utcnow()))