Orchard collaboration - orchardcms

Recently I'm making a web page using orchard, and I'm trying to create a Q&A page by using orchard collaboration. I know by using ticket-dashboard I can easily come up with a result like this.The questions will be divided into different groups according to the project it is about. But right now I am thinking of letting the administrator to see each project's project-dashboard when clicking on ticket-dashboard. Can anybody let me know about how to do it? Thanks a lot!

There are some options that can help you. One of them that comes to my mind is this.
Customizing ProjectDriver for a new DisplayType like "ProjectTicketDashboard". If you take a look at the ProjectDriver.Display method, it renders ProjectDetail (which contains portlets) for the Detail display type. You can add a new "case statement" there for the new DisplayType. For the new display Type, you can represents a ticket dashboard. Something like this:
case "ProjectTicketDashboard":
// Query the counts of the whole tickets in the system based on stateId
dynamic state = new JObject();
var contentQuery = this.services.ContentManager.HqlQuery().ForVersion(VersionOptions.Published);
state.ContentTypes = "Ticket";
contentQuery = this.projectionManagerWithDynamicSort.ApplyFilter(contentQuery, "Content", "ContentTypes", state);
state.Project_Id = part.Id;
contentQuery = this.projectionManagerWithDynamicSort.ApplyFilter(contentQuery, "AttachToProjectFilter", "Id", state);
var ticketCountsByStateIds = groupQuery.GetCount(contentQuery, "TicketPartRecord", "StatusRecord.Id");
model.AllTickets = new Collection<dynamic>();
CRMHelper.AddStatusGroupRecordsToModel(statusRecords, ticketCountsByStateIds, model.AllTickets);
state.MaxDueDate = DateTime.UtcNow.Date;
contentQuery = this.projectionManagerWithDynamicSort.ApplyFilter(contentQuery, TicketFieldsFilter.CategoryName, TicketFieldsFilter.TicketDueDateType, state);
model.AllOverrudeItemsCount = contentQuery.Count();
return ContentShape("Parts_Project_Dashboard",
() => shapeHelper.Parts_Project_Dashboard(
Model: model
));
You need a corresponding view for the Parts_Project_Dashboard and the associated entry in the placement.info. For the view, you can reuse the code of the view in Orchard.CRM.Core/Views/Parts/Dashboard.cshtml
Next step, you can create a custom Query that gets all projects with a shape layout and DisplayType = "ProjectTicketDashboard".
And finally, use a projection to display the previous query in the HomePage
Let me know, if you have any further questions.
Siyamand

Related

Creating detail view of doors in Revit api

How to create detail view in Revit of specific door using Revit API( external command)? For now I managed to create DetailView, but when I open in Revit that view it is not what I expected(see images: expected , what I get).
Here is the code:
IEnumerable<ViewFamilyType> viewFamilyTypes = from elem in new FilteredElementCollector(doc).OfClass(typeof(ViewFamilyType))
let type = elem as ViewFamilyType
where type.ViewFamily == ViewFamily.Detail
select type;
//uiDoc.Selection.SetElementIds(new List<ElementId>() { door.Id });
var dim = door.get_BoundingBox(null);
using (Transaction transaction = new Transaction(doc))
{
transaction.Start("Creating Detail View");
BoundingBoxXYZ box = dim;
var detailView = ViewSection.CreateDetail(doc,viewFamilyTypes.First().Id, box);
detailView.Discipline = ViewDiscipline.Architectural;
detailView.DetailLevel = ViewDetailLevel.Coarse;
transaction.Commit();
}
I'm using Revit 2018,
Any help or suggestion is welcome just to finish my student research.
Do The Building Coder articles on creating a section view help?

Making jslink target specific list

Background
I got a page where I’m showing two list views from two separate lists which both have Custom List as their ListTemplate. They got their separate jslink file cause I don’t want them to look alike.
Problem
The js link file targets both listviews since they use the same Template.
Code
(function () {
var listContext = {};
listContext.Templates = {};
listContext.ListTemplateType = 100;
listContext.Templates.Header = "<div><ul>";
listContext.Templates.Footer = "</ul></div>";
listContext.Templates.Item = LinkTemplate;
SPClientTemplates.TemplateManager.RegisterTemplateOverrides(listContext);
})();
Question
Is there any way to make the js only target a specific list?
Ended up going with Paul Hunts solution that he writes about on myfatblog.co.uk. http://www.myfatblog.co.uk/index.php/2013/09/listview-web-part-issues-with-jslink-and-display-templates-a-solution/
The script ended up looking like this and I pasted it into the jslink function where I define what listContext to override.
// Override the RenderListView once the ClientTemplates.JS has been called
ExecuteOrDelayUntilScriptLoaded(function(){
// Copy and override the existing RenderListView
var oldRenderListView = RenderListView;
RenderListView = function(ctx,webPartID)
{
// Check the title and set the BaseViewId
if (ctx.ListTitle == "List")
ctx.BaseViewID = "list";
//now call the original RenderListView
oldRenderListView(ctx,webPartID);
}
},"ClientTemplates.js");

Create A Record as Closed with C#

Can a record be created as closed?
If I create the records and then change the state, that could work, but is it possible to do it in a single step?
I am using ExecuteMultipleRequest to create Cases.
No, You have to make two request to create and resolve the case. See the examples below:
// Create an incident.
var incident = new Incident
{
CustomerId = new EntityReference(Account.EntityLogicalName, _accountId),
Title = "Sample Incident"
};
_incidentId = _serviceProxy.Create(incident);
// Create the incident's resolution.
var incidentResolution = new IncidentResolution
{
Subject = "Resolved Sample Incident",
IncidentId = new EntityReference(Incident.EntityLogicalName, _incidentId)
};
// Close the incident with the resolution.
var closeIncidentRequest = new CloseIncidentRequest
{
IncidentResolution = incidentResolution,
Status = new OptionSetValue((int)incident_statuscode.ProblemSolved)
};
_serviceProxy.Execute(closeIncidentRequest);
Ref: sdk\SampleCode\CS\BusinessDataModel\Service\CloseAnIncident.cs
You will always need two request, one to create the record and one to change the state.
You could have a plugin close the record on the create, so that way it happens in the same database transaction, but I'm guessing that it wouldn't be worth the over head.

