bunch more stuff! (savepoint)
This commit is contained in:
		
							parent
							
								
									0f77c11a87
								
							
						
					
					
						commit
						d8b8a7852b
					
				
					 6 changed files with 941 additions and 14 deletions
				
			
		|  | @ -27,8 +27,10 @@ | |||
| """ | ||||
| 
 | ||||
| from django.contrib import admin | ||||
| from django.contrib.admin.widgets import AdminTextInputWidget | ||||
| 
 | ||||
| from rattail.django.rattail.models import * | ||||
| from rattail.django.rattail.models.rattail import GPCField | ||||
| 
 | ||||
| 
 | ||||
| class ModelAdmin(admin.ModelAdmin): | ||||
|  | @ -36,27 +38,74 @@ class ModelAdmin(admin.ModelAdmin): | |||
|     Base admin manager for all Rattail models. | ||||
|     """ | ||||
| 
 | ||||
|     def get_form(self, request, obj=None, **kwargs): | ||||
|         kwargs.setdefault('exclude', ('uuid',)) | ||||
|         form = super(ModelAdmin, self).get_form(request, obj, **kwargs) | ||||
|         return form | ||||
|     exclude = ('uuid',) | ||||
| 
 | ||||
| 
 | ||||
| class StoreContactInfoInline(admin.TabularInline): | ||||
| class ContactInfoInline(admin.TabularInline): | ||||
|     """ | ||||
|     Base inline manager for all contact info models. | ||||
|     """ | ||||
| 
 | ||||
|     exclude = ('uuid', 'parent_type') | ||||
|     extra = 0 | ||||
| 
 | ||||
| class StorePhoneNumberInline(StoreContactInfoInline): | ||||
|     model = StorePhoneNumber | ||||
|     verbose_name_plural = "Phone Numbers" | ||||
| 
 | ||||
| class StoreEmailAddressInline(StoreContactInfoInline): | ||||
| class PersonPhoneNumberInline(ContactInfoInline): | ||||
|     model = PersonPhoneNumber | ||||
| 
 | ||||
| class PersonEmailAddressInline(ContactInfoInline): | ||||
|     model = PersonEmailAddress | ||||
| 
 | ||||
| class PersonAdmin(ModelAdmin): | ||||
|     inlines = [PersonPhoneNumberInline, PersonEmailAddressInline] | ||||
| 
 | ||||
|     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(Person, PersonAdmin) | ||||
| 
 | ||||
| 
 | ||||
| admin.site.register(Role, ModelAdmin) | ||||
| 
 | ||||
| 
 | ||||
| class UserRoleInline(admin.TabularInline): | ||||
|     model = UserRole | ||||
|     verbose_name = "Role" | ||||
|     verbose_name_plural = "Roles" | ||||
|     exclude = ('uuid',) | ||||
|     extra = 0 | ||||
| 
 | ||||
| class UserAdmin(ModelAdmin): | ||||
|     exclude = ('uuid', 'password', 'salt') | ||||
|     inlines = [UserRoleInline] | ||||
| 
 | ||||
|     def get_formsets(self, request, obj=None): | ||||
|         for inline in self.get_inline_instances(request): | ||||
|             if isinstance(inline, UserRoleInline) and obj is None: | ||||
|                 continue | ||||
|             yield inline.get_formset(request, obj) | ||||
| 
 | ||||
| admin.site.register(User, UserAdmin) | ||||
| 
 | ||||
| 
 | ||||
| class StorePhoneNumberInline(ContactInfoInline): | ||||
|     model = StorePhoneNumber | ||||
| 
 | ||||
| class StoreEmailAddressInline(ContactInfoInline): | ||||
|     model = StoreEmailAddress | ||||
|     verbose_name_plural = "Email Addresses" | ||||
| 
 | ||||
| class StoreAdmin(ModelAdmin): | ||||
|     inlines = [StorePhoneNumberInline, StoreEmailAddressInline] | ||||
| 
 | ||||
|     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(Store, StoreAdmin) | ||||
| 
 | ||||
| 
 | ||||
|  | @ -72,13 +121,120 @@ admin.site.register(Category, ModelAdmin) | |||
| admin.site.register(Brand, ModelAdmin) | ||||
| 
 | ||||
| 
 | ||||
| class VendorPhoneNumberInline(ContactInfoInline): | ||||
|     model = VendorPhoneNumber | ||||
| 
 | ||||
| class VendorEmailAddressInline(ContactInfoInline): | ||||
|     model = VendorEmailAddress | ||||
| 
 | ||||
| class VendorContactInline(admin.TabularInline): | ||||
|     model = VendorContact | ||||
|     verbose_name = "Contact" | ||||
|     verbose_name_plural = "Contacts" | ||||
|     exclude = ('uuid',) | ||||
|     extra = 0 | ||||
| 
 | ||||
| class VendorAdmin(ModelAdmin): | ||||
|     inlines = [VendorPhoneNumberInline, VendorEmailAddressInline, | ||||
|                VendorContactInline] | ||||
| 
 | ||||
|     def get_formsets(self, request, obj=None): | ||||
|         for inline in self.get_inline_instances(request): | ||||
|             if isinstance(inline, ContactInfoInline) and obj is None: | ||||
|                 continue | ||||
|             if isinstance(inline, VendorContactInline) and obj is None: | ||||
|                 continue | ||||
|             yield inline.get_formset(request, obj) | ||||
| 
 | ||||
| admin.site.register(Vendor, VendorAdmin) | ||||
| 
 | ||||
| 
 | ||||
| class ProductPriceInline(admin.TabularInline): | ||||
|     model = ProductPrice | ||||
|     verbose_name = "Price" | ||||
|     verbose_name_plural = "Prices" | ||||
|     exclude = ('uuid',) | ||||
|     extra = 0 | ||||
| 
 | ||||
| class ProductCostInline(admin.TabularInline): | ||||
|     model = ProductCost | ||||
|     verbose_name = "Cost" | ||||
|     verbose_name_plural = "Costs" | ||||
|     exclude = ('uuid',) | ||||
|     extra = 0 | ||||
| 
 | ||||
| class ProductAdmin(ModelAdmin): | ||||
|     inlines = [ProductPriceInline] | ||||
|     inlines = [ProductPriceInline, ProductCostInline] | ||||
| 
 | ||||
|     formfield_overrides = { | ||||
|         GPCField: { | ||||
|             'widget': AdminTextInputWidget, | ||||
|             }, | ||||
|         } | ||||
| 
 | ||||
|     def get_form(self, request, obj=None, **kwargs): | ||||
|         if obj is None: | ||||
|             kwargs['exclude'] = ('uuid', 'regular_price', 'current_price') | ||||
|         return super(ProductAdmin, self).get_form(request, obj, **kwargs) | ||||
| 
 | ||||
|     def get_formsets(self, request, obj=None): | ||||
|         for inline in self.get_inline_instances(request): | ||||
|             if isinstance(inline, ProductPriceInline) and obj is None: | ||||
|                 continue | ||||
|             if isinstance(inline, ProductCostInline) and obj is None: | ||||
|                 continue | ||||
|             yield inline.get_formset(request, obj) | ||||
| 
 | ||||
