We’ve developed some resources to help you work effectively from home during COVID-19 Click to learn more

Creating appointments with connected documents in NetServer


I'm trying to import some old data to documents and appointments through NetServer web services. I have however not been able to figure out how to address the linking between the appointments and the documents

If I create the document first, it automatically creates an "empty" appointment. And there is as far as I see no way to get what appointment this document created? I have also tried adding the appointment first, and then add linking to the appointment though Links object on the DocumentEntity but even so I creates a new "empty" appointment

Also what are the minimum requirements for creating appointments? Because I also get this error "Message: This is not a valid participant" 

I use SaveAppointmentEntity and SaveDocumentEntity

Code for updating/creating documents:

DocumentEntity documentEntity = null;
if (document.Id > 0)
documentEntity = da.GetDocumentEntity(document.Id);
documentEntity = da.CreateDefaultDocumentEntity();
if (document.ContactId > 0)
using (ContactAgent ca = new ContactAgent())
documentEntity.Contact = ca.GetContact(document.ContactId);
documentEntity.CreatedDate = document.CreatedDate;
documentEntity.UpdatedDate = document.ChangedDate;
if (document.CreatedAssociateId > 0)
using (AssociateAgent aa = new AssociateAgent())
documentEntity.CreatedBy = aa.GetAssociate(document.CreatedAssociateId);
if (document.ChangedAssociateId > 0)
using (AssociateAgent aa = new AssociateAgent())
documentEntity.UpdatedBy = aa.GetAssociate(document.ChangedAssociateId);
documentEntity.Name = document.Name;
documentEntity.Header = document.Header;
documentEntity.OurRef = document.OurRef;
documentEntity.Attention = document.Attention;
documentEntity.Description = document.Description;
if (document.AppointmentId > 0)
Link appointmentLink = new Link();
appointmentLink.EntityName = "appointment";
appointmentLink.Id = document.AppointmentId;
documentEntity.Links = new Link[] { appointmentLink };
documentEntity.ActiveLinks = 1;

documentEntity = da.SaveDocumentEntity(documentEntity);

return documentEntity.DocumentId;


Code for updating/creating appointments:

AppointmentEntity appointmentEntity = null;
if (appointment.Id > 0)
appointmentEntity = ap.GetAppointmentEntity(appointment.Id);
appointmentEntity = ap.CreateDefaultAppointmentEntity();

appointmentEntity.ActiveDate = appointment.ActiveDate;
if (appointment.ContactId > 0)
using (ContactAgent ca = new ContactAgent())
appointmentEntity.Contact = ca.GetContact(appointment.ContactId);
if (appointment.SaleId > 0)
using (SaleAgent sa = new SaleAgent())
appointmentEntity.Sale = sa.GetSale(appointment.SaleId);
if (appointment.AssociateId > 0)
using (AssociateAgent aa = new AssociateAgent())
appointmentEntity.Associate = aa.GetAssociate(appointment.AssociateId);
appointmentEntity.EndDate = appointment.EndDate;
appointmentEntity.Description = appointment.Description;
if (appointment.PersonId > 0)
using (PersonAgent pa = new PersonAgent())
appointmentEntity.Person = pa.GetPerson(appointment.PersonId);
if (appointment.TaskId > 0)
appointmentEntity.Task = ap.GetTaskListItem(appointment.TaskId);

appointmentEntity.Location = appointment.Location;
appointmentEntity.CreatedDate = appointment.CreatedDate;
appointmentEntity.StartDate = appointment.DoneDate;
if (appointment.DocumentId > 0)
Link documentLink = new Link();
documentLink.EntityName = "document";
documentLink.Id = appointment.DocumentId;
appointmentEntity.Links = new Link[] { documentLink };

appointmentEntity = ap.SaveAppointmentEntity(appointmentEntity);

return appointmentEntity.AppointmentId;


RE: Creating appointments with connected documents in NetServer

You are confused about the underlying structures/architecture.
When Adding/Editing document entities, do not concern yourself with the fact that our document entity makes use of a appointment entity to store some common data. Just use the document entity methods

A document entity has no implicit appointment entity that is for all intens and purposes visible to you - not a real appintment ever visible in the GUI.

If however, you want to link Appointment, Sale, Document, and or Project entities to a document, you need to look in the Activtiy Links system. This is implemented as 2-way relations and show up in the Links tab of the main entities.


Av: Conrad Weyns 1. apr 2019

RE: Creating appointments with connected documents in NetServer


Well that's not very intuitive, but OK :) A few follow-up questions then.

1. So create document, retrive the id, create appointment retrive the id and link them together, but not like I have done with Links then? Do you have a codeexample for this?

2. Also what are causing the Invalid participant error on appointment? What are the requirements here? As a test now, I send in an associcate that I know exists and also the person_id of that associate, but I still get the error.

3. When trying to create a document and setting the documentEntity.CreatedDate it does not stick. It always saves as current datetime. UpdatedDate works fine though.

Av: Jon Henning Bergane 2. apr 2019

RE: Creating appointments with connected documents in NetServer

Any help regarding how to use the Activity Links? Where can I find documentation regarding this?

Av: Jon Henning Bergane 4. apr 2019

RE: Creating appointments with connected documents in NetServer

Hi Jon,

As for working with documents, see this article here

As for linking a document to an appointment using the Link property, here is an example that demonstrates linking a document to an appointment. You only need to specify the Link EntityName, which is either document, sale or appointment, and the corresponding id of that entity.

