📘
TimeLine E3
  • TimeLine E3 Documentation
  • Framework
    • Introduction
    • DataSet Definition
    • Window Handling Object
      • Input/Output arguments
      • Open
      • BindDataControls
      • Item Changes
      • Item Search
      • MenuItemClicked
      • Print
      • ModuleOpened (BlueArrow)
      • BlueArrowArguments
      • New Row
      • Delete Row
      • Save
      • Transactions
      • Locking [deprecated]
      • Locking (new)
      • Resizing a response window
      • ParaPanel
      • Adding DMS Tab to a Module
    • BusinessObject
    • Controls
      • BindingFormat
      • LookupGrid and SearchDef
      • ComboBox
      • RadioButton
      • Multiline Textbox
      • xTextBoxSearch
      • xFileBrowse [v16+]
      • DxDispoColumn
      • DxProgressColumn
      • DxTemplateColumn
      • Change control caption programmatically
      • TabControl
      • Navigation
      • Enable controls programmatically
      • Enable a MenuItem programmatically
      • Filter search values
      • Jumping to another module
      • Messages, Notifications, Log, Exceptions, Translation
      • LoggerSink [deprecated]
      • Log
      • OpenFile, FolderBrowsing and SaveFile
      • Execute Actions while displaying an Hourglass
      • Using Progress
      • Async methods with progress bar
      • Wizard
      • Customizing controls using xBehaviors
      • TLProperty.AllowInReadOnly [v16+]
    • DataSet Operations
    • Business-related functionality
      • Getting the next primary key
      • Hybrids
      • Enums
      • Get Current User
    • SQL
    • SQL (using named parameters)
    • Advanced SQL
    • Expression Binding
    • Server-side logic & customization [v16+]
      • Service Hoster
      • Starting / stopping hosted services
      • Changes to scheduled jobs!
      • Business Object Proxies
      • Business Object API
    • Colors in Expression Bindings [v15+]
    • Theming
      • Icons
  • TimeLine Developer (TLD)
    • Debugging in TLD
    • Targets
    • Custom Project Rework [v16+]
  • TimeLine-specific LL functions
  • Stunnel proxy
    • Pre-requisites
    • 1. Initial setup
    • 2. Generate the server/web certificates
    • 3.a. Generating client certificates using the CSR flow
    • 3.b. Generate client certificates from the server console
    • 4. Setting up the E3 client connection
    • 5. Setting up the browser certificates
  • Configuration
    • Configuring the WCF timeout
  • Troubleshooting the E3 Bridge
  • [Deprecated]
    • TimeLine WEB - deprecated in v16+
      • Prerequisites for running the WASM modules on the server
      • Prerequisites for developing WASM modules with TLD
      • Creating a small web module with TLD
      • Terminal Configuration
    • Customization Examples - deprecated in v16+
    • Codestore [deprecated]
    • Configuring the scheduled jobs timeout - deprecated in v16+
Powered by GitBook
On this page
  • Document Transfer
  • Generating reports from server-side scheduled jobs
  • Creating server-side scheduled Jobs
  • Scheduled Task (v14 upwards)
  1. [Deprecated]

Customization Examples - deprecated in v16+

Please note that v16+ uses the busScheduledJobs and the ServiceHoster for developing and running custom server functions, as noted here: Changes to scheduled jobs!

Please note that any custom addition to the BusinessFunctions will require you to deploy the generated TimeLine.ServerFunctions.dll assembly generated in the customization folder to the server's DynamicAssemblies folder in order to run. Also note that a server reinstall might remove this file, so ensure you back it up when reinstalling the server.

Document Transfer

