How to get Project Guid and Model Guid from PathName? - revit-api

My Revit model has an RVT link with a PathName = "BIM 360://Testing Link Edit in BIM360/ArchitectureBIM360.rvt"
I want to construct a ModelPath and use it to open the cloud-hosted file as follows:
ModelPath mp = ModelPathUtils.ConvertCloudGUIDsToCloudPath(projectId, modelId);
linkDoc = uiapp.OpenAndActivateDocument(mp, new OpenOptions(), false, new cloudCallback()).Document;
How do I get the projectId and modelId GUIDs from the PathName?

Using Forge Data Management API you can list Hubs > Projects > Folders > Items > Versions. An item is essentially a file, but it can have 1+ versions, so that's why you need the specific version. This tutorial guides you on the steps.
Once you list version of an item, it should be an array under .data, each entry on the array should have something like (simplified):
{
"type":"versions",
"id":"urn:adsk.wipprod:fs.file:vf.abcd1234?version=1",
"attributes":{
"name":"fileName.rvt",
"displayName":"fileName.rvt",
...
"mimeType":"application/vnd.autodesk.r360",
"storageSize":123456,
"fileType":"rvt",
"extension":{
"type":"versions:autodesk.bim360:C4RModel",
....
"data":{
...
"projectGuid":"48da72af-3aa6-4b76-866b-c11bb3d53883",
....
"modelGuid":"e666fa30-9808-42f4-a05b-8cb8da576fe9",
....
}
}
},
....
}
Update
From the comment, on Revit desktop, you can use:
ModelPath path = doc.GetCloudModelPath();
Guid guid1 = path.GetModelGUID();
Guid guid2 = path.GetProjectGUID();

I'm not using the Forge API yet (I really need to go through the tutorial myself). I do not know if this would help in anyway or if you found the answer you were looking for but the cache folder does contain all the file and project GUIDs including links: "C:\Users\username\AppData\Local\Autodesk\Revit\Autodesk Revit 2019\CollaborationCache\2008062704538XX\4680d561-ed69-4a61-b9b2-587582b1627a\LinkedModels\1f96b01e-640e-4e16-93af-edcc11769570.rvt"

In the below path:
C:\Users\username\AppData\Local\Autodesk\Revit\Autodesk Revit 2019\CollaborationCache\2008062704538XX\4680d561-ed69-4a61-b9b2-587582b1627a\LinkedModels\1f96b01e-640e-4e16-93af-edcc11769570.rvt"
2008062704538XX is the oxygen ID which is a unique ID and it is linked to your Autodesk account.
4680d561-ed69-4a61-b9b2-587582b1627a is the GUID of the Project.
1f96b01e-640e-4e16-93af-edcc11769570 is the GUID of the linked model.

Related

Cannot get documentid using pnp.sp.search in spfx app

