public void FinishItem(WorkItemInfo toBeFinished) { IDbTransaction transaction = null; try { transaction = dbConn_.BeginTransaction(); var item = WorkItem.Select(dbConn_, toBeFinished.Id); if (item == null) { var msg = new StringBuilder(); msg.Append("cannot finish item ["); msg.Append(item.Name); msg.Append("], #"); msg.Append(item.Id); msg.Append("; not found in database"); throw new Exception(msg.ToString()); } var currentStep = Step.Select(dbConn_, item.StepId); if (currentStep == null) { throw new Exception("internal error, no such current step on " + item.ToString()); } var calc = new RuleCalculator(); var nextStep = calc.FindNextStep(dbConn_, toBeFinished, currentStep); if (nextStep == null) { // RuleCalculator enforces that this is a // terminating step, that there is no next step // etc. So we're clear to just delete the item // here: item.Delete(dbConn_); } else { item.StepId = nextStep.Id; item.ItemState = WorkItemState.Available; item.Entered = DateTime.UtcNow; item.SessionId = session_.Id; item.Priority = toBeFinished.Priority; item.Name = toBeFinished.Name; item.Update(dbConn_); WorkItemData.DeleteAll(dbConn_, item.Id); WorkItemData.Insert(dbConn_, item, toBeFinished); } transaction.Commit(); transaction = null; } finally { DbUtil.ReallyBackout(transaction); } }