@ -48,7 +48,6 @@ DOMAIN_MESSAGES = {
" zero_amount " : " The amount cannot be zero. " ,
}
UNKNOWN_DOMAIN_MESSAGE = " Unable to save this change. "
MAX_GUIDED_FILES = 10
@dataclass ( frozen = True )
@ -86,18 +85,12 @@ def imports_index(request):
action = request . POST . get ( " action " )
if action == " scan " :
discovered = guided_imports . discover_imports ( )
request . session . pop ( " guided_imports " , None )
if len ( discovered ) > MAX_GUIDED_FILES :
return render ( request , " core/imports/index.html " , {
" error " : f " SCAN_TOO_LARGE: Keep at most { MAX_GUIDED_FILES } files in imports/ and scan again. No files were imported. " ,
} )
files = [ {
" name " : row . name , " profile " : row . profile , " sections " : list ( row . sections ) ,
" state " : " NEEDS_ATTENTION " if row . code else " MAPPING_REQUIRED " ,
" code " : row . code , " counts " : None ,
} for row in discovered ]
scannable = [ _import_metadata ( row ) for row in discovered if not row . code ]
_remember_import_summaries ( request , [ row for row in files if row [ " code " ] ] )
return _render_imports ( request , files = files , scan_token = signing . dumps (
scannable , salt = " guided-imports-scan " , compress = True ,
) if scannable else None )
@ -111,14 +104,12 @@ def imports_index(request):
if action == " prepare " :
return _prepare_import_files ( request , payload )
else :
_commit_import_files ( request , payload )
return _commit_import_files ( request , payload )
else :
return render ( request , " core/imports/index.html " , {
" error " : " Choose an import action. Scan again before continuing. " ,
} , status = 400 )
return redirect ( " imports-index " )
return _render_imports ( request , files = request . session . get ( " guided_imports " , [ ] ) )
return _render_imports ( request , files = [ ] )
def _render_imports ( request , * , files , * * context ) :
@ -150,7 +141,7 @@ def _load_import_token(request, *, prepared):
keys = { " name " , " document_hash " , " profile " , " sections " }
if prepared :
keys | = { " batch_id " , " revision " }
if not isinstance ( payload , list ) or not payload or len ( payload ) > MAX_GUIDED_FILES :
if not isinstance ( payload , list ) or not payload :
raise ValueError
for row in payload :
if not isinstance ( row , dict ) or set ( row ) != keys :
@ -181,25 +172,6 @@ def _import_failure(metadata, code="IMPORT_FAILED"):
}
def _combined_import_results ( request , results ) :
# Retain exceptions from other files through each independent action.
names = { row [ " name " ] for row in results }
previous = request . session . get ( " guided_imports " , [ ] )
files = [ row for row in previous
if row [ " name " ] not in names and row [ " state " ] == " NEEDS_ATTENTION " ] + results
if len ( files ) > MAX_GUIDED_FILES :
# Another tab may have scanned a different group since this form opened.
files = results
return sorted ( files , key = lambda row : row [ " name " ] )
def _remember_import_summaries ( request , files ) :
# Do not retain hashes, batch identifiers, tokens, mappings, or source content.
request . session [ " guided_imports " ] = [ {
key : row [ key ] for key in ( " name " , " profile " , " state " , " code " , " counts " )
} for row in files ]
def _prepare_import_files ( request , payload ) :
results , ready = [ ] , [ ]
for index , metadata in enumerate ( payload ) :
@ -221,9 +193,7 @@ def _prepare_import_files(request, payload):
results . append ( _import_summary ( result ) )
if result . state in { " READY " , " ALREADY_IMPORTED " } :
ready . append ( _import_metadata ( result , prepared = True ) )
files = _combined_import_results ( request , results )
_remember_import_summaries ( request , [ row for row in files if row [ " state " ] == " NEEDS_ATTENTION " ] )
return _render_imports ( request , files = files , prepared_token = signing . dumps (
return _render_imports ( request , files = results , prepared_token = signing . dumps (
ready , salt = " guided-imports-prepared " , compress = True ,
) if ready else None )
@ -233,7 +203,7 @@ def _commit_import_files(request, payload):
for metadata in payload :
prepared = guided_imports . PreparedImport (
* * { * * metadata , " sections " : tuple ( metadata [ " sections " ] ) } ,
state = " READY " , counts = { " created " : 0 , " matched " : 0 , " skipped " : 0 } , code = None ,
state = " READY " , counts = { " created " : 0 , " matched " : 0 , " skipped " : 0 } , code = None , staged = True ,
)
try :
result = guided_imports . commit_prepared_import ( prepared = prepared , actor = LOCAL_ACTOR )
@ -241,7 +211,7 @@ def _commit_import_files(request, payload):
results . append ( _import_failure ( metadata ) )
continue
results . append ( _import_summary ( result ) )
_remember_import_summaries ( request , _combined_import_results ( request , results ) )
return _render_imports ( request , files = results )
def reconciliation_index ( request ) :