EDI Profiles Revision (in 3.3)

 

 

 Overview

xTuple ERP has long had the ability to send a few types of document via FTP and email. The increase in the number of xTuple ERP users and proliferation of electronic documents has lead to a number of requests to support electronic transmission of additional document types and more flexibility in how documents and their delivery are to be specified.

Functional Requirements

The EDI capabilities of xTuple ERP should be changed in the following ways:

  • Retain existing functionality, although the mechanics of achieving that may change (see below).
  • Make it easier to add to the set of document types supported by the EDI subsystem.
  • Expand the set of supported document types:
    • Credit Memos (issue 8110).
    • A/R Statements (issue 8110).
    • Quotes (issue 6365).
  • Normalize the storage of EDI Profile data.
  • Generalize the functionality to allow sending a single document to multiple recipients (issue 5467).
  • Store the actual messages sent, including the attachments, in the database with links to the appropriate records (issue 5468).
  • Support additional email header properties (issues 8322 and 8614):
    • Reply-to
    • Bcc
    • From
  • EDI sent should be stored for use as a knowledge base

This feature is not explicitly intended to move existing Batch Manager hooks from the core C++ GUI client to the xtbatch package, but this might be a fortunate side effect of the development effort.

New Terms and Definitions

N/A

Related Existing Functionality

The Standard and Manufacturing editions of xTuple ERP currently support electronic mailing of certain documents: Alarms, Events, Incidents, Invoices, Purchase Orders, Sales Orders. These documents are generated by sending jobs to the Batch Manager describing the report to run, the parameters to use when running the report, and the EDI profile to use.

EDI Profiles currently support two delivery mechanisms: FTP and electronic mail. If you choose FTP delivery then you are allowed to enter the server, login, password, and destination directory at the top level, and at a lower level you can select between running a user-defined query and predefined report or generating a comma- or tab-delimited file from one or more user-defined queries. If you choose email delivery then you can enter to, cc, from, subject, message body boilerplate, and either html or plain-text delivery.

Different parts of the application tap in to the EDI subsystem in different ways:

System -> Master Information -> Database Information lets you define a default from email address. Every time the Batch Manager reads a job from its queue it checks the batch_from field of the job. If this is empty or NULL then the Batch Manager uses the default email address. There are essentially two ways to submit a Batch Manager job - call submitActionToBatch(), which leaves the field for a from address blank, and submitEmailToBatch(), which sets the from address if the caller supplies it (in three out of four versions of of the procedure!).

The To address of an email EDI message is set in several ways. Sometimes the GUI client passes an explicit email address. If this isn't passed, then sometimes the application defaults to the email address of the current user and sometimes it is left blank.

You can link EDI Profiles to Incidents through Incident Categories, each of which can be associated with its own email delivery EDI Profile. If you have configured CRM to send email for Incidents, then the email will be constructed using the EDI Profile associated with the Incident Category. If the Incident Category's EDI Profile is undefined then a generic CRM Incident Email Profile will be used if it is set on the Configure CRM window.

The Customer record currently has two EDI profiles, one for invoices and one for sales orders. Choices allowed are No EDI, Custom email, or any of the EDI Profiles of type 'invoice' created via System -> Master Information -> EDI Profiles. These do not appear to be working correctly now (issue 7670).

The application supplies a Customer Form Assignments window which allows associating a Customer Type or pattern of the Customer Type with forms to use for Invoices, Credit Memos, Statements, Quotes, Packing Lists, and Sales Order Pick Lists. These forms are not used consistently by the EDI Profiles.

There are different processes for constructing email messages, depending on what message is being created:

Invoices

If the customer is configured to receive email EDI and an EDI Profile has been selected either for the customer or the Ship-To address, the following steps are followed (submitAction('TransmitInvoice')).

 The Batch Manager takes the following steps:

  • run the query in the ediform_query field.
  • for each field in the result, add to a parameter list a parameter named after the field with the value of the field.
  • for each </name> pattern in the ediform_file field, replace name with the value in the parameter list.
  • if ediform_output = report, run the report named in ediform_option1 and write the result to the file named in ediform_file (after replacing </name>)
  • else if ediform_output = csv then read the delimiter from ediform_option1, process each ediformdetail_query in order with MetaSQL using the same parameter list, and execute the query. For each row returned by the detail query, write the data to the named file using the supplied delimiter between columns.
  • if ediprofile_type = email then email the message from the user determined from batch_from (see above), to ediprofile_option1 and cc ediprofile_option4, with subject ediprofile_option2, the body text build from ediprofile_option3, and the file build above (report or csv) as an attachment.
  • else if ediprofile_type = ftp then ftp file file to its destination host (ediprofile_option1) as the user ediprofile_option2 with password ediprofile_option3, placing the file in the directory named ediprofile_option4.

Otherwise, if the customer is set to receive email but using customer-specific information rather than a generic EDI Profile, Invoice emails are built inside the GUI client by calling the deliverInvoice window whenever the user selects Email Invoice from the Accounting or Sales menu, or under certain circumstances listed in the previous table (rows marked deliverInvoice).

  • The email From field is set to the address of the current xTuple ERP user.
  • The report to use is found by calling findCustomerForm() for this customer's invoice.
  • The edi profile settings are collected from the edi* fields of the custinfo record.
  • The ediprofile's body text is always converted to plainText, regardless of the useHtml setting.
  • The application replaces </docnumber> and </doctype> in the email body, subject, and filename.
  • The user is presented with an application window to view and possibly edit the message before it is sent.
  • The user clicks a button, which calls submitReportToBatch and saves some data to the batchparam table.

 Why do some cases use submitReport() and others submitAction('TransmitInvoice')?

Incidents

