Selaa lähdekoodia

Synchro Data Sources Implementation on going...

git-svn-id: http://svn.code.sf.net/p/itop/code/trunk@1100 a333f486-631f-4898-b8df-5754b55c2be0
dflaven 14 vuotta sitten
vanhempi
commit
f066272302

+ 35 - 1
application/cmdbabstract.class.inc.php

@@ -1068,6 +1068,22 @@ EOF
 				$aEventsList[] ='change';
 				$aEventsList[] ='change';
 				$sHTMLValue = "<input title=\"$sHelpText\" class=\"date-pick\" type=\"text\" size=\"20\" name=\"attr_{$sFieldPrefix}{$sAttCode}{$sNameSuffix}\" value=\"$value\" id=\"$iId\"/>&nbsp;{$sValidationField}";
 				$sHTMLValue = "<input title=\"$sHelpText\" class=\"date-pick\" type=\"text\" size=\"20\" name=\"attr_{$sFieldPrefix}{$sAttCode}{$sNameSuffix}\" value=\"$value\" id=\"$iId\"/>&nbsp;{$sValidationField}";
 				break;
 				break;
+
+				case 'Duration':
+				$aEventsList[] ='validate';
+				$aEventsList[] ='change';
+				$oPage->add_ready_script("$('#{$iId}_d').bind('keyup change', function(evt, sFormId) { return UpdateDuration('$iId'); });");
+				$oPage->add_ready_script("$('#{$iId}_h').bind('keyup change', function(evt, sFormId) { return UpdateDuration('$iId'); });");
+				$oPage->add_ready_script("$('#{$iId}_m').bind('keyup change', function(evt, sFormId) { return UpdateDuration('$iId'); });");
+				$oPage->add_ready_script("$('#{$iId}_s').bind('keyup change', function(evt, sFormId) { return UpdateDuration('$iId'); });");
+				$aVal = AttributeDuration::SplitDuration($value);
+				$sDays = "<input title=\"$sHelpText\" type=\"text\" size=\"3\" name=\"attr_{$sFieldPrefix}{$sAttCode}[d]{$sNameSuffix}\" value=\"{$aVal['days']}\" id=\"{$iId}_d\"/>";
+				$sHours = "<input title=\"$sHelpText\" type=\"text\" size=\"2\" name=\"attr_{$sFieldPrefix}{$sAttCode}[h]{$sNameSuffix}\" value=\"{$aVal['hours']}\" id=\"{$iId}_h\"/>";
+				$sMinutes = "<input title=\"$sHelpText\" type=\"text\" size=\"2\" name=\"attr_{$sFieldPrefix}{$sAttCode}[m]{$sNameSuffix}\" value=\"{$aVal['minutes']}\" id=\"{$iId}_m\"/>";
+				$sSeconds = "<input title=\"$sHelpText\" type=\"text\" size=\"2\" name=\"attr_{$sFieldPrefix}{$sAttCode}[s]{$sNameSuffix}\" value=\"{$aVal['seconds']}\" id=\"{$iId}_s\"/>";
+				$sHidden = "<input type=\"hidden\" id=\"{$iId}\" value=\"$value\"/>";
+				$sHTMLValue = Dict::Format('UI:DurationForm_Days_Hours_Minutes_Seconds', $sDays, $sHours, $sMinutes, $sSeconds).$sHidden."&nbsp;".$sValidationField;
+				break;
 				
 				
 				case 'Password':
 				case 'Password':
 					$aEventsList[] ='validate';
 					$aEventsList[] ='validate';
@@ -1170,7 +1186,7 @@ EOF
 					}
 					}
 				break;
 				break;
 			}
 			}
