1
1
Prechádzať zdrojové kódy

Merge branch 'feature/transactions' of 1ffy/sp-1 into master

Всеволод Левитан 1 rok pred
rodič
commit
c037c89ec9

+ 2 - 0
main.py

@@ -1,4 +1,5 @@
 import os
+import sys
 from flask import Flask
 from src.errors.argument_exception import argument_exception
 from src.export.exporter_factory import exporter_factory
@@ -60,6 +61,7 @@ def run():
     strg = storage()
     start = start_factory(setman.settings, strg)
     start.create()
+    start.create_transactions()
     app.run()
 
 

+ 1 - 1
src/convert/model_converter.py

@@ -16,7 +16,7 @@ class model_converter(converter):
             if isinstance(attr, property):
                 v = attr.fget(obj)
                 if issubclass(v.__class__, abstract_reference):
-                    properties[name] = f"{v.id}"
+                    properties[name] = converter_factory.convert(v)
                 else:
                     properties[name] = converter_factory.convert(v)
         return properties

+ 7 - 0
src/logic/abstract_process.py

@@ -0,0 +1,7 @@
+from abc import ABC, abstractmethod
+
+
+class abstract_process(ABC):
+    @abstractmethod
+    def create(self):
+        pass

+ 27 - 0
src/logic/process_factory.py

@@ -0,0 +1,27 @@
+from click import argument
+from src.errors.argument_exception import argument_exception
+from src.logic.process_transaction import process_transaction
+from src.validation.validator import validator
+from src.storage.storage import storage
+
+
+class process_factory:
+    __smap = dict()
+
+    def __init__(self):
+        self.__vtor = validator()
+        self.__build__()
+
+    def __build__(self):
+        self.__smap[storage.transaction_key()] = process_transaction()
+
+    def create(self, format, strg):
+        self.__vtor.check_type(format, str)
+        self.__vtor.check_type(strg, storage)
+
+        if format not in self.__smap.keys():
+            raise argument_exception(
+                f"Несуществующий формат ({format} not in {str(self.__smap)})"
+            )
+
+        return self.__smap[format]

+ 22 - 0
src/logic/process_transaction.py

@@ -0,0 +1,22 @@
+from src.models.storage_turn_model import storage_turn_model
+from src.logic.abstract_process import abstract_process
+
+
+class process_transaction(abstract_process):
+    @classmethod
+    def create(self, transactions):
+        res = dict()
+        for t in transactions:
+            k = (t.warehouse, t.nomenclature, t.measurement_unit)
+            v = t.amount * t.transaction_type
+            if k in res.keys():
+                res[k] += v
+            else:
+                res[k] = v
+
+        ts = list()
+        for k, v in res.items():
+            t = storage_turn_model("Turn", k[0], v, k[1], k[2])
+            ts.append(t)
+
+        return t

+ 30 - 0
src/logic/start_factory.py

@@ -1,3 +1,6 @@
+import datetime
+from src.models.transaction_model import transaction_model
+from src.models.warehouse_model import warehouse_model
 from src.models.recipe_model import recipe_model
 from src.models.ingredient_model import ingredient_model
 from src.models.nomenclature_group_model import nomenclature_group_model
@@ -108,6 +111,7 @@ class start_factory:
 
             # Формируем и зпоминаем номеклатуру
             res = self.create_recipes()
+            tr = self.create_transactions()
             ingredients = set()
             for x in res:
                 for ing in x.ingredients:
@@ -126,3 +130,29 @@ class start_factory:
             self.__save(storage.recipe_key(), recipes)
 
         return result
+
+    def create_transactions(self):
+        units = [
+            measurement_unit_model.create_g(),
+            measurement_unit_model.create_kg(),
+            measurement_unit_model.create_l(),
+            measurement_unit_model.create_ml(),
+            measurement_unit_model.create_pcs(),
+        ]
+        nm = nomenclature_model(
+            "Test", "Test Test", units[0], nomenclature_group_model.create_group()
+        )
+        wh = warehouse_model.create("Test", "Testtest")
+        res = []
+
+        for i in range(0, 20):
+            unit = units[i % 5]
+            res.append(
+                transaction_model.create(
+                    "test", wh, nm, i, i % 2, unit, datetime.datetime.now()
+                )
+            )
+
+        self.__save(storage.transaction_key(), res)
+
+        return res