Incident email messages are built inside the xTuple ERP GUI client, but only if the incident category has an EDI Profile associated with it:

  • a hardcoded reason string is selected based on the nature of the change to the incident.
  • a hardcoded document body string is constructed from the reason string, fields of the incident record, the email address of the incident owner, the email address of the assigned user, and the incident history.
  • if the incident is associated with an invoice and the current user says s/he would like to attach a copy of the invoice, the invoice number is used to add invchead_id and findCustomerForm(this cust, 'I') to the parameter list.
  • the parameter list is used to replace hardcoded </name> patterns in ediprofile_option1 for the email recipient, ediprofile_option2 for the subject, ediprofile_option3 for the message body, and ediprofile_option4 for the cc.
  • duplicates in the values of the email1, email2, and email3 parameters are removed, then </email[123]> are replaced.
  • </comments> gets replaced with SELECT * FROM comments for the given document type and id.
  • finally the message is either previewed or sent, possibly including a report (the invoice??)

Sales Orders

Sales Order email messages are built inside the GUI client by calling the deliverSalesOrder window, either directly from the Sales menu, by clicking the Save or the Save & Add button on the Sales Order window, or by right-clicking selecting "Email Order Acknowledgement" on the Open Sales Orders window:

  • The email From field is set to the address of the current xTuple ERP user.
  • The user is presented with a combo box from which to choose the Sales Order form s/he wants to run.
  • The EDI Profile settings are read from the custinfo table's soedi* fields.
  • The application replaces </docnumber> and </doctype> in the email body, subject, and filename.
  • When the user clicks the Submit button, the application finds the report associated with the user-selected form, then calls submitReportToBatch and saves some data to the batchparam table.

Purchase Orders

Purchase Order email messages are built inside the xTuple ERP GUI client by calling the deliverPurchaseOrder window, either directly from the Purchase menu, by printing when saving from the Purchase Order window, or by clicking the Deliver button on the Unposted Purchase Orders window:

  • The email From field is set to the address of the current xTuple ERP user.
  • The report is hardcoded to 'PurchaseOrder'.
  • The EDI Profile settings are read from the vendinfo table.
  • The ediprofile's body text is always converted to plainText, regardless of the useHtml setting.
  • The application replaces </docnumber> and </doctype> in the email body, subject, and filename.
  • The user is presented with an application window to view and possibly edit the message before it is sent.
  • The user clicks a button, which calls submitReportToBatch and saves some data to the batchparam table.

Alarms

The main xTuple ERP client application calls sTick() every so often to take care of internal timer-based events. This calls the hasAlarms() stored procedure. For all alarms that are due to be sent by email before the current time where the current user is the creator, hard-coded messages are built for the different types of alarm and sent to the batch manager with submitEmailToBatch().

Events

Event email messages are constructed by a trigger on the evntlog table. The trigger has a hardcoded SELECT statement that builds the subject and body of the message from the evntlog data and a join with the evnttype and whsinfo tables. This message is then sent to the Batch Manager with submitEmailToBatch().

 

Similar and Related Requests

The following Mantis issues record open bugs and feature requests related to EDI profiles. Inclusion in this list does not mean that this specification addresses any particular issue.

3026 Filter lookups to speed EDI transfers
4854 OpenMFG should keep a history of communication events
5110 Global EDI profiles don't allow a way to default e-mail addresses
5466 option to send emails through local email client
5467 Recast EDI profiles as one-to-many "communications profiles"
5468 Link outgoing emails to Incidents
5469 Milestone and recurring invoice schedules
5863 Alert for extreme price costing changes
6196 Yahoo Store - Batch Manager SO/Invoice Conf. Email
6365 Ability to e-mail quotes
6534 Add EDI checkbox on save
6563 AP And AR Aging Scheduled Through Batch Manager - Increment AsOf
6898 Expand System Messages so they can be sent to specific users or user groups
7210 Send reminder notice to customers on Monthly Billing
7561 Add Batch Manager email for FRE Reports
7670 E-mail EDI profiles on customers do not work
7753 Add doc number to Print title
7272 Batch Manager: Column For Doc Number
8085 Outbound emails (invoice, SO, etc.) through Batch Manager should create Comment log
8110 Ability to e-mail credit memos and A/R statements
8122 Allow item files to be extracted to a package by PO, BOM or Item
8265 Completed actions don't give adequate info
8322 Add from and bcc addresses to EDI profiles
8614 Add bcc option to EDI profiles
8643 returns and refunds needs additional refinement (more specifically sending return statements via email)
6625 Vendor Forms that function the same way as Customer Forms
4933 Print PO with Rep Def by Vend Type

Feature requests 6625 and 4933 are included in this list because doing so might lead to simplification of the EDI processing, even though the overall application might become more complex. At the moment, some of the differences between Sales and Purchasing EDI involve using Sales Order forms as opposed to hardcoding the name of the Purchasing report. If all EDI documents operated through forms then the internals of EDI handling would need less special case handling.

Feature request 8345, bundling the Batch Manager into a separate package, is also related, as EDI profiles are currently used in conjunction with the Batch Manager.

There are also comments in the source files for the Return Authorization and Open Return Authorizations windows to allow sending Return Authorizations via e-mail.

Conflicting Features

N/A

User-Level Functionality

Currently there are several places in the application that allow the user to enter EDI Profile information. The entry method for profile information will be standardized, all EDI Profiles will be stored in a central location, the user interface will be modified to allow associating multiple EDI Profiles with a single parent record (such as Customer or Vendor), and the code for interactive and batch processing of EDI transfers will be normalized. This should reduce the amount of code required overall, allow supporting a number of new document types, allow more flexibility in the tokens accepted for embedding in EDI messages, and make the internals easier to follow.

The artificial distinction between using generating PDF for email EDI and PDF or tab- or comma-delimited files for FTP will be eliminated. The artificial distinction between associating document types with FTP profiles and not doing so with email profiles will also be eliminated.

