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 html.parser import HTMLParser | ||||||
| from django import views as DjangoViews | from django import views as DjangoViews | ||||||
| 
 | 
 | ||||||
|  | from django.db import transaction | ||||||
|  | 
 | ||||||
| from django.contrib.auth.models import AnonymousUser | from django.contrib.auth.models import AnonymousUser | ||||||
| from django.contrib.contenttypes.models import ContentType | from django.contrib.contenttypes.models import ContentType | ||||||
| from django.core.exceptions import ObjectDoesNotExist | from django.core.exceptions import ObjectDoesNotExist | ||||||
|  | @ -376,3 +378,134 @@ def sync_skoly(base_url): | ||||||
| 	for skola in serializers.deserialize('json', json): | 	for skola in serializers.deserialize('json', json): | ||||||
| 		skola.save() | 		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