Add cache table, importer for NationBuilder donations
This commit is contained in:
		
							parent
							
								
									719de78413
								
							
						
					
					
						commit
						63286679ad
					
				
					 6 changed files with 182 additions and 9 deletions
				
			
		|  | @ -0,0 +1,81 @@ | |||
| # -*- coding: utf-8; -*- | ||||
| """add donations cache table | ||||
| 
 | ||||
| Revision ID: c3cb75afcae2 | ||||
| Revises: 1e17031c4b3e | ||||
| Create Date: 2023-09-12 19:30:47.583505 | ||||
| 
 | ||||
| """ | ||||
| 
 | ||||
| # revision identifiers, used by Alembic. | ||||
| revision = 'c3cb75afcae2' | ||||
| down_revision = '1e17031c4b3e' | ||||
| branch_labels = None | ||||
| depends_on = None | ||||
| 
 | ||||
| from alembic import op | ||||
| import sqlalchemy as sa | ||||
| import rattail.db.types | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| def upgrade(): | ||||
| 
 | ||||
|     # nationbuilder_cache_donation | ||||
|     op.create_table('nationbuilder_cache_donation', | ||||
|                     sa.Column('uuid', sa.String(length=32), nullable=False), | ||||
|                     sa.Column('id', sa.Integer(), nullable=False), | ||||
|                     sa.Column('author_id', sa.Integer(), nullable=True), | ||||
|                     sa.Column('membership_id', sa.Integer(), nullable=True), | ||||
|                     sa.Column('donor_id', sa.Integer(), nullable=True), | ||||
|                     sa.Column('donor_external_id', sa.String(length=50), nullable=True), | ||||
|                     sa.Column('email', sa.String(length=255), nullable=True), | ||||
|                     sa.Column('amount', sa.Numeric(precision=10, scale=2), nullable=True), | ||||
|                     sa.Column('payment_type_name', sa.String(length=100), nullable=True), | ||||
|                     sa.Column('check_number', sa.String(length=255), nullable=True), | ||||
|                     sa.Column('tracking_code_slug', sa.String(length=255), nullable=True), | ||||
|                     sa.Column('note', sa.Text(), nullable=True), | ||||
|                     sa.Column('created_at', sa.DateTime(), nullable=True), | ||||
|                     sa.Column('succeeded_at', sa.DateTime(), nullable=True), | ||||
|                     sa.Column('failed_at', sa.DateTime(), nullable=True), | ||||
|                     sa.Column('canceled_at', sa.DateTime(), nullable=True), | ||||
|                     sa.Column('updated_at', sa.DateTime(), nullable=True), | ||||
|                     sa.PrimaryKeyConstraint('uuid'), | ||||
|                     sa.UniqueConstraint('id', name='nationbuilder_cache_donation_uq_id') | ||||
|                     ) | ||||
|     op.create_table('nationbuilder_cache_donation_version', | ||||
|                     sa.Column('uuid', sa.String(length=32), autoincrement=False, nullable=False), | ||||
|                     sa.Column('id', sa.Integer(), autoincrement=False, nullable=False), | ||||
|                     sa.Column('author_id', sa.Integer(), nullable=True), | ||||
|                     sa.Column('membership_id', sa.Integer(), nullable=True), | ||||
|                     sa.Column('donor_id', sa.Integer(), nullable=True), | ||||
|                     sa.Column('donor_external_id', sa.String(length=50), nullable=True), | ||||
|                     sa.Column('email', sa.String(length=255), nullable=True), | ||||
|                     sa.Column('amount', sa.Numeric(precision=10, scale=2), nullable=True), | ||||
|                     sa.Column('payment_type_name', sa.String(length=100), nullable=True), | ||||
|                     sa.Column('check_number', sa.String(length=255), nullable=True), | ||||
|                     sa.Column('tracking_code_slug', sa.String(length=255), nullable=True), | ||||
|                     sa.Column('note', sa.Text(), nullable=True), | ||||
|                     sa.Column('created_at', sa.DateTime(), nullable=True), | ||||
|                     sa.Column('succeeded_at', sa.DateTime(), nullable=True), | ||||
|                     sa.Column('failed_at', sa.DateTime(), nullable=True), | ||||
|                     sa.Column('canceled_at', sa.DateTime(), nullable=True), | ||||
|                     sa.Column('updated_at', sa.DateTime(), nullable=True), | ||||
|                     sa.Column('transaction_id', sa.BigInteger(), autoincrement=False, nullable=False), | ||||
|                     sa.Column('end_transaction_id', sa.BigInteger(), nullable=True), | ||||
|                     sa.Column('operation_type', sa.SmallInteger(), nullable=False), | ||||
|                     sa.PrimaryKeyConstraint('uuid', 'transaction_id') | ||||
|                     ) | ||||
|     op.create_index(op.f('ix_nationbuilder_cache_donation_version_end_transaction_id'), 'nationbuilder_cache_donation_version', ['end_transaction_id'], unique=False) | ||||
|     op.create_index(op.f('ix_nationbuilder_cache_donation_version_operation_type'), 'nationbuilder_cache_donation_version', ['operation_type'], unique=False) | ||||
|     op.create_index(op.f('ix_nationbuilder_cache_donation_version_transaction_id'), 'nationbuilder_cache_donation_version', ['transaction_id'], unique=False) | ||||
| 
 | ||||
