From 6d5ae6363042db9b1078ba3e6a1c2431977cf4ff Mon Sep 17 00:00:00 2001 From: Michal Proszek Date: Wed, 30 Aug 2017 13:00:53 +0200 Subject: [PATCH] [BE] show dollars instead of cents in discount value --- aa_stripe/management/commands/refresh_coupons.py | 2 +- aa_stripe/migrations/0010_auto_20170822_1004.py | 5 ++++- aa_stripe/models.py | 15 ++++++++++----- tests/test_coupons.py | 7 ++++--- tests/test_utils.py | 2 +- tests/test_webhooks.py | 4 ++-- 6 files changed, 22 insertions(+), 13 deletions(-) diff --git a/aa_stripe/management/commands/refresh_coupons.py b/aa_stripe/management/commands/refresh_coupons.py index e68683a..d6d8601 100644 --- a/aa_stripe/management/commands/refresh_coupons.py +++ b/aa_stripe/management/commands/refresh_coupons.py @@ -45,4 +45,4 @@ def handle(self, *args, **options): counts["deleted"] = StripeCoupon.objects.filter(is_deleted=False).exclude( pk__in=active_coupons_ids).update(is_deleted=True) if options.get("verbosity") > 1: - print("Coupons created: {created}, updated: {updated}, deleted {deleted}".format(**counts)) + print("Coupons created: {created}, updated: {updated}, deleted: {deleted}".format(**counts)) diff --git a/aa_stripe/migrations/0010_auto_20170822_1004.py b/aa_stripe/migrations/0010_auto_20170822_1004.py index a84e3aa..2eda7b1 100644 --- a/aa_stripe/migrations/0010_auto_20170822_1004.py +++ b/aa_stripe/migrations/0010_auto_20170822_1004.py @@ -2,6 +2,8 @@ # Generated by Django 1.11.3 on 2017-08-22 10:04 from __future__ import unicode_literals +from decimal import Decimal + import django.db.models.deletion import jsonfield.fields import stripe @@ -33,6 +35,7 @@ def migrate_subcription(apps, schema_editor): } update_data = {key: stripe_coupon[key] for key in fields} update_data["created"] = timestamp_to_timezone_aware_date(stripe_coupon.get("created")) + update_data["amount_off"] = Decimal(update_data["amount_off"]) / 100 coupon = StripeCoupon.objects.create(coupon_id=stripe_coupon.get("id"), is_created_at_stripe=True, **update_data) subscription.coupon = coupon @@ -53,7 +56,7 @@ class Migration(migrations.Migration): ('updated', models.DateTimeField(auto_now=True)), ('stripe_response', jsonfield.fields.JSONField(default=dict)), ('coupon_id', models.CharField(help_text='Identifier for the coupon', max_length=255)), - ('amount_off', models.PositiveIntegerField(blank=True, help_text='Amount (in the currency specified) that will be taken off the subtotal ofany invoices for this customer.', null=True)), + ('amount_off', models.DecimalField(decimal_places=2, max_digits=10, blank=True, help_text='Amount (in the currency specified) that will be taken off the subtotal ofany invoices for this customer.', null=True)), ('currency', models.CharField(default='usd', max_length=3, null=True, blank=True, help_text='If amount_off has been set, the three-letter ISO code for the currency of the amount to take off.', choices=[('usd', 'USD'), ('aed', 'AED'), ('afn', 'AFN'), ('all', 'ALL'), ('amd', 'AMD'), ('ang', 'ANG'), ('aoa', 'AOA'), ('ars', 'ARS'), ('aud', 'AUD'), ('awg', 'AWG'), ('azn', 'AZN'), ('bam', 'BAM'), ('bbd', 'BBD'), ('bdt', 'BDT'), ('bgn', 'BGN'), ('bif', 'BIF'), ('bmd', 'BMD'), ('bnd', 'BND'), ('bob', 'BOB'), ('brl', 'BRL'), ('bsd', 'BSD'), ('bwp', 'BWP'), ('bzd', 'BZD'), ('cad', 'CAD'), ('cdf', 'CDF'), ('chf', 'CHF'), ('clp', 'CLP'), ('cny', 'CNY'), ('cop', 'COP'), ('crc', 'CRC'), ('cve', 'CVE'), ('czk', 'CZK'), ('djf', 'DJF'), ('dkk', 'DKK'), ('dop', 'DOP'), ('dzd', 'DZD'), ('egp', 'EGP'), ('etb', 'ETB'), ('eur', 'EUR'), ('fjd', 'FJD'), ('fkp', 'FKP'), ('gbp', 'GBP'), ('gel', 'GEL'), ('gip', 'GIP'), ('gmd', 'GMD'), ('gnf', 'GNF'), ('gtq', 'GTQ'), ('gyd', 'GYD'), ('hkd', 'HKD'), ('hnl', 'HNL'), ('hrk', 'HRK'), ('htg', 'HTG'), ('huf', 'HUF'), ('idr', 'IDR'), ('ils', 'ILS'), ('inr', 'INR'), ('isk', 'ISK'), ('jmd', 'JMD'), ('jpy', 'JPY'), ('kes', 'KES'), ('kgs', 'KGS'), ('khr', 'KHR'), ('kmf', 'KMF'), ('krw', 'KRW'), ('kyd', 'KYD'), ('kzt', 'KZT'), ('lak', 'LAK'), ('lbp', 'LBP'), ('lkr', 'LKR'), ('lrd', 'LRD'), ('lsl', 'LSL'), ('mad', 'MAD'), ('mdl', 'MDL'), ('mga', 'MGA'), ('mkd', 'MKD'), ('mmk', 'MMK'), ('mnt', 'MNT'), ('mop', 'MOP'), ('mro', 'MRO'), ('mur', 'MUR'), ('mvr', 'MVR'), ('mwk', 'MWK'), ('mxn', 'MXN'), ('myr', 'MYR'), ('mzn', 'MZN'), ('nad', 'NAD'), ('ngn', 'NGN'), ('nio', 'NIO'), ('nok', 'NOK'), ('npr', 'NPR'), ('nzd', 'NZD'), ('pab', 'PAB'), ('pen', 'PEN'), ('pgk', 'PGK'), ('php', 'PHP'), ('pkr', 'PKR'), ('pln', 'PLN'), ('pyg', 'PYG'), ('qar', 'QAR'), ('ron', 'RON'), ('rsd', 'RSD'), ('rub', 'RUB'), ('rwf', 'RWF'), ('sar', 'SAR'), ('sbd', 'SBD'), ('scr', 'SCR'), ('sek', 'SEK'), ('sgd', 'SGD'), ('shp', 'SHP'), ('sll', 'SLL'), ('sos', 'SOS'), ('srd', 'SRD'), ('std', 'STD'), ('svc', 'SVC'), ('szl', 'SZL'), ('thb', 'THB'), ('tjs', 'TJS'), ('top', 'TOP'), ('try', 'TRY'), ('ttd', 'TTD'), ('twd', 'TWD'), ('tzs', 'TZS'), ('uah', 'UAH'), ('ugx', 'UGX'), ('uyu', 'UYU'), ('uzs', 'UZS'), ('vnd', 'VND'), ('vuv', 'VUV'), ('wst', 'WST'), ('xaf', 'XAF'), ('xcd', 'XCD'), ('xof', 'XOF'), ('xpf', 'XPF'), ('yer', 'YER'), ('zar', 'ZAR'), ('zmw', 'ZMW')])), ('duration', models.CharField(choices=[('forever', 'forever'), ('once', 'once'), ('repeating', 'repeating')], help_text='Describes how long a customer who applies this coupon will get the discount.', max_length=255)), ('duration_in_months', models.PositiveIntegerField(blank=True, help_text='If duration is repeating, the number of months the coupon applies.Null if coupon duration is forever or once.', null=True)), diff --git a/aa_stripe/models.py b/aa_stripe/models.py index f2bcd16..fede2cc 100644 --- a/aa_stripe/models.py +++ b/aa_stripe/models.py @@ -1,4 +1,5 @@ # -*- coding: utf-8 -*- +from decimal import Decimal from time import sleep import simplejson as json @@ -105,9 +106,10 @@ class StripeCoupon(StripeBasicModel): ) coupon_id = models.CharField(max_length=255, help_text=_("Identifier for the coupon")) - amount_off = models.PositiveIntegerField( - blank=True, null=True, help_text=_("Amount (in the currency specified) that will be taken off the subtotal of " - "any invoices for this customer.")) + amount_off = models.DecimalField( + blank=True, null=True, decimal_places=2, max_digits=10, + help_text=_("Amount (in the currency specified) that will be taken off the subtotal of any invoices for this" + "customer.")) currency = models.CharField( max_length=3, default="USD", choices=CURRENCY_CHOICES, blank=True, null=True, help_text=_("If amount_off has been set, the three-letter ISO code for the currency of the amount to take " @@ -154,9 +156,12 @@ def update_from_stripe_data(self, stripe_coupon, exclude_fields=None): """ fields_to_update = self.STRIPE_FIELDS - set(exclude_fields or []) update_data = {key: stripe_coupon[key] for key in fields_to_update} - if "created" in update_data: + if update_data.get("created"): update_data["created"] = timestamp_to_timezone_aware_date(update_data["created"]) + if update_data.get("amount_off"): + update_data["amount_off"] = Decimal(update_data["amount_off"]) / 100 + # also make sure the object is up to date (without the need to call database) for key, value in six.iteritems(update_data): setattr(self, key, value) @@ -195,7 +200,7 @@ def save(self, force_retrieve=False, *args, **kwargs): self.stripe_response = stripe.Coupon.create( id=self.coupon_id, duration=self.duration, - amount_off=self.amount_off, + 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, diff --git a/tests/test_coupons.py b/tests/test_coupons.py index 6bb33dd..c07ee75 100644 --- a/tests/test_coupons.py +++ b/tests/test_coupons.py @@ -1,5 +1,6 @@ import time from datetime import datetime +from decimal import Decimal import requests_mock import simplejson as json @@ -102,7 +103,7 @@ def test_delete(self): stripe_response = { "id": "CPON", "object": "coupon", - "amount_off": 1, + "amount_off": 100, "created": int(time.mktime(datetime.now().timetuple())), "currency": "usd", "duration": StripeCoupon.DURATION_FOREVER, @@ -229,7 +230,7 @@ def test_refresh_coupons_command(self): coupon_1a_new_response["metadata"] = {"new": "data"} coupon_4a_new_response = coupons["4A"].stripe_response.copy() coupon_4a_new_response["created"] += 1 - coupon_4a_new_response["amount_off"] = 99 + coupon_4a_new_response["amount_off"] = 9999 # fake limit stripe_response_part1 = { "object": "list", @@ -272,5 +273,5 @@ def test_refresh_coupons_command(self): self.assertTrue(coupons["4A"].is_deleted) new_4a_coupon = StripeCoupon.objects.get(coupon_id="4A", is_deleted=False) self.assertNotEqual(new_4a_coupon.pk, coupons["4A"].pk) - self.assertEqual(new_4a_coupon.amount_off, coupon_4a_new_response["amount_off"]) + self.assertEqual(new_4a_coupon.amount_off, Decimal(coupon_4a_new_response["amount_off"]) / 100) self.assertTrue(StripeCoupon.objects.filter(coupon_id="1B", is_deleted=False).exists) diff --git a/tests/test_utils.py b/tests/test_utils.py index b3b6379..d1d98b7 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -17,7 +17,7 @@ def _create_coupon(self, coupon_id, amount_off=None, duration=StripeCoupon.DURAT stripe_response = { "id": coupon_id, "object": "coupon", - "amount_off": amount_off, + "amount_off": int(amount_off * 100) if amount_off else None, "created": int(time.mktime(datetime.now().timetuple())), "currency": "usd", "duration": duration, diff --git a/tests/test_webhooks.py b/tests/test_webhooks.py index e346f0e..1456423 100644 --- a/tests/test_webhooks.py +++ b/tests/test_webhooks.py @@ -206,7 +206,7 @@ def test_coupon_create(self): self.assertEqual(coupon.coupon_id, "nicecoupon") def test_coupon_update(self): - coupon = self._create_coupon("nicecoupon", amount_off=10000, duration=StripeCoupon.DURATION_ONCE, + coupon = self._create_coupon("nicecoupon", amount_off=100, duration=StripeCoupon.DURATION_ONCE, metadata={"nie": "tak", "lol1": "rotfl"}) payload = json.loads("""{ "id": "evt_1AtuTOLoWm2f6pRw6dYfQzWh", @@ -261,7 +261,7 @@ def test_coupon_update(self): }) def test_coupon_delete(self): - coupon = self._create_coupon("nicecoupon", amount_off=10000, duration=StripeCoupon.DURATION_ONCE) + coupon = self._create_coupon("nicecoupon", amount_off=100, duration=StripeCoupon.DURATION_ONCE) self.assertFalse(coupon.is_deleted) payload = json.loads("""{ "id": "evt_1Atthtasdsaf6pRwkdLOSKls",