""" Author: Michel Peltriaux Organization: Struktur- und Genehmigungsdirektion Nord, Rhineland-Palatinate, Germany Contact: michel.peltriaux@sgdnord.rlp.de Created on: 31.05.22 """ from django.db import transaction from codelist.models import KonovaCode from compensation.models import CompensationAction, CompensationState from intervention.models import Legal, Handler, Responsibility from konova.management.commands.setup import BaseKonovaCommand class Command(BaseKonovaCommand): help = "Updates internal codelist by external API" def handle(self, *args, **options): try: with transaction.atomic(): self.sync_codelist() except KeyboardInterrupt: self._break_line() exit(-1) def __get_newest_code(self, code): code = KonovaCode.objects.filter( atom_id=code.atom_id, parent=code.parent, code_lists__in=code.code_lists.all(), ).order_by( "-id" ).first() return code def __migrate_compensation_action_codes(self): all_actions = CompensationAction.objects.all() used_codes = [] for action in all_actions: stored_codes = action.action_type.all() codes = [] for code in stored_codes: codes.append(self.__get_newest_code(code)) action.action_type.set(codes) used_codes += codes stored_codes = action.action_type_details.all() codes = [] for code in stored_codes: codes.append(self.__get_newest_code(code)) action.action_type_details.set(codes) used_codes += codes action.save() return used_codes def __migrate_compensation_state_codes(self): all_states = CompensationState.objects.all() used_codes = [] for state in all_states: code = state.biotope_type if code is not None: new_code = self.__get_newest_code(code) state.biotope_type = new_code used_codes.append(new_code) stored_codes = state.biotope_type_details.all() codes = [] for code in stored_codes: codes.append(self.__get_newest_code(code)) state.biotope_type_details.set(codes) used_codes += codes state.save() return used_codes def __migrate_legal_codes(self): all_legal = Legal.objects.all() used_codes = [] for legal in all_legal: code = legal.process_type if code is not None: new_code = self.__get_newest_code(code) legal.process_type = new_code used_codes.append(new_code) stored_codes = legal.laws.all() codes = [] for code in stored_codes: codes.append(self.__get_newest_code(code)) legal.laws.set(codes) used_codes += codes legal.save() return used_codes def __migrate_handler_codes(apps): all_handlers = Handler.objects.all() used_codes = [] for handler in all_handlers: code = handler.type if code is None: continue new_code = apps.__get_newest_code(code) handler.type = new_code used_codes.append(new_code) handler.save() return used_codes def __migrate_responsibility_codes(apps): all_resps = Responsibility.objects.all() used_codes = [] for responsibility in all_resps: code = responsibility.registration_office if code is not None: new_code = apps.__get_newest_code(code) responsibility.registration_office = new_code used_codes.append(new_code) code = responsibility.conservation_office if code is not None: new_code = apps.__get_newest_code(code) responsibility.conservation_office = new_code used_codes.append(new_code) responsibility.save() return used_codes def sync_codelist(self): """ Due to issues on the external codelist app there can be multiple entries of the same code (atom_id, parent, list) but with different identifiers. These issues have been resolved but already Returns: """ self._write_warning("Sync codes in usage and replace by newest entries...") used_codes = [] used_codes += self.__migrate_compensation_action_codes() used_codes += self.__migrate_compensation_state_codes() used_codes += self.__migrate_legal_codes() used_codes += self.__migrate_handler_codes() used_codes += self.__migrate_responsibility_codes() self._write_success(f"Synced {len(used_codes)} code usages!") all_codes = KonovaCode.objects.all() newest_code_ids = [] for code in all_codes: newest_code = self.__get_newest_code(code) newest_code_ids.append(newest_code.id) code_ids_to_keep = set(newest_code_ids) self._write_warning(f"Of {all_codes.count()} KonovaCodes there are {len(code_ids_to_keep)} to keep as newest versions...") deletable_codes = KonovaCode.objects.all().exclude( id__in=code_ids_to_keep ) deletable_codes_count = deletable_codes.count() self._write_warning(f"{deletable_codes_count} found which are obsolet...") if deletable_codes_count > 0: deletable_codes.delete() self._write_success("Obsolete codes deleted!")