Skip to content

Commit

Permalink
ZEVA-360: Credit Transfer Rescind Option (#439)
Browse files Browse the repository at this point in the history
* added rescind button to button component and action bar

* added new transfer status and updated conditions for rescind button on transfer details page

* added redirect for attempting to edit transfers not in draft or rescind form (or user not with initiating supplier), fixed conditions for displaying rescind buttons

* added signed by information to details page for bceid users, displaying only initiating supplier date if unsigned by partner

* updated logic for displaying signed and submitted information so that if a transfer is rescinded it only shows the signed dates after the rescind date

* added rescinded transfers to transfer list for receiving suppliers and added total value text to all details pages under table
  • Loading branch information
emi-hi authored and kuanfandevops committed Dec 11, 2020
1 parent 635c833 commit 15487e5
Show file tree
Hide file tree
Showing 8 changed files with 138 additions and 51 deletions.
1 change: 1 addition & 0 deletions backend/api/models/credit_transfer_statuses.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,6 @@ class CreditTransferStatuses(Enum):
RECOMMEND_APPROVAL = 'RECOMMEND_APPROVAL'
RECOMMEND_REJECTION = 'RECOMMEND_REJECTION'
VALIDATED = 'VALIDATED'
RESCINDED = 'RESCINDED'
REJECTED = 'REJECTED'
DELETED = 'DELETED'
1 change: 1 addition & 0 deletions backend/api/viewsets/credit_transfer.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ def get_queryset(self):
Q(status__in=[
CreditTransferStatuses.SUBMITTED,
CreditTransferStatuses.APPROVED,
CreditTransferStatuses.RESCINDED,
CreditTransferStatuses.VALIDATED,
CreditTransferStatuses.RECOMMEND_APPROVAL,
CreditTransferStatuses.RECOMMEND_REJECTION
Expand Down
26 changes: 16 additions & 10 deletions frontend/src/app/components/Button.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,11 @@ const Button = (props) => {
tooltip = buttonTooltip;
}
switch (buttonType) {
case 'approve':
text = optionalText;
classname += ' primary';
onclick = action;
break;
case 'back':
onclick = () => { getRoute(); };
text = 'Back';
Expand All @@ -48,6 +53,16 @@ const Button = (props) => {
icon = 'download';
onclick = action;
break;
case 'reject':
text = optionalText;
classname += ' text-danger';
onclick = action;
break;
case 'rescind':
text = 'Rescind Notice';
classname += ' text-danger';
onclick = action;
break;
case 'save':
text = 'Save';
icon = 'save';
Expand All @@ -61,16 +76,7 @@ const Button = (props) => {
classname += ' primary';
onclick = action;
break;
case 'approve':
text = optionalText;
classname += ' primary';
onclick = action;
break;
case 'reject':
text = optionalText;
classname += ' text-danger';
onclick = action;
break;

default:
text = optionalText;
onclick = action;
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/app/router.js
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,7 @@ class Router extends Component {
exact
key="route-credit-transfers-new"
path={ROUTES_CREDIT_TRANSFERS.NEW}
render={() => <CreditTransfersEditContainer keycloak={keycloak} user={user} newTransfer/>}
render={() => <CreditTransfersEditContainer keycloak={keycloak} user={user} newTransfer />}
/>,
<Route
exact
Expand Down
3 changes: 3 additions & 0 deletions frontend/src/credits/CreditTransfersEditContainer.js
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,9 @@ const CreditTransfersEditContainer = (props) => {
if (!newTransfer) {
axios.get(ROUTES_CREDIT_TRANSFERS.DETAILS.replace(/:id/gi, id)).then((response) => {
const details = response.data;
if (details.debitFrom.id !== user.organization.id || ['DRAFT', 'RESCINDED'].indexOf(details.status) < 0) {
history.push(ROUTES_CREDIT_TRANSFERS.DETAILS.replace(/:id/g, id));
}
setFields({ ...fields, transferPartner: details.creditTo.id });
const rowInfo = details.creditTransferContent.map((each) => ({
creditType: each.creditClass.creditClass,
Expand Down
49 changes: 30 additions & 19 deletions frontend/src/credits/components/CreditTransfersDetailsActionBar.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import Button from '../../app/components/Button';

const CreditTransfersDetailsActionBar = (props) => {
const {
setShowModal, setModalType, comment, allChecked, permissions, checkboxes, assertions,
setShowModal, setModalType, comment, allChecked, transferRole, checkboxes, assertions,
} = props;

const actionBar = (
Expand All @@ -13,20 +13,31 @@ const CreditTransfersDetailsActionBar = (props) => {
<div className="action-bar">
<span className="left-content">
<Button buttonType="back" locationRoute="/credit-transfers" />
{permissions.tradePartner
{transferRole.tradePartner
&& (
<Button
testid="reject-transfer"
buttonType="reject"
optionalText="Reject Notice"
disabled={comment.length === 0 || allChecked}
action={() => {
setModalType('partner-reject');
setShowModal(true);
}}
/>
<Button
testid="reject-transfer"
buttonType="reject"
optionalText="Reject Notice"
disabled={comment.length === 0 || allChecked}
action={() => {
setModalType('partner-reject');
setShowModal(true);
}}
/>
)}
{transferRole.rescindable
&& (
<Button
buttonType="rescind"
disabled={comment.length === 0}
action={() => {
setModalType('rescind');
setShowModal(true);
}}
/>
)}
{permissions.governmentAnalyst
{transferRole.governmentAnalyst
&& (
<Button
testid="recommend-reject-transfer"
Expand All @@ -38,7 +49,7 @@ const CreditTransfersDetailsActionBar = (props) => {
}}
/>
)}
{permissions.governmentDirector
{transferRole.governmentDirector
&& (
<Button
testid="director-reject-transfer"
Expand All @@ -52,7 +63,7 @@ const CreditTransfersDetailsActionBar = (props) => {
)}
</span>
<span className="right-content">
{ permissions.initiatingSupplier
{ transferRole.initiatingSupplier
&& (
<Button
testid="submit-to-partner"
Expand All @@ -65,7 +76,7 @@ const CreditTransfersDetailsActionBar = (props) => {
disabled={!checkboxes.authority || !checkboxes.accurate || !checkboxes.consent || comment.length > 0}
/>
)}
{permissions.governmentAnalyst
{transferRole.governmentAnalyst
&& (
<Button
testid="recommend-approve-transfer"
Expand All @@ -77,7 +88,7 @@ const CreditTransfersDetailsActionBar = (props) => {
}}
/>
)}
{permissions.tradePartner
{transferRole.tradePartner
&& (
<Button
testid="submit-to-gov"
Expand All @@ -90,7 +101,7 @@ const CreditTransfersDetailsActionBar = (props) => {
disabled={checkboxes.length < assertions.length}
/>
)}
{permissions.governmentDirector
{transferRole.governmentDirector
&& (
<Button
testid="director-record"
Expand Down Expand Up @@ -127,7 +138,7 @@ CreditTransfersDetailsActionBar.propTypes = {
PropTypes.number,
])).isRequired,
comment: PropTypes.string,
permissions: PropTypes.shape().isRequired,
transferRole: PropTypes.shape().isRequired,
setModalType: PropTypes.func.isRequired,
setShowModal: PropTypes.func.isRequired,

Expand Down
105 changes: 85 additions & 20 deletions frontend/src/credits/components/CreditTransfersDetailsPage.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,11 @@ const CreditTransfersDetailsPage = (props) => {
const [showModal, setShowModal] = useState(false);
const [modalType, setModalType] = useState('');

const permissions = {
initiatingSupplier: user.organization.id === submission.debitFrom.id && submission.status === 'DRAFT',
const transferRole = {
rescindable: (user.organization.id === submission.debitFrom.id
&& ['SUBMITTED', 'APPROVED', 'RECOMMEND_REJECTION', 'RECOMMEND_APPROVAL'].indexOf(submission.status) >= 0)
|| (user.organization.id === submission.creditTo.id && ['APPROVED', 'RECOMMEND_REJECTION', 'RECOMMEND_APPROVAL'].indexOf(submission.status) >= 0),
initiatingSupplier: user.organization.id === submission.debitFrom.id && ['DRAFT', 'RESCINDED'].indexOf(submission.status) >= 0,
tradePartner: user.organization.id === submission.creditTo.id && submission.status === 'SUBMITTED',
governmentAnalyst: user.hasPermission('RECOMMEND_CREDIT_TRANSFER')
&& user.isGovernment && submission.status === 'APPROVED',
Expand Down Expand Up @@ -73,6 +76,14 @@ const CreditTransfersDetailsPage = (props) => {
icon: <FontAwesomeIcon icon="paper-plane" />,
};
break;
case 'rescind':
modalProps = {
confirmLabel: ' Rescind',
handleSubmit: () => { handleSubmit('RESCINDED', comment); },
buttonClass: 'button primary',
modalText: 'Rescind notice?',
};
break;
case 'recommend-reject':
modalProps = {
confirmLabel: ' Recommend Rejection',
Expand Down Expand Up @@ -136,24 +147,71 @@ const CreditTransfersDetailsPage = (props) => {
</Modal>
);

const rescindComment = (
<>
<label htmlFor="transfer-rescind-comment">
<h4>
If you need to rescind this transfer notice
please enter a reason to your transfer partner.
</h4>
</label>
<textarea name="transfer-rescind-comment" className="col-sm-11" rows="3" onChange={(event) => { setComment(event.target.value); }} value={comment} />
</>
);
const transferValue = (
<div className="text-blue">
for a total value of ${submission.creditTransferContent.reduce(
(a, v) => a + v.dollarValue * v.creditValue, 0,
)} Canadian dollars.
</div>
);
const initiatingInformation = submission.history.find((each) => each.status === 'SUBMITTED');
const transferPartnerInformation = submission.history.find((each) => each.status === 'APPROVED');

let latestRescind = false;
let latestSubmit = false;
let latestApprove = false;
let showSubmissionConfirmation = true;
let showApproveConfirmation = true;
submission.history.forEach((history) => {
if (history.status === 'RESCINDED') {
latestRescind = history;
}
if (history.status === 'SUBMITTED') {
latestSubmit = history;
}
if (history.status === 'APPROVED') {
latestApprove = history;
}
});
if (latestRescind && latestSubmit) {
if (latestRescind.createTimestamp > latestSubmit.createTimestamp) {
showSubmissionConfirmation = false;
showApproveConfirmation = false;
}
if (latestApprove) {
if (latestSubmit.createTimestamp > latestApprove.createTimestamp) {
showApproveConfirmation = false;
}
} else {
showApproveConfirmation = false;
}
}

const signedSubmittedInfo = (
<>
{transferValue}
{initiatingInformation && transferPartnerInformation
{showSubmissionConfirmation
&& (
<div className="text-blue">
Signed and submitted by {initiatingInformation.createUser.displayName} of {initiatingInformation.createUser.organization.name} {moment(initiatingInformation.createTimestamp).tz('America/Vancouver').format('YYYY-MM-DD hh:mm:ss z')}
Signed and submitted by {latestSubmit.createUser.displayName} of&nbsp;
{latestSubmit.createUser.organization.name}&nbsp;
{moment(latestSubmit.createTimestamp).tz('America/Vancouver').format('YYYY-MM-DD hh:mm:ss z')}
<br />
Signed and submitted by {transferPartnerInformation.createUser.displayName} of {transferPartnerInformation.createUser.organization.name} {moment(transferPartnerInformation.createTimestamp).tz('America/Vancouver').format('YYYY-MM-DD hh:mm:ss z')}
{showApproveConfirmation && (
<>
Signed and submitted by {latestApprove.createUser.displayName} of&nbsp;
{latestApprove.createUser.organization.name}&nbsp;
{moment(latestApprove.createTimestamp).tz('America/Vancouver').format('YYYY-MM-DD hh:mm:ss z')}
</>
)}
</div>
)}
</>
Expand All @@ -167,7 +225,6 @@ const CreditTransfersDetailsPage = (props) => {
);
const tradePartnerSignoff = (
<div>
{transferValue}
<h4>
If you agree to this notice of transfer please confirm the following statements and click
Submit Notice to send to the Government of B.C. Director for the transfer to be recorded.
Expand Down Expand Up @@ -195,14 +252,14 @@ const CreditTransfersDetailsPage = (props) => {
<div className="col-sm-12">
<h2>Light Duty Vehicle Credit Transfer</h2>
</div>
{permissions.governmentDirector && submission.creditTransferComment
&& (
<div className="ml-3">
<Comment commentArray={submission.creditTransferComment} />
</div>
)}
{transferRole.governmentDirector && submission.creditTransferComment
&& (
<div className="ml-3">
<Comment commentArray={submission.creditTransferComment} />
</div>
)}
</div>
{permissions.governmentAnalyst && !sufficientCredit
{transferRole.governmentAnalyst && !sufficientCredit
&& (
<div
className="alert alert-danger"
Expand All @@ -213,7 +270,7 @@ const CreditTransfersDetailsPage = (props) => {
&nbsp;<b>WARNING:&nbsp;</b> Supplier has insufficient credits to fulfill all pending transfers.
</div>
)}
{permissions.governmentAnalyst
{transferRole.governmentAnalyst
&& (
<CreditTransfersDetailsSupplierTable submission={submission} tableType="supplierBalance" />
)}
Expand All @@ -224,16 +281,24 @@ const CreditTransfersDetailsPage = (props) => {
&& (
<div className="my-2 px-2 pb-2">
<CreditTransfersDetailsTable submission={submission} tableType="submissionSummary" />
{permissions.tradePartner
{transferValue}
{transferRole.tradePartner
&& tradePartnerSignoff}
{permissions.governmentAnalyst
{transferRole.rescindable
&& (
<>
{signedSubmittedInfo}
{rescindComment}
</>
)}
{transferRole.governmentAnalyst
&& analystSignoff}
<CreditTransfersDetailsActionBar
allChecked={allChecked}
assertions={assertions}
checkboxes={checkboxes}
comment={comment}
permissions={permissions}
transferRole={transferRole}
setModalType={setModalType}
setShowModal={setShowModal}
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ const CreditTransfersListTable = (props) => {
return {
onClick: () => {
const { id, status } = row.original;
if (status === 'DRAFT') {
if (status === 'DRAFT' || status === 'RESCINDED') {
history.push(ROUTES_CREDIT_TRANSFERS.EDIT.replace(/:id/g, id));
} else {
history.push(ROUTES_CREDIT_TRANSFERS.DETAILS.replace(/:id/g, id), filtered);
Expand Down

0 comments on commit 15487e5

Please sign in to comment.