models.py 6.84 KB
Newer Older
Skia's avatar
Skia committed
1
2
from django.db import models
from django.utils.translation import ugettext_lazy as _
3
from django.utils import timezone
Skia's avatar
Skia committed
4
from django.conf import settings
Skia's avatar
Skia committed
5
from django.core.urlresolvers import reverse
Skia's avatar
Skia committed
6

7
8
from datetime import timedelta

Skia's avatar
Skia committed
9
from club.models import Club
10
11
from accounting.models import CurrencyField
from core.models import Group, User
12
from subscription.models import Subscriber
Skia's avatar
Skia committed
13

14
15
16
17
18
19
20
class Customer(models.Model):
    """
    This class extends a user to make a customer. It adds some basic customers informations, such as the accound ID, and
    is used by other accounting classes as reference to the customer, rather than using User
    """
    user = models.OneToOneField(User, primary_key=True)
    account_id = models.CharField(_('account id'), max_length=10, unique=True)
Skia's avatar
Skia committed
21
    amount = CurrencyField(_('amount'))
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74

    class Meta:
        verbose_name = _('customer')
        verbose_name_plural = _('customers')

    def __str__(self):
        return self.user.username

class ProductType(models.Model):
    """
    This describes a product type
    Useful only for categorizing, changes are made at the product level for now
    """
    name = models.CharField(_('name'), max_length=30)
    description = models.TextField(_('description'), null=True, blank=True)
    icon = models.ImageField(upload_to='products', null=True, blank=True)

    def is_owned_by(self, user):
        """
        Method to see if that object can be edited by the given user
        """
        if user.is_in_group(settings.SITH_GROUPS['accounting-admin']['name']):
            return True
        return False

    def __str__(self):
        return self.name

class Product(models.Model):
    """
    This describes a product, with all its related informations
    """
    name = models.CharField(_('name'), max_length=30)
    description = models.TextField(_('description'), blank=True)
    product_type = models.ForeignKey(ProductType, related_name='products', null=True, blank=True)
    code = models.CharField(_('code'), max_length=10)
    purchase_price = CurrencyField(_('purchase price'))
    selling_price = CurrencyField(_('selling price'))
    special_selling_price = CurrencyField(_('special selling price'))
    icon = models.ImageField(upload_to='products', null=True, blank=True)
    club = models.ForeignKey(Club, related_name="products")

    def is_owned_by(self, user): # TODO do this for all models
        """
        Method to see if that object can be edited by the given user
        """
        if user.is_in_group(settings.SITH_GROUPS['accounting-admin']['name']):
            return True
        return False

    def __str__(self):
        return self.name

Skia's avatar
Skia committed
75
76
77
78
class Counter(models.Model):
    name = models.CharField(_('name'), max_length=30)
    club = models.ForeignKey(Club, related_name="counters")
    products = models.ManyToManyField(Product, related_name="counters", blank=True)
Skia's avatar
Skia committed
79
80
    type = models.CharField(_('subscription type'),
            max_length=255,
Skia's avatar
Skia committed
81
            choices=[('BAR',_('Bar')), ('OFFICE',_('Office'))])
Skia's avatar
Skia committed
82
83
    edit_groups = models.ManyToManyField(Group, related_name="editable_counters", blank=True)
    view_groups = models.ManyToManyField(Group, related_name="viewable_counters", blank=True)
Skia's avatar
Skia committed
84
    barmen_session = {}
Skia's avatar
Skia committed
85
86
87

    def __getattribute__(self, name):
        if name == "owner_group":
88
            return Group.objects.filter(name=self.club.unix_name+settings.SITH_BOARD_SUFFIX).first()
Skia's avatar
Skia committed
89
90
91
92
        return object.__getattribute__(self, name)

    def __str__(self):
        return self.name
Skia's avatar
Skia committed
93
94
95
96

    def get_absolute_url(self):
        return reverse('counter:details', kwargs={'counter_id': self.id})

97
98
99
    def can_be_edited_by(self, user):
        return user.is_in_group(settings.SITH_GROUPS['counter-admin']['name'])