As much as possible, the code to handle EDI Profiles will be removed from the guiclient C++ code, where it is currently hidden if the Batch Manager is unavailable, and reimplemented as scripts in the xtbatch package. This will make the generic core smaller and easier to maintain. This will also allow experimenting with defining generic signals to be emitted by the core GUI client for capture by scripts.

Window Changes

The EDI Profile window will be rearranged to allow email as well as FTP profiles to have associated form details and document types. The Forms may be left blank for email profiles. New fields will be added to expand the functionality of email handling: From, CC, BCC, and Reply-to addresses. Any or all of these may be left blank by the user. If the From address is left blank, email messages constructed from this EDI Profile will use the current methods for determining the From address. If the other fields are left blank then the corresponding fields in the email header will not be set. The contents of the From, Reply To, To, Cc, Bcc, Subject, and Message Body fields will all be processed for </name> tokens before the message gets sent.

Screenshot of proposed EDI Profile window for an email profile. Screenshot of proposed EDI Profile window for an FTP profile.

When the user defines a report form for the EDI Profile (as opposed to a CSV or TSV form), s/he will be given a combo box that lists the defined reports. If the document type is one that has a form mapping, such as Invoice, then the combo box will show "Use Pre-Assigned Form". The combo box will be disabled if the application has not yet been extended to allow form selections or if report names are still hardcoded for this document type (for example, the hard coded "PurchaseOrder" in 3.2.x and earlier).

After EDI Profiles are created, they may be associated with particular Customers, Vendors, Ship-To Addresses, Alarms, Incident Categories, etc. For example, the Vendor window's Transmission tab will be changed to look like this:

 proposed vendor Transmission tab showing EDI Profiles list

The Attach button will allow the user to attach a previously-defined EDI Profile to this Vendor. The Detach button will allow disassociating a selected EDI Profile from this Vendor. The New and Edit buttons will allow creating and modifying EDI Profiles for general use, although by default new EDI Profiles will only be associated with this one vendor. When the user clicks the Edit button for a Profile that is shared with other Vendors, Customers, etc., s/he will be asked if s/he wants to edit the shared Profile or make a copy of that shared profile for use with just this Vendor.

Similar changes will be made to the Customer window.

