finance-sdk 1.0.3__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- finance_sdk/__init__.py +2 -0
- finance_sdk/admin.py +3 -0
- finance_sdk/apps.py +6 -0
- finance_sdk/enums.py +52 -0
- finance_sdk/migrations/__init__.py +0 -0
- finance_sdk/models/__init__.py +0 -0
- finance_sdk/models/accounts.py +41 -0
- finance_sdk/models/bank.py +11 -0
- finance_sdk/models/category.py +17 -0
- finance_sdk/models/entry.py +53 -0
- finance_sdk/models/payment.py +29 -0
- finance_sdk/serializers/__init__.py +0 -0
- finance_sdk/serializers/accounts.py +45 -0
- finance_sdk/serializers/bank.py +20 -0
- finance_sdk/serializers/category.py +31 -0
- finance_sdk/serializers/entry.py +144 -0
- finance_sdk/serializers/payments.py +73 -0
- finance_sdk/services/__init__.py +0 -0
- finance_sdk/services/entriesService.py +77 -0
- finance_sdk/tests.py +3 -0
- finance_sdk/utils.py +63 -0
- finance_sdk/views/__init__.py +0 -0
- finance_sdk/views/account.py +50 -0
- finance_sdk/views/bank.py +30 -0
- finance_sdk/views/category.py +36 -0
- finance_sdk/views/entry.py +206 -0
- finance_sdk/views/payment.py +56 -0
- finance_sdk-1.0.3.dist-info/METADATA +23 -0
- finance_sdk-1.0.3.dist-info/RECORD +31 -0
- finance_sdk-1.0.3.dist-info/WHEEL +5 -0
- finance_sdk-1.0.3.dist-info/top_level.txt +1 -0
finance_sdk/__init__.py
ADDED
finance_sdk/admin.py
ADDED
finance_sdk/apps.py
ADDED
finance_sdk/enums.py
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
|
|
2
|
+
class Type:
|
|
3
|
+
ENTRY = "E"
|
|
4
|
+
OUT = "O"
|
|
5
|
+
AUTOMATIC_PAYMENT = "AP"
|
|
6
|
+
PAID_ENTRY = 'PE'
|
|
7
|
+
|
|
8
|
+
CHOICES = (
|
|
9
|
+
(ENTRY , "Entry"),
|
|
10
|
+
(OUT , "Out"),
|
|
11
|
+
(AUTOMATIC_PAYMENT, "Automatic Payment"),
|
|
12
|
+
(PAID_ENTRY , "Paid entry")
|
|
13
|
+
)
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class RegistryClassification:
|
|
18
|
+
VARIABLE = "variable"
|
|
19
|
+
FIX = "fix"
|
|
20
|
+
INVESTIMENT = "investiment"
|
|
21
|
+
|
|
22
|
+
CHOICES = (
|
|
23
|
+
(VARIABLE, "variable"),
|
|
24
|
+
(FIX , "fix"),
|
|
25
|
+
(INVESTIMENT, "investiment"),
|
|
26
|
+
)
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
class Frequency:
|
|
30
|
+
NONE = 0
|
|
31
|
+
WEEK = 7
|
|
32
|
+
BIWEEK = 15
|
|
33
|
+
MONTH = 30
|
|
34
|
+
YEAR = 365
|
|
35
|
+
|
|
36
|
+
CHOICES = (
|
|
37
|
+
(NONE, "None"),
|
|
38
|
+
(WEEK , "Week"),
|
|
39
|
+
(BIWEEK, "Biweek"),
|
|
40
|
+
(BIWEEK, "Biweek"),
|
|
41
|
+
)
|
|
42
|
+
|
|
43
|
+
@staticmethod
|
|
44
|
+
def get_frequency(frequency: int):
|
|
45
|
+
mapping = {
|
|
46
|
+
Frequency.WEEK : 2,
|
|
47
|
+
Frequency.BIWEEK : 3,
|
|
48
|
+
Frequency.MONTH : 4,
|
|
49
|
+
Frequency.YEAR : 5,
|
|
50
|
+
|
|
51
|
+
}
|
|
52
|
+
return mapping.get(frequency, 1)
|
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
from django.db import models
|
|
2
|
+
|
|
3
|
+
from models import bank
|
|
4
|
+
|
|
5
|
+
class Account(models.Model):
|
|
6
|
+
name = models.CharField(max_length=200, blank=False, null=False)
|
|
7
|
+
bank = models.ForeignKey(bank, on_delete=models.PROTECT)
|
|
8
|
+
deactivate = models.BooleanField(default=False, blank=False, null=False)
|
|
9
|
+
created_at = models.DateTimeField(auto_now_add=True)
|
|
10
|
+
updated_at = models.DateTimeField(auto_now=True)
|
|
11
|
+
client_app = models.JSONField()
|
|
12
|
+
|
|
13
|
+
def __str__(self):
|
|
14
|
+
return self.name + " - " + self.bank.name
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class AccountPermission(models.Model):
|
|
18
|
+
account = models.ForeignKey(Account, on_delete=models.CASCADE)
|
|
19
|
+
employee = models.JSONField()
|
|
20
|
+
deactivate = models.BooleanField(default=False, blank=False, null=False)
|
|
21
|
+
created_at = models.DateTimeField(auto_now_add=True)
|
|
22
|
+
updated_at = models.DateTimeField(auto_now=True)
|
|
23
|
+
client_app = models.JSONField()
|
|
24
|
+
|
|
25
|
+
def __str__(self):
|
|
26
|
+
return "Account: %s | %s" % (self.account, self.employee)
|
|
27
|
+
|
|
28
|
+
@staticmethod
|
|
29
|
+
def get_account(user_id, client_app):
|
|
30
|
+
accounts = Account.objects.filter(
|
|
31
|
+
id__in=[
|
|
32
|
+
AccountPermission.objects.filter(
|
|
33
|
+
employee__user_id=user_id,
|
|
34
|
+
client_app_id=client_app,
|
|
35
|
+
deactivate=False,
|
|
36
|
+
account__bank__deactivate=False,
|
|
37
|
+
).values_list("account_id")
|
|
38
|
+
]
|
|
39
|
+
)
|
|
40
|
+
|
|
41
|
+
return accounts
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
from django.db import models
|
|
2
|
+
|
|
3
|
+
class Bank(models.Model):
|
|
4
|
+
name = models.CharField(max_length=200, blank=False, null=False)
|
|
5
|
+
deactivate = models.BooleanField(default=False, blank=False, null=False)
|
|
6
|
+
created_at = models.DateTimeField(auto_now_add=True)
|
|
7
|
+
updated_at = models.DateTimeField(auto_now=True)
|
|
8
|
+
client_app = models.JSONField()
|
|
9
|
+
|
|
10
|
+
def __str__(self):
|
|
11
|
+
return self.name
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
from django.db import models
|
|
2
|
+
|
|
3
|
+
class Category(models.Model):
|
|
4
|
+
name = models.CharField("Nome", max_length=200, blank=False, null=False)
|
|
5
|
+
principal_category = models.ForeignKey(
|
|
6
|
+
"self", on_delete=models.PROTECT, blank=True, null=True
|
|
7
|
+
)
|
|
8
|
+
is_entry = models.BooleanField(default=True, blank=False, null=False)
|
|
9
|
+
is_out = models.BooleanField(default=True, blank=False, null=False)
|
|
10
|
+
deactivate = models.BooleanField(default=False, blank=False, null=False)
|
|
11
|
+
created_at = models.DateTimeField(auto_now_add=True)
|
|
12
|
+
updated_at = models.DateTimeField(auto_now=True)
|
|
13
|
+
client_app = models.JSONField()
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def __str__(self):
|
|
17
|
+
return self.name
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
from django.db import models
|
|
2
|
+
|
|
3
|
+
from category import Category
|
|
4
|
+
from payment import PaymentMethod
|
|
5
|
+
from accounts import Account
|
|
6
|
+
|
|
7
|
+
from enums import Frequency, Type, RegistryClassification
|
|
8
|
+
|
|
9
|
+
class Entry(models.Model):
|
|
10
|
+
due_date = models.DateField(blank=False)
|
|
11
|
+
payment_date = models.DateField(blank=True, null=True)
|
|
12
|
+
description = models.TextField("Description", blank=False)
|
|
13
|
+
category = models.ForeignKey(
|
|
14
|
+
Category,
|
|
15
|
+
verbose_name="Category",
|
|
16
|
+
on_delete=models.PROTECT,
|
|
17
|
+
blank=True,
|
|
18
|
+
null=True,
|
|
19
|
+
)
|
|
20
|
+
value = models.DecimalField(max_digits=9, decimal_places=2, blank=False, null=False)
|
|
21
|
+
received_value = models.DecimalField(
|
|
22
|
+
max_digits=9, decimal_places=2, blank=True, null=True
|
|
23
|
+
)
|
|
24
|
+
liquid_value = models.DecimalField(
|
|
25
|
+
max_digits=9, decimal_places=2, blank=True, null=True
|
|
26
|
+
)
|
|
27
|
+
payment_method = models.ForeignKey(
|
|
28
|
+
PaymentMethod, on_delete=models.PROTECT, null=True
|
|
29
|
+
)
|
|
30
|
+
registry_classification = models.CharField(
|
|
31
|
+
max_length=30,
|
|
32
|
+
blank=True,
|
|
33
|
+
null=False,
|
|
34
|
+
default=RegistryClassification.VARIABLE,
|
|
35
|
+
choices=RegistryClassification.CHOICES,
|
|
36
|
+
)
|
|
37
|
+
number_of_payments = models.PositiveIntegerField(default=1, null=False, blank=False)
|
|
38
|
+
current_payment = models.PositiveIntegerField(default=1, null=False, blank=False)
|
|
39
|
+
frequency = models.IntegerField(
|
|
40
|
+
choices=Frequency, default=Frequency.NONE, null=True, blank=True
|
|
41
|
+
)
|
|
42
|
+
reference_record = models.ForeignKey(
|
|
43
|
+
"self", on_delete=models.PROTECT, null=True, blank=False, related_name="payments"
|
|
44
|
+
)
|
|
45
|
+
observation = models.TextField(blank=True, null=True)
|
|
46
|
+
cost_center = models.JSONField(default=dict)
|
|
47
|
+
account = models.ForeignKey(Account, on_delete=models.PROTECT, blank=True, null=True)
|
|
48
|
+
entry_type = models.CharField(max_length=1, choices=Type.CHOICES, blank=False)
|
|
49
|
+
person = models.JSONField(default=dict)
|
|
50
|
+
tag = models.TextField(blank=True, null=True)
|
|
51
|
+
created_at = models.DateTimeField(auto_now_add=True)
|
|
52
|
+
updated_at = models.DateTimeField(auto_now=True)
|
|
53
|
+
client_app = models.JSONField(default=dict, null=False, blank=False)
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
from django.db import models
|
|
2
|
+
|
|
3
|
+
class PaymentMethod(models.Model):
|
|
4
|
+
name = models.CharField("Nome", max_length=200, blank=False, null=False)
|
|
5
|
+
tax = models.DecimalField(
|
|
6
|
+
decimal_places=2, max_digits=9, blank=True, null=True, default=0
|
|
7
|
+
)
|
|
8
|
+
deactivate = models.BooleanField(default=False, blank=False, null=False)
|
|
9
|
+
created_at = models.DateTimeField(auto_now_add=True)
|
|
10
|
+
updated_at = models.DateTimeField(auto_now=True)
|
|
11
|
+
client_app = models.JSONField()
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def __str__(self):
|
|
15
|
+
return self.nome
|
|
16
|
+
|
|
17
|
+
def save(self, *args, **kwargs):
|
|
18
|
+
if self.taxa == "":
|
|
19
|
+
self.taxa = 0
|
|
20
|
+
|
|
21
|
+
super(PaymentMethod, self).save(*args, **kwargs)
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
class PaymentMethodTaxs(models.Model):
|
|
25
|
+
initial_payment = models.PositiveIntegerField()
|
|
26
|
+
final_payment = models.PositiveIntegerField()
|
|
27
|
+
tax = models.DecimalField(decimal_places=2, max_digits=5)
|
|
28
|
+
PaymentMethod = models.ForeignKey(PaymentMethod, on_delete=models.PROTECT)
|
|
29
|
+
client_app = models.JSONField()
|
|
File without changes
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
from rest_framework import serializers
|
|
2
|
+
from models.accounts import Account, AccountPermission
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class AccountSerializer(serializers.ModelSerializer):
|
|
6
|
+
class Meta:
|
|
7
|
+
model = Account
|
|
8
|
+
fields = ["id", "name", "bank"]
|
|
9
|
+
|
|
10
|
+
def validate_name(self, value):
|
|
11
|
+
if not (self.instance and value == self.instance.name):
|
|
12
|
+
if Account.objects.filter(
|
|
13
|
+
name=value, deactivate=False, client_app=self.initial_data.get('client_app')).exists():
|
|
14
|
+
raise serializers.ValidationError(
|
|
15
|
+
"Already exists an account with this name."
|
|
16
|
+
)
|
|
17
|
+
|
|
18
|
+
return value
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class AccountPermissionSerializer(serializers.ModelSerializer):
|
|
23
|
+
|
|
24
|
+
class Meta:
|
|
25
|
+
model = AccountPermission
|
|
26
|
+
fields = ["id", "account", "employee"]
|
|
27
|
+
validators = []
|
|
28
|
+
|
|
29
|
+
def validate(self, attrs):
|
|
30
|
+
if (
|
|
31
|
+
AccountPermission.objects.filter(
|
|
32
|
+
employee__id=attrs["employee"],
|
|
33
|
+
account=attrs["account"],
|
|
34
|
+
deactivate=False,
|
|
35
|
+
account__deactivate=False,
|
|
36
|
+
account__bank__deactivate=False,
|
|
37
|
+
).exists()
|
|
38
|
+
):
|
|
39
|
+
raise serializers.ValidationError(
|
|
40
|
+
{"employee": "This employee already has permission"}
|
|
41
|
+
)
|
|
42
|
+
|
|
43
|
+
return attrs
|
|
44
|
+
|
|
45
|
+
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
from rest_framework import serializers
|
|
2
|
+
from models.bank import Bank
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class BankSerializer(serializers.ModelSerializer):
|
|
6
|
+
|
|
7
|
+
class Meta:
|
|
8
|
+
model = Bank
|
|
9
|
+
fields = ["id", "name"]
|
|
10
|
+
|
|
11
|
+
def validate_name(self, value):
|
|
12
|
+
if not (self.instance and value == self.instance.name):
|
|
13
|
+
if Bank.objects.filter(
|
|
14
|
+
name=value, deactivate =False, client_app=self.initial_data.get('client_app')
|
|
15
|
+
).exists():
|
|
16
|
+
raise serializers.ValidationError(
|
|
17
|
+
"Already exists a bank with this name"
|
|
18
|
+
)
|
|
19
|
+
|
|
20
|
+
return value
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
from rest_framework import serializers
|
|
2
|
+
from models.category import Category
|
|
3
|
+
|
|
4
|
+
class CategorySerializer(serializers.ModelSerializer):
|
|
5
|
+
|
|
6
|
+
class Meta:
|
|
7
|
+
model = Category
|
|
8
|
+
fields = [
|
|
9
|
+
"id",
|
|
10
|
+
"name",
|
|
11
|
+
"principal_category",
|
|
12
|
+
"is_entry",
|
|
13
|
+
"is_out",
|
|
14
|
+
"deactivate",
|
|
15
|
+
]
|
|
16
|
+
|
|
17
|
+
def validate_name(self, value):
|
|
18
|
+
if not (self.instance and value == self.instance.name):
|
|
19
|
+
if Category.objects.filter(
|
|
20
|
+
name=value, deactivate=False, client_app=self.initial_data.get('client_app')).exists():
|
|
21
|
+
raise serializers.ValidationError(
|
|
22
|
+
"Already exists a category with this name."
|
|
23
|
+
)
|
|
24
|
+
|
|
25
|
+
if Category.objects.filter(
|
|
26
|
+
name=value, deactivate=True, client_app=self.initial_data.get('client_app')).exists():
|
|
27
|
+
raise serializers.ValidationError(
|
|
28
|
+
"Already exists a category with this name."
|
|
29
|
+
)
|
|
30
|
+
|
|
31
|
+
return value
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
from django.db import transaction
|
|
2
|
+
from datetime import date, timedelta
|
|
3
|
+
|
|
4
|
+
from rest_framework import serializers
|
|
5
|
+
from finance_sdk.models.entry import Entry
|
|
6
|
+
from finance_sdk.models.accounts import AccountPermission
|
|
7
|
+
|
|
8
|
+
from enums import Frequency, Type, RegistryClassification
|
|
9
|
+
from services.entriesService import generate_entries
|
|
10
|
+
|
|
11
|
+
class EntrySerializer(serializers.ModelSerializer):
|
|
12
|
+
|
|
13
|
+
class Meta:
|
|
14
|
+
model = Entry
|
|
15
|
+
fields = [
|
|
16
|
+
"id",
|
|
17
|
+
"description",
|
|
18
|
+
"value",
|
|
19
|
+
"received_value",
|
|
20
|
+
"liquid_value",
|
|
21
|
+
"category",
|
|
22
|
+
"account",
|
|
23
|
+
"cost_center",
|
|
24
|
+
"payment_date",
|
|
25
|
+
"due_date",
|
|
26
|
+
"payment_method",
|
|
27
|
+
"person",
|
|
28
|
+
"entry_type",
|
|
29
|
+
"registry_classification",
|
|
30
|
+
"tag",
|
|
31
|
+
"number_of_payments",
|
|
32
|
+
"current_payment",
|
|
33
|
+
"frequency",
|
|
34
|
+
"reference_record",
|
|
35
|
+
|
|
36
|
+
]
|
|
37
|
+
|
|
38
|
+
read_only_fields = [
|
|
39
|
+
"current_payment",
|
|
40
|
+
"reference_record",
|
|
41
|
+
"frequency",
|
|
42
|
+
"liquid_value",
|
|
43
|
+
]
|
|
44
|
+
|
|
45
|
+
@transaction.atomic
|
|
46
|
+
def create(self, validated_data):
|
|
47
|
+
return generate_entries(self.initial_data, validated_data)
|
|
48
|
+
|
|
49
|
+
def update(self, instance, validated_data):
|
|
50
|
+
validated_data["number_of_payments"] = instance.number_of_payments
|
|
51
|
+
validated_data["frequency"] = instance.frequency
|
|
52
|
+
validated_data["reference_record"] = instance.reference_record
|
|
53
|
+
value = validated_data.get("value")
|
|
54
|
+
entry_type = (
|
|
55
|
+
validated_data.get("entry_type")
|
|
56
|
+
if validated_data.get("entry_type") is not None
|
|
57
|
+
else instance.entry_type
|
|
58
|
+
)
|
|
59
|
+
if value is not None and entry_type == Entry.entry_type.ENTRY:
|
|
60
|
+
payment_method = (
|
|
61
|
+
validated_data.get("payment_method")
|
|
62
|
+
if validated_data.get("payment_method") is not None
|
|
63
|
+
else instance.payment_method
|
|
64
|
+
)
|
|
65
|
+
if payment_method is not None:
|
|
66
|
+
validated_data["liquid_value"] = value * (payment_method.tax / 100)
|
|
67
|
+
|
|
68
|
+
if self.context.get("recalcular") and instance.forma_pagamento is not None:
|
|
69
|
+
validated_data["valor_liquido"] = instance.valor * (
|
|
70
|
+
instance.forma_pagamento.taxa / 100
|
|
71
|
+
)
|
|
72
|
+
|
|
73
|
+
return super().update(instance, validated_data)
|
|
74
|
+
|
|
75
|
+
def validate_payment_date(self, value):
|
|
76
|
+
DATE_LIMIT = date(2000, 1, 1)
|
|
77
|
+
|
|
78
|
+
if DATE_LIMIT > value:
|
|
79
|
+
raise serializers.ValidationError(
|
|
80
|
+
"Date can't be lower then 2000-01-01"
|
|
81
|
+
)
|
|
82
|
+
|
|
83
|
+
return value
|
|
84
|
+
|
|
85
|
+
def validate_due_date(self, value):
|
|
86
|
+
DATE_LIMIT = date(2000, 1, 1)
|
|
87
|
+
|
|
88
|
+
if DATE_LIMIT > value:
|
|
89
|
+
raise serializers.ValidationError(
|
|
90
|
+
"Date can't be lower then 2000-01-01"
|
|
91
|
+
)
|
|
92
|
+
return value
|
|
93
|
+
|
|
94
|
+
def validate_value(self, value):
|
|
95
|
+
if not value > 0:
|
|
96
|
+
raise serializers.ValidationError("The value must be greater than 0")
|
|
97
|
+
|
|
98
|
+
return value
|
|
99
|
+
|
|
100
|
+
def validate_account(self, value):
|
|
101
|
+
if not AccountPermission.objects.filter(
|
|
102
|
+
account=value, employee_id=self.initial_data.get('employee')
|
|
103
|
+
).exists():
|
|
104
|
+
raise serializers.ValidationError("Invalid Account")
|
|
105
|
+
|
|
106
|
+
return value
|
|
107
|
+
|
|
108
|
+
def validate_number_of_payments(self, value):
|
|
109
|
+
if not value > 0:
|
|
110
|
+
raise serializers.ValidationError(
|
|
111
|
+
"Number of payments must be greater then 0"
|
|
112
|
+
)
|
|
113
|
+
|
|
114
|
+
return value
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
def validate(self, attrs):
|
|
118
|
+
frequency = attrs.get("frequency", Frequency.NONE)
|
|
119
|
+
|
|
120
|
+
if (frequency == Frequency.NONE) and (attrs.get("number_of_payments", 1) > 1):
|
|
121
|
+
raise serializers.ValidationError(
|
|
122
|
+
{
|
|
123
|
+
"message": "An accounts payable/receivable entry without any recurrence cannot have more than one payment."
|
|
124
|
+
}
|
|
125
|
+
)
|
|
126
|
+
|
|
127
|
+
if (attrs.get("number_of_payments", 1) == 1) and (
|
|
128
|
+
frequency != Frequency.NONE
|
|
129
|
+
):
|
|
130
|
+
raise serializers.ValidationError(
|
|
131
|
+
{
|
|
132
|
+
"message": "The number of payments must be greater than 1 in order to have a frequency."
|
|
133
|
+
} )
|
|
134
|
+
|
|
135
|
+
value = attrs.get("value")
|
|
136
|
+
entry_type = attrs.get("entry_type")
|
|
137
|
+
if value and entry_type == Type.ENTRY:
|
|
138
|
+
paid_value = attrs.get("paid_value", 0)
|
|
139
|
+
if value < paid_value:
|
|
140
|
+
raise serializers.ValidationError(
|
|
141
|
+
{"message": "The Paid value can't be greater than the value."}
|
|
142
|
+
)
|
|
143
|
+
|
|
144
|
+
return attrs
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
from rest_framework import serializers
|
|
2
|
+
from models.payment import PaymentMethod, PaymentMethodTaxs
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class PaymentMethodSerializer(serializers.ModelSerializer):
|
|
6
|
+
class Meta:
|
|
7
|
+
model = PaymentMethod
|
|
8
|
+
fields = ["id", "name", "tax"]
|
|
9
|
+
|
|
10
|
+
def validate_name(self, value):
|
|
11
|
+
if not (self.instance and value == self.instance.name):
|
|
12
|
+
if PaymentMethod.objects.filter(
|
|
13
|
+
name=value, deactivate=False, client_app=self.initial_data.get('client_app')).exists():
|
|
14
|
+
raise serializers.ValidationError(
|
|
15
|
+
"Already exists a payment method with this name."
|
|
16
|
+
)
|
|
17
|
+
|
|
18
|
+
return value
|
|
19
|
+
|
|
20
|
+
def validate_tax(self, value):
|
|
21
|
+
if value is not None and value < 0:
|
|
22
|
+
raise serializers.ValidationError("the tax can't be negative")
|
|
23
|
+
|
|
24
|
+
return value
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
class PaymentMethodTaxsSerializer(serializers.ModelSerializer):
|
|
28
|
+
class Meta:
|
|
29
|
+
model = PaymentMethodTaxs
|
|
30
|
+
fields = ["id", "initial_payment", "final_payment", "tax"]
|
|
31
|
+
|
|
32
|
+
def validate(self, attrs):
|
|
33
|
+
if attrs["initial_payment"] > attrs["final_payment"]:
|
|
34
|
+
raise serializers.ValidationError(
|
|
35
|
+
{"menssage": " The initial payment can't be bigger then the final_payment"}
|
|
36
|
+
)
|
|
37
|
+
|
|
38
|
+
taxs = PaymentMethodTaxs.objects.filter(
|
|
39
|
+
payment_method_id=self.context.get("payment_method_id"),
|
|
40
|
+
client_app=self.initial_data.get('client_app'),
|
|
41
|
+
)
|
|
42
|
+
|
|
43
|
+
if self.instance:
|
|
44
|
+
taxs = taxs.exclude(id=self.instance.id)
|
|
45
|
+
|
|
46
|
+
for tax in taxs:
|
|
47
|
+
if attrs["initial_payment"] in range(
|
|
48
|
+
tax.initial_payment, tax.final_payment + 1
|
|
49
|
+
):
|
|
50
|
+
raise serializers.ValidationError(
|
|
51
|
+
{
|
|
52
|
+
"initial_payment": "Already exists a tax for this payment in this payment method."
|
|
53
|
+
}
|
|
54
|
+
)
|
|
55
|
+
elif attrs["final_payment"] in range(
|
|
56
|
+
tax.initial_payment, tax.final_payment + 1
|
|
57
|
+
):
|
|
58
|
+
raise serializers.ValidationError(
|
|
59
|
+
{
|
|
60
|
+
"final_payment": "Already exists a tax for this payment in this payment method."
|
|
61
|
+
}
|
|
62
|
+
)
|
|
63
|
+
elif (
|
|
64
|
+
tax.initial_payment >= attrs["initial_payment"]
|
|
65
|
+
and tax.final_payment <= attrs["final_payment"]
|
|
66
|
+
):
|
|
67
|
+
raise serializers.ValidationError(
|
|
68
|
+
{
|
|
69
|
+
"menssage": "Already exists a tax for this payments in this payment method."
|
|
70
|
+
}
|
|
71
|
+
)
|
|
72
|
+
|
|
73
|
+
return attrs
|
|
File without changes
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
from datetime import date, timedelta
|
|
2
|
+
from finance_sdk.models.entry import Entry
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
from enums import Frequency
|
|
6
|
+
|
|
7
|
+
def generate_entries(validated_data, initial_data):
|
|
8
|
+
number_of_payments = validated_data.get("number_of_payments", 1)
|
|
9
|
+
payment_value = validated_data.get("value") / number_of_payments
|
|
10
|
+
frequency = validated_data.get("frequency")
|
|
11
|
+
validated_data["frequency"] = Frequency.get_frequency(frequency=frequency)
|
|
12
|
+
primary_payment = Entry.objects.create(**validated_data)
|
|
13
|
+
payment_method = primary_payment.payment_method
|
|
14
|
+
tax = payment_method.tax / 100 if payment_method else 0
|
|
15
|
+
liquid_value = (
|
|
16
|
+
payment_value - payment_value * tax
|
|
17
|
+
if validated_data.get("type") == Entry.entry_type.ENTRY
|
|
18
|
+
else None
|
|
19
|
+
)
|
|
20
|
+
primary_payment.value = payment_value
|
|
21
|
+
primary_payment.liquid_value = liquid_value
|
|
22
|
+
primary_payment.client_app = initial_data.get('client_app')
|
|
23
|
+
primary_payment.reference_record_id = primary_payment.id
|
|
24
|
+
primary_payment.save()
|
|
25
|
+
|
|
26
|
+
if number_of_payments > 1:
|
|
27
|
+
entry_payments = []
|
|
28
|
+
for payment in range(2, number_of_payments + 1):
|
|
29
|
+
entry_payments.append(
|
|
30
|
+
Entry(
|
|
31
|
+
description=validated_data.get("description"),
|
|
32
|
+
value=payment_value,
|
|
33
|
+
liquid_value=liquid_value,
|
|
34
|
+
category=validated_data.get("category"),
|
|
35
|
+
account=validated_data.get("account"),
|
|
36
|
+
cost_center=validated_data.get("cost_center"),
|
|
37
|
+
due_date=validated_data.get("due_date")
|
|
38
|
+
+ timedelta(days=frequency * (payment - 1)),
|
|
39
|
+
payment_method=validated_data.get("payment_method"),
|
|
40
|
+
person=validated_data.get("person"),
|
|
41
|
+
entry_type=validated_data.get("entry_type"),
|
|
42
|
+
registry_classification=validated_data.get(
|
|
43
|
+
"registry_classification"
|
|
44
|
+
),
|
|
45
|
+
number_of_payments=validated_data.get("number_of_payments"),
|
|
46
|
+
current_payment=payment,
|
|
47
|
+
frequency=primary_payment.frequency,
|
|
48
|
+
reference_record_id=primary_payment.pk,
|
|
49
|
+
client_app=initial_data.get('client_app'),
|
|
50
|
+
)
|
|
51
|
+
)
|
|
52
|
+
|
|
53
|
+
Entry.objects.bulk_create(entry_payments)
|
|
54
|
+
else:
|
|
55
|
+
received_value = validated_data.get("received_value", 0)
|
|
56
|
+
total_value = validated_data.get("value", 0)
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
if received_value < total_value and received_value > 0:
|
|
60
|
+
Entry.objects.create(
|
|
61
|
+
description=validated_data.get("description"),
|
|
62
|
+
value=total_value - received_value,
|
|
63
|
+
category=validated_data.get("category"),
|
|
64
|
+
account=validated_data.get("account"),
|
|
65
|
+
cost_center=validated_data.get("cost_center"),
|
|
66
|
+
due_date=validated_data.get("due_date"),
|
|
67
|
+
person=validated_data.get("person"),
|
|
68
|
+
entry_type=validated_data.get("entry_type"),
|
|
69
|
+
registry_classification=validated_data.get("registry_classification"),
|
|
70
|
+
number_of_payments=validated_data.get("numero_parcelas", 1),
|
|
71
|
+
cliente_app_id=initial_data.get('client_app'),
|
|
72
|
+
)
|
|
73
|
+
|
|
74
|
+
return primary_payment
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
|
finance_sdk/tests.py
ADDED
finance_sdk/utils.py
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
from django.forms import ValidationError
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
def raise_error(message):
|
|
6
|
+
raise ValidationError(
|
|
7
|
+
{
|
|
8
|
+
"message": message,
|
|
9
|
+
})
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def validate_item_in_list(
|
|
13
|
+
item, list, message, message_if_empty="", required=False
|
|
14
|
+
):
|
|
15
|
+
if required and not item:
|
|
16
|
+
raise_error(message_if_empty)
|
|
17
|
+
|
|
18
|
+
if item:
|
|
19
|
+
if isinstance(item, list):
|
|
20
|
+
itens = item
|
|
21
|
+
|
|
22
|
+
return (
|
|
23
|
+
itens
|
|
24
|
+
if all(item in list for item in itens)
|
|
25
|
+
else raise_error(message)
|
|
26
|
+
)
|
|
27
|
+
|
|
28
|
+
return item if item in list else raise_error(message)
|
|
29
|
+
|
|
30
|
+
return False
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def validate_natural_number(
|
|
35
|
+
number, message, message_if_empty="", required=False
|
|
36
|
+
):
|
|
37
|
+
if isinstance(number, list):
|
|
38
|
+
number = list(filter(lambda x: x.strip() != "", number))
|
|
39
|
+
|
|
40
|
+
elif isinstance(number, str) and number.strip() == "":
|
|
41
|
+
number = None
|
|
42
|
+
|
|
43
|
+
if required and not number:
|
|
44
|
+
raise_error(message_if_empty)
|
|
45
|
+
|
|
46
|
+
if number:
|
|
47
|
+
if isinstance(number, list):
|
|
48
|
+
numbers = number
|
|
49
|
+
to_int = lambda x: int(x)
|
|
50
|
+
|
|
51
|
+
return (
|
|
52
|
+
list(map(to_int, numbers))
|
|
53
|
+
if all(number.isnumeric() and number != "0" for number in numbers)
|
|
54
|
+
else raise_error(message)
|
|
55
|
+
)
|
|
56
|
+
|
|
57
|
+
return (
|
|
58
|
+
number
|
|
59
|
+
if number.isnumeric() and number != "0"
|
|
60
|
+
else raise_error(message)
|
|
61
|
+
)
|
|
62
|
+
|
|
63
|
+
return False
|
|
File without changes
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import operator
|
|
2
|
+
from functools import reduce
|
|
3
|
+
from rest_framework import viewsets
|
|
4
|
+
from rest_framework.views import APIView
|
|
5
|
+
|
|
6
|
+
from django.db.models.query_utils import Q
|
|
7
|
+
|
|
8
|
+
from models.accounts import Account, AccountPermission
|
|
9
|
+
from serializers.accounts import AccountSerializer, AccountPermissionSerializer
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class AccountViewSet(viewsets.ModelViewSet):
|
|
14
|
+
|
|
15
|
+
serializer_class = AccountSerializer
|
|
16
|
+
queryset = Account.objects.all()
|
|
17
|
+
|
|
18
|
+
def get_queryset(self):
|
|
19
|
+
queryset = super().get_queryset()
|
|
20
|
+
|
|
21
|
+
query = Q(deactivate=False)
|
|
22
|
+
|
|
23
|
+
if self.action == "list":
|
|
24
|
+
LIST = "list"
|
|
25
|
+
INDICATORS = "indicators"
|
|
26
|
+
|
|
27
|
+
name = str(self.request.query_params.get("name", ""))
|
|
28
|
+
|
|
29
|
+
use = self.validate_item_in_list(
|
|
30
|
+
item=self.request.query_params.get("use", "list"),
|
|
31
|
+
list=[LIST, INDICATORS],
|
|
32
|
+
message="Invalid",
|
|
33
|
+
required=True,
|
|
34
|
+
)
|
|
35
|
+
|
|
36
|
+
if use == INDICATORS:
|
|
37
|
+
queryset = AccountPermission.get_conta(
|
|
38
|
+
self.request.user.id, self.request.META["HTTP_CLIENTE_APP_ID"]
|
|
39
|
+
)
|
|
40
|
+
|
|
41
|
+
if name != "":
|
|
42
|
+
query &= reduce(
|
|
43
|
+
operator.__and__,
|
|
44
|
+
(
|
|
45
|
+
Q(name__unaccent__icontains=word)
|
|
46
|
+
for word in name.split(" ")
|
|
47
|
+
),
|
|
48
|
+
)
|
|
49
|
+
|
|
50
|
+
return queryset.filter(query).order_by("name")
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import operator
|
|
2
|
+
from functools import reduce
|
|
3
|
+
from rest_framework import viewsets
|
|
4
|
+
from rest_framework.views import APIView
|
|
5
|
+
|
|
6
|
+
from django.db.models.query_utils import Q
|
|
7
|
+
|
|
8
|
+
from models.bank import Bank
|
|
9
|
+
from serializers.bank import BankSerializer
|
|
10
|
+
|
|
11
|
+
class BankViewSet(viewsets.ModelViewSet):
|
|
12
|
+
|
|
13
|
+
serializer_class = BankSerializer
|
|
14
|
+
queryset = Bank.objects.all()
|
|
15
|
+
|
|
16
|
+
def get_queryset(self):
|
|
17
|
+
queryset = super().get_queryset()
|
|
18
|
+
|
|
19
|
+
query = Q(deactivate=False)
|
|
20
|
+
|
|
21
|
+
if self.action == "list":
|
|
22
|
+
name = str(self.request.query_params.get("name", "")).split(" ")
|
|
23
|
+
|
|
24
|
+
if name != "":
|
|
25
|
+
query &= reduce(
|
|
26
|
+
operator.__and__,
|
|
27
|
+
(Q(name__unaccent__icontains=word) for word in name),
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
return queryset.filter(query).order_by("-name")
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import operator
|
|
2
|
+
from functools import reduce
|
|
3
|
+
from rest_framework import viewsets
|
|
4
|
+
from rest_framework.views import APIView
|
|
5
|
+
|
|
6
|
+
from django.db.models.query_utils import Q
|
|
7
|
+
|
|
8
|
+
from models.category import Category
|
|
9
|
+
from serializers.category import CategorySerializer
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class CategoryViewSet(viewsets.ModelViewSet):
|
|
13
|
+
serializer_class = CategorySerializer
|
|
14
|
+
queryset = Category.objects.all()
|
|
15
|
+
|
|
16
|
+
def get_queryset(self):
|
|
17
|
+
queryset = super().get_queryset()
|
|
18
|
+
|
|
19
|
+
query = Q()
|
|
20
|
+
|
|
21
|
+
if self.action == "list":
|
|
22
|
+
query_params = self.request.query_params
|
|
23
|
+
|
|
24
|
+
name = str(query_params.get("name", "")).split(" ")
|
|
25
|
+
|
|
26
|
+
if name != "":
|
|
27
|
+
query &= reduce(
|
|
28
|
+
operator.__and__,
|
|
29
|
+
(Q(name__unaccent__icontains=word) for word in name),
|
|
30
|
+
)
|
|
31
|
+
|
|
32
|
+
deactivates = query_params.get("deactivate", "").lower() == "true"
|
|
33
|
+
|
|
34
|
+
query &= Q(deactivate=deactivates)
|
|
35
|
+
|
|
36
|
+
return queryset.filter(query).order_by("name")
|
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
from argparse import Action
|
|
2
|
+
import operator
|
|
3
|
+
from functools import reduce
|
|
4
|
+
from rest_framework.response import Response
|
|
5
|
+
from rest_framework import viewsets
|
|
6
|
+
from rest_framework.views import APIView
|
|
7
|
+
|
|
8
|
+
from django.db.models.query_utils import Q
|
|
9
|
+
from finance_sdk_wlc.finance_sdk.utils import validate_item_in_list, validate_natural_number
|
|
10
|
+
|
|
11
|
+
from enums import Frequency, Type
|
|
12
|
+
|
|
13
|
+
from models.entry import Entry
|
|
14
|
+
from serializers.entry import EntrySerializer
|
|
15
|
+
|
|
16
|
+
from models.accounts import Account, AccountPermission
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class EntryViewSet( viewsets.ModelViewSet):
|
|
20
|
+
|
|
21
|
+
serializer_class = EntrySerializer
|
|
22
|
+
queryset = Entry.objects.all()
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def get_queryset(self):
|
|
26
|
+
client_app_id = self.request.query_params.get("client_app")
|
|
27
|
+
employee_id = self.request.query_params.get("employee")
|
|
28
|
+
|
|
29
|
+
queryset = self.queryset
|
|
30
|
+
|
|
31
|
+
query = (
|
|
32
|
+
(
|
|
33
|
+
Q(
|
|
34
|
+
account_id__in=AccountPermission.get_conta(
|
|
35
|
+
self.request.user.id, client_app_id
|
|
36
|
+
),
|
|
37
|
+
account__deactivate=False,
|
|
38
|
+
account__bank__deactivate=False,
|
|
39
|
+
)
|
|
40
|
+
| Q(account__isnull=True) )
|
|
41
|
+
&
|
|
42
|
+
|
|
43
|
+
(
|
|
44
|
+
Q(payment_method__isnull=False, payment_method__desativada=False)
|
|
45
|
+
| Q(payment_method__isnull=True)
|
|
46
|
+
)
|
|
47
|
+
& (
|
|
48
|
+
Q(category__isnull=False, category__deactivate=False)
|
|
49
|
+
| Q(category__isnull=True)
|
|
50
|
+
)
|
|
51
|
+
|
|
52
|
+
(
|
|
53
|
+
Q(person_isnull=False) | Q(person_isnull=True)
|
|
54
|
+
)
|
|
55
|
+
)
|
|
56
|
+
|
|
57
|
+
person_id = self.request.query_params.getlist("person_ids", [])
|
|
58
|
+
|
|
59
|
+
if person_id:
|
|
60
|
+
query &= Q(person__id__in=person_id)
|
|
61
|
+
|
|
62
|
+
if client_app_id:
|
|
63
|
+
query &= Q(client_app__id=client_app_id)
|
|
64
|
+
|
|
65
|
+
cost_center_id = self.request.query_params.getlist("cost_center", [])
|
|
66
|
+
|
|
67
|
+
if cost_center_id:
|
|
68
|
+
query &= Q(cost_center__id__in=cost_center_id)
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
if self.action == "list":
|
|
72
|
+
query_params = self.request.query_params
|
|
73
|
+
|
|
74
|
+
entry_type = self.validate_item_in_list(
|
|
75
|
+
item=query_params.get("tipo", False),
|
|
76
|
+
lista=dict(Entry.Type.TYPE).keys(),
|
|
77
|
+
message="Entry type invalid",
|
|
78
|
+
message_if_empty="Entry type required",
|
|
79
|
+
required=True,
|
|
80
|
+
)
|
|
81
|
+
|
|
82
|
+
initial_date, final_date = self.validar_periodo_datas(
|
|
83
|
+
initial_date=query_params.get("initial_date", False),
|
|
84
|
+
final_date=query_params.get("final_date", False),
|
|
85
|
+
)
|
|
86
|
+
|
|
87
|
+
query &= Q(
|
|
88
|
+
entry_type=entry_type, due_date__gte=initial_date, due_date__lte=final_date
|
|
89
|
+
)
|
|
90
|
+
|
|
91
|
+
cost_center = validate_natural_number(
|
|
92
|
+
numero=query_params.get("cost_center", False),
|
|
93
|
+
mensagem="Invalid Cost Center",
|
|
94
|
+
)
|
|
95
|
+
|
|
96
|
+
if cost_center:
|
|
97
|
+
query &= Q(cost_center_id=cost_center)
|
|
98
|
+
|
|
99
|
+
person = query_params.get("person", False)
|
|
100
|
+
|
|
101
|
+
if person:
|
|
102
|
+
person = person.split(" ")
|
|
103
|
+
query &= reduce(
|
|
104
|
+
operator.__and__,
|
|
105
|
+
(Q(person__name__unaccent__icontains=param) for param in person),
|
|
106
|
+
)
|
|
107
|
+
|
|
108
|
+
category = validate_natural_number(
|
|
109
|
+
number=query_params.get("category", False),
|
|
110
|
+
message="Inválid Category",
|
|
111
|
+
)
|
|
112
|
+
|
|
113
|
+
if category:
|
|
114
|
+
query &= Q(categoria_id=category)
|
|
115
|
+
|
|
116
|
+
account = validate_natural_number(
|
|
117
|
+
number=query_params.get("account", False), message="Invalid Account"
|
|
118
|
+
)
|
|
119
|
+
|
|
120
|
+
if account:
|
|
121
|
+
query &= Q(account_id=account)
|
|
122
|
+
|
|
123
|
+
return queryset.filter(query).order_by(
|
|
124
|
+
"due_date", "category", "description", "created_at", "id"
|
|
125
|
+
)
|
|
126
|
+
|
|
127
|
+
def list(self, request, *args, **kwargs):
|
|
128
|
+
if "values" not in request.query_params:
|
|
129
|
+
return super().list(request, *args, **kwargs)
|
|
130
|
+
|
|
131
|
+
serializer_data = EntrySerializer(
|
|
132
|
+
{"Entry": self.get_queryset()}, context={"request": request}
|
|
133
|
+
).data
|
|
134
|
+
|
|
135
|
+
return Response(data=serializer_data["valores"])
|
|
136
|
+
|
|
137
|
+
def update(self, request, *args, **kwargs):
|
|
138
|
+
partial = kwargs.pop("partial", False)
|
|
139
|
+
instance = self.get_object()
|
|
140
|
+
recalculate_liquid_value = request.data.get("recalculate", False)
|
|
141
|
+
serializer = EntrySerializer(
|
|
142
|
+
instance,
|
|
143
|
+
data=request.data,
|
|
144
|
+
partial=partial,
|
|
145
|
+
context={"request": request, "recalculate": recalculate_liquid_value},
|
|
146
|
+
)
|
|
147
|
+
serializer.is_valid(raise_exception=True)
|
|
148
|
+
self.perform_update(serializer)
|
|
149
|
+
|
|
150
|
+
if getattr(instance, "_prefetched_objects_cache", None):
|
|
151
|
+
instance._prefetched_objects_cache = {}
|
|
152
|
+
|
|
153
|
+
return Response(serializer.data)
|
|
154
|
+
|
|
155
|
+
def destroy(self, request, *args, **kwargs):
|
|
156
|
+
instance = self.get_object()
|
|
157
|
+
|
|
158
|
+
if Entry.objects.filter(reference_record=instance).count() > 1:
|
|
159
|
+
return Response(
|
|
160
|
+
{"message": "Payment deletion requires confirmation."},
|
|
161
|
+
),
|
|
162
|
+
|
|
163
|
+
|
|
164
|
+
instance.reference_record = None
|
|
165
|
+
instance.save()
|
|
166
|
+
|
|
167
|
+
self.perform_destroy(instance)
|
|
168
|
+
|
|
169
|
+
return Response(status=status.HTTP_204_NO_CONTENT)
|
|
170
|
+
|
|
171
|
+
@Action(methods=["GET"], detail=True, url_path="payments")
|
|
172
|
+
def list_payments(self, request, pk=None):
|
|
173
|
+
entry = self.get_object()
|
|
174
|
+
|
|
175
|
+
if entry.reference_record:
|
|
176
|
+
payments = Entry.objects.filter(
|
|
177
|
+
reference_record=entry.reference_record
|
|
178
|
+
).order_by("id")
|
|
179
|
+
else:
|
|
180
|
+
payments = Entry.objects.filter(id=entry.id)
|
|
181
|
+
|
|
182
|
+
|
|
183
|
+
page = self.paginate_queryset(payments)
|
|
184
|
+
serializer = self.get_serializer(page, many=True)
|
|
185
|
+
|
|
186
|
+
return self.get_paginated_response(serializer.data)
|
|
187
|
+
|
|
188
|
+
|
|
189
|
+
|
|
190
|
+
@Action(methods=["DELETE"], detail=True, url_path="confirm_payment")
|
|
191
|
+
def confirm_payment_deletion(self, request, pk=None):
|
|
192
|
+
entry = self.get_object()
|
|
193
|
+
|
|
194
|
+
payments = Entry.objects.filter(reference_record=entry).exclude(
|
|
195
|
+
pk=entry.pk
|
|
196
|
+
)
|
|
197
|
+
|
|
198
|
+
for payment in payments:
|
|
199
|
+
self.perform_destroy(payment)
|
|
200
|
+
|
|
201
|
+
entry.reference_record = None
|
|
202
|
+
entry.save()
|
|
203
|
+
|
|
204
|
+
self.perform_destroy(entry)
|
|
205
|
+
|
|
206
|
+
return Response()
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import operator
|
|
2
|
+
from functools import reduce
|
|
3
|
+
from rest_framework import viewsets
|
|
4
|
+
from rest_framework.views import APIView
|
|
5
|
+
from django.http.response import Http404, HttpResponse
|
|
6
|
+
from rest_framework.response import Response
|
|
7
|
+
|
|
8
|
+
from django.db.models.query_utils import Q
|
|
9
|
+
|
|
10
|
+
from models.payment import PaymentMethod, PaymentMethodTaxs
|
|
11
|
+
from serializers.payments import PaymentMethodSerializer, PaymentMethodTaxsSerializer
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class PaymentMethodViewSet(viewsets.ModelViewSet):
|
|
15
|
+
|
|
16
|
+
serializer_class = PaymentMethodSerializer
|
|
17
|
+
queryset = PaymentMethod.objects.all()
|
|
18
|
+
|
|
19
|
+
def get_queryset(self):
|
|
20
|
+
queryset = super().get_queryset()
|
|
21
|
+
|
|
22
|
+
query = Q(deactivate=False)
|
|
23
|
+
|
|
24
|
+
if self.action == "list":
|
|
25
|
+
name = str(self.request.query_params.get("name", "")).split(" ")
|
|
26
|
+
|
|
27
|
+
if name != "":
|
|
28
|
+
query &= reduce(
|
|
29
|
+
operator.__and__,
|
|
30
|
+
(Q(name__unaccent__icontains=word) for word in name),
|
|
31
|
+
)
|
|
32
|
+
|
|
33
|
+
return queryset.filter(query).order_by("name")
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
class ListPaymentMethodTaxs(viewsets.ModelViewSet):
|
|
37
|
+
|
|
38
|
+
serializer_class = PaymentMethodTaxsSerializer
|
|
39
|
+
queryset = PaymentMethodTaxs.objects.all()
|
|
40
|
+
|
|
41
|
+
def get_queryset(self):
|
|
42
|
+
queryset = super().get_queryset()
|
|
43
|
+
|
|
44
|
+
query = Q(deactivate=False)
|
|
45
|
+
|
|
46
|
+
if self.action == "list":
|
|
47
|
+
tax = str(self.request.query_params.get("tax", "")).split(" ")
|
|
48
|
+
|
|
49
|
+
if tax != "":
|
|
50
|
+
query &= reduce(
|
|
51
|
+
operator.__and__,
|
|
52
|
+
(Q(tax__icontains=word) for word in tax),
|
|
53
|
+
)
|
|
54
|
+
|
|
55
|
+
return queryset.filter(query).order_by("initial_date")
|
|
56
|
+
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: finance_sdk
|
|
3
|
+
Version: 1.0.3
|
|
4
|
+
Summary: SDK for Finance Module
|
|
5
|
+
Home-page: https://github.com/wlc-solucoes/wlc-sdk-financeiro.git
|
|
6
|
+
Author: WLC Soluções
|
|
7
|
+
Author-email: analiciasouza.11@gmail.com
|
|
8
|
+
Classifier: Environment :: Web Environment
|
|
9
|
+
Classifier: Framework :: Django
|
|
10
|
+
Classifier: Intended Audience :: Developers
|
|
11
|
+
Classifier: Programming Language :: Python
|
|
12
|
+
Requires-Dist: django
|
|
13
|
+
Requires-Dist: djangorestframework
|
|
14
|
+
Dynamic: author
|
|
15
|
+
Dynamic: author-email
|
|
16
|
+
Dynamic: classifier
|
|
17
|
+
Dynamic: home-page
|
|
18
|
+
Dynamic: requires-dist
|
|
19
|
+
Dynamic: summary
|
|
20
|
+
|
|
21
|
+
# SDK Financeiro - WLC Soluções
|
|
22
|
+
|
|
23
|
+
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
finance_sdk/__init__.py,sha256=Gzuvw8Ow_dRgrZIJptCgRtdYkXj-2sqilDbIlIxdHK8,78
|
|
2
|
+
finance_sdk/admin.py,sha256=suMo4x8I3JBxAFBVIdE-5qnqZ6JAZV0FESABHOSc-vg,63
|
|
3
|
+
finance_sdk/apps.py,sha256=UA4iSvwSqXkM9Dwlr3O8vO6AX8z3hwAQ9W5TnBGPMvE,153
|
|
4
|
+
finance_sdk/enums.py,sha256=V-Cn2r4KGoqxW35iK-_T_ve5KSxg2fJromIhcW-G2Dw,1176
|
|
5
|
+
finance_sdk/tests.py,sha256=mrbGGRNg5jwbTJtWWa7zSKdDyeB4vmgZCRc2nk6VY-g,60
|
|
6
|
+
finance_sdk/utils.py,sha256=zgZPMmxXeN9dAYPYvL4a3LECTeR7WFfVz1T0RZF3m44,1594
|
|
7
|
+
finance_sdk/migrations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
8
|
+
finance_sdk/models/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
9
|
+
finance_sdk/models/accounts.py,sha256=E41hh6yjrRpwfPtIwqGUZpC-q6ZxxS0MdwPrEyjGidI,1417
|
|
10
|
+
finance_sdk/models/bank.py,sha256=NHI1Dxd6VcxbKC2WeaLA5qG4BRlOY5oU7oqGzHArYyY,397
|
|
11
|
+
finance_sdk/models/category.py,sha256=FwUBQ2aDedyytfX6GOFKynM4N_u45qcwCm4_oAoBfu0,669
|
|
12
|
+
finance_sdk/models/entry.py,sha256=hDGeXDgyuJNhrgY3jUN4hPs5txhSxGqE-2NmzucKpKA,2153
|
|
13
|
+
finance_sdk/models/payment.py,sha256=4-5cHpYvor3mzSORfJ1SIyv_yeaK5LJYLtQb_vi9EuA,995
|
|
14
|
+
finance_sdk/serializers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
15
|
+
finance_sdk/serializers/accounts.py,sha256=JpWDwOQ4Ii08iYHd8TTPZjyFkS8PguIRfnT6KGL3oZw,1325
|
|
16
|
+
finance_sdk/serializers/bank.py,sha256=toIYBVwwoGv8BXbcTHI5DhVrsHtrRoIgGjcSQ14FJ7o,596
|
|
17
|
+
finance_sdk/serializers/category.py,sha256=ahx5wpHqvtYdVtFUDgUK_CrPyGEWDm_guP_7lH4VlvE,1023
|
|
18
|
+
finance_sdk/serializers/entry.py,sha256=lheWYdzhAa4WyZByGMxuvCKZMYP5y9vWZDwJEWngtq0,4665
|
|
19
|
+
finance_sdk/serializers/payments.py,sha256=ODmxwTzsmjsZ7ZFqCkS5MFniLDJRumXdI7mAf7CCUg4,2643
|
|
20
|
+
finance_sdk/services/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
21
|
+
finance_sdk/services/entriesService.py,sha256=esQ7F-wJ1SLRzoooIJKadX_gQvvlOpiTaD7oz3Wy2KY,3504
|
|
22
|
+
finance_sdk/views/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
23
|
+
finance_sdk/views/account.py,sha256=ptpnONCxRtCGMS2hGfo9WOQTqzSSY2ybHcAsVZKSkfg,1461
|
|
24
|
+
finance_sdk/views/bank.py,sha256=lrYVFSatTBEztW3HFbkMSYwMW5sJVwOqIyk_R6gxF64,824
|
|
25
|
+
finance_sdk/views/category.py,sha256=GGVZaRsxGz3y4urbCizIcmvZXVedndrF9rbsiyI6bpk,1003
|
|
26
|
+
finance_sdk/views/entry.py,sha256=pIuCiLiW0Kz_-9qDVn4XmeSAQlSoa0K4oxGUa9Jwer0,6420
|
|
27
|
+
finance_sdk/views/payment.py,sha256=lECY1E0tGguDZqjJ6xrGvCY-osGy3FR9RAgzz6QdupM,1646
|
|
28
|
+
finance_sdk-1.0.3.dist-info/METADATA,sha256=ae5-wb_vHXpL37nW8wY_ZVxNdbh6UG4_rqNTuLT8aq8,590
|
|
29
|
+
finance_sdk-1.0.3.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
30
|
+
finance_sdk-1.0.3.dist-info/top_level.txt,sha256=VghHbEzVbFaLJhFhyllLz1gaRt6DXhz_oBMN204-cNY,12
|
|
31
|
+
finance_sdk-1.0.3.dist-info/RECORD,,
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
finance_sdk
|