mirror of
				https://github.com/more-tech4-magnum-opus/backend.git
				synced 2025-11-04 01:27:35 +03:00 
			
		
		
		
	added blockchain operations, transaction history, minor optimisations
This commit is contained in:
		
							parent
							
								
									12f81dbf3f
								
							
						
					
					
						commit
						79587c322d
					
				
							
								
								
									
										0
									
								
								app/blockchain/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								app/blockchain/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										3
									
								
								app/blockchain/admin.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								app/blockchain/admin.py
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,3 @@
 | 
			
		|||
from django.contrib import admin
 | 
			
		||||
 | 
			
		||||
# Register your models here.
 | 
			
		||||
							
								
								
									
										6
									
								
								app/blockchain/apps.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								app/blockchain/apps.py
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,6 @@
 | 
			
		|||
from django.apps import AppConfig
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class BlockchainConfig(AppConfig):
 | 
			
		||||
    default_auto_field = 'django.db.models.BigAutoField'
 | 
			
		||||
    name = 'blockchain'
 | 
			
		||||
							
								
								
									
										15
									
								
								app/blockchain/migrations/0001_initial.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								app/blockchain/migrations/0001_initial.py
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,15 @@
 | 
			
		|||
# Generated by Django 4.0.8 on 2022-10-08 17:58
 | 
			
		||||
 | 
			
		||||
from django.conf import settings
 | 
			
		||||
import django.core.validators
 | 
			
		||||
from django.db import migrations, models
 | 
			
		||||
import django.db.models.deletion
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Migration(migrations.Migration):
 | 
			
		||||
 | 
			
		||||
    initial = True
 | 
			
		||||
 | 
			
		||||
    dependencies = []
 | 
			
		||||
 | 
			
		||||
    operations = []
 | 
			
		||||
							
								
								
									
										0
									
								
								app/blockchain/migrations/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								app/blockchain/migrations/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										52
									
								
								app/blockchain/models.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										52
									
								
								app/blockchain/models.py
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,52 @@
 | 
			
		|||
from django.core.validators import MinValueValidator
 | 
			
		||||
from django.db import models
 | 
			
		||||
 | 
			
		||||
# Create your models here.
 | 
			
		||||