+ 2 - 2
src/models/measurement_unit_model.py

@@ -33,7 +33,7 @@ class measurement_unit_model(abstract_reference):
         """
 
         if self.__base_measurement_unit is None:
-            return self
+            return None
 
         return self.__base_measurement_unit
 
@@ -127,4 +127,4 @@ class measurement_unit_model(abstract_reference):
         Returns:
             Модель литра
         """
-        return measurement_unit_model("литр", measurement_unit_model.create_ml(), 1000)
+        return measurement_unit_model("литр", 1000, measurement_unit_model.create_ml())

+ 69 - 0
src/models/storage_turn_model.py

@@ -0,0 +1,69 @@
+from src.models.measurement_unit_model import measurement_unit_model
+from src.models.nomenclature_model import nomenclature_model
+from src.models.warehouse_model import warehouse_model
+from src.validation.validator import validator
+from src.models.abstract_reference import abstract_reference
+
+
+class storage_turn_model(abstract_reference):
+    def __init__(self, name, warehouse, turn, nomenclature, measurement_unit):
+        self.__vtor = validator()
+
+        self.warehouse = warehouse
+        self.turn = turn
+        self.nomenclature = nomenclature
+        self.measurement_unit = measurement_unit
+
+        super().__init__(name)
+
+    __warehouse = None
+
+    @property
+    def warehouse(self):
+        """Склад"""
+        return self.__warehouse
+
+    @warehouse.setter
+    def warehouse(self, value):
+        """Склад"""
+        self.__vtor.check_type(value, warehouse_model)
+        self.__warehouse = value
+
+    __turn = 0
+
+    @property
+    def turn(self):
+        """Оборот"""
+        return self.__turn
+
+    @turn.setter
+    def turn(self, value):
+        """Оборот"""
+        self.__vtor.check_number(value)
+        self.__turn = value
+
+    __nomenclature = None
+
+    @property
+    def nomenclature(self):
+        """Номенклатура"""
+        return self.__nomenclature
+
+    @nomenclature.setter
+    def nomenclature(self, value):
+        """Номенклатура"""
+        self.__vtor.check_type(value, nomenclature_model)
+        self.__nomenclature = value
+
+    __measurement_unit = None
+
+    @property
+    def measurement_unit(self):
+        """Единица измерения"""
+        return self.__measurement_unit
+
+    @measurement_unit.setter
+    def measurement_unit(self, value):
+        """Единица измерения"""
+        self.__vtor.check_type(value, measurement_unit_model)
+        self.__measurement_unit = value

+ 110 - 0
src/models/transaction_model.py

@@ -0,0 +1,110 @@
+import datetime
+from src.models.measurement_unit_model import measurement_unit_model
+from src.models.nomenclature_model import nomenclature_model
+from src.models.warehouse_model import warehouse_model
+from src.models.abstract_reference import abstract_reference
+from src.validation.validator import validator
+
+
+class transaction_model(abstract_reference):
+    def __init__(self, name=None):
+        super().__init__(name)
+
+    @staticmethod
+    def create(
+        name,
+        warehouse,
+        nomenclature,
+        amount,
+        transactionType,
+        measurementUnit,
+        timeSpan,
+    ):
+        obj = transaction_model(name)
+        obj.__vtor = validator()
+        obj.warehouse = warehouse
+        obj.nomenclature = nomenclature
+        obj.amount = amount
+        obj.transaction_type = transactionType
+        obj.measurement_unit = measurementUnit
+        obj.time_span = timeSpan
+
+        return obj
+
+    __warehouse = None
+
+    @property
+    def warehouse(self):
+        """Склад"""
+        return self.__warehouse
+
+    @warehouse.setter
+    def warehouse(self, value):
+        """Склад"""
+        self.__vtor.check_type(value, warehouse_model)
+        self.__warehouse = value
+
+    __nomenclature = None
+
+    @property
+    def nomenclature(self):
+        """Номенклатура"""
+        return self.__nomenclature
+
+    @nomenclature.setter
+    def nomenclature(self, value):
+        """Номенклатура"""
+        self.__vtor.check_type(value, nomenclature_model)
+        self.__nomenclature = value
+
+    __amount = 0
+
+    @property
+    def amount(self):
+        """Количество товара"""
+        return self.__amount
+
+    @amount.setter
+    def amount(self, value):
+        """Количество товара"""
+        self.__vtor.check_number(value)
+        self.__amount = value
+
+    __transactionType = None
+
+    @property
+    def transaction_type(self):
+        """Тип транзакции"""
+        return self.__transactionType
+
+    @transaction_type.setter
+    def transaction_type(self, value):
+        """Тип транзакции"""
+        self.__vtor.check_type(value, int)
+        self.__transactionType = value
+
+    __measurementUnit = None
+
+    @property
+    def measurement_unit(self):
+        """Единица измерения"""
+        return self.__measurementUnit
+
+    @measurement_unit.setter
+    def measurement_unit(self, value):
+        """Единица измерения"""
+        self.__vtor.check_type(value, measurement_unit_model)
+        self.__measurementUnit = value
+
+    __timeSpan = None
+
+    @property
+    def time_span(self):
+        """Период"""
+        return self.__timeSpan
+
+    @time_span.setter
+    def time_span(self, value):
+        """Период"""
+        self.__vtor.check_type(value, datetime.datetime)
+        self.__timeSpan = value

