@@ -1,6 +1,7 @@
import { useState , useRef } from 'react' ;
import type { ImportStatementRespons e } from '@family-budget/shared' ;
import type { ImportPortfolioResponse , ImportStatementResponse , PortfolioFil e } from '@family-budget/shared' ;
import { importStatement } from '../api/import' ;
import { importPortfolio } from '../api/portfolio' ;
import { updateAccount } from '../api/accounts' ;
interface Props {
@@ -9,7 +10,7 @@ interface Props {
}
export function ImportModal ( { onClose , onDone } : Props ) {
const [ result , setResult ] = useState < ImportStatementResponse | null > ( null ) ;
const [ result , setResult ] = useState < ImportStatementResponse | ImportPortfolioResponse | null > ( null ) ;
const [ error , setError ] = useState ( '' ) ;
const [ loading , setLoading ] = useState ( false ) ;
const [ alias , setAlias ] = useState ( '' ) ;
@@ -37,7 +38,10 @@ export function ImportModal({ onClose, onDone }: Props) {
setResult ( null ) ;
try {
const resp = await importStatement ( file ) ;
const data = isJson ? JSON . parse ( await file . text ( ) ) : null ;
const resp = data ? . schemaVersion === 'broker-portfolio-1.0'
? await importPortfolio ( data as PortfolioFile )
: await importStatement ( file ) ;
setResult ( resp ) ;
} catch ( err : unknown ) {
const msg =
@@ -49,7 +53,7 @@ export function ImportModal({ onClose, onDone }: Props) {
} ;
const handleSaveAlias = async ( ) = > {
if ( ! result || ! alias . trim ( ) ) return ;
if ( ! result || 'reportId' in result || ! alias . trim ( ) ) return ;
try {
await updateAccount ( result . accountId , { alias : alias.trim ( ) } ) ;
setAliasSaved ( true ) ;
@@ -58,6 +62,8 @@ export function ImportModal({ onClose, onDone }: Props) {
}
} ;
const isPortfolioResult = result != null && 'reportId' in result ;
return (
< div
className = "modal"
@@ -79,7 +85,7 @@ export function ImportModal({ onClose, onDone }: Props) {
{ ! result && (
< div className = "import-upload" >
< p className = "import-upload__description" >
В ы б е р и т е ф а й л в ы п и с к и ( PDF и л и JSON , ф о р м а т 1.0 )
В ы б е р и т е PDF / JSON в ы п и с к и и л и JSON б р о к е р с к о г о п о р т ф е л я
< / p >
< input
ref = { fileRef }
@@ -97,33 +103,48 @@ export function ImportModal({ onClose, onDone }: Props) {
{ result && (
< div className = "import-result" >
< div className = "import-result__icon" aria-hidden = "true" > ✓ < / div >
< h3 className = "import-result__title" > И м п о р т з а в е р ш ё н < / h3 >
< h3 className = "import-result__title" > { isPortfolioResult ? 'Импорт портфеля завершён' : 'Импорт завершён' } < / h3 >
< table className = "import-result__stats" >
< tbody className = "import-result__stats-body" >
< tr className = "import-result__stat-row" >
< td className = "import-result__stat-cell import-result__stat-cell--label" > С ч ё т < / td >
< td className = "import-result__stat-cell import-result__stat-cell--value " > { result . accountNumberMasked } < / td >
< / tr >
< tr className = "import-result__stat-row" >
< td className = "import-result__stat-cell import-result__stat-cell--label" > Н о в ы й с ч ё т < / td >
< td className = "import-result__stat-cell import-result__stat-cell--value " > { result . isNewAccount ? 'Да' : 'Нет' } < / td >
< / tr >
< tr className = "import-result__stat-row" >
< td className = "import-result__stat-cell import-result__stat-cell--label" > И м п о р т и р о в а н о < / td >
< td className = "import-result__stat-cell import-result__stat-cell--value " > { result . imported } < / td >
< / tr >
< tr className = "import-result__stat-row" >
< td className = "import-result__stat-cell import-result__stat-cell--label" > Д у б л и к а т о в п р о п у щ е н о < / td >
< td className = "import-result__stat-cell import-result__stat-cell--value" > { result . duplicatesSkipped } < / td >
< / tr >
< tr className = "import-result__stat-row" >
< td className = "import-result__stat-cell import-result__stat-cell--label" > В с е г о в ф а й л е < / td >
< td className = "import-result__stat-cell import-result__stat-cell--value" > { result . totalInFile } < / td >
< / tr >
{ isPortfolioResult ? < >
< tr className = "import-result__stat-row" >
< td className = "import-result__stat-cell import-result__stat-cell--label " > И м п о р т и р о в а н о с д е л о к < / td >
< td className = "import-result__stat-cell import-result__stat-cell--value" > { result . importedTrades } < / td >
< / tr >
< tr className = "import-result__stat-row" >
< td className = "import-result__stat-cell import-result__stat-cell--label " > Д у б л и к а т о в с д е л о к < / td >
< td className = "import-result__stat-cell import-result__stat-cell--value" > { result . duplicateTrades } < / td >
< / tr >
< tr className = "import-result__stat-row" >
< td className = "import-result__stat-cell import-result__stat-cell--label " > П о з и ц и й < / td >
< td className = "import-result__stat-cell import-result__stat-cell--value" > { result . positions } < / td >
< / tr >
< / > : < >
< tr className = "import-result__stat-row" >
< td className = "import-result__stat-cell import-result__stat-cell--label" > С ч ё т < / td >
< td className = "import-result__stat-cell import-result__stat-cell--value" > { result . accountNumberMasked } < / td >
< / tr >
< tr className = "import-result__stat-row" >
< td className = "import-result__stat-cell import-result__stat-cell--label" > Н о в ы й с ч ё т < / td >
< td className = "import-result__stat-cell import-result__stat-cell--value" > { result . isNewAccount ? 'Да' : 'Нет' } < / td >
< / tr >
< tr className = "import-result__stat-row" >
< td className = "import-result__stat-cell import-result__stat-cell--label" > И м п о р т и р о в а н о < / td >
< td className = "import-result__stat-cell import-result__stat-cell--value" > { result . imported } < / td >
< / tr >
< tr className = "import-result__stat-row" >
< td className = "import-result__stat-cell import-result__stat-cell--label" > Д у б л и к а т о в п р о п у щ е н о < / td >
< td className = "import-result__stat-cell import-result__stat-cell--value" > { result . duplicatesSkipped } < / td >
< / tr >
< tr className = "import-result__stat-row" >
< td className = "import-result__stat-cell import-result__stat-cell--label" > В с е г о в ф а й л е < / td >
< td className = "import-result__stat-cell import-result__stat-cell--value" > { result . totalInFile } < / td >
< / tr >
< / > }
< / tbody >
< / table >
{ result . isNewAccount && ! aliasSaved && (
{ ! isPortfolioResult && result . isNewAccount && ! aliasSaved && (
< div className = "import-result__alias" >
< label className = "import-result__alias-label" > А л и а с д л я н о в о г о с ч ё т а < / label >
< div className = "import-result__alias-row" >