diff --git a/htdocs/admin/agenda_other.php b/htdocs/admin/agenda_other.php
index b9051f6f33a80631a777055c26ece6178739b165..76b3b06092578c5663ed39f86f404ff5eec53e61 100644
--- a/htdocs/admin/agenda_other.php
+++ b/htdocs/admin/agenda_other.php
@@ -1,8 +1,9 @@
 <?php
-/* Copyright (C) 2008-2015	Laurent Destailleur             <eldy@users.sourceforge.net>
- * Copyright (C) 2011		Regis Houssin                   <regis.houssin@capnetworks.com>
- * Copyright (C) 2011-2013  Juanjo Menent                   <jmenent@2byte.es>
- * Copyright (C) 2015		Jean-François Ferry		<jfefe@aternatik.fr>
+/* Copyright (C) 2008-2015	Laurent Destailleur     <eldy@users.sourceforge.net>
+ * Copyright (C) 2011		Regis Houssin           <regis.houssin@capnetworks.com>
+ * Copyright (C) 2011-2013  	Juanjo Menent           <jmenent@2byte.es>
+ * Copyright (C) 2015		Jean-François Ferry	<jfefe@aternatik.fr>
+ * Copyright (C) 2016		Charlie Benke		<charlie@patas-monkey.com>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -36,7 +37,11 @@ $langs->load("admin");
 $langs->load("other");
 
 $action = GETPOST('action','alpha');
+$value = GETPOST('value','alpha');
+$param = GETPOST('param','alpha');
 $cancel = GETPOST('cancel','alpha');
+$scandir = GETPOST('scandir','alpha');
+$type = 'action';
 
 
 /*
@@ -71,7 +76,21 @@ if (preg_match('/del_(.*)/',$action,$reg))
 		dol_print_error($db);
 	}
 }
+// Define constants for submodules that contains parameters (forms with param1, param2, ... and value1, value2, ...)
+if ($action == 'setModuleOptions')
+{
 
+	if ($param) $res = dolibarr_set_const($db,$param,$value,'chaine',0,'',$conf->entity);
+	if (! $res > 0) $error++;
+	if (! $error)
+	{
+		setEventMessages($langs->trans("SetupSaved"), null, 'mesgs');
+	}
+	else
+	{
+        setEventMessages($langs->trans("Error"), null, 'errors');
+	}
+}
 if ($action == 'set')
 {
 	dolibarr_set_const($db, 'AGENDA_USE_EVENT_TYPE_DEFAULT', GETPOST('AGENDA_USE_EVENT_TYPE_DEFAULT'), 'chaine', 0, '', $conf->entity);
@@ -79,6 +98,85 @@ if ($action == 'set')
     dolibarr_set_const($db, 'AGENDA_DEFAULT_FILTER_STATUS', GETPOST('AGENDA_DEFAULT_FILTER_STATUS'), 'chaine', 0, '', $conf->entity);
 	dolibarr_set_const($db, 'AGENDA_DEFAULT_VIEW', GETPOST('AGENDA_DEFAULT_VIEW'), 'chaine', 0, '', $conf->entity);
 }
+else if ($action == 'specimen')  // For orders
+{
+    $modele=GETPOST('module','alpha');
+
+    $commande = new CommandeFournisseur($db);
+    $commande->initAsSpecimen();
+    $commande->thirdparty=$specimenthirdparty;
+
+    // Search template files
+    $file=''; $classname=''; $filefound=0;
+    $dirmodels=array_merge(array('/'),(array) $conf->modules_parts['models']);
+    foreach($dirmodels as $reldir)
+    {
+    	$file=dol_buildpath($reldir."core/modules/action/doc/pdf_".$modele.".modules.php",0);
+    	if (file_exists($file))
+    	{
+    		$filefound=1;
+    		$classname = "pdf_".$modele;
+    		break;
+    	}
+    }
+
+    if ($filefound)
+    {
+    	require_once $file;
+
+    	$module = new $classname($db,$commande);
+
+    	if ($module->write_file($commande,$langs) > 0)
+    	{
+    		header("Location: ".DOL_URL_ROOT."/document.php?modulepart=action&file=SPECIMEN.pdf");
+    		return;
+    	}
+    	else
+    	{
+    		setEventMessages($module->error, $module->errors, 'errors');
+    		dol_syslog($module->error, LOG_ERR);
+    	}
+    }
+    else
+    {
+    	setEventMessages($langs->trans("ErrorModuleNotFound"), null, 'errors');
+    	dol_syslog($langs->trans("ErrorModuleNotFound"), LOG_ERR);
+    }
+}
+
+// Activate a model
+else if ($action == 'setmodel')
+{
+	print "sssd".$value;
+	$ret = addDocumentModel($value, $type, $label, $scandir);
+}
+
+else if ($action == 'del')
+{
+	$ret = delDocumentModel($value, $type);
+	if ($ret > 0)
+	{
+        if ($conf->global->ACTION_EVENT_ADDON_PDF == "$value") dolibarr_del_const($db, 'ACTION_EVENT_ADDON_PDF',$conf->entity);
+	}
+}
+
+// Set default model
+else if ($action == 'setdoc')
+{
+	if (dolibarr_set_const($db, "ACTION_EVENT_ADDON_PDF",$value,'chaine',0,'',$conf->entity))
+	{
+		// La constante qui a ete lue en avant du nouveau set
+		// on passe donc par une variable pour avoir un affichage coherent
+		$conf->global->ACTION_EVENT_ADDON_PDF = $value;
+	}
+
+	// On active le modele
+	$ret = delDocumentModel($value, $type);
+	if ($ret > 0)
+	{
+		$ret = addDocumentModel($value, $type, $label, $scandir);
+	}
+}
 
 
 /**
@@ -86,7 +184,7 @@ if ($action == 'set')
  */
 
 $formactions=new FormActions($db);