| admin.site.register(Product, ProductAdmin) | ||||
| 
 | ||||
| 
 | ||||
| class EmployeePhoneNumberInline(ContactInfoInline): | ||||
|     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) | ||||
| 
 | ||||
| 
 | ||||
| class CustomerPhoneNumberInline(ContactInfoInline): | ||||
|     model = CustomerPhoneNumber | ||||
| 
 | ||||
| class CustomerEmailAddressInline(ContactInfoInline): | ||||
|     model = CustomerEmailAddress | ||||
| 
 | ||||
| class CustomerGroupAssignmentInline(admin.TabularInline): | ||||
|     model = CustomerGroupAssignment | ||||
|     verbose_name = "Group Assignment" | ||||
|     verbose_name_plural = "Group Assignments" | ||||
|     exclude = ('uuid',) | ||||
|     extra = 0 | ||||
| 
 | ||||
| class CustomerAdmin(ModelAdmin): | ||||
|     inlines = [CustomerPhoneNumberInline, CustomerEmailAddressInline, | ||||
|                CustomerGroupAssignmentInline] | ||||
| 
 | ||||
|     def get_formsets(self, request, obj=None): | ||||
|         for inline in self.get_inline_instances(request): | ||||
|             if isinstance(inline, ContactInfoInline) and obj is None: | ||||
|                 continue | ||||
|             if isinstance(inline, CustomerGroupAssignmentInline) and obj is None: | ||||
|                 continue | ||||
|             yield inline.get_formset(request, obj) | ||||
| 
 | ||||
| admin.site.register(Customer, CustomerAdmin) | ||||
| 
 | ||||
| 
 | ||||
| admin.site.register(LabelProfile, ModelAdmin) | ||||
|  |  | |||
|  | @ -8,6 +8,15 @@ from django.db import models | |||
| class Migration(SchemaMigration): | ||||
| 
 | ||||
|     def forwards(self, orm): | ||||
|         # Adding model 'Person' | ||||
|         db.create_table('rattail_people', ( | ||||
|                 ('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)), | ||||
|                 ('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)), | ||||
|                 )) | ||||
|         db.send_create_signal('rattail', ['Person']) | ||||
| 
 | ||||
|         # Adding model 'PhoneNumber' | ||||
|         db.create_table('rattail_phone_numbers', ( | ||||
|                 ('uuid', self.gf('rattail.django.rattail.models.core.UUIDField')(max_length=32, primary_key=True)), | ||||
|  | @ -30,6 +39,31 @@ class Migration(SchemaMigration): | |||
|                 )) | ||||
|         db.send_create_signal('rattail', ['EmailAddress']) | ||||
| 
 | ||||
|         # Adding model 'Role' | ||||
|         db.create_table('rattail_roles', ( | ||||
|                 ('uuid', self.gf('rattail.django.rattail.models.core.UUIDField')(max_length=32, primary_key=True)), | ||||
|                 ('name', self.gf('django.db.models.fields.CharField')(unique=True, max_length=25)), | ||||
|                 )) | ||||
|         db.send_create_signal('rattail', ['Role']) | ||||
| 
 | ||||
|         # Adding model 'User' | ||||
|         db.create_table('rattail_users', ( | ||||
|                 ('uuid', self.gf('rattail.django.rattail.models.core.UUIDField')(max_length=32, primary_key=True)), | ||||
|                 ('username', self.gf('django.db.models.fields.CharField')(unique=True, max_length=25)), | ||||
|                 ('password', self.gf('django.db.models.fields.CharField')(max_length=60, null=True, blank=True)), | ||||
|                 ('salt', self.gf('django.db.models.fields.CharField')(max_length=29, null=True, blank=True)), | ||||
|                 ('person', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['rattail.Person'], null=True, db_column='person_uuid', blank=True)), | ||||
|                 )) | ||||
|         db.send_create_signal('rattail', ['User']) | ||||
| 
 | ||||
|         # Adding model 'UserRole' | ||||
|         db.create_table('rattail_users_roles', ( | ||||
|                 ('uuid', self.gf('rattail.django.rattail.models.core.UUIDField')(max_length=32, primary_key=True)), | ||||
|                 ('user', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['rattail.User'], db_column='user_uuid')), | ||||
|                 ('role', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['rattail.Role'], db_column='role_uuid')), | ||||
|                 )) | ||||
|         db.send_create_signal('rattail', ['UserRole']) | ||||
| 
 | ||||
|         # Adding model 'Store' | ||||
|         db.create_table('rattail_stores', ( | ||||
|                 ('uuid', self.gf('rattail.django.rattail.models.core.UUIDField')(max_length=32, primary_key=True)), | ||||
|  | @ -71,6 +105,24 @@ class Migration(SchemaMigration): | |||
|                 )) | ||||
|         db.send_create_signal('rattail', ['Brand']) | ||||
| 
 | ||||
|         # Adding model 'Vendor' | ||||
|         db.create_table('rattail_vendors', ( | ||||
|                 ('uuid', self.gf('rattail.django.rattail.models.core.UUIDField')(max_length=32, primary_key=True)), | ||||
|                 ('id', self.gf('django.db.models.fields.CharField')(max_length=15, null=True, blank=True)), | ||||
|                 ('name', self.gf('django.db.models.fields.CharField')(max_length=40, null=True, blank=True)), | ||||
|                 ('special_discount', self.gf('django.db.models.fields.DecimalField')(null=True, max_digits=5, decimal_places=3, blank=True)), | ||||
|                 )) | ||||
|         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' | ||||
|         db.create_table('rattail_products', ( | ||||
|                 ('uuid', self.gf('rattail.django.rattail.models.core.UUIDField')(max_length=32, primary_key=True)), | ||||
|  | @ -83,6 +135,8 @@ class Migration(SchemaMigration): | |||
|                 ('description2', self.gf('django.db.models.fields.CharField')(max_length=60, null=True, blank=True)), | ||||
|                 ('size', self.gf('django.db.models.fields.CharField')(max_length=30, null=True, blank=True)), | ||||
|                 ('unit_of_measure', self.gf('django.db.models.fields.CharField')(max_length=4, null=True, blank=True)), | ||||
|                 ('regular_price', self.gf('django.db.models.fields.related.ForeignKey')(blank=True, related_name='+', null=True, db_column='regular_price_uuid', to=orm['rattail.ProductPrice'])), | ||||
|                 ('current_price', self.gf('django.db.models.fields.related.ForeignKey')(blank=True, related_name='+', null=True, db_column='current_price_uuid', to=orm['rattail.ProductPrice'])), | ||||
|                 )) | ||||
|         db.send_create_signal('rattail', ['Product']) | ||||
| 
 | ||||
|  | @ -101,14 +155,115 @@ class Migration(SchemaMigration): | |||
|                 )) | ||||
|         db.send_create_signal('rattail', ['ProductPrice']) | ||||
| 
 | ||||
|         # Adding model 'ProductCost' | ||||
|         db.create_table('rattail_product_costs', ( | ||||
|                 ('uuid', self.gf('rattail.django.rattail.models.core.UUIDField')(max_length=32, primary_key=True)), | ||||
|                 ('product', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['rattail.Product'], db_column='product_uuid')), | ||||
|                 ('vendor', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['rattail.Vendor'], db_column='vendor_uuid')), | ||||
|                 ('preference', self.gf('django.db.models.fields.IntegerField')()), | ||||
|                 ('code', self.gf('django.db.models.fields.CharField')(max_length=15, null=True, blank=True)), | ||||
|                 ('case_size', self.gf('django.db.models.fields.IntegerField')(null=True, blank=True)), | ||||
|                 ('case_cost', self.gf('django.db.models.fields.DecimalField')(null=True, max_digits=9, decimal_places=5, blank=True)), | ||||
|                 ('pack_size', self.gf('django.db.models.fields.IntegerField')(null=True, blank=True)), | ||||
|                 ('pack_cost', self.gf('django.db.models.fields.DecimalField')(null=True, max_digits=9, decimal_places=5, blank=True)), | ||||
|                 ('unit_cost', self.gf('django.db.models.fields.DecimalField')(null=True, max_digits=9, decimal_places=5, blank=True)), | ||||
|                 ('effective', self.gf('django.db.models.fields.DateTimeField')(null=True, blank=True)), | ||||
|                 )) | ||||
|         db.send_create_signal('rattail', ['ProductCost']) | ||||
| 
 | ||||
|         # Adding model 'Employee' | ||||
|         db.create_table('rattail_employees', ( | ||||
|                 ('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)), | ||||
|                 ('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')()), | ||||
|                 ('display_name', self.gf('django.db.models.fields.CharField')(max_length=100, null=True, blank=True)), | ||||
|                 )) | ||||
|         db.send_create_signal('rattail', ['Employee']) | ||||
| 
 | ||||
|         # Adding model 'Customer' | ||||
|         db.create_table('rattail_customers', ( | ||||
|                 ('uuid', self.gf('rattail.django.rattail.models.core.UUIDField')(max_length=32, primary_key=True)), | ||||
|                 ('id', self.gf('django.db.models.fields.CharField')(max_length=20, null=True, blank=True)), | ||||
|                 ('name', self.gf('django.db.models.fields.CharField')(max_length=255, null=True, blank=True)), | ||||
|                 ('email_preference', self.gf('django.db.models.fields.IntegerField')(null=True, blank=True)), | ||||
|                 )) | ||||
|         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' | ||||
|         db.create_table('rattail_customer_groups', ( | ||||
|                 ('uuid', self.gf('rattail.django.rattail.models.core.UUIDField')(max_length=32, primary_key=True)), | ||||
|                 ('id', self.gf('django.db.models.fields.CharField')(max_length=20, null=True, blank=True)), | ||||
|                 ('name', self.gf('django.db.models.fields.CharField')(max_length=255, null=True, blank=True)), | ||||
|                 )) | ||||
|         db.send_create_signal('rattail', ['CustomerGroup']) | ||||
| 
 | ||||
|         # Adding model 'CustomerGroupAssignment' | ||||
|         db.create_table('rattail_customers_groups', ( | ||||
|                 ('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')), | ||||
|                 ('group', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['rattail.CustomerGroup'], db_column='group_uuid')), | ||||
|                 ('ordinal', self.gf('django.db.models.fields.IntegerField')()), | ||||
|                 )) | ||||
|         db.send_create_signal('rattail', ['CustomerGroupAssignment']) | ||||
| 
 | ||||
|         # Adding model 'LabelProfile' | ||||
|         db.create_table('rattail_label_profiles', ( | ||||
|                 ('uuid', self.gf('rattail.django.rattail.models.core.UUIDField')(max_length=32, primary_key=True)), | ||||
|                 ('ordinal', self.gf('django.db.models.fields.IntegerField')(null=True, blank=True)), | ||||
|                 ('code', self.gf('django.db.models.fields.CharField')(max_length=3, null=True, blank=True)), | ||||
|                 ('description', self.gf('django.db.models.fields.CharField')(max_length=50, null=True, blank=True)), | ||||
|                 ('printer_spec', self.gf('django.db.models.fields.CharField')(max_length=255, null=True, blank=True)), | ||||
|                 ('formatter_spec', self.gf('django.db.models.fields.CharField')(max_length=255, null=True, blank=True)), | ||||
|                 ('format', self.gf('django.db.models.fields.TextField')(null=True, blank=True)), | ||||
|                 ('visible', self.gf('django.db.models.fields.BooleanField')(default=False)), | ||||
|                 )) | ||||
|         db.send_create_signal('rattail', ['LabelProfile']) | ||||
| 
 | ||||
| 
 | ||||
|     def backwards(self, orm): | ||||
|         # Deleting model 'LabelProfile' | ||||
|         db.delete_table('rattail_label_profiles') | ||||
| 
 | ||||
|         # Deleting model 'CustomerGroupAssignment' | ||||
|         db.delete_table('rattail_customers_groups') | ||||
| 
 | ||||
|         # Deleting model 'CustomerGroup' | ||||
|         db.delete_table('rattail_customer_groups') | ||||
| 
 | ||||
|         # Deleting model 'CustomerPerson' | ||||
|         db.delete_table('rattail_customers_people') | ||||
| 
 | ||||
|         # Deleting model 'Customer' | ||||
|         db.delete_table('rattail_customers') | ||||
| 
 | ||||
|         # Deleting model 'Employee' | ||||
|         db.delete_table('rattail_employees') | ||||
| 
 | ||||
|         # Deleting model 'ProductCost' | ||||
|         db.delete_table('rattail_product_costs') | ||||
| 
 | ||||
|         # Deleting model 'ProductPrice' | ||||
|         db.delete_table('rattail_product_prices') | ||||
| 
 | ||||
|         # Deleting model 'Product' | ||||
|         db.delete_table('rattail_products') | ||||
| 
 | ||||
|         # Deleting model 'VendorContact' | ||||
|         db.delete_table('rattail_vendor_contacts') | ||||
| 
 | ||||
|         # Deleting model 'Vendor' | ||||
|         db.delete_table('rattail_vendors') | ||||
| 
 | ||||
|         # Deleting model 'Brand' | ||||
|         db.delete_table('rattail_brands') | ||||
| 
 | ||||
|  | @ -124,14 +279,33 @@ class Migration(SchemaMigration): | |||
|         # Deleting model 'Store' | ||||
|         db.delete_table('rattail_stores') | ||||
| 
 | ||||
|         # Deleting model 'UserRole' | ||||
|         db.delete_table('rattail_users_roles') | ||||
| 
 | ||||
|         # Deleting model 'User' | ||||
|         db.delete_table('rattail_users') | ||||
| 
 | ||||
|         # Deleting model 'Role' | ||||
|         db.delete_table('rattail_roles') | ||||
| 
 | ||||
|         # Deleting model 'EmailAddress' | ||||
|         db.delete_table('rattail_email_addresses') | ||||
| 
 | ||||
|         # Deleting model 'PhoneNumber' | ||||
|         db.delete_table('rattail_phone_numbers') | ||||
| 
 | ||||
