R: intorduce facade
This commit is contained in:
parent
39a18121c6
commit
79ad54ed84
|
@ -26,7 +26,7 @@ CstMapping = dict[str, Constituenta]
|
||||||
|
|
||||||
|
|
||||||
class ChangeManager:
|
class ChangeManager:
|
||||||
''' Change propagation API. '''
|
''' Change propagation wrapper for OSS. '''
|
||||||
class Cache:
|
class Cache:
|
||||||
''' Cache for RSForm constituents. '''
|
''' Cache for RSForm constituents. '''
|
||||||
|
|
||||||
|
|
42
rsconcept/backend/apps/oss/models/PropagationFacade.py
Normal file
42
rsconcept/backend/apps/oss/models/PropagationFacade.py
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
''' Models: Change propagation facade - managing all changes in OSS. '''
|
||||||
|
from apps.library.models import LibraryItem
|
||||||
|
from apps.rsform.models import Constituenta, RSForm
|
||||||
|
|
||||||
|
from .ChangeManager import ChangeManager
|
||||||
|
|
||||||
|
|
||||||
|
def _get_oss_hosts(item: LibraryItem) -> list[LibraryItem]:
|
||||||
|
''' Get all hosts for LibraryItem. '''
|
||||||
|
return list(LibraryItem.objects.filter(operations__result=item).only('pk'))
|
||||||
|
|
||||||
|
|
||||||
|
class PropagationFacade:
|
||||||
|
''' Change propagation API. '''
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def on_create_cst(cls, new_cst: Constituenta, source: RSForm) -> None:
|
||||||
|
''' Trigger cascade resolutions when new constituent is created. '''
|
||||||
|
hosts = _get_oss_hosts(source.model)
|
||||||
|
for host in hosts:
|
||||||
|
ChangeManager(host).on_create_cst(new_cst, source)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def on_change_cst_type(cls, target: Constituenta, source: RSForm) -> None:
|
||||||
|
''' Trigger cascade resolutions when constituenta type is changed. '''
|
||||||
|
hosts = _get_oss_hosts(source.model)
|
||||||
|
for host in hosts:
|
||||||
|
ChangeManager(host).on_change_cst_type(target, source)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def on_update_cst(cls, target: Constituenta, data: dict, old_data: dict, source: RSForm) -> None:
|
||||||
|
''' Trigger cascade resolutions when constituenta data is changed. '''
|
||||||
|
hosts = _get_oss_hosts(source.model)
|
||||||
|
for host in hosts:
|
||||||
|
ChangeManager(host).on_update_cst(target, data, old_data, source)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def before_delete(cls, delete_cst: list[Constituenta], source: RSForm) -> None:
|
||||||
|
''' Trigger cascade resolutions before constituents are deleted. '''
|
||||||
|
# hosts = _get_oss_hosts(source.model)
|
||||||
|
# for host in hosts:
|
||||||
|
# ChangeManager(host).before_delete(delete_cst, source)
|
|
@ -6,3 +6,4 @@ from .Inheritance import Inheritance
|
||||||
from .Operation import Operation, OperationType
|
from .Operation import Operation, OperationType
|
||||||
from .OperationSchema import OperationSchema
|
from .OperationSchema import OperationSchema
|
||||||
from .Substitution import Substitution
|
from .Substitution import Substitution
|
||||||
|
from .PropagationFacade import PropagationFacade
|
||||||
|
|
|
@ -16,7 +16,7 @@ from rest_framework.serializers import ValidationError
|
||||||
|
|
||||||
from apps.library.models import AccessPolicy, LibraryItem, LibraryItemType, LocationHead
|
from apps.library.models import AccessPolicy, LibraryItem, LibraryItemType, LocationHead
|
||||||
from apps.library.serializers import LibraryItemSerializer
|
from apps.library.serializers import LibraryItemSerializer
|
||||||
from apps.oss.models import ChangeManager
|
from apps.oss.models import PropagationFacade
|
||||||
from apps.users.models import User
|
from apps.users.models import User
|
||||||
from shared import messages as msg
|
from shared import messages as msg
|
||||||
from shared import permissions, utility
|
from shared import permissions, utility
|
||||||
|
@ -84,15 +84,10 @@ class RSFormViewSet(viewsets.GenericViewSet, generics.ListAPIView, generics.Retr
|
||||||
insert_after = None
|
insert_after = None
|
||||||
else:
|
else:
|
||||||
insert_after = data['insert_after']
|
insert_after = data['insert_after']
|
||||||
|
|
||||||
schema = m.RSForm(self._get_item())
|
schema = m.RSForm(self._get_item())
|
||||||
with transaction.atomic():
|
with transaction.atomic():
|
||||||
new_cst = schema.create_cst(data, insert_after)
|
new_cst = schema.create_cst(data, insert_after)
|
||||||
hosts = LibraryItem.objects.filter(operations__result=schema.model)
|
PropagationFacade.on_create_cst(new_cst, schema)
|
||||||
for host in hosts:
|
|
||||||
ChangeManager(host).on_create_cst(new_cst, schema)
|
|
||||||
|
|
||||||
|
|
||||||
return Response(
|
return Response(
|
||||||
status=c.HTTP_201_CREATED,
|
status=c.HTTP_201_CREATED,
|
||||||
data={
|
data={
|
||||||
|
@ -118,16 +113,12 @@ class RSFormViewSet(viewsets.GenericViewSet, generics.ListAPIView, generics.Retr
|
||||||
model = self._get_item()
|
model = self._get_item()
|
||||||
serializer = s.CstUpdateSerializer(data=request.data, partial=True, context={'schema': model})
|
serializer = s.CstUpdateSerializer(data=request.data, partial=True, context={'schema': model})
|
||||||
serializer.is_valid(raise_exception=True)
|
serializer.is_valid(raise_exception=True)
|
||||||
|
|
||||||
cst = cast(m.Constituenta, serializer.validated_data['target'])
|
cst = cast(m.Constituenta, serializer.validated_data['target'])
|
||||||
schema = m.RSForm(model)
|
schema = m.RSForm(model)
|
||||||
data = serializer.validated_data['item_data']
|
data = serializer.validated_data['item_data']
|
||||||
with transaction.atomic():
|
with transaction.atomic():
|
||||||
hosts = LibraryItem.objects.filter(operations__result=model)
|
|
||||||
old_data = schema.update_cst(cst, data)
|
old_data = schema.update_cst(cst, data)
|
||||||
for host in hosts:
|
PropagationFacade.on_update_cst(cst, data, old_data, schema)
|
||||||
ChangeManager(host).on_update_cst(cst, data, old_data, schema)
|
|
||||||
|
|
||||||
return Response(
|
return Response(
|
||||||
status=c.HTTP_200_OK,
|
status=c.HTTP_200_OK,
|
||||||
data=s.CstSerializer(m.Constituenta.objects.get(pk=request.data['target'])).data
|
data=s.CstSerializer(m.Constituenta.objects.get(pk=request.data['target'])).data
|
||||||
|
@ -164,13 +155,15 @@ class RSFormViewSet(viewsets.GenericViewSet, generics.ListAPIView, generics.Retr
|
||||||
status=c.HTTP_400_BAD_REQUEST,
|
status=c.HTTP_400_BAD_REQUEST,
|
||||||
data={f'{cst.pk}': msg.constituentaNoStructure()}
|
data={f'{cst.pk}': msg.constituentaNoStructure()}
|
||||||
)
|
)
|
||||||
|
schema = m.RSForm(model)
|
||||||
|
|
||||||
with transaction.atomic():
|
with transaction.atomic():
|
||||||
result = m.RSForm(model).produce_structure(cst, cst_parse)
|
result = schema.produce_structure(cst, cst_parse)
|
||||||
return Response(
|
return Response(
|
||||||
status=c.HTTP_200_OK,
|
status=c.HTTP_200_OK,
|
||||||
data={
|
data={
|
||||||
'cst_list': result,
|
'cst_list': result,
|
||||||
'schema': s.RSFormParseSerializer(model).data
|
'schema': s.RSFormParseSerializer(schema.model).data
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -191,28 +184,23 @@ class RSFormViewSet(viewsets.GenericViewSet, generics.ListAPIView, generics.Retr
|
||||||
model = self._get_item()
|
model = self._get_item()
|
||||||
serializer = s.CstRenameSerializer(data=request.data, context={'schema': model})
|
serializer = s.CstRenameSerializer(data=request.data, context={'schema': model})
|
||||||
serializer.is_valid(raise_exception=True)
|
serializer.is_valid(raise_exception=True)
|
||||||
|
|
||||||
cst = cast(m.Constituenta, serializer.validated_data['target'])
|
cst = cast(m.Constituenta, serializer.validated_data['target'])
|
||||||
changed_type = cst.cst_type != serializer.validated_data['cst_type']
|
changed_type = cst.cst_type != serializer.validated_data['cst_type']
|
||||||
mapping = {cst.alias: serializer.validated_data['alias']}
|
mapping = {cst.alias: serializer.validated_data['alias']}
|
||||||
cst.alias = serializer.validated_data['alias']
|
|
||||||
cst.cst_type = serializer.validated_data['cst_type']
|
|
||||||
schema = m.RSForm(model)
|
schema = m.RSForm(model)
|
||||||
|
|
||||||
with transaction.atomic():
|
with transaction.atomic():
|
||||||
|
cst.alias = serializer.validated_data['alias']
|
||||||
|
cst.cst_type = serializer.validated_data['cst_type']
|
||||||
cst.save()
|
cst.save()
|
||||||
schema.apply_mapping(mapping=mapping, change_aliases=False)
|
schema.apply_mapping(mapping=mapping, change_aliases=False)
|
||||||
cst.refresh_from_db()
|
cst.refresh_from_db()
|
||||||
if changed_type:
|
if changed_type:
|
||||||
hosts = LibraryItem.objects.filter(operations__result=model)
|
PropagationFacade.on_change_cst_type(cst, schema)
|
||||||
for host in hosts:
|
|
||||||
ChangeManager(host).on_change_cst_type(cst, schema)
|
|
||||||
|
|
||||||
return Response(
|
return Response(
|
||||||
status=c.HTTP_200_OK,
|
status=c.HTTP_200_OK,
|
||||||
data={
|
data={
|
||||||
'new_cst': s.CstSerializer(cst).data,
|
'new_cst': s.CstSerializer(cst).data,
|
||||||
'schema': s.RSFormParseSerializer(model).data
|
'schema': s.RSFormParseSerializer(schema.model).data
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -236,19 +224,17 @@ class RSFormViewSet(viewsets.GenericViewSet, generics.ListAPIView, generics.Retr
|
||||||
context={'schema': model}
|
context={'schema': model}
|
||||||
)
|
)
|
||||||
serializer.is_valid(raise_exception=True)
|
serializer.is_valid(raise_exception=True)
|
||||||
|
schema = m.RSForm(model)
|
||||||
|
substitutions: list[tuple[m.Constituenta, m.Constituenta]] = []
|
||||||
with transaction.atomic():
|
with transaction.atomic():
|
||||||
substitutions: list[tuple[m.Constituenta, m.Constituenta]] = []
|
|
||||||
for substitution in serializer.validated_data['substitutions']:
|
for substitution in serializer.validated_data['substitutions']:
|
||||||
original = cast(m.Constituenta, substitution['original'])
|
original = cast(m.Constituenta, substitution['original'])
|
||||||
replacement = cast(m.Constituenta, substitution['substitution'])
|
replacement = cast(m.Constituenta, substitution['substitution'])
|
||||||
substitutions.append((original, replacement))
|
substitutions.append((original, replacement))
|
||||||
m.RSForm(model).substitute(substitutions)
|
schema.substitute(substitutions)
|
||||||
|
|
||||||
model.refresh_from_db()
|
|
||||||
return Response(
|
return Response(
|
||||||
status=c.HTTP_200_OK,
|
status=c.HTTP_200_OK,
|
||||||
data=s.RSFormParseSerializer(model).data
|
data=s.RSFormParseSerializer(schema.model).data
|
||||||
)
|
)
|
||||||
|
|
||||||
@extend_schema(
|
@extend_schema(
|
||||||
|
@ -271,11 +257,14 @@ class RSFormViewSet(viewsets.GenericViewSet, generics.ListAPIView, generics.Retr
|
||||||
context={'schema': model}
|
context={'schema': model}
|
||||||
)
|
)
|
||||||
serializer.is_valid(raise_exception=True)
|
serializer.is_valid(raise_exception=True)
|
||||||
|
cst_list: list[m.Constituenta] = serializer.validated_data['items']
|
||||||
|
schema = m.RSForm(model)
|
||||||
with transaction.atomic():
|
with transaction.atomic():
|
||||||
m.RSForm(model).delete_cst(serializer.validated_data['items'])
|
PropagationFacade.before_delete(cst_list, schema)
|
||||||
|
schema.delete_cst(cst_list)
|
||||||
return Response(
|
return Response(
|
||||||
status=c.HTTP_200_OK,
|
status=c.HTTP_200_OK,
|
||||||
data=s.RSFormParseSerializer(model).data
|
data=s.RSFormParseSerializer(schema.model).data
|
||||||
)
|
)
|
||||||
|
|
||||||
@extend_schema(
|
@extend_schema(
|
||||||
|
|
Loading…
Reference in New Issue
Block a user