Pokus o implementaci mergovadla řešitelů
This commit is contained in:
		
							parent
							
								
									537e7b39f1
								
							
						
					
					
						commit
						f0f8a95e11
					
				
					 1 changed files with 133 additions and 0 deletions
				
			
		
							
								
								
									
										133
									
								
								seminar/utils.py
									
									
									
									
									
								
							
							
						
						
									
										133
									
								
								seminar/utils.py
									
									
									
									
									
								
							|  | @ -8,6 +8,8 @@ from django.contrib.auth.decorators import permission_required, \ | |||
| from html.parser import HTMLParser | ||||
| from django import views as DjangoViews | ||||
| 
 | ||||
| from django.db import transaction | ||||
| 
 | ||||
| from django.contrib.auth.models import AnonymousUser | ||||
| from django.contrib.contenttypes.models import ContentType | ||||
| from django.core.exceptions import ObjectDoesNotExist | ||||
|  | @ -376,3 +378,134 @@ def sync_skoly(base_url): | |||
| 	for skola in serializers.deserialize('json', json): | ||||
| 		skola.save() | ||||
| 
 | ||||
| @transaction.atomic | ||||
| def merge_resitele(cilovy, zdrojovy): | ||||
| 	"""Spojí dva řešitelské objekty do cílového. | ||||
| 
 | ||||
| 	Pojmenování "zdrojový" je silně nepřiléhající, ale co už…""" | ||||
| 
 | ||||
| 	# Postup: | ||||
| 	# Sjednotit / upravit informace cílového řešitele | ||||
| 	print('Upravuji data modelu') | ||||
| 	fieldy_shoda = ['skola', 'poznamka', 'rok_maturity', 'zasilat', 'zasilat_cislo_emailem'] | ||||
| 	 | ||||
| 	for f in fieldy_shoda: | ||||
| 		zf = getattr(zdrojovy, f) | ||||
| 		cf = getattr(cilovy, f) | ||||
| 		if cf == zf: | ||||
| 			print(f' Údaj {f} je shodný ({zf})') | ||||
| 		else: | ||||
| 			if zf is None: | ||||
| 				print(f' Údaj {f} je pouze v cílovém, používám') | ||||
| 				continue | ||||
| 			if cf is None: | ||||
| 				setattr(cilovy, f, zf) | ||||
| 				cilovy.poznamka += f'\nDEBUG: Merge: doplnéný údaj {f} ze zdrojového: {zf}' | ||||
| 				print(f" Přiřazuji {f} ze zdrojového: {zf}") | ||||
| 				continue | ||||
| 			# Jsou fakt různé… | ||||
| 			# FIXME: chybí možnost na vlastní úpravu… | ||||
| 			verdikt = input(f"\n\n Údaj {f} se u řešitele {cilovy} ({cilovy.id}) liší:\n  Zdrojový: {zf}\n  Cílový: {cf}\n Který použít, [z]drojový, [c]ílový? ") | ||||
| 			verdikt = verdikt[0].casefold() | ||||
| 			if verdikt == 'z': | ||||
| 				setattr(cilovy, f, zf) | ||||
| 				cilovy.poznamka += f'\nDEBUG: Merge: pro {f} použit údaj {zf} (zdrojový), nepoužit {cf} (cílový)' | ||||
| 			elif verdikt == 'c': | ||||
| 				cilovy.poznamka += f'\nDEBUG: Merge: pro {f} použit údaj {cf} (cílový), nepoužit {cf} (zdrojový)' | ||||
| 			else: raise ValueError('Špatná odpověď, řešitel pravděpodobně neuložen') | ||||
| 	# poznámku chceme nezahodit… | ||||
| 	cilovy.poznamka += f'\nDEBUG: Merge: Původní poznámka: {zdrojovy.poznamka}' | ||||
| 	print(f' Výsledný řešitel: {cilovy.__dict__}, ukládám') | ||||
| 	cilovy.save() | ||||
| 
 | ||||
| 
 | ||||
| 	# Přepojit všechny vazby ze zdrojového na cílového | ||||
| 	print('Přepojuji vazby') | ||||
| 	# Vazby: Škola (hotovo), Řešení_Řešitelé, Konfery_Účastníci, Soustředění_Účastníci, Osoba (vyřeší se později, nejde přepojit) | ||||
| 	ct = m.Reseni_Resitele.objects.filter(resitele=zdrojovy).update(resitele=cilovy) | ||||
| 	print(f' Přepojeno {ct} řešení') | ||||
| 	ct = m.Konfery_Ucastnici.objects.filter(resitel=zdrojovy).update(resitel=cilovy) | ||||
| 	print(f' Přepojeno {ct} konfer') | ||||
| 	ct = m.Soustredeni_Ucastnici.objects.filter(resitel=zdrojovy).update(resitel=cilovy) | ||||
| 	print(f' Přepojeno {ct} sousů') | ||||
| 
 | ||||
| 	# Teď by na zdrojovém řešiteli nemělo nic viset, smazat ho, pamatujíce si jeho Osobu | ||||
| 	zdrosoba = zdrojovy.osoba | ||||
| 	print(f'Mažu zdrojového řešitele {zdrojovy.__dict__}') | ||||
| 	zdrojovy.delete() | ||||
| 	# Spojit osoby (separátní funkce). | ||||
| 	merge_osoby(cilovy.osoba, zdrosoba) | ||||
| 
 | ||||
