private void AttachFileToDocuments(Guid fileId, IEnumerable <ARInvoice> documents) { var fcache = this.Caches[typeof(NoteDoc)]; foreach (var d in documents) { var fileNote = new NoteDoc { NoteID = d.NoteID, FileID = fileId }; fcache.Insert(fileNote); this.Persist(typeof(NoteDoc), PXDBOperation.Insert); } }
/// <summary> /// AttachDataAsFile /// </summary> /// <remarks>Invoke before persisting of DAC</remarks> public static void AttachDataAsFile(string fileName, string data, IDACWithNote dac, PXGraph graph) { var file = new FileInfo(Guid.NewGuid(), fileName, null, SerializationHelper.GetBytes(data)); var uploadFileMaintGraph = PXGraph.CreateInstance <UploadFileMaintenance>(); if (uploadFileMaintGraph.SaveFile(file) || file.UID == null) { var fileNote = new NoteDoc { NoteID = dac.NoteID, FileID = file.UID }; graph.Caches[typeof(NoteDoc)].Insert(fileNote); graph.Persist(typeof(NoteDoc), PXDBOperation.Insert); } }
private void SynchronizeFolderContentsWithScreen(string screenID, string folderID, bool isForcingSync) { // Retrieve top-level folder list var tokenHandler = PXGraph.CreateInstance <UserTokenHandler>(); List <BoxUtils.FileFolderInfo> boxFolderList = new List <BoxUtils.FileFolderInfo>(); if (FieldsGroupingByScreenID.Select(screenID).Any()) { boxFolderList = BoxUtils.GetFolderList(tokenHandler, folderID, (int)BoxUtils.RecursiveDepth.FirstSubLevel).Result; boxFolderList = boxFolderList.Where(x => x.Name.Contains("\\")).ToList(); } else { boxFolderList = BoxUtils.GetFolderList(tokenHandler, folderID, (int)BoxUtils.RecursiveDepth.NoDepth).Result; } foreach (BoxUtils.FileFolderInfo boxFolderInfo in boxFolderList) { BoxFolderCache bfc = FoldersByFolderID.Select(boxFolderInfo.ID); if (bfc != null) { //Make sure NoteDoc still exists NoteDoc nd = NoteDocs.Select(bfc.RefNoteID); if (nd == null) { //NoteDoc can't be found; this is likely a file coming from a record that was deleted. //Since an existing folder may be renamed to something which exists, we want to force system to treat it as if it was a new folder FoldersByFolderID.Delete(bfc); bfc = null; } } if (bfc == null) { // We've never seen this folder; sync it Guid?refNoteID; if (screenID == ActivityMaintScreenId) { //Activity folders use custom naming defined in GetFolderNameForActivityRow() - just look for GUID inside it. refNoteID = ExtractGuidFromString(boxFolderInfo.Name); } else { refNoteID = FindMatchingNoteIDForFolder(screenID, boxFolderInfo.Name); } if (refNoteID == null) { // User may have created some folder manually with a name not matching to any record, or record // may have been deleted in Acumatica. We can safely ignore it, but let's write to trace. PXTrace.WriteWarning(string.Format("No record found for folder {0} (screen {1}, ID {2})", boxFolderInfo.Name, screenID, boxFolderInfo.ID)); continue; } bfc = (BoxFolderCache)FoldersByNote.Select(refNoteID); if (bfc != null) { // A folder existed before for this record; clear the previous entry for this refNoteID FoldersByNote.Delete(bfc); } // Store folder in cache for future reference bfc = (BoxFolderCache)FoldersByFolderID.Cache.CreateInstance(); bfc.FolderID = boxFolderInfo.ID; bfc.ParentFolderID = boxFolderInfo.ParentFolderID; bfc.RefNoteID = refNoteID; bfc.LastModifiedDateTime = null; //To force initial sync bfc = FoldersByFolderID.Insert(bfc); } if (isForcingSync || bfc.LastModifiedDateTime != boxFolderInfo.ModifiedAt) { RefreshRecordFileList(screenID, boxFolderInfo.Name, boxFolderInfo.ID, bfc.RefNoteID, isForcingSync); bfc.LastModifiedDateTime = boxFolderInfo.ModifiedAt; FoldersByFolderID.Update(bfc); PXContext.SetSlot <bool>("BoxDisableLoad", true); try { Actions.PressSave(); } finally { PXContext.SetSlot <bool>("BoxDisableLoad", false); } } } }
public void RefreshRecordFileList(string screenID, string folderName, string folderID, Guid?refNoteID, bool isForcingSync) { var tokenHandler = PXGraph.CreateInstance <UserTokenHandler>(); //Get list of files contained in the record folder. RecurseDepth=0 will retrieve all subfolders List <BoxUtils.FileFolderInfo> boxFileList = BoxUtils.GetFileList(tokenHandler, folderID, (int)BoxUtils.RecursiveDepth.Unlimited).Result; // Remove files from cache if they don't exist on Box server foreach (PXResult <BoxFileCache, UploadFileRevisionNoData, UploadFile, NoteDoc> result in FilesByNoteID.Select(refNoteID)) { BoxUtils.FileFolderInfo boxFile = boxFileList.FirstOrDefault(f => f.ID == ((BoxFileCache)result).FileID); if (boxFile == null) { //File was deleted FilesByNoteID.Delete(result); UploadFiles.Delete(result); UploadFileRevisions.Delete(result); NoteDocs.Delete(result); } else { // File still exists, remove it from in-memory list // so we don't process it as a new file in the next loop boxFileList.Remove(boxFile); } } // Remove any files/folders coming from activities stored beneath the current record, they've been processed above var filesFoundOnlyOnServer = boxFileList.Where(x => !x.Name.StartsWith(Messages.ActivitiesFolderName)).ToList(); //Check for underlying activities records BoxFolderCache currentFolder = FoldersByFolderID.Select(folderID); if (currentFolder != null && boxFileList.Any(x => x.Name.StartsWith(Messages.ActivitiesFolderName))) { // If nullOrEmpty, Folder may have been created manually if (string.IsNullOrEmpty(currentFolder.ActivityFolderID)) { //Find actual folder ID and save in BoxFolderCache's ActivityFolderID field BoxUtils.FileFolderInfo activityFolderinfo = BoxUtils.FindFolder(tokenHandler, folderID, Messages.ActivitiesFolderName).Result; if (activityFolderinfo != null) { currentFolder.ActivityFolderID = activityFolderinfo?.ID; FoldersByFolderID.Update(currentFolder); } } if (currentFolder.ActivityFolderID != null) { SynchronizeFolderContentsWithScreen(ActivityMaintScreenId, currentFolder.ActivityFolderID, isForcingSync); } } //Remaining files aren't found in cache but are in Box server. if (filesFoundOnlyOnServer.Any()) { if (refNoteID == null) { // User may have created some folder manually with a name not matching to any record, or record // may have been deleted in Acumatica. We can safely ignore it, but let's write to trace. PXTrace.WriteWarning(string.Format("No record found for folder {0} (screen {1}, ID {2})", folderName, screenID, folderID)); return; } UploadFileMaintenance ufm = PXGraph.CreateInstance <UploadFileMaintenance>(); ufm.IgnoreFileRestrictions = true; ufm.RowInserting.AddHandler <UploadFileRevision>(delegate(PXCache sender, PXRowInsertingEventArgs e) { ((UploadFileRevision)e.Row).BlobHandler = Guid.NewGuid(); }); //Add files to the caches foreach (BoxUtils.FileFolderInfo boxFile in filesFoundOnlyOnServer) { ufm.Clear(); string fileName = string.Format("{0}\\{1}", folderName, boxFile.Name.Replace(Path.GetInvalidPathChars(), ' ')); FileInfo fileInfo = ufm.GetFileWithNoData(fileName); Guid? blobHandlerGuid; if (fileInfo == null) { fileInfo = new FileInfo(fileName, null, new byte[0]); //The SaveFile call will trigger a Load() on the BoxBlobStorageProvider which can be skipped PXContext.SetSlot <bool>("BoxDisableLoad", true); try { if (!ufm.SaveFile(fileInfo)) { throw new PXException(Messages.ErrorAddingFileSaveFileFailed, fileName); } } finally { PXContext.SetSlot <bool>("BoxDisableLoad", false); } if (!fileInfo.UID.HasValue) { throw new PXException(Messages.ErrorAddingFileUIDNull, fileName); } UploadFileMaintenance.SetAccessSource(fileInfo.UID.Value, null, screenID); NoteDoc noteDoc = (NoteDoc)NoteDocs.Cache.CreateInstance(); noteDoc.NoteID = refNoteID; noteDoc.FileID = fileInfo.UID; NoteDocs.Insert(noteDoc); blobHandlerGuid = ufm.Revisions.Current.BlobHandler; } else { //File already exists in the database, retrieve BlobHandler if (!fileInfo.UID.HasValue) { throw new PXException(Messages.GetFileWithNoDataReturnedUIDNull, fileName); } blobHandlerGuid = GetBlobHandlerForFileID(fileInfo.UID.Value); //Clear old references of this blob handler from cache; it will be reinserted with up-to-date info var bfcOrphan = (BoxFileCache)FilesByBlobHandler.Select(blobHandlerGuid); if (bfcOrphan != null) { FilesByBlobHandler.Delete(bfcOrphan); } //Update NoteDoc entry if existing file was moved to new NoteID or create it if not there NoteDoc nd = (NoteDoc)NoteDocsByFileID.Select(fileInfo.UID); if (nd == null) { nd = (NoteDoc)NoteDocs.Cache.CreateInstance(); nd.NoteID = refNoteID; nd.FileID = fileInfo.UID; NoteDocs.Insert(nd); } else if (nd.NoteID != refNoteID) { nd.NoteID = refNoteID; NoteDocs.Update(nd); } } var bfc = (BoxFileCache)FilesByBlobHandler.Cache.CreateInstance(); bfc.BlobHandler = blobHandlerGuid; bfc.FileID = boxFile.ID; bfc.ParentFolderID = boxFile.ParentFolderID; bfc = FilesByBlobHandler.Insert(bfc); } } }