Problem:
One of our clients uses Sage 500 as its ERP. One shortcoming we encountered when dealing directly with the data in the tables is that when tying sales orders to invoices, sales orders to shipments, invoices to shipments, etc using the trankeys, it requires multiple table joins to get there.
For example: To tie the sales order to the invoice, you tie the tsoSalesOrder table to tsoSOLine, then tie tsoSOLine to tsoSOLineDist, then tie tsoSOLineDist to tarInvoiceListDist, then tie tarInvoiceListDist to tarInvoiceDetl, then tie tarInvoiceDetl to tarInvoice and then you have tied the sales order to the invoice. That is 5 joins to connect 2 transactions, simply inefficient.
Seems rather like a long way to get to that data. We came up with an idea that seems to work for those of you struggling with a similar dislike of the long path to get two tables for related transactions to tie together. We created a trankeys table that pulls the trankeys from sales orders, invoices, shipments and RMAs into a single table. Then we can tie sales orders, invoices, shipments and RMAs together with one join.
For those that need it, here's the table structure that we used and the way we're populating it.
SQL Script Solution:
CREATE TABLE #tmp ( SOKey INT NULL ,SOLineKey INT NULL ,SOLineDistKey INT NULL ,InvcKey INT NULL ,InvoiceLineKey INT NULL ,InvoiceLineDistKey INT NULL ,RMAKey INT NULL ,RMALineKey INT NULL ,ShipKey INT NULL ,ShipLineKey INT NULL ,ItemKey INT NULL ,SOTranID VARCHAR(13) NULL ,InvTranID VARCHAR(13) NULL ,RMATranID VARCHAR(13) NULL ,ShipTranID VARCHAR(13) NULL ,ItemID VARCHAR(50) NULL ,CompanyID VARCHAR(3) NOT NULL ,PickListKey INT NULL ,PickListNo VARCHAR(10) NULL ); -- Create base data SELECT so.SOKey ,sol.SOLineKey ,sold.SOLineDistKey ,sol.ItemKey ,so.TranID ,i.ItemID ,so.CompanyID INTO #tmpSO FROM tsoSalesOrder so WITH ( NOLOCK ) LEFT JOIN tsoSOLine sol WITH ( NOLOCK ) ON so.SOKey = sol.SOKey LEFT JOIN tsoSOLineDist sold WITH (NOLOCK) ON sol.SOLineKey = sold.SOLineKey LEFT JOIN timItem i WITH ( NOLOCK ) ON sol.ItemKey = i.ItemKey WHERE so.CompanyID IN (YOUR LIST OF COMPANY IDs HERE); SELECT i.InvcKey ,d.InvoiceLineKey ,l.InvoiceLineDistKey ,l.SOLineDistKey ,d.SOLineKey ,d.ItemKey ,d.ShipLineKey ,i.TranID ,it.ItemID ,i.CompanyID INTO #tmpInv FROM tarInvoice i WITH (NOLOCK) LEFT JOIN tarInvoiceDetl d WITH (NOLOCK) ON i.InvcKey = d.InvcKey LEFT JOIN tarInvoiceLineDist l WITH (NOLOCK) ON d.InvoiceLineKey = l.InvoiceLineKey LEFT JOIN timItem it WITH (NOLOCK) ON d.ItemKey = it.ItemKey WHERE i.CompanyID IN (YOUR LIST OF COMPANY IDs HERE); SELECT r.RMAKey ,l.RMALineKey ,l.SOLineDistKey ,l.ShipLineKey ,it.ItemKey ,r.TranID ,it.ItemID ,r.CompanyID ,ship.InvcKey INTO #tmpRMA FROM tsoRMA r WITH (NOLOCK) LEFT JOIN tsoRMALine l WITH (NOLOCK) ON r.RMAKey = l.RMAKey LEFT JOIN timItem it WITH (NOLOCK) ON l.ItemKey = it.ItemKey LEFT JOIN tsoShipLine sl WITH (NOLOCK) ON l.ShipLineKey = sl.ShipLineKey LEFT JOIN tsoShipment s WITH (NOLOCK) ON sl.ShipKey = s.ShipKey LEFT JOIN tsoInvoiceShipment ship WITH (NOLOCK) ON s.ShipKey = ship.ShipKey WHERE r.CompanyID IN (YOUR LIST OF COMPANY IDs HERE); SELECT s.ShipKey ,ld.SOLineDistKey ,l.ShipLineKey ,l.SOLineKey ,l.ItemKey ,s.TranID ,i.ItemID ,s.CompanyID ,invship.InvcKey ,l.PickListKey ,pl.PickListNo INTO #tmpShip FROM tsoShipment s WITH (NOLOCK) LEFT JOIN tsoShipLine l WITH (NOLOCK) ON s.ShipKey = l.ShipKey LEFT JOIN tsoShipLineDist ld WITH (NOLOCK) ON l.ShipLineKey = ld.ShipLineKey LEFT JOIN timItem i WITH (NOLOCK) ON l.ItemKey = i.ItemKey LEFT JOIN tsoInvoiceShipment invship WITH (NOLOCK) ON s.ShipKey = invship.ShipKey LEFT JOIN tsoPickList pl WITH (NOLOCK) ON l.PickListKey = pl.PickListKey WHERE s.CompanyID IN (YOUR LIST OF COMPANY IDs HERE); INSERT INTO #tmp ( SOKey ,SOLineKey ,SOLineDistKey ,InvcKey ,InvoiceLineKey ,InvoiceLineDistKey ,RMAKey ,RMALineKey ,ShipKey ,ShipLineKey ,ItemKey ,SOTranID ,InvTranID ,RMATranID ,ShipTranID ,ItemID ,CompanyID ,PickListKey ,PickListNo ) SELECT so.SOKey ,so.SOLineKey ,so.SOLineDistKey ,inv.InvcKey ,inv.InvoiceLineKey ,inv.InvoiceLineDistKey ,rma.RMAKey ,rma.RMALineKey ,ship.ShipKey ,ship.ShipLineKey ,COALESCE(so.ItemKey, inv.ItemKey, rma.ItemKey, ship.ItemKey) ItemKey ,so.TranID SOTranID ,inv.TranID InvTranID ,rma.TranID RMATranID ,ship.TranID ShipTranID ,COALESCE(so.ItemID, inv.ItemID, rma.ItemID, ship.ItemID) ItemID ,COALESCE(so.CompanyID, inv.CompanyID, rma.CompanyID, ship.CompanyID) CompanyID ,ship.PickListKey ,ship.PickListNo FROM #tmpSO so FULL JOIN #tmpInv inv ON so.SOLineKey = inv.SOLineKey AND so.SOLineDistKey = inv.SOLineDistKey FULL JOIN #tmpShip ship ON so.SOLineDistKey = ship.SOLineDistKey AND inv.InvcKey = ship.InvcKey FULL JOIN #tmpRMA rma ON so.SOLineDistKey = rma.SOLineDistKey AND inv.InvcKey = rma.InvcKey /* Backfill here This corrects issues with things that are added to invoices directly, thereby adding ties to things like SO that don't exist */ UPDATE t SET SOKey = t2.SOKey FROM #tmp t JOIN #tmp t2 ON t.InvcKey = t2.InvcKey WHERE t.InvcKey IS NOT NULL AND t.SOKey IS NULL AND t2.SOKey IS NOT NULL; UPDATE t SET ShipKey = t2.ShipKey FROM #tmp t JOIN #tmp t2 ON t.InvcKey = t2.InvcKey WHERE t.InvcKey IS NOT NULL AND t.ShipKey IS NULL AND t2.ShipKey IS NOT NULL; UPDATE t SET SOTranID = t2.SOTranID FROM #tmp t JOIN #tmp t2 ON t.InvcKey = t2.InvcKey WHERE t.InvcKey IS NOT NULL AND t.SOTranID IS NULL AND t2.SOTranID IS NOT NULL; UPDATE t SET ShipTranID = t2.ShipTranID FROM #tmp t JOIN #tmp t2 ON t.InvcKey = t2.InvcKey WHERE t.InvcKey IS NOT NULL AND t.ShipTranID IS NULL AND t2.ShipTranID IS NOT NULL; DROP TABLE #tmpInv; DROP TABLE #tmpRMA; DROP TABLE #tmpShip; DROP TABLE #tmpSO; /* From this point you have the data loaded into your #tmp table so you can push itto your live table however you want We chose to just dump the data in the table and then reload it. It can be handled multiple ways but our process runs once per night so no need to keep it updated in real time */ BEGIN TRANSACTION myTran; TRUNCATE TABLE tblTranKeys; INSERT INTO tblTranKeys ( SOKey, SOLineKey, SOLineDistKey, InvcKey, InvoiceLineKey,InvoiceLineDistKey, RMAKey, RMALineKey, ShipKey, ShipLineKey, ItemKey, SOTranID, InvTranID, RMATranID, ShipTranID, ItemID, CompanyID, PickListKey, PickListNo ) SELECT SOKey, SOLineKey, SOLineDistKey, InvcKey, InvoiceLineKey,InvoiceLineDistKey, RMAKey, RMALineKey, ShipKey, ShipLineKey, ItemKey, SOTranID, InvTranID, RMATranID, ShipTranID, ItemID, CompanyID, PickListKey, PickListNo FROM #tmp; IF @@ERROR <> 0 ROLLBACK TRANSACTION myTran; ELSE COMMIT TRANSACTION myTran; DROP TABLE #tmp;
Conclusion:
Feel free to use this script however you like, however, Crackerjack-IT, Inc. is not responsible for the data accuracy in your system as this is adapted to one of our clients' systems, it is not guaranteed to work for your needs. If you need assistance with it, feel free to reach out to us.