+ 6 - 0
src/models/transaction_type.py

@@ -0,0 +1,6 @@
+import enum
+
+
+class TransactionType(enum.Enum):
+    income = 1
+    outcome = -1

+ 24 - 1
src/models/warehouse_model.py

@@ -1,6 +1,29 @@
 from src.models.abstract_reference import abstract_reference
+from src.validation.validator import validator
 
 
 class warehouse_model(abstract_reference):
-    def __init__(self, name):
+    # Адрес
+    __address = ""
+
+    def __init__(self, name=None):
+        self.__vtor = validator()
         super().__init__(name)
+
+    def create(name, address):
+        obj = warehouse_model(name)
+        obj.address = address
+        return obj
+
+    @property
+    def address(self):
+        """Адрес склада"""
+        return self.__address
+
+    @address.setter
+    def address(self, value):
+        """Адрес склада"""
+        self.__vtor.check_type(value, str)
+        self.__vtor.check_length_greater(value, 0)
+
+        self.__address = value

+ 6 - 0
src/storage/storage.py

@@ -63,3 +63,9 @@ class storage:
             _type_: _description_
         """
         return "recipe"
+
+    @staticmethod
+    def transaction_key():
+        """Список транзакций"""
+
+        return "transaction"

+ 43 - 0
tests/test_processes.py

@@ -0,0 +1,43 @@
+import os
+import unittest
+from src.logic.process_factory import process_factory
+from src.logic.start_factory import start_factory
+from src.export.strategies.json_export import json_export
+from src.models.recipe_model import recipe_model
+from src.models.nomenclature_group_model import nomenclature_group_model
+from src.models.nomenclature_model import nomenclature_model
+from src.models.ingredient_model import ingredient_model
+from src.export.strategies.csv_export import csv_export
+from src.export.exporter import exporter
+from src.models.measurement_unit_model import measurement_unit_model
+from src.settings.settings import settings
+from src.settings.settings_manager import settings_manager
+from src.storage.storage import storage
+
+
+class test_processes(unittest.TestCase):
+    #
+    # Проверка создания и записи транзакций
+    #
+    def test_create_transactions(self):
+        stor = storage()
+        setman = settings_manager()
+        setman.open(f"{os.path.dirname(__file__) + '/..'}/config/settings.json")
+        st = setman.settings
+
+        result = start_factory(st, stor).create_transactions()
+
+        assert len(stor.data[stor.transaction_key()]) > 0
+
+    def test_create_process(self):
+        stor = storage()
+        setman = settings_manager()
+        setman.open(f"{os.path.dirname(__file__) + '/..'}/config/settings.json")
+        st = setman.settings
+
+        ts = start_factory(st, stor).create_transactions()
+
+        ps = process_factory().create(stor.transaction_key(), stor)
+        res = ps.create(stor.data[stor.transaction_key()])
+
+        assert res is not None