Добрый день!
Есть задача.
Объект — учетная единица. С ней могут производиться определенные операции, которые отражают изменение местоположение объекта, изменение его характеристик и т.п. Суть операций — знать, что с объектом происходило до текущего момента, то есть всю историю операций.
Пример последовательности операций:
1 мая: объект образовался в пункте А
10 мая: объект переместили из А в Б
12 мая: объект переместили из Б в Г (*)
13 мая: объект прекратил свое существование в пункте Г
Вопрос заключается в том, как быть с историей редактирования операций? Например, пользователь считает, что ошибся, и захотел зайти в прошлую операцию и исправить ее. Но исправление в истории может привести к логическим ошибкам. Пример: в операции (*) он поставил дату 9 мая... Но 9 мая объект был в пункте А, и операция (*) в данном случае не имеет смысла! В итоге, в программу надо закладывать проверки, количество и сложность которых растет вместе с разными видами операций над объектом. Может быть в принципе неверно давать пользователю редактировать историю? Но юзеры утверждают, что могут ошибаться, и им это надо

. У кого есть опыт решения таких задач, прошу поделитесь им!
История должна быть объективной, если дать пользователям возможность ею манипулировать, то нужно вводить аудит/историю манипулирования историей.
Вона как.
Не понятно зачем пользователям в принципе понадобилась возможность редактировать историю ?
Просматривать пожалуйста, если были ошибки они будут отражены.
Историю можно фильтровать, например распознавать типичные ошибки пользователей при редактировании объекта и проглатывать ошибочные итераций.
И то в этом есть смысл если пользователи часто ошибаются объём исторических, данных велик, и они его часто просматривают и хотят видеть только ключевые изменения.
Ни что в жизни ни даёться так просто как... хотелось бы...
В том то вся и фишка, что еще хотят аудит манипулирования историей. А редактирование истории должно быть для возможности исправить ошибку.
Система исключительно ручного ввода данных. Факт выполнения чего-либо производится на бумаге. А в программе затем фиксируется согласно бумаге.
По сути система складского учета. История нужна якобы для расследований, а также для анализа.
Здравствуйте, welvist, Вы писали:
W>В том то вся и фишка, что еще хотят аудит манипулирования историей. А редактирование истории должно быть для возможности исправить ошибку.
W>Система исключительно ручного ввода данных. Факт выполнения чего-либо производится на бумаге. А в программе затем фиксируется согласно бумаге.
W>По сути система складского учета. История нужна якобы для расследований, а также для анализа.
Видится два варианта: один без отката изменений, второй с откатом.
Вариант 1 (простой, без отката изменений).
Если появляется ошибка, то в программу вводят операции, исправляющие эту ошибку, с какой-нибудь пометкой — типа "сторно". История хранит, как исходные операции, так и сторнирующие.
Пример истории:
1. Приход на склад А.
2. Перемещение с А на склад Б.
3. Перемешение с Б на склад С.
4. Перемешение с С на склад А. (сторно — анулирование документов 2 и 3).
Т.е. для исправления ошибки был введен еще один документ (номер 4), что и было отражено в истории.
Плюсы такого подхода:
— можно посмотреть все операции с объектом (обычные, ошибочные, а также исправления этих ошибок)
— легко реализовать (нужно хранить только последнюю версию объекта плюс длинную историю)
Вариант 2. По аналогии с 1С Предприятие.
Каждое перемешение — некий документ, который вносится в программу.
Документ может быть "проведен", тогда изменения отражены в базе, или "не проведен", тогда документ в базе есть, но изменения в базе не отражены.
1. Приход на склад А. (здесь ошибка — должно быть на склад Б)
2. Перемещение со склада А на склад Б.
3. Перемешение со склада Б на склад С.
Для исправления ошибки необходимо отменить проведение документов до ошибки. Потом исправить ошибочный документ и перепровести все остальные.
Т.е. отменить документы 2 и 3, потом исправить документ 1. Затем нужно перепровести документы 2 и 3. Вот здесь и вылезет ошибка, т.к. документ 2 не сможет быть проведен, т.к. на складе А объекта уже нет. Пользователю придется эту ситуацию разрулить.
Проблема здесь в "отмене проведения", т.е. к возврату к исходному состоянию. Проще всего хранить все версии объекта на соответствующие даты. И "вычеркивать" ненужные строки при отмене проведения. Для оптимизации отделять текущую версию объекта от предыдущих.
Реализовать этот вариант сложнее. К тому отмененные версии могли использовать в других местах системы и их тоже надо откатывать, т.е. придется хранить еще и эти связи в системе.
В общем, нужно строить целую инфраструктуру для этого.
... << RSDN@Home 1.2.0 alpha 4 rev. 1472>>
Здравствуйте, welvist, Вы писали:
W>В том то вся и фишка, что еще хотят аудит манипулирования историей. А редактирование истории должно быть для возможности исправить ошибку.
А по другому скорее всего вы и не решите задачу. Придется делать аудит истории.
Фактически можно сделать так: при изменении какого либо элемента истории вы перезаписываете сам элемент, а его старое значение добавляете к новому в его историю.
Постараюсь пояснить в коде:
// Эта структура представляет собой простую операцию
// которая содержит только описание операции и время
// когда она была создана
struct Operation
{
public string Text { get; set; }
public DateTime Date { get; set; }
}
// Этот клас представляет собой элемент истории
// который содержит операцию и стек из предыдущих операций
class HistoryEntry
{
public Operation Current { get; set; }
public Stack<Operation> OldOperations { get; set; }
public HistoryEntry()
{
OldOperations = new Stack<Operation>();
}
}
class Program
{
static void Main(string[] args)
{
// Создаем операцию
Operation operation = new Operation()
{
Text = "Operation_1",
Date = DateTime.Now
};
// Создаем запись истории и заносим созданную операцию
HistoryEntry entry = new HistoryEntry()
{
Current = operation
};
// Создаем операцию для редактирования,
// копируем в нее нужную операцию и редактируем ее
Operation operationToEdit = entry.Current;
operationToEdit.Text = "Edited Operation_1";
operationToEdit.Date = DateTime.Now;
// Заносим в стек старых операций, ту которая сейчас текущаа
entry.OldOperations.Push(entry.Current);
// Делаем текущей операцией ту, которую отредактировали.
entry.Current = operationToEdit;
}
}
Как то так.
W>Система исключительно ручного ввода данных. Факт выполнения чего-либо производится на бумаге. А в программе затем фиксируется согласно бумаге.
W>По сути система складского учета. История нужна якобы для расследований, а также для анализа.
Ха))) Интересная история для расследований, которую можно поправить!
Главное чтобы вас не попросили сделать историю изменения истории изменения истории)))
Спасибо! Про сторнирование и 1С понял, особенно понравилось про сторнирование. Завтра на свежую голову обдумаю.
Заказчик очень замороченный, наверное как и все

.