|         # Deleting model 'Person' | ||||
|         db.delete_table('rattail_people') | ||||
| 
 | ||||
| 
 | ||||
|     models = { | ||||
|         'rattail.person': { | ||||
|             'Meta': {'object_name': 'Person', 'db_table': "'rattail_people'"}, | ||||
|             'display_name': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}), | ||||
|             'first_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'}) | ||||
|         }, | ||||
|         'rattail.phonenumber': { | ||||
|             'Meta': {'object_name': 'PhoneNumber', 'db_table': "'rattail_phone_numbers'"}, | ||||
|             'number': ('django.db.models.fields.CharField', [], {'max_length': '20'}), | ||||
|  | @ -150,6 +324,25 @@ class Migration(SchemaMigration): | |||
|             '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'}) | ||||
|             }, | ||||
|         'rattail.role': { | ||||
|             'Meta': {'object_name': 'Role', 'db_table': "'rattail_roles'"}, | ||||
|             'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '25'}), | ||||
|             'uuid': ('rattail.django.rattail.models.core.UUIDField', [], {'max_length': '32', 'primary_key': 'True'}) | ||||
|             }, | ||||
|         'rattail.user': { | ||||
|             'Meta': {'object_name': 'User', 'db_table': "'rattail_users'"}, | ||||
|             'password': ('django.db.models.fields.CharField', [], {'max_length': '60', 'null': 'True', 'blank': 'True'}), | ||||
|             'person': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['rattail.Person']", 'null': 'True', 'db_column': "'person_uuid'", 'blank': 'True'}), | ||||
|             'salt': ('django.db.models.fields.CharField', [], {'max_length': '29', 'null': 'True', 'blank': 'True'}), | ||||
|             'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '25'}), | ||||
|             'uuid': ('rattail.django.rattail.models.core.UUIDField', [], {'max_length': '32', 'primary_key': 'True'}) | ||||
|             }, | ||||
|         'rattail.userrole': { | ||||
|             'Meta': {'object_name': 'UserRole', 'db_table': "'rattail_users_roles'"}, | ||||
|             'role': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['rattail.Role']", 'db_column': "'role_uuid'"}), | ||||
|             'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['rattail.User']", 'db_column': "'user_uuid'"}), | ||||
|             'uuid': ('rattail.django.rattail.models.core.UUIDField', [], {'max_length': '32', 'primary_key': 'True'}) | ||||
|             }, | ||||
|         'rattail.store': { | ||||
|             'Meta': {'object_name': 'Store', 'db_table': "'rattail_stores'"}, | ||||
|             'id': ('django.db.models.fields.CharField', [], {'max_length': '10', 'null': 'True', 'blank': 'True'}), | ||||
|  | @ -181,13 +374,29 @@ class Migration(SchemaMigration): | |||
|             'name': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}), | ||||
|             'uuid': ('rattail.django.rattail.models.core.UUIDField', [], {'max_length': '32', 'primary_key': 'True'}) | ||||
|             }, | ||||
|         'rattail.vendor': { | ||||
|             'Meta': {'object_name': 'Vendor', 'db_table': "'rattail_vendors'"}, | ||||
|             'id': ('django.db.models.fields.CharField', [], {'max_length': '15', 'null': 'True', 'blank': 'True'}), | ||||
|             'name': ('django.db.models.fields.CharField', [], {'max_length': '40', 'null': 'True', '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'}) | ||||
|             }, | ||||
|         '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': { | ||||
|             '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'}), | ||||
|             'category': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['rattail.Category']", 'null': 'True', 'db_column': "'category_uuid'", 'blank': 'True'}), | ||||
|             'current_price': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'+'", 'null': 'True', 'db_column': "'current_price_uuid'", 'to': "orm['rattail.ProductPrice']"}), | ||||
|             'department': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['rattail.Department']", 'null': 'True', 'db_column': "'department_uuid'", 'blank': 'True'}), | ||||
|             'description': ('django.db.models.fields.CharField', [], {'max_length': '60', 'null': 'True', 'blank': 'True'}), | ||||
|             'description2': ('django.db.models.fields.CharField', [], {'max_length': '60', 'null': 'True', 'blank': 'True'}), | ||||
|             'regular_price': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'+'", 'null': 'True', 'db_column': "'regular_price_uuid'", 'to': "orm['rattail.ProductPrice']"}), | ||||
|             'size': ('django.db.models.fields.CharField', [], {'max_length': '30', 'null': 'True', 'blank': 'True'}), | ||||
|             'subdepartment': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['rattail.Subdepartment']", 'null': 'True', 'db_column': "'subdepartment_uuid'", 'blank': 'True'}), | ||||
|             'unit_of_measure': ('django.db.models.fields.CharField', [], {'max_length': '4', 'null': 'True', 'blank': 'True'}), | ||||
|  | @ -207,6 +416,66 @@ class Migration(SchemaMigration): | |||
|             'type': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}), | ||||
|             'uuid': ('rattail.django.rattail.models.core.UUIDField', [], {'max_length': '32', 'primary_key': 'True'}) | ||||
|             }, | ||||
|         'rattail.productcost': { | ||||
|             'Meta': {'object_name': 'ProductCost', 'db_table': "'rattail_product_costs'"}, | ||||
|             'case_cost': ('django.db.models.fields.DecimalField', [], {'null': 'True', 'max_digits': '9', 'decimal_places': '5', 'blank': 'True'}), | ||||
|             'case_size': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}), | ||||
|             'code': ('django.db.models.fields.CharField', [], {'max_length': '15', 'null': 'True', 'blank': 'True'}), | ||||
|             'effective': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}), | ||||
|             'pack_cost': ('django.db.models.fields.DecimalField', [], {'null': 'True', 'max_digits': '9', 'decimal_places': '5', 'blank': 'True'}), | ||||
|             'pack_size': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}), | ||||
|             'preference': ('django.db.models.fields.IntegerField', [], {}), | ||||
|             'product': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['rattail.Product']", 'db_column': "'product_uuid'"}), | ||||
|             'unit_cost': ('django.db.models.fields.DecimalField', [], {'null': 'True', 'max_digits': '9', 'decimal_places': '5', 'blank': 'True'}), | ||||
|             '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.employee': { | ||||
|             'Meta': {'object_name': 'Employee', 'db_table': "'rattail_employees'"}, | ||||
|             'display_name': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}), | ||||
|             'id': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}), | ||||
|             'person': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['rattail.Person']", 'db_column': "'person_uuid'"}), | ||||
|             'status': ('django.db.models.fields.IntegerField', [], {}), | ||||
|             'uuid': ('rattail.django.rattail.models.core.UUIDField', [], {'max_length': '32', 'primary_key': 'True'}) | ||||
|             }, | ||||
|         'rattail.customer': { | ||||
|             'Meta': {'object_name': 'Customer', 'db_table': "'rattail_customers'"}, | ||||
|             'email_preference': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}), | ||||
|             'id': ('django.db.models.fields.CharField', [], {'max_length': '20', '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'}) | ||||
|             }, | ||||
|         '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': { | ||||
|             'Meta': {'object_name': 'CustomerGroup', 'db_table': "'rattail_customer_groups'"}, | ||||
|             'id': ('django.db.models.fields.CharField', [], {'max_length': '20', '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'}) | ||||
|             }, | ||||
|         'rattail.customergroupassignment': { | ||||
|             'Meta': {'object_name': 'CustomerGroupAssignment', 'db_table': "'rattail_customers_groups'"}, | ||||
|             'customer': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['rattail.Customer']", 'db_column': "'customer_uuid'"}), | ||||
|             'group': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['rattail.CustomerGroup']", 'db_column': "'group_uuid'"}), | ||||
|             'ordinal': ('django.db.models.fields.IntegerField', [], {}), | ||||
|             'uuid': ('rattail.django.rattail.models.core.UUIDField', [], {'max_length': '32', 'primary_key': 'True'}) | ||||
|             }, | ||||
|         'rattail.labelprofile': { | ||||
|             'Meta': {'object_name': 'LabelProfile', 'db_table': "'rattail_label_profiles'"}, | ||||
|             'code': ('django.db.models.fields.CharField', [], {'max_length': '3', 'null': 'True', 'blank': 'True'}), | ||||
|             'description': ('django.db.models.fields.CharField', [], {'max_length': '50', 'null': 'True', 'blank': 'True'}), | ||||
|             'format': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), | ||||
|             'formatter_spec': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}), | ||||
|             'ordinal': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}), | ||||
|             'printer_spec': ('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'}), | ||||
|             'visible': ('django.db.models.fields.BooleanField', [], {'default': 'False'}) | ||||
|             }, | ||||
|         } | ||||
| 
 | ||||
