Disallow Proposal Submissions to Expired RFPs (#25)
* disallow rfp proposal submissions after close * Add closed tag to closed RFPs
This commit is contained in:
parent
c1a014a4b5
commit
54b0d58ffa
|
@ -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 doesn’t exist"}, 400
|
return {"message": "The request this proposal was made for doesn’t 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)
|
||||||
|
|
|
@ -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>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue