Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 19 additions & 26 deletions src/logics/tbs_calculator.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
from typing import List, Dict
from typing import List
from datetime import date, datetime
from src.core.validator import Validator as vld
from src.logics.tbs_line import TbsLine
from src.models.storage_model import StorageModel
from src.models.transaction_model import TransactionModel
from src.singletons.repository import Repository
from src.singletons.start_service import StartService


Expand All @@ -23,28 +21,23 @@ def calculate(

start = datetime(start.year, start.month, start.day)
end = datetime(end.year, end.month, end.day, 23, 59, 59)
transactions = StartService().transactions
data: Dict[str, TbsLine] = dict()
for transaction in transactions.values():
if transaction.storage == storage and transaction.datetime <= end:
code = transaction.nomenclature.unique_code
if code not in data:
data[code] = TbsLine(transaction)
line = data[code]
line.add(transaction, start, end)

tbs_keys = data.keys()
all_keys = StartService().data[Repository.nomenclatures_key].keys()
other_keys = set(all_keys) - set(tbs_keys)
for key in other_keys:
nomenclature = StartService().repository.get(unique_code=key)
if nomenclature is None:
continue
data[key] = TbsLine(TransactionModel(
nomenclature=nomenclature,
storage=storage,
count=0,
measure_unit=nomenclature.measure_unit
))
result = list()
data = StartService().repository.transactions_data

return list(data.values())
for nom_key, stor_dict in data.items():
nomenclature = StartService().repository.get(unique_code=nom_key)
line = TbsLine(nomenclature=nomenclature)
list_ = stor_dict.get(storage.unique_code, list())
for dt, count in list_:
if dt < start:
line.start_count += count
elif dt <= end:
if count > 0:
line.income += count
else:
line.outgo += count

result += [line]

return result
60 changes: 40 additions & 20 deletions src/logics/tbs_line.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from typing import List
from typing import Optional, Union
from datetime import datetime
from src.core.validator import Validator as vld
from src.core.exceptions import OperationException
Expand All @@ -15,24 +15,33 @@ class TbsLine:
# Единица измерения (базовая для номенклатуры)
__measure_unit: MeasureUnitModel

# Значения транзакций до начальной даты
__counts_before_start: List[float]
# Начальный остаток
__start_count: float = 0.0

# Значения транзакций в промежутке между начальной и конечной датами
__counts_before_end: List[float]
# Приход
__income: float = 0.0

# Приход (вычисляемое поле)

# Расход (вычисляемое поле)
# Расход
__outgo: float = 0.0

# Остаток на дату окончания (вычисляемое поле)

def __init__(self, transaction: TransactionModel):
self.nomenclature = transaction.nomenclature
def __init__(
self,
nomenclature: NomenclatureModel,
start_count: Optional[float] = None,
income: Optional[float] = None,
outgo: Optional[float] = None,
):
self.nomenclature = nomenclature
base_unit, _ = self.nomenclature.measure_unit.get_base_unit()
self.measure_unit = base_unit
self.__counts_before_start = list()
self.__counts_before_end = list()
if start_count is not None:
self.start_count = start_count
if income is not None:
self.income = income
if outgo is not None:
self.outgo = outgo

"""Поле номенклатуры"""
@property
Expand All @@ -57,26 +66,37 @@ def measure_unit(self, value: MeasureUnitModel):
"""Поле начального остатка"""
@property
def start_count(self) -> float:
return sum(self.__counts_before_start)
return self.__start_count

@start_count.setter
def start_count(self, value: Union[int, float]):
vld.is_number(value, "start_count")
self.__start_count = value

"""Поле прихода"""
@property
def income(self) -> float:
return sum([value
for value in self.__counts_before_end
if value > 0])
return self.__income

@income.setter
def income(self, value: Union[int, float]):
vld.is_number(value, "income")
self.__income = value

"""Поле расхода"""
@property
def outgo(self) -> float:
return sum([value
for value in self.__counts_before_end
if value < 0])
return self.__outgo

@outgo.setter
def outgo(self, value: Union[int, float]):
vld.is_number(value, "outgo")
self.__outgo = value

"""Поле конечного остатка"""
@property
def end_count(self) -> float:
return self.start_count + self.income + self.outgo
return self.__start_count + self.__income + self.__outgo

"""
Метод, добавляющий значение транзакции к соответствующему полю __count
Expand Down
17 changes: 16 additions & 1 deletion src/singletons/repository.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from typing import List, Any, Optional
from typing import List, Any, Optional, Dict, Tuple
from datetime import datetime
from src.core.validator import Validator as vld
from src.core.exceptions import ParamException
from src.utils import get_properties
Expand All @@ -12,6 +13,9 @@ class Repository:
# Словарь наименований моделей
__data = dict()

# Вложенный словарь с данными о транзакциях
__transactions_data: Dict[str, Dict[str, List[Tuple[datetime, float]]]]

# Ключ для единиц измерения
measure_unit_key: str = "measure_units"

Expand Down Expand Up @@ -46,12 +50,23 @@ def keys() -> List[str]:
return [getattr(Repository, f) for f in get_properties(Repository)
if f.endswith("_key")]

"""Данные о транзакциях"""
@property
def transactions_data(self) -> Dict[str, Dict[str, List[Tuple[datetime, float]]]]:
return self.__transactions_data

@transactions_data.setter
def transactions_data(self, value: Dict):
vld.is_dict(value, "transactions_data")
self.__transactions_data = value

"""Инициализация списков в словаре данных"""
def initalize(self):
# Все ключи будут ссылаться на словари формата name: object
# с соответствующими объектами
for key in Repository.keys():
self.data[key] = dict()
self.transactions_data = dict()

"""Метод получения объекта в памяти по имени"""
def get_by_name(self, name: str) -> Optional[Any]:
Expand Down
11 changes: 11 additions & 0 deletions src/singletons/start_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,17 @@ def __convert_models(
model = model_type.from_dto(dto, self.__repository)
self.__repository.data[repo_key][model.unique_code] = model

if model_type is TransactionModel:
nom_id = model.nomenclature.unique_code
stor_id = model.storage.unique_code
_, coef = model.measure_unit.get_base_unit()
stor_dict = self.repository.transactions_data.get(nom_id,
dict())
list_ = stor_dict.get(stor_id, list())
list_.append((model.datetime, coef * model.count))
stor_dict[stor_id] = list_
self.repository.transactions_data[nom_id] = stor_dict

return True

"""Метод конвертации объекта в модели групп номенклатур"""
Expand Down