Skip to content

Commit db327d0

Browse files
Merge pull request Expensify#89454 from Expensify/claude-smartscanFieldSpecificMessages
[Payment due @dukenv0307] Show field-specific SmartScan failure messages
2 parents 40223f2 + 1c7073e commit db327d0

15 files changed

Lines changed: 164 additions & 18 deletions

File tree

src/components/ReportActionItem/MoneyRequestReceiptView.tsx

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -187,14 +187,15 @@ function MoneyRequestReceiptView({
187187
}
188188
}, [isLoading, hoverBind]);
189189

190-
const prevSource = usePrevious(transaction?.receipt?.source);
190+
const displayedReceiptSource = transaction?.receipt?.localSource ?? transaction?.receipt?.source;
191+
const prevDisplayedReceiptSource = usePrevious(displayedReceiptSource);
191192

192193
useEffect(() => {
193-
if (!transaction?.receipt?.source || prevSource === transaction?.receipt?.source) {
194+
if (!displayedReceiptSource || prevDisplayedReceiptSource === displayedReceiptSource) {
194195
return;
195196
}
196197
setIsLoading(true);
197-
}, [transaction?.receipt?.source, prevSource]);
198+
}, [displayedReceiptSource, prevDisplayedReceiptSource]);
198199

199200
// Flags for allowing or disallowing editing an expense
200201
// Used for non-restricted fields such as: description, category, tag, billable, etc...

src/languages/de.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8602,7 +8602,16 @@ Fügen Sie weitere Ausgabelimits hinzu, um den Cashflow Ihres Unternehmens zu sc
86028602
`<muted-text-label>Beleg ausstehend wegen unterbrochener Bankverbindung. Bitte in <a href="${workspaceCompanyCardRoute}">Firmenkarten</a> beheben.</muted-text-label>`,
86038603
memberBrokenConnectionError: 'Beleg ausstehend aufgrund einer unterbrochenen Bankverbindung. Bitte wende dich an eine Workspace-Admin, um das Problem zu beheben.',
86048604
markAsCashToIgnore: 'Als Barzahlung markieren, um sie zu ignorieren und Zahlung anzufordern.',
8605-
smartscanFailed: ({canEdit = true}) => `Beleg-Scan fehlgeschlagen.${canEdit ? 'Details manuell eingeben.' : ''}`,
8605+
smartscanFailed: ({canEdit = true, missingFields = []}: {canEdit?: boolean; missingFields?: string[]}) => {
8606+
if (missingFields.length > 0) {
8607+
const fieldNames: Record<string, string> = {merchant: 'Händler', date: 'Datum', amount: 'Betrag'};
8608+
const translated = missingFields.map((f) => fieldNames[f] ?? f);
8609+
const fieldList = translated.join(translated.length > 2 ? ', ' : ' und ');
8610+
const verb = translated.length === 1 ? 'fehlt' : 'fehlen';
8611+
return `Beleg-Scan fehlgeschlagen — ${fieldList} ${verb}.${canEdit ? ' Details manuell eingeben.' : ''}`;
8612+
}
8613+
return `Beleg-Scan fehlgeschlagen.${canEdit ? 'Details manuell eingeben.' : ''}`;
8614+
},
86068615
receiptGeneratedWithAI: 'Mögliche KI-generierte Quittung',
86078616
someTagLevelsRequired: (tagName?: string) => `Fehlende ${tagName ?? 'Tag'}`,
86088617
tagOutOfPolicy: (tagName?: string) => `${tagName ?? 'Tag'} nicht mehr gültig`,