Whenever the user chooses to print a document, the xTuple ERP GUI client will check to see if there is an appropriate EDI Profile for this document and its intended recipient (e.g. there is an EDI Profile associated with this Customer's Ship-To address for this Sales Order). If the EDI Profile is for email delivery and is marked as "review before sending" then the user will be given a window resembling the current deliverInvoice, deliverPurchaseOrder, deliverSalesOrder, and deliverEmail window with the </name> tokens replaced by the appropriate values. The user will be allowed to edit the email addresses, subject, and message body before sending. As in the current implementation, the user will not be given the option to see the generated report PDF or CSV. If the EDI Profile is for FTP delivery or is not marked for review before sending, the EDI message will be submitted to the Batch Manager for completion and delivery and the user will be shown a message box showing how many documents have been submitted.

The deliverInvoice, deliverPurchaseOrder, deliverSalesOrder will be merged into a single window, and possibly merged with the deliverEmail window.

One feature hinted at by the existing code is the ability to have the locally-printed version of the document to differ from the electronic version sent to the recipient. This appears to be partially implemented for Invoices through the ediform table and for Sales Orders through the presence of a Report combo box on the deliverSalesOrder window. This feature must be preserved but made more transparent if a better user interface can be found.

There will be a new EDI History window. This window will allow the user to select the EDI Profile type (email vs. FTP), a date range, either a particular document type or all document types, and either all recipients or some subset of recipients. insert image here

The following windows should remain relatively unchanged visually but may need to be modified internally to use the new EDI Profiles:

  • Reprint Invoices
  • Print Invoices
  • Purchase Order
  • Unposted Purchase Orders
  • Email Purchase Order Form - this will be the merged deliver* window
  • Sales Order - if cust email then deliverSalesOrder @ save&Add and at Save if printed
  • Email Invoice Form - this will be the merged deliver* window
  • Email Sales Order Form - this will be the merged deliver* window
  • Open Return Authorizations - this will get a new right-click option to send EDI if appropriate
  • Open Sales Orders
  • Print Invoices By Shipvia
  • Return Authorization - this will be modified to send EDI much like the Sales Order window does
  • Ship-To
  • Incident

It's unclear if there's a better way to associate EDI profiles with Incidents than through the Incident Category Definitions, although I'd like to think there is.

</token> Replacement for Email Profiles

All EDI Profiles will have three replacement tokens pre-defined: </doctype>, </docid>, and </docnumber>. For each type of document, there will be another token pre-defined for the primary document id (e.g. </invchead_id> for invoices, </pohead_id> for purchase orders, and </incdt_id> for incidents). In addition to these standardly available tokens, the person who creates an EDI Profile will be able to supply custom MetaSQL queries. The MetaSQL parser will be passed the standardly available tokens and their values in a parameter list. Each custom query belonging to the EDI Profile and defined for the current document type will then be executed and the first line of its results appended to the parameter list. This allows writing queries to build arbitrary lists of tokens to replace in the message body.

Sample EDI Profile showing use of a custom query to obtain additional replacement tokens.
Given the default tokens, the following query could be used to populate an EDI Profile shown below: SELECT vend_name, vend_number, p.cntct_email AS primary_email, s.cntct_email AS secondary_email,
           p.cntct_honorific AS primary_honorific, p.cntct_lastname AS primary_last
FROM pohead JOIN vendinfo ON (pohead_vend_id=vend_id)
LEFT OUTER JOIN cntct p ON (vend_cntct1_id=p.cntct_id)
LEFT OUTER JOIN cntct s ON (vend_Cntct2_id=s.cntct_id)
WHERE (pohead_id=<? value("docid") ?>);
Field on the EDI Profile window Value Notes
Type Email These tokens are only available for Email, except for </doctype>, </docid>, and </docnumber>
Document Type Purchase Order  
From [ blank ] defaults to "Default From Address" defined on Database Information window.
To </primary_email> Email address associated with the primary contact for this Vendor.
Cc </secondary_email> Email address associated with the secondary contact for this Vendor.
Message Body

To: </vend_name> (/vend_number)
Dear </primary_honorific> </primary_last>,
Attached is a PDF version of Purchase Order </docnumber>.
Thank you for your continuing partnership.
xTuple Purchasing

 

Report Changes

The EDIProfilesMasterList report will have to change to show new columns. If time permits it will be rewritten to group the email and ftp profiles separately and show different column headings for each.

Batch Manager Changes

The logic for determining which report to run for an EDI message, if any, will be removed from the Batch Manager code. All of the decisions on how to build the EDI message will be made by the GUI client and the stored procedures it calls. The flow inside the Batch Manager will be simplified to the following steps:

  1. Read Parameters
  2. Replace tokens (possibly recursive if there are token-replacement queries)
  3. Generate output
  4. Transmit output

The details of how to accomplish each of these steps will be embedded in a class hierarchy consisting of a parent class EDI and the child classes Email and FTP (find less generic names). The parent class will have a factory method that returns an instance of the proper subclass given an ediprofile_id.

Usability Considerations

EDI Profiles will be more complex than before, but hopefully the symmetry will make them easier to use than in earlier versions.

The </name> tokens need to be documented, including the use of queries to generate arbitrary tokens. The documentation should point to examples such as Alarms and Events, which will have system-supplied queries as well as profile fields that use them.

One potential problem is that people are used to looking for EDI Profile information on the Customer and Vendor windows and, because of problems in the existing code, might not be aware of uses of EDI Profiles in parts of the application they don't often visit. Therefore, they may not be aware that changes they make to EDI Profiles in the new system could affect other parts of the application (changing an EDI Profile used for a particular customer might also affect a Vendor, for example). To minimize the risk of harm from this, the application will ask users if they want to edit the shared version or work on a copy if they change an EDI Profile used multiple places.

How do we make more transparent the selection of different versions of a report to run for EDI purposes vs. local printing?

This spec specifically excludes generating the PDF or FTP files when the user previews the EDI before sending. Some users would find the ability to preview these data very helpful. This functionality should be implemented if we can address the following questions:

  • Do we really want to run the reports or queries twice, once for the user to preview and again when composing the message?
  • How do we present the paired message and attachments without taking over the entire display?
  • Have we misled the user if the final PDF differs because of last-minute changes to the document?

Problems and Alternatives

It would be nice to consolidate the EDI configuration into a single window, rather than leave it scattered about. The EDI Profiles window could be rewritten to be a more general Configure EDI/EMail window. The Default From Email Address should be moved from the Database Information window to Configure EDI/EMail. The EDI Profiles would be displayed as a list, along with the usual New, Edit, View, Delete buttons and possibly a Copy button.

Screenshot of proposed general Configure EDI/Email window.

It's unclear whether the Incident EMail options belong on the Configure CRM window or here, in part because it's unclear how to associate the individual categories of Incident email with ediprofiles. It might not be feasible to regularize Incident email in the first implementation pass because of this problem.

The fact that EDI Profiles are tied to specific recipients in this spec means that each recipient needs to be configured by hand. It would be nice if there were a default configuration by document type - every time a document of type X is generated, look for a recipient-specific profile/relation; if none is found then look for a recipient-generic profile/relation; use the first found profile/relation to generate the EDI. This could be implemented by allowing all three columns recipient id and type and email to be NULL in the edirelation table, as long as the document type were defined. The UI could get messy and there are some problems with data storage given the following questions:

  • Where in the GUI does this configuration take place? It could go in a second XTreeWidget on the generic EDI Profiles configuration window above.
  • How do we handle the case where most recipients share generic profiles but some potential recipients do not want to receive EDI?
  • How do we handle the case where half of the recipients want generic Email profiles and the other half want generic FTP profiles?

It would be nice to have the ability to consolidate EDI. For example, most recipients might like getting one email with all of their invoices for the day rather than one per invoice. On the other hand

  • It's hard to reconcile the one-at-a-time nature of generating the documents and associated batch manager submissions with the potential desire to group the results.
  • It's hard to know how to construct consolidated messages that aren't paper-centric. For example, how should a CSV file that contains multiple sales orders be organized? How does the Batch Manager know how to construct this file and also construct a single-sales-order file?

Is there a performance problem running all of the queries associated with an EDI Profile to get replacement tokens? Do we want to differentiate between 'get parameter' queries and 'get data' queries in the profile definition? Doing so would require an additional column or two and associated widgets.

Why do EDI Profiles use </name> instead of MetaSQL syntax? It would be nice if we could use MetaSQL. This would require that the upgrade rewrite EDI Profiles that already exist but would lead to more consistent usage throughout the application and give a lot more flexibility. For example, if an EDI Profile could be shared between Vendor and Customer docs, then the message body could contain a clause like this:

Attached is a copy of <? value("doctype") ?> <? value("docnumber") ?>.
Thank you for your <? if exists("cust_id") ?> business <? else ?> partnership <? endif ?>,
xTuple <? if exists("cust_id") ?> Sales <? else ?> Purchasing <? endif ?>

Would MetaSQL usage in EDI Profiles conflict in any way with sending HTML email? Would the MetaSQL directives interfere with saving the data from the windows into the database (QTextEdit::toPlainText() or QTextEdit::toRichText())? The potential problem with MetaSQL is the copious white-space it leaves behind after processing. There would have to be a regex replacement to consolidate unnecessary blanks and newlines. How can we be sure of the definition of 'unnecessary'?

Now that EDI handling is bundled as part of the xtbatch package instead of existing as components that are used in Manufacturing and Standard editions but not in PostBooks, there may be some problems that arise from the required changes to various views. The only way to handle this might be through vigorous documentation. There may be problems running upgrade scripts if there are site-specific views and functions that refer to the tables and views being changed.

If the adhoc email feature for mass mailings gets implemented (issue 5467, not specifically described in this spec), we should warn users about the risk of being blacklisted by Internet Service Providers. This feature would be for small-scale mailings only and isn't a substitute for using email marketing services.

Is it really appropriate for there to be only one ediprofile table? The ediprofile_option* columns are hard to figure out because they're overloaded. Maybe we should split this into child tables, one for email and another for ftp. That might make it easier to add a third edi type (about which we've recently heard inquiries on the forum). The parent ediprofile table would be empty; the data would actually be stored in its child tables.

