um..a bunch more changes (savepoint)

This commit is contained in:
Lance Edgar 2012-11-21 10:07:43 -08:00
parent d8b8a7852b
commit 88fc224abc
7 changed files with 650 additions and 152 deletions

View file

@ -50,14 +50,27 @@ class ContactInfoInline(admin.TabularInline):
extra = 0 extra = 0
class PartyInline(admin.TabularInline):
"""
Base inline manager for all party models.
"""
exclude = ('uuid', 'parent_type')
extra = 0
class PersonPhoneNumberInline(ContactInfoInline): class PersonPhoneNumberInline(ContactInfoInline):
model = PersonPhoneNumber model = PersonPhoneNumber
class PersonEmailAddressInline(ContactInfoInline): class PersonEmailAddressInline(ContactInfoInline):
model = PersonEmailAddress model = PersonEmailAddress
class PersonPostalAddressInline(ContactInfoInline):
model = PersonPostalAddress
class PersonAdmin(ModelAdmin): class PersonAdmin(ModelAdmin):
inlines = [PersonPhoneNumberInline, PersonEmailAddressInline] inlines = [PersonPhoneNumberInline, PersonEmailAddressInline,
PersonPostalAddressInline]
def get_formsets(self, request, obj=None): def get_formsets(self, request, obj=None):
for inline in self.get_inline_instances(request): for inline in self.get_inline_instances(request):
@ -97,8 +110,12 @@ class StorePhoneNumberInline(ContactInfoInline):
class StoreEmailAddressInline(ContactInfoInline): class StoreEmailAddressInline(ContactInfoInline):
model = StoreEmailAddress model = StoreEmailAddress
class StorePostalAddressInline(ContactInfoInline):
model = StorePostalAddress
class StoreAdmin(ModelAdmin): class StoreAdmin(ModelAdmin):
inlines = [StorePhoneNumberInline, StoreEmailAddressInline] inlines = [StorePhoneNumberInline, StoreEmailAddressInline,
StorePostalAddressInline]
def get_formsets(self, request, obj=None): def get_formsets(self, request, obj=None):
for inline in self.get_inline_instances(request): for inline in self.get_inline_instances(request):
@ -127,22 +144,21 @@ class VendorPhoneNumberInline(ContactInfoInline):
class VendorEmailAddressInline(ContactInfoInline): class VendorEmailAddressInline(ContactInfoInline):
model = VendorEmailAddress model = VendorEmailAddress
class VendorContactInline(admin.TabularInline): class VendorPostalAddressInline(ContactInfoInline):
model = VendorContact model = VendorPostalAddress
verbose_name = "Contact"
verbose_name_plural = "Contacts" class VendorPartyInline(PartyInline):
exclude = ('uuid',) model = VendorParty
extra = 0
class VendorAdmin(ModelAdmin): class VendorAdmin(ModelAdmin):
inlines = [VendorPhoneNumberInline, VendorEmailAddressInline, inlines = [VendorPhoneNumberInline, VendorEmailAddressInline,
VendorContactInline] VendorPostalAddressInline, VendorPartyInline]
def get_formsets(self, request, obj=None): def get_formsets(self, request, obj=None):
for inline in self.get_inline_instances(request): for inline in self.get_inline_instances(request):
if isinstance(inline, ContactInfoInline) and obj is None: if isinstance(inline, ContactInfoInline) and obj is None:
continue continue
if isinstance(inline, VendorContactInline) and obj is None: if isinstance(inline, PartyInline) and obj is None:
continue continue
yield inline.get_formset(request, obj) yield inline.get_formset(request, obj)
@ -188,22 +204,7 @@ class ProductAdmin(ModelAdmin):
admin.site.register(Product, ProductAdmin) admin.site.register(Product, ProductAdmin)
class EmployeePhoneNumberInline(ContactInfoInline): admin.site.register(Employee, ModelAdmin)
model = EmployeePhoneNumber
class EmployeeEmailAddressInline(ContactInfoInline):
model = EmployeeEmailAddress
class EmployeeAdmin(ModelAdmin):
inlines = [EmployeePhoneNumberInline, EmployeeEmailAddressInline]
def get_formsets(self, request, obj=None):
for inline in self.get_inline_instances(request):
if isinstance(inline, ContactInfoInline) and obj is None:
continue
yield inline.get_formset(request, obj)
admin.site.register(Employee, EmployeeAdmin)
admin.site.register(CustomerGroup, ModelAdmin) admin.site.register(CustomerGroup, ModelAdmin)
@ -215,6 +216,9 @@ class CustomerPhoneNumberInline(ContactInfoInline):
class CustomerEmailAddressInline(ContactInfoInline): class CustomerEmailAddressInline(ContactInfoInline):
model = CustomerEmailAddress model = CustomerEmailAddress
class CustomerPostalAddressInline(ContactInfoInline):
model = CustomerPostalAddress
class CustomerGroupAssignmentInline(admin.TabularInline): class CustomerGroupAssignmentInline(admin.TabularInline):
model = CustomerGroupAssignment model = CustomerGroupAssignment
verbose_name = "Group Assignment" verbose_name = "Group Assignment"
@ -222,9 +226,13 @@ class CustomerGroupAssignmentInline(admin.TabularInline):
exclude = ('uuid',) exclude = ('uuid',)
extra = 0 extra = 0
class CustomerPartyInline(PartyInline):
model = CustomerParty
class CustomerAdmin(ModelAdmin): class CustomerAdmin(ModelAdmin):
inlines = [CustomerPhoneNumberInline, CustomerEmailAddressInline, inlines = [CustomerPhoneNumberInline, CustomerEmailAddressInline,
CustomerGroupAssignmentInline] CustomerPostalAddressInline, CustomerGroupAssignmentInline,
CustomerPartyInline]
def get_formsets(self, request, obj=None): def get_formsets(self, request, obj=None):
for inline in self.get_inline_instances(request): for inline in self.get_inline_instances(request):
@ -232,6 +240,8 @@ class CustomerAdmin(ModelAdmin):
continue continue
if isinstance(inline, CustomerGroupAssignmentInline) and obj is None: if isinstance(inline, CustomerGroupAssignmentInline) and obj is None:
continue continue
if isinstance(inline, PartyInline) and obj is None:
continue
yield inline.get_formset(request, obj) yield inline.get_formset(request, obj)
admin.site.register(Customer, CustomerAdmin) admin.site.register(Customer, CustomerAdmin)