private void StartUebern()
{
   // boBelUebern has no xTransaction because it will NOT Save any busDoc directly
   var boBelUebern = ModuleManager.Instance.CreateBusObj("busBelUebern", UserSecurityToken.Instance.UserID) as busBelUebern;

   // using same transaction on boDoc and quellBusDoc to avoid locking each other
   using (var transaction = new xTransaction())
   {
      // create busDoc by using CreateBusinessObject and CreateChildBusinessObject to use same xTransaction
      var quellDoc = BusinessObjectFactory.CreateBusinessObject<busDoc>(transaction);

      var zielDoc = BusinessObjectFactory.CreateBusinessObject<busDoc>(transaction);
   
      // prepare the Target (Ziel) Document Header
      zielDoc.CreateBel((int)Enums.BelTyp.Lieferschein);
   
      // Note: calling InitializeZielBeleg/InitializeQuellBeleg the current created busDoc instances will be used as boBelUebern object members
      // which are needed into StartUebernahme to manage saving on same xTransaction to Roolback or commit in both busDoc objects
   
      // send already created zielDoc as busdoc Instance to boBelUebern
      boBelUebern.InitializeZielBeleg(zielDoc, retrievePersBelege: false);
   
      // ***** *** *****//
      // In case of only one quell Beleg, call only InitializeQuellBeleg which calls AddQuellBel(quellDoc) inside with blnClearPreviousresults: true
      // ***** *** *****//
   
      // add Order Confirmation 1 
      quellDoc.Retrieve(2, 10131);
      // send already created quellDoc as busdoc Instance to boBelUebern
      boBelUebern.InitializeQuellBeleg(quellDoc);
   
      // ***** *** *****//
      // In case of transferring more than one quell Beleg, call directly AddQuellBel(quellDoc, blnClearPreviousresults: false)
      //  to skip clearing the previous retrieved results
      // ***** *** *****//
   
      // add Order Confirmation 2 
      quellDoc.Retrieve(2, 10132);
      boBelUebern.AddQuellBel(quellDoc, blnClearPreviousresults: false);
   
      // add Order Confirmation 3 
      quellDoc.Retrieve(2, 10133);
      boBelUebern.AddQuellBel(quellDoc, blnClearPreviousresults: false);
   
      // ***** *** *****//
      // specifySerialCharge param is default 0
      //  calling it with 1 involve that CheckBelposDetailSerialChargeMenge returns true
      //      - conditions on belpos_detail in case of serien/chargen rows or
      //      - conditions on gebinde_inh in case of gebinde rows (since V14)
      // ***** *** *****//
      
      //  create Delivery Note 
      // NOTE: the last quellDoc that was added to boBelUebern with AddQuellBel will fill the pers infos into Ziel Beleg Header
      boBelUebern.StartUebernahme(Enums.BelTyp.Lieferschein, specifySerialCharge: 1, speichern: true);
   
      quellDoc.Dispose();
      quellDoc.Transaction.Rollback();
   }
}

Generating reports from server-side scheduled jobs

In order to use the translation features, the repositories should be put on the server.

public void ReportExportTest(IScheduledJobContext context)
{
    TranslationManager.Instance.LoadCurrentCulture();
    
    var rep = new TimeLine.Report.TLListAndLabel();
    xSqlArgs args = new TimeLine.Framework.Data.xSqlArgs();
    rep.DoPreview("rptBeleg02", args, null, "Beleg02", null, "c:\\TMP", "ExportTest", "pdf", null, null, null, null);
}

Creating server-side scheduled Jobs

The steps for creating a scheduled job are the following:

1.Create the custom server functions project using the TLD menu item:

2.Create a Server Function using TLD that returns Void with 0 arguments, or 1 argument of type TimeLine.Framework.Util.ScheduledJobs.IScheduledJobContext – example:

The IScheduledJobContext type has the following methods and properties:

  • void ReportProgress(string title, float percentage) - method used to report progress if you're writing a long running job - the progress can be viewed from the server console by double clicking a job status entry (will be shown further down in this document).

  • void Log(string message, LogMessageType messageType) – used to log information, warnings or errors that occur during the job run – these messages are also logged in the “error_log” database table.

  • bool ShouldCancelJob { get; } – property used to signal the job that it has been cancelled by the server administrator. Use this to periodically check if the job was cancelled inside your long running job – if this property is ignored for an arbitrary amount of time then the job running process will be killed.

3. Synchronise the custom server functions using the same button used on step 1 4. Open the server console application and navigate to the new “Scheduled Jobs” tab

