Fix/user feedback (#210)
* Add delete policies for provider consent tokens and provider OTC * Add trade name support for companies in settings and documents * Resolved currency selection issue * Enhance invoice line display with foreign currency support and update delivery date schema to allow empty values * Add currency display for journal entries and include currency metadata in transaction creation * Add trade_name column to company_settings for external display
This commit is contained in:
@@ -11,6 +11,7 @@ import JournalEntryForm from '@/components/bookkeeping/JournalEntryForm'
|
||||
import DocumentUploadZone from '@/components/bookkeeping/DocumentUploadZone'
|
||||
import type { UploadedFile } from '@/components/bookkeeping/DocumentUploadZone'
|
||||
import type { FormLine } from '@/components/bookkeeping/JournalEntryForm'
|
||||
import { resolveSekAmount, buildCurrencyMetadata } from '@/lib/bookkeeping/currency-utils'
|
||||
import type { TransactionWithInvoice } from './transaction-types'
|
||||
|
||||
interface TransactionBookingDialogProps {
|
||||
@@ -21,21 +22,40 @@ interface TransactionBookingDialogProps {
|
||||
}
|
||||
|
||||
function buildInitialLines(transaction: TransactionWithInvoice): FormLine[] {
|
||||
const amount = Math.round(Math.abs(transaction.amount_sek ?? transaction.amount) * 100) / 100
|
||||
const amountStr = amount.toFixed(2)
|
||||
const sekAmount = Math.round(Math.abs(resolveSekAmount(
|
||||
transaction.amount,
|
||||
transaction.amount_sek,
|
||||
transaction.currency,
|
||||
transaction.exchange_rate
|
||||
)) * 100) / 100
|
||||
const amountStr = sekAmount.toFixed(2)
|
||||
const isExpense = transaction.amount < 0
|
||||
|
||||
if (isExpense) {
|
||||
return [
|
||||
{ account_number: '1930', debit_amount: '', credit_amount: amountStr, line_description: 'Företagskonto' },
|
||||
{ account_number: '', debit_amount: amountStr, credit_amount: '', line_description: '' },
|
||||
]
|
||||
const isForeign = !!transaction.currency && transaction.currency !== 'SEK'
|
||||
const currencyMeta = isForeign
|
||||
? buildCurrencyMetadata(
|
||||
transaction.currency,
|
||||
Math.abs(transaction.amount),
|
||||
transaction.exchange_rate
|
||||
)
|
||||
: {}
|
||||
|
||||
const bankLine: FormLine = {
|
||||
account_number: '1930',
|
||||
debit_amount: isExpense ? '' : amountStr,
|
||||
credit_amount: isExpense ? amountStr : '',
|
||||
line_description: 'Företagskonto',
|
||||
...currencyMeta,
|
||||
}
|
||||
|
||||
return [
|
||||
{ account_number: '1930', debit_amount: amountStr, credit_amount: '', line_description: 'Företagskonto' },
|
||||
{ account_number: '', debit_amount: '', credit_amount: amountStr, line_description: '' },
|
||||
]
|
||||
const counterLine: FormLine = {
|
||||
account_number: '',
|
||||
debit_amount: isExpense ? amountStr : '',
|
||||
credit_amount: isExpense ? '' : amountStr,
|
||||
line_description: '',
|
||||
}
|
||||
|
||||
return isExpense ? [bankLine, counterLine] : [bankLine, counterLine]
|
||||
}
|
||||
|
||||
export default function TransactionBookingDialog({
|
||||
|
||||
@@ -6,7 +6,7 @@ import { Button } from '@/components/ui/button'
|
||||
import { Badge } from '@/components/ui/badge'
|
||||
import { Checkbox } from '@/components/ui/checkbox'
|
||||
import { cn, formatCurrency, formatDate } from '@/lib/utils'
|
||||
import { ArrowUpRight, ArrowDownRight, FileText, Loader2, Paperclip } from 'lucide-react'
|
||||
import { ArrowUpRight, ArrowDownRight, FileText, Loader2, Paperclip, Trash2 } from 'lucide-react'
|
||||
import { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider } from '@/components/ui/info-tooltip'
|
||||
import { getAccountName, formatAccountWithName } from '@/lib/bookkeeping/client-account-names'
|
||||
import { getTemplateById } from '@/lib/bookkeeping/booking-templates'
|
||||
@@ -26,7 +26,7 @@ interface TransactionInboxCardProps {
|
||||
onMarkPrivate: (id: string) => void
|
||||
onOpenMatchDialog: (transaction: TransactionWithInvoice) => void
|
||||
onOpenCategoryDialog: (transaction: TransactionWithInvoice) => void
|
||||
|
||||
onDelete?: (id: string) => void
|
||||
onOpenQuickReview?: (transaction: TransactionWithInvoice, suggestion: SuggestedCategory) => void
|
||||
onOpenTemplateReview?: (transaction: TransactionWithInvoice, templateId: string) => void
|
||||
onToggleSelect: (id: string) => void
|
||||
@@ -45,7 +45,7 @@ export default function TransactionInboxCard({
|
||||
onMarkPrivate,
|
||||
onOpenMatchDialog,
|
||||
onOpenCategoryDialog,
|
||||
|
||||
onDelete,
|
||||
onOpenQuickReview,
|
||||
onOpenTemplateReview,
|
||||
onToggleSelect,
|
||||
@@ -60,6 +60,7 @@ export default function TransactionInboxCard({
|
||||
const isUncategorized = transaction.is_business === null && !transaction.journal_entry_id
|
||||
const showCheckbox = isBatchMode && isUncategorized
|
||||
const hasDocumentMatch = !!transaction.matched_inbox_item
|
||||
const isManualTransaction = !transaction.bank_connection_id && !transaction.import_source && !transaction.journal_entry_id
|
||||
|
||||
function handleSuggestionClick(suggestion: SuggestedCategory) {
|
||||
if (onOpenQuickReview) {
|
||||
@@ -249,6 +250,20 @@ export default function TransactionInboxCard({
|
||||
>
|
||||
Välj mall...
|
||||
</Button>
|
||||
|
||||
{/* Delete button — only for manually added, unbooked transactions */}
|
||||
{isManualTransaction && onDelete && (
|
||||
<Button
|
||||
size="sm"
|
||||
variant="ghost"
|
||||
className="h-9 w-9 p-0 ml-auto text-muted-foreground hover:text-destructive"
|
||||
onClick={() => onDelete(transaction.id)}
|
||||
disabled={isProcessing || isDisabled}
|
||||
aria-label="Ta bort transaktion"
|
||||
>
|
||||
<Trash2 className="h-4 w-4" />
|
||||
</Button>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
</CardContent>
|
||||
|
||||
Reference in New Issue
Block a user