Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP // Export xlsx FSP auth code (MTCN) #4527

Draft
wants to merge 23 commits into
base: develop
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
686 changes: 381 additions & 305 deletions pdm.lock

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,9 @@ dependencies = [
"elastic-transport==8.13.0",
"flower>=2.0.1",
"factory-boy<4,>=3",
"django-fernet-fields>=0.6",
"msoffcrypto-tool>=5.4.2",
"pyzipper>=0.3.6",
]
requires-python = "==3.12.*"
readme = "README.md"
Expand Down
10 changes: 6 additions & 4 deletions src/frontend/data/schema.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ enum Action {
REJECT
FINISH
SEND_TO_PAYMENT_GATEWAY
SEND_XLSX_PASSWORD
}

input ActionPaymentPlanInput {
Expand Down Expand Up @@ -2329,9 +2330,9 @@ type Mutations {
invalidPaymentVerificationPlan(paymentVerificationPlanId: ID!, version: BigInt): InvalidPaymentVerificationPlan
deletePaymentVerificationPlan(paymentVerificationPlanId: ID!, version: BigInt): DeletePaymentVerificationPlan
updatePaymentVerificationStatusAndReceivedAmount(paymentVerificationId: ID!, receivedAmount: Decimal!, status: PaymentVerificationStatusForUpdate, version: BigInt): UpdatePaymentVerificationStatusAndReceivedAmount
updatePaymentVerificationReceivedAndReceivedAmount(paymentVerificationId: ID!, received: Boolean!, receivedAmount: Decimal!, version: BigInt): UpdatePaymentVerificationReceivedAndReceivedAmount
markPaymentAsFailed(paymentId: ID!): MarkPaymentAsFailedMutation
revertMarkPaymentAsFailed(deliveredQuantity: Decimal!, deliveryDate: Date!, paymentId: ID!): RevertMarkPaymentAsFailedMutation
updatePaymentVerificationReceivedAndReceivedAmount(paymentVerificationId: ID!, received: Boolean!, receivedAmount: Decimal!, version: BigInt): UpdatePaymentVerificationReceivedAndReceivedAmount
actionPaymentPlanMutation(input: ActionPaymentPlanInput!): ActionPaymentPlanMutation
createPaymentPlan(input: CreatePaymentPlanInput!): CreatePaymentPlanMutation
createFollowUpPaymentPlan(dispersionEndDate: Date!, dispersionStartDate: Date!, paymentPlanId: ID!): CreateFollowUpPaymentPlanMutation
Expand All @@ -2340,8 +2341,8 @@ type Mutations {
chooseDeliveryMechanismsForPaymentPlan(input: ChooseDeliveryMechanismsForPaymentPlanInput!): ChooseDeliveryMechanismsForPaymentPlanMutation
assignFspToDeliveryMechanism(input: AssignFspToDeliveryMechanismInput!): AssignFspToDeliveryMechanismMutation
splitPaymentPlan(paymentPlanId: ID!, paymentsNo: Int, splitType: String!): SplitPaymentPlanMutation
exportXlsxPaymentPlanPaymentList(paymentPlanId: ID!): ExportXLSXPaymentPlanPaymentListMutation
exportXlsxPaymentPlanPaymentListPerFsp(paymentPlanId: ID!): ExportXLSXPaymentPlanPaymentListPerFSPMutation
exportXlsxPaymentPlanPaymentList(fspXlsxTemplateId: ID, paymentPlanId: ID!): ExportXLSXPaymentPlanPaymentListMutation
exportXlsxPaymentPlanPaymentListPerFsp(fspXlsxTemplateId: ID, paymentPlanId: ID!): ExportXLSXPaymentPlanPaymentListPerFSPMutation
importXlsxPaymentPlanPaymentList(file: Upload!, paymentPlanId: ID!): ImportXLSXPaymentPlanPaymentListMutation
importXlsxPaymentPlanPaymentListPerFsp(file: Upload!, paymentPlanId: ID!): ImportXLSXPaymentPlanPaymentListPerFSPMutation
setSteficonRuleOnPaymentPlanPaymentList(paymentPlanId: ID!, steficonRuleId: ID!): SetSteficonRuleOnPaymentPlanPaymentListMutation
Expand Down Expand Up @@ -2659,6 +2660,7 @@ type PaymentPlanNode implements Node {
canSplit: Boolean
supportingDocuments: [PaymentPlanSupportingDocumentNode]
program: ProgramNode
canCreateXlsxWithFspAuthCode: Boolean
}

type PaymentPlanNodeConnection {
Expand Down Expand Up @@ -3115,7 +3117,7 @@ type Query {
allPayments(offset: Int, before: String, after: String, first: Int, last: Int, businessArea: String!, paymentPlanId: String!, programId: String, orderBy: String): PaymentNodeConnection
allPaymentRecordsAndPayments(businessArea: String!, program: String, household: ID, orderBy: String, first: Int, last: Int, before: String, after: String): PaginatedPaymentRecordsAndPaymentsNode
financialServiceProviderXlsxTemplate(id: ID!): FinancialServiceProviderXlsxTemplateNode
allFinancialServiceProviderXlsxTemplates(offset: Int, before: String, after: String, first: Int, last: Int, name: String, createdBy: ID, orderBy: String): FinancialServiceProviderXlsxTemplateNodeConnection
allFinancialServiceProviderXlsxTemplates(offset: Int, before: String, after: String, first: Int, last: Int, financialServiceProviders: [ID], name: String, createdBy: ID, orderBy: String): FinancialServiceProviderXlsxTemplateNodeConnection
financialServiceProvider(id: ID!): FinancialServiceProviderNode
allFinancialServiceProviders(offset: Int, before: String, after: String, first: Int, last: Int, createdBy: ID, name: String, visionVendorNumber: String, deliveryMechanisms: [String], distributionLimit: Float, communicationChannel: String, xlsxTemplates: [ID], orderBy: String): FinancialServiceProviderNodeConnection
paymentRecordVerification(id: ID!): PaymentVerificationNode
Expand Down
18 changes: 15 additions & 3 deletions src/frontend/src/__generated__/graphql.tsx

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -1,8 +1,14 @@
import { gql } from '@apollo/client';

export const ExportXlsxPPListPerFsp = gql`
mutation ExportXlsxPPListPerFsp($paymentPlanId: ID!) {
exportXlsxPaymentPlanPaymentListPerFsp(paymentPlanId: $paymentPlanId) {
mutation ExportXlsxPPListPerFsp(
$paymentPlanId: ID!
$fspXlsxTemplateId: String
) {
exportXlsxPaymentPlanPaymentListPerFsp(
paymentPlanId: $paymentPlanId
fspXlsxTemplateId: $fspXlsxTemplateId
) {
paymentPlan {
id
status
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { gql } from '@apollo/client';

export const ALL_FSP_XLSX_TEMPLATES = gql`
query allFinancialServiceProviderXlsxTemplates {
allFinancialServiceProviderXlsxTemplates {
edges {
node {
id
name
}
}
}
}
`;
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,7 @@ export const PAYMENT_PLAN_QUERY = gql`
}
hasPaymentListExportFile
hasFspDeliveryMechanismXlsxTemplate
canCreateXlsxWithFspAuthCode
importedFileDate
importedFileName
totalEntitledQuantityUsd
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ export function AcceptedPaymentPlanHeaderButtons({
await mutateExport({
variables: {
paymentPlanId: paymentPlan.id,
fspXlsxTemplateId: '',
},
});
showMessage(t('Exporting XLSX started'));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ export function ImportXlsxPaymentPlanPaymentListPerFsp({

return (
<>
{canUploadReconciliation && (
{canUploadReconciliation && paymentPlan.canSendToPaymentGateway && (
<Box key="import">
<Button
startIcon={
Expand Down
Original file line number Diff line number Diff line change
@@ -1,56 +1,72 @@
import { Box, Button } from '@mui/material';
import { GetApp } from '@mui/icons-material';
import { useTranslation } from 'react-i18next';
import { useSnackbar } from '@hooks/useSnackBar';
import { LoadingButton } from '../../../../core/LoadingButton';
import { CreateFollowUpPaymentPlan } from '../../../CreateFollowUpPaymentPlan';
import { useProgramContext } from '../../../../../programContext';
import { usePaymentPlanAction } from '../../../../../hooks/usePaymentPlanAction';
import React, { useState } from 'react';
import {
Action,
PaymentPlanBackgroundActionStatus,
PaymentPlanQuery,
useExportXlsxPpListPerFspMutation,
} from '../../../../../__generated__/graphql';
Box,
Dialog,
DialogActions,
DialogContent,
DialogTitle,
Button,
Select,
MenuItem,
} from '@mui/material';
import LoadingButton from '@mui/lab/LoadingButton';
import GetApp from '@mui/icons-material/GetApp';
import { Action } from '@generated/graphql';
import { LoadingComponent } from '@components/core/LoadingComponent';
import { CreateFollowUpPaymentPlan } from '@components/paymentmodule/CreateFollowUpPaymentPlan';
import { SplitIntoPaymentLists } from '../SplitIntoPaymentLists';
import { ReactElement } from 'react';

export interface AcceptedPaymentPlanHeaderButtonsProps {
canDownloadXlsx: boolean;
canExportXlsx: boolean;
canSendToPaymentGateway: boolean;
canSplit: boolean;
paymentPlan: PaymentPlanQuery['paymentPlan'];
}
import { useTranslation } from 'react-i18next';
import { usePermissions } from '@hooks/usePermissions';
import { hasPermissions, PERMISSIONS } from 'src/config/permissions';
import { usePaymentPlanAction } from '@hooks/usePaymentPlanAction';

export function AcceptedPaymentPlanHeaderButtons({
canDownloadXlsx,
canExportXlsx,
canSendToPaymentGateway,
canSplit,
export const AcceptedPaymentPlanHeaderButtons = ({
loadingExport,
isDisabledExportXlsx,
hasDownloadMtcnPermission,
mutateExport,
paymentPlan,
}: AcceptedPaymentPlanHeaderButtonsProps): ReactElement {
showMessage,
}) => {
const { t } = useTranslation();
const { showMessage } = useSnackbar();
const { isActiveProgram } = useProgramContext();
const [open, setOpen] = useState(false);
const [selectedTemplate, setSelectedTemplate] = useState('');
const permissions = usePermissions();
const { data, loading } = useAllFinancialServiceProviderXlsxTemplatesQuery();

Check failure on line 35 in src/frontend/src/components/paymentmodulepeople/PaymentPlanDetails/PaymentPlanDetailsHeader/HeaderButtons/AcceptedPaymentPlanHeaderButtons.tsx

View workflow job for this annotation

GitHub Actions / frontend_tests

'useAllFinancialServiceProviderXlsxTemplatesQuery' is not defined
const { mutatePaymentPlanAction: sendXlsxPassword, loading: loadingSend } =
usePaymentPlanAction(Action.SendXlsxPassword, paymentPlan.id, () =>
showMessage(t('Password has been sent.')),
);
const canSplit = hasPermissions(permissions, [PERMISSIONS.PM_SPLIT]);
if (loading) return <LoadingComponent />;
if (!data) return null;

const [mutateExport, { loading: loadingExport }] =
useExportXlsxPpListPerFspMutation();
const handleClickOpen = () => {
setOpen(true);
};

const {
mutatePaymentPlanAction: sendToPaymentGateway,
loading: LoadingSendToPaymentGateway,
} = usePaymentPlanAction(Action.SendToPaymentGateway, paymentPlan.id, () =>
showMessage(t('Sending to Payment Gateway started')),
);
const handleClose = () => {
setOpen(false);
};

const handleTemplateChange = (event) => {
setSelectedTemplate(event.target.value);
};

const shouldDisableExportXlsx =
loadingExport ||
!paymentPlan.hasFspDeliveryMechanismXlsxTemplate ||
!canExportXlsx ||
paymentPlan?.backgroundActionStatus ===
PaymentPlanBackgroundActionStatus.XlsxExporting ||
!isActiveProgram;
const handleExport = async () => {
try {
await mutateExport({
variables: {
paymentPlanId: paymentPlan.id,
template: selectedTemplate,
},
});
showMessage(t('Exporting XLSX started'));
handleClose();
} catch (e) {
e.graphQLErrors.map((x) => showMessage(x.message));
}
};

return (
<Box display="flex" alignItems="center">
Expand All @@ -66,65 +82,72 @@
canSplit={canSplit}
/>
</Box>
{!paymentPlan.hasPaymentListExportFile && (
<Box m={2}>
<Box m={2}>
{!paymentPlan.hasPaymentListExportFile && (
<LoadingButton
loading={loadingExport}
disabled={shouldDisableExportXlsx}
disabled={isDisabledExportXlsx || !hasDownloadMtcnPermission}
color="primary"
variant="contained"
startIcon={<GetApp />}
data-cy="button-export-xlsx"
onClick={async () => {
try {
await mutateExport({
variables: {
paymentPlanId: paymentPlan.id,
},
});
showMessage(t('Exporting XLSX started'));
} catch (e) {
e.graphQLErrors.map((x) => showMessage(x.message));
}
}}
onClick={handleClickOpen}
>
{t('Export Xlsx')}
</LoadingButton>
</Box>
)}
{paymentPlan.hasPaymentListExportFile && (
<Box m={2}>
<Button
color="primary"
component="a"
variant="contained"
data-cy="button-download-xlsx"
download
href={`/api/download-payment-plan-payment-list/${paymentPlan.id}`}
disabled={
!paymentPlan.hasFspDeliveryMechanismXlsxTemplate ||
!canDownloadXlsx
}
>
{t('Download XLSX')}
</Button>
</Box>
)}
{canSendToPaymentGateway && (
<Box m={2}>
<Button
type="button"
color="primary"
variant="contained"
onClick={() => sendToPaymentGateway()}
data-cy="button-send-to-payment-gateway"
disabled={LoadingSendToPaymentGateway}
>
{t('Send to FSP')}
</Button>
</Box>
)}
)}
<Dialog open={open} onClose={handleClose}>
<DialogTitle>{t('Select Template')}</DialogTitle>
<DialogContent>
<Select
value={selectedTemplate}
onChange={handleTemplateChange}
fullWidth
variant="outlined"
size="small"
data-cy="select-template"
>
{data.allFinancialServiceProviderXlsxTemplates.edges.map(
({ node }) => (
<MenuItem key={node.id} value={node.id}>
{node.name}
</MenuItem>
),
)}
</Select>
</DialogContent>
<DialogActions>
<Button
data-cy="cancel-button"
onClick={handleClose}
color="primary"
>
{t('Cancel')}
</Button>
<Button
onClick={handleExport}
data-cy="export-button"
color="primary"
disabled={!selectedTemplate}
>
{t('Export Xlsx')}
</Button>
</DialogActions>
</Dialog>
</Box>
<Box m={2}>
<LoadingButton
loading={loadingSend}
disabled={loadingSend}
color="primary"
variant="contained"
data-cy="button-send-xlsx-password"
onClick={() => sendXlsxPassword()}
>
{t('Send Xlsx Password')}
</LoadingButton>
</Box>
</>
</Box>
);
}
};
3 changes: 3 additions & 0 deletions src/frontend/src/config/permissions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,9 @@ export const PERMISSIONS = {
PM_PROGRAMME_CYCLE_UPDATE: 'PM_PROGRAMME_CYCLE_UPDATE',
PM_PROGRAMME_CYCLE_DELETE: 'PM_PROGRAMME_CYCLE_DELETE',

PM_DOWNLOAD_MTCN: 'PM_DOWNLOAD_MTCN',
PM_SEND_XLSX_PASSWORD: 'PM_SEND_XLSX_PASSWORD',

// Targeting
TARGETING_VIEW_LIST: 'TARGETING_VIEW_LIST',
TARGETING_VIEW_DETAILS: 'TARGETING_VIEW_DETAILS',
Expand Down
3 changes: 2 additions & 1 deletion src/frontend/src/utils/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -910,5 +910,6 @@
"If displayed exchange rate differs from Vision, please contact your designated focal point for resolution. If displayed exchange rate differs from Vision, please contact your designated focal point for resolution": "If displayed exchange rate differs from Vision, please contact your designated focal point for resolution",
"View Biometrics Results": "View Biometrics Results",
"Individual Delivery Mechanisms": "Individual Delivery Mechanisms",
"Beneficiary Group": "Beneficiary Group"
"Beneficiary Group": "Beneficiary Group",
"Password has been sent.": "Password has been sent."
}
Loading
Loading