-
+$dirmodels=array_merge(array('/'),(array) $conf->modules_parts['models']);
 llxHeader();
 
 $linkback='<a href="'.DOL_URL_ROOT.'/admin/modules.php">'.$langs->trans("BackToModuleList").'</a>';
@@ -95,14 +193,151 @@ print "<br>\n";
 
 
 
-print '<form action="'.$_SERVER["PHP_SELF"].'" name="agenda">';
-print '<input type="hidden" name="action" value="set">';
 
 $head=agenda_prepare_head();
 
 dol_fiche_head($head, 'other', $langs->trans("Agenda"), 0, 'action');
 
+
+/*
+ *  Documents models for supplier orders
+ */
+
+print load_fiche_titre($langs->trans("AgendaModelModule"),'','');
+
+// Define array def of models
+$def = array();
+
+$sql = "SELECT nom";
+$sql.= " FROM ".MAIN_DB_PREFIX."document_model";
+$sql.= " WHERE type = 'action'";
+$sql.= " AND entity = ".$conf->entity;
+
+$resql=$db->query($sql);
+if ($resql)
+{
+    $i = 0;
+    $num_rows=$db->num_rows($resql);
+    while ($i < $num_rows)
+    {
+        $array = $db->fetch_array($resql);
+        array_push($def, $array[0]);
+        $i++;
+    }
+}
+else
+{
+    dol_print_error($db);
+}
+
+print '<table class="noborder" width="100%">'."\n";
+print '<tr class="liste_titre">'."\n";
+print '<td width="100">'.$langs->trans("Name").'</td>'."\n";
+print '<td>'.$langs->trans("Description").'</td>'."\n";
+print '<td align="center" width="60">'.$langs->trans("Status").'</td>'."\n";
+print '<td align="center" width="60">'.$langs->trans("Default").'</td>'."\n";
+print '<td align="center" width="40">'.$langs->trans("ShortInfo").'</td>';
+print '<td align="center" width="40">'.$langs->trans("Preview").'</td>';
+print '</tr>'."\n";
+
+clearstatcache();
+
 $var=true;
