<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def save(self, force_retrieve=False, *args, **kwargs):
 """ Use the force_retrieve parameter to create a new StripeCoupon object from an existing coupon created at Stripe API or update the local object with data fetched from Stripe. """

        stripe.api_key = stripe_settings.API_KEY
        if self._previous_is_deleted != self.is_deleted and self.is_deleted:
            try:
                stripe_coupon = stripe.Coupon.retrieve(self.coupon_id)
                # make sure to delete correct coupon
                if self.created == timestamp_to_timezone_aware_date(stripe_coupon["created"]):
                    stripe_coupon.delete()
            except stripe.error.InvalidRequestError:
                # means that the coupon has already been removed from stripe
                pass

            return super(StripeCoupon, self).save(*args, **kwargs)

        if self.pk or force_retrieve:
            try:
                stripe_coupon = stripe.Coupon.retrieve(self.coupon_id)
                if not force_retrieve:
                    stripe_coupon.metadata = self.metadata
                    stripe_coupon.save()

                if force_retrieve:
                    # make sure we are not creating a duplicate
                    coupon_qs = StripeCoupon.objects.filter(coupon_id=self.coupon_id)
                    if coupon_qs.filter(created=timestamp_to_timezone_aware_date(stripe_coupon["created"])).exists():
                        raise StripeCouponAlreadyExists

                    # all old coupons should be deleted
                    for coupon in coupon_qs:
                        coupon.is_deleted = True
                        super(StripeCoupon, coupon).save()  # use super save() to call pre/post save signals
                # update all fields in the local object in case someone tried to change them
                self.update_from_stripe_data(stripe_coupon, exclude_fields=["metadata"] if not force_retrieve else [])
                self.stripe_response = stripe_coupon
            except stripe.error.InvalidRequestError:
                if force_retrieve:
                    raise

                self.is_deleted = True
        else:
            self.stripe_response = stripe.Coupon.create(
                id=self.coupon_id,
                duration=self.duration,
                amount_off=int(self.amount_off * 100) if self.amount_off else None,
                currency=self.currency,
                duration_in_months=self.duration_in_months,
                max_redemptions=self.max_redemptions,
                metadata=self.metadata,
                percent_off=self.percent_off,
                redeem_by=int(dateformat.format(self.redeem_by, "U")) if self.redeem_by else None
            )
            # stripe will generate coupon_id if none was specified in the request
            if not self.coupon_id:
                self.coupon_id = self.stripe_response["id"]

        self.created = timestamp_to_timezone_aware_date(self.stripe_response["created"])
        # for future
        self.is_created_at_stripe = True
        return super(StripeCoupon, self).save(*args, **kwargs)