|     complete_apps = ['rattail'] | ||||
|  |  | |||
|  | @ -31,6 +31,8 @@ from __future__ import absolute_import | |||
| from south.modelsinspector import add_introspection_rules | ||||
| 
 | ||||
| from rattail.django.rattail.models.core import * | ||||
| from rattail.django.rattail.models.contact import * | ||||
| from rattail.django.rattail.models.auth import * | ||||
| from rattail.django.rattail.models.rattail import * | ||||
| 
 | ||||
| 
 | ||||
|  |  | |||
							
								
								
									
										106
									
								
								rattail/django/rattail/models/auth.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										106
									
								
								rattail/django/rattail/models/auth.py
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,106 @@ | |||
| #!/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.models.auth`` -- Models for 'auth' Extension | ||||
| """ | ||||
| 
 | ||||
| from __future__ import absolute_import | ||||
| 
 | ||||
| from django.db import models | ||||
| 
 | ||||
| from rattail.django.rattail.models import Model, uuid_field | ||||
| 
 | ||||
| 
 | ||||
| __all__ = ['Role', 'User', 'UserRole'] | ||||
| 
 | ||||
| 
 | ||||
| class Role(Model): | ||||
|     """ | ||||
|     Represents a role within the system; used to manage permissions. | ||||
|     """ | ||||
| 
 | ||||
|     class Meta(Model.Meta): | ||||
|         db_table = Model.prefix('roles') | ||||
| 
 | ||||
|     uuid = uuid_field() | ||||
|     name = models.CharField(max_length=25, unique=True) | ||||
| 
 | ||||
|     def __repr__(self): | ||||
|         return "<Role: %s>" % self.name | ||||
| 
 | ||||
|     def __unicode__(self): | ||||
|         return unicode(self.name or '') | ||||
| 
 | ||||
| 
 | ||||
| class User(Model): | ||||
|     """ | ||||
|     Represents a user of the system.  This may or may not correspond to a real | ||||
|     person, i.e. some users may exist solely for automated tasks. | ||||
|     """ | ||||
| 
 | ||||
|     class Meta(Model.Meta): | ||||
|         db_table = Model.prefix('users') | ||||
| 
 | ||||
|     uuid = uuid_field() | ||||
|     username = models.CharField(max_length=25, unique=True) | ||||
|     password = models.CharField(max_length=60, blank=True, null=True) | ||||
|     salt = models.CharField(max_length=29, blank=True, null=True) | ||||
|     person = models.ForeignKey('Person', db_column='person_uuid', blank=True, null=True) | ||||
| 
 | ||||
|     def __repr__(self): | ||||
|         return "<User: %s>" % self.username | ||||
| 
 | ||||
|     def __unicode__(self): | ||||
|         return unicode(self.username or '') | ||||
| 
 | ||||
|     @property | ||||
|     def display_name(self): | ||||
|         """ | ||||
|         Returns :attr:`rattail.Person.display_name` if present; otherwise | ||||
|         returns :attr:`username`. | ||||
|         """ | ||||
| 
 | ||||
|         if self.person and self.person.display_name: | ||||
|             return self.person.display_name | ||||
|         return self.username | ||||
| 
 | ||||
| 
 | ||||
| class UserRole(Model): | ||||
|     """ | ||||
|     Represents the association between a :class:`User` and a :class:`Role`. | ||||
|     """ | ||||
| 
 | ||||
|     class Meta(Model.Meta): | ||||
|         db_table = Model.prefix('users_roles') | ||||
| 
 | ||||
|     uuid = uuid_field() | ||||
|     user = models.ForeignKey(User, db_column='user_uuid') | ||||
|     role = models.ForeignKey(Role, db_column='role_uuid') | ||||
| 
 | ||||
|     def __repr__(self): | ||||
|         return "<UserRole: %s : %s>" % (self.user, self.role) | ||||
| 
 | ||||
|     def __unicode__(self): | ||||
|         return unicode(self.role or '') | ||||
|  | @ -33,7 +33,8 @@ from django.db import models | |||
| from rattail.django.rattail.models import Model, uuid_field | ||||
| 
 | ||||
| 
 | ||||
| __all__ = ['PhoneNumber', 'EmailAddress'] | ||||
| __all__ = ['PhoneNumber', 'EmailAddress', | ||||
|            'Person', 'PersonPhoneNumber', 'PersonEmailAddress'] | ||||
| 
 | ||||
| 
 | ||||
| class ContactInfoManager(models.Manager): | ||||
|  | @ -68,6 +69,8 @@ class PhoneNumber(ContactInfo): | |||
|     class Meta(ContactInfo.Meta): | ||||
|         abstract = True | ||||
|         db_table = ContactInfo.prefix('phone_numbers') | ||||
|         verbose_name = "Phone Number" | ||||
|         verbose_name_plural = "Phone Numbers" | ||||
| 
 | ||||
|     number = models.CharField(max_length=20) | ||||
| 
 | ||||
|  | @ -86,6 +89,8 @@ class EmailAddress(ContactInfo): | |||
|     class Meta(ContactInfo.Meta): | ||||
|         abstract = True | ||||
|         db_table = ContactInfo.prefix('email_addresses') | ||||
|         verbose_name = "Email Address" | ||||
|         verbose_name_plural = "Email Addresses" | ||||
| 
 | ||||
|     address = models.CharField(max_length=255) | ||||
| 
 | ||||
|  | @ -94,3 +99,63 @@ class EmailAddress(ContactInfo): | |||
| 
 | ||||
|     def __unicode__(self): | ||||
|         return unicode(self.address) | ||||
| 
 | ||||
| 
 | ||||
| class Person(Model): | ||||
|     """ | ||||
|     Represents a real, living and breathing person.  (Or, at least was | ||||
|     previously living and breathing, in the case of the deceased.) | ||||
|     """ | ||||
| 
 | ||||
|     class Meta(Model.Meta): | ||||
|         db_table = Model.prefix('people') | ||||
|         verbose_name_plural = "People" | ||||
| 
 | ||||
|     uuid = uuid_field() | ||||
|     first_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") | ||||
| 
 | ||||
|     def __repr__(self): | ||||
|         return "<Person: %s>" % self.display_name | ||||
| 
 | ||||
|     def __unicode__(self): | ||||
|         return unicode(self.display_name or '') | ||||
| 
 | ||||
|     def save(self, *args, **kwargs): | ||||
|         if not 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 | ||||
|         super(Person, self).save(*args, **kwargs) | ||||
| 
 | ||||
| 
 | ||||
| class PersonContactInfo(models.Model): | ||||
|     """ | ||||
|     Base class for person contact models (phone number, etc.). | ||||
|     """ | ||||
| 
 | ||||
|     class Meta: | ||||
|         abstract = True | ||||
| 
 | ||||
|     store = models.ForeignKey(Person, db_column='parent_uuid') | ||||
|     objects = ContactInfoManager('Person') | ||||
| 
 | ||||
|     def save(self, *args, **kwargs): | ||||
|         self.parent_type = 'Person' | ||||
|         super(PersonContactInfo, self).save(*args, **kwargs) | ||||
| 
 | ||||
| 
 | ||||
| class PersonPhoneNumber(PhoneNumber, PersonContactInfo): | ||||
|     """ | ||||
|     Represents a phone (or fax) number associated with a :class:`Person`. | ||||
|     """ | ||||
| 
 | ||||
| 
 | ||||
| class PersonEmailAddress(EmailAddress, PersonContactInfo): | ||||
|     """ | ||||
|     Represents an email address associated with a :class:`Person`. | ||||
|     """     | ||||
|  |  | |||
|  | @ -30,8 +30,12 @@ from __future__ import absolute_import | |||
| 
 | ||||
| from django.db import models | ||||
| 
 | ||||
| from edbob.db.extensions.contact.enum import EMAIL_PREFERENCE | ||||
| 
 | ||||
| import rattail | ||||
| from rattail.gpc import GPC | ||||
| from rattail.db.extension.enum import EMPLOYEE_STATUS | ||||
| 
 | ||||
| from rattail.django.rattail.models import Model, uuid_field | ||||
| from rattail.django.rattail.models.contact import ( | ||||
|     ContactInfoManager, PhoneNumber, EmailAddress) | ||||
|  | @ -40,7 +44,12 @@ from rattail.django.util import enum_to_choices | |||
| 
 | ||||
| __all__ = ['Store', 'StorePhoneNumber', 'StoreEmailAddress', | ||||
|            'Department', 'Subdepartment', 'Category', 'Brand', | ||||
|            'Product', 'ProductPrice'] | ||||
|            'Vendor', 'VendorPhoneNumber', 'VendorEmailAddress', 'VendorContact', | ||||
|            'Product', 'ProductPrice', 'ProductCost', | ||||
|            'Employee', 'EmployeePhoneNumber', 'EmployeeEmailAddress', | ||||
|            'Customer', 'CustomerPhoneNumber', 'CustomerEmailAddress', 'CustomerPerson', | ||||
|            'CustomerGroup', 'CustomerGroupAssignment', | ||||
|            'LabelProfile'] | ||||
| 
 | ||||
| 
 | ||||
| class GPCField(models.BigIntegerField): | ||||
|  | @ -70,6 +79,7 @@ class Store(Model): | |||
| 
 | ||||
|     class Meta(Model.Meta): | ||||
|         db_table = Model.prefix('stores') | ||||
|         verbose_name = "Store" | ||||
| 
 | ||||
|     uuid = uuid_field() | ||||
|     id = models.CharField(max_length=10, blank=True, null=True, verbose_name="ID") | ||||
|  | @ -117,6 +127,7 @@ class Department(Model): | |||
| 
 | ||||
|     class Meta(Model.Meta): | ||||
|         db_table = Model.prefix('departments') | ||||
|         verbose_name = "Department" | ||||
| 
 | ||||
|     uuid = uuid_field() | ||||
|     number = models.IntegerField(blank=True, null=True) | ||||
|  | @ -136,6 +147,7 @@ class Subdepartment(Model): | |||
| 
 | ||||
|     class Meta(Model.Meta): | ||||
|         db_table = Model.prefix('subdepartments') | ||||
|         verbose_name = "Subdepartment" | ||||
| 
 | ||||
|     uuid = uuid_field() | ||||
|     number = models.IntegerField(blank=True, null=True) | ||||
|  | @ -156,6 +168,7 @@ class Category(Model): | |||
| 
 | ||||
|     class Meta(Model.Meta): | ||||
|         db_table = Model.prefix('categories') | ||||
|         verbose_name = "Category" | ||||
|         verbose_name_plural = "Categories" | ||||
| 
 | ||||
|     uuid = uuid_field() | ||||
|  | @ -177,6 +190,7 @@ class Brand(Model): | |||
| 
 | ||||
|     class Meta(Model.Meta): | ||||
|         db_table = Model.prefix('brands') | ||||
|         verbose_name = "Brand" | ||||
| 
 | ||||
|     uuid = uuid_field() | ||||
|     name = models.CharField(max_length=100, blank=True, null=True) | ||||
|  | @ -188,6 +202,77 @@ class Brand(Model): | |||
|         return unicode(self.name or '') | ||||
| 
 | ||||
| 
 | ||||
| class Vendor(Model): | ||||
|     """ | ||||
|     Represents a vendor from which products are purchased by the store. | ||||
|     """ | ||||
| 
 | ||||
|     class Meta(Model.Meta): | ||||
|         db_table = Model.prefix('vendors') | ||||
|         verbose_name = "Vendor" | ||||
| 
 | ||||
|     uuid = uuid_field() | ||||
|     id = models.CharField(max_length=15, blank=True, null=True, verbose_name="ID") | ||||
|     name = models.CharField(max_length=40, blank=True, null=True) | ||||
|     special_discount = models.DecimalField(max_digits=5, decimal_places=3, blank=True, null=True, verbose_name="Special Discount") | ||||
| 
 | ||||
|     def __repr__(self): | ||||
|         return "<Vendor: %s>" % self.name | ||||
| 
 | ||||
|     def __unicode__(self): | ||||
|         return unicode(self.name or '') | ||||
| 
 | ||||
| 
 | ||||
| class VendorContactInfo(models.Model): | ||||
|     """ | ||||
|     Base class for vendor contact models (phone number, etc.). | ||||
|     """ | ||||
| 
 | ||||
|     class Meta: | ||||
|         abstract = True | ||||
| 
 | ||||
|     vendor = models.ForeignKey(Vendor, db_column='parent_uuid') | ||||
|     objects = ContactInfoManager('Vendor') | ||||
| 
 | ||||
|     def save(self, *args, **kwargs): | ||||
|         self.parent_type = 'Vendor' | ||||
|         super(VendorContactInfo, self).save(*args, **kwargs) | ||||
| 
 | ||||
| 
 | ||||
| class VendorPhoneNumber(PhoneNumber, VendorContactInfo): | ||||
|     """ | ||||
|     Represents a phone (or fax) number associated with a :class:`Vendor`. | ||||
|     """ | ||||
| 
 | ||||
| 
 | ||||
| class VendorEmailAddress(EmailAddress, VendorContactInfo): | ||||
|     """ | ||||
|     Represents an email address associated with a :class:`Vendor`. | ||||
|     """ | ||||
| 
 | ||||
| 
 | ||||
| class VendorContact(Model): | ||||
|     """ | ||||
|     Represents a point of contact (e.g. salesperson) for a vendor, from the | ||||
|     retailer's perspective. | ||||
|     """ | ||||
| 
 | ||||
|     class Meta(Model.Meta): | ||||
|         db_table = Model.prefix('vendor_contacts') | ||||
|         verbose_name = "Vendor Contact" | ||||
| 
 | ||||
|     uuid = uuid_field() | ||||
|     vendor = models.ForeignKey(Vendor, db_column='vendor_uuid') | ||||
|     person = models.ForeignKey('Person', db_column='person_uuid') | ||||
|     preference = models.IntegerField() | ||||
| 
 | ||||
|     def __repr__(self): | ||||
|         return "<VendorContact: %s, %s>" % (self.vendor, self.person) | ||||
| 
 | ||||
|     def __unicode__(self): | ||||
|         return unicode(self.person) | ||||
| 
 | ||||
| 
 | ||||
| class Product(Model): | ||||
|     """ | ||||
|     Represents a product for sale and/or purchase. | ||||
|  | @ -195,6 +280,9 @@ class Product(Model): | |||
| 
 | ||||