5. Add a new Scheduled Job in the left-hand side data grid (labelled Configuration) 6. Follow the wizard’s instructions by picking a name for the scheduled job, the profile to run against, the server function to execute and the trigger type and trigger information (one-time trigger, daily trigger etc.)

Once this entry has been added you should see it in the left-hand side data grid and the scheduler should have already picked up the new job. Using the refresh button on the right-hand side panel will refresh the status of the running jobs – you can also use the provided filters to only see status entries for certain jobs, a certain time interval etc.

Clicking the document button next to each job status entry will open the log file associated with the job run in the default system text editor – holding Ctrl + Shift when clicking will open the day’s Scheduler log (a detailed log file that might be useful for debugging certain issues – you’ll probably never need to use this). The status column displays the status for the given scheduled job run – it can have the following values:

  • Completed successfully

  • Completed with warnings

  • Completed with errors

  • Cancelled successfully (the job was cancelled without the need of killing the running process)

  • Cancelled forcefully

  • Still running

Double clicking on a job status entry will open a detailed view – this is especially useful when dealing with log running tasks as this will display progress information from the with a progress bar (this makes use of the ReportProgress method on the IScheduledJobContext interface.

Each scheduled job will run under a different process than the Server windows service as to not interfere with the main application (unexpected crashes, StackOverflow exceptions etc.)

You can use the following SQL query to view job status from the “error_log” table:

SELECT  "extracted"."guid", 
        "extracted"."job_name", 
        "error_log"."lfdnr", 
        "error_log"."error_nr",
        "error_log"."message",
        "error_log"."user_id",
        "error_log"."date"
FROM "error_log" WITH (NOLOCK)
CROSS APPLY (
    SELECT regexp_substr( "message", '\[[a-zA-Z0-9]{8}-[a-zA-Z0-9]{4}-[a-zA-Z0-9]{4}-[a-zA-Z0-9]{4}-[a-zA-Z0-9]{12}\]') AS "guid",
           regexp_substr( "message", '^.+(?=\[[a-zA-Z0-9]{8}-[a-zA-Z0-9]{4}-[a-zA-Z0-9]{4}-[a-zA-Z0-9]{4}-[a-zA-Z0-9]{12})') AS "job_name"
) AS "extracted"
ORDER BY "date" DESC, "guid" DESC

Scheduled Task (v14 upwards)

The following example shows how to create a PDF and send it per email while using scheduled tasks.

public virtual void ReportLL(IScheduledJobContext context)
{
            
     string temp_folder = Path.GetTempPath();
     string temp_file = Guid.NewGuid().ToString();
     int report_code = -1;
     string dsd_id = "rptArtikelstammblatt01";
     string rpt_id = "Artikelstammblatt01";
     xSqlArgs args = new xSqlArgs();
     args.Add("artnr", "A1");


     using (TimeLine.Report.TLListAndLabel tlListLabel = new TimeLine.Report.TLListAndLabel())
     {
        report_code = tlListLabel.DoPreview(dsd_id, args, null, rpt_id, null, temp_folder, temp_file, "pdf", null, null, null, null);
     }

     if (report_code == 1)
     {
         context.Log("Report succesfully generated", LogMessageType.Information);    
     }
     else
     {
         context.Log("Error by generating the report", LogMessageType.Error);
         return;
     }

     string message = "Message";
     string recipient = "sales@timeline.ro";
     int smtp_user_id = 1;
     xMailMessage mailMessage = new xMailMessage();
     mailMessage.Body = message;
     mailMessage.AddAttachmentToList(Path.Combine(temp_folder, temp_file + ".pdf"));
     mailMessage.AddRecipients(recipient);
     int mail_code = mailMessage.SendWithUserId(smtp_user_id);

     if (mail_code >= 0)
     {
        context.Log("Email succesfully sent", LogMessageType.Information);     
     }
     
     else
     {        
       context.Log("Email sending failed", LogMessageType.Error);     
     }
}
PreviousTerminal ConfigurationNextCodestore [deprecated]

Last updated 1 year ago