diff --git a/apps/pos_device/models.py b/apps/pos_device/models.py index d60c2cf..43e8e04 100644 --- a/apps/pos_device/models.py +++ b/apps/pos_device/models.py @@ -1,3 +1,4 @@ +import datetime import random import string @@ -36,6 +37,7 @@ class Device(BaseModel): server_in = models.BooleanField(default=False) latitude = models.DecimalField(max_digits=20, decimal_places=10, null=True) longitude = models.DecimalField(max_digits=20, decimal_places=10, null=True) + is_activated = models.BooleanField(default=False) company = models.ForeignKey( ProviderCompany, on_delete=models.CASCADE, @@ -61,6 +63,30 @@ class Device(BaseModel): return super(Device, self).save(*args, **kwargs) +class DeviceActivationCode(BaseModel): + device = models.ForeignKey( + Device, + on_delete=models.CASCADE, + related_name="code", + null=True + ) + company = models.ForeignKey( + ProviderCompany, + on_delete=models.CASCADE, + related_name='code', + null=True + ) + code = models.CharField(max_length=10, null=True, unique=True) + expires_at = models.DateTimeField(default=datetime.datetime.now()) + is_used = models.BooleanField(default=False) + + def __str__(self): + return f'Device: {self.device.serial} - code: {self.code}' + + def save(self, *args, **kwargs): + return super(DeviceActivationCode, self).save(*args, **kwargs) + + class DeviceVersion(BaseModel): device = models.ForeignKey( Device, diff --git a/apps/pos_device/web/api/v1/viewsets/device.py b/apps/pos_device/web/api/v1/viewsets/device.py index f4637ee..62a8cd9 100644 --- a/apps/pos_device/web/api/v1/viewsets/device.py +++ b/apps/pos_device/web/api/v1/viewsets/device.py @@ -1,3 +1,5 @@ +from datetime import timedelta + from apps.pos_device.web.api.v1.serilaizers import device as device_serializer from apps.authentication.api.v1.api import UserViewSet from apps.authorization.models import UserRelations @@ -6,6 +8,8 @@ from apps.pos_device import models as pos_models from rest_framework.response import Response from rest_framework.decorators import action from common.tools import CustomOperations +from common.helpers import generate_code +from django.utils.timezone import now from rest_framework import viewsets from django.db import transaction from rest_framework import status @@ -82,6 +86,20 @@ class DeviceViewSet(viewsets.ModelViewSet): serializer = self.get_serializer(page, many=True) return self.get_paginated_response(serializer.data) + def activate_device(self, request): + """ activations of pos by a temporary code """ + + device = self.queryset.filter(serial=request.data['serial']).first() + if not device or not device.is_activated: + code = generate_code() + pos_models.DeviceActivationCode.objects.create( + code=code, + expires_at=now() + timedelta(hours=2) + ) + return Response({'code': code, 'detail': 'enter code in panel'}, status=status.HTTP_202_ACCEPTED) + elif device.is_activated: + raise APIException('device is activated', code=403) + class DeviceVersionViewSet(viewsets.ModelViewSet): queryset = pos_models.DeviceVersion.objects.all() diff --git a/apps/product/web/api/v1/serializers/quota_distribution_serializers.py b/apps/product/web/api/v1/serializers/quota_distribution_serializers.py index a760299..a35c75f 100644 --- a/apps/product/web/api/v1/serializers/quota_distribution_serializers.py +++ b/apps/product/web/api/v1/serializers/quota_distribution_serializers.py @@ -64,4 +64,16 @@ class QuotaDistributionSerializer(serializers.ModelSerializer): if instance.quota: representation['quota'] = QuotaSerializer(instance.quota).data + if instance.assigned_organization: + representation['assigned_organization'] = { + 'organization': instance.assigned_organization.name, + 'id': instance.assigned_organization.id + } + + if instance.assigner_organization: + representation['assigner_organization'] = { + 'organization': instance.assigner_organization.name, + 'id': instance.assigner_organization.id + } + return representation diff --git a/apps/warehouse/web/api/v1/api.py b/apps/warehouse/web/api/v1/api.py index b0a506e..a64f4fc 100644 --- a/apps/warehouse/web/api/v1/api.py +++ b/apps/warehouse/web/api/v1/api.py @@ -1,5 +1,6 @@ from apps.warehouse.web.api.v1 import serializers as warehouse_serializers from apps.warehouse import models as warehouse_models +from common.liara_tools import upload_to_liara from rest_framework.decorators import action from rest_framework.response import Response from rest_framework import viewsets, filters @@ -13,6 +14,25 @@ class InventoryEntryViewSet(viewsets.ModelViewSet): filter_backends = [filters.SearchFilter] search_fields = [''] + @action( + methods=['get'], + detail=True, + url_path='confirmation_document', + url_name='confirmation_document', + name='confirmation_document' + ) + def confirmation_document(self, request, pk=None): + """ upload document for inventory entry confirmation """ + + inventory = self.get_object() + + # upload document to liara + document = request.FILES.get('document') + document_url = upload_to_liara( + document, + f'inventory_entry_document_{inventory.di}' + ) + class InventoryQuotaSaleTransactionViewSet(viewsets.ModelViewSet): queryset = warehouse_models.InventoryQuotaSaleTransaction.objects.all() diff --git a/common/helpers.py b/common/helpers.py index 4cf4468..2511303 100644 --- a/common/helpers.py +++ b/common/helpers.py @@ -1,3 +1,5 @@ +import random +import string import typing from apps.authorization.models import UserRelations @@ -9,5 +11,11 @@ def detect_file_extension(file_name: str) -> typing.AnyStr: def get_organization_by_user(user: object = None) -> typing.Any: + """ get organization object by request user """ organization = UserRelations.objects.select_related('organization').get(user=user).organization return organization + + +def generate_code(length=6): + """ generate 6 digit code """ + return ''.join(random.choices(string.digits, k=length))