src/languages/en.ts

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8624,7 +8624,22 @@ const translations = {
86248624
`<muted-text-label>Receipt pending due to broken bank connection. Please resolve in <a href="${workspaceCompanyCardRoute}">Company cards</a>.</muted-text-label>`,
86258625
memberBrokenConnectionError: 'Receipt pending due to broken bank connection. Please ask a workspace admin to resolve.',
86268626
markAsCashToIgnore: 'Mark as cash to ignore and request payment.',
8627-
smartscanFailed: ({canEdit = true}) => `Receipt scanning failed.${canEdit ? ' Enter details manually.' : ''}`,
8627+
smartscanFailed: ({canEdit = true, missingFields = []}: {canEdit?: boolean; missingFields?: string[]}) => {
8628+
if (missingFields.length > 0) {
8629+
const fieldNames: Record<string, string> = {merchant: 'merchant', date: 'date', amount: 'amount'};
8630+
const translated = missingFields.map((f) => fieldNames[f] ?? f);
8631+
let fieldList = '';
8632+
if (translated.length === 1) {
8633+
fieldList = translated.at(0) ?? '';
8634+
} else if (translated.length === 2) {
8635+
fieldList = translated.join(' and ');
8636+
} else {
8637+
fieldList = `${translated.slice(0, translated.length - 1).join(', ')}, and ${translated.at(-1)}`;
8638+
}
8639+
return `Receipt scanning failed — missing ${fieldList}.${canEdit ? ' Enter details manually.' : ''}`;
8640+
}
8641+
return `Receipt scanning failed.${canEdit ? ' Enter details manually.' : ''}`;
8642+
},
86288643
receiptGeneratedWithAI: 'Potential AI-generated receipt',
86298644
someTagLevelsRequired: (tagName?: string) => `Missing ${tagName ?? 'Tag'}`,
86308645
tagOutOfPolicy: (tagName?: string) => `${tagName ?? 'Tag'} no longer valid`,

src/languages/es.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8773,7 +8773,16 @@ ${amount} para ${merchant} - ${date}`,
87738773
`<muted-text-label>Recibo pendiente debido a una conexión bancaria rota. Por favor, resuélvelo en <a href="${workspaceCompanyCardRoute}">Tarjetas de empresa</a>.</muted-text-label>`,
87748774
memberBrokenConnectionError: 'Recibo pendiente debido a una conexión bancaria rota. Por favor, pide a un administrador del espacio de trabajo que lo resuelva.',
87758775
markAsCashToIgnore: 'Márcalo como efectivo para ignorar y solicitar el pago.',
8776-
smartscanFailed: ({canEdit = true}) => `No se pudo escanear el recibo.${canEdit ? ' Introduce los datos manualmente.' : ''}`,
8776+
smartscanFailed: ({canEdit = true, missingFields = []}: {canEdit?: boolean; missingFields?: string[]}) => {
8777+
if (missingFields.length > 0) {
8778+
const fieldNames: Record<string, string> = {merchant: 'comerciante', date: 'fecha', amount: 'importe'};
8779+
const translated = missingFields.map((f) => fieldNames[f] ?? f);
8780+
const fieldList = translated.join(translated.length > 2 ? ', ' : ' y ');
8781+
const verb = translated.length === 1 ? 'falta' : 'faltan';
8782+
return `No se pudo escanear el recibo — ${verb} ${fieldList}.${canEdit ? ' Introduce los datos manualmente.' : ''}`;
8783+
}
8784+
return `No se pudo escanear el recibo.${canEdit ? ' Introduce los datos manualmente.' : ''}`;
8785+
},
87778786
receiptGeneratedWithAI: 'Posible recibo generado por IA',
87788787
someTagLevelsRequired: (tagName) => `Falta ${tagName ?? 'Tag'}`,
87798788
tagOutOfPolicy: (tagName) => `La etiqueta ${tagName ? `${tagName} ` : ''}ya no es válida`,

src/languages/fr.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8625,7 +8625,15 @@ Ajoutez davantage de règles de dépenses pour protéger la trésorerie de l’e
86258625
`<muted-text-label>Reçu en attente en raison d’une connexion bancaire rompue. Veuillez résoudre le problème dans les <a href="${workspaceCompanyCardRoute}">Cartes d’entreprise</a>.</muted-text-label>`,
86268626
memberBrokenConnectionError: 'Reçu en attente en raison d’une connexion bancaire rompue. Veuillez demander à un administrateur de l’espace de travail de résoudre le problème.',
86278627
markAsCashToIgnore: 'Marquer comme paiement en espèces pour l’ignorer et demander un paiement.',
8628-
smartscanFailed: ({canEdit = true}) => `L’analyse du reçu a échoué.${canEdit ? 'Saisir les détails manuellement.' : ''}`,
8628+
smartscanFailed: ({canEdit = true, missingFields = []}: {canEdit?: boolean; missingFields?: string[]}) => {
8629+
if (missingFields.length > 0) {
8630+
const fieldNames: Record<string, string> = {merchant: 'commerçant', date: 'date', amount: 'montant'};
8631+
const translated = missingFields.map((f) => fieldNames[f] ?? f);
8632+
const fieldList = translated.join(translated.length > 2 ? ', ' : ' et ');
8633+
return `L’analyse du reçu a échoué — champ(s) manquant(s) : ${fieldList}.${canEdit ? ' Saisir les détails manuellement.' : ''}`;
8634+
}
8635+
return `L’analyse du reçu a échoué.${canEdit ? 'Saisir les détails manuellement.' : ''}`;
8636+
},
86298637
receiptGeneratedWithAI: 'Reçu potentiellement généré par IA',
86308638
someTagLevelsRequired: (tagName?: string) => `${tagName ?? 'Tag'} manquant`,
86318639
tagOutOfPolicy: (tagName?: string) => `${tagName ?? 'Tag'} n’est plus valide`,

src/languages/it.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8594,7 +8594,16 @@ Aggiungi altre regole di spesa per proteggere il flusso di cassa aziendale.`,
85948594
`<muted-text-label>Ricevuta in sospeso a causa di un collegamento bancario interrotto. Risolvi il problema in <a href="${workspaceCompanyCardRoute}">Carte aziendali</a>.</muted-text-label>`,
85958595
memberBrokenConnectionError: 'Ricevuta in sospeso a causa di un collegamento bancario interrotto. Chiedi a un amministratore dello spazio di lavoro di risolvere il problema.',
85968596
markAsCashToIgnore: 'Segna come contante da ignorare e richiedi il pagamento.',
8597-
smartscanFailed: ({canEdit = true}) => `Scansione della ricevuta non riuscita.${canEdit ? 'Inserisci i dettagli manualmente.' : ''}`,
8597+
smartscanFailed: ({canEdit = true, missingFields = []}: {canEdit?: boolean; missingFields?: string[]}) => {
8598+
if (missingFields.length > 0) {
8599+
const fieldNames: Record<string, string> = {merchant: 'esercente', date: 'data', amount: 'importo'};
8600+
const translated = missingFields.map((f) => fieldNames[f] ?? f);
8601+
const fieldList = translated.join(translated.length > 2 ? ', ' : ' e ');
8602+
const verb = translated.length === 1 ? 'mancante' : 'mancanti';
8603+
return `Scansione della ricevuta non riuscita — ${fieldList} ${verb}.${canEdit ? ' Inserisci i dettagli manualmente.' : ''}`;
8604+
}
8605+
return `Scansione della ricevuta non riuscita.${canEdit ? 'Inserisci i dettagli manualmente.' : ''}`;
8606+
},
85988607
receiptGeneratedWithAI: 'Ricevuta potenzialmente generata dall’IA',
85998608
someTagLevelsRequired: (tagName?: string) => `Manca ${tagName ?? 'Etichetta'}`,
86008609
tagOutOfPolicy: (tagName?: string) => `${tagName ?? 'Etichetta'} non è più valido`,

src/languages/ja.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8488,7 +8488,15 @@ ${reportName}
84888488
`<muted-text-label>銀行接続の不具合により領収書が保留されています。<a href="${workspaceCompanyCardRoute}">会社カード</a>で解決してください。</muted-text-label>`,
84898489
memberBrokenConnectionError: '銀行連携の不具合により領収書が保留されています。ワークスペース管理者に対応を依頼してください。',
84908490
markAsCashToIgnore: '現金としてマークして無視し、支払いをリクエストします。',
8491-
smartscanFailed: ({canEdit = true}) => `レシートのスキャンに失敗しました。${canEdit ? '詳細を手動で入力してください。' : ''}`,
8491+
smartscanFailed: ({canEdit = true, missingFields = []}: {canEdit?: boolean; missingFields?: string[]}) => {
8492+
if (missingFields.length > 0) {
8493+
const fieldNames: Record<string, string> = {merchant: '加盟店', date: '日付', amount: '金額'};
8494+
const translated = missingFields.map((f) => fieldNames[f] ?? f);
8495+
const fieldList = translated.join('、');
8496+
return `レシートのスキャンに失敗しました — ${fieldList}が見つかりません。${canEdit ? '詳細を手動で入力してください。' : ''}`;
8497+
}
8498+
return `レシートのスキャンに失敗しました。${canEdit ? '詳細を手動で入力してください。' : ''}`;
8499+
},
84928500
receiptGeneratedWithAI: 'AI生成の可能性があるレシート',
84938501
someTagLevelsRequired: (tagName?: string) => `${tagName ?? 'タグ'} が見つかりません`,
84948502
tagOutOfPolicy: (tagName?: string) => `${tagName ?? 'タグ'} は無効になりました`,

src/languages/nl.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8565,7 +8565,16 @@ er bestedingsregels toe om de kasstroom van het bedrijf te beschermen.`,
85658565
`<muted-text-label>Bon in behandeling vanwege een verbroken bankverbinding. Los dit op in <a href="${workspaceCompanyCardRoute}">Bedrijfspassen</a>.</muted-text-label>`,
85668566
memberBrokenConnectionError: 'Bon wordt vastgehouden vanwege een verbroken bankkoppeling. Vraag een werkruimtebeheerder om dit op te lossen.',
85678567
markAsCashToIgnore: 'Markeren als contant om te negeren en betaling aan te vragen.',
8568-
smartscanFailed: ({canEdit = true}) => `Bon scannen mislukt.${canEdit ? 'Voer gegevens handmatig in.' : ''}`,
8568+
smartscanFailed: ({canEdit = true, missingFields = []}: {canEdit?: boolean; missingFields?: string[]}) => {
8569+
if (missingFields.length > 0) {
8570+
const fieldNames: Record<string, string> = {merchant: 'handelaar', date: 'datum', amount: 'bedrag'};
8571+
const translated = missingFields.map((f) => fieldNames[f] ?? f);
8572+
const fieldList = translated.join(translated.length > 2 ? ', ' : ' en ');
8573+
const verb = translated.length === 1 ? 'ontbreekt' : 'ontbreken';
8574+
return `Bon scannen mislukt — ${fieldList} ${verb}.${canEdit ? ' Voer gegevens handmatig in.' : ''}`;
8575+
}
8576+
return `Bon scannen mislukt.${canEdit ? 'Voer gegevens handmatig in.' : ''}`;
8577+
},
85698578
receiptGeneratedWithAI: 'Mogelijke AI-gegenereerde bon',
85708579
someTagLevelsRequired: (tagName?: string) => `Ontbreekt ${tagName ?? 'Label'}`,
85718580
tagOutOfPolicy: (tagName?: string) => `${tagName ?? 'Label'} niet meer geldig`,

src/languages/pl.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8551,7 +8551,15 @@ Dodaj więcej zasad wydatków, żeby chronić płynność finansową firmy.`,
85518551
`<muted-text-label>Oczekuje na rachunek z powodu przerwanego połączenia z bankiem. Rozwiąż problem w sekcji <a href="${workspaceCompanyCardRoute}">Karty firmowe</a>.</muted-text-label>`,
85528552
memberBrokenConnectionError: 'Paragon oczekuje z powodu zerwanego połączenia z bankiem. Poproś administratora przestrzeni roboczej o rozwiązanie problemu.',
85538553
markAsCashToIgnore: 'Oznacz jako gotówkę, aby zignorować i poprosić o płatność.',
8554-
smartscanFailed: ({canEdit = true}) => `Skanowanie paragonu nie powiodło się.${canEdit ? 'Wpisz szczegóły ręcznie.' : ''}`,
8554+
smartscanFailed: ({canEdit = true, missingFields = []}: {canEdit?: boolean; missingFields?: string[]}) => {
8555+
if (missingFields.length > 0) {
8556+
const fieldNames: Record<string, string> = {merchant: 'sprzedawcy', date: 'daty', amount: 'kwoty'};
8557+
const translated = missingFields.map((f) => fieldNames[f] ?? f);
8558+
const fieldList = translated.join(translated.length > 2 ? ', ' : ' i ');
8559+
return `Skanowanie paragonu nie powiodło się — brak ${fieldList}.${canEdit ? ' Wpisz szczegóły ręcznie.' : ''}`;
8560+
}
8561+
return `Skanowanie paragonu nie powiodło się.${canEdit ? 'Wpisz szczegóły ręcznie.' : ''}`;
8562+
},
85558563
receiptGeneratedWithAI: 'Potencjalny paragon wygenerowany przez AI',
85568564
someTagLevelsRequired: (tagName?: string) => `Brak ${tagName ?? 'Tag'}`,
85578565
tagOutOfPolicy: (tagName?: string) => `${tagName ?? 'Tag'} nie jest już ważny`,

src/languages/pt-BR.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8558,7 +8558,15 @@ Adicione mais regras de gasto para proteger o fluxo de caixa da empresa.`,
85588558
`<muted-text-label>Recibo pendente devido a uma conexão bancária interrompida. Resolva em <a href="${workspaceCompanyCardRoute}">Cartões corporativos</a>.</muted-text-label>`,
85598559
memberBrokenConnectionError: 'Recibo pendente devido à conexão bancária com problemas. Peça a um administrador do workspace para resolver.',
85608560
markAsCashToIgnore: 'Marcar como dinheiro para ignorar e solicitar pagamento.',
8561-
smartscanFailed: ({canEdit = true}) => `A digitalização do recibo falhou.${canEdit ? 'Insira os detalhes manualmente.' : ''}`,
8561+
smartscanFailed: ({canEdit = true, missingFields = []}: {canEdit?: boolean; missingFields?: string[]}) => {
8562+
if (missingFields.length > 0) {
8563+
const fieldNames: Record<string, string> = {merchant: 'estabelecimento', date: 'data', amount: 'valor'};
8564+
const translated = missingFields.map((f) => fieldNames[f] ?? f);
8565+
const fieldList = translated.join(translated.length > 2 ? ', ' : ' e ');
8566+
return `A digitalização do recibo falhou — faltando ${fieldList}.${canEdit ? ' Insira os detalhes manualmente.' : ''}`;
8567+
}
8568+
return `A digitalização do recibo falhou.${canEdit ? 'Insira os detalhes manualmente.' : ''}`;
8569+
},
85628570
receiptGeneratedWithAI: 'Recibo possivelmente gerado por IA',
85638571
someTagLevelsRequired: (tagName?: string) => `Faltando ${tagName ?? 'Etiqueta'}`,
85648572
tagOutOfPolicy: (tagName?: string) => `${tagName ?? 'Etiqueta'} não é mais válido`,

0 commit comments

Comments
 (0)