Skip to main content
Technical ManualLooking for step-by-step instructions? In the User Manual: Import Files

Imports

The Imports module brings files into records that are not content items (content types use Orchard Core's content transfer). The feature reads a CSV file, maps its columns to a target's fields, has the target check every row, imports, and offers the failed rows back as CSV. Each module offers its own targets.

ProjectsCrestApps.Almohaseb.Imports (module), CrestApps.Almohaseb.Imports.Core (contracts, CSV reader, mapping, templates)
FeatureCrestApps.Almohaseb.Imports (Imports); depends on the foundation; enabled by both business recipes
CollectionImports (templates)

Contracts​

All in CrestApps.Almohaseb.Imports (Imports.Core):

  • IImportTarget: Name (unique, in the URL), DisplayName, Description, Permission, Fields (ImportField: Key, Name, Required, Hint, Aliases for guessing), Options (ImportOption: check boxes for the whole import), ValidateAsync(rows, settings) and ImportAsync(rows, settings, user) returning ImportOutcome (Imported, Errors). A module registers its targets as scoped IImportTarget services in a startup with [RequireFeatures(ImportsConstants.Feature)].
  • ImportRow (Number, the 1-based row of the file; Values by field key; Get(key) trimmed or null), ImportRowError (Row, Message, localized by the target), ImportSettings (DateFormat, Options; Has(key)).
  • ImportMapping (HasHeader, Columns by field key, 0-based, DateFormat) and ImportTemplate (Target, Name, Mapping), kept by IImportTemplateStore (ListAsync(target), GetAsync, SaveAsync(target, name, mapping, user) replacing a template of the same name, DeleteAsync) with ImportTemplateIndex (Target, Name).

Pure helpers:

  • CsvReader.Parse(text): RFC 4180 (quoted fields, doubled quotes, line breaks inside quotes), the separator detected from the first line (comma, semicolon or tab), a byte order mark dropped, empty lines skipped. Banking reads statements with it.
  • ImportValues.TryParseAmount (1,234.56, $-12.00, (12.00), 12.00-), TryParseOptionalAmount (empty is 0), TryParseDate(text, format) (the format, or US and ISO dates; a time after the date ignored).
  • ImportMapper.Guess(header, fields, hasHeader) (a column whose name, ignoring case and punctuation, is the field's key, name or an alias; without a header the columns in order), Map(rows, mapping) (short rows get empty values), Unmapped(mapping, fields) (required fields without a column), FailedRows(rows, mapping, errors) (the header and the failed rows with a Problem column; values quoted when needed; a value starting with =, +, - or @ that is not a number gets a leading apostrophe so a spreadsheet does not run it).

Admin​

Tools > Import files (almohasebImports, permission ImportAlmohasebFiles). The flow is stateless: the file's text travels in the form.

Route (under the admin prefix)Route name
Almohaseb/ImportAlmohasebImportsthe targets the user has the permission of
Almohaseb/Import/{target}AlmohasebImportTargetGET the upload form; POST file or content, hasHeader, templateId → the mapping
Almohaseb/Import/{target}/CheckAlmohasebImportCheckPOST Content, HasHeader, DateFormat, Columns[key] (-1 for none), Options, TemplateName, SaveTemplate → the problems of each row
Almohaseb/Import/{target}/RunAlmohasebImportRunPOST the same → the outcome and the failed rows (a data: CSV link)

Files are limited to 2 MB (ImportsConstants.MaxLength). Every action checks ImportAlmohasebFiles and the target's permission.

PermissionKey
Import filesImportAlmohasebFilesAdministrator

Targets of the Ledger​

Registered by the Ledger's ImportsStartup:

  • JournalEntryImportTarget (journal-entries, ManageAlmohasebJournal): fields Entry, Date, Account, Debit, Credit, Amount, Description, Memo; option post. Rows group by Entry, else by the date and description as written. An account is found by number, by name, or by the number before a separator ("1000 · Cash"). A negative debit is a credit. An entry is left out when a row cannot be read, its dates differ, it does not balance or it has one line; the error is on every row of the entry, so the failed rows can be imported again. Entries are posted (IJournalService.PostAsync) with the option, else saved as drafts; the journal's own errors (closed period, inactive account) come back on the entry's rows.
  • OpeningBalanceImportTarget (opening-balances, CloseAlmohasebPeriods): fields Date, Account, Debit, Credit, Amount (balance). One date, each account once, balanced, at least one balance; all or nothing through IOpeningBalanceService.SaveAsync, which replaces the saved opening balances.

See also​

  • Banking: statement import uses CsvReader and ImportValues.
  • Jobs: imports run in the request today; a large import is a candidate for a background job.