예제 #1
0
class AbstractReportSliceSerializer(ModelSerializer):
    """Abstract serializer for the ReportSlice models."""

    report_platform_id = UUIDField(format='hex_verbose', required=False)
    report_slice_id = UUIDField(format='hex_verbose', required=False)
    account = CharField(max_length=50, required=False)
    report_json = JSONField(allow_null=False)
    git_commit = CharField(max_length=50, required=False)
    source = CharField(max_length=15, required=True)
    source_metadata = JSONField(allow_null=True, required=False)
    state = ChoiceField(choices=ReportSlice.STATE_CHOICES)
    retry_type = ChoiceField(choices=ReportSlice.RETRY_CHOICES,
                             default=ReportSlice.TIME)
    state_info = JSONField(allow_null=False)
    retry_count = IntegerField(default=0)
    hosts_count = IntegerField(min_value=1, max_value=MAX_HOSTS_PER_REP)
    last_update_time = DateTimeField(allow_null=False)
    failed_hosts = JSONField(allow_null=True)
    candidate_hosts = JSONField(allow_null=True)
    ready_to_archive = BooleanField(default=False)
    creation_time = DateTimeField(allow_null=False)
    processing_start_time = DateTimeField(allow_null=True, required=False)
    processing_end_time = DateTimeField(allow_null=True, required=False)

    class Meta:
        """Meta class for AbstractReportSliceSerializer."""

        abstract = True
        fields = '__all__'
class HttpConfigSerializer(ModelSerializer):
    header = JSONField()
    url_encoded_params = JSONField()

    class Meta:
        model = HttpConfig
        fields = ["url_encoded_params", "header"]

    @classmethod
    def build_from_metaclass(cls):
        properties = cls.build_properties()
        return type("MetaHttpConfigSerializer", (ModelSerializer, ),
                    properties)

    @classmethod
    def build_properties(cls):
        properties = {
            "Meta": cls.build_nested_meta_class(),
            "header": JSONField(),
            "url_encoded_params": JSONField()
        }
        return properties

    @classmethod
    def build_nested_meta_class(cls):
        properties = {
            "model": HttpConfig,
            "fields": ["header", "url_encoded_params"]
        }
        return type("Meta", (), properties)

    def create(self, validated_data):
        return self.Meta.model.objects.create(**validated_data)
예제 #3
0
class AbstractReportSerializer(ModelSerializer):
    """Abstract serializer for the Report models."""

    report_platform_id = UUIDField(format='hex_verbose', required=False)
    host_inventory_api_version = CharField(max_length=10, required=False)
    source = CharField(max_length=15, required=False)
    source_metadata = JSONField(allow_null=True, required=False)
    account = CharField(max_length=50, required=False)
    request_id = CharField(max_length=50, required=False)
    upload_ack_status = CharField(max_length=10, required=False)
    upload_srv_kafka_msg = JSONField(required=True)
    git_commit = CharField(max_length=50, required=False)
    state = ChoiceField(choices=Report.STATE_CHOICES)
    retry_type = ChoiceField(choices=Report.RETRY_CHOICES, default=Report.TIME)
    state_info = JSONField(allow_null=True)
    retry_count = IntegerField(default=0)
    last_update_time = DateTimeField(allow_null=True)
    ready_to_archive = BooleanField(default=False)
    arrival_time = DateTimeField(allow_null=False)
    processing_start_time = DateTimeField(allow_null=True, required=False)
    processing_end_time = DateTimeField(allow_null=True, required=False)

    class Meta:
        """Meta class for ReportSerializer."""

        abstract = True
        fields = '__all__'
 def build_properties(cls):
     properties = {
         "Meta": cls.build_nested_meta_class(),
         "header": JSONField(),
         "url_encoded_params": JSONField()
     }
     return properties
예제 #5
0
class CustomerContactSerializer(ModelSerializer):
    customer_id = UUIDField(read_only=True)
    customer_name_kanji = JSONField(read_only=True)
    cc_attrs = JSONField(read_only=True)
    is_basic = BooleanField(read_only=True)
    forests_count = IntegerField(read_only=True)
    business_id = CharField(read_only=True)

    class Meta:
        model = Contact
        exclude = ["contact_info", "deleted"]
class CampaignSerializer(ModelSerializer):

    location = JSONField()
    publicity_configuration = JSONField()
    products = JSONField()
    budget = DecimalField(max_digits=12, decimal_places=3)
    gender_range = ChoiceField(choices=['M', 'F', 'M-F'])

    class Meta:
        model = Campaign
        exclude = ('clients', )
예제 #7
0
class Payload(Serializer):
    user = User()
    response_url = CharField()
    actions = Action(many=True)
    trigger_id = CharField()
    submission = JSONField()
    callback_id = CharField()
