add coupon ability, refactor code and tests