class ThemeLock(amo.models.ModelBase): theme = models.OneToOneField('addons.Persona') reviewer = UserForeignKey() expiry = models.DateTimeField() class Meta: db_table = 'theme_locks'
class BlueViaConfig(amo.models.ModelBase): user = UserForeignKey() developer_id = models.CharField(max_length=64) class Meta: db_table = 'bluevia' unique_together = ('user', 'developer_id')
class SolitudeSeller(amo.models.ModelBase): # TODO: When Solitude allows for it, this should be updated to be 1:1 with # users. user = UserForeignKey() uuid = models.CharField(max_length=255, unique=True) resource_uri = models.CharField(max_length=255) class Meta: db_table = 'payments_seller' @classmethod def create(cls, user): uuid_ = str(uuid.uuid4()) res = client.api.generic.seller.post(data={'uuid': uuid_}) uri = res['resource_uri'] obj = cls.objects.create(user=user, uuid=uuid_, resource_uri=uri) log.info('[User:%s] Created Solitude seller (uuid:%s)' % (user, uuid_)) return obj
class PaymentAccount(amo.models.ModelBase): user = UserForeignKey() name = models.CharField(max_length=64) agreed_tos = models.BooleanField(default=False) solitude_seller = models.ForeignKey(SolitudeSeller) # These two fields can go away when we're not 1:1 with SolitudeSellers. seller_uri = models.CharField(max_length=255, unique=True) uri = models.CharField(max_length=255, unique=True) # A soft-delete so we can talk to Solitude asynchronously. inactive = models.BooleanField(default=False) # The id for this account from the provider. account_id = models.CharField(max_length=255) # Each account will be for a particular provider. provider = models.IntegerField(choices=PROVIDER_CHOICES, default=PROVIDER_BANGO) shared = models.BooleanField(default=False) class Meta: db_table = 'payment_accounts' unique_together = ('user', 'uri') def cancel(self, disable_refs=False): """Cancels the payment account. If `disable_refs` is set, existing apps that use this payment account will be set to STATUS_NULL. """ account_refs = AddonPaymentAccount.objects.filter(account_uri=self.uri) if self.shared and account_refs: # With sharing a payment account comes great responsibility. It # would be really mean to create a payment account, share it # and have lots of apps use it. Then one day you remove it and # make a whole pile of apps in the marketplace get removed from # the store, or have in-app payments fail. # # For the moment I'm just stopping this completely, if this ever # happens, we'll have to go through a deprecation phase. # - let all the apps that use it know # - when they have all stopped sharing it # - re-run this log.error('Cannot cancel a shared payment account that has ' 'apps using it.') raise CantCancel('You cannot cancel a shared payment account.') self.update(inactive=True) log.info('Soft-deleted payment account (uri: %s)' % self.uri) for acc_ref in account_refs: if (disable_refs and not acc_ref.addon.has_multiple_payment_accounts()): log.info('Changing app status to NULL for app: {0}' 'because of payment account deletion'.format( acc_ref.addon_id)) acc_ref.addon.update(status=amo.STATUS_NULL) log.info('Deleting AddonPaymentAccount for app: {0} because of ' 'payment account deletion'.format(acc_ref.addon_id)) acc_ref.delete() def get_provider(self): """Returns an instance of the payment provider for this account.""" # TODO: fix circular import. Providers imports models which imports # forms which imports models. from mkt.developers.providers import get_provider return get_provider(id=self.provider) def __unicode__(self): date = self.created.strftime('%m/%y') if not self.shared: return u'%s - %s' % (date, self.name) # L10n: {0} is the name of the account. return _(u'Shared Account: {0}'.format(self.name)) def get_agreement_url(self): return reverse('mkt.developers.provider.agreement', args=[self.pk])
class PaymentAccount(amo.models.ModelBase): user = UserForeignKey() name = models.CharField(max_length=64) agreed_tos = models.BooleanField() solitude_seller = models.ForeignKey(SolitudeSeller) # These two fields can go away when we're not 1:1 with SolitudeSellers. seller_uri = models.CharField(max_length=255, unique=True) uri = models.CharField(max_length=255, unique=True) # A soft-delete so we can talk to Solitude asynchronously. inactive = models.BooleanField(default=False) # The id for this account from the provider. account_id = models.IntegerField(blank=True, null=True) # Each account will be for a particular provider. provider = models.IntegerField(choices=PROVIDER_CHOICES, default=PROVIDER_BANGO) shared = models.BooleanField(default=False) BANGO_PACKAGE_VALUES = ('adminEmailAddress', 'supportEmailAddress', 'financeEmailAddress', 'paypalEmailAddress', 'vendorName', 'companyName', 'address1', 'address2', 'addressCity', 'addressState', 'addressZipCode', 'addressPhone', 'countryIso', 'currencyIso', 'vatNumber') BANGO_BANK_DETAILS_VALUES = ( 'seller_bango', 'bankAccountPayeeName', 'bankAccountNumber', 'bankAccountCode', 'bankName', 'bankAddress1', 'bankAddressZipCode', 'bankAddressIso', ) class Meta: db_table = 'payment_accounts' unique_together = ('user', 'uri') def cancel(self, disable_refs=False): """Cancels the payment account. If `disable_refs` is set, existing apps that use this payment account will be set to STATUS_NULL. """ account_refs = AddonPaymentAccount.objects.filter(account_uri=self.uri) if self.shared and account_refs: # With sharing a payment account comes great responsibility. It # would be really mean to create a payment account, share it # and have lots of apps use it. Then one day you remove it and # make a whole pile of apps in the marketplace get removed from # the store, or have in-app payments fail. # # For the moment I'm just stopping this completely, if this ever # happens, we'll have to go through a deprecation phase. # - let all the apps that use it know # - when they have all stopped sharing it # - re-run this log.error('Cannot cancel a shared payment account that has ' 'apps using it.') raise CantCancel('You cannot cancel a shared payment account.') self.update(inactive=True) log.info('Soft-deleted payment account (uri: %s)' % self.uri) for acc_ref in account_refs: if disable_refs: log.info('Changing app status to NULL for app: {0}' 'because of payment account deletion'.format( acc_ref.addon_id)) acc_ref.addon.update(status=amo.STATUS_NULL) log.info('Deleting AddonPaymentAccount for app: {0} because of ' 'payment account deletion'.format(acc_ref.addon_id)) acc_ref.delete() def update_account_details(self, **kwargs): self.update(name=kwargs.pop('account_name')) client.api.by_url(self.uri).patch(data=dict( (k, v) for k, v in kwargs.items() if k in self.BANGO_PACKAGE_VALUES)) def get_details(self): data = {'account_name': self.name} package_data = (client.api.bango.package(uri_to_pk( self.uri)).get(data={'full': True})) data.update((k, v) for k, v in package_data.get('full').items() if k in self.BANGO_PACKAGE_VALUES) return data def __unicode__(self): date = self.created.strftime('%m/%y') if not self.shared: return u'%s - %s' % (date, self.name) # L10n: {0} is the name of the account. return _(u'Shared Account: {0}'.format(self.name)) def get_agreement_url(self): return reverse('mkt.developers.bango.agreement', args=[self.pk]) def get_lookup_portal_url(self): return reverse('lookup.bango_portal_from_package', args=[self.account_id])
class PaymentAccount(amo.models.ModelBase): user = UserForeignKey() name = models.CharField(max_length=64) agreed_tos = models.BooleanField() solitude_seller = models.ForeignKey(SolitudeSeller) # These two fields can go away when we're not 1:1 with SolitudeSellers. seller_uri = models.CharField(max_length=255, unique=True) uri = models.CharField(max_length=255, unique=True) # A soft-delete so we can talk to Solitude asynchronously. inactive = models.BooleanField(default=False) bango_package_id = models.IntegerField(blank=True, null=True) BANGO_PACKAGE_VALUES = ('adminEmailAddress', 'supportEmailAddress', 'financeEmailAddress', 'paypalEmailAddress', 'vendorName', 'companyName', 'address1', 'addressCity', 'addressState', 'addressZipCode', 'addressPhone', 'countryIso', 'currencyIso', 'vatNumber') BANGO_BANK_DETAILS_VALUES = ( 'seller_bango', 'bankAccountPayeeName', 'bankAccountNumber', 'bankAccountCode', 'bankName', 'bankAddress1', 'bankAddressZipCode', 'bankAddressIso', ) class Meta: db_table = 'payment_accounts' unique_together = ('user', 'uri') @classmethod def create_bango(cls, user, form_data): # Get the seller object. user_seller = SolitudeSeller.create(user) # Get the data together for the package creation. package_values = dict((k, v) for k, v in form_data.items() if k in cls.BANGO_PACKAGE_VALUES) # Dummy value since we don't really use this. package_values.setdefault('paypalEmailAddress', '*****@*****.**') package_values['seller'] = user_seller.resource_uri log.info('[User:%s] Creating Bango package' % user) res = client.api.bango.package.post(data=package_values) uri = res['resource_uri'] # Get the data together for the bank details creation. bank_details_values = dict((k, v) for k, v in form_data.items() if k in cls.BANGO_BANK_DETAILS_VALUES) bank_details_values['seller_bango'] = uri log.info('[User:%s] Creating Bango bank details' % user) client.api.bango.bank.post(data=bank_details_values) obj = cls.objects.create(user=user, uri=uri, solitude_seller=user_seller, seller_uri=user_seller.resource_uri, bango_package_id=res['package_id'], name=form_data['account_name']) log.info('[User:%s] Created Bango payment account (uri: %s)' % (user, uri)) return obj def cancel(self, disable_refs=False): """Cancels the payment account. If `disable_refs` is set, existing apps that use this payment account will be set to STATUS_NULL. """ self.update(inactive=True) log.info('[1@None] Soft-deleted payment account (uri: %s)' % self.uri) account_refs = AddonPaymentAccount.objects.filter(account_uri=self.uri) for acc_ref in account_refs: if disable_refs: acc_ref.addon.update(status=amo.STATUS_NULL) acc_ref.delete() def update_account_details(self, **kwargs): self.update(name=kwargs.pop('account_name')) client.api.by_url(self.uri).patch(data=dict( (k, v) for k, v in kwargs.items() if k in self.BANGO_PACKAGE_VALUES)) def get_details(self): data = {'account_name': self.name} package_data = (client.api.bango.package(uri_to_pk( self.uri)).get(data={'full': True})) data.update((k, v) for k, v in package_data.get('full').items() if k in self.BANGO_PACKAGE_VALUES) return data def __unicode__(self): return u'%s - %s' % (self.created.strftime('%m/%y'), self.name) def get_agreement_url(self): return reverse('mkt.developers.bango.agreement', args=[self.pk])