예제 #8
0
class LessonProgressSerializer(ModelSerializer):
    """
    Annotates a Lesson with progress information based on logs generated
    by the requesting User
    """
    progress = SerializerMethodField()
    resources = JSONField(default='[]')

    class Meta:
        model = Lesson
        fields = (
            'description',
            'id',
            'is_active',
            'title',
            'progress',
            'resources',
        )

    def get_progress(self, instance):
        content_ids = [resource['content_id'] for resource in instance.resources]
        num_completed_logs = ContentSummaryLog.objects \
            .exclude(completion_timestamp__isnull=True) \
            .filter(
                user=self.context['user'],
                content_id__in=content_ids
            ) \
            .count()
        return {
            'resources_completed': num_completed_logs,
            'total_resources': len(instance.resources),
        }
예제 #9
0
class OutpostSerializer(ModelSerializer):
    """Outpost Serializer"""

    config = JSONField(validators=[is_dict], source="_config")
    providers_obj = ProviderSerializer(source="providers",
                                       many=True,
                                       read_only=True)

    def validate_config(self, config) -> dict:
        """Check that the config has all required fields"""
        try:
            from_dict(OutpostConfig, config)
        except DaciteError as exc:
            raise ValidationError(
                f"Failed to validate config: {str(exc)}") from exc
        return config

    class Meta:

        model = Outpost
        fields = [
            "pk",
            "name",
            "type",
            "providers",
            "providers_obj",
            "service_connection",
            "token_identifier",
            "config",
        ]
예제 #10
0
class DataFrameRecordsSerializer(Serializer):
    """
    A Serializer implementation that uses
    :func:`pandas.DataFrame.from_dict <pandas.DataFrame.from_records>` and
    :func:`pandas.DataFrame.to_dict <pandas.DataFrame.to_records>` to convert data to internal
    value and to external representation.
    """
    columns = ListField(child=CharField())
    data = ListField(child=JSONField())

    def to_internal_value(self, data):
        validated_data = super().to_internal_value(data)

        try:
            data_frame = pd.DataFrame.from_records(
                validated_data['data'],
                index='index',
                columns=validated_data['columns'])
            return data_frame
        except ValueError as e:
            raise ValidationError(
                {api_settings.NON_FIELD_ERRORS_KEY: [str(e)]})

    def to_representation(self, instance):
        recarray = instance.to_records(index=True)
        return OrderedDict([('columns', recarray.dtype.names),
                            ('data', recarray.tolist())])
예제 #11
0
class LessonProgressSerializer(ModelSerializer):
    """
    Annotates a Lesson with progress information based on logs generated
    by the requesting User
    """

    progress = SerializerMethodField()
    resources = JSONField(default="[]")

    class Meta:
        model = Lesson
        fields = ("description", "id", "is_active", "title", "progress", "resources")

    def get_progress(self, instance):
        content_ids = [resource["content_id"] for resource in instance.resources]
        resource_progress = (
            ContentSummaryLog.objects.filter(
                user=self.context["user"], content_id__in=content_ids
            )
            .aggregate(Sum("progress"))
            .get("progress__sum")
        )
        return {
            "resource_progress": resource_progress,
            "total_resources": len(instance.resources),
        }
class ArtifactStatsSerializer(Serializer):
    # Fields
    metadata = MetadataSerializer()
    timestamp = UnixEpochDateTimeField()
    metrics = JSONField(encoder=DjangoJSONEncoder)

    def create(self, validated_data):
        return ArtifactStatsRest(**validated_data)
예제 #13
0
파일: views.py 프로젝트: MagicMarvel/soj
    class ProblemPostSerializer(ModelSerializer):
        inputs = JSONField()
        sample_inputs = JSONField()
        solution_code = CharField()
        solution_lang = CharField()
        checker_type = CharField()
        checker_code = CharField(allow_blank=True)

        class Meta:
            model = Problem
            fields = ('title', 'description', 'time_limit', 'memory_limit',
                      'note', 'sample_inputs', 'checker_type', 'inputs',
                      'checker_code', 'solution_code', 'solution_lang')

        def create(self, validated_data):
            validated_data['checker_type'] = getattr(
                CheckerType, validated_data['checker_type']).value
            if not validated_data['sample_inputs']:
                validated_data['sample_inputs'] = validated_data['inputs'][:2]
            else:
                validated_data['inputs'] = validated_data[
                    'sample_inputs'] + validated_data['inputs']
            inputs = validated_data.pop('inputs')
            solution_code = validated_data.pop('solution_code')
            solution_lang = validated_data.pop('solution_lang')

            problem = Problem(**validated_data)
            problem.save()
            test_case = TestCase(problem=problem,
                                 inputs=inputs,
                                 expected_outputs="")
            solution = Solution(problem=problem,
                                code=solution_code,
                                lang=getattr(LanguageEnum,
                                             solution_lang).value,
                                is_model_solution=True)
            test_case.save()
            solution.save()

            save_input_files(problem.id, inputs)

            return problem

        def to_representation(self, problem):  # used in serializer.data
            return {'problem_id': problem.id}