| 
 | ||||
| def downgrade(): | ||||
| 
 | ||||
|     # nationbuilder_cache_donation | ||||
|     op.drop_index(op.f('ix_nationbuilder_cache_donation_version_transaction_id'), table_name='nationbuilder_cache_donation_version') | ||||
|     op.drop_index(op.f('ix_nationbuilder_cache_donation_version_operation_type'), table_name='nationbuilder_cache_donation_version') | ||||
|     op.drop_index(op.f('ix_nationbuilder_cache_donation_version_end_transaction_id'), table_name='nationbuilder_cache_donation_version') | ||||
|     op.drop_table('nationbuilder_cache_donation_version') | ||||
|     op.drop_table('nationbuilder_cache_donation') | ||||
|  | @ -24,4 +24,4 @@ | |||
| DB schema for NationBuilder integration | ||||
| """ | ||||
| 
 | ||||
| from .nationbuilder import NationBuilderCachePerson | ||||
| from .nationbuilder import NationBuilderCachePerson, NationBuilderCacheDonation | ||||
|  |  | |||
|  | @ -79,3 +79,37 @@ class NationBuilderCachePerson(model.Base): | |||
|                 if value == tag: | ||||
|                     return True | ||||
|         return False | ||||
| 
 | ||||
| 
 | ||||
| class NationBuilderCacheDonation(model.Base): | ||||
|     """ | ||||
|     Represents a Donation record in NationBuilder. | ||||
| 
 | ||||
|     https://apiexplorer.nationbuilder.com/nationbuilder#Donations | ||||
|     """ | ||||
|     __tablename__ = 'nationbuilder_cache_donation' | ||||
|     __table_args__ = ( | ||||
|         sa.UniqueConstraint('id', name='nationbuilder_cache_donation_uq_id'), | ||||
|     ) | ||||
|     __versioned__ = {} | ||||
|     model_title = "NationBuilder Donation" | ||||
|     model_title_plural = "NationBuilder Donations" | ||||
| 
 | ||||
|     uuid = model.uuid_column() | ||||
| 
 | ||||
|     id = sa.Column(sa.Integer(), nullable=False) | ||||
|     author_id = sa.Column(sa.Integer(), nullable=True) | ||||
|     membership_id = sa.Column(sa.Integer(), nullable=True) | ||||
|     donor_id = sa.Column(sa.Integer(), nullable=True) | ||||
|     donor_external_id = sa.Column(sa.String(length=50), nullable=True) | ||||
|     email = sa.Column(sa.String(length=255), nullable=True) | ||||
|     amount = sa.Column(sa.Numeric(precision=10, scale=2), nullable=True) | ||||
|     payment_type_name = sa.Column(sa.String(length=100), nullable=True) | ||||
|     check_number = sa.Column(sa.String(length=255), nullable=True) | ||||
|     tracking_code_slug = sa.Column(sa.String(length=255), nullable=True) | ||||
|     note = sa.Column(sa.Text(), nullable=True) | ||||
|     created_at = sa.Column(sa.DateTime(), nullable=True) | ||||
|     succeeded_at = sa.Column(sa.DateTime(), nullable=True) | ||||
|     failed_at = sa.Column(sa.DateTime(), nullable=True) | ||||
|     canceled_at = sa.Column(sa.DateTime(), nullable=True) | ||||
|     updated_at = sa.Column(sa.DateTime(), nullable=True) | ||||
|  |  | |||
|  | @ -34,3 +34,6 @@ from rattail_nationbuilder.db import model | |||
| 
 | ||||
| class NationBuilderCachePersonImporter(ToRattail): | ||||
|     model_class = model.NationBuilderCachePerson | ||||
| 
 | ||||
| class NationBuilderCacheDonationImporter(ToRattail): | ||||
|     model_class = model.NationBuilderCacheDonation | ||||
|  |  | |||
|  | @ -25,6 +25,7 @@ NationBuilder -> Rattail importing | |||
| """ | ||||
| 
 | ||||
| import datetime | ||||
| import decimal | ||||
| from collections import OrderedDict | ||||
| 
 | ||||
| from rattail import importing | ||||
|  | @ -43,6 +44,7 @@ class FromNationBuilderToRattail(importing.ToRattailHandler): | |||
|     def get_importers(self): | ||||
|         importers = OrderedDict() | ||||
|         importers['NationBuilderCachePerson'] = NationBuilderCachePersonImporter | ||||
|         importers['NationBuilderCacheDonation'] = NationBuilderCacheDonationImporter | ||||
|         return importers | ||||
| 
 | ||||
