jsnosal - Monday, December 3, 2012 2:21 PM:
I haven't written C# before. I took some code out of the programmers guide and I'm trying to integrate it into the ECO life cycle pre-transition method. The code I'm trying to get to work starts on line 3498. Thank you for your help.
// This method perform validation of Change item(ECN, ECO, etc..) which situated in state or promoted to another state.
// Also is performed processing of Affected Items which existing in current Change Item.
//
// Following classes encapsulate validation and processing behavior:
// ECN, SimpleECO, ExpressECO, ExpressDCO
// Validation logic is situated in ValidateState and ValidateTransition methods which implemented for each of ChangeItem inheritors.
// Process promotion is situated in ProcessTransition method.
//
// If you want to change existing behavior, you have to change ValidateState,ValidateTransition and ProcessTransition for particular class of change item(ECN, SimpleECO, ExpressECO, ExpressDCO)
Aras.Server.Security.Identity plmIdentity = Aras.Server.Security.Identity.GetByName("Aras PLM");
bool PermissionWasSet = Aras.Server.Security.Permissions.GrantIdentity(plmIdentity);
try
{
Utils.InitializeForRequest(this.getInnovator(), CCO);
ChangeItem changeItem;
// // is used because possible case when Change Item is not a root item. It happens when it child of Method item.
Item item = this.getItemsByXPath("//Item[@type='ECN' or @type='Simple ECO' or @type='Express ECO' or @type='Express DCO']");
//Create instance of promoted item
switch (item.getType())
{
case "ECN":
changeItem = new ECN(item);
break;
case "Simple ECO":
changeItem = new SimpleECO(item);
break;
case "Express ECO":
changeItem = new ExpressECO(item);
break;
case "Express DCO":
changeItem = new ExpressDCO(item);
break;
default:
changeItem = null;
break;
}
bool isProcessTransition = (changeItem.Transition != null);
ResultStatus status = changeItem.Validate();
if (status.IsSuccess)
{
if (isProcessTransition)
{
return changeItem.ProcessTransition();
}
else
{
return Utils.GetOkResult();
}
}
else
{
int numberOfDisplayedErrors = isProcessTransition ? 1 : status.Errors.Count;
return Utils.GetError(status, numberOfDisplayedErrors);
}
}
finally
{
if (PermissionWasSet) Aras.Server.Security.Permissions.RevokeIdentity(plmIdentity);
}
}
}
/// <summary>
/// Interface for validate Change Item instance(ECN,Express ECO, Express DCO etc)
/// </summary>
interface IChangeItemValidationRules
{
void IsItemExist(ResultStatus status);
void IsAffectedItemExists(ResultStatus status);
void IsAffectedItemOtherThanNoneActionExists(ResultStatus status);
}
/// <summary>
/// Interface for validate Affected item instance
/// </summary>
interface IAffectedItemValidationRules
{
void Compare_AffectedId_and_NewItem_IdTypes(ResultStatus status);
void Is_AffectedId_and_NewItemId_NotLocked(ResultStatus status);
void Is_AffectedId_InReleasedState(ResultStatus status);
void Is_NewItemId_InPreliminaryState(ResultStatus status);
void Is_AffectedId_Requiered(ResultStatus status);
void Is_NewItemId_Required(ResultStatus status);
void Is_NewItemId_RequiresNull(ResultStatus status);
void Is_AffectedId_RequiresNull(ResultStatus status);
void Is_NewItemId_HasNoPreviouslyReleasedGeneration(ResultStatus status);
}
/// <summary>
/// Interface extends validation rules of Affected Item interface for validating Extednded Affected Item
/// </summary>
interface IExtendedAffectedItemValidationRules : IAffectedItemValidationRules
{
void Is_AffectedItem_Action_Review(ResultStatus status);
void Is_NewItemId_InReleasedState(ResultStatus status);
void Is_AffectedId_InSupersededOrReleasedState(ResultStatus status);
void Is_AffectedRelationship_Allowed(ResultStatus status);
void VerifyAffectedItemProperties(ResultStatus status);
}
/// <summary>
/// Iterface for validate Affected Relationship
/// </summary>
interface IAffectedRelationshipValidationRules
{
void Is_AffectedRelationship_RequiresAttachAction(ResultStatus status);
void Is_AffectedRelId_Required(ResultStatus status);
void Is_AffectedRelId_Required_AffectedId_SourceID(ResultStatus status);
void Is_AffectedRelationshipProperty_Required(ResultStatus status);
void Verify(ResultStatus status);
}
// Class Diagramm:
// abstract class ItemContext;
// abstract class ChangeItem : ItemContext;
//
// ->The following classes are implements own Validation and ProcessTransition behavior<-
//
// class ECN : ChangeItem;
// class SimpleECO : ChangeItem;
// class ExpressECO : ChangeItem;
// class ExpressDCO : ChangeItem;
/// <summary>
/// Represent base class for Item wrappers
/// </summary>
abstract class ItemContext
{
/// <summary>
/// Constructor. Create empty prototype.
/// </summary>
protected ItemContext()
{
}
/// <summary>
/// Constructor. Wrap item and create Utils
/// </summary>
/// <param name="item"></param>
public ItemContext(Item item)
{
this.Item = item;
}
Item p_item;
/// <summary>
/// Get wrapped item
/// </summary>
public Item Item
{
get { return p_item; }
set { p_item = value; }
}
public string ID
{
get { return this.Item.getID(); }
}
public string Type
{
get { return this.Item.getType(); }
}
public bool IsLocked
{
get { return this.Item.getLockStatus() != 0; }
}
public string State
{
get { return this.Item.getProperty("state", ""); }
}
public string ConfigID
{
get { return this.Item.getProperty("config_id", ""); }
}
/// <summary>
/// Promote item
/// </summary>
/// <param name="nextStatus">to state</param>
/// <exception cref="ItemErrorException">throws if error</exception>
public void Promote(string nextStatus)
{
Item tempItem = Utils.Innovator.newItem(this.Type);
tempItem.setID(this.ID);
Item res = tempItem.promote(nextStatus, "PromoteItem Affected item");
Utils.AssertItem(res);
}
/// <summary>
/// Version item
/// </summary>
/// <returns>versioned item</returns>
/// <exception cref="ItemErrorException">throws if error</exception>
public ChangeControlledItem Version()
{
Item tempItem = Utils.Innovator.newItem(this.Type, "version");
tempItem.setID(this.ID);
tempItem.setProperty("effective_date", "");
tempItem = tempItem.apply();
Utils.AssertItem(tempItem);
return new ChangeControlledItem(tempItem);
}
/// <summary>
/// Unlock item
/// </summary>
/// <exception cref="ItemErrorException">throws if error</exception>
public void Unlock()
{
Item tempItem = Utils.Innovator.newItem(this.Type, "unlock");
tempItem.setID(this.ID);
tempItem = tempItem.apply();
Utils.AssertItem(tempItem);
}
/// <summary>
/// Apply item with action edit
/// </summary>
/// <exception cref="ItemErrorException">throws if error</exception>
public void ApplyEdit()
{
Item tmpItem = Utils.Innovator.newItem();
tmpItem.loadAML(this.Item.node.OuterXml);
tmpItem.setAction("edit");
tmpItem.setAttribute("version", "0");
Item res = tmpItem.apply();
Utils.AssertItem(res);
}
/// <summary>
/// Copy item
/// </summary>
/// <typeparam name="TCopy">ItemContext inheritor</typeparam>
/// <returns></returns>
/// <exception cref="ItemErrorException">throws if error</exception>
public TCopy ApplyCopy<TCopy>()
where TCopy : ItemContext
{
Item tmpItem = Utils.Innovator.newItem(this.Type, "copyAsNew");
tmpItem.setID(this.ID);
Item res = tmpItem.apply();
Utils.AssertItem(res);
return (TCopy)Activator.CreateInstance(typeof(TCopy), res);
}
/// <summary>
/// Apply item with action add
/// </summary>
/// <exception cref="ItemErrorException">throws if error</exception>
public void ApplyAdd()
{
Item tmpItem = Utils.Innovator.newItem();
tmpItem.loadAML(this.Item.node.OuterXml);
tmpItem.setAction("add");
tmpItem.setAttribute("version", "0");
Item res = tmpItem.apply();
Utils.AssertItem(res);
this.Item = res;
}
/// <summary>
/// Rised after item delete
/// </summary>
public event EventHandler Deleted;
protected void FireDeleted()
{
if (Deleted != null)
{
Deleted(this, null);
}
}
/// <summary>
/// Delete item
/// </summary>
/// <exception cref="ItemErrorException">throws if error</exception>
public virtual void Delete()
{
Item tmpItem = Utils.Innovator.newItem();
tmpItem.loadAML(this.Item.node.OuterXml);
tmpItem.setAction("delete");
tmpItem.setAttribute("version", "0");
Item res = tmpItem.apply();
Utils.AssertItem(res);
FireDeleted();
}
}
/// <summary>
/// Base class for change items which has Affected item relationship
/// </summary>
abstract class ChangeItem : ItemContext, IChangeItemValidationRules
{
protected delegate void TransitionHandler(IList<AffectedItem> item);
protected string AffectedItemRelshipName;
protected ChangeItem(Item changeItem, String affectedItemRelshipName)
: base(null)
{
this.AffectedItemRelshipName = affectedItemRelshipName;
Item transitionItem = changeItem.getPropertyItem("transition");
if (transitionItem != null)
{
this.Transition = new LifeCycleTransition(transitionItem);
}
this.Item = changeItem;
}
#region Relationships
RelationshipItemList<AffectedItem> p_aff_list;
/// <summary>
/// List of Affected Item
/// </summary>
public virtual RelationshipItemList<AffectedItem> AffectedItems
{
get
{
if (p_aff_list == null)
{
//IList<AffectedItem> tempRelshipList = new RelationshipItemList<AffectedItem>(this.AffectedItemRelshipName, new AffectedItem(), this);
//IOrderedEnumerable<AffectedItem> sortedList = tempRelshipList.OrderBy(affectedItem => affectedItem, new AffectedItemsHandlingOrder(this));
//p_aff_list = new RelationshipItemList<AffectedItem>(sortedList);
p_aff_list = new RelationshipItemList<AffectedItem>(this.AffectedItemRelshipName, new AffectedItem(), this);
}
return p_aff_list;
}
}
public class AffectedItemsHandlingOrder : IComparer<AffectedItem>
{
private Dictionary<string, int> orderedIdDict = new Dictionary<string, int>();
public AffectedItemsHandlingOrder(ChangeItem changeItem)
{
Item z = Utils.Innovator.newItem("SQL", "SQL PROCESS");
z.setProperty("name", "PE_GetAffectedItemHandlingOrder");
z.setProperty("PROCESS", "CALL");
z.setProperty("ARG1", changeItem.ID);
z.setProperty("TYPE", changeItem.AffectedItemRelshipName);
z = z.apply();
for (int i = 0; i < z.getItemCount(); i++)
{
String thisId = z.getItemByIndex(i).getProperty("obj_affected_item_id", ".");
orderedIdDict.Add(thisId, i);
}
}
public int Compare(AffectedItem x, AffectedItem y)
{
int xIndex;
int yIndex;
if (!orderedIdDict.TryGetValue(x.ID, out xIndex))
{
//If template doesn't contains affecteditem then put it in sorted array to the end.
return int.MaxValue;
}
if (!orderedIdDict.TryGetValue(x.ID, out yIndex))
{
//If template doesn't contains affecteditem then put it in sorted array to the end.
return int.MaxValue;
}
return xIndex - yIndex;
}
}
#endregion
#region Mapped Properties
public string Number
{
get { return this.Item.getProperty("item_number", ""); }
}
#endregion
/// <summary>
/// Get LifeCycleTransition object
/// </summary>
public LifeCycleTransition Transition
{
get;
private set;
}
/// <summary>
/// Validate item
/// </summary>
/// <returns></returns>
public ResultStatus Validate()
{
try
{
if (this.Transition != null)
{
return this.ValidateTransition();
}
else
{
return this.ValidateState();
}
}
catch (ValidationException ex)
{
return ex.ResultStatus;
}
}
/// <summary>
/// Validate state item(not on promote)
/// </summary>
/// <returns></returns>
/// <exception cref="ItemErrorException">throw if error</exception>
protected virtual ResultStatus ValidateState()
{
//throwExceptionOnSecondError = false
ResultStatus status = new ResultStatus(false);
IChangeItemValidationRules thisValidationRules = (IChangeItemValidationRules)this;
thisValidationRules.IsItemExist(status);
return status;
}
/// <summary>
/// Validate item on promote
/// </summary>
/// <returns></returns>
/// <exception cref="ItemErrorException">throw if error</exception>
protected virtual ResultStatus ValidateTransition()
{
//throwExceptionOnSecondError = true
ResultStatus status = new ResultStatus(true);
IChangeItemValidationRules thisValidationRules = (IChangeItemValidationRules)this;
thisValidationRules.IsItemExist(status);
return status;
}
/// <summary>
/// Process item on post promote.
/// </summary>
/// <returns></returns>
public virtual Item ProcessTransition()
{
return null;
}
/// <summary>
/// Process each affected item by TransitionHandler
/// </summary>
/// <param name="handler">Handler which will be executed for each affected item in collection</param>
/// <returns></returns>
protected Item ProcessTransitionHandler(TransitionHandler handler)
{
if (handler != null)
{
try
{
handler(this.AffectedItems);
}
catch (ItemErrorException ex)
{
return ex.Error;
}
}
return Utils.GetOkResult();
}
#region Validation Rules
/// <summary>
/// Validate that item exists in DB
/// </summary>
/// <param name="status"></param>
void IChangeItemValidationRules.IsItemExist(ResultStatus status)
{
Item item = Utils.Innovator.getItemById(this.Type, this.ID);
if (item == null || item.isError())
{
status.AddError("ValidateChangeItem_IsItemExist");
}
}
/// <summary>
/// At least one Affected Item must be attached to the change item
/// </summary>
/// <param name="status"></param>
void IChangeItemValidationRules.IsAffectedItemExists(ResultStatus status)
{
if (this.AffectedItems.Count == 0)
{
status.AddError("ValidateChangeItem_IsAffectedItemExists", this.Type, this.Number);
}
}
void IChangeItemValidationRules.IsAffectedItemOtherThanNoneActionExists(ResultStatus status)
{
IsAffectedItemOtherThanNoneActionExists(status);
}
protected virtual void IsAffectedItemOtherThanNoneActionExists(ResultStatus status)
{
if (this.AffectedItems.Count > 0 && !this.AffectedItems.Any(affectedItem => affectedItem.Action != AffectedItem.ActionType.None))
{
status.AddError("ValidateChangeItem_IsAffectedItemWithActionOtherThanEmptyExists", this.Type, this.Number);
}
}
#endregion
}
/// <summary>
/// Represent inheritor of ChangeItem
/// </summary>
class ECN : ChangeItem
{
public ECN(Item item)
: base(item, "ECN Affected Item")
{
}
/// <summary>
/// Validate state item(not on promote)
/// </summary>
/// <returns></returns>
/// <exception cref="ItemErrorException">throw if error</exception>
protected override ResultStatus ValidateState()
{
ResultStatus status = base.ValidateState();
if (!status.IsSuccess) return status;
IChangeItemValidationRules thisValidationRules = (IChangeItemValidationRules)this;
switch (this.State)
{
case "In Planning":
thisValidationRules.IsAffectedItemExists(status);
thisValidationRules.IsAffectedItemOtherThanNoneActionExists(status);
foreach (IAffectedItemValidationRules affectedItem in this.AffectedItems)
{
affectedItem.Compare_AffectedId_and_NewItem_IdTypes(status);
affectedItem.Is_AffectedId_and_NewItemId_NotLocked(status);
affectedItem.Is_AffectedId_InReleasedState(status);
affectedItem.Is_NewItemId_InPreliminaryState(status);
affectedItem.Is_AffectedId_Requiered(status);
affectedItem.Is_NewItemId_Required(status);
affectedItem.Is_NewItemId_RequiresNull(status);
affectedItem.Is_AffectedId_RequiresNull(status);
affectedItem.Is_NewItemId_HasNoPreviouslyReleasedGeneration(status);
}
break;
case "In Work":
case "In Review":
thisValidationRules.IsAffectedItemExists(status);
thisValidationRules.IsAffectedItemOtherThanNoneActionExists(status);
foreach (IAffectedItemValidationRules affectedItem in this.AffectedItems)
{
affectedItem.Compare_AffectedId_and_NewItem_IdTypes(status);
}
break;
}
return status;
}
/// <summary>
/// Validate item on promote
/// </summary>
/// <returns></returns>
/// <exception cref="ItemErrorException">throw if error</exception>
protected override ResultStatus ValidateTransition()
{
ResultStatus status = base.ValidateTransition();
if (!status.IsSuccess) return status;
IChangeItemValidationRules thisValidationRules = (IChangeItemValidationRules)this;
switch (this.Transition.ToString())
{
case "In Planning->In Work":
thisValidationRules.IsAffectedItemExists(status);
thisValidationRules.IsAffectedItemOtherThanNoneActionExists(status);
foreach (IAffectedItemValidationRules affectedItem in this.AffectedItems)
{
affectedItem.Compare_AffectedId_and_NewItem_IdTypes(status);
affectedItem.Is_AffectedId_and_NewItemId_NotLocked(status);
affectedItem.Is_AffectedId_InReleasedState(status);
affectedItem.Is_NewItemId_InPreliminaryState(status);
affectedItem.Is_AffectedId_Requiered(status);
affectedItem.Is_NewItemId_Required(status);
affectedItem.Is_NewItemId_RequiresNull(status);
affectedItem.Is_AffectedId_RequiresNull(status);
affectedItem.Is_NewItemId_HasNoPreviouslyReleasedGeneration(status);
}
break;
case "In Work->In Review":
case "In Review->Released":
thisValidationRules.IsAffectedItemExists(status);
thisValidationRules.IsAffectedItemOtherThanNoneActionExists(status);
foreach (IAffectedItemValidationRules affectedItem in this.AffectedItems)
{
affectedItem.Compare_AffectedId_and_NewItem_IdTypes(status);
}
break;
}
return status;
}
/// <summary>
/// Process each affected item by TransitionHandler
/// </summary>
/// <param name="handler">Handler which will be executed for each affected item in collection</param>
/// <returns></returns>
public override Item ProcessTransition()
{
TransitionHandler handler = null;
switch (this.Transition.ToString())
{
case "In Planning->In Work":
IList<AffectedItem> sortedAffectedItemList = this.AffectedItems;//.OrderBy(affectedItem => affectedItem, new ChangeItem.AffectedItemsHandlingOrder(this)).ToList();
#region Promote all not null affectedIdItem to In Change
{
IList<ChangeControlledItem> affectedIdItemList =
(from affectedItem in sortedAffectedItemList
where affectedItem.AffectedIdItem != null
select affectedItem.AffectedIdItem)
.ToList();
affectedIdItemList.Promote("In Change");
}
#endregion
#region Version affectedIdItem with action Change and Interchangeable = true
{
IList<AffectedItem> affectedItemList =
(from affectedItem in sortedAffectedItemList
where
affectedItem.Action == AffectedItem.ActionType.Change &&
affectedItem.Interchangeable
select affectedItem)
.ToList();
IList<ChangeControlledItem> versionedAffectedIdItemList =
affectedItemList
.Select(affectedItem => affectedItem.AffectedIdItem)
.ToList()
.Version();
versionedAffectedIdItemList.Unlock();
affectedItemList = affectedItemList.Select((AffectedItem affectedItem, int index) =>
{
affectedItem.NewItemIdItem = versionedAffectedIdItemList[index];
return affectedItem;
}
)
.ToList();
affectedItemList.Lock();
affectedItemList.ApplyUpdate("new_item_id");
affectedItemList.Unlock();
}
#endregion
break;
case "In Work->In Review":
handler = InWork_InReview;
break;
case "In Review->Released":
handler = InReview_Released;
break;
}
return ProcessTransitionHandler(handler);
}
#region Dispatch Methods
//---------------------------------------------
// Following methods are TransitionHandler implementations. Each change item has own transition handlers for
// process affected item depending on affected item properties.
//---------------------------------------------
private static void InWork_InReview(IList<AffectedItem> affectedItems)
{
IList<ChangeControlledItem> newItemIdItemList =
(from affectedItem in affectedItems
where
affectedItem.NewItemIdItem != null &&
affectedItem.NewItemIdItem.State != "Released" &&
affectedItem.NewItemIdItem.State != "In Review"
select affectedItem.NewItemIdItem).ToList();
newItemIdItemList.Promote("In Review");
}
private static void InReview_Released(IList<AffectedItem> affectedItems)
{
IList<ChangeControlledItem> newItemIdItemList =
(from affectedItem in affectedItems
where
affectedItem.NewItemIdItem != null &&
affectedItem.NewItemIdItem.State != "Released"
select affectedItem.NewItemIdItem).ToList();
newItemIdItemList.Promote("Released");
IList<ChangeControlledItem> affectedIdItemList =
(from affectedItem in affectedItems
where
affectedItem.AffectedIdItem != null &&
affectedItem.AffectedIdItem.State == "In Change"
select affectedItem.AffectedIdItem).ToList();
affectedIdItemList.Promote("Superseded");
}
#endregion
}
/// <summary>
/// Represent inheritor of ChangeItem
/// </summary>
class SimpleECO : ChangeItem
{
public SimpleECO(Item item)
: base(item, "Simple ECO Affected Item")
{
}
/// <summary>
/// Validate state item(not on promote)
/// </summary>
/// <returns></returns>
/// <exception cref="ItemErrorException">throw if error</exception>
protected override ResultStatus ValidateState()
{
ResultStatus status = base.ValidateState();
if (!status.IsSuccess) return status;
IChangeItemValidationRules thisValidationRules = (IChangeItemValidationRules)this;
switch (this.State)
{
case "New":
thisValidationRules.IsAffectedItemExists(status);
thisValidationRules.IsAffectedItemOtherThanNoneActionExists(status);
foreach (IAffectedItemValidationRules affectedItem in this.AffectedItems)
{
affectedItem.Compare_AffectedId_and_NewItem_IdTypes(status);
affectedItem.Is_AffectedId_and_NewItemId_NotLocked(status);
affectedItem.Is_AffectedId_InReleasedState(status);
affectedItem.Is_NewItemId_InPreliminaryState(status);
affectedItem.Is_AffectedId_Requiered(status);
affectedItem.Is_NewItemId_Required(status);
affectedItem.Is_NewItemId_RequiresNull(status);
affectedItem.Is_AffectedId_RequiresNull(status);
affectedItem.Is_NewItemId_HasNoPreviouslyReleasedGeneration(status);
}
break;
case "In Work":
case "In Review":
thisValidationRules.IsAffectedItemExists(status);
thisValidationRules.IsAffectedItemOtherThanNoneActionExists(status);
foreach (IAffectedItemValidationRules affectedItem in this.AffectedItems)
{
affectedItem.Compare_AffectedId_and_NewItem_IdTypes(status);
}
break;
}
return status;
}
/// <summary>
/// Validate item on promote
/// </summary>
/// <returns></returns>
/// <exception cref="ItemErrorException">throw if error</exception>
protected override ResultStatus ValidateTransition()
{
ResultStatus status = base.ValidateTransition();
if (!status.IsSuccess) return status;
IChangeItemValidationRules thisValidationRules = (IChangeItemValidationRules)this;
switch (this.Transition.ToString())
{
case "New->In Work":
thisValidationRules.IsAffectedItemExists(status);
thisValidationRules.IsAffectedItemOtherThanNoneActionExists(status);
foreach (IAffectedItemValidationRules affectedItem in this.AffectedItems)
{
affectedItem.Compare_AffectedId_and_NewItem_IdTypes(status);
affectedItem.Is_AffectedId_and_NewItemId_NotLocked(status);
affectedItem.Is_AffectedId_InReleasedState(status);
affectedItem.Is_NewItemId_InPreliminaryState(status);
affectedItem.Is_AffectedId_Requiered(status);
affectedItem.Is_NewItemId_Required(status);
affectedItem.Is_NewItemId_RequiresNull(status);
affectedItem.Is_AffectedId_RequiresNull(status);
affectedItem.Is_NewItemId_HasNoPreviouslyReleasedGeneration(status);
}
break;
case "In Work->In Review":
case "In Review->Released":
thisValidationRules.IsAffectedItemExists(status);
thisValidationRules.IsAffectedItemOtherThanNoneActionExists(status);
foreach (IAffectedItemValidationRules affectedItem in this.AffectedItems)
{
affectedItem.Compare_AffectedId_and_NewItem_IdTypes(status);
}
break;
}
return status;
}
/// <summary>
/// Process each affected item by TransitionHandler
/// </summary>
/// <param name="handler">Handler which will be executed for each affected item in collection</param>
/// <returns></returns>
public override Item ProcessTransition()
{
TransitionHandler handler = null;
switch (this.Transition.ToString())
{
case "New->In Work":
IList<AffectedItem> sortedAffectedItemList = this.AffectedItems;//.OrderBy(affectedItem => affectedItem, new ChangeItem.AffectedItemsHandlingOrder(this)).ToList();
#region Promote all not null affectedIdItem to In Change
{
IList<ChangeControlledItem> affectedIdItemList =
(from affectedItem in sortedAffectedItemList
where affectedItem.AffectedIdItem != null
select affectedItem.AffectedIdItem)
.ToList();
affectedIdItemList.Promote("In Change");
}
#endregion
#region Version affectedIdItem with action Change and Interchangeable = true
{
IList<AffectedItem> affectedItemList =
(from affectedItem in sortedAffectedItemList
where
affectedItem.Action == AffectedItem.ActionType.Change &&
affectedItem.Interchangeable
select affectedItem)
.ToList();
IList<ChangeControlledItem> versionedAffectedIdItemList =
affectedItemList
.Select(affectedItem => affectedItem.AffectedIdItem)
.ToList()
.Version();
versionedAffectedIdItemList.Unlock();
affectedItemList = affectedItemList.Select((AffectedItem affectedItem, int index) =>
{
affectedItem.NewItemIdItem = versionedAffectedIdItemList[index];
return affectedItem;
}
)
.ToList();
affectedItemList.Lock();
affectedItemList.ApplyUpdate("new_item_id");
affectedItemList.Unlock();
}
#endregion
break;
case "In Work->In Review":
handler = InWork_InReview;
break;
case "In Review->Released":
handler = InReview_Released;
break;
}
return ProcessTransitionHandler(handler);
}
#region Dispatch Methods
//---------------------------------------------
// Following methods are TransitionHandler implementations. Each change item has own transition handlers for
// process affected item depending on affected item properties.
//---------------------------------------------
private static void InWork_InReview(IList<AffectedItem> affectedItems)
{
IList<ChangeControlledItem> newItemIdList =
(from affectedItem in affectedItems
where
affectedItem.NewItemIdItem != null &&
affectedItem.NewItemIdItem.State != "Released" &&
affectedItem.NewItemIdItem.State != "In Review"
select affectedItem.NewItemIdItem).ToList();
newItemIdList.Promote("In Review");
}
private static void InReview_Released(IList<AffectedItem> affectedItems)
{
IList<ChangeControlledItem> newItemIdItemList =
(from affectedItem in affectedItems
where
affectedItem.NewItemIdItem != null &&
affectedItem.NewItemIdItem.State != "Released"
select affectedItem.NewItemIdItem).ToList();
newItemIdItemList.Promote("Released");
IList<ChangeControlledItem> affectedIdItemList =
(from affectedItem in affectedItems
where
affectedItem.AffectedIdItem != null &&
affectedItem.AffectedIdItem.State == "In Change"
select affectedItem.AffectedIdItem).ToList();
affectedIdItemList.Promote("Superseded");
}
#endregion
}
/// <summary>
/// Represent inheritor of ChangeItem
/// </summary>
class ExpressECO : ChangeItem
{
public ExpressECO(Item item)
: base(item, "Express ECO Affected Item")
{
}
#region Relationships
RelationshipItemList<AffectedItem> p_aff_list;
/// <summary>
/// List of ExtendedAffected Items
/// </summary>
public override RelationshipItemList<AffectedItem> AffectedItems
{
get
{
if (p_aff_list == null)
{
p_aff_list = new RelationshipItemList<AffectedItem>(this.AffectedItemRelshipName, new ExtendedAffectedItem(), this);
}
return p_aff_list;
}
}
#endregion
/// <summary>
/// Validate state item(not on promote)
/// </summary>
/// <returns></returns>
/// <exception cref="ItemErrorException">throw if error</exception>
protected override ResultStatus ValidateState()
{
ResultStatus status = base.ValidateState();
if (!status.IsSuccess) return status;
IChangeItemValidationRules thisValidationRules = (IChangeItemValidationRules)this;
switch (this.State)
{
case "In Planning":
case "Plan Review":
thisValidationRules.IsAffectedItemExists(status);
thisValidationRules.IsAffectedItemOtherThanNoneActionExists(status);
foreach (ExtendedAffectedItem affectedItem in this.AffectedItems)
{
IExtendedAffectedItemValidationRules affItemRules = (IExtendedAffectedItemValidationRules)affectedItem;
affItemRules.Compare_AffectedId_and_NewItem_IdTypes(status);
affItemRules.Is_AffectedId_and_NewItemId_NotLocked(status);
affItemRules.Is_AffectedId_InReleasedState(status);
affItemRules.Is_NewItemId_InPreliminaryState(status);
affItemRules.Is_AffectedId_Requiered(status);
affItemRules.Is_NewItemId_Required(status);
affItemRules.Is_NewItemId_RequiresNull(status);
affItemRules.Is_AffectedId_RequiresNull(status);
affItemRules.Is_NewItemId_HasNoPreviouslyReleasedGeneration(status);
affItemRules.Is_AffectedItem_Action_Review(status);
affItemRules.Is_NewItemId_InReleasedState(status);
affItemRules.Is_AffectedId_InSupersededOrReleasedState(status);
affItemRules.Is_AffectedRelationship_Allowed(status);
foreach (AffectedRelationship affectedRelationship in affectedItem.AffectedRelationships)
{
IAffectedRelationshipValidationRules affRelshRules = (IAffectedRelationshipValidationRules)affectedRelationship;
affRelshRules.Is_AffectedRelationship_RequiresAttachAction(status);
affRelshRules.Is_AffectedRelId_Required(status);
affRelshRules.Is_AffectedRelId_Required_AffectedId_SourceID(status);
affRelshRules.Is_AffectedRelationshipProperty_Required(status);
}
}
break;
case "In Work":
case "In Review":
thisValidationRules.IsAffectedItemExists(status);
thisValidationRules.IsAffectedItemOtherThanNoneActionExists(status);
foreach (ExtendedAffectedItem affectedItem in this.AffectedItems)
{
IExtendedAffectedItemValidationRules affItemRules = (IExtendedAffectedItemValidationRules)affectedItem;
affItemRules.Compare_AffectedId_and_NewItem_IdTypes(status);
affItemRules.VerifyAffectedItemProperties(status);
foreach (AffectedRelationship affectedRelationship in affectedItem.AffectedRelationships)
{
IAffectedRelationshipValidationRules affRelshRules = (IAffectedRelationshipValidationRules)affectedRelationship;
affRelshRules.Verify(status);
}
}
break;
}
return status;
}
/// <summary>
/// Validate item on promote
/// </summary>
/// <returns></returns>
/// <exception cref="ItemErrorException">throw if error</exception>
protected override ResultStatus ValidateTransition()
{
ResultStatus status = base.ValidateTransition();
if (!status.IsSuccess) return status;
IChangeItemValidationRules thisValidationRules = (IChangeItemValidationRules)this;
switch (this.Transition.ToString())
{
case "In Planning->In Work":
case "Plan Review->In Work":
thisValidationRules.IsAffectedItemExists(status);
thisValidationRules.IsAffectedItemOtherThanNoneActionExists(status);
foreach (ExtendedAffectedItem affectedItem in this.AffectedItems)
{
IExtendedAffectedItemValidationRules affItemRules = (IExtendedAffectedItemValidationRules)affectedItem;
affItemRules.Compare_AffectedId_and_NewItem_IdTypes(status);
affItemRules.Is_AffectedId_and_NewItemId_NotLocked(status);
affItemRules.Is_AffectedId_InReleasedState(status);
affItemRules.Is_NewItemId_InPreliminaryState(status);
affItemRules.Is_AffectedId_Requiered(status);
affItemRules.Is_NewItemId_Required(status);
affItemRules.Is_NewItemId_RequiresNull(status);
affItemRules.Is_AffectedId_RequiresNull(status);
affItemRules.Is_NewItemId_HasNoPreviouslyReleasedGeneration(status);
affItemRules.Is_AffectedItem_Action_Review(status);
affItemRules.Is_NewItemId_InReleasedState(status);
affItemRules.Is_AffectedId_InSupersededOrReleasedState(status);
affItemRules.Is_AffectedRelationship_Allowed(status);
foreach (AffectedRelationship affectedRelationship in affectedItem.AffectedRelationships)
{
IAffectedRelationshipValidationRules affRelshRules = (IAffectedRelationshipValidationRules)affectedRelationship;
affRelshRules.Is_AffectedRelationship_RequiresAttachAction(status);
affRelshRules.Is_AffectedRelId_Required(status);
affRelshRules.Is_AffectedRelId_Required_AffectedId_SourceID(status);
affRelshRules.Is_AffectedRelationshipProperty_Required(status);
}
}
break;
case "In Work->In Review":
thisValidationRules.IsAffectedItemExists(status);
thisValidationRules.IsAffectedItemOtherThanNoneActionExists(status);
foreach (IAffectedItemValidationRules affectedItem in this.AffectedItems)
{
affectedItem.Compare_AffectedId_and_NewItem_IdTypes(status);
}
break;
case "In Work->Released":
case "In Review->Released":
thisValidationRules.IsAffectedItemExists(status);
thisValidationRules.IsAffectedItemOtherThanNoneActionExists(status);
foreach (ExtendedAffectedItem affectedItem in this.AffectedItems)
{
IExtendedAffectedItemValidationRules affItemRules = (IExtendedAffectedItemValidationRules)affectedItem;
affItemRules.Compare_AffectedId_and_NewItem_IdTypes(status);
affItemRules.VerifyAffectedItemProperties(status);
foreach (AffectedRelationship affectedRelationship in affectedItem.AffectedRelationships)
{
IAffectedRelationshipValidationRules affRelshRules = (IAffectedRelationshipValidationRules)affectedRelationship;
affRelshRules.Verify(status);
}
}
break;
}
return status;
}
#region Validation Rules
protected override void IsAffectedItemOtherThanNoneActionExists(ResultStatus status)
{
if (this.AffectedItems.Count > 0 && !this.AffectedItems.Any(affectedItem => ((ExtendedAffectedItem)affectedItem).ItemAction != ExtendedAffectedItem.ItemActionType.None))
{
status.AddError("ValidateChangeItem_IsAffectedItemWithActionOtherThanNoneExists", this.Type, this.Number);
}
}
#endregion
/// <summary>
/// Process each affected item by TransitionHandler
/// </summary>
/// <param name="handler">Handler which will be executed for each affected item in collection</param>
/// <returns></returns>
public override Item ProcessTransition()
{
TransitionHandler handler = null;
switch (this.Transition.ToString())
{
case "In Planning->In Work":
case "Plan Review->In Work":
handler = To_InWork;
break;
case "In Review->In Work":
handler = InReview_InWork;
break;
case "In Work->In Review":
handler = InWork_InReview;
break;
case "In Work->Released":
case "In Review->Released":
handler = Changes_Released;
break;
}
return ProcessTransitionHandler(handler);
}
#region Dispatch Methods
//---------------------------------------------
// Following methods are TransitionHandler implementations. Each change item has own transition handlers for
// process affected item depending on affected item properties.
//---------------------------------------------
private static void To_InWork(IList<AffectedItem> affectedItems)
{
#region Release
{
//Select ItemAction == Release
IList<ExtendedAffectedItem> releaseExtAffectedItemList =
affectedItems
.Where(
(AffectedItem affectedItem) =>
{
ExtendedAffectedItem extAffectedItem = (ExtendedAffectedItem)affectedItem;
return (extAffectedItem.ItemAction == ExtendedAffectedItem.ItemActionType.Release);
}
)
.Select(affectedItem => (ExtendedAffectedItem)affectedItem)
.ToList();
releaseExtAffectedItemList.ProcessAffectedRelationships();
releaseExtAffectedItemList.ProcessAffectedItemProperties();
}
#endregion
#region Revise
{
//Select ItemAction == Revise
IList<ExtendedAffectedItem> reviseExtAffectedItemList =
affectedItems
.Where(
(AffectedItem affectedItem) =>
{
ExtendedAffectedItem extAffectedItem = (ExtendedAffectedItem)affectedItem;
return (extAffectedItem.ItemAction == ExtendedAffectedItem.ItemActionType.Revise);
}
)
.Select(affectedItem => (ExtendedAffectedItem)affectedItem)
.ToList();
//Select AffectedIdItem
IList<ChangeControlledItem> affectedIdItemList = reviseExtAffectedItemList
.Select(affectedItem => affectedItem.AffectedIdItem)
.ToList();
IList<ChangeControlledItem> versionedItemList = affectedIdItemList.Version();
versionedItemList.Unlock();
//Set NewItemIdItem by ids of versioned AffectedIdItems
reviseExtAffectedItemList = reviseExtAffectedItemList
.Select(
(ExtendedAffectedItem affectedItem, int index) =>
{
affectedItem.NewItemIdItem = versionedItemList.ElementAt(index);
return affectedItem;
}
)
.ToList();
//Apply chanes
reviseExtAffectedItemList.Lock();
reviseExtAffectedItemList.ApplyUpdate("new_item_id");
reviseExtAffectedItemList.Unlock();
affectedIdItemList.Promote("In Change");
reviseExtAffectedItemList.ProcessAffectedRelationships();
reviseExtAffectedItemList.ProcessAffectedItemProperties();
}
#endregion
#region Renumber
{
//Select ItemAction == Renumber
IList<ExtendedAffectedItem> renumberExtAffectedItemList =
affectedItems
.Where(
(AffectedItem affectedItem) =>
{
ExtendedAffectedItem extAffectedItem = (ExtendedAffectedItem)affectedItem;
return (extAffectedItem.ItemAction == ExtendedAffectedItem.ItemActionType.Renumber);
}
)
.Select(affectedItem => (ExtendedAffectedItem)affectedItem)
.ToList();
//Select AffectedIdItem
IList<ChangeControlledItem> affectedIdItemList = renumberExtAffectedItemList
.Select(affectedItem => affectedItem.AffectedIdItem)
.ToList();
IList<ChangeControlledItem> copiedItemList = affectedIdItemList.Copy();
copiedItemList.Unlock();
//Set NewItemIdItem by ids of copied AffectedIdItems
renumberExtAffectedItemList = renumberExtAffectedItemList
.Select(
(ExtendedAffectedItem affectedItem, int index) =>
{
affectedItem.NewItemIdItem = copiedItemList.ElementAt(index);
return affectedItem;
}
)
.ToList();
//Apply changes
renumberExtAffectedItemList.Lock();
renumberExtAffectedItemList.ApplyUpdate("new_item_id");
renumberExtAffectedItemList.Unlock();
affectedIdItemList.Promote("In Change");
renumberExtAffectedItemList.ProcessAffectedRelationships();
renumberExtAffectedItemList.ProcessAffectedItemProperties();
}
#endregion
}
private static void InWork_InReview(IList<AffectedItem> affectedItems)
{
//Select NewItemIdItem where AffectedItem.ItemAction == Release | Revise | Renumber
IList<ChangeControlledItem> newItemList =
affectedItems
.Where(
(AffectedItem affectedItem) =>
{
ExtendedAffectedItem extAffectedItem = (ExtendedAffectedItem)affectedItem;
return (extAffectedItem.ItemAction == ExtendedAffectedItem.ItemActionType.Release ||
extAffectedItem.ItemAction == ExtendedAffectedItem.ItemActionType.Revise ||
extAffectedItem.ItemAction == ExtendedAffectedItem.ItemActionType.Renumber);
}
)
.Select(affectedItem => affectedItem.NewItemIdItem)
.ToList();
newItemList.Promote("In Review");
}
private static void InReview_InWork(IList<AffectedItem> affectedItems)
{
//Select NewItemIdItem where AffectedItem.ItemAction == Release | Revise | Renumber
IList<ChangeControlledItem> newItemList =
affectedItems
.Where(
(AffectedItem affectedItem) =>
{
ExtendedAffectedItem extAffectedItem = (ExtendedAffectedItem)affectedItem;
return (extAffectedItem.ItemAction == ExtendedAffectedItem.ItemActionType.Release ||
extAffectedItem.ItemAction == ExtendedAffectedItem.ItemActionType.Revise ||
extAffectedItem.ItemAction == ExtendedAffectedItem.ItemActionType.Renumber);
}
)
.Select(affectedItem => affectedItem.NewItemIdItem)
.ToList();
newItemList.Promote("Preliminary");
}
private static void Changes_Released(IList<AffectedItem> affectedItems)
{
//Select NewItemIdItem where AffectedItem.ItemAction == Release | Revise | Renumber
IList<ChangeControlledItem> newItemList =
affectedItems
.Where(
(AffectedItem affectedItem) =>
{
ExtendedAffectedItem extAffectedItem = (ExtendedAffectedItem)affectedItem;
return (extAffectedItem.ItemAction == ExtendedAffectedItem.ItemActionType.Release ||
extAffectedItem.ItemAction == ExtendedAffectedItem.ItemActionType.Revise ||
extAffectedItem.ItemAction == ExtendedAffectedItem.ItemActionType.Renumber);
}
)
.Select(affectedItem => affectedItem.NewItemIdItem)
.ToList();
newItemList.Promote("Released");
//Select AffectedIdItem where AffectedItem.ItemAction == Supersede | Revise | Renumber
IList<ChangeControlledItem> supersedeItemList =
affectedItems
.Where(
(AffectedItem affectedItem) =>
{
ExtendedAffectedItem extAffectedItem = (ExtendedAffectedItem)affectedItem;
return (extAffectedItem.ItemAction == ExtendedAffectedItem.ItemActionType.Revise ||
extAffectedItem.ItemAction == ExtendedAffectedItem.ItemActionType.Renumber ||
extAffectedItem.ItemAction == ExtendedAffectedItem.ItemActionType.Supersede);
}
)
.Select(affectedItem => affectedItem.AffectedIdItem)
.ToList();
supersedeItemList.Promote("Superseded");
//Select AffectedIdItem where AffectedItem.ItemAction == Obsolete
IList<ChangeControlledItem> obsoleteItemList =
affectedItems
.Where(
(AffectedItem affectedItem) =>
{
ExtendedAffectedItem extAffectedItem = (ExtendedAffectedItem)affectedItem;
return (extAffectedItem.ItemAction == ExtendedAffectedItem.ItemActionType.Obsolete);
}
)
.Select(affectedItem => affectedItem.AffectedIdItem)
.ToList();
obsoleteItemList.Promote("Obsolete");
}
#endregion
}
/// <summary>
/// Represent inheritor of ChangeItem
/// </summary>
class ExpressDCO : ChangeItem
{
public ExpressDCO(Item item)
: base(item, "Express DCO Affected Item")
{
}
/// <summary>
/// Validate state item(not on promote)
/// </summary>
/// <returns></returns>
protected override ResultStatus ValidateState()
{
ResultStatus status = base.ValidateState();
if (!status.IsSuccess) return status;
IChangeItemValidationRules thisValidationRules = (IChangeItemValidationRules)this;
switch (this.State)
{
case "New":
thisValidationRules.IsAffectedItemExists(status);
thisValidationRules.IsAffectedItemOtherThanNoneActionExists(status);
foreach (IAffectedItemValidationRules affectedItem in this.AffectedItems)
{
affectedItem.Compare_AffectedId_and_NewItem_IdTypes(status);
affectedItem.Is_AffectedId_and_NewItemId_NotLocked(status);
affectedItem.Is_AffectedId_InReleasedState(status);
affectedItem.Is_NewItemId_InPreliminaryState(status);
affectedItem.Is_AffectedId_Requiered(status);
affectedItem.Is_NewItemId_Required(status);
affectedItem.Is_NewItemId_RequiresNull(status);
affectedItem.Is_AffectedId_RequiresNull(status);
affectedItem.Is_NewItemId_HasNoPreviouslyReleasedGeneration(status);
}
break;
case "In Work":
case "In Review":
thisValidationRules.IsAffectedItemExists(status);
thisValidationRules.IsAffectedItemOtherThanNoneActionExists(status);
foreach (IAffectedItemValidationRules affectedItem in this.AffectedItems)
{
affectedItem.Compare_AffectedId_and_NewItem_IdTypes(status);
}
break;
}
return status;
}
/// <summary>
/// Validate item on promote
/// </summary>
/// <returns></returns>
/// <exception cref="ItemErrorException">throw if error</exception>
protected override ResultStatus ValidateTransition()
{
ResultStatus status = base.ValidateTransition();
if (!status.IsSuccess) return status;
IChangeItemValidationRules thisValidationRules = (IChangeItemValidationRules)this;
switch (this.Transition.ToString())
{
case "New->In Work":
thisValidationRules.IsAffectedItemExists(status);
thisValidationRules.IsAffectedItemOtherThanNoneActionExists(status);
foreach (IAffectedItemValidationRules affectedItem in this.AffectedItems)
{
affectedItem.Compare_AffectedId_and_NewItem_IdTypes(status);
affectedItem.Is_AffectedId_and_NewItemId_NotLocked(status);
affectedItem.Is_AffectedId_InReleasedState(status);
affectedItem.Is_NewItemId_InPreliminaryState(status);
affectedItem.Is_AffectedId_Requiered(status);
affectedItem.Is_NewItemId_Required(status);
affectedItem.Is_NewItemId_RequiresNull(status);
affectedItem.Is_AffectedId_RequiresNull(status);
affectedItem.Is_NewItemId_HasNoPreviouslyReleasedGeneration(status);
}
break;
case "In Work->In Review":
case "In Work->Released":
case "In Review->Released":
thisValidationRules.IsAffectedItemExists(status);
thisValidationRules.IsAffectedItemOtherThanNoneActionExists(status);
foreach (IAffectedItemValidationRules affectedItem in this.AffectedItems)
{
affectedItem.Compare_AffectedId_and_NewItem_IdTypes(status);
}
break;
}
return status;
}
/// <summary>
/// Process each affected item by TransitionHandler
/// </summary>
/// <param name="handler">Handler which will be executed for each affected item in collection</param>
/// <returns></returns>
public override Item ProcessTransition()
{
TransitionHandler handler = null;
switch (this.Transition.ToString())
{
case "New->In Work":
handler = New_InWork;
break;
case "In Work->In Review":
handler = InWork_InReview;
break;
case "In Review->In Work":
handler = InReview_InWork;
break;
case "In Work->Released":
case "In Review->Released":
handler = Changes_Released;
break;
}
return ProcessTransitionHandler(handler);
}
#region Dispatch Methods
//---------------------------------------------
// Following methods are TransitionHandler implementations. Each change item has own transition handlers for
// process affected item depending on affected item properties.
//---------------------------------------------
private static void New_InWork(IList<AffectedItem> affectedItems)
{
#region Change
{
//Select Action == Change && Interchangeable == true
IList<AffectedItem> changeInterchangeableAffectedItemList =
(from affectedItem in affectedItems
where
affectedItem.Action == AffectedItem.ActionType.Change
&&
affectedItem.Interchangeable == true
select affectedItem)
.ToList();
//Version AffectedIdItem
IList<ChangeControlledItem> versionedAffectedIdItemList =
changeInterchangeableAffectedItemList
.Select(affectedItem => affectedItem.AffectedIdItem)
.ToList()
.Version();
versionedAffectedIdItemList.Unlock();
//Set NewItemIdItem by new id of versioned AffectedIdItem
changeInterchangeableAffectedItemList = changeInterchangeableAffectedItemList
.Select(
(AffectedItem affectedItem, int index) =>
{
affectedItem.NewItemIdItem = versionedAffectedIdItemList[index];
return affectedItem;
}
)
.ToList();
//Apply changes
changeInterchangeableAffectedItemList.Lock();
changeInterchangeableAffectedItemList.ApplyUpdate("new_item_id");
changeInterchangeableAffectedItemList.Unlock();
//Select Action == Change
IList<ChangeControlledItem> changeAffectedIdItemList =
(from affectedItem in affectedItems
where
affectedItem.Action == AffectedItem.ActionType.Change
select affectedItem.AffectedIdItem)
.ToList();
//Promote AffectedIdItem
changeAffectedIdItemList.Promote("In Change");
}
#endregion
#region Delete
{
//Select Delete == Change
IEnumerable<ChangeControlledItem> deleteAffectedIdItemList =
(from affectedItem in affectedItems
where
affectedItem.Action == AffectedItem.ActionType.Delete
select affectedItem.AffectedIdItem);
//Select AffectedIdItem and promote them
deleteAffectedIdItemList
.ToList()
.Promote("In Change");
}
#endregion
}
private static void InWork_InReview(IList<AffectedItem> affectedItems)
{
//Select NewItemIdItem where affectedItem Action == Add | Change
IList<ChangeControlledItem> newItemList =
(from affectedItem in affectedItems
where
affectedItem.Action == AffectedItem.ActionType.Add ||
affectedItem.Action == AffectedItem.ActionType.Change
select affectedItem.NewItemIdItem)
.ToList();
newItemList.Promote("In Review");
}
private static void InReview_InWork(IList<AffectedItem> affectedItems)
{
//Select NewItemIdItem where affectedItem Action == Add | Change
IList<ChangeControlledItem> newItemList =
(from affectedItem in affectedItems
where
affectedItem.Action == AffectedItem.ActionType.Add ||
affectedItem.Action == AffectedItem.ActionType.Change
select affectedItem.NewItemIdItem)
.ToList();
newItemList.Promote("Preliminary");
}
private static void Changes_Released(IList<AffectedItem> affectedItems)
{
//Select NewItemIdItem where affectedItem Action == Add | Change
IList<ChangeControlledItem> newItemList =
(from affectedItem in affectedItems
where
affectedItem.Action == AffectedItem.ActionType.Add ||
affectedItem.Action == AffectedItem.ActionType.Change
select affectedItem.NewItemIdItem)
.ToList();
newItemList.Promote("Released");
//Select AffectedIdItem where affectedItem Action == Delete | Change
IList<ChangeControlledItem> affectedItemList =
(from affectedItem in affectedItems
where
affectedItem.Action == AffectedItem.ActionType.Delete ||
affectedItem.Action == AffectedItem.ActionType.Change
select affectedItem.AffectedIdItem)
.ToList();
affectedItemList.Promote("Superseded");
}
#endregion
}
class ChangeControlledRelationship : Relationship
{
public ChangeControlledRelationship()
: base()
{
}
public ChangeControlledRelationship(Item item)
: base(item, null)
{
// replace Change Controlled Relationship poly type to particular type
// TODO: use itemtype property to detect defned type if Change Controlled Relationship will contain other than Part BOM relationships
item.setAttribute("type", "Part BOM");
}
public ChangeControlledRelationship(Item item, ItemContext sourceItem)
: base(item, sourceItem)
{
// replace Change Controlled Relationship poly type to particular type
// TODO: use itemtype property to detect defned type if Change Controlled Relationship will contain other than Part BOM relationships
item.setAttribute("type", "Part BOM");
}
#region Mapped Properties
public string SourceID
{
get { return this.Item.getProperty("source_id"); }
set { this.Item.setProperty("source_id", value); }
}
public string SortOrder
{
get { return this.Item.getProperty("sort_order"); }
}
public string ItemTypeID
{
get { return this.Item.getProperty("itemtype"); }
}
#endregion
public override void Delete()
{
Item tmpItem = Utils.Innovator.newItem();
tmpItem.setAttribute("typeId", this.ItemTypeID);
tmpItem.setID(this.ID);
tmpItem.setAction("delete");
Item res = tmpItem.apply();
Utils.AssertItem(res);
FireDeleted();
}
}
/// <summary>
/// Wrap Change Controlled Item type instance
/// </summary>
class ChangeControlledItem : ItemContext
{
public ChangeControlledItem(Item item)
: base(item)
{
p_relationships = new RelationshipItemList<ChangeControlledRelationship>("Change Controlled Relationship", new ChangeControlledRelationship(), this);
}
#region Mapped Properties
public string ItemNumber
{
get { return this.Item.getProperty("item_number", ""); }
}
#endregion
#region Relationships
public RelationshipItemList<ChangeControlledRelationship> p_relationships;
public RelationshipItemList<ChangeControlledRelationship> Relationships
{
get { return p_relationships; }
}
#endregion
/// <summary>
/// Is item has previosly released generations
/// </summary>
public bool HasPreviouslyReleasedGenerations
{
get
{
Item thisCheck = Utils.Innovator.newItem(this.Type, "get");
thisCheck.setAttribute("select", "config_id");
thisCheck.setProperty("generation", "*");
thisCheck.setPropertyCondition("generation", "like");
thisCheck.setProperty("config_id", this.ConfigID);
thisCheck.setProperty("is_released", "1");
thisCheck = thisCheck.apply();
return thisCheck.getItemCount() > 0;
}
}
}
/// <summary>
/// Wrap Life Cycle Transition item type instance
/// </summary>
class LifeCycleTransition : ItemContext
{
public LifeCycleTransition(Item item)
: base(item)
{
}
public string ToState
{
get { return this.Item.getPropertyAttribute("to_state", "keyed_name", ""); }
}
public string FromState
{
get { return this.Item.getPropertyAttribute("from_state", "keyed_name", ""); }
}
public override string ToString()
{
return String.Format(CultureInfo.InvariantCulture, "{0}->{1}", this.FromState, this.ToState);
}
}
/// <summary>
/// Affected Item wrapper.
/// </summary>
class AffectedItem : RelatedRelationshipItem, IAffectedItemValidationRules
{
public enum ActionType
{
None,
Add,
Change,
Delete
}
/// <summary>
/// Prototype constructor
/// </summary>
public AffectedItem()
: base()
{
}
public AffectedItem(Item item, ItemContext sourceItem)
: base(item, sourceItem)
{
this.Interchangeable = this.Item.getProperty("interchangeable", "") == "1";
string changeAction = this.Item.getProperty("action", "");
this.Action = Utils.GetEnumByValue<ActionType>(changeAction, "None");
}
#region Mapped Properties
ActionType p_action;
public ActionType Action
{
get { return p_action; }
private set { p_action = value; }
}
bool p_interchangeable;
public bool Interchangeable
{
get { return p_interchangeable; }
private set { p_interchangeable = value; }
}
ChangeControlledItem p_affected_id_item;
public ChangeControlledItem AffectedIdItem
{
get
{
if (p_affected_id_item == null)
{
Item affectedItem = this.Item.getPropertyItem("affected_id");
if (affectedItem == null)
{
return null;
}
p_affected_id_item = new ChangeControlledItem(affectedItem);
}
return p_affected_id_item;
}
set
{
p_affected_id_item = null;
this.Item.setPropertyItem("affected_id", value.Item);
}
}
ChangeControlledItem p_new_item_id_item;
public ChangeControlledItem NewItemIdItem
{
get
{
if (p_new_item_id_item == null)
{
Item newItem = this.Item.getPropertyItem("new_item_id");
if (newItem == null)
{
return null;
}
p_new_item_id_item = new ChangeControlledItem(newItem);
}
return p_new_item_id_item;
}
set
{
this.p_new_item_id_item = null;
this.Item.setPropertyItem("new_item_id", value.Item);
}
}
#endregion
#region IAffectedItemValidationRules Members
void IAffectedItemValidationRules.Compare_AffectedId_and_NewItem_IdTypes(ResultStatus status)
{
if (this.AffectedIdItem == null || this.NewItemIdItem == null) return;
if (this.AffectedIdItem.Type != this.NewItemIdItem.Type)
{
status.AddError("ValidateChangeItem_Compare_AffectedId_and_NewItem_IdTypes",
this.AffectedIdItem.Type, this.AffectedIdItem.ItemNumber,
this.NewItemIdItem.Type, this.NewItemIdItem.ItemNumber);
}
}
void IAffectedItemValidationRules.Is_AffectedId_and_NewItemId_NotLocked(ResultStatus status)
{
if (this.AffectedIdItem != null && this.AffectedIdItem.IsLocked)
{
status.AddError("ValidateChangeItem_Is_AffectedId_and_NewItemId_NotLocked",
this.AffectedIdItem.Type, this.AffectedIdItem.ItemNumber);
}
if (this.NewItemIdItem != null && this.NewItemIdItem.IsLocked)
{
status.AddError("ValidateChangeItem_Is_AffectedId_and_NewItemId_NotLocked",
this.NewItemIdItem.Type, this.NewItemIdItem.ItemNumber);
}
}
void IAffectedItemValidationRules.Is_AffectedId_InReleasedState(ResultStatus status)
{
if (this.AffectedIdItem != null && this.AffectedIdItem.State != "Released")
{
status.AddError("ValidateChangeItem_Is_AffectedId_InReleasedState",
this.AffectedIdItem.Type, this.AffectedIdItem.ItemNumber, this.AffectedIdItem.State);
}
}
void IAffectedItemValidationRules.Is_NewItemId_InPreliminaryState(ResultStatus status)
{
if (this.NewItemIdItem != null && this.NewItemIdItem.State != "Preliminary")
{
status.AddError("ValidateChangeItem_Is_NewItemId_InPreliminaryState",
this.NewItemIdItem.Type, this.NewItemIdItem.ItemNumber, this.NewItemIdItem.State);
}
}
void IAffectedItemValidationRules.Is_AffectedId_Requiered(ResultStatus status)
{
if (this.Action == AffectedItem.ActionType.Change || this.Action == AffectedItem.ActionType.Delete)
{
if (this.AffectedIdItem == null)
{
status.AddError("ValidateChangeItem_Is_AffectedId_Requiered");
}
}
}
void IAffectedItemValidationRules.Is_NewItemId_Required(ResultStatus status)
{
if (this.Action == AffectedItem.ActionType.Change && !this.Interchangeable)
{
if (this.NewItemIdItem == null)
{
if (this.AffectedIdItem == null)
{
status.AddError("ValidateChangeItem_Is_NewItemId_Required");
}
else
{
status.AddError("ValidateChangeItem_Is_NewItemId_Required_with_param", this.AffectedIdItem.Type, this.AffectedIdItem.ItemNumber);
}
}
}
if (this.Action == AffectedItem.ActionType.Add)
{
if (this.NewItemIdItem == null)
{
status.AddError("ValidateChangeItem_Is_NewItemId_Required_add_action");
}
}
}
void IAffectedItemValidationRules.Is_NewItemId_RequiresNull(ResultStatus status)
{
if (this.Action == AffectedItem.ActionType.Delete)
{
if (this.NewItemIdItem != null)
{
if (this.AffectedIdItem == null)
{
status.AddError("ValidateChangeItem_Is_NewItemId_RequiresNull_OnDelete");
}
else
{
status.AddError("ValidateChangeItem_Is_NewItemId_RequiresNull_OnDelete_with_param", this.AffectedIdItem.Type, this.AffectedIdItem.ItemNumber);
}
}
}
if (this.Action == AffectedItem.ActionType.Change && this.Interchangeable)
{
if (this.NewItemIdItem != null)
{
if (this.AffectedIdItem == null)
{
status.AddError("ValidateChangeItem_Is_NewItemId_RequiresNull_OnChange");
}
else
{
status.AddError("ValidateChangeItem_Is_NewItemId_RequiresNull_OnChange_with_param", this.AffectedIdItem.Type, this.AffectedIdItem.ItemNumber);
}
}
}
}
void IAffectedItemValidationRules.Is_AffectedId_RequiresNull(ResultStatus status)
{
if (this.Action == AffectedItem.ActionType.Add)
{
if (this.AffectedIdItem != null)
{
if (this.NewItemIdItem == null)
{
status.AddError("ValidateChangeItem_Is_AffectedId_RequiresNull");
}
else
{
status.AddError("ValidateChangeItem_Is_AffectedId_RequiresNull_with_param", this.NewItemIdItem.Type, this.NewItemIdItem.ItemNumber);
}
}
}
}
void IAffectedItemValidationRules.Is_NewItemId_HasNoPreviouslyReleasedGeneration(ResultStatus status)
{
if (this.NewItemIdItem == null) return;
if (this.Action == AffectedItem.ActionType.Add && this.NewItemIdItem.HasPreviouslyReleasedGenerations)
{
status.AddError("ValidateChangeItem_Is_NewItemId_HasNoPreviouslyReleasedGeneration",
this.NewItemIdItem.Type, this.NewItemIdItem.ItemNumber);
}
}
#endregion
}
/// <summary>
/// Extend AffectedItem class by new added properties and relationships to Affected Item type definition.
/// </summary>
class ExtendedAffectedItem : AffectedItem, IExtendedAffectedItemValidationRules
{
public enum ItemActionType
{
Empty,
None,
Release,
Revise,
Renumber,
Supersede,
Obsolete,
Review
}
public ExtendedAffectedItem()
: base()
{
}
public ExtendedAffectedItem(Item item, ItemContext sourceItem)
: base(item, sourceItem)
{
string itemChangeAction = this.Item.getProperty("item_action", "");
this.ItemAction = Utils.GetEnumByValue<ItemActionType>(itemChangeAction, "Empty");
p_aff_rel = new RelationshipItemList<AffectedRelationship>("Affected Item Relationship", new AffectedRelationship(), this);
p_aff_item_prop = new RelationshipItemList<AffectedItemProperty>("Affected Item Property", new AffectedItemProperty(), this);
}
#region Relationships
RelationshipItemList<AffectedRelationship> p_aff_rel;
/// <summary>
/// Affected Item Relationship relationship
/// </summary>
public RelationshipItemList<AffectedRelationship> AffectedRelationships
{
get { return p_aff_rel; }
}
RelationshipItemList<AffectedItemProperty> p_aff_item_prop;
/// <summary>
/// Affected Item Property relationship
/// </summary>
public RelationshipItemList<AffectedItemProperty> AffectedItemProperties
{
get { return p_aff_item_prop; }
}
#endregion
#region Mapped Properties
ItemActionType p_item_action;
public ItemActionType ItemAction
{
get { return p_item_action; }
private set { p_item_action = value; }
}
#endregion
#region IAffectedItemValidationRules Members
/// <summary>
/// All affected_id items must be in "Released" state when item_action is "Revise", "Renumber" or "Supersede" or "Obsolete"
/// </summary>
/// <param name="status"></param>
void IAffectedItemValidationRules.Is_AffectedId_InReleasedState(ResultStatus status)
{
if (this.ItemAction == ItemActionType.Revise ||
this.ItemAction == ItemActionType.Renumber ||
this.ItemAction == ItemActionType.Supersede)
{
if (this.AffectedIdItem != null && this.AffectedIdItem.State != "Released")
{
status.AddError("ValidateAffectedItem_Is_AffectedId_InReleasedState",
this.ItemAction.ToString(), this.AffectedIdItem.Type, this.AffectedIdItem.ItemNumber, this.AffectedIdItem.State);
}
}
}
/// <summary>
/// All new_item_id items must be in Preliminary state when item_action is "Release"
/// </summary>
/// <param name="status"></param>
void IAffectedItemValidationRules.Is_NewItemId_InPreliminaryState(ResultStatus status)
{
if (this.ItemAction == ItemActionType.Release)
{
if (this.NewItemIdItem != null && this.NewItemIdItem.State != "Preliminary")
{
status.AddError("ValidateAffectedItem_Is_NewItemId_InPreliminaryState",
this.NewItemIdItem.Type, this.NewItemIdItem.ItemNumber, this.NewItemIdItem.State);
}
}
}
/// <summary>
/// affected_id is required when item_action is "Revise", "Renumber", "Supersede" or "Obsolete"
/// </summary>
/// <param name="status"></param>
void IAffectedItemValidationRules.Is_AffectedId_Requiered(ResultStatus status)
{
if (this.ItemAction == ItemActionType.Revise ||
this.ItemAction == ItemActionType.Renumber ||
this.ItemAction == ItemActionType.Supersede ||
this.ItemAction == ItemActionType.Obsolete)
{
if (this.AffectedIdItem == null)
{
status.AddError("ValidateAffectedItem_Is_AffectedId_Requiered", this.ItemAction.ToString());
}
}
}
/// <summary>
/// new_item_id is required when action is "Release" or "Supersede"
/// </summary>
/// <param name="status"></param>
void IAffectedItemValidationRules.Is_NewItemId_Required(ResultStatus status)
{
if (this.ItemAction == ItemActionType.Release || this.ItemAction == ItemActionType.Supersede)
{
if (this.NewItemIdItem == null)
{
if (this.AffectedIdItem == null)
{
status.AddError("ValidateAffectedItem_Is_NewItemId_Required", this.ItemAction.ToString());
}
else
{
status.AddError("ValidateAffectedItem_Is_NewItemId_Required_with_param",
this.ItemAction.ToString(), this.AffectedIdItem.Type, this.AffectedIdItem.ItemNumber);
}
}
}
}
/// <summary>
/// new_item_id must be null when item_action is "Revise", "Renumber" or "Obsolete"
/// </summary>
/// <param name="status"></param>
void IAffectedItemValidationRules.Is_NewItemId_RequiresNull(ResultStatus status)
{
if (this.ItemAction == ItemActionType.Revise ||
this.ItemAction == ItemActionType.Renumber ||
this.ItemAction == ItemActionType.Obsolete)
{
if (this.NewItemIdItem != null)
{
if (this.AffectedIdItem == null)
{
status.AddError("ValidateAffectedItem_Is_NewItemId_RequiresNull", this.ItemAction.ToString());
}
else
{
status.AddError("ValidateAffectedItem_Is_NewItemId_RequiresNull_with_param",
this.ItemAction.ToString(), this.AffectedIdItem.Type, this.AffectedIdItem.ItemNumber);
}
}
}
}
/// <summary>
/// affected_id must be null when item_action is "Release"
/// </summary>
/// <param name="status"></param>
void IAffectedItemValidationRules.Is_AffectedId_RequiresNull(ResultStatus status)
{
if (this.ItemAction == ItemActionType.Release)
{
if (this.AffectedIdItem != null)
{
if (this.NewItemIdItem == null)
{
status.AddError("ValidateAffectedItem_Is_AffectedId_RequiresNull");
}
else
{
status.AddError("ValidateAffectedItem_Is_AffectedId_RequiresNull_with_param",
this.NewItemIdItem.Type, this.NewItemIdItem.ItemNumber);
}
}
}
}
/// <summary>
/// new_item_id items must not have a previously released generation when action is "Release"
/// </summary>
/// <param name="status"></param>
void IAffectedItemValidationRules.Is_NewItemId_HasNoPreviouslyReleasedGeneration(ResultStatus status)
{
if (this.NewItemIdItem == null) return;
if (this.ItemAction == ItemActionType.Release && this.NewItemIdItem.HasPreviouslyReleasedGenerations)
{
status.AddError("ValidateAffectedItem_Is_NewItemId_HasNoPreviouslyReleasedGeneration",
this.NewItemIdItem.Type, this.NewItemIdItem.ItemNumber);
}
}
#endregion
#region IExtendedAffectedItemValidationRules Members
/// <summary>
/// new_item_id items must not have a previously released generation when action is "Release"
/// </summary>
/// <param name="status"></param>
void IExtendedAffectedItemValidationRules.Is_AffectedItem_Action_Review(ResultStatus status)
{
if (this.ItemAction == ItemActionType.Review)
{
status.AddError("ValidateAffectedItem_Is_AffectedItem_Action_Review");
}
}
/// <summary>
/// All affected_id items must be in "Released" or "Superseded" state when item_action is "Obsolete"
/// </summary>
/// <param name="status"></param>
void IExtendedAffectedItemValidationRules.Is_AffectedId_InSupersededOrReleasedState(ResultStatus status)
{
if (this.ItemAction == ItemActionType.Obsolete)
{
if (this.AffectedIdItem != null && this.AffectedIdItem.State != "Superseded" && this.AffectedIdItem.State != "Released")
{
status.AddError("ValidateAffectedItem_Is_AffectedId_InSupersededOrReleasedState",
this.ItemAction.ToString(), this.AffectedIdItem.Type, this.AffectedIdItem.ItemNumber, this.AffectedIdItem.State);
}
}
}
/// <summary>
/// new_item_id items must not have a previously released generation when action is "Release"
/// </summary>
/// <param name="status"></param>
void IExtendedAffectedItemValidationRules.Is_NewItemId_InReleasedState(ResultStatus status)
{
if (this.ItemAction == ItemActionType.Supersede)
{
if (this.NewItemIdItem != null && this.NewItemIdItem.State != "Released")
{
status.AddError("ValidateAffectedItem_Is_NewItemId_InReleasedState",
this.ItemAction.ToString(), this.NewItemIdItem.Type, this.NewItemIdItem.ItemNumber, this.NewItemIdItem.State);
}
}
}
/// <summary>
/// No affected relationships may be attached to affected items with an item_action of "Supersede", "Obsolete" or "None"
/// </summary>
/// <param name="status"></param>
void IExtendedAffectedItemValidationRules.Is_AffectedRelationship_Allowed(ResultStatus status)
{
if (this.ItemAction == ItemActionType.Supersede || this.ItemAction == ItemActionType.Obsolete || this.ItemAction == ItemActionType.None)
{
if (this.AffectedRelationships.Count > 0)
{
status.AddError("ValidateAffectedItem_Is_AffectedRelationship_Allowed", this.ItemAction.ToString());
}
}
}
/// <summary>
/// Verify all Affected Item Properties.
/// </summary>
void IExtendedAffectedItemValidationRules.VerifyAffectedItemProperties(ResultStatus status)
{
foreach (AffectedItemProperty aff_item_prop in this.AffectedItemProperties)
{
string value = this.NewItemIdItem.Item.getProperty(aff_item_prop.PropertyName);
if (value != aff_item_prop.NewValue)
{
status.AddError("VerifyAffectedRelationship_NotAllItemPropertiesWereApplied", aff_item_prop.PropertyName, aff_item_prop.NewValue, this.NewItemIdItem.Type, this.NewItemIdItem.ItemNumber);
}
}
}
#endregion
#region Members
/// <summary>
/// Process all Affected Relationships relationships. In depend of action affected relationship will be Attached/Modified/Removed.
/// </summary>
public void ProcessAffectedRelationships()
{
foreach (AffectedRelationship aff_relship in this.AffectedRelationships)
{
aff_relship.Process();
}
}
/// <summary>
/// Process all Affected Item Properties relationships. Apply property to new item.
/// </summary>
public void ProcessAffectedItemProperties()
{
foreach (AffectedItemProperty aff_item_prop in this.AffectedItemProperties)
{
this.NewItemIdItem.Item.setProperty(aff_item_prop.PropertyName, aff_item_prop.NewValue);
}
this.NewItemIdItem.ApplyEdit();
}
#endregion
}
class AffectedRelationship : RelatedRelationshipItem, IAffectedRelationshipValidationRules
{
public enum RelationshipAction
{
Empty,
Attach,
Modify,
Remove
}
public AffectedRelationship()
: base()
{
}
public AffectedRelationship(Item item, ItemContext sourceItem)
: base(item, sourceItem)
{
string action = this.Item.getProperty("rel_action", "");
this.Action = Utils.GetEnumByValue<RelationshipAction>(action, "Empty");
p_aff_rel_prop = new RelationshipItemList<AffectedRelationshipProperty>("Affected Relationship Property", new AffectedRelationshipProperty(), this);
}
#region Relationships
RelationshipItemList<AffectedRelationshipProperty> p_aff_rel_prop;
public RelationshipItemList<AffectedRelationshipProperty> AffectedRelationshipProperties
{
get { return p_aff_rel_prop; }
}
#endregion
#region Mapped Properties
RelationshipAction p_relAction;
public RelationshipAction Action
{
get { return p_relAction; }
private set { p_relAction = value; }
}
ChangeControlledRelationship p_new_rel_item_id_item;
public ChangeControlledRelationship NewRelItemIdItem
{
get
{
if (p_new_rel_item_id_item == null)
{
Item newRelItem = this.Item.getPropertyItem("new_rel_id");
if (newRelItem == null)
{
return null;
}
p_new_rel_item_id_item = new ChangeControlledRelationship(newRelItem);
}
return p_new_rel_item_id_item;
}
set
{
this.p_new_rel_item_id_item = null;
this.Item.setPropertyItem("new_rel_id", value.Item);
}
}
ChangeControlledRelationship p_affected_rel_item_id_item;
public ChangeControlledRelationship AffectedRelItemIdItem
{
get
{
if (p_affected_rel_item_id_item == null)
{
Item affectedRelItem = this.Item.getPropertyItem("affected_rel_id");
if (affectedRelItem == null)
{
return null;
}
p_affected_rel_item_id_item = new ChangeControlledRelationship(affectedRelItem);
}
return p_affected_rel_item_id_item;
}
set
{
this.p_affected_rel_item_id_item = null;
this.Item.setPropertyItem("affected_rel_id", value.Item);
}
}
#endregion
#region IAffectedRelationshipValidationRules Members
/// <summary>
/// All affected relationships on affected items with an item_action of "Release" must have a rel_action of "Attach"
/// </summary>
/// <param name="status"></param>
void IAffectedRelationshipValidationRules.Is_AffectedRelationship_RequiresAttachAction(ResultStatus status)
{
ExtendedAffectedItem sourceItem = (ExtendedAffectedItem)this.Relationship.SourceItem;
if (sourceItem.ItemAction == ExtendedAffectedItem.ItemActionType.Release)
{
if (this.Action != RelationshipAction.Attach)
{
status.AddError("ValidateAffectedRelationship_Is_AffectedRelationship_RequiresAttachAction");
}
}
}
/// <summary>
/// affected_rel is required when rel_action is "Modify" or "Remove"
/// </summary>
/// <param name="status"></param>
void IAffectedRelationshipValidationRules.Is_AffectedRelId_Required(ResultStatus status)
{
if (this.Action == RelationshipAction.Modify || this.Action == RelationshipAction.Remove)
{
if (this.AffectedRelItemIdItem == null)
{
status.AddError("ValidateAffectedRelationship_Is_AffectedRelId_Required", this.Action.ToString());
}
}
}
/// <summary>
/// affected_rel relationships must have a source_id that matches the parent affected item's affected_id
/// </summary>
/// <param name="status"></param>
void IAffectedRelationshipValidationRules.Is_AffectedRelId_Required_AffectedId_SourceID(ResultStatus status)
{
ExtendedAffectedItem sourceItem = (ExtendedAffectedItem)this.Relationship.SourceItem;
if (sourceItem.AffectedIdItem == null || this.AffectedRelItemIdItem == null) return;
if (this.AffectedRelItemIdItem.SourceID != sourceItem.AffectedIdItem.ID)
{
status.AddError("ValidateAffectedRelationship_Is_AffectedRelId_Required_AffectedId_SourceID");
}
}
/// <summary>
/// At least one affected relationship property must be attached when rel_action is "Attach" or "Modify"
/// </summary>
/// <param name="status"></param>
void IAffectedRelationshipValidationRules.Is_AffectedRelationshipProperty_Required(ResultStatus status)
{
if (this.Action == RelationshipAction.Attach || this.Action == RelationshipAction.Modify)
{
if (this.AffectedRelationshipProperties.Count == 0)
{
status.AddError("ValidateAffectedRelationship_Is_AffectedRelationshipProperty_Required", this.Action.ToString());
}
}
}
void IAffectedRelationshipValidationRules.Verify(ResultStatus status)
{
ExtendedAffectedItem ext_affected_item = (ExtendedAffectedItem)this.Relationship.SourceItem;
if (ext_affected_item.ItemAction != ExtendedAffectedItem.ItemActionType.Release &&
ext_affected_item.ItemAction != ExtendedAffectedItem.ItemActionType.Revise &&
ext_affected_item.ItemAction != ExtendedAffectedItem.ItemActionType.Renumber)
{
return;
}
if (this.Action == RelationshipAction.Attach || this.Action == RelationshipAction.Modify)
{
//Verify that new_rel_id populated and new relationship was attached to correct sourceItem and that all properties were
//modified.
if (this.NewRelItemIdItem == null)
{
status.AddError("VerifyAffectedRelationship_NewRelItemIDIsNull");
return;
}
ChangeControlledRelationship new_relship =
(from relship in ext_affected_item.NewItemIdItem.Relationships
where
relship.ID == this.NewRelItemIdItem.ID
select relship).SingleOrDefault();
//if relationship not exists in new_item.
if (new_relship == null)
{
status.AddError("VerifyAffectedRelationship_NewItemNotContainRelationship", this.NewRelItemIdItem.Type, this.NewRelItemIdItem.ID, ext_affected_item.NewItemIdItem.Type, ext_affected_item.NewItemIdItem.ItemNumber);
return;
}
//validate properties which was set
foreach (AffectedRelationshipProperty relship_prop in this.AffectedRelationshipProperties)
{
string value = new_relship.Item.getProperty(relship_prop.PropertyName);
if (value != relship_prop.NewValue)
{
status.AddError("VerifyAffectedRelationship_NotAllRelationshipPropertiesWereApplied", relship_prop.PropertyName, relship_prop.NewValue, this.Type, this.ID);
}
}
}
else if (this.Action == RelationshipAction.Remove)
{
//Try to find the new relationship and check that it is null because it was deleted.
ChangeControlledRelationship new_relship =
(from relship in ext_affected_item.NewItemIdItem.Relationships
where
relship.SourceID == ext_affected_item.NewItemIdItem.ID &&
relship.SortOrder == this.AffectedRelItemIdItem.SortOrder &&
relship.ItemTypeID == this.AffectedRelItemIdItem.ItemTypeID
select relship).SingleOrDefault();
if (new_relship != null)
{
status.AddError("VerifyAffectedRelationship_RelationshipStillExistInItem", ext_affected_item.NewItemIdItem.Type, ext_affected_item.NewItemIdItem.ItemNumber, new_relship.Type, new_relship.ID);
}
}
}
#endregion
#region Members
/// <summary>
/// Process affected relationship in depend on Action property.
/// </summary>
public void Process()
{
ExtendedAffectedItem ext_affected_item = (ExtendedAffectedItem)this.Relationship.SourceItem;
if (this.Action == RelationshipAction.Attach)
{
//Create a new relationship with source_id equal to the new_item_id item on the parent Affected Item
//and other properties as specified in Affected Relationship Property relationships.
//Populate the new_rel property with the id of the new relationship
Item new_rel_item = Utils.Innovator.newItem("Part BOM"); // hardcoded, in first implementation iteration we have to do it.
ChangeControlledRelationship new_relship = new ChangeControlledRelationship(new_rel_item);
new_relship.SourceID = ext_affected_item.NewItemIdItem.ID;
//set
foreach (AffectedRelationshipProperty relship_prop in this.AffectedRelationshipProperties)
{
new_relship.Item.setProperty(relship_prop.PropertyName, relship_prop.NewValue);
}
new_relship.ApplyAdd();
this.NewRelItemIdItem = new_relship;
this.ApplyEdit();
}
else if (this.Action == RelationshipAction.Modify)
{
//Find the id of the new relationship and set the new_rel property.
//Edit the new relationship using the properties specified in Affected Relationship Property relationships.
ChangeControlledRelationship new_relship =
(from relship in ext_affected_item.NewItemIdItem.Relationships
where
relship.SourceID == ext_affected_item.NewItemIdItem.ID &&
relship.SortOrder == this.AffectedRelItemIdItem.SortOrder &&
relship.ItemTypeID == this.AffectedRelItemIdItem.ItemTypeID
select relship).Single();
this.NewRelItemIdItem = new_relship;
this.ApplyEdit();
//set
foreach (AffectedRelationshipProperty relship_prop in this.AffectedRelationshipProperties)
{
this.NewRelItemIdItem.Item.setProperty(relship_prop.PropertyName, relship_prop.NewValue);
}
this.NewRelItemIdItem.ApplyEdit();
}
else if (this.Action == RelationshipAction.Remove)
{
//Find the new relationship and delete it.
ChangeControlledRelationship new_relship =
(from relship in ext_affected_item.NewItemIdItem.Relationships
where
relship.SourceID == ext_affected_item.NewItemIdItem.ID &&
relship.SortOrder == this.AffectedRelItemIdItem.SortOrder &&
relship.ItemTypeID == this.AffectedRelItemIdItem.ItemTypeID
select relship).Single();
new_relship.Delete();
}
}
#endregion
}
/// <summary>
/// No related relationship Affected Item Property of Affected Item
/// </summary>
class AffectedItemProperty : NoRelatedRelationshipItem
{
public AffectedItemProperty()
: base()
{
}
public AffectedItemProperty(Item item, AffectedItem sourceItem)
: base(item, sourceItem)
{
this.PropertyName = item.getProperty("property_name", "");
this.NewValue = item.getProperty("new_value", "");
}
#region Mapped Properties
string property_name;
public string PropertyName
{
get { return property_name; }
private set { property_name = value; }
}
string new_value;
public string NewValue
{
get { return new_value; }
private set { new_value = value; }
}
#endregion
}
/// <summary>
/// No related relationship Affected Relationship Property of Affected Relationship
/// </summary>
class AffectedRelationshipProperty : NoRelatedRelationshipItem
{
public AffectedRelationshipProperty()
: base()
{
}
public AffectedRelationshipProperty(Item item, AffectedRelationship sourceItem)
: base(item, sourceItem)
{
this.PropertyName = item.getProperty("property_name", "");
this.NewValue = item.getProperty("new_value", "");
}
#region Mapped Properties
string property_name;
public string PropertyName
{
get { return property_name; }
private set { property_name = value; }
}
string new_value;
public string NewValue
{
get { return new_value; }
private set { new_value = value; }
}
#endregion
}
/// <summary>
/// Create and get access to Innovator object and provide help methods.
/// </summary>
static class Utils
{
public static void InitializeForRequest(Innovator innovator, Aras.Server.Core.CallContext CCO)
{
HttpContext.Current.Items["AffectedItemInnovatorObject"] = innovator;
HttpContext.Current.Items["AffectedItemInnovatorCCO"] = CCO;
}
/// <summary>
/// Instantiate item with "OK" result
/// </summary>
/// <returns>Item with "OK" result</returns>
public static Item GetOkResult()
{
return Utils.Innovator.newResult("OK");
}
/// <summary>
/// Get error item with specific parameters
/// </summary>
/// <param name="status">Status with errors</param>
/// <param name="numberOfDisplayedErrors">The number of displayed errors</param>
/// <returns>Item with error</returns>
public static Item GetError(ResultStatus status, int numberOfDisplayedErrors)
{
StringBuilder builder = new StringBuilder();
List<String> lookedupMessages = status.Errors
.Select((Error error) =>
{
return Utils.CCO.ErrorLookup.Lookup(error.name, error.parameters);
})
.Distinct()
.ToList();
lookedupMessages
.Where((String message, int index) =>
{
return index < numberOfDisplayedErrors;
})
.ToList()
.ForEach((String message) =>
{
builder.Append(message);
});
if (numberOfDisplayedErrors < lookedupMessages.Count)
{
builder.AppendLine("");
builder.AppendLine("");
builder.Append(Utils.CCO.ErrorLookup.Lookup("ValidateChangeItem_AdditionalErrors"));
}
return Utils.Innovator.newError(builder.ToString());
}
/// <summary>
/// Assert passed item, throw ItemErrorException if item has error
/// </summary>
/// <param name="item"></param>
public static void AssertItem(Item item)
{
if (item.isError())
{
throw new ItemErrorException(item);
}
}
/// <summary>
/// Get instance of Innovator object
/// </summary>
public static Innovator Innovator
{
get
{
return ((Innovator)HttpContext.Current.Items["AffectedItemInnovatorObject"]);
}
}
public static Aras.Server.Core.CallContext CCO
{
get
{
return ((Aras.Server.Core.CallContext)HttpContext.Current.Items["AffectedItemInnovatorCCO"]);
}
}
/// <summary>
/// Convert string name to enum
/// </summary>
/// <typeparam name="T">Enum</typeparam>
/// <param name="value">enum value</param>
/// <param name="noneValue">value which will be parsed if value not presented in enum</param>
/// <returns></returns>
public static T GetEnumByValue<T>(string value, string noneValue) where T : struct, IConvertible
{
Type en = typeof(T);
if (!en.IsEnum)
{
throw new ArgumentException("T must be an enumerated type");
}
if (String.IsNullOrEmpty(value))
{
return (T)Enum.Parse(en, noneValue);
}
return (T)Enum.Parse(en, value);
}
}
/// <summary>
/// Represent error
/// </summary>
struct Error
{
public string name;
public object[] parameters;
/// <summary>
/// Create error
/// </summary>
/// <param name="name">UserMessage name</param>
/// <param name="parameters">objects to format error</param>
public Error(string name, object[] parameters)
{
this.name = name;
this.parameters = parameters;
}
}
/// <summary>
/// Exception which wrap error Item
/// </summary>
[Serializable]
class ItemErrorException : Exception
{
public ItemErrorException(Item error)
: base()
{
this.error = error;
}
private Item error;
public Item Error
{
get { return error; }
}
}
/// <summary>
/// Exception which provide status of validation operation.
/// </summary>
[Serializable]
class ValidationException : Exception
{
public ValidationException(ResultStatus status)
: base()
{
this.status = status;
}
private ResultStatus status;
public ResultStatus ResultStatus
{
get { return status; }
}
}
/// <summary>
/// Type provide ability to agregate multiple errors
/// </summary>
class ResultStatus
{
private bool p_isSuccess;
private List<Error> p_errorList = new List<Error>();
private bool p_throwExceptionIfError;
private int p_numberOfErrorsBeforeThrowException;
/// <summary>
/// Constructor
/// </summary>
/// <param name="throwExceptionIfError">if true, then exception will be thrown when error add</param>
public ResultStatus(bool throwExceptionIfError)
{
this.p_isSuccess = true;
this.p_throwExceptionIfError = throwExceptionIfError;
this.p_numberOfErrorsBeforeThrowException = 2;
}
/// <summary>
/// Add error to collection. Toggle IsSuccess to false.
/// </summary>
/// <param name="name">UserMessage name</param>
/// <param name="parameters">objects to format error message</param>
/// <exception cref="ValidationException">throw if constructor get true to throwExceptionIfError</exception>
public void AddError(string name, params string[] parameters)
{
this.p_errorList.Add(new Error(name, parameters));
this.p_isSuccess = false;
//throw exception if only if number of available errors were handled
if (this.p_throwExceptionIfError && this.Errors.Count >= this.p_numberOfErrorsBeforeThrowException)
{
throw new ValidationException(this);
}
}
/// <summary>
/// Get is status success
/// </summary>
public bool IsSuccess
{
get { return p_isSuccess; }
}
/// <summary>
/// Get Error collection
/// </summary>
public IList<Error> Errors
{
get { return new System.Collections.ObjectModel.ReadOnlyCollection<Error>(p_errorList); }
}
}
/// <summary>
/// Base class for relationship item
/// </summary>
abstract class Relationship : ItemContext
{
public Relationship()
: base()
{
}
public Relationship(Item item, ItemContext sourceItem)
: base(item)
{
this.sourceItem = sourceItem;
}
#region Mapped Properties
ItemContext sourceItem;
public ItemContext SourceItem
{
get { return sourceItem; }
protected set { sourceItem = value; }
}
#endregion
}
/// <summary>
/// No Related relationship item
/// </summary>
abstract class NoRelatedRelationshipItem : Relationship
{
public NoRelatedRelationshipItem()
: base()
{
}
public NoRelatedRelationshipItem(Item item, ItemContext sourceItem)
: base(item, sourceItem)
{
}
}
/// <summary>
/// Represent intermediate related relationship item that link source item with related item.
/// </summary>
class RelatedRelationship : Relationship
{
public RelatedRelationship(Item item, ItemContext sourceItem)
: base(item, sourceItem)
{
}
#region Mapped Properties
public string RelatedID
{
get { return this.Item.getProperty("related_id"); }
}
public string SortOrder
{
get { return this.Item.getProperty("sort_order"); }
}
#endregion
}
/// <summary>
/// Related relationship item
/// </summary>
abstract class RelatedRelationshipItem : Relationship
{
public RelatedRelationshipItem()
: base()
{
}
public RelatedRelationshipItem(Item item, ItemContext sourceItem)
: base(item.getItemsByXPath("related_id/Item"), sourceItem)
{
}
private RelatedRelationship relationship;
/// <summary>
/// Get relationship item
/// </summary>
public RelatedRelationship Relationship
{
get
{
if (relationship == null)
{
relationship = new RelatedRelationship(this.Item.getItemsByXPath("../../Item"), this.SourceItem);
}
return relationship;
}
}
}
/// <summary>
/// Collection of relationships
/// </summary>
/// <typeparam name="T">Relationship related or no related item</typeparam>
class RelationshipItemList<T> : IList<T>, ICollection<T>, IEnumerable<T>
where T : Relationship
{
ItemContext sourceItem;
Type relationshipPrototypeType;
T relationshipPrototype;
/// <summary>
/// Constructor
/// </summary>
/// <param name="relshipName">Relationship name</param>
/// <param name="prototype">Pass instance of relationship item which will be a prototype of list items. Could be inheritors of base T type.</param>
/// <param name="sourceItem">Source item</param>
public RelationshipItemList(string relshipName, T prototype, ItemContext sourceItem)
{
this.Name = relshipName;
this.relationshipPrototype = prototype;
this.relationshipPrototypeType = this.relationshipPrototype.GetType();
this.sourceItem = sourceItem;
}
public RelationshipItemList(IEnumerable<T> collection)
{
list = new List<T>(collection);
readOnlyList = new System.Collections.ObjectModel.ReadOnlyCollection<T>(list);
}
string relshipName;
public string Name
{
get { return relshipName; }
private set { relshipName = value; }
}
private IList<T> list;
private IList<T> readOnlyList;
/// <summary>
/// Bind relationship collection. Attach to ItemContext.Deleted event
/// </summary>
public void Bind()
{
this.Unbind();
list = new List<T>();
readOnlyList = new System.Collections.ObjectModel.ReadOnlyCollection<T>(list);
Item relshipItems = Utils.Innovator.newItem(this.Name, "get");
relshipItems.setProperty("source_id", sourceItem.ID);
relshipItems.setAttribute("serverEvents", "0");
if (this.Name == "ECN Affected Item" ||
this.Name == "Simple ECO Affected Item" ||
this.Name == "Express DCO Affected Item" ||
this.Name == "Express ECO Affected Item")
{
Item affItem = Utils.Innovator.newItem("Affected Item", "get");
affItem.setAttribute("select", "interchangeable, item_action, action, affected_id, new_item_id");
affItem.setAttribute("serverEvents", "0");
Item changeControlledItem = Utils.Innovator.newItem("Change Controlled Item", "get");
changeControlledItem.setAttribute("serverEvents", "0");
affItem.setPropertyItem("affected_id", changeControlledItem);
affItem.setPropertyItem("new_item_id", changeControlledItem);
relshipItems.setPropertyItem("related_id", affItem);
}
if (this.Name == "Affected Item Relationship")
{
Item affRelshipItem = Utils.Innovator.newItem("Affected Relationship", "get");
affRelshipItem.setAttribute("select", "rel_action, affected_rel_id, new_rel_id");
affRelshipItem.setAttribute("serverEvents", "0");
Item changeControlledRelship = Utils.Innovator.newItem("Change Controlled Relationship", "get");
changeControlledRelship.setAttribute("serverEvents", "0");
changeControlledRelship.setAttribute("related_expand", "0");
affRelshipItem.setPropertyItem("affected_rel_id", changeControlledRelship);
affRelshipItem.setPropertyItem("new_rel_id", changeControlledRelship);
relshipItems.setPropertyItem("related_id", affRelshipItem);
}
relshipItems = relshipItems.apply();
int affItemRelshipCount = relshipItems.getItemCount();
for (int p = 0; p < affItemRelshipCount; p++)
{
Item affItem = relshipItems.getItemByIndex(p);
T instance = (T)Activator.CreateInstance(this.relationshipPrototypeType, affItem, sourceItem);
instance.Deleted += new EventHandler(instance_Deleted);
list.Add(instance);
}
}
/// <summary>
/// Detach from ItemContext.Deleted event
/// </summary>
private void Unbind()
{
if (list == null) return;
foreach (T t in list)
{
t.Deleted -= new EventHandler(instance_Deleted);
}
list.Clear();
list = null;
}
/// <summary>
/// ItemContext.Deleted event handler. remove item from relationship collection.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void instance_Deleted(object sender, EventArgs e)
{
T instance = (T)sender;
instance.Deleted -= new EventHandler(instance_Deleted);
list.Remove(instance);
}
/// <summary>
/// Bind collection if list was not initialized or was unbinded.
/// </summary>
private void BindIfNotInitialized()
{
if (list == null)
{
this.Bind();
}
}
#region IList<T> Members
public int IndexOf(T item)
{
this.BindIfNotInitialized();
return readOnlyList.IndexOf(item);
}
public void Insert(int index, T item)
{
this.BindIfNotInitialized();
readOnlyList.Insert(index, item);
}
public void RemoveAt(int index)
{
this.BindIfNotInitialized();
readOnlyList.RemoveAt(index);
}
public T this[int index]
{
get
{
this.BindIfNotInitialized();
return readOnlyList[index];
}
set
{
this.BindIfNotInitialized();
readOnlyList[index] = value;
}
}
#endregion
#region ICollection<T> Members
public void Add(T item)
{
this.BindIfNotInitialized();
readOnlyList.Add(item);
}
public void Clear()
{
this.BindIfNotInitialized();
readOnlyList.Clear();
}
public bool Contains(T item)
{
this.BindIfNotInitialized();
return readOnlyList.Contains(item);
}
public void CopyTo(T[] array, int arrayIndex)
{
this.BindIfNotInitialized();
readOnlyList.CopyTo(array, arrayIndex);
}
public int Count
{
get { this.BindIfNotInitialized(); return readOnlyList.Count; }
}
public bool IsReadOnly
{
get { this.BindIfNotInitialized(); return readOnlyList.IsReadOnly; }
}
public bool Remove(T item)
{
this.BindIfNotInitialized();
return readOnlyList.Remove(item);
}
#endregion
#region IEnumerable<T> Members
public IEnumerator<T> GetEnumerator()
{
this.BindIfNotInitialized();
return readOnlyList.GetEnumerator();
}
#endregion
#region IEnumerable Members
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
this.BindIfNotInitialized();
return ((System.Collections.IEnumerable)readOnlyList).GetEnumerator();
}
#endregion
}
internal static class ItemContextGroupOperations
{
public static void Promote<TSource>(this IList<TSource> items, string nextStatus) where TSource : ItemContext
{
items.InvokeActionByGroup((groupItems) =>
{
groupItems.PromoteImpl(nextStatus);
});
}
public static IList<TSource> Version<TSource>(this IList<TSource> items) where TSource : ItemContext
{
TSource[] result = new TSource[items.Count];
Dictionary<string, int> itemsIndexDict = items
.Select((templateItem, index) => index)
.ToDictionary((index) => items[index].ID);
items.InvokeActionByGroup((groupItems) =>
{
IList<TSource> groupItemsResult = groupItems.VersionImpl();
for (int indexInGroup = 0; indexInGroup < groupItems.Count; indexInGroup++)
{
string originalID = groupItems[indexInGroup].ID;
TSource versionedItem = groupItemsResult[indexInGroup];
int positionInInputList = itemsIndexDict[originalID];
result[positionInInputList] = versionedItem;
}
});
return result.ToList();
}
public static void Unlock<TSource>(this IList<TSource> items) where TSource : ItemContext
{
items.InvokeActionByGroup(UnlockImpl);
}
public static void Lock<TSource>(this IList<TSource> items) where TSource : ItemContext
{
items.InvokeActionByGroup(LockImpl);
}
public static void ApplyUpdate<TSource>(this IList<TSource> items, params string[] updateParameterNames) where TSource : ItemContext
{
if (items.Count() == 0)
{
return;
}
Item itemList = Utils.Innovator.newItem(items.First().Type);
XmlDocument amlDoc = new XmlDocument();
amlDoc.LoadXml("<AML/>");
XmlElement amlElement = amlDoc.DocumentElement;
StringBuilder sb = new StringBuilder();
sb.Append("<AML>");
foreach (TSource item in items)
{
sb.AppendFormat(CultureInfo.InvariantCulture, "<Item type='{0}' action='update' id='{1}' doGetItem='0' version='0'>", item.Type, item.ID);
foreach (string parameter in updateParameterNames)
{
sb.AppendFormat("<{0}>{1}</{0}>", parameter, item.Item.getProperty(parameter));
}
sb.Append("</Item>");
}
sb.Append("</AML>");
Item res = Utils.Innovator.applyAML(sb.ToString());
Utils.AssertItem(res);
}
//TODO: innovator doesn't support group copy yet
public static IList<TSource> Copy<TSource>(this IList<TSource> items) where TSource : ItemContext
{
if (items.Count() == 0)
{
return items;
}
List<TSource> result = new List<TSource>();
foreach (TSource item in items)
{
TSource resItem = item.ApplyCopy<TSource>();
result.Add(resItem);
}
return result;
}
public static void ProcessAffectedRelationships<TSource>(this IList<TSource> affectedItems) where TSource : ExtendedAffectedItem
{
foreach (TSource extAffectedItem in affectedItems)
{
extAffectedItem.ProcessAffectedRelationships();
}
}
public static void ProcessAffectedItemProperties<TSource>(this IList<TSource> affectedItems) where TSource : ExtendedAffectedItem
{
List<String> propertyListNames = new List<String>();
IList<ChangeControlledItem> newItemIdItemList =
affectedItems.Select(
(TSource affectedItem) =>
{
foreach (AffectedItemProperty affectedItemProperty in affectedItem.AffectedItemProperties)
{
affectedItem.NewItemIdItem.Item.setProperty(affectedItemProperty.PropertyName, affectedItemProperty.NewValue);
if (!propertyListNames.Contains(affectedItemProperty.PropertyName))
{
propertyListNames.Add(affectedItemProperty.PropertyName);
}
}
return affectedItem.NewItemIdItem;
}
)
.ToList();
newItemIdItemList.Lock();
newItemIdItemList.ApplyUpdate(propertyListNames.ToArray());
newItemIdItemList.Unlock();
}
#region Action implementations
private static void PromoteImpl<TSource>(this IList<TSource> items, string nextStatus) where TSource : ItemContext
{
if (items.Count() == 0)
{
return;
}
String[] promoteIds = items.Select((TSource item) => item.ID).ToArray();
Item promoteItem = Utils.Innovator.newItem(items.First().Type);
promoteItem.setAttribute("idlist", String.Join(",", promoteIds));
Item res = promoteItem.promote(nextStatus, "Promote set");
Utils.AssertItem(res);
}
private static IList<TSource> VersionImpl<TSource>(this IList<TSource> items) where TSource : ItemContext
{
if (items.Count() == 0)
{
return items;
}
String[] versionIds = items.Select((TSource item) => item.ID).ToArray();
String type = items.First().Type;
Item versionItem = Utils.Innovator.newItem(type, "version");
String idList = String.Join(",", versionIds);
versionItem.setAttribute("idlist", idList);
Item res = versionItem.apply();
Utils.AssertItem(res);
StringBuilder updateSql = new StringBuilder();
updateSql.AppendFormat("UPDATE {0} SET EFFECTIVE_DATE = NULL WHERE ID IN (", Utils.CCO.DB.InnDatabase.GetTableName(type));
List<TSource> result = new List<TSource>();
int versionedItemCount = res.getItemCount();
for (int i = 0; i < versionedItemCount; i++)
{
TSource item = (TSource)Activator.CreateInstance(typeof(TSource), res.getItemByIndex(i));
result.Add(item);
updateSql.AppendFormat("'{0}'", item.ID);
if (i != versionedItemCount - 1)
{
updateSql.Append(",");
}
}
updateSql.Append(")");
Utils.CCO.DB.InnDatabase.ExecuteSQL(updateSql.ToString());
return result;
}
private static void UnlockImpl<TSource>(this IList<TSource> items) where TSource : ItemContext
{
if (items.Count() == 0)
{
return;
}
String[] unlockIds = items.Select((TSource item) => item.ID).ToArray();
Item unlockItem = Utils.Innovator.newItem(items.First().Type, "unlock");
unlockItem.setAttribute("idlist", String.Join(",", unlockIds));
Item res = unlockItem.apply();
Utils.AssertItem(res);
}
private static void LockImpl<TSource>(this IList<TSource> items) where TSource : ItemContext
{
if (items.Count() == 0)
{
return;
}
String[] lockIds = items.Select((TSource item) => item.ID).ToArray();
Item lockItem = Utils.Innovator.newItem(items.First().Type, "lock");
lockItem.setAttribute("idlist", String.Join(",", lockIds));
Item res = lockItem.apply();
Utils.AssertItem(res);
}
#endregion
private static void InvokeActionByGroup<TSource>(this IList<TSource> items, Action<IList<TSource>> operationAction) where TSource : ItemContext
{
List<List<TSource>> itemGroups = items
.GroupBy((item) =>
{
return item.Type;
}, (item) =>
{
return item;
})
.Select((groupedItems) =>
{
return groupedItems.ToList();
}).ToList();
foreach (var itemGroup in itemGroups)
{
operationAction(itemGroup);
}
}
}
class getInnovator
{
public getInnovator()
{
Innovator innovatorQuantity = this.getInnovator();
if (Convert.ToDecimal(this.getProperty("quantity")) > 500)
{
Item error = innovatorQuantity.newError("Error promoting: Item costs more than $500.00");
return error;
}
return this;
}
}
class fin
{
void method()
{