class ProposalSerializer(HyperlinkedModelSerializer):
    data = JSONField()
    proposer = StringRelatedField()

    class Meta:
        model = PopularProposal
        fields = ('id', 'title', 'slug', 'get_absolute_url', 'data',
                  'proposer', 'created', 'clasification', 'is_local_meeting',
                  'nro_supports')
예제 #15
0
class ListCancelledOrderSerializer(serializers.ModelSerializer):
    payload = JSONField()

    class Meta:
        model = CancelledOrder
        fields = (
            'order_id',
            'payload',
            'created',
        )
예제 #16
0
파일: views.py 프로젝트: soj-allstars/soj
    class ProblemPutSerializer(ModelSerializer):
        inputs = JSONField()
        sample_inputs = JSONField()
        solution_code = CharField()
        solution_lang = CharField()
        checker_type = CharField()
        checker_code = CharField(allow_blank=True)

        class Meta:
            model = Problem
            fields = ('id', 'title', 'description', 'time_limit',
                      'memory_limit', 'note', 'sample_inputs', 'checker_type',
                      'inputs', 'checker_code', 'solution_code',
                      'solution_lang')

        def update(self, problem, validated_data):
            validated_data['checker_type'] = getattr(
                CheckerType, validated_data['checker_type']).value
            if not validated_data['sample_inputs']:
                validated_data['sample_inputs'] = validated_data['inputs'][:2]
            else:
                validated_data['inputs'] = validated_data[
                    'sample_inputs'] + validated_data['inputs']
            inputs = validated_data.pop('inputs')
            solution_code = validated_data.pop('solution_code')
            solution_lang = validated_data.pop('solution_lang')

            for k, v in validated_data.items():
                setattr(problem, k, v)
            problem.save()

            Solution.objects.filter(problem=problem,
                                    is_model_solution=True).update(
                                        code=solution_code,
                                        lang=getattr(LanguageEnum,
                                                     solution_lang).value)

            save_input_files(problem.id, inputs)

            return problem

        def to_representation(self, problem):  # used in serializer.data
            return {'problem_id': problem.id}
예제 #17
0
class ContextModelSerializer(serializers.ModelSerializer):
    context = JSONField(
        encoder=None,
        required=False,
        allow_null=True,
        write_only=True,
        help_text=
        "Provide extra context for dynamic jexl transforms and events",
    )

    def validate(self, data):
        self.context_data = data.pop("context", None)

        return super().validate(data)
예제 #18
0
class CategoryCreateSerializer(ModelSerializer):
    children = JSONField(required=False)

    class Meta:
        model = Category
        fields = ('name', 'children')

    def create(self, validated_data):
        name = self.get_name(validated_data)
        parent = Category.objects.create(name=name)
        children = self.get_children(validated_data)

        if len(children) > 0:
            self.process_kids(parent, children)
        return parent

    @staticmethod
    def get_name(validated_data):
        try:
            return validated_data.pop('name')
        except KeyError:
            raise ValidationError({'name': '"name" field is required.'})

    @staticmethod
    def get_children(validated_data):
        try:
            return validated_data.pop('children')
        except KeyError:
            return []

    @staticmethod
    def process_kids(parent, children):
        kids = []
        for child in children:
            kids.append(CategoryCreateSerializer.retreive_kid(child))
        parent.kids.add(*kids)
        CategoryCreateSerializer.set_siblings(kids)

    @staticmethod
    def retreive_kid(child):
        serializer = CategoryCreateSerializer(data=child)
        serializer.is_valid(raise_exception=True)
        return serializer.create(serializer.validated_data)

    @staticmethod
    def set_siblings(kids):
        if len(kids) > 0:
            for i, kid in enumerate(kids):
                kid.siblings.add(*kids[i + 1:])
예제 #19
0
class BankAccountSerializer(UuidModelSerializer):
    """
    Bank Account serializer.
    """

    bank = BankSerializer()
    identification = JSONField()

    class Meta(UuidModelSerializer.Meta):
        model = models.BankAccount
        fields = UuidModelSerializer.Meta.fields + (
            'bank',
            'type',
            'identification',
            'transferwise_recipient_id',
        )
예제 #20
0
class ContactSerializer(ModelSerializer):
    forest_internal_id = CharField(read_only=True)
    forest_id = UUIDField(read_only=True)
    forestcustomer_id = UUIDField(read_only=True)
    customer_id = UUIDField(read_only=True)
    owner_customer_id = UUIDField(read_only=True)
    cc_attrs = JSONField(read_only=True)
    # forest customer contact default
    default = BooleanField(read_only=True)
    is_basic = BooleanField(read_only=True)
    forests_count = IntegerField(read_only=True)
    business_id = CharField(read_only=True)

    class Meta:
        model = Contact
        exclude = ["contact_info", "deleted"]
