Слишком много "буков"
Разбивай задачу на этапы.
Аксиома 1: данные, влияющие на конечную цену продажи, должны так или иначе быть сохранены, для возможного "разбора полетов". Иначе программист всегда будет крайним: "программа плохая", "я ничего не менял", "она сама посчитала"
Аксимома 2: Если заказа проведен по бухгалтерии, то изменить его невозможно! Нужно сторнирование и проведение заново, но уже как
нового заказа (новые складские проводки, новые логи)
Т.е. выбирать/сохранять какие-либо реквизиты надо один раз в момент обработки заказа. Либо обработки счета-фактуры, либо накладной. Смотря по тому, в какой момент требуется окончательная цена в зависимости от бизнес-процессов. Ну, и необходимо блокировать возможность изменения реквизитов заказа, влияющих на цену после обработки
Лично у нас вообще сделана отдельная кнопка "Пересчет цен по прайсу", которая выполняется после резервирования, но до обработки заказа. Причем без пересчета цен обработка невозможна (пункты меню блокируются). Специальная галка в шапке заказа добавлена.
Соответсвенно, фиксируем только и исключительно то, что действовало на момент проведения заказа. И не важно, что там было "до" или стало "после". Еще менее важен интервал изменений. Хоть сутки, хоть год, хоть миллисекунды. Что "попало" в момент проведения, то и использовали.
Если возникла необходимость изменить цены (акции) "задним числом", то необходимо сторнировать ранее проведенный заказ и провести его заново с новыми ценами. Соответственно, будут сохранены новые акции, действующие на момент проведения после сторнирования (у нас в связи с этим была добавлена "дата действия" в шапке заказа)
Ну, а что именно надо зафиксировать - это уже другой вопрос.
Другими словами, не важно как и кто будет менять справочники акций, но если они влияют на цену продажи, то они должны быть зафиксированы на момент проведения заказа либо в самом заказе, либо в отдельной таблице логов, привязанных к конкретному заказу по аналогии со складскими проводками