|     class Meta(Model.Meta): | ||||
|         db_table = Model.prefix('products') | ||||
|         verbose_name = "Product" | ||||
| 
 | ||||
|     UNIT_OF_MEASURE_CHOICES = enum_to_choices(rattail.UNIT_OF_MEASURE) | ||||
| 
 | ||||
|     uuid = uuid_field() | ||||
|     upc = GPCField(db_index=True, verbose_name="UPC") | ||||
|  | @ -205,7 +293,9 @@ class Product(Model): | |||
|     description = models.CharField(max_length=60, blank=True, null=True) | ||||
|     description2 = models.CharField(max_length=60, blank=True, null=True, verbose_name="Description Line 2") | ||||
|     size = models.CharField(max_length=30, blank=True, null=True) | ||||
|     unit_of_measure = models.CharField(max_length=4, blank=True, null=True, verbose_name="Unit of Measure") | ||||
|     unit_of_measure = models.CharField(max_length=4, choices=UNIT_OF_MEASURE_CHOICES, blank=True, null=True, verbose_name="Unit of Measure") | ||||
|     regular_price = models.ForeignKey('ProductPrice', db_column='regular_price_uuid', related_name='+', blank=True, null=True, verbose_name="Regular Price") | ||||
|     current_price = models.ForeignKey('ProductPrice', db_column='current_price_uuid', related_name='+', blank=True, null=True, verbose_name="Current Price") | ||||
| 
 | ||||