Skia's avatar
Skia committed
100
    def can_be_viewed_by(self, user):
Skia's avatar
Skia committed
101
        return user.is_in_group(settings.SITH_MAIN_BOARD_GROUP)
102
103
104
105
106
107
108
109
110
111
112
113
114

    def get_barmen_list(counter_id):
        bl = []
        counter_id = str(counter_id)
        if counter_id in list(Counter.barmen_session.keys()):
            if (timezone.now() - Counter.barmen_session[counter_id]['time']) < timedelta(minutes=settings.SITH_BARMAN_TIMEOUT):
                for b in Counter.barmen_session[counter_id]['users']:
                    bl.append(Subscriber.objects.filter(id=b).first())
                Counter.barmen_session[counter_id]['time'] = timezone.now()
            else:
                Counter.barmen_session[counter_id]['users'] = set()
        return bl

Skia's avatar
Skia committed
115
116
117
118
119
120
121
122
123
124
    def get_random_barman(counter_id): # TODO: improve this function
        bl = Counter.get_barmen_list(counter_id)
        return bl[0]

class Refilling(models.Model):
    """
    Handle the refilling
    """
    counter = models.ForeignKey(Counter, related_name="refillings", blank=False)
    amount = CurrencyField(_('amount'))
125
126
    operator = models.ForeignKey(User, related_name="refillings_as_operator", blank=False)
    customer = models.ForeignKey(Customer, related_name="refillings", blank=False)
Skia's avatar
Skia committed
127
128
    date = models.DateTimeField(_('date'), auto_now=True)
    payment_method = models.CharField(_('payment method'), max_length=255,
129
130
131
            choices=settings.SITH_COUNTER_PAYMENT_METHOD, default='cash')
    bank = models.CharField(_('bank'), max_length=255,
            choices=settings.SITH_COUNTER_BANK, default='other')
Skia's avatar
Skia committed
132
133

    def __str__(self):
Skia's avatar
Skia committed
134
        return "Refilling: %.2f for %s" % (self.amount, self.customer.user.get_display_name())
Skia's avatar
Skia committed
135
136
137
138
139
140

    # def get_absolute_url(self):
    #     return reverse('counter:details', kwargs={'counter_id': self.id})

    def save(self, *args, **kwargs):
        self.full_clean()
Skia's avatar
Skia committed
141
        self.customer.amount += self.amount
Skia's avatar
Skia committed
142
        self.customer.save()
Skia's avatar
Skia committed
143
        super(Refilling, self).save(*args, **kwargs)
Skia's avatar
Skia committed
144
145
146
147
148
149
150
151
152

class Selling(models.Model):
    """
    Handle the sellings
    """
    product = models.ForeignKey(Product, related_name="sellings", blank=False)
    counter = models.ForeignKey(Counter, related_name="sellings", blank=False)
    unit_price = CurrencyField(_('unit price'))
    quantity = models.IntegerField(_('quantity'))
153
154
    seller = models.ForeignKey(User, related_name="sellings_as_operator", blank=False)
    customer = models.ForeignKey(Customer, related_name="buyings", blank=False)
Skia's avatar
Skia committed
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
    date = models.DateTimeField(_('date'), auto_now=True)

    def __str__(self):
        return "Selling: %d x %s (%f) for %s" % (self.quantity, self.product.name,
                self.quantity*self.unit_price, self.customer.user.get_display_name())

    def save(self, *args, **kwargs):
        self.full_clean()
        self.customer.amount -= self.quantity * self.unit_price
        self.customer.save()
        super(Selling, self).save(*args, **kwargs)

    # def get_absolute_url(self):
    #     return reverse('counter:details', kwargs={'counter_id': self.id})

170
171
172
173
174
175

# TODO:
# une classe Vente
# foreign key vers comptoir, vendeur, client, produit, mais stocker le prix du produit, pour gerer les maj de prix
# une classe Rechargement
# foreign key vers comptoir, vendeur, client, plus montant
Skia's avatar
Skia committed
176