Hey guys and gals,
I am implementing the Warehouse interface for a customer. From the WMS foreign system we get responses on pick orders. We get "ready packed" as an example. When everything is ready packed i should create a proforma packing slip and a proforma invoice. These are then transferred to the WMS system and are placed in the package. Later I have to post the invoice and the packing slip. I then have to make sure that the quantities, numbers etc. are correct.
I will try to explain the process that causes my problem below.
A confirmation of a pick order comes from the WMS with the message everything packed. Now we open a transaction, update the pick order, update quantities in the WMS shipment, write carton data, etc. Afterwards a proforma invoice and a packing slip should be created to the pick order. The documents are then transferred via interface to the WMS system where they are printed. If an error occurs, the transaction is rolled back and an error message appears.
When I create the proforma invoice and the proforma packing slip in a transaction there is a deadlock. If I have no transaction everything goes through. We almost think that this is a bug in d365. We are on the PU49. Here is my code...
public FormLetterToPrintArchiveResponse saveInvoiceFormLetterToPrintArchive(SalesId _salesId, SalesUpdate _specQty, boolean _proforma) { FormLetterToPrintArchiveResponse ret = new FormLetterToPrintArchiveResponse(); SalesFormLetter salesFormLetter = SalesFormLetter::construct(DocumentStatus::Invoice); SalesParmLine parmLine; SalesLine salesline; SalesTable localSalesTable; SRSPrintDestinationSettings printerSettings = new SRSPrintDestinationSettings(); guid uid = newGuid(); str fn_noext = guid2Str(uid); Filename fn = strFmt("%1.pdf", fn_noext); localSalesTable = SalesTable::find(_salesId); SRSPrintArchiveContract ac = new SRSPrintArchiveContract(SRSReportFileFormat::PDF); printerSettings.parmSRSPrintArchiveContract(ac); printerSettings.printMediumType(SRSPrintMediumType::Archive); printerSettings.fileFormat(SRSReportFileFormat::PDF); printerSettings.overwriteFile(true); printerSettings.fileName(fn); salesFormLetter.updatePrinterSettingsFormLetter(printerSettings.pack()); salesFormLetter.update(localSalesTable, systemDateGet(), _specQty, AccountOrder::None, _proforma, true, false); DocuRef docuRef; select firstonly docuRef where docuRef.RefTableId == tableNum(PrintJobHeader) && docuRef.Name == fn_noext && docuRef.ActualCompanyId == curExt(); ret.parmDocuRef(docuRef); ret.parmFileName(fn); ret.parmFileNameWithoutExtension(fn_noext); ret.parmPrinJobHeaderRecId(docuRef.RefRecId); return ret; }
The deadlock will be created here...
SrsReportRunRdpPreProcessStrategyRegular.cleanUp()
When the table SalesInvoiceHeaderFooterTmp should be deleted another connection with a cursor is blocking the delete. All other tables are working. When i run the same code with DocumentStatus::PackingSlip it will also run fine. Just on salesformletter_invoice ther is the problem. Sure, a packing slip do not need the SalesInvoiceHeaderFooterTmp i think.
////// Cleans up any pre-processed data. /// /// /// SrsReportPreProcessedDetails table. /// /// /// UserConnection object to use to connect. Optional. /// /// /// Iterates through all report tables and deletes data. /// public void cleanUp(SrsReportPreProcessedDetails _preProcessedTable, UserConnection _userConnection = null) { Set dataTables = rdpMetadata.getReportSchema(rdpInstance).getReportDataTables(); SetEnumerator dataTableEnum; SRSReportDataTable dataTable; Common tableBuffer; SysDictTable dictTable; if(_userConnection) { if (!isFlightEnabled(#SrsReportUserConnectionFinalizerLegacy)) { if(uc) { uc.finalize(); } } uc = _userConnection; } // start tx. if(_preProcessedTable) { uc.ttsbegin(); if(_preProcessedTable.CreatedTransactionId && dataTables && dataTables.elements() > 0) { dataTableEnum = dataTables.getEnumerator(); while(dataTableEnum.moveNext()) { dataTable = dataTableEnum.current(); dictTable = dataTable.getDictTable(); tableBuffer = dictTable.makeRecord(); tableBuffer.setConnection(uc); delete_from tableBuffer where tableBuffer.CreatedTransactionId == _preProcessedTable.CreatedTransactionId; } } // commmit tx. uc.ttscommit(); } super(_preProcessedTable, uc); }
if i do it like this..
ttsbegin; // update PickingRoute, check remaining qty on WMSShipment etc.... myClass.saveInvoiceFormLetterToPrintArchive(...); ttscommit;
it won't work.
If i do it like this..
//ttsbegin; // update PickingRoute, check remaining qty on WMSShipment etc.... myClass.saveInvoiceFormLetterToPrintArchive(...); //ttscommit;
it all works great...