• Automatic Counter

  • OpenKM has many interesting features, but requires some configuration process to show its full potential.
OpenKM has many interesting features, but requires some configuration process to show its full potential.
Forum rules: Please, before asking something see the documentation wiki or use the search feature of the forum. And remember we don't have a crystal ball or mental readers, so if you post about an issue tell us which OpenKM are you using and also the browser and operating system version. For more info read How to Report Bugs Effectively.
 #12840  by vrega
 
Hi all,
i'm wondering for a DMS with the counter feature.
I need to have an a configurable field that increases automatically its value for every document i insert in the system.
Is this DMS capable to do this?

Thanks in advance for your answer.

Vrega
 #12844  by jllort
 
Of course and it's very simply to implementing it.
The most simply way for doing it is using scripting and metadata.

The only question is if you want to considering updating file as new file or not ( you can do easilly with scripting event conditional ).

Take a look here.
http://wiki.openkm.com/index.php/Extension_Guide
http://wiki.openkm.com/index.php/Scripting
 #12912  by johnorange
 
jllort wrote:Of course and it's very simply to implementing it.
The most simply way for doing it is using scripting and metadata.

The only question is if you want to considering updating file as new file or not ( you can do easilly with scripting event conditional ).

Take a look here.
http://wiki.openkm.com/index.php/Extension_Guide
http://wiki.openkm.com/index.php/Scripting
Josep, two questions on this:
1. Would it be possible to have the automatic number assigned to the doc as per the above as a property (similar to name, size, date, author etc) of the object, rather than a metadata? I noticed metadatas are not shown in the panel (which has only certain fixed properties) and it would be great to see the respective id in the panel, rather than in the property box below.
2. Would it help to inherit from OKMDocument (I am assuming this is the base document class) and create a new class MyOKMDocument which could implement the approach above. Or, in such a case, one would need to re-program the whole frontend, as references to OKMDocuments are hardcoded?

Thanks for your time,
JO
 #12927  by jllort
 