| 
 | ||||
|  | @ -58,6 +60,14 @@ class FromNationBuilder(importing.Importer): | |||
|     def setup_api(self): | ||||
|         self.nationbuilder = NationBuilderWebAPI(self.config) | ||||
| 
 | ||||
|     def normalize_timestamp(self, value): | ||||
|         if not value: | ||||
|             return | ||||
| 
 | ||||
|         dt = datetime.datetime.strptime(value, '%Y-%m-%dT%H:%M:%S%z') | ||||
|         dt = self.app.localtime(dt) | ||||
|         return self.app.make_utc(dt) | ||||
| 
 | ||||
| 
 | ||||
| class NationBuilderCachePersonImporter(FromNationBuilder, nationbuilder_importing.model.NationBuilderCachePersonImporter): | ||||
|     """ | ||||
|  | @ -95,14 +105,6 @@ class NationBuilderCachePersonImporter(FromNationBuilder, nationbuilder_importin | |||
|     def get_host_objects(self): | ||||
|         return self.nationbuilder.get_people(page_size=500) | ||||
| 
 | ||||
|     def normalize_timestamp(self, value): | ||||
|         if not value: | ||||
|             return | ||||
| 
 | ||||
|         dt = datetime.datetime.strptime(value, '%Y-%m-%dT%H:%M:%S%z') | ||||
|         dt = self.app.localtime(dt) | ||||
|         return self.app.make_utc(dt) | ||||
| 
 | ||||
|     def normalize_host_object(self, person): | ||||
| 
 | ||||
|         # nb. some fields may not be present in person dict | ||||
|  | @ -130,3 +132,48 @@ class NationBuilderCachePersonImporter(FromNationBuilder, nationbuilder_importin | |||
|                     }) | ||||
| 
 | ||||
|             return data | ||||
| 
 | ||||
| 
 | ||||
| class NationBuilderCacheDonationImporter(FromNationBuilder, nationbuilder_importing.model.NationBuilderCacheDonationImporter): | ||||
|     """ | ||||
|     Importer for NB Donation cache | ||||
|     """ | ||||
|     key = 'id' | ||||
|     supported_fields = [ | ||||
|         'id', | ||||
|         'author_id', | ||||
|         'membership_id', | ||||
|         'donor_id', | ||||
|         'donor_external_id', | ||||
|         'email', | ||||
|         'amount', | ||||
|         'payment_type_name', | ||||
|         'check_number', | ||||
|         'tracking_code_slug', | ||||
|         'note', | ||||
|         'created_at', | ||||
|         'succeeded_at', | ||||
|         'failed_at', | ||||
|         'canceled_at', | ||||
|         'updated_at', | ||||
|     ] | ||||
| 
 | ||||
|     def get_host_objects(self): | ||||
|         return self.nationbuilder.get_donations(page_size=500) | ||||
| 
 | ||||
|     def normalize_host_object(self, donation): | ||||
| 
 | ||||
|         # nb. some fields may not be present in donation dict | ||||
|         data = dict([(field, donation.get(field)) | ||||
|                      for field in self.fields]) | ||||
|         if data: | ||||
| 
 | ||||
|             donor = donation.get('donor') | ||||
|             data['donor_external_id'] = donor.get('external_id') if donor else None | ||||
| 
 | ||||
|             data['amount'] = decimal.Decimal('{:0.2f}'.format(donation['amount_in_cents'] / 100)) | ||||
| 
 | ||||
|             for field in ('created_at', 'succeeded_at', 'failed_at', 'canceled_at', 'updated_at'): | ||||
|                 data[field] = self.normalize_timestamp(data[field]) | ||||
| 
 | ||||
|             return data | ||||
|  |  | |||
|  | @ -31,6 +31,7 @@ class NationBuilderVersionMixin(object): | |||
| 
 | ||||
|     def add_nationbuilder_importers(self, importers): | ||||
|         importers['NationBuilderCachePerson'] = NationBuilderCachePersonImporter | ||||
|         importers['NationBuilderCacheDonation'] = NationBuilderCacheDonationImporter | ||||
|         return importers | ||||
| 
 | ||||
| 
 | ||||
|  | @ -39,3 +40,10 @@ class NationBuilderCachePersonImporter(base.VersionImporter): | |||
|     @property | ||||
|     def host_model_class(self): | ||||
|         return self.model.NationBuilderCachePerson | ||||
| 
 | ||||
| 
 | ||||
| class NationBuilderCacheDonationImporter(base.VersionImporter): | ||||
| 
 | ||||
|     @property | ||||
|     def host_model_class(self): | ||||
|         return self.model.NationBuilderCacheDonation | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Lance Edgar
						Lance Edgar