<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://wiki.idempiere.org/w-en/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Tioraul</id>
	<title>iDempiere en - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.idempiere.org/w-en/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Tioraul"/>
	<link rel="alternate" type="text/html" href="https://wiki.idempiere.org/en/Special:Contributions/Tioraul"/>
	<updated>2026-05-05T08:11:57Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.35.2</generator>
	<entry>
		<id>https://wiki.idempiere.org/w-en/index.php?title=Plugin:_LCL_Rut_Taxid&amp;diff=17613</id>
		<title>Plugin: LCL Rut Taxid</title>
		<link rel="alternate" type="text/html" href="https://wiki.idempiere.org/w-en/index.php?title=Plugin:_LCL_Rut_Taxid&amp;diff=17613"/>
		<updated>2020-11-18T23:23:24Z</updated>

		<summary type="html">&lt;p&gt;Tioraul: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
* '''Maintainer:''' [[User:Tioraul|Raul Vasquez]] &lt;br /&gt;
* '''Status:''' Testing&lt;br /&gt;
* '''License:''' [http://www.gnu.org/licenses/gpl-2.0.html GPLv2]&lt;br /&gt;
* '''Price:''' Free&lt;br /&gt;
* '''Github Repository:''' [https://github.com/tioraulv/RUT/raw/master/VerificadorRutChile.zip]&lt;br /&gt;
* '''Zip file:''' VerificadorRutChile.zip&lt;br /&gt;
* '''Sources:''' [https://github.com/tioraulv/RUT/tree/master]&lt;br /&gt;
* '''On Feature:''' VerificadorRutChile.feature.group&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Description ==&lt;br /&gt;
&lt;br /&gt;
This functionality adds chilean Tax Id RUT Verification on TaxID field&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If you want to provide additional comments, please use the [[Talk:Plugin:_LCL_Rut_Taxid|Discussion page]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== How to Install ==&lt;br /&gt;
There are two ways to install, Felix Console or P2 Repository.&lt;br /&gt;
&lt;br /&gt;
=== Felix Console ===&lt;br /&gt;
&lt;br /&gt;
watch this video (spanish)[https://www.youtube.com/watch?v=oAQUK2FJBV0]&lt;br /&gt;
&lt;br /&gt;
=== P2 Repository ===&lt;br /&gt;
&lt;br /&gt;
Unzip VerificadorRutChile.zip&lt;br /&gt;
&lt;br /&gt;
 DESTINATION=/opt/idempiere-server  # Where your iDempiere server is installed&lt;br /&gt;
 REPO=/folder/where/you/unzip/VericadorRutChile.zip&lt;br /&gt;
 cd $DESTINATION&lt;br /&gt;
 sudo java -Dosgi.noShutdown=false -Dosgi.compatibility.bootdelegation=true -Dosgi.install.area=director \&lt;br /&gt;
   -jar plugins/org.eclipse.osgi_3.7.*.jar -application org.eclipse.equinox.p2.director \&lt;br /&gt;
   -consoleLog -profileProperties org.eclipse.update.install.features=true \&lt;br /&gt;
   -destination $DESTINATION -repository file://$REPO \&lt;br /&gt;
   -i VerificadorRutChile.feature.group&lt;br /&gt;
&lt;br /&gt;
Replace the DESTINATION variable with the folder where your iDempiere server is installed.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Available_Plugins]]&lt;br /&gt;
[[Category:Localisation|C]]&lt;/div&gt;</summary>
		<author><name>Tioraul</name></author>
	</entry>
	<entry>
		<id>https://wiki.idempiere.org/w-en/index.php?title=Plugin:_LCL_Rut_Taxid&amp;diff=17612</id>
		<title>Plugin: LCL Rut Taxid</title>
		<link rel="alternate" type="text/html" href="https://wiki.idempiere.org/w-en/index.php?title=Plugin:_LCL_Rut_Taxid&amp;diff=17612"/>
		<updated>2020-11-18T23:19:22Z</updated>

		<summary type="html">&lt;p&gt;Tioraul: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
* '''Maintainer:''' [[User:Tioraul|Raul Vasquez]] &lt;br /&gt;
* '''Status:''' Testing&lt;br /&gt;
* '''License:''' [http://www.gnu.org/licenses/gpl-2.0.html GPLv2]&lt;br /&gt;
* '''Price:''' Free&lt;br /&gt;
* '''Github Repository:''' [https://github.com/tioraulv/RUT/raw/master/VerificadorRutChile.zip]&lt;br /&gt;
* '''Zip file:''' VerificadorRutChile.zip&lt;br /&gt;
* '''Sources:''' [https://github.com/tioraulv/RUT/blob/master/]&lt;br /&gt;
* '''On Feature:''' VerificadorRutChile.feature.group&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Description ==&lt;br /&gt;
&lt;br /&gt;
This functionality adds chilean Tax Id RUT Verification on TaxID field&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If you want to provide additional comments, please use the [[Talk:Plugin:_LCL_Rut_Taxid|Discussion page]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== How to Install ==&lt;br /&gt;
There are two ways to install, Felix Console or P2 Repository.&lt;br /&gt;
&lt;br /&gt;
=== Felix Console ===&lt;br /&gt;
&lt;br /&gt;
watch this video (spanish)[https://www.youtube.com/watch?v=oAQUK2FJBV0]&lt;br /&gt;
&lt;br /&gt;
=== P2 Repository ===&lt;br /&gt;
&lt;br /&gt;
Unzip VerificadorRutChile.zip&lt;br /&gt;
&lt;br /&gt;
 DESTINATION=/opt/idempiere-server  # Where your iDempiere server is installed&lt;br /&gt;
 REPO=/folder/where/you/unzip/VericadorRutChile.zip&lt;br /&gt;
 cd $DESTINATION&lt;br /&gt;
 sudo java -Dosgi.noShutdown=false -Dosgi.compatibility.bootdelegation=true -Dosgi.install.area=director \&lt;br /&gt;
   -jar plugins/org.eclipse.osgi_3.7.*.jar -application org.eclipse.equinox.p2.director \&lt;br /&gt;
   -consoleLog -profileProperties org.eclipse.update.install.features=true \&lt;br /&gt;
   -destination $DESTINATION -repository file://$REPO \&lt;br /&gt;
   -i VerificadorRutChile.feature.group&lt;br /&gt;
&lt;br /&gt;
Replace the DESTINATION variable with the folder where your iDempiere server is installed.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Available_Plugins]]&lt;br /&gt;
[[Category:Localisation|C]]&lt;/div&gt;</summary>
		<author><name>Tioraul</name></author>
	</entry>
	<entry>
		<id>https://wiki.idempiere.org/w-en/index.php?title=Plugin:_LCL_Rut_Taxid&amp;diff=17611</id>
		<title>Plugin: LCL Rut Taxid</title>
		<link rel="alternate" type="text/html" href="https://wiki.idempiere.org/w-en/index.php?title=Plugin:_LCL_Rut_Taxid&amp;diff=17611"/>
		<updated>2020-11-18T23:14:21Z</updated>

		<summary type="html">&lt;p&gt;Tioraul: actualizando repositorios&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
* '''Maintainer:''' [[User:Tioraul|Raul Vasquez]] &lt;br /&gt;
* '''Status:''' Testing&lt;br /&gt;
* '''License:''' [http://www.gnu.org/licenses/gpl-2.0.html GPLv2]&lt;br /&gt;
* '''Price:''' Free&lt;br /&gt;
* '''Github Repository:''' [https://github.com/tioraulv/RUT/blob/master/VerificadorRutChile.zip]&lt;br /&gt;
* '''Zip file:''' VerificadorRutChile.zip&lt;br /&gt;
* '''Sources:''' [https://github.com/tioraulv/RUT/blob/master/]&lt;br /&gt;
* '''On Feature:''' VerificadorRutChile.feature.group&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Description ==&lt;br /&gt;
&lt;br /&gt;
This functionality adds chilean Tax Id RUT Verification on TaxID field&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If you want to provide additional comments, please use the [[Talk:Plugin:_LCL_Rut_Taxid|Discussion page]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== How to Install ==&lt;br /&gt;
There are two ways to install, Felix Console or P2 Repository.&lt;br /&gt;
&lt;br /&gt;
=== Felix Console ===&lt;br /&gt;
&lt;br /&gt;
watch this video (spanish)[https://www.youtube.com/watch?v=oAQUK2FJBV0]&lt;br /&gt;
&lt;br /&gt;
=== P2 Repository ===&lt;br /&gt;
&lt;br /&gt;
Unzip VerificadorRutChile.zip&lt;br /&gt;
&lt;br /&gt;
 DESTINATION=/opt/idempiere-server  # Where your iDempiere server is installed&lt;br /&gt;
 REPO=/folder/where/you/unzip/VericadorRutChile.zip&lt;br /&gt;
 cd $DESTINATION&lt;br /&gt;
 sudo java -Dosgi.noShutdown=false -Dosgi.compatibility.bootdelegation=true -Dosgi.install.area=director \&lt;br /&gt;
   -jar plugins/org.eclipse.osgi_3.7.*.jar -application org.eclipse.equinox.p2.director \&lt;br /&gt;
   -consoleLog -profileProperties org.eclipse.update.install.features=true \&lt;br /&gt;
   -destination $DESTINATION -repository file://$REPO \&lt;br /&gt;
   -i VerificadorRutChile.feature.group&lt;br /&gt;
&lt;br /&gt;
Replace the DESTINATION variable with the folder where your iDempiere server is installed.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Available_Plugins]]&lt;br /&gt;
[[Category:Localisation|C]]&lt;/div&gt;</summary>
		<author><name>Tioraul</name></author>
	</entry>
	<entry>
		<id>https://wiki.idempiere.org/w-en/index.php?title=Fixed_Assets,_a_practical_example&amp;diff=14534</id>
		<title>Fixed Assets, a practical example</title>
		<link rel="alternate" type="text/html" href="https://wiki.idempiere.org/w-en/index.php?title=Fixed_Assets,_a_practical_example&amp;diff=14534"/>
		<updated>2019-03-08T22:13:38Z</updated>

		<summary type="html">&lt;p&gt;Tioraul: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;[https://youtu.be/Nyt36LBhPIA Please watch this video (spanish)]&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Fixed Assets Setup ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===== 1. Setup Depreciation Method. =====&lt;br /&gt;
Only “Straight Line” is currently developed. Make sure to use “SL” as value in column&lt;br /&gt;
DepreciationType.&lt;br /&gt;
&lt;br /&gt;
===== 2. Setup Asset Group. =====&lt;br /&gt;
Asset Group is where the default setup for asset is derived. &lt;br /&gt;
Entry the Asset Group name and tick Owned and Depreciate. &lt;br /&gt;
Note that there is a Default flag. When you tick it, this Asset Group Accounting information will become Default for all other new Asset Group.&lt;br /&gt;
&lt;br /&gt;
===== 3. Setup Asset Group Acct =====&lt;br /&gt;
This is where you set all parameters related to Depreciation calculation and all those Accounting&lt;br /&gt;
account configurations. &lt;br /&gt;
&lt;br /&gt;
===== 4. Setup Product Category =====&lt;br /&gt;
Asset Group must be paired with Product Category. Create a product category for each asset group and set the Asset Group value.&lt;br /&gt;
&lt;br /&gt;
===== 5. Setup Product =====&lt;br /&gt;
&lt;br /&gt;
	• Product Category: 	you must set the appropriate Product Category that has been paired with a 				certain	Asset Group.&lt;br /&gt;
&lt;br /&gt;
	• Product Type: 	you must not use “Item”. Either “Expense” or Resource is recommended.&lt;br /&gt;
&lt;br /&gt;
	• Product price list setup: include the product in a price list.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Asset Addition ====&lt;br /&gt;
&lt;br /&gt;
Asset Addition may be from:&lt;br /&gt;
 			&lt;br /&gt;
* Match Invoice (it will be explain below)&lt;br /&gt;
* Import Asset&lt;br /&gt;
* Project&lt;br /&gt;
* Manual way&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== &amp;lt;big&amp;gt;Asset Addition from Match Invoice&amp;lt;/big&amp;gt; ==&lt;br /&gt;
&lt;br /&gt;
#  Create and Complete a Purchase Order with product that will be a new asset.&lt;br /&gt;
#  Create and Complete a Material Receipt document and its lines using “create lines from”&lt;br /&gt;
#  Create an Invoice Vendor and use “Create Lines From” to automatically create Match Invoice. &lt;br /&gt;
#  In the Invoice Vendor line You should notice that the “Asset Related?” [now called 'Create Asset'] flag is ticked. &lt;br /&gt;
#  Select “Capital” value on field “Capital vs Expense” and you'll see the related Asset Group value on field “Asset Group”.&lt;br /&gt;
#  Complete the Vendor Invoice.&lt;br /&gt;
#  Enter to Asset addition window, search and complete the new Asset. (When Match Invoice document is completed, a new asset record and a new asset addition record will be automatically generated.)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;[https://youtu.be/Nyt36LBhPIA Please watch this video (spanish)]&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The invoice vendor line will only show the link to the asset once the asset addition has been completed.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[NF1.0_Fixed_Assets]]&lt;/div&gt;</summary>
		<author><name>Tioraul</name></author>
	</entry>
	<entry>
		<id>https://wiki.idempiere.org/w-en/index.php?title=NF1.0_Fixed_Assets&amp;diff=14533</id>
		<title>NF1.0 Fixed Assets</title>
		<link rel="alternate" type="text/html" href="https://wiki.idempiere.org/w-en/index.php?title=NF1.0_Fixed_Assets&amp;diff=14533"/>
		<updated>2019-03-08T22:12:01Z</updated>

		<summary type="html">&lt;p&gt;Tioraul: link to Fixed Assets, a practical example&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= '''Feature:''' Fixed Assets Stabilization =&lt;br /&gt;
&lt;br /&gt;
'''Goal:''' Functional&lt;br /&gt;
&lt;br /&gt;
'''Contributor:''' [[User:Edwinang|Edwin Ang]]&lt;br /&gt;
&lt;br /&gt;
'''Description:'''&lt;br /&gt;
&lt;br /&gt;
With the release 1.0 of iDempiere the Fixed Assets extension was fully integrated and a stabilization effort was contributed.&lt;br /&gt;
&lt;br /&gt;
[[User:Edwinang|Edwin Ang]] contributed a manual available at [http://bitbucket.org/edwinang/fixed_assets/downloads/iDempiere%20FA%20User%20Manual.pdf iDempiere FA User Manual.pdf]&lt;br /&gt;
&lt;br /&gt;
[http://www.ntier.co.za nTier Software services] contributed additional notes, see this [https://groups.google.com/forum/#!topic/idempiere/oPDbr0Sm4MY Google Groups Post], available [https://bitbucket.org/ntiersoftware/various/downloads/iDempiere%20FA%20User%20Manual%20Addendum.pdf here].&lt;br /&gt;
&lt;br /&gt;
'''Technical Info:''' [http://idempiere.atlassian.net/browse/IDEMPIERE-197 IDEMPIERE-197]&lt;br /&gt;
&lt;br /&gt;
[[Fixed Assets, a practical example]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:New Features|F]]&lt;br /&gt;
[[Category:New Features v1.0|F]]&lt;br /&gt;
[[Category:New Features Functional]]&lt;br /&gt;
[[Category:User Manual‏‎]]&lt;br /&gt;
[[Category:Financial accounting‏‎]]&lt;br /&gt;
[[Category:Depreciation/amortization‏‎‏‏‎]]&lt;br /&gt;
[[Category:Materials management‏‎]]&lt;br /&gt;
[[Category:Materials management base data‏‎]]&lt;br /&gt;
[[Category:Article base data‎]]&lt;br /&gt;
[[Category:Price List‏‎]]&lt;/div&gt;</summary>
		<author><name>Tioraul</name></author>
	</entry>
	<entry>
		<id>https://wiki.idempiere.org/w-en/index.php?title=Fixed_Assets,_a_practical_example&amp;diff=14532</id>
		<title>Fixed Assets, a practical example</title>
		<link rel="alternate" type="text/html" href="https://wiki.idempiere.org/w-en/index.php?title=Fixed_Assets,_a_practical_example&amp;diff=14532"/>
		<updated>2019-03-08T22:10:16Z</updated>

		<summary type="html">&lt;p&gt;Tioraul: Created page with &amp;quot;  &amp;lt;big&amp;gt;[https://youtu.be/Nyt36LBhPIA Please watch this video (spanish)]&amp;lt;/big&amp;gt;  === Fixed Assets Setup ===   ===== 1. Setup Depreciation Method. ===== Only “Straight Line”...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;[https://youtu.be/Nyt36LBhPIA Please watch this video (spanish)]&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Fixed Assets Setup ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===== 1. Setup Depreciation Method. =====&lt;br /&gt;
Only “Straight Line” is currently developed. Make sure to use “SL” as value in column&lt;br /&gt;
DepreciationType.&lt;br /&gt;
&lt;br /&gt;
===== 2. Setup Asset Group. =====&lt;br /&gt;
Asset Group is where the default setup for asset is derived. &lt;br /&gt;
Entry the Asset Group name and tick Owned and Depreciate. &lt;br /&gt;
Note that there is a Default flag. When you tick it, this Asset Group Accounting information will become Default for all other new Asset Group.&lt;br /&gt;
&lt;br /&gt;
===== 3. Setup Asset Group Acct =====&lt;br /&gt;
This is where you set all parameters related to Depreciation calculation and all those Accounting&lt;br /&gt;
account configurations. &lt;br /&gt;
&lt;br /&gt;
===== 4. Setup Product Category =====&lt;br /&gt;
Asset Group must be paired with Product Category. Create a product category for each asset group and set the Asset Group value.&lt;br /&gt;
&lt;br /&gt;
===== 5. Setup Product =====&lt;br /&gt;
&lt;br /&gt;
	• Product Category: 	you must set the appropriate Product Category that has been paired with a 				certain	Asset Group.&lt;br /&gt;
&lt;br /&gt;
	• Product Type: 	you must not use “Item”. Either “Expense” or Resource is recommended.&lt;br /&gt;
&lt;br /&gt;
	• Product price list setup: include the product in a price list.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Asset Addition ====&lt;br /&gt;
&lt;br /&gt;
Asset Addition may be from:&lt;br /&gt;
 			&lt;br /&gt;
* Match Invoice (it will be explain below)&lt;br /&gt;
* Import Asset&lt;br /&gt;
* Project&lt;br /&gt;
* Manual way&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== &amp;lt;big&amp;gt;Asset Addition from Match Invoice&amp;lt;/big&amp;gt; ==&lt;br /&gt;
&lt;br /&gt;
#  Create and Complete a Purchase Order with product that will be a new asset.&lt;br /&gt;
#  Create and Complete a Material Receipt document and its lines using “create lines from”&lt;br /&gt;
#  Create an Invoice Vendor and use “Create Lines From” to automatically create Match Invoice. &lt;br /&gt;
#  In the Invoice Vendor line You should notice that the “Asset Related?” [now called 'Create Asset'] flag is ticked. &lt;br /&gt;
#  Select “Capital” value on field “Capital vs Expense” and you'll see the related Asset Group value on field “Asset Group”.&lt;br /&gt;
#  Complete the Vendor Invoice.&lt;br /&gt;
#  Enter to Asset addition window, search and complete the new Asset. (When Match Invoice document is completed, a new asset record and a new asset addition record will be automatically generated.)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;[https://youtu.be/Nyt36LBhPIA Please watch this video (spanish)]&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The invoice vendor line will only show the link to the asset once the asset addition has been completed.&lt;/div&gt;</summary>
		<author><name>Tioraul</name></author>
	</entry>
	<entry>
		<id>https://wiki.idempiere.org/w-en/index.php?title=Geografia_Chile:_LCL_Geografia&amp;diff=14531</id>
		<title>Geografia Chile: LCL Geografia</title>
		<link rel="alternate" type="text/html" href="https://wiki.idempiere.org/w-en/index.php?title=Geografia_Chile:_LCL_Geografia&amp;diff=14531"/>
		<updated>2019-03-03T21:29:25Z</updated>

		<summary type="html">&lt;p&gt;Tioraul: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== INSTALAR GEOGRAFIA DE CHILE ==&lt;br /&gt;
&lt;br /&gt;
* Descargue el paquete PaisChile.zip https://sourceforge.net/projects/adempierechile/files/PaisChile.zip/download&lt;br /&gt;
&lt;br /&gt;
* Ingrese en Idempiere con usuario SuperUser y Cliente System, en el Menu seleccione Pack In:&lt;br /&gt;
* Dele un nombre al nuevo Pack In.&lt;br /&gt;
* Adjunte (presione el icono de clip) el arichivo zip recien bajado.&lt;br /&gt;
  Luego Ok (el icono de ticket verde)&lt;br /&gt;
  Presione el botón PackIn&lt;br /&gt;
  Se demora algunos segundos y ya está la base de datos poblada con toda la geografía de Chile.&lt;br /&gt;
&lt;br /&gt;
* En el Menu seleccione Country Region and City&lt;br /&gt;
* Busque Chile&lt;br /&gt;
  Active casillero Country Has Region&lt;br /&gt;
  Adecuar la secuencia de captura (Capture Sequence) para que considere Region: &lt;br /&gt;
  @CO@, @R@, @C@ @A1@ @A2@ @P@&lt;br /&gt;
&lt;br /&gt;
[https://youtu.be/_PQBpt_KINg Video Instalación Geografía Chile]&lt;/div&gt;</summary>
		<author><name>Tioraul</name></author>
	</entry>
	<entry>
		<id>https://wiki.idempiere.org/w-en/index.php?title=Localizations&amp;diff=14530</id>
		<title>Localizations</title>
		<link rel="alternate" type="text/html" href="https://wiki.idempiere.org/w-en/index.php?title=Localizations&amp;diff=14530"/>
		<updated>2019-03-03T21:22:32Z</updated>

		<summary type="html">&lt;p&gt;Tioraul: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Colombia ==&lt;br /&gt;
&lt;br /&gt;
[[Image:Qss.jpg|right|160px]]&lt;br /&gt;
* '''Maintainer:''' [[User:CarlosRuiz|Carlos Ruiz]] - [http://globalqss.com Quality Systems &amp;amp; Solutions GlobalQSS]&lt;br /&gt;
* '''Last Update:''' January 9, 2019&lt;br /&gt;
* '''Status:''' Up to date with release 6.2&lt;br /&gt;
* '''Download URL:''' Look at installation guide&lt;br /&gt;
* [http://wiki.idempiere.org/es/LCO_Instrucciones_Instalacion Installation Guide in Spanish]&lt;br /&gt;
** Plugins&lt;br /&gt;
*** [[Plugin:_LCO_Detailed_Names|Nombres Detallados]]&lt;br /&gt;
*** Medios Magnéticos&lt;br /&gt;
*** Retenciones&lt;br /&gt;
*** Control de Resoluciones para Numeración de Facturación&lt;br /&gt;
** Datos&lt;br /&gt;
*** Geografía Capitales&lt;br /&gt;
*** Geografía Completa&lt;br /&gt;
*** Festivos&lt;br /&gt;
*** Datos Ejemplo Retenciones para GardenWorld&lt;br /&gt;
*** Datos Ejemplo Medios Magnéticos para GardenWorld&lt;br /&gt;
** [[Translations#Colombia|Lenguage es_CO]]&lt;br /&gt;
&lt;br /&gt;
== Chile ==&lt;br /&gt;
&lt;br /&gt;
* [[Geografia Chile: LCL Geografia|Geografia Chile (Regiones y Comunas) : LCL Geografia]]&lt;br /&gt;
* [[Plugin: LCL Rut Taxid|Plugin: LCL Rut Taxid (Verificador RUT o CI Chileno)]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Perú ==&lt;br /&gt;
[[Image:Logo_egs_group-1-1.png‎|right|225px]]&lt;br /&gt;
* '''Maintainer:''' [[User:PabloValdivia|Pablo Valdivia]] - [http://egs.pe EGS GROUP]&lt;br /&gt;
* '''Last Update:''' July 20, 2014&lt;br /&gt;
* '''Status:''' Up to date with release 2.0 &lt;br /&gt;
* '''Source Code:''' [https://bitbucket.org/grupoegs/grupoegs-idempiere-lpe/wiki/Home Home bitbucket LPE]&lt;br /&gt;
* '''Download URL:''' [https://bitbucket.org/grupoegs/grupoegs-idempiere-lpe/downloads downloads]&lt;br /&gt;
** Plugins&lt;br /&gt;
*** [[:es:LPE_Instrucciones_Instalacion|LPE Asientos de Amarre]]&lt;br /&gt;
** LPE Archivos base&lt;br /&gt;
*** [https://drive.google.com/file/d/0B49a4FHc8nJSTUVaY2hjMWt4bzQ/edit?usp=sharing  Geografia de Perú]&lt;br /&gt;
*** [https://drive.google.com/file/d/0B49a4FHc8nJSQ0lFYWp5aDRZSGM/edit?usp=sharing  Plan Contable Empresarial Perú]&lt;br /&gt;
&lt;br /&gt;
== Brasil ==&lt;br /&gt;
&lt;br /&gt;
* '''Maintainer:''' [[User:Alan.lesc1|Alan Lescano]]&lt;br /&gt;
* '''Status:''' on the road to 1.0&lt;br /&gt;
* '''Source-code URL:''' [https://bitbucket.org/idempierelbr/idempierelbr https://bitbucket.org/idempierelbr/idempierelbr]&lt;br /&gt;
** Plugin&lt;br /&gt;
*** [[Plugin:_LBR_Localization_Brazil|LBR Localization Brazil]]&lt;br /&gt;
&lt;br /&gt;
== España ==&lt;br /&gt;
* '''Maintainer:''' [[User:Efekto2k|Efekto 2k]] -- - [http://www.tecnoxp.com TecnoXperience]&lt;br /&gt;
* '''Last Update:''' November 14, 2014&lt;br /&gt;
** ''' Translation: ''' on November 18, 70%&lt;br /&gt;
*** '''Status:''' Preparing to Up to date with release 2.0 &lt;br /&gt;
*** '''Source Code:''' https://bitbucket.org/tecnoxperience/idempiere_spanish_location (Not finished yet)&lt;br /&gt;
*** '''Download URL:''' https://bitbucket.org/tecnoxperience/idempiere_spanish_location (Not finished yet)&lt;br /&gt;
** ''' Account Schema ''' &lt;br /&gt;
*** '''Status:''' Prepared to Up to date with release 2.0 &lt;br /&gt;
*** '''Source Code:''' https://bitbucket.org/tecnoxperience/idempiere_spanish_location/src/40150d344aeff94650d04c9626307acc4e1da844/PLAN%20CONTABLE%20ESPA%C3%91A.csv?at=default&lt;br /&gt;
*** '''Download URL:''' https://bitbucket.org/tecnoxperience/idempiere_spanish_location/src/40150d344aeff94650d04c9626307acc4e1da844/PLAN%20CONTABLE%20ESPA%C3%91A.csv?at=default&lt;br /&gt;
** ''' Spanish Regions ''' Already on trunk&lt;br /&gt;
** ''' Standar Account Reports ''' on November 18, 30%&lt;br /&gt;
*** ''' Pérdidas y Ganancias '''&lt;br /&gt;
*** ''' Balance de Situación '''&lt;br /&gt;
*** ''' IVA '''&lt;br /&gt;
*** ''' Diario del Mayor '''&lt;br /&gt;
&lt;br /&gt;
== Việt Nam ==&lt;br /&gt;
* '''Maintainer:''' [[User:hieplq|Hiêp Lê Quý]]&lt;br /&gt;
* '''Download URL:''' [https://bitbucket.org/hieplq/vn.hsv.vietnam.localization Bitbucket]&lt;br /&gt;
** Tiếng việt vi_vn&lt;br /&gt;
*** '''Status:''' not yet complete, very bad translate ([https://translations.launchpad.net/idempiere-vi-vn online maintain])&lt;br /&gt;
*** '''Data:''' folder /language&lt;br /&gt;
*** '''Guideline:''' /language/step make translate to launchpad.txt&lt;br /&gt;
** ''' Account Schema '''  maintain file from age of adempiere&lt;br /&gt;
*** '''Data:''' /accounting/AccountingVN-COA-QD15-VN.csv&lt;br /&gt;
** ''' Việt Name city list ''' List Việt Nam city with name, post code, phone code&lt;br /&gt;
*** '''Data:''' use import csv to import file /city/VietNam_C_City.csv or run sql in /city/[database name]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Japan ==&lt;br /&gt;
[[Image:JPiere-tate.png |200px|right|JPiere]]&lt;br /&gt;
* '''Creator:''' [[User:Hideaki_Hagiwara|Hagiwara Hideaki]] in JAPAN (I'm sorry for my poor English. Please modify correctly if my English expressions are mistaken.)&lt;br /&gt;
* '''SPONSOR:''' [http://www.oss-erp.co.jp/ OSS ERP Solutions] in JAPAN&lt;br /&gt;
* '''Source:''' [https://bitbucket.org/jpiere/  Bitbucket JPiere repository] &lt;br /&gt;
* '''More info(Japanese):'''[[:Plugin: Localization Japan|Plugin Localization Japan]]&lt;br /&gt;
* '''More info(Japanese):'''[http://www.compiere-distribution-lab.net/jpiere-lab/ JPiere Lab] &lt;br /&gt;
&lt;br /&gt;
== Nicaragua ==&lt;br /&gt;
&lt;br /&gt;
[[Image:SAC.jpg|right|160px]]&lt;br /&gt;
* '''Maintainer:''' [[User:CésarBaldelomar|César Baldelomar]] , [[User:obenavidez|Osmar Benavidez]] - [http://processus-erp.blogspot.com/ Soluciones Ágiles y Confiables]&lt;br /&gt;
* '''Last Update:''' Octubre 05, 2016&lt;br /&gt;
* '''Status:''' Up to date with release 3.1&lt;br /&gt;
* '''Download URL:''' [https://bitbucket.org/CesarBaldelomar/lco_nicaragua/downloads]&lt;br /&gt;
** Plugins&lt;br /&gt;
*** Retenciones&lt;br /&gt;
*** Detalles&lt;br /&gt;
*** LCO_Retenciones&lt;br /&gt;
*** [[Plugin:Notifications |Notificaciones]]&lt;br /&gt;
** Datos&lt;br /&gt;
*** Geografía Departamento - Municipios&lt;br /&gt;
*** Elemento Contable&lt;br /&gt;
** Lenguage es_NI&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:User Manual]]&lt;br /&gt;
[[Category:Setup]]&lt;br /&gt;
[[Category:System administration]]&lt;br /&gt;
[[Category:Localisation]]&lt;br /&gt;
[[Category:Translation]]&lt;/div&gt;</summary>
		<author><name>Tioraul</name></author>
	</entry>
	<entry>
		<id>https://wiki.idempiere.org/w-en/index.php?title=Localizations&amp;diff=14529</id>
		<title>Localizations</title>
		<link rel="alternate" type="text/html" href="https://wiki.idempiere.org/w-en/index.php?title=Localizations&amp;diff=14529"/>
		<updated>2019-03-03T21:14:00Z</updated>

		<summary type="html">&lt;p&gt;Tioraul: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Colombia ==&lt;br /&gt;
&lt;br /&gt;
[[Image:Qss.jpg|right|160px]]&lt;br /&gt;
* '''Maintainer:''' [[User:CarlosRuiz|Carlos Ruiz]] - [http://globalqss.com Quality Systems &amp;amp; Solutions GlobalQSS]&lt;br /&gt;
* '''Last Update:''' January 9, 2019&lt;br /&gt;
* '''Status:''' Up to date with release 6.2&lt;br /&gt;
* '''Download URL:''' Look at installation guide&lt;br /&gt;
* [http://wiki.idempiere.org/es/LCO_Instrucciones_Instalacion Installation Guide in Spanish]&lt;br /&gt;
** Plugins&lt;br /&gt;
*** [[Plugin:_LCO_Detailed_Names|Nombres Detallados]]&lt;br /&gt;
*** Medios Magnéticos&lt;br /&gt;
*** Retenciones&lt;br /&gt;
*** Control de Resoluciones para Numeración de Facturación&lt;br /&gt;
** Datos&lt;br /&gt;
*** Geografía Capitales&lt;br /&gt;
*** Geografía Completa&lt;br /&gt;
*** Festivos&lt;br /&gt;
*** Datos Ejemplo Retenciones para GardenWorld&lt;br /&gt;
*** Datos Ejemplo Medios Magnéticos para GardenWorld&lt;br /&gt;
** [[Translations#Colombia|Lenguage es_CO]]&lt;br /&gt;
&lt;br /&gt;
== Chile ==&lt;br /&gt;
&lt;br /&gt;
* [https://sourceforge.net/projects/adempierechile/files/GeografiaChileIdempiere.zip/download Geografía Completa con Comunas y Regiones]&lt;br /&gt;
* [[Geografia_Chile:_LCL_Geografia]]&lt;br /&gt;
* [http://wiki.idempiere.org/en/Plugin:_LCL_Rut_Taxid Plugin Verificador RUT o CI chileno]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Perú ==&lt;br /&gt;
[[Image:Logo_egs_group-1-1.png‎|right|225px]]&lt;br /&gt;
* '''Maintainer:''' [[User:PabloValdivia|Pablo Valdivia]] - [http://egs.pe EGS GROUP]&lt;br /&gt;
* '''Last Update:''' July 20, 2014&lt;br /&gt;
* '''Status:''' Up to date with release 2.0 &lt;br /&gt;
* '''Source Code:''' [https://bitbucket.org/grupoegs/grupoegs-idempiere-lpe/wiki/Home Home bitbucket LPE]&lt;br /&gt;
* '''Download URL:''' [https://bitbucket.org/grupoegs/grupoegs-idempiere-lpe/downloads downloads]&lt;br /&gt;
** Plugins&lt;br /&gt;
*** [[:es:LPE_Instrucciones_Instalacion|LPE Asientos de Amarre]]&lt;br /&gt;
** LPE Archivos base&lt;br /&gt;
*** [https://drive.google.com/file/d/0B49a4FHc8nJSTUVaY2hjMWt4bzQ/edit?usp=sharing  Geografia de Perú]&lt;br /&gt;
*** [https://drive.google.com/file/d/0B49a4FHc8nJSQ0lFYWp5aDRZSGM/edit?usp=sharing  Plan Contable Empresarial Perú]&lt;br /&gt;
&lt;br /&gt;
== Brasil ==&lt;br /&gt;
&lt;br /&gt;
* '''Maintainer:''' [[User:Alan.lesc1|Alan Lescano]]&lt;br /&gt;
* '''Status:''' on the road to 1.0&lt;br /&gt;
* '''Source-code URL:''' [https://bitbucket.org/idempierelbr/idempierelbr https://bitbucket.org/idempierelbr/idempierelbr]&lt;br /&gt;
** Plugin&lt;br /&gt;
*** [[Plugin:_LBR_Localization_Brazil|LBR Localization Brazil]]&lt;br /&gt;
&lt;br /&gt;
== España ==&lt;br /&gt;
* '''Maintainer:''' [[User:Efekto2k|Efekto 2k]] -- - [http://www.tecnoxp.com TecnoXperience]&lt;br /&gt;
* '''Last Update:''' November 14, 2014&lt;br /&gt;
** ''' Translation: ''' on November 18, 70%&lt;br /&gt;
*** '''Status:''' Preparing to Up to date with release 2.0 &lt;br /&gt;
*** '''Source Code:''' https://bitbucket.org/tecnoxperience/idempiere_spanish_location (Not finished yet)&lt;br /&gt;
*** '''Download URL:''' https://bitbucket.org/tecnoxperience/idempiere_spanish_location (Not finished yet)&lt;br /&gt;
** ''' Account Schema ''' &lt;br /&gt;
*** '''Status:''' Prepared to Up to date with release 2.0 &lt;br /&gt;
*** '''Source Code:''' https://bitbucket.org/tecnoxperience/idempiere_spanish_location/src/40150d344aeff94650d04c9626307acc4e1da844/PLAN%20CONTABLE%20ESPA%C3%91A.csv?at=default&lt;br /&gt;
*** '''Download URL:''' https://bitbucket.org/tecnoxperience/idempiere_spanish_location/src/40150d344aeff94650d04c9626307acc4e1da844/PLAN%20CONTABLE%20ESPA%C3%91A.csv?at=default&lt;br /&gt;
** ''' Spanish Regions ''' Already on trunk&lt;br /&gt;
** ''' Standar Account Reports ''' on November 18, 30%&lt;br /&gt;
*** ''' Pérdidas y Ganancias '''&lt;br /&gt;
*** ''' Balance de Situación '''&lt;br /&gt;
*** ''' IVA '''&lt;br /&gt;
*** ''' Diario del Mayor '''&lt;br /&gt;
&lt;br /&gt;
== Việt Nam ==&lt;br /&gt;
* '''Maintainer:''' [[User:hieplq|Hiêp Lê Quý]]&lt;br /&gt;
* '''Download URL:''' [https://bitbucket.org/hieplq/vn.hsv.vietnam.localization Bitbucket]&lt;br /&gt;
** Tiếng việt vi_vn&lt;br /&gt;
*** '''Status:''' not yet complete, very bad translate ([https://translations.launchpad.net/idempiere-vi-vn online maintain])&lt;br /&gt;
*** '''Data:''' folder /language&lt;br /&gt;
*** '''Guideline:''' /language/step make translate to launchpad.txt&lt;br /&gt;
** ''' Account Schema '''  maintain file from age of adempiere&lt;br /&gt;
*** '''Data:''' /accounting/AccountingVN-COA-QD15-VN.csv&lt;br /&gt;
** ''' Việt Name city list ''' List Việt Nam city with name, post code, phone code&lt;br /&gt;
*** '''Data:''' use import csv to import file /city/VietNam_C_City.csv or run sql in /city/[database name]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Japan ==&lt;br /&gt;
[[Image:JPiere-tate.png |200px|right|JPiere]]&lt;br /&gt;
* '''Creator:''' [[User:Hideaki_Hagiwara|Hagiwara Hideaki]] in JAPAN (I'm sorry for my poor English. Please modify correctly if my English expressions are mistaken.)&lt;br /&gt;
* '''SPONSOR:''' [http://www.oss-erp.co.jp/ OSS ERP Solutions] in JAPAN&lt;br /&gt;
* '''Source:''' [https://bitbucket.org/jpiere/  Bitbucket JPiere repository] &lt;br /&gt;
* '''More info(Japanese):'''[[:Plugin: Localization Japan|Plugin Localization Japan]]&lt;br /&gt;
* '''More info(Japanese):'''[http://www.compiere-distribution-lab.net/jpiere-lab/ JPiere Lab] &lt;br /&gt;
&lt;br /&gt;
== Nicaragua ==&lt;br /&gt;
&lt;br /&gt;
[[Image:SAC.jpg|right|160px]]&lt;br /&gt;
* '''Maintainer:''' [[User:CésarBaldelomar|César Baldelomar]] , [[User:obenavidez|Osmar Benavidez]] - [http://processus-erp.blogspot.com/ Soluciones Ágiles y Confiables]&lt;br /&gt;
* '''Last Update:''' Octubre 05, 2016&lt;br /&gt;
* '''Status:''' Up to date with release 3.1&lt;br /&gt;
* '''Download URL:''' [https://bitbucket.org/CesarBaldelomar/lco_nicaragua/downloads]&lt;br /&gt;
** Plugins&lt;br /&gt;
*** Retenciones&lt;br /&gt;
*** Detalles&lt;br /&gt;
*** LCO_Retenciones&lt;br /&gt;
*** [[Plugin:Notifications |Notificaciones]]&lt;br /&gt;
** Datos&lt;br /&gt;
*** Geografía Departamento - Municipios&lt;br /&gt;
*** Elemento Contable&lt;br /&gt;
** Lenguage es_NI&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:User Manual]]&lt;br /&gt;
[[Category:Setup]]&lt;br /&gt;
[[Category:System administration]]&lt;br /&gt;
[[Category:Localisation]]&lt;br /&gt;
[[Category:Translation]]&lt;/div&gt;</summary>
		<author><name>Tioraul</name></author>
	</entry>
	<entry>
		<id>https://wiki.idempiere.org/w-en/index.php?title=Geografia_Chile:_LCL_Geografia&amp;diff=14528</id>
		<title>Geografia Chile: LCL Geografia</title>
		<link rel="alternate" type="text/html" href="https://wiki.idempiere.org/w-en/index.php?title=Geografia_Chile:_LCL_Geografia&amp;diff=14528"/>
		<updated>2019-03-03T21:01:40Z</updated>

		<summary type="html">&lt;p&gt;Tioraul: Instalacion Packin Geografia Chile&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== INSTALAR GEOGRAFIA DE CHILE ==&lt;br /&gt;
&lt;br /&gt;
Descargue el paquete PaisChile.zip https://sourceforge.net/projects/adempierechile/files/PaisChile.zip/download&lt;br /&gt;
&lt;br /&gt;
Ingrese en Idempiere con usuario SuperUser y Cliente System, en el Menu seleccione Pack In:&lt;br /&gt;
Dele un nombre al nuevo Pack In.&lt;br /&gt;
Adjunte (presione el icono de clip) el arichivo zip recien bajado.&lt;br /&gt;
Luego Ok (el icono de ticket verde)&lt;br /&gt;
Presione el boton PackIn&lt;br /&gt;
&lt;br /&gt;
Se demora algunos segundos y ya está la base de datos poblada con toda la geografía de Chile.&lt;br /&gt;
&lt;br /&gt;
En el Menu seleccione Country Region and City&lt;br /&gt;
Busque Chile&lt;br /&gt;
Active casillero Country Has Region&lt;br /&gt;
&lt;br /&gt;
Adecuar la secuencia de captura (Capture Sequence) para que considere Region: &lt;br /&gt;
@CO@, @R@, @C@ @A1@ @A2@ @P@&lt;br /&gt;
&lt;br /&gt;
[https://youtu.be/_PQBpt_KINg Video Instalación Geografía Chile]&lt;/div&gt;</summary>
		<author><name>Tioraul</name></author>
	</entry>
	<entry>
		<id>https://wiki.idempiere.org/w-en/index.php?title=Hackers_Guide_to_Documents&amp;diff=14314</id>
		<title>Hackers Guide to Documents</title>
		<link rel="alternate" type="text/html" href="https://wiki.idempiere.org/w-en/index.php?title=Hackers_Guide_to_Documents&amp;diff=14314"/>
		<updated>2018-07-28T18:23:41Z</updated>

		<summary type="html">&lt;p&gt;Tioraul: google translate&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Modes of document characteristics =&lt;br /&gt;
&lt;br /&gt;
== Document number ==&lt;br /&gt;
&lt;br /&gt;
If a table has a column with the title DocumentNo, it will be treated automatically in a special way. In the first usage of the table a sequence will be installed, which takes care of a consecutively document numeration. This document number can be edited more precisly in [[Belegnummernkreis (Fenster_ID-112)]]. It can be set as a determinded initial value or it can preserve a prefix or a suffix. Document numbers can also have a context variable where a date can be fit, e.g.Rechnung 00001/2014&amp;quot; (s.e.g. [[:en:NF001_Document_Sequence_Improved]]).&lt;br /&gt;
&lt;br /&gt;
== Model ==&lt;br /&gt;
&lt;br /&gt;
For a document type, which implements its own logic, you need to write a model. This means you create its own plugin, where you write a java class, the so-called model class (M*). This has to be derived from a predeterminded basis class (X_*). In turn this will be created with the help of the tool [[GenerateModel]] from the table definition of the data bank.&lt;br /&gt;
&lt;br /&gt;
=== Columns ===&lt;br /&gt;
&lt;br /&gt;
For the best you setup these following columns:&lt;br /&gt;
&lt;br /&gt;
* DocumentNo (mandatory; 30 character)&lt;br /&gt;
* DateDoc (mandatory)&lt;br /&gt;
* DateAcct (mandatory)&lt;br /&gt;
* Doc_User_ID (either a column or a getter-methode, which reads out a column like SalesRep_ID or standard logic, e.g. '@$C_Currency_ID@').&lt;br /&gt;
* C_Currency_ID (mandatory; standard logic e.g. &amp;quot;@$C_Currency_ID@')&lt;br /&gt;
* DocAction (mandatory; 2 characters; default 'CO'; pushbutton; reference &amp;quot;_Document Action&amp;quot;; here will be a process indicated, which indicates the according workflow of our document type)&lt;br /&gt;
* DocStatus (mandatory; 2 characters; default 'DR'; list reference; reference &amp;quot;_Document Status&amp;quot; )&lt;br /&gt;
* processed (mandatory; default 'N')&lt;br /&gt;
* processing (mandatory; default 'N') - after Dantam's article is a varchar(1), supposely the pushbutton. For example in C_Invoice is the same process inscribed like in DocAction. But until now I have no idea why you need two columns.&lt;br /&gt;
* isApproved (mandatory; default 'Y')&lt;br /&gt;
&lt;br /&gt;
=== What does DocumentEngine do in the process? ===&lt;br /&gt;
&lt;br /&gt;
Document actions will be done by the class DocEngine. Who wants to conduct a status operation, can do this best with the odel-method processIt(). This should invoke the accordingly method of DocEngine, which takes over the management of different status possibilties.&lt;br /&gt;
&lt;br /&gt;
* http://www.adempiere.com/Document_Engine - u.a. links to Sourcecode of Doc_* classes&lt;br /&gt;
* http://www.adempiere.com/Development_Guidelines_in_German#Klasse_DocumentEngine - german introduction, written quite well&lt;br /&gt;
&lt;br /&gt;
== Workflow ==&lt;br /&gt;
&lt;br /&gt;
You can install a receipt-Workflow which defines the change between several status values. You define a Workflow with three nodes: Start, Prepare and Complete. The two last ones will be combined with the last receipt action, therewith these take action. Then you definde a transition which in each case from Start to Prepare and from Prepare to Complete.&lt;br /&gt;
&lt;br /&gt;
This defined Workflow provides for properly done documents. It serves for further experiments.&lt;br /&gt;
&lt;br /&gt;
=== Reversing documents ===&lt;br /&gt;
&lt;br /&gt;
Who wants to reverse documents, requires these following columns in addition:&lt;br /&gt;
&lt;br /&gt;
* Reversal_ID (reference type table, as a reference you need to register new created table reference, which close about my whole table and can be assorted after DocumentNo)&lt;br /&gt;
&lt;br /&gt;
I never tried this reversal. Probably you need to configure an accordingly Workflow. Besides this you should be very careful, if you want to reverse booked documents.&lt;br /&gt;
&lt;br /&gt;
=== Reactivating Documents ===&lt;br /&gt;
&lt;br /&gt;
I would like to reactivate my document, after it is finalizied. In addition I created a further node 'Reactivate' and attached this with the accordingly receipt action. Then I definded a second transition with the start to Reactivate. The first transition has a condition, which only takes action, if 'Doc-Action = 'CO''. Besides this the first transition obtains a small order of numbers, which executes first.&lt;br /&gt;
&lt;br /&gt;
As a matter of principle the reactivating requires a reversal of the effects of the document. This implementation is not needed, but I recommend you this.&lt;br /&gt;
&lt;br /&gt;
=== Approval / release ===&lt;br /&gt;
&lt;br /&gt;
Workflows also allow to make the processing of a document dependent on a previous release. Thus, e.g. Invoices over 1.000, - € are always submitted to the superior or the like.&lt;br /&gt;
&lt;br /&gt;
* http://www.adempiere.com/How_to_Activate_Document_Approval_Workflow&lt;br /&gt;
&lt;br /&gt;
=== More about Workflows ===&lt;br /&gt;
&lt;br /&gt;
taken from http://en.wikiversity.org/wiki/Adempiere_Technical_Training#Document_Process_Workflow:&lt;br /&gt;
&lt;br /&gt;
Every document has a defined process – the workflow is started with the Process button:&amp;lt;br /&amp;gt;&lt;br /&gt;
These workflows have a defined start context (the document) and a responsible.&lt;br /&gt;
* Start (Draft)&lt;br /&gt;
** Auto&lt;br /&gt;
** Prepare (In Progress)&lt;br /&gt;
*** Complete (Completed)&lt;br /&gt;
&lt;br /&gt;
If you want to customize a workflow for a document:&amp;lt;br /&amp;gt;&lt;br /&gt;
* for all clients&lt;br /&gt;
** add customized node/transitions and/or inactivate standard transitions&lt;br /&gt;
* for a client or organization&lt;br /&gt;
** make changes on System workflow with entity type &amp;lt;&amp;gt; Dictionary/Adempiere&lt;br /&gt;
** execute process “Workflow to Client”&lt;br /&gt;
&lt;br /&gt;
== Booking Document ==&lt;br /&gt;
&lt;br /&gt;
A document that can generate its own posting lines must contain the following fields:&lt;br /&gt;
&lt;br /&gt;
* Posted (mandatory; boolean; default 'N')&lt;br /&gt;
* ProcessedOn (integer)&lt;br /&gt;
* C_DocType_ID (mandatory; Table; reference C_DocType)&lt;br /&gt;
&lt;br /&gt;
The corresponding logic is activated by the presence of the &amp;quot;Posted&amp;quot; field. In this case, after completing a document, an update class matching the model is used to carry out the update. For this there is the convention that this ends on &amp;quot;_Doc&amp;quot;. Within the iDempiere kernel, the name of this class (based on this convention) is automatically determined. In ADempiere this was also the case for own classes. In iDempiere, which no longer allows core access to our plugin classes through the OSGi packages, there is a factory for that purpose.&lt;br /&gt;
&lt;br /&gt;
== Document base type ==&lt;br /&gt;
&lt;br /&gt;
Our new document type must also have an entry in the database. However, we first have to think about which basic type he belongs to. This base type is used for sorting and grouping document types, in particular for the document type input fields. In addition, the period can be opened or closed in the period control (in the calendar) for each individual basic document category. Although, interestingly enough, it is not necessarily mandatory, it still makes sense to set up a document base type for your own accounting document class.&lt;br /&gt;
&lt;br /&gt;
The base document type consists of an entry in the reference list &amp;quot;C_DocType DocBaseType&amp;quot; and always has three letters. If you want, you can set up a type &amp;quot;DOC&amp;quot; for all your documents here. However, it makes more sense to create your own basic types for each document type you create. Then, a selection field in the window can be validated to filter for this basic type and the user will always be able to generate their own derivations later.&lt;br /&gt;
&lt;br /&gt;
For some base types of the standard iDempiere, multiple base types work with objects of the same table. For example, by splitting &amp;quot;API Accounts Payable Invoice&amp;quot; and &amp;quot;ARI Accounts Receivable Invoice&amp;quot; ensures that incoming and outgoing invoices are never mixed. Although both are in the same table and use much the same business logic, they each have their own windows and are also distinguished by the field &amp;quot;isSOTrx&amp;quot; (and the different base document type). Due to the two basic document types, a simple validation on the input field for the document type is enough, so that you can only select sales document types for customers and vice versa.&lt;br /&gt;
&lt;br /&gt;
After you have created the basic document categories (in the system client), you should now call the process &amp;quot;Check Document Types&amp;quot; in the client. This creates a document type for each base document type and also directly creates corresponding period entries in the calendar.&lt;br /&gt;
&lt;br /&gt;
The automatically generated document types can be viewed in the &amp;quot;Document type&amp;quot; window and adjusted if necessary. It is recommended to activate number management and specify (or create) a document number range.&lt;br /&gt;
&lt;br /&gt;
In this window you can now derive even more document types from its basic document category. This has different purposes:&lt;br /&gt;
&lt;br /&gt;
* First of all, this can serve the in-house grouping of documents. Anyone who thinks in his business that a bill of goods is different from a service bill and a foreign bill, in turn, differently and a freight bill, can divide this so without much trouble.&lt;br /&gt;
* You can specify your own print format (in this window) and make the printed receipt look very different.&lt;br /&gt;
* You can group direct bookings (batches) using the direct posting type (fee type depending on the translation) and only allow specific bookings for certain document types. Thus, the freight invoice can be posted to the account for freight, the foreign invoice to the account for customs, etc.&lt;br /&gt;
&lt;br /&gt;
Next, you should create a validation rule. This gets the name &amp;quot;C_DocType MyPatementName&amp;quot; and as SQL-Code something like the following line:&lt;br /&gt;
&lt;br /&gt;
  C_DocType.DocBaseType IN ('ARZ', 'APZ') AND C_DocType.IsSOTrx='@IsSOTrx@'  AND C_DocType.AD_Client_ID=@#AD_Client_ID@&lt;br /&gt;
&lt;br /&gt;
Of course, you can omit the part with IsSOTrx if we do not have a separate document type for input and output windows. This part of the formula ensures that we can use identical field definitions for incoming and outgoing documents. The two windows then differ only in that the context variable &amp;quot;IsSOTrx&amp;quot; is set when the window is opened. This will then control everything else. This value can be set in the window definition.&lt;br /&gt;
&lt;br /&gt;
== Purchase and sales documents ==&lt;br /&gt;
&lt;br /&gt;
If you have a document category that is supposed to post different purchasing and sales documents (AP and AR), you also need this field. With this type of document, it is generally appropriate to also generate two separate basic document types and possibly two separate windows. The window definitions can be largely identical except for the &amp;quot;Sales Transaction&amp;quot; entry, which sets the context variable &amp;quot;IsSOTrx&amp;quot; and thus makes it distinguishable.&lt;br /&gt;
&lt;br /&gt;
* isSOTrx (mandatory; boolean, in the window best not displayed nciht or at least write-protected)&lt;br /&gt;
&lt;br /&gt;
== Windows, tabs &amp;amp; fields ==&lt;br /&gt;
&lt;br /&gt;
The window should be set to the window type &amp;quot;Transaction&amp;quot;. This turns on [[http://www.adempiere.com/History History]]. This ensures that only the current and incomplete documents are displayed.&lt;br /&gt;
&lt;br /&gt;
Incidentally, when configuring the window, the following fields should be displayed (according to Dantam):&lt;br /&gt;
&lt;br /&gt;
* Processed (set to &amp;quot;Read Only&amp;quot;)&lt;br /&gt;
* DocStatus (set to &amp;quot;Read Only&amp;quot;)&lt;br /&gt;
* DocAction&lt;br /&gt;
* Currency (if used, it may be read-only)&lt;br /&gt;
&lt;br /&gt;
For documents that differentiate purchasing and sales documents, it makes sense to copy them and introduce a WHERE clause, so that you have two windows for these actually different document types. You can define a window as a sales transaction in the window definition, and thus set a context variable that is used in many queries and validations to ensure that all fields work properly. Of course, this requires some care in generating your own queries, but there are enough existing examples, such &amp;quot;Invoice (Customer)&amp;quot; and &amp;quot;Invoice (Supplier)&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Print ==&lt;br /&gt;
&lt;br /&gt;
Basically, you can print a record by clicking on the button in the toolbar for a report. This will then create a print format that you can adjust accordingly. If you often want to have individual data sets, for example As a form print as a list of sentences, so it is useful to activate the print button, with which you can print individual records. This is done by making an entry in the Process &amp;amp; Report window. This was set to &amp;quot;Report&amp;quot; and indicates, if necessary, a prepared print format. This can then be started with the buttons for &amp;quot;Print&amp;quot; and &amp;quot;Print preview&amp;quot; by entering it in the window register record.&lt;br /&gt;
&lt;br /&gt;
By the way, there is a little problem here. You have to set up the &amp;quot;Process &amp;amp; Report&amp;quot; window in the system client, whereas most of the time you have prepared your print format in the normal client. You can release the print format in this case. It is automatically selected the one that has set the field &amp;quot;Standard&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
=== Use Report View to print more columns than shown in the table ===&lt;br /&gt;
&lt;br /&gt;
An extension can be added by entering a similar entry in the field &amp;quot;Report view&amp;quot; in &amp;quot;Process &amp;amp; Report&amp;quot;. In this case, a print format is selected that has selected this report view. This allows you to narrow the selection of the print format even further.&lt;br /&gt;
&lt;br /&gt;
In particular, one can also specify a report view based on a completely different table. This table should only contain the primary key field of our document because it will filter out the printed record. I used this, for example, to use a database view instead of the table edited in the current window for the expression, which, while based on that same table, adds a lot of additional data via JOIN. This large amount of information can then be restricted (if you like) through a report view and then processed in print format. Such a print format is created in the window &amp;quot;Print format&amp;quot;, where you can set the table and the view when creating the record. Then you create the fields by means of the automatic process button for this purpose and can then set the print format already in the target window and use it there in the print view. If this is the first time to see, then you can customize it as usual resulting print formats.&lt;br /&gt;
&lt;br /&gt;
=== Print by program ===&lt;br /&gt;
&lt;br /&gt;
In my model for the BAY_InterestCalculation table, I can use the following method to get an expression based on a view called RV_BAY_InterestCalculation. One can use this method e.g. in completeIt () to make sure that a document is always printed when it completes. Incidentally, one can set in the process window whether the printout happens immediately in the background or only with consultation.&lt;br /&gt;
&lt;br /&gt;
  public void print() {&lt;br /&gt;
    int viewTable = MTable.getTable_ID(&amp;quot;RV_&amp;quot; + Table_Name);&lt;br /&gt;
    MPrintFormat format = new Query(getCtx(), MPrintFormat.Table_Name, MPrintFormat.COLUMNNAME_AD_Table_ID&lt;br /&gt;
      + &amp;quot;=? AND &amp;quot; + MPrintFormat.COLUMNNAME_IsDefault + &amp;quot;=? &amp;quot;, get_TrxName()).setParameters(viewTable, &amp;quot;Y&amp;quot;)&lt;br /&gt;
      .first();&lt;br /&gt;
    MQuery query = new MQuery(get_Table_ID());&lt;br /&gt;
    query.addRestriction(get_KeyColumns()[0], MQuery.EQUAL, get_ID());&lt;br /&gt;
    PrintInfo info = new PrintInfo(getDocumentInfo(), get_Table_ID(), get_ID());&lt;br /&gt;
    ReportEngine re = new ReportEngine(getCtx(), format, query, info, get_TrxName());&lt;br /&gt;
    re.print();&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
= Links =&lt;br /&gt;
&lt;br /&gt;
== Articles that explain documents ==&lt;br /&gt;
&lt;br /&gt;
Basic statements&lt;br /&gt;
&lt;br /&gt;
* http://wiki.idempiere.org/en/Create_a_custom_document_class - quite new article by Daniel Tamm in the iDempiere Wiki, still has many gaps&lt;br /&gt;
* http://www.adempiere.com/How_to_create_a_new_document_with_specific_accounting&lt;br /&gt;
&lt;br /&gt;
Further explanations&lt;br /&gt;
&lt;br /&gt;
* http://www.adempiere.com/How_to_Activate_Document_Approval_Workflow&lt;br /&gt;
* http://www.adempiere.com/Document_Action_Dialog - Explanation of the action button and the window that opens up&lt;br /&gt;
* http://www.adempiere.com/Document_Sequence - Document Sequence&lt;br /&gt;
* Extensions&lt;br /&gt;
** http://www.adempiere.com/Enhance_Document_No_Formatting - Improvement of document numbering (this allows context variables)&lt;br /&gt;
** http://wiki.idempiere.org/en/NF001_Document_Sequence_Improved - Improvement of organizations and restart of number ranges&lt;br /&gt;
** http://www.adempiere.com/Sponsored_Development:_Document_Signing - Document Signing Extension, evidently never realized&lt;br /&gt;
&lt;br /&gt;
Articles that I use as sources, but have already incorporated much here:&lt;br /&gt;
&lt;br /&gt;
* http://www.adempiere.com/HOWTO_Process_Documents - quite well explains the use of existing document types; less the development of new ones&lt;br /&gt;
* http://en.wikiversity.org/wiki/Adempiere_Technical_Training#Document_Process_Workflow - contains short but insightful parts on the topic, in particular &amp;quot;Document Process Workflow&amp;quot;&lt;br /&gt;
* http://www.adempiere.com/Document_Engine&lt;br /&gt;
* https://groups.google.com/forum/#!topic/idempiere/WtTlVL1ZjWw - Briefed forum thread about how to implement a workflow&lt;br /&gt;
&lt;br /&gt;
Windows related to documents:&lt;br /&gt;
&lt;br /&gt;
* http://wiki.idempiere.org/en/Document_Type_%28Window_ID-135%29&lt;br /&gt;
* http://wiki.idempiere.org/en/Document_Sequence_%28Window_ID-112%29&lt;br /&gt;
&lt;br /&gt;
* http://wiki.idempiere.org/en/Unprocessed_Documents_%28All%29_%28Window_ID-53087%29&lt;br /&gt;
* http://wiki.idempiere.org/en/UnPosted_Documents_%28Window_ID-294%29&lt;br /&gt;
* http://wiki.idempiere.org/en/My_Unprocessed_Documents_%28Window_ID-53086%29&lt;br /&gt;
* http://wiki.idempiere.org/de/Workflow_%28Fenster_ID-113%29&lt;br /&gt;
&lt;br /&gt;
(What is the difference between &amp;quot;unprocessed&amp;quot; and &amp;quot;unposted&amp;quot; and how do these windows know which tables to scan?)&lt;br /&gt;
&lt;br /&gt;
* http://wiki.idempiere.org/en/Verify_Document_Types_%28Process_ID-233%29 - what does this process do? He probably creates open entries for new document types. Is there anything else?&lt;br /&gt;
&lt;br /&gt;
= Further information =&lt;br /&gt;
&lt;br /&gt;
== involved classes and interfaces ==&lt;br /&gt;
&lt;br /&gt;
=== MSetup ===&lt;br /&gt;
&lt;br /&gt;
Create the list of document type for new Client ( Method createAccounting ). &lt;br /&gt;
&lt;br /&gt;
=== org.compiere.server.AcctProcessor ===&lt;br /&gt;
&lt;br /&gt;
Background process running on the JBoss server that perform the accounting document posting process. &lt;br /&gt;
&lt;br /&gt;
=== org.compiere.grid.ed.VDocAction ===&lt;br /&gt;
&lt;br /&gt;
Define hardcoded in dynInit method the list of possible transitions, and transitions by table&lt;br /&gt;
&lt;br /&gt;
= Examples of implementing some DocAction methods =&lt;br /&gt;
&lt;br /&gt;
=== getDocumentInfo() ===&lt;br /&gt;
&lt;br /&gt;
Returns a short but unique name of the record, which is mainly used in log lines and other program messages. This example uses an existing document type.&lt;br /&gt;
&lt;br /&gt;
  public String getDocumentInfo(){&lt;br /&gt;
    MDocType dt = MDocType.get(getCtx(), getC_DocType_ID());&lt;br /&gt;
    String msgreturn = dt.getNameTrl()+&amp;quot; &amp;quot;+getDocumentNo();&lt;br /&gt;
    return msgreturn.toString();&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
=== createPDF() ===&lt;br /&gt;
&lt;br /&gt;
There is a method to output the document as a PDF. This will - as far as I've seen - only used to send the document by email. But because you never know, you can do that, e.g. as follows. Of course you can also choose more precisely when selecting the print format.&lt;br /&gt;
&lt;br /&gt;
  public File createPDF (){&lt;br /&gt;
    try{&lt;br /&gt;
      StringBuilder msgfile = new StringBuilder().append(get_TableName()).append(get_ID()).append(&amp;quot;_&amp;quot;);&lt;br /&gt;
      File temp = File.createTempFile(msgfile.toString(), &amp;quot;.pdf&amp;quot;);&lt;br /&gt;
      return createPDF (temp);&lt;br /&gt;
    }catch (Exception e){&lt;br /&gt;
      log.severe(&amp;quot;Could not create PDF - &amp;quot; + e.getMessage());&lt;br /&gt;
    }&lt;br /&gt;
    return null;&lt;br /&gt;
  }&lt;br /&gt;
  &lt;br /&gt;
  public File createPDF (File file){&lt;br /&gt;
    MPrintFormat format = MPrintFormat.get(getCtx(), 0, get_Table_ID());&lt;br /&gt;
    MQuery query=new MQuery(get_Table_ID());&lt;br /&gt;
    query.addRestriction(get_KeyColumns()[0],MQuery.EQUAL,get_ID());&lt;br /&gt;
    PrintInfo info = new PrintInfo(getDocumentNo(),get_Table_ID(),0);&lt;br /&gt;
    ReportEngine re = new ReportEngine(getCtx(), format, query, info, get_TrxName());&lt;br /&gt;
    &lt;br /&gt;
    if(format.getJasperProcess_ID() &amp;gt; 0){&lt;br /&gt;
      // JasperReports Print Format&lt;br /&gt;
      ProcessInfo pi = new ProcessInfo (&amp;quot;&amp;quot;, format.getJasperProcess_ID());&lt;br /&gt;
      pi.setRecord_ID(get_ID());&lt;br /&gt;
      pi.setIsBatch(true);&lt;br /&gt;
      ServerProcessCtl.process(pi, null);&lt;br /&gt;
      return pi.getPDFReport();&lt;br /&gt;
    }else{&lt;br /&gt;
      // Standard Print Format (Non-Jasper)&lt;br /&gt;
      return re.getPDF(file);&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Development‏‎]]&lt;br /&gt;
[[Category:Developer documentation‏‎]]&lt;br /&gt;
[[Category:System administration‏‎]]&lt;br /&gt;
[[Category:Applying means‏‎]]&lt;br /&gt;
[[Category:Document‎]]&lt;br /&gt;
[[Category:Workflow]]&lt;/div&gt;</summary>
		<author><name>Tioraul</name></author>
	</entry>
	<entry>
		<id>https://wiki.idempiere.org/w-en/index.php?title=Hackers_Guide_to_Documents&amp;diff=14313</id>
		<title>Hackers Guide to Documents</title>
		<link rel="alternate" type="text/html" href="https://wiki.idempiere.org/w-en/index.php?title=Hackers_Guide_to_Documents&amp;diff=14313"/>
		<updated>2018-07-28T18:21:48Z</updated>

		<summary type="html">&lt;p&gt;Tioraul: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Modes of document characteristics =&lt;br /&gt;
&lt;br /&gt;
== Document number ==&lt;br /&gt;
&lt;br /&gt;
If a table has a column with the title DocumentNo, it will be treated automatically in a special way. In the first usage of the table a sequence will be installed, which takes care of a consecutively document numeration. This document number can be edited more precisly in [[Belegnummernkreis (Fenster_ID-112)]]. It can be set as a determinded initial value or it can preserve a prefix or a suffix. Document numbers can also have a context variable where a date can be fit, e.g.Rechnung 00001/2014&amp;quot; (s.e.g. [[:en:NF001_Document_Sequence_Improved]]).&lt;br /&gt;
&lt;br /&gt;
== Model ==&lt;br /&gt;
&lt;br /&gt;
For a document type, which implements its own logic, you need to write a model. This means you create its own plugin, where you write a java class, the so-called model class (M*). This has to be derived from a predeterminded basis class (X_*). In turn this will be created with the help of the tool [[GenerateModel]] from the table definition of the data bank.&lt;br /&gt;
&lt;br /&gt;
=== Columns ===&lt;br /&gt;
&lt;br /&gt;
For the best you setup these following columns:&lt;br /&gt;
&lt;br /&gt;
* DocumentNo (mandatory; 30 character)&lt;br /&gt;
* DateDoc (mandatory)&lt;br /&gt;
* DateAcct (mandatory)&lt;br /&gt;
* Doc_User_ID (either a column or a getter-methode, which reads out a column like SalesRep_ID or standard logic, e.g. '@$C_Currency_ID@').&lt;br /&gt;
* C_Currency_ID (mandatory; standard logic e.g. &amp;quot;@$C_Currency_ID@')&lt;br /&gt;
* DocAction (mandatory; 2 characters; default 'CO'; pushbutton; reference &amp;quot;_Document Action&amp;quot;; here will be a process indicated, which indicates the according workflow of our document type)&lt;br /&gt;
* DocStatus (mandatory; 2 characters; default 'DR'; list reference; reference &amp;quot;_Document Status&amp;quot; )&lt;br /&gt;
* processed (mandatory; default 'N')&lt;br /&gt;
* processing (mandatory; default 'N') - after Dantam's article is a varchar(1), supposely the pushbutton. For example in C_Invoice is the same process inscribed like in DocAction. But until now I have no idea why you need two columns.&lt;br /&gt;
* isApproved (mandatory; default 'Y')&lt;br /&gt;
&lt;br /&gt;
=== What does DocumentEngine do in the process? ===&lt;br /&gt;
&lt;br /&gt;
Document actions will be done by the class DocEngine. Who wants to conduct a status operation, can do this best with the odel-method processIt(). This should invoke the accordingly method of DocEngine, which takes over the management of different status possibilties.&lt;br /&gt;
&lt;br /&gt;
* http://www.adempiere.com/Document_Engine - u.a. links to Sourcecode of Doc_* classes&lt;br /&gt;
* http://www.adempiere.com/Development_Guidelines_in_German#Klasse_DocumentEngine - german introduction, written quite well&lt;br /&gt;
&lt;br /&gt;
== Workflow ==&lt;br /&gt;
&lt;br /&gt;
You can install a receipt-Workflow which defines the change between several status values. You define a Workflow with three nodes: Start, Prepare and Complete. The two last ones will be combined with the last receipt action, therewith these take action. Then you definde a transition which in each case from Start to Prepare and from Prepare to Complete.&lt;br /&gt;
&lt;br /&gt;
This defined Workflow provides for properly done documents. It serves for further experiments.&lt;br /&gt;
&lt;br /&gt;
=== Reversing documents ===&lt;br /&gt;
&lt;br /&gt;
Who wants to reverse documents, requires these following columns in addition:&lt;br /&gt;
&lt;br /&gt;
* Reversal_ID (reference type table, as a reference you need to register new created table reference, which close about my whole table and can be assorted after DocumentNo)&lt;br /&gt;
&lt;br /&gt;
I never tried this reversal. Probably you need to configure an accordingly Workflow. Besides this you should be very careful, if you want to reverse booked documents.&lt;br /&gt;
&lt;br /&gt;
=== Reactivating Documents ===&lt;br /&gt;
&lt;br /&gt;
I would like to reactivate my document, after it is finalizied. In addition I created a further node 'Reactivate' and attached this with the accordingly receipt action. Then I definded a second transition with the start to Reactivate. The first transition has a condition, which only takes action, if 'Doc-Action = 'CO''. Besides this the first transition obtains a small order of numbers, which executes first.&lt;br /&gt;
&lt;br /&gt;
As a matter of principle the reactivating requires a reversal of the effects of the document. This implementation is not needed, but I recommend you this.&lt;br /&gt;
&lt;br /&gt;
=== Approval / Freigabe ===&lt;br /&gt;
&lt;br /&gt;
Workflows erlauben auch, die Bearbeitung eines Dokumentes von einer vorherigen Freigabe abhängig zu machen. So können z.B. Rechnungen über 1.000,- € immer erst dem Vorgesetzten vorgelegt werden oder dergleichen.&lt;br /&gt;
&lt;br /&gt;
* http://www.adempiere.com/How_to_Activate_Document_Approval_Workflow&lt;br /&gt;
&lt;br /&gt;
=== More about Workflows ===&lt;br /&gt;
&lt;br /&gt;
taken from http://en.wikiversity.org/wiki/Adempiere_Technical_Training#Document_Process_Workflow:&lt;br /&gt;
&lt;br /&gt;
Every document has a defined process – the workflow is started with the Process button:&amp;lt;br /&amp;gt;&lt;br /&gt;
These workflows have a defined start context (the document) and a responsible.&lt;br /&gt;
* Start (Draft)&lt;br /&gt;
** Auto&lt;br /&gt;
** Prepare (In Progress)&lt;br /&gt;
*** Complete (Completed)&lt;br /&gt;
&lt;br /&gt;
If you want to customize a workflow for a document:&amp;lt;br /&amp;gt;&lt;br /&gt;
* for all clients&lt;br /&gt;
** add customized node/transitions and/or inactivate standard transitions&lt;br /&gt;
* for a client or organization&lt;br /&gt;
** make changes on System workflow with entity type &amp;lt;&amp;gt; Dictionary/Adempiere&lt;br /&gt;
** execute process “Workflow to Client”&lt;br /&gt;
&lt;br /&gt;
== Booking Document ==&lt;br /&gt;
&lt;br /&gt;
A document that can generate its own posting lines must contain the following fields:&lt;br /&gt;
&lt;br /&gt;
* Posted (mandatory; boolean; default 'N')&lt;br /&gt;
* ProcessedOn (integer)&lt;br /&gt;
* C_DocType_ID (mandatory; Table; reference C_DocType)&lt;br /&gt;
&lt;br /&gt;
The corresponding logic is activated by the presence of the &amp;quot;Posted&amp;quot; field. In this case, after completing a document, an update class matching the model is used to carry out the update. For this there is the convention that this ends on &amp;quot;_Doc&amp;quot;. Within the iDempiere kernel, the name of this class (based on this convention) is automatically determined. In ADempiere this was also the case for own classes. In iDempiere, which no longer allows core access to our plugin classes through the OSGi packages, there is a factory for that purpose.&lt;br /&gt;
&lt;br /&gt;
== Document base type ==&lt;br /&gt;
&lt;br /&gt;
Our new document type must also have an entry in the database. However, we first have to think about which basic type he belongs to. This base type is used for sorting and grouping document types, in particular for the document type input fields. In addition, the period can be opened or closed in the period control (in the calendar) for each individual basic document category. Although, interestingly enough, it is not necessarily mandatory, it still makes sense to set up a document base type for your own accounting document class.&lt;br /&gt;
&lt;br /&gt;
The base document type consists of an entry in the reference list &amp;quot;C_DocType DocBaseType&amp;quot; and always has three letters. If you want, you can set up a type &amp;quot;DOC&amp;quot; for all your documents here. However, it makes more sense to create your own basic types for each document type you create. Then, a selection field in the window can be validated to filter for this basic type and the user will always be able to generate their own derivations later.&lt;br /&gt;
&lt;br /&gt;
For some base types of the standard iDempiere, multiple base types work with objects of the same table. For example, by splitting &amp;quot;API Accounts Payable Invoice&amp;quot; and &amp;quot;ARI Accounts Receivable Invoice&amp;quot; ensures that incoming and outgoing invoices are never mixed. Although both are in the same table and use much the same business logic, they each have their own windows and are also distinguished by the field &amp;quot;isSOTrx&amp;quot; (and the different base document type). Due to the two basic document types, a simple validation on the input field for the document type is enough, so that you can only select sales document types for customers and vice versa.&lt;br /&gt;
&lt;br /&gt;
After you have created the basic document categories (in the system client), you should now call the process &amp;quot;Check Document Types&amp;quot; in the client. This creates a document type for each base document type and also directly creates corresponding period entries in the calendar.&lt;br /&gt;
&lt;br /&gt;
The automatically generated document types can be viewed in the &amp;quot;Document type&amp;quot; window and adjusted if necessary. It is recommended to activate number management and specify (or create) a document number range.&lt;br /&gt;
&lt;br /&gt;
In this window you can now derive even more document types from its basic document category. This has different purposes:&lt;br /&gt;
&lt;br /&gt;
* First of all, this can serve the in-house grouping of documents. Anyone who thinks in his business that a bill of goods is different from a service bill and a foreign bill, in turn, differently and a freight bill, can divide this so without much trouble.&lt;br /&gt;
* You can specify your own print format (in this window) and make the printed receipt look very different.&lt;br /&gt;
* You can group direct bookings (batches) using the direct posting type (fee type depending on the translation) and only allow specific bookings for certain document types. Thus, the freight invoice can be posted to the account for freight, the foreign invoice to the account for customs, etc.&lt;br /&gt;
&lt;br /&gt;
Next, you should create a validation rule. This gets the name &amp;quot;C_DocType MyPatementName&amp;quot; and as SQL-Code something like the following line:&lt;br /&gt;
&lt;br /&gt;
  C_DocType.DocBaseType IN ('ARZ', 'APZ') AND C_DocType.IsSOTrx='@IsSOTrx@'  AND C_DocType.AD_Client_ID=@#AD_Client_ID@&lt;br /&gt;
&lt;br /&gt;
Of course, you can omit the part with IsSOTrx if we do not have a separate document type for input and output windows. This part of the formula ensures that we can use identical field definitions for incoming and outgoing documents. The two windows then differ only in that the context variable &amp;quot;IsSOTrx&amp;quot; is set when the window is opened. This will then control everything else. This value can be set in the window definition.&lt;br /&gt;
&lt;br /&gt;
== Purchase and sales documents ==&lt;br /&gt;
&lt;br /&gt;
If you have a document category that is supposed to post different purchasing and sales documents (AP and AR), you also need this field. With this type of document, it is generally appropriate to also generate two separate basic document types and possibly two separate windows. The window definitions can be largely identical except for the &amp;quot;Sales Transaction&amp;quot; entry, which sets the context variable &amp;quot;IsSOTrx&amp;quot; and thus makes it distinguishable.&lt;br /&gt;
&lt;br /&gt;
* isSOTrx (mandatory; boolean, in the window best not displayed nciht or at least write-protected)&lt;br /&gt;
&lt;br /&gt;
== Windows, tabs &amp;amp; fields ==&lt;br /&gt;
&lt;br /&gt;
The window should be set to the window type &amp;quot;Transaction&amp;quot;. This turns on [[http://www.adempiere.com/History History]]. This ensures that only the current and incomplete documents are displayed.&lt;br /&gt;
&lt;br /&gt;
Incidentally, when configuring the window, the following fields should be displayed (according to Dantam):&lt;br /&gt;
&lt;br /&gt;
* Processed (set to &amp;quot;Read Only&amp;quot;)&lt;br /&gt;
* DocStatus (set to &amp;quot;Read Only&amp;quot;)&lt;br /&gt;
* DocAction&lt;br /&gt;
* Currency (if used, it may be read-only)&lt;br /&gt;
&lt;br /&gt;
For documents that differentiate purchasing and sales documents, it makes sense to copy them and introduce a WHERE clause, so that you have two windows for these actually different document types. You can define a window as a sales transaction in the window definition, and thus set a context variable that is used in many queries and validations to ensure that all fields work properly. Of course, this requires some care in generating your own queries, but there are enough existing examples, such &amp;quot;Invoice (Customer)&amp;quot; and &amp;quot;Invoice (Supplier)&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Print ==&lt;br /&gt;
&lt;br /&gt;
Basically, you can print a record by clicking on the button in the toolbar for a report. This will then create a print format that you can adjust accordingly. If you often want to have individual data sets, for example As a form print as a list of sentences, so it is useful to activate the print button, with which you can print individual records. This is done by making an entry in the Process &amp;amp; Report window. This was set to &amp;quot;Report&amp;quot; and indicates, if necessary, a prepared print format. This can then be started with the buttons for &amp;quot;Print&amp;quot; and &amp;quot;Print preview&amp;quot; by entering it in the window register record.&lt;br /&gt;
&lt;br /&gt;
By the way, there is a little problem here. You have to set up the &amp;quot;Process &amp;amp; Report&amp;quot; window in the system client, whereas most of the time you have prepared your print format in the normal client. You can release the print format in this case. It is automatically selected the one that has set the field &amp;quot;Standard&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
=== Use Report View to print more columns than shown in the table ===&lt;br /&gt;
&lt;br /&gt;
An extension can be added by entering a similar entry in the field &amp;quot;Report view&amp;quot; in &amp;quot;Process &amp;amp; Report&amp;quot;. In this case, a print format is selected that has selected this report view. This allows you to narrow the selection of the print format even further.&lt;br /&gt;
&lt;br /&gt;
In particular, one can also specify a report view based on a completely different table. This table should only contain the primary key field of our document because it will filter out the printed record. I used this, for example, to use a database view instead of the table edited in the current window for the expression, which, while based on that same table, adds a lot of additional data via JOIN. This large amount of information can then be restricted (if you like) through a report view and then processed in print format. Such a print format is created in the window &amp;quot;Print format&amp;quot;, where you can set the table and the view when creating the record. Then you create the fields by means of the automatic process button for this purpose and can then set the print format already in the target window and use it there in the print view. If this is the first time to see, then you can customize it as usual resulting print formats.&lt;br /&gt;
&lt;br /&gt;
=== Print by program ===&lt;br /&gt;
&lt;br /&gt;
In my model for the BAY_InterestCalculation table, I can use the following method to get an expression based on a view called RV_BAY_InterestCalculation. One can use this method e.g. in completeIt () to make sure that a document is always printed when it completes. Incidentally, one can set in the process window whether the printout happens immediately in the background or only with consultation.&lt;br /&gt;
&lt;br /&gt;
  public void print() {&lt;br /&gt;
    int viewTable = MTable.getTable_ID(&amp;quot;RV_&amp;quot; + Table_Name);&lt;br /&gt;
    MPrintFormat format = new Query(getCtx(), MPrintFormat.Table_Name, MPrintFormat.COLUMNNAME_AD_Table_ID&lt;br /&gt;
      + &amp;quot;=? AND &amp;quot; + MPrintFormat.COLUMNNAME_IsDefault + &amp;quot;=? &amp;quot;, get_TrxName()).setParameters(viewTable, &amp;quot;Y&amp;quot;)&lt;br /&gt;
      .first();&lt;br /&gt;
    MQuery query = new MQuery(get_Table_ID());&lt;br /&gt;
    query.addRestriction(get_KeyColumns()[0], MQuery.EQUAL, get_ID());&lt;br /&gt;
    PrintInfo info = new PrintInfo(getDocumentInfo(), get_Table_ID(), get_ID());&lt;br /&gt;
    ReportEngine re = new ReportEngine(getCtx(), format, query, info, get_TrxName());&lt;br /&gt;
    re.print();&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
= Links =&lt;br /&gt;
&lt;br /&gt;
== Articles that explain documents ==&lt;br /&gt;
&lt;br /&gt;
Basic statements&lt;br /&gt;
&lt;br /&gt;
* http://wiki.idempiere.org/en/Create_a_custom_document_class - quite new article by Daniel Tamm in the iDempiere Wiki, still has many gaps&lt;br /&gt;
* http://www.adempiere.com/How_to_create_a_new_document_with_specific_accounting&lt;br /&gt;
&lt;br /&gt;
Further explanations&lt;br /&gt;
&lt;br /&gt;
* http://www.adempiere.com/How_to_Activate_Document_Approval_Workflow&lt;br /&gt;
* http://www.adempiere.com/Document_Action_Dialog - Explanation of the action button and the window that opens up&lt;br /&gt;
* http://www.adempiere.com/Document_Sequence - Document Sequence&lt;br /&gt;
* Extensions&lt;br /&gt;
** http://www.adempiere.com/Enhance_Document_No_Formatting - Improvement of document numbering (this allows context variables)&lt;br /&gt;
** http://wiki.idempiere.org/en/NF001_Document_Sequence_Improved - Improvement of organizations and restart of number ranges&lt;br /&gt;
** http://www.adempiere.com/Sponsored_Development:_Document_Signing - Document Signing Extension, evidently never realized&lt;br /&gt;
&lt;br /&gt;
Articles that I use as sources, but have already incorporated much here:&lt;br /&gt;
&lt;br /&gt;
* http://www.adempiere.com/HOWTO_Process_Documents - quite well explains the use of existing document types; less the development of new ones&lt;br /&gt;
* http://en.wikiversity.org/wiki/Adempiere_Technical_Training#Document_Process_Workflow - contains short but insightful parts on the topic, in particular &amp;quot;Document Process Workflow&amp;quot;&lt;br /&gt;
* http://www.adempiere.com/Document_Engine&lt;br /&gt;
* https://groups.google.com/forum/#!topic/idempiere/WtTlVL1ZjWw - Briefed forum thread about how to implement a workflow&lt;br /&gt;
&lt;br /&gt;
Windows related to documents:&lt;br /&gt;
&lt;br /&gt;
* http://wiki.idempiere.org/en/Document_Type_%28Window_ID-135%29&lt;br /&gt;
* http://wiki.idempiere.org/en/Document_Sequence_%28Window_ID-112%29&lt;br /&gt;
&lt;br /&gt;
* http://wiki.idempiere.org/en/Unprocessed_Documents_%28All%29_%28Window_ID-53087%29&lt;br /&gt;
* http://wiki.idempiere.org/en/UnPosted_Documents_%28Window_ID-294%29&lt;br /&gt;
* http://wiki.idempiere.org/en/My_Unprocessed_Documents_%28Window_ID-53086%29&lt;br /&gt;
* http://wiki.idempiere.org/de/Workflow_%28Fenster_ID-113%29&lt;br /&gt;
&lt;br /&gt;
(What is the difference between &amp;quot;unprocessed&amp;quot; and &amp;quot;unposted&amp;quot; and how do these windows know which tables to scan?)&lt;br /&gt;
&lt;br /&gt;
* http://wiki.idempiere.org/en/Verify_Document_Types_%28Process_ID-233%29 - what does this process do? He probably creates open entries for new document types. Is there anything else?&lt;br /&gt;
&lt;br /&gt;
= Further information =&lt;br /&gt;
&lt;br /&gt;
== involved classes and interfaces ==&lt;br /&gt;
&lt;br /&gt;
=== MSetup ===&lt;br /&gt;
&lt;br /&gt;
Create the list of document type for new Client ( Method createAccounting ). &lt;br /&gt;
&lt;br /&gt;
=== org.compiere.server.AcctProcessor ===&lt;br /&gt;
&lt;br /&gt;
Background process running on the JBoss server that perform the accounting document posting process. &lt;br /&gt;
&lt;br /&gt;
=== org.compiere.grid.ed.VDocAction ===&lt;br /&gt;
&lt;br /&gt;
Define hardcoded in dynInit method the list of possible transitions, and transitions by table&lt;br /&gt;
&lt;br /&gt;
= Examples of implementing some DocAction methods =&lt;br /&gt;
&lt;br /&gt;
=== getDocumentInfo() ===&lt;br /&gt;
&lt;br /&gt;
Returns a short but unique name of the record, which is mainly used in log lines and other program messages. This example uses an existing document type.&lt;br /&gt;
&lt;br /&gt;
  public String getDocumentInfo(){&lt;br /&gt;
    MDocType dt = MDocType.get(getCtx(), getC_DocType_ID());&lt;br /&gt;
    String msgreturn = dt.getNameTrl()+&amp;quot; &amp;quot;+getDocumentNo();&lt;br /&gt;
    return msgreturn.toString();&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
=== createPDF() ===&lt;br /&gt;
&lt;br /&gt;
There is a method to output the document as a PDF. This will - as far as I've seen - only used to send the document by email. But because you never know, you can do that, e.g. as follows. Of course you can also choose more precisely when selecting the print format.&lt;br /&gt;
&lt;br /&gt;
  public File createPDF (){&lt;br /&gt;
    try{&lt;br /&gt;
      StringBuilder msgfile = new StringBuilder().append(get_TableName()).append(get_ID()).append(&amp;quot;_&amp;quot;);&lt;br /&gt;
      File temp = File.createTempFile(msgfile.toString(), &amp;quot;.pdf&amp;quot;);&lt;br /&gt;
      return createPDF (temp);&lt;br /&gt;
    }catch (Exception e){&lt;br /&gt;
      log.severe(&amp;quot;Could not create PDF - &amp;quot; + e.getMessage());&lt;br /&gt;
    }&lt;br /&gt;
    return null;&lt;br /&gt;
  }&lt;br /&gt;
  &lt;br /&gt;
  public File createPDF (File file){&lt;br /&gt;
    MPrintFormat format = MPrintFormat.get(getCtx(), 0, get_Table_ID());&lt;br /&gt;
    MQuery query=new MQuery(get_Table_ID());&lt;br /&gt;
    query.addRestriction(get_KeyColumns()[0],MQuery.EQUAL,get_ID());&lt;br /&gt;
    PrintInfo info = new PrintInfo(getDocumentNo(),get_Table_ID(),0);&lt;br /&gt;
    ReportEngine re = new ReportEngine(getCtx(), format, query, info, get_TrxName());&lt;br /&gt;
    &lt;br /&gt;
    if(format.getJasperProcess_ID() &amp;gt; 0){&lt;br /&gt;
      // JasperReports Print Format&lt;br /&gt;
      ProcessInfo pi = new ProcessInfo (&amp;quot;&amp;quot;, format.getJasperProcess_ID());&lt;br /&gt;
      pi.setRecord_ID(get_ID());&lt;br /&gt;
      pi.setIsBatch(true);&lt;br /&gt;
      ServerProcessCtl.process(pi, null);&lt;br /&gt;
      return pi.getPDFReport();&lt;br /&gt;
    }else{&lt;br /&gt;
      // Standard Print Format (Non-Jasper)&lt;br /&gt;
      return re.getPDF(file);&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Development‏‎]]&lt;br /&gt;
[[Category:Developer documentation‏‎]]&lt;br /&gt;
[[Category:System administration‏‎]]&lt;br /&gt;
[[Category:Applying means‏‎]]&lt;br /&gt;
[[Category:Document‎]]&lt;br /&gt;
[[Category:Workflow]]&lt;/div&gt;</summary>
		<author><name>Tioraul</name></author>
	</entry>
	<entry>
		<id>https://wiki.idempiere.org/w-en/index.php?title=Hackers_Guide_to_Documents&amp;diff=14312</id>
		<title>Hackers Guide to Documents</title>
		<link rel="alternate" type="text/html" href="https://wiki.idempiere.org/w-en/index.php?title=Hackers_Guide_to_Documents&amp;diff=14312"/>
		<updated>2018-07-27T23:00:34Z</updated>

		<summary type="html">&lt;p&gt;Tioraul: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Modes of document characteristics =&lt;br /&gt;
&lt;br /&gt;
== Document number ==&lt;br /&gt;
&lt;br /&gt;
If a table has a column with the title DocumentNo, it will be treated automatically in a special way. In the first usage of the table a sequence will be installed, which takes care of a consecutively document numeration. This document number can be edited more precisly in [[Belegnummernkreis (Fenster_ID-112)]]. It can be set as a determinded initial value or it can preserve a prefix or a suffix. Document numbers can also have a context variable where a date can be fit, e.g.Rechnung 00001/2014&amp;quot; (s.e.g. [[:en:NF001_Document_Sequence_Improved]]).&lt;br /&gt;
&lt;br /&gt;
== Model ==&lt;br /&gt;
&lt;br /&gt;
For a document type, which implements its own logic, you need to write a model. This means you create its own plugin, where you write a java class, the so-called model class (M*). This has to be derived from a predeterminded basis class (X_*). In turn this will be created with the help of the tool [[GenerateModel]] from the table definition of the data bank.&lt;br /&gt;
&lt;br /&gt;
=== Columns ===&lt;br /&gt;
&lt;br /&gt;
For the best you setup these following columns:&lt;br /&gt;
&lt;br /&gt;
* DocumentNo (mandatory; 30 Zeichen)&lt;br /&gt;
* DateDoc (mandatory)&lt;br /&gt;
* DateAcct (mandatory)&lt;br /&gt;
* Doc_User_ID (either a column or a getter-methode, which reads out a column like SalesRep_ID or standard logic, e.g. '@$C_Currency_ID@').&lt;br /&gt;
* C_Currency_ID (mandatory; Standardlogik e.g. &amp;quot;@$C_Currency_ID@')&lt;br /&gt;
* DocAction (mandatory; 2 characters; default 'CO'; pushbutton; reference &amp;quot;_Document Action&amp;quot;; here will be a process indicated, which indicates the according workflow of our document type)&lt;br /&gt;
* DocStatus (mandatory; 2 characters; default 'DR'; list reference; Referenz &amp;quot;_Document Status&amp;quot; )&lt;br /&gt;
* processed (mandatory; default 'N')&lt;br /&gt;
* processing (mandatory; default 'N') - after Dantam's article is a varchar(1), supposely the pushbutton. For example in C_Invoice is the same process inscribed like in DocAction. But until now I have no idea why you need two columns.&lt;br /&gt;
* isApproved (mandatory; default 'Y')&lt;br /&gt;
&lt;br /&gt;
=== What does DocumentEngine do in the process? ===&lt;br /&gt;
&lt;br /&gt;
Document actions will be done by the class DocEngine. Who wants to conduct a status operation, can do this best with the odel-method processIt(). This should invoke the accordingly method of DocEngine, which takes over the management of different status possibilties.&lt;br /&gt;
&lt;br /&gt;
* http://www.adempiere.com/Document_Engine - u.a. links to Sourcecode of Doc_* classes&lt;br /&gt;
* http://www.adempiere.com/Development_Guidelines_in_German#Klasse_DocumentEngine - german introduction, written quite well&lt;br /&gt;
&lt;br /&gt;
== Workflow ==&lt;br /&gt;
&lt;br /&gt;
You can install a receipt-Workflow which defines the change between several status values. You define a Workflow with three nodes: Start, Prepare and Complete. The two last ones will be combined with the last receipt action, therewith these take action. Then you definde a transition which in each case from Start to Prepare and from Prepare to Complete.&lt;br /&gt;
&lt;br /&gt;
This defined Workflow provides for properly done documents. It serves for further experiments.&lt;br /&gt;
&lt;br /&gt;
=== Reversing documents ===&lt;br /&gt;
&lt;br /&gt;
Who wants to reverse documents, requires these following columns in addition:&lt;br /&gt;
&lt;br /&gt;
* Reversal_ID (reference type table, as a reference you need to register new created table reference, which close about my whole table and can be assorted after DocumentNo)&lt;br /&gt;
&lt;br /&gt;
I never tried this reversal. Probably you need to configure an accordingly Workflow. Besides this you should be very careful, if you want to reverse booked documents.&lt;br /&gt;
&lt;br /&gt;
=== Reactivating Documents ===&lt;br /&gt;
&lt;br /&gt;
I would like to reactivate my document, after it is finalizied. In addition I created a further node 'Reactivate' and attached this with the accordingly receipt action. Then I definded a second transition with the start to Reactivate. The first transition has a condition, which only takes action, if 'Doc-Action = 'CO''. Besides this the first transition obtains a small order of numbers, which executes first.&lt;br /&gt;
&lt;br /&gt;
As a matter of principle the reactivating requires a reversal of the effects of the document. This implementation is not needed, but I recommend you this.&lt;br /&gt;
&lt;br /&gt;
=== Approval / Freigabe ===&lt;br /&gt;
&lt;br /&gt;
Workflows erlauben auch, die Bearbeitung eines Dokumentes von einer vorherigen Freigabe abhängig zu machen. So können z.B. Rechnungen über 1.000,- € immer erst dem Vorgesetzten vorgelegt werden oder dergleichen.&lt;br /&gt;
&lt;br /&gt;
* http://www.adempiere.com/How_to_Activate_Document_Approval_Workflow&lt;br /&gt;
&lt;br /&gt;
=== More about Workflows ===&lt;br /&gt;
&lt;br /&gt;
taken from http://en.wikiversity.org/wiki/Adempiere_Technical_Training#Document_Process_Workflow:&lt;br /&gt;
&lt;br /&gt;
Every document has a defined process – the workflow is started with the Process button:&amp;lt;br /&amp;gt;&lt;br /&gt;
These workflows have a defined start context (the document) and a responsible.&lt;br /&gt;
* Start (Draft)&lt;br /&gt;
** Auto&lt;br /&gt;
** Prepare (In Progress)&lt;br /&gt;
*** Complete (Completed)&lt;br /&gt;
&lt;br /&gt;
If you want to customize a workflow for a document:&amp;lt;br /&amp;gt;&lt;br /&gt;
* for all clients&lt;br /&gt;
** add customized node/transitions and/or inactivate standard transitions&lt;br /&gt;
* for a client or organization&lt;br /&gt;
** make changes on System workflow with entity type &amp;lt;&amp;gt; Dictionary/Adempiere&lt;br /&gt;
** execute process “Workflow to Client”&lt;br /&gt;
&lt;br /&gt;
== Booking Document ==&lt;br /&gt;
&lt;br /&gt;
A document that can generate its own posting lines must contain the following fields:&lt;br /&gt;
&lt;br /&gt;
* Posted (mandatory; boolean; default 'N')&lt;br /&gt;
* ProcessedOn (integer)&lt;br /&gt;
* C_DocType_ID (mandatory; Table; reference C_DocType)&lt;br /&gt;
&lt;br /&gt;
The corresponding logic is activated by the presence of the &amp;quot;Posted&amp;quot; field. In this case, after completing a document, an update class matching the model is used to carry out the update. For this there is the convention that this ends on &amp;quot;_Doc&amp;quot;. Within the iDempiere kernel, the name of this class (based on this convention) is automatically determined. In ADempiere this was also the case for own classes. In iDempiere, which no longer allows core access to our plugin classes through the OSGi packages, there is a factory for that purpose.&lt;br /&gt;
&lt;br /&gt;
== Document base type ==&lt;br /&gt;
&lt;br /&gt;
Our new document type must also have an entry in the database. However, we first have to think about which basic type he belongs to. This base type is used for sorting and grouping document types, in particular for the document type input fields. In addition, the period can be opened or closed in the period control (in the calendar) for each individual basic document category. Although, interestingly enough, it is not necessarily mandatory, it still makes sense to set up a document base type for your own accounting document class.&lt;br /&gt;
&lt;br /&gt;
The base document type consists of an entry in the reference list &amp;quot;C_DocType DocBaseType&amp;quot; and always has three letters. If you want, you can set up a type &amp;quot;DOC&amp;quot; for all your documents here. However, it makes more sense to create your own basic types for each document type you create. Then, a selection field in the window can be validated to filter for this basic type and the user will always be able to generate their own derivations later.&lt;br /&gt;
&lt;br /&gt;
For some base types of the standard iDempiere, multiple base types work with objects of the same table. For example, by splitting &amp;quot;API Accounts Payable Invoice&amp;quot; and &amp;quot;ARI Accounts Receivable Invoice&amp;quot; ensures that incoming and outgoing invoices are never mixed. Although both are in the same table and use much the same business logic, they each have their own windows and are also distinguished by the field &amp;quot;isSOTrx&amp;quot; (and the different base document type). Due to the two basic document types, a simple validation on the input field for the document type is enough, so that you can only select sales document types for customers and vice versa.&lt;br /&gt;
&lt;br /&gt;
After you have created the basic document categories (in the system client), you should now call the process &amp;quot;Check Document Types&amp;quot; in the client. This creates a document type for each base document type and also directly creates corresponding period entries in the calendar.&lt;br /&gt;
&lt;br /&gt;
The automatically generated document types can be viewed in the &amp;quot;Document type&amp;quot; window and adjusted if necessary. It is recommended to activate number management and specify (or create) a document number range.&lt;br /&gt;
&lt;br /&gt;
In this window you can now derive even more document types from its basic document category. This has different purposes:&lt;br /&gt;
&lt;br /&gt;
* First of all, this can serve the in-house grouping of documents. Anyone who thinks in his business that a bill of goods is different from a service bill and a foreign bill, in turn, differently and a freight bill, can divide this so without much trouble.&lt;br /&gt;
* You can specify your own print format (in this window) and make the printed receipt look very different.&lt;br /&gt;
* You can group direct bookings (batches) using the direct posting type (fee type depending on the translation) and only allow specific bookings for certain document types. Thus, the freight invoice can be posted to the account for freight, the foreign invoice to the account for customs, etc.&lt;br /&gt;
&lt;br /&gt;
Next, you should create a validation rule. This gets the name &amp;quot;C_DocType MyPatementName&amp;quot; and as SQL-Code something like the following line:&lt;br /&gt;
&lt;br /&gt;
  C_DocType.DocBaseType IN ('ARZ', 'APZ') AND C_DocType.IsSOTrx='@IsSOTrx@'  AND C_DocType.AD_Client_ID=@#AD_Client_ID@&lt;br /&gt;
&lt;br /&gt;
Of course, you can omit the part with IsSOTrx if we do not have a separate document type for input and output windows. This part of the formula ensures that we can use identical field definitions for incoming and outgoing documents. The two windows then differ only in that the context variable &amp;quot;IsSOTrx&amp;quot; is set when the window is opened. This will then control everything else. This value can be set in the window definition.&lt;br /&gt;
&lt;br /&gt;
== Purchase and sales documents ==&lt;br /&gt;
&lt;br /&gt;
If you have a document category that is supposed to post different purchasing and sales documents (AP and AR), you also need this field. With this type of document, it is generally appropriate to also generate two separate basic document types and possibly two separate windows. The window definitions can be largely identical except for the &amp;quot;Sales Transaction&amp;quot; entry, which sets the context variable &amp;quot;IsSOTrx&amp;quot; and thus makes it distinguishable.&lt;br /&gt;
&lt;br /&gt;
* isSOTrx (mandatory; boolean, in the window best not displayed nciht or at least write-protected)&lt;br /&gt;
&lt;br /&gt;
== Windows, tabs &amp;amp; fields ==&lt;br /&gt;
&lt;br /&gt;
The window should be set to the window type &amp;quot;Transaction&amp;quot;. This turns on [[http://www.adempiere.com/History History]]. This ensures that only the current and incomplete documents are displayed.&lt;br /&gt;
&lt;br /&gt;
Incidentally, when configuring the window, the following fields should be displayed (according to Dantam):&lt;br /&gt;
&lt;br /&gt;
* Processed (set to &amp;quot;Read Only&amp;quot;)&lt;br /&gt;
* DocStatus (set to &amp;quot;Read Only&amp;quot;)&lt;br /&gt;
* DocAction&lt;br /&gt;
* Currency (if used, it may be read-only)&lt;br /&gt;
&lt;br /&gt;
For documents that differentiate purchasing and sales documents, it makes sense to copy them and introduce a WHERE clause, so that you have two windows for these actually different document types. You can define a window as a sales transaction in the window definition, and thus set a context variable that is used in many queries and validations to ensure that all fields work properly. Of course, this requires some care in generating your own queries, but there are enough existing examples, such &amp;quot;Invoice (Customer)&amp;quot; and &amp;quot;Invoice (Supplier)&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Print ==&lt;br /&gt;
&lt;br /&gt;
Basically, you can print a record by clicking on the button in the toolbar for a report. This will then create a print format that you can adjust accordingly. If you often want to have individual data sets, for example As a form print as a list of sentences, so it is useful to activate the print button, with which you can print individual records. This is done by making an entry in the Process &amp;amp; Report window. This was set to &amp;quot;Report&amp;quot; and indicates, if necessary, a prepared print format. This can then be started with the buttons for &amp;quot;Print&amp;quot; and &amp;quot;Print preview&amp;quot; by entering it in the window register record.&lt;br /&gt;
&lt;br /&gt;
By the way, there is a little problem here. You have to set up the &amp;quot;Process &amp;amp; Report&amp;quot; window in the system client, whereas most of the time you have prepared your print format in the normal client. You can release the print format in this case. It is automatically selected the one that has set the field &amp;quot;Standard&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
=== Use Report View to print more columns than shown in the table ===&lt;br /&gt;
&lt;br /&gt;
An extension can be added by entering a similar entry in the field &amp;quot;Report view&amp;quot; in &amp;quot;Process &amp;amp; Report&amp;quot;. In this case, a print format is selected that has selected this report view. This allows you to narrow the selection of the print format even further.&lt;br /&gt;
&lt;br /&gt;
In particular, one can also specify a report view based on a completely different table. This table should only contain the primary key field of our document because it will filter out the printed record. I used this, for example, to use a database view instead of the table edited in the current window for the expression, which, while based on that same table, adds a lot of additional data via JOIN. This large amount of information can then be restricted (if you like) through a report view and then processed in print format. Such a print format is created in the window &amp;quot;Print format&amp;quot;, where you can set the table and the view when creating the record. Then you create the fields by means of the automatic process button for this purpose and can then set the print format already in the target window and use it there in the print view. If this is the first time to see, then you can customize it as usual resulting print formats.&lt;br /&gt;
&lt;br /&gt;
=== Print by program ===&lt;br /&gt;
&lt;br /&gt;
In my model for the BAY_InterestCalculation table, I can use the following method to get an expression based on a view called RV_BAY_InterestCalculation. One can use this method e.g. in completeIt () to make sure that a document is always printed when it completes. Incidentally, one can set in the process window whether the printout happens immediately in the background or only with consultation.&lt;br /&gt;
&lt;br /&gt;
  public void print() {&lt;br /&gt;
    int viewTable = MTable.getTable_ID(&amp;quot;RV_&amp;quot; + Table_Name);&lt;br /&gt;
    MPrintFormat format = new Query(getCtx(), MPrintFormat.Table_Name, MPrintFormat.COLUMNNAME_AD_Table_ID&lt;br /&gt;
      + &amp;quot;=? AND &amp;quot; + MPrintFormat.COLUMNNAME_IsDefault + &amp;quot;=? &amp;quot;, get_TrxName()).setParameters(viewTable, &amp;quot;Y&amp;quot;)&lt;br /&gt;
      .first();&lt;br /&gt;
    MQuery query = new MQuery(get_Table_ID());&lt;br /&gt;
    query.addRestriction(get_KeyColumns()[0], MQuery.EQUAL, get_ID());&lt;br /&gt;
    PrintInfo info = new PrintInfo(getDocumentInfo(), get_Table_ID(), get_ID());&lt;br /&gt;
    ReportEngine re = new ReportEngine(getCtx(), format, query, info, get_TrxName());&lt;br /&gt;
    re.print();&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
= Links =&lt;br /&gt;
&lt;br /&gt;
== Articles that explain documents ==&lt;br /&gt;
&lt;br /&gt;
Basic statements&lt;br /&gt;
&lt;br /&gt;
* http://wiki.idempiere.org/en/Create_a_custom_document_class - quite new article by Daniel Tamm in the iDempiere Wiki, still has many gaps&lt;br /&gt;
* http://www.adempiere.com/How_to_create_a_new_document_with_specific_accounting&lt;br /&gt;
&lt;br /&gt;
Further explanations&lt;br /&gt;
&lt;br /&gt;
* http://www.adempiere.com/How_to_Activate_Document_Approval_Workflow&lt;br /&gt;
* http://www.adempiere.com/Document_Action_Dialog - Explanation of the action button and the window that opens up&lt;br /&gt;
* http://www.adempiere.com/Document_Sequence - Document Sequence&lt;br /&gt;
* Extensions&lt;br /&gt;
** http://www.adempiere.com/Enhance_Document_No_Formatting - Improvement of document numbering (this allows context variables)&lt;br /&gt;
** http://wiki.idempiere.org/en/NF001_Document_Sequence_Improved - Improvement of organizations and restart of number ranges&lt;br /&gt;
** http://www.adempiere.com/Sponsored_Development:_Document_Signing - Document Signing Extension, evidently never realized&lt;br /&gt;
&lt;br /&gt;
Articles that I use as sources, but have already incorporated much here:&lt;br /&gt;
&lt;br /&gt;
* http://www.adempiere.com/HOWTO_Process_Documents - quite well explains the use of existing document types; less the development of new ones&lt;br /&gt;
* http://en.wikiversity.org/wiki/Adempiere_Technical_Training#Document_Process_Workflow - contains short but insightful parts on the topic, in particular &amp;quot;Document Process Workflow&amp;quot;&lt;br /&gt;
* http://www.adempiere.com/Document_Engine&lt;br /&gt;
* https://groups.google.com/forum/#!topic/idempiere/WtTlVL1ZjWw - Briefed forum thread about how to implement a workflow&lt;br /&gt;
&lt;br /&gt;
Windows related to documents:&lt;br /&gt;
&lt;br /&gt;
* http://wiki.idempiere.org/en/Document_Type_%28Window_ID-135%29&lt;br /&gt;
* http://wiki.idempiere.org/en/Document_Sequence_%28Window_ID-112%29&lt;br /&gt;
&lt;br /&gt;
* http://wiki.idempiere.org/en/Unprocessed_Documents_%28All%29_%28Window_ID-53087%29&lt;br /&gt;
* http://wiki.idempiere.org/en/UnPosted_Documents_%28Window_ID-294%29&lt;br /&gt;
* http://wiki.idempiere.org/en/My_Unprocessed_Documents_%28Window_ID-53086%29&lt;br /&gt;
* http://wiki.idempiere.org/de/Workflow_%28Fenster_ID-113%29&lt;br /&gt;
&lt;br /&gt;
(What is the difference between &amp;quot;unprocessed&amp;quot; and &amp;quot;unposted&amp;quot; and how do these windows know which tables to scan?)&lt;br /&gt;
&lt;br /&gt;
* http://wiki.idempiere.org/en/Verify_Document_Types_%28Process_ID-233%29 - what does this process do? He probably creates open entries for new document types. Is there anything else?&lt;br /&gt;
&lt;br /&gt;
= Further information =&lt;br /&gt;
&lt;br /&gt;
== involved classes and interfaces ==&lt;br /&gt;
&lt;br /&gt;
=== MSetup ===&lt;br /&gt;
&lt;br /&gt;
Create the list of document type for new Client ( Method createAccounting ). &lt;br /&gt;
&lt;br /&gt;
=== org.compiere.server.AcctProcessor ===&lt;br /&gt;
&lt;br /&gt;
Background process running on the JBoss server that perform the accounting document posting process. &lt;br /&gt;
&lt;br /&gt;
=== org.compiere.grid.ed.VDocAction ===&lt;br /&gt;
&lt;br /&gt;
Define hardcoded in dynInit method the list of possible transitions, and transitions by table&lt;br /&gt;
&lt;br /&gt;
= Examples of implementing some DocAction methods =&lt;br /&gt;
&lt;br /&gt;
=== getDocumentInfo() ===&lt;br /&gt;
&lt;br /&gt;
Returns a short but unique name of the record, which is mainly used in log lines and other program messages. This example uses an existing document type.&lt;br /&gt;
&lt;br /&gt;
  public String getDocumentInfo(){&lt;br /&gt;
    MDocType dt = MDocType.get(getCtx(), getC_DocType_ID());&lt;br /&gt;
    String msgreturn = dt.getNameTrl()+&amp;quot; &amp;quot;+getDocumentNo();&lt;br /&gt;
    return msgreturn.toString();&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
=== createPDF() ===&lt;br /&gt;
&lt;br /&gt;
There is a method to output the document as a PDF. This will - as far as I've seen - only used to send the document by email. But because you never know, you can do that, e.g. as follows. Of course you can also choose more precisely when selecting the print format.&lt;br /&gt;
&lt;br /&gt;
  public File createPDF (){&lt;br /&gt;
    try{&lt;br /&gt;
      StringBuilder msgfile = new StringBuilder().append(get_TableName()).append(get_ID()).append(&amp;quot;_&amp;quot;);&lt;br /&gt;
      File temp = File.createTempFile(msgfile.toString(), &amp;quot;.pdf&amp;quot;);&lt;br /&gt;
      return createPDF (temp);&lt;br /&gt;
    }catch (Exception e){&lt;br /&gt;
      log.severe(&amp;quot;Could not create PDF - &amp;quot; + e.getMessage());&lt;br /&gt;
    }&lt;br /&gt;
    return null;&lt;br /&gt;
  }&lt;br /&gt;
  &lt;br /&gt;
  public File createPDF (File file){&lt;br /&gt;
    MPrintFormat format = MPrintFormat.get(getCtx(), 0, get_Table_ID());&lt;br /&gt;
    MQuery query=new MQuery(get_Table_ID());&lt;br /&gt;
    query.addRestriction(get_KeyColumns()[0],MQuery.EQUAL,get_ID());&lt;br /&gt;
    PrintInfo info = new PrintInfo(getDocumentNo(),get_Table_ID(),0);&lt;br /&gt;
    ReportEngine re = new ReportEngine(getCtx(), format, query, info, get_TrxName());&lt;br /&gt;
    &lt;br /&gt;
    if(format.getJasperProcess_ID() &amp;gt; 0){&lt;br /&gt;
      // JasperReports Print Format&lt;br /&gt;
      ProcessInfo pi = new ProcessInfo (&amp;quot;&amp;quot;, format.getJasperProcess_ID());&lt;br /&gt;
      pi.setRecord_ID(get_ID());&lt;br /&gt;
      pi.setIsBatch(true);&lt;br /&gt;
      ServerProcessCtl.process(pi, null);&lt;br /&gt;
      return pi.getPDFReport();&lt;br /&gt;
    }else{&lt;br /&gt;
      // Standard Print Format (Non-Jasper)&lt;br /&gt;
      return re.getPDF(file);&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Development‏‎]]&lt;br /&gt;
[[Category:Developer documentation‏‎]]&lt;br /&gt;
[[Category:System administration‏‎]]&lt;br /&gt;
[[Category:Applying means‏‎]]&lt;br /&gt;
[[Category:Document‎]]&lt;br /&gt;
[[Category:Workflow]]&lt;/div&gt;</summary>
		<author><name>Tioraul</name></author>
	</entry>
	<entry>
		<id>https://wiki.idempiere.org/w-en/index.php?title=Hackers_Guide_to_Documents&amp;diff=14311</id>
		<title>Hackers Guide to Documents</title>
		<link rel="alternate" type="text/html" href="https://wiki.idempiere.org/w-en/index.php?title=Hackers_Guide_to_Documents&amp;diff=14311"/>
		<updated>2018-07-27T22:58:11Z</updated>

		<summary type="html">&lt;p&gt;Tioraul: google translate&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Modes of document characteristics =&lt;br /&gt;
&lt;br /&gt;
== Document number ==&lt;br /&gt;
&lt;br /&gt;
If a table has a column with the title DocumentNo, it will be treated automatically in a special way. In the first usage of the table a sequence will be installed, which takes care of a consecutively document numeration. This document number can be edited more precisly in [[Belegnummernkreis (Fenster_ID-112)]]. It can be set as a determinded initial value or it can preserve a prefix or a suffix. Document numbers can also have a context variable where a date can be fit, e.g.Rechnung 00001/2014&amp;quot; (s.e.g. [[:en:NF001_Document_Sequence_Improved]]).&lt;br /&gt;
&lt;br /&gt;
== Model ==&lt;br /&gt;
&lt;br /&gt;
For a document type, which implements its own logic, you need to write a model. This means you create its own plugin, where you write a java class, the so-called model class (M*). This has to be derived from a predeterminded basis class (X_*). In turn this will be created with the help of the tool [[GenerateModel]] from the table definition of the data bank.&lt;br /&gt;
&lt;br /&gt;
=== Columns ===&lt;br /&gt;
&lt;br /&gt;
For the best you setup these following columns:&lt;br /&gt;
&lt;br /&gt;
* DocumentNo (mandatory; 30 Zeichen)&lt;br /&gt;
* DateDoc (mandatory)&lt;br /&gt;
* DateAcct (mandatory)&lt;br /&gt;
* Doc_User_ID (either a column or a getter-methode, which reads out a column like SalesRep_ID or standard logic, e.g. '@$C_Currency_ID@').&lt;br /&gt;
* C_Currency_ID (mandatory; Standardlogik e.g. &amp;quot;@$C_Currency_ID@')&lt;br /&gt;
* DocAction (mandatory; 2 characters; default 'CO'; pushbutton; reference &amp;quot;_Document Action&amp;quot;; here will be a process indicated, which indicates the according workflow of our document type)&lt;br /&gt;
* DocStatus (mandatory; 2 characters; default 'DR'; list reference; Referenz &amp;quot;_Document Status&amp;quot; )&lt;br /&gt;
* processed (mandatory; default 'N')&lt;br /&gt;
* processing (mandatory; default 'N') - after Dantam's article is a varchar(1), supposely the pushbutton. For example in C_Invoice is the same process inscribed like in DocAction. But until now I have no idea why you need two columns.&lt;br /&gt;
* isApproved (mandatory; default 'Y')&lt;br /&gt;
&lt;br /&gt;
=== What does DocumentEngine do in the process? ===&lt;br /&gt;
&lt;br /&gt;
Document actions will be done by the class DocEngine. Who wants to conduct a status operation, can do this best with the odel-method processIt(). This should invoke the accordingly method of DocEngine, which takes over the management of different status possibilties.&lt;br /&gt;
&lt;br /&gt;
* http://www.adempiere.com/Document_Engine - u.a. links to Sourcecode of Doc_* classes&lt;br /&gt;
* http://www.adempiere.com/Development_Guidelines_in_German#Klasse_DocumentEngine - german introduction, written quite well&lt;br /&gt;
&lt;br /&gt;
== Workflow ==&lt;br /&gt;
&lt;br /&gt;
You can install a receipt-Workflow which defines the change between several status values. You define a Workflow with three nodes: Start, Prepare and Complete. The two last ones will be combined with the last receipt action, therewith these take action. Then you definde a transition which in each case from Start to Prepare and from Prepare to Complete.&lt;br /&gt;
&lt;br /&gt;
This defined Workflow provides for properly done documents. It serves for further experiments.&lt;br /&gt;
&lt;br /&gt;
=== Reversing documents ===&lt;br /&gt;
&lt;br /&gt;
Who wants to reverse documents, requires these following columns in addition:&lt;br /&gt;
&lt;br /&gt;
* Reversal_ID (reference type table, as a reference you need to register new created table reference, which close about my whole table and can be assorted after DocumentNo)&lt;br /&gt;
&lt;br /&gt;
I never tried this reversal. Probably you need to configure an accordingly Workflow. Besides this you should be very careful, if you want to reverse booked documents.&lt;br /&gt;
&lt;br /&gt;
=== Reactivating Documents ===&lt;br /&gt;
&lt;br /&gt;
I would like to reactivate my document, after it is finalizied. In addition I created a further node 'Reactivate' and attached this with the accordingly receipt action. Then I definded a second transition with the start to Reactivate. The first transition has a condition, which only takes action, if 'Doc-Action = 'CO''. Besides this the first transition obtains a small order of numbers, which executes first.&lt;br /&gt;
&lt;br /&gt;
As a matter of principle the reactivating requires a reversal of the effects of the document. This implementation is not needed, but I recommend you this.&lt;br /&gt;
&lt;br /&gt;
=== Approval / Freigabe ===&lt;br /&gt;
&lt;br /&gt;
Workflows erlauben auch, die Bearbeitung eines Dokumentes von einer vorherigen Freigabe abhängig zu machen. So können z.B. Rechnungen über 1.000,- € immer erst dem Vorgesetzten vorgelegt werden oder dergleichen.&lt;br /&gt;
&lt;br /&gt;
* http://www.adempiere.com/How_to_Activate_Document_Approval_Workflow&lt;br /&gt;
&lt;br /&gt;
=== More about Workflows ===&lt;br /&gt;
&lt;br /&gt;
taken from http://en.wikiversity.org/wiki/Adempiere_Technical_Training#Document_Process_Workflow:&lt;br /&gt;
&lt;br /&gt;
Every document has a defined process – the workflow is started with the Process button:&amp;lt;br /&amp;gt;&lt;br /&gt;
These workflows have a defined start context (the document) and a responsible.&lt;br /&gt;
* Start (Draft)&lt;br /&gt;
** Auto&lt;br /&gt;
** Prepare (In Progress)&lt;br /&gt;
*** Complete (Completed)&lt;br /&gt;
&lt;br /&gt;
If you want to customize a workflow for a document:&amp;lt;br /&amp;gt;&lt;br /&gt;
* for all clients&lt;br /&gt;
** add customized node/transitions and/or inactivate standard transitions&lt;br /&gt;
* for a client or organization&lt;br /&gt;
** make changes on System workflow with entity type &amp;lt;&amp;gt; Dictionary/Adempiere&lt;br /&gt;
** execute process “Workflow to Client”&lt;br /&gt;
&lt;br /&gt;
== Booking Document ==&lt;br /&gt;
&lt;br /&gt;
A document that can generate its own posting lines must contain the following fields:&lt;br /&gt;
&lt;br /&gt;
* Posted (mandatory; boolean; default 'N')&lt;br /&gt;
* ProcessedOn (integer)&lt;br /&gt;
* C_DocType_ID (mandatory; Table; reference C_DocType)&lt;br /&gt;
&lt;br /&gt;
The corresponding logic is activated by the presence of the &amp;quot;Posted&amp;quot; field. In this case, after completing a document, an update class matching the model is used to carry out the update. For this there is the convention that this ends on &amp;quot;_Doc&amp;quot;. Within the iDempiere kernel, the name of this class (based on this convention) is automatically determined. In ADempiere this was also the case for own classes. In iDempiere, which no longer allows core access to our plugin classes through the OSGi packages, there is a factory for that purpose.&lt;br /&gt;
&lt;br /&gt;
== Document base type ==&lt;br /&gt;
&lt;br /&gt;
Our new document type must also have an entry in the database. However, we first have to think about which basic type he belongs to. This base type is used for sorting and grouping document types, in particular for the document type input fields. In addition, the period can be opened or closed in the period control (in the calendar) for each individual basic document category. Although, interestingly enough, it is not necessarily mandatory, it still makes sense to set up a document base type for your own accounting document class.&lt;br /&gt;
&lt;br /&gt;
The base document type consists of an entry in the reference list &amp;quot;C_DocType DocBaseType&amp;quot; and always has three letters. If you want, you can set up a type &amp;quot;DOC&amp;quot; for all your documents here. However, it makes more sense to create your own basic types for each document type you create. Then, a selection field in the window can be validated to filter for this basic type and the user will always be able to generate their own derivations later.&lt;br /&gt;
&lt;br /&gt;
For some base types of the standard iDempiere, multiple base types work with objects of the same table. For example, by splitting &amp;quot;API Accounts Payable Invoice&amp;quot; and &amp;quot;ARI Accounts Receivable Invoice&amp;quot; ensures that incoming and outgoing invoices are never mixed. Although both are in the same table and use much the same business logic, they each have their own windows and are also distinguished by the field &amp;quot;isSOTrx&amp;quot; (and the different base document type). Due to the two basic document types, a simple validation on the input field for the document type is enough, so that you can only select sales document types for customers and vice versa.&lt;br /&gt;
&lt;br /&gt;
After you have created the basic document categories (in the system client), you should now call the process &amp;quot;Check Document Types&amp;quot; in the client. This creates a document type for each base document type and also directly creates corresponding period entries in the calendar.&lt;br /&gt;
&lt;br /&gt;
The automatically generated document types can be viewed in the &amp;quot;Document type&amp;quot; window and adjusted if necessary. It is recommended to activate number management and specify (or create) a document number range.&lt;br /&gt;
&lt;br /&gt;
In this window you can now derive even more document types from its basic document category. This has different purposes:&lt;br /&gt;
&lt;br /&gt;
* First of all, this can serve the in-house grouping of documents. Anyone who thinks in his business that a bill of goods is different from a service bill and a foreign bill, in turn, differently and a freight bill, can divide this so without much trouble.&lt;br /&gt;
* You can specify your own print format (in this window) and make the printed receipt look very different.&lt;br /&gt;
* You can group direct bookings (batches) using the direct posting type (fee type depending on the translation) and only allow specific bookings for certain document types. Thus, the freight invoice can be posted to the account for freight, the foreign invoice to the account for customs, etc.&lt;br /&gt;
&lt;br /&gt;
Next, you should create a validation rule. This gets the name &amp;quot;C_DocType MyPatementName&amp;quot; and as SQL-Code something like the following line:&lt;br /&gt;
&lt;br /&gt;
  C_DocType.DocBaseType IN ('ARZ', 'APZ') AND C_DocType.IsSOTrx='@IsSOTrx@'  AND C_DocType.AD_Client_ID=@#AD_Client_ID@&lt;br /&gt;
&lt;br /&gt;
Of course, you can omit the part with IsSOTrx if we do not have a separate document type for input and output windows. This part of the formula ensures that we can use identical field definitions for incoming and outgoing documents. The two windows then differ only in that the context variable &amp;quot;IsSOTrx&amp;quot; is set when the window is opened. This will then control everything else. This value can be set in the window definition.&lt;br /&gt;
&lt;br /&gt;
== Purchase and sales documents ==&lt;br /&gt;
&lt;br /&gt;
If you have a document category that is supposed to post different purchasing and sales documents (AP and AR), you also need this field. With this type of document, it is generally appropriate to also generate two separate basic document types and possibly two separate windows. The window definitions can be largely identical except for the &amp;quot;Sales Transaction&amp;quot; entry, which sets the context variable &amp;quot;IsSOTrx&amp;quot; and thus makes it distinguishable.&lt;br /&gt;
&lt;br /&gt;
* isSOTrx (mandatory; boolean, in the window best not displayed nciht or at least write-protected)&lt;br /&gt;
&lt;br /&gt;
== Windows, tabs &amp;amp; fields ==&lt;br /&gt;
&lt;br /&gt;
The window should be set to the window type &amp;quot;Transaction&amp;quot;. This turns on [[http://www.adempiere.com/History History]]. This ensures that only the current and incomplete documents are displayed.&lt;br /&gt;
&lt;br /&gt;
Incidentally, when configuring the window, the following fields should be displayed (according to Dantam):&lt;br /&gt;
&lt;br /&gt;
* Processed (set to &amp;quot;Read Only&amp;quot;)&lt;br /&gt;
* DocStatus (set to &amp;quot;Read Only&amp;quot;)&lt;br /&gt;
* DocAction&lt;br /&gt;
* Currency (if used, it may be read-only)&lt;br /&gt;
&lt;br /&gt;
For documents that differentiate purchasing and sales documents, it makes sense to copy them and introduce a WHERE clause, so that you have two windows for these actually different document types. You can define a window as a sales transaction in the window definition, and thus set a context variable that is used in many queries and validations to ensure that all fields work properly. Of course, this requires some care in generating your own queries, but there are enough existing examples, such &amp;quot;Invoice (Customer)&amp;quot; and &amp;quot;Invoice (Supplier)&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Print ==&lt;br /&gt;
&lt;br /&gt;
Basically, you can print a record by clicking on the button in the toolbar for a report. This will then create a print format that you can adjust accordingly. If you often want to have individual data sets, for example As a form print as a list of sentences, so it is useful to activate the print button, with which you can print individual records. This is done by making an entry in the Process &amp;amp; Report window. This was set to &amp;quot;Report&amp;quot; and indicates, if necessary, a prepared print format. This can then be started with the buttons for &amp;quot;Print&amp;quot; and &amp;quot;Print preview&amp;quot; by entering it in the window register record.&lt;br /&gt;
&lt;br /&gt;
By the way, there is a little problem here. You have to set up the &amp;quot;Process &amp;amp; Report&amp;quot; window in the system client, whereas most of the time you have prepared your print format in the normal client. You can release the print format in this case. It is automatically selected the one that has set the field &amp;quot;Standard&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
=== Use Report View to print more columns than shown in the table ===&lt;br /&gt;
&lt;br /&gt;
An extension can be added by entering a similar entry in the field &amp;quot;Report view&amp;quot; in &amp;quot;Process &amp;amp; Report&amp;quot;. In this case, a print format is selected that has selected this report view. This allows you to narrow the selection of the print format even further.&lt;br /&gt;
&lt;br /&gt;
In particular, one can also specify a report view based on a completely different table. This table should only contain the primary key field of our document because it will filter out the printed record. I used this, for example, to use a database view instead of the table edited in the current window for the expression, which, while based on that same table, adds a lot of additional data via JOIN. This large amount of information can then be restricted (if you like) through a report view and then processed in print format. Such a print format is created in the window &amp;quot;Print format&amp;quot;, where you can set the table and the view when creating the record. Then you create the fields by means of the automatic process button for this purpose and can then set the print format already in the target window and use it there in the print view. If this is the first time to see, then you can customize it as usual resulting print formats.&lt;br /&gt;
&lt;br /&gt;
=== Print by program ===&lt;br /&gt;
&lt;br /&gt;
In my model for the BAY_InterestCalculation table, I can use the following method to get an expression based on a view called RV_BAY_InterestCalculation. One can use this method e.g. in completeIt () to make sure that a document is always printed when it completes. Incidentally, one can set in the process window whether the printout happens immediately in the background or only with consultation.&lt;br /&gt;
&lt;br /&gt;
  public void print() {&lt;br /&gt;
    int viewTable = MTable.getTable_ID(&amp;quot;RV_&amp;quot; + Table_Name);&lt;br /&gt;
    MPrintFormat format = new Query(getCtx(), MPrintFormat.Table_Name, MPrintFormat.COLUMNNAME_AD_Table_ID&lt;br /&gt;
      + &amp;quot;=? AND &amp;quot; + MPrintFormat.COLUMNNAME_IsDefault + &amp;quot;=? &amp;quot;, get_TrxName()).setParameters(viewTable, &amp;quot;Y&amp;quot;)&lt;br /&gt;
      .first();&lt;br /&gt;
    MQuery query = new MQuery(get_Table_ID());&lt;br /&gt;
    query.addRestriction(get_KeyColumns()[0], MQuery.EQUAL, get_ID());&lt;br /&gt;
    PrintInfo info = new PrintInfo(getDocumentInfo(), get_Table_ID(), get_ID());&lt;br /&gt;
    ReportEngine re = new ReportEngine(getCtx(), format, query, info, get_TrxName());&lt;br /&gt;
    re.print();&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
= Links =&lt;br /&gt;
&lt;br /&gt;
== Articles that explain documents ==&lt;br /&gt;
&lt;br /&gt;
basic statements&lt;br /&gt;
&lt;br /&gt;
* http://wiki.idempiere.org/en/Create_a_custom_document_class - quite new article by Daniel Tamm in the iDempiere Wiki, still has many gaps&lt;br /&gt;
* http://www.adempiere.com/How_to_create_a_new_document_with_specific_accounting&lt;br /&gt;
&lt;br /&gt;
further explanations&lt;br /&gt;
&lt;br /&gt;
* http://www.adempiere.com/How_to_Activate_Document_Approval_Workflow&lt;br /&gt;
* http://www.adempiere.com/Document_Action_Dialog - Explanation of the action button and the window that opens up&lt;br /&gt;
* http://www.adempiere.com/Document_Sequence - Document Sequence&lt;br /&gt;
* Extensions&lt;br /&gt;
** http://www.adempiere.com/Enhance_Document_No_Formatting - Improvement of document numbering (this allows context variables)&lt;br /&gt;
** http://wiki.idempiere.org/en/NF001_Document_Sequence_Improved - Improvement of organizations and restart of number ranges&lt;br /&gt;
** http://www.adempiere.com/Sponsored_Development:_Document_Signing - Document Signing Extension, evidently never realized&lt;br /&gt;
&lt;br /&gt;
Articles that I use as sources, but have already incorporated much here:&lt;br /&gt;
&lt;br /&gt;
* http://www.adempiere.com/HOWTO_Process_Documents - quite well explains the use of existing document types; less the development of new ones&lt;br /&gt;
* http://en.wikiversity.org/wiki/Adempiere_Technical_Training#Document_Process_Workflow - contains short but insightful parts on the topic, in particular &amp;quot;Document Process Workflow&amp;quot;&lt;br /&gt;
* http://www.adempiere.com/Document_Engine&lt;br /&gt;
* https://groups.google.com/forum/#!topic/idempiere/WtTlVL1ZjWw - Briefed forum thread about how to implement a workflow&lt;br /&gt;
&lt;br /&gt;
Windows related to documents:&lt;br /&gt;
&lt;br /&gt;
* http://wiki.idempiere.org/en/Document_Type_%28Window_ID-135%29&lt;br /&gt;
* http://wiki.idempiere.org/en/Document_Sequence_%28Window_ID-112%29&lt;br /&gt;
&lt;br /&gt;
* http://wiki.idempiere.org/en/Unprocessed_Documents_%28All%29_%28Window_ID-53087%29&lt;br /&gt;
* http://wiki.idempiere.org/en/UnPosted_Documents_%28Window_ID-294%29&lt;br /&gt;
* http://wiki.idempiere.org/en/My_Unprocessed_Documents_%28Window_ID-53086%29&lt;br /&gt;
* http://wiki.idempiere.org/de/Workflow_%28Fenster_ID-113%29&lt;br /&gt;
&lt;br /&gt;
(What is the difference between &amp;quot;unprocessed&amp;quot; and &amp;quot;unposted&amp;quot; and how do these windows know which tables to scan?)&lt;br /&gt;
&lt;br /&gt;
* http://wiki.idempiere.org/en/Verify_Document_Types_%28Process_ID-233%29 - what does this process do? He probably creates open entries for new document types. Is there anything else?&lt;br /&gt;
&lt;br /&gt;
= Further information =&lt;br /&gt;
&lt;br /&gt;
== involved classes and interfaces ==&lt;br /&gt;
&lt;br /&gt;
=== MSetup ===&lt;br /&gt;
&lt;br /&gt;
Create the list of document type for new Client ( Method createAccounting ). &lt;br /&gt;
&lt;br /&gt;
=== org.compiere.server.AcctProcessor ===&lt;br /&gt;
&lt;br /&gt;
Background process running on the JBoss server that perform the accounting document posting process. &lt;br /&gt;
&lt;br /&gt;
=== org.compiere.grid.ed.VDocAction ===&lt;br /&gt;
&lt;br /&gt;
Define hardcoded in dynInit method the list of possible transitions, and transitions by table&lt;br /&gt;
&lt;br /&gt;
= Examples of implementing some DocAction methods =&lt;br /&gt;
&lt;br /&gt;
=== getDocumentInfo() ===&lt;br /&gt;
&lt;br /&gt;
Returns a short but unique name of the record, which is mainly used in log lines and other program messages. This example uses an existing document type.&lt;br /&gt;
&lt;br /&gt;
  public String getDocumentInfo(){&lt;br /&gt;
    MDocType dt = MDocType.get(getCtx(), getC_DocType_ID());&lt;br /&gt;
    String msgreturn = dt.getNameTrl()+&amp;quot; &amp;quot;+getDocumentNo();&lt;br /&gt;
    return msgreturn.toString();&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
=== createPDF() ===&lt;br /&gt;
&lt;br /&gt;
There is a method to output the document as a PDF. This will - as far as I've seen - only used to send the document by email. But because you never know, you can do that, e.g. as follows. Of course you can also choose more precisely when selecting the print format.&lt;br /&gt;
&lt;br /&gt;
  public File createPDF (){&lt;br /&gt;
    try{&lt;br /&gt;
      StringBuilder msgfile = new StringBuilder().append(get_TableName()).append(get_ID()).append(&amp;quot;_&amp;quot;);&lt;br /&gt;
      File temp = File.createTempFile(msgfile.toString(), &amp;quot;.pdf&amp;quot;);&lt;br /&gt;
      return createPDF (temp);&lt;br /&gt;
    }catch (Exception e){&lt;br /&gt;
      log.severe(&amp;quot;Could not create PDF - &amp;quot; + e.getMessage());&lt;br /&gt;
    }&lt;br /&gt;
    return null;&lt;br /&gt;
  }&lt;br /&gt;
  &lt;br /&gt;
  public File createPDF (File file){&lt;br /&gt;
    MPrintFormat format = MPrintFormat.get(getCtx(), 0, get_Table_ID());&lt;br /&gt;
    MQuery query=new MQuery(get_Table_ID());&lt;br /&gt;
    query.addRestriction(get_KeyColumns()[0],MQuery.EQUAL,get_ID());&lt;br /&gt;
    PrintInfo info = new PrintInfo(getDocumentNo(),get_Table_ID(),0);&lt;br /&gt;
    ReportEngine re = new ReportEngine(getCtx(), format, query, info, get_TrxName());&lt;br /&gt;
    &lt;br /&gt;
    if(format.getJasperProcess_ID() &amp;gt; 0){&lt;br /&gt;
      // JasperReports Print Format&lt;br /&gt;
      ProcessInfo pi = new ProcessInfo (&amp;quot;&amp;quot;, format.getJasperProcess_ID());&lt;br /&gt;
      pi.setRecord_ID(get_ID());&lt;br /&gt;
      pi.setIsBatch(true);&lt;br /&gt;
      ServerProcessCtl.process(pi, null);&lt;br /&gt;
      return pi.getPDFReport();&lt;br /&gt;
    }else{&lt;br /&gt;
      // Standard Print Format (Non-Jasper)&lt;br /&gt;
      return re.getPDF(file);&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Development‏‎]]&lt;br /&gt;
[[Category:Developer documentation‏‎]]&lt;br /&gt;
[[Category:System administration‏‎]]&lt;br /&gt;
[[Category:Applying means‏‎]]&lt;br /&gt;
[[Category:Document‎]]&lt;br /&gt;
[[Category:Workflow]]&lt;/div&gt;</summary>
		<author><name>Tioraul</name></author>
	</entry>
	<entry>
		<id>https://wiki.idempiere.org/w-en/index.php?title=Hackers_Guide_to_Documents&amp;diff=14310</id>
		<title>Hackers Guide to Documents</title>
		<link rel="alternate" type="text/html" href="https://wiki.idempiere.org/w-en/index.php?title=Hackers_Guide_to_Documents&amp;diff=14310"/>
		<updated>2018-07-27T22:50:41Z</updated>

		<summary type="html">&lt;p&gt;Tioraul: google translate&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Modes of document characteristics =&lt;br /&gt;
&lt;br /&gt;
== Document number ==&lt;br /&gt;
&lt;br /&gt;
If a table has a column with the title DocumentNo, it will be treated automatically in a special way. In the first usage of the table a sequence will be installed, which takes care of a consecutively document numeration. This document number can be edited more precisly in [[Belegnummernkreis (Fenster_ID-112)]]. It can be set as a determinded initial value or it can preserve a prefix or a suffix. Document numbers can also have a context variable where a date can be fit, e.g.Rechnung 00001/2014&amp;quot; (s.e.g. [[:en:NF001_Document_Sequence_Improved]]).&lt;br /&gt;
&lt;br /&gt;
== Model ==&lt;br /&gt;
&lt;br /&gt;
For a document type, which implements its own logic, you need to write a model. This means you create its own plugin, where you write a java class, the so-called model class (M*). This has to be derived from a predeterminded basis class (X_*). In turn this will be created with the help of the tool [[GenerateModel]] from the table definition of the data bank.&lt;br /&gt;
&lt;br /&gt;
=== Columns ===&lt;br /&gt;
&lt;br /&gt;
For the best you setup these following columns:&lt;br /&gt;
&lt;br /&gt;
* DocumentNo (mandatory; 30 Zeichen)&lt;br /&gt;
* DateDoc (mandatory)&lt;br /&gt;
* DateAcct (mandatory)&lt;br /&gt;
* Doc_User_ID (either a column or a getter-methode, which reads out a column like SalesRep_ID or standard logic, e.g. '@$C_Currency_ID@').&lt;br /&gt;
* C_Currency_ID (mandatory; Standardlogik e.g. &amp;quot;@$C_Currency_ID@')&lt;br /&gt;
* DocAction (mandatory; 2 characters; default 'CO'; pushbutton; reference &amp;quot;_Document Action&amp;quot;; here will be a process indicated, which indicates the according workflow of our document type)&lt;br /&gt;
* DocStatus (mandatory; 2 characters; default 'DR'; list reference; Referenz &amp;quot;_Document Status&amp;quot; )&lt;br /&gt;
* processed (mandatory; default 'N')&lt;br /&gt;
* processing (mandatory; default 'N') - after Dantam's article is a varchar(1), supposely the pushbutton. For example in C_Invoice is the same process inscribed like in DocAction. But until now I have no idea why you need two columns.&lt;br /&gt;
* isApproved (mandatory; default 'Y')&lt;br /&gt;
&lt;br /&gt;
=== What does DocumentEngine do in the process? ===&lt;br /&gt;
&lt;br /&gt;
Document actions will be done by the class DocEngine. Who wants to conduct a status operation, can do this best with the odel-method processIt(). This should invoke the accordingly method of DocEngine, which takes over the management of different status possibilties.&lt;br /&gt;
&lt;br /&gt;
* http://www.adempiere.com/Document_Engine - u.a. links to Sourcecode of Doc_* classes&lt;br /&gt;
* http://www.adempiere.com/Development_Guidelines_in_German#Klasse_DocumentEngine - german introduction, written quite well&lt;br /&gt;
&lt;br /&gt;
== Workflow ==&lt;br /&gt;
&lt;br /&gt;
You can install a receipt-Workflow which defines the change between several status values. You define a Workflow with three nodes: Start, Prepare and Complete. The two last ones will be combined with the last receipt action, therewith these take action. Then you definde a transition which in each case from Start to Prepare and from Prepare to Complete.&lt;br /&gt;
&lt;br /&gt;
This defined Workflow provides for properly done documents. It serves for further experiments.&lt;br /&gt;
&lt;br /&gt;
=== Reversing documents ===&lt;br /&gt;
&lt;br /&gt;
Who wants to reverse documents, requires these following columns in addition:&lt;br /&gt;
&lt;br /&gt;
* Reversal_ID (reference type table, as a reference you need to register new created table reference, which close about my whole table and can be assorted after DocumentNo)&lt;br /&gt;
&lt;br /&gt;
I never tried this reversal. Probably you need to configure an accordingly Workflow. Besides this you should be very careful, if you want to reverse booked documents.&lt;br /&gt;
&lt;br /&gt;
=== Reactivating Documents ===&lt;br /&gt;
&lt;br /&gt;
I would like to reactivate my document, after it is finalizied. In addition I created a further node 'Reactivate' and attached this with the accordingly receipt action. Then I definded a second transition with the start to Reactivate. The first transition has a condition, which only takes action, if 'Doc-Action = 'CO''. Besides this the first transition obtains a small order of numbers, which executes first.&lt;br /&gt;
&lt;br /&gt;
As a matter of principle the reactivating requires a reversal of the effects of the document. This implementation is not needed, but I recommend you this.&lt;br /&gt;
&lt;br /&gt;
=== Approval / Freigabe ===&lt;br /&gt;
&lt;br /&gt;
Workflows erlauben auch, die Bearbeitung eines Dokumentes von einer vorherigen Freigabe abhängig zu machen. So können z.B. Rechnungen über 1.000,- € immer erst dem Vorgesetzten vorgelegt werden oder dergleichen.&lt;br /&gt;
&lt;br /&gt;
* http://www.adempiere.com/How_to_Activate_Document_Approval_Workflow&lt;br /&gt;
&lt;br /&gt;
=== More about Workflows ===&lt;br /&gt;
&lt;br /&gt;
taken from http://en.wikiversity.org/wiki/Adempiere_Technical_Training#Document_Process_Workflow:&lt;br /&gt;
&lt;br /&gt;
Every document has a defined process – the workflow is started with the Process button:&amp;lt;br /&amp;gt;&lt;br /&gt;
These workflows have a defined start context (the document) and a responsible.&lt;br /&gt;
* Start (Draft)&lt;br /&gt;
** Auto&lt;br /&gt;
** Prepare (In Progress)&lt;br /&gt;
*** Complete (Completed)&lt;br /&gt;
&lt;br /&gt;
If you want to customize a workflow for a document:&amp;lt;br /&amp;gt;&lt;br /&gt;
* for all clients&lt;br /&gt;
** add customized node/transitions and/or inactivate standard transitions&lt;br /&gt;
* for a client or organization&lt;br /&gt;
** make changes on System workflow with entity type &amp;lt;&amp;gt; Dictionary/Adempiere&lt;br /&gt;
** execute process “Workflow to Client”&lt;br /&gt;
&lt;br /&gt;
== Booking Document ==&lt;br /&gt;
&lt;br /&gt;
A document that can generate its own posting lines must contain the following fields:&lt;br /&gt;
&lt;br /&gt;
* Posted (mandatory; boolean; default 'N')&lt;br /&gt;
* ProcessedOn (integer)&lt;br /&gt;
* C_DocType_ID (mandatory; Table; reference C_DocType)&lt;br /&gt;
&lt;br /&gt;
The corresponding logic is activated by the presence of the &amp;quot;Posted&amp;quot; field. In this case, after completing a document, an update class matching the model is used to carry out the update. For this there is the convention that this ends on &amp;quot;_Doc&amp;quot;. Within the iDempiere kernel, the name of this class (based on this convention) is automatically determined. In ADempiere this was also the case for own classes. In iDempiere, which no longer allows core access to our plugin classes through the OSGi packages, there is a factory for that purpose.&lt;br /&gt;
&lt;br /&gt;
== Document base type ==&lt;br /&gt;
&lt;br /&gt;
Our new document type must also have an entry in the database. However, we first have to think about which basic type he belongs to. This base type is used for sorting and grouping document types, in particular for the document type input fields. In addition, the period can be opened or closed in the period control (in the calendar) for each individual basic document category. Although, interestingly enough, it is not necessarily mandatory, it still makes sense to set up a document base type for your own accounting document class.&lt;br /&gt;
&lt;br /&gt;
The base document type consists of an entry in the reference list &amp;quot;C_DocType DocBaseType&amp;quot; and always has three letters. If you want, you can set up a type &amp;quot;DOC&amp;quot; for all your documents here. However, it makes more sense to create your own basic types for each document type you create. Then, a selection field in the window can be validated to filter for this basic type and the user will always be able to generate their own derivations later.&lt;br /&gt;
&lt;br /&gt;
For some base types of the standard iDempiere, multiple base types work with objects of the same table. For example, by splitting &amp;quot;API Accounts Payable Invoice&amp;quot; and &amp;quot;ARI Accounts Receivable Invoice&amp;quot; ensures that incoming and outgoing invoices are never mixed. Although both are in the same table and use much the same business logic, they each have their own windows and are also distinguished by the field &amp;quot;isSOTrx&amp;quot; (and the different base document type). Due to the two basic document types, a simple validation on the input field for the document type is enough, so that you can only select sales document types for customers and vice versa.&lt;br /&gt;
&lt;br /&gt;
After you have created the basic document categories (in the system client), you should now call the process &amp;quot;Check Document Types&amp;quot; in the client. This creates a document type for each base document type and also directly creates corresponding period entries in the calendar.&lt;br /&gt;
&lt;br /&gt;
The automatically generated document types can be viewed in the &amp;quot;Document type&amp;quot; window and adjusted if necessary. It is recommended to activate number management and specify (or create) a document number range.&lt;br /&gt;
&lt;br /&gt;
In this window you can now derive even more document types from its basic document category. This has different purposes:&lt;br /&gt;
&lt;br /&gt;
* First of all, this can serve the in-house grouping of documents. Anyone who thinks in his business that a bill of goods is different from a service bill and a foreign bill, in turn, differently and a freight bill, can divide this so without much trouble.&lt;br /&gt;
* You can specify your own print format (in this window) and make the printed receipt look very different.&lt;br /&gt;
* You can group direct bookings (batches) using the direct posting type (fee type depending on the translation) and only allow specific bookings for certain document types. Thus, the freight invoice can be posted to the account for freight, the foreign invoice to the account for customs, etc.&lt;br /&gt;
&lt;br /&gt;
Next, you should create a validation rule. This gets the name &amp;quot;C_DocType MyPatementName&amp;quot; and as SQL-Code something like the following line:&lt;br /&gt;
&lt;br /&gt;
  C_DocType.DocBaseType IN ('ARZ', 'APZ') AND C_DocType.IsSOTrx='@IsSOTrx@'  AND C_DocType.AD_Client_ID=@#AD_Client_ID@&lt;br /&gt;
&lt;br /&gt;
Of course, you can omit the part with IsSOTrx if we do not have a separate document type for input and output windows. This part of the formula ensures that we can use identical field definitions for incoming and outgoing documents. The two windows then differ only in that the context variable &amp;quot;IsSOTrx&amp;quot; is set when the window is opened. This will then control everything else. This value can be set in the window definition.&lt;br /&gt;
&lt;br /&gt;
== Purchase and sales documents ==&lt;br /&gt;
&lt;br /&gt;
If you have a document category that is supposed to post different purchasing and sales documents (AP and AR), you also need this field. With this type of document, it is generally appropriate to also generate two separate basic document types and possibly two separate windows. The window definitions can be largely identical except for the &amp;quot;Sales Transaction&amp;quot; entry, which sets the context variable &amp;quot;IsSOTrx&amp;quot; and thus makes it distinguishable.&lt;br /&gt;
&lt;br /&gt;
* isSOTrx (mandatory; boolean, in the window best not displayed nciht or at least write-protected)&lt;br /&gt;
&lt;br /&gt;
== Windows, tabs &amp;amp; fields ==&lt;br /&gt;
&lt;br /&gt;
The window should be set to the window type &amp;quot;Transaction&amp;quot;. This turns on [[http://www.adempiere.com/History History]]. This ensures that only the current and incomplete documents are displayed.&lt;br /&gt;
&lt;br /&gt;
Incidentally, when configuring the window, the following fields should be displayed (according to Dantam):&lt;br /&gt;
&lt;br /&gt;
* Processed (set to &amp;quot;Read Only&amp;quot;)&lt;br /&gt;
* DocStatus (set to &amp;quot;Read Only&amp;quot;)&lt;br /&gt;
* DocAction&lt;br /&gt;
* Currency (if used, it may be read-only)&lt;br /&gt;
&lt;br /&gt;
For documents that differentiate purchasing and sales documents, it makes sense to copy them and introduce a WHERE clause, so that you have two windows for these actually different document types. You can define a window as a sales transaction in the window definition, and thus set a context variable that is used in many queries and validations to ensure that all fields work properly. Of course, this requires some care in generating your own queries, but there are enough existing examples, such &amp;quot;Invoice (Customer)&amp;quot; and &amp;quot;Invoice (Supplier)&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Print ==&lt;br /&gt;
&lt;br /&gt;
Basically, you can print a record by clicking on the button in the toolbar for a report. This will then create a print format that you can adjust accordingly. If you often want to have individual data sets, for example As a form print as a list of sentences, so it is useful to activate the print button, with which you can print individual records. This is done by making an entry in the Process &amp;amp; Report window. This was set to &amp;quot;Report&amp;quot; and indicates, if necessary, a prepared print format. This can then be started with the buttons for &amp;quot;Print&amp;quot; and &amp;quot;Print preview&amp;quot; by entering it in the window register record.&lt;br /&gt;
&lt;br /&gt;
By the way, there is a little problem here. You have to set up the &amp;quot;Process &amp;amp; Report&amp;quot; window in the system client, whereas most of the time you have prepared your print format in the normal client. You can release the print format in this case. It is automatically selected the one that has set the field &amp;quot;Standard&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
=== Use Report View to print more columns than shown in the table ===&lt;br /&gt;
&lt;br /&gt;
An extension can be added by entering a similar entry in the field &amp;quot;Report view&amp;quot; in &amp;quot;Process &amp;amp; Report&amp;quot;. In this case, a print format is selected that has selected this report view. This allows you to narrow the selection of the print format even further.&lt;br /&gt;
&lt;br /&gt;
In particular, one can also specify a report view based on a completely different table. This table should only contain the primary key field of our document because it will filter out the printed record. I used this, for example, to use a database view instead of the table edited in the current window for the expression, which, while based on that same table, adds a lot of additional data via JOIN. This large amount of information can then be restricted (if you like) through a report view and then processed in print format. Such a print format is created in the window &amp;quot;Print format&amp;quot;, where you can set the table and the view when creating the record. Then you create the fields by means of the automatic process button for this purpose and can then set the print format already in the target window and use it there in the print view. If this is the first time to see, then you can customize it as usual resulting print formats.&lt;br /&gt;
&lt;br /&gt;
=== Print by program ===&lt;br /&gt;
&lt;br /&gt;
In my model for the BAY_InterestCalculation table, I can use the following method to get an expression based on a view called RV_BAY_InterestCalculation. One can use this method e.g. in completeIt () to make sure that a document is always printed when it completes. Incidentally, one can set in the process window whether the printout happens immediately in the background or only with consultation.&lt;br /&gt;
&lt;br /&gt;
  public void print() {&lt;br /&gt;
    int viewTable = MTable.getTable_ID(&amp;quot;RV_&amp;quot; + Table_Name);&lt;br /&gt;
    MPrintFormat format = new Query(getCtx(), MPrintFormat.Table_Name, MPrintFormat.COLUMNNAME_AD_Table_ID&lt;br /&gt;
      + &amp;quot;=? AND &amp;quot; + MPrintFormat.COLUMNNAME_IsDefault + &amp;quot;=? &amp;quot;, get_TrxName()).setParameters(viewTable, &amp;quot;Y&amp;quot;)&lt;br /&gt;
      .first();&lt;br /&gt;
    MQuery query = new MQuery(get_Table_ID());&lt;br /&gt;
    query.addRestriction(get_KeyColumns()[0], MQuery.EQUAL, get_ID());&lt;br /&gt;
    PrintInfo info = new PrintInfo(getDocumentInfo(), get_Table_ID(), get_ID());&lt;br /&gt;
    ReportEngine re = new ReportEngine(getCtx(), format, query, info, get_TrxName());&lt;br /&gt;
    re.print();&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
= Links =&lt;br /&gt;
&lt;br /&gt;
== Articles that explain documents ==&lt;br /&gt;
&lt;br /&gt;
basic statements&lt;br /&gt;
&lt;br /&gt;
* http://wiki.idempiere.org/en/Create_a_custom_document_class - quite new article by Daniel Tamm in the iDempiere Wiki, still has many gaps&lt;br /&gt;
* http://www.adempiere.com/How_to_create_a_new_document_with_specific_accounting&lt;br /&gt;
&lt;br /&gt;
further explanations&lt;br /&gt;
&lt;br /&gt;
* http://www.adempiere.com/How_to_Activate_Document_Approval_Workflow&lt;br /&gt;
* http://www.adempiere.com/Document_Action_Dialog - Explanation of the action button and the window that opens up&lt;br /&gt;
* http://www.adempiere.com/Document_Sequence - Document Sequence&lt;br /&gt;
* Extensions&lt;br /&gt;
** http://www.adempiere.com/Enhance_Document_No_Formatting - Improvement of document numbering (this allows context variables)&lt;br /&gt;
** http://wiki.idempiere.org/en/NF001_Document_Sequence_Improved - Improvement of organizations and restart of number ranges&lt;br /&gt;
** http://www.adempiere.com/Sponsored_Development:_Document_Signing - Document Signing Extension, evidently never realized&lt;br /&gt;
&lt;br /&gt;
Articles that I use as sources, but have already incorporated much here:&lt;br /&gt;
&lt;br /&gt;
* http://www.adempiere.com/HOWTO_Process_Documents - quite well explains the use of existing document types; less the development of new ones&lt;br /&gt;
* http://en.wikiversity.org/wiki/Adempiere_Technical_Training#Document_Process_Workflow - contains short but insightful parts on the topic, in particular &amp;quot;Document Process Workflow&amp;quot;&lt;br /&gt;
* http://www.adempiere.com/Document_Engine&lt;br /&gt;
* https://groups.google.com/forum/#!topic/idempiere/WtTlVL1ZjWw - Briefed forum thread about how to implement a workflow&lt;br /&gt;
&lt;br /&gt;
Windows related to documents:&lt;br /&gt;
&lt;br /&gt;
* http://wiki.idempiere.org/en/Document_Type_%28Window_ID-135%29&lt;br /&gt;
* http://wiki.idempiere.org/en/Document_Sequence_%28Window_ID-112%29&lt;br /&gt;
&lt;br /&gt;
* http://wiki.idempiere.org/en/Unprocessed_Documents_%28All%29_%28Window_ID-53087%29&lt;br /&gt;
* http://wiki.idempiere.org/en/UnPosted_Documents_%28Window_ID-294%29&lt;br /&gt;
* http://wiki.idempiere.org/en/My_Unprocessed_Documents_%28Window_ID-53086%29&lt;br /&gt;
* http://wiki.idempiere.org/de/Workflow_%28Fenster_ID-113%29&lt;br /&gt;
&lt;br /&gt;
(What is the difference between &amp;quot;unprocessed&amp;quot; and &amp;quot;unposted&amp;quot; and how do these windows know which tables to scan?)&lt;br /&gt;
&lt;br /&gt;
* http://wiki.idempiere.org/en/Verify_Document_Types_%28Process_ID-233%29 - what does this process do? He probably creates open entries for new document types. Is there anything else?&lt;br /&gt;
&lt;br /&gt;
= Further information =&lt;br /&gt;
&lt;br /&gt;
== involved classes and interfaces ==&lt;br /&gt;
&lt;br /&gt;
=== MSetup ===&lt;br /&gt;
&lt;br /&gt;
Create the list of document type for new Client ( Method createAccounting ). &lt;br /&gt;
&lt;br /&gt;
=== org.compiere.server.AcctProcessor ===&lt;br /&gt;
&lt;br /&gt;
Background process running on the JBoss server that perform the accounting document posting process. &lt;br /&gt;
&lt;br /&gt;
=== org.compiere.grid.ed.VDocAction ===&lt;br /&gt;
&lt;br /&gt;
Define hardcoded in dynInit method the list of possible transitions, and transitions by table&lt;br /&gt;
&lt;br /&gt;
= Beispiele für die Implementierung einiger DocAction-Methoden =&lt;br /&gt;
&lt;br /&gt;
=== getDocumentInfo() ===&lt;br /&gt;
&lt;br /&gt;
Ergibt eine kurze aber eindeutige Bezeichnung des Datensatzes, die vor allem in Logzeilen und sonstigen Programm-Mitteilungen verwendet wird. Dieses Beispiel nutzt einen vorhandenen Documenttyp.&lt;br /&gt;
&lt;br /&gt;
  public String getDocumentInfo(){&lt;br /&gt;
    MDocType dt = MDocType.get(getCtx(), getC_DocType_ID());&lt;br /&gt;
    String msgreturn = dt.getNameTrl()+&amp;quot; &amp;quot;+getDocumentNo();&lt;br /&gt;
    return msgreturn.toString();&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
=== createPDF() ===&lt;br /&gt;
&lt;br /&gt;
Es gibt eine Methode, um das Dokument als PDF auszugeben. Diese wird - soweit ich gesehen habe - nur benutzt, um das Dokument per EMail zu versenden. Da man aber nie weiss, kann man das z.B. so wie folgend implementieren. Dabei kann man bei der Auswähl des Printformats natürlich auch genauer auswählen.&lt;br /&gt;
&lt;br /&gt;
  public File createPDF (){&lt;br /&gt;
    try{&lt;br /&gt;
      StringBuilder msgfile = new StringBuilder().append(get_TableName()).append(get_ID()).append(&amp;quot;_&amp;quot;);&lt;br /&gt;
      File temp = File.createTempFile(msgfile.toString(), &amp;quot;.pdf&amp;quot;);&lt;br /&gt;
      return createPDF (temp);&lt;br /&gt;
    }catch (Exception e){&lt;br /&gt;
      log.severe(&amp;quot;Could not create PDF - &amp;quot; + e.getMessage());&lt;br /&gt;
    }&lt;br /&gt;
    return null;&lt;br /&gt;
  }&lt;br /&gt;
  &lt;br /&gt;
  public File createPDF (File file){&lt;br /&gt;
    MPrintFormat format = MPrintFormat.get(getCtx(), 0, get_Table_ID());&lt;br /&gt;
    MQuery query=new MQuery(get_Table_ID());&lt;br /&gt;
    query.addRestriction(get_KeyColumns()[0],MQuery.EQUAL,get_ID());&lt;br /&gt;
    PrintInfo info = new PrintInfo(getDocumentNo(),get_Table_ID(),0);&lt;br /&gt;
    ReportEngine re = new ReportEngine(getCtx(), format, query, info, get_TrxName());&lt;br /&gt;
    &lt;br /&gt;
    if(format.getJasperProcess_ID() &amp;gt; 0){&lt;br /&gt;
      // JasperReports Print Format&lt;br /&gt;
      ProcessInfo pi = new ProcessInfo (&amp;quot;&amp;quot;, format.getJasperProcess_ID());&lt;br /&gt;
      pi.setRecord_ID(get_ID());&lt;br /&gt;
      pi.setIsBatch(true);&lt;br /&gt;
      ServerProcessCtl.process(pi, null);&lt;br /&gt;
      return pi.getPDFReport();&lt;br /&gt;
    }else{&lt;br /&gt;
      // Standard Print Format (Non-Jasper)&lt;br /&gt;
      return re.getPDF(file);&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Development‏‎]]&lt;br /&gt;
[[Category:Developer documentation‏‎]]&lt;br /&gt;
[[Category:System administration‏‎]]&lt;br /&gt;
[[Category:Applying means‏‎]]&lt;br /&gt;
[[Category:Document‎]]&lt;br /&gt;
[[Category:Workflow]]&lt;/div&gt;</summary>
		<author><name>Tioraul</name></author>
	</entry>
	<entry>
		<id>https://wiki.idempiere.org/w-en/index.php?title=Hackers_Guide_to_Documents&amp;diff=14309</id>
		<title>Hackers Guide to Documents</title>
		<link rel="alternate" type="text/html" href="https://wiki.idempiere.org/w-en/index.php?title=Hackers_Guide_to_Documents&amp;diff=14309"/>
		<updated>2018-07-27T22:49:08Z</updated>

		<summary type="html">&lt;p&gt;Tioraul: google translate&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Modes of document characteristics =&lt;br /&gt;
&lt;br /&gt;
== Document number ==&lt;br /&gt;
&lt;br /&gt;
If a table has a column with the title DocumentNo, it will be treated automatically in a special way. In the first usage of the table a sequence will be installed, which takes care of a consecutively document numeration. This document number can be edited more precisly in [[Belegnummernkreis (Fenster_ID-112)]]. It can be set as a determinded initial value or it can preserve a prefix or a suffix. Document numbers can also have a context variable where a date can be fit, e.g.Rechnung 00001/2014&amp;quot; (s.e.g. [[:en:NF001_Document_Sequence_Improved]]).&lt;br /&gt;
&lt;br /&gt;
== Model ==&lt;br /&gt;
&lt;br /&gt;
For a document type, which implements its own logic, you need to write a model. This means you create its own plugin, where you write a java class, the so-called model class (M*). This has to be derived from a predeterminded basis class (X_*). In turn this will be created with the help of the tool [[GenerateModel]] from the table definition of the data bank.&lt;br /&gt;
&lt;br /&gt;
=== Columns ===&lt;br /&gt;
&lt;br /&gt;
For the best you setup these following columns:&lt;br /&gt;
&lt;br /&gt;
* DocumentNo (mandatory; 30 Zeichen)&lt;br /&gt;
* DateDoc (mandatory)&lt;br /&gt;
* DateAcct (mandatory)&lt;br /&gt;
* Doc_User_ID (either a column or a getter-methode, which reads out a column like SalesRep_ID or standard logic, e.g. '@$C_Currency_ID@').&lt;br /&gt;
* C_Currency_ID (mandatory; Standardlogik e.g. &amp;quot;@$C_Currency_ID@')&lt;br /&gt;
* DocAction (mandatory; 2 characters; default 'CO'; pushbutton; reference &amp;quot;_Document Action&amp;quot;; here will be a process indicated, which indicates the according workflow of our document type)&lt;br /&gt;
* DocStatus (mandatory; 2 characters; default 'DR'; list reference; Referenz &amp;quot;_Document Status&amp;quot; )&lt;br /&gt;
* processed (mandatory; default 'N')&lt;br /&gt;
* processing (mandatory; default 'N') - after Dantam's article is a varchar(1), supposely the pushbutton. For example in C_Invoice is the same process inscribed like in DocAction. But until now I have no idea why you need two columns.&lt;br /&gt;
* isApproved (mandatory; default 'Y')&lt;br /&gt;
&lt;br /&gt;
=== What does DocumentEngine do in the process? ===&lt;br /&gt;
&lt;br /&gt;
Document actions will be done by the class DocEngine. Who wants to conduct a status operation, can do this best with the odel-method processIt(). This should invoke the accordingly method of DocEngine, which takes over the management of different status possibilties.&lt;br /&gt;
&lt;br /&gt;
* http://www.adempiere.com/Document_Engine - u.a. links to Sourcecode of Doc_* classes&lt;br /&gt;
* http://www.adempiere.com/Development_Guidelines_in_German#Klasse_DocumentEngine - german introduction, written quite well&lt;br /&gt;
&lt;br /&gt;
== Workflow ==&lt;br /&gt;
&lt;br /&gt;
You can install a receipt-Workflow which defines the change between several status values. You define a Workflow with three nodes: Start, Prepare and Complete. The two last ones will be combined with the last receipt action, therewith these take action. Then you definde a transition which in each case from Start to Prepare and from Prepare to Complete.&lt;br /&gt;
&lt;br /&gt;
This defined Workflow provides for properly done documents. It serves for further experiments.&lt;br /&gt;
&lt;br /&gt;
=== Reversing documents ===&lt;br /&gt;
&lt;br /&gt;
Who wants to reverse documents, requires these following columns in addition:&lt;br /&gt;
&lt;br /&gt;
* Reversal_ID (reference type table, as a reference you need to register new created table reference, which close about my whole table and can be assorted after DocumentNo)&lt;br /&gt;
&lt;br /&gt;
I never tried this reversal. Probably you need to configure an accordingly Workflow. Besides this you should be very careful, if you want to reverse booked documents.&lt;br /&gt;
&lt;br /&gt;
=== Reactivating Documents ===&lt;br /&gt;
&lt;br /&gt;
I would like to reactivate my document, after it is finalizied. In addition I created a further node 'Reactivate' and attached this with the accordingly receipt action. Then I definded a second transition with the start to Reactivate. The first transition has a condition, which only takes action, if 'Doc-Action = 'CO''. Besides this the first transition obtains a small order of numbers, which executes first.&lt;br /&gt;
&lt;br /&gt;
As a matter of principle the reactivating requires a reversal of the effects of the document. This implementation is not needed, but I recommend you this.&lt;br /&gt;
&lt;br /&gt;
=== Approval / Freigabe ===&lt;br /&gt;
&lt;br /&gt;
Workflows erlauben auch, die Bearbeitung eines Dokumentes von einer vorherigen Freigabe abhängig zu machen. So können z.B. Rechnungen über 1.000,- € immer erst dem Vorgesetzten vorgelegt werden oder dergleichen.&lt;br /&gt;
&lt;br /&gt;
* http://www.adempiere.com/How_to_Activate_Document_Approval_Workflow&lt;br /&gt;
&lt;br /&gt;
=== More about Workflows ===&lt;br /&gt;
&lt;br /&gt;
taken from http://en.wikiversity.org/wiki/Adempiere_Technical_Training#Document_Process_Workflow:&lt;br /&gt;
&lt;br /&gt;
Every document has a defined process – the workflow is started with the Process button:&amp;lt;br /&amp;gt;&lt;br /&gt;
These workflows have a defined start context (the document) and a responsible.&lt;br /&gt;
* Start (Draft)&lt;br /&gt;
** Auto&lt;br /&gt;
** Prepare (In Progress)&lt;br /&gt;
*** Complete (Completed)&lt;br /&gt;
&lt;br /&gt;
If you want to customize a workflow for a document:&amp;lt;br /&amp;gt;&lt;br /&gt;
* for all clients&lt;br /&gt;
** add customized node/transitions and/or inactivate standard transitions&lt;br /&gt;
* for a client or organization&lt;br /&gt;
** make changes on System workflow with entity type &amp;lt;&amp;gt; Dictionary/Adempiere&lt;br /&gt;
** execute process “Workflow to Client”&lt;br /&gt;
&lt;br /&gt;
== Booking Document ==&lt;br /&gt;
&lt;br /&gt;
A document that can generate its own posting lines must contain the following fields:&lt;br /&gt;
&lt;br /&gt;
* Posted (mandatory; boolean; default 'N')&lt;br /&gt;
* ProcessedOn (integer)&lt;br /&gt;
* C_DocType_ID (mandatory; Table; reference C_DocType)&lt;br /&gt;
&lt;br /&gt;
The corresponding logic is activated by the presence of the &amp;quot;Posted&amp;quot; field. In this case, after completing a document, an update class matching the model is used to carry out the update. For this there is the convention that this ends on &amp;quot;_Doc&amp;quot;. Within the iDempiere kernel, the name of this class (based on this convention) is automatically determined. In ADempiere this was also the case for own classes. In iDempiere, which no longer allows core access to our plugin classes through the OSGi packages, there is a factory for that purpose.&lt;br /&gt;
&lt;br /&gt;
== Document base type ==&lt;br /&gt;
&lt;br /&gt;
Our new document type must also have an entry in the database. However, we first have to think about which basic type he belongs to. This base type is used for sorting and grouping document types, in particular for the document type input fields. In addition, the period can be opened or closed in the period control (in the calendar) for each individual basic document category. Although, interestingly enough, it is not necessarily mandatory, it still makes sense to set up a document base type for your own accounting document class.&lt;br /&gt;
&lt;br /&gt;
The base document type consists of an entry in the reference list &amp;quot;C_DocType DocBaseType&amp;quot; and always has three letters. If you want, you can set up a type &amp;quot;DOC&amp;quot; for all your documents here. However, it makes more sense to create your own basic types for each document type you create. Then, a selection field in the window can be validated to filter for this basic type and the user will always be able to generate their own derivations later.&lt;br /&gt;
&lt;br /&gt;
For some base types of the standard iDempiere, multiple base types work with objects of the same table. For example, by splitting &amp;quot;API Accounts Payable Invoice&amp;quot; and &amp;quot;ARI Accounts Receivable Invoice&amp;quot; ensures that incoming and outgoing invoices are never mixed. Although both are in the same table and use much the same business logic, they each have their own windows and are also distinguished by the field &amp;quot;isSOTrx&amp;quot; (and the different base document type). Due to the two basic document types, a simple validation on the input field for the document type is enough, so that you can only select sales document types for customers and vice versa.&lt;br /&gt;
&lt;br /&gt;
After you have created the basic document categories (in the system client), you should now call the process &amp;quot;Check Document Types&amp;quot; in the client. This creates a document type for each base document type and also directly creates corresponding period entries in the calendar.&lt;br /&gt;
&lt;br /&gt;
The automatically generated document types can be viewed in the &amp;quot;Document type&amp;quot; window and adjusted if necessary. It is recommended to activate number management and specify (or create) a document number range.&lt;br /&gt;
&lt;br /&gt;
In this window you can now derive even more document types from its basic document category. This has different purposes:&lt;br /&gt;
&lt;br /&gt;
* First of all, this can serve the in-house grouping of documents. Anyone who thinks in his business that a bill of goods is different from a service bill and a foreign bill, in turn, differently and a freight bill, can divide this so without much trouble.&lt;br /&gt;
* You can specify your own print format (in this window) and make the printed receipt look very different.&lt;br /&gt;
* You can group direct bookings (batches) using the direct posting type (fee type depending on the translation) and only allow specific bookings for certain document types. Thus, the freight invoice can be posted to the account for freight, the foreign invoice to the account for customs, etc.&lt;br /&gt;
&lt;br /&gt;
Next, you should create a validation rule. This gets the name &amp;quot;C_DocType MyPatementName&amp;quot; and as SQL-Code something like the following line:&lt;br /&gt;
&lt;br /&gt;
  C_DocType.DocBaseType IN ('ARZ', 'APZ') AND C_DocType.IsSOTrx='@IsSOTrx@'  AND C_DocType.AD_Client_ID=@#AD_Client_ID@&lt;br /&gt;
&lt;br /&gt;
Of course, you can omit the part with IsSOTrx if we do not have a separate document type for input and output windows. This part of the formula ensures that we can use identical field definitions for incoming and outgoing documents. The two windows then differ only in that the context variable &amp;quot;IsSOTrx&amp;quot; is set when the window is opened. This will then control everything else. This value can be set in the window definition.&lt;br /&gt;
&lt;br /&gt;
== Purchase and sales documents ==&lt;br /&gt;
&lt;br /&gt;
If you have a document category that is supposed to post different purchasing and sales documents (AP and AR), you also need this field. With this type of document, it is generally appropriate to also generate two separate basic document types and possibly two separate windows. The window definitions can be largely identical except for the &amp;quot;Sales Transaction&amp;quot; entry, which sets the context variable &amp;quot;IsSOTrx&amp;quot; and thus makes it distinguishable.&lt;br /&gt;
&lt;br /&gt;
* isSOTrx (mandatory; boolean, in the window best not displayed nciht or at least write-protected)&lt;br /&gt;
&lt;br /&gt;
== Windows, tabs &amp;amp; fields ==&lt;br /&gt;
&lt;br /&gt;
The window should be set to the window type &amp;quot;Transaction&amp;quot;. This turns on [[http://www.adempiere.com/History History]]. This ensures that only the current and incomplete documents are displayed.&lt;br /&gt;
&lt;br /&gt;
Incidentally, when configuring the window, the following fields should be displayed (according to Dantam):&lt;br /&gt;
&lt;br /&gt;
* Processed (set to &amp;quot;Read Only&amp;quot;)&lt;br /&gt;
* DocStatus (set to &amp;quot;Read Only&amp;quot;)&lt;br /&gt;
* DocAction&lt;br /&gt;
* Currency (if used, it may be read-only)&lt;br /&gt;
&lt;br /&gt;
For documents that differentiate purchasing and sales documents, it makes sense to copy them and introduce a WHERE clause, so that you have two windows for these actually different document types. You can define a window as a sales transaction in the window definition, and thus set a context variable that is used in many queries and validations to ensure that all fields work properly. Of course, this requires some care in generating your own queries, but there are enough existing examples, such &amp;quot;Invoice (Customer)&amp;quot; and &amp;quot;Invoice (Supplier)&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Print ==&lt;br /&gt;
&lt;br /&gt;
Basically, you can print a record by clicking on the button in the toolbar for a report. This will then create a print format that you can adjust accordingly. If you often want to have individual data sets, for example As a form print as a list of sentences, so it is useful to activate the print button, with which you can print individual records. This is done by making an entry in the Process &amp;amp; Report window. This was set to &amp;quot;Report&amp;quot; and indicates, if necessary, a prepared print format. This can then be started with the buttons for &amp;quot;Print&amp;quot; and &amp;quot;Print preview&amp;quot; by entering it in the window register record.&lt;br /&gt;
&lt;br /&gt;
By the way, there is a little problem here. You have to set up the &amp;quot;Process &amp;amp; Report&amp;quot; window in the system client, whereas most of the time you have prepared your print format in the normal client. You can release the print format in this case. It is automatically selected the one that has set the field &amp;quot;Standard&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
=== Use Report View to print more columns than shown in the table ===&lt;br /&gt;
&lt;br /&gt;
An extension can be added by entering a similar entry in the field &amp;quot;Report view&amp;quot; in &amp;quot;Process &amp;amp; Report&amp;quot;. In this case, a print format is selected that has selected this report view. This allows you to narrow the selection of the print format even further.&lt;br /&gt;
&lt;br /&gt;
In particular, one can also specify a report view based on a completely different table. This table should only contain the primary key field of our document because it will filter out the printed record. I used this, for example, to use a database view instead of the table edited in the current window for the expression, which, while based on that same table, adds a lot of additional data via JOIN. This large amount of information can then be restricted (if you like) through a report view and then processed in print format. Such a print format is created in the window &amp;quot;Print format&amp;quot;, where you can set the table and the view when creating the record. Then you create the fields by means of the automatic process button for this purpose and can then set the print format already in the target window and use it there in the print view. If this is the first time to see, then you can customize it as usual resulting print formats.&lt;br /&gt;
&lt;br /&gt;
=== Print by program ===&lt;br /&gt;
&lt;br /&gt;
In my model for the BAY_InterestCalculation table, I can use the following method to get an expression based on a view called RV_BAY_InterestCalculation. One can use this method e.g. in completeIt () to make sure that a document is always printed when it completes. Incidentally, one can set in the process window whether the printout happens immediately in the background or only with consultation.&lt;br /&gt;
&lt;br /&gt;
  public void print() {&lt;br /&gt;
    int viewTable = MTable.getTable_ID(&amp;quot;RV_&amp;quot; + Table_Name);&lt;br /&gt;
    MPrintFormat format = new Query(getCtx(), MPrintFormat.Table_Name, MPrintFormat.COLUMNNAME_AD_Table_ID&lt;br /&gt;
      + &amp;quot;=? AND &amp;quot; + MPrintFormat.COLUMNNAME_IsDefault + &amp;quot;=? &amp;quot;, get_TrxName()).setParameters(viewTable, &amp;quot;Y&amp;quot;)&lt;br /&gt;
      .first();&lt;br /&gt;
    MQuery query = new MQuery(get_Table_ID());&lt;br /&gt;
    query.addRestriction(get_KeyColumns()[0], MQuery.EQUAL, get_ID());&lt;br /&gt;
    PrintInfo info = new PrintInfo(getDocumentInfo(), get_Table_ID(), get_ID());&lt;br /&gt;
    ReportEngine re = new ReportEngine(getCtx(), format, query, info, get_TrxName());&lt;br /&gt;
    re.print();&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
= Links =&lt;br /&gt;
&lt;br /&gt;
== Articles that explain documents ==&lt;br /&gt;
&lt;br /&gt;
basic statements&lt;br /&gt;
&lt;br /&gt;
* http://wiki.idempiere.org/en/Create_a_custom_document_class - quite new article by Daniel Tamm in the iDempiere Wiki, still has many gaps&lt;br /&gt;
* http://www.adempiere.com/How_to_create_a_new_document_with_specific_accounting&lt;br /&gt;
&lt;br /&gt;
further explanations&lt;br /&gt;
&lt;br /&gt;
* http://www.adempiere.com/How_to_Activate_Document_Approval_Workflow&lt;br /&gt;
* http://www.adempiere.com/Document_Action_Dialog - Explanation of the action button and the window that opens up&lt;br /&gt;
* http://www.adempiere.com/Document_Sequence - Document Sequence&lt;br /&gt;
* Extensions&lt;br /&gt;
** http://www.adempiere.com/Enhance_Document_No_Formatting - Improvement of document numbering (this allows context variables)&lt;br /&gt;
** http://wiki.idempiere.org/en/NF001_Document_Sequence_Improved - Improvement of organizations and restart of number ranges&lt;br /&gt;
** http://www.adempiere.com/Sponsored_Development:_Document_Signing - Document Signing Extension, evidently never realized&lt;br /&gt;
&lt;br /&gt;
Articles that I use as sources, but have already incorporated much here:&lt;br /&gt;
&lt;br /&gt;
* http://www.adempiere.com/HOWTO_Process_Documents - quite well explains the use of existing document types; less the development of new ones&lt;br /&gt;
* http://en.wikiversity.org/wiki/Adempiere_Technical_Training#Document_Process_Workflow - contains short but insightful parts on the topic, in particular &amp;quot;Document Process Workflow&amp;quot;&lt;br /&gt;
* http://www.adempiere.com/Document_Engine&lt;br /&gt;
* https://groups.google.com/forum/#!topic/idempiere/WtTlVL1ZjWw - Briefed forum thread about how to implement a workflow&lt;br /&gt;
&lt;br /&gt;
Windows related to documents:&lt;br /&gt;
&lt;br /&gt;
* http://wiki.idempiere.org/en/Document_Type_%28Window_ID-135%29&lt;br /&gt;
* http://wiki.idempiere.org/en/Document_Sequence_%28Window_ID-112%29&lt;br /&gt;
&lt;br /&gt;
* http://wiki.idempiere.org/en/Unprocessed_Documents_%28All%29_%28Window_ID-53087%29&lt;br /&gt;
* http://wiki.idempiere.org/en/UnPosted_Documents_%28Window_ID-294%29&lt;br /&gt;
* http://wiki.idempiere.org/en/My_Unprocessed_Documents_%28Window_ID-53086%29&lt;br /&gt;
* http://wiki.idempiere.org/de/Workflow_%28Fenster_ID-113%29&lt;br /&gt;
&lt;br /&gt;
(What is the difference between &amp;quot;unprocessed&amp;quot; and &amp;quot;unposted&amp;quot; and how do these windows know which tables to scan?)&lt;br /&gt;
&lt;br /&gt;
* http://wiki.idempiere.org/en/Verify_Document_Types_%28Process_ID-233%29 - what does this process do? He probably creates open entries for new document types. Is there anything else?&lt;br /&gt;
&lt;br /&gt;
= weitere Informationen =&lt;br /&gt;
&lt;br /&gt;
== involvierte Klassen und Interfaces ==&lt;br /&gt;
&lt;br /&gt;
=== MSetup ===&lt;br /&gt;
&lt;br /&gt;
Create the list of document type for new Client ( Method createAccounting ). &lt;br /&gt;
&lt;br /&gt;
=== org.compiere.server.AcctProcessor ===&lt;br /&gt;
&lt;br /&gt;
Background process running on the JBoss server that perform the accounting document posting process. &lt;br /&gt;
&lt;br /&gt;
=== org.compiere.grid.ed.VDocAction ===&lt;br /&gt;
&lt;br /&gt;
Define hardcoded in dynInit method the list of possible transitions, and transitions by table &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Beispiele für die Implementierung einiger DocAction-Methoden =&lt;br /&gt;
&lt;br /&gt;
=== getDocumentInfo() ===&lt;br /&gt;
&lt;br /&gt;
Ergibt eine kurze aber eindeutige Bezeichnung des Datensatzes, die vor allem in Logzeilen und sonstigen Programm-Mitteilungen verwendet wird. Dieses Beispiel nutzt einen vorhandenen Documenttyp.&lt;br /&gt;
&lt;br /&gt;
  public String getDocumentInfo(){&lt;br /&gt;
    MDocType dt = MDocType.get(getCtx(), getC_DocType_ID());&lt;br /&gt;
    String msgreturn = dt.getNameTrl()+&amp;quot; &amp;quot;+getDocumentNo();&lt;br /&gt;
    return msgreturn.toString();&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
=== createPDF() ===&lt;br /&gt;
&lt;br /&gt;
Es gibt eine Methode, um das Dokument als PDF auszugeben. Diese wird - soweit ich gesehen habe - nur benutzt, um das Dokument per EMail zu versenden. Da man aber nie weiss, kann man das z.B. so wie folgend implementieren. Dabei kann man bei der Auswähl des Printformats natürlich auch genauer auswählen.&lt;br /&gt;
&lt;br /&gt;
  public File createPDF (){&lt;br /&gt;
    try{&lt;br /&gt;
      StringBuilder msgfile = new StringBuilder().append(get_TableName()).append(get_ID()).append(&amp;quot;_&amp;quot;);&lt;br /&gt;
      File temp = File.createTempFile(msgfile.toString(), &amp;quot;.pdf&amp;quot;);&lt;br /&gt;
      return createPDF (temp);&lt;br /&gt;
    }catch (Exception e){&lt;br /&gt;
      log.severe(&amp;quot;Could not create PDF - &amp;quot; + e.getMessage());&lt;br /&gt;
    }&lt;br /&gt;
    return null;&lt;br /&gt;
  }&lt;br /&gt;
  &lt;br /&gt;
  public File createPDF (File file){&lt;br /&gt;
    MPrintFormat format = MPrintFormat.get(getCtx(), 0, get_Table_ID());&lt;br /&gt;
    MQuery query=new MQuery(get_Table_ID());&lt;br /&gt;
    query.addRestriction(get_KeyColumns()[0],MQuery.EQUAL,get_ID());&lt;br /&gt;
    PrintInfo info = new PrintInfo(getDocumentNo(),get_Table_ID(),0);&lt;br /&gt;
    ReportEngine re = new ReportEngine(getCtx(), format, query, info, get_TrxName());&lt;br /&gt;
    &lt;br /&gt;
    if(format.getJasperProcess_ID() &amp;gt; 0){&lt;br /&gt;
      // JasperReports Print Format&lt;br /&gt;
      ProcessInfo pi = new ProcessInfo (&amp;quot;&amp;quot;, format.getJasperProcess_ID());&lt;br /&gt;
      pi.setRecord_ID(get_ID());&lt;br /&gt;
      pi.setIsBatch(true);&lt;br /&gt;
      ServerProcessCtl.process(pi, null);&lt;br /&gt;
      return pi.getPDFReport();&lt;br /&gt;
    }else{&lt;br /&gt;
      // Standard Print Format (Non-Jasper)&lt;br /&gt;
      return re.getPDF(file);&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Development‏‎]]&lt;br /&gt;
[[Category:Developer documentation‏‎]]&lt;br /&gt;
[[Category:System administration‏‎]]&lt;br /&gt;
[[Category:Applying means‏‎]]&lt;br /&gt;
[[Category:Document‎]]&lt;br /&gt;
[[Category:Workflow]]&lt;/div&gt;</summary>
		<author><name>Tioraul</name></author>
	</entry>
	<entry>
		<id>https://wiki.idempiere.org/w-en/index.php?title=Hackers_Guide_to_Documents&amp;diff=14308</id>
		<title>Hackers Guide to Documents</title>
		<link rel="alternate" type="text/html" href="https://wiki.idempiere.org/w-en/index.php?title=Hackers_Guide_to_Documents&amp;diff=14308"/>
		<updated>2018-07-27T22:41:25Z</updated>

		<summary type="html">&lt;p&gt;Tioraul: google translate&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Modes of document characteristics =&lt;br /&gt;
&lt;br /&gt;
== Document number ==&lt;br /&gt;
&lt;br /&gt;
If a table has a column with the title DocumentNo, it will be treated automatically in a special way. In the first usage of the table a sequence will be installed, which takes care of a consecutively document numeration. This document number can be edited more precisly in [[Belegnummernkreis (Fenster_ID-112)]]. It can be set as a determinded initial value or it can preserve a prefix or a suffix. Document numbers can also have a context variable where a date can be fit, e.g.Rechnung 00001/2014&amp;quot; (s.e.g. [[:en:NF001_Document_Sequence_Improved]]).&lt;br /&gt;
&lt;br /&gt;
== Model ==&lt;br /&gt;
&lt;br /&gt;
For a document type, which implements its own logic, you need to write a model. This means you create its own plugin, where you write a java class, the so-called model class (M*). This has to be derived from a predeterminded basis class (X_*). In turn this will be created with the help of the tool [[GenerateModel]] from the table definition of the data bank.&lt;br /&gt;
&lt;br /&gt;
=== Columns ===&lt;br /&gt;
&lt;br /&gt;
For the best you setup these following columns:&lt;br /&gt;
&lt;br /&gt;
* DocumentNo (mandatory; 30 Zeichen)&lt;br /&gt;
* DateDoc (mandatory)&lt;br /&gt;
* DateAcct (mandatory)&lt;br /&gt;
* Doc_User_ID (either a column or a getter-methode, which reads out a column like SalesRep_ID or standard logic, e.g. '@$C_Currency_ID@').&lt;br /&gt;
* C_Currency_ID (mandatory; Standardlogik e.g. &amp;quot;@$C_Currency_ID@')&lt;br /&gt;
* DocAction (mandatory; 2 characters; default 'CO'; pushbutton; reference &amp;quot;_Document Action&amp;quot;; here will be a process indicated, which indicates the according workflow of our document type)&lt;br /&gt;
* DocStatus (mandatory; 2 characters; default 'DR'; list reference; Referenz &amp;quot;_Document Status&amp;quot; )&lt;br /&gt;
* processed (mandatory; default 'N')&lt;br /&gt;
* processing (mandatory; default 'N') - after Dantam's article is a varchar(1), supposely the pushbutton. For example in C_Invoice is the same process inscribed like in DocAction. But until now I have no idea why you need two columns.&lt;br /&gt;
* isApproved (mandatory; default 'Y')&lt;br /&gt;
&lt;br /&gt;
=== What does DocumentEngine do in the process? ===&lt;br /&gt;
&lt;br /&gt;
Document actions will be done by the class DocEngine. Who wants to conduct a status operation, can do this best with the odel-method processIt(). This should invoke the accordingly method of DocEngine, which takes over the management of different status possibilties.&lt;br /&gt;
&lt;br /&gt;
* http://www.adempiere.com/Document_Engine - u.a. links to Sourcecode of Doc_* classes&lt;br /&gt;
* http://www.adempiere.com/Development_Guidelines_in_German#Klasse_DocumentEngine - german introduction, written quite well&lt;br /&gt;
&lt;br /&gt;
== Workflow ==&lt;br /&gt;
&lt;br /&gt;
You can install a receipt-Workflow which defines the change between several status values. You define a Workflow with three nodes: Start, Prepare and Complete. The two last ones will be combined with the last receipt action, therewith these take action. Then you definde a transition which in each case from Start to Prepare and from Prepare to Complete.&lt;br /&gt;
&lt;br /&gt;
This defined Workflow provides for properly done documents. It serves for further experiments.&lt;br /&gt;
&lt;br /&gt;
=== Reversing documents ===&lt;br /&gt;
&lt;br /&gt;
Who wants to reverse documents, requires these following columns in addition:&lt;br /&gt;
&lt;br /&gt;
* Reversal_ID (reference type table, as a reference you need to register new created table reference, which close about my whole table and can be assorted after DocumentNo)&lt;br /&gt;
&lt;br /&gt;
I never tried this reversal. Probably you need to configure an accordingly Workflow. Besides this you should be very careful, if you want to reverse booked documents.&lt;br /&gt;
&lt;br /&gt;
=== Reactivating Documents ===&lt;br /&gt;
&lt;br /&gt;
I would like to reactivate my document, after it is finalizied. In addition I created a further node 'Reactivate' and attached this with the accordingly receipt action. Then I definded a second transition with the start to Reactivate. The first transition has a condition, which only takes action, if 'Doc-Action = 'CO''. Besides this the first transition obtains a small order of numbers, which executes first.&lt;br /&gt;
&lt;br /&gt;
As a matter of principle the reactivating requires a reversal of the effects of the document. This implementation is not needed, but I recommend you this.&lt;br /&gt;
&lt;br /&gt;
=== Approval / Freigabe ===&lt;br /&gt;
&lt;br /&gt;
Workflows erlauben auch, die Bearbeitung eines Dokumentes von einer vorherigen Freigabe abhängig zu machen. So können z.B. Rechnungen über 1.000,- € immer erst dem Vorgesetzten vorgelegt werden oder dergleichen.&lt;br /&gt;
&lt;br /&gt;
* http://www.adempiere.com/How_to_Activate_Document_Approval_Workflow&lt;br /&gt;
&lt;br /&gt;
=== More about Workflows ===&lt;br /&gt;
&lt;br /&gt;
taken from http://en.wikiversity.org/wiki/Adempiere_Technical_Training#Document_Process_Workflow:&lt;br /&gt;
&lt;br /&gt;
Every document has a defined process – the workflow is started with the Process button:&amp;lt;br /&amp;gt;&lt;br /&gt;
These workflows have a defined start context (the document) and a responsible.&lt;br /&gt;
* Start (Draft)&lt;br /&gt;
** Auto&lt;br /&gt;
** Prepare (In Progress)&lt;br /&gt;
*** Complete (Completed)&lt;br /&gt;
&lt;br /&gt;
If you want to customize a workflow for a document:&amp;lt;br /&amp;gt;&lt;br /&gt;
* for all clients&lt;br /&gt;
** add customized node/transitions and/or inactivate standard transitions&lt;br /&gt;
* for a client or organization&lt;br /&gt;
** make changes on System workflow with entity type &amp;lt;&amp;gt; Dictionary/Adempiere&lt;br /&gt;
** execute process “Workflow to Client”&lt;br /&gt;
&lt;br /&gt;
== Booking Document ==&lt;br /&gt;
&lt;br /&gt;
A document that can generate its own posting lines must contain the following fields:&lt;br /&gt;
&lt;br /&gt;
* Posted (mandatory; boolean; default 'N')&lt;br /&gt;
* ProcessedOn (integer)&lt;br /&gt;
* C_DocType_ID (mandatory; Table; reference C_DocType)&lt;br /&gt;
&lt;br /&gt;
The corresponding logic is activated by the presence of the &amp;quot;Posted&amp;quot; field. In this case, after completing a document, an update class matching the model is used to carry out the update. For this there is the convention that this ends on &amp;quot;_Doc&amp;quot;. Within the iDempiere kernel, the name of this class (based on this convention) is automatically determined. In ADempiere this was also the case for own classes. In iDempiere, which no longer allows core access to our plugin classes through the OSGi packages, there is a factory for that purpose.&lt;br /&gt;
&lt;br /&gt;
== Document base type ==&lt;br /&gt;
&lt;br /&gt;
Our new document type must also have an entry in the database. However, we first have to think about which basic type he belongs to. This base type is used for sorting and grouping document types, in particular for the document type input fields. In addition, the period can be opened or closed in the period control (in the calendar) for each individual basic document category. Although, interestingly enough, it is not necessarily mandatory, it still makes sense to set up a document base type for your own accounting document class.&lt;br /&gt;
&lt;br /&gt;
The base document type consists of an entry in the reference list &amp;quot;C_DocType DocBaseType&amp;quot; and always has three letters. If you want, you can set up a type &amp;quot;DOC&amp;quot; for all your documents here. However, it makes more sense to create your own basic types for each document type you create. Then, a selection field in the window can be validated to filter for this basic type and the user will always be able to generate their own derivations later.&lt;br /&gt;
&lt;br /&gt;
For some base types of the standard iDempiere, multiple base types work with objects of the same table. For example, by splitting &amp;quot;API Accounts Payable Invoice&amp;quot; and &amp;quot;ARI Accounts Receivable Invoice&amp;quot; ensures that incoming and outgoing invoices are never mixed. Although both are in the same table and use much the same business logic, they each have their own windows and are also distinguished by the field &amp;quot;isSOTrx&amp;quot; (and the different base document type). Due to the two basic document types, a simple validation on the input field for the document type is enough, so that you can only select sales document types for customers and vice versa.&lt;br /&gt;
&lt;br /&gt;
After you have created the basic document categories (in the system client), you should now call the process &amp;quot;Check Document Types&amp;quot; in the client. This creates a document type for each base document type and also directly creates corresponding period entries in the calendar.&lt;br /&gt;
&lt;br /&gt;
The automatically generated document types can be viewed in the &amp;quot;Document type&amp;quot; window and adjusted if necessary. It is recommended to activate number management and specify (or create) a document number range.&lt;br /&gt;
&lt;br /&gt;
In this window you can now derive even more document types from its basic document category. This has different purposes:&lt;br /&gt;
&lt;br /&gt;
* First of all, this can serve the in-house grouping of documents. Anyone who thinks in his business that a bill of goods is different from a service bill and a foreign bill, in turn, differently and a freight bill, can divide this so without much trouble.&lt;br /&gt;
* You can specify your own print format (in this window) and make the printed receipt look very different.&lt;br /&gt;
* You can group direct bookings (batches) using the direct posting type (fee type depending on the translation) and only allow specific bookings for certain document types. Thus, the freight invoice can be posted to the account for freight, the foreign invoice to the account for customs, etc.&lt;br /&gt;
&lt;br /&gt;
Next, you should create a validation rule. This gets the name &amp;quot;C_DocType MyPatementName&amp;quot; and as SQL-Code something like the following line:&lt;br /&gt;
&lt;br /&gt;
  C_DocType.DocBaseType IN ('ARZ', 'APZ') AND C_DocType.IsSOTrx='@IsSOTrx@'  AND C_DocType.AD_Client_ID=@#AD_Client_ID@&lt;br /&gt;
&lt;br /&gt;
Of course, you can omit the part with IsSOTrx if we do not have a separate document type for input and output windows. This part of the formula ensures that we can use identical field definitions for incoming and outgoing documents. The two windows then differ only in that the context variable &amp;quot;IsSOTrx&amp;quot; is set when the window is opened. This will then control everything else. This value can be set in the window definition.&lt;br /&gt;
&lt;br /&gt;
== Purchase and sales documents ==&lt;br /&gt;
&lt;br /&gt;
If you have a document category that is supposed to post different purchasing and sales documents (AP and AR), you also need this field. With this type of document, it is generally appropriate to also generate two separate basic document types and possibly two separate windows. The window definitions can be largely identical except for the &amp;quot;Sales Transaction&amp;quot; entry, which sets the context variable &amp;quot;IsSOTrx&amp;quot; and thus makes it distinguishable.&lt;br /&gt;
&lt;br /&gt;
* isSOTrx (mandatory; boolean, in the window best not displayed nciht or at least write-protected)&lt;br /&gt;
&lt;br /&gt;
== Windows, tabs &amp;amp; fields ==&lt;br /&gt;
&lt;br /&gt;
The window should be set to the window type &amp;quot;Transaction&amp;quot;. This turns on [[http://www.adempiere.com/History History]]. This ensures that only the current and incomplete documents are displayed.&lt;br /&gt;
&lt;br /&gt;
Incidentally, when configuring the window, the following fields should be displayed (according to Dantam):&lt;br /&gt;
&lt;br /&gt;
* Processed (set to &amp;quot;Read Only&amp;quot;)&lt;br /&gt;
* DocStatus (set to &amp;quot;Read Only&amp;quot;)&lt;br /&gt;
* DocAction&lt;br /&gt;
* Currency (if used, it may be read-only)&lt;br /&gt;
&lt;br /&gt;
For documents that differentiate purchasing and sales documents, it makes sense to copy them and introduce a WHERE clause, so that you have two windows for these actually different document types. You can define a window as a sales transaction in the window definition, and thus set a context variable that is used in many queries and validations to ensure that all fields work properly. Of course, this requires some care in generating your own queries, but there are enough existing examples, such &amp;quot;Invoice (Customer)&amp;quot; and &amp;quot;Invoice (Supplier)&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Print ==&lt;br /&gt;
&lt;br /&gt;
Basically, you can print a record by clicking on the button in the toolbar for a report. This will then create a print format that you can adjust accordingly. If you often want to have individual data sets, for example As a form print as a list of sentences, so it is useful to activate the print button, with which you can print individual records. This is done by making an entry in the Process &amp;amp; Report window. This was set to &amp;quot;Report&amp;quot; and indicates, if necessary, a prepared print format. This can then be started with the buttons for &amp;quot;Print&amp;quot; and &amp;quot;Print preview&amp;quot; by entering it in the window register record.&lt;br /&gt;
&lt;br /&gt;
By the way, there is a little problem here. You have to set up the &amp;quot;Process &amp;amp; Report&amp;quot; window in the system client, whereas most of the time you have prepared your print format in the normal client. You can release the print format in this case. It is automatically selected the one that has set the field &amp;quot;Standard&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
=== Use Report View to print more columns than shown in the table ===&lt;br /&gt;
&lt;br /&gt;
An extension can be added by entering a similar entry in the field &amp;quot;Report view&amp;quot; in &amp;quot;Process &amp;amp; Report&amp;quot;. In this case, a print format is selected that has selected this report view. This allows you to narrow the selection of the print format even further.&lt;br /&gt;
&lt;br /&gt;
In particular, one can also specify a report view based on a completely different table. This table should only contain the primary key field of our document because it will filter out the printed record. I used this, for example, to use a database view instead of the table edited in the current window for the expression, which, while based on that same table, adds a lot of additional data via JOIN. This large amount of information can then be restricted (if you like) through a report view and then processed in print format. Such a print format is created in the window &amp;quot;Print format&amp;quot;, where you can set the table and the view when creating the record. Then you create the fields by means of the automatic process button for this purpose and can then set the print format already in the target window and use it there in the print view. If this is the first time to see, then you can customize it as usual resulting print formats.&lt;br /&gt;
&lt;br /&gt;
=== Print by program ===&lt;br /&gt;
&lt;br /&gt;
In my model for the BAY_InterestCalculation table, I can use the following method to get an expression based on a view called RV_BAY_InterestCalculation. One can use this method e.g. in completeIt () to make sure that a document is always printed when it completes. Incidentally, one can set in the process window whether the printout happens immediately in the background or only with consultation.&lt;br /&gt;
&lt;br /&gt;
  public void print() {&lt;br /&gt;
    int viewTable = MTable.getTable_ID(&amp;quot;RV_&amp;quot; + Table_Name);&lt;br /&gt;
    MPrintFormat format = new Query(getCtx(), MPrintFormat.Table_Name, MPrintFormat.COLUMNNAME_AD_Table_ID&lt;br /&gt;
      + &amp;quot;=? AND &amp;quot; + MPrintFormat.COLUMNNAME_IsDefault + &amp;quot;=? &amp;quot;, get_TrxName()).setParameters(viewTable, &amp;quot;Y&amp;quot;)&lt;br /&gt;
      .first();&lt;br /&gt;
    MQuery query = new MQuery(get_Table_ID());&lt;br /&gt;
    query.addRestriction(get_KeyColumns()[0], MQuery.EQUAL, get_ID());&lt;br /&gt;
    PrintInfo info = new PrintInfo(getDocumentInfo(), get_Table_ID(), get_ID());&lt;br /&gt;
    ReportEngine re = new ReportEngine(getCtx(), format, query, info, get_TrxName());&lt;br /&gt;
    re.print();&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
= Links =&lt;br /&gt;
&lt;br /&gt;
== Artikel, die Dokumente erklären ==&lt;br /&gt;
&lt;br /&gt;
Basiserklärungen&lt;br /&gt;
&lt;br /&gt;
* http://wiki.idempiere.org/en/Create_a_custom_document_class - recht neuer Artikel von Daniel Tamm im iDempiere Wiki, hat noch viele Lücken&lt;br /&gt;
* http://www.adempiere.com/How_to_create_a_new_document_with_specific_accounting&lt;br /&gt;
&lt;br /&gt;
weiterführende Erklärungen&lt;br /&gt;
&lt;br /&gt;
* http://www.adempiere.com/How_to_Activate_Document_Approval_Workflow&lt;br /&gt;
* http://www.adempiere.com/Document_Action_Dialog - Erklärung zum Action Button und dem davon aufgehenden Fenster&lt;br /&gt;
* http://www.adempiere.com/Document_Sequence - Document Sequence&lt;br /&gt;
* Erweiterungen&lt;br /&gt;
** http://www.adempiere.com/Enhance_Document_No_Formatting - Verbesserung der Dokumentnummerierung (hierdurch sind Kontextvariablen erlaubt)&lt;br /&gt;
** http://wiki.idempiere.org/en/NF001_Document_Sequence_Improved - Verbesserung bzgl. Organisationen und Neustart von Nummernkreisen&lt;br /&gt;
** http://www.adempiere.com/Sponsored_Development:_Document_Signing - Document Signing Erweiterung, augenscheinlich nie verwirklicht worden&lt;br /&gt;
&lt;br /&gt;
Artikel, die ich als Quellen verwendet, aber bereits weitgehend hier eingearbeitet habe:&lt;br /&gt;
&lt;br /&gt;
* http://www.adempiere.com/HOWTO_Process_Documents - erklärt recht gut die Benutzung der vorhandenen Dokumenttypen; weniger die Entwicklung neuer&lt;br /&gt;
* http://en.wikiversity.org/wiki/Adempiere_Technical_Training#Document_Process_Workflow - enthält kurze, aber aufschlussreiche Teile zum Thema, insbesondere &amp;quot;Document Process Workflow&amp;quot;&lt;br /&gt;
* http://www.adempiere.com/Document_Engine&lt;br /&gt;
* https://groups.google.com/forum/#!topic/idempiere/WtTlVL1ZjWw - kurzed Forumsthread darüber, wie man einen Workflow implementieren kann&lt;br /&gt;
&lt;br /&gt;
Fenster, die mit Dokumenten zusammenhängen:&lt;br /&gt;
&lt;br /&gt;
* http://wiki.idempiere.org/en/Document_Type_%28Window_ID-135%29&lt;br /&gt;
* http://wiki.idempiere.org/en/Document_Sequence_%28Window_ID-112%29&lt;br /&gt;
&lt;br /&gt;
* http://wiki.idempiere.org/en/Unprocessed_Documents_%28All%29_%28Window_ID-53087%29&lt;br /&gt;
* http://wiki.idempiere.org/en/UnPosted_Documents_%28Window_ID-294%29&lt;br /&gt;
* http://wiki.idempiere.org/en/My_Unprocessed_Documents_%28Window_ID-53086%29&lt;br /&gt;
* http://wiki.idempiere.org/de/Workflow_%28Fenster_ID-113%29&lt;br /&gt;
&lt;br /&gt;
(Was ist der Unterschied zwischen &amp;quot;unprocessed&amp;quot; und &amp;quot;unposted&amp;quot; und woher wissen diese Fenster, welche Tabellen sie absuchen sollen?)&lt;br /&gt;
&lt;br /&gt;
* http://wiki.idempiere.org/en/Verify_Document_Types_%28Process_ID-233%29 - was macht dieser Prozeß? Er erzeugt wohl Open-Einträge für neue Dokumenttypen. Sonst noch was?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= weitere Informationen =&lt;br /&gt;
&lt;br /&gt;
== involvierte Klassen und Interfaces ==&lt;br /&gt;
&lt;br /&gt;
=== MSetup ===&lt;br /&gt;
&lt;br /&gt;
Create the list of document type for new Client ( Method createAccounting ). &lt;br /&gt;
&lt;br /&gt;
=== org.compiere.server.AcctProcessor ===&lt;br /&gt;
&lt;br /&gt;
Background process running on the JBoss server that perform the accounting document posting process. &lt;br /&gt;
&lt;br /&gt;
=== org.compiere.grid.ed.VDocAction ===&lt;br /&gt;
&lt;br /&gt;
Define hardcoded in dynInit method the list of possible transitions, and transitions by table &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Beispiele für die Implementierung einiger DocAction-Methoden =&lt;br /&gt;
&lt;br /&gt;
=== getDocumentInfo() ===&lt;br /&gt;
&lt;br /&gt;
Ergibt eine kurze aber eindeutige Bezeichnung des Datensatzes, die vor allem in Logzeilen und sonstigen Programm-Mitteilungen verwendet wird. Dieses Beispiel nutzt einen vorhandenen Documenttyp.&lt;br /&gt;
&lt;br /&gt;
  public String getDocumentInfo(){&lt;br /&gt;
    MDocType dt = MDocType.get(getCtx(), getC_DocType_ID());&lt;br /&gt;
    String msgreturn = dt.getNameTrl()+&amp;quot; &amp;quot;+getDocumentNo();&lt;br /&gt;
    return msgreturn.toString();&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
=== createPDF() ===&lt;br /&gt;
&lt;br /&gt;
Es gibt eine Methode, um das Dokument als PDF auszugeben. Diese wird - soweit ich gesehen habe - nur benutzt, um das Dokument per EMail zu versenden. Da man aber nie weiss, kann man das z.B. so wie folgend implementieren. Dabei kann man bei der Auswähl des Printformats natürlich auch genauer auswählen.&lt;br /&gt;
&lt;br /&gt;
  public File createPDF (){&lt;br /&gt;
    try{&lt;br /&gt;
      StringBuilder msgfile = new StringBuilder().append(get_TableName()).append(get_ID()).append(&amp;quot;_&amp;quot;);&lt;br /&gt;
      File temp = File.createTempFile(msgfile.toString(), &amp;quot;.pdf&amp;quot;);&lt;br /&gt;
      return createPDF (temp);&lt;br /&gt;
    }catch (Exception e){&lt;br /&gt;
      log.severe(&amp;quot;Could not create PDF - &amp;quot; + e.getMessage());&lt;br /&gt;
    }&lt;br /&gt;
    return null;&lt;br /&gt;
  }&lt;br /&gt;
  &lt;br /&gt;
  public File createPDF (File file){&lt;br /&gt;
    MPrintFormat format = MPrintFormat.get(getCtx(), 0, get_Table_ID());&lt;br /&gt;
    MQuery query=new MQuery(get_Table_ID());&lt;br /&gt;
    query.addRestriction(get_KeyColumns()[0],MQuery.EQUAL,get_ID());&lt;br /&gt;
    PrintInfo info = new PrintInfo(getDocumentNo(),get_Table_ID(),0);&lt;br /&gt;
    ReportEngine re = new ReportEngine(getCtx(), format, query, info, get_TrxName());&lt;br /&gt;
    &lt;br /&gt;
    if(format.getJasperProcess_ID() &amp;gt; 0){&lt;br /&gt;
      // JasperReports Print Format&lt;br /&gt;
      ProcessInfo pi = new ProcessInfo (&amp;quot;&amp;quot;, format.getJasperProcess_ID());&lt;br /&gt;
      pi.setRecord_ID(get_ID());&lt;br /&gt;
      pi.setIsBatch(true);&lt;br /&gt;
      ServerProcessCtl.process(pi, null);&lt;br /&gt;
      return pi.getPDFReport();&lt;br /&gt;
    }else{&lt;br /&gt;
      // Standard Print Format (Non-Jasper)&lt;br /&gt;
      return re.getPDF(file);&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Development‏‎]]&lt;br /&gt;
[[Category:Developer documentation‏‎]]&lt;br /&gt;
[[Category:System administration‏‎]]&lt;br /&gt;
[[Category:Applying means‏‎]]&lt;br /&gt;
[[Category:Document‎]]&lt;br /&gt;
[[Category:Workflow]]&lt;/div&gt;</summary>
		<author><name>Tioraul</name></author>
	</entry>
	<entry>
		<id>https://wiki.idempiere.org/w-en/index.php?title=Hackers_Guide_to_Documents&amp;diff=14307</id>
		<title>Hackers Guide to Documents</title>
		<link rel="alternate" type="text/html" href="https://wiki.idempiere.org/w-en/index.php?title=Hackers_Guide_to_Documents&amp;diff=14307"/>
		<updated>2018-07-27T22:35:51Z</updated>

		<summary type="html">&lt;p&gt;Tioraul: google translate&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Modes of document characteristics =&lt;br /&gt;
&lt;br /&gt;
== Document number ==&lt;br /&gt;
&lt;br /&gt;
If a table has a column with the title DocumentNo, it will be treated automatically in a special way. In the first usage of the table a sequence will be installed, which takes care of a consecutively document numeration. This document number can be edited more precisly in [[Belegnummernkreis (Fenster_ID-112)]]. It can be set as a determinded initial value or it can preserve a prefix or a suffix. Document numbers can also have a context variable where a date can be fit, e.g.Rechnung 00001/2014&amp;quot; (s.e.g. [[:en:NF001_Document_Sequence_Improved]]).&lt;br /&gt;
&lt;br /&gt;
== Model ==&lt;br /&gt;
&lt;br /&gt;
For a document type, which implements its own logic, you need to write a model. This means you create its own plugin, where you write a java class, the so-called model class (M*). This has to be derived from a predeterminded basis class (X_*). In turn this will be created with the help of the tool [[GenerateModel]] from the table definition of the data bank.&lt;br /&gt;
&lt;br /&gt;
=== Columns ===&lt;br /&gt;
&lt;br /&gt;
For the best you setup these following columns:&lt;br /&gt;
&lt;br /&gt;
* DocumentNo (mandatory; 30 Zeichen)&lt;br /&gt;
* DateDoc (mandatory)&lt;br /&gt;
* DateAcct (mandatory)&lt;br /&gt;
* Doc_User_ID (either a column or a getter-methode, which reads out a column like SalesRep_ID or standard logic, e.g. '@$C_Currency_ID@').&lt;br /&gt;
* C_Currency_ID (mandatory; Standardlogik e.g. &amp;quot;@$C_Currency_ID@')&lt;br /&gt;
* DocAction (mandatory; 2 characters; default 'CO'; pushbutton; reference &amp;quot;_Document Action&amp;quot;; here will be a process indicated, which indicates the according workflow of our document type)&lt;br /&gt;
* DocStatus (mandatory; 2 characters; default 'DR'; list reference; Referenz &amp;quot;_Document Status&amp;quot; )&lt;br /&gt;
* processed (mandatory; default 'N')&lt;br /&gt;
* processing (mandatory; default 'N') - after Dantam's article is a varchar(1), supposely the pushbutton. For example in C_Invoice is the same process inscribed like in DocAction. But until now I have no idea why you need two columns.&lt;br /&gt;
* isApproved (mandatory; default 'Y')&lt;br /&gt;
&lt;br /&gt;
=== What does DocumentEngine do in the process? ===&lt;br /&gt;
&lt;br /&gt;
Document actions will be done by the class DocEngine. Who wants to conduct a status operation, can do this best with the odel-method processIt(). This should invoke the accordingly method of DocEngine, which takes over the management of different status possibilties.&lt;br /&gt;
&lt;br /&gt;
* http://www.adempiere.com/Document_Engine - u.a. links to Sourcecode of Doc_* classes&lt;br /&gt;
* http://www.adempiere.com/Development_Guidelines_in_German#Klasse_DocumentEngine - german introduction, written quite well&lt;br /&gt;
&lt;br /&gt;
== Workflow ==&lt;br /&gt;
&lt;br /&gt;
You can install a receipt-Workflow which defines the change between several status values. You define a Workflow with three nodes: Start, Prepare and Complete. The two last ones will be combined with the last receipt action, therewith these take action. Then you definde a transition which in each case from Start to Prepare and from Prepare to Complete.&lt;br /&gt;
&lt;br /&gt;
This defined Workflow provides for properly done documents. It serves for further experiments.&lt;br /&gt;
&lt;br /&gt;
=== Reversing documents ===&lt;br /&gt;
&lt;br /&gt;
Who wants to reverse documents, requires these following columns in addition:&lt;br /&gt;
&lt;br /&gt;
* Reversal_ID (reference type table, as a reference you need to register new created table reference, which close about my whole table and can be assorted after DocumentNo)&lt;br /&gt;
&lt;br /&gt;
I never tried this reversal. Probably you need to configure an accordingly Workflow. Besides this you should be very careful, if you want to reverse booked documents.&lt;br /&gt;
&lt;br /&gt;
=== Reactivating Documents ===&lt;br /&gt;
&lt;br /&gt;
I would like to reactivate my document, after it is finalizied. In addition I created a further node 'Reactivate' and attached this with the accordingly receipt action. Then I definded a second transition with the start to Reactivate. The first transition has a condition, which only takes action, if 'Doc-Action = 'CO''. Besides this the first transition obtains a small order of numbers, which executes first.&lt;br /&gt;
&lt;br /&gt;
As a matter of principle the reactivating requires a reversal of the effects of the document. This implementation is not needed, but I recommend you this.&lt;br /&gt;
&lt;br /&gt;
=== Approval / Freigabe ===&lt;br /&gt;
&lt;br /&gt;
Workflows erlauben auch, die Bearbeitung eines Dokumentes von einer vorherigen Freigabe abhängig zu machen. So können z.B. Rechnungen über 1.000,- € immer erst dem Vorgesetzten vorgelegt werden oder dergleichen.&lt;br /&gt;
&lt;br /&gt;
* http://www.adempiere.com/How_to_Activate_Document_Approval_Workflow&lt;br /&gt;
&lt;br /&gt;
=== More about Workflows ===&lt;br /&gt;
&lt;br /&gt;
taken from http://en.wikiversity.org/wiki/Adempiere_Technical_Training#Document_Process_Workflow:&lt;br /&gt;
&lt;br /&gt;
Every document has a defined process – the workflow is started with the Process button:&amp;lt;br /&amp;gt;&lt;br /&gt;
These workflows have a defined start context (the document) and a responsible.&lt;br /&gt;
* Start (Draft)&lt;br /&gt;
** Auto&lt;br /&gt;
** Prepare (In Progress)&lt;br /&gt;
*** Complete (Completed)&lt;br /&gt;
&lt;br /&gt;
If you want to customize a workflow for a document:&amp;lt;br /&amp;gt;&lt;br /&gt;
* for all clients&lt;br /&gt;
** add customized node/transitions and/or inactivate standard transitions&lt;br /&gt;
* for a client or organization&lt;br /&gt;
** make changes on System workflow with entity type &amp;lt;&amp;gt; Dictionary/Adempiere&lt;br /&gt;
** execute process “Workflow to Client”&lt;br /&gt;
&lt;br /&gt;
== Booking Document ==&lt;br /&gt;
&lt;br /&gt;
A document that can generate its own posting lines must contain the following fields:&lt;br /&gt;
&lt;br /&gt;
* Posted (mandatory; boolean; default 'N')&lt;br /&gt;
* ProcessedOn (integer)&lt;br /&gt;
* C_DocType_ID (mandatory; Table; reference C_DocType)&lt;br /&gt;
&lt;br /&gt;
The corresponding logic is activated by the presence of the &amp;quot;Posted&amp;quot; field. In this case, after completing a document, an update class matching the model is used to carry out the update. For this there is the convention that this ends on &amp;quot;_Doc&amp;quot;. Within the iDempiere kernel, the name of this class (based on this convention) is automatically determined. In ADempiere this was also the case for own classes. In iDempiere, which no longer allows core access to our plugin classes through the OSGi packages, there is a factory for that purpose.&lt;br /&gt;
&lt;br /&gt;
== Document base type ==&lt;br /&gt;
&lt;br /&gt;
Our new document type must also have an entry in the database. However, we first have to think about which basic type he belongs to. This base type is used for sorting and grouping document types, in particular for the document type input fields. In addition, the period can be opened or closed in the period control (in the calendar) for each individual basic document category. Although, interestingly enough, it is not necessarily mandatory, it still makes sense to set up a document base type for your own accounting document class.&lt;br /&gt;
&lt;br /&gt;
The base document type consists of an entry in the reference list &amp;quot;C_DocType DocBaseType&amp;quot; and always has three letters. If you want, you can set up a type &amp;quot;DOC&amp;quot; for all your documents here. However, it makes more sense to create your own basic types for each document type you create. Then, a selection field in the window can be validated to filter for this basic type and the user will always be able to generate their own derivations later.&lt;br /&gt;
&lt;br /&gt;
For some base types of the standard iDempiere, multiple base types work with objects of the same table. For example, by splitting &amp;quot;API Accounts Payable Invoice&amp;quot; and &amp;quot;ARI Accounts Receivable Invoice&amp;quot; ensures that incoming and outgoing invoices are never mixed. Although both are in the same table and use much the same business logic, they each have their own windows and are also distinguished by the field &amp;quot;isSOTrx&amp;quot; (and the different base document type). Due to the two basic document types, a simple validation on the input field for the document type is enough, so that you can only select sales document types for customers and vice versa.&lt;br /&gt;
&lt;br /&gt;
After you have created the basic document categories (in the system client), you should now call the process &amp;quot;Check Document Types&amp;quot; in the client. This creates a document type for each base document type and also directly creates corresponding period entries in the calendar.&lt;br /&gt;
&lt;br /&gt;
The automatically generated document types can be viewed in the &amp;quot;Document type&amp;quot; window and adjusted if necessary. It is recommended to activate number management and specify (or create) a document number range.&lt;br /&gt;
&lt;br /&gt;
In this window you can now derive even more document types from its basic document category. This has different purposes:&lt;br /&gt;
&lt;br /&gt;
* First of all, this can serve the in-house grouping of documents. Anyone who thinks in his business that a bill of goods is different from a service bill and a foreign bill, in turn, differently and a freight bill, can divide this so without much trouble.&lt;br /&gt;
* You can specify your own print format (in this window) and make the printed receipt look very different.&lt;br /&gt;
* You can group direct bookings (batches) using the direct posting type (fee type depending on the translation) and only allow specific bookings for certain document types. Thus, the freight invoice can be posted to the account for freight, the foreign invoice to the account for customs, etc.&lt;br /&gt;
&lt;br /&gt;
Next, you should create a validation rule. This gets the name &amp;quot;C_DocType MyPatementName&amp;quot; and as SQL-Code something like the following line:&lt;br /&gt;
&lt;br /&gt;
  C_DocType.DocBaseType IN ('ARZ', 'APZ') AND C_DocType.IsSOTrx='@IsSOTrx@'  AND C_DocType.AD_Client_ID=@#AD_Client_ID@&lt;br /&gt;
&lt;br /&gt;
Of course, you can omit the part with IsSOTrx if we do not have a separate document type for input and output windows. This part of the formula ensures that we can use identical field definitions for incoming and outgoing documents. The two windows then differ only in that the context variable &amp;quot;IsSOTrx&amp;quot; is set when the window is opened. This will then control everything else. This value can be set in the window definition.&lt;br /&gt;
&lt;br /&gt;
== Purchase and sales documents ==&lt;br /&gt;
&lt;br /&gt;
If you have a document category that is supposed to post different purchasing and sales documents (AP and AR), you also need this field. With this type of document, it is generally appropriate to also generate two separate basic document types and possibly two separate windows. The window definitions can be largely identical except for the &amp;quot;Sales Transaction&amp;quot; entry, which sets the context variable &amp;quot;IsSOTrx&amp;quot; and thus makes it distinguishable.&lt;br /&gt;
&lt;br /&gt;
* isSOTrx (mandatory; boolean, in the window best not displayed nciht or at least write-protected)&lt;br /&gt;
&lt;br /&gt;
== Windows, tabs &amp;amp; fields ==&lt;br /&gt;
&lt;br /&gt;
The window should be set to the window type &amp;quot;Transaction&amp;quot;. This turns on [[http://www.adempiere.com/History History]]. This ensures that only the current and incomplete documents are displayed.&lt;br /&gt;
&lt;br /&gt;
Incidentally, when configuring the window, the following fields should be displayed (according to Dantam):&lt;br /&gt;
&lt;br /&gt;
* Processed (set to &amp;quot;Read Only&amp;quot;)&lt;br /&gt;
* DocStatus (set to &amp;quot;Read Only&amp;quot;)&lt;br /&gt;
* DocAction&lt;br /&gt;
* Currency (if used, it may be read-only)&lt;br /&gt;
&lt;br /&gt;
For documents that differentiate purchasing and sales documents, it makes sense to copy them and introduce a WHERE clause, so that you have two windows for these actually different document types. You can define a window as a sales transaction in the window definition, and thus set a context variable that is used in many queries and validations to ensure that all fields work properly. Of course, this requires some care in generating your own queries, but there are enough existing examples, such &amp;quot;Invoice (Customer)&amp;quot; and &amp;quot;Invoice (Supplier)&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Drucken ==&lt;br /&gt;
&lt;br /&gt;
Grnudsätzlich kann man einen Datensatz ausdrucken, indem man in der Toolbar auf den Button für einen entsprechenden Bericht klickt. Durch diesen wird dann ein Druckformat erzeugt, das man entsprechend anpassen kann. Will man oft eher einzelne Datensätze z.B. als Formular drucken als eine Liste von Sätzen, so bietet es sich an, den Druck-Button zu aktivieren, mit dem man einzelne Datensätze drucken kann. Das macht man, indem man im Fenster &amp;quot;Prozeß &amp;amp; Bericht&amp;quot; einen Eintrag macht. Diesen setzte man auf &amp;quot;Bericht&amp;quot; und gibt ggf. ein vorbereitetes Druckformat an. Dieses kann dann mit mit den Buttons für &amp;quot;Druck&amp;quot; und &amp;quot;Druckvorschau&amp;quot; gestartet werden, indem man es im Datensatz des Fensterregisters einträgt.&lt;br /&gt;
&lt;br /&gt;
Hier gibt es übrigens ein kleines Problem. Das Fenster &amp;quot;Prozeß &amp;amp; Bericht&amp;quot; muss man im Systemmandanten einrichten, während man sein Druckformat ja zumeist vorher im normalen Mandanten vorbereitet hat. Man kann in diesem Fall das Druckformat freilassen. Es wird automatisch das gewählt, das das Feld &amp;quot;Standard&amp;quot; gesetzt hat.&lt;br /&gt;
&lt;br /&gt;
=== Berichtsansicht benutzen, um mehr Spalten auszudrucken als in der Tabelle stehen ===&lt;br /&gt;
&lt;br /&gt;
Eine Erweiterung gibt es noch, indem man in &amp;quot;Prozeß &amp;amp; Bericht&amp;quot; im Feld &amp;quot;Berichtsansicht&amp;quot; eine ebensolche einträgt. In diesem Fall wird ein Druckformat ausgewählt, das ebendiese Berichtsansicht ausgewählt hat. Hierdurch kann man die Auswahl des Druckformats noch weiter eingrenzen.&lt;br /&gt;
&lt;br /&gt;
Insbesondere kann man hier auch eine Berichtsansicht angeben, die auf einer ganz anderen Tabelle basiert. Diese Tabelle sollte lediglich das Primärschlüsselfeld unseres Dokumentes beinhalten, weil hierdurch der ausgedruckte Datensatz heruasgefiltert wird. Ich habe das beispielsweise benutzt, um anstatt der im aktuellen Fenster bearbeiteten Tabelle ein Datenbank-View für den Ausdruck zu benutzen, das zwar auf ebendieser Tabelle basiert, ihnr per JOIN aber jede Menge weitere Daten hinzufügt. Diese grosse Menge an Informationen kann man dann (wenn man möchte) durch eine Berichtsansicht wieder einschränken und dann im Druckformat verarbeiten. Ein derartiges Druckformat erzeugt man im Fenster &amp;quot;Druckformat&amp;quot;, wo man die Tabelle und die Ansicht bei der Neuanlage des Datensatzes einstellen kann. Dann erzeugt man die Felder mittels des automatischen Proßess-Knopfes hierfür und kann dann das Druckformat schon im Zielfenster einstellen und dort in der Druckansicht benutzen. Ist diese das erste Mal zu sehen, kann man es dann wie gewöhnlich entstandene Druckformate auch anpassen.&lt;br /&gt;
&lt;br /&gt;
=== Drucken per Programm ===&lt;br /&gt;
&lt;br /&gt;
Mit der folgenden Methode kann ich in meinem Model für die Tabelle BAY_InterestCalculation einen Ausdruck veranlassen, der auf einem View basiert, das RV_BAY_InterestCalculation heisst. Man kann diese Methode z.B. in completeIt() aufrufen, um dafür zu sorgen, das ein Dokument immer gedruckt wird, wenn es abgeschlossen wird. Man kann übrigens im Prozeßfenster einstellen, ob der Ausdruck sofort im Hintergrund oder erst mit Rückfrage geschieht.&lt;br /&gt;
&lt;br /&gt;
  public void print() {&lt;br /&gt;
    int viewTable = MTable.getTable_ID(&amp;quot;RV_&amp;quot; + Table_Name);&lt;br /&gt;
    MPrintFormat format = new Query(getCtx(), MPrintFormat.Table_Name, MPrintFormat.COLUMNNAME_AD_Table_ID&lt;br /&gt;
      + &amp;quot;=? AND &amp;quot; + MPrintFormat.COLUMNNAME_IsDefault + &amp;quot;=? &amp;quot;, get_TrxName()).setParameters(viewTable, &amp;quot;Y&amp;quot;)&lt;br /&gt;
      .first();&lt;br /&gt;
    MQuery query = new MQuery(get_Table_ID());&lt;br /&gt;
    query.addRestriction(get_KeyColumns()[0], MQuery.EQUAL, get_ID());&lt;br /&gt;
    PrintInfo info = new PrintInfo(getDocumentInfo(), get_Table_ID(), get_ID());&lt;br /&gt;
    ReportEngine re = new ReportEngine(getCtx(), format, query, info, get_TrxName());&lt;br /&gt;
    re.print();&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
= Links =&lt;br /&gt;
&lt;br /&gt;
== Artikel, die Dokumente erklären ==&lt;br /&gt;
&lt;br /&gt;
Basiserklärungen&lt;br /&gt;
&lt;br /&gt;
* http://wiki.idempiere.org/en/Create_a_custom_document_class - recht neuer Artikel von Daniel Tamm im iDempiere Wiki, hat noch viele Lücken&lt;br /&gt;
* http://www.adempiere.com/How_to_create_a_new_document_with_specific_accounting&lt;br /&gt;
&lt;br /&gt;
weiterführende Erklärungen&lt;br /&gt;
&lt;br /&gt;
* http://www.adempiere.com/How_to_Activate_Document_Approval_Workflow&lt;br /&gt;
* http://www.adempiere.com/Document_Action_Dialog - Erklärung zum Action Button und dem davon aufgehenden Fenster&lt;br /&gt;
* http://www.adempiere.com/Document_Sequence - Document Sequence&lt;br /&gt;
* Erweiterungen&lt;br /&gt;
** http://www.adempiere.com/Enhance_Document_No_Formatting - Verbesserung der Dokumentnummerierung (hierdurch sind Kontextvariablen erlaubt)&lt;br /&gt;
** http://wiki.idempiere.org/en/NF001_Document_Sequence_Improved - Verbesserung bzgl. Organisationen und Neustart von Nummernkreisen&lt;br /&gt;
** http://www.adempiere.com/Sponsored_Development:_Document_Signing - Document Signing Erweiterung, augenscheinlich nie verwirklicht worden&lt;br /&gt;
&lt;br /&gt;
Artikel, die ich als Quellen verwendet, aber bereits weitgehend hier eingearbeitet habe:&lt;br /&gt;
&lt;br /&gt;
* http://www.adempiere.com/HOWTO_Process_Documents - erklärt recht gut die Benutzung der vorhandenen Dokumenttypen; weniger die Entwicklung neuer&lt;br /&gt;
* http://en.wikiversity.org/wiki/Adempiere_Technical_Training#Document_Process_Workflow - enthält kurze, aber aufschlussreiche Teile zum Thema, insbesondere &amp;quot;Document Process Workflow&amp;quot;&lt;br /&gt;
* http://www.adempiere.com/Document_Engine&lt;br /&gt;
* https://groups.google.com/forum/#!topic/idempiere/WtTlVL1ZjWw - kurzed Forumsthread darüber, wie man einen Workflow implementieren kann&lt;br /&gt;
&lt;br /&gt;
Fenster, die mit Dokumenten zusammenhängen:&lt;br /&gt;
&lt;br /&gt;
* http://wiki.idempiere.org/en/Document_Type_%28Window_ID-135%29&lt;br /&gt;
* http://wiki.idempiere.org/en/Document_Sequence_%28Window_ID-112%29&lt;br /&gt;
&lt;br /&gt;
* http://wiki.idempiere.org/en/Unprocessed_Documents_%28All%29_%28Window_ID-53087%29&lt;br /&gt;
* http://wiki.idempiere.org/en/UnPosted_Documents_%28Window_ID-294%29&lt;br /&gt;
* http://wiki.idempiere.org/en/My_Unprocessed_Documents_%28Window_ID-53086%29&lt;br /&gt;
* http://wiki.idempiere.org/de/Workflow_%28Fenster_ID-113%29&lt;br /&gt;
&lt;br /&gt;
(Was ist der Unterschied zwischen &amp;quot;unprocessed&amp;quot; und &amp;quot;unposted&amp;quot; und woher wissen diese Fenster, welche Tabellen sie absuchen sollen?)&lt;br /&gt;
&lt;br /&gt;
* http://wiki.idempiere.org/en/Verify_Document_Types_%28Process_ID-233%29 - was macht dieser Prozeß? Er erzeugt wohl Open-Einträge für neue Dokumenttypen. Sonst noch was?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= weitere Informationen =&lt;br /&gt;
&lt;br /&gt;
== involvierte Klassen und Interfaces ==&lt;br /&gt;
&lt;br /&gt;
=== MSetup ===&lt;br /&gt;
&lt;br /&gt;
Create the list of document type for new Client ( Method createAccounting ). &lt;br /&gt;
&lt;br /&gt;
=== org.compiere.server.AcctProcessor ===&lt;br /&gt;
&lt;br /&gt;
Background process running on the JBoss server that perform the accounting document posting process. &lt;br /&gt;
&lt;br /&gt;
=== org.compiere.grid.ed.VDocAction ===&lt;br /&gt;
&lt;br /&gt;
Define hardcoded in dynInit method the list of possible transitions, and transitions by table &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Beispiele für die Implementierung einiger DocAction-Methoden =&lt;br /&gt;
&lt;br /&gt;
=== getDocumentInfo() ===&lt;br /&gt;
&lt;br /&gt;
Ergibt eine kurze aber eindeutige Bezeichnung des Datensatzes, die vor allem in Logzeilen und sonstigen Programm-Mitteilungen verwendet wird. Dieses Beispiel nutzt einen vorhandenen Documenttyp.&lt;br /&gt;
&lt;br /&gt;
  public String getDocumentInfo(){&lt;br /&gt;
    MDocType dt = MDocType.get(getCtx(), getC_DocType_ID());&lt;br /&gt;
    String msgreturn = dt.getNameTrl()+&amp;quot; &amp;quot;+getDocumentNo();&lt;br /&gt;
    return msgreturn.toString();&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
=== createPDF() ===&lt;br /&gt;
&lt;br /&gt;
Es gibt eine Methode, um das Dokument als PDF auszugeben. Diese wird - soweit ich gesehen habe - nur benutzt, um das Dokument per EMail zu versenden. Da man aber nie weiss, kann man das z.B. so wie folgend implementieren. Dabei kann man bei der Auswähl des Printformats natürlich auch genauer auswählen.&lt;br /&gt;
&lt;br /&gt;
  public File createPDF (){&lt;br /&gt;
    try{&lt;br /&gt;
      StringBuilder msgfile = new StringBuilder().append(get_TableName()).append(get_ID()).append(&amp;quot;_&amp;quot;);&lt;br /&gt;
      File temp = File.createTempFile(msgfile.toString(), &amp;quot;.pdf&amp;quot;);&lt;br /&gt;
      return createPDF (temp);&lt;br /&gt;
    }catch (Exception e){&lt;br /&gt;
      log.severe(&amp;quot;Could not create PDF - &amp;quot; + e.getMessage());&lt;br /&gt;
    }&lt;br /&gt;
    return null;&lt;br /&gt;
  }&lt;br /&gt;
  &lt;br /&gt;
  public File createPDF (File file){&lt;br /&gt;
    MPrintFormat format = MPrintFormat.get(getCtx(), 0, get_Table_ID());&lt;br /&gt;
    MQuery query=new MQuery(get_Table_ID());&lt;br /&gt;
    query.addRestriction(get_KeyColumns()[0],MQuery.EQUAL,get_ID());&lt;br /&gt;
    PrintInfo info = new PrintInfo(getDocumentNo(),get_Table_ID(),0);&lt;br /&gt;
    ReportEngine re = new ReportEngine(getCtx(), format, query, info, get_TrxName());&lt;br /&gt;
    &lt;br /&gt;
    if(format.getJasperProcess_ID() &amp;gt; 0){&lt;br /&gt;
      // JasperReports Print Format&lt;br /&gt;
      ProcessInfo pi = new ProcessInfo (&amp;quot;&amp;quot;, format.getJasperProcess_ID());&lt;br /&gt;
      pi.setRecord_ID(get_ID());&lt;br /&gt;
      pi.setIsBatch(true);&lt;br /&gt;
      ServerProcessCtl.process(pi, null);&lt;br /&gt;
      return pi.getPDFReport();&lt;br /&gt;
    }else{&lt;br /&gt;
      // Standard Print Format (Non-Jasper)&lt;br /&gt;
      return re.getPDF(file);&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Development‏‎]]&lt;br /&gt;
[[Category:Developer documentation‏‎]]&lt;br /&gt;
[[Category:System administration‏‎]]&lt;br /&gt;
[[Category:Applying means‏‎]]&lt;br /&gt;
[[Category:Document‎]]&lt;br /&gt;
[[Category:Workflow]]&lt;/div&gt;</summary>
		<author><name>Tioraul</name></author>
	</entry>
	<entry>
		<id>https://wiki.idempiere.org/w-en/index.php?title=Hackers_Guide_to_Documents&amp;diff=14306</id>
		<title>Hackers Guide to Documents</title>
		<link rel="alternate" type="text/html" href="https://wiki.idempiere.org/w-en/index.php?title=Hackers_Guide_to_Documents&amp;diff=14306"/>
		<updated>2018-07-27T22:33:23Z</updated>

		<summary type="html">&lt;p&gt;Tioraul: google translate&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Modes of document characteristics =&lt;br /&gt;
&lt;br /&gt;
== Document number ==&lt;br /&gt;
&lt;br /&gt;
If a table has a column with the title DocumentNo, it will be treated automatically in a special way. In the first usage of the table a sequence will be installed, which takes care of a consecutively document numeration. This document number can be edited more precisly in [[Belegnummernkreis (Fenster_ID-112)]]. It can be set as a determinded initial value or it can preserve a prefix or a suffix. Document numbers can also have a context variable where a date can be fit, e.g.Rechnung 00001/2014&amp;quot; (s.e.g. [[:en:NF001_Document_Sequence_Improved]]).&lt;br /&gt;
&lt;br /&gt;
== Model ==&lt;br /&gt;
&lt;br /&gt;
For a document type, which implements its own logic, you need to write a model. This means you create its own plugin, where you write a java class, the so-called model class (M*). This has to be derived from a predeterminded basis class (X_*). In turn this will be created with the help of the tool [[GenerateModel]] from the table definition of the data bank.&lt;br /&gt;
&lt;br /&gt;
=== Columns ===&lt;br /&gt;
&lt;br /&gt;
For the best you setup these following columns:&lt;br /&gt;
&lt;br /&gt;
* DocumentNo (mandatory; 30 Zeichen)&lt;br /&gt;
* DateDoc (mandatory)&lt;br /&gt;
* DateAcct (mandatory)&lt;br /&gt;
* Doc_User_ID (either a column or a getter-methode, which reads out a column like SalesRep_ID or standard logic, e.g. '@$C_Currency_ID@').&lt;br /&gt;
* C_Currency_ID (mandatory; Standardlogik e.g. &amp;quot;@$C_Currency_ID@')&lt;br /&gt;
* DocAction (mandatory; 2 characters; default 'CO'; pushbutton; reference &amp;quot;_Document Action&amp;quot;; here will be a process indicated, which indicates the according workflow of our document type)&lt;br /&gt;
* DocStatus (mandatory; 2 characters; default 'DR'; list reference; Referenz &amp;quot;_Document Status&amp;quot; )&lt;br /&gt;
* processed (mandatory; default 'N')&lt;br /&gt;
* processing (mandatory; default 'N') - after Dantam's article is a varchar(1), supposely the pushbutton. For example in C_Invoice is the same process inscribed like in DocAction. But until now I have no idea why you need two columns.&lt;br /&gt;
* isApproved (mandatory; default 'Y')&lt;br /&gt;
&lt;br /&gt;
=== What does DocumentEngine do in the process? ===&lt;br /&gt;
&lt;br /&gt;
Document actions will be done by the class DocEngine. Who wants to conduct a status operation, can do this best with the odel-method processIt(). This should invoke the accordingly method of DocEngine, which takes over the management of different status possibilties.&lt;br /&gt;
&lt;br /&gt;
* http://www.adempiere.com/Document_Engine - u.a. links to Sourcecode of Doc_* classes&lt;br /&gt;
* http://www.adempiere.com/Development_Guidelines_in_German#Klasse_DocumentEngine - german introduction, written quite well&lt;br /&gt;
&lt;br /&gt;
== Workflow ==&lt;br /&gt;
&lt;br /&gt;
You can install a receipt-Workflow which defines the change between several status values. You define a Workflow with three nodes: Start, Prepare and Complete. The two last ones will be combined with the last receipt action, therewith these take action. Then you definde a transition which in each case from Start to Prepare and from Prepare to Complete.&lt;br /&gt;
&lt;br /&gt;
This defined Workflow provides for properly done documents. It serves for further experiments.&lt;br /&gt;
&lt;br /&gt;
=== Reversing documents ===&lt;br /&gt;
&lt;br /&gt;
Who wants to reverse documents, requires these following columns in addition:&lt;br /&gt;
&lt;br /&gt;
* Reversal_ID (reference type table, as a reference you need to register new created table reference, which close about my whole table and can be assorted after DocumentNo)&lt;br /&gt;
&lt;br /&gt;
I never tried this reversal. Probably you need to configure an accordingly Workflow. Besides this you should be very careful, if you want to reverse booked documents.&lt;br /&gt;
&lt;br /&gt;
=== Reactivating Documents ===&lt;br /&gt;
&lt;br /&gt;
I would like to reactivate my document, after it is finalizied. In addition I created a further node 'Reactivate' and attached this with the accordingly receipt action. Then I definded a second transition with the start to Reactivate. The first transition has a condition, which only takes action, if 'Doc-Action = 'CO''. Besides this the first transition obtains a small order of numbers, which executes first.&lt;br /&gt;
&lt;br /&gt;
As a matter of principle the reactivating requires a reversal of the effects of the document. This implementation is not needed, but I recommend you this.&lt;br /&gt;
&lt;br /&gt;
=== Approval / Freigabe ===&lt;br /&gt;
&lt;br /&gt;
Workflows erlauben auch, die Bearbeitung eines Dokumentes von einer vorherigen Freigabe abhängig zu machen. So können z.B. Rechnungen über 1.000,- € immer erst dem Vorgesetzten vorgelegt werden oder dergleichen.&lt;br /&gt;
&lt;br /&gt;
* http://www.adempiere.com/How_to_Activate_Document_Approval_Workflow&lt;br /&gt;
&lt;br /&gt;
=== More about Workflows ===&lt;br /&gt;
&lt;br /&gt;
taken from http://en.wikiversity.org/wiki/Adempiere_Technical_Training#Document_Process_Workflow:&lt;br /&gt;
&lt;br /&gt;
Every document has a defined process – the workflow is started with the Process button:&amp;lt;br /&amp;gt;&lt;br /&gt;
These workflows have a defined start context (the document) and a responsible.&lt;br /&gt;
* Start (Draft)&lt;br /&gt;
** Auto&lt;br /&gt;
** Prepare (In Progress)&lt;br /&gt;
*** Complete (Completed)&lt;br /&gt;
&lt;br /&gt;
If you want to customize a workflow for a document:&amp;lt;br /&amp;gt;&lt;br /&gt;
* for all clients&lt;br /&gt;
** add customized node/transitions and/or inactivate standard transitions&lt;br /&gt;
* for a client or organization&lt;br /&gt;
** make changes on System workflow with entity type &amp;lt;&amp;gt; Dictionary/Adempiere&lt;br /&gt;
** execute process “Workflow to Client”&lt;br /&gt;
&lt;br /&gt;
== Booking Document ==&lt;br /&gt;
&lt;br /&gt;
A document that can generate its own posting lines must contain the following fields:&lt;br /&gt;
&lt;br /&gt;
* Posted (mandatory; boolean; default 'N')&lt;br /&gt;
* ProcessedOn (integer)&lt;br /&gt;
* C_DocType_ID (mandatory; Table; reference C_DocType)&lt;br /&gt;
&lt;br /&gt;
The corresponding logic is activated by the presence of the &amp;quot;Posted&amp;quot; field. In this case, after completing a document, an update class matching the model is used to carry out the update. For this there is the convention that this ends on &amp;quot;_Doc&amp;quot;. Within the iDempiere kernel, the name of this class (based on this convention) is automatically determined. In ADempiere this was also the case for own classes. In iDempiere, which no longer allows core access to our plugin classes through the OSGi packages, there is a factory for that purpose.&lt;br /&gt;
&lt;br /&gt;
== Document base type ==&lt;br /&gt;
&lt;br /&gt;
Our new document type must also have an entry in the database. However, we first have to think about which basic type he belongs to. This base type is used for sorting and grouping document types, in particular for the document type input fields. In addition, the period can be opened or closed in the period control (in the calendar) for each individual basic document category. Although, interestingly enough, it is not necessarily mandatory, it still makes sense to set up a document base type for your own accounting document class.&lt;br /&gt;
&lt;br /&gt;
The base document type consists of an entry in the reference list &amp;quot;C_DocType DocBaseType&amp;quot; and always has three letters. If you want, you can set up a type &amp;quot;DOC&amp;quot; for all your documents here. However, it makes more sense to create your own basic types for each document type you create. Then, a selection field in the window can be validated to filter for this basic type and the user will always be able to generate their own derivations later.&lt;br /&gt;
&lt;br /&gt;
For some base types of the standard iDempiere, multiple base types work with objects of the same table. For example, by splitting &amp;quot;API Accounts Payable Invoice&amp;quot; and &amp;quot;ARI Accounts Receivable Invoice&amp;quot; ensures that incoming and outgoing invoices are never mixed. Although both are in the same table and use much the same business logic, they each have their own windows and are also distinguished by the field &amp;quot;isSOTrx&amp;quot; (and the different base document type). Due to the two basic document types, a simple validation on the input field for the document type is enough, so that you can only select sales document types for customers and vice versa.&lt;br /&gt;
&lt;br /&gt;
After you have created the basic document categories (in the system client), you should now call the process &amp;quot;Check Document Types&amp;quot; in the client. This creates a document type for each base document type and also directly creates corresponding period entries in the calendar.&lt;br /&gt;
&lt;br /&gt;
The automatically generated document types can be viewed in the &amp;quot;Document type&amp;quot; window and adjusted if necessary. It is recommended to activate number management and specify (or create) a document number range.&lt;br /&gt;
&lt;br /&gt;
In this window you can now derive even more document types from its basic document category. This has different purposes:&lt;br /&gt;
&lt;br /&gt;
* First of all, this can serve the in-house grouping of documents. Anyone who thinks in his business that a bill of goods is different from a service bill and a foreign bill, in turn, differently and a freight bill, can divide this so without much trouble.&lt;br /&gt;
* You can specify your own print format (in this window) and make the printed receipt look very different.&lt;br /&gt;
* You can group direct bookings (batches) using the direct posting type (fee type depending on the translation) and only allow specific bookings for certain document types. Thus, the freight invoice can be posted to the account for freight, the foreign invoice to the account for customs, etc.&lt;br /&gt;
&lt;br /&gt;
Next, you should create a validation rule. This gets the name &amp;quot;C_DocType MyPatementName&amp;quot; and as SQL-Code something like the following line:&lt;br /&gt;
&lt;br /&gt;
  C_DocType.DocBaseType IN ('ARZ', 'APZ') AND C_DocType.IsSOTrx='@IsSOTrx@'  AND C_DocType.AD_Client_ID=@#AD_Client_ID@&lt;br /&gt;
&lt;br /&gt;
Of course, you can omit the part with IsSOTrx if we do not have a separate document type for input and output windows. This part of the formula ensures that we can use identical field definitions for incoming and outgoing documents. The two windows then differ only in that the context variable &amp;quot;IsSOTrx&amp;quot; is set when the window is opened. This will then control everything else. This value can be set in the window definition.&lt;br /&gt;
&lt;br /&gt;
== Purchase and sales documents ==&lt;br /&gt;
&lt;br /&gt;
If you have a document category that is supposed to post different purchasing and sales documents (AP and AR), you also need this field. With this type of document, it is generally appropriate to also generate two separate basic document types and possibly two separate windows. The window definitions can be largely identical except for the &amp;quot;Sales Transaction&amp;quot; entry, which sets the context variable &amp;quot;IsSOTrx&amp;quot; and thus makes it distinguishable.&lt;br /&gt;
&lt;br /&gt;
* isSOTrx (mandatory; boolean, in the window best not displayed nciht or at least write-protected)&lt;br /&gt;
&lt;br /&gt;
== Fenster, Tab &amp;amp; Felder ==&lt;br /&gt;
&lt;br /&gt;
Das Fenster sollte auf den Fenstertyp &amp;quot;Transaktion&amp;quot; gesetzt werden. Dadurch wird die [[http://www.adempiere.com/History History-Funktion]] aktiviert. Diese sorgt dafür, das immer nur die aktuellen und nicht abgeschlossenen Dokumente angezeigt werden.&lt;br /&gt;
&lt;br /&gt;
Bei der Konfiguration des Fensters sollten übrigens die folgenden Felder angezeigt werden (laut Dantam):&lt;br /&gt;
&lt;br /&gt;
* Processed (set to &amp;quot;Read Only&amp;quot;)&lt;br /&gt;
* DocStatus (set to &amp;quot;Read Only&amp;quot;)&lt;br /&gt;
* DocAction&lt;br /&gt;
* Currency (wenn benutzt sollte es u.U. schreibgeschützt sein)&lt;br /&gt;
&lt;br /&gt;
Für Dokumente, die Einkaufs- und Verkaufsbelege unterscheiden, bietet es sich an, diese zu kopieren und eine WHERE-Klasel einzuführen, so das man zwei Fenster für diese eigentlich unterschiedlichen Belegtypen hat. Man kann in der Fensterdefinition ein Fenster als Verkaufstransaktion definieren und somit eine Kontextvariable setzen, die in vielen Abfragen und Validierungen benutzt wird, um sicherzustellen, das alle Felder entsprechend angepasst funktionieren. Das erfordert natürlich bei der Erzeugung eigener Abfragen etwas Sorgfalt, aber es gibt ja genug bestehende Beispiele wie z.B. &amp;quot;Rechnung (Kunde)&amp;quot; und &amp;quot;Rechnung (Lieferant)&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Drucken ==&lt;br /&gt;
&lt;br /&gt;
Grnudsätzlich kann man einen Datensatz ausdrucken, indem man in der Toolbar auf den Button für einen entsprechenden Bericht klickt. Durch diesen wird dann ein Druckformat erzeugt, das man entsprechend anpassen kann. Will man oft eher einzelne Datensätze z.B. als Formular drucken als eine Liste von Sätzen, so bietet es sich an, den Druck-Button zu aktivieren, mit dem man einzelne Datensätze drucken kann. Das macht man, indem man im Fenster &amp;quot;Prozeß &amp;amp; Bericht&amp;quot; einen Eintrag macht. Diesen setzte man auf &amp;quot;Bericht&amp;quot; und gibt ggf. ein vorbereitetes Druckformat an. Dieses kann dann mit mit den Buttons für &amp;quot;Druck&amp;quot; und &amp;quot;Druckvorschau&amp;quot; gestartet werden, indem man es im Datensatz des Fensterregisters einträgt.&lt;br /&gt;
&lt;br /&gt;
Hier gibt es übrigens ein kleines Problem. Das Fenster &amp;quot;Prozeß &amp;amp; Bericht&amp;quot; muss man im Systemmandanten einrichten, während man sein Druckformat ja zumeist vorher im normalen Mandanten vorbereitet hat. Man kann in diesem Fall das Druckformat freilassen. Es wird automatisch das gewählt, das das Feld &amp;quot;Standard&amp;quot; gesetzt hat.&lt;br /&gt;
&lt;br /&gt;
=== Berichtsansicht benutzen, um mehr Spalten auszudrucken als in der Tabelle stehen ===&lt;br /&gt;
&lt;br /&gt;
Eine Erweiterung gibt es noch, indem man in &amp;quot;Prozeß &amp;amp; Bericht&amp;quot; im Feld &amp;quot;Berichtsansicht&amp;quot; eine ebensolche einträgt. In diesem Fall wird ein Druckformat ausgewählt, das ebendiese Berichtsansicht ausgewählt hat. Hierdurch kann man die Auswahl des Druckformats noch weiter eingrenzen.&lt;br /&gt;
&lt;br /&gt;
Insbesondere kann man hier auch eine Berichtsansicht angeben, die auf einer ganz anderen Tabelle basiert. Diese Tabelle sollte lediglich das Primärschlüsselfeld unseres Dokumentes beinhalten, weil hierdurch der ausgedruckte Datensatz heruasgefiltert wird. Ich habe das beispielsweise benutzt, um anstatt der im aktuellen Fenster bearbeiteten Tabelle ein Datenbank-View für den Ausdruck zu benutzen, das zwar auf ebendieser Tabelle basiert, ihnr per JOIN aber jede Menge weitere Daten hinzufügt. Diese grosse Menge an Informationen kann man dann (wenn man möchte) durch eine Berichtsansicht wieder einschränken und dann im Druckformat verarbeiten. Ein derartiges Druckformat erzeugt man im Fenster &amp;quot;Druckformat&amp;quot;, wo man die Tabelle und die Ansicht bei der Neuanlage des Datensatzes einstellen kann. Dann erzeugt man die Felder mittels des automatischen Proßess-Knopfes hierfür und kann dann das Druckformat schon im Zielfenster einstellen und dort in der Druckansicht benutzen. Ist diese das erste Mal zu sehen, kann man es dann wie gewöhnlich entstandene Druckformate auch anpassen.&lt;br /&gt;
&lt;br /&gt;
=== Drucken per Programm ===&lt;br /&gt;
&lt;br /&gt;
Mit der folgenden Methode kann ich in meinem Model für die Tabelle BAY_InterestCalculation einen Ausdruck veranlassen, der auf einem View basiert, das RV_BAY_InterestCalculation heisst. Man kann diese Methode z.B. in completeIt() aufrufen, um dafür zu sorgen, das ein Dokument immer gedruckt wird, wenn es abgeschlossen wird. Man kann übrigens im Prozeßfenster einstellen, ob der Ausdruck sofort im Hintergrund oder erst mit Rückfrage geschieht.&lt;br /&gt;
&lt;br /&gt;
  public void print() {&lt;br /&gt;
    int viewTable = MTable.getTable_ID(&amp;quot;RV_&amp;quot; + Table_Name);&lt;br /&gt;
    MPrintFormat format = new Query(getCtx(), MPrintFormat.Table_Name, MPrintFormat.COLUMNNAME_AD_Table_ID&lt;br /&gt;
      + &amp;quot;=? AND &amp;quot; + MPrintFormat.COLUMNNAME_IsDefault + &amp;quot;=? &amp;quot;, get_TrxName()).setParameters(viewTable, &amp;quot;Y&amp;quot;)&lt;br /&gt;
      .first();&lt;br /&gt;
    MQuery query = new MQuery(get_Table_ID());&lt;br /&gt;
    query.addRestriction(get_KeyColumns()[0], MQuery.EQUAL, get_ID());&lt;br /&gt;
    PrintInfo info = new PrintInfo(getDocumentInfo(), get_Table_ID(), get_ID());&lt;br /&gt;
    ReportEngine re = new ReportEngine(getCtx(), format, query, info, get_TrxName());&lt;br /&gt;
    re.print();&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
= Links =&lt;br /&gt;
&lt;br /&gt;
== Artikel, die Dokumente erklären ==&lt;br /&gt;
&lt;br /&gt;
Basiserklärungen&lt;br /&gt;
&lt;br /&gt;
* http://wiki.idempiere.org/en/Create_a_custom_document_class - recht neuer Artikel von Daniel Tamm im iDempiere Wiki, hat noch viele Lücken&lt;br /&gt;
* http://www.adempiere.com/How_to_create_a_new_document_with_specific_accounting&lt;br /&gt;
&lt;br /&gt;
weiterführende Erklärungen&lt;br /&gt;
&lt;br /&gt;
* http://www.adempiere.com/How_to_Activate_Document_Approval_Workflow&lt;br /&gt;
* http://www.adempiere.com/Document_Action_Dialog - Erklärung zum Action Button und dem davon aufgehenden Fenster&lt;br /&gt;
* http://www.adempiere.com/Document_Sequence - Document Sequence&lt;br /&gt;
* Erweiterungen&lt;br /&gt;
** http://www.adempiere.com/Enhance_Document_No_Formatting - Verbesserung der Dokumentnummerierung (hierdurch sind Kontextvariablen erlaubt)&lt;br /&gt;
** http://wiki.idempiere.org/en/NF001_Document_Sequence_Improved - Verbesserung bzgl. Organisationen und Neustart von Nummernkreisen&lt;br /&gt;
** http://www.adempiere.com/Sponsored_Development:_Document_Signing - Document Signing Erweiterung, augenscheinlich nie verwirklicht worden&lt;br /&gt;
&lt;br /&gt;
Artikel, die ich als Quellen verwendet, aber bereits weitgehend hier eingearbeitet habe:&lt;br /&gt;
&lt;br /&gt;
* http://www.adempiere.com/HOWTO_Process_Documents - erklärt recht gut die Benutzung der vorhandenen Dokumenttypen; weniger die Entwicklung neuer&lt;br /&gt;
* http://en.wikiversity.org/wiki/Adempiere_Technical_Training#Document_Process_Workflow - enthält kurze, aber aufschlussreiche Teile zum Thema, insbesondere &amp;quot;Document Process Workflow&amp;quot;&lt;br /&gt;
* http://www.adempiere.com/Document_Engine&lt;br /&gt;
* https://groups.google.com/forum/#!topic/idempiere/WtTlVL1ZjWw - kurzed Forumsthread darüber, wie man einen Workflow implementieren kann&lt;br /&gt;
&lt;br /&gt;
Fenster, die mit Dokumenten zusammenhängen:&lt;br /&gt;
&lt;br /&gt;
* http://wiki.idempiere.org/en/Document_Type_%28Window_ID-135%29&lt;br /&gt;
* http://wiki.idempiere.org/en/Document_Sequence_%28Window_ID-112%29&lt;br /&gt;
&lt;br /&gt;
* http://wiki.idempiere.org/en/Unprocessed_Documents_%28All%29_%28Window_ID-53087%29&lt;br /&gt;
* http://wiki.idempiere.org/en/UnPosted_Documents_%28Window_ID-294%29&lt;br /&gt;
* http://wiki.idempiere.org/en/My_Unprocessed_Documents_%28Window_ID-53086%29&lt;br /&gt;
* http://wiki.idempiere.org/de/Workflow_%28Fenster_ID-113%29&lt;br /&gt;
&lt;br /&gt;
(Was ist der Unterschied zwischen &amp;quot;unprocessed&amp;quot; und &amp;quot;unposted&amp;quot; und woher wissen diese Fenster, welche Tabellen sie absuchen sollen?)&lt;br /&gt;
&lt;br /&gt;
* http://wiki.idempiere.org/en/Verify_Document_Types_%28Process_ID-233%29 - was macht dieser Prozeß? Er erzeugt wohl Open-Einträge für neue Dokumenttypen. Sonst noch was?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= weitere Informationen =&lt;br /&gt;
&lt;br /&gt;
== involvierte Klassen und Interfaces ==&lt;br /&gt;
&lt;br /&gt;
=== MSetup ===&lt;br /&gt;
&lt;br /&gt;
Create the list of document type for new Client ( Method createAccounting ). &lt;br /&gt;
&lt;br /&gt;
=== org.compiere.server.AcctProcessor ===&lt;br /&gt;
&lt;br /&gt;
Background process running on the JBoss server that perform the accounting document posting process. &lt;br /&gt;
&lt;br /&gt;
=== org.compiere.grid.ed.VDocAction ===&lt;br /&gt;
&lt;br /&gt;
Define hardcoded in dynInit method the list of possible transitions, and transitions by table &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Beispiele für die Implementierung einiger DocAction-Methoden =&lt;br /&gt;
&lt;br /&gt;
=== getDocumentInfo() ===&lt;br /&gt;
&lt;br /&gt;
Ergibt eine kurze aber eindeutige Bezeichnung des Datensatzes, die vor allem in Logzeilen und sonstigen Programm-Mitteilungen verwendet wird. Dieses Beispiel nutzt einen vorhandenen Documenttyp.&lt;br /&gt;
&lt;br /&gt;
  public String getDocumentInfo(){&lt;br /&gt;
    MDocType dt = MDocType.get(getCtx(), getC_DocType_ID());&lt;br /&gt;
    String msgreturn = dt.getNameTrl()+&amp;quot; &amp;quot;+getDocumentNo();&lt;br /&gt;
    return msgreturn.toString();&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
=== createPDF() ===&lt;br /&gt;
&lt;br /&gt;
Es gibt eine Methode, um das Dokument als PDF auszugeben. Diese wird - soweit ich gesehen habe - nur benutzt, um das Dokument per EMail zu versenden. Da man aber nie weiss, kann man das z.B. so wie folgend implementieren. Dabei kann man bei der Auswähl des Printformats natürlich auch genauer auswählen.&lt;br /&gt;
&lt;br /&gt;
  public File createPDF (){&lt;br /&gt;
    try{&lt;br /&gt;
      StringBuilder msgfile = new StringBuilder().append(get_TableName()).append(get_ID()).append(&amp;quot;_&amp;quot;);&lt;br /&gt;
      File temp = File.createTempFile(msgfile.toString(), &amp;quot;.pdf&amp;quot;);&lt;br /&gt;
      return createPDF (temp);&lt;br /&gt;
    }catch (Exception e){&lt;br /&gt;
      log.severe(&amp;quot;Could not create PDF - &amp;quot; + e.getMessage());&lt;br /&gt;
    }&lt;br /&gt;
    return null;&lt;br /&gt;
  }&lt;br /&gt;
  &lt;br /&gt;
  public File createPDF (File file){&lt;br /&gt;
    MPrintFormat format = MPrintFormat.get(getCtx(), 0, get_Table_ID());&lt;br /&gt;
    MQuery query=new MQuery(get_Table_ID());&lt;br /&gt;
    query.addRestriction(get_KeyColumns()[0],MQuery.EQUAL,get_ID());&lt;br /&gt;
    PrintInfo info = new PrintInfo(getDocumentNo(),get_Table_ID(),0);&lt;br /&gt;
    ReportEngine re = new ReportEngine(getCtx(), format, query, info, get_TrxName());&lt;br /&gt;
    &lt;br /&gt;
    if(format.getJasperProcess_ID() &amp;gt; 0){&lt;br /&gt;
      // JasperReports Print Format&lt;br /&gt;
      ProcessInfo pi = new ProcessInfo (&amp;quot;&amp;quot;, format.getJasperProcess_ID());&lt;br /&gt;
      pi.setRecord_ID(get_ID());&lt;br /&gt;
      pi.setIsBatch(true);&lt;br /&gt;
      ServerProcessCtl.process(pi, null);&lt;br /&gt;
      return pi.getPDFReport();&lt;br /&gt;
    }else{&lt;br /&gt;
      // Standard Print Format (Non-Jasper)&lt;br /&gt;
      return re.getPDF(file);&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Development‏‎]]&lt;br /&gt;
[[Category:Developer documentation‏‎]]&lt;br /&gt;
[[Category:System administration‏‎]]&lt;br /&gt;
[[Category:Applying means‏‎]]&lt;br /&gt;
[[Category:Document‎]]&lt;br /&gt;
[[Category:Workflow]]&lt;/div&gt;</summary>
		<author><name>Tioraul</name></author>
	</entry>
	<entry>
		<id>https://wiki.idempiere.org/w-en/index.php?title=Hackers_Guide_to_Documents&amp;diff=14305</id>
		<title>Hackers Guide to Documents</title>
		<link rel="alternate" type="text/html" href="https://wiki.idempiere.org/w-en/index.php?title=Hackers_Guide_to_Documents&amp;diff=14305"/>
		<updated>2018-07-27T22:30:15Z</updated>

		<summary type="html">&lt;p&gt;Tioraul: google translate&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Modes of document characteristics =&lt;br /&gt;
&lt;br /&gt;
== Document number ==&lt;br /&gt;
&lt;br /&gt;
If a table has a column with the title DocumentNo, it will be treated automatically in a special way. In the first usage of the table a sequence will be installed, which takes care of a consecutively document numeration. This document number can be edited more precisly in [[Belegnummernkreis (Fenster_ID-112)]]. It can be set as a determinded initial value or it can preserve a prefix or a suffix. Document numbers can also have a context variable where a date can be fit, e.g.Rechnung 00001/2014&amp;quot; (s.e.g. [[:en:NF001_Document_Sequence_Improved]]).&lt;br /&gt;
&lt;br /&gt;
== Model ==&lt;br /&gt;
&lt;br /&gt;
For a document type, which implements its own logic, you need to write a model. This means you create its own plugin, where you write a java class, the so-called model class (M*). This has to be derived from a predeterminded basis class (X_*). In turn this will be created with the help of the tool [[GenerateModel]] from the table definition of the data bank.&lt;br /&gt;
&lt;br /&gt;
=== Columns ===&lt;br /&gt;
&lt;br /&gt;
For the best you setup these following columns:&lt;br /&gt;
&lt;br /&gt;
* DocumentNo (mandatory; 30 Zeichen)&lt;br /&gt;
* DateDoc (mandatory)&lt;br /&gt;
* DateAcct (mandatory)&lt;br /&gt;
* Doc_User_ID (either a column or a getter-methode, which reads out a column like SalesRep_ID or standard logic, e.g. '@$C_Currency_ID@').&lt;br /&gt;
* C_Currency_ID (mandatory; Standardlogik e.g. &amp;quot;@$C_Currency_ID@')&lt;br /&gt;
* DocAction (mandatory; 2 characters; default 'CO'; pushbutton; reference &amp;quot;_Document Action&amp;quot;; here will be a process indicated, which indicates the according workflow of our document type)&lt;br /&gt;
* DocStatus (mandatory; 2 characters; default 'DR'; list reference; Referenz &amp;quot;_Document Status&amp;quot; )&lt;br /&gt;
* processed (mandatory; default 'N')&lt;br /&gt;
* processing (mandatory; default 'N') - after Dantam's article is a varchar(1), supposely the pushbutton. For example in C_Invoice is the same process inscribed like in DocAction. But until now I have no idea why you need two columns.&lt;br /&gt;
* isApproved (mandatory; default 'Y')&lt;br /&gt;
&lt;br /&gt;
=== What does DocumentEngine do in the process? ===&lt;br /&gt;
&lt;br /&gt;
Document actions will be done by the class DocEngine. Who wants to conduct a status operation, can do this best with the odel-method processIt(). This should invoke the accordingly method of DocEngine, which takes over the management of different status possibilties.&lt;br /&gt;
&lt;br /&gt;
* http://www.adempiere.com/Document_Engine - u.a. links to Sourcecode of Doc_* classes&lt;br /&gt;
* http://www.adempiere.com/Development_Guidelines_in_German#Klasse_DocumentEngine - german introduction, written quite well&lt;br /&gt;
&lt;br /&gt;
== Workflow ==&lt;br /&gt;
&lt;br /&gt;
You can install a receipt-Workflow which defines the change between several status values. You define a Workflow with three nodes: Start, Prepare and Complete. The two last ones will be combined with the last receipt action, therewith these take action. Then you definde a transition which in each case from Start to Prepare and from Prepare to Complete.&lt;br /&gt;
&lt;br /&gt;
This defined Workflow provides for properly done documents. It serves for further experiments.&lt;br /&gt;
&lt;br /&gt;
=== Reversing documents ===&lt;br /&gt;
&lt;br /&gt;
Who wants to reverse documents, requires these following columns in addition:&lt;br /&gt;
&lt;br /&gt;
* Reversal_ID (reference type table, as a reference you need to register new created table reference, which close about my whole table and can be assorted after DocumentNo)&lt;br /&gt;
&lt;br /&gt;
I never tried this reversal. Probably you need to configure an accordingly Workflow. Besides this you should be very careful, if you want to reverse booked documents.&lt;br /&gt;
&lt;br /&gt;
=== Reactivating Documents ===&lt;br /&gt;
&lt;br /&gt;
I would like to reactivate my document, after it is finalizied. In addition I created a further node 'Reactivate' and attached this with the accordingly receipt action. Then I definded a second transition with the start to Reactivate. The first transition has a condition, which only takes action, if 'Doc-Action = 'CO''. Besides this the first transition obtains a small order of numbers, which executes first.&lt;br /&gt;
&lt;br /&gt;
As a matter of principle the reactivating requires a reversal of the effects of the document. This implementation is not needed, but I recommend you this.&lt;br /&gt;
&lt;br /&gt;
=== Approval / Freigabe ===&lt;br /&gt;
&lt;br /&gt;
Workflows erlauben auch, die Bearbeitung eines Dokumentes von einer vorherigen Freigabe abhängig zu machen. So können z.B. Rechnungen über 1.000,- € immer erst dem Vorgesetzten vorgelegt werden oder dergleichen.&lt;br /&gt;
&lt;br /&gt;
* http://www.adempiere.com/How_to_Activate_Document_Approval_Workflow&lt;br /&gt;
&lt;br /&gt;
=== More about Workflows ===&lt;br /&gt;
&lt;br /&gt;
taken from http://en.wikiversity.org/wiki/Adempiere_Technical_Training#Document_Process_Workflow:&lt;br /&gt;
&lt;br /&gt;
Every document has a defined process – the workflow is started with the Process button:&amp;lt;br /&amp;gt;&lt;br /&gt;
These workflows have a defined start context (the document) and a responsible.&lt;br /&gt;
* Start (Draft)&lt;br /&gt;
** Auto&lt;br /&gt;
** Prepare (In Progress)&lt;br /&gt;
*** Complete (Completed)&lt;br /&gt;
&lt;br /&gt;
If you want to customize a workflow for a document:&amp;lt;br /&amp;gt;&lt;br /&gt;
* for all clients&lt;br /&gt;
** add customized node/transitions and/or inactivate standard transitions&lt;br /&gt;
* for a client or organization&lt;br /&gt;
** make changes on System workflow with entity type &amp;lt;&amp;gt; Dictionary/Adempiere&lt;br /&gt;
** execute process “Workflow to Client”&lt;br /&gt;
&lt;br /&gt;
== Booking Document ==&lt;br /&gt;
&lt;br /&gt;
A document that can generate its own posting lines must contain the following fields:&lt;br /&gt;
&lt;br /&gt;
* Posted (mandatory; boolean; default 'N')&lt;br /&gt;
* ProcessedOn (integer)&lt;br /&gt;
* C_DocType_ID (mandatory; Table; reference C_DocType)&lt;br /&gt;
&lt;br /&gt;
The corresponding logic is activated by the presence of the &amp;quot;Posted&amp;quot; field. In this case, after completing a document, an update class matching the model is used to carry out the update. For this there is the convention that this ends on &amp;quot;_Doc&amp;quot;. Within the iDempiere kernel, the name of this class (based on this convention) is automatically determined. In ADempiere this was also the case for own classes. In iDempiere, which no longer allows core access to our plugin classes through the OSGi packages, there is a factory for that purpose.&lt;br /&gt;
&lt;br /&gt;
== Document base type ==&lt;br /&gt;
&lt;br /&gt;
Our new document type must also have an entry in the database. However, we first have to think about which basic type he belongs to. This base type is used for sorting and grouping document types, in particular for the document type input fields. In addition, the period can be opened or closed in the period control (in the calendar) for each individual basic document category. Although, interestingly enough, it is not necessarily mandatory, it still makes sense to set up a document base type for your own accounting document class.&lt;br /&gt;
&lt;br /&gt;
The base document type consists of an entry in the reference list &amp;quot;C_DocType DocBaseType&amp;quot; and always has three letters. If you want, you can set up a type &amp;quot;DOC&amp;quot; for all your documents here. However, it makes more sense to create your own basic types for each document type you create. Then, a selection field in the window can be validated to filter for this basic type and the user will always be able to generate their own derivations later.&lt;br /&gt;
&lt;br /&gt;
For some base types of the standard iDempiere, multiple base types work with objects of the same table. For example, by splitting &amp;quot;API Accounts Payable Invoice&amp;quot; and &amp;quot;ARI Accounts Receivable Invoice&amp;quot; ensures that incoming and outgoing invoices are never mixed. Although both are in the same table and use much the same business logic, they each have their own windows and are also distinguished by the field &amp;quot;isSOTrx&amp;quot; (and the different base document type). Due to the two basic document types, a simple validation on the input field for the document type is enough, so that you can only select sales document types for customers and vice versa.&lt;br /&gt;
&lt;br /&gt;
After you have created the basic document categories (in the system client), you should now call the process &amp;quot;Check Document Types&amp;quot; in the client. This creates a document type for each base document type and also directly creates corresponding period entries in the calendar.&lt;br /&gt;
&lt;br /&gt;
The automatically generated document types can be viewed in the &amp;quot;Document type&amp;quot; window and adjusted if necessary. It is recommended to activate number management and specify (or create) a document number range.&lt;br /&gt;
&lt;br /&gt;
In this window you can now derive even more document types from its basic document category. This has different purposes:&lt;br /&gt;
&lt;br /&gt;
* First of all, this can serve the in-house grouping of documents. Anyone who thinks in his business that a bill of goods is different from a service bill and a foreign bill, in turn, differently and a freight bill, can divide this so without much trouble.&lt;br /&gt;
* You can specify your own print format (in this window) and make the printed receipt look very different.&lt;br /&gt;
* You can group direct bookings (batches) using the direct posting type (fee type depending on the translation) and only allow specific bookings for certain document types. Thus, the freight invoice can be posted to the account for freight, the foreign invoice to the account for customs, etc.&lt;br /&gt;
&lt;br /&gt;
Next, you should create a validation rule. This gets the name &amp;quot;C_DocType MyPatementName&amp;quot; and as SQL-Code something like the following line:&lt;br /&gt;
&lt;br /&gt;
  C_DocType.DocBaseType IN ('ARZ', 'APZ') AND C_DocType.IsSOTrx='@IsSOTrx@'  AND C_DocType.AD_Client_ID=@#AD_Client_ID@&lt;br /&gt;
&lt;br /&gt;
Of course, you can omit the part with IsSOTrx if we do not have a separate document type for input and output windows. This part of the formula ensures that we can use identical field definitions for incoming and outgoing documents. The two windows then differ only in that the context variable &amp;quot;IsSOTrx&amp;quot; is set when the window is opened. This will then control everything else. This value can be set in the window definition.&lt;br /&gt;
&lt;br /&gt;
== Einkaufs- und Verkaufsbelege ==&lt;br /&gt;
&lt;br /&gt;
Wer einen Belegtyp hat, der Einkaufs- und Verkaufsbelege (AP und AR) unterschiedlich verbuchen soll, braucht auch noch dieses Feld. Bei dieser Art Belegen bietet es sich im Allgemeinen an, auch zwei getrennte Basisbelegtypen und ggf. zwei getrennte Fenster zu erzeugen. Die Fensterdefinitionen können weitgehend identisch sein bis auf den Eintrag &amp;quot;Verkaufstransaktion&amp;quot;, der die Kontextvariable &amp;quot;IsSOTrx&amp;quot; setzt und sie somit unterscheidbar macht.&lt;br /&gt;
&lt;br /&gt;
* isSOTrx (mandatory; boolean; im Fenster am besten gar nciht angezeigt oder mindestens schreibgeschützt)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Fenster, Tab &amp;amp; Felder ==&lt;br /&gt;
&lt;br /&gt;
Das Fenster sollte auf den Fenstertyp &amp;quot;Transaktion&amp;quot; gesetzt werden. Dadurch wird die [[http://www.adempiere.com/History History-Funktion]] aktiviert. Diese sorgt dafür, das immer nur die aktuellen und nicht abgeschlossenen Dokumente angezeigt werden.&lt;br /&gt;
&lt;br /&gt;
Bei der Konfiguration des Fensters sollten übrigens die folgenden Felder angezeigt werden (laut Dantam):&lt;br /&gt;
&lt;br /&gt;
* Processed (set to &amp;quot;Read Only&amp;quot;)&lt;br /&gt;
* DocStatus (set to &amp;quot;Read Only&amp;quot;)&lt;br /&gt;
* DocAction&lt;br /&gt;
* Currency (wenn benutzt sollte es u.U. schreibgeschützt sein)&lt;br /&gt;
&lt;br /&gt;
Für Dokumente, die Einkaufs- und Verkaufsbelege unterscheiden, bietet es sich an, diese zu kopieren und eine WHERE-Klasel einzuführen, so das man zwei Fenster für diese eigentlich unterschiedlichen Belegtypen hat. Man kann in der Fensterdefinition ein Fenster als Verkaufstransaktion definieren und somit eine Kontextvariable setzen, die in vielen Abfragen und Validierungen benutzt wird, um sicherzustellen, das alle Felder entsprechend angepasst funktionieren. Das erfordert natürlich bei der Erzeugung eigener Abfragen etwas Sorgfalt, aber es gibt ja genug bestehende Beispiele wie z.B. &amp;quot;Rechnung (Kunde)&amp;quot; und &amp;quot;Rechnung (Lieferant)&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Drucken ==&lt;br /&gt;
&lt;br /&gt;
Grnudsätzlich kann man einen Datensatz ausdrucken, indem man in der Toolbar auf den Button für einen entsprechenden Bericht klickt. Durch diesen wird dann ein Druckformat erzeugt, das man entsprechend anpassen kann. Will man oft eher einzelne Datensätze z.B. als Formular drucken als eine Liste von Sätzen, so bietet es sich an, den Druck-Button zu aktivieren, mit dem man einzelne Datensätze drucken kann. Das macht man, indem man im Fenster &amp;quot;Prozeß &amp;amp; Bericht&amp;quot; einen Eintrag macht. Diesen setzte man auf &amp;quot;Bericht&amp;quot; und gibt ggf. ein vorbereitetes Druckformat an. Dieses kann dann mit mit den Buttons für &amp;quot;Druck&amp;quot; und &amp;quot;Druckvorschau&amp;quot; gestartet werden, indem man es im Datensatz des Fensterregisters einträgt.&lt;br /&gt;
&lt;br /&gt;
Hier gibt es übrigens ein kleines Problem. Das Fenster &amp;quot;Prozeß &amp;amp; Bericht&amp;quot; muss man im Systemmandanten einrichten, während man sein Druckformat ja zumeist vorher im normalen Mandanten vorbereitet hat. Man kann in diesem Fall das Druckformat freilassen. Es wird automatisch das gewählt, das das Feld &amp;quot;Standard&amp;quot; gesetzt hat.&lt;br /&gt;
&lt;br /&gt;
=== Berichtsansicht benutzen, um mehr Spalten auszudrucken als in der Tabelle stehen ===&lt;br /&gt;
&lt;br /&gt;
Eine Erweiterung gibt es noch, indem man in &amp;quot;Prozeß &amp;amp; Bericht&amp;quot; im Feld &amp;quot;Berichtsansicht&amp;quot; eine ebensolche einträgt. In diesem Fall wird ein Druckformat ausgewählt, das ebendiese Berichtsansicht ausgewählt hat. Hierdurch kann man die Auswahl des Druckformats noch weiter eingrenzen.&lt;br /&gt;
&lt;br /&gt;
Insbesondere kann man hier auch eine Berichtsansicht angeben, die auf einer ganz anderen Tabelle basiert. Diese Tabelle sollte lediglich das Primärschlüsselfeld unseres Dokumentes beinhalten, weil hierdurch der ausgedruckte Datensatz heruasgefiltert wird. Ich habe das beispielsweise benutzt, um anstatt der im aktuellen Fenster bearbeiteten Tabelle ein Datenbank-View für den Ausdruck zu benutzen, das zwar auf ebendieser Tabelle basiert, ihnr per JOIN aber jede Menge weitere Daten hinzufügt. Diese grosse Menge an Informationen kann man dann (wenn man möchte) durch eine Berichtsansicht wieder einschränken und dann im Druckformat verarbeiten. Ein derartiges Druckformat erzeugt man im Fenster &amp;quot;Druckformat&amp;quot;, wo man die Tabelle und die Ansicht bei der Neuanlage des Datensatzes einstellen kann. Dann erzeugt man die Felder mittels des automatischen Proßess-Knopfes hierfür und kann dann das Druckformat schon im Zielfenster einstellen und dort in der Druckansicht benutzen. Ist diese das erste Mal zu sehen, kann man es dann wie gewöhnlich entstandene Druckformate auch anpassen.&lt;br /&gt;
&lt;br /&gt;
=== Drucken per Programm ===&lt;br /&gt;
&lt;br /&gt;
Mit der folgenden Methode kann ich in meinem Model für die Tabelle BAY_InterestCalculation einen Ausdruck veranlassen, der auf einem View basiert, das RV_BAY_InterestCalculation heisst. Man kann diese Methode z.B. in completeIt() aufrufen, um dafür zu sorgen, das ein Dokument immer gedruckt wird, wenn es abgeschlossen wird. Man kann übrigens im Prozeßfenster einstellen, ob der Ausdruck sofort im Hintergrund oder erst mit Rückfrage geschieht.&lt;br /&gt;
&lt;br /&gt;
  public void print() {&lt;br /&gt;
    int viewTable = MTable.getTable_ID(&amp;quot;RV_&amp;quot; + Table_Name);&lt;br /&gt;
    MPrintFormat format = new Query(getCtx(), MPrintFormat.Table_Name, MPrintFormat.COLUMNNAME_AD_Table_ID&lt;br /&gt;
      + &amp;quot;=? AND &amp;quot; + MPrintFormat.COLUMNNAME_IsDefault + &amp;quot;=? &amp;quot;, get_TrxName()).setParameters(viewTable, &amp;quot;Y&amp;quot;)&lt;br /&gt;
      .first();&lt;br /&gt;
    MQuery query = new MQuery(get_Table_ID());&lt;br /&gt;
    query.addRestriction(get_KeyColumns()[0], MQuery.EQUAL, get_ID());&lt;br /&gt;
    PrintInfo info = new PrintInfo(getDocumentInfo(), get_Table_ID(), get_ID());&lt;br /&gt;
    ReportEngine re = new ReportEngine(getCtx(), format, query, info, get_TrxName());&lt;br /&gt;
    re.print();&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
= Links =&lt;br /&gt;
&lt;br /&gt;
== Artikel, die Dokumente erklären ==&lt;br /&gt;
&lt;br /&gt;
Basiserklärungen&lt;br /&gt;
&lt;br /&gt;
* http://wiki.idempiere.org/en/Create_a_custom_document_class - recht neuer Artikel von Daniel Tamm im iDempiere Wiki, hat noch viele Lücken&lt;br /&gt;
* http://www.adempiere.com/How_to_create_a_new_document_with_specific_accounting&lt;br /&gt;
&lt;br /&gt;
weiterführende Erklärungen&lt;br /&gt;
&lt;br /&gt;
* http://www.adempiere.com/How_to_Activate_Document_Approval_Workflow&lt;br /&gt;
* http://www.adempiere.com/Document_Action_Dialog - Erklärung zum Action Button und dem davon aufgehenden Fenster&lt;br /&gt;
* http://www.adempiere.com/Document_Sequence - Document Sequence&lt;br /&gt;
* Erweiterungen&lt;br /&gt;
** http://www.adempiere.com/Enhance_Document_No_Formatting - Verbesserung der Dokumentnummerierung (hierdurch sind Kontextvariablen erlaubt)&lt;br /&gt;
** http://wiki.idempiere.org/en/NF001_Document_Sequence_Improved - Verbesserung bzgl. Organisationen und Neustart von Nummernkreisen&lt;br /&gt;
** http://www.adempiere.com/Sponsored_Development:_Document_Signing - Document Signing Erweiterung, augenscheinlich nie verwirklicht worden&lt;br /&gt;
&lt;br /&gt;
Artikel, die ich als Quellen verwendet, aber bereits weitgehend hier eingearbeitet habe:&lt;br /&gt;
&lt;br /&gt;
* http://www.adempiere.com/HOWTO_Process_Documents - erklärt recht gut die Benutzung der vorhandenen Dokumenttypen; weniger die Entwicklung neuer&lt;br /&gt;
* http://en.wikiversity.org/wiki/Adempiere_Technical_Training#Document_Process_Workflow - enthält kurze, aber aufschlussreiche Teile zum Thema, insbesondere &amp;quot;Document Process Workflow&amp;quot;&lt;br /&gt;
* http://www.adempiere.com/Document_Engine&lt;br /&gt;
* https://groups.google.com/forum/#!topic/idempiere/WtTlVL1ZjWw - kurzed Forumsthread darüber, wie man einen Workflow implementieren kann&lt;br /&gt;
&lt;br /&gt;
Fenster, die mit Dokumenten zusammenhängen:&lt;br /&gt;
&lt;br /&gt;
* http://wiki.idempiere.org/en/Document_Type_%28Window_ID-135%29&lt;br /&gt;
* http://wiki.idempiere.org/en/Document_Sequence_%28Window_ID-112%29&lt;br /&gt;
&lt;br /&gt;
* http://wiki.idempiere.org/en/Unprocessed_Documents_%28All%29_%28Window_ID-53087%29&lt;br /&gt;
* http://wiki.idempiere.org/en/UnPosted_Documents_%28Window_ID-294%29&lt;br /&gt;
* http://wiki.idempiere.org/en/My_Unprocessed_Documents_%28Window_ID-53086%29&lt;br /&gt;
* http://wiki.idempiere.org/de/Workflow_%28Fenster_ID-113%29&lt;br /&gt;
&lt;br /&gt;
(Was ist der Unterschied zwischen &amp;quot;unprocessed&amp;quot; und &amp;quot;unposted&amp;quot; und woher wissen diese Fenster, welche Tabellen sie absuchen sollen?)&lt;br /&gt;
&lt;br /&gt;
* http://wiki.idempiere.org/en/Verify_Document_Types_%28Process_ID-233%29 - was macht dieser Prozeß? Er erzeugt wohl Open-Einträge für neue Dokumenttypen. Sonst noch was?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= weitere Informationen =&lt;br /&gt;
&lt;br /&gt;
== involvierte Klassen und Interfaces ==&lt;br /&gt;
&lt;br /&gt;
=== MSetup ===&lt;br /&gt;
&lt;br /&gt;
Create the list of document type for new Client ( Method createAccounting ). &lt;br /&gt;
&lt;br /&gt;
=== org.compiere.server.AcctProcessor ===&lt;br /&gt;
&lt;br /&gt;
Background process running on the JBoss server that perform the accounting document posting process. &lt;br /&gt;
&lt;br /&gt;
=== org.compiere.grid.ed.VDocAction ===&lt;br /&gt;
&lt;br /&gt;
Define hardcoded in dynInit method the list of possible transitions, and transitions by table &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Beispiele für die Implementierung einiger DocAction-Methoden =&lt;br /&gt;
&lt;br /&gt;
=== getDocumentInfo() ===&lt;br /&gt;
&lt;br /&gt;
Ergibt eine kurze aber eindeutige Bezeichnung des Datensatzes, die vor allem in Logzeilen und sonstigen Programm-Mitteilungen verwendet wird. Dieses Beispiel nutzt einen vorhandenen Documenttyp.&lt;br /&gt;
&lt;br /&gt;
  public String getDocumentInfo(){&lt;br /&gt;
    MDocType dt = MDocType.get(getCtx(), getC_DocType_ID());&lt;br /&gt;
    String msgreturn = dt.getNameTrl()+&amp;quot; &amp;quot;+getDocumentNo();&lt;br /&gt;
    return msgreturn.toString();&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
=== createPDF() ===&lt;br /&gt;
&lt;br /&gt;
Es gibt eine Methode, um das Dokument als PDF auszugeben. Diese wird - soweit ich gesehen habe - nur benutzt, um das Dokument per EMail zu versenden. Da man aber nie weiss, kann man das z.B. so wie folgend implementieren. Dabei kann man bei der Auswähl des Printformats natürlich auch genauer auswählen.&lt;br /&gt;
&lt;br /&gt;
  public File createPDF (){&lt;br /&gt;
    try{&lt;br /&gt;
      StringBuilder msgfile = new StringBuilder().append(get_TableName()).append(get_ID()).append(&amp;quot;_&amp;quot;);&lt;br /&gt;
      File temp = File.createTempFile(msgfile.toString(), &amp;quot;.pdf&amp;quot;);&lt;br /&gt;
      return createPDF (temp);&lt;br /&gt;
    }catch (Exception e){&lt;br /&gt;
      log.severe(&amp;quot;Could not create PDF - &amp;quot; + e.getMessage());&lt;br /&gt;
    }&lt;br /&gt;
    return null;&lt;br /&gt;
  }&lt;br /&gt;
  &lt;br /&gt;
  public File createPDF (File file){&lt;br /&gt;
    MPrintFormat format = MPrintFormat.get(getCtx(), 0, get_Table_ID());&lt;br /&gt;
    MQuery query=new MQuery(get_Table_ID());&lt;br /&gt;
    query.addRestriction(get_KeyColumns()[0],MQuery.EQUAL,get_ID());&lt;br /&gt;
    PrintInfo info = new PrintInfo(getDocumentNo(),get_Table_ID(),0);&lt;br /&gt;
    ReportEngine re = new ReportEngine(getCtx(), format, query, info, get_TrxName());&lt;br /&gt;
    &lt;br /&gt;
    if(format.getJasperProcess_ID() &amp;gt; 0){&lt;br /&gt;
      // JasperReports Print Format&lt;br /&gt;
      ProcessInfo pi = new ProcessInfo (&amp;quot;&amp;quot;, format.getJasperProcess_ID());&lt;br /&gt;
      pi.setRecord_ID(get_ID());&lt;br /&gt;
      pi.setIsBatch(true);&lt;br /&gt;
      ServerProcessCtl.process(pi, null);&lt;br /&gt;
      return pi.getPDFReport();&lt;br /&gt;
    }else{&lt;br /&gt;
      // Standard Print Format (Non-Jasper)&lt;br /&gt;
      return re.getPDF(file);&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Development‏‎]]&lt;br /&gt;
[[Category:Developer documentation‏‎]]&lt;br /&gt;
[[Category:System administration‏‎]]&lt;br /&gt;
[[Category:Applying means‏‎]]&lt;br /&gt;
[[Category:Document‎]]&lt;br /&gt;
[[Category:Workflow]]&lt;/div&gt;</summary>
		<author><name>Tioraul</name></author>
	</entry>
	<entry>
		<id>https://wiki.idempiere.org/w-en/index.php?title=Hackers_Guide_to_Documents&amp;diff=14304</id>
		<title>Hackers Guide to Documents</title>
		<link rel="alternate" type="text/html" href="https://wiki.idempiere.org/w-en/index.php?title=Hackers_Guide_to_Documents&amp;diff=14304"/>
		<updated>2018-07-27T22:16:38Z</updated>

		<summary type="html">&lt;p&gt;Tioraul: Google Translate&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Modes of document characteristics =&lt;br /&gt;
&lt;br /&gt;
== Document number ==&lt;br /&gt;
&lt;br /&gt;
If a table has a column with the title DocumentNo, it will be treated automatically in a special way. In the first usage of the table a sequence will be installed, which takes care of a consecutively document numeration. This document number can be edited more precisly in [[Belegnummernkreis (Fenster_ID-112)]]. It can be set as a determinded initial value or it can preserve a prefix or a suffix. Document numbers can also have a context variable where a date can be fit, e.g.Rechnung 00001/2014&amp;quot; (s.e.g. [[:en:NF001_Document_Sequence_Improved]]).&lt;br /&gt;
&lt;br /&gt;
== Model ==&lt;br /&gt;
&lt;br /&gt;
For a document type, which implements its own logic, you need to write a model. This means you create its own plugin, where you write a java class, the so-called model class (M*). This has to be derived from a predeterminded basis class (X_*). In turn this will be created with the help of the tool [[GenerateModel]] from the table definition of the data bank.&lt;br /&gt;
&lt;br /&gt;
=== Columns ===&lt;br /&gt;
&lt;br /&gt;
For the best you setup these following columns:&lt;br /&gt;
&lt;br /&gt;
* DocumentNo (mandatory; 30 Zeichen)&lt;br /&gt;
* DateDoc (mandatory)&lt;br /&gt;
* DateAcct (mandatory)&lt;br /&gt;
* Doc_User_ID (either a column or a getter-methode, which reads out a column like SalesRep_ID or standard logic, e.g. '@$C_Currency_ID@').&lt;br /&gt;
* C_Currency_ID (mandatory; Standardlogik e.g. &amp;quot;@$C_Currency_ID@')&lt;br /&gt;
* DocAction (mandatory; 2 characters; default 'CO'; pushbutton; reference &amp;quot;_Document Action&amp;quot;; here will be a process indicated, which indicates the according workflow of our document type)&lt;br /&gt;
* DocStatus (mandatory; 2 characters; default 'DR'; list reference; Referenz &amp;quot;_Document Status&amp;quot; )&lt;br /&gt;
* processed (mandatory; default 'N')&lt;br /&gt;
* processing (mandatory; default 'N') - after Dantam's article is a varchar(1), supposely the pushbutton. For example in C_Invoice is the same process inscribed like in DocAction. But until now I have no idea why you need two columns.&lt;br /&gt;
* isApproved (mandatory; default 'Y')&lt;br /&gt;
&lt;br /&gt;
=== What does DocumentEngine do in the process? ===&lt;br /&gt;
&lt;br /&gt;
Document actions will be done by the class DocEngine. Who wants to conduct a status operation, can do this best with the odel-method processIt(). This should invoke the accordingly method of DocEngine, which takes over the management of different status possibilties.&lt;br /&gt;
&lt;br /&gt;
* http://www.adempiere.com/Document_Engine - u.a. links to Sourcecode of Doc_* classes&lt;br /&gt;
* http://www.adempiere.com/Development_Guidelines_in_German#Klasse_DocumentEngine - german introduction, written quite well&lt;br /&gt;
&lt;br /&gt;
== Workflow ==&lt;br /&gt;
&lt;br /&gt;
You can install a receipt-Workflow which defines the change between several status values. You define a Workflow with three nodes: Start, Prepare and Complete. The two last ones will be combined with the last receipt action, therewith these take action. Then you definde a transition which in each case from Start to Prepare and from Prepare to Complete.&lt;br /&gt;
&lt;br /&gt;
This defined Workflow provides for properly done documents. It serves for further experiments.&lt;br /&gt;
&lt;br /&gt;
=== Reversing documents ===&lt;br /&gt;
&lt;br /&gt;
Who wants to reverse documents, requires these following columns in addition:&lt;br /&gt;
&lt;br /&gt;
* Reversal_ID (reference type table, as a reference you need to register new created table reference, which close about my whole table and can be assorted after DocumentNo)&lt;br /&gt;
&lt;br /&gt;
I never tried this reversal. Probably you need to configure an accordingly Workflow. Besides this you should be very careful, if you want to reverse booked documents.&lt;br /&gt;
&lt;br /&gt;
=== Reactivating Documents ===&lt;br /&gt;
&lt;br /&gt;
I would like to reactivate my document, after it is finalizied. In addition I created a further node 'Reactivate' and attached this with the accordingly receipt action. Then I definded a second transition with the start to Reactivate. The first transition has a condition, which only takes action, if 'Doc-Action = 'CO''. Besides this the first transition obtains a small order of numbers, which executes first.&lt;br /&gt;
&lt;br /&gt;
As a matter of principle the reactivating requires a reversal of the effects of the document. This implementation is not needed, but I recommend you this.&lt;br /&gt;
&lt;br /&gt;
=== Approval / Freigabe ===&lt;br /&gt;
&lt;br /&gt;
Workflows erlauben auch, die Bearbeitung eines Dokumentes von einer vorherigen Freigabe abhängig zu machen. So können z.B. Rechnungen über 1.000,- € immer erst dem Vorgesetzten vorgelegt werden oder dergleichen.&lt;br /&gt;
&lt;br /&gt;
* http://www.adempiere.com/How_to_Activate_Document_Approval_Workflow&lt;br /&gt;
&lt;br /&gt;
=== More about Workflows ===&lt;br /&gt;
&lt;br /&gt;
taken from http://en.wikiversity.org/wiki/Adempiere_Technical_Training#Document_Process_Workflow:&lt;br /&gt;
&lt;br /&gt;
Every document has a defined process – the workflow is started with the Process button:&amp;lt;br /&amp;gt;&lt;br /&gt;
These workflows have a defined start context (the document) and a responsible.&lt;br /&gt;
* Start (Draft)&lt;br /&gt;
** Auto&lt;br /&gt;
** Prepare (In Progress)&lt;br /&gt;
*** Complete (Completed)&lt;br /&gt;
&lt;br /&gt;
If you want to customize a workflow for a document:&amp;lt;br /&amp;gt;&lt;br /&gt;
* for all clients&lt;br /&gt;
** add customized node/transitions and/or inactivate standard transitions&lt;br /&gt;
* for a client or organization&lt;br /&gt;
** make changes on System workflow with entity type &amp;lt;&amp;gt; Dictionary/Adempiere&lt;br /&gt;
** execute process “Workflow to Client”&lt;br /&gt;
&lt;br /&gt;
== Booking Document ==&lt;br /&gt;
&lt;br /&gt;
A document that can generate its own posting lines must contain the following fields:&lt;br /&gt;
&lt;br /&gt;
* Posted (mandatory; boolean; default 'N')&lt;br /&gt;
* ProcessedOn (integer)&lt;br /&gt;
* C_DocType_ID (mandatory; Table; reference C_DocType)&lt;br /&gt;
&lt;br /&gt;
The corresponding logic is activated by the presence of the &amp;quot;Posted&amp;quot; field. In this case, after completing a document, an update class matching the model is used to carry out the update. For this there is the convention that this ends on &amp;quot;_Doc&amp;quot;. Within the iDempiere kernel, the name of this class (based on this convention) is automatically determined. In ADempiere this was also the case for own classes. In iDempiere, which no longer allows core access to our plugin classes through the OSGi packages, there is a factory for that purpose.&lt;br /&gt;
&lt;br /&gt;
== Dokument-Basisbelegtyp ==&lt;br /&gt;
&lt;br /&gt;
Unser neuer Belegtyp muss auch einen Eintrag in der Datenbank erhalten. Dazu müssen wir uns allerdings zuerst überlegen, welchem Basistyp er zugehört. Dieser Basistyp dient der Sortierung und Gruppierung von Belegtypen insbesondere für die Belegtyp-Eingabefelder. Außerdem kann/muss in der Periodenkontrolle (im Kalender) für jeden einzelnen Basisbelegtyp die Periode geöffnet oder geschlossen werden. Obwohl es interessanterweise nicht unbedingt zwingend vorgeschrieben ist, bietet es sich dennoch an, für eine eigene verbuchende Dokumentenklasse auch einen Dokument-Basistyp einzurichten. &lt;br /&gt;
&lt;br /&gt;
Der Basisbelegtyp besteht aus einem Eintrag in der Referenzliste &amp;quot;C_DocType DocBaseType&amp;quot; und hat immer drei Buchstaben. Wer möchte, kann hier prinzipiell für alle seine Dokumente einen Typ &amp;quot;DOC&amp;quot; einrichten. Allerdings ist es sinnvoller, für jeden Belegtyp, den man erzeugt, einen eigenen Basistypen zu erzeugen. Dann kann ein Auswahlfeld im Fenster per Validierung nach diesem Basistyp filtern und dem Benutzer bleibt so später immer die Möglichkeit, eigene Ableitungen zu generieren.&lt;br /&gt;
&lt;br /&gt;
Bei einigen Basistypen des Standard-iDempiere ist es so, das mehrere Basistypen mit Objekten derselben Tabelle arbeiten. So ist z.B. durch die Aufteilung &amp;quot;API Accounts Payable Invoice&amp;quot; und &amp;quot;ARI Accounts Receivable Invoice&amp;quot; sichergestellt, das Eingangs- und Ausgangsrechnungen niemals gemischt werden. Beide stehen zwar in derselben Tabelle und benutzen weitgehend dieselbe Geschäftslogik, sie haben jedoch jeweils eigene Fenster und werden auch durch das Feld &amp;quot;isSOTrx&amp;quot; (und eben den unterschiedlichen Basisbelegtyp) unterschieden. Durch die zwei Basis-Belegtypen reicht eine einfache Validierung auf dem Eingabefeld für den Belegtyp, so das man für Kunden auch wirklich nur Verkaufs-Belegtypen auswählen kann und umgekehrt.&lt;br /&gt;
&lt;br /&gt;
Nachdem man die Basis-Belegtypen erstellt hat (im System-Mandant), sollte man nun im Mandanten den Prozeß &amp;quot;Belegarten überprüfen&amp;quot; aufrufen. Dieser legt zu jeder Basisbelegart eine Belegart an und erzeugt auch direkt entsprechende Perioden-Einträge im Kalender.&lt;br /&gt;
&lt;br /&gt;
Die so automatisch erzeugten Belegarten kann man im Fenster &amp;quot;Belegart&amp;quot; ansehen und ggf. anpassen. Es empfiehlt sich, die Nummernverwaltung einzuschalten und einen Belegnummernkreis anzugeben (oder neu zu erzeugen).&lt;br /&gt;
&lt;br /&gt;
In diesem Fenster kann man nun noch weitere Belegarten von seinem Basisbelegtyp ableiten. Das hat verschiedene Zwecke:&lt;br /&gt;
&lt;br /&gt;
* Zuerst einmal kann das der betriebsinternen Gruppierung von Belegen dienen. Wer in seinem Betrieb meint, das eine Warenrechnung anders ist als eine Dienstleistungsrechnung und eine Auslandsrechnung wiederum anders und eine Frachtrechnung auch, kann das so ohne grosse Probleme aufteilen.&lt;br /&gt;
* Man kann (in diesem Fenster) ein eigenes Druckformat angeben und so den gedruckten Beleg ganz anders aussehen lassen.&lt;br /&gt;
* Man kann die Direktbuchungen (Charge) über die Direktbuchungsart (Gebührenart je nach Übersetzung) gruppieren und für bestimmte Belegarten nur bestimmte Buchungen erlauben. So kann also die Frachtrechnung auf das Konto für Fracht buchen, die Auslandsrechnung auf das Konto für Zoll, etc.&lt;br /&gt;
&lt;br /&gt;
Als nächstes sollte man eine Validierungsregel erstellen. Diese bekommt den Namen &amp;quot;C_DocType MeinBelegtypname&amp;quot; und als SQL-Code sowas wie die folgende Zeile:&lt;br /&gt;
&lt;br /&gt;
  C_DocType.DocBaseType IN ('ARZ', 'APZ') AND C_DocType.IsSOTrx='@IsSOTrx@'  AND C_DocType.AD_Client_ID=@#AD_Client_ID@&lt;br /&gt;
&lt;br /&gt;
Den Teil mit IsSOTrx kann man natürlich weglassen, wenn wir keinen getrennten Belegtyp für Eingangs- und Ausgangsfenster haben. Dieser Teil der Formel sorgt dafür, das wir identische Felddefinitionen für Eingangs- und Ausgangsbelege nehmen können. Die beiden Fenster unterscheiden sich dann nur dadurch, das beim Öffnen des Fensters die Kontextvariable &amp;quot;IsSOTrx&amp;quot; gesetzt wird. Hiermit wird dann alles andere gesteuert. Das dieser Wert gesetzt ist, kann man in der Fensterdefinition einstellen.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Einkaufs- und Verkaufsbelege ==&lt;br /&gt;
&lt;br /&gt;
Wer einen Belegtyp hat, der Einkaufs- und Verkaufsbelege (AP und AR) unterschiedlich verbuchen soll, braucht auch noch dieses Feld. Bei dieser Art Belegen bietet es sich im Allgemeinen an, auch zwei getrennte Basisbelegtypen und ggf. zwei getrennte Fenster zu erzeugen. Die Fensterdefinitionen können weitgehend identisch sein bis auf den Eintrag &amp;quot;Verkaufstransaktion&amp;quot;, der die Kontextvariable &amp;quot;IsSOTrx&amp;quot; setzt und sie somit unterscheidbar macht.&lt;br /&gt;
&lt;br /&gt;
* isSOTrx (mandatory; boolean; im Fenster am besten gar nciht angezeigt oder mindestens schreibgeschützt)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Fenster, Tab &amp;amp; Felder ==&lt;br /&gt;
&lt;br /&gt;
Das Fenster sollte auf den Fenstertyp &amp;quot;Transaktion&amp;quot; gesetzt werden. Dadurch wird die [[http://www.adempiere.com/History History-Funktion]] aktiviert. Diese sorgt dafür, das immer nur die aktuellen und nicht abgeschlossenen Dokumente angezeigt werden.&lt;br /&gt;
&lt;br /&gt;
Bei der Konfiguration des Fensters sollten übrigens die folgenden Felder angezeigt werden (laut Dantam):&lt;br /&gt;
&lt;br /&gt;
* Processed (set to &amp;quot;Read Only&amp;quot;)&lt;br /&gt;
* DocStatus (set to &amp;quot;Read Only&amp;quot;)&lt;br /&gt;
* DocAction&lt;br /&gt;
* Currency (wenn benutzt sollte es u.U. schreibgeschützt sein)&lt;br /&gt;
&lt;br /&gt;
Für Dokumente, die Einkaufs- und Verkaufsbelege unterscheiden, bietet es sich an, diese zu kopieren und eine WHERE-Klasel einzuführen, so das man zwei Fenster für diese eigentlich unterschiedlichen Belegtypen hat. Man kann in der Fensterdefinition ein Fenster als Verkaufstransaktion definieren und somit eine Kontextvariable setzen, die in vielen Abfragen und Validierungen benutzt wird, um sicherzustellen, das alle Felder entsprechend angepasst funktionieren. Das erfordert natürlich bei der Erzeugung eigener Abfragen etwas Sorgfalt, aber es gibt ja genug bestehende Beispiele wie z.B. &amp;quot;Rechnung (Kunde)&amp;quot; und &amp;quot;Rechnung (Lieferant)&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Drucken ==&lt;br /&gt;
&lt;br /&gt;
Grnudsätzlich kann man einen Datensatz ausdrucken, indem man in der Toolbar auf den Button für einen entsprechenden Bericht klickt. Durch diesen wird dann ein Druckformat erzeugt, das man entsprechend anpassen kann. Will man oft eher einzelne Datensätze z.B. als Formular drucken als eine Liste von Sätzen, so bietet es sich an, den Druck-Button zu aktivieren, mit dem man einzelne Datensätze drucken kann. Das macht man, indem man im Fenster &amp;quot;Prozeß &amp;amp; Bericht&amp;quot; einen Eintrag macht. Diesen setzte man auf &amp;quot;Bericht&amp;quot; und gibt ggf. ein vorbereitetes Druckformat an. Dieses kann dann mit mit den Buttons für &amp;quot;Druck&amp;quot; und &amp;quot;Druckvorschau&amp;quot; gestartet werden, indem man es im Datensatz des Fensterregisters einträgt.&lt;br /&gt;
&lt;br /&gt;
Hier gibt es übrigens ein kleines Problem. Das Fenster &amp;quot;Prozeß &amp;amp; Bericht&amp;quot; muss man im Systemmandanten einrichten, während man sein Druckformat ja zumeist vorher im normalen Mandanten vorbereitet hat. Man kann in diesem Fall das Druckformat freilassen. Es wird automatisch das gewählt, das das Feld &amp;quot;Standard&amp;quot; gesetzt hat.&lt;br /&gt;
&lt;br /&gt;
=== Berichtsansicht benutzen, um mehr Spalten auszudrucken als in der Tabelle stehen ===&lt;br /&gt;
&lt;br /&gt;
Eine Erweiterung gibt es noch, indem man in &amp;quot;Prozeß &amp;amp; Bericht&amp;quot; im Feld &amp;quot;Berichtsansicht&amp;quot; eine ebensolche einträgt. In diesem Fall wird ein Druckformat ausgewählt, das ebendiese Berichtsansicht ausgewählt hat. Hierdurch kann man die Auswahl des Druckformats noch weiter eingrenzen.&lt;br /&gt;
&lt;br /&gt;
Insbesondere kann man hier auch eine Berichtsansicht angeben, die auf einer ganz anderen Tabelle basiert. Diese Tabelle sollte lediglich das Primärschlüsselfeld unseres Dokumentes beinhalten, weil hierdurch der ausgedruckte Datensatz heruasgefiltert wird. Ich habe das beispielsweise benutzt, um anstatt der im aktuellen Fenster bearbeiteten Tabelle ein Datenbank-View für den Ausdruck zu benutzen, das zwar auf ebendieser Tabelle basiert, ihnr per JOIN aber jede Menge weitere Daten hinzufügt. Diese grosse Menge an Informationen kann man dann (wenn man möchte) durch eine Berichtsansicht wieder einschränken und dann im Druckformat verarbeiten. Ein derartiges Druckformat erzeugt man im Fenster &amp;quot;Druckformat&amp;quot;, wo man die Tabelle und die Ansicht bei der Neuanlage des Datensatzes einstellen kann. Dann erzeugt man die Felder mittels des automatischen Proßess-Knopfes hierfür und kann dann das Druckformat schon im Zielfenster einstellen und dort in der Druckansicht benutzen. Ist diese das erste Mal zu sehen, kann man es dann wie gewöhnlich entstandene Druckformate auch anpassen.&lt;br /&gt;
&lt;br /&gt;
=== Drucken per Programm ===&lt;br /&gt;
&lt;br /&gt;
Mit der folgenden Methode kann ich in meinem Model für die Tabelle BAY_InterestCalculation einen Ausdruck veranlassen, der auf einem View basiert, das RV_BAY_InterestCalculation heisst. Man kann diese Methode z.B. in completeIt() aufrufen, um dafür zu sorgen, das ein Dokument immer gedruckt wird, wenn es abgeschlossen wird. Man kann übrigens im Prozeßfenster einstellen, ob der Ausdruck sofort im Hintergrund oder erst mit Rückfrage geschieht.&lt;br /&gt;
&lt;br /&gt;
  public void print() {&lt;br /&gt;
    int viewTable = MTable.getTable_ID(&amp;quot;RV_&amp;quot; + Table_Name);&lt;br /&gt;
    MPrintFormat format = new Query(getCtx(), MPrintFormat.Table_Name, MPrintFormat.COLUMNNAME_AD_Table_ID&lt;br /&gt;
      + &amp;quot;=? AND &amp;quot; + MPrintFormat.COLUMNNAME_IsDefault + &amp;quot;=? &amp;quot;, get_TrxName()).setParameters(viewTable, &amp;quot;Y&amp;quot;)&lt;br /&gt;
      .first();&lt;br /&gt;
    MQuery query = new MQuery(get_Table_ID());&lt;br /&gt;
    query.addRestriction(get_KeyColumns()[0], MQuery.EQUAL, get_ID());&lt;br /&gt;
    PrintInfo info = new PrintInfo(getDocumentInfo(), get_Table_ID(), get_ID());&lt;br /&gt;
    ReportEngine re = new ReportEngine(getCtx(), format, query, info, get_TrxName());&lt;br /&gt;
    re.print();&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
= Links =&lt;br /&gt;
&lt;br /&gt;
== Artikel, die Dokumente erklären ==&lt;br /&gt;
&lt;br /&gt;
Basiserklärungen&lt;br /&gt;
&lt;br /&gt;
* http://wiki.idempiere.org/en/Create_a_custom_document_class - recht neuer Artikel von Daniel Tamm im iDempiere Wiki, hat noch viele Lücken&lt;br /&gt;
* http://www.adempiere.com/How_to_create_a_new_document_with_specific_accounting&lt;br /&gt;
&lt;br /&gt;
weiterführende Erklärungen&lt;br /&gt;
&lt;br /&gt;
* http://www.adempiere.com/How_to_Activate_Document_Approval_Workflow&lt;br /&gt;
* http://www.adempiere.com/Document_Action_Dialog - Erklärung zum Action Button und dem davon aufgehenden Fenster&lt;br /&gt;
* http://www.adempiere.com/Document_Sequence - Document Sequence&lt;br /&gt;
* Erweiterungen&lt;br /&gt;
** http://www.adempiere.com/Enhance_Document_No_Formatting - Verbesserung der Dokumentnummerierung (hierdurch sind Kontextvariablen erlaubt)&lt;br /&gt;
** http://wiki.idempiere.org/en/NF001_Document_Sequence_Improved - Verbesserung bzgl. Organisationen und Neustart von Nummernkreisen&lt;br /&gt;
** http://www.adempiere.com/Sponsored_Development:_Document_Signing - Document Signing Erweiterung, augenscheinlich nie verwirklicht worden&lt;br /&gt;
&lt;br /&gt;
Artikel, die ich als Quellen verwendet, aber bereits weitgehend hier eingearbeitet habe:&lt;br /&gt;
&lt;br /&gt;
* http://www.adempiere.com/HOWTO_Process_Documents - erklärt recht gut die Benutzung der vorhandenen Dokumenttypen; weniger die Entwicklung neuer&lt;br /&gt;
* http://en.wikiversity.org/wiki/Adempiere_Technical_Training#Document_Process_Workflow - enthält kurze, aber aufschlussreiche Teile zum Thema, insbesondere &amp;quot;Document Process Workflow&amp;quot;&lt;br /&gt;
* http://www.adempiere.com/Document_Engine&lt;br /&gt;
* https://groups.google.com/forum/#!topic/idempiere/WtTlVL1ZjWw - kurzed Forumsthread darüber, wie man einen Workflow implementieren kann&lt;br /&gt;
&lt;br /&gt;
Fenster, die mit Dokumenten zusammenhängen:&lt;br /&gt;
&lt;br /&gt;
* http://wiki.idempiere.org/en/Document_Type_%28Window_ID-135%29&lt;br /&gt;
* http://wiki.idempiere.org/en/Document_Sequence_%28Window_ID-112%29&lt;br /&gt;
&lt;br /&gt;
* http://wiki.idempiere.org/en/Unprocessed_Documents_%28All%29_%28Window_ID-53087%29&lt;br /&gt;
* http://wiki.idempiere.org/en/UnPosted_Documents_%28Window_ID-294%29&lt;br /&gt;
* http://wiki.idempiere.org/en/My_Unprocessed_Documents_%28Window_ID-53086%29&lt;br /&gt;
* http://wiki.idempiere.org/de/Workflow_%28Fenster_ID-113%29&lt;br /&gt;
&lt;br /&gt;
(Was ist der Unterschied zwischen &amp;quot;unprocessed&amp;quot; und &amp;quot;unposted&amp;quot; und woher wissen diese Fenster, welche Tabellen sie absuchen sollen?)&lt;br /&gt;
&lt;br /&gt;
* http://wiki.idempiere.org/en/Verify_Document_Types_%28Process_ID-233%29 - was macht dieser Prozeß? Er erzeugt wohl Open-Einträge für neue Dokumenttypen. Sonst noch was?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= weitere Informationen =&lt;br /&gt;
&lt;br /&gt;
== involvierte Klassen und Interfaces ==&lt;br /&gt;
&lt;br /&gt;
=== MSetup ===&lt;br /&gt;
&lt;br /&gt;
Create the list of document type for new Client ( Method createAccounting ). &lt;br /&gt;
&lt;br /&gt;
=== org.compiere.server.AcctProcessor ===&lt;br /&gt;
&lt;br /&gt;
Background process running on the JBoss server that perform the accounting document posting process. &lt;br /&gt;
&lt;br /&gt;
=== org.compiere.grid.ed.VDocAction ===&lt;br /&gt;
&lt;br /&gt;
Define hardcoded in dynInit method the list of possible transitions, and transitions by table &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Beispiele für die Implementierung einiger DocAction-Methoden =&lt;br /&gt;
&lt;br /&gt;
=== getDocumentInfo() ===&lt;br /&gt;
&lt;br /&gt;
Ergibt eine kurze aber eindeutige Bezeichnung des Datensatzes, die vor allem in Logzeilen und sonstigen Programm-Mitteilungen verwendet wird. Dieses Beispiel nutzt einen vorhandenen Documenttyp.&lt;br /&gt;
&lt;br /&gt;
  public String getDocumentInfo(){&lt;br /&gt;
    MDocType dt = MDocType.get(getCtx(), getC_DocType_ID());&lt;br /&gt;
    String msgreturn = dt.getNameTrl()+&amp;quot; &amp;quot;+getDocumentNo();&lt;br /&gt;
    return msgreturn.toString();&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
=== createPDF() ===&lt;br /&gt;
&lt;br /&gt;
Es gibt eine Methode, um das Dokument als PDF auszugeben. Diese wird - soweit ich gesehen habe - nur benutzt, um das Dokument per EMail zu versenden. Da man aber nie weiss, kann man das z.B. so wie folgend implementieren. Dabei kann man bei der Auswähl des Printformats natürlich auch genauer auswählen.&lt;br /&gt;
&lt;br /&gt;
  public File createPDF (){&lt;br /&gt;
    try{&lt;br /&gt;
      StringBuilder msgfile = new StringBuilder().append(get_TableName()).append(get_ID()).append(&amp;quot;_&amp;quot;);&lt;br /&gt;
      File temp = File.createTempFile(msgfile.toString(), &amp;quot;.pdf&amp;quot;);&lt;br /&gt;
      return createPDF (temp);&lt;br /&gt;
    }catch (Exception e){&lt;br /&gt;
      log.severe(&amp;quot;Could not create PDF - &amp;quot; + e.getMessage());&lt;br /&gt;
    }&lt;br /&gt;
    return null;&lt;br /&gt;
  }&lt;br /&gt;
  &lt;br /&gt;
  public File createPDF (File file){&lt;br /&gt;
    MPrintFormat format = MPrintFormat.get(getCtx(), 0, get_Table_ID());&lt;br /&gt;
    MQuery query=new MQuery(get_Table_ID());&lt;br /&gt;
    query.addRestriction(get_KeyColumns()[0],MQuery.EQUAL,get_ID());&lt;br /&gt;
    PrintInfo info = new PrintInfo(getDocumentNo(),get_Table_ID(),0);&lt;br /&gt;
    ReportEngine re = new ReportEngine(getCtx(), format, query, info, get_TrxName());&lt;br /&gt;
    &lt;br /&gt;
    if(format.getJasperProcess_ID() &amp;gt; 0){&lt;br /&gt;
      // JasperReports Print Format&lt;br /&gt;
      ProcessInfo pi = new ProcessInfo (&amp;quot;&amp;quot;, format.getJasperProcess_ID());&lt;br /&gt;
      pi.setRecord_ID(get_ID());&lt;br /&gt;
      pi.setIsBatch(true);&lt;br /&gt;
      ServerProcessCtl.process(pi, null);&lt;br /&gt;
      return pi.getPDFReport();&lt;br /&gt;
    }else{&lt;br /&gt;
      // Standard Print Format (Non-Jasper)&lt;br /&gt;
      return re.getPDF(file);&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Development‏‎]]&lt;br /&gt;
[[Category:Developer documentation‏‎]]&lt;br /&gt;
[[Category:System administration‏‎]]&lt;br /&gt;
[[Category:Applying means‏‎]]&lt;br /&gt;
[[Category:Document‎]]&lt;br /&gt;
[[Category:Workflow]]&lt;/div&gt;</summary>
		<author><name>Tioraul</name></author>
	</entry>
	<entry>
		<id>https://wiki.idempiere.org/w-en/index.php?title=Business_Partner_Manual&amp;diff=14295</id>
		<title>Business Partner Manual</title>
		<link rel="alternate" type="text/html" href="https://wiki.idempiere.org/w-en/index.php?title=Business_Partner_Manual&amp;diff=14295"/>
		<updated>2018-06-01T15:16:11Z</updated>

		<summary type="html">&lt;p&gt;Tioraul: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__TOC__&lt;br /&gt;
&lt;br /&gt;
This tutorial is brought to you by Dr. Stanley Mungwe from IT-Kamer Company Ltd and ERP University Cameroon (http://erp-university-africa.com). If you have questions, criticism or improvement suggestions, feel free to visit me ([[User:Doctor|Doctor]]) or write me [mailto:sales@itkamer.com an email]. Thanks goes to Jan Thielmann for the initial discussions around this.&lt;br /&gt;
&lt;br /&gt;
=Goal of Manual=&lt;br /&gt;
The goal of this manual is to give you an introduction to Business Partner in Idempiere from a user's perspective.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Introduction to Business Partner=&lt;br /&gt;
A Business Partner in Idempiere represents an entity with whom you carry out business operations. Idempiere differentiates three different types of Business Partners: Vendors, Customers, and Employees or any combination of the three.&lt;br /&gt;
&lt;br /&gt;
A Business Partner should have one or more Locations and one or more Contacts, which can or may not be linked to a location. Contacts can have Interest Areas. These Interest Areas are the basis for Customer Relationship Management and gives a sales personnel or sales representative the opportunity to manage Email-Lists. &lt;br /&gt;
&lt;br /&gt;
In Idempiere a Business Partner also possess a &amp;quot;Bank Account&amp;quot; and &amp;quot;Withholding&amp;quot; capabilities.&lt;br /&gt;
&lt;br /&gt;
Relationships can exist between Business Partners and other Business Partners. This enables a Sales Order to be shipped to one Business Partner and Invoiced to a second Business Partner.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:User Manual]]&lt;br /&gt;
[[Category: Business Partner]]&lt;br /&gt;
[[Category: Business Partner base data]]&lt;/div&gt;</summary>
		<author><name>Tioraul</name></author>
	</entry>
	<entry>
		<id>https://wiki.idempiere.org/w-en/index.php?title=Install_Prerequisites&amp;diff=14117</id>
		<title>Install Prerequisites</title>
		<link rel="alternate" type="text/html" href="https://wiki.idempiere.org/w-en/index.php?title=Install_Prerequisites&amp;diff=14117"/>
		<updated>2017-12-11T22:50:09Z</updated>

		<summary type="html">&lt;p&gt;Tioraul: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;!-- breadcrumb --&amp;gt;&lt;br /&gt;
&amp;lt;font size=-2&amp;gt;&lt;br /&gt;
&amp;amp;lArr;&lt;br /&gt;
[[Installing iDempiere|Table of Contents]] |&lt;br /&gt;
Install Prerequisites |&lt;br /&gt;
[[Downloading Installers]]&lt;br /&gt;
&amp;amp;rArr;&lt;br /&gt;
&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In order to run iDempiere you need to have a JDK (not JRE) version of java, and a proper database (PostgreSQL and Oracle are supported).&lt;br /&gt;
&lt;br /&gt;
The examples on this guide are using the following versions:&lt;br /&gt;
* Ubuntu 16.04.1 64 bits&lt;br /&gt;
* PostgreSQL 9.6.1&lt;br /&gt;
* PostgreSQL contrib (for UUID support)&lt;br /&gt;
* OpenJDK 1.8.0_91&lt;br /&gt;
&lt;br /&gt;
But this guide can be used in other systems (even Windows) taking care of installing the corresponding packages and using corresponding commands.&lt;br /&gt;
&lt;br /&gt;
== Install Ubuntu ==&lt;br /&gt;
&lt;br /&gt;
Please refer to http://www.ubuntu.com/download&lt;br /&gt;
&lt;br /&gt;
Downloaded and installed Ubuntu Server 16.04.1 LTS&lt;br /&gt;
&lt;br /&gt;
== Install PostgreSQL 9.6.1 ==&lt;br /&gt;
&lt;br /&gt;
iDempiere can also run with Oracle 10G or 11G, and also with PostgreSQL 8.4 to 9.3, but for this tutorial we use postgresql 9.4.1 - see http://www.postgresql.org/download/linux/ubuntu/ for details&lt;br /&gt;
&lt;br /&gt;
 echo &amp;quot;deb http://apt.postgresql.org/pub/repos/apt/ xenial-pgdg main&amp;quot; | sudo tee /etc/apt/sources.list.d/pgdg.list&lt;br /&gt;
 wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | sudo apt-key add -&lt;br /&gt;
 sudo apt-get update&lt;br /&gt;
 sudo apt-get install postgresql-9.6 postgresql-contrib-9.6&lt;br /&gt;
 sudo service postgresql start&lt;br /&gt;
 sudo update-rc.d postgresql defaults&lt;br /&gt;
&lt;br /&gt;
=== Assign a password to user postgres ===&lt;br /&gt;
&lt;br /&gt;
In order to create the database the installer needs to know the password of user postgres, by default this user doesn't have a password in ubuntu (windows installer asks for a password).&lt;br /&gt;
&lt;br /&gt;
In the event that there's no 'postgres' role in your postgres db, you have to create on your own using the following steps:&lt;br /&gt;
&lt;br /&gt;
# Connect to your postgres db instance via psql.&lt;br /&gt;
# Create 'postgres' role via &amp;quot;CREATE USER postgres&amp;quot; without the double quote.&lt;br /&gt;
# Alter the role and specify what the role suppose to be. EX. &amp;quot;ALTER USER postgres SUPERUSER CREATEDB&amp;quot; without the double quote.&lt;br /&gt;
&lt;br /&gt;
Then you can proceed to the following steps.&lt;br /&gt;
&lt;br /&gt;
Please take note of the password you assign here as it will be required in the setup process:&lt;br /&gt;
&lt;br /&gt;
Steps are (replace your_chosen_password by your preferred):&lt;br /&gt;
&lt;br /&gt;
 sudo su - postgres&lt;br /&gt;
 psql -U postgres -c &amp;quot;alter user postgres unencrypted password 'your_chosen_password'&amp;quot;&lt;br /&gt;
 logout&lt;br /&gt;
&lt;br /&gt;
== Install OpenJDK 1.8.0_91 ==&lt;br /&gt;
&lt;br /&gt;
 sudo apt-get install openjdk-8-jdk&lt;br /&gt;
&lt;br /&gt;
Now you have your prerequisites ready to receive the iDempiere installer&lt;br /&gt;
&lt;br /&gt;
== Troubleshooting ==&lt;br /&gt;
&lt;br /&gt;
=== Linux  ===&lt;br /&gt;
&lt;br /&gt;
After installing postgres you must check the correct configuration of /etc/postgresql/9.6/main/pg_hba.conf.&lt;br /&gt;
These two entries must be configured to use password (md5):&lt;br /&gt;
 local   all         all                               md5&lt;br /&gt;
 host    all         all         127.0.0.1/32          md5&lt;br /&gt;
NOTE that some guides suggest configuring trust - but that creates a security issue on your postgres server.&lt;br /&gt;
&lt;br /&gt;
=== Windows ===&lt;br /&gt;
&lt;br /&gt;
Most installation problems in Windows are caused by not configured environment variables:&lt;br /&gt;
* PATH must be configured to make the commands psql and jar accessible&lt;br /&gt;
* JAVA_HOME environment variable must be configured&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
''This tutorial is brought to you by [[User:CarlosRuiz|Carlos Ruiz]] from [http://globalqss.com GlobalQSS].  Feel free to improve directly or suggest using the Discussion tab.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:User Manual|I]]&lt;br /&gt;
[[Category:Installation|L]] &lt;br /&gt;
[[Category:Installation Linux]] &lt;br /&gt;
[[Category:Installation Windows]]&lt;br /&gt;
[[Category:Installation Server‏‎]]&lt;br /&gt;
[[Category:Installation Database‏‎]]&lt;/div&gt;</summary>
		<author><name>Tioraul</name></author>
	</entry>
	<entry>
		<id>https://wiki.idempiere.org/w-en/index.php?title=Plugin:_LCL_Rut_Taxid&amp;diff=11908</id>
		<title>Plugin: LCL Rut Taxid</title>
		<link rel="alternate" type="text/html" href="https://wiki.idempiere.org/w-en/index.php?title=Plugin:_LCL_Rut_Taxid&amp;diff=11908"/>
		<updated>2017-09-01T01:06:21Z</updated>

		<summary type="html">&lt;p&gt;Tioraul: corrige link archivo zip&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
* '''Maintainer:''' [[User:Tioraul|Raul Vasquez]] &lt;br /&gt;
* '''Status:''' Testing&lt;br /&gt;
* '''License:''' [http://www.gnu.org/licenses/gpl-2.0.html GPLv2]&lt;br /&gt;
* '''Price:''' Free&lt;br /&gt;
* '''Bitbucket Repository:''' [https://bitbucket.org/raul_vasquez/lcl/downloads/VerificadorRutChile.zip]&lt;br /&gt;
* '''Zip file:''' VerificadorRutChile.zip&lt;br /&gt;
* '''Sources:''' [https://bitbucket.org/raul_vasquez/lcl bitbucket]&lt;br /&gt;
* '''On Feature:''' VerificadorRutChile.feature.group&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Description ==&lt;br /&gt;
&lt;br /&gt;
This functionality adds chilean Tax Id RUT Verification on TaxID field&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Feedback ==&lt;br /&gt;
&lt;br /&gt;
Please rate this plugin:&lt;br /&gt;
 &lt;br /&gt;
{{#w4grb_rate:Plugin:_LCL_Rut_Taxid}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;w4grb_ratinglist pagevotes idpage=&amp;quot;Plugin:_LCL_Rut_Taxid&amp;quot; items=&amp;quot;30&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If you want to provide additional comments, please use the [[Talk:Plugin:_LCL_Rut_Taxid|Discussion page]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== How to Install ==&lt;br /&gt;
There are two ways to install, Felix Console or P2 Repository.&lt;br /&gt;
&lt;br /&gt;
=== Felix Console ===&lt;br /&gt;
&lt;br /&gt;
watch this video (spanish)[https://www.youtube.com/watch?v=oAQUK2FJBV0]&lt;br /&gt;
&lt;br /&gt;
=== P2 Repository ===&lt;br /&gt;
&lt;br /&gt;
Unzip VerificadorRutChile.zip&lt;br /&gt;
&lt;br /&gt;
 DESTINATION=/opt/idempiere-server  # Where your iDempiere server is installed&lt;br /&gt;
 REPO=/folder/where/you/unzip/VericadorRutChile.zip&lt;br /&gt;
 cd $DESTINATION&lt;br /&gt;
 sudo java -Dosgi.noShutdown=false -Dosgi.compatibility.bootdelegation=true -Dosgi.install.area=director \&lt;br /&gt;
   -jar plugins/org.eclipse.osgi_3.7.*.jar -application org.eclipse.equinox.p2.director \&lt;br /&gt;
   -consoleLog -profileProperties org.eclipse.update.install.features=true \&lt;br /&gt;
   -destination $DESTINATION -repository file://$REPO \&lt;br /&gt;
   -i VerificadorRutChile.feature.group&lt;br /&gt;
&lt;br /&gt;
Replace the DESTINATION variable with the folder where your iDempiere server is installed.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Available_Plugins]]&lt;br /&gt;
[[Category:Localisation|C]]&lt;/div&gt;</summary>
		<author><name>Tioraul</name></author>
	</entry>
	<entry>
		<id>https://wiki.idempiere.org/w-en/index.php?title=Queries:_AD&amp;diff=6968</id>
		<title>Queries: AD</title>
		<link rel="alternate" type="text/html" href="https://wiki.idempiere.org/w-en/index.php?title=Queries:_AD&amp;diff=6968"/>
		<updated>2015-05-15T22:02:46Z</updated>

		<summary type="html">&lt;p&gt;Tioraul: /* Tabs */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Code Scratchpad]]&lt;br /&gt;
&lt;br /&gt;
= Client =&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;select ad_client_id,value,name from ad_client order by ad_client_id;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Windows =&lt;br /&gt;
== Tabs ==&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;select b.name as WindowName from ad_tab a&lt;br /&gt;
join ad_window b on a.ad_window_id = b.ad_window_id&lt;br /&gt;
where &lt;br /&gt;
	a.ad_table_id = &lt;br /&gt;
	(select ad_table_id from ad_table where name='tablename');&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Combining Window, tab, field ==&lt;br /&gt;
	&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;select &lt;br /&gt;
	win.name as WindowName, &lt;br /&gt;
	tab.name as TabName,&lt;br /&gt;
	tabtable.tablename as TabTable, &lt;br /&gt;
	fld.name as field_display_name, &lt;br /&gt;
	fld.displaylogic as field_display_logic,&lt;br /&gt;
	fld.readonlylogic as field_readonly_logic,&lt;br /&gt;
	col.columnname as column_name,&lt;br /&gt;
	ref.name as ref_name, refvalue.name as ref_value,&lt;br /&gt;
	refvalue.ad_reference_id,&lt;br /&gt;
	reftabletbl.tablename as ref_table&lt;br /&gt;
from &lt;br /&gt;
	ad_field fld&lt;br /&gt;
join ad_tab tab on fld.ad_tab_id = tab.ad_tab_id&lt;br /&gt;
join ad_table tabtable on tabtable.ad_table_id = tab.ad_table_id&lt;br /&gt;
join ad_window win on tab.ad_window_id = win.ad_window_id&lt;br /&gt;
join ad_column col on fld.ad_column_id = col.ad_column_id&lt;br /&gt;
left join ad_reference ref on col.ad_reference_id = ref.ad_reference_id&lt;br /&gt;
left join ad_reference refvalue on col.ad_reference_value_id = refvalue.ad_reference_id&lt;br /&gt;
left join ad_ref_table reftable on reftable.ad_reference_id = refvalue.ad_reference_id&lt;br /&gt;
left join ad_table reftabletbl on reftabletbl.ad_table_id = reftable.ad_table_id&lt;br /&gt;
where &lt;br /&gt;
	--upper(win.name) like upper('Window Name') and&lt;br /&gt;
	fld.isdisplayed = 'Y' -- and&lt;br /&gt;
	--upper(col.columnname) = upper('columnname')&lt;br /&gt;
	upper(fld.name) like upper('Field Name')&lt;br /&gt;
	--upper(tabtable.tablename) = upper('tablename')&lt;br /&gt;
order by win.name, tab.seqno, col.columnname&lt;br /&gt;
	;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
	&lt;br /&gt;
== Shorter field info ==&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;select &lt;br /&gt;
	--win.name as WindowName, &lt;br /&gt;
	tab.name as TabName,&lt;br /&gt;
	tabtable.tablename as TabTable, &lt;br /&gt;
	fld.seqno,&lt;br /&gt;
	fld.name as field_display_name, &lt;br /&gt;
	--fld.displaylogic as field_display_logic,&lt;br /&gt;
	--fld.readonlylogic as field_readonly_logic,&lt;br /&gt;
	col.columnname as column_name&lt;br /&gt;
	--ref.name as ref_name, refvalue.name as ref_value,&lt;br /&gt;
	--refvalue.ad_reference_id,&lt;br /&gt;
	--reftabletbl.tablename as ref_table&lt;br /&gt;
from &lt;br /&gt;
	ad_field fld&lt;br /&gt;
join ad_tab tab on fld.ad_tab_id = tab.ad_tab_id&lt;br /&gt;
join ad_table tabtable on tabtable.ad_table_id = tab.ad_table_id&lt;br /&gt;
join ad_window win on tab.ad_window_id = win.ad_window_id&lt;br /&gt;
join ad_column col on fld.ad_column_id = col.ad_column_id&lt;br /&gt;
left join ad_reference ref on col.ad_reference_id = ref.ad_reference_id&lt;br /&gt;
left join ad_reference refvalue on col.ad_reference_value_id = refvalue.ad_reference_id&lt;br /&gt;
left join ad_ref_table reftable on reftable.ad_reference_id = refvalue.ad_reference_id&lt;br /&gt;
left join ad_table reftabletbl on reftabletbl.ad_table_id = reftable.ad_table_id&lt;br /&gt;
where &lt;br /&gt;
	--upper(win.name) like upper('Window Name') and&lt;br /&gt;
	fld.isdisplayed = 'Y'  and&lt;br /&gt;
	--upper(col.columnname) = upper('column_name') and&lt;br /&gt;
	--upper(fld.name) like upper('User column name')&lt;br /&gt;
	--upper(tabtable.tablename) = upper('tablename') and&lt;br /&gt;
	win.name in ( 'Window Name' ) --and &lt;br /&gt;
	--tab.seqno = 10&lt;br /&gt;
order by win.name, tab.seqno, fld.seqno, col.columnname&lt;br /&gt;
	;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Windows referencing a specific process ==&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;select name from ad_window where ad_window_id in (&lt;br /&gt;
select ad_window_id from ad_tab where ad_process_id in (&lt;br /&gt;
select ad_process_id from ad_process where value = 'processname')&lt;br /&gt;
);&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Window ==&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;select * from ad_window a&lt;br /&gt;
where a.ad_window_id=id&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Tab ==&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;select * from ad_tab a&lt;br /&gt;
where a.ad_window_id=id&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Field ==&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;select a.* from ad_field a&lt;br /&gt;
join ad_tab b on a.ad_tab_id=b.ad_tab_id&lt;br /&gt;
where b.ad_window_id=id&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Table =&lt;br /&gt;
== Table ==&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;select a.* from ad_table a&lt;br /&gt;
where a.ad_table_id in (id, id)&lt;br /&gt;
&lt;br /&gt;
(select ad_table_id from ad_table where tablename='tablename')&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Table Columns =&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;select a.name, a.columnname from ad_column a&lt;br /&gt;
join ad_element b on a.ad_element_id=b.ad_element_id&lt;br /&gt;
where a.ad_table_id in ((select ad_table_id from ad_table where tablename='tablename'))&lt;br /&gt;
order by a.name;&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Callout =&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;select a.ad_column_id,tbl.tablename, a.columnname,a.name, a.callout from ad_column a&lt;br /&gt;
join ad_table tbl on a.ad_table_id = tbl.ad_table_id&lt;br /&gt;
where a.callout is not null and a.callout like '%bPartner%'&lt;br /&gt;
order by tbl.tablename, a.callout, a.name;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Update callout ==&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;update ad_column set callout = 'org.compiere.model.CalloutInvoiceNew.bPartner' where ad_column_id = 3499;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= References =&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;select * from ad_ref_list where ad_reference_id in ( select ad_reference_id from ad_reference where name = 'Ref Name' );&lt;br /&gt;
-&lt;br /&gt;
Incomplete:&lt;br /&gt;
left join&lt;br /&gt;
	ad_reference ref on ref.name = 'ZZ_Status'&lt;br /&gt;
left join&lt;br /&gt;
	ad_ref_list reflist on reflist.ad_reference_id = ref.ad_reference_id and reflist.value = perm.zz_status&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Elements =&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;select b.* from ad_column a&lt;br /&gt;
join ad_element b on a.ad_element_id=b.ad_element_id&lt;br /&gt;
where a.ad_table_id in (1000153, 1000152, 1000154, 1000156)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Report and process =&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;select * from ad_process order by created desc;&lt;br /&gt;
&lt;br /&gt;
select * from ad_process_para where ad_process_para_id = 1000000;&lt;br /&gt;
&lt;br /&gt;
select columnname, name, defaultvalue from ad_process_para where ad_process_id = 1000000 order by seqno;&lt;br /&gt;
&lt;br /&gt;
update ad_process_para set defaultvalue='1' where ad_process_id = 1000000 and columnname = 'columname';	--Sequence&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Delete fields from window =&lt;br /&gt;
== Delete all fields on window ==&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;delete from ad_field where ad_tab_id in ( select ad_tab_id from ad_tab where ad_window_id in &lt;br /&gt;
(&lt;br /&gt;
	select ad_window_id from ad_window where name like 'Name of window' &lt;br /&gt;
) );&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Delete all fields on tab ==&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;delete from ad_field where ad_tab_id in ( select ad_tab_id from ad_tab where name = 'tabname' and ad_window_id in &lt;br /&gt;
(&lt;br /&gt;
	select ad_window_id from ad_window where name = 'Name of window' &lt;br /&gt;
) );&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Sequences =&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;update ad_sequence a set CURRENTNEXTSYS =13000  where a.name = 'name';&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Doctype =&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;select c_doctype_id from c_doctype where name = 'DocumentName'&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Delete all attachments of process =&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;delete from ad_attachment where record_id in (&lt;br /&gt;
	select ad_process_id from ad_process where value like 'processname%' ) ...&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Synchronize Translations =&lt;br /&gt;
&lt;br /&gt;
An example:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;update ad_process_trl a set name = b.name, description = b.name from ad_process b where a.ad_process_id = b.ad_process_id and b.name = 'Process Name';&amp;lt;/nowiki&amp;gt;&lt;/div&gt;</summary>
		<author><name>Tioraul</name></author>
	</entry>
	<entry>
		<id>https://wiki.idempiere.org/w-en/index.php?title=Plugin:_LCL_Rut_Taxid&amp;diff=6804</id>
		<title>Plugin: LCL Rut Taxid</title>
		<link rel="alternate" type="text/html" href="https://wiki.idempiere.org/w-en/index.php?title=Plugin:_LCL_Rut_Taxid&amp;diff=6804"/>
		<updated>2015-04-19T20:53:40Z</updated>

		<summary type="html">&lt;p&gt;Tioraul: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
* '''Maintainer:''' [[User:Tioraul|Raul Vasquez]] &lt;br /&gt;
* '''Status:''' Testing&lt;br /&gt;
* '''License:''' [http://www.gnu.org/licenses/gpl-2.0.html GPLv2]&lt;br /&gt;
* '''Price:''' Free&lt;br /&gt;
* '''Bitbucket Repository:''' [https://bitbucket.org/raul_vasquez/lcl/src/488c4614acd4dca27e3bdee1a2195bdcbe8f2d44/VerificadorRutChile.zip?at=default#]&lt;br /&gt;
* '''Zip file:''' VerificadorRutChile.zip&lt;br /&gt;
* '''Sources:''' [https://bitbucket.org/raul_vasquez/lcl bitbucket]&lt;br /&gt;
* '''On Feature:''' VerificadorRutChile.feature.group&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Description ==&lt;br /&gt;
&lt;br /&gt;
This functionality adds chilean Tax Id RUT Verification on TaxID field&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Feedback ==&lt;br /&gt;
&lt;br /&gt;
Please rate this plugin:&lt;br /&gt;
 &lt;br /&gt;
{{#w4grb_rate:Plugin:_LCL_Rut_Taxid}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;w4grb_ratinglist pagevotes idpage=&amp;quot;Plugin:_LCL_Rut_Taxid&amp;quot; items=&amp;quot;30&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If you want to provide additional comments, please use the [[Talk:Plugin:_LCL_Rut_Taxid|Discussion page]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== How to Install ==&lt;br /&gt;
There are two ways to install, Felix Console or P2 Repository.&lt;br /&gt;
&lt;br /&gt;
=== Felix Console ===&lt;br /&gt;
&lt;br /&gt;
watch this video (spanish)[https://www.youtube.com/watch?v=oAQUK2FJBV0]&lt;br /&gt;
&lt;br /&gt;
=== P2 Repository ===&lt;br /&gt;
&lt;br /&gt;
Unzip VerificadorRutChile.zip&lt;br /&gt;
&lt;br /&gt;
 DESTINATION=/opt/idempiere-server  # Where your iDempiere server is installed&lt;br /&gt;
 REPO=/folder/where/you/unzip/VericadorRutChile.zip&lt;br /&gt;
 cd $DESTINATION&lt;br /&gt;
 sudo java -Dosgi.noShutdown=false -Dosgi.compatibility.bootdelegation=true -Dosgi.install.area=director \&lt;br /&gt;
   -jar plugins/org.eclipse.osgi_3.7.*.jar -application org.eclipse.equinox.p2.director \&lt;br /&gt;
   -consoleLog -profileProperties org.eclipse.update.install.features=true \&lt;br /&gt;
   -destination $DESTINATION -repository file://$REPO \&lt;br /&gt;
   -i VerificadorRutChile.feature.group&lt;br /&gt;
&lt;br /&gt;
Replace the DESTINATION variable with the folder where your iDempiere server is installed.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Available_Plugins]]&lt;/div&gt;</summary>
		<author><name>Tioraul</name></author>
	</entry>
	<entry>
		<id>https://wiki.idempiere.org/w-en/index.php?title=Plugin:_LCL_Rut_Taxid&amp;diff=6780</id>
		<title>Plugin: LCL Rut Taxid</title>
		<link rel="alternate" type="text/html" href="https://wiki.idempiere.org/w-en/index.php?title=Plugin:_LCL_Rut_Taxid&amp;diff=6780"/>
		<updated>2015-03-25T17:50:51Z</updated>

		<summary type="html">&lt;p&gt;Tioraul: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
* '''Maintainer:''' [[User:Tioraul|Raul Vasquez]] &lt;br /&gt;
* '''Status:''' Testing&lt;br /&gt;
* '''License:''' [http://www.gnu.org/licenses/gpl-2.0.html GPLv2]&lt;br /&gt;
* '''Price:''' Free&lt;br /&gt;
* '''Bitbucket Repository:''' [https://bitbucket.org/raul_vasquez/lcl/src/488c4614acd4dca27e3bdee1a2195bdcbe8f2d44/VerificadorRutChile.zip?at=default#]&lt;br /&gt;
* '''Zip file:''' VerificadorRutChile.zip&lt;br /&gt;
* '''Sources:''' [https://bitbucket.org/raul_vasquez/lcl bitbucket]&lt;br /&gt;
* '''On Feature:''' VerificadorRutChile.feature.group&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Description ==&lt;br /&gt;
&lt;br /&gt;
This functionality adds chilean Tax Id RUT Verification on TaxID field&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Feedback ==&lt;br /&gt;
&lt;br /&gt;
Please rate this plugin:&lt;br /&gt;
 &lt;br /&gt;
{{#w4grb_rate:Plugin:_LCL_Rut_Taxid}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;w4grb_ratinglist pagevotes idpage=&amp;quot;Plugin:_LCL_Rut_Taxid&amp;quot; items=&amp;quot;30&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If you want to provide additional comments, please use the [[Talk:Plugin:_LCL_Rut_Taxid|Discussion page]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== How to Install ==&lt;br /&gt;
There two ways to install, Felix Console or P2 Repository.&lt;br /&gt;
&lt;br /&gt;
=== Felix Console ===&lt;br /&gt;
&lt;br /&gt;
watch this video (spanish)[https://www.youtube.com/watch?v=oAQUK2FJBV0]&lt;br /&gt;
&lt;br /&gt;
=== P2 Repository ===&lt;br /&gt;
&lt;br /&gt;
Unzip VerificadorRutChile.zip&lt;br /&gt;
&lt;br /&gt;
 DESTINATION=/opt/idempiere-server  # Where your iDempiere server is installed&lt;br /&gt;
 REPO=/folder/where/you/unzip/VericadorRutChile.zip&lt;br /&gt;
 cd $DESTINATION&lt;br /&gt;
 sudo java -Dosgi.noShutdown=false -Dosgi.compatibility.bootdelegation=true -Dosgi.install.area=director \&lt;br /&gt;
   -jar plugins/org.eclipse.osgi_3.7.*.jar -application org.eclipse.equinox.p2.director \&lt;br /&gt;
   -consoleLog -profileProperties org.eclipse.update.install.features=true \&lt;br /&gt;
   -destination $DESTINATION -repository file://$REPO \&lt;br /&gt;
   -i VerificadorRutChile.feature.group&lt;br /&gt;
&lt;br /&gt;
Replace the DESTINATION variable with the folder where your iDempiere server is installed.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Available_Plugins]]&lt;/div&gt;</summary>
		<author><name>Tioraul</name></author>
	</entry>
	<entry>
		<id>https://wiki.idempiere.org/w-en/index.php?title=Plugin:_LCL_Rut_Taxid&amp;diff=6779</id>
		<title>Plugin: LCL Rut Taxid</title>
		<link rel="alternate" type="text/html" href="https://wiki.idempiere.org/w-en/index.php?title=Plugin:_LCL_Rut_Taxid&amp;diff=6779"/>
		<updated>2015-03-25T17:49:43Z</updated>

		<summary type="html">&lt;p&gt;Tioraul: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
* '''Maintainer:''' [[User:Tioraul|Raul Vasquez]] &lt;br /&gt;
* '''Status:''' Testing&lt;br /&gt;
* '''License:''' [http://www.gnu.org/licenses/gpl-2.0.html GPLv2]&lt;br /&gt;
* '''Price:''' Free&lt;br /&gt;
* '''Bitbucket Repository:''' [https://bitbucket.org/raul_vasquez/lcl/src/488c4614acd4dca27e3bdee1a2195bdcbe8f2d44/VerificadorRutChile.zip?at=default#]&lt;br /&gt;
* '''Zip file:''' VerificadorRutChile.zip&lt;br /&gt;
* '''Sources:''' [https://bitbucket.org/raul_vasquez/lcl bitbucket]&lt;br /&gt;
* '''On Feature:''' VerificadorRutChile.feature.group&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Description ==&lt;br /&gt;
&lt;br /&gt;
This functionality adds chilean Tax Id RUT Verification on TaxID field&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Feedback ==&lt;br /&gt;
&lt;br /&gt;
Please rate this plugin:&lt;br /&gt;
 &lt;br /&gt;
{{#w4grb_rate:Plugin:_LCL_Rut_Taxid}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;w4grb_ratinglist pagevotes idpage=&amp;quot;Plugin:_LCL_Rut_Taxid&amp;quot; items=&amp;quot;30&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If you want to provide additional comments, please use the [[Talk:Plugin:_LCL_Rut_Taxid|Discussion page]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== How to Install ==&lt;br /&gt;
There two ways to install:&lt;br /&gt;
&lt;br /&gt;
=== Felix Console ===&lt;br /&gt;
&lt;br /&gt;
watch this video (spanish)[https://www.youtube.com/watch?v=oAQUK2FJBV0]&lt;br /&gt;
&lt;br /&gt;
=== P2 Repository ===&lt;br /&gt;
&lt;br /&gt;
Unzip VerificadorRutChile.zip&lt;br /&gt;
&lt;br /&gt;
 DESTINATION=/opt/idempiere-server  # Where your iDempiere server is installed&lt;br /&gt;
 REPO=/folder/where/you/unzip/VericadorRutChile.zip&lt;br /&gt;
 cd $DESTINATION&lt;br /&gt;
 sudo java -Dosgi.noShutdown=false -Dosgi.compatibility.bootdelegation=true -Dosgi.install.area=director \&lt;br /&gt;
   -jar plugins/org.eclipse.osgi_3.7.*.jar -application org.eclipse.equinox.p2.director \&lt;br /&gt;
   -consoleLog -profileProperties org.eclipse.update.install.features=true \&lt;br /&gt;
   -destination $DESTINATION -repository file://$REPO \&lt;br /&gt;
   -i VerificadorRutChile.feature.group&lt;br /&gt;
&lt;br /&gt;
Replace the DESTINATION variable with the folder where your iDempiere server is installed.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Available_Plugins]]&lt;/div&gt;</summary>
		<author><name>Tioraul</name></author>
	</entry>
	<entry>
		<id>https://wiki.idempiere.org/w-en/index.php?title=Plugin:_LCL_Rut_Taxid&amp;diff=6778</id>
		<title>Plugin: LCL Rut Taxid</title>
		<link rel="alternate" type="text/html" href="https://wiki.idempiere.org/w-en/index.php?title=Plugin:_LCL_Rut_Taxid&amp;diff=6778"/>
		<updated>2015-03-25T17:46:53Z</updated>

		<summary type="html">&lt;p&gt;Tioraul: /* P2 Repository */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
* '''Maintainer:''' [[User:Tioraul|Raul Vasquez]] &lt;br /&gt;
* '''Status:''' Testing&lt;br /&gt;
* '''License:''' [http://www.gnu.org/licenses/gpl-2.0.html GPLv2]&lt;br /&gt;
* '''Price:''' Free&lt;br /&gt;
* '''Bitbucket Repository:''' [https://bitbucket.org/raul_vasquez/lcl/src/488c4614acd4dca27e3bdee1a2195bdcbe8f2d44/VerificadorRutChile.zip?at=default#]&lt;br /&gt;
* '''Zip file:''' VerificadorRutChile.zip&lt;br /&gt;
* '''Sources:''' [https://bitbucket.org/raul_vasquez/lcl bitbucket]&lt;br /&gt;
* '''On Feature:''' VerificadorRutChile.feature.group&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Description ==&lt;br /&gt;
&lt;br /&gt;
This functionality adds chilean Tax Id RUT Verification on TaxID field&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Feedback ==&lt;br /&gt;
&lt;br /&gt;
Please rate this plugin:&lt;br /&gt;
 &lt;br /&gt;
{{#w4grb_rate:Plugin:_LCL_Rut_Taxid}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;w4grb_ratinglist pagevotes idpage=&amp;quot;Plugin:_LCL_Rut_Taxid&amp;quot; items=&amp;quot;30&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If you want to provide additional comments, please use the [[Talk:Plugin:_LCL_Rut_Taxid|Discussion page]]&lt;br /&gt;
&lt;br /&gt;
== Configuration ==&lt;br /&gt;
&lt;br /&gt;
=== SysConfig Parameters ===&lt;br /&gt;
&lt;br /&gt;
N/A&lt;br /&gt;
&lt;br /&gt;
== How to Install ==&lt;br /&gt;
&lt;br /&gt;
=== Felix Console ===&lt;br /&gt;
&lt;br /&gt;
watch this video (spanish)[https://www.youtube.com/watch?v=oAQUK2FJBV0]&lt;br /&gt;
&lt;br /&gt;
=== P2 Repository ===&lt;br /&gt;
&lt;br /&gt;
Unzip VerificadorRutChile.zip&lt;br /&gt;
&lt;br /&gt;
 DESTINATION=/opt/idempiere-server  # Where your iDempiere server is installed&lt;br /&gt;
 REPO=/folder/where/you/unzip/VericadorRutChile.zip&lt;br /&gt;
 cd $DESTINATION&lt;br /&gt;
 sudo java -Dosgi.noShutdown=false -Dosgi.compatibility.bootdelegation=true -Dosgi.install.area=director \&lt;br /&gt;
   -jar plugins/org.eclipse.osgi_3.7.*.jar -application org.eclipse.equinox.p2.director \&lt;br /&gt;
   -consoleLog -profileProperties org.eclipse.update.install.features=true \&lt;br /&gt;
   -destination $DESTINATION -repository file://$REPO \&lt;br /&gt;
   -i VerificadorRutChile.feature.group&lt;br /&gt;
&lt;br /&gt;
Replace the DESTINATION variable with the folder where your iDempiere server is installed.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Available_Plugins]]&lt;/div&gt;</summary>
		<author><name>Tioraul</name></author>
	</entry>
	<entry>
		<id>https://wiki.idempiere.org/w-en/index.php?title=Plugin:_LCL_Rut_Taxid&amp;diff=6777</id>
		<title>Plugin: LCL Rut Taxid</title>
		<link rel="alternate" type="text/html" href="https://wiki.idempiere.org/w-en/index.php?title=Plugin:_LCL_Rut_Taxid&amp;diff=6777"/>
		<updated>2015-03-25T17:46:34Z</updated>

		<summary type="html">&lt;p&gt;Tioraul: /* P2 Repository */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
* '''Maintainer:''' [[User:Tioraul|Raul Vasquez]] &lt;br /&gt;
* '''Status:''' Testing&lt;br /&gt;
* '''License:''' [http://www.gnu.org/licenses/gpl-2.0.html GPLv2]&lt;br /&gt;
* '''Price:''' Free&lt;br /&gt;
* '''Bitbucket Repository:''' [https://bitbucket.org/raul_vasquez/lcl/src/488c4614acd4dca27e3bdee1a2195bdcbe8f2d44/VerificadorRutChile.zip?at=default#]&lt;br /&gt;
* '''Zip file:''' VerificadorRutChile.zip&lt;br /&gt;
* '''Sources:''' [https://bitbucket.org/raul_vasquez/lcl bitbucket]&lt;br /&gt;
* '''On Feature:''' VerificadorRutChile.feature.group&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Description ==&lt;br /&gt;
&lt;br /&gt;
This functionality adds chilean Tax Id RUT Verification on TaxID field&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Feedback ==&lt;br /&gt;
&lt;br /&gt;
Please rate this plugin:&lt;br /&gt;
 &lt;br /&gt;
{{#w4grb_rate:Plugin:_LCL_Rut_Taxid}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;w4grb_ratinglist pagevotes idpage=&amp;quot;Plugin:_LCL_Rut_Taxid&amp;quot; items=&amp;quot;30&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If you want to provide additional comments, please use the [[Talk:Plugin:_LCL_Rut_Taxid|Discussion page]]&lt;br /&gt;
&lt;br /&gt;
== Configuration ==&lt;br /&gt;
&lt;br /&gt;
=== SysConfig Parameters ===&lt;br /&gt;
&lt;br /&gt;
N/A&lt;br /&gt;
&lt;br /&gt;
== How to Install ==&lt;br /&gt;
&lt;br /&gt;
=== Felix Console ===&lt;br /&gt;
&lt;br /&gt;
watch this video (spanish)[https://www.youtube.com/watch?v=oAQUK2FJBV0]&lt;br /&gt;
&lt;br /&gt;
=== P2 Repository ===&lt;br /&gt;
&lt;br /&gt;
Unzip VerificadorRutChile.zip&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 DESTINATION=/opt/idempiere-server  # Where your iDempiere server is installed&lt;br /&gt;
 REPO=/folder/where/you/unzip/VericadorRutChile.zip&lt;br /&gt;
 cd $DESTINATION&lt;br /&gt;
 sudo java -Dosgi.noShutdown=false -Dosgi.compatibility.bootdelegation=true -Dosgi.install.area=director \&lt;br /&gt;
   -jar plugins/org.eclipse.osgi_3.7.*.jar -application org.eclipse.equinox.p2.director \&lt;br /&gt;
   -consoleLog -profileProperties org.eclipse.update.install.features=true \&lt;br /&gt;
   -destination $DESTINATION -repository file://$REPO \&lt;br /&gt;
   -i VerificadorRutChile.feature.group&lt;br /&gt;
&lt;br /&gt;
Replace the DESTINATION variable with the folder where your iDempiere server is installed.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Available_Plugins]]&lt;/div&gt;</summary>
		<author><name>Tioraul</name></author>
	</entry>
	<entry>
		<id>https://wiki.idempiere.org/w-en/index.php?title=Plugin:_LCL_Rut_Taxid&amp;diff=6776</id>
		<title>Plugin: LCL Rut Taxid</title>
		<link rel="alternate" type="text/html" href="https://wiki.idempiere.org/w-en/index.php?title=Plugin:_LCL_Rut_Taxid&amp;diff=6776"/>
		<updated>2015-03-25T17:45:16Z</updated>

		<summary type="html">&lt;p&gt;Tioraul: /* Felix Console */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
* '''Maintainer:''' [[User:Tioraul|Raul Vasquez]] &lt;br /&gt;
* '''Status:''' Testing&lt;br /&gt;
* '''License:''' [http://www.gnu.org/licenses/gpl-2.0.html GPLv2]&lt;br /&gt;
* '''Price:''' Free&lt;br /&gt;
* '''Bitbucket Repository:''' [https://bitbucket.org/raul_vasquez/lcl/src/488c4614acd4dca27e3bdee1a2195bdcbe8f2d44/VerificadorRutChile.zip?at=default#]&lt;br /&gt;
* '''Zip file:''' VerificadorRutChile.zip&lt;br /&gt;
* '''Sources:''' [https://bitbucket.org/raul_vasquez/lcl bitbucket]&lt;br /&gt;
* '''On Feature:''' VerificadorRutChile.feature.group&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Description ==&lt;br /&gt;
&lt;br /&gt;
This functionality adds chilean Tax Id RUT Verification on TaxID field&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Feedback ==&lt;br /&gt;
&lt;br /&gt;
Please rate this plugin:&lt;br /&gt;
 &lt;br /&gt;
{{#w4grb_rate:Plugin:_LCL_Rut_Taxid}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;w4grb_ratinglist pagevotes idpage=&amp;quot;Plugin:_LCL_Rut_Taxid&amp;quot; items=&amp;quot;30&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If you want to provide additional comments, please use the [[Talk:Plugin:_LCL_Rut_Taxid|Discussion page]]&lt;br /&gt;
&lt;br /&gt;
== Configuration ==&lt;br /&gt;
&lt;br /&gt;
=== SysConfig Parameters ===&lt;br /&gt;
&lt;br /&gt;
N/A&lt;br /&gt;
&lt;br /&gt;
== How to Install ==&lt;br /&gt;
&lt;br /&gt;
=== Felix Console ===&lt;br /&gt;
&lt;br /&gt;
watch this video (spanish)[https://www.youtube.com/watch?v=oAQUK2FJBV0]&lt;br /&gt;
&lt;br /&gt;
=== P2 Repository ===&lt;br /&gt;
&lt;br /&gt;
The recommended way to install the plugin is using the p2 repository.&lt;br /&gt;
&lt;br /&gt;
Unzip VerificadorRutChile.zip&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 DESTINATION=/opt/idempiere-server  # Where your iDempiere server is installed&lt;br /&gt;
 REPO=/folder/where/you/unzip/VericadorRutChile.zip&lt;br /&gt;
 cd $DESTINATION&lt;br /&gt;
 sudo java -Dosgi.noShutdown=false -Dosgi.compatibility.bootdelegation=true -Dosgi.install.area=director \&lt;br /&gt;
   -jar plugins/org.eclipse.osgi_3.7.*.jar -application org.eclipse.equinox.p2.director \&lt;br /&gt;
   -consoleLog -profileProperties org.eclipse.update.install.features=true \&lt;br /&gt;
   -destination $DESTINATION -repository file://$REPO \&lt;br /&gt;
   -i VerificadorRutChile.feature.group&lt;br /&gt;
&lt;br /&gt;
Replace the DESTINATION variable with the folder where your iDempiere server is installed.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Available_Plugins]]&lt;/div&gt;</summary>
		<author><name>Tioraul</name></author>
	</entry>
	<entry>
		<id>https://wiki.idempiere.org/w-en/index.php?title=Plugin:_LCL_Rut_Taxid&amp;diff=6775</id>
		<title>Plugin: LCL Rut Taxid</title>
		<link rel="alternate" type="text/html" href="https://wiki.idempiere.org/w-en/index.php?title=Plugin:_LCL_Rut_Taxid&amp;diff=6775"/>
		<updated>2015-03-25T17:44:36Z</updated>

		<summary type="html">&lt;p&gt;Tioraul: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
* '''Maintainer:''' [[User:Tioraul|Raul Vasquez]] &lt;br /&gt;
* '''Status:''' Testing&lt;br /&gt;
* '''License:''' [http://www.gnu.org/licenses/gpl-2.0.html GPLv2]&lt;br /&gt;
* '''Price:''' Free&lt;br /&gt;
* '''Bitbucket Repository:''' [https://bitbucket.org/raul_vasquez/lcl/src/488c4614acd4dca27e3bdee1a2195bdcbe8f2d44/VerificadorRutChile.zip?at=default#]&lt;br /&gt;
* '''Zip file:''' VerificadorRutChile.zip&lt;br /&gt;
* '''Sources:''' [https://bitbucket.org/raul_vasquez/lcl bitbucket]&lt;br /&gt;
* '''On Feature:''' VerificadorRutChile.feature.group&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Description ==&lt;br /&gt;
&lt;br /&gt;
This functionality adds chilean Tax Id RUT Verification on TaxID field&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Feedback ==&lt;br /&gt;
&lt;br /&gt;
Please rate this plugin:&lt;br /&gt;
 &lt;br /&gt;
{{#w4grb_rate:Plugin:_LCL_Rut_Taxid}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;w4grb_ratinglist pagevotes idpage=&amp;quot;Plugin:_LCL_Rut_Taxid&amp;quot; items=&amp;quot;30&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If you want to provide additional comments, please use the [[Talk:Plugin:_LCL_Rut_Taxid|Discussion page]]&lt;br /&gt;
&lt;br /&gt;
== Configuration ==&lt;br /&gt;
&lt;br /&gt;
=== SysConfig Parameters ===&lt;br /&gt;
&lt;br /&gt;
N/A&lt;br /&gt;
&lt;br /&gt;
== How to Install ==&lt;br /&gt;
&lt;br /&gt;
=== Felix Console ===&lt;br /&gt;
&lt;br /&gt;
watch this video (spanish)[watch this video]&lt;br /&gt;
&lt;br /&gt;
=== P2 Repository ===&lt;br /&gt;
&lt;br /&gt;
The recommended way to install the plugin is using the p2 repository.&lt;br /&gt;
&lt;br /&gt;
Unzip VerificadorRutChile.zip&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 DESTINATION=/opt/idempiere-server  # Where your iDempiere server is installed&lt;br /&gt;
 REPO=/folder/where/you/unzip/VericadorRutChile.zip&lt;br /&gt;
 cd $DESTINATION&lt;br /&gt;
 sudo java -Dosgi.noShutdown=false -Dosgi.compatibility.bootdelegation=true -Dosgi.install.area=director \&lt;br /&gt;
   -jar plugins/org.eclipse.osgi_3.7.*.jar -application org.eclipse.equinox.p2.director \&lt;br /&gt;
   -consoleLog -profileProperties org.eclipse.update.install.features=true \&lt;br /&gt;
   -destination $DESTINATION -repository file://$REPO \&lt;br /&gt;
   -i VerificadorRutChile.feature.group&lt;br /&gt;
&lt;br /&gt;
Replace the DESTINATION variable with the folder where your iDempiere server is installed.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Available_Plugins]]&lt;/div&gt;</summary>
		<author><name>Tioraul</name></author>
	</entry>
	<entry>
		<id>https://wiki.idempiere.org/w-en/index.php?title=Plugin:_LCL_Rut_Taxid&amp;diff=6302</id>
		<title>Plugin: LCL Rut Taxid</title>
		<link rel="alternate" type="text/html" href="https://wiki.idempiere.org/w-en/index.php?title=Plugin:_LCL_Rut_Taxid&amp;diff=6302"/>
		<updated>2014-10-28T15:19:27Z</updated>

		<summary type="html">&lt;p&gt;Tioraul: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
* '''Maintainer:''' [[User:Tioraul|Raul Vasquez]] &lt;br /&gt;
* '''Status:''' Testing&lt;br /&gt;
* '''License:''' [http://www.gnu.org/licenses/gpl-2.0.html GPLv2]&lt;br /&gt;
* '''Price:''' Free&lt;br /&gt;
* '''Bitbucket Repository:''' [https://bitbucket.org/raul_vasquez/lcl/src/488c4614acd4dca27e3bdee1a2195bdcbe8f2d44/VerificadorRutChile.zip?at=default#]&lt;br /&gt;
* '''Zip file:''' VerificadorRutChile.zip&lt;br /&gt;
* '''Sources:''' [https://bitbucket.org/raul_vasquez/lcl bitbucket]&lt;br /&gt;
* '''On Feature:''' VerificadorRutChile.feature.group&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Description ==&lt;br /&gt;
&lt;br /&gt;
This functionality adds chilean Tax Id RUT Verification on TaxID field&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Feedback ==&lt;br /&gt;
&lt;br /&gt;
Please rate this plugin:&lt;br /&gt;
 &lt;br /&gt;
{{#w4grb_rate:Plugin:_LCL_Rut_Taxid}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;w4grb_ratinglist pagevotes idpage=&amp;quot;Plugin:_LCL_Rut_Taxid&amp;quot; items=&amp;quot;30&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If you want to provide additional comments, please use the [[Talk:Plugin:_LCL_Rut_Taxid|Discussion page]]&lt;br /&gt;
&lt;br /&gt;
== Configuration ==&lt;br /&gt;
&lt;br /&gt;
=== SysConfig Parameters ===&lt;br /&gt;
&lt;br /&gt;
N/A&lt;br /&gt;
&lt;br /&gt;
== How to Install ==&lt;br /&gt;
&lt;br /&gt;
=== P2 Repository ===&lt;br /&gt;
&lt;br /&gt;
The recommended way to install the plugin is using the p2 repository.&lt;br /&gt;
&lt;br /&gt;
Unzip VerificadorRutChile.zip&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 DESTINATION=/opt/idempiere-server  # Where your iDempiere server is installed&lt;br /&gt;
 REPO=/folder/where/you/unzip/VericadorRutChile.zip&lt;br /&gt;
 cd $DESTINATION&lt;br /&gt;
 sudo java -Dosgi.noShutdown=false -Dosgi.compatibility.bootdelegation=true -Dosgi.install.area=director \&lt;br /&gt;
   -jar plugins/org.eclipse.osgi_3.7.*.jar -application org.eclipse.equinox.p2.director \&lt;br /&gt;
   -consoleLog -profileProperties org.eclipse.update.install.features=true \&lt;br /&gt;
   -destination $DESTINATION -repository file://$REPO \&lt;br /&gt;
   -i VerificadorRutChile.feature.group&lt;br /&gt;
&lt;br /&gt;
Replace the DESTINATION variable with the folder where your iDempiere server is installed.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Available_Plugins]]&lt;/div&gt;</summary>
		<author><name>Tioraul</name></author>
	</entry>
	<entry>
		<id>https://wiki.idempiere.org/w-en/index.php?title=Plugin:_LCL_Rut_Taxid&amp;diff=5674</id>
		<title>Plugin: LCL Rut Taxid</title>
		<link rel="alternate" type="text/html" href="https://wiki.idempiere.org/w-en/index.php?title=Plugin:_LCL_Rut_Taxid&amp;diff=5674"/>
		<updated>2014-07-03T18:49:40Z</updated>

		<summary type="html">&lt;p&gt;Tioraul: /* P2 Repository */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
* '''Maintainer:''' [[User:Tioraul|Raul Vasquez]] &lt;br /&gt;
* '''Status:''' Testing&lt;br /&gt;
* '''License:''' [http://www.gnu.org/licenses/gpl-2.0.html GPLv2]&lt;br /&gt;
* '''Price:''' Free&lt;br /&gt;
* '''Bitbucket Repository:''' [https://bitbucket.org/raul_vasquez/lcl/src/488c4614acd4dca27e3bdee1a2195bdcbe8f2d44/VerificadorRutChile.zip?at=default#]&lt;br /&gt;
* '''Zip file:''' VerificadorRutChile.zip&lt;br /&gt;
* '''Sources:''' [https://bitbucket.org/raul_vasquez/lcl bitbucket]&lt;br /&gt;
* '''On Feature:''' VerificadorRutChile.feature.group&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Description ==&lt;br /&gt;
&lt;br /&gt;
This functionality adds chilean Tax Id RUT Verification on TaxID field&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Feedback ==&lt;br /&gt;
&lt;br /&gt;
Please rate this plugin:&lt;br /&gt;
 &lt;br /&gt;
{{#w4grb_rate:Plugin:_LCL_Rut_Taxid}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;w4grb_ratinglist pagevotes idpage=&amp;quot;Plugin:_LCL_Rut_Taxid&amp;quot; items=&amp;quot;30&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If you want to provide additional comments, please use the [[Talk:Plugin:_LCL_Rut_Taxid|Discussion page]]&lt;br /&gt;
&lt;br /&gt;
== Configuration ==&lt;br /&gt;
&lt;br /&gt;
=== SysConfig Parameters ===&lt;br /&gt;
&lt;br /&gt;
N/A&lt;br /&gt;
&lt;br /&gt;
== How to Install ==&lt;br /&gt;
&lt;br /&gt;
=== P2 Repository ===&lt;br /&gt;
&lt;br /&gt;
The recommended way to install the plugin is using the p2 repository.&lt;br /&gt;
&lt;br /&gt;
Unzip VerificadorRutChile.zip&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 DESTINATION=/opt/idempiere-server  # Where your iDempiere server is installed&lt;br /&gt;
 REPO=/folder/where/you/unzip/VericadorRutChile.zip&lt;br /&gt;
 cd $DESTINATION&lt;br /&gt;
 java -Dosgi.noShutdown=false -Dosgi.compatibility.bootdelegation=true -Dosgi.install.area=director \&lt;br /&gt;
   -jar plugins/org.eclipse.osgi_3.7.*.jar -application org.eclipse.equinox.p2.director \&lt;br /&gt;
   -consoleLog -profileProperties org.eclipse.update.install.features=true \&lt;br /&gt;
   -destination $DESTINATION -repository file://$REPO \&lt;br /&gt;
   -i VerificadorRutChile.feature.group&lt;br /&gt;
&lt;br /&gt;
Replace the DESTINATION variable with the folder where your iDempiere server is installed.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Available_Plugins]]&lt;/div&gt;</summary>
		<author><name>Tioraul</name></author>
	</entry>
	<entry>
		<id>https://wiki.idempiere.org/w-en/index.php?title=Localizations&amp;diff=4993</id>
		<title>Localizations</title>
		<link rel="alternate" type="text/html" href="https://wiki.idempiere.org/w-en/index.php?title=Localizations&amp;diff=4993"/>
		<updated>2013-12-16T15:11:00Z</updated>

		<summary type="html">&lt;p&gt;Tioraul: /* Chile */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Colombia ==&lt;br /&gt;
&lt;br /&gt;
[[Image:Qss.jpg|right|160px]]&lt;br /&gt;
* '''Maintainer:''' [[User:CarlosRuiz|Carlos Ruiz]] - [http://globalqss.com Quality Systems &amp;amp; Solutions GlobalQSS]&lt;br /&gt;
* '''Last Update:''' November 21, 2013&lt;br /&gt;
* '''Status:''' Up to date with release 2.0&lt;br /&gt;
* '''Download URL:''' [https://bitbucket.org/CarlosRuiz_globalqss/globalqss-idempiere-lco/downloads downloads]&lt;br /&gt;
** Plugins&lt;br /&gt;
*** Nombres Detallados&lt;br /&gt;
*** Medios Magnéticos&lt;br /&gt;
*** Retenciones&lt;br /&gt;
** Datos&lt;br /&gt;
*** Geografía Completa&lt;br /&gt;
*** Geografía Capitales&lt;br /&gt;
*** Festivos&lt;br /&gt;
*** Datos Ejemplo Retenciones para GardenWorld&lt;br /&gt;
*** Datos Ejemplo Medios Magnéticos para GardenWorld&lt;br /&gt;
** [[Translations#Colombia|Lenguage es_CO]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Chile ==&lt;br /&gt;
&lt;br /&gt;
* [https://sourceforge.net/projects/adempierechile/files/GeografiaChileIdempiere.zip/download Geografía Completa con Comunas y Regiones]&lt;br /&gt;
* [http://wiki.idempiere.org/en/Plugin:_LCL_Rut_Taxid Plugin Verificador RUT o CI chileno]&lt;/div&gt;</summary>
		<author><name>Tioraul</name></author>
	</entry>
	<entry>
		<id>https://wiki.idempiere.org/w-en/index.php?title=Localizations&amp;diff=4992</id>
		<title>Localizations</title>
		<link rel="alternate" type="text/html" href="https://wiki.idempiere.org/w-en/index.php?title=Localizations&amp;diff=4992"/>
		<updated>2013-12-16T15:10:01Z</updated>

		<summary type="html">&lt;p&gt;Tioraul: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Colombia ==&lt;br /&gt;
&lt;br /&gt;
[[Image:Qss.jpg|right|160px]]&lt;br /&gt;
* '''Maintainer:''' [[User:CarlosRuiz|Carlos Ruiz]] - [http://globalqss.com Quality Systems &amp;amp; Solutions GlobalQSS]&lt;br /&gt;
* '''Last Update:''' November 21, 2013&lt;br /&gt;
* '''Status:''' Up to date with release 2.0&lt;br /&gt;
* '''Download URL:''' [https://bitbucket.org/CarlosRuiz_globalqss/globalqss-idempiere-lco/downloads downloads]&lt;br /&gt;
** Plugins&lt;br /&gt;
*** Nombres Detallados&lt;br /&gt;
*** Medios Magnéticos&lt;br /&gt;
*** Retenciones&lt;br /&gt;
** Datos&lt;br /&gt;
*** Geografía Completa&lt;br /&gt;
*** Geografía Capitales&lt;br /&gt;
*** Festivos&lt;br /&gt;
*** Datos Ejemplo Retenciones para GardenWorld&lt;br /&gt;
*** Datos Ejemplo Medios Magnéticos para GardenWorld&lt;br /&gt;
** [[Translations#Colombia|Lenguage es_CO]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Chile ==&lt;br /&gt;
&lt;br /&gt;
* [https://sourceforge.net/projects/adempierechile/files/GeografiaChileIdempiere.zip/download Geografía Completa con Comunas y Regiones]&lt;br /&gt;
* [http://wiki.idempiere.org/en/Plugin:_LCL_Rut_Taxid Verificador RUT o CI chileno]&lt;/div&gt;</summary>
		<author><name>Tioraul</name></author>
	</entry>
	<entry>
		<id>https://wiki.idempiere.org/w-en/index.php?title=Plugin:_LCL_Rut_Taxid&amp;diff=4974</id>
		<title>Plugin: LCL Rut Taxid</title>
		<link rel="alternate" type="text/html" href="https://wiki.idempiere.org/w-en/index.php?title=Plugin:_LCL_Rut_Taxid&amp;diff=4974"/>
		<updated>2013-12-16T02:09:23Z</updated>

		<summary type="html">&lt;p&gt;Tioraul: Created page with &amp;quot; * '''Maintainer:''' Raul Vasquez  * '''Status:''' Testing * '''License:''' [http://www.gnu.org/licenses/gpl-2.0.html GPLv2] * '''Price:''' Free * '''Bitbucke...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
* '''Maintainer:''' [[User:Tioraul|Raul Vasquez]] &lt;br /&gt;
* '''Status:''' Testing&lt;br /&gt;
* '''License:''' [http://www.gnu.org/licenses/gpl-2.0.html GPLv2]&lt;br /&gt;
* '''Price:''' Free&lt;br /&gt;
* '''Bitbucket Repository:''' [https://bitbucket.org/raul_vasquez/lcl/src/488c4614acd4dca27e3bdee1a2195bdcbe8f2d44/VerificadorRutChile.zip?at=default#]&lt;br /&gt;
* '''Zip file:''' VerificadorRutChile.zip&lt;br /&gt;
* '''Sources:''' [https://bitbucket.org/raul_vasquez/lcl bitbucket]&lt;br /&gt;
* '''On Feature:''' VerificadorRutChile.feature.group&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Description ==&lt;br /&gt;
&lt;br /&gt;
This functionality adds chilean Tax Id RUT Verification on TaxID field&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Feedback ==&lt;br /&gt;
&lt;br /&gt;
Please rate this plugin:&lt;br /&gt;
 &lt;br /&gt;
{{#w4grb_rate:Plugin:_LCL_Rut_Taxid}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;w4grb_ratinglist pagevotes idpage=&amp;quot;Plugin:_LCL_Rut_Taxid&amp;quot; items=&amp;quot;30&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If you want to provide additional comments, please use the [[Talk:Plugin:_LCL_Rut_Taxid|Discussion page]]&lt;br /&gt;
&lt;br /&gt;
== Configuration ==&lt;br /&gt;
&lt;br /&gt;
=== SysConfig Parameters ===&lt;br /&gt;
&lt;br /&gt;
N/A&lt;br /&gt;
&lt;br /&gt;
== How to Install ==&lt;br /&gt;
&lt;br /&gt;
=== P2 Repository ===&lt;br /&gt;
&lt;br /&gt;
The recommended way to install the plugin is using the p2 repository.&lt;br /&gt;
&lt;br /&gt;
Unzip VerificadorRutChile.zip&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 DESTINATION=/opt/idempiere-server  # Where your iDempiere server is installed&lt;br /&gt;
 REPO=/folder/where/you/unzip/VericadorRutChile.zip&lt;br /&gt;
 cd $DESTINATION&lt;br /&gt;
 java -Dosgi.noShutdown=false -Dosgi.compatibility.bootdelegation=true -Dosgi.install.area=director \&lt;br /&gt;
   -jar plugins/org.eclipse.osgi_3.7.*.jar -application org.eclipse.equinox.p2.director \&lt;br /&gt;
   -consoleLog -profileProperties org.eclipse.update.install.features=true \&lt;br /&gt;
   -destination $DESTINATION -repository $REPO \&lt;br /&gt;
   -i VerificadorRutChile.feature.group&lt;br /&gt;
&lt;br /&gt;
Replace the DESTINATION variable with the folder where your iDempiere server is installed.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:AvailablePlugins]]&lt;/div&gt;</summary>
		<author><name>Tioraul</name></author>
	</entry>
	<entry>
		<id>https://wiki.idempiere.org/w-en/index.php?title=Localizations&amp;diff=4878</id>
		<title>Localizations</title>
		<link rel="alternate" type="text/html" href="https://wiki.idempiere.org/w-en/index.php?title=Localizations&amp;diff=4878"/>
		<updated>2013-12-06T02:53:19Z</updated>

		<summary type="html">&lt;p&gt;Tioraul: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Colombia ==&lt;br /&gt;
&lt;br /&gt;
[[Image:Qss.jpg|right|160px]]&lt;br /&gt;
* '''Maintainer:''' [[User:CarlosRuiz|Carlos Ruiz]] - [http://globalqss.com Quality Systems &amp;amp; Solutions GlobalQSS]&lt;br /&gt;
* '''Last Update:''' November 21, 2013&lt;br /&gt;
* '''Status:''' Up to date with release 2.0&lt;br /&gt;
* '''Download URL:''' [https://bitbucket.org/CarlosRuiz_globalqss/globalqss-idempiere-lco/downloads downloads]&lt;br /&gt;
** Plugins&lt;br /&gt;
*** Nombres Detallados&lt;br /&gt;
*** Medios Magnéticos&lt;br /&gt;
*** Retenciones&lt;br /&gt;
** Datos&lt;br /&gt;
*** Geografía Completa&lt;br /&gt;
*** Geografía Capitales&lt;br /&gt;
*** Festivos&lt;br /&gt;
*** Datos Ejemplo Retenciones para GardenWorld&lt;br /&gt;
*** Datos Ejemplo Medios Magnéticos para GardenWorld&lt;br /&gt;
** [[Translations#Colombia|Lenguage es_CO]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Chile ==&lt;br /&gt;
&lt;br /&gt;
* [https://sourceforge.net/projects/adempierechile/files/GeografiaChileIdempiere.zip/download Geografía Completa con Comunas y Regiones]&lt;/div&gt;</summary>
		<author><name>Tioraul</name></author>
	</entry>
</feed>