constructor({
        Member,
        MemberNewsletter,
        MemberCancelEvent,
        MemberSubscribeEventModel,
        MemberEmailChangeEvent,
        MemberPaidSubscriptionEvent,
        MemberStatusEvent,
        MemberProductEvent,
        StripeCustomer,
        StripeCustomerSubscription,
        OfferRedemption,
        stripeAPIService,
        labsService,
        productRepository,
        offerRepository,
        tokenService,
        newslettersService
    }) {
        this._Member = Member;
        this._MemberNewsletter = MemberNewsletter;
        this._MemberCancelEvent = MemberCancelEvent;
        this._MemberSubscribeEvent = MemberSubscribeEventModel;
        this._MemberEmailChangeEvent = MemberEmailChangeEvent;
        this._MemberPaidSubscriptionEvent = MemberPaidSubscriptionEvent;
        this._MemberStatusEvent = MemberStatusEvent;
        this._MemberProductEvent = MemberProductEvent;
        this._OfferRedemption = OfferRedemption;
        this._StripeCustomer = StripeCustomer;
        this._StripeCustomerSubscription = StripeCustomerSubscription;
        this._stripeAPIService = stripeAPIService;
        this._productRepository = productRepository;
        this._offerRepository = offerRepository;
        this.tokenService = tokenService;
        this._newslettersService = newslettersService;
        this._labsService = labsService;

        DomainEvents.subscribe(OfferRedemptionEvent, async function (event) {
            if (!event.data.offerId) {
                return;
            }

            // To be extra safe, check if the redemption already exists before adding it
            const existingRedemption = await OfferRedemption.findOne({
                member_id: event.data.memberId,
                subscription_id: event.data.subscriptionId,
                offer_id: event.data.offerId
            });

            if (!existingRedemption) {
                await OfferRedemption.add({
                    member_id: event.data.memberId,
                    subscription_id: event.data.subscriptionId,
                    offer_id: event.data.offerId,
                    created_at: event.timestamp || Date.now()
                });
            }
        });
    }
@param {object} deps
@param {any} deps.Member
@param {any} deps.MemberNewsletter
@param {any} deps.MemberCancelEvent
@param {any} deps.MemberSubscribeEventModel
@param {any} deps.MemberEmailChangeEvent
@param {any} deps.MemberPaidSubscriptionEvent
@param {any} deps.MemberStatusEvent
@param {any} deps.MemberProductEvent
@param {any} deps.StripeCustomer
@param {any} deps.StripeCustomerSubscription
@param {any} deps.OfferRedemption
@param {import('../../services/stripe-api')} deps.stripeAPIService
@param {any} deps.labsService
@param {any} deps.productRepository
@param {any} deps.offerRepository
@param {ITokenService} deps.tokenService
@param {any} deps.newslettersService