In an older JavaScript app I used keyword-query to search for document properties, and I could add the 'DlcDocID' field (Document id) to be retrieved.
I am currently developing an Spfx version of the app, and use pnp.sp.search to get document data. This way I can get the UniqueId and the DocId, but not the Document Id. How can I have this parameter included in the search results?
Extra:
I am using 1.3.11, and this code
pnp.sp.search(
{
Querytext:query,
RowLimit:rows,
StartRow:start,
SelectProperties: ["DocId"
, "UniqueId"
,"FileType"
,"ServerRedirectedEmbedURL"
, "ServerRedirectedPreviewURL"
,"LastModifiedTime"
,"Write"
,"Size"
,"SPWebUrl"
,"ParentLink"
,"Title"
,"HitHighlightedSummary"
,"Path"
,"Author"
,"LastModifiedTime"
,"DlcDocID"
],
But DlcDocID is never retrieved.
Looking at the docs, DlcDocID should be retrievable (it's queryable and retrievable by default). Have you tried using SearchQueryBuilder and selectProperties?
const q = SearchQueryBuilder().text(yourQuery).
.rowLimit(10).processPersonalFavorites.selectProperties('*', 'DlcDocID');
const results = await sp.search(q);
SearchQueryBuilder reference
The issue was that the pnp
SearchResult interface didn't have the DlcDocID in this version. Adding it solved the problem.

Retrieve Documents from a Template

I created a template within my DocuSign developer Sandbox that contains one document. I'm using the C# SDK to try and send out an envelope to a user, based on a template.
Here's the code where I retrieve all of the templates.
TemplatesApi templateApi = new TemplatesApi(ApiClient.Configuration);
EnvelopeTemplateResults templateResults = templateApi.ListTemplates(AccountID);
The issue I am having is the EnvelopeTemplateResults does NOT have any documents associated with it.
When I use the REST API using POSTMAN, performing a GET to this URL, I can see that there's an envelopeTemplateDefinition, that has a Document on it, which is the one I want.
My question is, how, using the SDK API, can I get the envelopeTemplateDefinition ?
In order to have the ListTemplates method include the Documents info, you have to set an Include parameter:
var templatesApi = new TemplatesApi(apiClient.Configuration);
var listTemplatesOptions = new TemplatesApi.ListTemplatesOptions { include = "documents" };
var templateResults = templatesApi.ListTemplates(accountId, listTemplatesOptions);
If you are trying to get the Template Definition of a single template, the templatesApi.Get() method can be used with its own set of Include options:
var getTemplateOptions = new TemplatesApi.GetOptions { include = "documents" };
var templateDefinition = templatesApi.Get(accountId, templateId, getTemplateOptions);
Finally, if you're trying to get an actual PDF out of a specific template, that would be the templatesApi.GetDocument() method:
templatesApi.GetDocument(accountId, templateId, documentId);
Where DocumentId is the specific document you want to pull, or "Combined" if you want to pull all the documents in as a single PDF.
Chris, if you are using the v2 API, there's an endpoint:
GET /v2/accounts/{accountId}/templates/{templateId}/documents/{documentId}
you can try it here - https://apiexplorer.docusign.com/#/esign/restapi?categories=Templates&tags=TemplateDocuments&operations=get
the c# SDK inside TemplateAPI has GetDocument() and UpdateDocument() methods

How can I upload lot/serial # allocations in Purchase Receipt popup?

I would like to upload a spreadsheet of lot/serial #'s into the Allocation popup on the Purchase Receipts screen. It's not uncommon for my company to receive 1,000+ serial #'s in an order and entering them one-at-a-time via this popup is too cumbersome. (My serial numbers aren't sequential, so I can't use the Generate tool.)
I've found a related post here, but I'm unable make the source work.
How to include a dialog for file upload
... begin snippet ...
byte[] filedata = info.BinData;
using (NVExcelReader reader = new NVExcelReader())
{
Dictionary<UInt32, string[]> data = reader.loadWorksheet(filedata);
foreach (string[] textArray in data.Values)
{
// do stuff
}
}
...
The code references a class called NVExcelReader(). Where does this class originate from? Is this part of stock Acumatica? I've been unable to find this class in the source. I'm using Acumatica 2017 R2. Is it possible this class was renamed or moved in newer versions?
Can someone point me in the right direction or explain how I might go about recreating the functionality of NVExcelReader() in Acumatica?
NVExcelReader is not an Acumatica class, the main idea here is to use any existing class to read the excel file.
So what you really need to do:
declare PXUploadDialog element in your aspx file
<px:PXUploadDialog ID="ImportPanel" runat="server" Key="NewRevisionPanel" Height="120px" Style="position: static" Width="560px"
Caption="Import XML File (*.xml)" AutoSaveFile="false" RenderCheckIn="false" SessionKey="ImportStatementProtoFile" />
add a button delegate
public PXSelect<PO.POReceipt> NewRevisionPanel;
public PXAction<PO.POReceipt> ImportAllocations;
[PXUIField(DisplayName = "Import Allocations",
MapEnableRights = PXCacheRights.Update,
MapViewRights = PXCacheRights.Update,
Enabled = true)]
[PXButton()]
public virtual void importAllocations()
{
}
Get selected file data using PXInfo class
const string PanelSessionKey = "ImportStatementProtoFile";
PX.SM.FileInfo info = PX.Common.PXContext
.SessionTyped<PXSessionStatePXData>()
.FileInfo[PanelSessionKey] as PX.SM.FileInfo;
System.Web.HttpContext.Current.Session.Remove(PanelSessionKey);
if (info != null)
{
// here is your file data in bytes
byte[] filedata = info.BinData;
read your excel file in bytes using any existing library. Note this step is not related to Acumatica. You can find helpful information here and here for example
then set values from the file to Acumatica entity (POReceiptLineSplit for example)
Base.splits.Insert(new PO.POReceiptLineSplit()
{
InventoryID = Base.transactions.Current.InventoryID,
LocationID = Base.transactions.Current.LocationID,
LotSerialNbr = valueFromExcelFile1,
Qty = valueFromExcelFile2
});
NVExcelReader is not part of Acumatica framework. I say this because neither resharper was able to find NVExcelReader in Acumatica dlls nor search of string in Acumatica directory was able to find any file that contained NVExcelReader string value. Also Google search for NVExcelReader class doesn't give any good results beside referencing your thread on stackoverflow. In order to recreate NVExcelReader in Acumatica you can consider usage of some third party library which can read from excel files. There are plenty of options starting from COM interfaces, OLE DB for excel and Aspose library for parsing xml files.

SharePoint 2013 Activity Event in Newsfeed

I need to add custom notifications to the personal Newsfeed on people's MySites. I found several tutorials and code examples for SharePoint 2010 on the net and tried to do the same with SharePoint 2013. They're all about creating ActivityEvents with the ActivityManager.
Here's the code I tried:
var targetSite = new SPSite("URL to MySite webapp");
SPServiceContext context = SPServiceContext.GetContext(targetSite);
var userProfileManager = new UserProfileManager(context);
var ownerProfile = userProfileManager.GetUserProfile("domain\\user1");
var publisherProfile = userProfileManager.GetUserProfile("domain\\user2");
var activityManager = new ActivityManager(ownerProfile, context);
Entity publisher = new MinimalPerson(publisherProfile).CreateEntity(activityManager);
Entity owner = new MinimalPerson(ownerProfile).CreateEntity(activityManager);
ActivityEvent activityEvent = ActivityEvent.CreateActivityEvent(activityManager, 17, owner, publisher);
activityEvent.Name = "StatusMessage";
activityEvent.ItemPrivacy = (int)Privacy.Public;
activityEvent.Owner = owner;
activityEvent.Publisher = publisher;
activityEvent.Value = "HELLOOOO";
activityEvent.Commit();
ActivityFeedGatherer.BatchWriteActivityEvents(new List<ActivityEvent> { activityEvent }, 0, 1);
The Id 17 in the CreateActivityEvent function is for the StatusMessage activity type, which is layouted like {Publisher} says: {Value} in the ressource files, so I provide the Value property of my ActivityEvent.
The code runs without any exception and in the User Profile Service Application_ProfileDB database I can see the right entries appear in the ActivityEventsConsolidated table.
But the activity is not visible in the activity feed, neither on the Owner's one, nor on the Publisher's one, even though these people follow each other. I ran the Activity Feed Job in the CA manually to update the activity feed.
Also, I tried to do the same with custom ActivityTypes with own ressource files, same result: The entry in the ActivityEventsConsolidated table (or ActivityEventsPublished if Owner=Publisher) appear, but no entries on the MySite.
Can anyone help?
I found the solution for this problem myself.
In Central Administration, Setup MySites, you have to enable the Enable SharePoint 2010 activity migration setting in the Newsfeed section in order to support SP1010 legacy activities in SP2013.

How do you get SharePoint "My Links" back after a profile has been deleted and restored?

We're running SharePoint 2007 SP1 and profiles are imported from Active Directory (a full import runs daily). We had a problem where many of the users were disabled unintentionally in Active Directory and this caused their profiles to be removed from SharePoint. We re-enabled their Active Directory accounts and ran a full import which restored their SharePoint profiles. However, all of their My Links are missing. Is there a method or best practice for restoring them?
I posted this because I couldn't find an answer to my problem anywhere. This post by Joel Oleson that describes a similar problem to mine gave me a hint as to where to go looking for the missing data. And This post by Corey Roth showed me how to programatically add the links to a users My Links.
First things first - you need to restore a backup of the database that contains the My Links data. You don't want to restore over your working database, you want to restore it to another location. The links stored in the SSP Database. (You can find out the name of the database by going into Central Admin --> Shared Services Admin then open the menu for the SSP and click on Edit Properties - the SSP Database is listed on the properties page.)
Once the database has been restored you want to retrieve the Link information:
the domain account name of the user who owns the link,
the url of the link
the name of the link
This query will get you that information:
SELECT UPF.NTName, UL.Url, UL.Title
FROM UserLinks UL INNER JOIN UserProfile_full UPF ON UL.recordID = UPF.recordID
INNER JOIN UserPrivacyPolicy UPP ON UL.PolicyId = UPP.id
ORDER BY NTName
(I should note that I did not take into account what group or what privacy level the links were set to, you could probably find that information by looking at the information in the UserPrivacyPolicy table)
I copied the results into Excel & saved it as a .csv file (comma separated list) - just because my production server did not have access to the location where I restored my database. I ordered the columns with Title last because the Title could contain commas and that would mess up how I'm reading in the data. (I checked and the other two fields do not contain commas - you should check yours before making this assumption.)
I then wrote a little console app to import the data. It takes two arguments:
the path where the file containing all of the links is located (ie c:\temp\links.csv)
the url of the SSP from with the My Links have gone missing (ie https://portal.mydomain.com)
These are the references used:
Microsoft.Office.Server (C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\12\ISAPI\Microsoft.Office.Server.dll)
Microsoft.SharePoint (C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\12\ISAPI\Microsoft.SharePoint.dll)
System
System.Data
System.Web
System.Xml
And this is the code:
using System;
using System.IO;
using System.Collections.Generic;
using System.Text;
using Microsoft.Office.Server;
using Microsoft.Office.Server.UserProfiles;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Administration;
using System.Web;
namespace UserLinks
{
class Program
{
static void Main(string[] args)
{
string _accountName = "", _linkTitle = "", _url = "", _tmp = "", _path = "", _SPSsite = "";
// Check arguments
if (args.Length != 2)
{
ShowUsage();
return;
}
_path = args[0];
_SPSsite = args[1];
using (SPSite _site = new SPSite(_SPSsite))
{
ServerContext _context = ServerContext.GetContext(_site);
UserProfileManager _userProfileManger = new UserProfileManager(_context);
/* Expecting a comma seperated list with 3 columns:
* AccountName in the format Domain\Account name - I am assuming there are no commas in this field
* URL - I am assuming there are no commas in this field
* Link Title - link title is last because there may be commas in the title
*/
TextReader _reader = new StreamReader(_path, System.Text.Encoding.Default);
while (_reader.Peek() != -1)
{
_tmp = _reader.ReadLine();
_accountName = _tmp.Substring(0, _tmp.IndexOf(','));
_tmp = _tmp.Replace(_accountName + ",", "");
_url = _tmp.Substring(0, _tmp.IndexOf(','));
_linkTitle = _tmp.Replace(_url + ",", "");
try
{
UserProfile _currentUser = _userProfileManger.GetUserProfile(_accountName);
QuickLinkManager _quickLinkManager = _currentUser.QuickLinks;
_quickLinkManager.Create(_linkTitle, _url, QuickLinkGroupType.General, null, Privacy.Private); //I am assuming that all links have no group assigned to them and they are all private links
}
catch (Exception ex)
{
Console.WriteLine(_accountName);
Console.WriteLine(ex);
}
}
_reader.Close();
}
}
private static void ShowUsage()
{
Console.WriteLine("Usage");
Console.WriteLine("UserLinks [FilePath] [SharePoint URL]");
}
}
}
So problem solved & as a side benefit, this program can be used to force links to show up in a user's My Links list.
This post has some pretty good information about MyLinks and its relationship with the SSP database (that's actually where these links are stored counterintuitively.) Hopefully you can have your DBA validate that these links still exist; and that they're associated with the correct profiles.
http://www.k2distillery.com/2009/01/moving-sharepoint-my-links-between-ssps.html
When you do a profile import, you normally risk losing the existing customization/updated information.

Resources