예제 #21
0
class ReceiveMessageSerializer(serializers.ModelSerializer):
    uuid = serializers.CharField()
    payload = JSONField()

    class Meta:
        model = Inbox
        fields = (
            'origin_create_time', 'uuid', 'message_source',
            'message_type', 'payload'
        )

    def create(self, validated_data):
        return get_inbox_service().handle_message(
            validated_data['uuid'], validated_data['origin_create_time'],
            validated_data['message_source'], validated_data['message_type'],
            validated_data['payload'],
        )
class ClientSerializer(ModelSerializer):

    location = JSONField(required=False)
    email = EmailField()
    salary = DecimalField(max_digits=9,
                          decimal_places=2,
                          required=False,
                          source='earnings')
    gender = ChoiceField(choices=['M', 'F'], required=False)
    total_campaigns = IntegerField(required=False)
    birth_date = DateField(required=False)
    name = CharField(max_length=256, source='full_name')

    class Meta:
        model = Client
        fields = ('location', 'email', 'salary', 'gender', 'total_campaigns',
                  'birth_date', 'name', 'dni', 'id')
예제 #23
0
class UserFilterSerializer(HyperlinkedModelSerializer):
    user = PrimaryKeyRelatedField(read_only=True)
    filter = JSONField()

    def to_representation(self, instance):
        ret = super(UserFilterSerializer, self).to_representation(instance)
        filter = ret['filter']
        ret['filter'] = json.loads(filter)
        return ret

    class Meta:
        model = UserFilter
        fields = ('url',
                  'id',
                  'user',
                  'name',
                  'filter',
                  'date')
예제 #24
0
class OutpostSerializer(ModelSerializer):
    """Outpost Serializer"""

    _config = JSONField(validators=[is_dict])
    providers_obj = ProviderSerializer(source="providers",
                                       many=True,
                                       read_only=True)

    class Meta:

        model = Outpost
        fields = [
            "pk",
            "name",
            "providers",
            "providers_obj",
            "service_connection",
            "token_identifier",
            "_config",
        ]
예제 #25
0
class StripeCustomerSerializer(ModelSerializer):
    stripe_js_response = JSONField()

    def create(self, validated_data):
        instance = None
        if validated_data.get("stripe_js_response"):
            # Create a Customer
            try:
                user = self.context['request'].user
                stripe_js_response = validated_data.pop("stripe_js_response")
                instance = StripeCustomer.objects.create(
                    user=user, stripe_js_response=stripe_js_response)
                instance.create_at_stripe()
            except stripe.StripeError as e:
                raise ValidationError({"stripe_js_response": e})

        return instance

    class Meta:
        model = StripeCustomer
        fields = ["stripe_js_response"]
예제 #26
0
 class TestSerializer(Serializer):  # pylint: disable=abstract-method
     boolean_field = BooleanField()
     char_field = CharField()
     choice_field = ChoiceField([])
     date_field = DateField()
     date_time_field = DateTimeField()
     decimal_field = DecimalField(1, 1)
     dict_field = DictField()
     duration_field = DurationField()
     email_field = EmailField()
     file_field = FileField()
     file_path_field = FilePathField('')
     float_field = FloatField()
     image_field = ImageField()
     integer_field = IntegerField()
     ip_address_field = IPAddressField()
     json_field = JSONField()
     string_list_field = ListField(child=CharField())
     int_list_field = ListField(child=IntegerField())
     int_list_list_field = ListField(
         child=ListField(
             child=IntegerField(),
         ),
     )
     multiple_choice_field = MultipleChoiceField([])
     null_boolean_field = NullBooleanField()
     regex_field = RegexField('')
     slug_field = SlugField()
     time_field = TimeField()
     url_field = URLField()
     uuid_field = UUIDField()
     nullable_char_field = CharField(allow_null=True)
     nullable_char_listfield = ListField(
         child=CharField(allow_null=True),
     )
     write_only_field = CharField(write_only=True)
예제 #27
0
class StripeCustomerSerializer(ModelSerializer):
    stripe_js_response = JSONField()

    def create(self, validated_data):
        instance = None
        if validated_data.get("stripe_js_response"):
            # Create a Customer
            try:
                user = self.context['request'].user
                stripe_js_response = validated_data.pop("stripe_js_response")
                instance = StripeCustomer.objects.create(
                    user=user, stripe_js_response=stripe_js_response)
                instance.create_at_stripe()
            except stripe.error.StripeError as e:
                logging.error(
                    "[AA-Stripe] creating customer failed for user {user.id}: {error}".format(user=user, error=e)
                )
                raise ValidationError({"stripe_error": e._message})

        return instance

    class Meta:
        model = StripeCustomer
        fields = ["stripe_js_response"]