Possible ediprofile parent table structure
ediprofile_id   serial  
ediprofile_name   text not null  
ediprofile_notes   text  
ediprofile_type   text not null 'email' or 'ftp'
ediprofile_filename   text the base filename to use when storing results, such as a PDF version of a report or a CSV file. This may include </name> tokens.

Then there would be a child table called ediemail to hold email-specific records with the following additional columns:

Fields specific to the proposed ediemail table, a child of the ediprofile table.
ediemail_from   text If null or blank, use the default From address as described above for the current system behavior.
ediemail_replyto   text If null or blank, this field will not be set in the email header.
ediprofile_to   text not null  
ediprofile_cc   text If null or blank, this field will not be set in the email header.
ediprofile_bcc   text If null or blank, this field will not be set in the email header.
ediemail_html   bool not null with default false If true, the email message will be composed with the body marked as HTML content. If false, the body will be treated as plain text.
ediemail_body   text not null  
ediemail_subject   text not null  
ediemail_preview   bool not null with default true If true, the </tokens> will be replaced in the from, replyto, to, cc, bcc, body, and subject, then shown to the user for final edit and approval before being sent.

For ftp EDI Profiles there would be an ediftp table for ftp-specific data:

Fields specific to the proposed ediftp table, a child of the ediprofile table.
ediftp_host   text not null  
ediftp_user   text not null  
ediftp_password   text not null  
ediftp_dir   text The directory in which to store the transfered EDI files.
ediftp_encrypted   bool not null with default false A value of true indicates that the host, user, password, and dir(ectory) fields of this record are stored in encrypted form using the local encryption key.

Internal Design

Now what does it look like from the inside?

Basic Algorithms

In the GUI client application when it's time to send EDI:

find the EDI profile for this document (see below)
if no EDI profile is found
  return - no EDI should be sent
end if
create a parameter list containing docid, doctype, and docnumber
if email and user should/can review
  for each query associated with this edi profile for this document type
    preprocess the query with metasql
    run the query limit 1
    add the column names and values to the parameter list passed in
  end for
  replace all tokens with values from the parameter list (could be a simple metasql call)
  display for editing
  if user clicks cancel
    return without saving
  else if user clicks save
    write the edited/token-substituted result to the batch and batch parameter tables
  end if
else // either an ftp profile or no review of email profile
  write the unprocessed message and parameters to the batch and batch parameter tables
end if

In the Batch Manager, processing is similar to the way it's done now, only more consistent across document types and edi profile types:

for each query associated with this edi profile for this document type
  preprocess the query with metasql
  run the query limit 1
  add the column names and values to the parameter list
end for
if this is a report EDI
  run the report with the populated parameter list to a .pdf
else if this is a CSV or TSV EDI
  for each query in the proper order
    preprocess the query with metasql
    run the query to completion
    write the data to a file with the proper delimiter
  end for
end if
if email
  replace all tokens in the message body and header with values from the parameter list (could be a simple metasql call)
  send the email
else if ftp
  send the .pdf, .csv, or .tsv file to the EDI Profile-defined destination
end if

Note that the token replacement is used twice, in the GUI client and in the Batch Manager. This will be implemented in an EDI helper class in the guiclient source directory and made available for linking into the Batch Manager. The knowledge of how to retrieve and format the data, put the pieces together into a properly constructed email message or transfer file, and deliver the completed message will remain in the Batch Manager. To simplify adding a third message format or delivery mechanism it might be worthwhile creating an abstract class with basic methods to generate the data, assemble the message, and deliver it, with the details of how this is done embedded in concrete classes (one for email and another for ftp).

To find the EDI Profile for a given document:

find the recipient's id (vend_id, cust_id, crmacct_id, ...) based on the doctype and docid
build a list of potential ediprofile records by searching edirelation for this recipient, looking for either this doctype or no doctype
if an ediprofile is found for the given doctype
  return the ediprofile
else if no ediprofile is found for the given doctype but an ediprofile is found for this recipient but with no doctype
  return the ediprofile
else
  there is no EDI to send
end if

Custom Widget Changes

The EDI History table and the potential need for an edirelation maintenance window might justify the creation of an EDIRecipient widget.

Do widgets/alarmMaint.cpp and widgets/alarms.cpp need to change?

Widgets that allow selecting an EDI Profile will be configured so the user can only select EDI Profiles defined for the current document type or for all document types. This will probably be an ad-hoc XComboBox.

Schema Changes

Table Changes

This feature will require a number of changes to the database schema, some of which are related to the creation of a separate xtbatch package feature 8345). The ediprofile and ediform tables will be removed from the public schema, since they are not part of PostBooks and their remaining there has lead to at least one bug.

In particular, the following columns will be removed:

From custinfo:

  • cust_ediemail
  • cust_edisubject
  • cust_edifilename
  • cust_ediemailbody
  • cust_edicc
  • cust_ediprofile_id
  • cust_soediemail text
  • cust_soedisubject
  • cust_soedifilename
  • cust_soediemailbody
  • cust_soedicc
  • cust_soediprofile_id
  • cust_ediemailhtml
  • cust_soediemailhtml

From shiptoinfo:

  • shipto_ediprofile_id