+foreach ($dirmodels as $reldir)
+{
+	$dir = dol_buildpath($reldir."core/modules/action/doc/");
+
+    if (is_dir($dir))
+    {
+        $handle=opendir($dir);
+        if (is_resource($handle))
+        {
+            while (($file = readdir($handle))!==false)
+            {
+                if (preg_match('/\.modules\.php$/i',$file) && preg_match('/^(pdf_|doc_)/',$file))
+                {
+			$name = substr($file, 4, dol_strlen($file) -16);
+			$classname = substr($file, 0, dol_strlen($file) -12);
+			
+			require_once $dir.'/'.$file;
+			$module = new $classname($db, new ActionComm($db));
+			
+			$var=!$var;
+			print "<tr ".$bc[$var].">\n";
+			print "<td>";
+			print (empty($module->name)?$name:$module->name);
+			print "</td>\n";
+			print "<td>\n";
+			require_once $dir.$file;
+			$module = new $classname($db,$specimenthirdparty);
+			if (method_exists($module,'info')) 
+				print $module->info($langs);
+			else 
+				print $module->description;
+			print "</td>\n";
+			
+			// Active
+			if (in_array($name, $def))
+			{
+			    
+			print '<td align="center">'."\n";
+			if ($conf->global->ACTION_EVENT_ADDON_PDF != "$name")
+			{
+				print '<a href="'.$_SERVER["PHP_SELF"].'?action=del&amp;value='.$name.'&amp;scandir='.$module->scandir.'&amp;label='.urlencode($module->name).'&amp;type=action">';
+				print img_picto($langs->trans("Enabled"),'switch_on');
+				print '</a>';
+			}
+			else
+			{
+				print img_picto($langs->trans("Enabled"),'switch_on');
+			}
+				print "</td>";
+			}
+			else
+			{
+				print '<td align="center">'."\n";
+				print '<a href="'.$_SERVER["PHP_SELF"].'?action=setmodel&amp;value='.$name.'&amp;scandir='.$module->scandir.'&amp;label='.urlencode($module->name).'&amp;type=action">'.img_picto($langs->trans("Disabled"),'switch_off').'</a>';
+				print "</td>";
+			}
+			
+			// Default
+			print '<td align="center">';
+			if ($conf->global->ACTION_EVENT_ADDON_PDF == "$name")
+			{
+				print img_picto($langs->trans("Default"),'on');
+			}
+			else
+			{
+				print '<a href="'.$_SERVER["PHP_SELF"].'?action=setdoc&amp;value='.$name.'&amp;scandir='.$module->scandir.'&amp;label='.urlencode($module->name).'&amp;type=action"" alt="'.$langs->trans("Default").'">'.img_picto($langs->trans("Disabled"),'off').'</a>';
+			}
+			print '</td>';
+			
+			// Info
+			$htmltooltip =    ''.$langs->trans("Name").': '.$module->name;
+			$htmltooltip.='<br>'.$langs->trans("Type").': '.($module->type?$module->type:$langs->trans("Unknown"));
+			$htmltooltip.='<br>'.$langs->trans("Width").'/'.$langs->trans("Height").': '.$module->page_largeur.'/'.$module->page_hauteur;
+			$htmltooltip.='<br><br><u>'.$langs->trans("FeaturesSupported").':</u>';
+			$htmltooltip.='<br>'.$langs->trans("Logo").': '.yn($module->option_logo,1,1);
+			print '<td align="center">';
+			print $form->textwithpicto('',$htmltooltip,1,0);
+			print '</td>';
+			print '<td align="center">';
+			print '<a href="'.$_SERVER["PHP_SELF"].'?action=specimen&amp;module='.$name.'">'.img_object($langs->trans("Preview"),'order').'</a>';
+			print '</td>';
+			
+			print "</tr>\n";
+                }
+            }
+            closedir($handle);
+        }
+    }
+}
+print '</table><br>';
+
+$var=true;
+
+print '<form action="'.$_SERVER["PHP_SELF"].'" name="agenda">';
+print '<input type="hidden" name="action" value="set">';
 
 print '<table class="noborder allwidth">'."\n";
 print '<tr class="liste_titre">'."\n";
diff --git a/htdocs/core/class/html.formfile.class.php b/htdocs/core/class/html.formfile.class.php
index f4163a889f051e9d5eb2b3c79552dcc390905daf..0e57118f4bb6094243157241fb11b2f67a5b45d8 100644
--- a/htdocs/core/class/html.formfile.class.php
+++ b/htdocs/core/class/html.formfile.class.php
@@ -460,11 +460,20 @@ class FormFile
                     $modellist=ModeleDon::liste_modeles($this->db);
                 }
             }
+            elseif ($modulepart == 'agenda')
+            {
+                if (is_array($genallowed)) $modellist=$genallowed;
+                else
+                {
+                    include_once DOL_DOCUMENT_ROOT.'/core/modules/action/modules_action.php';
+                    $modellist=ModeleAction::liste_modeles($this->db);
+                }
+            }
             else if ($modulepart == 'unpaid')
             {
                 $modellist='';
             }