예제 #28
0
class CreateSaleSerializer(serializers.ModelSerializer):
    solditems = ItemSerializer(many=True)
    payment_data = JSONField()

    class Meta:
        model = Sales
        fields = ('id', 'user', 'invoice_number', 'table', 'sale_point',
                  'total_net', 'sub_total', 'balance', 'terminal',
                  'amount_paid', 'payment_data', 'status', 'total_tax',
                  'discount_amount', 'solditems')

    def validate_total_net(self, value):
        data = self.get_initial()
        try:
            Decimal(data.get('total_net'))
        except Exception as e:
            raise ValidationError('Total Net should be a decimal/integer')
        return value

    def validate_total_tax(self, value):
        data = self.get_initial()
        try:
            total_net = Decimal(data.get('total_net'))
            total_tax = Decimal(data.get('total_tax'))
            if total_tax >= total_net:
                raise ValidationError(
                    'Total tax cannot be more than total net')
        except Exception as e:
            raise ValidationError('Total Net should be a decimal/integer')
        return value

    def validate_discount_amount(self, value):
        data = self.get_initial()
        try:
            discount = Decimal(data.get('discount_amount'))
        except Exception as e:
            raise ValidationError('Discount should be a decimal/integer *' +
                                  str(discount) + '*')
        return value

    def validate_status(self, value):
        data = self.get_initial()
        status = str(data.get('status'))
        if status == 'fully-paid' or status == 'payment-pending':
            return value
        else:
            raise ValidationError(
                'Enter correct Status. Expecting either fully-paid/payment-pending'
            )

    def validate_terminal(self, value):
        data = self.get_initial()
        terminal_id = int(data.get('terminal'))
        try:
            Terminal.objects.get(pk=terminal_id)
        except Exception as e:
            raise ValidationError('Terminal specified does not exist')
        return value

    def create(self, validated_data):
        # add sold amount to drawer
        try:
            total_net = Decimal(validated_data.get('total_net'))
        except Exception as e:
            total_net = Decimal(0)
        try:
            total_tax = Decimal(validated_data.get('total_tax'))
        except Exception as e:
            total_tax = Decimal(0)
        terminal = validated_data.get('terminal')
        terminal.amount += Decimal(total_net)
        terminal.save()

        sale = Sales()

        try:
            sold_items_data = validated_data.pop('solditems')
        except Exception as e:
            raise ValidationError('Ordered items field should not be empty')
        status = validated_data.get('status')
        # make a sale
        sale.user = validated_data.get('user')
        sale.invoice_number = validated_data.get('invoice_number')
        sale.total_net = validated_data.get('total_net')
        sale.debt = validated_data.get('total_net')
        sale.sub_total = validated_data.get('sub_total')
        sale.balance = validated_data.get('balance')
        sale.terminal = validated_data.get('terminal')
        #sale.table = validated_data.get('table')
        sale.sale_point = validated_data.get('sale_point')
        sale.amount_paid = validated_data.get('amount_paid')
        sale.status = status
        sale.payment_data = validated_data.get('payment_data')
        sale.total_tax = total_tax
        sale.mobile = validated_data.get('mobile')
        sale.discount_amount = validated_data.get('discount_amount')

        sale.save()
        # add payment options

        for sold_item_data in sold_items_data:
            SoldItem.objects.create(sales=sale, **sold_item_data)
            try:
                item = Item.objects.get(stock__sku=sold_item_data['sku'])
                if item:
                    Item.objects.decrease_stock(item,
                                                sold_item_data['quantity'])
                else:
                    print('stock not found')
            except Exception as e:
                print('Error reducing stock!')

        return sale