-			$sPattern = addslashes($oAttDef->GetValidationPattern()); //'^([0-9]+)$';
+			$sPattern = addslashes($oAttDef->GetValidationPattern()); //'^([0-9]+)$';			
 			if (!empty($aEventsList))
 			if (!empty($aEventsList))
 			{
 			{
 				$sNullValue = $oAttDef->GetNullValue();
 				$sNullValue = $oAttDef->GetNullValue();
@@ -1768,6 +1784,24 @@ EOF
 						$this->Set($sAttCode, $rawValue);
 						$this->Set($sAttCode, $rawValue);
 					}
 					}
 				}
 				}
+				elseif ($oAttDef->GetEditClass() == 'Duration')
+				{
+					$rawValue = utils::ReadPostedParam("attr_{$sFormPrefix}{$sAttCode}", null);
+					if (!is_array($rawValue))
+					{
+						$iValue = null;
+					}
+					else
+					{
+						$iValue = (((24*$rawValue['d'])+$rawValue['h'])*60 +$rawValue['m'])*60 + $rawValue['s'];
+					}		
+					$this->Set($sAttCode, $iValue);
+					$previousValue = $this->Get($sAttCode);
+					if ($previousValue !== $iValue)
+					{
+						$this->Set($sAttCode, $iValue);
+					}
+				}
 				else
 				else
 				{
 				{
 					$rawValue = utils::ReadPostedParam("attr_{$sFormPrefix}{$sAttCode}", null);
 					$rawValue = utils::ReadPostedParam("attr_{$sFormPrefix}{$sAttCode}", null);

+ 76 - 0
core/attributedef.class.inc.php

@@ -1620,6 +1620,82 @@ class AttributeDateTime extends AttributeDBField
 }
 }
 
 
 /**
 /**
+ * Store a duration as a number of seconds 
+ *
+ * @package     iTopORM
+ */
+class AttributeDuration extends AttributeInteger
+{
+	public function GetEditClass() {return "Duration";}
+	protected function GetSQLCol() {return "INT(11) UNSIGNED";}
+
+	public function GetNullValue() {return '0';}
+	public function GetDefaultValue()
+	{
+		return 0;
+	}
+
+	public function MakeRealValue($proposedValue)
+	{
+		if (is_null($proposedValue)) return null;
+		if (!is_numeric($proposedValue)) return null;
+		if ( ((int)$proposedValue) < 0) return null;
+
+		return (int)$proposedValue;
+	}
+
+	public function ScalarToSQL($value)
+	{
+		if (is_null($value))
+		{	
+			return null;
+		}
+		return $value;
+	}
+
+	public function GetAsHTML($value)
+	{
+		return Str::pure2html(self::FormatDuration($value));
+	}
+
+	static function FormatDuration($duration)
+	{
+		$aDuration = self::SplitDuration($duration);
+		$sResult = '';
+		
+		if ($duration < 60)
+		{
+			// Less than 1 min
+			$sResult = Dict::Format('Core:Duration_Seconds', $aDuration['seconds']);			
+		}
+		else if ($duration < 3600)
+		{
+			// less than 1 hour, display it in minutes/seconds
+			$sResult = Dict::Format('Core:Duration_Minutes_Seconds', $aDuration['minutes'], $aDuration['seconds']);			
+		}
+		else if ($duration < 86400)
+		{
+			// Less than 1 day, display it in hours/minutes/seconds	
+			$sResult = Dict::Format('Core:Duration_Hours_Minutes_Seconds', $aDuration['hours'], $aDuration['minutes'], $aDuration['seconds']);			
+		}
+		else
+		{
+			// more than 1 day, display it in days/hours/minutes/seconds
+			$sResult = Dict::Format('Core:Duration_Days_Hours_Minutes_Seconds', $aDuration['days'], $aDuration['hours'], $aDuration['minutes'], $aDuration['seconds']);			
+		}
+		return $sResult;
+	}
+	
+	static function SplitDuration($duration)
+	{
+		$days = floor($duration / 86400);
+		$hours = floor(($duration - (86400*$days)) / 3600);
+		$minutes = floor(($duration - (86400*$days + 3600*$hours)) / 60);
+		$seconds = ($duration % 60); // modulo
+		return array( 'days' => $days, 'hours' => $hours, 'minutes' => $minutes, 'seconds' => $seconds );		
+	}
+}
+/**
  * Map a date+time column to an attribute 
  * Map a date+time column to an attribute 
  *
  *
  * @package     iTopORM
  * @package     iTopORM

+ 6 - 1
core/dbobject.class.php

@@ -349,7 +349,12 @@ abstract class DBObject
 			// #@# non-scalar attributes.... handle that differently
 			// #@# non-scalar attributes.... handle that differently
 			$this->Reload();
 			$this->Reload();
 		}
 		}
-		return $this->m_aCurrValues[$sAttCode];
+		$value = $this->m_aCurrValues[$sAttCode];
+		if ($value instanceof DBObjectSet)
+		{
+			$value->Rewind();
+		}
+		return $value; 
 	}
 	}
 
 
 	public function GetOriginal($sAttCode)
 	public function GetOriginal($sAttCode)

+ 14 - 0
dictionaries/dictionary.itop.core.php

@@ -537,5 +537,19 @@ Dict::Add('EN US', 'English', 'English', array(
 	'Core:SynchroLogTitle' => '%1$s - %2$s',
 	'Core:SynchroLogTitle' => '%1$s - %2$s',
 	'Core:Synchro:Nb_Replica' => 'Replica processed: %1$s',
 	'Core:Synchro:Nb_Replica' => 'Replica processed: %1$s',
 	'Core:Synchro:Nb_Class:Objects' => '%1$s: %2$s',
 	'Core:Synchro:Nb_Class:Objects' => '%1$s: %2$s',
+	'Class:SynchroDataSource/Error:AtLeastOneReconciliationKeyMustBeSpecified' => 'At Least one reconciliation key must be specified.',			
+	'Class:SynchroDataSource/Error:DeleteRetentionDurationMustBeSpecified' => 'A delete retention period must be specified, since objects are to be deleted after being marked as obsolete',			
+	'Class:SynchroDataSource/Error:DeletePolicyUpdateMustBeSpecified' => 'Obsolete objects are to be updated, but no update is specified.',		
 ));
 ));
+
+//
+// Attribute Duration
+//
+Dict::Add('EN US', 'English', 'English', array(
+	'Core:Duration_Seconds'	=> '%1$ds',	
+	'Core:Duration_Minutes_Seconds'	=>'%1$dmin %2$ds',	
+	'Core:Duration_Hours_Minutes_Seconds' => '%1$dh %2$dmin %3$ds',		
+	'Core:Duration_Days_Hours_Minutes_Seconds' => '%1$sd %2$dh %3$dmin %4$ds',		
+));
+
 ?>
 ?>

+ 3 - 5
dictionaries/dictionary.itop.ui.php

@@ -400,7 +400,7 @@ Dict::Add('EN US', 'English', 'English', array(
 	'UI:HistoryTab' => 'History',
 	'UI:HistoryTab' => 'History',
 	'UI:NotificationsTab' => 'Notifications',
 	'UI:NotificationsTab' => 'Notifications',
 	'UI:History:BulkImports' => 'History',
 	'UI:History:BulkImports' => 'History',
-	'UI:History:BulkImports+' => 'List of CSV imports (last first)',
+	'UI:History:BulkImports+' => 'List of CSV imports (latest import first)',
 	'UI:History:BulkImportDetails' => 'Changes resulting from the CSV import performed on %1$s (by %2$s)',
 	'UI:History:BulkImportDetails' => 'Changes resulting from the CSV import performed on %1$s (by %2$s)',
 	'UI:History:Date' => 'Date',
 	'UI:History:Date' => 'Date',
 	'UI:History:Date+' => 'Date of the change',
 	'UI:History:Date+' => 'Date of the change',
@@ -879,9 +879,7 @@ When associated with a trigger, each action is given an "order" number, specifyi
 	'Portal:AddAttachment' => ' Add Attachment ',
 	'Portal:AddAttachment' => ' Add Attachment ',
 	'Portal:RemoveAttachment' => ' Remove Attachment ',
 	'Portal:RemoveAttachment' => ' Remove Attachment ',
 	'Portal:Attachment_No_To_Ticket_Name' => 'Attachment #%1$d to %2$s (%3$s)',
 	'Portal:Attachment_No_To_Ticket_Name' => 'Attachment #%1$d to %2$s (%3$s)',
-	'Enum:Undefined' => 'Undefined',
+	'Enum:Undefined' => 'Undefined',	
+	'UI:DurationForm_Days_Hours_Minutes_Seconds' => '%1$s Days %2$s Hours %3$s Minutes %4$s Seconds',
 ));
 ));
-
-
-
 ?>
 ?>

+ 14 - 0
js/forms-json-utils.js

@@ -292,6 +292,20 @@ function ValidatePasswordField(id, sFormId)
 	return true;
 	return true;
 }
 }
 
 
+// Manage a 'duration' field
+function UpdateDuration(iId)
+{
+	var iDays = parseInt($('#'+iId+'_d').val(), 10);
+	var iHours = parseInt($('#'+iId+'_h').val(), 10);
+	var iMinutes = parseInt($('#'+iId+'_m').val(), 10);
+	var iSeconds = parseInt($('#'+iId+'_s').val(), 10);
+	
+	var iDuration = (((iDays*24)+ iHours)*60+ iMinutes)*60 + iSeconds;
+	$('#'+iId).val(iDuration);
+	$('#'+iId).trigger('change');
+	return true;
+}
+
 // Called when filling an autocomplete field
 // Called when filling an autocomplete field
 function OnAutoComplete(id, event, data, formatted)
 function OnAutoComplete(id, event, data, formatted)
 {
 {

+ 53 - 32
synchro/synchrodatasource.class.inc.php

@@ -57,8 +57,8 @@ class SynchroDataSource extends cmdbAbstractObject
 		
 		
 		//MetaModel::Init_AddAttribute(new AttributeDateTime("last_synchro_date", array("allowed_values"=>null, "sql"=>"last_synchro_date", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array())));
 		//MetaModel::Init_AddAttribute(new AttributeDateTime("last_synchro_date", array("allowed_values"=>null, "sql"=>"last_synchro_date", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array())));
 
 
-		// Format: '1 hour', '2 weeks', '3 hoursABCDEF'... Cf DateTime->Modify()
-		MetaModel::Init_AddAttribute(new AttributeString("full_load_periodicity", array("allowed_values"=>null, "sql"=>"full_load_periodicity", "default_value"=>"", "is_null_allowed"=>true, "depends_on"=>array())));
+		// Format: seconds (int)
+		MetaModel::Init_AddAttribute(new AttributeDuration("full_load_periodicity", array("allowed_values"=>null, "sql"=>"full_load_periodicity", "default_value"=>"", "is_null_allowed"=>true, "depends_on"=>array())));
 		
 		
 //		MetaModel::Init_AddAttribute(new AttributeString("reconciliation_list", array("allowed_values"=>null, "sql"=>"reconciliation_list", "default_value"=>null, "is_null_allowed"=>false, "depends_on"=>array())));
 //		MetaModel::Init_AddAttribute(new AttributeString("reconciliation_list", array("allowed_values"=>null, "sql"=>"reconciliation_list", "default_value"=>null, "is_null_allowed"=>false, "depends_on"=>array())));
 		MetaModel::Init_AddAttribute(new AttributeEnum("reconciliation_policy", array("allowed_values"=>new ValueSetEnum('use_primary_key,use_attributes'), "sql"=>"reconciliation_policy", "default_value"=>"use_attributes", "is_null_allowed"=>false, "depends_on"=>array())));
 		MetaModel::Init_AddAttribute(new AttributeEnum("reconciliation_policy", array("allowed_values"=>new ValueSetEnum('use_primary_key,use_attributes'), "sql"=>"reconciliation_policy", "default_value"=>"use_attributes", "is_null_allowed"=>false, "depends_on"=>array())));
@@ -69,8 +69,8 @@ class SynchroDataSource extends cmdbAbstractObject
 		MetaModel::Init_AddAttribute(new AttributeEnum("delete_policy", array("allowed_values"=>new ValueSetEnum('ignore,delete,update,update_then_delete'), "sql"=>"delete_policy", "default_value"=>"ignore", "is_null_allowed"=>false, "depends_on"=>array())));
 		MetaModel::Init_AddAttribute(new AttributeEnum("delete_policy", array("allowed_values"=>new ValueSetEnum('ignore,delete,update,update_then_delete'), "sql"=>"delete_policy", "default_value"=>"ignore", "is_null_allowed"=>false, "depends_on"=>array())));
 		MetaModel::Init_AddAttribute(new AttributeString("delete_policy_update", array("allowed_values"=>null, "sql"=>"delete_policy_update", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array())));
 		MetaModel::Init_AddAttribute(new AttributeString("delete_policy_update", array("allowed_values"=>null, "sql"=>"delete_policy_update", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array())));
 
 
-		// Format: '1 hour', '2 weeks', '3 hoursABCDEF'... Cf DateTime->Modify()
-		MetaModel::Init_AddAttribute(new AttributeString("delete_policy_retention", array("allowed_values"=>null, "sql"=>"delete_policy_retention", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array())));
+		// Format: seconds (unsigned int)
+		MetaModel::Init_AddAttribute(new AttributeDuration("delete_policy_retention", array("allowed_values"=>null, "sql"=>"delete_policy_retention", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array())));
 
 
 		MetaModel::Init_AddAttribute(new AttributeLinkedSet("attribute_list", array("linked_class"=>"SynchroAttribute", "ext_key_to_me"=>"sync_source_id", "allowed_values"=>null, "count_min"=>0, "count_max"=>0, "depends_on"=>array())));
 		MetaModel::Init_AddAttribute(new AttributeLinkedSet("attribute_list", array("linked_class"=>"SynchroAttribute", "ext_key_to_me"=>"sync_source_id", "allowed_values"=>null, "count_min"=>0, "count_max"=>0, "depends_on"=>array())));
 		MetaModel::Init_AddAttribute(new AttributeLinkedSet("status_list", array("linked_class"=>"SynchroLog", "ext_key_to_me"=>"sync_source_id", "allowed_values"=>null, "count_min"=>0, "count_max"=>0, "depends_on"=>array())));
 		MetaModel::Init_AddAttribute(new AttributeLinkedSet("status_list", array("linked_class"=>"SynchroLog", "ext_key_to_me"=>"sync_source_id", "allowed_values"=>null, "count_min"=>0, "count_max"=>0, "depends_on"=>array())));
@@ -90,6 +90,7 @@ class SynchroDataSource extends cmdbAbstractObject
 			$oPage->SetCurrentTab(Dict::S('Core:SynchroAttributes'));
 			$oPage->SetCurrentTab(Dict::S('Core:SynchroAttributes'));
 			$oAttributeSet = $this->Get('attribute_list');
 			$oAttributeSet = $this->Get('attribute_list');
 			$aAttributes = array();
 			$aAttributes = array();
+
 			while($oAttribute = $oAttributeSet->Fetch())
 			while($oAttribute = $oAttributeSet->Fetch())
 			{
 			{
 				$aAttributes[$oAttribute->Get('attcode')] = $oAttribute;
 				$aAttributes[$oAttribute->Get('attcode')] = $oAttribute;
@@ -351,6 +352,47 @@ EOF
 		}
 		}
 		$this->Set('attribute_list', $oAttributeSet);
 		$this->Set('attribute_list', $oAttributeSet);
 	}
 	}
+	
+	/*
+	* Overload the standard behavior
+	*/	
+	public function DoCheckToWrite()
+	{
+		parent::DoCheckToWrite();
+
+		// Check that there is at least one reconciliation key defined
+		if ($this->Get('reconciliation_policy') == 'use_attributes')
+		{
+			$oSet = $this->Get('attribute_list');
+			$oSynchroAttributeList = $oSet->ToArray();
+			$bReconciliationKey = false;
+			foreach($oSynchroAttributeList as $oSynchroAttribute)
+			{
+				if ($oSynchroAttribute->Get('reconcile') == 1)
+				{
+					$bReconciliationKey = true; // At least one key is defined
+				}
+			}
+			if (!$bReconciliationKey)
+			{
+				$this->m_aCheckIssues[] = Dict::Format('Class:SynchroDataSource/Error:AtLeastOneReconciliationKeyMustBeSpecified');			
+			}
+		}
+		
+		// If 'update_then_delete' is specified there must be a delete_retention_period
+		if (($this->Get('delete_policy') == 'update_then_delete') && ($this->Get('delete_policy_retention') == 0))
+		{
+			$this->m_aCheckIssues[] = Dict::Format('Class:SynchroDataSource/Error:DeleteRetentionDurationMustBeSpecified');			
+		}
+
+		// If update is specified, then something to update must be defined
+		if ((($this->Get('delete_policy') == 'update_then_delete') ||  ($this->Get('delete_policy') == 'update'))
+		    && ($this->Get('delete_policy_update') == ''))
+		{
+			$this->m_aCheckIssues[] = Dict::Format('Class:SynchroDataSource/Error:DeletePolicyUpdateMustBeSpecified');			
+		}
+	}
+	
 	public function GetTargetClass()
 	public function GetTargetClass()
 	{
 	{
 		return $this->Get('scope_class');
 		return $this->Get('scope_class');
@@ -562,22 +604,11 @@ EOF
 		{
 		{
 			// No previous import known, use the full_load_periodicity value... and the current date
 			// No previous import known, use the full_load_periodicity value... and the current date
 			$oLastFullLoadStartDate = new DateTime(); // Now
 			$oLastFullLoadStartDate = new DateTime(); // Now
-			// TO DO: how do we support localization here ??
-			$sLoadPeriodicity = trim($this->Get('full_load_periodicity'));
-			if (strlen($sLoadPeriodicity) > 0)
+			$iLoadPeriodicity = $this->Get('full_load_periodicity'); // Duration in seconds
+			if ($iLoadPeriodicity > 0)
 			{
 			{
-				$sInterval = '-'.$sLoadPeriodicity;
-				// Note: the PHP doc states that Modify return FALSE in case of error
-				//       but, this is actually NOT the case
-				//       Therefore, I do compare before and after, considering that the
-				//       format is incorrect when the datetime remains unchanged
-				$sBefore = $oLastFullLoadStartDate->Format('Y-m-d H:i:s');
+				$sInterval = "-$iLoadPeriodicity seconds";
 				$oLastFullLoadStartDate->Modify($sInterval);
 				$oLastFullLoadStartDate->Modify($sInterval);
-				$sAfter = $oLastFullLoadStartDate->Format('Y-m-d H:i:s');
-				if ($sBefore == $sAfter)
-				{
-					throw new SynchroExceptionNotStarted("Data exchange: Wrong interval specification", array('interval' => $sInterval, 'source_id' => $this->GetKey()));
-				}
 			}
 			}
 		}
 		}
 		$sLimitDate = $oLastFullLoadStartDate->Format('Y-m-d H:i:s');	
 		$sLimitDate = $oLastFullLoadStartDate->Format('Y-m-d H:i:s');	
@@ -689,21 +720,11 @@ EOF
 		if ($sDeletePolicy == 'update_then_delete')
 		if ($sDeletePolicy == 'update_then_delete')
 		{
 		{
 			$oDeletionDate = $oLastFullLoadStartDate;
 			$oDeletionDate = $oLastFullLoadStartDate;
-			$sDeleteRetention = trim($this->Get('delete_policy_retention')); // MUST NOT BE NULL
-			if (strlen($sDeleteRetention) > 0)
+			$iDeleteRetention = $this->Get('delete_policy_retention'); // Duration in seconds
+			if ($iDeleteRetention > 0)
 			{
 			{
-				$sInterval = '-'.$sDeleteRetention;
-				// Note: the PHP doc states that Modify return FALSE in case of error
-				//       but, this is actually NOT the case
-				//       Therefore, I do compare before and after, considering that the
-				//       format is incorrect when the datetime remains unchanged
-				$sBefore = $oDeletionDate->Format('Y-m-d H:i:s');
+				$sInterval = "-$iDeleteRetention seconds";
 				$oDeletionDate->Modify($sInterval);
 				$oDeletionDate->Modify($sInterval);
-				$sAfter = $oDeletionDate->Format('Y-m-d H:i:s');
-				if ($sBefore == $sAfter)
-				{
-					throw new SynchroExceptionNotStarted("Data exchange: Wrong interval specification", array('interval' => $sInterval, 'source_id' => $this->GetKey()));
-				}
 			}
 			}
 			$sDeletionDate = $oDeletionDate->Format('Y-m-d H:i:s');	
 			$sDeletionDate = $oDeletionDate->Format('Y-m-d H:i:s');	
 			$aTraces[] = "Deletion date: $sDeletionDate";
 			$aTraces[] = "Deletion date: $sDeletionDate";
@@ -982,7 +1003,7 @@ class SynchroReplica extends DBObject
 
 
 		MetaModel::Init_AddAttribute(new AttributeExternalKey("sync_source_id", array("targetclass"=>"SynchroDataSource", "jointype"=> "", "allowed_values"=>null, "sql"=>"sync_source_id", "is_null_allowed"=>false, "on_target_delete"=>DEL_AUTO, "depends_on"=>array())));
 		MetaModel::Init_AddAttribute(new AttributeExternalKey("sync_source_id", array("targetclass"=>"SynchroDataSource", "jointype"=> "", "allowed_values"=>null, "sql"=>"sync_source_id", "is_null_allowed"=>false, "on_target_delete"=>DEL_AUTO, "depends_on"=>array())));
 		MetaModel::Init_AddAttribute(new AttributeInteger("dest_id", array("allowed_values"=>null, "sql"=>"dest_id", "default_value"=>0, "is_null_allowed"=>true, "depends_on"=>array())));
 		MetaModel::Init_AddAttribute(new AttributeInteger("dest_id", array("allowed_values"=>null, "sql"=>"dest_id", "default_value"=>0, "is_null_allowed"=>true, "depends_on"=>array())));
-		MetaModel::Init_AddAttribute(new AttributeClass("dest_class", array("class_category"=>"bizmodel", "more_values"=>"", "sql"=>"dest_class", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array())));
+		MetaModel::Init_AddAttribute(new AttributeClass("dest_class", array("class_category"=>"bizmodel", "more_values"=>"", "sql"=>"dest_class", "default_value"=>'Organization', "is_null_allowed"=>true, "depends_on"=>array())));
 
 
 		MetaModel::Init_AddAttribute(new AttributeDateTime("status_last_seen", array("allowed_values"=>null, "sql"=>"status_last_seen", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array())));
 		MetaModel::Init_AddAttribute(new AttributeDateTime("status_last_seen", array("allowed_values"=>null, "sql"=>"status_last_seen", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array())));
 		MetaModel::Init_AddAttribute(new AttributeEnum("status", array("allowed_values"=>new ValueSetEnum('new,synchronized,modified,orphan,obsolete'), "sql"=>"status", "default_value"=>"new", "is_null_allowed"=>false, "depends_on"=>array())));
 		MetaModel::Init_AddAttribute(new AttributeEnum("status", array("allowed_values"=>new ValueSetEnum('new,synchronized,modified,orphan,obsolete'), "sql"=>"status", "default_value"=>"new", "is_null_allowed"=>false, "depends_on"=>array())));