Update RFP model with new fields, api endpoint for editing them.
This commit is contained in:
parent
92bbbfe506
commit
b03a9d3caf
|
@ -2,6 +2,7 @@ from flask import Blueprint, request
|
|||
from flask import Blueprint, request
|
||||
from flask_yoloapi import endpoint, parameter
|
||||
from decimal import Decimal
|
||||
from datetime import datetime
|
||||
from grant.comment.models import Comment, user_comments_schema
|
||||
from grant.email.send import generate_email, send_email
|
||||
from grant.extensions import db
|
||||
|
@ -17,7 +18,7 @@ from grant.user.models import User, admin_users_schema, admin_user_schema
|
|||
from grant.rfp.models import RFP, admin_rfp_schema, admin_rfps_schema
|
||||
from grant.utils.admin import admin_auth_required, admin_is_authed, admin_login, admin_logout
|
||||
from grant.utils.misc import make_url
|
||||
from grant.utils.enums import ProposalStatus, ContributionStatus
|
||||
from grant.utils.enums import ProposalStatus, ContributionStatus, RFPStatus
|
||||
from grant.utils import pagination
|
||||
from sqlalchemy import func, or_
|
||||
|
||||
|
@ -284,15 +285,13 @@ def get_rfps():
|
|||
parameter('brief', type=str),
|
||||
parameter('content', type=str),
|
||||
parameter('category', type=str),
|
||||
parameter('bounty', type=str),
|
||||
parameter('matching', type=bool),
|
||||
parameter('dateCloses', type=int),
|
||||
)
|
||||
@admin_auth_required
|
||||
def create_rfp(title, brief, content, category):
|
||||
rfp = RFP(
|
||||
title=title,
|
||||
brief=brief,
|
||||
content=content,
|
||||
category=category,
|
||||
)
|
||||
def create_rfp(**kwargs):
|
||||
rfp = RFP(**kwargs)
|
||||
db.session.add(rfp)
|
||||
db.session.commit()
|
||||
return admin_rfp_schema.dump(rfp), 201
|
||||
|
@ -315,19 +314,33 @@ def get_rfp(rfp_id):
|
|||
parameter('brief', type=str),
|
||||
parameter('content', type=str),
|
||||
parameter('category', type=str),
|
||||
parameter('bounty', type=str),
|
||||
parameter('matching', type=bool),
|
||||
parameter('dateCloses', type=int),
|
||||
parameter('status', type=str),
|
||||
)
|
||||
@admin_auth_required
|
||||
def update_rfp(rfp_id, title, brief, content, category, status):
|
||||
def update_rfp(rfp_id, title, brief, content, category, bounty, matching, date_closes, status):
|
||||
rfp = RFP.query.filter(RFP.id == rfp_id).first()
|
||||
if not rfp:
|
||||
return {"message": "No RFP matching that id"}, 404
|
||||
|
||||
# Update fields
|
||||
rfp.title = title
|
||||
rfp.brief = brief
|
||||
rfp.content = content
|
||||
rfp.category = category
|
||||
rfp.status = status
|
||||
rfp.bounty = bounty
|
||||
rfp.matching = matching
|
||||
rfp.date_closes = date_closes
|
||||
|
||||
# Update timestamps if status changed
|
||||
if rfp.status != status:
|
||||
if status == RFPStatus.LIVE:
|
||||
rfp.date_opened = datetime.now()
|
||||
if status == RFPStatus.CLOSED:
|
||||
rfp.date_closed = datetime.now()
|
||||
rfp.status = status
|
||||
|
||||
db.session.add(rfp)
|
||||
db.session.commit()
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import datetime
|
||||
from datetime import datetime
|
||||
from grant.extensions import ma, db
|
||||
from grant.utils.enums import RFPStatus
|
||||
from grant.utils.misc import dt_to_unix
|
||||
|
@ -15,6 +15,11 @@ class RFP(db.Model):
|
|||
content = db.Column(db.Text, nullable=False)
|
||||
category = db.Column(db.String(255), nullable=False)
|
||||
status = db.Column(db.String(255), nullable=False)
|
||||
matching = db.Column(db.Boolean, default=False, nullable=False)
|
||||
bounty = db.Column(db.String(255), nullable=True)
|
||||
date_closes = db.Column(db.DateTime, nullable=True)
|
||||
date_opened = db.Column(db.DateTime, nullable=True)
|
||||
date_closed = db.Column(db.DateTime, nullable=True)
|
||||
|
||||
# Relationships
|
||||
proposals = db.relationship(
|
||||
|
@ -36,13 +41,19 @@ class RFP(db.Model):
|
|||
brief: str,
|
||||
content: str,
|
||||
category: str,
|
||||
bounty: str,
|
||||
date_closes: datetime,
|
||||
matching: bool = False,
|
||||
status: str = RFPStatus.DRAFT,
|
||||
):
|
||||
self.date_created = datetime.datetime.now()
|
||||
self.date_created = datetime.now()
|
||||
self.title = title
|
||||
self.brief = brief
|
||||
self.content = content
|
||||
self.category = category
|
||||
self.bounty = bounty
|
||||
self.date_closes = date_closes
|
||||
self.matching = matching
|
||||
self.status = status
|
||||
|
||||
|
||||
|
@ -87,10 +98,22 @@ class AdminRFPSchema(ma.Schema):
|
|||
)
|
||||
|
||||
date_created = ma.Method("get_date_created")
|
||||
date_closes = ma.Method("get_date_closes")
|
||||
date_opened = ma.Method("get_date_opened")
|
||||
date_closed = ma.Method("get_date_closed")
|
||||
proposals = ma.Nested("ProposalSchema", many=True, exclude=["rfp"])
|
||||
|
||||
def get_date_created(self, obj):
|
||||
return dt_to_unix(obj.date_created)
|
||||
|
||||
def get_date_closes(self, obj):
|
||||
return dt_to_unix(obj.date_closes)
|
||||
|
||||
def get_date_opened(self, obj):
|
||||
return dt_to_unix(obj.date_opened)
|
||||
|
||||
def get_date_closed(self, obj):
|
||||
return dt_to_unix(obj.date_closes)
|
||||
|
||||
admin_rfp_schema = AdminRFPSchema()
|
||||
admin_rfps_schema = AdminRFPSchema(many=True)
|
||||
|
|
|
@ -0,0 +1,53 @@
|
|||
"""Adds RFP bounty, matching, and date fields
|
||||
|
||||
Revision ID: d39bb526eef4
|
||||
Revises: 310dca400b81
|
||||
Create Date: 2019-02-07 15:09:11.548655
|
||||
|
||||
"""
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
from sqlalchemy.sql import expression
|
||||
from datetime import datetime
|
||||
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision = 'd39bb526eef4'
|
||||
down_revision = '310dca400b81'
|
||||
branch_labels = None
|
||||
depends_on = None
|
||||
|
||||
|
||||
def upgrade():
|
||||
# ### commands auto generated by Alembic - please adjust! ###
|
||||
op.drop_table('rfp_proposal')
|
||||
op.add_column('rfp', sa.Column('bounty', sa.String(length=255), nullable=True))
|
||||
op.add_column('rfp', sa.Column('date_closed', sa.DateTime(), nullable=True))
|
||||
op.add_column('rfp', sa.Column('date_closes', sa.DateTime(), nullable=True))
|
||||
op.add_column('rfp', sa.Column('date_opened', sa.DateTime(), nullable=True))
|
||||
op.add_column('rfp', sa.Column('matching', sa.Boolean(), nullable=False, server_default=expression.false()))
|
||||
# ### end Alembic commands ###
|
||||
|
||||
# Set columns for times based on status.
|
||||
now = datetime.now()
|
||||
connection = op.get_bind()
|
||||
connection.execute("UPDATE rfp SET date_closed = now() WHERE status = 'CLOSED'")
|
||||
connection.execute("UPDATE rfp SET date_opened = now() WHERE status = 'LIVE'")
|
||||
|
||||
|
||||
|
||||
def downgrade():
|
||||
# ### commands auto generated by Alembic - please adjust! ###
|
||||
op.drop_column('rfp', 'matching')
|
||||
op.drop_column('rfp', 'date_opened')
|
||||
op.drop_column('rfp', 'date_closes')
|
||||
op.drop_column('rfp', 'date_closed')
|
||||
op.drop_column('rfp', 'bounty')
|
||||
op.create_table('rfp_proposal',
|
||||
sa.Column('rfp_id', sa.INTEGER(), autoincrement=False, nullable=True),
|
||||
sa.Column('proposal_id', sa.INTEGER(), autoincrement=False, nullable=True),
|
||||
sa.ForeignKeyConstraint(['proposal_id'], ['proposal.id'], name='rfp_proposal_proposal_id_fkey'),
|
||||
sa.ForeignKeyConstraint(['rfp_id'], ['rfp.id'], name='rfp_proposal_rfp_id_fkey'),
|
||||
sa.UniqueConstraint('proposal_id', name='rfp_proposal_proposal_id_key')
|
||||
)
|
||||
# ### end Alembic commands ###
|
Loading…
Reference in New Issue