|     def __repr__(self): | ||||
|         return "<Product: %s>" % self.description | ||||
|  | @ -221,6 +311,7 @@ class ProductPrice(Model): | |||
| 
 | ||||
|     class Meta(Model.Meta): | ||||
|         db_table = Model.prefix('product_prices') | ||||
|         verbose_name = "Product Price" | ||||
| 
 | ||||
|     PRICE_TYPE_CHOICES = enum_to_choices(rattail.PRICE_TYPE) | ||||
| 
 | ||||
|  | @ -239,5 +330,243 @@ class ProductPrice(Model): | |||
|         return "<ProductPrice: %s : %s>" % (self.product, self.price) | ||||
| 
 | ||||
|     def __unicode__(self): | ||||
|         if self.price is None: | ||||
|             return u'' | ||||
|         type = rattail.PRICE_TYPE.get(self.type, "?") | ||||
|         return u'$ %0.2f / %d (%s)' % (self.price, self.multiple or 1, type) | ||||
| 
 | ||||
| 
 | ||||
| class ProductCost(Model): | ||||
|     """ | ||||
|     Represents a source from which a product may be obtained via purchase. | ||||
|     """ | ||||
| 
 | ||||
|     class Meta(Model.Meta): | ||||
|         db_table = Model.prefix('product_costs') | ||||
|         verbose_name = "Product Cost" | ||||
| 
 | ||||
|     uuid = uuid_field() | ||||
|     product = models.ForeignKey(Product, db_column='product_uuid') | ||||
|     vendor = models.ForeignKey(Vendor, db_column='vendor_uuid') | ||||
|     preference = models.IntegerField() | ||||
|     code = models.CharField(max_length=15, blank=True, null=True) | ||||
|     case_size = models.IntegerField(blank=True, null=True, verbose_name="Case Size") | ||||
|     case_cost = models.DecimalField(max_digits=9, decimal_places=5, blank=True, null=True, verbose_name="Case Cost") | ||||
|     pack_size = models.IntegerField(blank=True, null=True, verbose_name="Pack Size") | ||||
|     pack_cost = models.DecimalField(max_digits=9, decimal_places=5, blank=True, null=True, verbose_name="Pack Cost") | ||||
|     unit_cost = models.DecimalField(max_digits=9, decimal_places=5, blank=True, null=True, verbose_name="Unit Cost") | ||||
|     effective = models.DateTimeField(blank=True, null=True) | ||||
| 
 | ||||
|     def __repr__(self): | ||||
|         return "<ProductCost: %s : %s>" % (self.product, self.vendor) | ||||
| 
 | ||||
|     def __unicode__(self): | ||||
|         if self.unit_cost is None: | ||||
|             return u'' | ||||
|         return '$ %0.4f (%s)' % (self.unit_cost, self.vendor) | ||||
| 
 | ||||
| 
 | ||||
| class Employee(Model): | ||||
|     """ | ||||
|     Represents an employee within the organization. | ||||
|     """ | ||||
| 
 | ||||
|     class Meta(Model.Meta): | ||||
|         db_table = Model.prefix('employees') | ||||
|         verbose_name = "Employee" | ||||
| 
 | ||||
|     EMPLOYEE_STATUS_CHOICES = enum_to_choices(EMPLOYEE_STATUS) | ||||
| 
 | ||||
|     uuid = uuid_field() | ||||
|     id = models.IntegerField(blank=True, null=True, verbose_name="ID") | ||||
|     person = models.ForeignKey('Person', db_column='person_uuid') | ||||
|     status = models.IntegerField(choices=EMPLOYEE_STATUS_CHOICES) | ||||
|     display_name = models.CharField(max_length=100, blank=True, null=True, verbose_name="Display Name") | ||||
| 
 | ||||
|     def __repr__(self): | ||||
|         return "<Employee: %s>" % self.person | ||||
| 
 | ||||
