PageRenderTime 59ms CodeModel.GetById 31ms RepoModel.GetById 1ms app.codeStats 0ms

/customers/models.py

https://github.com/LittleForker/django-minishop
Python | 317 lines | 298 code | 12 blank | 7 comment | 6 complexity | 4a83e4679ce5c6c907211e8a6fc5d4e8 MD5 | raw file
  1. from django.db import models
  2. from django.db.models import Q
  3. from django.contrib.comments.models import Comment
  4. import datetime
  5. import random
  6. import re
  7. from django.conf import settings
  8. from django.contrib.auth.models import User
  9. from django.contrib.sites.models import Site
  10. from django.db import transaction
  11. from django.template.loader import render_to_string
  12. from django.utils.hashcompat import sha_constructor
  13. from django.utils.translation import ugettext_lazy as _
  14. from django.contrib.auth.models import User
  15. class LastAddress(Exception):
  16. pass
  17. # Create your models here.
  18. CUSTOMER_TYPES = (
  19. ('1', _('Private')),
  20. ('2', _('Corporate')),
  21. )
  22. SHA1_RE = re.compile('^[a-f0-9]{40}$')
  23. class CustomerManager(models.Manager):
  24. # most manager stuff taken from django.registration by ubernostrum
  25. def activate_user(self, activation_key):
  26. from customers.signals import user_activated
  27. # Make sure the key we're trying conforms to the pattern of a
  28. # SHA1 hash; if it doesn't, no point trying to look it up in
  29. # the database.
  30. if SHA1_RE.search(activation_key):
  31. try:
  32. profile = self.get(activation_key=activation_key)
  33. except self.model.DoesNotExist:
  34. return False
  35. if not profile.activation_key_expired():
  36. user = profile.user
  37. user.is_active = True
  38. user.save()
  39. profile.activation_key = self.model.ACTIVATED
  40. profile.save()
  41. user_activated.send(sender=self.model, user=user)
  42. return user
  43. return False
  44. def create_inactive_user(self, username, password, email, first_name, last_name, send_email=True):
  45. from customers.signals import user_registered
  46. new_user = User.objects.create_user(username, email, password)
  47. new_user.is_active = False
  48. new_user.first_name = first_name
  49. new_user.last_name = last_name
  50. new_user.save()
  51. registration_profile = self.create_profile(new_user)
  52. if send_email:
  53. from django.core.mail import send_mail
  54. current_site = Site.objects.get_current()
  55. #subject = render_to_string('customers/activation_email_subject.txt', { 'site': current_site })
  56. subject = _("Account activation at biolander.com")
  57. # Email subject *must not* contain newlines
  58. subject = ''.join(subject.splitlines())
  59. message = render_to_string('customers/activation_email.txt',
  60. { 'activation_key': registration_profile.activation_key,
  61. 'user': new_user,
  62. # 'expiration_days': settings.ACCOUNT_ACTIVATION_DAYS,
  63. # 'site': current_site
  64. })
  65. send_mail(subject, message, settings.DEFAULT_FROM_EMAIL, [new_user.email])
  66. user_registered.send(sender=self.model, user=new_user)
  67. return new_user
  68. create_inactive_user = transaction.commit_on_success(create_inactive_user)
  69. def create_profile(self, user):
  70. salt = sha_constructor(str(random.random())).hexdigest()[:5]
  71. activation_key = sha_constructor(salt+user.username).hexdigest()
  72. return self.create(user=user, activation_key=activation_key)
  73. def delete_expired_users(self):
  74. for profile in self.all():
  75. if profile.activation_key_expired():
  76. user = profile.user
  77. if not user.is_active:
  78. user.delete()
  79. class Customer(models.Model):
  80. ACTIVATED = u"ALREADY_ACTIVATED"
  81. #TODO: remove company name and customer type
  82. type = models.PositiveIntegerField(choices=CUSTOMER_TYPES, default=1, verbose_name=_("type"), null=True, blank=True)
  83. company_name = models.CharField(max_length=200, null=True, blank=True, verbose_name=_("company name"))
  84. birthdate = models.DateField(null=True, blank=True, verbose_name=_("birth date"))
  85. user = models.ForeignKey(User, unique=True, verbose_name=_("user"))
  86. activation_key = models.CharField(max_length=40, editable=False)
  87. objects = CustomerManager()
  88. newsletter = models.BooleanField(default=False, verbose_name=_("newsletter"))
  89. def get_type(self):
  90. if self.type:
  91. return CUSTOMER_TYPES[int(self.type)-1][1]
  92. def activation_key_expired(self):
  93. expiration_date = datetime.timedelta(days=settings.ACCOUNT_ACTIVATION_DAYS)
  94. return self.activation_key == self.ACTIVATED or \
  95. (self.user.date_joined + expiration_date <= datetime.datetime.now())
  96. activation_key_expired.boolean = True
  97. def __unicode__(self):
  98. if self.user:
  99. return self.user.first_name+" "+self.user.last_name
  100. else:
  101. return 'Customer with incomplete data'
  102. def delete(self):
  103. self.user.delete()
  104. def joined(self):
  105. if self.user:
  106. return self.user.date_joined.strftime("%d-%m-%Y")
  107. joined.admin_order_field = 'user__date_joined'
  108. def first_name(self):
  109. if self.user:
  110. return self.user.first_name
  111. first_name.admin_order_field = 'user__first_name'
  112. def last_name(self):
  113. if self.user:
  114. return self.user.last_name
  115. last_name.admin_order_field = 'user__last_name'
  116. def email(self):
  117. if self.user:
  118. return self.user.email
  119. email.admin_order_field = 'user__email'
  120. def active(self):
  121. if self.user:
  122. return self.user.is_active
  123. active.boolean = True
  124. def shipping_address(self):
  125. try:
  126. return self.address_set.get(is_shipping=True, deleted=False)
  127. except Customer.MultipleObjectsReturned:
  128. return self.address_set.filter(is_shipping=True, deleted=False)[0]
  129. except:
  130. return self.billing_address()
  131. def is_partner(self):
  132. from resellers.models import Partner
  133. if Partner.objects.filter(user=self.user).count():
  134. return True
  135. else:
  136. return False
  137. def is_active_partner(self):
  138. from resellers.models import Partner
  139. try:
  140. partner = Partner.objects.get(user=self.user)
  141. except:
  142. return False
  143. if partner.is_active:
  144. return True
  145. else:
  146. return False
  147. def billing_address(self):
  148. try:
  149. return self.address_set.get(is_billing=True, deleted=False)
  150. except Customer.MultipleObjectsReturned:
  151. return self.address_set.filter(is_billing=True, deleted=False)[0]
  152. except:
  153. if len(self.address_set.filter(is_shipping=True, deleted=False)):
  154. return self.shipping_address()
  155. else:
  156. return None
  157. class AddressManager(models.Manager):
  158. def get_query_set(self):
  159. return super(AddressManager, self).get_query_set().filter(deleted=False)
  160. class Address(models.Model):
  161. customer = models.ForeignKey(Customer, verbose_name=_("customer"))
  162. first_name = models.CharField(max_length=200, verbose_name=_("first name"), blank=True, null=True)
  163. last_name = models.CharField(max_length=200, verbose_name=_("last name"), blank=True, null=True)
  164. company_name = models.CharField(max_length=200, verbose_name=_("company name"), blank=True, null=True)
  165. nip = models.CharField(max_length=13, null=True, blank=True, verbose_name=_("nip"))
  166. city = models.CharField(max_length=200, verbose_name=_("city"))
  167. street = models.CharField(max_length=200, verbose_name=_("street"))
  168. house_number = models.CharField(max_length=200, verbose_name=_("house/flat number"))
  169. postal_code = models.CharField(max_length=200, verbose_name=_("postal code"))
  170. phone_number = models.CharField(max_length=200, verbose_name=_("phone number"))
  171. # address type
  172. is_corporate = models.BooleanField(default=False, verbose_name=_("address type"))
  173. # main billing address?
  174. is_billing = models.BooleanField(default=False, verbose_name=_("is main billing address"))
  175. # main shipping address?
  176. is_shipping = models.BooleanField(default=False, verbose_name=_("is main shipping address"))
  177. deleted = models.BooleanField(default=False, verbose_name=_("the adress has beed deleted by the customer"), editable=False)
  178. @property
  179. def display(self):
  180. if self.is_corporate:
  181. result = """ %(company_name)s <br />
  182. NIP: %(nip)s <br />
  183. %(postal_code)s, %(city)s <br />
  184. %(street)s %(house_number)s
  185. """ % self.__dict__
  186. else:
  187. if not self.first_name and not self.last_name:
  188. self.first_name = self.customer.user.first_name
  189. self.last_name = self.customer.user.last_name
  190. result = """ %(first_name)s %(last_name)s <br />
  191. %(postal_code)s, %(city)s <br />
  192. %(street)s %(house_number)s
  193. """ % self.__dict__
  194. return result
  195. @property
  196. def display_pdf(self):
  197. if self.is_corporate:
  198. result = """ %(company_name)s
  199. NIP: %(nip)s
  200. %(postal_code)s, %(city)s
  201. %(street)s %(house_number)s
  202. """ % self.__dict__
  203. else:
  204. if not self.first_name and not self.last_name:
  205. self.first_name = self.customer.user.first_name
  206. self.last_name = self.customer.user.last_name
  207. result = """ %(first_name)s %(last_name)s
  208. %(postal_code)s, %(city)s
  209. %(street)s %(house_number)s
  210. """ % self.__dict__
  211. return result
  212. objects = models.Manager()
  213. published = AddressManager()
  214. class Meta:
  215. verbose_name = _('address')
  216. verbose_name_plural = _('addresses')
  217. ordering = ('-is_billing','-is_shipping','city')
  218. def __unicode__(self):
  219. return self.city+", "+self.street+" "+self.house_number
  220. def save(self, clean=False):
  221. if not clean:
  222. billing_addresses = self.customer.address_set.filter(is_billing=True, deleted=False)
  223. if self.is_billing and len(billing_addresses) > 0:
  224. billing_addresses.update(is_billing=False)
  225. shipping_addresses = self.customer.address_set.filter(is_shipping=True, deleted=False)
  226. if self.is_shipping and len(shipping_addresses) > 0:
  227. shipping_addresses.update(is_shipping=False)
  228. else:
  229. self.is_shipping = False
  230. self.is_billing = False
  231. if self.is_corporate:
  232. self.first_name = ""
  233. self.last_name = ""
  234. else:
  235. self.nip = ""
  236. self.company_name = ""
  237. super(Address, self).save()
  238. def delete(self, force=False):
  239. if not force:
  240. other_addresses = self.customer.address_set.exclude(Q(pk=self.pk) | Q(deleted=True))
  241. if len(other_addresses) > 0 and self.is_shipping:
  242. try:
  243. billing_address = self.customer.address_set.exclude(pk=self.pk).get(is_billing=True, deleted=False)
  244. except:
  245. billing_address = other_addresses[0]
  246. billing_address.is_shipping = True
  247. billing_address.save()
  248. if len(other_addresses) > 0 and self.is_billing:
  249. try:
  250. shipping_address = self.customer.address_set.exclude(pk=self.pk).get(is_shipping=True, deleted=False)
  251. except:
  252. shipping_address = other_addresses[0]
  253. shipping_address.is_billing = True
  254. shipping_address.save()
  255. if len(other_addresses) == 0:
  256. raise LastAddress
  257. self.deleted = True
  258. self.save(clean=True)
  259. def notify_about_comment(sender, **kwargs):
  260. comment = kwargs['comment']
  261. subject = _("Nowy komentarz do produktu %s" % comment.content_object.name)
  262. subject = ''.join(subject.splitlines())
  263. message = render_to_string('email/new_comment.html', {'comment':comment,})
  264. from django.core.mail import send_mail
  265. send_mail(subject, message, settings.DEFAULT_FROM_EMAIL,
  266. settings.SHOP_STAFF_EMAILS)
  267. from django.contrib.comments.signals import comment_was_posted
  268. # cholera wie czemu wysyla sygnaly po dwa razy, ponizej chamowate
  269. # obejscie, za pomoca argumentu dispatch_uid, wiecej info tu:
  270. # http://www.mail-archive.com/django-users@googlegroups.com/msg71068.html
  271. comment_was_posted.connect(notify_about_comment, Comment,
  272. dispatch_uid='comment.post_comment')