Skip to content
Merged
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
2 changes: 2 additions & 0 deletions src/languages/de.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3260,6 +3260,8 @@ ${amount} für ${merchant} – ${date}`,
defaultWorkflowApproverNotWorkspaceMember: 'Diese genehmigende Person ist nicht mehr Mitglied des Arbeitsbereichs. Wählen Sie eine neue genehmigende Person.',
overLimitApproverNotWorkspaceMember:
'Die zusätzliche genehmigende Person für Berichte über dem Limit ist nicht mehr Mitglied des Arbeitsbereichs. Wählen Sie eine neue zusätzliche genehmigende Person.',
overLimitApproverInWorkflow:
'Die zusätzliche Genehmigungsperson für Berichte über dem Limit ist bereits eine Genehmigungsperson in diesem Workflow. Wählen Sie eine andere zusätzliche Genehmigungsperson.',
Comment thread
Gonals marked this conversation as resolved.
Resolved
approverCircularReference: (name1: string, name2: string) =>
`<strong>${name1}</strong> genehmigt bereits Berichte für <strong>${name2}</strong>. Bitte wähle eine andere approvierende Person, um einen zirkulären Workflow zu vermeiden.`,
emptyContent: {
Expand Down
1 change: 1 addition & 0 deletions src/languages/el.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3319,6 +3319,7 @@ ${amount} για ${merchant} - ${date}`,
approverNotWorkspaceMember: 'Αυτός ο εγκρίνων δεν είναι πλέον μέλος του χώρου εργασίας. Επιλέξτε νέο εγκρίνοντα ή διαγράψτε αυτή τη ροή εργασίας.',
defaultWorkflowApproverNotWorkspaceMember: 'Αυτός ο εγκρίνων δεν είναι πλέον μέλος του χώρου εργασίας. Επιλέξτε νέο εγκρίνοντα.',
overLimitApproverNotWorkspaceMember: 'Ο πρόσθετος εγκρίνων για αναφορές πάνω από το όριο δεν είναι πλέον μέλος του χώρου εργασίας. Επιλέξτε νέο πρόσθετο εγκρίνοντα.',
overLimitApproverInWorkflow: 'Ο επιπλέον εγκρίνων για αναφορές πάνω από το όριο είναι ήδη εγκρίνων σε αυτή τη ροή εργασίας. Επιλέξτε έναν διαφορετικό επιπλέον εγκρίνοντα.',
Comment thread
Gonals marked this conversation as resolved.
Resolved
approverCircularReference: (name1: string, name2: string) =>
`Ο/Η <strong>${name1}</strong> ήδη εγκρίνει αναφορές προς τον/την <strong>${name2}</strong>. Παρακαλούμε επιλέξτε διαφορετικό εγκρίνων για να αποφύγετε έναν κυκλικό κύκλο έγκρισης.`,
emptyContent: {
Expand Down
1 change: 1 addition & 0 deletions src/languages/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3413,6 +3413,7 @@ const translations = {
approverNotWorkspaceMember: 'This approver is no longer a workspace member. Choose a new approver or delete this workflow.',
defaultWorkflowApproverNotWorkspaceMember: 'This approver is no longer a workspace member. Choose a new approver.',
overLimitApproverNotWorkspaceMember: 'The additional approver for reports over the limit is no longer a workspace member. Choose a new additional approver.',
overLimitApproverInWorkflow: 'The additional approver for reports over the limit is already an approver in this workflow. Choose a different additional approver.',
approverCircularReference: (name1: string, name2: string) =>
`<strong>${name1}</strong> already approves reports to <strong>${name2}</strong>. Please choose a different approver to avoid a circular workflow.`,
emptyContent: {
Expand Down
1 change: 1 addition & 0 deletions src/languages/es.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3156,6 +3156,7 @@ ${amount} para ${merchant} - ${date}`,
approverNotWorkspaceMember: 'Este aprobador ya no es miembro del espacio de trabajo. Elige un nuevo aprobador o elimina este flujo de trabajo.',
defaultWorkflowApproverNotWorkspaceMember: 'Este aprobador ya no es miembro del espacio de trabajo. Elige un nuevo aprobador.',
overLimitApproverNotWorkspaceMember: 'El aprobador adicional para los informes que superan el límite ya no es miembro del espacio de trabajo. Elige un nuevo aprobador adicional.',
overLimitApproverInWorkflow: 'El aprobador adicional para los informes que superan el límite ya es un aprobador en este flujo de trabajo. Elige un aprobador adicional diferente.',
approverCircularReference: (name1, name2) =>
`<strong>${name1}</strong> ya aprueba informes a <strong>${name2}</strong>. Por favor, elige un aprobador diferente para evitar un flujo de trabajo circular.`,
emptyContent: {
Expand Down
2 changes: 2 additions & 0 deletions src/languages/fr.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3265,6 +3265,8 @@ ${amount} pour ${merchant} - ${date}`,
defaultWorkflowApproverNotWorkspaceMember: 'Cet approbateur n’est plus membre de l’espace de travail. Choisissez un nouvel approbateur.',
overLimitApproverNotWorkspaceMember:
'L’approbateur supplémentaire pour les notes de frais au-delà de la limite n’est plus membre de l’espace de travail. Choisissez un nouvel approbateur supplémentaire.',
overLimitApproverInWorkflow:
'L’approbateur supplémentaire pour les notes de frais dépassant la limite est déjà un approbateur dans ce flux de travail. Choisissez un autre approbateur supplémentaire.',
Comment thread
Gonals marked this conversation as resolved.
Resolved
approverCircularReference: (name1: string, name2: string) =>
`<strong>${name1}</strong> approuve déjà les notes de frais de <strong>${name2}</strong>. Veuillez choisir un autre approbateur pour éviter un circuit d'approbation circulaire.`,
emptyContent: {
Expand Down
1 change: 1 addition & 0 deletions src/languages/it.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3245,6 +3245,7 @@ ${amount} per ${merchant} - ${date}`,
approverNotWorkspaceMember: 'Questo approvatore non è più un membro dello spazio di lavoro. Scegli un nuovo approvatore oppure elimina questo workflow.',
defaultWorkflowApproverNotWorkspaceMember: 'Questo approvatore non è più un membro dello spazio di lavoro. Scegli un nuovo approvatore.',
overLimitApproverNotWorkspaceMember: 'L’approvatore aggiuntivo per i report oltre il limite non è più un membro dello spazio di lavoro. Scegli un nuovo approvatore aggiuntivo.',
overLimitApproverInWorkflow: 'L’approvatore aggiuntivo per i report oltre il limite è già un approvatore in questo workflow. Scegli un altro approvatore aggiuntivo.',
approverCircularReference: (name1: string, name2: string) =>
`<strong>${name1}</strong> approva già i report per <strong>${name2}</strong>. Scegli un altro approvatore per evitare un flusso di lavoro circolare.`,
emptyContent: {
Expand Down
1 change: 1 addition & 0 deletions src/languages/ja.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3220,6 +3220,7 @@ ${date} の ${merchant} への ${amount}`,
approverNotWorkspaceMember: 'この承認者はワークスペースのメンバーではなくなりました。新しい承認者を選択するか、このワークフローを削除してください。',
defaultWorkflowApproverNotWorkspaceMember: 'この承認者はワークスペースのメンバーではなくなりました。新しい承認者を選択してください。',
overLimitApproverNotWorkspaceMember: '上限を超えるレポートの追加承認者は、ワークスペースのメンバーではなくなりました。新しい追加承認者を選択してください。',
overLimitApproverInWorkflow: '上限を超えるレポートの追加承認者として選択されたユーザーは、このワークフロー内ですでに承認者になっています。別の追加承認者を選択してください。',
Comment thread
Gonals marked this conversation as resolved.
Resolved
approverCircularReference: (name1: string, name2: string) =>
`<strong>${name1}</strong> はすでに <strong>${name2}</strong> にレポートを承認しています。ワークフローが循環しないよう、別の承認者を選択してください。`,
emptyContent: {
Expand Down
1 change: 1 addition & 0 deletions src/languages/nl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3248,6 +3248,7 @@ ${amount} voor ${merchant} - ${date}`,
approverNotWorkspaceMember: 'Deze fiatteur is geen lid meer van de workspace. Kies een nieuwe fiatteur of verwijder deze workflow.',
defaultWorkflowApproverNotWorkspaceMember: 'Deze fiatteur is geen lid meer van de workspace. Kies een nieuwe fiatteur.',
overLimitApproverNotWorkspaceMember: 'De extra fiatteur voor rapporten boven de limiet is geen lid meer van de workspace. Kies een nieuwe extra fiatteur.',
overLimitApproverInWorkflow: 'De extra fiatteur voor rapporten boven de limiet is al een fiatteur in deze workflow. Kies een andere extra fiatteur.',
approverCircularReference: (name1: string, name2: string) =>
`<strong>${name1}</strong> keurt al rapporten goed voor <strong>${name2}</strong>. Kies een andere fiatteur om een cirkelstroom te voorkomen.`,
emptyContent: {
Expand Down
1 change: 1 addition & 0 deletions src/languages/pl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3281,6 +3281,7 @@ ${amount} dla ${merchant} - ${date}`,
approverNotWorkspaceMember: 'Ten zatwierdzający nie jest już członkiem tego workspace’u. Wybierz nowego zatwierdzającego albo usuń ten workflow.',
defaultWorkflowApproverNotWorkspaceMember: 'Ten zatwierdzający nie jest już członkiem tego workspace’u. Wybierz nowego zatwierdzającego.',
overLimitApproverNotWorkspaceMember: 'Dodatkowy zatwierdzający dla raportów powyżej limitu nie jest już członkiem tego workspace’u. Wybierz nowego dodatkowego zatwierdzającego.',
overLimitApproverInWorkflow: 'Dodatkowy akceptujący dla raportów powyżej limitu jest już akceptującym w tym przepływie pracy. Wybierz innego dodatkowego akceptującego.',
Comment thread
Gonals marked this conversation as resolved.
Resolved
approverCircularReference: (name1: string, name2: string) =>
`<strong>${name1}</strong> już zatwierdza raporty dla <strong>${name2}</strong>. Wybierz innego zatwierdzającego, aby uniknąć zapętlenia przepływu pracy.`,
emptyContent: {
Expand Down
1 change: 1 addition & 0 deletions src/languages/pt-BR.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3238,6 +3238,7 @@ ${amount} para ${merchant} - ${date}`,
approverNotWorkspaceMember: 'Esse aprovador não é mais membro do workspace. Escolha um novo aprovador ou exclua este fluxo de trabalho.',
defaultWorkflowApproverNotWorkspaceMember: 'Esse aprovador não é mais membro do workspace. Escolha um novo aprovador.',
overLimitApproverNotWorkspaceMember: 'O aprovador adicional para relatórios acima do limite não é mais membro do workspace. Escolha um novo aprovador adicional.',
overLimitApproverInWorkflow: 'O aprovador adicional para relatórios acima do limite já é um aprovador neste fluxo de trabalho. Escolha um aprovador adicional diferente.',
approverCircularReference: (name1: string, name2: string) =>
`<strong>${name1}</strong> já aprova relatórios para <strong>${name2}</strong>. Escolha um aprovador diferente para evitar um fluxo de aprovação circular.`,
emptyContent: {
Expand Down
1 change: 1 addition & 0 deletions src/languages/zh-hans.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3145,6 +3145,7 @@ ${amount},商户:${merchant} - 日期:${date}`,
approverNotWorkspaceMember: '此审批人已不再是工作区成员。请选择新的审批人或删除此工作流程。',
defaultWorkflowApproverNotWorkspaceMember: '此审批人已不再是工作区成员。请选择新的审批人。',
overLimitApproverNotWorkspaceMember: '超出限额报告的额外审批人已不再是工作区成员。请选择新的额外审批人。',
overLimitApproverInWorkflow: '此限额以上报表的额外审批人已是此工作流中的审批人。请选择其他额外审批人。',
Comment thread
Gonals marked this conversation as resolved.
Resolved
approverCircularReference: (name1: string, name2: string) => `<strong>${name1}</strong> 已经将报表提交给 <strong>${name2}</strong> 审批。请选择其他审批人以避免形成循环审批流程。`,
emptyContent: {
title: '没有可显示的成员',
Expand Down
12 changes: 11 additions & 1 deletion src/libs/actions/Workflow.ts
Original file line number Diff line number Diff line change
Expand Up @@ -754,9 +754,10 @@ type ApprovalWorkflowOnyxValidated = Omit<ApprovalWorkflowOnyx, 'approvers'> & {
/**
* Validates the approval workflow and sets the errors on the approval workflow
* @param approvalWorkflow the approval workflow to validate
* @param isMultipleApproversBetaEnabled whether the `MULTIPLE_APPROVERS` beta is enabled, which saves the workflow as approval workflow rules
* @returns true if the approval workflow is valid, false otherwise
*/
function validateApprovalWorkflow(approvalWorkflow: ApprovalWorkflowOnyx): approvalWorkflow is ApprovalWorkflowOnyxValidated {
function validateApprovalWorkflow(approvalWorkflow: ApprovalWorkflowOnyx, isMultipleApproversBetaEnabled: boolean): approvalWorkflow is ApprovalWorkflowOnyxValidated {
const errors: Record<string, TranslationPaths> = {};

for (const [approverIndex, approver] of approvalWorkflow.approvers.entries()) {
Expand All @@ -773,6 +774,15 @@ function validateApprovalWorkflow(approvalWorkflow: ApprovalWorkflowOnyx): appro
errors[`approver-${approverIndex}`] = nonMemberApproverError;
}

// Someone who already approves in this workflow approves every report anyway, so the limit can't add them
if (
isMultipleApproversBetaEnabled &&
approver?.overLimitForwardsTo &&
approvalWorkflow.approvers.some((workflowApprover) => workflowApprover?.email === approver.overLimitForwardsTo)
) {
errors[`approver-${approverIndex}`] = 'workflowsPage.overLimitApproverInWorkflow';
}
Comment thread
Gonals marked this conversation as resolved.
Resolved

// Validate that if overLimitForwardsTo is set, approvalLimit must also be set
if (approver?.overLimitForwardsTo && (!approver?.approvalLimit || approver.approvalLimit <= 0)) {
errors[`approver-${approverIndex}`] = 'workflowsApprovalLimitPage.enterAmountError';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,12 @@ function WorkspaceWorkflowsApprovalsApproverPage({policy, personalDetails, isLoa
if (isEmailAlreadyInApprovers && visibleSelectedApproverEmail !== email) {
return null;
}

// Another step's additional approver can't also approve here, or that step's limit would add no one
const isOtherStepsAdditionalApprover = approversFromWorkflow?.some((approver, index) => approver?.overLimitForwardsTo === email && index !== approverIndex);
if (isMultipleApproversBetaEnabled && isOtherStepsAdditionalApprover && visibleSelectedApproverEmail !== email) {
return null;
}
if (!isMultipleApproversBetaEnabled && !isDefault && approverIndex === 0 && defaultApprover === email) {
return null;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ function WorkspaceWorkflowsApprovalsCreatePage({policy, isLoadingReportData = tr
return;
}

if (!validateApprovalWorkflow(approvalWorkflow)) {
if (!validateApprovalWorkflow(approvalWorkflow, isBetaEnabled(CONST.BETAS.MULTIPLE_APPROVERS))) {
return;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ function WorkspaceWorkflowsApprovalsEditPage({policy, isLoadingReportData = true
return;
}

if (!validateApprovalWorkflow(approvalWorkflow)) {
if (!validateApprovalWorkflow(approvalWorkflow, isBetaEnabled(CONST.BETAS.MULTIPLE_APPROVERS))) {
Comment thread
Gonals marked this conversation as resolved.
Resolved
return;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import useCurrentUserPersonalDetails from '@hooks/useCurrentUserPersonalDetails'
import {useMemoizedLazyExpensifyIcons} from '@hooks/useLazyAsset';
import useLocalize from '@hooks/useLocalize';
import useOnyx from '@hooks/useOnyx';
import usePermissions from '@hooks/usePermissions';
import {usePersonalDetailsByLogins} from '@hooks/usePersonalDetailByLogin';
import usePersonalDetailsByEmail from '@hooks/usePersonalDetailsByEmail';
import useThemeStyles from '@hooks/useThemeStyles';
Expand Down Expand Up @@ -42,6 +43,8 @@ function WorkspaceWorkflowsApprovalsOverLimitApproverPage({policy, personalDetai
const personalDetailsByEmail = usePersonalDetailsByEmail();
const employeePersonalDetails = usePersonalDetailsByLogins(Object.keys(policy?.employeeList ?? {}));
const {login: currentUserLogin = ''} = useCurrentUserPersonalDetails();
const {isBetaEnabled} = usePermissions();
const isMultipleApproversBetaEnabled = isBetaEnabled(CONST.BETAS.MULTIPLE_APPROVERS);
const expensifyIcons = useMemoizedLazyExpensifyIcons(['FallbackAvatar']);

const policyID = route.params.policyID;
Expand All @@ -51,6 +54,7 @@ function WorkspaceWorkflowsApprovalsOverLimitApproverPage({policy, personalDetai
const employeeList = policy?.employeeList;
const isDefault = approvalWorkflow?.isDefault;
const membersEmail = approvalWorkflow?.members.map((member) => member.email);
const workflowApproverEmails = new Set(approvalWorkflow?.approvers?.map((approver) => approver?.email));

const currentApproverEmail = currentApprover?.email;

Expand Down Expand Up @@ -88,6 +92,11 @@ function WorkspaceWorkflowsApprovalsOverLimitApproverPage({policy, personalDetai
return null;
}

// Someone who already approves in this workflow approves every report anyway, so the limit can't add them
if (isMultipleApproversBetaEnabled && workflowApproverEmails.has(email)) {
return null;
}

const accountID = Number(policyMemberEmailsToAccountIDs[email] ?? '');
if (!accountID) {
return null;
Expand Down
Loading
Loading