From vendinfo:

  • vend_ediemail
  • vend_ediemailbody
  • vend_edisubject
  • vend_edifilename
  • vend_emailpodelivery
  • vend_edicc
  • vend_ediemailhtml

incdtcat

  • incdtcat_ediprofile_id

The ediprofile table will change. It isn't yet clear whether new columns will be added for new functionality or if the ediprofile will become a parent table with one child for each transmission protocol. See Problems and Alternatives for more information. The discussion there lists the data that need to be stored, regardless of whether one table is used or three.

They will be replaced by a new table in the xtbatch schema that connects EDI profiles to the relevant parent records:

The new edirelation table

Column Name Description Data Type Comments
edirelation_id Primary key and internal id serial  
edirelation_ediprofile_id The EDI Profile to which this EDI Relation pertains integer not null foreign key to xtbatch.ediprofile_id

 

edirelation_recipient_id The recipient object to which this EDI Relation pertains integer This is the internal id of the Customer, Vendor, CRM Account, Tax Authority, ... to which this EDI Relation pertains. If this is NULL then this applies to all records, regardless of type.
edirelation_recipient_type The type of record to which the edirelation_recipient_id points. text not null

This, together with the edirelation_recipient_id, describe fully the object to which this EDI Relation pertains. Possible values are:

A CRM Account
C Customer
P Prospect
T Tax Authority
U System User (for alarms and events)
V Vendor

 What about Partner? Competitor? other CRM Account types?

edirelation_doctype The type of document for which this EDI Relation holds. text not null

The following values have been chosen to be consistent with document types in the gltrans table. Items marked * are not valid gltrans_doctype values but are known not to overlap with those values.

NULL Applies to all document types *
ADHOC Miscellaneous mail merge. How do we send these? *
AM Alarm *
AR A/R Statement *
CD Cash Deposit  
CK Check  
CM Credit Memo. Do we need separate values for A/R and A/P credit memos?  
CR Cash Receipt  
DM Debit Memo. Do we need separate values for A/R and A/P debit memos? *
EV Event *
IC Incident *
IN Invoice  
PO Purchase Order  
QT Quote *
RA Return Authorization *
SO Sales Order  
VO Voucher  

The table is unique on parent_id, parent_type, doctype. Correlate edirelation_doctype with xtbatch.ediprofile.ediprofile_type and xtbatch.ediform_type. Remove the type fields from ediprofile and ediform?

The ediprofile table will get new fields for replyto, bcc, and preview options. The storage formats of these fields are described above in the Problems and Alternatives description of ediprofile and possible child tables.

The edihist table will be added to capture all of the messages sent by EDI.

edihist_id serial  
edihist_ediprofile_id integer not null Foreign key to ediprofile_id
edihist_recipient_id integer not null Acts as a foreign key to a table defined by the edihist_recipient_type
edihist_recipient_type text not null One of the values of edirelation_recipient_type
edihist_doctype text not null See the edirelation_doctype list
edihist_docnumber text not null The document number
edihist_docid integer not null Acts as a foreign key to the internal id of the sent document (vohead_id, pohead_id, ... as determined by the doctype)
edihist_user text not null with default CURRENT_USER The username of the person who initiated the sending of the EDI. This should be taken from the batch record.
edihist_timestamp timestamp not null with default CURRENT_TIMESTAMP The timestamp when the EDI message was sent
edihist_message text not null The full content of the message sent, including email headers and attachments or the ftp'ed files. If the original message was binary then this is a uuencoded version of the message.

View Changes in public

The removal of ediform and ediprofile from the public schema will require that certain views in the public schema be changed: cust, shipto, and vend. If time permits, these views will be removed - they are known to cause both confusion and performance problems - but there are ~160 source files that refer to cust, ~70 to vend, and ~30 to shipto. If they cannot be removed then each of these views will need two versions, one for PostBooks and another in the xtbatch package. The versions in PostBooks will not have the EDI columns while the versions in the xtbatch package will have them but the underlying queries will be modified. The affected columns for each view are:

views/cust.sql

cust_ediemail
cust_edisubject
cust_edifilename
cust_ediemailbody
cust_edicc
cust_ediprofile_id

views/shipto.sql

shipto_ediprofile_id

views/vend.sql

vend_ediemail
vend_ediemailbody
vend_edisubject
vend_edifilename
vend_emailpodelivery
vend_edicc

API View Changes

The removal of ediform and ediprofile from the public schema will require that the API views named customer, custshipto, and vendor be changed. As the goal of the API Views is to mirror the windows in the GUI client and these fields are being moved off these windows, the EDI-related columns will be removed from the API views. The affected columns for each view are:

api.customer

so_edi_profile
so_edi_email
so_edi_cc
so_edi_subject
so_edi_filename
so_edi_emailbody
invc_edi_profile
invc_edi_email
invc_edi_cc
invc_edi_subject
invc_edi_filename
invc_edi_emailbody

api.custshipto

edi_profile

api.vendor

po_edi_email
po_edi_cc
po_edi_subject
po_edi_filename
po_edi_emailbody

A new view will be created to allow importing EDI Relations and EDI Profiles together.

Privileges

There will be a new privilege to allow the user to edit an EDI message before it gets sent. Currently the user can replace much of the text, including email addresses, when presented with an EDI message for review. The ability to see this message and the ability to change it should be controlled separately. For the first pass, the ability to see it will be controlled by the preview flag on the EDI Profile itself. Users without this new privilege will be able Cancel the sending of EDI.

 

Privileges for Reviewing EDI before sending

Name

Description

EditEDIEmailBeforeSending

Can Edit the message header and body of an EDI email before submitting the job to the Batch Manager for processing.

Stored Procedure Changes

The following stored procedures may need to be changed, but the details of how they will change have not yet been determined:

  • public.createRecurringInvoices
  • submitReportToBatch
  • public.getediprofileid
  • xtbatch.deleteediform
  • xtbatch.deleteediprofile
  • public.getediprofileid
  • public.getshiptonumberfrominfo 