from users.models import User
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Transaction(models.Model):
 | 
			
		||||
    user_from = models.ForeignKey(
 | 
			
		||||
        User, related_name="transactions_from", on_delete=models.CASCADE
 | 
			
		||||
    )
 | 
			
		||||
    user_to = models.ForeignKey(
 | 
			
		||||
        User, related_name="transactions_to", on_delete=models.CASCADE
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
    amount = models.IntegerField(validators=[MinValueValidator(1)])
 | 
			
		||||
 | 
			
		||||
    created = models.DateTimeField(auto_now_add=True)
 | 
			
		||||
 | 
			
		||||
    hash = models.CharField(max_length=256, unique=True)
 | 
			
		||||
 | 
			
		||||
    def __str__(self):
 | 
			
		||||
        return f"transaction from {self.user_from} to {self.user_to}"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class AdminTransaction(models.Model):
 | 
			
		||||
    class TransactionType(models.TextChoices):
 | 
			
		||||
        FROM = "PAYMENT", "payment"
 | 
			
		||||
        TO = "SALARY", "salary"
 | 
			
		||||
 | 
			
		||||
    type = models.CharField(max_length=7, choices=TransactionType.choices)
 | 
			
		||||
    amount = models.IntegerField(validators=[MinValueValidator(1)])
 | 
			
		||||
    user = models.ForeignKey(
 | 
			
		||||
        User, related_name="admin_transactions", on_delete=models.CASCADE
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
    created = models.DateTimeField(auto_now_add=True)
 | 
			
		||||
 | 
			
		||||
    hash = models.CharField(max_length=256, unique=True)
 | 
			
		||||
 | 
			
		||||
    @property
 | 
			
		||||
    def user_from(self):
 | 
			
		||||
        return "system" if self.type == self.TransactionType.TO else self.user.username
 | 
			
		||||
 | 
			
		||||
    @property
 | 
			
		||||
    def user_to(self):
 | 
			
		||||
        return (
 | 
			
		||||
            "system" if self.type == self.TransactionType.FROM else self.user.username
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
    def __str__(self):
 | 
			
		||||
        return str(self.amount)
 | 
			
		||||
							
								
								
									
										38
									
								
								app/blockchain/services.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								app/blockchain/services.py
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,38 @@
 | 
			
		|||
from django.conf import settings
 | 
			
		||||
 | 
			
		||||
from blockchain.models import Transaction, AdminTransaction
 | 
			
		||||
from users.models import User
 | 
			
		||||
from utils.blockchain import transfer_rubbles
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def list_user_transactions(user: User) -> list:
 | 
			
		||||
    transaction = []
 | 
			
		||||
    qs = (
 | 
			
		||||
        user.transactions_to.all()
 | 
			
		||||
        | user.transactions_from.all()
 | 
			
		||||
        | user.admin_transactions.all()
 | 
			
		||||
    )
 | 
			
		||||
    qs.order_by("created")
 | 
			
		||||
    username = user.username
 | 
			
		||||
    for el in qs:  # type: Transaction
 | 
			
		||||
        transaction.append(
 | 
			
		||||
            {
 | 
			
		||||
                "type": "addition" if el.user_from.username == username else "transfer",
 | 
			
		||||
                "user_from": el.user_from.username,
 | 
			
		||||
                "user_to": el.user_to.username,
 | 
			
		||||
                "amount": el.amount,
 | 
			
		||||
            }
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
    return transaction
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def transact_from_admin(user: User, amount: int):
 | 
			
		||||
    priv_key = settings.MAIN_WALLET
 | 
			
		||||
    t = transfer_rubbles(priv_key, user.wallet_public_key, amount)
 | 
			
		||||
    AdminTransaction.objects.create(
 | 
			
		||||
        type="SALARY", amount=amount, user=user, hash=t.transaction_hash
 | 
			
		||||
    )
 | 
			
		||||
    user.money += amount
 | 
			
		||||
    user.save(update_fields=["money"])
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										40
									
								
								app/blockchain/signals.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								app/blockchain/signals.py
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,40 @@
 | 
			
		|||
from django.db.models.signals import pre_save
 | 
			
		||||
from django.dispatch import receiver
 | 
			
		||||
from rest_framework.exceptions import ValidationError
 | 
			
		||||
 | 
			
		||||
from blockchain.models import Transaction
 | 
			
		||||
from utils.blockchain import get_balance, transfer_rubbles
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@receiver(pre_save, sender=Transaction)
 | 
			
		||||
def validate_create_transaction(sender, instance: Transaction, **kwargs):
 | 
			
		||||
    # validate transaction
 | 
			
		||||
    if instance.user_from == instance.user_to:
 | 
			
		||||
        raise ValidationError("Cannot transfer to yourself")
 | 
			
		||||
 | 
			
		||||
    if instance.amount == 0:
 | 
			
		||||
        raise ValidationError("Cannot transfer 0 money")
 | 
			
		||||
 | 
			
		||||
    #  Potential Race condition, use transaction with atomics in prod
 | 
			
		||||
    user_from_money = int(get_balance(instance.user_from.wallet_public_key).coins)
 | 
			
		||||
    if instance.user_from.money != user_from_money:
 | 
			
		||||
        instance.user_from.money = user_from_money
 | 
			
		||||
        instance.user_from.save(update_fields=["money"])
 | 
			
		||||
 | 
			
		||||
    if user_from_money - instance.amount <= 0:
 | 
			
		||||
        raise ValidationError(
 | 
			
		||||
            f"{instance.user_from.username} doesn't have enough money"
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
    transaction = transfer_rubbles(
 | 
			
		||||
        instance.user_from.wallet_private_key,
 | 
			
		||||
        instance.user_to.wallet_public_key,
 | 
			
		||||
        amount=instance.amount,
 | 
			
		||||
    )
 | 
			
		||||
    instance.user_from.money -= instance.amount
 | 
			
		||||
    instance.user_from.save(update_fields=["money"])
 | 
			
		||||
 | 
			
		||||
    instance.user_to.money += instance.amount
 | 
			
		||||
    instance.user_to.save(update_fields=["money"])
 | 
			
		||||
 | 
			
		||||
    instance.hash = transaction.transaction_hash
 | 
			
		||||
| 
						 | 
				
			
			@ -9,37 +9,6 @@ class Migration(migrations.Migration):
 | 
			
		|||
 | 
			
		||||
    initial = True
 | 
			
		||||
 | 
			
		||||
    dependencies = [
 | 
			
		||||
        migrations.swappable_dependency(settings.AUTH_USER_MODEL),
 | 
			
		||||
    ]
 | 
			
		||||
    dependencies = []
 | 
			
		||||
 | 
			
		||||
    operations = [
 | 
			
		||||
        migrations.CreateModel(
 | 
			
		||||
            name='Event',
 | 
			
		||||
            fields=[
 | 
			
		||||
                ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
 | 
			
		||||
                ('name', models.CharField(max_length=100)),
 | 
			
		||||
                ('slug', models.SlugField(max_length=8)),
 | 
			
		||||
                ('about', models.TextField(blank=True)),
 | 
			
		||||
                ('starts', models.DateTimeField()),
 | 
			
		||||
                ('image', models.ImageField(blank=True, upload_to='uploads/')),
 | 
			
		||||
                ('image_cropped', models.ImageField(blank=True, upload_to='cropped/')),
 | 
			
		||||
                ('planning', models.IntegerField(default=0)),
 | 
			
		||||
                ('attended', models.IntegerField(default=0)),
 | 
			
		||||
                ('creator', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='events_created', to=settings.AUTH_USER_MODEL)),
 | 
			
		||||
            ],
 | 
			
		||||
            options={
 | 
			
		||||
                'ordering': ['-starts'],
 | 
			
		||||
            },
 | 
			
		||||
        ),
 | 
			
		||||
        migrations.CreateModel(
 | 
			
		||||
            name='EventAttendance',
 | 
			
		||||
            fields=[
 | 
			
		||||
                ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
 | 
			
		||||
                ('token', models.CharField(max_length=128, unique=True)),
 | 
			
		||||
                ('attended', models.BooleanField(default=False)),
 | 
			
		||||
                ('event', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='people', to='events.event')),
 | 
			
		||||
                ('worker', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='events', to=settings.AUTH_USER_MODEL)),
 | 
			
		||||
            ],
 | 
			
		||||
        ),
 | 
			
		||||
    ]
 | 
			
		||||
    operations = []
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										32
									
								
								app/fixtures/departmens.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								app/fixtures/departmens.json
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,32 @@
 | 
			
		|||
[
 | 
			
		||||
{
 | 
			
		||||
    "model": "users.department",
 | 
			
		||||
    "pk": 1,
 | 
			
		||||
    "fields": {
 | 
			
		||||
        "name": "Backend"
 | 
			
		||||
    }
 | 
			
		||||
},
 | 
			
		||||
{
 | 
			
		||||
    "model": "users.department",
 | 
			
		||||
    "pk": 2,
 | 
			
		||||
    "fields": {
 | 
			
		||||
        "name": "Frontend"
 | 
			
		||||
    }
 | 
			
		||||
},
 | 
			
		||||
{
 | 
			
		||||
    "model": "users.stream",
 | 
			
		||||
    "pk": 1,
 | 
			
		||||
    "fields": {
 | 
			
		||||
        "name": "Colloring buttons",
 | 
			
		||||
        "department": 2
 | 
			
		||||
    }
 | 
			
		||||
},
 | 
			
		||||
{
 | 
			
		||||
    "model": "users.command",
 | 
			
		||||
    "pk": 1,
 | 
			
		||||
    "fields": {
 | 
			
		||||
        "name": "Colloring main page button go get money",
 | 
			
		||||
        "stream": 1
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
]
 | 
			
		||||
| 
						 | 
				
			
			@ -9,22 +9,6 @@ class Migration(migrations.Migration):
 | 
			
		|||
 | 
			
		||||
    initial = True
 | 
			
		||||
 | 
			
		||||
    dependencies = [
 | 
			
		||||
        migrations.swappable_dependency(settings.AUTH_USER_MODEL),
 | 
			
		||||
    ]
 | 
			
		||||
    dependencies = []
 | 
			
		||||
 | 
			
		||||
    operations = [
 | 
			
		||||
        migrations.CreateModel(
 | 
			
		||||
            name='Product',
 | 
			
		||||
            fields=[
 | 
			
		||||
                ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
 | 
			
		||||
                ('name', models.CharField(max_length=200)),
 | 
			
		||||
                ('description', models.TextField()),
 | 
			
		||||
                ('image', models.ImageField(upload_to='uploads/')),
 | 
			
		||||
                ('image_cropped', models.ImageField(blank=True, upload_to='cropped/')),
 | 
			
		||||
                ('nft', models.CharField(blank=True, max_length=500)),
 | 
			
		||||
                ('price', models.IntegerField()),
 | 
			
		||||
                ('creator', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='products', to=settings.AUTH_USER_MODEL)),
 | 
			
		||||
            ],
 | 
			
		||||
        ),
 | 
			
		||||
    ]
 | 
			
		||||
    operations = []
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,7 +1,6 @@
 | 
			
		|||
from rest_framework import serializers
 | 
			
		||||
from ..services import create_season
 | 
			
		||||
from users.models import User, Clan
 | 
			
		||||
from users.models import User, Department, Stream, Command
 | 
			
		||||
from users.models import User, Department, Stream, Command, Clan
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class UserSerializer(serializers.ModelSerializer):
 | 
			
		||||
| 
						 | 
				
			
			@ -19,12 +18,14 @@ class UserSerializer(serializers.ModelSerializer):
 | 
			
		|||
            "command",
 | 
			
		||||
            "department",
 | 
			
		||||
            "clan_name",
 | 
			
		||||
            "money",
 | 
			
		||||
        ]
 | 
			
		||||
        extra_kwargs = {
 | 
			
		||||
            "password": {"write_only": True},
 | 
			
		||||
            "wallet_public_key": {"read_only": True},
 | 
			
		||||
            "clan_name": {"read_only": True},
 | 
			
		||||
            "department": {"read_only": True},
 | 
			
		||||
            "money": {"read_only": True},
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    def create(self, validated_data):
 | 
			
		||||
| 
						 | 
				
			
			@ -41,6 +42,9 @@ class CreateSeasonSerializer(serializers.Serializer):
 | 
			
		|||
        create_season()
 | 
			
		||||
        return {"created": True}
 | 
			
		||||
 | 
			
		||||
    def update(self, instance, validated_data):
 | 
			
		||||
        pass
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class CommandSerializer(serializers.ModelSerializer):
 | 
			
		||||
    workers = UserSerializer(many=True)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -10,110 +10,6 @@ class Migration(migrations.Migration):
 | 
			
		|||
 | 
			
		||||
    initial = True
 | 
			
		||||
 | 
			
		||||
    dependencies = [
 | 
			
		||||
        ("auth", "0012_alter_user_first_name_max_length"),
 | 
			
		||||
    ]
 | 
			
		||||
    dependencies = []
 | 
			
		||||
 | 
			
		||||
    operations = [
 | 
			
		||||
        migrations.CreateModel(
 | 
			
		||||
            name="User",
 | 
			
		||||
            fields=[
 | 
			
		||||
                (
 | 
			
		||||
                    "id",
 | 
			
		||||
                    models.BigAutoField(
 | 
			
		||||
                        auto_created=True,
 | 
			
		||||
                        primary_key=True,
 | 
			
		||||
                        serialize=False,
 | 
			
		||||
                        verbose_name="ID",
 | 
			
		||||
                    ),
 | 
			
		||||
                ),
 | 
			
		||||
                ("password", models.CharField(max_length=128, verbose_name="password")),
 | 
			
		||||
                (
 | 
			
		||||
                    "last_login",
 | 
			
		||||
                    models.DateTimeField(
 | 
			
		||||
                        blank=True, null=True, verbose_name="last login"
 | 
			
		||||
                    ),
 | 
			
		||||
                ),
 | 
			
		||||
                (
 | 
			
		||||
                    "is_superuser",
 | 
			
		||||
                    models.BooleanField(
 | 
			
		||||
                        default=False,
 | 
			
		||||
                        help_text="Designates that this user has all permissions without explicitly assigning them.",
 | 
			
		||||
                        verbose_name="superuser status",
 | 
			
		||||
                    ),
 | 
			
		||||
                ),
 | 
			
		||||
                (
 | 
			
		||||
                    "username",
 | 
			
		||||
                    models.CharField(
 | 
			
		||||
                        error_messages={
 | 
			
		||||
                            "unique": "A user with that username already exists."
 | 
			
		||||
                        },
 | 
			
		||||
                        help_text="Required. 150 characters or fewer. Letters, digits and @/./+/-/_ only.",
 | 
			
		||||
                        max_length=150,
 | 
			
		||||
                        unique=True,
 | 
			
		||||
                        validators=[
 | 
			
		||||
                            django.contrib.auth.validators.UnicodeUsernameValidator()
 | 
			
		||||
                        ],
 | 
			
		||||
                        verbose_name="username",
 | 
			
		||||
                    ),
 | 
			
		||||
                ),
 | 
			
		||||
                (
 | 
			
		||||
                    "email",
 | 
			
		||||
                    models.EmailField(
 | 
			
		||||
                        blank=True, max_length=254, verbose_name="email address"
 | 
			
		||||
                    ),
 | 
			
		||||
                ),
 | 
			
		||||
                (
 | 
			
		||||
                    "is_staff",
 | 
			
		||||
                    models.BooleanField(
 | 
			
		||||
                        default=False,
 | 
			
		||||
                        help_text="Designates whether the user can log into this admin site.",
 | 
			
		||||
                        verbose_name="staff status",
 | 
			
		||||
                    ),
 | 
			
		||||
                ),
 | 
			
		||||
                (
 | 
			
		||||
                    "is_active",
 | 
			
		||||
                    models.BooleanField(
 | 
			
		||||
                        default=True,
 | 
			
		||||
                        help_text="Designates whether this user should be treated as active. Unselect this instead of deleting accounts.",
 | 
			
		||||
                        verbose_name="active",
 | 
			
		||||
                    ),
 | 
			
		||||
                ),
 | 
			
		||||
                (
 | 
			
		||||
                    "date_joined",
 | 
			
		||||
                    models.DateTimeField(
 | 
			
		||||
                        default=django.utils.timezone.now, verbose_name="date joined"
 | 
			
		||||
                    ),
 | 
			
		||||
                ),
 | 
			
		||||
                ("about", models.TextField(blank=True)),
 | 
			
		||||
                (
 | 
			
		||||
                    "groups",
 | 
			
		||||
                    models.ManyToManyField(
 | 
			
		||||
                        blank=True,
 | 
			
		||||
                        help_text="The groups this user belongs to. A user will get all permissions granted to each of their groups.",
 | 
			
		||||
                        related_name="user_set",
 | 
			
		||||
                        related_query_name="user",
 | 
			
		||||
                        to="auth.group",
 | 
			
		||||
                        verbose_name="groups",
 | 
			
		||||
                    ),
 | 
			
		||||
                ),
 | 
			
		||||
                (
 | 
			
		||||
                    "user_permissions",
 | 
			
		||||
                    models.ManyToManyField(
 | 
			
		||||
                        blank=True,
 | 
			
		||||
                        help_text="Specific permissions for this user.",
 | 
			
		||||
                        related_name="user_set",
 | 
			
		||||
                        related_query_name="user",
 | 
			
		||||
                        to="auth.permission",
 | 
			
		||||
                        verbose_name="user permissions",
 | 
			
		||||
                    ),
 | 
			
		||||
                ),
 | 
			
		||||
            ],
 | 
			
		||||
            options={
 | 
			
		||||
                "ordering": ["-id"],
 | 
			
		||||
            },
 | 
			
		||||
            managers=[
 | 
			
		||||
                ("objects", django.contrib.auth.models.UserManager()),
 | 
			
		||||
            ],
 | 
			
		||||
        ),
 | 
			
		||||
    ]
 | 
			
		||||
    operations = []
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -22,7 +22,9 @@ class User(AbstractUser):
 | 
			
		|||
    type = models.CharField(
 | 
			
		||||
        max_length=6, choices=WorkerType.choices, default=WorkerType.WORKER
 | 
			
		||||
    )
 | 
			
		||||
    clan = models.ForeignKey("users.Clan", related_name="users", on_delete=models.SET_NULL, null=True)
 | 
			
		||||
    clan = models.ForeignKey(
 | 
			
		||||
        "users.Clan", related_name="users", on_delete=models.SET_NULL, null=True
 | 
			
		||||
    )
 | 
			
		||||
    command = models.ForeignKey(
 | 
			
		||||
        "users.Command", related_name="workers", on_delete=models.CASCADE
 | 
			
		||||
    )
 | 
			
		||||
| 
						 | 
				
			
			@ -30,6 +32,8 @@ class User(AbstractUser):
 | 
			
		|||
    respect = models.IntegerField(default=0, validators=[MinValueValidator(0)])
 | 
			
		||||
    wallet_private_key = models.CharField(max_length=96, unique=True)
 | 
			
		||||
    wallet_public_key = models.CharField(max_length=96, unique=True)
 | 
			
		||||
    money = models.IntegerField(default=0, validators=[MinValueValidator(0)])
 | 
			
		||||
 | 
			
		||||
    telegram = models.CharField(max_length=100, unique=True)
 | 
			
		||||
 | 
			
		||||
    def __str__(self):
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -2,8 +2,8 @@ from random import shuffle
 | 
			
		|||
 | 
			
		||||
from django.conf import settings
 | 
			
		||||
 | 
			
		||||
from blockchain.services import transact_from_admin
 | 
			
		||||
from .models import Clan, User
 | 
			
		||||
from utils.blockchain import transfer_rubbles
 | 
			
		||||
import requests as r
 | 
			
		||||
import json
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -16,13 +16,13 @@ def end_season():
 | 
			
		|||
            mx_value = sum(map(lambda user: user.respect, clan.users.all()))
 | 
			
		||||
            mx_clan = clan
 | 
			
		||||
    for user in mx_clan.users.all():
 | 
			
		||||
        transfer_rubbles(
 | 
			
		||||
            settings.MAIN_WALLET,
 | 
			
		||||
            user.wallet_public_key,
 | 
			
		||||
            100,
 | 
			
		||||
        )
 | 
			
		||||
        transact_from_admin(user, 100)
 | 
			
		||||
    Clan.objects.all().delete()
 | 
			
		||||
 | 
			
		||||
    for user in User.objects.filter(type=User.WorkerType.WORKER):
 | 
			
		||||
        if user.salary > 0:
 | 
			
		||||
            transact_from_admin(user, user.salary)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def create_chat(clan: Clan):
 | 
			
		||||
    user_list = list(map(lambda user: user.telegram, clan.users.all()))
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue
	
	Block a user