I use ATG 10.0.3 and have a problem: when I create two equal promotions, but first has priority = 1, and secont = 3. When my order suited to the conditions, bouth promotions are used. And I want, that the promotion with the highest priority was used. Do you know eny ways to do this
When applying promotions, the pricing engine internally creates a list of promotions by combining global promotions and the promotions from current profile's activePromotions property. The pricing engine then applies promotions from this list based on priority. Lower the number in priority property value, higher would be the promotion priority. Promotion having the highest priority will be applied first then the one with next priority and so on. This is the default behavior.
For your case I think using your own promotion vetoer implementation might be one option you may want to explore further for excluding a promotion based on its priority:
It is available in 10.0.3 as well and ATG provides one OOB implementation for PricingModelEvaluationVetoer which is for vetoing a promotion if it is not valid for the current site. You can create your own implementation for PricingModelEvaluationVetoer and add it to the pricingModelEvaluationVetoers property of PricingEngineService. Your PricingModelEvaluationVetoer implementation can have the logic to check the current promotion priority with other promotion.
If you were on ATG10.1+, then you could have tried using "Stacking Rules" functionality in Merchandising. There you can create stacking rules and link your different priority promotions to different stacking rules. So if an order qualifies for more than one promotion and those promotions are linked to mutually exclusive stacking rules, the promotion with the highest priority is applied and all other promotions are skipped.
Veto promotions works good. But another problem is happened. In method vetoPromotion I can get list of al enable promotion by type(Shipping, Order or Item). But some of them won't be used cause of conditions. For example: I have two promotion. 1 - free shipping if you spend 300$ in order(priority=3), 2 - free shipping in London(priority=1). If I live in Milan, I will see both promotions in vetoPromotion. And I will veto 1-st, because of priority. And 2-d will be not used because of conditions on calculation step.
Is were any way to know, will promotion apply to order or not?
Glad that it works for you. I do hope you should be making use of both the methods of PricingModelEvaluationVetoer - prepareForVetoing() for preparing the vetoer and vetoPromotion() to actually veto the promotions in PricingContext. Just throwing some ideas - see if you can also make use of PromotionTools utility methods to exactly meet your requirements or may be get the Qualifier from PromotionTools and try using one of those filterX or findQualifyingX methods. Hope it helps.