Performance Considerations

The PostBooks edition of the application should run somewhat faster and be marginally smaller once these changes have been implemented because some of the code to implement EDI features will be removed. If the cust, vend, and shipto views are eliminated entirely, a large number of queries should run faster than they do currently.

If xtbatch is installed, either as an add-on module to PostBooks or as part of the Standard or Manufacturing editions, EDI functionality will run marginally slower because of added internal complexity and some windows may take marginally longer to open because they will have scripts to load.

Error Handling

No new errors are anticipated.

QA Considerations

The largest area of concern for QA purposes is upgrade testing. There will be a number of changed tables, with data shifted from one to another, so special consideration will have to be taken to ensure that EDI behaves the same way before and after the upgrade.

The second greatest area of concern is making sure that no features of the EDI functionality have been removed by the changes.

Not all Related Issues will be addressed in the first pass at implementation, so it's difficult to predict at the time of writing this spec exactly what will need testing.

Documentation Considerations

The Reference Guide for the various windows described above will need to be updated. In addition we should add to the Standard Edition or Batch Manager documentation a description of how EDI Profiles are used and how to build templates for use by EDI messaging.

We will also have to publicize the changes to EDI configuration before release so customers are not surprised by the new UI. Also, if the cust, vend, and shipto views are removed then customers will have to know this so they have a chance to update any reports that depend on these views.

Release Considerations

This functionality is targeted for xTuple ERP 3.3. The release of the GUI client and schema changes will have to be coordinated with the release of the xtbatch package.

The schema changes and references to the old schema in the GUI client should be staged such that the legacy features are not broken at any point. There are some uses of the values -1 and -2 in what should be foreign key fields pointing to ediprofile_id to cause special behavior and special care will be needed to handle these correctly during upgrade conversion and at runtime.

If the generalization of document type handling is completed, then implementation of any particular as-yet-unsupported document type (such as Quotes) can be put off for a future release. The addition of new mail header fields (such as bcc) is independent of the generalization or addition of new document types, so these can be implemented for different releases.

Upgrades will have to take existing Vendor, Customer, and Ship-To profile data and create ediprofile and edirelation data from them. The upgrades will also have to create new EDI Profiles to replace the hardcoded messages currently used for Incidents, Alarms, and Events.

Users of the Standard and Manufacturing editions may be confused by the changes in appearance to the GUI. However, we don't expect there to be a need to change existing EDI Profile definitions or report definitions.

 

petebisson's picture
Offline
Joined: 11/20/2008
Multiple Contact email handling

One topic that does not seem clear to me from this document is how to flexibly handle multiple contacts/ email addresses for a single customer.

Our custom implementation currently works on the following simple rules:

. Quotes and Sales Orders are emailed to the selected bill-to contact on the SO form, regardless of EDI profile settings.
(We override the free form bill-to logic on all customers & prospects to explicitly enable selecting a contact)

. Invoices, A/R statements, Credit Memos etc *always* go to the designated Billing Contact on the customer record, regardless of who the Order contact is.

. Purchase Orders and assorted "Where the heck is my delivery for P/O 12345?" type reports always go to the primary contact for a Vendor (covered by the example given above).

This ties in with (2) below

We will happily continue with our customised solution if nobody else wants this functionality, but it seems reasonable to us :-)

-----
Other thoughts and comments:

-----
1. Support user specific default from email addresses, names and signatures in addition to the global default from address.

Why use

To: </vend_name> (/vend_number)
Dear </primary_honorific> </primary_last>,
Attached is a PDF version of Purchase Order </docnumber>.
Thank you for your continuing partnership.
xTuple Purchasing

When you could have

From : </user_fullname> </user_email>
To: </vend_name> (/vend_number)
Dear </primary_honorific> </primary_last>,
Attached is a PDF version of Purchase Order </docnumber>.
Thank you for your continuing partnership.
</user_fullname>
</user_sig>

-----

2. Generic EDI profiles able to be allocated in the usual way to All Customers, Customer Groups, Vendors, Prospects etc would save huge amounts of (very repetitive) configuration.

The example given for the additional replacement tokens in the document is almost exactly what we currently do for all purchase orders to every vendor, but due to lack of support in the client all the lookup & replacement has to be done in a custom database function.

Variations of this are also done for all Quotes, Sales Orders and A/R Statements.

Should / could this be a default EDI profile tied to the Report rather than the intended recipient or recipient type?

-----
3. The (explicitly excluded above) preview PDF would be immensely useful as an option on "review before send" profiles.