View file

@ -12,8 +12,11 @@ class Migration(SchemaMigration):
db.create_table('rattail_people', ( db.create_table('rattail_people', (
('uuid', self.gf('rattail.django.rattail.models.core.UUIDField')(max_length=32, primary_key=True)), ('uuid', self.gf('rattail.django.rattail.models.core.UUIDField')(max_length=32, primary_key=True)),
('first_name', self.gf('django.db.models.fields.CharField')(max_length=50, null=True, blank=True)), ('first_name', self.gf('django.db.models.fields.CharField')(max_length=50, null=True, blank=True)),
('middle_name', self.gf('django.db.models.fields.CharField')(max_length=50, null=True, blank=True)),
('last_name', self.gf('django.db.models.fields.CharField')(max_length=50, null=True, blank=True)), ('last_name', self.gf('django.db.models.fields.CharField')(max_length=50, null=True, blank=True)),
('display_name', self.gf('django.db.models.fields.CharField')(max_length=100, null=True, blank=True)), ('display_name', self.gf('django.db.models.fields.CharField')(max_length=100, null=True, blank=True)),
('driver_license_state', self.gf('django.db.models.fields.CharField')(max_length=4, null=True, blank=True)),
('driver_license_number', self.gf('django.db.models.fields.CharField')(max_length=20, null=True, blank=True)),
)) ))
db.send_create_signal('rattail', ['Person']) db.send_create_signal('rattail', ['Person'])
@ -22,7 +25,7 @@ class Migration(SchemaMigration):
('uuid', self.gf('rattail.django.rattail.models.core.UUIDField')(max_length=32, primary_key=True)), ('uuid', self.gf('rattail.django.rattail.models.core.UUIDField')(max_length=32, primary_key=True)),
('parent_type', self.gf('django.db.models.fields.CharField')(max_length=20)), ('parent_type', self.gf('django.db.models.fields.CharField')(max_length=20)),
('parent_uuid', self.gf('django.db.models.fields.CharField')(max_length=32)), ('parent_uuid', self.gf('django.db.models.fields.CharField')(max_length=32)),
('preference', self.gf('django.db.models.fields.IntegerField')()), ('preference', self.gf('django.db.models.fields.IntegerField')(null=True, blank=True)),
('type', self.gf('django.db.models.fields.CharField')(max_length=15, null=True, blank=True)), ('type', self.gf('django.db.models.fields.CharField')(max_length=15, null=True, blank=True)),
('number', self.gf('django.db.models.fields.CharField')(max_length=20)), ('number', self.gf('django.db.models.fields.CharField')(max_length=20)),
)) ))
@ -33,12 +36,38 @@ class Migration(SchemaMigration):
('uuid', self.gf('rattail.django.rattail.models.core.UUIDField')(max_length=32, primary_key=True)), ('uuid', self.gf('rattail.django.rattail.models.core.UUIDField')(max_length=32, primary_key=True)),
('parent_type', self.gf('django.db.models.fields.CharField')(max_length=20)), ('parent_type', self.gf('django.db.models.fields.CharField')(max_length=20)),
('parent_uuid', self.gf('django.db.models.fields.CharField')(max_length=32)), ('parent_uuid', self.gf('django.db.models.fields.CharField')(max_length=32)),
('preference', self.gf('django.db.models.fields.IntegerField')()), ('preference', self.gf('django.db.models.fields.IntegerField')(null=True, blank=True)),
('type', self.gf('django.db.models.fields.CharField')(max_length=15, null=True, blank=True)), ('type', self.gf('django.db.models.fields.CharField')(max_length=15, null=True, blank=True)),
('address', self.gf('django.db.models.fields.CharField')(max_length=255)), ('address', self.gf('django.db.models.fields.CharField')(max_length=255)),
)) ))
db.send_create_signal('rattail', ['EmailAddress']) db.send_create_signal('rattail', ['EmailAddress'])
# Adding model 'PostalAddress'
db.create_table('rattail_postal_addresses', (
('uuid', self.gf('rattail.django.rattail.models.core.UUIDField')(max_length=32, primary_key=True)),
('parent_type', self.gf('django.db.models.fields.CharField')(max_length=20)),
('parent_uuid', self.gf('django.db.models.fields.CharField')(max_length=32)),
('preference', self.gf('django.db.models.fields.IntegerField')(null=True, blank=True)),
('type', self.gf('django.db.models.fields.CharField')(max_length=15, null=True, blank=True)),
('street', self.gf('django.db.models.fields.CharField')(max_length=100, null=True, blank=True)),
('street2', self.gf('django.db.models.fields.CharField')(max_length=100, null=True, blank=True)),
('city', self.gf('django.db.models.fields.CharField')(max_length=100, null=True, blank=True)),
('state', self.gf('django.db.models.fields.CharField')(max_length=2, null=True, blank=True)),
('zipcode', self.gf('django.db.models.fields.CharField')(max_length=10, null=True, blank=True)),
))
db.send_create_signal('rattail', ['PostalAddress'])
# Adding model 'Party'
db.create_table('rattail_parties', (
('uuid', self.gf('rattail.django.rattail.models.core.UUIDField')(max_length=32, primary_key=True)),
('parent_type', self.gf('django.db.models.fields.CharField')(max_length=20)),
('parent_uuid', self.gf('django.db.models.fields.CharField')(max_length=32)),
('person', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['rattail.Person'], db_column='person_uuid')),
('type', self.gf('django.db.models.fields.CharField')(max_length=25, null=True, blank=True)),
('preference', self.gf('django.db.models.fields.IntegerField')(null=True, blank=True)),
))
db.send_create_signal('rattail', ['Party'])
# Adding model 'Role' # Adding model 'Role'
db.create_table('rattail_roles', ( db.create_table('rattail_roles', (
('uuid', self.gf('rattail.django.rattail.models.core.UUIDField')(max_length=32, primary_key=True)), ('uuid', self.gf('rattail.django.rattail.models.core.UUIDField')(max_length=32, primary_key=True)),
@ -114,15 +143,6 @@ class Migration(SchemaMigration):
)) ))
db.send_create_signal('rattail', ['Vendor']) db.send_create_signal('rattail', ['Vendor'])
# Adding model 'VendorContact'
db.create_table('rattail_vendor_contacts', (
('uuid', self.gf('rattail.django.rattail.models.core.UUIDField')(max_length=32, primary_key=True)),
('vendor', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['rattail.Vendor'], db_column='vendor_uuid')),
('person', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['rattail.Person'], db_column='person_uuid')),
('preference', self.gf('django.db.models.fields.IntegerField')()),
))
db.send_create_signal('rattail', ['VendorContact'])
# Adding model 'Product' # Adding model 'Product'
db.create_table('rattail_products', ( db.create_table('rattail_products', (
('uuid', self.gf('rattail.django.rattail.models.core.UUIDField')(max_length=32, primary_key=True)), ('uuid', self.gf('rattail.django.rattail.models.core.UUIDField')(max_length=32, primary_key=True)),
@ -174,9 +194,9 @@ class Migration(SchemaMigration):
# Adding model 'Employee' # Adding model 'Employee'
db.create_table('rattail_employees', ( db.create_table('rattail_employees', (
('uuid', self.gf('rattail.django.rattail.models.core.UUIDField')(max_length=32, primary_key=True)), ('uuid', self.gf('rattail.django.rattail.models.core.UUIDField')(max_length=32, primary_key=True)),
('id', self.gf('django.db.models.fields.IntegerField')(null=True, blank=True)), ('id', self.gf('django.db.models.fields.CharField')(max_length=20, null=True, blank=True)),
('person', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['rattail.Person'], db_column='person_uuid')), ('person', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['rattail.Person'], db_column='person_uuid')),
('status', self.gf('django.db.models.fields.IntegerField')()), ('status', self.gf('django.db.models.fields.IntegerField')(null=True, blank=True)),
('display_name', self.gf('django.db.models.fields.CharField')(max_length=100, null=True, blank=True)), ('display_name', self.gf('django.db.models.fields.CharField')(max_length=100, null=True, blank=True)),
)) ))
db.send_create_signal('rattail', ['Employee']) db.send_create_signal('rattail', ['Employee'])
@ -190,15 +210,6 @@ class Migration(SchemaMigration):
)) ))
db.send_create_signal('rattail', ['Customer']) db.send_create_signal('rattail', ['Customer'])
# Adding model 'CustomerPerson'
db.create_table('rattail_customers_people', (
('uuid', self.gf('rattail.django.rattail.models.core.UUIDField')(max_length=32, primary_key=True)),
('customer', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['rattail.Customer'], db_column='customer_uuid')),
('person', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['rattail.Person'], db_column='person_uuid')),
('ordinal', self.gf('django.db.models.fields.IntegerField')()),
))
db.send_create_signal('rattail', ['CustomerPerson'])
# Adding model 'CustomerGroup' # Adding model 'CustomerGroup'
db.create_table('rattail_customer_groups', ( db.create_table('rattail_customer_groups', (
('uuid', self.gf('rattail.django.rattail.models.core.UUIDField')(max_length=32, primary_key=True)), ('uuid', self.gf('rattail.django.rattail.models.core.UUIDField')(max_length=32, primary_key=True)),
@ -240,9 +251,6 @@ class Migration(SchemaMigration):
# Deleting model 'CustomerGroup' # Deleting model 'CustomerGroup'
db.delete_table('rattail_customer_groups') db.delete_table('rattail_customer_groups')
# Deleting model 'CustomerPerson'
db.delete_table('rattail_customers_people')
# Deleting model 'Customer' # Deleting model 'Customer'
db.delete_table('rattail_customers') db.delete_table('rattail_customers')
@ -258,9 +266,6 @@ class Migration(SchemaMigration):
# Deleting model 'Product' # Deleting model 'Product'
db.delete_table('rattail_products') db.delete_table('rattail_products')
# Deleting model 'VendorContact'
db.delete_table('rattail_vendor_contacts')
# Deleting model 'Vendor' # Deleting model 'Vendor'
db.delete_table('rattail_vendors') db.delete_table('rattail_vendors')
@ -288,6 +293,12 @@ class Migration(SchemaMigration):
# Deleting model 'Role' # Deleting model 'Role'
db.delete_table('rattail_roles') db.delete_table('rattail_roles')
# Deleting model 'Party'
db.delete_table('rattail_parties')
# Deleting model 'PostalAddress'
db.delete_table('rattail_postal_addresses')
# Deleting model 'EmailAddress' # Deleting model 'EmailAddress'
db.delete_table('rattail_email_addresses') db.delete_table('rattail_email_addresses')
@ -302,7 +313,10 @@ class Migration(SchemaMigration):
'rattail.person': { 'rattail.person': {
'Meta': {'object_name': 'Person', 'db_table': "'rattail_people'"}, 'Meta': {'object_name': 'Person', 'db_table': "'rattail_people'"},
'display_name': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}), 'display_name': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
'driver_license_state': ('django.db.models.fields.CharField', [], {'max_length': '4', 'null': 'True', 'blank': 'True'}),
'driver_license_number': ('django.db.models.fields.CharField', [], {'max_length': '20', 'null': 'True', 'blank': 'True'}),
'first_name': ('django.db.models.fields.CharField', [], {'max_length': '50', 'null': 'True', 'blank': 'True'}), 'first_name': ('django.db.models.fields.CharField', [], {'max_length': '50', 'null': 'True', 'blank': 'True'}),
'middle_name': ('django.db.models.fields.CharField', [], {'max_length': '50', 'null': 'True', 'blank': 'True'}),
'last_name': ('django.db.models.fields.CharField', [], {'max_length': '50', 'null': 'True', 'blank': 'True'}), 'last_name': ('django.db.models.fields.CharField', [], {'max_length': '50', 'null': 'True', 'blank': 'True'}),
'uuid': ('rattail.django.rattail.models.core.UUIDField', [], {'max_length': '32', 'primary_key': 'True'}) 'uuid': ('rattail.django.rattail.models.core.UUIDField', [], {'max_length': '32', 'primary_key': 'True'})
}, },
@ -311,7 +325,7 @@ class Migration(SchemaMigration):
'number': ('django.db.models.fields.CharField', [], {'max_length': '20'}), 'number': ('django.db.models.fields.CharField', [], {'max_length': '20'}),
'parent_type': ('django.db.models.fields.CharField', [], {'max_length': '20'}), 'parent_type': ('django.db.models.fields.CharField', [], {'max_length': '20'}),
'parent_uuid': ('django.db.models.fields.CharField', [], {'max_length': '32'}), 'parent_uuid': ('django.db.models.fields.CharField', [], {'max_length': '32'}),
'preference': ('django.db.models.fields.IntegerField', [], {}), 'preference': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
'type': ('django.db.models.fields.CharField', [], {'max_length': '15', 'null': 'True', 'blank': 'True'}), 'type': ('django.db.models.fields.CharField', [], {'max_length': '15', 'null': 'True', 'blank': 'True'}),
'uuid': ('rattail.django.rattail.models.core.UUIDField', [], {'max_length': '32', 'primary_key': 'True'}) 'uuid': ('rattail.django.rattail.models.core.UUIDField', [], {'max_length': '32', 'primary_key': 'True'})
}, },
@ -320,10 +334,32 @@ class Migration(SchemaMigration):
'address': ('django.db.models.fields.CharField', [], {'max_length': '255'}), 'address': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'parent_type': ('django.db.models.fields.CharField', [], {'max_length': '20'}), 'parent_type': ('django.db.models.fields.CharField', [], {'max_length': '20'}),
'parent_uuid': ('django.db.models.fields.CharField', [], {'max_length': '32'}), 'parent_uuid': ('django.db.models.fields.CharField', [], {'max_length': '32'}),
'preference': ('django.db.models.fields.IntegerField', [], {}), 'preference': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
'type': ('django.db.models.fields.CharField', [], {'max_length': '15', 'null': 'True', 'blank': 'True'}), 'type': ('django.db.models.fields.CharField', [], {'max_length': '15', 'null': 'True', 'blank': 'True'}),
'uuid': ('rattail.django.rattail.models.core.UUIDField', [], {'max_length': '32', 'primary_key': 'True'}) 'uuid': ('rattail.django.rattail.models.core.UUIDField', [], {'max_length': '32', 'primary_key': 'True'})
}, },
'rattail.postaladdress': {
'Meta': {'object_name': 'PostalAddress', 'db_table': "'rattail_postal_addresses'"},
'city': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
'parent_type': ('django.db.models.fields.CharField', [], {'max_length': '20'}),
'parent_uuid': ('django.db.models.fields.CharField', [], {'max_length': '32'}),
'preference': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
'state': ('django.db.models.fields.CharField', [], {'max_length': '2', 'null': 'True', 'blank': 'True'}),
'street': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
'street2': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
'type': ('django.db.models.fields.CharField', [], {'max_length': '15', 'null': 'True', 'blank': 'True'}),
'uuid': ('rattail.django.rattail.models.core.UUIDField', [], {'max_length': '32', 'primary_key': 'True'}),
'zipcode': ('django.db.models.fields.CharField', [], {'max_length': '10', 'null': 'True', 'blank': 'True'})
},
'rattail.party': {
'Meta': {'object_name': 'Party', 'db_table': "'rattail_parties'"},
'parent_type': ('django.db.models.fields.CharField', [], {'max_length': '20'}),
'parent_uuid': ('django.db.models.fields.CharField', [], {'max_length': '32'}),
'person': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['rattail.Person']", 'db_column': "'person_uuid'"}),
'preference': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
'type': ('django.db.models.fields.CharField', [], {'max_length': '25', 'null': 'True', 'blank': 'True'}),
'uuid': ('rattail.django.rattail.models.core.UUIDField', [], {'max_length': '32', 'primary_key': 'True'}),
},
'rattail.role': { 'rattail.role': {
'Meta': {'object_name': 'Role', 'db_table': "'rattail_roles'"}, 'Meta': {'object_name': 'Role', 'db_table': "'rattail_roles'"},
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '25'}), 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '25'}),
@ -381,13 +417,6 @@ class Migration(SchemaMigration):
'special_discount': ('django.db.models.fields.DecimalField', [], {'null': 'True', 'max_digits': '5', 'decimal_places': '3', 'blank': 'True'}), 'special_discount': ('django.db.models.fields.DecimalField', [], {'null': 'True', 'max_digits': '5', 'decimal_places': '3', 'blank': 'True'}),
'uuid': ('rattail.django.rattail.models.core.UUIDField', [], {'max_length': '32', 'primary_key': 'True'}) 'uuid': ('rattail.django.rattail.models.core.UUIDField', [], {'max_length': '32', 'primary_key': 'True'})
}, },
'rattail.vendorcontact': {
'Meta': {'object_name': 'VendorContact', 'db_table': "'rattail_vendor_contacts'"},
'person': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['rattail.Person']", 'db_column': "'person_uuid'"}),
'preference': ('django.db.models.fields.IntegerField', [], {}),
'uuid': ('rattail.django.rattail.models.core.UUIDField', [], {'max_length': '32', 'primary_key': 'True'}),
'vendor': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['rattail.Vendor']", 'db_column': "'vendor_uuid'"})
},
'rattail.product': { 'rattail.product': {
'Meta': {'object_name': 'Product', 'db_table': "'rattail_products'"}, 'Meta': {'object_name': 'Product', 'db_table': "'rattail_products'"},
'brand': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['rattail.Brand']", 'null': 'True', 'db_column': "'brand_uuid'", 'blank': 'True'}), 'brand': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['rattail.Brand']", 'null': 'True', 'db_column': "'brand_uuid'", 'blank': 'True'}),
@ -433,9 +462,9 @@ class Migration(SchemaMigration):
'rattail.employee': { 'rattail.employee': {
'Meta': {'object_name': 'Employee', 'db_table': "'rattail_employees'"}, 'Meta': {'object_name': 'Employee', 'db_table': "'rattail_employees'"},
'display_name': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}), 'display_name': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
'id': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}), 'id': ('django.db.models.fields.CharField', [], {'max_length': '20', 'null': 'True', 'blank': 'True'}),
'person': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['rattail.Person']", 'db_column': "'person_uuid'"}), 'person': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['rattail.Person']", 'db_column': "'person_uuid'"}),
'status': ('django.db.models.fields.IntegerField', [], {}), 'status': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
'uuid': ('rattail.django.rattail.models.core.UUIDField', [], {'max_length': '32', 'primary_key': 'True'}) 'uuid': ('rattail.django.rattail.models.core.UUIDField', [], {'max_length': '32', 'primary_key': 'True'})
}, },
'rattail.customer': { 'rattail.customer': {
@ -445,13 +474,6 @@ class Migration(SchemaMigration):
'name': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}), 'name': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
'uuid': ('rattail.django.rattail.models.core.UUIDField', [], {'max_length': '32', 'primary_key': 'True'}) 'uuid': ('rattail.django.rattail.models.core.UUIDField', [], {'max_length': '32', 'primary_key': 'True'})
}, },
'rattail.customerperson': {
'Meta': {'object_name': 'CustomerPerson', 'db_table': "'rattail_customers_people'"},
'customer': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['rattail.Customer']", 'db_column': "'customer_uuid'"}),
'ordinal': ('django.db.models.fields.IntegerField', [], {}),
'person': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['rattail.Person']", 'db_column': "'person_uuid'"}),
'uuid': ('rattail.django.rattail.models.core.UUIDField', [], {'max_length': '32', 'primary_key': 'True'})
},
'rattail.customergroup': { 'rattail.customergroup': {
'Meta': {'object_name': 'CustomerGroup', 'db_table': "'rattail_customer_groups'"}, 'Meta': {'object_name': 'CustomerGroup', 'db_table': "'rattail_customer_groups'"},
'id': ('django.db.models.fields.CharField', [], {'max_length': '20', 'null': 'True', 'blank': 'True'}), 'id': ('django.db.models.fields.CharField', [], {'max_length': '20', 'null': 'True', 'blank': 'True'}),

View file

@ -29,12 +29,14 @@
from __future__ import absolute_import from __future__ import absolute_import
from django.db import models from django.db import models
from django.core.exceptions import ObjectDoesNotExist
from rattail.django.rattail.models import Model, uuid_field from rattail.django.rattail.models import Model, uuid_field
__all__ = ['PhoneNumber', 'EmailAddress', __all__ = ['Contact', 'PhoneNumber', 'EmailAddress', 'PostalAddress',
'Person', 'PersonPhoneNumber', 'PersonEmailAddress'] 'Person', 'PersonPhoneNumber', 'PersonEmailAddress', 'PersonPostalAddress',
'Party']
class ContactInfoManager(models.Manager): class ContactInfoManager(models.Manager):
@ -57,7 +59,7 @@ class ContactInfo(Model):
uuid = uuid_field() uuid = uuid_field()
parent_type = models.CharField(max_length=20) parent_type = models.CharField(max_length=20)
preference = models.IntegerField() preference = models.IntegerField(blank=True, null=True)
type = models.CharField(max_length=15, blank=True, null=True) type = models.CharField(max_length=15, blank=True, null=True)
@ -101,20 +103,223 @@ class EmailAddress(ContactInfo):
return unicode(self.address) return unicode(self.address)
class Person(Model): class PostalAddress(ContactInfo):
"""
Represents a postal (mailing) address associated with a contactable entity.
"""
class Meta(ContactInfo.Meta):
abstract = True
db_table = ContactInfo.prefix('postal_addresses')
verbose_name = "Postal Address"
verbose_name_plural = "Postal Addresses"
street = models.CharField(max_length=100, blank=True, null=True)
street2 = models.CharField(max_length=100, blank=True, null=True)
city = models.CharField(max_length=100, blank=True, null=True)
state = models.CharField(max_length=2, blank=True, null=True)
zipcode = models.CharField(max_length=10, blank=True, null=True)
def __repr__(self):
return "<%s: %s>" % (self.__class__.__name__, self.street)
def __unicode__(self):
return unicode(self.street)
class Contact(Model):
"""
Base class for models which may be associated with contact info data.
This class exists only to define convenience methods and properties on the
derived class.
"""
class Meta(Model.Meta):
abstract = True
def __init__(self, *args, **kwargs):
super(Contact, self).__init__(*args, **kwargs)
self._phones = {}
self._emails = {}
self._addresses = {}
self._preferred = {}
def _translate_info_class(self, class_):
from rattail.django.rattail import models
class_name = self.__class__.__name__ + class_.__name__
if hasattr(models, class_name):
class_ = getattr(models, class_name)
return class_
def _filter_queryset(self, qs):
parent = self.__class__.__name__.lower()
kwargs = {parent: self}
return qs.filter(**kwargs)
def _assign_parent(self, info):
parent = self.__class__.__name__.lower()
setattr(info, parent, self)
def _get_info_dict(self, class_):
if issubclass(class_, PhoneNumber):
return self._phones
elif issubclass(class_, EmailAddress):
return self._emails
elif issubclass(class_, PostalAddress):
return self._addresses
raise ValueError("Expected a subclass of ContactInfo; got %s" % class_.__name__)
def _get_info_key(self, class_):
if issubclass(class_, PhoneNumber):
return 'phone'
elif issubclass(class_, EmailAddress):
return 'email'
elif issubclass(class_, PostalAddress):
return 'address'
raise ValueError("Expected a subclass of ContactInfo; got %s" % class_.__name__)
def _get_info(self, class_, type, info_dict=None):
class_ = self._translate_info_class(class_)
if info_dict is None:
info_dict = self._get_info_dict(class_)
if type not in info_dict:
qs = class_.objects
qs = self._filter_queryset(qs)
qs = qs.filter(type=type)
try:
info = qs.get()
except ObjectDoesNotExist:
info = None
info_dict[type] = info
return info_dict[type]
def get_phone(self, type):
return self._get_info(PhoneNumber, type)
def get_email(self, type):
return self._get_info(EmailAddress, type)
def get_address(self, type):
return self._get_info(PostalAddress, type)
def _update_info(self, class_, type, data):
class_ = self._translate_info_class(class_)
info_dict = self._get_info_dict(class_)
info = self._get_info(class_, type, info_dict)
# Check data for values; if none exist then we'll delete the info.
values = False
for value in data.itervalues():
if value:
values = True
break
if values:
if not info:
info = class_()
self._assign_parent(info)
info.type = type
info_dict[type] = info
for key, value in data.iteritems():
setattr(info, key, value)
info.save()
return info
if info:
info.delete()
info_dict[type] = None
return None
def update_phone(self, type, data):
return self._update_info(PhoneNumber, type, data)
def update_email(self, type, data):
return self._update_info(EmailAddress, type, data)
def update_address(self, type, data):
return self._update_info(PostalAddress, type, data)
def _get_preferred_info(self, class_):
class_ = self._translate_info_class(class_)
info_key = self._get_info_key(class_)
if info_key not in self._preferred:
qs = class_.objects
qs = self._filter_queryset(qs)
qs = qs.filter(preference=1)
try:
info = qs.get()
except ObjectDoesNotExist:
info = None
self._preferred[info_key] = info
return self._preferred[info_key]
def get_preferred_phone(self):
return self._get_preferred_info(PhoneNumber)
def get_preferred_email(self):
return self._get_preferred_info(EmailAddress)
def get_preferred_address(self):
return self._get_preferred_info(PostalAddress)
@property
def phone(self):
return self.get_preferred_phone()
@property
def email(self):
return self.get_preferred_email()
@property
def address(self):
return self.get_preferred_address()
def _set_preferred_info(self, class_, info):
class_ = self._translate_info_class(class_)
info_dict = self._get_info_dict(class_)
info_key = self._get_info_key(class_)
if info.preference != 1:
info.preference = 1
info.save()
self._preferred[info_key] = info
preference = 2
for other_info in sorted(info_dict.values(),
key=lambda x: x.preference if x else 999):
if other_info and other_info is not info:
other_info.preference = preference
other_info.save()
preference += 1
def set_preferred_phone(self, phone):
self._set_preferred_info(PhoneNumber, phone)
def set_preferred_email(self, email):
self._set_preferred_info(EmailAddress, email)
def set_preferred_address(self, address):
self._set_preferred_info(PostalAddress, address)
class Person(Contact):
""" """
Represents a real, living and breathing person. (Or, at least was Represents a real, living and breathing person. (Or, at least was
previously living and breathing, in the case of the deceased.) previously living and breathing, in the case of the deceased.)
""" """
class Meta(Model.Meta): class Meta(Contact.Meta):
db_table = Model.prefix('people') db_table = Contact.prefix('people')
verbose_name_plural = "People" verbose_name_plural = "People"
uuid = uuid_field() uuid = uuid_field()
first_name = models.CharField(max_length=50, blank=True, null=True) first_name = models.CharField(max_length=50, blank=True, null=True)
middle_name = models.CharField(max_length=50, blank=True, null=True)
last_name = models.CharField(max_length=50, blank=True, null=True) last_name = models.CharField(max_length=50, blank=True, null=True)
display_name = models.CharField(max_length=100, blank=True, null=True, verbose_name="Display Name") display_name = models.CharField(max_length=100, blank=True, null=True, verbose_name="Display Name")
driver_license_state = models.CharField(max_length=4, blank=True, null=True)
driver_license_number = models.CharField(max_length=20, blank=True, null=True)
def __repr__(self): def __repr__(self):
return "<Person: %s>" % self.display_name return "<Person: %s>" % self.display_name
@ -122,16 +327,51 @@ class Person(Model):
def __unicode__(self): def __unicode__(self):
return unicode(self.display_name or '') return unicode(self.display_name or '')
def update_display_name(self):
orig_display_name = self.display_name
if self.first_name and self.last_name:
self.display_name = self.first_name + ' ' + self.last_name
elif self.first_name:
self.display_name = self.first_name
elif self.last_name:
self.display_name = self.last_name
return self.display_name != orig_display_name
def save(self, *args, **kwargs): def save(self, *args, **kwargs):
if not self.display_name: if not self.display_name:
if self.first_name and self.last_name: self.update_display_name()
self.display_name = self.first_name + ' ' + self.last_name
elif self.first_name:
self.display_name = self.first_name
elif self.last_name:
self.display_name = self.last_name
super(Person, self).save(*args, **kwargs) super(Person, self).save(*args, **kwargs)
_employee = None
@property
def employee(self):
if self._employee is None:
from rattail.django.rattail.models import Employee
qs = Employee.objects
qs = qs.filter(person=self)
try:
self._employee = qs.get()
except ObjectDoesNotExist:
pass
return self._employee
def make_employee(self, **kwargs):
if self.employee:
return
from rattail.django.rattail.models import Employee
employee = Employee(**kwargs)
employee.person = self
employee.save()
self._employee = employee
return employee
def unmake_employee(self):
if self.employee:
self.employee.delete()
self._employee = None
class PersonContactInfo(models.Model): class PersonContactInfo(models.Model):
""" """
@ -141,7 +381,7 @@ class PersonContactInfo(models.Model):
class Meta: class Meta:
abstract = True abstract = True
store = models.ForeignKey(Person, db_column='parent_uuid') person = models.ForeignKey(Person, db_column='parent_uuid')
objects = ContactInfoManager('Person') objects = ContactInfoManager('Person')
def save(self, *args, **kwargs): def save(self, *args, **kwargs):
@ -159,3 +399,44 @@ class PersonEmailAddress(EmailAddress, PersonContactInfo):
""" """
Represents an email address associated with a :class:`Person`. Represents an email address associated with a :class:`Person`.
""" """
class PersonPostalAddress(PostalAddress, PersonContactInfo):
"""
Represents a postal (mailing) address associated with a :class:`Person`.
"""
class PartyManager(models.Manager):
def __init__(self, parent_type):
super(PartyManager, self).__init__()
self.parent_type = parent_type
def get_query_set(self):
qs = super(PartyManager, self).get_query_set()
qs = qs.filter(parent_type=self.parent_type)
qs = qs.order_by('preference')
return qs
class Party(Model):
"""
Base class for "party" relationships, e.g. sales contacts for vendors and
authorized shoppers for customers.
"""
class Meta(Model.Meta):
abstract = True
db_table = Model.prefix('parties')
verbose_name = "Party"
verbose_name_plural = "Parties"
uuid = uuid_field()
parent_type = models.CharField(max_length=20)
person = models.ForeignKey(Person, db_column='person_uuid')
type = models.CharField(max_length=25, blank=True, null=True)
preference = models.IntegerField(blank=True, null=True)
def __unicode__(self):
return u'%s (%s)' % (self.person, self.type)

View file

@ -32,7 +32,7 @@ from django.conf import settings
import edbob import edbob
__all__ = ['Model', 'uuid_field'] __all__ = ['Model', 'uuid_field', 'ProxyModel', 'PersonProxyModel']
class Model(models.Model): class Model(models.Model):
@ -61,6 +61,80 @@ class Model(models.Model):
return table_name return table_name
class ProxyModel(models.Model):
"""
Base class for models which intend to "proxy" certain attributes to an
underlying Rattail model. This is designed for use in apps which use
Rattail as their primary schema but need to extend it in some way.
"""
class Meta:
abstract = True
_proxy_attribute_map = {}
def __getattr__(self, name):
for proxy, attrs in self.__class__._proxy_attribute_map.iteritems():
for attr in attrs:
if isinstance(attr, tuple):
convenient, actual = attr
else:
convenient = actual = attr
if convenient == name:
return getattr(getattr(self, proxy), actual)
return super(ProxyModel, self).__getattr__(name)
def __setattr__(self, name, value):
for proxy, attrs in self.__class__._proxy_attribute_map.iteritems():
for attr in attrs:
if isinstance(attr, tuple):
convenient, actual = attr
else:
convenient = actual = attr
if convenient == name:
print 'setting %s.%s.%s (via %s) to %s' % (
self.__class__.__name__, proxy, actual, convenient, repr(value))
return setattr(getattr(self, proxy), actual, value)
return super(ProxyModel, self).__setattr__(name, value)
class PersonProxyModel(ProxyModel):
"""
Proxy model specific to :class:`rattail.django.rattail.models.Person`.
"""
class Meta(ProxyModel.Meta):
abstract = True
_proxy_person = 'person'
def __init__(self, *args, **kwargs):
self._proxy_attribute_map[self._proxy_person] = [
'first_name',
'middle_name',
'last_name',
'driver_license_number',
'driver_license_state',
'address',
'update_address',
'set_preferred_address',
'phone',
'get_phone',
'update_phone',
'set_preferred_phone',
'email',
'update_email',
'set_preferred_email',
'make_employee',
'unmake_employee',
]
super(PersonProxyModel, self).__init__(*args, **kwargs)
def save(self, **kwargs):
getattr(self, self._proxy_person).save(**kwargs)
super(PersonProxyModel, self).save(**kwargs)
class UUIDField(models.CharField): class UUIDField(models.CharField):
""" """
"Custom" type for UUID fields. This is actually only necessary so that the "Custom" type for UUID fields. This is actually only necessary so that the

View file

@ -29,6 +29,7 @@
from __future__ import absolute_import from __future__ import absolute_import
from django.db import models from django.db import models
from django.core.exceptions import ObjectDoesNotExist
from edbob.db.extensions.contact.enum import EMAIL_PREFERENCE from edbob.db.extensions.contact.enum import EMAIL_PREFERENCE
@ -38,17 +39,18 @@ from rattail.db.extension.enum import EMPLOYEE_STATUS
from rattail.django.rattail.models import Model, uuid_field from rattail.django.rattail.models import Model, uuid_field
from rattail.django.rattail.models.contact import ( from rattail.django.rattail.models.contact import (
ContactInfoManager, PhoneNumber, EmailAddress) ContactInfoManager, PhoneNumber, EmailAddress, PostalAddress,
PartyManager, Party, Person)
from rattail.django.util import enum_to_choices from rattail.django.util import enum_to_choices
__all__ = ['Store', 'StorePhoneNumber', 'StoreEmailAddress', __all__ = ['Store', 'StorePhoneNumber', 'StoreEmailAddress', 'StorePostalAddress',
'Department', 'Subdepartment', 'Category', 'Brand', 'Department', 'Subdepartment', 'Category', 'Brand',
'Vendor', 'VendorPhoneNumber', 'VendorEmailAddress', 'VendorContact', 'Vendor', 'VendorPhoneNumber', 'VendorEmailAddress', 'VendorPostalAddress', 'VendorParty',
'Product', 'ProductPrice', 'ProductCost', 'Product', 'ProductPrice', 'ProductCost',
'Employee', 'EmployeePhoneNumber', 'EmployeeEmailAddress', 'Employee',
'Customer', 'CustomerPhoneNumber', 'CustomerEmailAddress', 'CustomerPerson', 'Customer', 'CustomerPhoneNumber', 'CustomerEmailAddress', 'CustomerPostalAddress',
'CustomerGroup', 'CustomerGroupAssignment', 'CustomerGroup', 'CustomerGroupAssignment', 'CustomerParty',
'LabelProfile'] 'LabelProfile']
@ -120,6 +122,12 @@ class StoreEmailAddress(EmailAddress, StoreContactInfo):
""" """
class StorePostalAddress(PostalAddress, StoreContactInfo):
"""
Represents a postal (mailing) address associated with a :class:`Store`.
"""
class Department(Model): class Department(Model):
""" """
Represents an organizational department. Represents an organizational department.
@ -251,26 +259,27 @@ class VendorEmailAddress(EmailAddress, VendorContactInfo):
""" """
class VendorContact(Model): class VendorPostalAddress(PostalAddress, VendorContactInfo):
""" """
Represents a point of contact (e.g. salesperson) for a vendor, from the Represents a postal (mailing) address associated with a :class:`Vendor`.
retailer's perspective.
""" """
class Meta(Model.Meta):
db_table = Model.prefix('vendor_contacts')
verbose_name = "Vendor Contact"
uuid = uuid_field() class VendorParty(Party):
vendor = models.ForeignKey(Vendor, db_column='vendor_uuid') """
person = models.ForeignKey('Person', db_column='person_uuid') Represents a "party" (e.g. sales contact) for a vendor, from the retailer's
preference = models.IntegerField() perspective.
"""
vendor = models.ForeignKey(Vendor, db_column='parent_uuid')
objects = PartyManager('Vendor')
def __repr__(self): def __repr__(self):
return "<VendorContact: %s, %s>" % (self.vendor, self.person) return "<VendorParty: %s, %s>" % (self.vendor, self.person)
def __unicode__(self): def save(self, *args, **kwargs):
return unicode(self.person) self.parent_type = 'Vendor'
super(VendorParty, self).save(*args, **kwargs)
class Product(Model): class Product(Model):
@ -378,9 +387,9 @@ class Employee(Model):
EMPLOYEE_STATUS_CHOICES = enum_to_choices(EMPLOYEE_STATUS) EMPLOYEE_STATUS_CHOICES = enum_to_choices(EMPLOYEE_STATUS)
uuid = uuid_field() uuid = uuid_field()
id = models.IntegerField(blank=True, null=True, verbose_name="ID") id = models.CharField(max_length=20, blank=True, null=True, verbose_name="ID")
person = models.ForeignKey('Person', db_column='person_uuid') person = models.OneToOneField(Person, db_column='person_uuid', related_name='+')
status = models.IntegerField(choices=EMPLOYEE_STATUS_CHOICES) status = models.IntegerField(choices=EMPLOYEE_STATUS_CHOICES, blank=True, null=True)
display_name = models.CharField(max_length=100, blank=True, null=True, verbose_name="Display Name") display_name = models.CharField(max_length=100, blank=True, null=True, verbose_name="Display Name")
def __repr__(self): def __repr__(self):
@ -402,34 +411,6 @@ class Employee(Model):
super(Employee, self).save(*args, **kwargs) super(Employee, self).save(*args, **kwargs)
class EmployeeContactInfo(models.Model):
"""
Base class for employee contact models (phone number, etc.).
"""
class Meta:
abstract = True
employee = models.ForeignKey(Employee, db_column='parent_uuid')
objects = ContactInfoManager('Employee')
def save(self, *args, **kwargs):
self.parent_type = 'Employee'
super(EmployeeContactInfo, self).save(*args, **kwargs)
class EmployeePhoneNumber(PhoneNumber, EmployeeContactInfo):
"""
Represents a phone (or fax) number associated with a :class:`Employee`.
"""
class EmployeeEmailAddress(EmailAddress, EmployeeContactInfo):
"""
Represents an email address associated with a :class:`Employee`.
"""
class Customer(Model): class Customer(Model):
""" """
Represents a customer account. Customer accounts may consist of more than Represents a customer account. Customer accounts may consist of more than
@ -453,6 +434,34 @@ class Customer(Model):
def __unicode__(self): def __unicode__(self):
return unicode(self.name or '') return unicode(self.name or '')
_primary_party = None
@property
def primary_party(self):
if self._primary_party is None:
qs = CustomerParty.objects
qs = qs.filter(customer=self)
qs = qs.filter(preference=1)
try:
self._primary_party = qs.get()
except ObjectDoesNotExist:
pass
return self._primary_party
def update_name(self):
orig_name = self.name
if self.primary_party:
person = self.primary_party.person
if not person.display_name:
person.update_display_name()
self.name = person.display_name
return self.name != orig_name
def save(self, *args, **kwargs):
if not self.name:
self.update_name()
super(Customer, self).save(*args, **kwargs)
class CustomerContactInfo(models.Model): class CustomerContactInfo(models.Model):
""" """
@ -482,26 +491,27 @@ class CustomerEmailAddress(EmailAddress, CustomerContactInfo):
""" """
class CustomerPerson(Model): class CustomerPostalAddress(PostalAddress, CustomerContactInfo):
""" """
Represents the association between a :class:`Person` and a customer account Represents a postal (mailing) address associated with a :class:`Customer`.
(:class:`Customer`).
""" """
class Meta(Model.Meta):
db_table = Model.prefix('customers_people')
verbose_name = "Customer Person"
uuid = uuid_field() class CustomerParty(Party):
customer = models.ForeignKey(Customer, db_column='customer_uuid') """
person = models.ForeignKey('Person', db_column='person_uuid') Represents a "party" (e.g. authorized shopper) for a customer, from the
ordinal = models.IntegerField() retailer's perspective.
"""
customer = models.ForeignKey(Customer, db_column='parent_uuid')
objects = PartyManager('Customer')
def __repr__(self): def __repr__(self):
return "<CustomerPerson: %s>" % self.person return "<CustomerParty: %s, %s>" % (self.customer, self.person)
def __unicode__(self): def save(self, *args, **kwargs):
return unicode(self.person or '') self.parent_type = 'Customer'
super(CustomerParty, self).save(*args, **kwargs)
class CustomerGroup(Model): class CustomerGroup(Model):

View file

@ -0,0 +1,42 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
################################################################################
#
# Rattail -- Retail Software Framework
# Copyright © 2010-2012 Lance Edgar
#
# This file is part of Rattail.
#
# Rattail is free software: you can redistribute it and/or modify it under the
# terms of the GNU Affero General Public License as published by the Free
# Software Foundation, either version 3 of the License, or (at your option)
# any later version.
#
# Rattail is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for
# more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with Rattail. If not, see <http://www.gnu.org/licenses/>.
#
################################################################################
"""
``rattail.django.rattail.urls`` -- URL Configuration
"""
from django.conf.urls import patterns, url
from rattail.django.rattail import views
urlpatterns = patterns(
'',
url(r'^zipcode/$',
views.get_zipcode_data,
name='rattail_zipcode'),
)

View file

@ -0,0 +1,59 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
################################################################################
#
# Rattail -- Retail Software Framework
# Copyright © 2010-2012 Lance Edgar
#
# This file is part of Rattail.
#
# Rattail is free software: you can redistribute it and/or modify it under the
# terms of the GNU Affero General Public License as published by the Free
# Software Foundation, either version 3 of the License, or (at your option)
# any later version.
#
# Rattail is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for
# more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with Rattail. If not, see <http://www.gnu.org/licenses/>.
#
################################################################################
"""
``rattail.django.rattail.views`` -- Views
"""
from django.http import HttpResponse
from django.utils import simplejson as json
from pyzipcode import ZipCodeDatabase
zcdb = ZipCodeDatabase()
def get_zipcode_data(request):
"""
Returns everything knowable about a given zipcode, as a JSON string.
Returns an empty string if the zipcode is not found in the database.
"""
zipcode = request.GET.get('zipcode')
zipcode = zcdb.get(zipcode)
if not zipcode:
return HttpResponse('')
zipcode = zipcode[0]
data = {
'city': zipcode.city,
'state': zipcode.state,
'zip': zipcode.zip,
'latitude': zipcode.latitude,
'longitude': zipcode.longitude,
'timezone': zipcode.timezone,
'dst': zipcode.dst,
}
return HttpResponse(json.dumps(data), content_type='application/json')