public void CreateAppointmentAndLinkDocument(DocumentEntity documentEntity)
    AppointmentAgent appntAgent = new AppointmentAgent();
    AppointmentEntity appntEntity = appntAgent.CreateDefaultAppointmentEntity();
    appntEntity.Description = documentEntity.Header;
    appntEntity.Contact = documentEntity.Contact;

    // ... whatever else you want to set

    Link documentLink = new Link();
    documentLink.EntityName = "document"; // or sale or appointment
    documentLink.Id = documentEntity.DocumentId;

    // link document to the appointment
    appntEntity.Links = new Link[] { documentLink };

You had some other questions, regarding what's the minimum properties needed to create create an appointment. Well there aren't many, but consider what you want to see in SuperOffice, you will want a Type, Start and End Times, possibly the corresponding company (Contact), contact person (Person), Project and/or Sale, etc. 

With regards to setting Contact, Person, Project and Sale, know that you do not have to use the agents to fetch them using the Agent.Get methods. If you know their ID values, that is enough, i.e. 

appntEntity.Person = new Person { PersonId = 0 };

Hope this helps get you a little closer to reaching your goal!

Best regards

Av: Tony Yates 4. apr 2019

RE: Creating appointments with connected documents in NetServer


Still not figured out this. My usecase is that I have some appointments and documents in an old CRM8 database that I want to import to a new one through the API.

So for example I have this for one contact in old DB, 6 appointments and 3 document:

And I end up with this after import though Netserver:


As you can see I end up with 9 appointments, and that's due to the fact that when I create a a document I automatically get an entry in the appointment table. But this entry does not however have all the fields that the document should have, like associate, dates etc. Also registered on the document is not set correctly even though it is set in same manner as updated is, which works fine.

My codeflow is this:

1. Build up appointmentEntity, but do not save it yet.

2. Create documentEntity with same contact_id as the appointmentEntity in step 1

3. Save documentEntity

4. Set documentId from step 3 on the appointmentEntity.Links object

5. Save appointmentEntity






Av: Jon Henning Bergane 12. apr 2019

RE: Creating appointments with connected documents in NetServer

Hi Jon,

OK, to replicate what you want, you will create 3 documents and 3 appointments, that's it. 

  1. Create the document entity and populate accordingly, then save and capture the return DocumentEntity. (creates one record in the document table and one in the appointment table)
  2. Create the appointment that will contain the Linked document, populate properties accordingly, then Save the AppointmentEntity (creates one record in the appointment table) 
  3. Repeat this process for the remaining two appointments and documents. 

You will end up with 6 appointment records, 3 with Type equal to 1 (for in Diary), and 3 with Type = 4 (for document). You will also end up with 3 document records, one for each document. 

Hope this helps!

Av: Tony Yates 12. apr 2019

RE: Creating appointments with connected documents in NetServer

I think that your are trying to run before you can walk...
Look at your old DB document records.
Look at column appointment_id.
40743, 40742 and 40741.

You will find these in your appointment records.

Ergo, you are not importing 6 appointments but 3.
40743, 40742 and 40741 are the concern of the Document entity and you need not concern yourself with these.

As I see it, you need to import 3 document and 3 appointments.
And there is no need to involve Activity Linking either which is a completely different thing.

You will aslso have to correctly map the Task list types fro one db to another.



Av: Conrad Weyns 13. apr 2019

RE: Creating appointments with connected documents in NetServer

Yes, I think I was confused by the fact that it uses the appointment table to store document info. So therefore my sourcedata has rows that should have been excluded. So right, now I then have exclude all rows from appointment table with Type = 4 in order to only get appointments right?

But there are some documents that in fact are connected/linked/attached or whatever you call it, to an appointment. Where in the DB can I find this then info? I assume I use the Link object on the appointment to connect these then?

Av: Jon Henning Bergane 15. apr 2019

RE: Creating appointments with connected documents in NetServer

If you are refering to these links:

then these are called Activity Links and are stored as 2-way relations in the Relation table.
The Netserver Document Entity has an ActivityLinksHelper called LinksHelper. 
This one has useful helper methods.
I suspect the (Service) Agents might also have this. 


Av: Conrad Weyns 15. apr 2019

RE: Creating appointments with connected documents in NetServer

Relations: https://community.superoffice.com/documentation/SDK/SO.Database/html/Tables-relations.htm

SourceTable/TargetTable points to Sequence tablenumber for the tables: https://community.superoffice.com/documentation/SDK/SO.Database/html/Tables-sequence.htm

(appointment=9 and document=10 in all databases, it's the tables after we introduced CDD that may differ and is the reason why you now find tablenumber and tablename in the sequence table)

Av: Margrethe Romnes 15. apr 2019

RE: Creating appointments with connected documents in NetServer

Thanks for all the help, I'm getting closer now :)

What's left is some of the dates that I can't seem to set. The registered dates won't stick even though I set the CreatedDate on the entities. Also how do I set the done date on the appointment?


Av: Jon Henning Bergane 15. apr 2019

RE: Creating appointments with connected documents in NetServer

Hi Jon, 

(EDITED) The CreateDate, which is set the Registered date in the database, is overriden on the first time the appointment is saved. It will always be set to the current datetime. However, if you capture the returned saved appointment, and change the CreatedDate to what you want, and then save again, it will persist to the updated CreatedDate. It's not ideal, but is the current state of the implementation.

The Done date is set when the Completed activity status is set. 

If you need more granular control over the Done date, you will need to use one of the core data access layers, i.e. SuperOffice.CRM.Entities, SuperOffice.CRM.Row to set it directly. 

Best regards.


Av: Tony Yates 15. apr 2019