예제 #29
0
class SystemFingerprintSerializer(NotEmptySerializer):
    """Serializer for the Fingerprint model."""

    # Common facts
    system_platform_id = UUIDField(format='hex_verbose', read_only=True)
    name = CharField(required=False, max_length=256)

    os_name = CharField(required=False, max_length=64)
    os_release = CharField(required=False, max_length=128)
    os_version = CharField(required=False, max_length=64)

    infrastructure_type = ChoiceField(
        required=False, choices=SystemFingerprint.INFRASTRUCTURE_TYPE)

    mac_addresses = CustomJSONField(required=False)
    ip_addresses = CustomJSONField(required=False)

    cpu_count = IntegerField(required=False, min_value=0)

    architecture = CharField(required=False, max_length=64)

    # Network scan facts
    bios_uuid = CharField(required=False, max_length=36)
    subscription_manager_id = CharField(required=False, max_length=36)

    cpu_socket_count = IntegerField(required=False, min_value=0)
    cpu_core_count = FloatField(required=False, min_value=0)
    cpu_core_per_socket = IntegerField(required=False, min_value=0)

    system_creation_date = DateField(required=False)
    system_last_checkin_date = DateField(required=False)

    system_role = CharField(required=False, max_length=128)
    system_addons = JSONField(required=False)
    system_service_level_agreement = CharField(required=False, max_length=128)
    system_usage_type = CharField(required=False, max_length=128)

    insights_client_id = CharField(required=False, max_length=128)

    virtualized_type = CharField(required=False, max_length=64)

    # VCenter scan facts
    vm_state = CharField(required=False, max_length=24)
    vm_uuid = CharField(required=False, max_length=36)
    vm_dns_name = CharField(required=False, max_length=256)

    vm_host = CharField(required=False, max_length=128)
    vm_host_socket_count = IntegerField(required=False, min_value=0)
    vm_host_core_count = IntegerField(required=False, min_value=0)

    vm_cluster = CharField(required=False, max_length=128)
    vm_datacenter = CharField(required=False, max_length=128)

    products = ProductSerializer(many=True, allow_null=True, required=False)
    entitlements = EntitlementSerializer(many=True,
                                         allow_null=True,
                                         required=False)

    # Red Hat facts
    is_redhat = NullBooleanField(required=False)
    redhat_certs = CharField(required=False)
    # pylint: disable=invalid-name
    redhat_package_count = IntegerField(required=False, min_value=0)

    metadata = CustomJSONField(required=True)
    sources = CustomJSONField(required=True)
    etc_machine_id = CharField(required=False, max_length=48)

    class Meta:
        """Meta class for SystemFingerprintSerializer."""

        model = SystemFingerprint
        fields = '__all__'

    def create(self, validated_data):
        """Create a system fingerprint."""
        products_data = validated_data.pop('products', [])
        entitlements_data = validated_data.pop('entitlements', [])
        fingerprint = SystemFingerprint.objects.create(**validated_data)
        for product_data in products_data:
            Product.objects.create(fingerprint=fingerprint, **product_data)
        for entitlement_data in entitlements_data:
            Entitlement.objects.create(fingerprint=fingerprint,
                                       **entitlement_data)
        return fingerprint
