трудности можно избежать, если сделать Math.Round((decimal)sum, 2); не помню как это в диалекте SQL, но суть такая, сначала сумму привести к decimal, округлить в типе данных decimal, а потом уже обратно перевести в float (или double, в зависимости от типа данных в БД), тогда всё сойдется.
Копать же надо так: вклчюить логирование trace у службы лояльности и в логах службы смотреть, в каких случаях в chequeDisc в кассу уходит в цене (или сумме) позиции знаков после запятой, более чем 2, там же видно будет какая скидка при этом применена.
На самом деле даже просто по chequeDisc можно увидеть запросом вида
sum-Math.Round((decimal)sum, 2)<>0 || price-Math.Round((price)sum, 2)<>0
(в диалект SQL думаю сами сможете перевести)
(предполагаю что где-то так: (на базе SES и при необходимости SES_Archive)
SELECT TOP 1000 *
FROM SES_Archive.[dbo].[ChequeDisc]
where ROUND(cast([DiscSumm] as decimal(18,3)),2)-cast([DiscSumm] as decimal(18,3)) <>0
SELECT TOP 1000 *
FROM SES_Archive.[dbo].[ChequeHead]
where ROUND(cast([Disc_Sum] as decimal(18,3)) ,2)-cast([Disc_Sum] as decimal(18,3)) <>0
SELECT TOP 1000 *
FROM SES_Archive.[dbo].[ChequePos]
where ROUND(cast([Disc_Summ] as decimal(18,3)) ,2)-cast([Disc_Summ] as decimal(18,3)) <>0
)
во вложении результат
К примеру у меня это при применении скидок 262154 и 43
Id DiscType Name DiscGroup Visible DiscountTypeValueFromCash
41 141 Скидка на текущую позицию по купонингу NULL 1 262154
Id DiscType Name DiscGroup Visible DiscountTypeValueFromCash
43 143 Суммируемая скидка по купонингу NULL 1 43
(смотреть скидки в [SES].[dbo].[DiscountType] по DiscountTypeValueFromCash=)
Что является правдой, ибо у кристалл был баг как раз связанный с "забыли окгруглить" при применении купонинга.