Can either the existing Print Preview functionality in OpenRPT or the Qt classes QPrintPreviewDialog / QPrintPreviewWidget not be used to accomplish this?
(I know that's scope explosion rather than merely scope creep, but it would be handy ;-)

Failing that, why not enable passing the batchparams for the selected report through to the existing ScriptToolbox functionality?
(printReport() to PDF, return file to user or open with default PDF viewer)

----

I'll be back when I think of more ways to keep you busy ;-)

Regards,

Pete

julesstp's picture
Offline
Joined: 09/15/2009
Also looking for User params (From email)

I am also looking for user parameters like those listed in #1. I don't really understand how these parameters are created or where they are stored but maybe if pointed in the right direction I can figure it out. Especially the From field for email from user because if the user types in their email address incorrectly the email will fail.

gmoskowitz's picture
Online
Joined: 12/10/2008
Re: Also looking for User params (From email)

Now that this has actually been coded, released, and documented, you can find the answer of how to create your own tokens in the xTuple Connect 3.5 Product Guide's description here: http://www.xtuple.org/sites/default/files/prodguide/xTupleConnect-HTML3....

petebisson's picture
Offline
Joined: 11/20/2008
Better multipart mail handling

Pure wishful thinking here, but significantly better support for multipart emails would be nice.

Some uses for this:

. Real multipart/alternative emails (plain text and HTML in the same mail, inline images in signatures)
(Maybe go as far as to create the text/plain part from provided HTML text with the appropriate string processing)

. Multiple reports attached to a single email.
("Here's a copy of your statement and the three invoices you requested")

. Arbitrary attachments to emails in addition to rendered reports.
(Probably Base64 encoded on file selection through UI to avoid any file location issues?)

Pete

gmoskowitz's picture
Online
Joined: 12/10/2008
Re: Multiple Contact email handling

Pete,

Thanks for looking this over so quickly. I'll modify the spec to reflect what you've posted but I'm not sure what to say in some cases.

Quote:
One topic that does not seem clear to me from this document is how to flexibly handle multiple contacts/ email addresses for a single customer.

I'm confused... What's missing that you need? The first paragraph of the section on token replacement mentions populating the parameter list for token replacement using queries and the table's first line gives an example query. Flexible contact handling was the primary motivation for this section. Your rewritten message body example could easily be handled by either adding another couple of columns to the query or by adding a second query. Does this section need expansion and clarification?

Quote:
2. Generic EDI profiles able to be allocated in the usual way to All Customers, Customer Groups, Vendors, Prospects etc would save huge amounts of (very repetitive) configuration.
...
Should / could this be a default EDI profile tied to the Report rather than the intended recipient or recipient type?

EDI profiles are tied to Customers/Vendors/... because different recipients want/need the data in different formats. I'll make a note in the spec to provide a default profile tied to document types.

Quote:
3. The (explicitly excluded above) preview PDF would be immensely useful as an option on "review before send" profiles.
...
(I know that's scope explosion rather than merely scope creep, but it would be handy ;-)

Actually there were several concerns - scope creep, performance, and usability; do we really want to render PDF twice (once for the user and again when composing the message), how do we present the paired message and attachments without taking over the entire display, and have we misled the user if the final PDF differs because of last-minute changes to the document? I'll add this to the spec as a desirable feature anyway.

Quote:
Pure wishful thinking here, but significantly better support for multipart emails would be nice.

This is supposed to handle the routine mailings and file transfers, not the special cases like

Quote:
"Here's a copy of your statement and the three invoices you requested"

Message consolidation makes sense ("Here are all of today's invoices.") but that conflicts with the one-at-a-time nature of generating the requests. How do we queue the requests for the batch manager in such a way that it knows to bundle them together?

Look for spec updates later today.

Gil

petebisson's picture
Offline
Joined: 11/20/2008
Clarifications

Hi Gil,

I was already compiling a list of what I wanted adding to the xtBatch package, so this turned up at just the right time :-)

To address your queries:

Quote:
... Flexible contact handling was the primary motivation for this section. ...

Having re-read the spec, I think that I should in future be able to create a S/O profile with a query something like [select email for salesorder_contact] and similarly for quotes.

For invoices etc it would be [select email for cust_billing_contact]

If this is correct, then that's fine - I obviously missed something on the first pass how the new profiles would work.

I didn't explain clearly the thinking about user name replacement templates.

I think that /user_fullname or perhaps /user_firstname and /user_lastname should be provided as additional globally available macros. While I understand that these could be built in MetaSQL I can see these being used as often as doctype and docnumber.

Quote:
EDI profiles are tied to Customers/Vendors/... because different recipients want/need the data in different formats.
I'll make a note in the spec to provide a default profile tied to document types.

The document types concept was really just me thinking aloud. Being able to assign an edi profile to e.g. {All Customers | Customer Group |Customer Group pattern ?} would be consistent with other similar mappings across the whole application, and would satisfy my needs. Obviously this would need to do the usual checks to select the correct profile, but that's a solved problem in every other [whatever]Assignment in xTuple.

Quote:
(PDF) ... scope creep, performance, and usability...

Understood. However this feature is so compelling for us that I have already tweaked OpenRPT to make the PreviewDialog available to the script toolbox ( by overloading orReport::print ). It's a proof-of-concept hack at the moment, but I'll clean it up and submit a patch for discussion.

I would expect the UI to simply have a button or active link that would render the PDF when clicked. This is usual for attachments in a compose window for just about every GUI mail client out there, and would only add extra rendering on demand.

I agree that there might be edge cases where the report data could change between the preview and the batch job, but I think this would probably be used mostly for send-it-now type reports like sales orders or quotes. Maybe this could be a configuration option on the new EDI profile?

Quote:
... routine mailings and file transfers ...

I guess that was another bad example then :-D

Obviously these would not (usually!) be attached directly via an edi profile, but would be selected by the user, probably on the preview email form. A very frequent use case for us would be to attach a print proof to a sales order acknowledgement - on over 90% of orders!

Having the batch_filename field in the main batch table looks like a hard coded assumption that there will only ever be one attachment per email.

Support for multiple reports and/or arbitrary binary attachments for one email would need to be designed into the batch manager revisions, for example batch_filename would have to move out of batch down to an appropriate child table - probably into batchparam (insert appropriate database hand waving here).

Cheers,

Pete

petebisson's picture
Offline
Joined: 11/20/2008
... and another thing

All my comments so far have been regarding the email functionality of xtBatch, but I have also been thinking about "proper" EDI functionality.

Should we consider allowing for (future) expansion of the transmission capability of the system during this redesign?

The most obvious example would be allowing for HTTP(s) transmission (required for things like AS2).

This could also provide the mechanism for re-synchronising xTuple with web stores (update third party carts etc)

Note that I'm not suggesting all this goes into 3.3, I just think that restricting the new profile design to *only* FTP or email during the design phase might be the wrong thing to do.

I'll stop now ;-)

Pete

EDIT:

The spec seems to disagree with itself on this point. It does mention possibly splitting out transmission protocols, but the ediprofile table design has an 'email' or 'ftp' restriction on it.

I read the table spec but not the further thoughts before adding this comment.