How to make instance of PIM Event and set thsi attributes to it
public String eventType;
public Date eventFromDate;
public Date eventToDate;
public Date alarmFromDate;
public Date alarmToDate;
public Vector recepient;
public String descriptionOfEvent;
Here is an example of how to add an event to calendar using the PIM API
Related
Can I change the business date through BLC code? I know it's in the AccessInfo DAC (AccessInfo.businessDate).
Thanks...
The static PXContext has a public static method called SetBusinessDate, You can use that method to change the Business Date.
public static void SetBusinessDate(DateTime? date)
{
PXContext.PXIdentity.BusinessDate = date;
}
You can simply call PXContext.SetBusinessDate method and force a page refresh after that, otherwise the UI will still show the old business date.
var YOUR_NEW_BUSINESS_DATE = new DateTime(2022,01,01);
PXContext.SetBusinessDate(YOUR_NEW_BUSINESS_DATE);
throw new PXRefreshException();
I have elected to leverage Azure Event Grid in an enterprise multi-tenant model application. I also want to use Cloud Events instead of the proprietary AEG format. I am using AEG domains for each tenant and then I want a custom topic and subject for my messages. The v0.1 of cloud events had a "#" delimited property for cloud events topic and subjects. It looks like V1.0 does not anymore? It really is not clear in the Azure docs.
Secondarily, with Azure Event Grid Domains it seems you can only create a Domain Topic via Powershell (https://learn.microsoft.com/en-us/cli/azure/eventgrid/domain/topic?view=azure-cli-latest) and not in the portal. I can't find a clear way to create a topic for an event domain any other way.
My topic is currently set to : /providers/Microsoft.EventGrid/domains/{tenantname}/topics/refresh.
Do domain topics just appear once they're published for the first time?
Any insight on the format of the cloud events schema and managing topics would be great!
So I now see the UI for this in Azure Portal. You simply, add an event subscription on the domain and one of the options is to filer by topic, where you add your topics.
https://learn.microsoft.com/bs-latn-ba/azure/event-grid/how-to-event-domains?tabs=azurecli#create-topics-and-subscriptions
It is clear here that "There's no separate step to create a topic in a domain.".
Secondarily, I was able to set source = topic for Cloud Events v1.0 and separate out subject as well. Here is my CloudEvent generic class :
public class CloudEvent<T> where T : class
{
[JsonProperty("id")]
public string EventId
{
protected set { }
get => Guid.NewGuid().ToString();
}
[JsonProperty("specversion")]
public string CloudEventVersion
{
protected set { }
get => "1.0";
}
[JsonProperty("type")]
public string EventType { get; set; }
[JsonProperty("eventTypeVersion")]
public string EventTypeVersion
{
protected set { }
get => "1.0";
}
[JsonProperty("source")]
public string Source { get; set; }
[JsonProperty("subject")]
public string Subject { get; set; }
[JsonProperty("time")]
public string Time
{
protected set { }
get => DateTime.UtcNow.ToString(CultureInfo.InvariantCulture);
}
[JsonProperty("data")]
public T Data { get; set; }
}
My topic (which is set to source property for cloud events) is :
/resourceGroups/{rgname}/providers/Microsoft.EventGrid/domains/{domainname}/topics/{topic}
I think this would also set subject properly according to this schema.
https://learn.microsoft.com/en-us/azure/event-grid/cloudevents-schema
Create winform project targeting .net 4.5.1
Install-Package PropertyChanged.Fody
[ImplementPropertyChanged]
public class PersonFody
{
public string Name { get; set; }
}
PersonFody _fod = new PersonFody();
_fod. //Name is the only property and no events to subscribe
Is it possible to subscribe to a PropertyChanged event at design time using fody?
I guess this is late, but yes you can. Just add this event to your class:
public event PropertyChangedEventHandler PropertyChanged;
Fody will recognize you have the correct event for the IPropertyChanged interface and wire all your properties to trigger that event.
I have a Page which fills on every "preRenderView" some lists with values of a DB
//preRenderView Method
public void init(){
loadChapterStructure();
loadCategoryStructure();
}
Due to the fact, that the chapters and categories don't chance really often (e.g. just one time a day), they only should be loaded once for every user (on first page load).
When the user now performs some GET-requests on the same view (to keep the page etc. bookmarkable), it would be good not to load these "static" values again.
Is there a way to achieve e.g. loading the chapters and categories e.g. only once every hour? Is there any best-practice for this issue?
Thanks for any help!
You can implement an #ApplicationScoped managed bean which caches the DB values. Just access the data through it instead of directly using the DAO from your view beans:
#ManagedBean
#ApplicationScoped
public class CacheManager(){
private static Date lastChapterAccess;
private static Date lastCategoryAccess;
private List<Chapter> cachedChapters;
private List<Category> cachedCategories;
private Dao dao;
//Refresh the list if the last DB access happened
//to occur more than one hour before
public List<Chapter> loadChapterStructure(){
if (lastChapterAccess==null || new Date().getTime()
- lastChapterAccess.getTime() > 3600000){
cachedChapters = dao.loadChapterStructure();
lastChapterAccess = new Date();
}
return cachedChapters;
}
public List<Category> loadCategoryStructure(){
if (lastCategoryAccess==null || new Date().getTime()
- lastCategoryAccess.getTime() > 3600000){
cachedCategories = dao.loadCategoryStructure();
lastCategoryAccess = new Date();
}
return cachedCategories;
}
}
Then inject the bean wherever your want using the #ManagedProperty annotation:
#ManagedBean
#ViewScoped
public class ViewBean{
#ManagedProperty(value="#{cacheManager}")
private CacheManager cacheManager;
//preRenderView Method
public void init(){
chapters = cacheManager.loadChapterStructure();
categories = cacheManager.loadCategoryStructure();
}
}
I was wondering if how my presentation layer is structured could be a lead to design my aggregate roots.
Lets have an entity ProjectEntity and its related entity ProjectMemberEntity (1:M)
The page is structured as follows:
The top of the page is a form for ProjectEntity
Underneath the form is a grid that shows a list of ProjectMemberEntity.
If a new ProjectMember will be added, the user have to go to this page and click on the button "add new member" which is located in the header of the grid.also edit and delete has the same analogy.
I'm wondering if this behavior/'page structure' could be a hint for a aggregate root(projectentity)
That's a hint for sure. But no more.
Better way to clarify kind of that entity relationship is to ask domain expert:
does project member makes any sense without project?
can member participate in multiple projects?
If those are answered positively, it's highly likely that You should model project member as an aggregate root itself. Otherwise - demote it as an entity that cannot live w/o a project.
Here is some code that might give You some ideas:
public class Project:Root{
private List _members;
public IEnumerable<Member> Members{get {return _members;}}
public string Name{get;private set;}
public bool IsFinished{get;private set;}
public bool FinishedOn{get;private set;}
public Project(string projectName){
_members=new List<Member>();
Name=projectName;
}
public Member AssignMember(string memberName){
var member=new Member(memberName);
_members.Add(member);
return member;
}
public void UnassignMember(string memberName){
var member=_members.First(m=>m.Name==memberName);
if(!member.HasCompletedAllTasks())
throw new Exception
("Cannot unassign member with incompleted tasks!");
_members.Remove(member);
}
public void AssignTaskToMember(string taskName, string memberName){
var member=_members.First(m=>m.Name==memberName);
member.AssignTask(taskName);
}
public void MemberHasCompletedTask(Member member, Task task){
EnsureListContains(_members,member);
EnsureListContains(member.Tasks,task);
task.MarkAsCompleted();
}
public void FinishProject(){
if(_members.Any(m=>!m.HasCompletedAllTasks()))
throw new Exception
("Can't finish project before members have completed all their tasks.");
IsFinished=true;
FinishedOn=DateTime.Now;
}
private void EnsureListContains<T>(IList<T> lst, T itm){
if(!lst.Contains(itm)) throw new Exception();
}
}
public class Member:Entity{
public string Name{get;private set;}
private List<Task> _tasks;
public IEnumerable<Task> Tasks{get{return _tasks;}}
internal Member(string memberName){
Name=name;
_tasks=new List<Task>();
}
internal void AssignTask(string taskName){
_tasks.Add(new Task(taskName));
}
public bool HasCompletedAllTasks(){
return _tasks.All(t=>t.IsCompleted);
}
public Task GetNextAssignedTask(){
return _tasks.Where(t=>!t.IsCompleted)
.OrderBy(t=>t.AssignedOn).First();
}
}
public class Task:Entity{
public string Name{get; private set;}
public bool IsCompleted{get; private set;}
public DateTime CompletedOn{get; private set;}
public DateTime AssignedOn{get; private set;}
internal Task(string name){
Name=name;
AssignedOn=DateTime.Now;
}
internal void MarkAsCompleted(){
if(IsCompleted) throw new Exception
("Task is already completed!");
IsCompleted=true;
CompletedOn=DateTime.Now;
}
}
public class App{
public static void Main(){
var project=new Project
("Question: Aggregate root design and presentation layer");
var me=project.AssignMember("Arnis Lapsa");
project.AssignTaskToMember("Try to help user137348","Lapsa");
var currentTask=me.GetNextAssignedTask();
//SpamStackOverflow();
project.MemberHasCompletedTask(me,currentTask);
if(me.HasCompletedAllTasks()) project.Finish();
else throw new Exception("Enough for today...");
}
}
Keep in mind that I got little knowledge of what Your business is about. This is just an improvisation. :)
When it comes to DDD, make sure you don't get analysis paralysis when trying to design your domain and aggregates. It happened to me. My project got literally STOPPED for a whole month because i wasn't enable to get my aggregates straight. And i am talking about a simple 3 database tables situation. User, Address and UserProfile.
The thing with DDD is that there is no such a thing like DONE THE RIGHT WAY. If you post the same question here with an interval of 3 months from each other, you will always get the "experts" giving you completely different answers in each question. Amis L. was kind enough to give you a solid simple example. Most people would copy and paste from Eric's books.
Do whatever floats your boat. At the end of the day, no matter how handcrafted your domain is, it's never RIGHT to the community. Just chill and enjoy coding.