|     def __unicode__(self): | ||||
|         return unicode(self.display_name or self.person) | ||||
| 
 | ||||
|     def save(self, *args, **kwargs): | ||||
|         if not self.display_name and self.person: | ||||
|             if self.person.display_name: | ||||
|                 self.display_name = self.person.display_name | ||||
|             elif self.person.first_name and self.person.last_name: | ||||
|                 self.display_name = self.person.first_name + ' ' + self.person.last_name | ||||
|             elif self.person.first_name: | ||||
|                 self.display_name = self.person.first_name | ||||
|             elif self.person.last_name: | ||||
|                 self.display_name = self.person.last_name | ||||
|         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): | ||||
|     """ | ||||
|     Represents a customer account.  Customer accounts may consist of more than | ||||
|     one :class:`Person`, in some cases. | ||||
|     """ | ||||
| 
 | ||||
|     class Meta(Model.Meta): | ||||
|         db_table = Model.prefix('customers') | ||||
|         verbose_name = "Customer" | ||||
| 
 | ||||
|     EMAIL_PREFERENCE_CHOICES = enum_to_choices(EMAIL_PREFERENCE) | ||||
| 
 | ||||
|     uuid = uuid_field() | ||||
|     id = models.CharField(max_length=20, null=True, blank=True, verbose_name="ID") | ||||
|     name = models.CharField(max_length=255, null=True, blank=True) | ||||
|     email_preference = models.IntegerField(choices=EMAIL_PREFERENCE_CHOICES, null=True, blank=True, verbose_name="Email Preference") | ||||
| 
 | ||||
|     def __repr__(self): | ||||
|         return "<Customer: %s, %s>" % (self.id, self.name) | ||||
| 
 | ||||
|     def __unicode__(self): | ||||
|         return unicode(self.name or '') | ||||
| 
 | ||||
| 
 | ||||
| class CustomerContactInfo(models.Model): | ||||
|     """ | ||||
|     Base class for customer contact models (phone number, etc.). | ||||
|     """ | ||||
| 
 | ||||
|     class Meta: | ||||
|         abstract = True | ||||
| 
 | ||||
|     customer = models.ForeignKey(Customer, db_column='parent_uuid') | ||||
|     objects = ContactInfoManager('Customer') | ||||
| 
 | ||||
|     def save(self, *args, **kwargs): | ||||
|         self.parent_type = 'Customer' | ||||
|         super(CustomerContactInfo, self).save(*args, **kwargs) | ||||
| 
 | ||||
| 
 | ||||
| class CustomerPhoneNumber(PhoneNumber, CustomerContactInfo): | ||||
|     """ | ||||
|     Represents a phone (or fax) number associated with a :class:`Customer`. | ||||
|     """ | ||||
| 
 | ||||
| 
 | ||||
| class CustomerEmailAddress(EmailAddress, CustomerContactInfo): | ||||
|     """ | ||||
|     Represents an email address associated with a :class:`Customer`. | ||||
|     """ | ||||
| 
 | ||||
| 
 | ||||
| class CustomerPerson(Model): | ||||
|     """ | ||||
|     Represents the association between a :class:`Person` and a customer account | ||||
|     (:class:`Customer`). | ||||
|     """ | ||||
| 
 | ||||
|     class Meta(Model.Meta): | ||||
|         db_table = Model.prefix('customers_people') | ||||
|         verbose_name = "Customer Person" | ||||
| 
 | ||||
|     uuid = uuid_field() | ||||
|     customer = models.ForeignKey(Customer, db_column='customer_uuid') | ||||
|     person = models.ForeignKey('Person', db_column='person_uuid') | ||||
|     ordinal = models.IntegerField() | ||||
| 
 | ||||
|     def __repr__(self): | ||||
|         return "<CustomerPerson: %s>" % self.person | ||||
| 
 | ||||
|     def __unicode__(self): | ||||
|         return unicode(self.person or '') | ||||
| 
 | ||||
| 
 | ||||
| class CustomerGroup(Model): | ||||
|     """ | ||||
|     Represents an arbitrary group to which :class:`Customer` instances may (or | ||||
|     may not) belong. | ||||
|     """ | ||||
| 
 | ||||
|     class Meta(Model.Meta): | ||||
|         db_table = Model.prefix('customer_groups') | ||||
|         verbose_name = "Customer Group" | ||||
| 
 | ||||
|     uuid = uuid_field() | ||||
|     id = models.CharField(max_length=20, blank=True, null=True, verbose_name="ID") | ||||
|     name = models.CharField(max_length=255, blank=True, null=True) | ||||
| 
 | ||||
|     def __repr__(self): | ||||
|         return "<CustomerGroup: %s, %s>" % (self.id, self.name) | ||||
| 
 | ||||
|     def __unicode__(self): | ||||
|         return unicode(self.name or '') | ||||
| 
 | ||||
| 
 | ||||
| class CustomerGroupAssignment(Model): | ||||
|     """ | ||||
|     Represents the assignment of a :class:`Customer` to a | ||||
|     :class:`CustomerGroup`. | ||||
|     """ | ||||
| 
 | ||||
|     class Meta(Model.Meta): | ||||
|         db_table = Model.prefix('customers_groups') | ||||
|         verbose_name = "Customer Group Assignment" | ||||
| 
 | ||||
|     uuid = uuid_field() | ||||
|     customer = models.ForeignKey(Customer, db_column='customer_uuid') | ||||
|     group = models.ForeignKey(CustomerGroup, db_column='group_uuid') | ||||
|     ordinal = models.IntegerField() | ||||
| 
 | ||||
|     def __repr__(self): | ||||
|         return "<CustomerGroupAssignment: %s, %s>" % (self.customer, self.group) | ||||
| 
 | ||||
|     def __unicode__(self): | ||||
|         return u'%s, %s' % (self.customer, self.group) | ||||
| 
 | ||||
| 
 | ||||
| class LabelProfile(Model): | ||||
|     """ | ||||
|     Represents a "profile" (collection of settings) for product label printing. | ||||
|     """ | ||||
| 
 | ||||
|     class Meta(Model.Meta): | ||||
|         db_table = Model.prefix('label_profiles') | ||||
|         verbose_name = "Label Profile" | ||||
| 
 | ||||
|     uuid = uuid_field() | ||||
|     ordinal = models.IntegerField(blank=True, null=True) | ||||
|     code = models.CharField(max_length=3, blank=True, null=True) | ||||
|     description = models.CharField(max_length=50, blank=True, null=True) | ||||
|     printer_spec = models.CharField(max_length=255, blank=True, null=True, verbose_name="Printer Spec") | ||||
|     formatter_spec = models.CharField(max_length=255, blank=True, null=True, verbose_name="Formatter Spec") | ||||
|     format = models.TextField(blank=True, null=True) | ||||
|     visible = models.BooleanField() | ||||
| 
 | ||||
|     def __repr__(self): | ||||
|         return "<LabelProfile: %s>" % self.code | ||||
| 
 | ||||
|     def __unicode__(self): | ||||
|         return unicode(self.description or '') | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Lance Edgar
						Lance Edgar