Retrieve related entities of each, using RetrieveMultipleRequest

I'm trying to retrieve a list of entities from CRM, but I'd like to get each one with the related entities. So far, I've the following code:
FilterExpression filterExpression = new FilterExpression();
ConditionExpression condition = new ConditionExpression(Constants.ModifiedOnAttribute, ConditionOperator.GreaterEqual, lastSync);
filterExpression.AddCondition(condition);
QueryExpression query = new QueryExpression()
{
EntityName = entityName,
ColumnSet = new ColumnSet(attributesMetadata.Select(att => att.Name).ToArray<string>()),
Criteria = filterExpression,
Distinct = false,
NoLock = true
};
RetrieveMultipleRequest multipleRequest = new RetrieveMultipleRequest();
multipleRequest.Query = queryExpression;
RetrieveMultipleResponse response = (RetrieveMultipleResponse)proxy.Execute(multipleRequest);
In the variable response, I can see the EntityCollection attribute, but inside, Related entities always come empty.
I'd like to know if it is possible to retrieve the set of a given entities, with the related entities, using RetrieveMultipleRequest, rather than go one by one using RetrieveRequest.
One approach to retreive related entities data - adding LinkEntities to your query. Example below will make you an idea how to make this:
LinkEntity linkEntity = new LinkEntity("email", "new_emails", "activityid", "new_relatedemail", JoinOperator.Inner);
linkEntity.Columns.AddColumn("versionnumber");
linkEntity.Columns.AddColumn("new_emailsid");
linkEntity.EntityAlias = "related";
query = new QueryExpression("email");
query.ColumnSet.AddColumn("activityid");
query.ColumnSet.AddColumn("versionnumber");
query.Criteria.AddCondition("modifiedon", ConditionOperator.NotNull);
query.LinkEntities.Add(linkEntity);
And then you can access attributes from related entities using EntityAlias you specified above:
foreach (Entity entity in entities.Entities)
{
if ((long)(entity["related.versionnumber"] as AliasedValue).Value > 0)
{
stop = false;
}
}
The RetrieveMultipleRequest is for returning multiple instances of a particular type of entity. I have spent a year using the CRM SDK from C# and I have found no way of populating those related entity collections in a single query. This basically leaves you with two options:
Use the AliasedValue as SergeyS recommends. Remember when querying 1:Many relationships, be aware that you could be returning multiple results for the same parent entity. This is what I use most of the time.
Perform a second query for each relationship you want access to. You'll probably get better performance if you can use an IN statement in your second query, based on the results of the first, rather than performing a separate query for each result of the first.
Below is some pseudo code to show the difference.
var contacts = GetContacts();
// One Request to get the cars for the contacts
var cars = GetCarsWhereContactIdIn(contacts.Select( c => c.new_ContactId));
foreach(var c in contacts){
c.new_Cars.AddRange(cars.where(car => car.new_contactId = c.ContactId));
}
// Verses
var contacts = GetContacts();
foreach(var c in contacts){
// One Request for each contact
c.new_Cars.AddRange(GetCarsForContact(c.ContactId));
}

Using FindView in Orchard

I'm trying to use:
var viewEngineResult = ViewEngines.Engines.FindView(ControllerContext, myViewName, null);
as part of a process to render the contents of a view to send nice formatted emails. I'm using it inside an Orchard Controller. I have used similar code outside of Orchard in an MVC project and it works fine.
However in Orchard running this code fails to find the view I'm looking for and returns a view engine result that has searched 0 locations.
viewEngineResult has the following values after it is called:
SearchedLocations: Count = 0,
View: null,
ViewEngine: null
Is there a reason this doesn't work in Orchard and is there a way to make it work?
This answer is based on the advise given me by Bertrand, but I wanted to bring it together with what I'd discovered.
To be able to use FindPartialView I needed to inject an instance of IViewEngineProvider into my controller.
I then used the following code to resolve and render a view:
private String RenderView(String viewName, object model)
{
var paths = new List<string>(); // This can just be an empty list and it still finds it.
var viewEngine = _viewEngineProvider.CreateModulesViewEngine(new CreateModulesViewEngineParams {VirtualPaths = paths});
var viewResult = viewEngine.FindPartialView(ControllerContext, viewName, false);
if (viewResult.View == null) {
throw new Exception("Couldn't find view " + viewName);
}
var viewData = new ViewDataDictionary {Model = model};
using (var sw = new StringWriter())
{
var viewContext = new ViewContext(ControllerContext, viewResult.View, viewData, TempData, sw);
viewResult.View.Render(viewContext, sw);
return sw.GetStringBuilder().ToString();
}
}
I think you'll want to take a close look at Orchard.Framework/Mvc/ViewEngines, in particular IViewEngineProvider and ThemeAwareViewEngine. There's a lot more going on when in Orchard, such as themes, multi-tenancy, and a richer environment in general that may be needed to make this work.
What's likely happening here is that the view engines don't have enough information to resolve a view and thus opt out of the chain. You might want to put a breakpoint into ThemeAwareViewEngine.FindView, and then inspect the private dependency fields of that class. I wouldn't be surprised if they were null, because getting to FindView through statics will probably not allow dependency injection to do its stuff properly.
Then again I'm just guessing.

Resources