The most simpliest way to doing it, is at the same time is created the document you can add the metadata to the document and then create the count number ( that's the most easiest way for doing it ).

Otherside you need to change in frontend as a frontend extension that could implement actual Document.java extended with some call to database metadata tables. Take a look here http://wiki.openkm.com/index.php/Database_Metadata.

Finally you could modify Document.java class, and then you need modifying GWTDocument, and DocumentServlet.java too .. really so much modifications ... arrived at this point you need to change core implementation to store count value, or more easies simply use as I suggest before database metadata tables.
 #13048  by johnorange
 
jllort wrote:The most simpliest way to doing it, is at the same time is created the document you can add the metadata to the document and then create the count number ( that's the most easiest way for doing it ).

Otherside you need to change in frontend as a frontend extension that could implement actual Document.java extended with some call to database metadata tables. Take a look here http://wiki.openkm.com/index.php/Database_Metadata.

Finally you could modify Document.java class, and then you need modifying GWTDocument, and DocumentServlet.java too .. really so much modifications ... arrived at this point you need to change core implementation to store count value, or more easies simply use as I suggest before database metadata tables.
Thanks for the follow up Josep. Kindly allow me to revert on thus as I think this feature - assigning an ID number to a document upon create - is very useful. In essence, it allows people to quickly find a document in the repository by simply knowing its ID. This is essentially a more user friendly version of the UUID.

Could you explain a bit how the various classes OKMDocument, GWTDocument, Document.java, DocumentServlet.java interact? I have been looking over the code, but probably a bit of explanation on your side could put things into persective. On my side, I would hope for a solution which is code based and which is able to extend your code. So that one can keep updating OpenKM when you release new versions. Alternativelly, would it be possible you add such a new property to the main document class in the next release? One could simply take it from there and use such new property for population with the counter value.

Looking forward to hearing from you.

With kind regards,
JO
 #13050  by johnorange
 
Hi there Josep,

One more question. If I decide to add a new property to the document object, what classes I should be looking at from a data base perspective? Currently, the frontend displays my newly added property, so I now have to identify the persistence related classes.

Many thanks,
JO
 #13053  by jllort
 
I don't suggest modify DocumentServlet, Document.java class etc ... because we're doing strong changes on actual source code and you'll get problem to upgrade newer version from actual, and because it's not the idea we've got in mind to extend OpenKM features. I'll try explain you better how I thinking it.

We can separate the solution in two problems, assign UUID and view it.
Start with the second to view it ... simply create a property group ( metadata ) with field UUID, and register to openkm. From this point you've got manually UUID. Take a look here http://wiki.openkm.com/index.php/Property_Groups and http://wiki.openkm.com/index.php/Proper ... definition
When it'll be done then we want automatically UUID setting ... I suggest to starting the most easiest way, and probably what will run better, scripting. Take a look here http://wiki.openkm.com/index.php/Scripting
That could be separed by two task:
First; register script to okm:root node because we wants to take effect on all repository. The first step idea is, when event CREATE_DOCUMENT is fired must add property to the document ( take a look at PropertyGroupServer to know which class method must be used ( it's easy )).
Secondly you must change property group value, here must generate some number etc... I'll need to understanding the logic of the autogenerated number to help you on how doing it ( are several ways depending what you want to doing ).

I suggest you starting from here, and when you'll be arrived to automatically assing property group to document then we could continue talking in more deep about the logic of the autonumeric, meanwhile if you've got problems while doing the first steps, post here and I'll continue trying helping you.
 #13057  by johnorange
 
jllort wrote:I don't suggest modify DocumentServlet, Document.java class etc ... because we're doing strong changes on actual source code and you'll get problem to upgrade newer version from actual, and because it's not the idea we've got in mind to extend OpenKM features. I'll try explain you better how I thinking it.
HI there Josep. Your position is clear. For the record, I was trying merely to see if a more direct approach could work, with the aim to get myself familiarised with the platform and the role of specific classes thereunder. As it stands, the OpenKM platform has great features worth building on. So, by changing code directly, I am actually trying to better understand the inner workings of the application. With this in mind, when you have a bit of time, maybe you could detail a bit on the role of the diverse classes within OKM ,e.g. basedocument, okmdocument, gwtdocument, documentmodule etc.
jllort wrote: We can separate the solution in two problems, assign UUID and view it.
Start with the second to view it ... simply create a property group ( metadata ) with field UUID, and register to openkm. From this point you've got manually UUID. Take a look here http://wiki.openkm.com/index.php/Property_Groups and http://wiki.openkm.com/index.php/Proper ... definition
When it'll be done then we want automatically UUID setting ... I suggest to starting the most easiest way, and probably what will run better, scripting. Take a look here http://wiki.openkm.com/index.php/Scripting
That could be separed by two task:
First; register script to okm:root node because we wants to take effect on all repository. The first step idea is, when event CREATE_DOCUMENT is fired must add property to the document ( take a look at PropertyGroupServer to know which class method must be used ( it's easy )).
Secondly you must change property group value, here must generate some number etc... I'll need to understanding the logic of the autogenerated number to help you on how doing it ( are several ways depending what you want to doing ).
This is indeed a very suple, non-invasive approach and update ready. I am currently working on it as well. The only issue I had with it was that it is not all code, it also requires certain non-code related steps (metadata creating + code for metadata access) as well as scripting. In my current implementation, the documentid is a string, a property of the document class, and gwtdocument - think of it similarly to the "title" implementation that is currently being marked as comment in the source code.
jllort wrote: Secondly you must change property group value, here must generate some number etc... I'll need to understanding the logic of the autogenerated number to help you on how doing it ( are several ways depending what you want to doing ).
The number is a simple incremental id. You set the base, eg. 10000, and then each document created in the repository gets a new number base+1. As a simple primary key in a data base, which means that whatever happens to the document, the id keeps increasing. What it is important is that each document (not each version) gets such an id upon create in the repository. The idea is to be able to search the document based on this id, rather than title. Also, if one deals with docx documents, one could pass the id to the actual docx document using properties and fields. In essence, this approach allows a far better tracking of the printed documents and their correspondents in the repository. If you ask me, this should definetly be included in one of your future releases. I am ready to help as well, if the case.

Hope this helps and keep in touch.

WIth kind regards,
JO
 #13061  by johnorange
 
Hi there Josep,

Just wanted to say that I tried the approach with the property group and so far so good. I have created the property group with no issues, and things look really easy. I am about to start preparing the script. I will revert with news.

Best,
JO
 #13062  by johnorange
 
Hi there Josep,

I managed to add the property group upon create_event. I have however two issues:
1. I cannot seem to write correctly the script necessary to set the value of each of the properties in the respective group. I am using OKMPropertyGroup.getInstance().setProperties(null, nodeEvent.getPath, "mygroupname", properties).

I think the issue is with Beanshell and its way of handling collections, in the sense that whatever I pass as value for the "properties" argument, I get an error in the server console. Normally, the "properties" argument should be List<FormElement>, but I cannot seem to make it work. Could you suggest any Beanshell code that would work with the setProperties method of the current instance of OKMPropertyGroup? Most specifically the "properties" argument.

2. Is there any way to prevent the user from being able to remove the PropertyGroup from the UI?

Thanks for your time and support.

Best,
JO
 #13078  by jllort
 
Beanshell not supports generics must working
Code: Select all
List properties = new ArrayList();
....
FormElement fe = (FormElement) properties.next();
To prevent user deleting, simply declare PropertyGroup as readonly you can internally assign by scripting etc... there's no limitation on it ... but from UI can not be removed, changed etc...
 #13091  by johnorange
 
Hi there Josep,

Good news.

1. I managed to populate the properties argument. The issue was that I was trying to pass a FormElement type of object, but in reality I should have passed an Input type object in my case. The PropertyGroupServlet.java file was the key indeed, but it took me I while to realise the magic that the GWTUtil.copy method does. Nice code you wrote, btw!

2. Tested the suggestion re: property group set as readonly in the propertygroup.xml and it works. Thanks for it.

In terms of next steps, I am thinking of using metadata to store the value of the counter. The only issue so far is that while I can read the metadatavalues, I have not succeeded in updating them. Whenever I am executing the string generated by the buildupdate static method suggested in the wiki, I get the following error:
Code: Select all
Target exception: com.openkm.core.DatabaseException: Not supported for DML operations [update com.openkm.dao.bean.DatabaseMetadataValue dmv set dmv.col01 = 6000 where dmv.table='test'] 
If using the SQL code on OKM_DB_METADATA_VALUES, I can update the values just fine.

One note. I am using the LegacyDAO.executeQuery method. I am not sure this is ok. I plan to try with the DatabaseMetadataDAO methods as well.

Any idea why this happens? Could you please suggest a bit of code on how would you update a metadata record from java.

Many thanks,
JO
 #13097  by johnorange
 
Hi there,

Just wanted to say that I have made it to access the metadata. In essence, I have used the methods in the DatabaseMetadataDAO. getValueByPk, and updateValue are the key methods in accessing and changing the metadata.

Next ideas in line, adding a new column in the file browser and a search by DocID function.

I will post a different thread on this.

Best,
JO
 #13103  by jllort
 
Bean exemple
Code: Select all
public class GWTBorrador extends DatabaseMetadataCommon implements IsSerializable {
	// Metadata Virtual Name mapping 
	public static final String MV_TABLE_NAME		 		= "borrador";
	public static final String MV_COLUMN_NAME_ID			= "bor_id";
	public static final String MV_COLUMN_NAME_UUID		= "bor_uuid";

	
	private Integer id;
	private String uuid;
	
	@Override
	public void loadFromMap(Map<String, String> map) {
		super.loadFromMap(map);
		
		if (map.containsKey(MV_COLUMN_NAME_ID)) {
			setId(DatabaseMetadataMap.getIntegerValue(map.get(MV_COLUMN_NAME_ID)));
		}
		
		if (map.containsKey(MV_COLUMN_NAME_UUID)) {
			setUuid(map.get(MV_COLUMN_NAME_UUID));
		}
	}
	
	@Override
	public Map<String, String> restoreToMap() {
		Map<String,String> map = super.restoreToMap();
		
		if (id != null) {
			map.put(MV_COLUMN_NAME_ID, DatabaseMetadataMap.mapIntegerValue(getId()));
		}
		
		if (uuid != null) {
			map.put(MV_COLUMN_NAME_UUID, getUuid());
		}
		
		return map;
	}
	
	public Integer getId() {
		return id;
	}

	public void setId(Integer id) {
		this.id = id;
	}

	public String getUuid() {
		return uuid;
	}

	public void setUuid(String uuid) {
		this.uuid = uuid;
	}
}
DatabaseMetadataCommojn.java
Code: Select all
public abstract class DatabaseMetadataCommon {
	private Double realId;	
	private String realTable;
	
	/**
	 * loadFromMap
	 */
	public void loadFromMap(Map<String,String> map) {
		if (map.containsKey(DatabaseMetadataMap.MV_NAME_ID)) {
			setRealId(DatabaseMetadataMap.getDoubleValue(map.get(DatabaseMetadataMap.MV_NAME_ID)));
		}
		
		if (map.containsKey(DatabaseMetadataMap.MV_NAME_TABLE)) {
			setRealTable(map.get(DatabaseMetadataMap.MV_NAME_TABLE));
		}
	}
	
	/**
	 * restoreToMap
	 */
	public Map<String,String> restoreToMap() {
		Map<String,String> map = new HashMap<String,String>();
		
		if (realId != null) {
			map.put(DatabaseMetadataMap.MV_NAME_ID, DatabaseMetadataMap.mapDoubleValue(getRealId()));
		}
		
		if (realTable != null) {
			map.put(DatabaseMetadataMap.MV_NAME_TABLE, getRealTable());
		}
		
		return map;
	}
	
	public Double getRealId() {
		return realId;
	}

	public void setRealId(Double realId) {
		this.realId = realId;
	}

	public String getRealTable() {
		return realTable;
	}

	public void setRealTable(String realTable) {
		this.realTable = realTable;
	}
}

Query example from gwt
Code: Select all
String filter = "$" + GWTRequisito.MV_COLUMN_MUNICIPIO + "='" + municipio.getId() +"' and ";
		Date fechaActual = new Date();

		filter += "$" + GWTRequisito.MV_COLUMN_FECHA_EXP + ">='" + DatabaseMetadataMap.mapDateValue(fechaActual);
		String order = "$" + GWTRequisito.MV_COLUMN_FECHA_EXP;
		
		metadataService.executeValueQuery(GWTRequisito.MV_TABLE_NAME, filter, order, new AsyncCallback<List<Map<String,String>>>() {
			@Override
			public void onSuccess(List<Map<String, String>> result) {
				if (result.size() > 0) {
					requisito = new GWTRequisito();
					requisito.loadFromMap(result.get(0));
Take a look at DatabaseMetadataServlet.java and take a look DatabaseMetadataUtils.getDatabaseMetadataValueByMap(map) and DatabaseMetadataUtils.buildQuery(table, filter, order)
 #13105  by johnorange
 
Hi there Josep,

A. Thanks for the suggestions. Such great and prompt reactions! You gentlemen are great.

Two questions:
(a) From what I see, I assume these are meant to address the two points above: (i) new column, and (ii) search function. Is my understanding correct?
(b) there are no extensions to address the above? I mean I would wish to ensure that I keep your code clean from mine. So I can update when time comes

B. May I suggest you move this thread to the Board index ‹ OpenKM Developers ‹ Customization & Improvements. It is more related to that section. Also, I noticed there are other people interested in the matter.

Best,
JO

About Us

OpenKM is part of the management software. A management software is a program that facilitates the accomplishment of administrative tasks. OpenKM is a document management system that allows you to manage business content and workflow in a more efficient way. Document managers guarantee data protection by establishing information security for business content.