diff --git a/accounting/migrations/0003_auto_20160509_0712.py b/accounting/migrations/0003_auto_20160509_0712.py new file mode 100644 index 00000000..4b6e26a7 --- /dev/null +++ b/accounting/migrations/0003_auto_20160509_0712.py @@ -0,0 +1,32 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('club', '0001_initial'), + ('accounting', '0002_auto_20160502_0952'), + ] + + operations = [ + migrations.AddField( + model_name='bankaccount', + name='club', + field=models.OneToOneField(to='club.Club', related_name='bank_accounts', default=1), + preserve_default=False, + ), + migrations.AddField( + model_name='product', + name='club', + field=models.OneToOneField(to='club.Club', related_name='products', default=1), + preserve_default=False, + ), + migrations.AlterField( + model_name='clubaccount', + name='club', + field=models.OneToOneField(related_name='club_account', to='club.Club'), + ), + ] diff --git a/accounting/migrations/0004_auto_20160509_0715.py b/accounting/migrations/0004_auto_20160509_0715.py new file mode 100644 index 00000000..a73359f2 --- /dev/null +++ b/accounting/migrations/0004_auto_20160509_0715.py @@ -0,0 +1,19 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('accounting', '0003_auto_20160509_0712'), + ] + + operations = [ + migrations.AlterField( + model_name='product', + name='club', + field=models.ForeignKey(related_name='products', to='club.Club'), + ), + ] diff --git a/accounting/migrations/0005_auto_20160509_0716.py b/accounting/migrations/0005_auto_20160509_0716.py new file mode 100644 index 00000000..e4ab3be4 --- /dev/null +++ b/accounting/migrations/0005_auto_20160509_0716.py @@ -0,0 +1,19 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('accounting', '0004_auto_20160509_0715'), + ] + + operations = [ + migrations.AlterField( + model_name='bankaccount', + name='club', + field=models.ForeignKey(related_name='bank_accounts', to='club.Club'), + ), + ] diff --git a/accounting/models.py b/accounting/models.py index d8a4b785..3508928b 100644 --- a/accounting/models.py +++ b/accounting/models.py @@ -39,19 +39,7 @@ class Customer(models.Model): def __str__(self): return self.user.username -class AccountingMixin(): - """ - Mixin providing the rights managment for all accounting classes - """ - def can_be_edited_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 - -class ProductType(models.Model, AccountingMixin): +class ProductType(models.Model): """ This describes a product type Useful only for categorizing, changes are made at the product level for now @@ -60,10 +48,18 @@ class ProductType(models.Model, AccountingMixin): 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, AccountingMixin): +class Product(models.Model): """ This describes a product, with all its related informations """ @@ -75,14 +71,35 @@ class Product(models.Model, AccountingMixin): 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 -class BankAccount(models.Model, AccountingMixin): +class BankAccount(models.Model): name = models.CharField(_('name'), max_length=30) rib = models.CharField(_('rib'), max_length=255, blank=True) number = models.CharField(_('account number'), max_length=255, blank=True) + club = models.ForeignKey(Club, related_name="bank_accounts") + + 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 + m = self.club.get_membership_for(user) + if m is not None and m.role >= 7: + return True + return False def get_absolute_url(self): return reverse('accounting:bank_details', kwargs={'b_account_id': self.id}) @@ -90,18 +107,35 @@ class BankAccount(models.Model, AccountingMixin): def __str__(self): return self.name -class ClubAccount(models.Model, AccountingMixin): +class ClubAccount(models.Model): name = models.CharField(_('name'), max_length=30) - club = models.OneToOneField(Club, related_name="club_accounts") + club = models.OneToOneField(Club, related_name="club_account") bank_account = models.ForeignKey(BankAccount, related_name="club_accounts") + 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 can_be_edited_by(self, user): + """ + Method to see if that object can be edited by the given user + """ + m = self.club.get_membership_for(user) + if m is not None and m.role >= 7: + return True + return False + def get_absolute_url(self): return reverse('accounting:club_details', kwargs={'c_account_id': self.id}) def __str__(self): return self.name -class GeneralJournal(models.Model, AccountingMixin): +class GeneralJournal(models.Model): """ Class storing all the operations for a period of time """ @@ -111,13 +145,29 @@ class GeneralJournal(models.Model, AccountingMixin): closed = models.BooleanField(_('is closed'), default=False) club_account = models.ForeignKey(ClubAccount, related_name="journals", null=False) + 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 can_be_edited_by(self, user): + """ + Method to see if that object can be edited by the given user + """ + if self.club_account.can_be_edited_by(user): + return True + return False + def get_absolute_url(self): return reverse('accounting:journal_details', kwargs={'j_id': self.id}) def __str__(self): return self.name -class AccountingType(models.Model, AccountingMixin): +class AccountingType(models.Model): """ Class describing the accounting types. @@ -127,13 +177,21 @@ class AccountingType(models.Model, AccountingMixin): label = models.CharField(_('label'), max_length=60) movement_type = models.CharField(_('movement type'), choices=[('credit', 'Credit'), ('debit', 'Debit'), ('neutral', 'Neutral')], max_length=12) + 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 get_absolute_url(self): return reverse('accounting:type_list') def __str__(self): return self.movement_type+" - "+self.code+" - "+self.label -class Operation(models.Model, AccountingMixin): +class Operation(models.Model): """ An operation is a line in the journal, a debit or a credit """ @@ -146,6 +204,26 @@ class Operation(models.Model, AccountingMixin): done = models.BooleanField(_('is done'), default=False) type = models.ForeignKey(AccountingType, related_name="operations") + 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 + m = self.journal.club_account.get_membership_for(user) + if m is not None and m.role >= 7: + return True + return False + + def can_be_edited_by(self, user): + """ + Method to see if that object can be edited by the given user + """ + if self.journal.can_be_edited_by(user): + return True + return False + + def get_absolute_url(self): return reverse('accounting:journal_details', kwargs={'j_id': self.journal.id}) diff --git a/accounting/views.py b/accounting/views.py index e0f576b3..e6e758b4 100644 --- a/accounting/views.py +++ b/accounting/views.py @@ -24,7 +24,7 @@ class AccountingTypeEditView(CanViewMixin, UpdateView): fields = ['code', 'label', 'movement_type'] template_name = 'accounting/account_edit.jinja' -class AccountingTypeCreateView(CanEditMixin, CreateView): +class AccountingTypeCreateView(CanEditPropMixin, CreateView): """ Create an accounting type (for the admins) """ @@ -58,7 +58,7 @@ class BankAccountDetailView(CanViewMixin, DetailView): pk_url_kwarg = "b_account_id" template_name = 'accounting/bank_account_details.jinja' -class BankAccountCreateView(CanEditMixin, CreateView): +class BankAccountCreateView(CanEditPropMixin, CreateView): """ Create a bank account (for the admins) """ @@ -66,7 +66,7 @@ class BankAccountCreateView(CanEditMixin, CreateView): fields = ['name', 'rib', 'number'] template_name = 'accounting/account_edit.jinja' -class BankAccountDeleteView(CanEditMixin, DeleteView): # TODO change Delete to Close +class BankAccountDeleteView(CanEditPropMixin, DeleteView): # TODO change Delete to Close """ Delete a bank account (for the admins) """ @@ -94,7 +94,7 @@ class ClubAccountDetailView(CanViewMixin, DetailView): pk_url_kwarg = "c_account_id" template_name = 'accounting/club_account_details.jinja' -class ClubAccountCreateView(CanEditMixin, CreateView): +class ClubAccountCreateView(CanEditPropMixin, CreateView): """ Create a club account (for the admins) """ @@ -102,7 +102,7 @@ class ClubAccountCreateView(CanEditMixin, CreateView): fields = ['name', 'club', 'bank_account'] template_name = 'accounting/account_edit.jinja' -class ClubAccountDeleteView(CanEditMixin, DeleteView): # TODO change Delete to Close +class ClubAccountDeleteView(CanEditPropMixin, DeleteView): # TODO change Delete to Close """ Delete a club account (for the admins) """ diff --git a/club/templates/club/club_tools.jinja b/club/templates/club/club_tools.jinja new file mode 100644 index 00000000..9649c8da --- /dev/null +++ b/club/templates/club/club_tools.jinja @@ -0,0 +1,12 @@ +{% extends "core/base.jinja" %} + +{% block content %} +