| 	input("Potvrdit transakci řešitelů (^C pro zrušení) ") | ||||
| 
 | ||||
| @transaction.atomic | ||||
| def merge_osoby(cilova, zdrojova): | ||||
| 	""" Spojí dvě osoby do cílové | ||||
| 
 | ||||
| 	Nehlídá omezení typu "max 1 řešitel na osobu", to by měla hlídat databáze (OneToOneField).""" | ||||
| 	# Sjednocení dat | ||||
| 	print('Sjednocuji data osob') | ||||
| 	# ID, User neřešíme, poznámku vyřešíme separátně. | ||||
| 	fieldy = ['datum_narozeni', 'datum_registrace', 'datum_souhlasu_udaje', | ||||
| 			'datum_souhlasu_zasilani', 'email', 'foto', 'jmeno', 'mesto', | ||||
| 			'pohlavi_muz', 'prezdivka', 'prijmeni', 'psc', 'stat', 'telefon', 'ulice'] | ||||
| 	for f in fieldy: | ||||
| 		zf = getattr(zdrojova, f) | ||||
| 		cf = getattr(cilova, f) | ||||
| 		if cf == zf: | ||||
| 			print(f' Údaj {f} je shodný ({zf})') | ||||
| 		else: | ||||
| 			if zf is None: | ||||
| 				print(f' Údaj {f} je pouze v cílové, používám') | ||||
| 				continue | ||||
| 			if cf is None: | ||||
| 				setattr(cilova, f, zf) | ||||
| 				cilova.poznamka += f'\nDEBUG: Merge: doplnéný údaj {f} ze zdrojové: {zf}' | ||||
| 				print(f" Přiřazuji {f} ze zdrojové: {zf}") | ||||
| 				continue | ||||
| 			# Jsou fakt různé… | ||||
| 			# FIXME: chybí možnost na vlastní úpravu… | ||||
| 			verdikt = input(f"\n\n Údaj {f} se u osoby {cilova} ({cilova.id}) liší:\n  Zdrojový: {zf}\n  Cílový: {cf}\n Který použít, [z]drojový, [c]ílový? ") | ||||
| 			verdikt = verdikt[0].casefold() | ||||
| 			if verdikt == 'z': | ||||
| 				setattr(cilova, f, zf) | ||||
| 				cilova.poznamka += f'\nDEBUG: Merge: pro {f} použit údaj {zf} (zdrojová), nepoužit {cf} (cílová)' | ||||
| 			elif verdikt == 'c': | ||||
| 				cilova.poznamka += f'\nDEBUG: Merge: pro {f} použit údaj {cf} (cílová), nepoužit {cf} (zdrojová)' | ||||
| 			else: raise ValueError('Špatná odpověď, řešitel pravděpodobně neuložen') | ||||
| 	# poznámku chceme nezahodit… | ||||
| 	cilova.poznamka += f'\nDEBUG: Merge: Původní poznámka: {zdrojova.poznamka}' | ||||
| 	print(f' Výsledná osoba: {cilova.__dict__}, ukládám') | ||||
| 	cilova.save() | ||||
| 
 | ||||
| 	# Vazby: Řešitel, User, Příjemce, Organizátor, Škola.kontaktní_osoba | ||||
| 	print('Přepojuji vazby') | ||||
| 	ct = m.Skola.objects.filter(kontaktni_osoba=zdrojova).update(kontaktni_osoba=cilova) | ||||
| 	print(f' Přepojeno {ct} kontaktních osob') | ||||
| 	# Ostatní vazby vyřeší OneToOneFieldy, ale někdy nemusí existovat… | ||||
| 	ct = m.Resitel.objects.filter(osoba=zdrojova).update(osoba=cilova) | ||||
| 	print(f' Přepojeno {ct} řešitelů') | ||||
| 	ct = m.Prijemce.objects.filter(osoba=zdrojova).update(osoba=cilova) | ||||
| 	print(f' Přepojeno {ct} příjemců') | ||||
| 	ct = m.Organizator.objects.filter(osoba=zdrojova).update(osoba=cilova) | ||||
| 	print(f' Přepojeno {ct} organizátorů') | ||||
| 	# Uživatelé vedou opačným směrem, radši chceme zkontrolovat, že jsou různí ručně: | ||||
| 	if zdrojova.user != cilova.user: | ||||
| 		# Jeden z nich může být nenastavený… | ||||
| 		if zdrojova.user is None: | ||||
| 			print('Uživatel je již v cílové osobě') | ||||
| 		elif cilova.user is None: | ||||
| 			print('Používám uživatele zdrojové osoby') | ||||
| 			cilova.user = zdrojova.user | ||||
| 			# Teď nemůžeme uložit, protože kolize uživatelů. Ukládat cílovou budeme až po smazání zdrojové. | ||||
| 		else: raise ValueError('Osoby mají obě uživatele, radši padám') | ||||
| 	 | ||||
| 	# Uložení a mazání | ||||
| 	print(f'Mažu zdrojovou osobu {zdrojova.__dict__}') | ||||
| 	zdrojova.delete() | ||||
| 	print(f'Ukládám cílovou osobu {cilova.__dict__}') | ||||
| 	cilova.save() | ||||
| 
 | ||||
| 	input("Potvrdit transakci osob (^C pro zrušení) ") | ||||
| 
 | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue
	
	 Pavel "LEdoian" Turinsky
						Pavel "LEdoian" Turinsky