Disallow Proposal Submissions to Expired RFPs (#25)

* disallow rfp proposal submissions after close

* Add closed tag to closed RFPs
This commit is contained in:
Danny Skubak 2019-10-10 20:12:38 -04:00 committed by Daniel Ternyak
parent c1a014a4b5
commit 54b0d58ffa
2 changed files with 35 additions and 18 deletions

View File

@ -1,4 +1,5 @@
from decimal import Decimal from decimal import Decimal
from datetime import datetime
from flask import Blueprint, g, request, current_app from flask import Blueprint, g, request, current_app
from marshmallow import fields, validate from marshmallow import fields, validate
@ -25,7 +26,7 @@ from grant.utils.auth import (
internal_webhook internal_webhook
) )
from grant.utils.enums import Category from grant.utils.enums import Category
from grant.utils.enums import ProposalStatus, ProposalStage, ContributionStatus from grant.utils.enums import ProposalStatus, ProposalStage, ContributionStatus, RFPStatus
from grant.utils.exceptions import ValidationException from grant.utils.exceptions import ValidationException
from grant.utils.misc import is_email, make_url, from_zat, make_explore_url from grant.utils.misc import is_email, make_url, from_zat, make_explore_url
from .models import ( from .models import (
@ -187,6 +188,10 @@ def make_proposal_draft(rfp_id):
rfp = RFP.query.filter_by(id=rfp_id).first() rfp = RFP.query.filter_by(id=rfp_id).first()
if not rfp: if not rfp:
return {"message": "The request this proposal was made for doesnt exist"}, 400 return {"message": "The request this proposal was made for doesnt exist"}, 400
if datetime.now() > rfp.date_closes:
return {"message": "The request this proposal was made for has expired"}, 400
if rfp.status == RFPStatus.CLOSED:
return {"message": "The request this proposal was made for has been closed"}, 400
proposal.category = rfp.category proposal.category = rfp.category
rfp.proposals.append(proposal) rfp.proposals.append(proposal)
db.session.add(rfp) db.session.add(rfp)

View File

@ -13,6 +13,7 @@ import Markdown from 'components/Markdown';
import ProposalCard from 'components/Proposals/ProposalCard'; import ProposalCard from 'components/Proposals/ProposalCard';
import UnitDisplay from 'components/UnitDisplay'; import UnitDisplay from 'components/UnitDisplay';
import HeaderDetails from 'components/HeaderDetails'; import HeaderDetails from 'components/HeaderDetails';
import { RFP_STATUS } from 'api/constants';
import './index.less'; import './index.less';
interface OwnProps { interface OwnProps {
@ -48,6 +49,7 @@ class RFPDetail extends React.Component<Props> {
} }
} }
const isLive = rfp.status === RFP_STATUS.LIVE;
const tags = []; const tags = [];
if (rfp.matching) { if (rfp.matching) {
@ -66,6 +68,14 @@ class RFPDetail extends React.Component<Props> {
); );
} }
if (!isLive) {
tags.push(
<Tag key="closed" color="#f5222d">
Closed
</Tag>
);
}
return ( return (
<div className="RFPDetail"> <div className="RFPDetail">
<HeaderDetails title={rfp.title} description={rfp.brief} /> <HeaderDetails title={rfp.title} description={rfp.brief} />
@ -117,23 +127,25 @@ class RFPDetail extends React.Component<Props> {
</div> </div>
)} )}
<div className="RFPDetail-submit"> {isLive && (
<Affix offsetBottom={0}> <div className="RFPDetail-submit">
<div className="RFPDetail-submit-inner"> <Affix offsetBottom={0}>
<span>Ready to take on this request?</span>{' '} <div className="RFPDetail-submit-inner">
<Link to={`/create?rfp=${rfp.id}`}> <span>Ready to take on this request?</span>{' '}
<Button <Link to={`/create?rfp=${rfp.id}`}>
className="RFPDetail-submit-inner-button" <Button
type="primary" className="RFPDetail-submit-inner-button"
size="large" type="primary"
> size="large"
Start a Proposal >
<Icon type="right-circle" /> Start a Proposal
</Button> <Icon type="right-circle" />
</Link> </Button>
</div> </Link>
</Affix> </div>
</div> </Affix>
</div>
)}
</div> </div>
); );
} }