Summary
JTL is a fulfillment platform. Merchants send their products to a JTL fulfillment partner, and the warehouse receives the goods, stores them, picks, packs, and then ships customer orders. Outsource warehousing to a JTL fulfillment partner without leaving Odoo. Orders flow to JTL automatically, and shipments validate in Odoo when JTL ships. It includes JTL authentication, configuration rules for each operation, background queues, and logs and alerts for failed records.
Odoo remains the system where products, orders and accounting are managed, while JTL handles the physical warehouse work. Products are sent to JTL and linked through the JTL product ID (JFSKU). Delivery orders are sent to JTL automatically based on defined rules, and when JTL ships them, the tracking number, carrier and weight are written back to Odoo and the delivery order is validated. Receipts are announced to JTL, stock levels are pulled back into Odoo, and returns can be announced to JTL and imported when they arrive at the warehouse. JTL does not push changes to Odoo, so Odoo sends data to JTL and checks JTL regularly for updates.
Authentication
The JTL instance is created in Odoo and the Client ID, Client Secret and Redirect URI from the JTL customer account are entered. The Redirect URI points back to the Odoo database, so that JTL can return the user to Odoo after login.
By clicking “Authenticate”, the user is redirected to the JTL login page and approves read and write access for Odoo. After approval, JTL returns to Odoo, and the Access Token and Refresh Token are automatically generated and saved on the instance. The instance status changes from Draft to Connected. The Fulfiller ID of the JTL fulfillment partner can then be fetched with one click.
The Access Token expires after a limited time, so the Refresh Token is used to obtain a new one automatically before each request. This allows Odoo to stay connected to JTL without the user having to authenticate again. Only if JTL rejects the Refresh Token does the instance need to be authenticated again, and an alert is then sent to the selected users.
Configuration
In the JTL instance, each flow has its own settings. For every flow we can define the operation types that should be sent to JTL, the status at which a transfer is sent, a delay before sending, a start date and the users who are alerted on errors. Master data is linked to JTL as well: the Odoo warehouse and stock location are chosen, JTL shipping methods are fetched and matched with the delivery methods in Odoo, and products receive their JTL product ID.
In this example, the Outbound Operation Type is selected as Delivery Orders, so delivery orders are sent to JTL. The Trigger Status is set to Ready, so a delivery order is sent only when its stock is reserved. The Sync Delay is set to 5 minutes, so the order is held for a short time to allow other internal processes to finish. The Start Date makes sure that only transfers created on or after that date are sent, which protects older records from being synchronized by mistake. A default shipping method is used when the delivery order does not define one.
Product Sync
Products are sent from Odoo to JTL through a product queue. The categories and the pricelist to use are chosen in the instance, and only storable products that are marked for synchronization, and are new or changed, are sent. Product pictures are uploaded together with the product.
When JTL creates the product, its JTL product ID (JFSKU) is stored on the Odoo product. For products that already exist in JTL, the JFSKU can be fetched and matched, so that no duplicate is created. Products can also be sent manually from the Products menu, and a button on the product opens it in the JTL portal.
Stock Sync
JTL is the source of truth for the stock held in the fulfillment warehouse. Stock changes are fetched from JTL into a stock queue and applied in Odoo as inventory adjustments on the stock location selected in the instance. Scrap quantities reported by JTL are booked on the selected scrap location.
The stock sync can run in three ways:
- Regular update: only the stock changes since the last sync are fetched.
- Refresh of older products: products whose stock was not updated for a number of days are read again from JTL, so that no product stays out of date.
- Full sync: the complete JTL stock is fetched, for example for the first setup or a manual correction.
Outbound Sync (Delivery Orders)
Send delivery order to JTL
Delivery orders of the selected operation types are sent to JTL as outbounds when they reach the trigger status and the products are available. Each outbound contains the delivery address, the products, the shipping method and the invoice and delivery note documents, which are generated from the selected reports. On the delivery order, the sync status, the JTL ID and the JTL shipping status are shown, and a button opens the outbound in the JTL portal. A delivery order is never sent twice, and an order that failed can be sent again after the error is corrected.
Shipping update from JTL
Odoo checks JTL regularly for the delivery orders that are not shipped yet. The tracking numbers, carrier, weight and JTL status are written to the delivery order. When JTL reports the outbound as shipped, the delivery order is validated automatically in Odoo, so stock moves out of the warehouse without any manual step. Stock reserved for a delivery order that was already sent to JTL is protected, so the order does not go back to Waiting before JTL ships it.
Inbound Sync (Receipts)
Receipts are announced to JTL as inbounds, so that the warehouse knows which goods to expect. Two modes are available. In the first mode, one JTL inbound is created for each receipt. In the second mode, all open receipts of one supplier are combined into one JTL inbound each night. The mode is selected in the instance and can be changed for individual suppliers. When JTL has received the goods, the status and the received quantities are returned and the receipt is updated in Odoo.
Internal Transfers
Internal transfers that move goods into or out of the JTL warehouse can be sent to JTL as well. For each case, a mapping defines the operation type, the source and destination locations, the trigger status, the delay, and whether the transfer is sent as an inbound or as an outbound. Transfers that match a mapping are then handled in the same way as receipts or delivery orders, including the status update from JTL.
Returns
Return transfers can be announced to JTL, so that the warehouse can identify the parcel when it arrives, and the return label can be downloaded from the return transfer. JTL also reports returns that were registered at the warehouse. Odoo checks for new returns regularly, skips the ones that already exist, links each return to its original order and delivery, and creates or completes the return transfer in Odoo. A past period can be fetched again if returns were missed, and a summary of the imported returns can be printed.
Queues, Logs and Alerts
Every exchange with JTL runs through a queue (product, stock, outbound, inbound and return). A queue shows its status and the number of records that are waiting, done or failed. Failed records can be processed again after the error is corrected, without affecting the other records.
The Logs menu lists the error of each failed record, and the Execution Log records every call to JTL with its result and duration, which helps to find the cause of a problem. Alerts can be switched on for each flow, and the selected users receive an email when a sync fails. Completed queues and old logs can be deleted automatically after a number of days.
Conclusion
The JTL integration in Odoo provides an easy way to run warehouse fulfillment through JTL. Products, delivery orders, receipts, internal transfers and returns are sent to JTL based on defined rules, while stock levels, shipping information and returns are brought back into Odoo. Delivery orders are validated automatically when JTL ships them. Queues, logs and alerts help to keep the data correct and make it easier to find and fix failed records between Odoo and JTL.