I had to do some custom development to upload/Attach document in Ax programmatically from a webApi. So I did some research on what is the best way to it.
here I share the different options I found to do it.
OPTION 1
USE \Classes\DocuActionArchive\add (it extends DocuActionFile)
NOTE, is the preferred way, but doesn't let you customize anything. the description of the file is the file name
static void JobEF_DocumentInsert(Args _args)
{
DocuType docuType;
DocuTypeId docuTypeId;
DocuRef docuRef;
DocuValue docuValue;
DocuActionArchive archive;
Filename filename;
HcmDiscussion hcmDiscussion;
docuTypeId = 'AppraisalEnrico';
hcmDiscussion = HcmDiscussion::findByDiscussionWorker('xx', HcmWorker::findByPersonnelNumber('xx').RecId);
filename = @'\\...\Myfile.PNG';
if ( ! hcmDiscussion ) return;
docuType = DocuType::find(docuTypeId);
ttsBegin;
docuRef.RefCompanyId = hcmDiscussion.DataAreaId;
docuRef.RefTableId = hcmDiscussion.TableId;
docuRef.RefRecId = hcmDiscussion.RecId;
docuRef.TypeId = docuType.TypeId;
docuRef.insert();
archive = new DocuActionArchive();
archive.add(docuRef, filename);
ttsCommit;
}
OPTION 2
USE \Classes\DocuActionFile\insertDocuValue
Note: seems quite good option. you can't use this method directly as it is an abstract class, use \Classes\DocuActionArchive\
static void JobEF_DocumentInsert2(Args _args)
{
DocuType docuType;
DocuTypeId docuTypeId;
DocuRef docuRef;
DocuValue docuValue;
DocuActionArchive archive;
Filename filename;
HcmDiscussion hcmDiscussion;
docuTypeId = 'AppraisalEnrico';
hcmDiscussion = HcmDiscussion::findByDiscussionWorker('xx', HcmWorker::findByPersonnelNumber('xx').RecId);
filename = @'\\...\Myfile.PNG';
if ( ! hcmDiscussion ) return;
docuType = DocuType::find(docuTypeId);
ttsBegin;
docuRef.RefCompanyId = hcmDiscussion.DataAreaId;
docuRef.RefTableId = hcmDiscussion.TableId;
docuRef.RefRecId = hcmDiscussion.RecId;
docuRef.TypeId = docuType.TypeId;
docuRef.Name = strFmt('prova - %1', Docu::getFileName(filename));
docuRef.insert();
archive = new DocuActionArchive();
archive.insertDocuValue(docuRef, filename);
ttsCommit;
}
OPTION 3
NOTE: is using Docu::insertFile. more complex.
static void JobEF_DocumentInsert1(Args _args)
{
DocuType docuType;
DocuTypeId docuTypeId;
DocuRef docuRef;
DocuValue docuValue;
DocuActionArchive archive;
Filename filename;
DocuValueFile file;
BinData binData;
boolean fileLocked;
HcmDiscussion hcmDiscussion;
#File
//done like: \Classes\TrvImportReceiptsBatch\processFolder
DocuValueFile getDocuValueFile(FileName _fullPathOfFile)
{
binData = new BinData();
new FileIOPermission(_fullPathOfFile,'r').assert();
// BP Deviation documented
binData.loadFile(_fullPathOfFile);
CodeAccessPermission::revertAssert();
return binData.getData();
}
//done like: \Data Dictionary\Tables\DocuValue\Methods\writeDocuValue
DocuValueFile getDocuValueFile1(FileName _fullPathOfFile)
{
binData = new BinData();
if (isRunningOnServer())
{
// Assert permission and get the temp filename
new FileIOPermission(_fullPathOfFile,#io_read).assert();
// BP deviation documented
fileLocked = WinApiServer::fileLocked(_fullPathOfFile);
CodeAccessPermission::revertAssert();
}
else
{
// BP deviation documented
fileLocked = WinApi::fileLocked(_fullPathOfFile);
}
// Insert to database
if (fileLocked)
{
info("@SYS72783");
}
else
{
// LoadFile demands read permission on the file
new FileIOPermission(_fullPathOfFile, #io_read).assert();
// BP deviation documented
if (binData.loadFile(_fullPathOfFile)) //only works if file not locked
{
file = binData.getData();
}
CodeAccessPermission::revertAssert();
}
return file;
}
docuTypeId = 'AppraisalEnrico';
hcmDiscussion = HcmDiscussion::findByDiscussionWorker('123', HcmWorker::findByPersonnelNumber('123').RecId);
filename = @'\\...\Myfile.PNG';
file = getDocuValueFile(filename);
if ( ! hcmDiscussion ) return;
docuType = DocuType::find(docuTypeId);
ttsBegin;
docuRef.RefCompanyId = hcmDiscussion.DataAreaId;
docuRef.RefTableId = hcmDiscussion.TableId;
docuRef.RefRecId = hcmDiscussion.RecId;
docuRef.TypeId = docuType.TypeId;
docuValue = Docu::insertFile(docuRef, filename, file, true);
docuRef.ValueRecId = docuValue.RecId;
docuRef.Name = 'mia prova';
docuRef.insert();
ttsCommit;
}
OPTION 4
USE \Classes\DocumentFileHelper\attachDocumentAsUser
SEE EXAMPLE: \Data Dictionary\Tables\RetailDiscountCode\Methods\createBarCodeImage
private void createBarCodeImage()
{
#define.AttachmentName('BarcodeImage.jpg')
RetailSharedParameters sharedParams;
BarcodeSetup barcodeSetup;
str base64ImageString;
container attachDocumentParams;
DocuRef DocuRefTable;
RecId docuRefRecId;
if (this.BarCode)
{
// Get selected barcode
select firstOnly BarcodeSetupId from sharedParams
join RetailBarcodeMask, fontName, fontSize from barcodeSetup
where sharedParams.barcodeSetupId == barcodeSetup.barcodeSetupId;
// Get base64 string of barcode image.
base64ImageString = RetailBarcodeManagement::getBarcodeJpegImageAsBase64String(this.BarCode, barcodeSetup.fontName, barcodeSetup.fontSize);
// Attach barcode image to the discount code.
attachDocumentParams = [0, base64ImageString, #AttachmentName, '', DateTimeUtil::utcNow(), this.TableId, this.RecId, curext(), DocuType::typeFile()];
[docuRefRecId] = DocumentFileHelper::attachDocumentAsUser(attachDocumentParams);
// Make attached image external.
select forUpdate DocuRefTable where DocuRefTable.RecId == docuRefRecId;
// set document description to 'Bar code'
DocuRefTable.Name = "@RET3053";
DocuRefTable.Restriction = DocuRestriction::External;
DocuRefTable.update();
}
}
OR see \Classes\TrvUnreconciledExpenseService\createAttachments
OR \Classes\TrvReceiptService\createReceiptHelper
private DocuRef createReceiptHelper(RefTableId _tableId, RefRecId _recId, DataAreaId _dataAreaId, str _name, str _documentName, str _documentContents)
{
Filename documentName;
FilePath documentUrl;
RefRecId contentType;
str documentFile;
DocumentFileReceiveDate receiveDate;
DocuTypeId docuTypeId;
TrvReceiptsHelper trvReceiptsHelper = new TrvReceiptsHelper();
container args;
RecId createdRecId;
DocuRef docuRef;
[documentName, documentUrl, contentType, receiveDate, documentFile] = DocumentFileHelper::getValidateUnpackedDocumentFileData(
_documentName, "", "",
DateTimeUtil::utcNow(), _documentContents);
docuTypeId = trvReceiptsHelper.getDocuTypeId();
args = [contentType, documentFile, documentName, documentUrl, receiveDate, _tableId, _recId, _dataAreaId, docuTypeId];
[createdRecId] = DocumentFileHelper::attachDocumentAsUser(args);
if (createdRecId != 0)
{
docuRef = DocuRef::findRecId(createdRecId, true);
if (_name != '')
{
docuRef.Name = _name;
}
else
{
docuRef.Name = "@SYS138348";
}
docuRef.update();
}
return docuRef;
}
NOTE to get the documentContents see: \Classes\TrvReceiptService\getDocumentContents
....
// Get the receipt contents and serialize them.
binData = DOCommonDocuUtils::GetDocuContent(docuRef);
if (binData && conLen(binData.getData()) > 0)
{
documentContents = binData.base64Encode();
}
return documentContents;
------------------------------------------------
Finally I didn’t use none of them but I ended extending an existing class which gives me the advantage to code less (always use existing methods!) and also to upload all the files in a directory in one go. So from the WebApi I create a shared folder where I upload all the documents I want to be attached to an Ax record and my extended class is responsible to Attach the document.
When the process ends Ax deletes the shared folder.
class MYD_HcmDiscussionAttachmentHelper extends TrvImportReceiptsBatch
{
HcmDiscussion hcmDiscussion;
DocuTypeId docuTypeId;
}
//for trials only
public static void main(Args _args)
{
FilePath dirPath;
HcmDiscussion hcmDiscussion;
MYD_HcmDiscussionAttachmentHelper cl = new MYD_HcmDiscussionAttachmentHelper();
dirPath = @'\\...\temp\000198';
hcmDiscussion = HcmDiscussion::findByDiscussionWorker('000198', HcmWorker::findByPersonnelNumber('123').RecId);
cl.parmDirPath(dirPath);
cl.parmHcmDiscussion(hcmDiscussion);
cl.parmDocuTypeId('AppraisalEnrico');
cl.run();
}
boolean importFile(Filename _filename, DocuValueFile _file)
{
DocuRef docuRef;
DocuValue docuValue;
boolean ret = false;
if (hcmDiscussion)
{
ttsbegin;
docuRef.RefCompanyId = hcmDiscussion.DataAreaId;
docuRef.RefTableId = hcmDiscussion.TableId;
docuRef.RefRecId = hcmDiscussion.RecId;
docuRef.TypeId = docuTypeId;
docuValue = Docu::insertFile(docuRef, _filename, _file, true);
docuRef.ValueRecId = docuValue.RecId;
docuRef.Name = System.IO.Path::GetFileNameWithoutExtension(_filename);
docuRef.insert();
ttscommit;
ret = true;
}
return ret;
}
public DocuTypeId parmDocuTypeId(DocuTypeId _docuTypeId = docuTypeId)
{
docuTypeId = _docuTypeId;
return docuTypeId;
}
public HcmDiscussion parmHcmDiscussion(HcmDiscussion _hcmDiscussion = hcmDiscussion)
{
hcmDiscussion = _hcmDiscussion;
return hcmDiscussion;
}
public void run()
{
boolean result = true;
try
{
super();
}
catch
{
result = false;
}
if (result)
{
new FileIOPermission(dirPath,'W').assert();
System.IO.Directory::Delete(dirPath, true);
CodeAccessPermission::revertAssert();
}
}
No comments:
Post a Comment