-            else if ($modulepart != 'agenda')
+            else //if ($modulepart != 'agenda')
             {
             	// For normalized standard modules
             	$file=dol_buildpath('/core/modules/'.$modulepart.'/modules_'.$modulepart.'.php',0);
diff --git a/htdocs/core/modules/action/modules_actions.php b/htdocs/core/modules/action/modules_actions.php
new file mode 100644
index 0000000000000000000000000000000000000000..2971b6f59ee11bfd5aa3f0d41f4d894bd923f230
--- /dev/null
+++ b/htdocs/core/modules/action/modules_actions.php
@@ -0,0 +1,149 @@
+<?php
+/* Copyright (C) 2003-2005	Rodolphe Quiedeville <rodolphe@quiedeville.org>
+ * Copyright (C) 2004-2010	Laurent Destailleur  <eldy@users.sourceforge.net>
+ * Copyright (C) 2004     	Eric Seigne          <eric.seigne@ryxeo.com>
+ * Copyright (C) 2005-2012	Regis Houssin        <regis.houssin@capnetworks.com>
+ * Copyright (C) 2016		Charlie Benke		<charlie@patas-monkey.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ * or see http://www.gnu.org/
+ */
+
+require_once DOL_DOCUMENT_ROOT.'/core/class/commondocgenerator.class.php';
+
+/**
+ *	\class      ModeleAction
+ *	\brief      Parent class for product models of doc generators
+ */
+abstract class ModeleAction extends CommonDocGenerator
+{
+    var $error='';
+
+    /**
+     *  Return list of active generation modules
+     *
+	 * 	@param	DoliDB		$db					Database handler
+     *  @param	integer		$maxfilenamelength  Max length of value to show
+     * 	@return	array							List of templates
+     */
+    static function liste_modeles($db,$maxfilenamelength=0)
+    {
+        global $conf;
+
+        $type='action';
+        $liste=array();
+
+        include_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
+        $liste=getListOfModels($db,$type,$maxfilenamelength);
+
+        return $liste;
+    }
+}
+/**
+ *  Create an product document on disk using template defined into PRODUCT_ADDON_PDF
+ *
+ *  @param	DoliDB		$db  			objet base de donnee
+ *  @param	Object		$object			Object fichinter
+ *  @param	string		$modele			force le modele a utiliser ('' par defaut)
+ *  @param	Translate	$outputlangs	objet lang a utiliser pour traduction
+ *  @param  int			$hidedetails    Hide details of lines
+ *  @param  int			$hidedesc       Hide description
+ *  @param  int			$hideref        Hide ref
+ *  @return int         				0 if KO, 1 if OK
+ */
+function action_create($db, $object, $modele, $outputlangs, $hidedetails=0, $hidedesc=0, $hideref=0)
+{
+	global $conf,$langs,$user;
+	$langs->load("action");
+
+	$error=0;
+
+	$srctemplatepath='';
+
+	// Positionne modele sur le nom du modele de fichinter a utiliser
+	if (! dol_strlen($modele))
+	{
+		if (! empty($conf->global->ACTION_EVENT_ADDON_PDF))
+		{
+			$modele = $conf->global->ACTION_EVENT_ADDON_PDF;
+		}
+		else
+		{
+			$modele = 'soleil';
+		}
+	}
+
+	// If selected modele is a filename template (then $modele="modelname:filename")
+	$tmp=explode(':',$modele,2);
+    if (! empty($tmp[1]))
+    {
+        $modele=$tmp[0];
+        $srctemplatepath=$tmp[1];
+    }
+
+	// Search template files
+	$file=''; $classname=''; $filefound=0;
+	$dirmodels=array('/');
+	if (is_array($conf->modules_parts['models'])) $dirmodels=array_merge($dirmodels,$conf->modules_parts['models']);
+	foreach($dirmodels as $reldir)
+	{
+    	foreach(array('doc','pdf') as $prefix)
+    	{
+    	    $file = $prefix."_".$modele.".modules.php";
+
+    		// On verifie l'emplacement du modele
+	        $file=dol_buildpath($reldir."core/modules/action/doc/".$file,0);
+    		if (file_exists($file))
+    		{
+    			$filefound=1;
+    			$classname=$prefix.'_'.$modele;
+    			break;
+    		}
+    	}
+    	if ($filefound) break;
+    }
+
+	// Charge le modele
+	if ($filefound)
+	{
+		require_once $file;
+
+		$obj = new $classname($db);
+
+		// We save charset_output to restore it because write_file can change it if needed for
+		// output format that does not support UTF8.
+		$sav_charset_output=$outputlangs->charset_output;
+		if ($obj->write_file($object, $outputlangs, $srctemplatepath, $hidedetails, $hidedesc, $hideref) > 0)
+		{
+			$outputlangs->charset_output=$sav_charset_output;
+
+			// We delete old preview
+			require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
+			dol_delete_preview($object);
+
+			return 1;
+		}
+		else
+		{
+			$outputlangs->charset_output=$sav_charset_output;
+			dol_print_error($db,"action_pdf_create Error: ".$obj->error);
+			return 0;
+		}
+	}
+	else
+	{
+		print $langs->trans("Error")." ".$langs->trans("ErrorFileDoesNotExists",$file);
+		return 0;
+	}
+}