예제 #30
0
class OrderUpdateSerializer(serializers.ModelSerializer):
    ordered_items = ItemSerializer(many=True)
    payment_data = JSONField()
    mpesaIds = JSONField(required=False, write_only=True)
    visaIds = JSONField(required=False, write_only=True)
    create_credit = serializers.BooleanField(write_only=True)
    update_credit = serializers.BooleanField(write_only=True)
    due_date = serializers.CharField(required=False, write_only=True)

    class Meta:
        model = Orders
        fields = ('id', 'invoice_number', 'total_net', 'sub_total', 'balance',
                  'terminal', 'table', 'room', 'amount_paid', 'status',
                  'total_tax', 'discount_amount', 'debt', 'ordered_items',
                  'payment_data', 'mpesaIds', 'visaIds', 'customer',
                  'customer_name', 'create_credit', 'update_credit',
                  'due_date')

    def validate_status(self, value):
        data = self.get_initial()
        status = str(data.get('status'))
        if status == 'fully-paid' or status == 'payment-pending':
            status = status
            amount_paid = Decimal(data.get('amount_paid'))
            sale = Orders.objects.get(
                invoice_number=str(data.get('invoice_number')))
            if status == 'fully-paid' and sale.balance > amount_paid:
                raise ValidationError(
                    "Status error. Amount paid is less than balance.")
            else:
                return value
        elif status == "cancelled" or status == "credited":
            pass
            return value
        else:
            raise ValidationError(
                'Enter correct Status. Expecting either fully-paid/payment-pending or cancelled'
            )

    def validate_payment_data(self, value):
        data = self.get_initial()
        dictionary_value = dict(data.get('payment_data'))
        return value

    def validate_total_net(self, value):
        data = self.get_initial()
        try:
            Decimal(data.get('total_net'))
            return value
        except Exception as e:
            raise ValidationError('Total Net should be a decimal/integer')

    def validate_debt(self, value):
        data = self.get_initial()
        try:
            Decimal(data.get('debt'))
        except Exception as e:
            raise ValidationError('Debt should be a decimal/integer')
        return value

    def validate_amount_paid(self, value):
        data = self.get_initial()
        try:
            Decimal(data.get('amount_paid'))
        except Exception as e:
            raise ValidationError('Amount paid should be a decimal/integer')
        return value

    def validate_terminal(self, value):
        data = self.get_initial()
        terminal = Terminal.objects.filter(pk=int(data.get('terminal')))
        if terminal.exists():
            return value
        else:
            raise ValidationError('Terminal specified does not exist')

    def validate_customer(self, value):
        data = self.get_initial()
        customer_id = int(data.get('customer'))
        customer_name = data.get('customer_name')
        user = None
        try:
            user = Customer.objects.get(pk=customer_id)
        except Exception as e:
            if customer_name:
                user = Customer.objects.create(name=customer_name,
                                               creditable=True)
        return user

    def send_to_credit(self, order):
        credit = Credit()
        credit.user = order.user
        credit.invoice_number = order.invoice_number
        credit.total_net = order.total_net
        credit.sub_total = order.sub_total
        credit.balance = order.balance
        credit.terminal = order.terminal
        credit.amount_paid = order.amount_paid
        credit.status = order.status
        credit.status = 'payment-pending'
        credit.payment_data = order.payment_data
        credit.customer = order.customer
        credit.customer_name = order.customer_name

        try:
            if order.due_date:
                from datetime import datetime
                due_date = datetime.strptime(order.due_date, '%Y-%m-%d').date()
                credit.due_date = due_date
        except Exception as e:
            logger.error(e)

        try:
            credit.table = order.table
            credit.room = order.room
            credit.carry = 'Sitting'
        except Exception as e:
            credit.carry = 'Take Away'
            logger.error(e)
        credit.total_tax = order.total_tax
        credit.save()

        # add credit history
        try:
            history = CreditHistoryEntry()
            history.credit = credit
            history.balance = credit.total_net
            history.amount = credit.amount_paid
            history.save()
        except Exception as e:
            logger.error(e)

        for option in order.payment_data:
            try:
                pay_opt = PaymentOption.objects.get(
                    pk=int(option['payment_id']))
                credit.payment_options.add(pay_opt)
            except Exception as e:
                logger.error("error adding options " + str(e))

        for item in order.items():
            try:
                new_item = CreditedItem.objects.create(
                    credit=credit,
                    sku=item.sku,
                    quantity=item.quantity,
                    product_name=item.product_name,
                    total_cost=item.total_cost,
                    unit_cost=item.unit_cost,
                    product_category=item.product_category)
                new_item.counter = item.counter
                new_item.transfer_id = item.transfer_id
                new_item.order = item.id
                new_item.attributes = item.attributes
                new_item.unit_purchase = item.unit_purchase
                new_item.total_purchase = item.total_purchase
                if item.discount_id:
                    new_item.discount_id = item.discount_id.pk
                new_item.discount_quantity = item.discount_quantity
                new_item.discount_total = item.discount_total
                new_item.discount_set_status = item.discount_set_status
                new_item.cold = item.cold
                new_item.cold_quantity = item.cold_quantity

                if item.counter:
                    try:
                        stock = Stock.objects.filter(sku=item.sku).first()
                        new_item.minimum_price = stock.minimum_price
                        new_item.wholesale_override = stock.wholesale_override
                        new_item.low_stock_threshold = stock.low_stock_threshold
                        new_item.unit_purchase = stock.cost_price
                    except Exception as e:
                        pass
                elif item.kitchen:
                    new_item.is_stock = False
                else:
                    pass
                new_item.kitchen = item.kitchen
                new_item.save()
            except Exception as e:
                logger.error(e.message, exception=e)

    def diff(self, list1, list2):
        s = set(list2)
        d = [x for x in list1 if x not in s]
        return list(d)

    def same(self, list1, list2):
        s = set(list1) & set(list2)
        return list(s)

    def update(self, instance, validated_data):

        terminal = validated_data.get('terminal', instance.terminal.id)
        terminal.amount += Decimal(
            validated_data.get('amount_paid', instance.amount_paid))
        terminal.save()
        instance.table = validated_data.get('table', instance.table)
        instance.room = validated_data.get('room', instance.room)
        instance.total_net = validated_data.get('total_net',
                                                instance.total_net)
        instance.debt = instance.debt - validated_data.get(
            'amount_paid', instance.amount_paid)
        instance.amount_paid = instance.amount_paid + validated_data.get(
            'amount_paid', instance.amount_paid)
        instance.balance = validated_data.get('balance', instance.balance)
        instance.customer = validated_data.get('customer', instance.customer)
        instance.customer_name = validated_data.get('customer_name',
                                                    instance.customer_name)

        if validated_data.get('customer_name'):
            try:
                customer = Customer.objects.get(name=instance.customer_name)
            except:
                customer = Customer.objects.create(name=instance.customer_name,
                                                   creditable=True)
            instance.customer = customer

        if instance.amount_paid >= instance.total_net:
            instance.status = 'fully-paid'
            instance.payment_data = validated_data.get('payment_data')
            if validated_data.get('mpesaIds'):
                change_mpesa_id_status(validated_data.get('mpesaIds'))

            if validated_data.get('visaIds'):
                change_visa_id_status(validated_data.get('visaIds'))
        else:
            instance.status = validated_data.get('status', instance.status)

        if validated_data.get('status') == "credited":
            instance.status = "credited"
        instance.last_status_change = now()
        instance.save()
        try:
            ordered_items_data = validated_data.pop('ordered_items')
        except Exception as e:
            raise ValidationError('Ordered items field should not be empty')

        # return order sold item to transfer stock then delete them
        # Item = CounterTransferItems
        items = instance.ordered_items.all()

        client_ids = [int(i['transfer_id']) for i in ordered_items_data]
        server_ids = [int(i.transfer_id) for i in items]

        # get the ids in client not in server
        client_ids_to_add = self.diff(client_ids, server_ids)

        # get ids that are both in the client and the server to update their quantities
        common_ids = self.same(server_ids, client_ids)

        # add client_ids to the new payload
        new_payload = [
            i for i in ordered_items_data
            if int(i['transfer_id']) in client_ids_to_add
        ]

        # loop through the ordered_items_data and get those that have changed in quantities
        for item_data in ordered_items_data:
            # check if the transfer_id exists in the common_ids to match the item
            if item_data['transfer_id'] in common_ids:
                try:
                    ordered_item_match = items.get(
                        product_name=item_data['product_name'],
                        sku=item_data['sku'],
                        transfer_id=int(item_data['transfer_id']))

                    # check if item from counter
                    if ordered_item_match.counter and ordered_item_match.counter == item_data[
                            'counter']:
                        try:
                            transferred_item = Item.objects.get(
                                pk=ordered_item_match.transfer_id)
                            # check if stock returned to store and the current stock quantity exceeds the ordered
                            # quantity
                            if (ordered_item_match.quantity +
                                    transferred_item.qty) >= int(
                                        item_data['quantity']):
                                Item.objects.increase_stock(
                                    transferred_item,
                                    int(ordered_item_match.quantity))
                                new_payload.append(item_data)
                            else:
                                # should remain the same
                                item_data[
                                    'quantity'] = ordered_item_match.quantity
                                item_data[
                                    'unit_cost'] = ordered_item_match.unit_cost
                                item_data[
                                    'total_cost'] = ordered_item_match.total_cost
                                item_data[
                                    'unit_purchase'] = ordered_item_match.unit_purchase
                                item_data[
                                    'discount_id'] = ordered_item_match.discount_id
                                item_data[
                                    'discount_quantity'] = ordered_item_match.discount_quantity
                                item_data[
                                    'discount_total'] = ordered_item_match.discount_total
                                item_data[
                                    'discount_set_status'] = ordered_item_match.discount_set_status
                                new_payload.append(item_data)

                        except Exception as e:
                            logger.error(e.message, exception=e)

                    # check if item from kitchen
                    elif ordered_item_match.kitchen and ordered_item_match.kitchen == item_data[
                            'kitchen']:
                        try:
                            transferred_item = MenuItem.objects.get(
                                pk=ordered_item_match.transfer_id)
                            # check if stock returned to store and the current stock quantity exceeds the ordered
                            # quantity
                            if (ordered_item_match.quantity +
                                    transferred_item.qty) >= int(
                                        item_data['quantity']):
                                MenuItem.objects.increase_stock(
                                    transferred_item,
                                    int(ordered_item_match.quantity))
                                new_payload.append(item_data)
                            else:
                                # should remain the same
                                item_data[
                                    'quantity'] = ordered_item_match.quantity
                                item_data[
                                    'unit_cost'] = ordered_item_match.unit_cost
                                item_data[
                                    'total_cost'] = ordered_item_match.total_cost
                                item_data[
                                    'unit_purchase'] = ordered_item_match.unit_purchase
                                item_data[
                                    'discount_id'] = ordered_item_match.discount_id
                                item_data[
                                    'discount_quantity'] = ordered_item_match.discount_quantity
                                item_data[
                                    'discount_total'] = ordered_item_match.discount_total
                                item_data[
                                    'discount_set_status'] = ordered_item_match.discount_set_status
                                new_payload.append(item_data)
                        except Exception as e:
                            logger.error(e.message, exception=e)

                except Exception as e:
                    logger.error(e.message, exception=e)

        # delete all order items
        items.delete()
        """ recreate orders """
        for ordered_item_data in new_payload:
            OrderedItem.objects.create(orders=instance, **ordered_item_data)
            if ordered_item_data.get('counter'):
                try:
                    item = Item.objects.get(
                        pk=int(ordered_item_data['transfer_id']))
                    if item:
                        Item.objects.decrease_stock(
                            item, ordered_item_data['quantity'])
                    else:
                        logger.info('stock not found')
                except Exception as e:
                    logger.error('Error reducing counter stock!', exception=e)
            elif ordered_item_data.get('kitchen'):
                try:
                    item = MenuItem.objects.get(
                        pk=int(ordered_item_data['transfer_id']))
                    if item:
                        MenuItem.objects.decrease_stock(
                            item, ordered_item_data['quantity'])
                    else:
                        logger.info('stock not found')
                except Exception as e:
                    logger.error('Error reducing kitchen stock!', exception=e)
            else:
                logger.info('Kitchen or counter were not provided')

        if validated_data.get('create_credit'):
            if validated_data.get('due_date'):
                instance.due_date = validated_data.get('due_date')
            self.send_to_credit(instance)

        return instance