Recurring jobs
invoiceR performs many tasks on a schedule in the background: collecting the mailbox, synchronizing master data, handing documents over to the ERP, importing users and much more. These recurring jobs (also called cron jobs) are run by the Hangfire component.
Viewing and starting jobs
Section titled “Viewing and starting jobs”Administration > Job-Ausführunglists all configured jobs with their schedule (Cron), next and last run. Run Task starts a job immediately.Administration > Hangfire dashboardshows details: history, logs of each run and failed jobs.
Both menu items are only visible with the corresponding permissions.
Configuring jobs
Section titled “Configuring jobs”Each job is an entry in the table conf.IrRecurringJobs:
| Column | Meaning |
|---|---|
Id | GUID of the entry. |
TenantId | Tenant. |
Enabled | 1 = the job is active. |
HangfireId | Unique technical name, for example ch.invoicer.tool.delete.files. |
Description | Label shown in the job list and in Hangfire. |
CronExpression | Schedule in cron format, for example 0 6 * * * for daily at 6 am. |
ClassIdentifier | Full class name of the job in invoiceR or a plugin. |
MethodName | Method that is started. |
MethodArgumentIdentifier | Class name of the configuration into which Configuration is read. |
Configuration | JSON with the job settings. |
EnvironmentFilter | Empty: always applies. Otherwise only in the named environments, for example Production. |
VisibleFilterRoleId, EditFilterRoleId | Optional. Role allowed to see or edit the job. |
SequenceCode, SequenceOrder | Optional, for batch jobs (see below). |
ObjectMappingCode | Optional, only used by some jobs. |
Changes to the table only take effect after the job Wiederkehrende Hangfire-Jobs anmelden (ID
ch.invoicer.fix.setupRecurringJobs) has run. It runs once a day on its own; after a change, start it by hand
under Administration > Job-Ausführung or in the Hangfire dashboard. It re-registers all active jobs and removes
jobs that are no longer configured.
Batch jobs
Section titled “Batch jobs”If several jobs must always run one after the other (for example first import master data, then export documents), group them into a batch:
SequenceCode: the same number for all jobs of the batch.SequenceOrder: order within the batch.
The batch appears as its own job BatchJob_<SequenceCode> and uses the schedule of the first job. The
CronExpression of the other jobs in the batch is ignored.
Deleting files
Section titled “Deleting files”Deletes old files in a folder on the invoiceR server, for example temporary import files. Files can first be moved to an archive subfolder and deleted later.
| Column | Value |
|---|---|
ClassIdentifier | enio.tool.Plugin.FileDeleter.FileDeleter |
MethodName | CheckFiles |
MethodArgumentIdentifier | enio.tool.Plugin.FileDeleter.FileDeleterArgument |
{ "FolderPath": "D:\\invoiceR\\Import", "MoveToArchiveAfterXDays": 14, "DeleteFromArchiveAfterXDays": 40, "DirectDeleteAfterXDays": null, "ArchiveFolderName": "Archive", "AddTimestampInArchiveFileName": true}| Key | Meaning |
|---|---|
FolderPath | Absolute path of the folder on the invoiceR server. |
MoveToArchiveAfterXDays | After this many days without change, a file moves to the archive folder. |
DeleteFromArchiveAfterXDays | After this many days without change, a file in the archive folder is deleted. |
DirectDeleteAfterXDays | If set, files are deleted directly after this many days, without the archive folder. |
ArchiveFolderName | Name of the archive subfolder (default Archive). |
AddTimestampInArchiveFileName | true adds the last modification date to the file name when moving. |
Running SQL
Section titled “Running SQL”Regularly runs an SQL statement on the invoiceR database, for example a stored procedure for clean-up work.
| Column | Value |
|---|---|
ClassIdentifier | enio.tool.Plugin.SqlExecutor.ExecuteSqlStatement |
MethodName | RunSql |
MethodArgumentIdentifier | enio.tool.Plugin.SqlExecutor.ExecuteSqlStatementArgument |
{ "StatementDescription": "Starts the procedure dbo.MyCleanup", "SqlContent": "EXEC [dbo].[MyCleanup]", "NumberOfRowsAffectedForNoError": -1}| Key | Meaning |
|---|---|
StatementDescription | Description shown in the log. |
SqlContent | SQL to run. Move longer logic into a stored procedure. |
NumberOfRowsAffectedForNoError | Expected number of affected rows. If it does not match, the job fails. -1 turns the check off. |
CommandTimeout | Optional. Time limit in seconds for long statements (default 1800). |
Importing exchange rates
Section titled “Importing exchange rates”Imports monthly average rates from the Federal Office for Customs and Border Security (FOCBS, German BAZG) and updates the exchange rates in invoiceR.
| Column | Value |
|---|---|
ClassIdentifier | enio.tool.Plugin.CurrencyExchangeRateImport.CurrencyExchangeRateImport |
MethodName | DoImport |
MethodArgumentIdentifier | enio.tool.Plugin.CurrencyExchangeRateImport.CurrencyExchangeRateImportArgument |
{ "Xmlurl": "https://www.backend-rates.bazg.admin.ch/api/xmlavgmonth", "FilterCurrencies": ["USD", "EUR"]}| Key | Meaning |
|---|---|
Xmlurl | Address of the XML file with the FOCBS rates. |
FilterCurrencies | Currencies to update. Empty: all currencies. |
Example: creating a job
Section titled “Example: creating a job”INSERT INTO conf.IrRecurringJobs (Id, TenantId, Enabled, HangfireId, Description, CronExpression, ClassIdentifier, MethodName, MethodArgumentIdentifier, Configuration)VALUES (NEWID(), 1, 1, N'ch.invoicer.tool.delete.files', N'Clean up import files', N'5 3 * * *', N'enio.tool.Plugin.FileDeleter.FileDeleter', N'CheckFiles', N'enio.tool.Plugin.FileDeleter.FileDeleterArgument', N'{ "FolderPath": "D:\\invoiceR\\Import", "DirectDeleteAfterXDays": 30 }');Then start Wiederkehrende Hangfire-Jobs anmelden.
